@@ -133,15 +133,18 @@ def __init__(self, nx, ny, ng=1,
133133 self .yr = (np .arange (self .qy ) + 1.0 - ng )* self .dy + ymin
134134 self .y = 0.5 * (self .yl + self .yr )
135135
136- # 2-d versions of the zone coordinates (replace with meshgrid?)
137- x2d = np .repeat (self .x , self .qy )
138- x2d . shape = ( self . qx , self . qy )
139- self .x2d = x2d
136+ # 2-d versions of the zone coordinates
137+ x2d , y2d = np .meshgrid (self .x , self .y , indexing = 'ij' )
138+ self . x2d = ArrayIndexer ( d = x2d , grid = self )
139+ self .y2d = ArrayIndexer ( d = y2d , grid = self )
140140
141- y2d = np .repeat (self .y , self .qx )
142- y2d .shape = (self .qy , self .qx )
143- y2d = np .transpose (y2d )
144- self .y2d = y2d
141+ xl2d , yl2d = np .meshgrid (self .xl , self .yl , indexing = 'ij' )
142+ self .xl2d = ArrayIndexer (d = xl2d , grid = self )
143+ self .yl2d = ArrayIndexer (d = yl2d , grid = self )
144+
145+ xr2d , yr2d = np .meshgrid (self .xr , self .yr , indexing = 'ij' )
146+ self .xr2d = ArrayIndexer (d = xr2d , grid = self )
147+ self .yr2d = ArrayIndexer (d = yr2d , grid = self )
145148
146149 def scratch_array (self , nvar = 1 ):
147150 """
@@ -186,6 +189,115 @@ def __eq__(self, other):
186189 return result
187190
188191
192+ class Cartesian2d (Grid2d ):
193+ """
194+ This class defines a 2D Cartesian Grid.
195+
196+ Define:
197+ x = x
198+ y = y
199+ """
200+
201+ def __init__ (self , nx , ny , ng = 1 ,
202+ xmin = 0.0 , xmax = 1.0 , ymin = 0.0 , ymax = 1.0 ):
203+
204+ super ().__init__ (nx , ny , ng , xmin , xmax , ymin , ymax )
205+
206+ self .coord_type = 0
207+
208+ # Length of the side in x- and y-direction
209+
210+ self .Lx = ArrayIndexer (np .full ((self .qx , self .qy ), self .dx ),
211+ grid = self )
212+ self .Ly = ArrayIndexer (np .full ((self .qx , self .qy ), self .dy ),
213+ grid = self )
214+
215+ # This is area of the side that is perpendicular to x.
216+
217+ self .Ax = self .Ly
218+
219+ # This is area of the side that is perpendicular to y.
220+
221+ self .Ay = self .Lx
222+
223+ # Volume of the cell.
224+
225+ self .V = ArrayIndexer (np .full ((self .qx , self .qy ), self .dx * self .dy ),
226+ grid = self )
227+
228+ def __str__ (self ):
229+ """ print out some basic information about the grid object """
230+ return f"Cartesian 2D Grid: xmin = { self .xmin } , xmax = { self .xmax } , " + \
231+ f"ymin = { self .ymin } , ymax = { self .ymax } , " + \
232+ f"nx = { self .nx } , ny = { self .ny } , ng = { self .ng } "
233+
234+
235+ class SphericalPolar (Grid2d ):
236+ """
237+ This class defines a spherical polar grid.
238+ This is technically a 2D geometry but assumes azimuthal symmetry.
239+
240+ Define:
241+ r = x
242+ theta = y
243+ """
244+
245+ def __init__ (self , nx , ny , ng = 1 ,
246+ xmin = 0.2 , xmax = 1.0 , ymin = 0.0 , ymax = 1.0 ):
247+
248+ # Make sure theta is within [0, PI]
249+ assert ymin >= 0.0 and ymax <= np .pi , "y or \u03b8 should be within [0, \u03c0 ]."
250+
251+ # Make sure the ghost cells doesn't extend out negative x(r)
252+ assert xmin - ng * (xmax - xmin )/ nx >= 0.0 , \
253+ "xmin (r-direction), must be large enough so ghost cell doesn't have negative x."
254+
255+ super ().__init__ (nx , ny , ng , xmin , xmax , ymin , ymax )
256+
257+ self .coord_type = 1
258+
259+ # Length of the side along r-direction, dr
260+
261+ self .Lx = ArrayIndexer (np .full ((self .qx , self .qy ), self .dx ),
262+ grid = self )
263+
264+ # Length of the side along theta-direction, r*dtheta
265+
266+ self .Ly = ArrayIndexer (np .full ((self .qx , self .qy ), self .x2d * self .dy ),
267+ grid = self )
268+
269+ # Returns an array of the face area that points in the r(x) direction.
270+ # dL_theta x dL_phi = r^2 * sin(theta) * dtheta * dphi
271+
272+ # dAr_l = - r{i-1/2}^2 * 2pi * cos(theta{i+1/2}) - cos(theta{i-1/2})
273+ self .Ax = np .abs (- 2.0 * np .pi * self .xl2d ** 2 *
274+ (np .cos (self .yr2d ) - np .cos (self .yl2d )))
275+
276+ # Returns an array of the face area that points in the theta(y) direction.
277+ # dL_phi x dL_r = dr * r * sin(theta) * dphi
278+
279+ # dAtheta_l = pi * sin(theta{i-1/2}) * (r{i+1/2}^2 - r{i-1/2}^2)
280+ self .Ay = np .abs (np .pi * np .sin (self .yl2d ) *
281+ (self .xr2d ** 2 - self .xl2d ** 2 ))
282+
283+ # Returns an array of the volume of each cell.
284+ # dV = dL_r * dL_theta * dL_phi
285+ # = (dr) * (r * dtheta) * (r * sin(theta) * dphi)
286+ # dV = - 2*np.pi / 3 * (cos(theta{i+1/2}) - cos(theta{i-1/2})) * (r{i+1/2}^3 - r{i-1/2}^3)
287+
288+ self .V = np .abs (- 2.0 * np .pi / 3.0 *
289+ (np .cos (self .yr2d ) - np .cos (self .yl2d )) *
290+ (self .xr2d - self .xl2d ) *
291+ (self .xr2d ** 2 + self .xl2d ** 2 + self .xr2d * self .xl2d ))
292+
293+ def __str__ (self ):
294+ """ print out some basic information about the grid object """
295+ return "Spherical Polar 2D Grid: Define x : r, y : \u03b8 . " + \
296+ f"xmin (r) = { self .xmin } , xmax= { self .xmax } , " + \
297+ f"ymin = { self .ymin } , ymax = { self .ymax } , " + \
298+ f"nx = { self .nx } , ny = { self .ny } , ng = { self .ng } "
299+
300+
189301class CellCenterData2d :
190302 """
191303 A class to define cell-centered data that lives on a grid. A
0 commit comments