Repository navigation
Require the PCD Earth radius for spherical meshes - #547
Conversation
TestingCTests on Chrysalis with Intel and OpenMPI, Release, built from All 49 tests pass. With the previous Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly. |
TestingI ran the Polaris 23 of 24 tasks pass and are bit for bit with the baseline, including the spherical Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly. |
|
@brian-oneill, it looks like you are the author of |
mwarusz
left a comment
There was a problem hiding this comment.
Looks good, but I have a few comments.
| cos(LatEdge(IEdge)) * cos(Pi * TSim / Tau); | ||
| const R8 normalVel = REarth * (u * cos(AngleEdge(IEdge)) + | ||
| v * sin(AngleEdge(IEdge))); | ||
| const R8 normalVel = SphereRadius * (u * cos(AngleEdge(IEdge)) + |
There was a problem hiding this comment.
If we require REarth to be very close to HorzMesh.SphereRadius why not do the opposite, i.e. use REarth everywhere in the code. REarth is simpler to get, since it is a global constant.
There was a problem hiding this comment.
Agreed. With the check at 1e-8 the mesh value adds nothing, so cc31158 uses REarth in the operators, the prescribed velocities and the test setups. The coupled driver still reads HMesh->SphereRadius; I left it since it is outside this PR.
Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly.
There was a problem hiding this comment.
The coupled driver still reads HMesh->SphereRadius; I left it since it is outside this PR.
@andrewdnolan, perhaps consider whether this should be changed as well.
| // scalarB is differentiated by the tracer diffusion test, so it must be | ||
| // smooth on the sphere: cos(Lon)*cos(Lat)*sin(Lat) = x*z/R^2 vanishes at | ||
| // the poles, whereas cos(Lon)*sin(Lat) has no limit there and makes the | ||
| // exact diffusion at a polar cell depend on the arbitrary longitude of | ||
| // that cell's center. |
There was a problem hiding this comment.
LLM comment talking about what the code used to do. Please rephrase or remove it. Every test field defined in this file was always supposed to be smooth.
| if (std::abs((pcd::mean_radius - TmpRadius) / pcd::mean_radius) > | ||
| RadiusRelTol) | ||
| ABORT_ERROR("Input mesh sphere radius {} does not match the Earth " | ||
| "radius {} from the Physical Constants Dictionary " | ||
| "(relative tolerance {})", | ||
| TmpRadius, pcd::mean_radius, RadiusRelTol); |
There was a problem hiding this comment.
This is a very minor suggestion, but I think we should get in the habit of stating requirements using OMEGA_REQUIRE.
| if (std::abs((pcd::mean_radius - TmpRadius) / pcd::mean_radius) > | |
| RadiusRelTol) | |
| ABORT_ERROR("Input mesh sphere radius {} does not match the Earth " | |
| "radius {} from the Physical Constants Dictionary " | |
| "(relative tolerance {})", | |
| TmpRadius, pcd::mean_radius, RadiusRelTol); | |
| OMEGA_REQUIRE(std::abs((pcd::mean_radius - TmpRadius) / pcd::mean_radius) < | |
| RadiusRelTol, | |
| "Input mesh sphere radius {} does not match the Earth " | |
| "radius {} from the Physical Constants Dictionary " | |
| "(relative tolerance {})", | |
| TmpRadius, pcd::mean_radius, RadiusRelTol); |
TestingI ran the Polaris All 23 tasks pass and are bit-for-bit with the Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly. |
|
And @mwarusz, thanks very much for your review! |
| - [Global Mesh](https://web.lcrc.anl.gov/public/e3sm/polaris/ocean/omega_ctest/cosine_bell_icos480.omega_vars.260807.nc) | ||
| - [Planar Mesh](https://web.lcrc.anl.gov/public/e3sm/polaris/ocean/omega_ctest/PlanarPeriodic48x48.omega_vars.260720.nc) | ||
| - [Global Mesh](https://web.lcrc.anl.gov/public/e3sm/polaris/ocean/omega_ctest/cosine_bell_icos480.omega_vars.260911.nc) | ||
| - [Planar Mesh](https://web.lcrc.anl.gov/public/e3sm/polaris/ocean/omega_ctest/PlanarPeriodic48x48.omega_vars.260825.nc) |
There was a problem hiding this comment.
It seems that this PR also updates the planar test mesh with vector reconstruction weights. I'm not opposed to the change, but wanted to highlight it for others, since it isn't mentioned anywhere in the PR description. I was confused why this PR needs to update this mesh.
There was a problem hiding this comment.
The update here is merely that the update (already made and documented previously in Polaris) was somehow missing from the Omega. I will follow up with details.
There was a problem hiding this comment.
Good catch; the description now says so. The planar mesh itself is not new to this PR: omega_ctest.py has downloaded PlanarPeriodic48x48.omega_vars.260825.nc since E3SM-Project/polaris#721 (2026-08-26), which added the reconstruction weights, but the Omega quick start was not updated then. This PR only brings the link into line with what the utility already uses.
Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly.
TestingI ran the ctests successfully (using the new |
brian-oneill
left a comment
There was a problem hiding this comment.
The function I had initial used in TendencyTermsTest was chosen arbitrarily, so I'm fine with a more robust choice of test function. Everything here looks good to me. Approved.
|
Thanks @brian-oneill! I'll rebase to fix the conflict right now. |
SecondDerivativeOnCell and the prescribed nondivergent and divergent velocities used the REarth constant to scale spherical geometry, while the rest of the mesh geometry comes from the input file. Take the radius from HorzMesh::SphereRadius instead, so a single value describes the sphere the mesh lies on; HorzMesh checks it against REarth on read. DetermineSphericalPatchGeometry now receives the radius as an argument, and the unit test that projects a synthetic hexagonal patch onto a sphere passes REarth explicitly, since it builds its own sphere and also runs on the planar mesh. Also correct the comment on the divergent-flow period (12 days, not 14). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The spherical test setups evaluated their analytic fields with REarth while the mesh they compared against could lie on a slightly different sphere; the CTest icosahedral mesh was 3.3e-5 larger, which contributed a systematic error of that size to every spherical operator test. Read the radius from the default HorzMesh instead, which resolves the long-standing TODO in three of the setups. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
HorzMeshTest verified that cell centers are equidistant from the origin but never compared that distance with the SphereRadius attribute read from the file, nor with the REarth constant the model assumes. Add both checks, with a tolerance that follows the build precision since the coordinates are stored as Real. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The relative tolerance on the input mesh's sphere radius was 1e-4 so that the CTest icosahedral mesh, generated with an older Earth radius, would still load. That mesh has been regenerated on the sphere of the Physical Constants Dictionary, so require agreement to 1e-8. Compare the file value with pcd::mean_radius in double precision, before the cast to Real, so that a single-precision build applies the same test. Closes E3SM-Project#346 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TestSetupSphere::scalarB was 2 + cos(Lon) sin(Lat), which has no limit at the poles: its value there depends on the direction of approach. The tracer diffusion test differentiates it, so the exact tendency at a polar cell depended on the arbitrary longitude assigned to that cell's center, through a term 2 cos^3(Lon)/R. On the old CTest mesh the polar pentagons happened to sit near Lon = 58 and 257 degrees, where the term is small (LInf 0.049); on the regenerated mesh they sit near 20 and 191 degrees and the LInf error rose to 0.235, all of it in those two cells. Use 2 + cos(Lon) cos(Lat) sin(Lat) = 2 + x z / R^2 instead, which is smooth on the sphere, and update the exact divergence accordingly. The error is then 0.0156 on either mesh, with its maximum at 30 degrees latitude as ordinary truncation error. The other uses of scalarB on the sphere are pointwise at edges, away from the poles, and unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The icosahedral CTest mesh, cosine_bell_icos480.omega_vars.260911.nc, was regenerated by Polaris on the sphere with the Physical Constants Dictionary radius. The mesh has the same connectivity as before but JIGSAW places the cells up to 7e-4 (relative) differently, and the analytic test fields are now evaluated with the mesh radius, so the error norms of the spherical operator, auxiliary variable, tendency and forcing tests move by up to a few tenths of a percent (2 percent for those with a radius-scaled analytic solution). Record the new values. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The MPAS mesh page said there was no requirement on the sphere radius, which has not been true since the model started checking it. State that spherical meshes must use the Physical Constants Dictionary Earth radius, and point to the Polaris converter for older MPAS-Ocean meshes. Mention the check on the horizontal mesh page, and update the quick start links to the regenerated icosahedral mesh and the current planar mesh. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With the input mesh now required to lie on the sphere of radius REarth to 1e-8, carrying HorzMesh::SphereRadius into SecondDerivativeOnCell, the prescribed velocities and the test setups adds plumbing without adding information. Use the REarth constant directly, as suggested in review. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The FCT low-order flux test built its reference solution from a single hardcoded edge length per geometry, 0.012028130608117 on the plane and 277371 m on the sphere. The spherical value was the mean dvEdge of an earlier icosahedral CTest mesh, so the test measured how far each edge departs from that mean and its expected errors had to be re-derived whenever the mesh changed. Use Mesh->DvEdge instead. The low-order flux of a uniform tracer is then exactly DvEdge times the normal velocity, and the expected errors are zero on both meshes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The spherical FCT test advects with a constant lon/lat velocity, so the provisional layer thickness error is dt |div u| = 3 dt tan(lat) / R and scales with 1/R. On the regenerated icosahedral CTest mesh, with the Physical Constants Dictionary radius, the L2 errors of the provisional thickness and its inverse rise by 2.6e-5 relative (3.3e-5 from the radius alone) and the LInf errors by 1e-5 to 7e-5. Record the new values. The FCTHNewInv check still yields inf on every mesh; that is separate from the mesh change and left alone here. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
427f0cf to
1a564eb
Compare
|
Rebased onto TestingAll 50 CTests pass on Chrysalis with Intel and the Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly. |
|
I did a local merge and I'm seeing a bunch of CTest fails with gnugpu on pm-gpu: I don't see how these could be related to this PR. |
|
CTests on pm-cpu (gnu) pass and the omega_pr suite passes with both gnu and gnugpu on pm-cpu/pm-gpu. Polaris
|
|
@sbrus89 That abort is a mesh file Omega could not read, not the radius check this PR tightens.
You do separately need E3SM-Project/polaris#779 for Worth checking both, so that relinking the mesh does not just leave you on the IO failure. pm-gpu, gnugpu, mpichWith polaris#779 and this branch at 1a564eb: Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly. |
|
Yep, I was testing multiple things at a time and forgot to link the meshes for this one. CTests pass on pm-gpu (gnugpu) Thanks @xylar. |
|
Passes |
Require the sphere radius of a spherical input mesh to match the Physical Constants Dictionary Earth radius to a relative 1e-8 instead of 1e-4, now that the icosahedral CTest mesh has been regenerated on that sphere. Fix a spherical test field that was singular at the poles, add a check in HorzMeshTest that the mesh coordinates, the sphere_radius attribute and REarth agree, and document the requirement.
Fixes #346.
Please review specifically:
scalarBin the spherical tracer diffusion test ofTendencyTermsTest(from Add tracer tendency terms and auxiliary variables #140, @brian-oneill) has no limit at the poles, so the exact tendency at a polar cell depended on that cell's arbitrary longitude; the regenerated mesh exposed this (LInf error 0.049 to 0.235, all of it in the two polar pentagons). The new field is smooth on the sphere and the error is 0.016 on either mesh (c25835d):pcd::mean_radiusin double precision before the cast toReal, so a single-precision build applies the same tolerance.The CTests need
cosine_bell_icos480.omega_vars.260911.ncasOmegaSphereMesh.nc; the companion Polaris PR E3SM-Project/polaris#779 pointsomega_ctest.pyat it. The quick start also now links the planar meshPlanarPeriodic48x48.omega_vars.260825.nc(the one with vector reconstruction weights) thatomega_ctest.pyhas downloaded since E3SM-Project/polaris#721; the Omega docs were not updated at the time. The expected error norms of the spherical tests are updated for the new mesh, which has the same connectivity as the old one but slightly different cell positions.Checklist
Documentation:
Linting
Building
Testing
chrysalis, intel, openmpi
chrysalis, gnu, openmpi
pm-cpu, gnu, mpich
pm-gpu, gnugpu, mpich
Provide relevant details in a comment to the PR titled
Testing🤖 Generated with Claude Code