1- """
2- solve
1+ import numpy
32
4- a + u a + v a = 0
5- t x y
3+ import mesh .reconstruction_f as reconstruction_f
64
7- """
5+ def unsplitFluxes (my_data , dt , scalar_name ):
6+ """
7+ Construct the fluxes through the interfaces for the linear advection
8+ equation:
89
9- import numpy
10+ a + u a + v a = 0
11+ t x y
1012
11- import mesh .reconstruction_f as reconstruction_f
13+ We use a second-order (piecewise linear) unsplit Godunov method
14+ (following Colella 1990).
1215
13- def unsplitFluxes (my_data , dt , a ):
16+ In the pure advection case, there is no Riemann problem we need to
17+ solve -- we just simply do upwinding. So there is only one 'state'
18+ at each interface, and the zone the information comes from depends
19+ on the sign of the velocity.
20+
21+ Our convection is that the fluxes are going to be defined on the
22+ left edge of the computational zones
23+
24+
25+ | | | |
26+ | | | |
27+ -+------+------+------+------+------+------+--
28+ | i-1 | i | i+1 |
29+
30+ a_l,i a_r,i a_l,i+1
31+
32+
33+ a_r,i and a_l,i+1 are computed using the information in
34+ zone i,j.
35+
36+ Parameters
37+ ----------
38+ my_data : CellCenterData2d object
39+ The data object containing the grid and advective scalar that
40+ we are advecting.
41+ dt : float
42+ The timestep we are advancing through.
43+ scalar_name : str
44+ The name of the variable contained in my_data that we are
45+ advecting
46+
47+ Returns
48+ -------
49+ out : ndarray, ndarray
50+ The fluxes on the x- and y-interfaces
51+
52+ """
1453
1554 my_grid = my_data .grid
1655 rp = my_data .rp
1756
57+ a = my_data .get_var (scalar_name )
58+
1859 # get the advection velocities
1960 u = rp .get_param ("advection.u" )
2061 v = rp .get_param ("advection.v" )
2162
2263 cx = u * dt / my_grid .dx
2364 cy = v * dt / my_grid .dy
24-
65+
66+ qx = my_grid .qx
67+ qy = my_grid .qy
2568
2669 #--------------------------------------------------------------------------
2770 # monotonized central differences
2871 #--------------------------------------------------------------------------
2972
3073 limiter = rp .get_param ("advection.limiter" )
31- if ( limiter == 0 ) :
74+ if limiter == 0 :
3275 limitFunc = reconstruction_f .nolimit
33- elif ( limiter == 1 ) :
76+ elif limiter == 1 :
3477 limitFunc = reconstruction_f .limit2
3578 else :
3679 limitFunc = reconstruction_f .limit4
3780
38- ldelta_a = limitFunc (1 , a , my_grid . qx , my_grid . qy , my_grid .ng )
81+ ldelta_a = limitFunc (1 , a , qx , qy , my_grid .ng )
3982
40-
41-
42- # in the pure advection case, there is no Riemann problem we need to
43- # solve -- we just simply do upwinding. So there is only one 'state'
44- # at each interface, and the zone the information comes from depends
45- # on the sign of the velocity -- this should be vectorized.
46- a_x = numpy .zeros ((my_grid .qx ,my_grid .qy ), dtype = numpy .float64 )
47-
48- """
49-
50- the fluxes are going to be defined on the left edge of the
51- computational zones
52-
53-
54- | | | |
55- | | | |
56- -+------+------+------+------+------+------+--
57- | i-1 | i | i+1 |
58-
59- a_l,i a_r,i a_l,i+1
60-
61-
62- a_r,i and a_l,i+1 are computed using the information in
63- zone i,j.
83+ a_x = my_grid .scratch_array ()
6484
65- """
66-
67- qx = my_grid .qx
68- qy = my_grid .qy
6985
7086 # upwind
71- if ( u < 0 ) :
87+ if u < 0 :
7288 # a_x[i,j] = a[i,j] - 0.5*(1.0 + cx)*ldelta_a[i,j]
7389 a_x [:,:] = a [:,:] - 0.5 * (1.0 + cx )* ldelta_a [:,:]
7490 else :
@@ -77,13 +93,13 @@ def unsplitFluxes(my_data, dt, a):
7793
7894
7995 # y-direction
80- ldelta_a = limitFunc (2 , a , my_grid . qx , my_grid . qy , my_grid .ng )
96+ ldelta_a = limitFunc (2 , a , qx , qy , my_grid .ng )
8197
82- a_y = numpy . zeros (( my_grid .qx , my_grid . qy ), dtype = numpy . float64 )
98+ a_y = my_grid .scratch_array ( )
8399
84100
85101 # upwind
86- if ( v < 0 ) :
102+ if v < 0 :
87103 # a_y[i,j] = a[i,j] - 0.5*(1.0 + cy)*ldelta_a[i,j]
88104 a_y [:,:] = a [:,:] - 0.5 * (1.0 + cy )* ldelta_a [:,:]
89105 else :
@@ -96,8 +112,8 @@ def unsplitFluxes(my_data, dt, a):
96112 F_xt = u * a_x
97113 F_yt = v * a_y
98114
99- F_x = numpy . zeros (( my_grid .qx , my_grid . qy ), dtype = numpy . float64 )
100- F_y = numpy . zeros (( my_grid .qx , my_grid . qy ), dtype = numpy . float64 )
115+ F_x = my_grid .scratch_array ( )
116+ F_y = my_grid .scratch_array ( )
101117
102118 # the zone where we grab the transverse flux derivative from
103119 # depends on the sign of the advective velocity
@@ -107,7 +123,6 @@ def unsplitFluxes(my_data, dt, a):
107123 else :
108124 mx = - 1
109125
110-
111126 if v <= 0 :
112127 my = 0
113128 else :
@@ -118,29 +133,26 @@ def unsplitFluxes(my_data, dt, a):
118133 dtdy2 = 0.5 * dt / my_grid .dy
119134
120135 i = my_grid .ilo
121- while ( i <= my_grid .ihi + 1 ) :
136+ while i <= my_grid .ihi + 1 :
122137
123138 j = my_grid .jlo
124- while ( j <= my_grid .jhi + 1 ) :
139+ while j <= my_grid .jhi + 1 :
125140
126141 F_x [i ,j ] = u * (a_x [i ,j ] - dtdy2 * (F_yt [i + mx ,j + 1 ] - F_yt [i + mx ,j ]))
127142
128143 j += 1
129144 i += 1
130145
131146 i = my_grid .ilo
132- while ( i <= my_grid .ihi + 1 ) :
147+ while i <= my_grid .ihi + 1 :
133148
134149 j = my_grid .jlo
135- while ( j <= my_grid .jhi + 1 ) :
150+ while j <= my_grid .jhi + 1 :
136151
137152 F_y [i ,j ] = v * (a_y [i ,j ] - dtdx2 * (F_xt [i + 1 ,j + my ] - F_xt [i ,j + my ]))
138153
139154 j += 1
140155 i += 1
141156
142157
143- return [F_x , F_y ]
144-
145-
146-
158+ return F_x , F_y
0 commit comments