Skip to content

Commit 9cf2c4a

Browse files
author
Daniel Ruprecht
committed
test verifies that do_coll_update=False leads to simple copy of last stage; can now switch between collocation update and copy be setting do_coll_update as sweeper parameter
1 parent 5bb103a commit 9cf2c4a

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

pySDC/Sweeper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(self,params):
4545
coll = params['collocation_class'](params['num_nodes'],0,1)
4646
assert isinstance(coll, CollBase)
4747
if not coll.right_is_node:
48-
assert params['do_coll_update'], "For nodes where the right end point is not a node, do_coll_update has to be set to True"
48+
assert self.params.do_coll_update, "For nodes where the right end point is not a node, do_coll_update has to be set to True"
4949

5050
# This will be set as soon as the sweeper is instantiated at the level
5151
self.__level = None

pySDC/sweeper_classes/generic_LU.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ def compute_end_point(self):
135135
L = self.level
136136
P = L.prob
137137

138-
- # check if Mth node is equal to right point and do_coll_update is false, perform a simple copy
139-
- if (self.coll.right_is_node and not self.params['do_coll_update']):
140-
- # a copy is sufficient
141-
- L.uend = P.dtype_u(L.u[-1])
138+
# check if Mth node is equal to right point and do_coll_update is false, perform a simple copy
139+
if (self.coll.right_is_node and not self.params.do_coll_update):
140+
# a copy is sufficient
141+
L.uend = P.dtype_u(L.u[-1])
142142
else:
143143
# start with u0 and add integral over the full interval (using coll.weights)
144144
L.uend = P.dtype_u(L.u[0])

pySDC/sweeper_classes/imex_1st_order.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,24 @@ def compute_end_point(self):
134134
"""
135135
Compute u at the right point of the interval
136136
137-
The value uend computed here is a full evaluation of the Picard formulation (always!)
137+
The value uend computed here is a full evaluation of the Picard formulation unless do_full_update==False
138138
"""
139139

140140
# get current level and problem description
141141
L = self.level
142142
P = L.prob
143143

144-
# start with u0 and add integral over the full interval (using coll.weights)
145-
L.uend = P.dtype_u(L.u[0])
146-
for m in range(self.coll.num_nodes):
147-
L.uend += L.dt*self.coll.weights[m]*(L.f[m+1].impl + L.f[m+1].expl)
148-
# add up tau correction of the full interval (last entry)
149-
if L.tau is not None:
150-
L.uend += L.tau[-1]
144+
# check if Mth node is equal to right point and do_coll_update is false, perform a simple copy
145+
if (self.coll.right_is_node and not self.params.do_coll_update):
146+
# a copy is sufficient
147+
L.uend = P.dtype_u(L.u[-1])
148+
else:
149+
# start with u0 and add integral over the full interval (using coll.weights)
150+
L.uend = P.dtype_u(L.u[0])
151+
for m in range(self.coll.num_nodes):
152+
L.uend += L.dt*self.coll.weights[m]*(L.f[m+1].impl + L.f[m+1].expl)
153+
# add up tau correction of the full interval (last entry)
154+
if L.tau is not None:
155+
L.uend += L.tau[-1]
151156

152157
return None

tests/test_imexsweeper.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,41 @@ def test_norightnode_collupdate_fails(self):
239239
# Has to throw an exception
240240
with self.assertRaises(AssertionError):
241241
step, level, problem, nnodes = self.setupLevelStepProblem()
242+
243+
#
244+
# Make sure the update with do_coll_update=False reproduces last stage
245+
#
246+
def test_update_nocollupdate_laststage(self):
247+
self.swparams['do_coll_update'] = False
248+
step, level, problem, nnodes = self.setupLevelStepProblem()
249+
level.sweep.predict()
250+
ulaststage = np.random.rand()
251+
level.u[nnodes].values = ulaststage
252+
level.sweep.compute_end_point()
253+
uend = level.uend.values
254+
assert abs(uend-ulaststage)<1e-14, "compute_end_point with do_coll_update=False did not reproduce last stage value"
255+
256+
#
257+
# Make sure that update with do_coll_update=False is identical to update formula with q=(0,...,0,1)
258+
#
259+
def test_updateformula_no_coll_update(self):
260+
self.swparams['do_coll_update'] = False
261+
step, level, problem, nnodes = self.setupLevelStepProblem()
262+
level.sweep.predict()
263+
u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ])
264+
265+
# Perform update step in sweeper
266+
level.sweep.update_nodes()
267+
ustages = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ])
268+
269+
# Compute end value through provided function
270+
level.sweep.compute_end_point()
271+
uend_sweep = level.uend.values
272+
# Compute end value from matrix formulation
273+
q = np.zeros(nnodes)
274+
q[nnodes-1] = 1.0
275+
print q
276+
uend_mat = q.dot(ustages)
277+
print uend_sweep
278+
print uend_mat
279+
assert np.linalg.norm(uend_sweep - uend_mat, np.infty)<1e-14, "For do_coll_update=False, update formula in sweeper gives different result than matrix update formula with q=(0,..,0,1)"

0 commit comments

Comments
 (0)