Skip to content

sima0_13_002: Refactor vertical coordinate computation in MPAS dynamical core#456

Merged
kuanchihwang merged 10 commits intoESCOMP:developmentfrom
kuanchihwang:staging/mpas-dycore-refactor-height
Mar 27, 2026
Merged

sima0_13_002: Refactor vertical coordinate computation in MPAS dynamical core#456
kuanchihwang merged 10 commits intoESCOMP:developmentfrom
kuanchihwang:staging/mpas-dycore-refactor-height

Conversation

@kuanchihwang
Copy link
Copy Markdown
Collaborator

@kuanchihwang kuanchihwang commented Dec 23, 2025

Tag name (required for release branches):

sima0_13_002

Originator(s):

kuanchihwang

Descriptions (include the issue title, and the keyword ['closes', 'fixes', 'resolves'] followed by the issue number):

MPAS dynamical core uses height, denoted by $\zeta$, as the vertical coordinate system. In CAM-SIMA, the coordinate values are computed in the interface layer of MPAS dynamical core for history and physics initialization.

However, it can be argued that the vertical coordinate system should be considered an implementation detail of MPAS dynamical core, and that it should not concern CAM-SIMA. See Appendix "C.2 Vertical grid" in MPAS user guide for more information.

This PR refactors and relocates vertical coordinate computation to the subdriver layer of MPAS dynamical core. Now, CAM-SIMA just calls the appropriate procedures to get the coordinate values. Unit tests are added to ensure correctness.

This PR also ports a fix from CAM (ESCOMP/CAM#1095) to limit longitude values within the range of $[0, 2 \pi)$ according to MPAS mesh specifications.

Describe any changes made to the build system:

None

Describe any changes made to the namelist:

None

List any changes to the defaults for the input datasets (e.g., boundary datasets):

None

List all files eliminated and why:

None

List all files added and what they do:

None

List all existing files that have been modified, and describe the changes:

M       src/dynamics/mpas/driver/dyn_mpas_procedures.F90
  * Implement standardized procedures for computing vertical coordinates
M       src/dynamics/mpas/driver/dyn_mpas_subdriver.F90
  * Allow selective queries to mesh dimensions
  * Limit longitude values within the range of [0, 2 * pi)
M       src/dynamics/mpas/dyn_grid_impl.F90
  * Refactor reference height computation in terms of standardized procedures
M       src/dynamics/mpas/tests/unit/test_dyn_mpas_procedures.pf
  * Implement unit tests

Regression tests:

SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho (Overall: DIFF)
SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_intel.cam-outfrq_kessler_mpas_derecho (Overall: DIFF)

Round-off errors due to limiting longitude values within the range of $[0, 2 \pi)$.

SMS_Ln9.ne3pg3_ne3pg3_mg37.FADIAB.derecho_gnu.cam-outfrq_se_cslam (Overall: FAIL)
SMS_Ln9.ne3pg3_ne3pg3_mg37.FKESSLER.derecho_intel.cam-outfrq_se_cslam_multitape (Overall: NLFAIL)

Known failing tests.

@kuanchihwang kuanchihwang marked this pull request as ready for review December 23, 2025 20:45
Copy link
Copy Markdown
Collaborator

@nusbaume nusbaume left a comment

Choose a reason for hiding this comment

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

Thanks @kuanchihwang!

@kuanchihwang kuanchihwang temporarily deployed to CI-tests-on-CIRRUS March 20, 2026 18:08 — with GitHub Actions Inactive
@nusbaume nusbaume requested a review from jimmielin March 23, 2026 17:27
Copy link
Copy Markdown
Member

@jimmielin jimmielin left a comment

Choose a reason for hiding this comment

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

Thanks @kuanchihwang! The PR looks good to me, I have two optional changes for your consideration.

Comment on lines +181 to +183
do k = 1, size(zw)
zw(k) = sum(dzw(1:k - 1))
end do
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a nitpick but maybe the cumulative sum could be constructed through the loop instead of calling sum for each k

Suggested change
do k = 1, size(zw)
zw(k) = sum(dzw(1:k - 1))
end do
zw(1) = 0.0_real32
do k = 2, size(zw)
zw(k) = zw(k - 1) + dzw(k - 1)
end do

same for the real64 variant. I think either construction is clear in intent and the performance difference would be minimal, so please feel free to ignore this.

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.

The suggested form of loop introduces read-after-write (RAW) dependency, which prevents vectorization. Intel compiler gives the following remark:

remark #15344: Loop was not vectorized: vector dependence prevents vectorization

However, I agree that the loop trip count is likely never large enough for this to matter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for testing! Sounds good.

Comment on lines +353 to +385
100.0_real32, &
200.0_real32, &
300.0_real32, &
400.0_real32, &
500.0_real32, &
600.0_real32, &
700.0_real32, &
800.0_real32, &
900.0_real32, &
1000.0_real32, &
1100.0_real32, &
1200.0_real32, &
1300.0_real32, &
1400.0_real32, &
1500.0_real32 &
]
real(real32), parameter :: expected_zw(*) = [ &
0.0_real32, &
100.0_real32, &
300.0_real32, &
600.0_real32, &
1000.0_real32, &
1500.0_real32, &
2100.0_real32, &
2800.0_real32, &
3600.0_real32, &
4500.0_real32, &
5500.0_real32, &
6600.0_real32, &
7800.0_real32, &
9100.0_real32, &
10500.0_real32, &
12000.0_real32 &
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks good, I wonder if making the dzw have more realistic numbers (not whole numbers, e.g., 55.1, 101.2, 202.3) would better exercise the ULP tolerance?

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.

Unit tests can be seen as a form of code documentation. I chose whole numbers here because they are easier to grasp for humans. People can just glance at the code and quickly understand what it is supposed to do without a calculator in hand.

@kuanchihwang kuanchihwang temporarily deployed to CI-tests-on-CIRRUS March 27, 2026 16:52 — with GitHub Actions Inactive
@kuanchihwang kuanchihwang changed the title Refactor vertical coordinate computation in MPAS dynamical core sima0_13_002: Refactor vertical coordinate computation in MPAS dynamical core Mar 27, 2026
@kuanchihwang kuanchihwang merged commit f9e9d23 into ESCOMP:development Mar 27, 2026
19 checks passed
@kuanchihwang kuanchihwang deleted the staging/mpas-dycore-refactor-height branch March 27, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants