Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
path = src/dynamics/mpas/dycore
url = https://github.com/MPAS-Dev/MPAS-Model.git
fxsparse = ../.mpas_sparse_checkout
fxtag = v8.3.1
fxtag = v8.4.0
fxrequired = AlwaysRequired
fxDONOTUSEurl = https://github.com/MPAS-Dev/MPAS-Model.git
[submodule "ncar-physics"]
Expand Down
45 changes: 45 additions & 0 deletions src/dynamics/mpas/assets/0001-Fix-Fortran-standard-violation.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
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.

Just double-checking that these three patch files won't be needed once MPAS PR MPAS-Dev/MPAS-Model#1448 has been merged?

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.

Yes, once that PR is merged and MPAS gets the next tag, we can then update the git submodule in CAM-SIMA and delete those patches.

From: Kuan-Chih Wang <kuanchihw@ucar.edu>
Date: Tue, 21 Apr 2026 13:50:09 -0600
Subject: [PATCH] Fix Fortran standard violation due to pointer argument not
being associated

At line 1970, if the `DO_PHYSICS` macro is undefined, the `diag_physics` pointer
will not be initialized by the call to `mpas_pool_get_subpool`, and therefore
its pointer association status will remain undefined.

However, at line 2250, this pointer is used as an argument to call `atm_compute_dyn_tend`,
which constitutes a Fortran standard violation.

Quoted from Fortran 2023,

> 15.5.2.4 Argument association
> Except in references to intrinsic inquiry functions, a pointer actual argument that
> corresponds to a nonoptional nonpointer dummy argument shall be pointer associated with
> a target.

This bug can lead to a runtime crash for models that use MPAS as a dynamical core
(e.g., CAM, CAM-SIMA).

Fix this issue by adding the `pointer` attribute to the `diag_physics` dummy argument
for the `atm_compute_dyn_tend` subroutine.
---
src/core_atmosphere/dynamics/mpas_atm_time_integration.F | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core_atmosphere/dynamics/mpas_atm_time_integration.F b/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
index 238ca7235..c16072976 100644
--- a/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
+++ b/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
@@ -5813,7 +5813,7 @@ module atm_time_integration
type (mpas_pool_type), intent(in) :: state
type (mpas_pool_type), intent(in) :: diag
type (mpas_pool_type), intent(in) :: mesh
- type (mpas_pool_type), intent(in) :: diag_physics
+ type (mpas_pool_type), pointer, intent(in) :: diag_physics
type (mpas_pool_type), intent(in) :: configs
integer, intent(in) :: nVertLevels ! for allocating stack variables
integer, intent(in) :: rk_step, dynamics_substep
--
2.48.1

28 changes: 28 additions & 0 deletions src/dynamics/mpas/assets/0002-Add-missing-argument-intent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kuan-Chih Wang <kuanchihw@ucar.edu>
Date: Tue, 21 Apr 2026 14:35:05 -0600
Subject: [PATCH] Add missing argument intent

Throughout the `atm_compute_dyn_tend` subroutine, the `tend_physics` pointer
never changes its pointer association status. Add the missing `intent(in)`
attribute for better safety.
---
src/core_atmosphere/dynamics/mpas_atm_time_integration.F | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core_atmosphere/dynamics/mpas_atm_time_integration.F b/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
index c16072976..b6e620fe1 100644
--- a/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
+++ b/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
@@ -5809,7 +5809,7 @@ module atm_time_integration
! Dummy arguments
!
type (mpas_pool_type), intent(inout) :: tend
- type (mpas_pool_type), pointer :: tend_physics
+ type (mpas_pool_type), pointer, intent(in) :: tend_physics
type (mpas_pool_type), intent(in) :: state
type (mpas_pool_type), intent(in) :: diag
type (mpas_pool_type), intent(in) :: mesh
--
2.48.1

29 changes: 29 additions & 0 deletions src/dynamics/mpas/assets/0003-Avoid-implicit-save-attribute.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kuan-Chih Wang <kuanchihw@ucar.edu>
Date: Tue, 21 Apr 2026 14:49:58 -0600
Subject: [PATCH] Avoid implicit `save` attribute during variable declaration

In Fortran, explicit initialization of a variable implies the `save` attribute,
which may have surprising result and is not thread-safe.

Avoid doing it to conform to the Fortran best practices.
---
src/core_atmosphere/dynamics/mpas_atm_time_integration.F | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core_atmosphere/dynamics/mpas_atm_time_integration.F b/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
index b6e620fe1..227fbde86 100644
--- a/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
+++ b/src/core_atmosphere/dynamics/mpas_atm_time_integration.F
@@ -1918,7 +1918,7 @@ module atm_time_integration
type (mpas_pool_type), pointer :: diag_physics
type (mpas_pool_type), pointer :: mesh
type (mpas_pool_type), pointer :: tend
- type (mpas_pool_type), pointer :: tend_physics => null()
+ type (mpas_pool_type), pointer :: tend_physics
type (mpas_pool_type), pointer :: lbc ! regional_MPAS addition

real (kind=RKIND), dimension(:,:), pointer :: w
--
2.48.1

4 changes: 2 additions & 2 deletions src/dynamics/mpas/assets/Makefile.in.CESM
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export BUILD_TARGET := N/A
export CORE := atmosphere
export EXE_NAME := atmosphere_model
export GEN_F90 := false
export GIT_VERSION := $(shell git -C "$(MPAS_SRC_ROOT)" describe --always --dirty --tags || echo "N/A")
export GIT_VERSION := $(shell git -C "$(MPAS_SRC_ROOT)" describe --always --dirty --tags 2>/dev/null || echo "N/A")
export NAMELIST_SUFFIX := atmosphere

# Customize variables (e.g., build options) for use with CESM.
Expand Down Expand Up @@ -101,7 +101,7 @@ libmpas-prepare: libmpas-apply-patch libmpas-archiver-script.txt libmpas-preview
.PHONY: libmpas-apply-patch
libmpas-apply-patch:
@for file in *.patch; do \
if git apply --check -p2 "$${file}"; then \
if [ -f "$${file}" ] && git apply --check -p2 "$${file}" 1>/dev/null 2>&1; then \
echo "Applying $${file}"; \
git apply -p2 "$${file}"; \
fi; \
Expand Down
17 changes: 16 additions & 1 deletion src/dynamics/mpas/assets/generate_namelist_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'''

import argparse
import re
import textwrap
import xml.etree.ElementTree as ET

Expand All @@ -14,6 +15,7 @@
'assimilation',
'iau',
'limited_area',
'musica',
'physics',
'restart'
]
Expand Down Expand Up @@ -101,7 +103,7 @@ def parse_argument() -> argparse.Namespace:
default=None,
type=str,
required=False,
help='XML schema for CAM-SIMA namelist definition file.',
help='XML schema (i.e., entry_id_pg.xsd) for CAM-SIMA namelist definition file.',
dest='nml_xsd'
)

Expand Down Expand Up @@ -193,13 +195,21 @@ def translate_element_tree(reg_xml_et: ET.ElementTree) -> ET.ElementTree:
group_element.text = transform_name(namelist_group.attrib['name'].strip().lower())

# The `type` element.
# The `units` element.
# The `values` element and its containing `value` element.
type_text = namelist_option.attrib['type'].strip().lower()
if 'units' in namelist_option.attrib and namelist_option.attrib['units'].strip() not in ('', '-'):
# Filter out illegal characters in accordance with the `entry_id_pg.xsd` XML schema.
units_text = re.sub('[^-+A-Za-z0-9 ]', '', namelist_option.attrib['units'].strip())
else:
units_text = 'none'
value_text = namelist_option.attrib['default_value']

# Do some sanitization.
if type_text.startswith('ch'):
type_text = 'char*256'
# The units of a Fortran character variable is customarily 'none' in accordance with the ESM Standard Names.
units_text = 'none'
value_text = value_text.strip()

if not value_text.isascii():
Expand All @@ -209,6 +219,8 @@ def translate_element_tree(reg_xml_et: ET.ElementTree) -> ET.ElementTree:
value_text = canonicalize_int(value_text)
elif type_text.startswith('lo'):
type_text = 'logical'
# The units of a Fortran logical variable is customarily 'flag' in accordance with the ESM Standard Names.
units_text = 'flag'
value_text = value_text.strip().lower()

if value_text.startswith(('t', '.t')):
Expand All @@ -226,6 +238,9 @@ def translate_element_tree(reg_xml_et: ET.ElementTree) -> ET.ElementTree:
type_element = ET.SubElement(entry_element, 'type')
type_element.text = type_text

units_element = ET.SubElement(entry_element, 'units')
units_element.text = units_text

values_element = ET.SubElement(entry_element, 'values')

if entry_element.attrib['id'] in OVERRIDDEN_NAMELIST_OPTION:
Expand Down
Loading
Loading