11import numpy as np
22import scipy .sparse as sp
33import 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