Skip to content

Commit 378b089

Browse files
Use waveform iteration with partitioned-heat-conduction/fenics/heat.py (#281)
1 parent 25177cf commit 378b089

File tree

2 files changed

+93
-22
lines changed

2 files changed

+93
-22
lines changed

partitioned-heat-conduction/fenics/heat.py

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def determine_gradient(V_g, u, flux):
6363

6464
args = parser.parse_args()
6565

66-
fenics_dt = .1 # time step size
66+
fenics_dt = .01 # time step size
6767
# Error is bounded by coupling accuracy. In theory we would obtain the analytical solution.
6868
error_tol = args.error_tol
6969

@@ -112,7 +112,6 @@ def determine_gradient(V_g, u, flux):
112112
precice.initialize(coupling_boundary, read_function_space=W, write_object=u_D_function)
113113
precice_dt = precice.get_max_time_step_size()
114114

115-
116115
dt = Constant(0)
117116
dt.assign(np.min([fenics_dt, precice_dt]))
118117

@@ -164,13 +163,32 @@ def determine_gradient(V_g, u, flux):
164163

165164
# output solution and reference solution at t=0, n=0
166165
n = 0
167-
print('output u^%d and u_ref^%d' % (n, n))
168-
temperature_out << (u_n, t)
169-
ref_out << u_ref
166+
print("output u^%d and u_ref^%d" % (n, n))
170167
ranks << mesh_rank
171168

172169
error_total, error_pointwise = compute_errors(u_n, u_ref, V)
173-
error_out << error_pointwise
170+
171+
# create buffer for output. We need this buffer, because we only want to
172+
# write the converged output at the end of the window, but we also want to
173+
# write the samples that are resulting from substeps inside the window
174+
u_write = []
175+
ref_write = []
176+
error_write = []
177+
# copy data to buffer and rename
178+
uu = u_n.copy()
179+
uu.rename("u", "")
180+
u_write.append((uu, t))
181+
uu_ref = u_ref.copy()
182+
uu_ref.rename("u_ref", "")
183+
ref_write.append(uu_ref)
184+
err = error_pointwise.copy()
185+
err.rename("err", "")
186+
error_write.append(err)
187+
188+
# set t_1 = t_0 + dt, this gives u_D^1
189+
# call dt(0) to evaluate FEniCS Constant. Todo: is there a better way?
190+
u_D.t = t + dt(0)
191+
f.t = t + dt(0)
174192

175193
if problem is ProblemType.DIRICHLET:
176194
flux = Function(V_g)
@@ -182,6 +200,17 @@ def determine_gradient(V_g, u, flux):
182200
if precice.requires_writing_checkpoint():
183201
precice.store_checkpoint(u_n, t, n)
184202

203+
# output solution and reference solution at t_n+1 and substeps (read from buffer)
204+
print('output u^%d and u_ref^%d' % (n, n))
205+
for sample in u_write:
206+
temperature_out << sample
207+
208+
for sample in ref_write:
209+
ref_out << sample
210+
211+
for sample in error_write:
212+
error_out << error_pointwise
213+
185214
precice_dt = precice.get_max_time_step_size()
186215
dt.assign(np.min([fenics_dt, precice_dt]))
187216

@@ -217,21 +246,45 @@ def determine_gradient(V_g, u, flux):
217246
u_n.assign(u_cp)
218247
t = t_cp
219248
n = n_cp
249+
# empty buffer if window has not converged
250+
u_write = []
251+
ref_write = []
252+
error_write = []
220253
else: # update solution
221254
u_n.assign(u_np1)
222255
t += float(dt)
223256
n += 1
257+
# copy data to buffer and rename
258+
uu = u_n.copy()
259+
uu.rename("u", "")
260+
u_write.append((uu, t))
261+
uu_ref = u_ref.copy()
262+
uu_ref.rename("u_ref", "")
263+
ref_write.append(uu_ref)
264+
err = error_pointwise.copy()
265+
err.rename("err", "")
266+
error_write.append(err)
224267

225268
if precice.is_time_window_complete():
226269
u_ref = interpolate(u_D, V)
227270
u_ref.rename("reference", " ")
228271
error, error_pointwise = compute_errors(u_n, u_ref, V, total_error_tol=error_tol)
229-
print('n = %d, t = %.2f: L2 error on domain = %.3g' % (n, t, error))
230-
# output solution and reference solution at t_n+1
231-
print('output u^%d and u_ref^%d' % (n, n))
232-
temperature_out << (u_n, t)
233-
ref_out << u_ref
234-
error_out << error_pointwise
272+
print("n = %d, t = %.2f: L2 error on domain = %.3g" % (n, t, error))
273+
274+
# Update Dirichlet BC
275+
u_D.t = t + float(dt)
276+
f.t = t + float(dt)
277+
278+
# output solution and reference solution at t_n+1 and substeps (read from buffer)
279+
print("output u^%d and u_ref^%d" % (n, n))
280+
for sample in u_write:
281+
temperature_out << sample
282+
283+
for sample in ref_write:
284+
ref_out << sample
285+
286+
for sample in error_write:
287+
error_out << error_pointwise
235288

236289
# Hold plot
237290
precice.finalize()

partitioned-heat-conduction/precice-config.xml

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
enabled="true" />
88
</log>
99

10-
<data:scalar name="Temperature" />
11-
<data:scalar name="Heat-Flux" />
10+
<data:scalar name="Temperature" waveform-degree="1" />
11+
<data:scalar name="Heat-Flux" waveform-degree="1" />
1212

1313
<mesh name="Dirichlet-Mesh" dimensions="2">
1414
<use-data name="Temperature" />
@@ -25,15 +25,23 @@
2525
<receive-mesh name="Neumann-Mesh" from="Neumann" />
2626
<write-data name="Heat-Flux" mesh="Dirichlet-Mesh" />
2727
<read-data name="Temperature" mesh="Dirichlet-Mesh" />
28-
<mapping:nearest-neighbor direction="read" from="Neumann-Mesh" to="Dirichlet-Mesh" constraint="consistent" />
28+
<mapping:nearest-neighbor
29+
direction="read"
30+
from="Neumann-Mesh"
31+
to="Dirichlet-Mesh"
32+
constraint="consistent" />
2933
</participant>
3034

3135
<participant name="Neumann">
3236
<provide-mesh name="Neumann-Mesh" />
3337
<receive-mesh name="Dirichlet-Mesh" from="Dirichlet" />
3438
<write-data name="Temperature" mesh="Neumann-Mesh" />
3539
<read-data name="Heat-Flux" mesh="Neumann-Mesh" />
36-
<mapping:nearest-neighbor direction="read" from="Dirichlet-Mesh" to="Neumann-Mesh" constraint="consistent" />
40+
<mapping:nearest-neighbor
41+
direction="read"
42+
from="Dirichlet-Mesh"
43+
to="Neumann-Mesh"
44+
constraint="consistent" />
3745
</participant>
3846

3947
<m2n:sockets acceptor="Dirichlet" connector="Neumann" exchange-directory=".." />
@@ -43,21 +51,31 @@
4351
<max-time value="1.0" />
4452
<time-window-size value="0.1" />
4553
<max-iterations value="100" />
46-
<exchange data="Heat-Flux" mesh="Dirichlet-Mesh" from="Dirichlet" to="Neumann" />
54+
<exchange
55+
data="Heat-Flux"
56+
mesh="Dirichlet-Mesh"
57+
from="Dirichlet"
58+
to="Neumann"
59+
initialize="true"
60+
substeps="true" />
4761
<exchange
4862
data="Temperature"
4963
mesh="Neumann-Mesh"
5064
from="Neumann"
5165
to="Dirichlet"
52-
initialize="true" />
53-
<relative-convergence-measure data="Heat-Flux" mesh="Dirichlet-Mesh" limit="1e-5" />
54-
<relative-convergence-measure data="Temperature" mesh="Neumann-Mesh" limit="1e-5" />
55-
<acceleration:IQN-ILS>
66+
initialize="true"
67+
substeps="true" />
68+
<relative-convergence-measure data="Heat-Flux" mesh="Dirichlet-Mesh" limit="1e-10" />
69+
<relative-convergence-measure data="Temperature" mesh="Neumann-Mesh" limit="1e-10" />
70+
<!-- <acceleration:IQN-ILS>
5671
<data name="Temperature" mesh="Neumann-Mesh" />
5772
<initial-relaxation value="0.1" />
5873
<max-used-iterations value="10" />
5974
<time-windows-reused value="5" />
6075
<filter type="QR2" limit="1e-3" />
61-
</acceleration:IQN-ILS>
76+
</acceleration:IQN-ILS> -->
77+
<acceleration:constant>
78+
<relaxation value="0.5" />
79+
</acceleration:constant>
6280
</coupling-scheme:serial-implicit>
6381
</precice-configuration>

0 commit comments

Comments
 (0)