Skip to content

Commit 27d6598

Browse files
committed
Merge pull request #37 from danielru/boussinesq/selectable_order
Boussinesq/selectable order
2 parents 7229d67 + e72d23c commit 27d6598

File tree

5 files changed

+174
-84
lines changed

5 files changed

+174
-84
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/build2DFDMatrix.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
import scipy.sparse as sp
55
from buildFDMatrix import getMatrix, getUpwindMatrix, getBCLeft, getBCRight
66

7-
def get2DUpwindMatrix(N, dx):
7+
#
8+
#
9+
#
10+
def get2DUpwindMatrix(N, dx, order):
811

9-
Dx = getUpwindMatrix( N[0], dx)
12+
Dx = getUpwindMatrix( N[0], dx, order)
1013
return sp.kron( Dx, sp.eye(N[1]), format="csr" )
1114

15+
#
16+
#
17+
#
1218
def get2DMesh(N, x_b, z_b, bc_hor, bc_ver):
1319
assert np.size(N)==2, 'N needs to be an array with two entries: N[0]=Nx and N[1]=Nz'
1420
assert np.size(x_b)==2, 'x_b needs to be an array with two entries: x_b[0] = left boundary, x_b[1] = right boundary'
@@ -39,12 +45,16 @@ def get2DMesh(N, x_b, z_b, bc_hor, bc_ver):
3945
xx, zz = np.meshgrid(x,z,indexing="ij")
4046
return xx, zz, h
4147

42-
def get2DMatrix(N, h, bc_hor, bc_ver):
48+
#
49+
#
50+
#
51+
def get2DMatrix(N, h, bc_hor, bc_ver, order):
52+
4353
assert np.size(N)==2, 'N needs to be an array with two entries: N[0]=Nx and N[1]=Nz'
4454
assert np.size(h)==2, 'h needs to be an array with two entries: h[0]=dx and h[1]=dz'
4555

46-
Ax = getMatrix( N[0], h[0], bc_hor[0], bc_hor[1])
47-
Az = getMatrix( N[1], h[1], bc_ver[0], bc_ver[1])
56+
Ax = getMatrix( N[0], h[0], bc_hor[0], bc_hor[1], order)
57+
Az = getMatrix( N[1], h[1], bc_ver[0], bc_ver[1], order)
4858

4959
Dx = sp.kron( Ax, sp.eye(N[1]), format="csr")
5060
Dz = sp.kron( sp.eye(N[0]), Az, format="csr")
@@ -83,4 +93,4 @@ def getBCVertical( value, N, dz, bc_ver):
8393
bu = getBCRight( value[1], N[1], dz, bc_ver[1])
8494
bu = np.kron( np.ones(N[0]), bu)
8595

86-
return bd, bu
96+
return bd, bu

examples/boussinesq_2d_imex/buildBoussinesq2DMatrix.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
def getBoussinesq2DUpwindMatrix(N, dx, u_adv, order):
66

7-
Dx = get2DUpwindMatrix(N, dx)
7+
Dx = get2DUpwindMatrix(N, dx, order)
88

99
# Note: In the equations it is u_t + u_adv* D_x u = ... so in order to comply with the form u_t = M u,
1010
# add a minus sign in front of u_adv
@@ -19,10 +19,12 @@ def getBoussinesq2DUpwindMatrix(N, dx, u_adv, order):
1919
return sp.csc_matrix(M)
2020

2121
def getBoussinesq2DMatrix(N, h, bc_hor, bc_ver, c_s, Nfreq, order):
22-
Dx_u, Dz_u = get2DMatrix(N, h, bc_hor[0], bc_ver[0])
23-
Dx_w, Dz_w = get2DMatrix(N, h, bc_hor[1], bc_ver[1])
24-
Dx_b, Dz_b = get2DMatrix(N, h, bc_hor[2], bc_ver[2])
25-
Dx_p, Dz_p = get2DMatrix(N, h, bc_hor[3], bc_ver[3])
22+
23+
Dx_u, Dz_u = get2DMatrix(N, h, bc_hor[0], bc_ver[0], order)
24+
Dx_w, Dz_w = get2DMatrix(N, h, bc_hor[1], bc_ver[1], order)
25+
Dx_b, Dz_b = get2DMatrix(N, h, bc_hor[2], bc_ver[2], order)
26+
Dx_p, Dz_p = get2DMatrix(N, h, bc_hor[3], bc_ver[3], order)
27+
2628
Id_N = sp.eye(N[0]*N[1])
2729

2830
Zero = np.zeros((N[0]*N[1],N[0]*N[1]))
@@ -53,4 +55,4 @@ def getBoussinesqBCHorizontal(value, N, dx, bc_hor):
5355
return b_left, b_right
5456

5557
def getBoussinesqBCVertical():
56-
return 0.0
58+
return 0.0
Lines changed: 134 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
import numpy as np
22
import scipy.sparse as sp
33
import scipy.linalg as la
4+
import sys
5+
46
# Only for periodic BC because we have advection only in x direction
5-
def getUpwindMatrix(N, dx):
6-
7-
#stencil = [-1.0, 1.0]
8-
#zero_pos = 2
9-
#coeff = 1.0
10-
11-
#stencil = [1.0, -4.0, 3.0]
12-
#coeff = 1.0/2.0
13-
#zero_pos = 3
14-
15-
#stencil = [1.0, -6.0, 3.0, 2.0]
16-
#coeff = 1.0/6.0
17-
#zero_pos = 3
7+
def getUpwindMatrix(N, dx, order):
188

19-
#stencil = [-5.0, 30.0, -90.0, 50.0, 15.0]
20-
#coeff = 1.0/60.0
21-
#zero_pos = 4
9+
if order==1:
10+
stencil = [-1.0, 1.0]
11+
zero_pos = 2
12+
coeff = 1.0
2213

23-
stencil = [3.0, -20.0, 60.0, -120.0, 65.0, 12.0]
24-
coeff = 1.0/60.0
25-
zero_pos = 5
14+
elif order==2:
15+
stencil = [1.0, -4.0, 3.0]
16+
coeff = 1.0/2.0
17+
zero_pos = 3
18+
19+
elif order==3:
20+
stencil = [1.0, -6.0, 3.0, 2.0]
21+
coeff = 1.0/6.0
22+
zero_pos = 3
23+
24+
elif order==4:
25+
stencil = [-5.0, 30.0, -90.0, 50.0, 15.0]
26+
coeff = 1.0/60.0
27+
zero_pos = 4
2628

29+
elif order==5:
30+
stencil = [3.0, -20.0, 60.0, -120.0, 65.0, 12.0]
31+
coeff = 1.0/60.0
32+
zero_pos = 5
33+
else:
34+
sys.exit('Order '+str(order)+' not implemented')
35+
2736
first_col = np.zeros(N)
2837

2938
# Because we need to specific first column (not row) in circulant, flip stencil array
@@ -34,78 +43,145 @@ def getUpwindMatrix(N, dx):
3443

3544
return sp.csc_matrix( coeff*(1.0/dx)*la.circulant(first_col) )
3645

37-
def getMatrix(N, dx, bc_left, bc_right):
38-
stencil = [1.0, -8.0, 0.0, 8.0, -1.0]
39-
range = [ -2, -1, 0, 1, 2]
40-
A = sp.diags(stencil, range, shape=(N,N))
41-
A = sp.lil_matrix(A)
46+
def getMatrix(N, dx, bc_left, bc_right, order):
4247

4348
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)
63+
64+
#
65+
# Periodic boundary conditions
66+
#
4467
if bc_left in ['periodic']:
4568
assert bc_right in ['periodic'], "Periodic BC can only be selected for both sides simultaneously"
4669

4770
if bc_left in ['periodic']:
48-
A[0,N-2] = stencil[0]
49-
A[0,N-1] = stencil[1]
50-
A[1,N-1] = stencil[0]
71+
if order==2:
72+
A[0,N-1] = stencil[0]
5173

52-
if bc_right in ['periodic']:
53-
A[N-2,0] = stencil[4]
54-
A[N-1,0] = stencil[3]
55-
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]
5678

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+
#
5790
if bc_left in ['neumann']:
5891
A[0,:] = np.zeros(N)
59-
A[0,0] = -8.0
60-
A[0,1] = 8.0
61-
A[1,0] = -8.0 + 4.0/3.0
62-
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
63100

64101
if bc_right in ['neumann']:
65102
A[N-1,:] = np.zeros(N)
66-
A[N-2,N-1] = 8.0 - 4.0/3.0
67-
A[N-2,N-2] = 1.0/3.0
68-
A[N-1,N-1] = 8.0
69-
A[N-1,N-2] = -8.0
70-
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+
#
71115
if bc_left in ['dirichlet']:
72-
A[0,:] = np.zeros(N)
73-
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
74120

75121
if bc_right in ['dirichlet']:
76-
A[N-1,:] = np.zeros(N)
77-
A[N-1,N-2] = -6.0
78-
79-
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
80126

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

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

85136
assert type in ['periodic','neumann','dirichlet'], "Unknown type of BC"
86137

138+
if order==2:
139+
coeff = 1.0/2.0
140+
elif order==4:
141+
coeff = 1.0/12.0
142+
87143
b = np.zeros(N)
88144
if type in ['dirichlet']:
89-
b[0] = -6.0*value
90-
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
91150

92151
if type in ['neumann']:
93-
b[0] = 4.0*dx*value
94-
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
95157

96-
return (1.0/(12.0*dx))*b
158+
return coeff*(1.0/dx)*b
97159

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

100165
assert type in ['periodic','neumann','dirichlet'], "Unknown type of BC"
101166

167+
if order==2:
168+
coeff = 1.0/2.0
169+
elif order==4:
170+
coeff = 1.0/12.0
171+
102172
b = np.zeros(N)
103173
if type in ['dirichlet']:
104-
b[N-2] = -1.0*value
105-
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
106179

107180
if type in ['neumann']:
108-
b[N-2] = -(2.0/3.0)*dx*value
109-
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
110186

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

0 commit comments

Comments
 (0)