Skip to content

Commit 2ff0f64

Browse files
authored
Merge pull request #3446 from samsrabin/merge-master-20250822
Merge tag 'ctsm5.3.071' into merge-master-20250822
2 parents 58513d7 + 54cd9ec commit 2ff0f64

File tree

29 files changed

+833
-31
lines changed

29 files changed

+833
-31
lines changed

.gitmodules

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
[submodule "fates"]
2929
path = src/fates
3030
url = https://github.com/NGEET/fates
31-
fxtag = sci.1.84.0_api.40.0.0
31+
fxtag = sci.1.87.0_api.41.0.0
3232
fxrequired = AlwaysRequired
3333
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
3434
fxDONOTUSEurl = https://github.com/NGEET/fates
@@ -44,15 +44,15 @@ fxDONOTUSEurl = https://github.com/ESCOMP/CISM-wrapper
4444
[submodule "rtm"]
4545
path = components/rtm
4646
url = https://github.com/ESCOMP/RTM
47-
fxtag = rtm1_0_88
47+
fxtag = rtm1_0_89
4848
fxrequired = ToplevelRequired
4949
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
5050
fxDONOTUSEurl = https://github.com/ESCOMP/RTM
5151

5252
[submodule "mosart"]
5353
path = components/mosart
5454
url = https://github.com/ESCOMP/MOSART
55-
fxtag = mosart1.1.10
55+
fxtag = mosart1.1.12
5656
fxrequired = ToplevelRequired
5757
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
5858
fxDONOTUSEurl = https://github.com/ESCOMP/MOSART
@@ -76,15 +76,15 @@ fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git
7676
[submodule "cime"]
7777
path = cime
7878
url = https://github.com/ESMCI/cime
79-
fxtag = cime6.1.107
79+
fxtag = cime6.1.112
8080
fxrequired = ToplevelRequired
8181
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
8282
fxDONOTUSEurl = https://github.com/ESMCI/cime
8383

8484
[submodule "cmeps"]
8585
path = components/cmeps
8686
url = https://github.com/ESCOMP/CMEPS.git
87-
fxtag = cmeps1.1.2
87+
fxtag = cmeps1.1.5
8888
fxrequired = ToplevelRequired
8989
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
9090
fxDONOTUSEurl = https://github.com/ESCOMP/CMEPS.git

bld/CLMBuildNamelist.pm

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,8 @@ sub setup_cmdl_fates_mode {
811811
"flandusepftdat","use_fates_potentialveg","use_fates_lupft","fates_history_dimlevel",
812812
"use_fates_daylength_factor", "fates_photosynth_acclimation", "fates_stomatal_model",
813813
"fates_stomatal_assimilation", "fates_leafresp_model", "fates_cstarvation_model",
814-
"fates_regeneration_model", "fates_hydro_solver", "fates_radiation_model", "fates_electron_transport_model"
814+
"fates_regeneration_model", "fates_hydro_solver", "fates_radiation_model", "fates_electron_transport_model",
815+
"use_fates_managed_fire"
815816
);
816817

817818
# dis-allow fates specific namelist items with non-fates runs
@@ -4761,12 +4762,13 @@ sub setup_logic_fates {
47614762

47624763
if (&value_is_true( $nl_flags->{'use_fates'}) ) {
47634764
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'});
4764-
my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys",
4765+
my @list = ( "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys",
47654766
"use_fates_inventory_init","fates_seeddisp_cadence","fates_history_dimlevel",
47664767
"fates_harvest_mode","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage",
47674768
"use_fates_daylength_factor", "fates_photosynth_acclimation", "fates_stomatal_model",
47684769
"fates_stomatal_assimilation", "fates_leafresp_model", "fates_cstarvation_model",
4769-
"fates_regeneration_model", "fates_hydro_solver", "fates_radiation_model", "fates_electron_transport_model"
4770+
"fates_regeneration_model", "fates_hydro_solver", "fates_radiation_model", "fates_electron_transport_model",
4771+
"use_fates_managed_fire"
47704772
);
47714773

47724774
foreach my $var ( @list ) {
@@ -4786,6 +4788,9 @@ sub setup_logic_fates {
47864788
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_fixed_biogeog', 'use_fates'=>$nl_flags->{'use_fates'},
47874789
'use_fates_lupft'=>$nl->get_value('use_fates_lupft'),
47884790
'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
4791+
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_spitfire_mode', 'use_fates'=>$nl_flags->{'use_fates'},
4792+
'use_fates_managed_fire'=>$nl->get_value('use_fates_managed_fire'),
4793+
'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
47894794

47904795
my $suplnitro = $nl->get_value('suplnitro');
47914796
my $parteh_mode = $nl->get_value('fates_parteh_mode');
@@ -4807,7 +4812,7 @@ sub setup_logic_fates {
48074812
}
48084813
# spit-fire can't be on with FATES SP mode is active
48094814
if ( $nl->get_value('fates_spitfire_mode') > 0 ) {
4810-
$log->fatal_error('fates_spitfire_mode can NOT be set to greater than 0 when use_fates_sp is true');
4815+
$log->fatal_error("fates_spitfire_mode can NOT be set to greater than 0 when use_fates_sp is true");
48114816
}
48124817

48134818
# fates landuse can't be on with FATES SP mode is active
@@ -4920,6 +4925,16 @@ sub setup_logic_fates {
49204925
}
49214926
}
49224927
}
4928+
4929+
# Check use_fates_managed_fire mode is running with spitfire on
4930+
my $var = "use_fates_managed_fire";
4931+
if ( defined($nl->get_value($var)) ) {
4932+
if ( &value_is_true($nl->get_value($var)) ) {
4933+
if ( $nl->get_value('fates_spitfire_mode') == 0 ) {
4934+
$log->fatal_error("fates_spitfire_mode must be non-zero when $var is true");
4935+
}
4936+
}
4937+
}
49234938
}
49244939
}
49254940

bld/namelist_files/namelist_defaults_ctsm.xml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
152152
<megan clm_accelerated_spinup="sasu">0</megan>
153153
<megan configuration="nwp" >0</megan>
154154

155-
<!-- Setting to TRUE replicates previous ctsm5.3.063 answers, setting to false turns the soil moisture effect off -->
156-
<megan_use_gamma_sm>.true.</megan_use_gamma_sm>
155+
<!-- The soil moisture effect was added in ctsm5.2.020 with MEGAN2.1 and was hardcoded on. -->
156+
<!-- As of ctsm5.3.068 megan_use_gamma_sm became default false, which is closer to MEGAN before 2.1. -->
157+
<!-- Hence we made megan_use_gamma_sm default off for all CLM physics versions. -->
158+
<megan_use_gamma_sm>.false.</megan_use_gamma_sm>
157159
<megan_min_gamma_sm>0.0d00</megan_min_gamma_sm>
158160

159161
<!-- Supplmental Nitrogen mode -->
@@ -553,7 +555,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
553555
<!-- FATES default parameter file -->
554556
<!-- ================================================================== -->
555557

556-
<fates_paramfile>lnd/clm2/paramdata/fates_params_api.40.0.0_14pft_c250512.nc</fates_paramfile>
558+
<fates_paramfile>lnd/clm2/paramdata/fates_params_api.41.0.0_14pft_c250813.nc</fates_paramfile>
557559

558560

559561
<!-- ================================================================== -->
@@ -2434,6 +2436,7 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.3.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2
24342436
<fates_electron_transport_model use_fates=".true.">FvCB1980</fates_electron_transport_model>
24352437
<fates_photosynth_acclimation use_fates=".true.">nonacclimating</fates_photosynth_acclimation>
24362438
<fates_spitfire_mode use_fates=".true.">0</fates_spitfire_mode>
2439+
<fates_spitfire_mode use_fates=".true." use_fates_managed_fire=".true." >1</fates_spitfire_mode>
24372440
<fates_harvest_mode use_fates=".true.">no_harvest</fates_harvest_mode>
24382441
<fates_stomatal_model use_fates=".true.">ballberry1987</fates_stomatal_model>
24392442
<fates_stomatal_assimilation use_fates=".true.">net</fates_stomatal_assimilation>
@@ -2442,6 +2445,7 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.3.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2
24422445
<fates_regeneration_model use_fates=".true.">default</fates_regeneration_model>
24432446
<fates_radiation_model use_fates=".true.">norman</fates_radiation_model>
24442447
<fates_hydro_solver use_fates=".true.">2D_Picard</fates_hydro_solver>
2448+
<use_fates_managed_fire use_fates=".true.">.false.</use_fates_managed_fire>
24452449
<use_fates_planthydro use_fates=".true.">.false.</use_fates_planthydro>
24462450
<use_fates_tree_damage use_fates=".true.">.false.</use_fates_tree_damage>
24472451
<use_fates_cohort_age_tracking use_fates=".true.">.false.</use_fates_cohort_age_tracking>

bld/namelist_files/namelist_definition_ctsm.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,17 @@ ignitions.
750750
(Only relevant if FATES is on)
751751
</entry>
752752

753+
<entry id="use_fates_managed_fire" type="logical" category="physics"
754+
group="clm_inparm" valid_values="" value=".false.">
755+
Enable FATES managed fire mode. Requires that fates_spitfire_mode is on (in any mode).
756+
This mode allows the FATES model to conduct fuel-load reduction through managed burns.
757+
The boundary conditions in which a managed fire is allowed is set via the FATES parameter
758+
file. The burned area fraction of a managed burn is defined through the FATES parameter
759+
file as well. This mode works in conjunction with the SPITFIRE module to determine
760+
whether a wildfire or managed fire takes place on a given patch.
761+
(Only relevant if FATES is on)
762+
</entry>
763+
753764
<entry id="use_fates_fixed_biogeog" type="logical" category="physics"
754765
group="clm_inparm" valid_values="" value=".false.">
755766
Toggle to turn on fixed biogeography mode

bld/unit_testers/build-namelist_test.pl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ sub cat_and_create_namelistinfile {
163163
#
164164
# Figure out number of tests that will run
165165
#
166-
my $ntests = 3393;
166+
my $ntests = 3394;
167167

168168
if ( defined($opts{'compare'}) ) {
169169
$ntests += 2061;
@@ -1118,6 +1118,10 @@ sub cat_and_create_namelistinfile {
11181118
namelst=>"fates_spitfire_mode=1,use_fates_sp=.true.",
11191119
phys=>"clm5_0",
11201120
},
1121+
"managedfirenospitfire" =>{ options=>"-envxml_dir . --bgc fates",
1122+
namelst=>"fates_spitfire_mode=0,use_fates_managed_fire=.true.",
1123+
phys=>"clm5_0",
1124+
},
11211125
"usefatesspusefateshydro" =>{ options=>"-envxml_dir . --bgc fates",
11221126
namelst=>"use_fates_sp=.true.,use_fates_planthydro=.true.",
11231127
phys=>"clm5_0",

cime

Submodule cime updated 121 files
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
Parent class for CTSM-specific tests that first run the subset_data tool and then ensure
3+
that CTSM does not fail using the just-generated input files
4+
"""
5+
6+
import os
7+
import sys
8+
import logging
9+
from CIME.SystemTests.system_tests_common import SystemTestsCommon
10+
from CIME.user_mod_support import apply_user_mods
11+
from CIME.XML.standard_module_setup import *
12+
13+
# In case we need to import subset_data later
14+
_CTSM_PYTHON = os.path.join(
15+
os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python"
16+
)
17+
sys.path.insert(1, _CTSM_PYTHON)
18+
19+
logger = logging.getLogger(__name__)
20+
21+
22+
class SUBSETDATASHARED(SystemTestsCommon):
23+
def __init__(self, case, subset_data_cmd):
24+
"""
25+
initialize an object interface to the SMS system test
26+
"""
27+
SystemTestsCommon.__init__(self, case)
28+
29+
# Check the test setup
30+
if not self._case.get_value("LND_GRID") == "CLM_USRDAT":
31+
raise RuntimeError("SUBSETDATA tests require resolution CLM_USRDAT")
32+
if "serial" not in self._case.get_value("MPILIB"):
33+
raise RuntimeError("SUBSETDATA tests require a serial MPILIB")
34+
if "BGC-CROP" not in self._case.get_value("COMPSET"):
35+
raise RuntimeError("SUBSETDATA tests require a BGC-CROP compset")
36+
37+
# Add standard subset_data arguments
38+
out_dir = os.path.join(self._get_caseroot(), "subset_data_output")
39+
self.usermods_dir = os.path.join(out_dir, "user_mods")
40+
self.subset_data_cmd = subset_data_cmd + [
41+
"--create-user-mods",
42+
"--outdir",
43+
out_dir,
44+
"--user-mods-dir",
45+
self.usermods_dir,
46+
"--overwrite",
47+
]
48+
49+
# Run subset_data, if needed.
50+
# It's needed during SETUP and/or NLCOMP phases if comparing/generating a baseline because
51+
# the namelist comparison will require generating a namelist, and that will fail if we
52+
# haven't specified our custom fsurdat and other stuff. By calling self._run_subset_data()
53+
# only if the usermods directory doesn't yet exist, we avoid it being called every time the
54+
# test class is initialized (which happens, e.g., in RUN phase).
55+
# if not os.path.exists(self.usermods_dir):
56+
# self._run_subset_data()
57+
58+
def build_phase(self, sharedlib_only=False, model_only=False):
59+
"""
60+
Run subset_data and then build the model
61+
"""
62+
63+
# Run subset_data.
64+
# build_phase gets called twice:
65+
# - once with sharedlib_only = True and
66+
# - once with model_only = True
67+
# Because we only need subset_data run once, we only do it for the sharedlib_only call.
68+
# We could also check for the existence of the subset_data outputs, but that might lead to
69+
# a situation where the user expects subset_data to be called but it's not. Better to run
70+
# unnecessarily (e.g., if you fixed some FORTRAN code and just need to rebuild).
71+
# In that same vein, yes we did run subset_data during the first time this test case was
72+
# initialized (see __init__() above), but we're doing it again here just to be safe.
73+
if sharedlib_only:
74+
self._run_subset_data()
75+
76+
# Do the build
77+
self.build_indv(sharedlib_only=sharedlib_only, model_only=model_only)
78+
79+
def _run_subset_data(self):
80+
"""
81+
Run subset_data
82+
"""
83+
# Import subset_data. Do it here rather than at top because otherwise the import will
84+
# be attempted even during RUN phase.
85+
# pylint: disable=wrong-import-position,import-outside-toplevel
86+
from ctsm.subset_data import main as subset_data
87+
88+
# Run subset_data
89+
sys.argv = self.subset_data_cmd
90+
subset_data()
91+
92+
# Required so that CTSM doesn't fail
93+
user_nl_clm_path = os.path.join(self.usermods_dir, "user_nl_clm")
94+
with open(user_nl_clm_path, "a", encoding="utf-8") as user_nl_clm:
95+
user_nl_clm.write("\ncheck_dynpft_consistency = .false.\n")
96+
97+
# Apply the user mods
98+
self._case.flush(flushall=True)
99+
apply_user_mods(self._get_caseroot(), self.usermods_dir)
100+
self._case.read_xml()
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
CTSM-specific test that first runs the subset_data point tool and then ensures
3+
that CTSM does not fail using the just-generated input files
4+
"""
5+
6+
from subsetdata import SUBSETDATASHARED
7+
8+
9+
class SUBSETDATAPOINT(SUBSETDATASHARED):
10+
def __init__(self, case):
11+
"""
12+
initialize an object interface to the SMS system test
13+
"""
14+
15+
lat = 45.402252
16+
lon = -92.798085
17+
18+
# Don't need to include things that are added during SUBSETDATASHARED.__init__()
19+
subset_data_cmd = [
20+
"tools/site_and_regional/subset_data",
21+
"point",
22+
"--lat",
23+
str(lat),
24+
"--lon",
25+
str(lon),
26+
"--create-surface",
27+
"--crop",
28+
"--create-landuse",
29+
"--surf-year",
30+
"1850",
31+
"--create-datm",
32+
"--datm-syr",
33+
"1901",
34+
"--datm-eyr",
35+
"1901",
36+
]
37+
38+
super().__init__(case, subset_data_cmd)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
CTSM-specific test that first runs the subset_data region tool and then ensures
3+
that CTSM does not fail using the just-generated input files
4+
"""
5+
6+
from subsetdata import SUBSETDATASHARED
7+
8+
9+
class SUBSETDATAREGION(SUBSETDATASHARED):
10+
def __init__(self, case):
11+
"""
12+
initialize an object interface to the SMS system test
13+
"""
14+
15+
lat1 = -9
16+
lat2 = -7
17+
lon1 = 291
18+
lon2 = 293
19+
20+
# Don't need to include things that are added during SUBSETDATASHARED.__init__()
21+
subset_data_cmd = [
22+
"tools/site_and_regional/subset_data",
23+
"region",
24+
"--lat1",
25+
str(lat1),
26+
"--lat2",
27+
str(lat2),
28+
"--lon1",
29+
str(lon1),
30+
"--lon2",
31+
str(lon2),
32+
"--create-mesh",
33+
"--create-domain",
34+
"--create-surface",
35+
"--crop",
36+
"--create-landuse",
37+
"--surf-year",
38+
"1850",
39+
]
40+
41+
super().__init__(case, subset_data_cmd)

cime_config/config_archive.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
<hist_file_extension>e</hist_file_extension>
1010
<rest_history_varname>locfnh</rest_history_varname>
1111
<rpointer>
12-
<rpointer_file>rpointer.lnd$NINST_STRING</rpointer_file>
12+
<rpointer_file>rpointer.lnd$NINST_STRING.$DATENAME</rpointer_file>
1313
<rpointer_content>./$CASE.clm2$NINST_STRING.r.$DATENAME.nc</rpointer_content>
1414
</rpointer>
1515
<test_file_names>
16-
<tfile disposition="copy">rpointer.lnd</tfile>
16+
<tfile disposition="copy">rpointer.lnd.1976-01-01-00000</tfile>
1717
<tfile disposition="copy">rpointer.lnd_9999.1976-01-01-00000</tfile>
1818
<tfile disposition="copy">casename.clm2.r.1976-01-01-00000.nc</tfile>
1919
<tfile disposition="copy">casename.clm2.rh4a.1976-01-01-00000.nc</tfile>

0 commit comments

Comments
 (0)