Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F37007534
__main__.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Sep 22, 00:59
Size
8 KB
Mime Type
text/x-python
Expires
Sun, Sep 24, 00:59 (2 d)
Engine
blob
Format
Raw Data
Handle
13699546
Attached To
rTAMAAS tamaas
__main__.py
View Options
#!/usr/bin/env python3
# -*- mode: python; coding: utf-8 -*-
# vim: set ft=python:
#
# Copyright (©) 2016-2022 EPFL (École Polytechnique Fédérale de Lausanne),
# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Module entry point."""
import
sys
import
io
import
time
import
argparse
import
tamaas
as
tm
import
numpy
as
np
from
types
import
SimpleNamespace
from
pathlib
import
Path
__author__
=
"Lucas Frérot"
__copyright__
=
(
"Copyright (©) 2019-2022, EPFL (École Polytechnique Fédérale de Lausanne),"
"
\n
Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)"
)
__license__
=
"SPDX-License-Identifier: AGPL-3.0-or-later"
def
load_stream
(
stream
):
"""
Load numpy from binary stream (allows piping).
Code from
https://gist.github.com/CMCDragonkai/3c99fd4aabc8278b9e17f50494fcc30a
"""
np_magic
=
stream
.
read
(
6
)
# use the sys.stdin.buffer to read binary data
np_data
=
stream
.
read
()
# read it all into an io.BytesIO object
return
io
.
BytesIO
(
np_magic
+
np_data
)
def
print_version
():
"""Print version information."""
print
(
f
"""Tamaas {tm.__version__}
{tm.__copyright__}
Authors: {', '.join(tm.__author__)}
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."""
)
def
make_surface
(
args
):
"""Generate a surface."""
if
args
.
generator
==
"random_phase"
:
generator
=
tm
.
SurfaceGeneratorRandomPhase2D
(
args
.
sizes
)
elif
args
.
generator
==
"filter"
:
generator
=
tm
.
SurfaceGeneratorFilter2D
(
args
.
sizes
)
else
:
raise
ValueError
(
f
"Unknown generator method {args.generator}"
)
generator
.
spectrum
=
tm
.
Isopowerlaw2D
()
generator
.
spectrum
.
q0
=
args
.
cutoffs
[
0
]
generator
.
spectrum
.
q1
=
args
.
cutoffs
[
1
]
generator
.
spectrum
.
q2
=
args
.
cutoffs
[
2
]
generator
.
spectrum
.
hurst
=
args
.
hurst
if
'seed'
in
args
.
__dict__
:
generator
.
random_seed
=
args
.
seed
surface
=
(
generator
.
buildSurface
()
/
generator
.
spectrum
.
rmsSlopes
()
*
args
.
rms
)
params
=
{
"q0"
:
generator
.
spectrum
.
q0
,
"q1"
:
generator
.
spectrum
.
q1
,
"q2"
:
generator
.
spectrum
.
q2
,
"hurst"
:
generator
.
spectrum
.
hurst
,
"random_seed"
:
generator
.
random_seed
,
"rms_slopes"
:
args
.
rms
,
"generator"
:
args
.
generator
,
}
return
params
,
surface
def
surface
(
args
):
"""Print a surface to stdout."""
params
,
surface
=
make_surface
(
args
)
output
=
args
.
output
if
args
.
output
is
not
None
else
sys
.
stdout
try
:
np
.
savetxt
(
output
,
surface
,
header
=
str
(
params
))
except
BrokenPipeError
:
pass
def
declarative
(
args
):
"""Run simulation defined in YAML."""
from
ruamel.yaml
import
YAML
tm
.
set_log_level
(
tm
.
LogLevel
.
error
)
if
not
args
.
input
:
input
=
sys
.
stdin
else
:
input
=
args
.
input
yml
=
YAML
(
typ
=
'safe'
)
data
=
yml
.
load
(
Path
(
input
))
# Handle surface definition
if
'surface'
not
in
data
:
sys
.
exit
(
"Error: simulation description does not declare a surface"
)
if
len
(
data
[
'surface'
])
>
1
:
sys
.
exit
(
"Error: expected only one surface definition, got multiple"
)
args
=
SimpleNamespace
()
args
.
generator
=
list
(
data
[
'surface'
])[
0
]
for
k
,
v
in
data
[
'surface'
][
args
.
generator
]
.
items
():
setattr
(
args
,
k
,
v
)
try
:
_
,
surface
=
make_surface
(
args
)
except
AttributeError
as
e
:
attr
=
str
(
e
)
.
split
(
" "
)[
-
1
]
.
replace
(
"'"
,
""
)
sys
.
exit
(
f
"Error: Surface property '{attr}' required but not specified"
)
# Handle model definition
if
'model'
not
in
data
:
sys
.
exit
(
"Error: simulation description does not declare a model"
)
mdata
=
data
[
'model'
]
try
:
if
mdata
[
'type'
]
not
in
{
'basic_1d'
,
'basic_2d'
}:
sys
.
exit
(
f
'Error: unrecognized model type
\'
{mdata["type"]}
\'
'
)
mtype
=
getattr
(
tm
.
model_type
,
mdata
[
'type'
])
model
=
tm
.
ModelFactory
.
createModel
(
mtype
,
mdata
[
'system_size'
],
mdata
[
'shape'
],
)
except
KeyError
as
e
:
sys
.
exit
(
f
"Error: model property {e} required but not specified"
)
model
.
E
=
mdata
.
get
(
'E'
,
1
)
model
.
nu
=
mdata
.
get
(
'nu'
,
0
)
def
contact
(
args
):
"""Solve a contact problem."""
from
tamaas.dumpers
import
NumpyDumper
tm
.
set_log_level
(
tm
.
LogLevel
.
error
)
if
not
args
.
input
:
input
=
sys
.
stdin
else
:
input
=
args
.
input
surface
=
np
.
loadtxt
(
input
)
discretization
=
surface
.
shape
system_size
=
[
1.0
,
1.0
]
model
=
tm
.
ModelFactory
.
createModel
(
tm
.
model_type
.
basic_2d
,
system_size
,
discretization
)
solver
=
tm
.
PolonskyKeerRey
(
model
,
surface
,
args
.
tol
)
solver
.
solve
(
args
.
load
)
dumper
=
NumpyDumper
(
"numpy"
,
"traction"
,
"displacement"
)
dumper
.
dump_to_file
(
sys
.
stdout
.
buffer
,
model
)
def
plot
(
args
):
"""Plot displacement and pressure maps."""
try
:
import
matplotlib.pyplot
as
plt
except
ImportError
:
print
(
"Please install matplotlib to use the 'plot' command"
,
file
=
sys
.
stderr
,
)
sys
.
exit
(
1
)
fig
,
(
ax_traction
,
ax_displacement
)
=
plt
.
subplots
(
1
,
2
)
ax_traction
.
set_title
(
"Traction"
)
ax_displacement
.
set_title
(
"Displacement"
)
with
load_stream
(
sys
.
stdin
.
buffer
)
as
f_np
:
data
=
np
.
load
(
f_np
)
ax_traction
.
imshow
(
data
[
"traction"
])
ax_displacement
.
imshow
(
data
[
"displacement"
])
fig
.
set_size_inches
(
10
,
6
)
fig
.
tight_layout
()
plt
.
show
()
def
main
():
"""Process command line arguments."""
parser
=
argparse
.
ArgumentParser
(
prog
=
"tamaas"
,
description
=
(
"The tamaas command is a simple utility for surface"
" generation, contact computation and"
" plotting of contact solutions"
),
)
parser
.
add_argument
(
"--version"
,
action
=
"store_true"
,
help
=
"print version info"
)
subs
=
parser
.
add_subparsers
(
title
=
"commands"
,
description
=
"utility commands"
)
# Arguments for surface command
parser_surface
=
subs
.
add_parser
(
"surface"
,
description
=
"Generate a self-affine rough surface"
)
parser_surface
.
add_argument
(
"--cutoffs"
,
"-K"
,
nargs
=
3
,
type
=
int
,
help
=
"Long, rolloff, short wavelength cutoffs"
,
metavar
=
(
"k_l"
,
"k_r"
,
"k_s"
),
required
=
True
,
)
parser_surface
.
add_argument
(
"--sizes"
,
nargs
=
2
,
type
=
int
,
help
=
"Number of points"
,
metavar
=
(
"nx"
,
"ny"
),
required
=
True
,
)
parser_surface
.
add_argument
(
"--hurst"
,
"-H"
,
type
=
float
,
help
=
"Hurst exponent"
,
required
=
True
)
parser_surface
.
add_argument
(
"--rms"
,
type
=
float
,
help
=
"Root-mean-square of slopes"
,
default
=
1.0
)
parser_surface
.
add_argument
(
"--seed"
,
type
=
int
,
help
=
"Random seed"
,
default
=
int
(
time
.
time
())
)
parser_surface
.
add_argument
(
"--generator"
,
help
=
"Generation method"
,
choices
=
(
"random_phase"
,
"filter"
),
default
=
"random_phase"
,
)
parser_surface
.
add_argument
(
"--output"
,
"-o"
,
help
=
"Output file name (compressed if .gz)"
)
parser_surface
.
set_defaults
(
func
=
surface
)
# Arguments for contact command
parser_contact
=
subs
.
add_parser
(
"contact"
,
description
=
"Compute the elastic contact solution with a given surface"
,
)
parser_contact
.
add_argument
(
"--input"
,
"-i"
,
help
=
"Rough surface file (default stdin)"
)
parser_contact
.
add_argument
(
"--tol"
,
type
=
float
,
default
=
1e-12
,
help
=
"Solver tolerance"
)
parser_contact
.
add_argument
(
"load"
,
type
=
float
,
help
=
"Applied average pressure"
)
parser_contact
.
set_defaults
(
func
=
contact
)
# Arguments for plot command
parser_plot
=
subs
.
add_parser
(
"plot"
,
description
=
"Plot contact solution"
)
parser_plot
.
set_defaults
(
func
=
plot
)
# Arguments for declarative command
parser_decl
=
subs
.
add_parser
(
"declarative"
,
description
=
"Run simulation described by YAML file"
)
parser_decl
.
add_argument
(
"input"
,
help
=
"YAML file"
)
parser_decl
.
set_defaults
(
func
=
declarative
)
args
=
parser
.
parse_args
()
if
args
.
version
:
print_version
()
return
try
:
args
.
func
(
args
)
except
AttributeError
:
parser
.
print_usage
()
if
__name__
==
"__main__"
:
main
()
Event Timeline
Log In to Comment