Skip to content

Commit 8912dd7

Browse files
committed
Update example and store more solver results
1 parent d22986c commit 8912dd7

3 files changed

Lines changed: 87 additions & 11 deletions

File tree

diffmpm/solver.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ def tree_unflatten(cls, aux_data, children):
3030
return cls(*children, aux_data[0], scheme=aux_data[1])
3131

3232
def solve(self, nsteps: int, gravity: float):
33-
# self.initialize_materials()
34-
# self.initialize_mesh()
35-
# self.initialize_particles()
3633
result = {"position": [], "velocity": []}
3734
for step in tqdm(range(nsteps)):
3835
self.mpm_scheme.compute_nodal_kinematics()
@@ -52,13 +49,19 @@ def solve_jit(self, nsteps: int, gravity: float):
5249
result = {
5350
"position": jnp.zeros((nsteps, nparticles)),
5451
"velocity": jnp.zeros((nsteps, nparticles)),
52+
"strain_energy": jnp.zeros((nsteps, nparticles)),
53+
"kinetic_energy": jnp.zeros((nsteps, nparticles)),
54+
"total_energy": jnp.zeros((nsteps, nparticles)),
55+
"stress": jnp.zeros((nsteps, nparticles)),
56+
"strain": jnp.zeros((nsteps, nparticles)),
5557
}
5658

5759
def _step(i, data):
5860
self, result = data
5961
self.mpm_scheme.compute_nodal_kinematics()
6062
self.mpm_scheme.precompute_stress_strain()
6163
self.mpm_scheme.compute_forces(gravity)
64+
self.mpm_scheme.update_nodal_momentum()
6265
self.mpm_scheme.compute_particle_kinematics()
6366
self.mpm_scheme.postcompute_stress_strain()
6467

@@ -76,6 +79,38 @@ def _step(i, data):
7679
.at[i, idl:idu]
7780
.set(self.mesh.particles[j].velocity.squeeze())
7881
)
82+
result["stress"] = (
83+
result["stress"]
84+
.at[i, idl:idu]
85+
.set(self.mesh.particles[j].stress[:, 0, :].squeeze())
86+
)
87+
result["strain"] = (
88+
result["strain"]
89+
.at[i, idl:idu]
90+
.set(self.mesh.particles[j].strain[:, 0, :].squeeze())
91+
)
92+
strain_energy = (
93+
0.5
94+
* self.mesh.particles[j].stress[:, 0, :].squeeze()
95+
* self.mesh.particles[j].strain[:, 0, :].squeeze()
96+
* self.mesh.particles[j].volume.squeeze()
97+
)
98+
kinetic_energy = (
99+
0.5
100+
* self.mesh.particles[j].velocity.squeeze() ** 2
101+
* self.mesh.particles[j].mass.squeeze()
102+
)
103+
result["strain_energy"] = (
104+
result["strain_energy"].at[i, idl:idu].set(strain_energy)
105+
)
106+
result["kinetic_energy"] = (
107+
result["kinetic_energy"].at[i, idl:idu].set(kinetic_energy)
108+
)
109+
result["total_energy"] = (
110+
result["total_energy"]
111+
.at[i, idl:idu]
112+
.set(strain_energy + kinetic_energy)
113+
)
79114
return (self, result)
80115

81116
_, result = lax.fori_loop(0, nsteps, _step, (self, result))

examples/optim_1d.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
b1 = jnp.pi * 0.5
2020
particles.velocity += 0.1
2121
particles.set_mass_volume(1.0)
22-
dt = 0.001
23-
nsteps = 2000
22+
dt = 0.01
23+
nsteps = 1000
2424
mesh = _MeshBase({"particles": [particles], "elements": elements})
2525

2626
mpm = MPMExplicit(mesh, dt, scheme="usl")
@@ -32,11 +32,9 @@
3232

3333
@jit
3434
def compute_loss(E, mpm, target_vel):
35-
# debug.breakpoint()
3635
mpm.mesh.particles[0].material.properties["E"] = E
3736
mpm.mesh.particles[0].velocity = mesh.particles[0].velocity.at[:].set(0.1)
38-
# debug.breakpoint()
39-
nsteps = 2000
37+
nsteps = 1000
4038
result = mpm.solve_jit(nsteps, 0)
4139
vel = result["velocity"]
4240
loss = jnp.linalg.norm(vel - target_vel)
@@ -63,7 +61,7 @@ def optax_adam(params, niter, mpm, target_vel):
6361
return param_list, loss_list
6462

6563

66-
params = 95.0
64+
params = 107.5
6765
material = SimpleMaterial({"E": params, "density": 1})
6866
elements = Linear1D(1, 1, jnp.array([0]))
6967
particles = Particles(

examples/simple_1d.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,28 @@
1616
# particles.velocity = velocity
1717
particles.velocity += 0.1
1818
particles.set_mass_volume(1.0)
19-
dt = 0.001
20-
nsteps = 2500
19+
dt = 0.01
20+
nsteps = 1000
2121
mesh = _MeshBase({"particles": [particles], "elements": elements})
2222

2323
mpm = MPMExplicit(mesh, dt, scheme="usl")
2424
result = mpm.solve_jit(nsteps, 0)
2525

2626

27+
res_json = {
28+
"x_p": result["position"].squeeze().tolist(),
29+
"v_p": result["velocity"].squeeze().tolist(),
30+
"strain_p": result["strain"].squeeze().tolist(),
31+
"stress_p": result["stress"].squeeze().tolist(),
32+
"ke_p": result["kinetic_energy"].squeeze().tolist(),
33+
"se_p": result["strain_energy"].squeeze().tolist(),
34+
"te_p": result["total_energy"].squeeze().tolist(),
35+
"f_int_n": result["f_int"].squeeze().tolist(),
36+
"f_ext_n": result["f_ext"].squeeze().tolist(),
37+
"f_total_n": result["f_total"].squeeze().tolist(),
38+
}
39+
40+
2741
def analytical_vibration(E, rho, v0, x_loc, L, dt, nsteps):
2842
tt, vt, xt = [], [], []
2943
t = 0
@@ -54,4 +68,33 @@ def analytical_vibration(E, rho, v0, x_loc, L, dt, nsteps):
5468
ax[1].plot(ta, result["position"].squeeze(), "ob", markersize=2, label="mpm")
5569
ax[1].legend()
5670
ax[1].set_title("Position")
71+
72+
fig, ax = plt.subplots()
73+
ax.plot(
74+
ta,
75+
result["strain_energy"].squeeze(),
76+
"r",
77+
linewidth=1,
78+
alpha=0.7,
79+
label="Strain energy",
80+
)
81+
ax.plot(
82+
ta,
83+
result["kinetic_energy"].squeeze(),
84+
"b",
85+
linewidth=1,
86+
alpha=0.7,
87+
label="Kinetic energy",
88+
)
89+
ax.plot(
90+
ta,
91+
result["total_energy"].squeeze(),
92+
"k",
93+
linewidth=1,
94+
alpha=0.7,
95+
label="Total energy",
96+
)
97+
ax.legend()
98+
ax.set_title("Energies")
99+
57100
plt.show()

0 commit comments

Comments
 (0)