Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion test/grid/grid/test_areas.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ def test_latlon_bounds_populate_bounds_MPAS(gridpath):
uxgrid = ux.open_grid(gridpath("mpas", "QU", "oQU480.231010.nc"))
bounds_xarray = uxgrid.bounds


def _sum_quadrature_jacobians(x, y, z, quadrature_rule, order):
"""Independently sum the Jacobian at each quadrature point of a triangle.

Expand Down Expand Up @@ -163,3 +162,10 @@ def test_calculate_face_area_jacobian_is_quadrature_sum(quadrature_rule, order):

assert jacobian > 0
nt.assert_allclose(jacobian, expected, rtol=1e-12)


def test_face_areas_fesom(gridpath):
"""Ensure correct total area for FESOM grid (~8.3780 sr). Regression test for #425."""
uxgrid = ux.open_grid(gridpath("ugrid", "fesom", "fesom.mesh.diag.nc"))
total_area = uxgrid.calculate_total_face_area()
nt.assert_almost_equal(total_area, 8.3780, decimal=4)
20 changes: 17 additions & 3 deletions uxarray/grid/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -1958,7 +1958,12 @@ def calculate_total_face_area(
"""Calculate the total surface area of all the faces in a mesh.

Equivalent to ``self.compute_face_areas(...).sum()``; provided as a
convenience.
convenience. (Note: for HEALPix grids, when called with default arguments,
this method actually returns ``self.face_areas.sum()`` instead,
which respects HEALPix equal-area property.)

Additionally, raises a warning if the result is larger than
the total area of a sphere (4 * pi * self.sphere_radius**2).

Parameters
----------
Expand Down Expand Up @@ -1986,16 +1991,25 @@ def calculate_total_face_area(
and order == 4
and not latitude_adjusted_area
):
return np.sum(self.face_areas.values)
result = np.sum(self.face_areas.values)
Comment thread
dylannelson marked this conversation as resolved.

return np.sum(
result = np.sum(
self.compute_face_areas(
quadrature_rule=quadrature_rule,
order=order,
latitude_adjusted_area=latitude_adjusted_area,
)
)

RTOL = 1e-6 # 1e-7 had warnings in existing CI tests (as of 2026-08-05), 1e-6 did not.
if result > 4 * np.pi * self.sphere_radius**2 * (1 + RTOL):
Comment thread
cmdupuis3 marked this conversation as resolved.
warnings.warn(
f"Total face area (={result}) exceeds the surface area of the whole sphere "
f"(={4 * np.pi * self.sphere_radius**2}) (with sphere_radius={self.sphere_radius}).",
)

return result

def compute_face_areas(
self,
quadrature_rule: str = "triangular",
Expand Down