Skip to content

Commit 1c891a7

Browse files
authored
Modify FEniCS tutorials to enable parallel runs (#120)
* Modifying all FEniCS based tutorials to be compatible with parallel design of FEniCS-Adapter Co-authored-by: BenjaminRueth <benjamin.rueth@tum.de>
1 parent bb5d51b commit 1c891a7

File tree

7 files changed

+67
-43
lines changed

7 files changed

+67
-43
lines changed

CHT/flow-over-plate/buoyantPimpleFoam-fenics/Solid/heat.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from fenics import Function, SubDomain, RectangleMesh, BoxMesh, FunctionSpace, VectorFunctionSpace, Point, \
77
Expression, Constant, DirichletBC, \
88
TrialFunction, TestFunction, File, solve, plot, lhs, rhs, grad, inner, dot, dx, ds, interpolate, project, \
9-
near
9+
near, MeshFunction, MPI
1010
from fenicsprecice import Adapter
1111
import numpy as np
1212

@@ -140,8 +140,17 @@ def determine_heat_flux(V_g, u, k, flux):
140140
t = 0
141141
u_D.t = t + dt
142142

143+
# mark mesh w.r.t ranks
144+
ranks = File("Solid/VTK/ranks%s.pvd.pvd" % precice.get_participant_name())
145+
mesh_rank = MeshFunction("size_t", mesh, mesh.topology().dim())
146+
mesh_rank.set_all(MPI.rank(MPI.comm_world))
147+
mesh_rank.rename("myRank", "")
148+
ranks << mesh_rank
149+
150+
# Create output file
143151
file_out = File("Solid/VTK/%s.pvd" % precice.get_participant_name())
144152
file_out << u_n
153+
145154
print("output vtk for time = {}".format(float(t)))
146155
n = 0
147156

CHT/flow-over-plate/buoyantPimpleFoam-fenics/precice-config.xml

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<sink filter="%Severity% > debug and %Rank% = 0" format="---[precice] %ColorizedSeverity% %Message%" enabled="true"/>
77
</log>
88

9-
<solver-interface dimensions="3">
9+
<solver-interface dimensions="2">
1010

1111
<data:scalar name="Temperature"/>
1212
<data:scalar name="Heat-Flux"/>
@@ -23,32 +23,32 @@
2323

2424
<participant name="Fluid">
2525
<use-mesh name="Fluid-Mesh" provide="yes"/>
26+
<use-mesh name="Solid-Mesh" from="Solid"/>
2627
<read-data name="Heat-Flux" mesh="Fluid-Mesh"/>
2728
<write-data name="Temperature" mesh="Fluid-Mesh"/>
29+
<mapping:nearest-neighbor direction="read" from="Solid-Mesh" to="Fluid-Mesh" constraint="consistent"/>
2830
</participant>
2931

3032
<participant name="Solid">
3133
<use-mesh name="Fluid-Mesh" from="Fluid"/>
3234
<use-mesh name="Solid-Mesh" provide="yes"/>
3335
<read-data name="Temperature" mesh="Solid-Mesh"/>
3436
<write-data name="Heat-Flux" mesh="Solid-Mesh"/>
35-
<mapping:nearest-neighbor direction="read" from="Fluid-Mesh" to="Solid-Mesh" constraint="consistent" timing="initial"/>
36-
<mapping:nearest-neighbor direction="write" from="Solid-Mesh" to="Fluid-Mesh" constraint="consistent" timing="initial"/>
37+
<mapping:nearest-neighbor direction="read" from="Fluid-Mesh" to="Solid-Mesh" constraint="consistent"/>
3738
</participant>
3839

3940
<m2n:sockets from="Fluid" to="Solid"/>
4041

4142
<coupling-scheme:serial-implicit>
4243
<time-window-size value="0.01"/>
4344
<max-time value="1"/>
44-
<max-iterations value="200"/>
4545
<participants first="Fluid" second="Solid"/>
4646
<exchange data="Temperature" mesh="Fluid-Mesh" from="Fluid" to="Solid"/>
47-
<exchange data="Heat-Flux" mesh="Fluid-Mesh" from="Solid" to="Fluid"/>
47+
<exchange data="Heat-Flux" mesh="Solid-Mesh" from="Solid" to="Fluid"/>
48+
<max-iterations value="200"/>
4849
<relative-convergence-measure limit="1.0e-6" data="Temperature" mesh="Fluid-Mesh"/>
49-
<extrapolation-order value="0"/>
5050
<acceleration:IQN-ILS>
51-
<data mesh="Fluid-Mesh" name="Heat-Flux" />
51+
<data mesh="Solid-Mesh" name="Heat-Flux" />
5252
<initial-relaxation value="0.01" />
5353
<max-used-iterations value="80" />
5454
<time-windows-reused value="10" />

FSI/cylinderFlap/OpenFOAM-FEniCS/precice-config.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<sink filter="%Severity% > debug and %Rank% = 0" format="---[precice] %ColorizedSeverity% %Message%" enabled="true"/>
77
</log>
88

9-
<solver-interface dimensions="3">
9+
<solver-interface dimensions="2">
1010

1111
<data:vector name="Forces0"/>
1212
<data:vector name="Displacements0"/>
@@ -30,15 +30,15 @@
3030
<use-mesh name="Solid" from="fenics"/>
3131
<write-data name="Forces0" mesh="Fluid-Mesh-Faces"/>
3232
<read-data name="Displacements0" mesh="Fluid-Mesh-Nodes"/>
33-
<mapping:rbf-thin-plate-splines direction="write" from="Fluid-Mesh-Faces" to="Solid" constraint="conservative" z-dead="true"/>
34-
<mapping:rbf-thin-plate-splines direction="read" from="Solid" to="Fluid-Mesh-Nodes" constraint="consistent" z-dead="true"/>
33+
<mapping:rbf-thin-plate-splines direction="write" from="Fluid-Mesh-Faces" to="Solid" constraint="conservative"/>
34+
<mapping:rbf-thin-plate-splines direction="read" from="Solid" to="Fluid-Mesh-Nodes" constraint="consistent"/>
3535
</participant>
3636

3737
<participant name="fenics">
3838
<use-mesh name="Solid" provide="yes"/>
3939
<read-data name="Forces0" mesh="Solid"/>
4040
<write-data name="Displacements0" mesh="Solid"/>
41-
<watch-point mesh="Solid" name="point1" coordinate="0.6;0.2;0." />
41+
<watch-point mesh="Solid" name="point1" coordinate="0.6;0." />
4242
</participant>
4343

4444
<m2n:sockets from="Fluid" to="fenics"/>

FSI/flap_perp/OpenFOAM-FEniCS/Solid/perp-flap.py

+26-22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Import required libs
22
from fenics import Constant, Function, AutoSubDomain, RectangleMesh, VectorFunctionSpace, interpolate, \
3-
TrialFunction, TestFunction, Point, Expression, DirichletBC, nabla_grad, \
4-
Identity, inner, dx, ds, sym, grad, lhs, rhs, dot, File, solve, PointSource, assemble_system
3+
TrialFunction, TestFunction, Point, Expression, DirichletBC, nabla_grad, SubDomain, \
4+
Identity, inner, dx, ds, sym, grad, lhs, rhs, dot, File, solve, PointSource, assemble_system, MPI, MeshFunction
55
import dolfin
66

77
from ufl import nabla_div
@@ -11,17 +11,22 @@
1111
from enum import Enum
1212

1313

14-
# define the two kinds of boundary: clamped and coupling Neumann Boundary
15-
def clamped_boundary(x, on_boundary):
16-
return on_boundary and abs(x[1]) < tol
14+
class clampedBoundary(SubDomain):
15+
def inside(self, x, on_boundary):
16+
tol = 1E-14
17+
if on_boundary and abs(x[1]) < tol:
18+
return True
19+
else:
20+
return False
1721

1822

19-
def neumann_boundary(x, on_boundary):
20-
"""
21-
determines whether a node is on the coupling boundary
22-
23-
"""
24-
return on_boundary and ((abs(x[1] - 1) < tol) or abs(abs(x[0]) - W / 2) < tol)
23+
class neumannBoundary(SubDomain):
24+
def inside(self, x, on_boundary):
25+
tol = 1E-14
26+
if on_boundary and ((abs(x[1] - 1) < tol) or abs(abs(x[0]) - W / 2) < tol):
27+
return True
28+
else:
29+
return False
2530

2631

2732
# Geometry and material properties
@@ -46,9 +51,6 @@ def neumann_boundary(x, on_boundary):
4651
# create Function Space
4752
V = VectorFunctionSpace(mesh, 'P', 2)
4853

49-
# BCs
50-
tol = 1E-14
51-
5254
# Trial and Test Functions
5355
du = TrialFunction(V)
5456
v = TestFunction(V)
@@ -64,24 +66,19 @@ def neumann_boundary(x, on_boundary):
6466
f_N_function = interpolate(Expression(("1", "0"), degree=1), V)
6567
u_function = interpolate(Expression(("0", "0"), degree=1), V)
6668

67-
coupling_boundary = AutoSubDomain(neumann_boundary)
68-
6969
precice = Adapter(adapter_config_filename="precice-adapter-config-fsi-s.json")
7070

71-
clamped_boundary_domain = AutoSubDomain(clamped_boundary)
72-
force_boundary = AutoSubDomain(neumann_boundary)
73-
7471
# Initialize the coupling interface
7572
# Function space V is passed twice as both read and write functions are defined using the same space
76-
precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=V,
77-
fixed_boundary=clamped_boundary_domain)
73+
precice_dt = precice.initialize(neumannBoundary(), read_function_space=V, write_object=V,
74+
fixed_boundary=clampedBoundary())
7875

7976
fenics_dt = precice_dt # if fenics_dt == precice_dt, no subcycling is applied
8077
# fenics_dt = 0.02 # if fenics_dt < precice_dt, subcycling is applied
8178
dt = Constant(np.min([precice_dt, fenics_dt]))
8279

8380
# clamp the beam at the bottom
84-
bc = DirichletBC(V, Constant((0, 0)), clamped_boundary)
81+
bc = DirichletBC(V, Constant((0, 0)), clampedBoundary())
8582

8683
# alpha method parameters
8784
alpha_m = Constant(0.2)
@@ -179,11 +176,18 @@ def avg(x_old, x_new, alpha):
179176
u_tip.append(0.0)
180177
E_ext = 0
181178

179+
# mark mesh w.r.t ranks
180+
mesh_rank = MeshFunction("size_t", mesh, mesh.topology().dim())
181+
mesh_rank.set_all(MPI.rank(MPI.comm_world) + 0)
182+
mesh_rank.rename("myRank", "")
183+
182184
displacement_out = File("Solid/FSI-S/u_fsi.pvd")
185+
ranks = File("Solid/FSI-S/ranks%s.pvd" % precice.get_participant_name())
183186

184187
u_n.rename("Displacement", "")
185188
u_np1.rename("Displacement", "")
186189
displacement_out << u_n
190+
ranks << mesh_rank
187191

188192
while precice.is_coupling_ongoing():
189193

FSI/flap_perp/OpenFOAM-FEniCS/precice-config.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<sink filter="%Severity% > debug and %Rank% = 0" format="---[precice] %ColorizedSeverity% %Message%" enabled="true"/>
77
</log>
88

9-
<solver-interface dimensions="3">
9+
<solver-interface dimensions="2">
1010

1111
<data:vector name="Forces0"/>
1212
<data:vector name="Displacements0"/>
@@ -30,15 +30,15 @@
3030
<use-mesh name="Solid" from="fenics"/>
3131
<write-data name="Forces0" mesh="Fluid-Mesh-Faces"/>
3232
<read-data name="Displacements0" mesh="Fluid-Mesh-Nodes"/>
33-
<mapping:rbf-thin-plate-splines direction="write" from="Fluid-Mesh-Faces" to="Solid" constraint="conservative" z-dead="true"/>
34-
<mapping:rbf-thin-plate-splines direction="read" from="Solid" to="Fluid-Mesh-Nodes" constraint="consistent" z-dead="true"/>
33+
<mapping:rbf-thin-plate-splines direction="write" from="Fluid-Mesh-Faces" to="Solid" constraint="conservative"/>
34+
<mapping:rbf-thin-plate-splines direction="read" from="Solid" to="Fluid-Mesh-Nodes" constraint="consistent"/>
3535
</participant>
3636

3737
<participant name="fenics">
3838
<use-mesh name="Solid" provide="yes"/>
3939
<read-data name="Forces0" mesh="Solid"/>
4040
<write-data name="Displacements0" mesh="Solid"/>
41-
<watch-point mesh="Solid" name="point1" coordinate="-0.05;0;1" />
41+
<watch-point mesh="Solid" name="point1" coordinate="-0.05;1" />
4242
</participant>
4343

4444
<m2n:sockets from="Fluid" to="fenics"/>

HT/partitioned-heat/fenics-fenics/heat.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from __future__ import print_function, division
2828
from fenics import Function, FunctionSpace, Expression, Constant, DirichletBC, TrialFunction, TestFunction, \
29-
File, solve, lhs, rhs, grad, inner, dot, dx, ds, interpolate, VectorFunctionSpace
29+
File, solve, lhs, rhs, grad, inner, dot, dx, ds, interpolate, VectorFunctionSpace, MeshFunction, MPI
3030
from fenicsprecice import Adapter
3131
from errorcomputation import compute_errors
3232
from my_enums import ProblemType, Subcycling
@@ -174,16 +174,26 @@ def determine_gradient(V_g, u, flux):
174174
u_ref = interpolate(u_D, V)
175175
u_ref.rename("reference", " ")
176176

177+
# mark mesh w.r.t ranks
178+
mesh_rank = MeshFunction("size_t", mesh, mesh.topology().dim())
179+
if problem is ProblemType.NEUMANN:
180+
mesh_rank.set_all(MPI.rank(MPI.comm_world) + 4)
181+
else:
182+
mesh_rank.set_all(MPI.rank(MPI.comm_world) + 0)
183+
mesh_rank.rename("myRank", "")
184+
177185
# Generating output files
178186
temperature_out = File("out/%s.pvd" % precice.get_participant_name())
179187
ref_out = File("out/ref%s.pvd" % precice.get_participant_name())
180188
error_out = File("out/error%s.pvd" % precice.get_participant_name())
189+
ranks = File("out/ranks%s.pvd" % precice.get_participant_name())
181190

182191
# output solution and reference solution at t=0, n=0
183192
n = 0
184193
print('output u^%d and u_ref^%d' % (n, n))
185194
temperature_out << u_n
186195
ref_out << u_ref
196+
ranks << mesh_rank
187197

188198
error_total, error_pointwise = compute_errors(u_n, u_ref, V)
189199
error_out << error_pointwise

HT/partitioned-heat/fenics-fenics/precice-config.xml

+5-4
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@
2626
<use-mesh name="NeumannNodes" from="HeatNeumann"/>
2727
<write-data name="Flux" mesh="DirichletNodes"/>
2828
<read-data name="Temperature" mesh="DirichletNodes"/>
29-
<mapping:nearest-projection direction="write" from="DirichletNodes" to="NeumannNodes" constraint="consistent" timing="initial"/>
3029
<mapping:nearest-projection direction="read" from="NeumannNodes" to="DirichletNodes" constraint="consistent" timing="initial"/>
3130
</participant>
3231

3332
<participant name="HeatNeumann">
34-
<use-mesh name="NeumannNodes" provide="yes"/>
33+
<use-mesh name="NeumannNodes" provide="yes"/>
34+
<use-mesh name="DirichletNodes" from="HeatDirichlet"/>
3535
<write-data name="Temperature" mesh="NeumannNodes"/>
3636
<read-data name="Flux" mesh="NeumannNodes"/>
37+
<mapping:nearest-projection direction="read" from="DirichletNodes" to="NeumannNodes" constraint="consistent" timing="initial"/>
3738
</participant>
3839

3940
<m2n:sockets from="HeatDirichlet" to="HeatNeumann"/>
@@ -43,9 +44,9 @@
4344
<max-time value="1"/>
4445
<time-window-size value=".1" valid-digits="8"/>
4546
<max-iterations value="100"/>
46-
<exchange data="Flux" mesh="NeumannNodes" from="HeatDirichlet" to="HeatNeumann" />
47+
<exchange data="Flux" mesh="DirichletNodes" from="HeatDirichlet" to="HeatNeumann" />
4748
<exchange data="Temperature" mesh="NeumannNodes" from="HeatNeumann" to="HeatDirichlet" initialize="true"/>
48-
<relative-convergence-measure data="Flux" mesh="NeumannNodes" limit="1e-5"/>
49+
<relative-convergence-measure data="Flux" mesh="DirichletNodes" limit="1e-5"/>
4950
<relative-convergence-measure data="Temperature" mesh="NeumannNodes" limit="1e-5"/>
5051
<acceleration:IQN-ILS>
5152
<data name="Temperature" mesh="NeumannNodes"/>

0 commit comments

Comments
 (0)