Skip to content

Commit a8498b2

Browse files
add nutils solid participant
1 parent 458817e commit a8498b2

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
set -e -u
3+
4+
. ../../tools/cleaning-tools.sh
5+
6+
clean_nutils .
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
set -e -u
3+
4+
python3 solid.py richoutput=no
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#! /usr/bin/env python3
2+
3+
from nutils import mesh, function, solver, export, cli
4+
from nutils.expression_v2 import Namespace
5+
import numpy
6+
import treelog
7+
import precice
8+
9+
def main(young=4e6, density=3e3, poisson=.3, nelems=2, timestepsize=0.01):
10+
11+
topo, geom = mesh.rectilinear([numpy.linspace(-.05, .05, nelems+1), numpy.linspace(0, 1, 10*nelems+1)])
12+
bezier = topo.sample('bezier', 2)
13+
wall = topo.boundary['left,top,right']
14+
wallsample = wall.sample('gauss', degree=2)
15+
16+
ns = Namespace()
17+
ns.X = geom
18+
ns.δ = function.eye(2)
19+
ns.define_for('X', gradient='∇', normal='n', jacobians=('dV', 'dS'))
20+
ns.add_field('dt')
21+
ns.add_field(('u', 'u0', 'testu', 'v', 'v0', 'testv'), topo.basis('std', degree=1), shape=(2,))
22+
ns.add_field('tdS', wallsample.basis(), shape=(2,))
23+
ns.dudt_i = '(u_i - u0_i) / dt'
24+
ns.dvdt_i = '(v_i - v0_i) / dt'
25+
ns.λ = young * poisson / ((1 + poisson) * (1 - 2 * poisson))
26+
ns.μ = young / (2 * (1 + poisson))
27+
ns.σ_ij = 'λ ∇_k(u_k) δ_ij + μ (∇_j(u_i) + ∇_i(u_j))'
28+
ns.ρ = density
29+
ns.x_i = 'X_i + u_i'
30+
31+
# continuum equations: ρ v' = ∇·σ + F, u' = v
32+
res = topo.integral('(testv_i (dudt_i - v_i) + testu_i ρ dvdt_i + ∇_j(testu_i) σ_ij) dV' @ ns, degree=2)
33+
res -= wallsample.integral('testu_i tdS_i' @ ns)
34+
35+
# boundary conditions: fully constrained at y=0
36+
sqr = topo.boundary['bottom'].integral('u_k u_k' @ ns, degree=2)
37+
cons = solver.optimize('u,', sqr, droptol=1e-10)
38+
39+
# initial conditions: undeformed and still
40+
sqr = topo.integral('u_k u_k + v_k v_k' @ ns, degree=2)
41+
arguments = solver.optimize('u,v', sqr, constrain=cons)
42+
43+
# preCICE setup
44+
solverProcessIndex = 0
45+
solverProcessSize = 1
46+
interface = precice.Interface("Solid", "../precice-config.xml", solverProcessIndex, solverProcessSize)
47+
meshID = interface.get_mesh_id("Solid-Mesh")
48+
dataIndices = interface.set_mesh_vertices(meshID, wallsample.eval(ns.X))
49+
writedataID = interface.get_data_id("Displacement", meshID)
50+
readdataID = interface.get_data_id("Force", meshID)
51+
52+
# initialize preCICE
53+
precice_dt = interface.initialize()
54+
55+
timestep = 0
56+
traction = numpy.zeros((wallsample.npoints, 2))
57+
58+
while interface.is_coupling_ongoing():
59+
with treelog.context(f'timestep {timestep}'):
60+
61+
# read displacements from interface
62+
if interface.is_read_data_available():
63+
traction = interface.read_block_vector_data(readdataID, dataIndices)
64+
65+
# save checkpoint
66+
if interface.is_action_required(precice.action_write_iteration_checkpoint()):
67+
checkpoint = timestep, arguments
68+
interface.mark_action_fulfilled(precice.action_write_iteration_checkpoint())
69+
70+
# advance variables
71+
timestep += 1
72+
dt = min(precice_dt, timestepsize)
73+
arguments = dict(dt=dt, u0=arguments['u'], v0=arguments['v'], tdS=traction)
74+
arguments = solver.solve_linear('u:testu,v:testv', res, arguments=arguments, constrain=cons)
75+
76+
# write forces to interface
77+
if interface.is_write_data_required(dt):
78+
writedata = wallsample.eval(ns.u, **arguments)
79+
interface.write_block_vector_data(writedataID, dataIndices, writedata)
80+
81+
# do the coupling
82+
precice_dt = interface.advance(dt)
83+
84+
# read checkpoint if required
85+
if interface.is_action_required(precice.action_read_iteration_checkpoint()):
86+
timestep, arguments = checkpoint
87+
interface.mark_action_fulfilled(precice.action_read_iteration_checkpoint())
88+
89+
if interface.is_time_window_complete():
90+
treelog.user('tip displacement:', topo.boundary['top'].sample('uniform', 1).eval(ns.u, **arguments).mean(0))
91+
92+
interface.finalize()
93+
94+
95+
if __name__ == '__main__':
96+
cli.run(main)

0 commit comments

Comments
 (0)