FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
diffmpm/diffmpm/solver.py at main · geoelements/diffmpm · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
geoelements
/
diffmpm
Public
Notifications
You must be signed in to change notification settings
Fork
5
Star
48
Code
Issues
7
Pull requests
6
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
diffmpm
/
diffmpm
/
solver.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
222 lines (192 loc) · 7.53 KB
Breadcrumbs
diffmpm
/
diffmpm
/
solver.py
Copy path
File metadata and controls
222 lines (192 loc) · 7.53 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
from
__future__
import
annotations
import
functools
from
typing
import
TYPE_CHECKING
,
Callable
,
Optional
import
jax
.
numpy
as
jnp
from
jax
import
lax
from
jax
.
experimental
.
host_callback
import
id_tap
from
jax
.
tree_util
import
register_pytree_node_class
from
jax
.
typing
import
ArrayLike
from
diffmpm
.
scheme
import
USF
,
USL
,
_MPMScheme
,
_schemes
if
TYPE_CHECKING
:
from
diffmpm
.
mesh
import
_MeshBase
@
register_pytree_node_class
class
MPMExplicit
:
"""A class to implement the fully explicit MPM."""
__particle_props
=
(
"loc"
,
"velocity"
,
"stress"
,
"strain"
)
def
__init__
(
self
,
mesh
:
_MeshBase
,
dt
:
float
,
scheme
:
str
=
"usf"
,
velocity_update
:
bool
=
False
,
sim_steps
:
int
=
1
,
out_steps
:
int
=
1
,
out_dir
:
str
=
"results/"
,
writer_func
:
Optional
[
Callable
]
=
None
,
)
->
None
:
"""Create an `MPMExplicit` object.
This can be used to solve a given configuration of an MPM
problem.
Parameters
----------
mesh: _MeshBase
A `diffmpm.Mesh` object that contains the elements that form
the underlying mesh used to solve the simulation.
dt: float
Timestep used in the simulation.
scheme: str
The MPM Scheme type used for the simulation. Can be one of
`"usl"` or `"usf"`. Default set to `"usf"`.
velocity_update: bool
Flag to control if velocity should be updated using nodal
velocity or interpolated nodal acceleration. If `True`, nodal
velocity is used, else nodal acceleration. Default `False`.
sim_steps: int
Number of steps to run the simulation for. Default set to 1.
out_steps: int
Frequency with which to store the results. For example, if
set to 5, the result at every 5th step will be stored. Default
set to 1.
out_dir: str
Path to the output directory where results are stored.
writer_func: Callable, None
Function that is used to write the state in the output
directory.
"""
if
scheme
==
"usf"
:
self
.
mpm_scheme
:
_MPMScheme
=
USF
(
mesh
,
dt
,
velocity_update
)
# type: ignore
elif
scheme
==
"usl"
:
self
.
mpm_scheme
:
_MPMScheme
=
USL
(
mesh
,
dt
,
velocity_update
)
# type: ignore
else
:
raise
ValueError
(
f"Please select scheme from
{
_schemes
}
. Found
{
scheme
}
"
)
self
.
mesh
=
mesh
self
.
dt
=
dt
self
.
scheme
=
scheme
self
.
velocity_update
=
velocity_update
self
.
sim_steps
=
sim_steps
self
.
out_steps
=
out_steps
self
.
out_dir
=
out_dir
self
.
writer_func
=
writer_func
self
.
mpm_scheme
.
mesh
.
apply_on_elements
(
"set_particle_element_ids"
)
self
.
mpm_scheme
.
mesh
.
apply_on_elements
(
"compute_volume"
)
self
.
mpm_scheme
.
mesh
.
apply_on_particles
(
"compute_volume"
,
args
=
(
self
.
mesh
.
elements
.
total_elements
,)
)
def
tree_flatten
(
self
):
children
=
(
self
.
mesh
,)
aux_data
=
{
"dt"
:
self
.
dt
,
"scheme"
:
self
.
scheme
,
"velocity_update"
:
self
.
velocity_update
,
"sim_steps"
:
self
.
sim_steps
,
"out_steps"
:
self
.
out_steps
,
"out_dir"
:
self
.
out_dir
,
"writer_func"
:
self
.
writer_func
,
}
return
children
,
aux_data
@
classmethod
def
tree_unflatten
(
cls
,
aux_data
,
children
):
return
cls
(
*
children
,
aux_data
[
"dt"
],
scheme
=
aux_data
[
"scheme"
],
velocity_update
=
aux_data
[
"velocity_update"
],
sim_steps
=
aux_data
[
"sim_steps"
],
out_steps
=
aux_data
[
"out_steps"
],
out_dir
=
aux_data
[
"out_dir"
],
writer_func
=
aux_data
[
"writer_func"
],
)
def
_jax_writer
(
self
,
func
,
args
):
id_tap
(
func
,
args
)
def
solve
(
self
,
gravity
:
ArrayLike
):
"""Non-JIT solve method.
This method runs the entire simulation for the defined number
of steps.
.. note::
This is mainly used for debugging and might be removed in
future versions or moved to the JIT solver.
Parameters
----------
gravity: ArrayLike
Gravity present in the system. This should be an array equal
with shape `(1, ndim)` where `ndim` is the dimension of the
simulation.
Returns
-------
dict
A dictionary of `ArrayLike` arrays corresponding to the
all states of the simulation after completing all steps.
"""
from
collections
import
defaultdict
from
tqdm
import
tqdm
# type: ignore
result
=
defaultdict
(
list
)
for
step
in
tqdm
(
range
(
self
.
sim_steps
)):
self
.
mpm_scheme
.
compute_nodal_kinematics
()
self
.
mpm_scheme
.
precompute_stress_strain
()
self
.
mpm_scheme
.
compute_forces
(
gravity
,
step
)
self
.
mpm_scheme
.
compute_particle_kinematics
()
self
.
mpm_scheme
.
postcompute_stress_strain
()
for
pset
in
self
.
mesh
.
particles
:
result
[
"position"
].
append
(
pset
.
loc
)
result
[
"velocity"
].
append
(
pset
.
velocity
)
result
[
"stress"
].
append
(
pset
.
stress
[:, :
2
,
0
])
result
[
"strain"
].
append
(
pset
.
strain
[:, :
2
,
0
])
result_arr
=
{
k
:
jnp
.
asarray
(
v
)
for
k
,
v
in
result
.
items
()}
return
result_arr
def
solve_jit
(
self
,
gravity
:
ArrayLike
)
->
dict
:
"""Solver method that runs the simulation.
This method runs the entire simulation for the defined number
of steps.
Parameters
----------
gravity: ArrayLike
Gravity present in the system. This should be an array equal
with shape `(1, ndim)` where `ndim` is the dimension of the
simulation.
Returns
-------
dict
A dictionary of `jax.numpy` arrays corresponding to the
final state of the simulation after completing all steps.
"""
def
_step
(
i
,
data
):
self
=
data
self
.
mpm_scheme
.
compute_nodal_kinematics
()
self
.
mpm_scheme
.
precompute_stress_strain
()
self
.
mpm_scheme
.
compute_forces
(
gravity
,
i
)
self
.
mpm_scheme
.
compute_particle_kinematics
()
self
.
mpm_scheme
.
postcompute_stress_strain
()
def
_write
(
self
,
i
):
arrays
=
{}
for
name
in
self
.
__particle_props
:
arrays
[
name
]
=
jnp
.
array
(
[
getattr
(
self
.
mesh
.
particles
[
j
],
name
).
squeeze
()
for
j
in
range
(
len
(
self
.
mesh
.
particles
))
]
)
self
.
_jax_writer
(
functools
.
partial
(
self
.
writer_func
,
out_dir
=
self
.
out_dir
,
max_steps
=
self
.
sim_steps
),
(
arrays
,
i
),
)
if
self
.
writer_func
is
not
None
:
lax
.
cond
(
i
%
self
.
out_steps
==
0
,
_write
,
lambda
s
,
i
:
None
,
self
,
i
,
)
return
self
self
=
lax
.
fori_loop
(
0
,
self
.
sim_steps
,
_step
,
self
)
arrays
=
{}
for
name
in
self
.
__particle_props
:
arrays
[
name
]
=
jnp
.
array
(
[
getattr
(
self
.
mesh
.
particles
[
j
],
name
)
for
j
in
range
(
len
(
self
.
mesh
.
particles
))
]
).
squeeze
()
return
arrays
Back
|
FazBrowse Home
|
New Git URL