Skip to content

warn if calculate_total_face_area() too large; add FESOM areas regression test - #1649

Open
Sevans711 wants to merge 3 commits into
mainfrom
sevans/area-error-checks
Open

warn if calculate_total_face_area() too large; add FESOM areas regression test#1649
Sevans711 wants to merge 3 commits into
mainfrom
sevans/area-error-checks

Conversation

@Sevans711

Copy link
Copy Markdown
Collaborator

Closes #425

Overview

As discussed in thread in #425, the issue initially reported there has since been fixed by other changes. This PR adds a regression test (ensuring the total area for this FESOM grid is close to ~8.38 sr).

It also adds a warning to calculate_total_face_areas() if the result is larger than the total area of the sphere, to avoid silently returning wrong answers on malformed grids. It also updates the docstring for that function to clarify the warning might be raised.

Finally, a slight addition beyond just solving 425: updates the calculate_total_face_areas() docstring to clarify the actual behavior: it is not actually always equivalent to compute_face_areas().sum(). Specifically, for HEALPix grids, when using default values for all arguments, it is equivalent to face_areas.sum() (which respects HEALPix equal areas) instead.

Did not add any CI tests for this warning… please let me know if you think a regression test is necessary for it. Tested locally by temporarily locally adding result = result * 1.5 near the end of calculate_total_face_areas(), to ensure bad results actually lead to raising warning and failing FESOM area regression test.

PR Checklist

General

  • An issue is created and linked
  • Added appropriate labels (if your uxarray repo permissions allow it)
  • Filled out Overview and Expected Usage (if applicable) sections

Testing & Benchmarking

  • [N/A] Adequate tests are created if there is new functionality
  • Tests are not too basic (such as simply calling a function and nothing else)
  • Tests cover all major paths in your new functions
  • [N/A] If this PR could affect performance, ran ASV benchmarks and confirmed they show expected behavior (add a new benchmark if necessary)

Documentation

  • [N/A] Docstrings have been added to all new functions
  • Docstrings have been updated with any function changes
  • [N/A] User (public) functions have been added to docs/api.rst
  • [N/A] Internal (private) function names start with an underscore (_)

@Sevans711 Sevans711 added the testing Test Cases label Aug 5, 2026
Comment thread uxarray/grid/grid.py
Comment on lines +2004 to +2005
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):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to also check if result < ... * (1 - RTOL)?

@Sevans711 Sevans711 Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That check would be like asking "is the total area less than the sphere's surface area?", right?

I wouldn't want a check like that because grids are always free to only cover a smaller region or have holes (e.g., see example in discussion of originally-linked issue).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. What I mean is that depending on how you approximate the sphere, you may be able to say something about the bounds, so it could be the case that this approximation is strictly larger than the sphere's total area. But if not, we should have tolerance on the lower bound also. But yeah, if we're not worried about preserving area on the lower bound, then we don't need to worry about it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we aren't worried about the lower bound here, I'm mostly understanding the upper bound warning as a quick way to flag the possibility of a malformed grid.

Yeah. What I mean is that depending on how you approximate the sphere, you may be able to say something about the bounds, so it could be the case that this approximation is strictly larger than the sphere's total area. But if not, we should have tolerance on the lower bound also.

I'm not sure what this means, could you clarify a bit further (if still relevant, assuming you agree it is okay to not check a lower bound)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So like, consider if you were trying to build a grid on the inside surface of the sphere, by placing nodes on the sphere. The area would approximate the sphere's area, but it would inherently be slightly smaller because it's strictly inside. In that case you'd expect the approximate area to be within (1 - RTOL) * sphere area. If we put faces tangent to the sphere, you'd have the opposite situation because the nodes are inherently outside of the sphere. What I'm getting at is depending on the method, you could have some mix of the two, or maybe you have some other way of knowing if the grid area is supposed to be strictly larger or smaller than the sphere.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, thank you, that helped me understand. I think that could be good to consider in the future, but isn't as relevant here. Here, maybe a clearer way to phrase the intention of the check would be to write something like:

full_sphere_area = 4 * np.pi * self.sphere_radius**2
assert (result < full_sphere_area) or np.isclose(result, full_sphere_area, rtol=RTOL)

I.e., the result is definitely small enough (less than full sphere area) or maybe this is a grid that covers the whole sphere (but account for possible rounding errors in calculations). Right now I am planning to keep the underlying code unchanged, but please let me know if you would want to see it rewritten or maybe with an extra comment added to clarify. (Note, the docstring does already include: Additionally, raises a warning if the result is larger than the total area of a sphere (4 * pi * self.sphere_radius**2).)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Test Cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error checks for area calculation

2 participants