Skip to content

Commit 4a1595c

Browse files
author
Daniel Ruprecht
committed
added tests for imex_sweeper; fails test_updateformula
1 parent 884b57f commit 4a1595c

File tree

2 files changed

+207
-2
lines changed

2 files changed

+207
-2
lines changed

examples/SWFW/ProblemClass.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def solve_system(self,rhs,factor,u0,t):
5959
me = mesh(self.nvars)
6060
for i in range(self.lambda_s.size):
6161
for j in range(self.lambda_f.size):
62-
me.values[i,j] = rhs.values[i,j]/(1-factor*self.lambda_f[j])
62+
me.values[i,j] = rhs.values[i,j]/(1.0-factor*self.lambda_f[j])
6363

6464
return me
6565

@@ -130,7 +130,7 @@ def u_exact(self,t):
130130
Returns:
131131
exact solution
132132
"""
133-
133+
134134
me = mesh(self.nvars)
135135
for i in range(self.lambda_s.size):
136136
for j in range(self.lambda_f.size):

tests/test_imexsweeper.py

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
from pySDC import Level as lvl
2+
from pySDC import Hooks as hookclass
3+
from pySDC import CollocationClasses as collclass
4+
from pySDC import Step as stepclass
5+
6+
from pySDC.datatype_classes.complex_mesh import mesh, rhs_imex_mesh
7+
from pySDC.sweeper_classes.imex_1st_order import imex_1st_order as imex
8+
from examples.SWFW.ProblemClass import swfw_scalar
9+
10+
from nose.tools import *
11+
import unittest
12+
import numpy as np
13+
14+
class TestImexSweeper(unittest.TestCase):
15+
16+
#
17+
#
18+
#
19+
def setUp(self):
20+
self.pparams = {}
21+
self.pparams['lambda_s'] = np.array([-0.1*1j], dtype='complex')
22+
self.pparams['lambda_f'] = np.array([-1.0*1j], dtype='complex')
23+
self.pparams['u0'] = 1.0
24+
self.swparams = {}
25+
self.swparams['collocation_class'] = collclass.CollGaussLobatto
26+
self.swparams['num_nodes'] = 2
27+
28+
#
29+
#
30+
#
31+
def test_caninstantiate(self):
32+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
33+
34+
#
35+
#
36+
#
37+
def test_canregisterlevel(self):
38+
step = stepclass.step(params={})
39+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
40+
step.register_level(L)
41+
42+
#
43+
#
44+
#
45+
def test_canrunsweep(self):
46+
47+
step = stepclass.step(params={})
48+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
49+
step.register_level(L)
50+
step.status.dt = 1.0
51+
step.status.time = 0.0
52+
nnodes = step.levels[0].sweep.coll.num_nodes
53+
u0 = step.levels[0].prob.u_exact(step.status.time)
54+
step.init_step(u0)
55+
step.levels[0].sweep.predict()
56+
u0full = np.array([ step.levels[0].u[l].values.flatten() for l in range(1,nnodes+1) ])
57+
58+
step.levels[0].sweep.update_nodes()
59+
assert step.levels[0].uend is None, "uend should be None previous to running compute_end_point"
60+
step.levels[0].sweep.compute_end_point()
61+
#print "Sweep: %s" % step.levels[0].uend.values
62+
63+
#
64+
# Make sure a sweep in matrix form is equal to a sweep in node-to-node form
65+
#
66+
def test_sweepequalmatrix(self):
67+
68+
step = stepclass.step(params={})
69+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
70+
step.register_level(L)
71+
step.status.dt = 1.0
72+
step.status.time = 0.0
73+
nnodes = step.levels[0].sweep.coll.num_nodes
74+
u0 = step.levels[0].prob.u_exact(step.status.time)
75+
step.init_step(u0)
76+
step.levels[0].sweep.predict()
77+
u0full = np.array([ step.levels[0].u[l].values.flatten() for l in range(1,nnodes+1) ])
78+
79+
# Perform node-to-node SDC sweep
80+
step.levels[0].sweep.update_nodes()
81+
82+
# Build SDC sweep matrix
83+
level = step.levels[0]
84+
problem = level.prob
85+
QE = level.sweep.QE[1:,1:]
86+
QI = level.sweep.QI[1:,1:]
87+
Q = level.sweep.coll.Qmat[1:,1:]
88+
dt = step.status.dt
89+
LHS = np.eye(nnodes) - step.status.dt*( problem.lambda_f[0]*QI + problem.lambda_s[0]*QE )
90+
RHS = step.status.dt*( (problem.lambda_f[0]+problem.lambda_s[0])*Q - (problem.lambda_f[0]*QI + problem.lambda_s[0]*QE) )
91+
unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(u0full) )
92+
usweep = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ])
93+
assert np.linalg.norm(unew - usweep, np.infty)<1e-14, "Single SDC sweeps in matrix and node-to-node formulation yield different results"
94+
95+
#
96+
#
97+
#
98+
def test_updateformula(self):
99+
100+
step = stepclass.step(params={})
101+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
102+
step.register_level(L)
103+
step.status.dt = 1.0
104+
step.status.time = 0.0
105+
nnodes = step.levels[0].sweep.coll.num_nodes
106+
u0 = step.levels[0].prob.u_exact(step.status.time)
107+
step.init_step(u0)
108+
step.levels[0].sweep.predict()
109+
u0full = np.array([ step.levels[0].u[l].values.flatten() for l in range(1,nnodes+1) ])
110+
111+
# Build SDC sweep matrix
112+
level = step.levels[0]
113+
problem = level.prob
114+
QE = level.sweep.QE[1:,1:]
115+
QI = level.sweep.QI[1:,1:]
116+
Q = level.sweep.coll.Qmat[1:,1:]
117+
118+
# Perform update step in sweeper
119+
step.levels[0].sweep.update_nodes()
120+
ustages = np.array([ step.levels[0].u[l].values.flatten() for l in range(1,nnodes+1) ])
121+
122+
step.levels[0].sweep.compute_end_point()
123+
uend_sweep = step.levels[0].uend.values
124+
uend_mat = u0.values + step.status.dt*step.levels[0].sweep.coll.weights.dot(ustages*(problem.lambda_s[0] + problem.lambda_f[0]))
125+
assert np.linalg.norm(uend_sweep - uend_mat, np.infty)<1e-14, "Update formula in sweeper gives different result than matrix update formula"
126+
127+
#
128+
# Compute the exact collocation solution by matrix inversion and make sure it is a fixed point
129+
#
130+
def test_collocationinvariant(self):
131+
132+
step = stepclass.step(params={})
133+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
134+
step.register_level(L)
135+
step.status.dt = 1.0
136+
step.status.time = 0.0
137+
nnodes = step.levels[0].sweep.coll.num_nodes
138+
u0 = step.levels[0].prob.u_exact(step.status.time)
139+
step.init_step(u0)
140+
step.levels[0].sweep.predict()
141+
u0full = np.array([ step.levels[0].u[l].values.flatten() for l in range(1,nnodes+1) ])
142+
143+
# Build SDC sweep matrix
144+
level = step.levels[0]
145+
problem = level.prob
146+
QE = level.sweep.QE[1:,1:]
147+
QI = level.sweep.QI[1:,1:]
148+
Q = level.sweep.coll.Qmat[1:,1:]
149+
150+
Mcoll = np.eye(nnodes) - step.status.dt*Q*(problem.lambda_s[0] + problem.lambda_f[0])
151+
ucoll = np.linalg.inv(Mcoll).dot(u0full)
152+
for l in range(0,nnodes):
153+
step.levels[0].u[l+1].values = ucoll[l]
154+
step.levels[0].f[l+1].impl.values = problem.lambda_f[0]*ucoll[l]
155+
step.levels[0].f[l+1].expl.values = problem.lambda_s[0]*ucoll[l]
156+
157+
# Perform node-to-node SDC sweep
158+
step.levels[0].sweep.update_nodes()
159+
160+
LHS = np.eye(nnodes) - step.status.dt*( problem.lambda_f[0]*QI + problem.lambda_s[0]*QE )
161+
RHS = step.status.dt*( (problem.lambda_f[0]+problem.lambda_s[0])*Q - (problem.lambda_f[0]*QI + problem.lambda_s[0]*QE) )
162+
unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(ucoll) )
163+
assert np.linalg.norm( unew - ucoll, np.infty )<1e-14, "Collocation solution not invariant under matrix SDC sweep"
164+
unew_sweep = np.array([ step.levels[0].u[l].values.flatten() for l in range(1,nnodes+1) ])
165+
assert np.linalg.norm( unew_sweep - ucoll, np.infty )<1e-14, "Collocation solution not invariant under node-to-node sweep"
166+
167+
#
168+
#
169+
#
170+
def test_canrunmatrixsweep(self):
171+
step = stepclass.step(params={})
172+
L = lvl.level(problem_class=swfw_scalar, problem_params=self.pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=self.swparams, level_params={}, hook_class=hookclass.hooks, id="imextest")
173+
step.register_level(L)
174+
step.status.dt = 1.0
175+
step.status.time = 0.0
176+
u0 = step.levels[0].prob.u_exact(step.status.time)
177+
step.init_step(u0)
178+
nnodes = step.levels[0].sweep.coll.num_nodes
179+
level = step.levels[0]
180+
problem = level.prob
181+
QE = level.sweep.QE[1:,1:]
182+
QI = level.sweep.QI[1:,1:]
183+
Q = level.sweep.coll.Qmat[1:,1:]
184+
185+
P = np.eye(nnodes) - step.status.dt*problem.lambda_s[0]*QE - step.status.dt*problem.lambda_f[0]*QI
186+
187+
Pinv = np.linalg.inv(P)
188+
M = np.eye(nnodes) - step.status.dt*( problem.lambda_s[0] + problem.lambda_f[0] )*Q
189+
#M = step.status.dt*( (problem.lambda_s[0]+problem.lambda_f[0])*Q - problem.lambda_f[0]*QI - problem.lambda_s[0]*QE )
190+
#print QI
191+
#print P
192+
#print Pinv
193+
#print M
194+
#level.sweep.predict()
195+
#u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ])
196+
#ufull = u0full + Pinv.dot( u0full ) - Pinv.dot( M.dot(u0full) )
197+
#print u0.values
198+
#print Pinv.dot(u0full)
199+
#print Pinv.dot(M)
200+
#print Pinv.dot(M.dot(u0full))
201+
#ufull = Pinv.dot(M.dot(u0full)) + Pinv.dot(u0full)
202+
#ufull = np.linalg.inv(M).dot(u0full)
203+
#print ufull
204+
#uend = u0.values + step.status.dt*level.sweep.coll.weights.dot( (problem.lambda_f[0]+problem.lambda_s[0])*ufull )
205+
#print "Matrix: %s" % uend

0 commit comments

Comments
 (0)