Skip to content

Fix computation of angleEdge in NetCDF-C mesh converter #710

Merged
xylar merged 5 commits intoMPAS-Dev:masterfrom
xylar:fix-mesh-converter-angle-edge
Apr 3, 2026
Merged

Fix computation of angleEdge in NetCDF-C mesh converter #710
xylar merged 5 commits intoMPAS-Dev:masterfrom
xylar:fix-mesh-converter-angle-edge

Conversation

@xylar
Copy link
Copy Markdown
Collaborator

@xylar xylar commented Apr 1, 2026

The old spherical angleEdge calculation in MpasMeshConverter.x inferred the
edge angle from the latitude difference between edge vertices and then used a
sign correction based on a nearby artificial "north pole" point. This
approximation becomes inaccurate and unstable near the poles, where local
east/north directions are poorly represented by latitude differences.

This merge replaces that logic with a Cartesian geometric formulation:
compute the edge normal from the vertex chord and edge position on the
sphere, project it onto the local east/north basis at the edge, and
compute angleEdge with atan2. This matches the downstream Polaris
fix and gives robust spherical angles across the globe, including polar
regions.

This merge also adds mpas_tools.mesh.spherical with utilities to compute local east/north
vectors, edge-normal vectors, and recomputed spherical angleEdge values from
mesh geometry. These routines mirror the corrected spherical formulation used
for the C++ mesh converter and provide a reusable Python reference
implementation.

Finally, this merge adds a regression test to make sure a QU1920 mesh gets the same angleEdge from the python and C++ codes.

@xylar xylar requested a review from cbegeman April 1, 2026 10:48
@xylar xylar self-assigned this Apr 1, 2026
@xylar xylar added the bug label Apr 1, 2026
@xylar
Copy link
Copy Markdown
Collaborator Author

xylar commented Apr 1, 2026

See E3SM-Project/polaris#479 for more discussion of this issue.

@xylar xylar force-pushed the fix-mesh-converter-angle-edge branch from 945708e to 6a007f9 Compare April 1, 2026 11:18
@xylar xylar changed the title Fix mesh converter angle edge Fix computation of angleEdge in NetCDF-C mesh converter Apr 1, 2026
@xylar
Copy link
Copy Markdown
Collaborator Author

xylar commented Apr 1, 2026

@cbegeman, no rush on this but have a look when you can.

write_netcdf(dsMask, 'antarctic_mask.nc')


def test_conversion_angle_edge():
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Copy link
Copy Markdown
Contributor

@cbegeman cbegeman left a comment

Choose a reason for hiding this comment

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

Approving based on visual inspection. Did you test any meshes with finer resolutions than 1290km?

@xylar
Copy link
Copy Markdown
Collaborator Author

xylar commented Apr 2, 2026

No, I figured if it works for one mesh, it should work for all but happy to check something higher res before I merge.

xylar added 4 commits April 3, 2026 12:39
The old spherical `angleEdge` calculation in `MpasMeshConverter.x` inferred the
edge angle from the latitude difference between edge vertices and then used a
sign correction based on a nearby artificial "north pole" point. This
approximation becomes inaccurate and unstable near the poles, where local
east/north directions are poorly represented by latitude differences.

This merge replaces that logic with a Cartesian geometric formulation:
compute the edge normal from the vertex chord and edge position on the
sphere, project it onto the local east/north basis at the edge, and
compute `angleEdge` with `atan2`.  This matches the downstream Polaris
fix and gives robust spherical angles across the globe, including polar
regions.
Add `mpas_tools.mesh.spherical` with utilities to compute local east/north
vectors, edge-normal vectors, and recomputed spherical `angleEdge` values from
mesh geometry. These routines mirror the corrected spherical formulation used
for the C++ mesh converter and provide a reusable Python reference
implementation.
Add a conversion test that runs `MpasMeshConverter.x` on the low-resolution
QU test mesh, recomputes `angleEdge` in Python from spherical geometry, and
verifies the converted mesh agrees to tight tolerance. This gives us a
lightweight regression test for the polar `angleEdge` fix without introducing
a dedicated C++ unit-test harness.
@xylar xylar force-pushed the fix-mesh-converter-angle-edge branch from 6a007f9 to 9d2d739 Compare April 3, 2026 10:39
@xylar
Copy link
Copy Markdown
Collaborator Author

xylar commented Apr 3, 2026

@cbegeman, I tested this in a similar way (C++ vs. python) on an EC30to60 mesh, again without any problems.

I also added some fixes to the documentation I noticed when I was trying to install the conda package into my local pixi environment.

@xylar
Copy link
Copy Markdown
Collaborator Author

xylar commented Apr 3, 2026

Just a note to say that I emailed @mgduda and he agreed that we could proceed here without his input. They use a different tool (not in MPAS-Tools) to compute angleEdge but he'll check if this fix might be needed there, too.

@xylar xylar merged commit 1c837b3 into MPAS-Dev:master Apr 3, 2026
5 checks passed
@xylar xylar deleted the fix-mesh-converter-angle-edge branch April 3, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants