Skip to content

Commit dc7f40e

Browse files
author
Daniel Ruprecht
committed
can now also choose between order 2 and 4 for non-advection terms; simple test for PFASST on eight processors with operator coarsening indicates reasonable convergence
1 parent e244a0a commit dc7f40e

File tree

3 files changed

+116
-48
lines changed

3 files changed

+116
-48
lines changed

examples/boussinesq_2d_imex/ProblemClass.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(self, cparams, dtype_u, dtype_f):
6262
assert 'Nfreq' in cparams
6363
assert 'x_bounds' in cparams
6464
assert 'z_bounds' in cparams
65+
assert 'order_upw' in cparams
6566
assert 'order' in cparams
6667
assert 'gmres_maxiter' in cparams
6768
assert 'gmres_restart' in cparams
@@ -82,7 +83,7 @@ def __init__(self, cparams, dtype_u, dtype_f):
8283
self.xx, self.zz, self.h = get2DMesh(self.N, self.x_bounds, self.z_bounds, self.bc_hor[0], self.bc_ver[0])
8384

8485
self.Id, self.M = getBoussinesq2DMatrix(self.N, self.h, self.bc_hor, self.bc_ver, self.c_s, self.Nfreq, self.order)
85-
self.D_upwind = getBoussinesq2DUpwindMatrix( self.N, self.h[0], self.u_adv , self.order)
86+
self.D_upwind = getBoussinesq2DUpwindMatrix( self.N, self.h[0], self.u_adv , self.order_upw)
8687

8788
self.logger = logging()
8889

examples/boussinesq_2d_imex/buildFDMatrix.py

Lines changed: 105 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def getUpwindMatrix(N, dx, order):
3131
coeff = 1.0/60.0
3232
zero_pos = 5
3333
else:
34-
sys.exit("Order "+str(order)+" not implemented.")
34+
sys.exit('Order '+str(order)+' not implemented')
3535

3636
first_col = np.zeros(N)
3737

@@ -44,78 +44,144 @@ def getUpwindMatrix(N, dx, order):
4444
return sp.csc_matrix( coeff*(1.0/dx)*la.circulant(first_col) )
4545

4646
def getMatrix(N, dx, bc_left, bc_right, order):
47-
stencil = [1.0, -8.0, 0.0, 8.0, -1.0]
48-
range = [ -2, -1, 0, 1, 2]
49-
A = sp.diags(stencil, range, shape=(N,N))
50-
A = sp.lil_matrix(A)
5147

5248
assert bc_left in ['periodic','neumann','dirichlet'], "Unknown type of BC"
49+
50+
if order==2:
51+
stencil = [-1.0, 0.0, 1.0]
52+
range = [-1, 0, 1]
53+
coeff = 1.0/2.0
54+
elif order==4:
55+
stencil = [1.0, -8.0, 0.0, 8.0, -1.0]
56+
range = [ -2, -1, 0, 1, 2]
57+
coeff = 1.0/12.0
58+
else:
59+
sys.exit('Order '+str(order)+' not implemented')
60+
61+
A = sp.diags(stencil, range, shape=(N,N))
62+
A = sp.lil_matrix(A)
5363

64+
#
65+
# Periodic boundary conditions
66+
#
5467
if bc_left in ['periodic']:
5568
assert bc_right in ['periodic'], "Periodic BC can only be selected for both sides simultaneously"
5669

5770
if bc_left in ['periodic']:
58-
A[0,N-2] = stencil[0]
59-
A[0,N-1] = stencil[1]
60-
A[1,N-1] = stencil[0]
71+
if order==2:
72+
A[0,N-1] = stencil[0]
6173

62-
if bc_right in ['periodic']:
63-
A[N-2,0] = stencil[4]
64-
A[N-1,0] = stencil[3]
65-
A[N-1,1] = stencil[4]
74+
elif order==4:
75+
A[0,N-2] = stencil[0]
76+
A[0,N-1] = stencil[1]
77+
A[1,N-1] = stencil[0]
6678

79+
if bc_right in ['periodic']:
80+
if order==2:
81+
A[N-1,0] = stencil[2]
82+
elif order==4:
83+
A[N-2,0] = stencil[4]
84+
A[N-1,0] = stencil[3]
85+
A[N-1,1] = stencil[4]
86+
87+
#
88+
# Neumann boundary conditions
89+
#
6790
if bc_left in ['neumann']:
6891
A[0,:] = np.zeros(N)
69-
A[0,0] = -8.0
70-
A[0,1] = 8.0
71-
A[1,0] = -8.0 + 4.0/3.0
72-
A[1,1] = -1.0/3.0
92+
if order==2:
93+
A[0,0] = -4.0/3.0
94+
A[0,1] = 4.0/3.0
95+
elif order==4:
96+
A[0,0] = -8.0
97+
A[0,1] = 8.0
98+
A[1,0] = -8.0 + 4.0/3.0
99+
A[1,1] = -1.0/3.0
73100

74101
if bc_right in ['neumann']:
75102
A[N-1,:] = np.zeros(N)
76-
A[N-2,N-1] = 8.0 - 4.0/3.0
77-
A[N-2,N-2] = 1.0/3.0
78-
A[N-1,N-1] = 8.0
79-
A[N-1,N-2] = -8.0
80-
103+
if order==2:
104+
A[N-1,N-2] = -4.0/3.0
105+
A[N-1,N-1] = 4.0/3.0
106+
elif order==4:
107+
A[N-2,N-1] = 8.0 - 4.0/3.0
108+
A[N-2,N-2] = 1.0/3.0
109+
A[N-1,N-1] = 8.0
110+
A[N-1,N-2] = -8.0
111+
112+
#
113+
# Dirichlet boundary conditions
114+
#
81115
if bc_left in ['dirichlet']:
82-
A[0,:] = np.zeros(N)
83-
A[0,1] = 6.0
116+
# For order==2, nothing to do here
117+
if order==4:
118+
A[0,:] = np.zeros(N)
119+
A[0,1] = 6.0
84120

85121
if bc_right in ['dirichlet']:
86-
A[N-1,:] = np.zeros(N)
87-
A[N-1,N-2] = -6.0
88-
89-
A = 1.0/(12.0*dx)*A
122+
# For order==2, nothing to do here
123+
if order==4:
124+
A[N-1,:] = np.zeros(N)
125+
A[N-1,N-2] = -6.0
90126

127+
128+
A = coeff*(1.0/dx)*A
91129
return sp.csc_matrix(A)
92130

93-
def getBCLeft(value, N, dx, type):
131+
#
132+
#
133+
#
134+
def getBCLeft(value, N, dx, type, order):
94135

95136
assert type in ['periodic','neumann','dirichlet'], "Unknown type of BC"
96137

138+
if order==2:
139+
coeff = 1.0/2.0
140+
elif order==4:
141+
coeff = 1.0/12.0
142+
97143
b = np.zeros(N)
98144
if type in ['dirichlet']:
99-
b[0] = -6.0*value
100-
b[1] = 1.0*value
145+
if order==2:
146+
b[0] = -value;
147+
elif order==4:
148+
b[0] = -6.0*value
149+
b[1] = 1.0*value
101150

102151
if type in ['neumann']:
103-
b[0] = 4.0*dx*value
104-
b[1] = -(2.0/3.0)*dx*value
152+
if order==2:
153+
b[0] = (2.0/3.0)*dx*value
154+
elif order==4:
155+
b[0] = 4.0*dx*value
156+
b[1] = -(2.0/3.0)*dx*value
105157

106-
return (1.0/(12.0*dx))*b
158+
return coeff*(1.0/dx)*b
107159

108-
def getBCRight(value, N, dx, type):
160+
#
161+
#
162+
#
163+
def getBCRight(value, N, dx, type, order):
109164

110165
assert type in ['periodic','neumann','dirichlet'], "Unknown type of BC"
111166

167+
if order==2:
168+
coeff = 1.0/2.0
169+
elif order==4:
170+
coeff = 1.0/12.0
171+
112172
b = np.zeros(N)
113173
if type in ['dirichlet']:
114-
b[N-2] = -1.0*value
115-
b[N-1] = 6.0*value
174+
if order==2:
175+
b[N-1] = value
176+
elif order==4:
177+
b[N-2] = -1.0*value
178+
b[N-1] = 6.0*value
116179

117180
if type in ['neumann']:
118-
b[N-2] = -(2.0/3.0)*dx*value
119-
b[N-1] = 4.0*dx*value
181+
if order==2:
182+
b[N-1] = (2.0/3.0)*dx*value
183+
elif order==4:
184+
b[N-2] = -(2.0/3.0)*dx*value
185+
b[N-1] = 4.0*dx*value
120186

121-
return (1.0/(12.0*dx))*b
187+
return coeff*(1.0/dx)*b

examples/boussinesq_2d_imex/playground.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
# set global logger (remove this if you do not want the output at all)
2525
logger = Log.setup_custom_logger('root')
2626

27-
num_procs = 1
27+
num_procs = 8
2828

2929
# This comes as read-in for the level class
3030
lparams = {}
@@ -48,16 +48,17 @@
4848

4949
# This comes as read-in for the problem class
5050
pparams = {}
51-
pparams['nvars'] = [(4,450,30)]
51+
pparams['nvars'] = [(4,450,30), (4,450,30)]
5252
pparams['u_adv'] = 0.02
5353
pparams['c_s'] = 0.3
5454
pparams['Nfreq'] = 0.01
5555
pparams['x_bounds'] = [(-150.0, 150.0)]
5656
pparams['z_bounds'] = [( 0.0, 10.0)]
57-
pparams['order'] = [1] # [fine_level, coarse_level]
58-
pparams['gmres_maxiter'] = [50]
59-
pparams['gmres_restart'] = 20
60-
pparams['gmres_tol'] = 1e-6
57+
pparams['order'] = [4, 2] # [fine_level, coarse_level]
58+
pparams['order_upw'] = [5, 1]
59+
pparams['gmres_maxiter'] = [50, 50]
60+
pparams['gmres_restart'] = [20, 20]
61+
pparams['gmres_tol'] = [1e-6, 1e-6]
6162

6263
# This comes as read-in for the transfer operations
6364
tparams = {}
@@ -73,8 +74,8 @@
7374
description['sweeper_class'] = imex_1st_order
7475
description['level_params'] = lparams
7576
description['hook_class'] = plot_solution
76-
#description['transfer_class'] = mesh_to_mesh_2d
77-
#description['transfer_params'] = tparams
77+
description['transfer_class'] = mesh_to_mesh_2d
78+
description['transfer_params'] = tparams
7879

7980
# quickly generate block of steps
8081
MS = mp.generate_steps(num_procs,sparams,description)

0 commit comments

Comments
 (0)