Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declare constants at the native precision of MPAS #1282

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

kuanchihwang
Copy link
Contributor

@kuanchihwang kuanchihwang commented Jan 28, 2025

When building MPAS as a dynamical core, certain constants in the mpas_constants module are imported from the physconst module, which is a part of CAM/CAM-SIMA. However, multiple issues arise if the precision of those constants differs from MPAS.

For example, building MPAS in single precision mode with CAM-SIMA fails due to multiple occurrences of type mismatch between actual and dummy arguments.

mpas_geometry_utils.F:885:157:

  885 |          call mpas_log_write('$r', MPAS_LOG_ERR, realArgs=(/mpas_triangle_signed_area_sphere(a,b,c,sphereRadius) - pii/2.0_RKIND*sphereRadius*sphereRadius/))
      |                                                                                                                                                             1
Error: Type mismatch in argument 'realargs' at (1); passed REAL(8) to REAL(4)

Here, pii is declared by CAM-SIMA to be double precision, and it causes unintended floating-point promotion in the expression.

The solution is to ensure that constants in the mpas_constants module are declared at the native precision of MPAS. Note that CAM does not support running MPAS in single precision mode at all, so the above build error cannot be reproduced.

In addition, some best practices of modern Fortran have been implemented.

For stand-alone MPAS, the compiled executables stay bitwise identical, with or without this PR. No further tests are needed. For CAM/CAM-SIMA, it generates bitwise identical model results, with or without this PR. Additionally for CAM-SIMA, its regression tests all pass, indicating identical model results to the previous baseline.

When building MPAS as a dycore, certain constants in the `mpas_constants` module are
imported from the `physconst` module, which is a part of CAM/CAM-SIMA. However,
multiple issues arise if the precision of those constants differs from MPAS.

For example, building MPAS in single precision mode with CAM-SIMA fails due to
multiple occurrences of type mismatch between actual and dummy arguments.

mpas_geometry_utils.F:885:157:

  885 |          call mpas_log_write('$r', MPAS_LOG_ERR, realArgs=(/mpas_triangle_signed_area_sphere(a,b,c,sphereRadius) - pii/2.0_RKIND*sphereRadius*sphereRadius/))
      |                                                                                                                                                             1
Error: Type mismatch in argument 'realargs' at (1); passed REAL(8) to REAL(4)

Here, `pii` is declared by CAM-SIMA to be double precision, and it causes unintended
floating-point promotion in the expression.

The solution is to ensure that constants in the `mpas_constants` module are declared
at the native precision of MPAS.
Enforce `implicit none` at the module level so it applies everywhere
within. It is also a best practice in Fortran.
…e level

A blanket `use` statement imports all public entities from that module.
For the case here, it causes namespace pollution at the module level. Also,
it is difficult to tell where the imported entities come from.

Therefore, `use` statements should always include the `only` option. It is
also a best practice in Fortran.
It is a best practice in Fortran to always specify the accessibility of
module variables (as well as procedures).

For the case here, `RKIND` is imported from `mpas_kind_types`. Due to
the lack of accessibility attributes, other modules that
`use mpas_constants` also have access to `RKIND`.

Therefore, avoid causing unexpected namespace pollution to other
modules by specifying accessibility attributes.
implicit none

public
private :: RKIND
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a significance for this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this question might also be answered by the commit message, quoted below:

It is a best practice in Fortran to always specify the accessibility of module variables (as well as procedures).

For the case here, RKIND is imported from mpas_kind_types. Due to the lack of accessibility attributes, other modules that use mpas_constants also have access to RKIND.

Therefore, avoid causing unexpected namespace pollution to other modules by specifying accessibility attributes.

@@ -51,15 +57,14 @@ module mpas_constants

contains


Copy link
Collaborator

Choose a reason for hiding this comment

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

We may want this newline preserved I think

@@ -74,9 +79,25 @@ module mpas_constants
!-----------------------------------------------------------------------
subroutine mpas_constants_compute_derived()

implicit none

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a specific reason for removing the implicit none here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looking at the commit history, my question is answered

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, implicit none has been moved to the module level so it applies everywhere within.

Copy link
Collaborator

@abishekg7 abishekg7 left a comment

Choose a reason for hiding this comment

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

Overall looks good. I did have a few comments and question though.

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

Successfully merging this pull request may close these issues.

3 participants