@@ -305,6 +305,12 @@ def integrate_midpoints(self, variable, *, dims=None):
305305 """
306306 ds = self .data
307307
308+ if isinstance (variable , str ):
309+ variable = ds [variable ]
310+
311+ location = variable .cell_location
312+ suffix = "" if location == "CELL_CENTRE" else f"_{ location } "
313+
308314 tcoord = ds .metadata ["bout_tdim" ]
309315 xcoord = ds .metadata ["bout_xdim" ]
310316 ycoord = ds .metadata ["bout_ydim" ]
@@ -331,55 +337,61 @@ def integrate_midpoints(self, variable, *, dims=None):
331337 elif isinstance (dims , str ):
332338 dims = [dims ]
333339
334- dx = ds ["dx" ]
335- dy = ds ["dy" ]
340+ dx = ds [f "dx{ suffix } " ]
341+ dy = ds [f "dy{ suffix } " ]
336342 dz = ds .metadata ["dz" ]
337343
338344 # Work out the spatial volume element
339345 if xcoord in dims and ycoord in dims and zcoord in dims :
340346 # Volume integral, use the 3d Jacobian "J"
341- spatial_volume_element = ds ["J " ] * dx * dy * dz
347+ spatial_volume_element = ds [f"J { suffix } " ] * dx * dy * dz
342348 elif xcoord in dims and ycoord in dims :
343349 # 2d integral on poloidal planes
344- if ds [ variable ] .direction_y == "Standard" :
350+ if variable .direction_y == "Standard" :
345351 # Need to use a metric constructed from basis vectors within the
346352 # poloidal plane, so use 'reciprocal basis vectors' Grad(x^i)
347353 # J = 1/sqrt(det(g_2d))
348354 # det(g_2d) = g11*g22 - g12**2
349- g = ds ["g11" ] * ds ["g22" ] - ds ["g12" ] ** 2
355+ g = ds [f "g11{ suffix } " ] * ds [f "g22{ suffix } " ] - ds [f "g12{ suffix } " ] ** 2
350356 J = 1.0 / np .sqrt (g )
351- elif ds [ variable ] .direction_y == "Aligned" :
357+ elif variable .direction_y == "Aligned" :
352358 # Need to work out area element from metric coefficients. See book by
353359 # D'haeseleer, Hitchon, Callen and Shohet eq. (2.5.51).
354360 # Need to use a metric constructed from basis vectors within the
355361 # field-aligned x-y plane, so use 'tangent basis vectors' e_i
356362 # J = sqrt(g_11*g_22 - g_12**2)
357- J = np .sqrt (ds ["g_11" ] * ds ["g_22" ] - ds ["g_12" ] ** 2 )
363+ J = np .sqrt (
364+ ds [f"g_11{ suffix } " ] * ds [f"g_22{ suffix } " ] - ds [f"g_12{ suffix } " ] ** 2
365+ )
358366 spatial_volume_element = J * dx * dy
359367 elif xcoord in dims and zcoord in dims :
360368 # 2d integral on toroidal planes
361369 # Need to work out area element from metric coefficients. See book by
362370 # D'haeseleer, Hitchon, Callen and Shohet eq. (2.5.51)
363371 # J = sqrt(g_11*g_33 - g_13**2)
364- J = np .sqrt (ds ["g_11" ] * ds ["g_33" ] - ds ["g_13" ] ** 2 )
372+ J = np .sqrt (
373+ ds [f"g_11{ suffix } " ] * ds [f"g_33{ suffix } " ] - ds [f"g_13{ suffix } " ] ** 2
374+ )
365375 spatial_volume_element = J * dx * dz
366376 elif ycoord in dims and zcoord in dims :
367377 # 2d integral on flux-surfaces
368378 # Need to work out area element from metric coefficients. See book by
369379 # D'haeseleer, Hitchon, Callen and Shohet eq. (2.5.51)
370380 # J = sqrt(g_22*g_33 - g_23**2)
371- J = np .sqrt (ds ["g_22" ] * ds ["g_33" ] - ds ["g_23" ] ** 2 )
381+ J = np .sqrt (
382+ ds [f"g_22{ suffix } " ] * ds [f"g_33{ suffix } " ] - ds [f"g_23{ suffix } " ] ** 2
383+ )
372384 spatial_volume_element = J * dy * dz
373385 elif xcoord in dims :
374- if ds [ variable ] .direction_y == "Aligned" :
386+ if variable .direction_y == "Aligned" :
375387 raise ValueError (
376388 "Variable is field-aligned, but radial integral along coordinate "
377389 "line in globally field-aligned coordinates not supported"
378390 )
379391 # 1d radial integral, line element is sqrt(g_11)*dx
380- spatial_volume_element = np .sqrt (ds ["g_11" ]) * dx
392+ spatial_volume_element = np .sqrt (ds [f "g_11{ suffix } " ]) * dx
381393 elif ycoord in dims :
382- if ds [ variable ] .direction_y == "Standard" :
394+ if variable .direction_y == "Standard" :
383395 # Poloidal integral, line element is e_y projected onto a unit vector in
384396 # the poloidal direction. e_z is in the toroidal direction and Grad(x)
385397 # is orthogonal to flux surfaces, so their cross product is in the
@@ -398,34 +410,35 @@ def integrate_midpoints(self, variable, *, dims=None):
398410 # For 'orthogonal' coordinates (radial and poloidal directions are
399411 # orthogonal) this is equal to 1/sqrt(g22)
400412 spatial_volume_element = (
401- (ds ["g_22" ] * ds ["g_33" ] - ds ["g_23" ] ** 2 )
402- / (ds ["J" ] * np .sqrt (ds ["g11" ] * ds ["g_33" ]))
413+ (
414+ ds [f"g_22{ suffix } " ] * ds [f"g_33{ suffix } " ]
415+ - ds [f"g_23{ suffix } " ] ** 2
416+ )
417+ / (
418+ ds [f"J{ suffix } " ]
419+ * np .sqrt (ds [f"g11{ suffix } " ] * ds [f"g_33{ suffix } " ])
420+ )
403421 * dy
404422 )
405- elif ds [ variable ] .direction_y == "Aligned" :
423+ elif variable .direction_y == "Aligned" :
406424 # Parallel integral, line element is sqrt(g_22)*dy
407- spatial_volume_element = np .sqrt (ds ["g_22" ]) * dy
425+ spatial_volume_element = np .sqrt (ds [f "g_22{ suffix } " ]) * dy
408426 elif zcoord in dims :
409427 # Toroidal integral, line element is sqrt(g_33)*dz
410- spatial_volume_element = np .sqrt (ds ["g_33" ]) * dz
428+ spatial_volume_element = np .sqrt (ds [f "g_33{ suffix } " ]) * dz
411429 else :
412430 # No spatial integral
413431 spatial_volume_element = 1.0
414432
415- if isinstance (variable , xr .DataArray ):
416- integrand = variable
417- else :
418- integrand = ds [variable ]
419-
420433 spatial_dims = set (dims ) - set ([tcoord ])
421434
422435 # Need to check if the variable being integrated is a Field2D, which does not
423436 # have a z-dimension to sum over. Other variables are OK because metric
424437 # coefficients, dx and dy all have both x- and y-dimensions so variable would be
425438 # broadcast to include them if necessary
426- missing_z_sum = zcoord in dims and zcoord not in integrand .dims
439+ missing_z_sum = zcoord in dims and zcoord not in variable .dims
427440
428- integrand = integrand * spatial_volume_element
441+ integrand = variable * spatial_volume_element
429442
430443 integral = integrand .sum (dim = spatial_dims )
431444
0 commit comments