Skip to content

Commit 26890cf

Browse files
Daniel RuprechtDaniel Ruprecht
authored andcommitted
update finite difference matrix builders
1 parent 155193b commit 26890cf

File tree

4 files changed

+158
-94
lines changed

4 files changed

+158
-94
lines changed

examples/acoustic_1d_imex/buildFDMatrix.py

Lines changed: 104 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def getHorizontalDx(N, dx, order):
3030
coeff = 1.0/60.0
3131
zero_pos = 5
3232
else:
33-
print "Order "+str(order)+" not implemented."
33+
print "Order "+order+" not implemented."
3434

3535
first_col = np.zeros(N)
3636

@@ -42,79 +42,143 @@ def getHorizontalDx(N, dx, order):
4242

4343
return sp.csc_matrix( coeff*(1.0/dx)*la.circulant(first_col) )
4444

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

5147
assert bc_left in ['periodic','neumann','dirichlet'], "Unknown type of BC"
48+
49+
if order==2:
50+
stencil = [-1.0, 0.0, 1.0]
51+
range = [-1, 0, 1]
52+
coeff = 1.0/2.0
53+
elif order==4:
54+
stencil = [1.0, -8.0, 0.0, 8.0, -1.0]
55+
range = [ -2, -1, 0, 1, 2]
56+
coeff = 1.0/12.0
57+
58+
A = sp.diags(stencil, range, shape=(N,N))
59+
A = sp.lil_matrix(A)
5260

61+
#
62+
# Periodic boundary conditions
63+
#
5364
if bc_left in ['periodic']:
5465
assert bc_right in ['periodic'], "Periodic BC can only be selected for both sides simultaneously"
5566

5667
if bc_left in ['periodic']:
57-
A[0,N-2] = stencil[0]
58-
A[0,N-1] = stencil[1]
59-
A[1,N-1] = stencil[0]
68+
if order==2:
69+
A[0,N-1] = stencil[0]
6070

61-
if bc_right in ['periodic']:
62-
A[N-2,0] = stencil[4]
63-
A[N-1,0] = stencil[3]
64-
A[N-1,1] = stencil[4]
71+
elif order==4:
72+
A[0,N-2] = stencil[0]
73+
A[0,N-1] = stencil[1]
74+
A[1,N-1] = stencil[0]
6575

76+
if bc_right in ['periodic']:
77+
if order==2:
78+
A[N-1,0] = stencil[2]
79+
elif order==4:
80+
A[N-2,0] = stencil[4]
81+
A[N-1,0] = stencil[3]
82+
A[N-1,1] = stencil[4]
83+
84+
#
85+
# Neumann boundary conditions
86+
#
6687
if bc_left in ['neumann']:
6788
A[0,:] = np.zeros(N)
68-
A[0,0] = -8.0
69-
A[0,1] = 8.0
70-
A[1,0] = -8.0 + 4.0/3.0
71-
A[1,1] = -1.0/3.0
89+
if order==2:
90+
A[0,0] = -4.0/3.0
91+
A[0,1] = 4.0/3.0
92+
elif order==4:
93+
A[0,0] = -8.0
94+
A[0,1] = 8.0
95+
A[1,0] = -8.0 + 4.0/3.0
96+
A[1,1] = -1.0/3.0
7297

7398
if bc_right in ['neumann']:
7499
A[N-1,:] = np.zeros(N)
75-
A[N-2,N-1] = 8.0 - 4.0/3.0
76-
A[N-2,N-2] = 1.0/3.0
77-
A[N-1,N-1] = 8.0
78-
A[N-1,N-2] = -8.0
79-
100+
if order==2:
101+
A[N-1,N-2] = -4.0/3.0
102+
A[N-1,N-1] = 4.0/3.0
103+
elif order==4:
104+
A[N-2,N-1] = 8.0 - 4.0/3.0
105+
A[N-2,N-2] = 1.0/3.0
106+
A[N-1,N-1] = 8.0
107+
A[N-1,N-2] = -8.0
108+
109+
#
110+
# Dirichlet boundary conditions
111+
#
80112
if bc_left in ['dirichlet']:
81-
A[0,:] = np.zeros(N)
82-
A[0,1] = 6.0
113+
# For order==2, nothing to do here
114+
if order==4:
115+
A[0,:] = np.zeros(N)
116+
A[0,1] = 6.0
83117

84118
if bc_right in ['dirichlet']:
85-
A[N-1,:] = np.zeros(N)
86-
A[N-1,N-2] = -6.0
87-
88-
A = 1.0/(12.0*dx)*A
119+
# For order==2, nothing to do here
120+
if order==4:
121+
A[N-1,:] = np.zeros(N)
122+
A[N-1,N-2] = -6.0
89123

124+
125+
A = coeff*(1.0/dx)*A
90126
return sp.csc_matrix(A)
91127

92-
def getBCLeft(value, N, dx, type):
128+
#
129+
#
130+
#
131+
def getBCLeft(value, N, dx, type, order):
93132

94133
assert type in ['periodic','neumann','dirichlet'], "Unknown type of BC"
95134

135+
if order==2:
136+
coeff = 1.0/2.0
137+
elif order==4:
138+
coeff = 1.0/12.0
139+
96140
b = np.zeros(N)
97141
if type in ['dirichlet']:
98-
b[0] = -6.0*value
99-
b[1] = 1.0*value
142+
if order==2:
143+
b[0] = -value;
144+
elif order==4:
145+
b[0] = -6.0*value
146+
b[1] = 1.0*value
100147

101148
if type in ['neumann']:
102-
b[0] = 4.0*dx*value
103-
b[1] = -(2.0/3.0)*dx*value
149+
if order==2:
150+
b[0] = (2.0/3.0)*dx*value
151+
elif order==4:
152+
b[0] = 4.0*dx*value
153+
b[1] = -(2.0/3.0)*dx*value
104154

105-
return (1.0/(12.0*dx))*b
155+
return coeff*(1.0/dx)*b
106156

107-
def getBCRight(value, N, dx, type):
157+
#
158+
#
159+
#
160+
def getBCRight(value, N, dx, type, order):
108161

109162
assert type in ['periodic','neumann','dirichlet'], "Unknown type of BC"
110163

164+
if order==2:
165+
coeff = 1.0/2.0
166+
elif order==4:
167+
coeff = 1.0/12.0
168+
111169
b = np.zeros(N)
112170
if type in ['dirichlet']:
113-
b[N-2] = -1.0*value
114-
b[N-1] = 6.0*value
171+
if order==2:
172+
b[N-1] = value
173+
elif order==4:
174+
b[N-2] = -1.0*value
175+
b[N-1] = 6.0*value
115176

116177
if type in ['neumann']:
117-
b[N-2] = -(2.0/3.0)*dx*value
118-
b[N-1] = 4.0*dx*value
178+
if order==2:
179+
b[N-1] = (2.0/3.0)*dx*value
180+
elif order==4:
181+
b[N-2] = -(2.0/3.0)*dx*value
182+
b[N-1] = 4.0*dx*value
119183

120-
return (1.0/(12.0*dx))*b
184+
return coeff*(1.0/dx)*b

examples/acoustic_1d_imex/buildWave1DMatrix.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import scipy.sparse as sp
55
from buildFDMatrix import getMatrix, getHorizontalDx, getBCLeft, getBCRight
66

7+
wave_order = 4
8+
79
def getWave1DMatrix(N, dx, bc_left, bc_right):
810

911
Id = sp.eye(2*N)
1012

11-
D_u = getMatrix(N, dx, bc_left[0], bc_right[0])
12-
D_p = getMatrix(N, dx, bc_left[1], bc_right[1])
13+
D_u = getMatrix(N, dx, bc_left[0], bc_right[0], wave_order)
14+
D_p = getMatrix(N, dx, bc_left[1], bc_right[1], wave_order)
1315
Zero = np.zeros((N,N))
1416
M1 = sp.hstack((Zero, D_p), format="csc")
1517
M2 = sp.hstack((D_u, Zero), format="csc")
@@ -25,11 +27,11 @@ def getWave1DAdvectionMatrix(N, dx, order):
2527
return sp.csc_matrix(M)
2628

2729
def getWaveBCLeft(value, N, dx, bc_left):
28-
bu = getBCLeft(value[0], N, dx, bc_left[0])
29-
bp = getBCLeft(value[1], N, dx, bc_left[1])
30+
bu = getBCLeft(value[0], N, dx, bc_left[0], wave_order)
31+
bp = getBCLeft(value[1], N, dx, bc_left[1], wave_order)
3032
return np.concatenate((bp, bu))
3133

3234
def getWaveBCRight(value, N, dx, bc_right):
33-
bu = getBCRight(value[0], N, dx, bc_right[0])
34-
bp = getBCRight(value[1], N, dx, bc_right[1])
35+
bu = getBCRight(value[0], N, dx, bc_right[0], wave_order)
36+
bp = getBCRight(value[1], N, dx, bc_right[1], wave_order)
3537
return np.concatenate((bp, bu))

examples/acoustic_1d_imex/plotconvdata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22
from matplotlib import pyplot as plt
33

4-
fs = 18
4+
fs = 18
55
order = np.array([])
66
nsteps = np.array([])
77
error = np.array([])

examples/acoustic_1d_imex/runconvergence.py

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import numpy as np
55

6-
from ProblemClass import acoustic_1d_imex
6+
from ProblemClass_conv import acoustic_1d_imex
77
from examples.acoustic_1d_imex.HookClass import plot_solution
88

99
from pySDC.datatype_classes.mesh import mesh, rhs_imex_mesh
@@ -12,9 +12,6 @@
1212
from pySDC import Log
1313
from pySDC.Stats import grep_stats, sort_stats
1414

15-
# Sharpclaw imports
16-
from clawpack import pyclaw
17-
from clawpack import riemann
1815
from matplotlib import pyplot as plt
1916

2017

@@ -36,7 +33,7 @@
3633
pparams = {}
3734
pparams['nvars'] = [(2,250)]
3835
pparams['cadv'] = 0.05
39-
pparams['cs'] = 1.0
36+
pparams['cs'] = 1.00
4037
pparams['order_adv'] = 5
4138
pparams['waveno'] = 5
4239

@@ -50,67 +47,68 @@
5047
description['problem_params'] = pparams
5148
description['dtype_u'] = mesh
5249
description['dtype_f'] = rhs_imex_mesh
53-
description['collocation_class'] = collclass.CollGaussLobatto
50+
description['collocation_class'] = collclass.CollGaussRadau_Right
5451
description['sweeper_class'] = imex_1st_order
5552
description['level_params'] = lparams
5653
description['hook_class'] = plot_solution
5754
#description['transfer_class'] = mesh_to_mesh_1d
5855
#description['transfer_params'] = tparams
5956

60-
Nsteps = [3, 4, 6, 8, 10, 12, 15, 18, 20]
61-
order = 4
62-
error = np.zeros(np.size(Nsteps))
63-
64-
# setup parameters "in time"
65-
t0 = 0
66-
Tend = 1.0
57+
Nsteps = [65]
6758

68-
if order==2:
69-
file = open('conv-data.txt', 'w')
70-
else:
71-
file = open('conv-data.txt', 'a')
72-
73-
if order==2:
74-
description['num_nodes'] = 2
75-
elif order==3:
76-
description['num_nodes'] = 3
77-
elif order==4:
78-
description['num_nodes'] = 3
59+
for order in [4]:
7960

80-
sparams['maxiter'] = order
61+
error = np.zeros(np.size(Nsteps))
8162

82-
# quickly generate block of steps
83-
MS = mp.generate_steps(num_procs,sparams,description)
84-
85-
for ii in range(0,np.size(Nsteps)):
86-
87-
dt = Tend/float(Nsteps[ii])
63+
# setup parameters "in time"
64+
t0 = 0
65+
Tend = 1.0
66+
67+
if order==2:
68+
file = open('conv-data.txt', 'w')
69+
else:
70+
file = open('conv-data.txt', 'a')
71+
72+
if order==2:
73+
description['num_nodes'] = 2
74+
elif order==3:
75+
description['num_nodes'] = 3
76+
elif order==4:
77+
description['num_nodes'] = 3
78+
79+
sparams['maxiter'] = order
80+
81+
# quickly generate block of steps
82+
MS = mp.generate_steps(num_procs,sparams,description)
83+
for ii in range(0,np.size(Nsteps)):
84+
85+
dt = Tend/float(Nsteps[ii])
8886

89-
# get initial values on finest level
90-
P = MS[0].levels[0].prob
91-
uinit = P.u_exact(t0)
87+
# get initial values on finest level
88+
P = MS[0].levels[0].prob
89+
uinit = P.u_exact(t0)
9290

93-
# call main function to get things done...
94-
uend,stats = mp.run_pfasst(MS, u0=uinit, t0=t0, dt=dt, Tend=Tend)
91+
# call main function to get things done...
92+
uend,stats = mp.run_pfasst(MS, u0=uinit, t0=t0, dt=dt, Tend=Tend)
9593

96-
# compute exact solution and compare
97-
uex = P.u_exact(Tend)
94+
# compute exact solution and compare
95+
uex = P.u_exact(Tend)
9896

99-
error[ii] = np.linalg.norm(uex.values-uend.values,np.inf)/np.linalg.norm(uex.values,np.inf)
100-
file.write(str(order)+" "+str(Nsteps[ii])+" "+str(error[ii])+"\n")
97+
error[ii] = np.linalg.norm(uex.values-uend.values,np.inf)/np.linalg.norm(uex.values,np.inf)
98+
file.write(str(order)+" "+str(Nsteps[ii])+" "+str(error[ii])+"\n")
10199

102-
file.close()
100+
file.close()
103101

104102
if np.size(Nsteps)==1:
105103
fig = plt.figure(figsize=(8,8))
106104

107-
plt.plot(P.state.grid.x.centers, uex.values[0,:], '+', color='b', label='u (exact)')
108-
plt.plot(P.state.grid.x.centers, uend.values[0,:], '-', color='b', label='u (SDC)')
109-
plt.plot(P.state.grid.x.centers, uex.values[1,:], '+', color='r', label='p (exact)')
110-
plt.plot(P.state.grid.x.centers, uend.values[1,:], '-', color='r', label='p (SDC)')
105+
plt.plot(P.mesh, uex.values[0,:], '+', color='b', label='u (exact)')
106+
plt.plot(P.mesh, uend.values[0,:], '-', color='b', label='u (SDC)')
107+
plt.plot(P.mesh, uex.values[1,:], '+', color='r', label='p (exact)')
108+
plt.plot(P.mesh, uend.values[1,:], '-', color='r', label='p (SDC)')
111109
plt.legend()
112-
plt.xlim([0, 1])
113-
plt.ylim([-1, 1])
110+
plt.xlim([0.0, 1.0])
111+
plt.ylim([-1.0, 1.0])
114112
plt.show()
115113
else:
116114
for ii in range(0,np.size(Nsteps)):

0 commit comments

Comments
 (0)