Skip to content

Commit 70ca0c9

Browse files
author
Daniel Ruprecht
committed
added problem definition and driver file for multiscale example
1 parent c94f6b3 commit 70ca0c9

File tree

2 files changed

+271
-0
lines changed

2 files changed

+271
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
r"""
2+
One-dimensional IMEX acoustic-advection
3+
=========================
4+
5+
Integrate the linear 1D acoustic-advection problem:
6+
7+
.. math::
8+
u_t + U u_x + c p_x & = 0 \\
9+
p_t + U p_x + c u_x & = 0.
10+
11+
"""
12+
13+
import numpy as np
14+
import scipy.sparse as sp
15+
import scipy.sparse.linalg as LA
16+
17+
from pySDC.Problem import ptype
18+
from pySDC.datatype_classes.mesh import mesh, rhs_imex_mesh
19+
20+
from buildWave1DMatrix import getWave1DMatrix, getWave1DAdvectionMatrix
21+
22+
class acoustic_1d_imex(ptype):
23+
"""
24+
Example implementing the forced 1D heat equation with Dirichlet-0 BC in [0,1]
25+
26+
Attributes:
27+
solver: Sharpclaw solver
28+
state: Sharclaw state
29+
domain: Sharpclaw domain
30+
"""
31+
32+
def __init__(self, cparams, dtype_u, dtype_f):
33+
"""
34+
Initialization routine
35+
36+
Args:
37+
cparams: custom parameters for the example
38+
dtype_u: particle data type (will be passed parent class)
39+
dtype_f: acceleration data type (will be passed parent class)
40+
"""
41+
42+
# these parameters will be used later, so assert their existence
43+
assert 'nvars' in cparams
44+
assert 'cs' in cparams
45+
assert 'cadv' in cparams
46+
assert 'order_adv' in cparams
47+
assert 'multiscale' in cparams
48+
49+
# add parameters as attributes for further reference
50+
for k,v in cparams.items():
51+
setattr(self,k,v)
52+
53+
# invoke super init, passing number of dofs, dtype_u and dtype_f
54+
super(acoustic_1d_imex,self).__init__(self.nvars,dtype_u,dtype_f)
55+
56+
self.mesh = np.linspace(0.0, 1.0, self.nvars[1], endpoint=False)
57+
self.dx = self.mesh[1] - self.mesh[0]
58+
59+
self.Dx = -self.cadv*getWave1DAdvectionMatrix(self.nvars[1], self.dx, self.order_adv)
60+
self.Id, A = getWave1DMatrix(self.nvars[1], self.dx, ['periodic','periodic'], ['periodic','periodic'])
61+
self.A = -self.cs*A
62+
63+
def solve_system(self,rhs,factor,u0,t):
64+
"""
65+
Simple linear solver for (I-dtA)u = rhs
66+
67+
Args:
68+
rhs: right-hand side for the nonlinear system
69+
factor: abbrev. for the node-to-node stepsize (or any other factor required)
70+
u0: initial guess for the iterative solver (not used here so far)
71+
t: current time (e.g. for time-dependent BCs)
72+
73+
Returns:
74+
solution as mesh
75+
"""
76+
77+
M = self.Id - factor*self.A
78+
79+
b = np.concatenate( (rhs.values[0,:], rhs.values[1,:]) )
80+
81+
sol = LA.spsolve(M, b)
82+
83+
me = mesh(self.nvars)
84+
me.values[0,:], me.values[1,:] = np.split(sol, 2)
85+
86+
return me
87+
88+
89+
def __eval_fexpl(self,u,t):
90+
"""
91+
Helper routine to evaluate the explicit part of the RHS
92+
93+
Args:
94+
u: current values (not used here)
95+
t: current time
96+
97+
Returns:
98+
explicit part of RHS
99+
"""
100+
101+
102+
b = np.concatenate( (u.values[0,:], u.values[1,:]) )
103+
sol = self.Dx.dot(b)
104+
105+
fexpl = mesh(self.nvars)
106+
fexpl.values[0,:], fexpl.values[1,:] = np.split(sol, 2)
107+
108+
return fexpl
109+
110+
111+
def __eval_fimpl(self,u,t):
112+
"""
113+
Helper routine to evaluate the implicit part of the RHS
114+
115+
Args:
116+
u: current values
117+
t: current time (not used here)
118+
119+
Returns:
120+
implicit part of RHS
121+
"""
122+
123+
b = np.concatenate( (u.values[0,:], u.values[1,:]) )
124+
sol = self.A.dot(b)
125+
126+
fimpl = mesh(self.nvars,val=0)
127+
fimpl.values[0,:], fimpl.values[1,:] = np.split(sol, 2)
128+
129+
return fimpl
130+
131+
132+
def eval_f(self,u,t):
133+
"""
134+
Routine to evaluate both parts of the RHS
135+
136+
Args:
137+
u: current values
138+
t: current time
139+
140+
Returns:
141+
the RHS divided into two parts
142+
"""
143+
144+
f = rhs_imex_mesh(self.nvars)
145+
f.impl = self.__eval_fimpl(u,t)
146+
f.expl = self.__eval_fexpl(u,t)
147+
return f
148+
149+
def u_exact(self,t):
150+
"""
151+
Routine to compute the exact solution at time t
152+
153+
Args:
154+
t: current time
155+
156+
Returns:
157+
exact solution
158+
"""
159+
160+
sigma_0 = 0.1
161+
k = 7.0*2.0*np.pi
162+
x_0 = 0.75
163+
x_1 = 0.25
164+
165+
ms = 0.0
166+
if self.multiscale:
167+
ms = 1.0
168+
169+
me = mesh(self.nvars)
170+
me.values[0,:] = np.exp(-np.square(self.mesh-x_0-self.cs*t)/(sigma_0*sigma_0)) + ms*np.exp(-np.square(self.mesh-x_1-self.cs*t)/(sigma_0*sigma_0))*np.cos(k*(self.mesh-self.cs*t)/sigma_0)
171+
me.values[1,:] = me.values[0,:]
172+
return me
173+
174+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
from pySDC import CollocationClasses as collclass
3+
4+
import numpy as np
5+
6+
from ProblemClass_multiscale import acoustic_1d_imex
7+
from examples.acoustic_1d_imex.HookClass import plot_solution
8+
9+
from pySDC.datatype_classes.mesh import mesh, rhs_imex_mesh
10+
from pySDC.sweeper_classes.imex_1st_order import imex_1st_order
11+
import pySDC.PFASST_stepwise as mp
12+
from pySDC import Log
13+
from pySDC.Stats import grep_stats, sort_stats
14+
15+
# Sharpclaw imports
16+
#from clawpack import pyclaw
17+
#from clawpack import riemann
18+
from matplotlib import pyplot as plt
19+
20+
21+
if __name__ == "__main__":
22+
23+
# set global logger (remove this if you do not want the output at all)
24+
logger = Log.setup_custom_logger('root')
25+
26+
num_procs = 1
27+
28+
# This comes as read-in for the level class
29+
lparams = {}
30+
lparams['restol'] = 1E-10
31+
32+
sparams = {}
33+
sparams['maxiter'] = 4
34+
35+
# setup parameters "in time"
36+
t0 = 0.0
37+
Tend = 3.0
38+
dt = Tend/float(154)
39+
40+
# This comes as read-in for the problem class
41+
pparams = {}
42+
pparams['nvars'] = [(2,512)]
43+
pparams['cadv'] = 0.05
44+
pparams['cs'] = 1.0
45+
pparams['order_adv'] = 5
46+
pparams['multiscale'] = True
47+
48+
# This comes as read-in for the transfer operations
49+
tparams = {}
50+
tparams['finter'] = True
51+
52+
# Fill description dictionary for easy hierarchy creation
53+
description = {}
54+
description['problem_class'] = acoustic_1d_imex
55+
description['problem_params'] = pparams
56+
description['dtype_u'] = mesh
57+
description['dtype_f'] = rhs_imex_mesh
58+
description['collocation_class'] = collclass.CollGaussLobatto
59+
description['num_nodes'] = 3
60+
description['sweeper_class'] = imex_1st_order
61+
description['level_params'] = lparams
62+
description['hook_class'] = plot_solution
63+
#description['transfer_class'] = mesh_to_mesh_1d
64+
#description['transfer_params'] = tparams
65+
66+
# quickly generate block of steps
67+
MS = mp.generate_steps(num_procs,sparams,description)
68+
69+
# get initial values on finest level
70+
P = MS[0].levels[0].prob
71+
uinit = P.u_exact(t0)
72+
73+
# call main function to get things done...
74+
uend,stats = mp.run_pfasst(MS,u0=uinit,t0=t0,dt=dt,Tend=Tend)
75+
76+
# compute exact solution and compare
77+
uex = P.u_exact(Tend)
78+
79+
fig = plt.figure(figsize=(8,8))
80+
81+
sigma_0 = 0.1
82+
k = 7.0*2.0*np.pi
83+
x_0 = 0.75
84+
x_1 = 0.25
85+
86+
#plt.plot(P.mesh, uex.values[0,:], '+', color='b', label='u (exact)')
87+
plt.plot(P.mesh, uend.values[1,:], '-', color='b', label='SDC')
88+
#plt.plot(P.mesh, uex.values[1,:], '+', color='r', label='p (exact)')
89+
#plt.plot(P.mesh, uend.values[1,:], '-', color='b', linewidth=2.0, label='p (SDC)')
90+
p_slow = np.exp(-np.square(P.mesh-x_0-pparams['cadv']*Tend)/(sigma_0*sigma_0))
91+
plt.plot(P.mesh, p_slow, '-', color='r', markersize=4, label='slow mode')
92+
plt.legend(loc=2)
93+
plt.xlim([0, 1])
94+
plt.ylim([-0.1, 1.1])
95+
fig.gca().grid()
96+
plt.show()
97+
#plt.gcf().savefig('fwsw-sdc-K'+str(sparams['maxiter'])+'-M'+str(description['num_nodes'])+'.pdf', bbox_inches='tight')

0 commit comments

Comments
 (0)