-
+
'O3','NO2','HNO3','NO','HO2NO2','CH3OOH','CH2O','CO','H2O2','CH3COOOH','PAN','MPAN','C2H5OOH','ONIT','POOH','C3H7OOH','ROOH','CH3COCHO','CH3COCH3','Pb','ONITR','MACROOH','XOOH','ISOPOOH','CH3OH','C2H5OH','CH3CHO','GLYALD','HYAC','HYDRALD','ALKOOH','MEKOOH','TOLOOH','TERPOOH','CH3COOH','CB1','CB2','OC1','OC2','SOA','SO2','SO4','NH3','NH4NO3'
@@ -21,10 +21,11 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
atm/cam/chem/trop_mozart/dvel/dep_data_c201019.nc
-
+
'ISOP = isoprene', 'C10H16 = pinene_a + carene_3 + thujene_a', 'CH3OH = methanol', 'C2H5OH = ethanol', 'CH2O = formaldehyde', 'CH3CHO = acetaldehyde', 'CH3COOH = acetic_acid', 'CH3COCH3 = acetone'
+atm/cam/chem/trop_mozart/emis/megan21_emis_factors_78pft_c20161108.nc
atm/cam/chem/trop_mozart/emis/megan21_emis_factors_78pft_c20161108.nc
atm/cam/chem/trop_mozart/emis/megan21_emis_factors_78pft_c20161108.nc
atm/cam/chem/trop_mozart/emis/megan21_emis_factors_78pft_c20161108.nc
diff --git a/bld/namelist_files/namelist_defaults_dust_emis.xml b/bld/namelist_files/namelist_defaults_dust_emis.xml
new file mode 100644
index 0000000000..a13a23d14b
--- /dev/null
+++ b/bld/namelist_files/namelist_defaults_dust_emis.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+Zender_2003
+Leung_2023
+
+atm
+
+
diff --git a/bld/namelist_files/namelist_defaults_fire_emis.xml b/bld/namelist_files/namelist_defaults_fire_emis.xml
index b7536ba66b..ad74eafd16 100644
--- a/bld/namelist_files/namelist_defaults_fire_emis.xml
+++ b/bld/namelist_files/namelist_defaults_fire_emis.xml
@@ -5,7 +5,7 @@
-
+
'bc_a1 = BC','pom_a1 = 1.4*OC','SO2 = SO2'
-lnd/clm2/firedata/fire_emis_factors_c140116.nc
+lnd/clm2/firedata/fire_emission_factors_78PFTs_c20240624.nc
diff --git a/bld/namelist_files/namelist_defaults_overall.xml b/bld/namelist_files/namelist_defaults_overall.xml
index c4ccac6467..5b7ae1bdd9 100644
--- a/bld/namelist_files/namelist_defaults_overall.xml
+++ b/bld/namelist_files/namelist_defaults_overall.xml
@@ -22,30 +22,31 @@ determine default values for namelists.
-->
-arb_ic
-arb_ic
-arb_ic
-arb_ic
-arb_ic
-arb_ic
-startup
-startup
-startup
-startup
-startup
-startup
-arb_ic
-arb_ic
-arb_ic
-arb_ic
+arb_ic
cold
+cold
+cold
+startup
+startup
+
+
+cold
+cold
+cold
+cold
+cold
+cold
+cold
+cold
arb_ic
-flanduse_timeseries
-flanduse_timeseries
+null
+null
+flanduse_timeseries
+flanduse_timeseries
@@ -61,6 +62,7 @@ determine default values for namelists.
1x1_urbanc_alpha
1x1_numaIA
1x1_smallvilleIA
+1x1_cidadinhoBR
2000
@@ -109,6 +111,7 @@ determine default values for namelists.
test
navy
test
+test
gx1v7
diff --git a/bld/namelist_files/namelist_definition.xsl b/bld/namelist_files/namelist_definition.xsl
index 545d810e52..7917cc262f 100644
--- a/bld/namelist_files/namelist_definition.xsl
+++ b/bld/namelist_files/namelist_definition.xsl
@@ -252,18 +252,6 @@
These are namelist items that appear in the CLM Tools under components/clm/tools.
- CLM mksurfdata
-
- Name |
- Type |
- Description |
-
-
- Valid values |
-
-
-
-
CLM mkgriddata
Name |
@@ -276,17 +264,6 @@
- CLM mkmapdata
-
- Name |
- Type |
- Description |
-
-
- Valid values |
-
-
-
CLM mkgriddata
diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml
index a08795dd1f..351cdc5c80 100644
--- a/bld/namelist_files/namelist_definition_ctsm.xml
+++ b/bld/namelist_files/namelist_definition_ctsm.xml
@@ -150,6 +150,54 @@ specify spatially variable soil thickness. If not present, use bottom
of soil column (nlevsoi).
+
+number of wavelength bands used in SNICAR snow albedo calculation
+(snicar_numrad_snw=5 is the only supported option; others are EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+type of downward solar radiation spectrum for SNICAR snow albedo calculation
+(snicar_solarspec='mid_latitude_winter' is the only supported option; others are EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+dust optics type for SNICAR snow albedo calculation
+(snicar_dust_optics='sahara' is the only supported option; others are EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+snow grain shape used in SNICAR snow albedo calculation
+(snicar_snw_shape='hexagonal_plate' is supported in ctsm5.1 and 'sphere' in older model versions; others are EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+Toggle to turn on/off aerosol deposition flux in snow in SNICAR
+(snicar_use_aerosol='.false.' is EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+option to activate BC-snow internal mixing in SNICAR snow albedo calculation
+(snicar_snobc_intmix='.true.' is EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+option to activate dust-snow internal mixing in SNICAR snow albedo calculation
+(snicar_snodst_intmix='.true.' is EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
+
+option to activate organic carbon (OC) in SNICAR snow albedo calculation
+(do_sno_oc='.true.' is EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
+
+
Index of rooting profile for water
@@ -204,13 +252,15 @@ formulation (1).
+ group="cnfire_inparm" valid_values="nofire,li2014qianfrc,li2016crufrc,li2021gswpfrc,li2024gswpfrc,li2024crujra" >
The method type to use for CNFire
nofire: Turn fire effects off
li2014qianfrc: Reference paper Li, et. al.(2014) tuned with QIAN atmospheric forcing
li2016crufrc: Reference paper Li, et. al.(2016) tuned with CRU-NCEP atmospheric forcing
-li2021gswpfrc: Reference paper Li, et. al.(2021?) tuned with GSWP3 atmospheric forcing
+li2021gswpfrc: No reference paper yet, tuned with GSWP3 atmospheric forcing
+li2024gswpfrc: No reference paper yet, tuned with GSWP3 atmospheric forcing
+li2024crujra: No reference paper yet, tuned with CRU-JRA forcing
+
+Value above which 30-day running relative humidity has no effect on fuel combustibility
+
+
+
+Value (mm/d) above which running mean daily precipitation (10 or 60 days) does not allow deforestation fire for a column with broadleaf evergreen tropical trees but no broadleaf deciduous tropical trees. "PFT-dependent thresholds of P60d and P10d" in Li et al. (2013, doi:10.5194/bg-10-2293-2013).
+
+
+
+Value (mm/d) above which running mean daily precipitation (10 or 60 days) does not allow deforestation fire for a column with broadleaf deciduous tropical trees but no broadleaf evergreen tropical trees. "PFT-dependent thresholds of P60d and P10d" in Li et al. (2013, doi:10.5194/bg-10-2293-2013).
+
+
+
+Denominator of precipitation in equation relating that to non-boreal peat fire (unitless). Eq. 9 in Li et al. (2013, doi:10.5194/bg-10-2293-2013).
+
+
+
+Denominator of exponential in soil moisture term of equation relating that and temperature to boreal peat fire (unitless). Eq. 10 in Li et al. (2013, doi:10.5194/bg-10-2293-2013).
+
+
Critical threshold for truncation of Nitrogen (truncate Nitrogen states to zero below this value)
@@ -329,21 +404,11 @@ Max number of iterations used in subr. CanopyFluxes. For many years, 40 was the
Default: 40
-
-Fraction of intercepted precipitation
-
-
If TRUE use clm5 equation for fraction of intercepted precipitation
-
-Maximum fraction of leaf that may be wet prior to drip occuring
-
-
Scalar multiplier for base flow rate
@@ -502,7 +567,7 @@ Only works when running with a non-stub glacier model.
+ valid_values="multiple,virtual,single_at_atm_topo,UNSET" >
Behavior of each glacier region (GLACIER_REGION in surface dataset).
First item corresponds to GLACIER_REGION with ID 0 in the surface dataset,
second to GLACIER_REGION with ID 1, etc.
@@ -515,12 +580,21 @@ Allowed values are:
'single_at_atm_topo': glacier landunits in these grid cells have a single column,
whose elevation matches the atmosphere's topographic height (so that there is no
adjustment due to downscaling)
-Behavior of 'virtual' is required in the region where we have an ice sheet model
+'UNSET': place-holder for non-existent regions
+Most (if not all) of the region where there is an ice sheet model should have a behavior
+of 'virtual': This behavior is needed to compute surface mass balance (SMB) in all
+elevation classes for the sake of vertical downscaling, and is needed to allow two-way
+feedbacks of glacier areas. You are allowed to have gridcells with non-virtual behavior in
+this domain, but this should be minimized: SMB cannot be computed there, and CLM subgrid
+areas will not remain in sync with the GLC model. (Within the icemask - i.e., the active
+glc domain - you are NOT allowed to have gridcells with non-virtual behavior that also
+have glacier_region_melt_behavior='replaced_by_ice': within the icemask, you're only
+allowed to have non-virtual behavior in places where you are not computing SMB).
+ valid_values="replaced_by_ice,remains_in_place,UNSET" >
Treatment of ice melt for each glacier region (GLACIER_REGION in surface dataset).
First item corresponds to GLACIER_REGION with ID 0 in the surface dataset,
second to GLACIER_REGION with ID 1, etc.
@@ -529,17 +603,18 @@ Allowed values are:
this results in positive liquid runoff and negative ice runoff
'remains_in_place': any melted ice remains in place as liquid until it refreezes;
thus, ice melt does not result in any runoff
-IMPORTANT NOTE: Regions with the 'remains_in_place' behavior also do not
-compute SMB (because negative SMB would be pretty much meaningless in
-those regions). Thus, you cannot use this behavior where GLC is
-operating.
-Regions with the 'replaced_by_ice' behavior also compute SMB for the
-vegetated column.
+'UNSET': place-holder for non-existent regions
+IMPORTANT NOTE: Regions with the 'remains_in_place' behavior also do not compute SMB
+(because negative SMB would be pretty much meaningless in those regions). Thus, most (if
+not all) of the region where there is an ice sheet model should have the 'replaced_by_ice'
+behavior; the SMB sent to the GLC model will be 0 in any gridcells with the
+'remains_in_place' behavior.
+Regions with the 'replaced_by_ice' behavior also compute SMB for the vegetated column.
+ valid_values="remains_ice,melted,UNSET" >
Treatment of ice runoff for each glacier region (GLACIER_REGION in surface dataset).
First item corresponds to GLACIER_REGION with ID 0 in the surface dataset,
second to GLACIER_REGION with ID 1, etc.
@@ -550,7 +625,13 @@ Allowed values are:
'melted': ice runoff generated by the CLM physics (primarily due to snow capping) is melted
(generating a negative sensible heat flux) and runs off as liquid; this is appropriate in
regions that have little iceberg calving in reality. This can be important to avoid unrealistic
- cooling of the ocean and consequent runaway sea ice growth.
+ cooling of the ocean and consequent runaway sea ice growth. This option cannot be
+ combined with glacier_region_melt_behavior='replaced_by_ice': While there is nothing
+ fundamentally wrong with this combination, it can result in problematic, non-physical
+ fluxes (particularly, a large positive sensible heat flux during glacial melt in
+ regions where the ice sheet is not fully dynamic and two-way-coupled; see
+ https://github.com/ESCOMP/ctsm/issues/423 for details).
+'UNSET': place-holder for non-existent regions
Only applies when melt_non_icesheet_ice_runoff is .true.
@@ -621,11 +702,6 @@ Scalar of leaf respiration to vcmax
The maximum value to use for zeta under stable conditions
-
-baseline proportion of nitrogen allocated for electron transport (J)
-
-
Toggle to turn on the FATES model
@@ -638,6 +714,17 @@ Switch deciding which nutrient model to use in FATES.
(Only relevant if FATES is on)
+
+Switch defining the cadence at which seeds are dispersed across
+gridcells. Setting the switch value to zero turns off dispersal.
+Setting the switch to 1, 2, or 3 sets the dispersal cadence to
+daily, monthly or yearly. The daily cadence is primarily
+recommended for test and debug only. Note that turning this
+feature on will result in more memory usage.
+(Only relevant if FATES is on)
+
+
Toggle to turn on the tree damage module in FATES
@@ -675,10 +762,17 @@ Toggle to turn on no competition mode (only relevant if FATES is being used).
Toggle to turn on FATES satellite phenology mode (only relevant if FATES is being used).
-
-Toggle to turn on the logging module
-(Only relevant if FATES is on)
+
+Set FATES harvesting mode by setting fates_harvest_mode to a valid string option.
+Allowed values are:
+ no_harvest: no fates harvesting of any kind
+ event_code: fates logging via fates logging event codes (see fates parameter file) only
+ landuse_timeseries: fates harvest driven by CLM flanduse_timeseries file (dynHarvestMod)**
+ luhdata_area: fates harvest driven by LUH2 raw harvest data, area-based (dynFATESLandUseChangeMod)
+ luhdata_mass: fates harvest driven by LUH2 raw harvest data, mass-based (dynFATESLandUseChangeMod)
+**Note that the landuse_timeseries option is not the same as the FATES fluh_timeseries data file.
+This option is older than the luhdata options and may be depricated at some point in the future.
+
+ Setting for what types of FATES history to be allocate and
+ calculated at the dynamics timestep (1st integer) and the
+ model timestep (2nd integer). This must be consistent with
+ hist_fincl*, ie output variables must not be listed if the
+ output level is not enabled.
+ 0 = no fates history variables are calculated or allocated
+ 1 = only time x space (3d) fates history variables allowed
+ 2 = multiplexed dimensioned fates history is also allowed
+ (Only relevant if FATES is on)
+
+
+
+
+If TRUE, enable use of land use harmonization (LUH) state and transition data from luh_timeseries file.
+This is enabled by default if fates_harvest_mode is set to use the raw LUH2 harvest data
+(Also, only valid for use_fates = true and is incompatible with transient runs currently.)
+
+
+
+If TRUE, enable use of FATES land use with no competition and fixed biogeography. This mode
+requires the use of the land use x pft association static data map file. See the
+flandusepftdat definition entry in this file for more information.
+(Only valid for use_fates = true and is incompatible with transient runs currently.)
+
+
+
+If TRUE, ignore the land-use state vector and transitions, and assert that all lands
+are primary, and that there is no harvest. This mode is only relevant for FATES
+spin-up workflows that are intending to use the spin-up restart output to start a
+FATES land use transient case using the use_fates_lupft namelist option. The option
+should be set to true for the spin-up case and false for the transient case.
+
+
+
+
+Full pathname of unified land use harmonization (LUH) data file. This causes the land-use
+types to vary over time.
+(Required, if use_fates_luh=T)
+(Only relevant if FATES is on).
+
+
+
+Full pathname of fates landuse x pft association static data map.
+The file associates land use types with pfts across a static global map.
+This file is necessary for running FATES with use_fates_luh,
+use_fates_nocomp, and use_fates_fixedbiogeo engaged (note that use_fates_lupft
+is provided as a namelist option to engage all necessary options). The file is output
+by the FATES land use data tool (https://github.com/NGEET/tools-fates-landusedata)
+which processes the raw land use data from the THEMIS tool data sets
+(https://doi.org/10.5065/29s7-7b41)
+
+
Toggle to turn on the LUNA model, to effect Photosynthesis by leaf Nitrogen
@@ -725,6 +878,46 @@ LUNA operates on C3 and non-crop vegetation (see vcmax_opt for how other veg is
LUNA: Leaf Utilization of Nitrogen for Assimilation
+
+Toggle to turn on the hillslope model
+
+
+
+Toggle to turn on meteorological downscaling in hillslope model
+
+
+
+Toggle to turn on surface water routing in the hillslope hydrology model
+
+
+
+If true, set fsat to zero for hillslope columns
+
+
+
+Method for calculating hillslope saturated head gradient
+
+
+
+Method for calculating transmissivity of hillslope columns
+
+
+
+Method for distributing pfts across hillslope columns
+
+
+
+Method for distributing soil thickness across hillslope columns
+
+
Toggle to turn on the plant hydraulic stress model
@@ -754,6 +947,11 @@ Full pathname datafile with fates parameters
Full pathname of surface data file.
+
+Full pathname of hillslope data file.
+
+
SNICAR (SNow, ICe, and Aerosol Radiative model) optical data file name
@@ -764,9 +962,9 @@ SNICAR (SNow, ICe, and Aerosol Radiative model) optical data file name
SNICAR (SNow, ICe, and Aerosol Radiative model) snow aging data file name
-
-If TRUE, write master field list to separate file for documentation purposes
+If TRUE, write list of all output fields to separate file for documentation purposes
+
+If TRUE, use explicit, time-varying AC adoption rate for air-conditioning flux and interior building temperature calculations.
+
+
If TRUE, urban traffic flux will be activated (Currently NOT implemented).
@@ -1013,6 +1216,50 @@ e.g., because we have integrated AgSys and have tests of it that make
these software infrastructure tests obsolete.
+
+
+
+
+Turn on the Matrix solution for above ground biogeochemistry, requires CN to be on
+
+
+
+Turn on the Matrix solution for soil biogeochemistry
+
+
+
+Turn on extra output for the matrix solution
+
+
+
+Turn on semi-analytic spinup solution for the CN/Soil matrix, requires soil matrix to be on
+This will drive the solution to equilibrium
+
+
+
+Number of years to average the storage capacitance over for the soil Matrix solution during semi-analytic spinup (spinup_matrixcn=T)
+Normally should be the same as the number of years the atmospheric forcing is run over
+
+
+
+length of each semi-analytic solution. eg. nyr_SASU=5, analytic solutions will be calculated every five years.
+nyr_SASU=1: the fastest SASU, but inaccurate; nyr_SASU=nyr_forcing(eg. 20): the lowest SASU but accurate
+
+
+
+The restart file will be based on the average of all analytic solutions within the iloop_avg^th loop.
+eg. if nyr_forcing = 20, iloop_avg = 8, the restart file in yr 160 will be based on analytic solutions from yr 141 to 160.
+The number of the analytic solutions within one loop depends on ratio between nyr_forcing and nyr_SASU.
+eg. if nyr_forcing = 20, nyr_SASU = 5, number of analytic solutions is 20/5=4
+
+
@@ -1065,13 +1312,13 @@ Maximum nitrification rate constant (1/s)
Toggle to turn on the VIC hydrologic parameterizations
-(vichydro=".true." is EXPERIMENTAL NOT SUPPORTED!)
+(vichydro=".true." is EXPERIMENTAL, UNSUPPORTED!)
+
+Fraction of post-harvest crop residues (leaf and stem) to move to
+1-year product pool instead of letting them fall as litter.
+Default: 0.0
+
+
+ group="crop_inparm" valid_values="constant,varytropicsbylat" value="constant">
Type of mapping to use for base temperature for prognostic crop model
constant = Just use baset from the PFT parameter file
varytropicsbylat = Vary the tropics by latitude
+ group="crop_inparm" valid_values="" value="0.4d00">
Only used when baset_mapping == varytropicsbylat
Slope with latitude in degrees to vary tropical baset by
+ group="crop_inparm" valid_values="" value="12.0d00">
Only used when baset_mapping == varytropicsbylat
Intercept at zero latitude to add to baset from the PFT parameter file
@@ -1129,6 +1383,16 @@ Phenology onset depends on the vegetation type
(only used when CN is on)
+
+Set to .true. in order to override crop harvesting logic and to instead harvest the day before the next sowing date. Used to generate growing-degree day outputs that can be used with an external script to generate new GDD requirement ("cultivar") files.
+
+
+
+Set to .false. in order to ignore crop PFT parameter for maximum growing season length (mxmat). Must be set to .false. when generate_crop_gdds is .true.
+
+
Method for determining what the minimum critical day length for seasonal decidious leaf offset depends on
@@ -1141,9 +1405,8 @@ DependsOnLatAndVeg - Arctic vegetation depends on latitude as above, but tempera
-Toggle to turn on calculation of SNow and Ice Aerosol Radiation model (SNICAR) radiative forcing
-(snicar_frc=".true." is EXPERIMENTAL NOT SUPPORTED!)
+ group="clm_inparm" value=".false.">
+Toggle to turn on calculation of SNow and Ice Aerosol Radiation model (SNICAR) albedo forcing diagnostics for each aerosol species
+
+If true, any ocean (i.e., wetland) points on the surface dataset are
+converted to bare ground (or whatever vegetation is given in that grid
+cell - but typically this will be bare ground due to lack of vegetation
+in grid cells with 100% ocean).
+
+
@@ -1217,248 +1488,11 @@ Percentage threshold above which the model keeps the urban landunits. Selecting
Default: 0
-
-Toggle to turn on the dynamic root model
-
-
Toggle to turn on on diagnostic Snow Radiative Effect
-
-
-
-
-
-SCRIP format grid data file
-
-
-
-Flag to pass to the ESMF mapping utility, telling it what kind of large
-file support is needed for an output file generated with this grid as
-either the source or destination ('none', '64bit_offset' or 'netcdf4').
-
-
-
-Flag to pass to the ESMF mapping utility, telling it what kind of grid
-file this is (SCRIP or UGRID).
-
-
-
-For UGRID files, flag to pass to the ESMF mapping utility, telling it the
-name of the dummy variable that has all of the topology information stored
-in its attributes. (Only used if scripgriddata_src_type = UGRID.)
-
-
-
-
-
-
-Output of "git describe" to give the tag/commit the version being used corresponds to
-
-
-
-Filename for mksurfdata_map to remap raw data into the output surface dataset
-
-
-
-Plant Function Type dataset for mksurfdata
-
-
-
-Harvest dataset for mksurfdata
-
-
-
-Dataset for percent glacier land-unit for mksurfdata
-
-
-
-Dataset for glacier region ID for mksurfdata
-
-
-
-Dataset for topography used to define urban threshold
-
-
-
-Leaf Area Index dataset for mksurfdata
-
-
-
-Soil texture dataset for mksurfdata
-
-
-
-Soil color dataset for mksurfdata
-
-
-
-Soil max fraction dataset for mksurfdata
-
-
-
-High resolution land mask/fraction dataset for mksurfdata
-(used for glacier_mec land-units)
-
-
-
-Type of grid to create for mksurfdata
-
-
-
-Grid file at the output resolution for mksurfdata
-
-
-
-Text file with filepaths (or list of XML elements) for vegetation fractions
-and harvesting for each year to run over for mksurfdata to be able to model
-transient land-use change
-
-
-
-High resolution topography dataset for mksurfdata
-(used for glacier_mec land-units)
-
-
-
-Irrigation dataset for mksurfdata
-
-
-
-Organic soil dataset for mksurfdata
-
-
-
-Lake water dataset for mksurfdata
-
-
-
-Wetland dataset for mksurfdata
-
-
-
-Urban dataset for mksurfdata
-
-
-
-Biogenic Volatile Organic Compounds (VOC) emissions dataset for mksurfdata
-
-
-
-GDP dataset for mksurfdata
-
-
-
-Peat dataset for mksurfdata
-
-
-
-Soil depth dataset for mksurfdata
-
-
-
-Agricultural burning dominant month dataset for mksurfdata
-
-
-
-Topography statistics dataset for mksurfdata
-
-
-
-VIC parameters dataset for mksurfdata
-
-
-
-If TRUE, output variables in double precision for mksurfdata
-
-
-
-If TRUE, ignore other files, and set the output percentage to 100% urban and
-zero for other land-use types.
-
-
-
-If TRUE, set wetland to 0% over land (renormalizing other landcover types as needed);
-wetland will only be used for ocean points.
-
-
-
-Number of Plant Functional Types (excluding bare-soil)
-
-
-
-Plant Function Type index to override global file with for mksurfdata
-
-
-
-Plant Function Type fraction to override global file with for mksurfdata
-
-
-
-Soil color index to override global file with for mksurfdata
-
-
-
-Soil maximum fraction to override global file with for mksurfdata
-
-
-
-Soil percent sand to override global file with for mksurfdata
-
-
-
-Soil percent clay to override global file with for mksurfdata
-
-
-
@@ -1693,6 +1727,54 @@ Mapping method from Nitrogen deposition input file to the model resolution
copy = copy using the same indices
+
+
+
+
+
+If TRUE use the Prigent roughness dataset
+
+
+
+Filename of input stream data for aeolian roughness length (from Prigent's roughness dataset)
+
+
+
+mesh filename of input stream data for aeolian roughness length (from Prigent's roughness dataset)
+
+
+
+
+
+
+
+Option only applying for the Zender_2003 method for whether the soil erodibility file is handled
+here in CTSM, or in the ATM model.
+(only used when dust_emis_method is Zender_2003)
+ bilinear = bilinear interpolation
+ nn = nearest neighbor
+ nnoni = nearest neighbor on the "i" (longitude) axis
+ nnonj = nearest neighbor on the "j" (latitude) axis
+ spval = set to special value
+ copy = copy using the same indices
+
+
+
+Filename of input stream data for Zender's soil erodibility source function
+(only used when dust_emis_method is Zender_2003, and zender_soil_erod_source is lnd)
+
+
+
+mesh filename of input stream data for Zender's soil erodibility source function
+(only used when dust_emis_method is Zender_2003, and zender_soil_erod_source is lnd)
+
+
@@ -1753,6 +1835,7 @@ If true, will ignore the prescribed soilm data for that point and let the model
prescribed data.
+
@@ -1761,7 +1844,6 @@ prescribed data.
Toggle to turn on use of LAI streams in place of the LAI on the surface dataset when using Satellite Phenology mode.
-(EXPERIMENTAL and NOT tested)
+
+dtlimit (ratio of max/min stream delta times) for LAI streams, which allows for cycling over a year of data
+
+
+
Time interpolation method to use with LAI streams
@@ -1805,6 +1893,106 @@ Mapping method from LAI input file to the model resolution
copy = copy using the same indices
+
+
+
+
+
+
+Flag to enable prescribed crop calendars (sowing window dates and maturity requirement)
+
+
+
+Flag to enable prescribed crop calendars (sowing window dates and maturity requirement), with maturity requirement adaptive based on recent climate
+
+
+
+First year to loop over for crop sowing windows
+
+
+
+Last year to loop over for crop sowing windows
+
+
+
+Simulation year that aligns with stream_year_first_cropcal_swindows value
+
+
+
+First year to loop over for crop maturity requirements
+
+
+
+Last year to loop over for crop maturity requirements
+
+
+
+Simulation year that aligns with stream_year_first_cropcal_cultivar_gdds value
+
+
+
+By default, a value in stream_fldFileName_swindow_start or _end outside the range [1, 365] (or 366 in leap years) will cause the run to fail. Set this to .true. to instead fall back on the paramfile sowing windows.
+
+
+
+Filename of input stream data for date (day of year) of start of sowing window. Cells with the same sowing window start and end date are always planted on that date, regardless of climatic conditions/history.
+
+
+
+Filename of input stream data for date (day of year) of end of sowing window. Cells with the same sowing window start and end date are always planted on that date, regardless of climatic conditions/history.
+
+
+
+Filename of input stream data for cultivar growing degree-day targets
+
+
+
+Filename of input stream data for baseline GDD20 values
+
+
+
+Set this to true to read gdd20 accumulation season start and end dates from stream files, rather than using hard-coded hemisphere-specific "warm seasons."
+
+
+
+Set this to true to flush the accumulated GDD20 variables as soon as possible.
+
+
+
+By default, a value in stream_fldFileName_gdd20_season_start or _end outside the range [1, 365] (or 366 in leap years) will cause the run to fail. Set this to .true. to instead have such cells fall back to the hard-coded hemisphere-specific "warm seasons."
+
+
+
+Filename of input stream data for date (day of year) of start of gdd20 accumulation season.
+
+
+
+Filename of input stream data for date (day of year) of end of gdd20 accumulation season.
+
+
+
+Filename of input stream data for crop calendar inputs
+
+
@@ -1973,13 +2161,6 @@ Mapping file to go from one resolution/land-mask to another resolution/land-mask
Land mask description for mksurfdata input files
-
-Horizontal grid resolutions for mksurfdata input files
-
-
-
@@ -1992,9 +2173,9 @@ to use for methane model
-Resolution of Lightning dataset to use for CN fire model
-(only applies when CN and the CN fire model are turned on)
+ group="default_settings" valid_values="none,360x720,106x174,94x192">
+Resolution of Lightning dataset to use for CN or FATES fire model
+(only applies when CN or FATES and the fire model is turned on)
-
-Horizontal resolutions
-Note: 0.25x0.25, 0.5x0.5, 5x5min, 10x10min, 3x3min, 1km-merge-10min and 0.33x0.33 are only used for CLM toolsI
-
-
@@ -2041,13 +2215,15 @@ hist means do NOT use a future scenario, just use historical data.
Land mask description
+
+ valid_values="clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam7.0,clm4_5_cam6.0,clm4_5_cam5.0,clm4_5_cam4.0,clm5_0_cam7.0,clm5_0_cam6.0,clm5_0_cam5.0,clm5_0_cam4.0,clm5_0_CRUv7,clm5_0_GSWP3v1,clm5_1_GSWP3v1,clm5_1_CRUv7,clm5_1_cam7.0,clm5_1_cam6.0,clm5_1_cam5.0,clm5_1_cam4.0,clm6_0_GSWP3v1,clm6_0_cam7.0,clm6_0_cam6.0,clm6_0_cam5.0,clm6_0_cam4.0">
General configuration of model version and atmospheric forcing to tune the model to run under.
This sets the model to run with constants and initial conditions that were set to run well under
the configuration of model version and atmospheric forcing. To run well constants would need to be changed
to run with a different type of atmospheric forcing.
+(Some options for the newest physics will be based on previous tuning, and buildnml will let you know about this)
+"PtVg,1000,850,1100,1350,1600,1850,1855,1865,1875,1885,1895,1905,1915,1925,1935,1945,1955,1965,1975,1979,1980,1982,1985,1995,2000,2005,2010,2013,2015,2018,2025,2035,2045,2055,2065,2075,2085,2095,2105">
Year to simulate and to provide datasets for (such as surface datasets, initial conditions, aerosol-deposition, Nitrogen deposition rates etc.)
A sim_year of 1000 corresponds to data used for testing only, NOT corresponding to any real datasets.
A sim_year greater than 2015 corresponds to ssp_rcp scenario data
@@ -2100,21 +2276,21 @@ How close in years to use when looking for an initial condition file (finidat) i
Simulation years you can look for in initial condition files (finidat) if interpolation is turned on (use_init_interp is .true.)
-
+
Command line argument for setting up your simulation in a mode for faster
throughput. By default turns off some options, and sets up for a lower level
of output. When bgc_mode is some level of prognostic BGC (so NOT Satellite Phenology)
-it also sets up for accelerated decomposition.
+it also sets up for accelerated decomposition. The "sasu" mode sets up
+for using the CN-matrix mode with Semi-Analytic Spin Up.
NOTE: THIS CORRESPONDS DIRECTLY TO THE env_run.xml VARIABLE OF THE SAME NAME.
Set the env_run variable, rather than setting this directly.
+ group="default_settings" valid_values="sp,bgc,fates" >
Command line arguement for biogeochemistry mode for CLM4.5
sp = Satellitte Phenology
- cn = Carbon Nitrogen model
bgc = CLM4.5 BGC model with:
CENTURY model pools
Nitrification/De-nitrification
@@ -2179,7 +2355,7 @@ Profile over which to distribute C and N coming from surface pools (leaves, stem
If true, no denitrification or nitrification in frozen soil layers.
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
If TRUE, weight btran (vegetation soil moisture availability) by unfrozen layers only, assuming that vegetation
will allocate roots preferentially to the active layer.
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
If TRUE, weight btran (vegetation soil moisture availability) by the active layer, as defined by the greatest thaw depth over the current and prior years.
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
@@ -2300,7 +2476,7 @@ How much Carbon to initialize vegetation pools (leafc/frootc and storage) to whe
Flexible CN ratio used for Phenology
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
Vcmax calculation for Photosynthesis
- vcmax_opt = 4 As for vcmax_opt=0, but using leafN, and exponential if tree (EXPERIMENTAL NOT TESTED!)
+ vcmax_opt = 4 As for vcmax_opt=0, but using leafN, and exponential if tree (EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
vcmax_opt = 3 Based on leafN and VCAD (used with Luna for crop and C4 vegetation)
vcmax_opt = 0 Based on canopy top and foilage Nitrogen limitation factor from params file (clm4.5)
@@ -2320,13 +2496,13 @@ Vcmax calculation for Photosynthesis
Evergreen phenology option for CNPhenology
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
Carbon respiration option to burn off carbon when CN ratio is too high (do NOT use when FUN is on)
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
@@ -2363,12 +2539,6 @@ If surface water is active or not
(deprecated -- will be removed)
-
-Use original CLM4 soil hydraulic properties
-(deprecated -- will be removed)
-
-
@@ -2384,7 +2554,7 @@ then don't fix aere (see ch4Mod.F90).
If TRUE, turn on methane biogeochemistry model for lake columns, using a simplified version of the CH4 submodel.
-(EXPERIMENTAL)
+(EXPERIMENTAL, UNSUPPORTED!)
If TRUE, use the fine root carbon predicted by CN when calculating the aerenchyma area, rather than the parametrization
based on annual NPP, aboveground NPP fraction, and LAI.
-(EXPERIMENTAL and NOT tested)
+(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!)
@@ -2475,6 +2645,13 @@ If TRUE, apply harvest from flanduse_timeseries file.
(Also, only valid for use_cn = true.)
+
+If TRUE, apply gross unrepresented landuse/land-cover change from flanduse_timeseries file.
+(Only valid for transient runs, where there is a flanduse_timeseries file.)
+(Also, only valid for use_cn = true.)
+
+
If TRUE, reset baseline values of total column water and energy in the
@@ -2652,22 +2829,12 @@ TruncatedAnderson1976 -- Truncate the Anderson-1976 equation at the value for -1
Slater2017 ------------- Use equation from Slater that increases snow density for very cold temperatures (Arctic, Antarctic)
-
-Upper Limit on Destructive Metamorphism Compaction [kg/m3]
-
-
Snow compaction overburden exponential factor (1/K)
Not used for snow_overburden_compaction_method=Vionnet2012
-
-maximum warm (at freezing) fresh snow effective radius [microns]
-
-
If set to .true., then reset the snow pack over non-glacier columns to a small value.
@@ -2725,6 +2892,11 @@ NiuYang2007: Niu and Yang 2007
SwensonLawrence2012: Swenson and Lawrence 2012
+
+Parameterization to use for snow thermal conductivity
+
+
@@ -2742,6 +2914,24 @@ the related bulk quantities.
If .true., run with water isotopes
+
+
+
+
+
+Parameterization/parameters to use for surface roughness
+ZengWang2007: Zeng and Wang 2007
+Meier2022: Meier et al. in prep. 2022
+
+
+
+If FALSE use constant snow z0m
+If TRUE use parameterization of snow z0m as a function of accumulated
+snow melt of Brock et al. (2006)
+
+
@@ -2796,4 +2986,68 @@ use case.)
+
+
+
+
+If TRUE turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020)
+
+
+
+Initial soil temperature to use for gridcells with excess ice present during a run starting with coldstart (deg C). Value only applys if use_excess_ice is true.
+
+
+
+Soil depth below which initial excess ice concentration will be applied during a run starting with coldstart (m). Value only applys if use_excess_ice is true.
+If this is set below depth of the soil depth, only the last soil layer will get excess ice.
+
+
+
+
+If TRUE and use_excess_ice is TRUE, use the excess ice stream to determine the initial values of the excess ice field
+if FALSE and use_excess_ice is TRUE, expect excess ice to come from the initial conditions or restart file
+Expect to be FALSE is use_excess_ice is FALSE
+
+
+
+Filename of input stream data for excess ice data
+
+
+
+mesh filename of input stream data for excess ice
+
+
+
+Mapping method from excess ice input stream data to the model resolution
+ bilinear = bilinear interpolation
+ nn = nearest neighbor
+ none = no interpolation
+
+
+
+
+
+
+
+Whether to till crop soil, and if so, with what intensity.
+
+
+
+Toggle to use original (Graham et al. 2021) tillage logic, with bug for seasons crossing into a new calendar year
+
+
+
+Maximum depth to till soil (m). Default 0.26; original (Graham et al., 2021) value was unintentionally 0.32.
+
+
diff --git a/bld/namelist_files/namelist_definition_drv_flds.xml b/bld/namelist_files/namelist_definition_drv_flds.xml
index 088f5c5fa9..f440a9a678 100644
--- a/bld/namelist_files/namelist_definition_drv_flds.xml
+++ b/bld/namelist_files/namelist_definition_drv_flds.xml
@@ -35,10 +35,14 @@
group="megan_emis_nl"
valid_values="" >
MEGAN specifier. This is in the form of: Chem-compound = megan_compound(s)
- where megan_compound(s) can be the sum of megan compounds with a "+" between them.
+ where megan_compound(s) can be an equation with megan compounds added or subtracted together with multiplication
In each equation, the item to the left of the equal sign is a CAM chemistry compound, the
items to the right are compounds known to the MEGAN model (single or combinations).
+ Long lines for equations can be split into multiple specifiers
For example: megan_specifier = 'ISOP = isoprene', 'C10H16 = pinene_a + carene_3 + thujene_a'
+ or... megan_specifier = 'SOAE = 0.5954*isoprene + 5.1004*(carene_3 + pinene_a + thujene_a + bornene +',
+ ' terpineol_4 + terpineol_a + terpinyl_ACT_a + myrtenal + sabinene + pinene_b + camphene +',
+ and etcetera...
+
+
+
+
+
+ Which dust emission method is going to be used. Either the Zender 2003 scheme or the Leung 2023 scheme.
+ (NOTE: The Leung 2023 method is NOT currently available)
+
+
+
+ Option only applying for the Zender_2003 method for whether the soil erodibility file is handled
+ in the active LAND model or in the ATM model.
+ (only used when dust_emis_method is Zender_2003)
+
+
+
+
+
+
+
+ Frequency of surface ozone field passed from CAM to surface components.
+ Surface ozone is passed every coupling interval, but this namelist flag
+ indicates whether the timestep-level values are interpolated from a
+ coarser temporal resolution.
+ Default: set by CAM
+
+
+
+
+
+
+
+ If TRUE atmosphere model will provide prognosed lightning flash frequency.
+ (NOTE: NOT CONNECTED INTO CTSM YET)
+
+
diff --git a/bld/namelist_files/use_cases/1850_control.xml b/bld/namelist_files/use_cases/1850_control.xml
index 94ee8c5d0d..6ea033629f 100644
--- a/bld/namelist_files/use_cases/1850_control.xml
+++ b/bld/namelist_files/use_cases/1850_control.xml
@@ -8,47 +8,18 @@
constant
-.false.
-.false.
-.false.
+.false.
-1850
-1850
+1850
+1850
-1850
-1850
+1850
+1850
-1850
-1850
+1850
+1850
-1850
-1850
-
-1850
-1850
-
-1850
-1850
-
-1850
-1850
-
-1850
-1850
-
-1850
-1850
-
-lnd/clm2/ndepdata/fndep_clm_WACCM6_CMIP6piControl001_y21-50avg_1850monthly_0.95x1.25_c180802.nc
-
-lnd/clm2/ndepdata/fndep_clm_WACCM6_CMIP6piControl001_y21-50avg_1850monthly_0.95x1.25_c180802.nc
-
-lnd/clm2/ndepdata/fndep_clm_WACCM6_CMIP6piControl001_y21-50avg_1850monthly_0.95x1.25_c180802.nc
-
-cycle
-cycle
diff --git a/bld/namelist_files/use_cases/1850_noanthro_control.xml b/bld/namelist_files/use_cases/1850_noanthro_control.xml
index 636164a729..d84903f43c 100644
--- a/bld/namelist_files/use_cases/1850_noanthro_control.xml
+++ b/bld/namelist_files/use_cases/1850_noanthro_control.xml
@@ -10,26 +10,11 @@
.false.
-1850
-1850
+1850
+1850
-1850
-1850
-
-1850
-1850
-
-cycle
-cycle
-
-1925
-1925
-
-1925
-1925
-
-1925
-1925
+1925
+1925
none
nn
-1850
-1850
-
-1850
-1850
-
-1850
-1850
+1850
+1850
NONE
diff --git a/bld/namelist_files/use_cases/2000_control.xml b/bld/namelist_files/use_cases/2000_control.xml
index f3c4980fc8..2fce7c5cce 100644
--- a/bld/namelist_files/use_cases/2000_control.xml
+++ b/bld/namelist_files/use_cases/2000_control.xml
@@ -8,37 +8,17 @@
constant
-.true.
-.false.
-.true.
-.false.
-.false.
+.true.
+.false.
+.false.
-2000
-2000
+2000
+2000
-2000
-2000
+2000
+2000
-2000
-2000
-
-2000
-2000
-
-2000
-2000
-
-2000
-2000
-
-2000
-2000
-
-2000
-2000
-
-2000
-2000
+2000
+2000
diff --git a/bld/namelist_files/use_cases/2010_control.xml b/bld/namelist_files/use_cases/2010_control.xml
index 9316ecfb7f..2f72624077 100644
--- a/bld/namelist_files/use_cases/2010_control.xml
+++ b/bld/namelist_files/use_cases/2010_control.xml
@@ -8,44 +8,17 @@
constant
-.true.
-.true.
-.false.
-.true.
-.false.
-.false.
+.true.
+.false.
+.false.
-2010
-2010
+2010
+2010
-2010
-2010
+2010
+2010
-2010
-2010
-
-2010
-2010
-
-2010
-2010
-
-2010
-2010
-
-2010
-2010
-
-2010
-2010
-
-2010
-2010
-
-2010
-2010
-
-2010
-2010
+2010
+2010
diff --git a/bld/namelist_files/use_cases/2018-PD_transient.xml b/bld/namelist_files/use_cases/2018-PD_transient.xml
new file mode 100644
index 0000000000..96f14207ad
--- /dev/null
+++ b/bld/namelist_files/use_cases/2018-PD_transient.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+Simulate transient Nitrogen-deposition, aerosol deposition, urban, and fire related (pop-density, lightning) changes from 2018 to current day with a mix of historical data, and future scenario data
+Simulate transient Nitrogen-deposition, aerosol deposition, urban, and fire related (pop-density, lightning) changes from 2018 to current day with a mix of historical data, and future scenario data
+Simulate transient urban and aerosol deposition changes from 2018 to current day with a mix of historical data, and future scenario data
+
+
+
+2018
+
+1850-2100
+
+
+SSP3-7.0
+
+2018
+2022
+2018
+
+2018
+2022
+2018
+
+2018
+2022
+2018
+
+
diff --git a/bld/namelist_files/use_cases/2018_control.xml b/bld/namelist_files/use_cases/2018_control.xml
new file mode 100644
index 0000000000..28554074c4
--- /dev/null
+++ b/bld/namelist_files/use_cases/2018_control.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+Conditions to simulate 2018 land-use
+
+2018
+
+constant
+
+
+SSP3-7.0
+
+
diff --git a/bld/namelist_files/use_cases/20thC_transient.xml b/bld/namelist_files/use_cases/20thC_transient.xml
index d6dd729b35..6cbf9e0d38 100644
--- a/bld/namelist_files/use_cases/20thC_transient.xml
+++ b/bld/namelist_files/use_cases/20thC_transient.xml
@@ -18,46 +18,20 @@
flanduse_timeseries
-.true.
-.false.
-.true.
-.false.
-.false.
-
-1850
-2015
-1850
-
-1850
-2015
-1850
-
-1850
-2015
-1850
-
-1850
-2016
-1850
-
-1850
-2016
-1850
-
-1850
-2016
-1850
-
-1850
-2106
-1850
-
-1850
-2106
-1850
-
-1850
-2106
-1850
+.true.
+.false.
+.false.
+
+1850
+2015
+1850
+
+1850
+2016
+1850
+
+1850
+2106
+1850
diff --git a/bld/namelist_files/use_cases/README b/bld/namelist_files/use_cases/README
index 4ccaf00bdc..f139759b57 100644
--- a/bld/namelist_files/use_cases/README
+++ b/bld/namelist_files/use_cases/README
@@ -2,9 +2,7 @@ $CTSMROOT/namelist_files/use_cases/README Jun/08/2018
Naming Convention for CLM use-cases
-It's important that this naming convention be followed so that the PTCLMmkdata.py
-utility can parse the use-cases appropriately. The build-namelist script also
-checks for conformance with these conventions and won't work for names that
+The build-namelist script checks for conformance with these conventions and won't work for names that
don't follow the convention.
Ending suffix requires one of these endings: _transient, _control or _pd
@@ -17,6 +15,10 @@ Transient cases:
20thC$desc_transient (means nominal 1850-2000 although some datasets are 1850-2005)
+ or
+
+ yyyy-PD_$desc_transient (means nominal year yyyy through present day (PD) (with the year for PD advancing)
+
Control cases:
yyyy$desc_control
@@ -30,6 +32,7 @@ Where
yyyy = Simulation year (such as 1850 or 2000).
yyyy-yyyy = Range of simulation years to run over (i.e.. 1850-2000).
+yyyy-PD = Range of simulation years to run over until present day (i.e.. 2018-2024).
$ssp_rcp = Shared Socieconomic Pathway (SSP) Representative concentration pathway (RCP) description string
for future scenarios:
SSP#-#.# (for example: SSP5-8.5, SSP1-2.6, SSP4-6.0
diff --git a/bld/namelist_files/use_cases/stdurbpt_pd.xml b/bld/namelist_files/use_cases/stdurbpt_pd.xml
index 65786f32ae..6f5e754ba0 100644
--- a/bld/namelist_files/use_cases/stdurbpt_pd.xml
+++ b/bld/namelist_files/use_cases/stdurbpt_pd.xml
@@ -18,10 +18,8 @@
'OFF'
-.true.
-.false.
-.true.
-.false.
-.false.
+.true.
+.false.
+.false.
diff --git a/bld/queryDefaultNamelist.pl b/bld/queryDefaultNamelist.pl
deleted file mode 100755
index 920e91eb48..0000000000
--- a/bld/queryDefaultNamelist.pl
+++ /dev/null
@@ -1,315 +0,0 @@
-#!/usr/bin/env perl
-#=======================================================================
-#
-# This is a script to read the CLM namelist XML file
-#
-# Usage:
-#
-# queryDefaultNamelist.pl [options]
-#
-# To get help on options and usage:
-#
-# queryDefaultNamelist.pl -help
-#
-#=======================================================================
-
-use Cwd;
-use strict;
-#use diagnostics;
-use Getopt::Long;
-use English;
-
-#-----------------------------------------------------------------------------------------------
-
-#Figure out where configure directory is and where can use the XML/Lite module from
-my $ProgName;
-($ProgName = $PROGRAM_NAME) =~ s!(.*)/!!; # name of program
-my $ProgDir = $1; # name of directory where program lives
-
-my $cwd = getcwd(); # current working directory
-my $cfgdir;
-
-if ($ProgDir) { $cfgdir = $ProgDir; }
-else { $cfgdir = $cwd; }
-
-#-----------------------------------------------------------------------------------------------
-# Add $cfgdir to the list of paths that Perl searches for modules
-my @dirs = ( "$cfgdir",
- "$cfgdir/../cime/utils/perl5lib",
- "$cfgdir/../../../cime/utils/perl5lib" );
-unshift @INC, @dirs;
-my $result = eval "require XML::Lite";
-if ( ! defined($result) ) {
- die <<"EOF";
-** Cannot find perl module \"XML/Lite.pm\" from directories: @dirs **
-EOF
-}
-require Build::Config;
-require Build::NamelistDefinition;
-require queryDefaultXML;
-
-# Defaults
-my $namelist = "clm_inparm";
-my $config = "config_cache.xml";
-
-
-sub usage {
- die < $namelist,
- var => undef,
- hgrid => undef,
- config => undef,
- cesm => undef,
- csmdata => undef,
- demand => undef,
- test => undef,
- onlyfiles => undef,
- fileonly => undef,
- silent => undef,
- usrname => undef,
- help => undef,
- options => undef,
- );
-
- my $cmdline = "@ARGV";
- GetOptions(
- "f|file=s" => \$opts{'file'},
- "n|namelist=s" => \$opts{'namelist'},
- "v|var=s" => \$opts{'var'},
- "r|res=s" => \$opts{'hgrid'},
- "config=s" => \$opts{'config'},
- "cesm" => \$opts{'cesm'},
- "csmdata=s" => \$opts{'csmdata'},
- "demand" => \$opts{'demand'},
- "options=s" => \$opts{'options'},
- "t|test" => \$opts{'test'},
- "onlyfiles" => \$opts{'onlyfiles'},
- "filenameonly" => \$opts{'fileonly'},
- "justvalues" => \$opts{'justvalues'},
- "usrname=s" => \$opts{'usrname'},
- "s|silent" => \$opts{'silent'},
- "h|elp" => \$opts{'help'},
- ) or usage();
-
- # Check for unparsed arguments
- if (@ARGV) {
- print "ERROR: unrecognized arguments: @ARGV\n";
- usage();
- }
- if ( $opts{'help'} ) {
- usage();
- }
- # Set if should do extra printing or not (if silent mode is not set)
- my $printing = 1;
- if ( defined($opts{'silent'}) ) {
- $printing = 0;
- }
- # Get list of options from command-line into the settings hash
- my %settings;
- if ( defined($opts{'options'}) ) {
- $opts{'options'} =~ s/\s//g; # Remove all white-space in options
- my @optionlist = split( ",", $opts{'options'} );
- foreach my $item ( @optionlist ) {
- my ($key,$value) = split( "=", $item );
- $settings{$key} = $value;
- }
- }
- my $csmdata = "";
- if ( defined($opts{'fileonly'}) ) {
- if ( ! defined($opts{'justvalues'}) ) { print "When -filenameonly option used, -justvalues is set as well\n" if $printing; }
- if ( ! defined($opts{'onlyfiles'}) ) { print "When -filenameonly option used, -onlyfiles is set as well\n" if $printing; }
- $opts{'justvalues'} = 1;
- $opts{'onlyfiles'} = 1;
- }
- # List of input options
- my %inputopts;
- # This namelist files under the cime directories are in version 2 format and can't be read by perl code EBK 11/15/2016
- my @nl_definition_files = ("$cfgdir/namelist_files/namelist_definition_drv.xml",
- "$cfgdir/namelist_files/namelist_definition_ctsm.xml"
- );
- $inputopts{empty_cfg_file} = "$cfgdir/config_files/config_definition_ctsm.xml";
- $inputopts{nldef_files} = \@nl_definition_files;
- $inputopts{namelist} = $opts{namelist};
- $inputopts{printing} = $printing;
- $inputopts{cfgdir} = $cfgdir;
- $inputopts{ProgName} = $ProgName;
- $inputopts{cmdline} = $cmdline;
-
- my $exitearly = 0;
- my $definition = Build::NamelistDefinition->new( $nl_definition_files[0] );
- foreach my $nl_defin_file ( @nl_definition_files ) {
- if ( ! -f "$nl_defin_file" ) {
- die "($ProgName $cmdline) ERROR:: bad namelist definition filename: $nl_defin_file.\n";
- }
- $definition->add( "$nl_defin_file" );
- }
-
- if ( ! defined($opts{csmdata}) ) {
- $inputopts{csmdata} = "default";
- } else {
- $inputopts{csmdata} = $opts{csmdata};
- }
- if ( defined($opts{cesm}) ) {
- $inputopts{csmdata} = '$DIN_LOC_ROOT';
- }
- if ( ! defined($opts{config}) ) {
- $inputopts{config} = "noconfig";
- } else {
- $inputopts{config} = $opts{config};
- }
- if ( ! defined($opts{var}) ) {
- $settings{'var'} = undef;
- } elsif ( $opts{var} eq "list" ) {
- print "Valid variables: " if $printing;
- my @vars = $definition->get_var_names( );
- print "@vars\n";
- $exitearly = 1;
- } else {
- $settings{'var'} = $opts{'var'};
- }
- if ( ! defined($opts{hgrid}) ) {
- $inputopts{hgrid} = "any";
- } elsif ( $opts{hgrid} eq "list" ) {
- print "Valid resolutions: " if $printing;
- my @hgrids = $definition->get_valid_values( "res", 'noquotes'=>1 );
- print "@hgrids\n";
- $exitearly = 1;
- } else {
- if ( ! $definition->is_valid_value( "res", $opts{hgrid}, 'noquotes'=>1 ) ) {
- if ( $opts{'hgrid'} ne $opts{'usrname'} ) {
- die "($ProgName $cmdline) ERROR:: invalid resolution entered.\n";
- }
- }
- $inputopts{hgrid} = $opts{hgrid};
- }
- # The namelist defaults file contains default values for all required namelist variables.
- my @nl_defaults_files = ( "$cfgdir/namelist_files/namelist_defaults_overall.xml" );
- if ( defined($opts{'usrname'}) ) {
- my $nl_defaults_file = "$cfgdir/namelist_files/namelist_defaults_usr_files.xml";
- push( @nl_defaults_files, $nl_defaults_file );
- $settings{'clm_usr_name'} = $opts{'usrname'};
- $settings{'notest'} = ! $opts{'test'};
- $settings{'csmdata'} = $inputopts{csmdata};
- } else {
- my @files = ( "$cfgdir/namelist_files/namelist_defaults_ctsm.xml",
- "$cfgdir/namelist_files/namelist_defaults_ctsm_tools.xml",
- "$cfgdir/namelist_files/namelist_defaults_drv.xml",
- "$cfgdir/namelist_files/namelist_defaults_drydep.xml",
- );
- push( @nl_defaults_files, @files );
- }
- if ( ! $exitearly ) {
- $inputopts{files} = \@nl_defaults_files;
-
- my $defaults_ref = &queryDefaultXML::ReadDefaultXMLFile( \%inputopts, \%settings );
- my %defaults = %$defaults_ref;
- my @keys = keys(%defaults);
- if ( defined($opts{'demand'}) && ($#keys == -1) ) {
- die "($ProgName $cmdline) ERROR:: demand option is set and nothing was found.\n";
- }
- my $print;
- foreach my $var ( @keys ) {
- $print = 1;
- my $value = $defaults{$var}{value};
- my $isadir = $defaults{$var}{isdir};
- my $isafile = $defaults{$var}{isfile};
- my $isastr = $defaults{$var}{isstr};
- # If onlyfiles option set do NOT print if is NOT a file
- if ( defined($opts{'onlyfiles'}) && (! $isafile) ) {
- $print = undef;
- }
- # If is a directory
- if ( $isadir ) {
- # Test that this directory exists
- if ( defined($opts{'test'}) && defined($print) ) {
- print "Test that directory $value exists\n" if $printing;
- if ( ! -d "$value" ) {
- die "($ProgName) ERROR:: directory $value does NOT exist!\n";
- }
- }
- }
- # If is a file
- if ( $isafile ) {
- # Test that this file exists
- if ( defined($opts{'test'}) && defined($print) ) {
- chomp( $value );
- print "Test that file $value exists\n" if $printing;
- if ( ! -f "$value" ) {
- die "($ProgName) ERROR:: file $value does NOT exist!\n";
- }
- }
- }
- # If a string
- if ( (! defined($opts{'justvalues'}) ) && ($isastr) ) {
- $value = "\'$value\'";
- }
- # if you just want the filename -- not the full path with the directory
- if ( defined($opts{'fileonly'}) ) {
- $value =~ s!(.*)/!!;
- }
- if ( defined($print) ) {
- if ( ! defined($opts{'justvalues'}) ) {
- print "$var = ";
- }
- print "$value\n";
- }
- }
- }
- if ( $printing && defined($opts{'test'}) ) {
- print "\n\nTesting was successful\n\n"
- }
-
diff --git a/bld/queryDefaultXML.pm b/bld/queryDefaultXML.pm
deleted file mode 100644
index 85a81d8f9a..0000000000
--- a/bld/queryDefaultXML.pm
+++ /dev/null
@@ -1,161 +0,0 @@
-#=======================================================================
-#
-# This is a perl module to read in a list of namelist_default files.
-#
-#=======================================================================
-use strict;
-use Build::Config;
-use Build::NamelistDefinition;
-use Build::NamelistDefaults;
-use Build::Namelist;
-
-package queryDefaultXML;
-
-#-------------------------------------------------------------------------------
-
-sub read_cfg_file
-#
-# Read in the configuration cache XML file on the build-time configuration
-#
-{
- my ($file, $empty_cfg_file, $printing, $settings_ref) = @_;
-
- my $cfg;
- my %config;
- if ( $file eq "noconfig" ) {
- print "No configuration cache file to read in.\n" if $printing;
- $cfg = Build::Config->new( $empty_cfg_file );
- } elsif ( -f "$file" ) {
- $cfg = Build::Config->new($file);
- } else {
- die "Bad filename entered: $file does NOT exist or can not open it.\n";
- }
- #
- # Make sure variables are set to valid values
- #
- foreach my $key ( keys( %config ) ) {
- if ( $cfg->is_valid_name( $key ) ) {
- $cfg->set( $key, $config{$key} );
- }
- }
- foreach my $key ( $cfg->get_names( ) ) {
- if ( defined($$settings_ref{$key}) ) {
- if ( $cfg->is_valid_name( $key ) ) {
- $cfg->set( $key, $$settings_ref{$key} );
- }
- }
- }
- return( $cfg );
-}
-
-#-------------------------------------------------------------------------------
-
-sub ReadDefaultXMLFile {
-#
-# Read in the default XML file for the default namelist settings
-#
- my $opts_ref = shift;
- my $settings_ref = shift;
-
- # Error check that input and opts hash has the expected variables
- my $ProgName = $$opts_ref{'ProgName'};
- my $nm = "${ProgName}::ReadDefaultXMLFile";
- my @required_list = ( "files", "nldef_files", "empty_cfg_file", "config", "namelist",
- "csmdata", "hgrid", "printing", "ProgName", "cmdline",
- "cfgdir" );
- foreach my $var ( @required_list ) {
- if ( ! defined($$opts_ref{$var}) ) {
- die "ERROR($nm): Required input variable $var was not found\n";
- }
- }
- my $printing = $$opts_ref{'printing'};
- my $cmdline = $$opts_ref{'cmdline'};
- # Initialize some local variables
- my $files_ref = $$opts_ref{'files'};
- my @files = @$files_ref;
- my $nldef_ref = $$opts_ref{'nldef_files'};
- my @nl_definition_files= @$nldef_ref;
- my $empty_config_file = $$opts_ref{'empty_cfg_file'};
- my $namelist = $$opts_ref{'namelist'};
-
- my $cfg = read_cfg_file( $$opts_ref{'config'}, $$opts_ref{'empty_cfg_file'},
- $printing, $settings_ref );
-
- #
- # Set up options to send to namelist defaults object
- #
- my %nlopts;
- foreach my $var ( keys( %$settings_ref) ) {
- if ( $var ne "csmdata" ) {
- $nlopts{$var} = $$settings_ref{$var};
- }
- }
- if ( $$opts_ref{'hgrid'} ne "any" ) {
- $nlopts{'hgrid'} = $$opts_ref{'hgrid'};
- }
- #
- # Loop through all variables in files
- #
- print "($nm) Read: $files[0]\n" if $printing;
- my %defaults;
- my $nldefaults = Build::NamelistDefaults->new($files[0], $cfg);
- for ( my $i = 1; $i <= $#files; $i++ ) {
- print "($nm) Read: $files[$i]\n" if $printing;
- $nldefaults->add( $files[$i] );
- }
- my $definition = Build::NamelistDefinition->new( $nl_definition_files[0] );
- for ( my $i = 1; $i <= $#nl_definition_files; $i++ ) {
- print "($nm) Read: $nl_definition_files[$i]\n" if $printing;
- $definition->add( $nl_definition_files[$i] );
- }
- if ( $$opts_ref{'csmdata'} eq "default" ) {
- $$opts_ref{'csmdata'} = $nldefaults->get_value( "csmdata", \%nlopts );
- }
- $nlopts{'csmdata'} = $$opts_ref{'csmdata'};
- foreach my $name ( $nldefaults->get_variable_names() ) {
- my $value = $nldefaults->get_value( $name, \%nlopts );
- if ( $value eq "null" ) { next; }
- if ( defined($$settings_ref{'var'}) ) {
- if ( $name ne $$settings_ref{'var'} ) { next; }
- }
- $value =~ s/\n//g;
- my $isafile = 0;
- if ( $definition->is_input_pathname($name) ) {
-
- if ( defined($$settings_ref{'clm_usr_name'}) ) {
- $value = $nldefaults->get_usr_file( $name, $definition, \%nlopts );
- }
- if ( $value && ($value !~ /^\/.+$/) ) {
- $value = $$opts_ref{'csmdata'} . "/" . $value;
- }
- $isafile = 1;
- }
- my $isadir = 0;
- my $isastr = 0;
- if ( $definition->get_str_len($name) > 0 ) {
- $isastr = 1;
- }
- #
- # If is a directory (is a file and csmdata or a var with dir in name)
- #
- if ( $isafile && (($name eq "csmdata") || ($name =~ /dir/)) ) {
- if ( $name eq "csmdata" ) {
- $value = $$opts_ref{'csmdata'};
- $isadir = 1;
- } else {
- $isadir = 1;
- }
- }
- # Return hash with the results
- my $group = $definition->get_group_name( $name );
- if ( $group eq $namelist && $value && (! exists($defaults{$name}{'value'})) ) {
- $defaults{$name}{'value'} = $value;
- $defaults{$name}{'isfile'} = $isafile;
- $defaults{$name}{'isdir'} = $isadir;
- $defaults{$name}{'isstr'} = $isastr;
- }
- }
- return( \%defaults );
-}
-
-1 # To make use or require happy
diff --git a/bld/unit_testers/Buildconf/camconf/drv_flds_in b/bld/unit_testers/Buildconf/camconf/drv_flds_in
new file mode 100644
index 0000000000..c551ccacf5
--- /dev/null
+++ b/bld/unit_testers/Buildconf/camconf/drv_flds_in
@@ -0,0 +1,24 @@
+&drydep_inparm
+ dep_data_file = '/glade/campaign/cesm/cesmdata/inputdata/atm/cam/chem/trop_mozart/dvel/dep_data_c20221208.nc'
+ drydep_list = 'DMS','H2O2','H2SO4','SO2','SOAG'
+/
+&megan_emis_nl
+ megan_factors_file = '/glade/campaign/cesm/cesmdata/inputdata/atm/cam/chem/trop_mozart/emis/megan21_emis_factors_78pft_c20161108.nc'
+ megan_mapped_emisfctrs = .false.
+ megan_specifier = 'SOAE = 0.5954*isoprene + 5.1004*(carene_3 + pinene_a + thujene_a + bornene +', ' terpineol_4 + terpineol_a + terpinyl_ACT_a + myrtenal + sabinene + pinene_b + camphene +',
+ ' fenchene_a + limonene + phellandrene_a + terpinene_a + terpinene_g + terpinolene +', ' phellandrene_b + linalool + ionone_b + geranyl_acetone + neryl_acetone + jasmone +',
+ ' verbenene + ipsenol + myrcene + ocimene_t_b + ocimene_al + ocimene_c_b + 2met_nonatriene) + ', ' 12.3942*(farnescene_a + caryophyllene_b + acoradiene + aromadendrene + bergamotene_a +',
+ ' bergamotene_b + bisabolene_a + bisabolene_b + bourbonene_b + cadinene_d + cadinene_g +', ' cedrene_a + copaene_a + cubebene_a + cubebene_b + elemene_b + farnescene_b +',
+ ' germacrene_B + germacrene_D + gurjunene_b + humulene_a + humulene_g + isolongifolene +', ' longifolene + longipinene + muurolene_a + muurolene_g + selinene_b + selinene_d +',
+ ' nerolidol_c + nerolidol_t)'
+/
+&dust_emis_inparm
+ dust_emis_method = 'Zender_2003'
+ zender_soil_erod_source = 'atm'
+/
+&lightning_coupling_nl
+ atm_provides_lightning = .true.
+/
+&ozone_coupling_nl
+ atm_ozone_frequency = 'multiday_average'
+/
diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl
index f6c8d75937..bab664666c 100755
--- a/bld/unit_testers/build-namelist_test.pl
+++ b/bld/unit_testers/build-namelist_test.pl
@@ -42,7 +42,7 @@ sub make_env_run {
my %settings = @_;
# Set default settings
- my %env_vars = ( DIN_LOC_ROOT=>"MYDINLOCROOT", GLC_TWO_WAY_COUPLING=>"FALSE" );
+ my %env_vars = ( DIN_LOC_ROOT=>"MYDINLOCROOT", GLC_TWO_WAY_COUPLING=>"FALSE", LND_SETS_DUST_EMIS_DRV_FLDS=>"TRUE", NEONSITE=>"", PLUMBER2SITE=>"" );
# Set any settings that came in from function call
foreach my $item ( keys(%settings) ) {
$env_vars{$item} = $settings{$item};
@@ -78,7 +78,7 @@ sub make_config_cache {
-Specifies clm physics
+Specifies clm physics
EOF
$fh->close();
@@ -139,7 +139,7 @@ sub cat_and_create_namelistinfile {
$inputdata_rootdir = $ENV{'CSMDATA'};
} else {
# use yellowstone location as default
- $inputdata_rootdir="/glade/p/cesm/cseg/inputdata";
+ $inputdata_rootdir="/glade/campaign/cesm/cesmdata/cseg/inputdata";
print("WARNING: -csmdata nor CSMDATA are set, using default yellowstone location: $inputdata_rootdir\n");
}
@@ -163,9 +163,10 @@ sub cat_and_create_namelistinfile {
#
# Figure out number of tests that will run
#
-my $ntests = 1846;
+my $ntests = 3997;
+
if ( defined($opts{'compare'}) ) {
- $ntests += 1254;
+ $ntests += 2437;
}
plan( tests=>$ntests );
@@ -188,9 +189,8 @@ sub cat_and_create_namelistinfile {
my $mode = "-phys $phys";
&make_config_cache($phys);
-my $DOMFILE = "$inputdata_rootdir/atm/datm7/domain.lnd.T31_gx3v7.090928.nc";
-my $real_par_file = "user_nl_ctsm_real_parameters";
-my $bldnml = "../build-namelist -verbose -csmdata $inputdata_rootdir -configuration clm -structure standard -glc_nec 10 -no-note -output_reals $real_par_file";
+my $DOMFILE = "$inputdata_rootdir/atm/datm7/domain.lnd.fv0.9x1.25_gx1v6.090309.nc";
+my $bldnml = "../build-namelist -verbose -csmdata $inputdata_rootdir -configuration clm -structure standard -glc_nec 10 -no-note";
if ( $opts{'test'} ) {
$bldnml .= " -test";
}
@@ -200,7 +200,7 @@ sub cat_and_create_namelistinfile {
system( "/bin/rm $tempfile" );
}
-my @files = ( "lnd_in", $tempfile, $real_par_file );
+my @files = ( "lnd_in", $tempfile );
my $cwd = `pwd`;
chomp( $cwd );
my $cfiles = NMLTest::CompFiles->new( $cwd, @files );
@@ -259,7 +259,7 @@ sub cat_and_create_namelistinfile {
# Exercise a bunch of options
my $options = "-co2_ppmv 250 ";
- $options .= " -res 0.9x1.25 -ssp_rcp SSP1-2.6 -envxml_dir .";
+ $options .= " -res 10x15 -ssp_rcp SSP2-4.5 -envxml_dir .";
&make_env_run();
eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
@@ -268,13 +268,11 @@ sub cat_and_create_namelistinfile {
$cfiles->copyfiles( "most_options", $mode );
# Compare to default
$cfiles->doNOTdodiffonfile( "lnd_in", "default", $mode );
- $cfiles->doNOTdodiffonfile( "$real_par_file", "default", $mode );
$cfiles->doNOTdodiffonfile( "$tempfile", "default", $mode );
$cfiles->comparefiles( "default", $mode );
# Compare to baseline
if ( defined($opts{'compare'}) ) {
$cfiles->dodiffonfile( "lnd_in", "most_options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "most_options", $mode );
$cfiles->doNOTdodiffonfile( "$tempfile", "most_options", $mode );
$cfiles->comparefiles( "most_options", $mode, $opts{'compare'} );
}
@@ -316,28 +314,33 @@ sub cat_and_create_namelistinfile {
print "=================================================================================\n";
my $startfile = "clmrun.clm2.r.1964-05-27-00000.nc";
-foreach my $driver ( "mct", "nuopc" ) {
+foreach my $driver ( "nuopc" ) {
print " For $driver driver\n\n";
# configuration, structure, irrigate, verbose, clm_demand, ssp_rcp, test, sim_year, use_case
- foreach my $options ( "-configuration nwp",
- "-structure fast",
- "-namelist '&a irrigate=.true./'", "-verbose", "-ssp_rcp SSP1-2.6", "-test", "-sim_year 1850",
- "-namelist '&a use_lai_streams=.true.,use_soil_moisture_streams=.true./'",
- "-use_case 1850_control",
+ foreach my $options ( "-res 0.9x1.25 -configuration nwp",
+ "-res 0.9x1.25 -structure fast",
+ "-res 0.9x1.25 -namelist '&a irrigate=.true./'", "-res 0.9x1.25 -verbose", "-res 0.9x1.25 -ssp_rcp SSP2-4.5", "-res 0.9x1.25 -test", "-res 0.9x1.25 -sim_year 1850",
+ "-res 0.9x1.25 -namelist '&a use_lai_streams=.true.,use_soil_moisture_streams=.true./'",
+ "-res 0.9x1.25 -namelist '&a use_excess_ice=.true. use_excess_ice_streams=.true./'",
+ "-res 0.9x1.25 --clm_start_type cold -namelist '&a use_excess_ice=.true. use_excess_ice_streams=.true./'",
+ "-res 0.9x1.25 -use_case 1850_control",
"-res 1x1pt_US-UMB -clm_usr_name 1x1pt_US-UMB -namelist '&a fsurdat=\"/dev/null\"/'",
"-res 1x1_brazil",
- "-clm_start_type startup", "-namelist '&a irrigate=.false./' -crop -bgc bgc",
- "-envxml_dir . -infile myuser_nl_clm",
- "-ignore_ic_date -clm_start_type branch -namelist '&a nrevsn=\"thing.nc\"/' -bgc bgc -crop",
- "-clm_start_type branch -namelist '&a nrevsn=\"thing.nc\",use_init_interp=T/'",
- "-ignore_ic_date -clm_start_type startup -namelist '&a finidat=\"thing.nc\"/' -bgc bgc -crop",
+ "-namelist '&a use_matrixcn=F,use_soil_matrixcn=F,hist_wrt_matrixcn_diag=F,spinup_matrixcn=F/' -bgc sp",
+ "-namelist '&a use_matrixcn=T,use_soil_matrixcn=T,hist_wrt_matrixcn_diag=T,spinup_matrixcn=T/' -bgc bgc -crop -clm_accelerated_spinup on",
+ "-namelist \"&a soil_decomp_method='MIMICSWieder2015',use_matrixcn=F/\" -bgc bgc -crop",
+ "-namelist \"&a soil_decomp_method='MIMICSWieder2015',use_matrixcn=T/\" -bgc bgc -crop",
+ "-bgc bgc -crop -clm_accelerated_spinup sasu",
+ "-res 0.9x1.25 -clm_start_type startup", "-namelist '&a irrigate=.false./' -crop -bgc bgc",
+ "-res 0.9x1.25 -infile myuser_nl_clm",
+ "-res 0.9x1.25 -ignore_ic_date -clm_start_type branch -namelist '&a nrevsn=\"thing.nc\"/' -bgc bgc -crop",
+ "-res 0.9x1.25 -clm_start_type branch -namelist '&a nrevsn=\"thing.nc\",use_init_interp=T/'",
+ "-res 0.9x1.25 -ignore_ic_date -clm_start_type startup -namelist '&a finidat=\"thing.nc\"/' -bgc bgc -crop",
) {
my $file = $startfile;
&make_env_run();
- my $base_options = "-res 0.9x1.25 -envxml_dir . -driver $driver";
- if ( $driver eq "mct" ) {
- $base_options = "$base_options -lnd_frac $DOMFILE";
- } else {
+ my $base_options = "-envxml_dir . -driver $driver";
+ if ( $driver eq "nuopc" ) {
$base_options = "$base_options -namelist '&a force_send_to_atm = .false./'";
}
eval{ system( "$bldnml $base_options $options > $tempfile 2>&1 " ); };
@@ -351,7 +354,6 @@ sub cat_and_create_namelistinfile {
}
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$base_options $options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$base_options $options", $mode );
$cfiles->comparefiles( "$base_options $options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -363,7 +365,7 @@ sub cat_and_create_namelistinfile {
print "\n===============================================================================\n";
print "Test the NEON sites\n";
print "=================================================================================\n";
-my $phys = "clm5_1";
+my $phys = "clm6_0";
$mode = "-phys $phys";
&make_config_cache($phys);
my $neondir = "../../cime_config/usermods_dirs/NEON";
@@ -374,7 +376,7 @@ sub cat_and_create_namelistinfile {
"JORN", "LAJA", "MOAB", "OAES", "OSBS", "SCBI", "SOAP", "STER", "TOOL",
"UNDE", "YELL"
) {
- &make_env_run();
+ &make_env_run( NEONSITE=>"$site" );
#
# Concatonate default usermods and specific sitetogether expanding env variables while doing that
#
@@ -391,9 +393,67 @@ sub cat_and_create_namelistinfile {
my $namelistfile = "temp.namelistinfile_$site";
&cat_and_create_namelistinfile( $neondefaultfile, $neonsitefile, $namelistfile );
#
+ # Now run the site for both bgc and non-FATES
+ #
+ foreach my $bgc ( "bgc", "fates") {
+ if ( ($bgc eq "bgc") or ($site ne "STER" and $site ne "KONA")) {
+ my $options = "--res CLM_USRDAT --clm_usr_name NEON --no-megan --bgc $bgc --use_case 2018_control --infile $namelistfile";
+ eval{ system( "$bldnml -envxml_dir . $options > $tempfile 2>&1 " ); };
+ is( $@, '', "options: $options" );
+ $cfiles->checkfilesexist( "$options", $mode );
+ $cfiles->shownmldiff( "default", $mode );
+ if ( defined($opts{'compare'}) ) {
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->dodiffonfile( "lnd_in", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ }
+ if ( defined($opts{'generate'}) ) {
+ $cfiles->copyfiles( "$options", $mode );
+ }
+ }
+ }
+ system( "/bin/rm $namelistfile" );
+ &cleanup();
+}
+print "\n===============================================================================\n";
+print "Test the PLUMBER2 sites\n";
+print "=================================================================================\n";
+my $phys = "clm6_0";
+$mode = "-phys $phys";
+&make_config_cache($phys);
+my $plumdir = "../../cime_config/usermods_dirs/PLUMBER2";
+foreach my $site (
+ "AR-SLu", "AU-Emr", "AU-TTE", "CA-NS1", "CA-SF3", "CN-HaM", "DE-Obe", "ES-ES1", "FR-Gri", "IE-Dri", "IT-LMa", "IT-SRo", "RU-Fyo", "US-Aud", "US-Ho1", "US-Ne2", "US-Syv", "ZM-Mon",
+ "AT-Neu", "AU-Gin", "AU-Tum", "CA-NS2", "CH-Cha", "CN-Qia", "DE-Seh", "ES-ES2", "FR-Hes", "IT-Amp", "IT-Mal", "JP-SMF", "RU-Zot", "US-Bar", "US-KS2", "US-Ne3", "US-Ton",
+ "AU-ASM", "AU-GWW", "AU-Whr", "CA-NS4", "CH-Dav", "CZ-wet", "DE-SfN", "ES-LgS", "FR-LBr", "IT-BCi", "IT-MBo", "NL-Ca1", "SD-Dem", "US-Bkg", "US-Los", "US-NR1", "US-Tw4",
+ "AU-Cow", "AU-How", "AU-Wrr", "CA-NS5", "CH-Fru", "DE-Bay", "DE-Tha", "ES-LMa", "FR-Lq1", "IT-CA1", "IT-Noe", "NL-Hor", "SE-Deg", "US-Blo", "US-Me2", "US-PFa", "US-Twt",
+ "AU-Cpr", "AU-Lit", "AU-Ync", "CA-NS6", "CH-Oe1", "DE-Wet", "ES-VDA", "FR-Lq2", "IT-CA2", "IT-Non", "NL-Loo", "UK-Gri", "US-Bo1", "US-Me4", "US-Prr", "US-UMB",
+ "AU-Ctr", "AU-Otw", "BE-Bra", "CA-NS7", "CN-Cha", "DE-Geb", "DK-Fou", "FI-Hyy", "FR-Pue", "IT-CA3", "IT-PT1", "PL-wet", "UK-Ham", "US-Cop", "US-Me6", "US-SP1", "US-Var",
+ "AU-Cum", "AU-Rig", "BE-Lon", "CA-Qcu", "CN-Cng", "DE-Gri", "DK-Lva", "FI-Kaa", "GF-Guy", "IT-Col", "IT-Ren", "PT-Esp", "UK-PL3", "US-FPe", "US-MMS", "US-SP2", "US-WCr",
+ "AU-DaP", "AU-Rob", "BE-Vie", "CA-Qfo", "CN-Dan", "DE-Hai", "DK-Ris", "FI-Lom", "HU-Bug", "IT-Cpz", "IT-Ro1", "PT-Mi1", "US-AR1", "US-GLE", "US-MOz", "US-SP3", "US-Whs",
+ "AU-DaS", "AU-Sam", "BR-Sa3", "CA-SF1", "CN-Din", "DE-Kli", "DK-Sor", "FI-Sod", "ID-Pag", "IT-Isp", "IT-Ro2", "PT-Mi2", "US-AR2", "US-Goo", "US-Myb", "US-SRG", "US-Wkg",
+ "AU-Dry", "AU-Stp", "BW-Ma1", "CA-SF2", "CN-Du2", "DE-Meh", "DK-ZaH", "FR-Fon", "IE-Ca1", "IT-Lav", "IT-SR2", "RU-Che", "US-ARM", "US-Ha1", "US-Ne1", "US-SRM", "ZA-Kru"
+ ) {
+ &make_env_run( PLUMBER2SITE=>"$site" );
+ #
+ # Concatonate default usermods and specific sitetogether expanding env variables while doing that
+ #
+ if ( ! -d "$plumdir/$site" ) {
+ print "PLUMBER2 directory is not there: $plumdir/$site\n";
+ die "ERROR:: PLUMBER2 site does not exist: $site\n";
+ }
+ my $plumdefaultfile = "$plumdir/defaults/user_nl_clm";
+ my $plumsitefile = "$plumdir/$site/user_nl_clm";
+ if ( ! -f $plumsitefile ) {
+ $plumsitefile = undef;
+ }
+ $ENV{'PLUMBER2'} = $site;
+ my $namelistfile = "temp.namelistinfile_$site";
+ &cat_and_create_namelistinfile( $plumdefaultfile, $plumsitefile, $namelistfile );
+ #
# Now run the site
#
- my $options = "-res CLM_USRDAT -clm_usr_name NEON -no-megan -bgc bgc -sim_year 2000 -infile $namelistfile";
+ my $options = "--res CLM_USRDAT --clm_usr_name PLUMBER2 --no-megan --bgc sp --infile $namelistfile";
eval{ system( "$bldnml -envxml_dir . $options > $tempfile 2>&1 " ); };
is( $@, '', "options: $options" );
$cfiles->checkfilesexist( "$options", $mode );
@@ -401,7 +461,6 @@ sub cat_and_create_namelistinfile {
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
$cfiles->dodiffonfile( "lnd_in", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
$cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -418,17 +477,17 @@ sub cat_and_create_namelistinfile {
$mode = "-phys $phys";
&make_config_cache($phys);
foreach my $options (
- "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res ne0np4.ARCTICGRIS.ne30x8 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 0.9x1.25 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 0.9x1.25 -bgc bgc -crop -use_case 20thC_transient -namelist '&a start_ymd=19500101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20030101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1.9x2.5 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1x1_brazil -bgc fates -no-megan -use_case 2000_control -lnd_tuning_mode ${phys}_CRUv7",
- "-res C192 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0",
+ "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res ne0np4.ARCTICGRIS.ne30x8 -bgc sp -use_case 1850_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 0.9x1.25 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 0.9x1.25 -bgc bgc -crop -use_case 20thC_transient -namelist '&a start_ymd=19500101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20030101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1.9x2.5 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1x1_brazil -no-megan -use_case 2000_control -lnd_tuning_mode ${phys}_CRUv7",
+ "-res C96 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam7.0",
) {
&make_env_run();
eval{ system( "$bldnml -envxml_dir . $options > $tempfile 2>&1 " ); };
@@ -438,7 +497,6 @@ sub cat_and_create_namelistinfile {
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
$cfiles->dodiffonfile( "lnd_in", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
$cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -447,7 +505,32 @@ sub cat_and_create_namelistinfile {
&cleanup();
}
}
-
+print "\n===============================================================================\n";
+print "Test setting drv_flds_in fields in CAM";
+print "=================================================================================\n";
+foreach my $phys ( "clm5_0", "clm6_0" ) {
+ $mode = "-phys $phys CAM_SETS_DRV_FLDS";
+ &make_config_cache($phys);
+ foreach my $options (
+ "--res 1.9x2.5 --mask gx1v7 --bgc sp --use_case 20thC_transient --namelist '&a start_ymd=19790101/' --lnd_tuning_mode ${phys}_cam6.0 --infile empty_user_nl_clm",
+ "--res 1.9x2.5 --mask gx1v7 --bgc sp --use_case 20thC_transient --namelist '&a start_ymd=19790101/' --lnd_tuning_mode ${phys}_cam7.0 --infile empty_user_nl_clm",
+ ) {
+ &make_env_run( 'LND_SETS_DUST_EMIS_DRV_FLDS'=>"FALSE" );
+ eval{ system( "$bldnml --envxml_dir . $options > $tempfile 2>&1 " ); };
+ is( $@, '', "options: $options" );
+ $cfiles->checkfilesexist( "$options", $mode );
+ $cfiles->shownmldiff( "default", $mode );
+ if ( defined($opts{'compare'}) ) {
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->dodiffonfile( "lnd_in", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ }
+ if ( defined($opts{'generate'}) ) {
+ $cfiles->copyfiles( "$options", $mode );
+ }
+ &cleanup();
+ }
+}
print "\n==============================================================\n";
print "Test several use_cases and specific configurations for clm5_0\n";
print "==============================================================\n";
@@ -455,17 +538,19 @@ sub cat_and_create_namelistinfile {
$mode = "-phys $phys";
&make_config_cache($phys);
foreach my $options (
- "-bgc bgc -use_case 1850-2100_SSP1-2.6_transient -namelist '&a start_ymd=20100101/'",
- "-bgc sp -use_case 1850-2100_SSP2-4.5_transient -namelist '&a start_ymd=18501223/'",
- "-bgc bgc -use_case 1850-2100_SSP3-7.0_transient -namelist '&a start_ymd=20701029/'",
+ "--res 0.9x1.25 --bgc sp --use_case 1850-2100_SSP2-4.5_transient --namelist '&a start_ymd=18501223/'",
"-bgc fates -use_case 2000_control -no-megan",
"-bgc fates -use_case 20thC_transient -no-megan",
"-bgc fates -use_case 1850_control -no-megan -namelist \"&a use_fates_sp=T, soil_decomp_method='None'/\"",
"-bgc sp -use_case 2000_control -res 0.9x1.25 -namelist '&a use_soil_moisture_streams = T/'",
- "-bgc bgc -use_case 1850-2100_SSP5-8.5_transient -namelist '&a start_ymd=19101023/'",
+ "--res 1.9x2.5 --bgc bgc --use_case 1850-2100_SSP2-4.5_transient --namelist '&a start_ymd=19101023/'",
+ "-namelist \"&a dust_emis_method='Zender_2003', zender_soil_erod_source='lnd' /'\"",
"-bgc bgc -use_case 2000_control -namelist \"&a fire_method='nofire'/\" -crop",
"-res 0.9x1.25 -bgc sp -use_case 1850_noanthro_control -drydep -fire_emis",
"-res 0.9x1.25 -bgc bgc -use_case 1850_noanthro_control -drydep -fire_emis -light_res 360x720",
+ "--bgc bgc --light_res none --namelist \"&a fire_method='nofire'/\"",
+ "--bgc fates --light_res 360x720 --no-megan --namelist \"&a fates_spitfire_mode=2/\"",
+ "--bgc fates --light_res none --no-megan --namelist \"&a fates_spitfire_mode=1/\"",
) {
my $file = $startfile;
&make_env_run();
@@ -476,7 +561,6 @@ sub cat_and_create_namelistinfile {
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
$cfiles->dodiffonfile( "lnd_in", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
$cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -498,432 +582,358 @@ sub cat_and_create_namelistinfile {
my %failtest = (
"coldstart but with IC file"=>{ options=>"-clm_start_type cold -envxml_dir .",
namelst=>"finidat='$finidat'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"clm_demand on finidat" =>{ options=>"-clm_demand finidat -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"blank IC file, not cold" =>{ options=>"-clm_start_type startup -envxml_dir .",
namelst=>"finidat=' '",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"startup without interp" =>{ options=>"-clm_start_type startup -envxml_dir . -bgc sp -sim_year 1850",
namelst=>"use_init_interp=.false., start_ymd=19200901",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"use_crop without -crop" =>{ options=>" -envxml_dir .",
namelst=>"use_crop=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
- "soilm_stream wo use" =>{ options=>"-res 0.9x1.25 -envxml_dir .",
- namelst=>"use_soil_moisture_streams = .false.,stream_fldfilename_soilm='missing_file'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ "LeungDust_WO_Prigent" =>{ options=>" -envxml_dir . -bgc sp",
+ namelst=>"use_prigent_roughness=.true.",
+ phys=>"clm5_1",
+ },
+ "soilm_stream off w file" =>{ options=>"-res 0.9x1.25 -envxml_dir .",
+ namelst=>"use_soil_moisture_streams = .false.,stream_fldfilename_soilm='file_provided_when_off'",
+ phys=>"clm5_0",
+ },
+ "exice_stream off w file" =>{ options=>"-res 0.9x1.25 -envxml_dir .",
+ namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.,stream_fldfilename_exice='file_provided_when_off'",
+ phys=>"clm5_0",
+ },
+ "exice_stream off w mesh" =>{ options=>"-res 0.9x1.25 -envxml_dir .",
+ namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.,stream_meshfile_exice='file_provided_when_off'",
+ phys=>"clm5_0",
+ },
+ "exice off, but stream on" =>{ options=>"-res 0.9x1.25 -envxml_dir .",
+ namelst=>"use_excess_ice=.false., use_excess_ice_streams = .true.,stream_fldfilename_exice='file_provided', stream_meshfile_exice='file_provided'",
phys=>"clm5_0",
},
+ "exice stream off, but setmap"=>{ options=>"-res 0.9x1.25 -envxml_dir .",
+ namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.,stream_mapalgo_exice='bilinear'",
+ phys=>"clm5_0",
+ },
+ "coldstart exice on wo stream"=>{ options=>"-res 0.9x1.25 -envxml_dir . --clm_start_type cold",
+ namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.",
+ phys=>"clm6_0",
+ },
+ "coldstart exice on bad temp" =>{ options=>"-res 0.9x1.25 -envxml_dir . --clm_start_type cold",
+ namelst=>"use_excess_ice=.true., use_excess_ice_streams = .true., excess_ice_coldstart_temp=0.0",
+ phys=>"clm6_0",
+ },
+ "coldstart exice on bad depth" =>{ options=>"-res 0.9x1.25 -envxml_dir . --clm_start_type cold",
+ namelst=>"use_excess_ice=.true., use_excess_ice_streams = .true., excess_ice_coldstart_depth=0.0",
+ phys=>"clm6_0",
+ },
"clm50CNDVwtransient" =>{ options=>" -envxml_dir . -use_case 20thC_transient -dynamic_vegetation -res 10x15 -ignore_warnings",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"decomp_without_cn" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"soil_decomp_method='CENTURYKoven2013'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_with_no_decomp" =>{ options=>" -envxml_dir . -bgc bgc",
namelst=>"soil_decomp_method='None'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"reseed without CN" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"reseed_dead_plants=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"onset_threh w SP" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"onset_thresh_depends_on_veg=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"dribble_crphrv w/o CN" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"dribble_crophrv_xsmrpool_2atm=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"dribble_crphrv w/o crop" =>{ options=>" -envxml_dir . -bgc bgc -no-crop",
namelst=>"dribble_crophrv_xsmrpool_2atm=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"CNDV with flanduse_timeseries - clm4_5"=>{ options=>"-bgc bgc -dynamic_vegetation -envxml_dir . -ignore_warnings",
namelst=>"flanduse_timeseries='my_flanduse_timeseries_file.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_cndv=T without bldnml op"=>{ options=>"-bgc bgc -envxml_dir . -ignore_warnings",
namelst=>"use_cndv=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_cndv=F with dyn_veg op"=>{ options=>"-bgc bgc -dynamic_vegetation -envxml_dir . -ignore_warnings",
namelst=>"use_cndv=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"crop with use_crop false" =>{ options=>"-crop -bgc bgc -envxml_dir .",
namelst=>"use_crop=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"crop without CN" =>{ options=>"-crop -bgc sp -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"toosmall soil w trans" =>{ options=>"-envxml_dir .",
namelst=>"toosmall_soil=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall lake w trans" =>{ options=>"-envxml_dir .",
namelst=>"toosmall_lake=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall crop w trans" =>{ options=>"-bgc bgc -crop -envxml_dir .",
namelst=>"toosmall_crop=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall wetl w trans" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"toosmall_wetland=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall glc w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"toosmall_glacier=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall urban w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"toosmall_urban=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"collapse_urban w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"collapse_urban=T, dyn_transient_crops=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"n_dom_landunits w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"n_dom_landunits=2, dyn_transient_crops=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"n_dom_pfts w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"n_dom_pfts=2, dyn_transient_crops=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"baset_map without crop" =>{ options=>"-bgc bgc -envxml_dir . -no-crop",
namelst=>"baset_mapping='constant'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"mapvary var w/o varymap" =>{ options=>"-crop -bgc bgc -envxml_dir . -crop",
namelst=>"baset_mapping='constant', baset_latvary_slope=1.0, baset_latvary_intercept=10.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"grainproductWOcrop" =>{ options=>"-bgc bgc -no-crop -envxml_dir .",
namelst=>"use_grainproduct=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"interp without finidat" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_init_interp=.true. finidat=' '",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"sp and c13" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c13=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"sp and c14" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c14=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"bombspike no c14" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_c14=.false. use_c14_bombspike=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"use c13 timeseries no cn" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c13_timeseries=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use c13 timeseries no c13"=>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_c13=.false. use_c13_timeseries=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"bombspike no cn" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c14_bombspike=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightres no cn" =>{ options=>"-bgc sp -envxml_dir . -light_res 360x720",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
+ "NEONlightresButGlobal" =>{ options=>"--res 4x5 --bgc bgc --envxml_dir . --light_res 106x740",
+ namelst=>"",
+ phys=>"clm6_0",
+ },
"spno-fire" =>{ options=>"-bgc sp -envxml_dir . -use_case 2000_control",
namelst=>"fire_method='nofire'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightres no fire" =>{ options=>"-bgc bgc -envxml_dir . -light_res 360x720",
namelst=>"fire_method='nofire'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightres none bgc" =>{ options=>"-bgc bgc -envxml_dir . -light_res none",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightresnotnone-nofire" =>{ options=>"-bgc bgc -envxml_dir . -light_res 94x192",
namelst=>"fire_method='nofire'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightresnonenofirelightfil"=>{ options=>"-bgc bgc -envxml_dir . -light_res none",
namelst=>"fire_method='nofire',stream_fldfilename_lightng='build-namelist_test.pl'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightrescontradictlightfil"=>{ options=>"-bgc bgc -envxml_dir . -light_res 360x720",
namelst=>"stream_fldfilename_lightng='build-namelist_test.pl'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"finundated and not methane"=>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_lch4=.false.,finundation_method='h2osfc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"use_cn=true bgc=sp" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_cn=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"freeliv wo fun" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"freelivfix_intercept=9.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_cn=false bgc=bgc" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_cn=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"lower=aqu-45 with/o Zeng" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=4,soilwater_movement_method=1,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"Zeng w lower=flux" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=1,soilwater_movement_method=0,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"Zeng w lower=zeroflux" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=2,soilwater_movement_method=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"Zeng w lower=table" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=3,soilwater_movement_method=0,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_vic=F with -vic op" =>{ options=>"-vichydro -envxml_dir .",
namelst=>"use_vichydro=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"-vic with l_bnd=flux" =>{ options=>"-vichydro -envxml_dir .",
namelst=>"lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"-vic with l_bnd=zeroflux" =>{ options=>"-vichydro -envxml_dir .",
namelst=>"lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm4_5",
- },
- "-vic with origflag=1" =>{ options=>"-vichydro -envxml_dir .",
- namelst=>"origflag=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm4_5",
- },
- "l_bnd=flux with origflag=0"=>{ options=>"-envxml_dir .",
- namelst=>"origflag=0, lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm4_5",
- },
- "l_bnd=zflux with origflag=0"=>{ options=>"-envxml_dir .",
- namelst=>"origflag=0, lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"bedrock with l_bnc=flux" =>{ options=>"-envxml_dir .",
namelst=>"use_bedrock=.true., lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bedrock with l_bnc=tabl" =>{ options=>"-envxml_dir .",
namelst=>"use_bedrock=.true., lower_boundary_condition=3",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bedrock with l_bnc=aqui" =>{ options=>"-envxml_dir .",
namelst=>"use_bedrock=.true., lower_boundary_condition=4",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"zengdeck with l_bnc=flux" =>{ options=>"-envxml_dir .",
namelst=>"soilwater_movement_method=0, lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"zengdeck with l_bnc=z-flux"=>{ options=>"-envxml_dir .",
namelst=>"soilwater_movement_method=0, lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"zengdeck with l_bnc=tabl" =>{ options=>"-envxml_dir .",
namelst=>"soilwater_movement_method=0, lower_boundary_condition=3",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"l_bnd=tabl with h2osfcfl=0"=>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0, lower_boundary_condition=3",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"l_bnd=flux with h2osfcfl=0"=>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0, lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"l_bnd=zflux with h2osfcfl=0"=>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0, lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"h2osfcfl=0 with clm5.0" =>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"45bad lnd_tuning_mode value" =>{ options=>"-lnd_tuning_mode clm5_0_GSWP3 -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"50bad lnd_tuning_mode value" =>{ options=>"-lnd_tuning_mode clm4_5_CRUNCEP -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_spinup without cn" =>{ options=>"-clm_accelerated_spinup on -bgc sp -envxml_dir .",
namelst=>"spinup_state=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"spinup=1 without bldnml op"=>{ options=>"-clm_accelerated_spinup off -bgc bgc -envxml_dir .",
namelst=>"spinup_state=1",,
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_spinup without cn" =>{ options=>"-clm_accelerated_spinup on -bgc sp -envxml_dir .",
namelst=>"spinup_state=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"baseflow w aquifer" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"baseflow_scalar=1.0, lower_boundary_condition=4,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"baseflow w table" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"baseflow_scalar=1.0, lower_boundary_condition=3,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"br_root and bgc=sp" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"br_root=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"both co2_type and on nml" =>{ options=>"-co2_type constant -envxml_dir .",
namelst=>"co2_type='prognostic'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_0",
- },
- "both lnd_frac and on nml" =>{ options=>"-driver mct -lnd_frac $DOMFILE -envxml_dir .",
- namelst=>"fatmlndfrc='frac.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
- "lnd_frac set to UNSET" =>{ options=>"-driver mct -lnd_frac UNSET -envxml_dir .",
- namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
- },
"lnd_frac set but nuopc" =>{ options=>"-driver nuopc -lnd_frac $DOMFILE -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"lnd_frac not set but lilac"=>{ options=>"-driver nuopc -lilac -envxml_dir . -lnd_frac UNSET",
namelst=>"fsurdat='surfdata.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"fatmlndfrc set but nuopc" =>{ options=>"-driver nuopc -envxml_dir .",
namelst=>"fatmlndfrc='frac.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
- },
- "force_send but not nuopc" =>{ options=>"-driver mct -lnd_frac $DOMFILE -envxml_dir .",
- namelst=>"force_send_to_atm = .false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"branch but NO nrevsn" =>{ options=>"-clm_start_type branch -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"glc_nec inconsistent" =>{ options=>"-envxml_dir .",
namelst=>"maxpatch_glc=5",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"NoGLCMec" =>{ options=>"-envxml_dir . -glc_nec 0",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"UpdateGlcContradict" =>{ options=>"-envxml_dir .",
@@ -931,228 +941,365 @@ sub cat_and_create_namelistinfile {
GLC_TWO_WAY_COUPLING=>"TRUE",
phys=>"clm4_5",
},
+ "matrixWOBGC" =>{ options=>"-envxml_dir . -bgc sp",
+ namelst=>"use_matrixcn=.true.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "soilmatrixWOBGC" =>{ options=>"-envxml_dir . -bgc sp",
+ namelst=>"use_soil_matrixcn=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "soilmatrixWmimics" =>{ options=>"-envxml_dir . -bgc bgc",
+ namelst=>"use_soil_matrixcn=T,soil_decomp_method='MIMICSWieder2015'",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "matrixcn_diagWOmatrix" =>{ options=>"-envxml_dir . -bgc bgc",
+ namelst=>"use_soil_matrixcn=.false.,use_matrixcn=F,hist_wrt_matrixcn_diag=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "spinupWOsoilmatrix" =>{ options=>"-envxml_dir . -bgc bgc",
+ namelst=>"use_soil_matrixcn=F,use_matrixcn=T,spinup_matrixcn=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "sasuspinupWOsoilmatx" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_soil_matrixcn=.false.,use_matrixcn=.false.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_1",
+ },
+ "sasuspinupWOCN" =>{ options=>"-envxml_dir . -bgc sp -clm_accelerated_spinup sasu",
+ namelst=>"",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_1",
+ },
+ "nyrforceWOspinup" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_matrixcn=.false.,spinup_matrixcn=F,nyr_forcing=20",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "nyrsasuGTnyrforce" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_matrixcn=.false.,spinup_matrixcn=T,nyr_forcing=20,nyr_sasu=21",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "iloopZero" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_matrixcn=.false.,spinup_matrixcn=T,iloop_avg=0",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "matrixspinupWADmode" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"spinup_matrixcn=T,spinup_state=2",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "matrixspinupWclmaccell" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup off",
+ namelst=>"use_soil_matrixcn=T,spinup_matrixcn=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "fatesWuse_cnmatrix" =>{ options=>"-envxml_dir . -bgc fates",
+ namelst=>"use_matrixcn=.true.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "fatesWuse_soilcnmatrix" =>{ options=>"-envxml_dir . -bgc fates",
+ namelst=>"use_soil_matrixcn=.true.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
"useFATESContradict" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFATESContradict2" =>{ options=>"-envxml_dir . -no-megan",
namelst=>"use_fates=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFATESWCN" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_cn=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useFATESWcrop" =>{ options=>"-bgc fates -envxml_dir . -no-megan -crop",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"useFATESWcreatecrop" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"create_crop_landunit=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useFATESWn_dom_pft" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"n_dom_pfts = 1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useFATESWbMH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_biomass_heat_storage=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"FireNoneButFATESfireon" =>{ options=>"-bgc fates -envxml_dir . -no-megan -light_res none",
namelst=>"fates_spitfire_mode=4",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
+ },
+ "FATESwspitfireOffLigtOn" =>{ options=>"-bgc fates -envxml_dir . -no-megan -light_res 360x720",
+ namelst=>"fates_spitfire_mode=0",
+ phys=>"clm6_0",
+ },
+ "useFATESWluna" =>{ options=>"--bgc fates --envxml_dir . --no-megan",
+ namelst=>"use_luna=TRUE",
+ phys=>"clm6_0",
+ },
+ "useFATESWfun" =>{ options=>"--bgc fates --envxml_dir . --no-megan",
+ namelst=>"use_fun=TRUE",
+ phys=>"clm6_0",
+ },
+ "useFATESWOsuplnitro" =>{ options=>"--bgc fates --envxml_dir . --no-megan",
+ namelst=>"suplnitro='NONE'",
+ phys=>"clm6_0",
},
"FireNoneButBGCfireon" =>{ options=>"-bgc bgc -envxml_dir . -light_res none",
namelst=>"fire_method='li2021gswpfrc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"createcropFalse" =>{ options=>"-bgc bgc -envxml_dir . -no-megan",
namelst=>"create_crop_landunit=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"usespitfireButNOTFATES" =>{ options=>"-envxml_dir . -no-megan",
namelst=>"fates_spitfire_mode=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
+ "usespitfireusefatessp" =>{ options=>"-envxml_dir . --bgc fates",
+ namelst=>"fates_spitfire_mode=1,use_fates_sp=.true.",
+ phys=>"clm5_0",
+ },
+ "usefatesspusefateshydro" =>{ options=>"-envxml_dir . --bgc fates",
+ namelst=>"use_fates_sp=.true.,use_fates_planthydro=.true.",
+ phys=>"clm5_0",
+ },
"useloggingButNOTFATES" =>{ options=>"-envxml_dir . -no-megan",
- namelst=>"use_fates_logging=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ namelst=>"fates_harvest_mode='event_code'",
phys=>"clm4_5",
},
"useinventorybutnotfile" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_inventory_init=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"inventoryfileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_inventory_init=.true., fates_inventory_ctrl_filename='zztop'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ phys=>"clm4_5",
+ },
+ "useFATESLUH2butnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan",
+ namelst=>"use_fates_luh=.true.",
+ phys=>"clm4_5",
+ },
+ "useFATESLUPFTbutnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan",
+ namelst=>"use_fates_lupft=.true.",
+ phys=>"clm4_5",
+ },
+ "inventoryfileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_luh=.true., fluh_timeseries='zztop'",
phys=>"clm4_5",
},
"useMEGANwithFATES" =>{ options=>"-bgc fates -envxml_dir . -megan",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
+ "useFIREEMISwithFATES" =>{ options=>"-bgc fates -envxml_dir . -fire_emis --no-megan",
+ namelst=>"",
+ phys=>"clm4_5",
+ },
"useDRYDEPwithFATES" =>{ options=>"--bgc fates --envxml_dir . --no-megan --drydep",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFATESSPWONOCOMP" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_sp=T,use_fates_nocomp=F",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
- "useFATESTRANSWdynPFT" =>{ options=>"-bgc fates -envxml_dir . -use_case 20thC_transient -no-megan",
- namelst=>"do_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ "useFATESSPwithLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_sp=T,use_fates_luh=T",
phys=>"clm5_0",
},
- "useHYDSTwithFATES" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
- namelst=>"use_hydrstress=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ "useFATESPOTVEGwithHARVEST" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_potentialveg=T,fates_harvest_mode='event_code',use_fates_luh=T",
+ phys=>"clm5_0",
+ },
+ "useFATESHARVEST3WOLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_luh=F,fates_harvest_mode='luhdata_area'",
+ phys=>"clm5_0",
+ },
+ "useFATESLUPFTWOLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_lupft=T,use_fates_luh=F",
phys=>"clm5_0",
},
- "useHYDSTwithdynroot" =>{ options=>"-bgc bgc -envxml_dir . -megan",
- namelst=>"use_hydrstress=.true., use_dynroot=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ "useFATESLUPFTWONOCOMP" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_lupft=T,use_fates_nocomp=F",
phys=>"clm5_0",
},
- "specWOfireemis" =>{ options=>"-envxml_dir . -no-fire_emis",
- namelst=>"fire_emis_specifier='bc_a1 = BC'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ "useFATESLUPFTWOFBG" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_lupft=T,use_fates_fixedbiogeog=F",
+ phys=>"clm5_0",
+ },
+ "useFATESTRANSWdynPFT" =>{ options=>"-bgc fates -envxml_dir . -use_case 20thC_transient -no-megan",
+ namelst=>"do_transient_pfts=T",
phys=>"clm5_0",
},
- "elevWOfireemis" =>{ options=>"-envxml_dir . -no-fire_emis",
- namelst=>"fire_emis_elevated=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ "useHYDSTwithFATES" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_hydrstress=.true.",
phys=>"clm5_0",
},
"noanthro_w_crop" =>{ options=>"-envxml_dir . -res 0.9x1.25 -bgc bgc -crop -use_case 1850_noanthro_control",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"noanthro_w_irrig" =>{ options=>"-envxml_dir . -res 0.9x1.25 -bgc bgc -use_case 1850_noanthro_control",
namelst=>"irrigate=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"spdotransconflict" =>{ options=>"-envxml_dir . -bgc sp -use_case 20thC_transient",
namelst=>"do_transient_pfts=T,do_transient_crops=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ phys=>"clm5_0",
+ },
+ "dogrossandsp" =>{ options=>"--envxml_dir . --bgc sp --use_case 20thC_transient",
+ namelst=>"do_grossunrep=.true.",
+ phys=>"clm5_0",
+ },
+ "dogrossandfates" =>{ options=>"--envxml_dir . --bgc fates --use_case 20thC_transient --no-megan",
+ namelst=>"do_grossunrep=.true.",
+ phys=>"clm5_0",
+ },
+ "dogrossandnottrans" =>{ options=>"--envxml_dir . --bgc bgc --use_case 2000_control",
+ namelst=>"do_grossunrep=.true.",
phys=>"clm5_0",
},
"nocropwfert" =>{ options=>"-envxml_dir . -bgc sp -no-crop",
namelst=>"use_fertilizer=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lmr1WOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"leafresp_method=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lmr2WOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"leafresp_method=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lmr0Wcn" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"leafresp_method=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"nofireButSetcli_scale" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"fire_method='nofire', cli_scale=5.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"nocnButSetrh_low" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"rh_low=5.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"funWOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_fun=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"flexCNWOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_flexibleCN=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"flexCNFUNwcarbonresp" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_flexibleCN=.true.,use_FUN=.true.,carbon_resp_opt=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"funWOnitrif" =>{ options=>"-envxml_dir .",
namelst=>"use_fun=.true., use_nitrif_denitrif=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"SPModeWNitrifNMethane" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_lch4=.true., use_nitrif_denitrif=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"knitrmaxWOnitrif" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_nitrif_denitrif=.false., k_nitr_max=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"respcoefWOnitrif" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_nitrif_denitrif=.false., denitrif_respiration_coefficient=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"respexpWOnitrif" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_nitrif_denitrif=.false., denitrif_respiration_exponent=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lunaWSPandlnctrue" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_luna=.true., lnc_opt=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_0",
- },
- "NOlunabutsetJmaxb1" =>{ options=>"-envxml_dir . -bgc sp",
- namelst=>"use_luna=.false., jmaxb1=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"envxml_not_dir" =>{ options=>"-envxml_dir myuser_nl_clm",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"envxml_emptydir" =>{ options=>"-envxml_dir xFail",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
+ "fates_non_sp_laistreams" =>{ options=>"--envxml_dir . --bgc fates",
+ namelst=>"use_lai_streams=.true., use_fates_sp=.false.",
+ phys=>"clm5_0",
+ },
+ "bgc_non_sp_laistreams" =>{ options=>"--envxml_dir . -bgc bgc",
+ namelst=>"use_lai_streams=.true.",
+ phys=>"clm5_0",
+ },
+ "bgc_laistreams_input" =>{ options=>"--envxml_dir . --bgc bgc",
+ namelst=>"stream_year_first_lai=1999",
+ phys=>"clm5_0",
+ },
+ "crop_laistreams_input" =>{ options=>"--envxml_dir . --bgc sp --crop",
+ namelst=>"use_lai_streams=.true.",
+ phys=>"clm5_0",
+ },
+ "soil_erod_wo_Zender" =>{ options=>"--envxml_dir . --ignore_warnings",
+ namelst=>"dust_emis_method='Leung_2023', stream_meshfile_zendersoilerod = '/dev/null'",
+ phys=>"clm6_0",
+ },
+ "soil_erod_wo_lnd_source" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003', stream_fldfilename_zendersoilerod = '/dev/null', zender_soil_erod_source='atm'",
+ phys=>"clm6_0",
+ },
+ "soil_erod_none_w_Zender" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003', zender_soil_erod_source='none'",
+ phys=>"clm6_0",
+ },
+ "soil_erod_bad_w_Zender" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003', zender_soil_erod_source='zztop'",
+ phys=>"clm6_0",
+ },
+ "Set_Dust_When_CAM_Sets" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003'",
+ LND_SETS_DUST_EMIS_DRV_FLDS=>"FALSE",
+ phys=>"clm6_0",
+ },
);
foreach my $key ( keys(%failtest) ) {
print( "$key\n" );
+ my $var;
+ foreach $var ( "phys" , "options", "namelst" ) {
+ if ( not exists $failtest{$key}{$var} ) {
+ die "ERROR: Subkey $var does not exist for failtest $key\nERROR:Check if you spelled $var correctly\n"
+ }
+ }
+
&make_config_cache($failtest{$key}{"phys"});
my $options = $failtest{$key}{"options"};
my $namelist = $failtest{$key}{"namelst"};
- &make_env_run( GLC_TWO_WAY_COUPLING=>$failtest{$key}{"GLC_TWO_WAY_COUPLING"} );
+ my %settings;
+ foreach my $xmlvar ( "GLC_TWO_WAY_COUPLING", "LND_SETS_DUST_EMIS_DRV_FLDS") {
+ if ( defined($failtest{$key}{$xmlvar}) ) {
+ $settings{$xmlvar} = $failtest{$key}{$xmlvar};
+ }
+ }
+ &make_env_run( %settings );
eval{ system( "$bldnml $options -namelist \"&clmexp $namelist /\" > $tempfile 2>&1 " ); };
isnt( $?, 0, $key );
system( "cat $tempfile" );
@@ -1167,53 +1314,75 @@ sub cat_and_create_namelistinfile {
my %warntest = (
# Warnings without the -ignore_warnings option given
- "coldwfinidat" =>{ options=>"-envxml_dir . -clm_start_type cold",
- namelst=>"finidat = 'testfile.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_0",
- },
"bgcspin_w_suplnitro" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup on",
namelst=>"suplnitro='ALL'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc=bgc WO nitrif_denit" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_nitrif_denitrif=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"methane off W nitrif_denit"=>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_nitrif_denitrif=.true.,use_lch4=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
},
"soilm_stream w transient" =>{ options=>"-res 0.9x1.25 -envxml_dir . -use_case 20thC_transient",
namelst=>"use_soil_moisture_streams=T,soilm_tintalgo='linear'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"missing_ndep_file" =>{ options=>"-envxml_dir . -bgc bgc -ssp_rcp SSP5-3.4",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bad_megan_spec" =>{ options=>"-envxml_dir . -bgc bgc -megan",
- namelst=>"megan_specifier='ZZTOP=zztop'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ namelst=>"megan_specifier='ZZTOP=zztop%'",
phys=>"clm4_5",
},
"FUN_wo_flexCN" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_fun=.true.,use_flexiblecn=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ phys=>"clm6_0",
+ },
+ "Set coldtemp wo coldstart" =>{ options=>"-envxml_dir . --clm_start_type startup",
+ namelst=>"use_excess_ice=.true.,excess_ice_coldstart_temp=-10.",
+ phys=>"clm6_0",
+ },
+ "Set colddepth wo coldstart" =>{ options=>"-envxml_dir . --clm_start_type startup",
+ namelst=>"use_excess_ice=.true.,excess_ice_coldstart_depth=0.5",
+ phys=>"clm6_0",
+ },
+ "PrigentOnWOLeung" =>{ options=>"-envxml_dir . -bgc sp",
+ namelst=>"use_prigent_roughness=.true.,dust_emis_method='Zender_2003'",
+ phys=>"clm6_0",
+ },
+ "NotNEONbutNEONlightres" =>{ options=>"--res CLM_USRDAT --clm_usr_name regional --envxml_dir . --bgc bgc --light_res 106x174",
+ namelst=>"fsurdat='build-namelist_test.pl'",
+ phys=>"clm6_0",
+ },
+ "hillslope with init_interp"=>{ options=>"--res 10x15 --bgc bgc --envxml_dir .",
+ namelst=>"use_init_interp=.true.,use_hillslope=.true.,hillslope_file='/dev/null'",
+ phys=>"clm6_0",
},
);
foreach my $key ( keys(%warntest) ) {
print( "$key\n" );
+
+ my $var;
+ foreach $var ( "phys" , "options", "namelst" ) {
+ if ( not exists $warntest{$key}{$var} ) {
+ die "ERROR: Subkey $var does not exist for warntest $key\nERROR:Check if you spelled $var correctly\n"
+ }
+ }
+
&make_config_cache($warntest{$key}{"phys"});
my $options = $warntest{$key}{"options"};
my $namelist = $warntest{$key}{"namelst"};
- &make_env_run( GLC_TWO_WAY_COUPLING=>$warntest{$key}{"GLC_TWO_WAY_COUPLING"} );
+ my %settings;
+ foreach my $xmlvar ( "GLC_TWO_WAY_COUPLING" ) {
+ if ( defined($failtest{$key}{$xmlvar}) ) {
+ $settings{$xmlvar} = $failtest{$key}{$xmlvar};
+ }
+ }
+ &make_env_run( %settings );
eval{ system( "$bldnml $options -namelist \"&clmexp $namelist /\" > $tempfile 2>&1 " ); };
isnt( $?, 0, $key );
system( "cat $tempfile" );
@@ -1225,91 +1394,113 @@ sub cat_and_create_namelistinfile {
system( "cat $tempfile" );
}
+print "\n===============================================================================\n";
+print "Ensure cold starts with finidat are handled properly \n";
+print "=================================================================================\n";
+
+my %coldwfinidat = (
+ "bgc" => { options=>"-envxml_dir . -clm_start_type cold",
+ namelst=>"finidat = 'testfile.nc'",
+ phys=>"clm5_0",
+ expected_fail=>1,
+ },
+ "fates" => { options=>"-envxml_dir . -clm_start_type cold -bgc fates -no-megan",
+ namelst=>"finidat = 'testfile.nc', use_fates = .true.",
+ phys=>"clm5_0",
+ expected_fail=>0,
+ },
+);
+my $finidat;
+foreach my $key ( keys(%coldwfinidat) ) {
+ print( "$key\n" );
+
+ my $var;
+ foreach $var ( "phys" , "options", "namelst", "expected_fail" ) {
+ if ( not exists $coldwfinidat{$key}{$var} ) {
+ die "ERROR: Subkey $var does not exist for coldwfinidat $key\nERROR:Check if you spelled $var correctly\n"
+ }
+ }
+
+ &make_config_cache($coldwfinidat{$key}{"phys"});
+ my $options = $coldwfinidat{$key}{"options"};
+ my $namelist = $coldwfinidat{$key}{"namelst"};
+ my $expected_fail = $coldwfinidat{$key}{"expected_fail"};
+ my %settings;
+ &make_env_run( %settings );
+
+ # Should fail if expected to, pass otherwise
+ eval{ system( "$bldnml $options -namelist \"&clmexp $namelist /\" > $tempfile 2>&1 " ); };
+ is( $? eq 0, $expected_fail eq 0, "coldwfinidat $key run");
+
+ if ( $expected_fail ) {
+ # Now run with -ignore_warnings and make sure it still doesn't work
+ $options .= " -ignore_warnings";
+ eval{ system( "$bldnml $options -namelist \"&clmexp $namelist /\" > $tempfile 2>&1 " ); };
+ isnt( $?, 0, "coldwfinidat $key run -ignore_warnings" );
+ } else {
+ # Check that finidat was correctly set
+ $finidat = `grep finidat lnd_in`;
+ ok ( $finidat =~ "testfile.nc", "coldwfinidat $key finidat? $finidat" );
+ }
+}
+
#
# Loop over all physics versions
#
-foreach my $phys ( "clm4_5", "clm5_0", "clm5_1" ) {
+foreach my $phys ( "clm4_5", "clm5_0", "clm5_1", "clm6_0" ) {
$mode = "-phys $phys";
&make_config_cache($phys);
-print "\n==================================================\n";
-print "Test ALL resolutions with SP\n";
-print "==================================================\n";
+print "\n========================================================================\n";
+print "Test ALL resolutions that have surface datasets with SP for 1850 and 2000\n";
+print "========================================================================\n";
# Check for ALL resolutions with CLM50SP
-my $reslist = `../queryDefaultNamelist.pl -res list -s`;
-my @resolutions = split( / /, $reslist );
+my @resolutions = ( "360x720cru", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4", "ne30np4.pg2", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C96", "mpasa480", "mpasa120" );
+my @only2000_resolutions = ( "1x1_numaIA", "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa3p75" );
my @regional;
foreach my $res ( @resolutions ) {
chomp($res);
print "=== Test $res === \n";
- my $options = "-res $res -bgc sp -envxml_dir .";
-
- # Regional single point resolutions
- if ( $res =~ /^([0-9]+x[0-9]+_[a-zA-Z]+)$/ ) {
- push( @regional, $res );
- next;
- # Resolutions for mksurfdata mapping
- } elsif ( $res eq "0.5x0.5" ||
- $res eq "0.25x0.25" ||
- $res eq "3x3min" ||
- $res eq "5x5min" ||
- $res eq "10x10min" ||
- $res eq "0.125x0.125" ||
- $res eq "0.33x0.33" ||
- $res eq "1km-merge-10min" ) {
- next;
- # Resolutions that were supported in clm40 but NOT clm45/clm50
- } elsif ( $res eq "ne240np4" ||
- $res eq "ne60np4" ||
- $res eq "ne4np4" ||
- $res eq "2.5x3.33" ||
- $res eq "0.23x0.31" ||
- $res eq "0.47x0.63" ||
- $res eq "94x192" ||
- $res eq "8x16" ||
- $res eq "32x64" ||
- $res eq "128x256" ||
- $res eq "360x720cru" ||
- $res eq "512x1024" ) {
- next;
- # Resolutions not supported on release branch
- } elsif ( $res eq "ne120np4" ||
- $res eq "conus_30_x8" ) {
- next;
- }
+ foreach my $use_case ( "1850_control", "2000_control" ) {
+ # Skip resolutions that only have 2000 versions
+ if ( ($use_case eq "1850_control") && ($res ~~ @only2000_resolutions) ) {
+ next;
+ }
+ print "=== Test $use_case === \n";
+ my $options = "-res $res -bgc sp -envxml_dir . --use_case $use_case";
- &make_env_run();
- eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
- is( $@, '', "$options" );
+ &make_env_run();
+ eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
+ is( $@, '', "$options" );
- $cfiles->checkfilesexist( "$options", $mode );
+ $cfiles->checkfilesexist( "$options", $mode );
- $cfiles->shownmldiff( "default", "standard" );
- if ( defined($opts{'compare'}) ) {
- $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
- $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
- }
+ $cfiles->shownmldiff( "default", "standard" );
+ if ( defined($opts{'compare'}) ) {
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ }
- if ( defined($opts{'generate'}) ) {
- $cfiles->copyfiles( "$options", $mode );
+ if ( defined($opts{'generate'}) ) {
+ $cfiles->copyfiles( "$options", $mode );
+ }
+ &cleanup(); print "\n";
}
- &cleanup(); print "\n";
}
print "\n==================================================\n";
-print " Test important resolutions for BGC\n";
+print " Test important resolutions for BGC and historical\n";
print "==================================================\n";
-my @resolutions = ( "4x5", "10x15", "ne30np4", "ne16np4", "1.9x2.5", "0.9x1.25" );
+my @resolutions = ( "4x5", "10x15", "360x720cru", "ne30np4.pg3", "ne3np4.pg3", "1.9x2.5", "0.9x1.25", "C96", "mpasa120" );
my @regional;
my $nlbgcmode = "bgc";
my $mode = "$phys-$nlbgcmode";
foreach my $res ( @resolutions ) {
chomp($res);
print "=== Test $res === \n";
- my $options = "-res $res -envxml_dir . -bgc $nlbgcmode";
+ my $options = "-res $res -envxml_dir . -bgc $nlbgcmode --use_case 20thC_transient";
&make_env_run();
eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
@@ -1330,30 +1521,174 @@ sub cat_and_create_namelistinfile {
}
print "\n==================================================\n";
-print " Test all use-cases \n";
+print " Test all use-cases over all physics options\n";
print "==================================================\n";
-# Run over all use-cases...
+# Run over all use-cases for f09 and all physics...
my $list = `$bldnml -use_case list 2>&1 | grep "use case"`;
my @usecases;
if ( $list =~ /build-namelist : use cases : (.+)$/ ) {
- my @usecases = split( / /, $list );
+ @usecases = split( / /, $1 );
} else {
die "ERROR:: Trouble getting list of use-cases\n";
}
-foreach my $usecase ( @usecases ) {
- $options = "-use_case $usecase -envxml_dir .";
+if ( $#usecases != 15 ) {
+ print "use-cases = @usecases\n";
+ die "ERROR:: Number of use-cases isn't what's expected\n";
+}
+my @expect_fails = ( "1850-2100_SSP5-3.4_transient", "1850-2100_SSP4-3.4_transient", "2018-PD_transient", "1850-2100_SSP1-1.9_transient",
+ "1850-2100_SSP4-6.0_transient", "2018_control" );
+foreach my $phys ( "clm4_5", "clm5_0", "clm5_1", "clm6_0" ) {
+ print "physics = $phys\n";
+ &make_config_cache($phys);
+ foreach my $usecase ( @usecases ) {
+ print "usecase = $usecase\n";
+ $options = "-res 0.9x1.25 -use_case $usecase -envxml_dir .";
+ &make_env_run();
+ my $expect_fail = undef;
+ foreach my $failusecase ( @expect_fails ) {
+ if ( $failusecase eq $usecase ) {
+ $expect_fail = 1;
+ last;
+ }
+ }
+ eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
+ if ( ! defined($expect_fail) ) {
+ is( $@, '', "options: $options" );
+ $cfiles->checkfilesexist( "$options", $mode );
+ $cfiles->shownmldiff( "default", "standard" );
+ if ( defined($opts{'compare'}) ) {
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ }
+ if ( defined($opts{'generate'}) ) {
+ $cfiles->copyfiles( "$options", $mode );
+ }
+ } else {
+ isnt( $@, 0, "options: $options" );
+ }
+ &cleanup();
+ }
+}
+
+print "\n=======================================================================================\n";
+print " Test the seperate initial condition files, for ones not tested elsewhere\n";
+print "=========================================================================================\n";
+
+my %finidat_files = (
+ "f091850Clm45BgcGSW" =>{ phys =>"clm4_5",
+ atm_forc=>"GSWP3v1",
+ res => "0.9x1.25",
+ bgc => "bgc",
+ crop => "--no-crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=T",
+ },
+ "f091850Clm45BgcCRU" =>{ phys =>"clm4_5",
+ atm_forc=>"CRUv7",
+ res => "0.9x1.25",
+ bgc => "bgc",
+ crop => "--no-crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=T",
+ },
+ "f091850Clm45BgcCAM6" =>{ phys =>"clm4_5",
+ atm_forc=>"cam6.0",
+ res => "0.9x1.25",
+ bgc => "bgc",
+ crop => "--crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=F",
+ },
+ "f091850Clm50BgcGSW" =>{ phys =>"clm5_0",
+ atm_forc=>"GSWP3v1",
+ res => "0.9x1.25",
+ bgc => "bgc",
+ crop => "--crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=F",
+ },
+ "f091850Clm50SpGSW" =>{ phys =>"clm5_0",
+ atm_forc=>"GSWP3v1",
+ res => "0.9x1.25",
+ bgc => "sp",
+ crop => "--no-crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=T",
+ },
+ "f091850Clm50BgcCRU" =>{ phys =>"clm5_0",
+ atm_forc=>"CRUv7",
+ res => "0.9x1.25",
+ bgc => "bgc",
+ crop => "--crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=F",
+ },
+ "f091850Clm50SpCRU" =>{ phys =>"clm5_0",
+ atm_forc=>"CRUv7",
+ res => "0.9x1.25",
+ bgc => "sp",
+ crop => "--no-crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=T",
+ },
+ "f091850Clm50BgcCAM6" =>{ phys =>"clm5_0",
+ atm_forc=>"cam6.0",
+ res => "0.9x1.25",
+ bgc => "bgc",
+ crop => "--crop",
+ use_case => "1850_control",
+ start_ymd => "18500101",
+ namelist => "irrigate=F",
+ },
+ );
+
+foreach my $key ( keys(%finidat_files) ) {
+ print( "$key\n" );
+
+ my $var;
+ foreach $var ( "phys" , "atm_forc", "res", "bgc", "crop", "use_case", "start_ymd", "namelist" ) {
+ if ( not exists $finidat_files{$key}{$var} ) {
+ die "ERROR: Subkey $var does not exist for finidat_file $key\nERROR:Check if you spelled $var correctly\n"
+ }
+ }
+
+ my $phys = $finidat_files{$key}{'phys'};
+ print "physics = $phys\n";
+ &make_config_cache($phys);
+ my $usecase = $finidat_files{$key}{'use_case'};
+ my $bgc = $finidat_files{$key}{'bgc'};
+ my $res = $finidat_files{$key}{'res'};
+ my $crop = $finidat_files{$key}{'crop'};
+ my $namelist = $finidat_files{$key}{'namelist'};
+ my $start_ymd = $finidat_files{$key}{'start_ymd'};
+ my $lnd_tuning_mode = "${phys}_" . $finidat_files{$key}{'atm_forc'};
+ $options = "-bgc $bgc -res $res -use_case $usecase -envxml_dir . $crop --lnd_tuning_mode $lnd_tuning_mode " .
+ "-namelist '&a start_ymd=$start_ymd, $namelist/'";
&make_env_run();
eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
is( $@, '', "options: $options" );
+ my $finidat = `grep finidat lnd_in`;
+ if ( $finidat =~ /initdata_map/ ) {
+ my $result;
+ eval( $result = `grep use_init_interp lnd_in` );
+ is ( $result =~ /.true./, 1, "use_init_interp needs to be true here: $result");
+ }
$cfiles->checkfilesexist( "$options", $mode );
$cfiles->shownmldiff( "default", "standard" );
if ( defined($opts{'compare'}) ) {
- $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
- $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
- $cfiles->copyfiles( "$options", $mode );
+ $cfiles->copyfiles( "$options", $mode );
}
&cleanup();
}
@@ -1363,7 +1698,29 @@ sub cat_and_create_namelistinfile {
print "==================================================\n";
# Check for crop resolutions
-my @crop_res = ( "1x1_numaIA", "1x1_smallvilleIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne30np4" );
+my @crop1850_res = ( "1x1_smallvilleIA", "1x1_cidadinhoBR" );
+foreach my $res ( @crop1850_res ) {
+ my $use_case = "1850_control";
+ if ( $res =~ /1x1_cidadinhoBR/ ) {
+ $use_case = "2000_control";
+ }
+ $options = "-bgc bgc -crop -res $res -use_case $use_case -envxml_dir .";
+ &make_env_run();
+ eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
+ is( $@, '', "$options" );
+ $cfiles->checkfilesexist( "$options", $mode );
+ $cfiles->shownmldiff( "default", "standard" );
+ if ( defined($opts{'compare'}) ) {
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ }
+ if ( defined($opts{'generate'}) ) {
+ $cfiles->copyfiles( "$options", $mode );
+ }
+ &cleanup();
+}
+
+my @crop_res = ( "1x1_numaIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "ne30np4.pg3", "C96", "mpasa120" );
foreach my $res ( @crop_res ) {
$options = "-bgc bgc -crop -res $res -envxml_dir .";
&make_env_run();
@@ -1373,7 +1730,6 @@ sub cat_and_create_namelistinfile {
$cfiles->shownmldiff( "default", "standard" );
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
$cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -1397,17 +1753,15 @@ sub cat_and_create_namelistinfile {
# cases; I'm not sure if it's actually important to test this with all
# of the different use cases.
my @glc_res = ( "0.9x1.25", "1.9x2.5" );
-my @use_cases = ( "1850-2100_SSP1-2.6_transient",
+my @use_cases = (
"1850-2100_SSP2-4.5_transient",
- "1850-2100_SSP3-7.0_transient",
- "1850-2100_SSP5-8.5_transient",
"1850_control",
"2000_control",
"2010_control",
"20thC_transient",
);
foreach my $res ( @glc_res ) {
- foreach my $usecase ( @usecases ) {
+ foreach my $usecase ( @use_cases ) {
my $startymd = undef;
if ( ($usecase eq "1850_control") || ($usecase eq "20thC_transient") ) {
$startymd = 18500101;
@@ -1435,11 +1789,11 @@ sub cat_and_create_namelistinfile {
}
}
# Transient 20th Century simulations
-my @tran_res = ( "0.9x1.25", "1.9x2.5", "ne30np4", "10x15" );
+my @tran_res = ( "0.9x1.25", "1.9x2.5", "ne30np4.pg3", "10x15" );
my $usecase = "20thC_transient";
my $GLC_NEC = 10;
foreach my $res ( @tran_res ) {
- $options = "-res $res -use_case $usecase -envxml_dir . -namelist '&a start_ymd=18500101/'";
+ $options = "-res $res -use_case $usecase -envxml_dir . -namelist '&a start_ymd=18500101/' -bgc bgc -crop -namelist '&a do_grossunrep=T/'";
&make_env_run();
eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
is( $@, '', "$options" );
@@ -1447,7 +1801,6 @@ sub cat_and_create_namelistinfile {
$cfiles->shownmldiff( "default", "standard" );
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
$cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -1456,15 +1809,9 @@ sub cat_and_create_namelistinfile {
&cleanup();
}
# Transient ssp_rcp scenarios that work
-my @tran_res = ( "0.9x1.25", "1.9x2.5", "10x15" );
-foreach my $usecase ( "1850_control", "1850-2100_SSP5-8.5_transient", "1850-2100_SSP1-2.6_transient", "1850-2100_SSP3-7.0_transient",
- "1850-2100_SSP2-4.5_transient" ) {
- my $startymd = undef;
- if ( $usecase eq "1850_control") {
- $startymd = 18500101;
- } else {
- $startymd = 20150101;
- }
+my @tran_res = ( "4x5", "0.9x1.25", "1.9x2.5", "10x15", "360x720cru", "ne3np4.pg3", "ne16np4.pg3", "ne30np4.pg3", "C96", "mpasa120" );
+foreach my $usecase ( "1850-2100_SSP2-4.5_transient" ) {
+ my $startymd = 20150101;
foreach my $res ( @tran_res ) {
$options = "-res $res -bgc bgc -crop -use_case $usecase -envxml_dir . -namelist '&a start_ymd=$startymd/'";
&make_env_run();
@@ -1474,7 +1821,6 @@ sub cat_and_create_namelistinfile {
$cfiles->shownmldiff( "default", "standard" );
if ( defined($opts{'compare'}) ) {
$cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
- $cfiles->dodiffonfile( "$real_par_file", "$options", $mode );
$cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
}
if ( defined($opts{'generate'}) ) {
@@ -1488,25 +1834,11 @@ sub cat_and_create_namelistinfile {
# End loop over versions
#
-# The SSP's that fail...
-$phys = "clm5_0";
-$mode = "-phys $phys";
-&make_config_cache($phys);
-my $res = "0.9x1.25";
-foreach my $usecase ( "1850-2100_SSP4-3.4_transient", "1850-2100_SSP5-3.4_transient", "1850-2100_SSP1-1.9_transient",
- "1850-2100_SSP4-6.0_transient" ) {
- $options = "-res $res -bgc bgc -crop -use_case $usecase -envxml_dir . -namelist '&a start_ymd=20150101/'";
- &make_env_run();
- eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
- isnt( $?, 0, $usecase );
- system( "cat $tempfile" );
-}
-
print "\n==================================================\n";
-print "Test clm4.5/clm5.0/clm5_1 resolutions \n";
+print "Test clm4.5/clm5.0/clm5_1/clm6_0 resolutions \n";
print "==================================================\n";
-foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1' ) {
+foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1', "clm6_0" ) {
my $mode = "-phys $phys";
&make_config_cache($phys);
my @clmoptions = ( "-bgc bgc -envxml_dir .", "-bgc bgc -envxml_dir . -clm_accelerated_spinup=on", "-bgc bgc -envxml_dir . -light_res 360x720",
@@ -1514,7 +1846,7 @@ sub cat_and_create_namelistinfile {
"-bgc bgc -clm_demand flanduse_timeseries -sim_year 1850-2000 -namelist '&a start_ymd=18500101/'",
"-bgc bgc -envxml_dir . -namelist '&a use_c13=.true.,use_c14=.true.,use_c14_bombspike=.true./'" );
foreach my $clmopts ( @clmoptions ) {
- my @clmres = ( "10x15", "0.9x1.25", "1.9x2.5" );
+ my @clmres = ( "10x15", "4x5", "360x720cru", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4.pg3", "C96", "mpasa120" );
foreach my $res ( @clmres ) {
$options = "-res $res -envxml_dir . ";
&make_env_run( );
@@ -1535,7 +1867,7 @@ sub cat_and_create_namelistinfile {
my @clmoptions = ( "-bgc bgc -envxml_dir .",
"-bgc sp -envxml_dir .", );
foreach my $clmopts ( @clmoptions ) {
- my @clmres = ( "ne16np4" );
+ my @clmres = ( "ne16np4.pg3" );
foreach my $res ( @clmres ) {
$options = "-res $res -envxml_dir . ";
&make_env_run( );
@@ -1571,7 +1903,7 @@ sub cat_and_create_namelistinfile {
&cleanup();
# Run FATES mode for several resolutions and configurations
my $clmoptions = "-bgc fates -envxml_dir . -no-megan";
- my @clmres = ( "1x1_brazil", "5x5_amazon", "4x5", "1.9x2.5" );
+ my @clmres = ( "4x5", "1.9x2.5" );
foreach my $res ( @clmres ) {
$options = "-res $res -clm_start_type cold";
my @edoptions = ( "-use_case 2000_control",
@@ -1601,23 +1933,25 @@ sub cat_and_create_namelistinfile {
}
}
#
-# Run over the differen lnd_tuning modes
+# Run over the different lnd_tuning modes
#
my $res = "0.9x1.25";
-my $mask = "gx1v6";
+my $mask = "gx1v7";
my $simyr = "1850";
-foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1' ) {
+foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1', 'clm6_0' ) {
my $mode = "-phys $phys";
&make_config_cache($phys);
my @forclist = ();
- if ( $phys == "clm5_1" ) {
- @forclist = ( "GSWP3v1" );
- } else {
- @forclist = ( "CRUv7", "GSWP3v1", "cam6.0" );
- }
+ @forclist = ( "CRUv7", "GSWP3v1", "cam7.0", "cam6.0", "cam5.0", "cam4.0" );
foreach my $forc ( @forclist ) {
foreach my $bgc ( "sp", "bgc" ) {
my $lndtuningmode = "${phys}_${forc}";
+ if ( $lndtuningmode eq "clm5_1_CRUv7" ) {
+ next;
+ }
+ if ( $lndtuningmode eq "clm6_0_CRUv7" ) {
+ next;
+ }
my $clmoptions = "-res $res -mask $mask -sim_year $simyr -envxml_dir . -lnd_tuning_mod $lndtuningmode -bgc $bgc";
&make_env_run( );
eval{ system( "$bldnml $clmoptions > $tempfile 2>&1 " ); };
@@ -1657,7 +1991,6 @@ sub cleanup {
my $type = shift;
print "Cleanup files created\n";
- system( "/bin/rm env_run.xml $real_par_file" );
if ( defined($type) ) {
if ( $type eq "config" ) {
system( "/bin/rm config_cache.xml" );
diff --git a/bld/unit_testers/cmp_baseline_lnd_in_files b/bld/unit_testers/cmp_baseline_lnd_in_files
new file mode 100755
index 0000000000..3c6d84954c
--- /dev/null
+++ b/bld/unit_testers/cmp_baseline_lnd_in_files
@@ -0,0 +1,71 @@
+#!/bin/bash
+#
+# A simple script to compare lnd_in namelists between two baselines on Derecho
+#
+
+#----------------------------------------------------------------------
+# Usage subroutine
+usage() {
+ echo ""
+ echo "***********************************************************************"
+ echo "usage:"
+ echo "./cmp_baseline_lnd_in_files "
+ echo " "
+ echo "Compares lnd_in files between two baselines on Derecho"
+ echo "***********************************************************************"
+}
+
+#----------------------------------------------------------------------
+
+if [ "$#" -ne 2 ]; then
+ echo "Need to give two baseline directories to compare"
+ usage
+ exit 1
+fi
+baseline=$1
+compare=$2
+
+cwd=`pwd`
+if [ -z "$1" ]; then
+ echo "Need to enter a baseline directory tag name"
+ usage
+ exit 1
+fi
+if [ -z "$2" ]; then
+ echo "Need to enter a comparison directory tag name"
+ usage
+ exit 1
+fi
+
+BASELINE_ROOT=/glade/campaign/cgd/tss/ctsm_baselines
+root=$BASELINE_ROOT/$baseline
+if ! test -d "$root"; then
+ echo "Root directory of $root does NOT exist"
+ exit 1
+fi
+comp_root=$BASELINE_ROOT/$compare
+if ! test -d "$comp_root"; then
+ echo "Root comparison directory of $comp_root does NOT exist"
+ usage
+ exit 1
+fi
+cd $root
+filepat="*"
+dirnames=($filepat)
+if [ "${filenames[*]}" = "$filepat" ]; then
+ echo "No directoctories exist in this directory"
+ exit 1
+fi
+for dir in ${dirnames[*]}
+do
+ echo $dir
+ base=$dir/CaseDocs/lnd_in
+ comp=$BASELINE_ROOT/$compare/$dir/CaseDocs/lnd_in
+ if ! test -f "$base"; then
+ echo "$base, does NOT exist, skipping"
+ elif ! test -f "$comp"; then
+ echo "$comp, does NOT exist, skipping"
+ else
+ $cwd/../../cime/CIME/Tools/compare_namelists $base $comp
+ fi
+done
diff --git a/bld/unit_testers/compare_namelists b/bld/unit_testers/compare_namelists
new file mode 100755
index 0000000000..0d0168b316
--- /dev/null
+++ b/bld/unit_testers/compare_namelists
@@ -0,0 +1,115 @@
+#! /bin/bash
+# Compare namelists made by the unit-tester to either themselves (for different physics versions)
+# or to a baseline also made by the unit-tester
+#
+
+#----------------------------------------------------------------------
+# Usage subroutine
+usage() {
+ echo ""
+ echo "***********************************************************************"
+ echo "usage:"
+ echo "./compare_namelists "
+ echo ""
+ echo "valid options: "
+ echo "[-h|--help] "
+ echo " Displays this help message"
+ echo "[-v|--verbose] "
+ echo " Run in verbose mode"
+ echo "[-pa|--physicsA ] "
+ echo " Namelists of first physics version for comparison"
+ echo " (in baseline directory)"
+ echo "[-pb|--physicsB ] "
+ echo " Namelists of second physics version to compare to the first one"
+ echo " (in current directory)"
+ echo "[-b|--baseline ] "
+ echo " Baseline directory to compare to (default current directory)"
+ echo " "
+ echo "NOTE: When --physicsA or --physicsB is chosen you must also set the other"
+ echo "***********************************************************************"
+}
+
+
+# Current working directory: the location of this script
+cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+
+# Default settings
+verbose="No"
+PHYSA="all"
+PHYSB="all"
+baseline="."
+
+# Parse command-line options
+while [ $# -gt 0 ]; do
+ case $1 in
+ -h|--help )
+ usage
+ exit 0
+ ;;
+ -v|--verbose )
+ verbose="YES"
+ ;;
+ -pa|--physicsA )
+ PHYSA=$2
+ shift
+ ;;
+ -pb|--physicsB )
+ PHYSB=$2
+ shift
+ ;;
+ -b|--baseline )
+ baseline=$2
+ shift
+ ;;
+ * )
+ echo "ERROR:: invalid argument sent in: $2"
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+done
+if [ "$PHYSA" = "all" ] && [ "$PHYSB" != "all" ]; then
+ echo "When setting --physicsB you MUST also set --physicsA"
+ echo "$PHYSA $PHYSB"
+ exit 1
+fi
+if [ "$PHYSB" = "all" ] && [ "$PHYSA" != "all" ]; then
+ echo "When setting --physicsA you MUST also set --physicsB"
+ exit 1
+fi
+
+if [ "$verbose" = "YES" ]; then echo "Get list of lnd_in.* files"; fi
+if [ "$verbose" = "YES" ]; then pwd; fi
+filepat="lnd_in.*"
+filenames=($filepat)
+if [ "$verbose" = "YES" ]; then echo "filename list = ${filenames[*]}"; fi
+if [ "${filenames[*]}" = "$filepat" ]; then
+ echo "No lnd_in files exist in the current directory -- run ./build-namelist_test.pl first"
+ exit 1
+fi
+for file in ${filenames[*]}
+do
+ fileA="$baseline/$file"
+ fileB="./$file"
+ # If physicsA option used and the file matches the physics input
+ if [[ "$fileA" =~ "-phys+$PHYSA" ]] || [ "$PHYSA" = "all" ]; then
+ # Replace physicsB for fileB
+ if [ ! "$PHYSA" = "all" ]; then
+ fileB=${fileB/-phys+$PHYSA/-phys+$PHYSB}
+ fi
+ if ! test -f $fileB; then
+ if [ "$verbose" = "YES" ]; then echo "$fileB does NOT exist -- skipping"; fi
+ else
+ if [ "$verbose" = "YES" ]; then echo "Compare namelists for $file"; fi
+ if [ "$fileA" = "$fileB" ]; then
+ echo "Comparing files to themself:"
+ echo "fileA = $fileA"
+ echo "fileB = $fileB"
+ exit 1
+ fi
+ $cwd/../../cime/CIME/Tools/compare_namelists $fileA $fileB
+ fi
+ fi
+done
+if [ "$verbose" = "YES" ]; then echo "Successfully ran through lnd_in files to compare"; fi
diff --git a/bld/unit_testers/empty_user_nl_clm b/bld/unit_testers/empty_user_nl_clm
new file mode 100644
index 0000000000..45fda13d2c
--- /dev/null
+++ b/bld/unit_testers/empty_user_nl_clm
@@ -0,0 +1 @@
+! empty user_nl_clm file
diff --git a/bld/unit_testers/xFail/expectedClmTestFails.xml b/bld/unit_testers/xFail/expectedClmTestFails.xml
index 12c954d38b..380e614ea1 100644
--- a/bld/unit_testers/xFail/expectedClmTestFails.xml
+++ b/bld/unit_testers/xFail/expectedClmTestFails.xml
@@ -20,33 +20,6 @@
-
-
-
-
-
-
-
- goldbach not recognized
- goldbach not recognized
- goldbach not recognized
-
-
-
-
-
-
-
- Doesn't check for valid values
-
-
-
-
-
-
-
-
diff --git a/bld/unit_testers/xFail/expectedFail.pm b/bld/unit_testers/xFail/expectedFail.pm
index 9feaa3e38b..067e3a51d8 100755
--- a/bld/unit_testers/xFail/expectedFail.pm
+++ b/bld/unit_testers/xFail/expectedFail.pm
@@ -5,7 +5,7 @@ Documentation for expectedFail.pm
=head1 Overview
The module expectedFail.pm supplies the capability of checking if a failed test is expected to fail.
-It is called directly from either test_driver.sh (for batch and interactive tests) or build-namelist_test.pl.
+It is called directly from build-namelist_test.pl.
Future plans involve integrating this module into cesm tests.
=head1 Use Case
@@ -112,7 +112,7 @@ sub new {
=head1 parseOutput
-parseOutput parsese the output from the build-namelist_test.pl script. It is similar
+parseOutput parses the output from the build-namelist_test.pl script. It is similar
to, but not interchangable with parseOutputCLM.
The only argument is that of the reference variable that contains the information dumped
@@ -223,119 +223,6 @@ sub parseOutput
#
##############################################################################
-=head1 parseOutputCLM
-
-parseOutputCLM parsese the output from the test_driver.sh script. It is similar
-to, but not interchangable with parseOutput.
-
-parseOutputCLM takes one arguments:
- $statFoo-> the name of the td..status file
-
-returns: nothing
-
-=cut
-
-##############################################################################
-#
-##############################################################################
-sub parseOutputCLM
-{
-
- my $report;
- my $testId;
- my @testName={};
- my $testReason;
-
- my ($self, $statFoo) = @_ ;
-
- open(FOO, "< $statFoo"); # open for input
- open(FOO_OUT, "> $statFoo.xFail"); # open for input
-
- my(@reportLines);
-
- while () {
-
- my($line) = $_;
-
- my @outArr=split(/ /,$line);
- if (looks_like_number(@outArr[0])) {
-
- $self->{_numericalTestId}++;
-
- my $num=sprintf("%03d", $self->{_numericalTestId});
- my $totNum=sprintf("%03d", $self->{_totTests});
-
- #_# last element has the pass/fail info.
- chomp(@outArr[-1]);
- my $repPass=substr(@outArr[-1], -4, 4);
-
- if ($DEBUG) {
- print ("xFail::expectedFail::parseOutput @outArr[0] \n");
- print ("xFail::expectedFail::parseOutput @outArr[1] \n");
- print ("xFail::expectedFail::parseOutput @outArr[2] \n");
- print ("xFail::expectedFail::parseOutput @outArr[3] \n");
- print ("xFail::expectedFail::parseOutput @outArr[4] \n");
- print ("xFail::expectedFail::parseOutput @outArr[5] \n");
- print ("xFail::expectedFail::parseOutput @outArr[6] \n");
- print ("xFail::expectedFail::parseOutput @outArr[-1] \n");
- print ("xFail::expectedFail::parseOutput $repPass \n");
- }
-
- my $size = @outArr-1;
- if ($DEBUG) {
- print ("size of line $size \n");
- }
- my $endOfDesc=$size-1;
-
- if ($repPass eq "PASS") {
- $report=$pass;
- $testId=@outArr[1];
- @testName=@outArr[2..$endOfDesc];
-
- my ($retVal,$xFailText)=$self->_searchExpectedFail($testId);
-
- my $testReason=$self->_testNowPassing($testId,$retVal,$xFailText);
-
- #_# print out the test results
- print FOO_OUT ("$num/$totNum <$report> $testReason \n");
-
- } else {
- $testId=@outArr[1];
- my ($retVal,$xFailText)=$self->_searchExpectedFail($testId);
-
- if ($DEBUG) {
- print ("xFail::expectedFail::parseOutput Id $retVal,$xFailText \n");
- }
-
- @testName=@outArr[2..$endOfDesc];
-
- if ($retVal eq "TRUE"){
- #_# found an expected FAIL (xFAIL)
- $report=$xfail;
- $testReason= "";
- } else {
- #_# print a regular FAIL
- $report=$fail;
- $testReason="";
- }
-
- #_# print out the test results
- print FOO_OUT ("$num/$totNum <$report> $testReason \n");
-
- }
-
- } else {
- print FOO_OUT $line;
- }
- }
- close(FOO);
- close(FOO_OUT);
-}
-
-##############################################################################
-#
-##############################################################################
-
=head1 _searchExpectedFail
searches the list of expected fails for a match with testId.
@@ -608,8 +495,6 @@ sub _getTestType
my %testTypes = (
"build-namelist_test.pl" => "namelistTest",
- "test_driver.sh-i" => "clmInteractive",
- "test_driver.sh" => "clmBatch",
"clm-cesm.sh" => "cesm"
);
diff --git a/bld/unit_testers/xFail/wrapClmTests.pl b/bld/unit_testers/xFail/wrapClmTests.pl
deleted file mode 100755
index 28238b9d5d..0000000000
--- a/bld/unit_testers/xFail/wrapClmTests.pl
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env perl
-
-#-# =========================================================================================
-
-=head1 wrapClmTest.pl
-
-=head1 Overview
-
-This is a wrapper script that is called from test_driver.sh for either interactive or batch
-tests. It calls the CTOR for the xFail::expectedFail.pm module and also parses the td*.status
-file to create a new file with xFails listed.
-
-It takes the following arguments:
-
- numberOfTests -> number of tests from test_driver.sh
- statusFile -> name of the td..status file
- callingScript -> name of script calling this. For test_driver.sh it may be one of:
- 1) test_driver.sh-i for interactive tests
- 2) test_driver.sh for batch tests
-
-=head1 Notes
-
-This script may be run standalone which is useful for testing purposes.
-
-=cut
-
-#-# =========================================================================================
-
-use strict;
-use Getopt::Long;
-use English;
-use Cwd;
-use Scalar::Util qw(looks_like_number);
-
-my $DEBUG=0;
-
-sub usage {
- die < 0,
- numberOfTests => undef,
- statusFile => undef,
- callingScript => undef,
- );
-
-GetOptions(
- "h|help" => \$opts{'help'},
- "numberOfTests=s" => \$opts{'numberOfTests'},
- "statusFile=s" => \$opts{'statusFile'},
- "callingScript=s" => \$opts{'callingScript'},
-) or usage();
-
-# Give usage message.
-usage() if $opts{'help'};
-
-my $statFoo = undef;
-my $nTests = undef;
-my $script= undef;
-
-if (defined($opts{'statusFile'})) {
- $statFoo = $opts{'statusFile'};
-}
-if (defined($opts{'numberOfTests'})) {
- $nTests = $opts{'numberOfTests'};
-}
-if (defined($opts{'callingScript'})) {
- $script = $opts{'callingScript'};
-}
-
-my ( $self ) = @_;
-
-#Figure out where configure directory is and where can use the XML/Lite module from
-my $ProgName;
-($ProgName = $PROGRAM_NAME) =~ s!(.*)/!!; # name of program
-my $ProgDir = $1; # name of directory where program lives
-
-my $cwd = getcwd(); # current working directory
-my $cfgdir;
-
-if ($ProgDir) { $cfgdir = $ProgDir; }
-else { $cfgdir = $cwd; }
-
-#-----------------------------------------------------------------------------------------------
-# Add $cfgdir to the list of paths that Perl searches for modules
-#-----------------------------------------------------------------------------------------------
-my @dirs = ( $cfgdir,
- "$cfgdir/../",
- "$cfgdir/../../../../../cime/utils/perl5lib");
-unshift @INC, @dirs;
-my $result = eval "require expectedFail";
-if ( ! defined($result) ) {
- die <<"EOF";
-** Cannot find perl module \"xFail/expectedFail.pm\" from directories: @dirs **
-EOF
-}
-
-#_# ====================================
-#_# setup work complete. Now parse file
-#_# ====================================
-
-if ($DEBUG) {
- print (" wrapClmTests.pl:: calling script $script \n");
- print (" wrapClmTests.pl:: number of tests $nTests \n");
- print (" wrapClmTests.pl:: processing $statFoo \n");
-}
-
-#_# compGen not used for CLM batch or interactive tests, but we use "compare" as the default in this case
-my $compGen="compare";
-my $xFail = xFail::expectedFail->new($script,$compGen,$nTests);
-
-$xFail->parseOutputCLM($statFoo);
-
-exit(0);
diff --git a/ccs_config b/ccs_config
new file mode 160000
index 0000000000..3640d984aa
--- /dev/null
+++ b/ccs_config
@@ -0,0 +1 @@
+Subproject commit 3640d984aad755c2b536abe2ddbcb428cca130ae
diff --git a/cime b/cime
new file mode 160000
index 0000000000..f4a63723ea
--- /dev/null
+++ b/cime
@@ -0,0 +1 @@
+Subproject commit f4a63723ead19bf5391abf21e5d49bd3741f7e39
diff --git a/cime_config/SystemTests/__init__.py b/cime_config/SystemTests/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cime_config/SystemTests/fsurdatmodifyctsm.py b/cime_config/SystemTests/fsurdatmodifyctsm.py
index 899ab1aead..03e437d5c4 100644
--- a/cime_config/SystemTests/fsurdatmodifyctsm.py
+++ b/cime_config/SystemTests/fsurdatmodifyctsm.py
@@ -5,114 +5,90 @@
import os
import re
-import subprocess
from CIME.SystemTests.system_tests_common import SystemTestsCommon
from CIME.XML.standard_module_setup import *
from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files
+# For calling fsurdat_modifier
+from argparse import Namespace
+
+_CTSM_PYTHON = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python"
+)
+sys.path.insert(1, _CTSM_PYTHON)
+
logger = logging.getLogger(__name__)
-class FSURDATMODIFYCTSM(SystemTestsCommon):
+class FSURDATMODIFYCTSM(SystemTestsCommon):
def __init__(self, case):
"""
initialize an object interface to the SMS system test
"""
SystemTestsCommon.__init__(self, case)
- if not os.path.exists(os.path.join(self._get_caseroot(),
- 'done_FSURDATMODIFYCTSM_setup.txt')):
+ if not os.path.exists(
+ os.path.join(self._get_caseroot(), "done_FSURDATMODIFYCTSM_setup.txt")
+ ):
# Create out-of-the-box lnd_in to obtain fsurdat_in
- case.create_namelists(component='lnd')
+ case.create_namelists(component="lnd")
# If fsurdat_in does not exist, download it from the server
case.check_all_input_data()
- lnd_in_path = os.path.join(self._get_caseroot(), 'CaseDocs/lnd_in')
- with open (lnd_in_path,'r') as lnd_in:
+ lnd_in_path = os.path.join(self._get_caseroot(), "CaseDocs/lnd_in")
+ with open(lnd_in_path, "r") as lnd_in:
for line in lnd_in:
fsurdat_in = re.match(r" *fsurdat *= *'(.*)'", line)
if fsurdat_in:
self._fsurdat_in = fsurdat_in.group(1)
break
- self._fsurdat_out = os.path.join(self._get_caseroot(), 'fsurdat.nc')
- self._ctsm_root = self._case.get_value( 'COMP_ROOT_DIR_LND')
- self._cfg_file_path = os.path.join(self._get_caseroot(),
- 'modify_fsurdat.cfg')
+ self._fsurdat_out = os.path.join(self._get_caseroot(), "fsurdat.nc")
+ self._ctsm_root = self._case.get_value("COMP_ROOT_DIR_LND")
+ self._cfg_file_path = os.path.join(self._get_caseroot(), "modify_fsurdat.cfg")
+ logger.info(" create config file to modify")
self._create_config_file()
+ logger.info(" run modify_fsurdat")
self._run_modify_fsurdat()
+ logger.info(" modify user_nl files")
self._modify_user_nl()
- with open('done_FSURDATMODIFYCTSM_setup.txt', 'w') as fp:
+ with open("done_FSURDATMODIFYCTSM_setup.txt", "w") as fp:
pass
def _create_config_file(self):
- cfg_template_path = os.path.join(self._ctsm_root,
- 'tools/modify_input_files/modify_fsurdat_template.cfg')
+ cfg_template_path = os.path.join(
+ self._ctsm_root, "tools/modify_input_files/modify_fsurdat_template.cfg"
+ )
- with open (self._cfg_file_path,'w') as cfg_out:
- with open (cfg_template_path,'r') as cfg_in:
+ with open(self._cfg_file_path, "w") as cfg_out:
+ with open(cfg_template_path, "r") as cfg_in:
for line in cfg_in:
- if re.match(r' *fsurdat_in *=', line):
- line = 'fsurdat_in = {}'.format(self._fsurdat_in)
- elif re.match(r' *fsurdat_out *=', line):
- line = 'fsurdat_out = {}'.format(self._fsurdat_out)
- elif re.match(r' *idealized *=', line):
- line = 'idealized = True'
+ if re.match(r" *fsurdat_in *=", line):
+ line = "fsurdat_in = {}".format(self._fsurdat_in)
+ elif re.match(r" *fsurdat_out *=", line):
+ line = "fsurdat_out = {}".format(self._fsurdat_out)
+ elif re.match(r" *idealized *=", line):
+ line = "idealized = True"
cfg_out.write(line)
-
def _run_modify_fsurdat(self):
- tool_path = os.path.join(self._ctsm_root,
- 'tools/modify_input_files/fsurdat_modifier')
- # Need to specify a specific python version that has the required
- # dependencies
- python_path = _get_python_path()
- subprocess.check_call([python_path, tool_path, self._cfg_file_path])
+ fsurdat_modifier_args = Namespace(
+ cfg_path=self._cfg_file_path,
+ debug=False,
+ fsurdat_in="UNSET",
+ fsurdat_out="UNSET",
+ overwrite=False,
+ silent=False,
+ verbose=False,
+ )
+ from ctsm.modify_input_files.fsurdat_modifier import fsurdat_modifier
+
+ fsurdat_modifier(fsurdat_modifier_args)
def _modify_user_nl(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "fsurdat = '{}'".format(self._fsurdat_out))
-
-def _get_python_path():
- """Get path to ncar_pylib's python on cheyenne
-
- This is needed because we need a python environment that includes xarray
- and its dependencies. This is currently hard-coded for cheyenne until we
- come up with a robust way in CIME of ensuring that the correc python
- environment is loaded.
-
- """
- out = subprocess.check_output(['/glade/u/apps/opt/ncar_pylib/ncar_pylib',
- '-l'], universal_newlines=True)
-
- # First look for a loaded ('L') python
- path = _find_path_from_pylib_output(out, 'L')
- # If no loaded python found, look for a default ('D') python
- if path is None:
- path = _find_path_from_pylib_output(out, 'D')
-
- if path is None:
- raise RuntimeError('No python found')
-
- return os.path.join(path, 'bin', 'python')
-
-def _find_path_from_pylib_output(ncar_pylib_output, char):
- """Given line-by-line output from ncar_pylib, return the path to python if found
-
- Args:
- - ncar_pylib_output: line-by-line output from ncar_pylib
- - char: the character to look for in the leading parenthetical expression (typically 'L' or 'D')
-
- Returns a path to python, or None if not found
- """
- # The line of interest looks like the following (for char = 'L'):
- # (L) ... /path/to/python
- regex = r'\(' + char + r'\).* (/\S+)'
- for line in ncar_pylib_output.splitlines():
- match_line = re.match(regex, line)
- if match_line:
- return match_line.group(1)
-
- return None
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="fsurdat = '{}'".format(self._fsurdat_out),
+ )
diff --git a/cime_config/SystemTests/funitctsm.py b/cime_config/SystemTests/funitctsm.py
index 8634a74c2f..783e5b5d85 100644
--- a/cime_config/SystemTests/funitctsm.py
+++ b/cime_config/SystemTests/funitctsm.py
@@ -14,8 +14,8 @@
logger = logging.getLogger(__name__)
-class FUNITCTSM(FUNIT):
+class FUNITCTSM(FUNIT):
def __init__(self, case):
FUNIT.__init__(self, case)
diff --git a/cime_config/SystemTests/lciso.py b/cime_config/SystemTests/lciso.py
index 12a74d5d5c..a9edba8e80 100644
--- a/cime_config/SystemTests/lciso.py
+++ b/cime_config/SystemTests/lciso.py
@@ -14,24 +14,28 @@
logger = logging.getLogger(__name__)
-class LCISO(SystemTestsCompareTwo):
+class LCISO(SystemTestsCompareTwo):
def __init__(self, case):
self.comp = case.get_value("COMP_LND")
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = 'cisoallon',
- run_one_description = 'carbon isotopes off',
- run_two_description = 'c13 and c14 isotopes on as well as C isotope time series',
- ignore_fieldlist_diffs = True)
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="cisoallon",
+ run_one_description="carbon isotopes off",
+ run_two_description="c13 and c14 isotopes on as well as C isotope time series",
+ ignore_fieldlist_diffs=True,
+ )
def _case_one_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = self.comp,
- contents = "use_c13=F, use_c14=F")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(), component=self.comp, contents="use_c13=F, use_c14=F"
+ )
def _case_two_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = self.comp,
- contents = "use_c13=.true.,use_c14=.true.,use_c13_timeseries=.true.,use_c14_bombspike=.true." )
-
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component=self.comp,
+ contents="use_c13=.true.,use_c14=.true.,use_c13_timeseries=.true.,use_c14_bombspike=.true.",
+ )
diff --git a/cime_config/SystemTests/lgrain2.py b/cime_config/SystemTests/lgrain2.py
index 129c3275e3..f4e19ad930 100644
--- a/cime_config/SystemTests/lgrain2.py
+++ b/cime_config/SystemTests/lgrain2.py
@@ -19,22 +19,29 @@
logger = logging.getLogger(__name__)
-class LGRAIN2(SystemTestsCompareTwo):
+class LGRAIN2(SystemTestsCompareTwo):
def __init__(self, case):
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = 'grain1',
- run_one_description = 'use a second grain pool',
- run_two_description = 'use a single grain pool',
- ignore_fieldlist_diffs = True)
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="grain1",
+ run_one_description="use a second grain pool",
+ run_two_description="use a single grain pool",
+ ignore_fieldlist_diffs=True,
+ )
def _case_one_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "for_testing_use_second_grain_pool=.true.")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="for_testing_use_second_grain_pool=.true.",
+ )
def _case_two_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "for_testing_use_second_grain_pool=.false.")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="for_testing_use_second_grain_pool=.false.",
+ )
diff --git a/cime_config/SystemTests/lii.py b/cime_config/SystemTests/lii.py
index d89bd0aa09..de274256a3 100644
--- a/cime_config/SystemTests/lii.py
+++ b/cime_config/SystemTests/lii.py
@@ -35,22 +35,24 @@
logger = logging.getLogger(__name__)
-class LII(SystemTestsCompareTwo):
+class LII(SystemTestsCompareTwo):
def __init__(self, case):
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = 'no_interp',
- run_one_description = 'use_init_interp set to true',
- run_two_description = 'use_init_interp set to false')
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="no_interp",
+ run_one_description="use_init_interp set to true",
+ run_two_description="use_init_interp set to false",
+ )
def _case_one_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "use_init_interp = .true.")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(), component="clm", contents="use_init_interp = .true."
+ )
def _case_two_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "use_init_interp = .false.")
-
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(), component="clm", contents="use_init_interp = .false."
+ )
diff --git a/cime_config/SystemTests/lii2finidatareas.py b/cime_config/SystemTests/lii2finidatareas.py
index f7a0a2f10e..337e46bf39 100644
--- a/cime_config/SystemTests/lii2finidatareas.py
+++ b/cime_config/SystemTests/lii2finidatareas.py
@@ -58,13 +58,15 @@
logger = logging.getLogger(__name__)
-class LII2FINIDATAREAS(LII):
+class LII2FINIDATAREAS(LII):
def __init__(self, case):
super(LII2FINIDATAREAS, self).__init__(case)
def _case_one_setup(self):
super(LII2FINIDATAREAS, self)._case_one_setup()
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "init_interp_method = 'use_finidat_areas'")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="init_interp_method = 'use_finidat_areas'",
+ )
diff --git a/cime_config/SystemTests/lilacsmoke.py b/cime_config/SystemTests/lilacsmoke.py
index eec54579a5..5bdbb31ec1 100644
--- a/cime_config/SystemTests/lilacsmoke.py
+++ b/cime_config/SystemTests/lilacsmoke.py
@@ -27,57 +27,61 @@
from CIME.SystemTests.system_tests_common import SystemTestsCommon
from CIME.utils import run_cmd, run_cmd_no_fail, symlink_force, new_lid, safe_copy, append_testlog
from CIME.build import post_build
-from CIME.test_status import NAMELIST_PHASE, GENERATE_PHASE, BASELINE_PHASE, TEST_PASS_STATUS, TEST_FAIL_STATUS
+from CIME.test_status import (
+ NAMELIST_PHASE,
+ GENERATE_PHASE,
+ BASELINE_PHASE,
+ TEST_PASS_STATUS,
+ TEST_FAIL_STATUS,
+)
from CIME.XML.standard_module_setup import *
logger = logging.getLogger(__name__)
-_LILAC_RUNTIME_FILES = ['lnd_in', 'lnd_modelio.nml', 'lilac_in']
+_LILAC_RUNTIME_FILES = ["lnd_in", "lnd_modelio.nml", "drv_flds_in", "lilac_in"]
-class LILACSMOKE(SystemTestsCommon):
+class LILACSMOKE(SystemTestsCommon):
def __init__(self, case):
SystemTestsCommon.__init__(self, case)
def build_phase(self, sharedlib_only=False, model_only=False):
if not sharedlib_only:
- lndroot = self._case.get_value('COMP_ROOT_DIR_LND')
- exeroot = self._case.get_value('EXEROOT')
+ lndroot = self._case.get_value("COMP_ROOT_DIR_LND")
+ exeroot = self._case.get_value("EXEROOT")
build_dir = self._lilac_build_dir()
- script_path = os.path.abspath(os.path.join(lndroot, 'lilac', 'build_ctsm'))
+ script_path = os.path.abspath(os.path.join(lndroot, "lilac", "build_ctsm"))
# We only run the initial build command if the build_dir doesn't exist
# yet. This is to support rebuilding the test case. (The first time through,
# the build_dir won't exist yet; subsequent times, it will already exist, so
# we skip to the rebuild command.)
if not os.path.isdir(build_dir):
- machine = self._case.get_value('MACH')
- compiler = self._case.get_value('COMPILER')
- debug = self._case.get_value('DEBUG')
+ machine = self._case.get_value("MACH")
+ compiler = self._case.get_value("COMPILER")
+ debug = self._case.get_value("DEBUG")
# It would be possible to do this testing via the python interface rather
# than through a separate subprocess. However, we do it through a
# subprocess in order to test the full build_ctsm script, including
# command-line parsing.
- cmd = '{script_path} {build_dir} --machine {machine} --compiler {compiler}'.format(
- script_path=script_path,
- build_dir=build_dir,
- machine=machine,
- compiler=compiler)
+ cmd = "{script_path} {build_dir} --machine {machine} --compiler {compiler}".format(
+ script_path=script_path, build_dir=build_dir, machine=machine, compiler=compiler
+ )
# It isn't straightforward to determine if pnetcdf is available on a
# machine. To keep things simple, always run without pnetcdf.
- cmd += ' --no-pnetcdf'
+ cmd += " --no-pnetcdf"
if debug:
- cmd += ' --build-debug'
- self._run_build_cmd(cmd, exeroot, 'build_ctsm.bldlog')
+ cmd += " --build-debug"
+ self._run_build_cmd(cmd, exeroot, "build_ctsm.bldlog")
# We call the build script with --rebuild even for an initial build. This is
# so we make sure to test the code path for --rebuild. (This is also needed if
# the user rebuilds the test case, in which case this will be the only command
# run, since the build_dir will already exist.)
- cmd = '{script_path} {build_dir} --rebuild'.format(
- script_path=script_path,
- build_dir=build_dir)
- self._run_build_cmd(cmd, exeroot, 'rebuild_ctsm.bldlog')
+ cmd = "{script_path} {build_dir} --rebuild".format(
+ script_path=script_path, build_dir=build_dir
+ )
+ self._run_build_cmd(cmd, exeroot, "rebuild_ctsm.bldlog")
self._build_atm_driver()
@@ -95,51 +99,62 @@ def build_phase(self, sharedlib_only=False, model_only=False):
post_build(self._case, logs=[], build_complete=True)
def _build_atm_driver(self):
- caseroot = self._case.get_value('CASEROOT')
- lndroot = self._case.get_value('COMP_ROOT_DIR_LND')
- blddir = os.path.join(caseroot, 'lilac_atm_driver', 'bld')
+ caseroot = self._case.get_value("CASEROOT")
+ lndroot = self._case.get_value("COMP_ROOT_DIR_LND")
+ blddir = os.path.join(caseroot, "lilac_atm_driver", "bld")
if not os.path.exists(blddir):
os.makedirs(blddir)
- symlink_force(os.path.join(lndroot, 'lilac', 'atm_driver', 'Makefile'),
- os.path.join(blddir, 'Makefile'))
- symlink_force(os.path.join(lndroot, 'lilac', 'atm_driver', 'atm_driver.F90'),
- os.path.join(blddir, 'atm_driver.F90'))
- symlink_force(os.path.join(self._lilac_build_dir(), 'case', 'Macros.make'),
- os.path.join(blddir, 'Macros.make'))
-
- makevars = 'COMPILER={compiler} DEBUG={debug} CTSM_MKFILE={ctsm_mkfile}'.format(
- compiler=self._case.get_value('COMPILER'),
- debug=str(self._case.get_value('DEBUG')).upper(),
- ctsm_mkfile=os.path.join(self._lilac_build_dir(), 'ctsm.mk'))
- makecmd = 'make {makevars} atm_driver'.format(makevars=makevars)
+ symlink_force(
+ os.path.join(lndroot, "lilac", "atm_driver", "Makefile"),
+ os.path.join(blddir, "Makefile"),
+ )
+ symlink_force(
+ os.path.join(lndroot, "lilac", "atm_driver", "atm_driver.F90"),
+ os.path.join(blddir, "atm_driver.F90"),
+ )
+ symlink_force(
+ os.path.join(self._lilac_build_dir(), "case", "Macros.make"),
+ os.path.join(blddir, "Macros.make"),
+ )
+
+ makevars = "COMPILER={compiler} DEBUG={debug} CTSM_MKFILE={ctsm_mkfile}".format(
+ compiler=self._case.get_value("COMPILER"),
+ debug=str(self._case.get_value("DEBUG")).upper(),
+ ctsm_mkfile=os.path.join(self._lilac_build_dir(), "ctsm.mk"),
+ )
+ makecmd = "make {makevars} atm_driver".format(makevars=makevars)
# Normally the user will source either ctsm_build_environment.sh or
# ctsm_build_environment.csh before building the atmosphere model. In the context
# of this test case, case.load_env does the equivalent.
self._case.load_env()
- self._run_build_cmd(makecmd, blddir, 'atm_driver.bldlog')
+ self._run_build_cmd(makecmd, blddir, "atm_driver.bldlog")
def _create_link_to_atm_driver(self):
- caseroot = self._case.get_value('CASEROOT')
- run_exe = (self._case.get_value('run_exe')).strip()
+ caseroot = self._case.get_value("CASEROOT")
+ run_exe = (self._case.get_value("run_exe")).strip()
# Make a symlink to the atm_driver executable so that the case's run command finds
# it in the expected location
- symlink_force(os.path.join(caseroot, 'lilac_atm_driver', 'bld', 'atm_driver.exe'),
- run_exe)
+ symlink_force(os.path.join(caseroot, "lilac_atm_driver", "bld", "atm_driver.exe"), run_exe)
def _create_runtime_inputs(self):
- caseroot = self._case.get_value('CASEROOT')
+ caseroot = self._case.get_value("CASEROOT")
runtime_inputs = self._runtime_inputs_dir()
# NOTE: *** this test is currently tied to this single 10x15 grid resolution ***
- lnd_grid = self._case.get_value('LND_GRID')
- expect(lnd_grid == '10x15',
- "this test is currently tied to this single 10x15 grid resolution")
- lnd_domain_file = os.path.join(self._case.get_value('DIN_LOC_ROOT'),"share","domains",
- "domain.lnd.fv10x15_gx3v7.180321.nc")
+ lnd_grid = self._case.get_value("LND_GRID")
+ expect(
+ lnd_grid == "10x15", "this test is currently tied to this single 10x15 grid resolution"
+ )
+ lnd_domain_file = os.path.join(
+ self._case.get_value("DIN_LOC_ROOT"),
+ "share",
+ "domains",
+ "domain.lnd.fv10x15_gx3v7.180321.nc",
+ )
# Cheat a bit here: Get the fsurdat file from the already-generated lnd_in file in
# the host test case - i.e., from the standard cime-based preview_namelists. But
@@ -147,75 +162,96 @@ def _create_runtime_inputs(self):
# we expect the user to identify fsurdat manually; in this testing situation, we
# need to come up with some way to replace this manual identification, so cheating
# feels acceptable.
- self._case.create_namelists(component='lnd')
+ self._case.create_namelists(component="lnd")
fsurdat = self._extract_var_from_namelist(
- nl_filename=os.path.join(caseroot, 'CaseDocs', 'lnd_in'),
- varname='fsurdat')
+ nl_filename=os.path.join(caseroot, "CaseDocs", "lnd_in"), varname="fsurdat"
+ )
- self._fill_in_variables_in_file(filepath=os.path.join(runtime_inputs, 'ctsm.cfg'),
- replacements={'lnd_domain_file':lnd_domain_file,
- 'fsurdat':fsurdat})
+ self._fill_in_variables_in_file(
+ filepath=os.path.join(runtime_inputs, "ctsm.cfg"),
+ replacements={"lnd_domain_file": lnd_domain_file, "fsurdat": fsurdat},
+ )
# The user_nl_ctsm in the case directory is set up based on the standard testmods
# mechanism. We use that one in place of the standard user_nl_ctsm, since the one
# in the case directory may contain test-specific modifications.
- shutil.copyfile(src=os.path.join(caseroot, 'user_nl_ctsm'),
- dst=os.path.join(runtime_inputs, 'user_nl_ctsm'))
-
- script_to_run = os.path.join(runtime_inputs, 'make_runtime_inputs')
- self._run_build_cmd('{} --rundir {}'.format(script_to_run, runtime_inputs),
- runtime_inputs,
- 'make_runtime_inputs.log')
+ shutil.copyfile(
+ src=os.path.join(caseroot, "user_nl_ctsm"),
+ dst=os.path.join(runtime_inputs, "user_nl_ctsm"),
+ )
+
+ script_to_run = os.path.join(runtime_inputs, "make_runtime_inputs")
+ self._run_build_cmd(
+ "{} --rundir {}".format(script_to_run, runtime_inputs),
+ runtime_inputs,
+ "make_runtime_inputs.log",
+ )
# In lilac_in, we intentionally use the land mesh file for both atm_mesh_filename
# and lnd_mesh_filename
- lnd_mesh = self._case.get_value('LND_DOMAIN_MESH')
- casename = self._case.get_value('CASE')
- self._fill_in_variables_in_file(filepath=os.path.join(runtime_inputs, 'lilac_in'),
- replacements={'caseid':casename,
- 'atm_mesh_filename':lnd_mesh,
- 'lnd_mesh_filename':lnd_mesh,
- 'lilac_histfreq_option':'ndays'},
- placeholders={'caseid':'ctsm_lilac',
- 'lilac_histfreq_option':'never'})
+ lnd_mesh = self._case.get_value("LND_DOMAIN_MESH")
+ casename = self._case.get_value("CASE")
+ self._fill_in_variables_in_file(
+ filepath=os.path.join(runtime_inputs, "lilac_in"),
+ replacements={
+ "caseid": casename,
+ "atm_mesh_filename": lnd_mesh,
+ "lnd_mesh_filename": lnd_mesh,
+ "lilac_histfreq_option": "ndays",
+ },
+ placeholders={"caseid": "ctsm_lilac", "lilac_histfreq_option": "never"},
+ )
# We run download_input_data partly because it may be needed and partly to test
# this script.
- script_to_run = os.path.join(runtime_inputs, 'download_input_data')
- self._run_build_cmd('{} --rundir {}'.format(script_to_run, runtime_inputs),
- runtime_inputs,
- 'download_input_data.log')
+ script_to_run = os.path.join(runtime_inputs, "download_input_data")
+ self._run_build_cmd(
+ "{} --rundir {}".format(script_to_run, runtime_inputs),
+ runtime_inputs,
+ "download_input_data.log",
+ )
def _setup_atm_driver_rundir(self):
"""Set up the directory from which we will actually do the run"""
- lndroot = self._case.get_value('COMP_ROOT_DIR_LND')
+ lndroot = self._case.get_value("COMP_ROOT_DIR_LND")
rundir = self._atm_driver_rundir()
if not os.path.exists(rundir):
os.makedirs(rundir)
- shutil.copyfile(src=os.path.join(lndroot, 'lilac', 'atm_driver', 'atm_driver_in'),
- dst=os.path.join(rundir, 'atm_driver_in'))
+ shutil.copyfile(
+ src=os.path.join(lndroot, "lilac", "atm_driver", "atm_driver_in"),
+ dst=os.path.join(rundir, "atm_driver_in"),
+ )
# As elsewhere: assume the land variables also apply to the atmosphere
- lnd_mesh = self._case.get_value('LND_DOMAIN_MESH')
- lnd_nx = self._case.get_value('LND_NX')
- lnd_ny = self._case.get_value('LND_NY')
- expect(self._case.get_value('STOP_OPTION') == 'ndays',
- 'LILAC testing currently assumes STOP_OPTION of ndays, not {}'.format(
- self._case.get_value('STOP_OPTION')))
- stop_n = self._case.get_value('STOP_N')
- casename = self._case.get_value('CASE')
- self._fill_in_variables_in_file(filepath=os.path.join(rundir, 'atm_driver_in'),
- replacements={'caseid':casename,
- 'atm_mesh_file':lnd_mesh,
- 'atm_global_nx':str(lnd_nx),
- 'atm_global_ny':str(lnd_ny),
- 'atm_stop_day':str(stop_n+1),
- 'atm_ndays_all_segs':str(stop_n)})
+ lnd_mesh = self._case.get_value("LND_DOMAIN_MESH")
+ lnd_nx = self._case.get_value("LND_NX")
+ lnd_ny = self._case.get_value("LND_NY")
+ expect(
+ self._case.get_value("STOP_OPTION") == "ndays",
+ "LILAC testing currently assumes STOP_OPTION of ndays, not {}".format(
+ self._case.get_value("STOP_OPTION")
+ ),
+ )
+ stop_n = self._case.get_value("STOP_N")
+ casename = self._case.get_value("CASE")
+ self._fill_in_variables_in_file(
+ filepath=os.path.join(rundir, "atm_driver_in"),
+ replacements={
+ "caseid": casename,
+ "atm_mesh_file": lnd_mesh,
+ "atm_global_nx": str(lnd_nx),
+ "atm_global_ny": str(lnd_ny),
+ "atm_stop_day": str(stop_n + 1),
+ "atm_ndays_all_segs": str(stop_n),
+ },
+ )
for file_to_link in _LILAC_RUNTIME_FILES:
- symlink_force(os.path.join(self._runtime_inputs_dir(), file_to_link),
- os.path.join(rundir, file_to_link))
+ symlink_force(
+ os.path.join(self._runtime_inputs_dir(), file_to_link),
+ os.path.join(rundir, file_to_link),
+ )
init_generated_files_dir = os.path.join(rundir, "init_generated_files")
if not os.path.exists(init_generated_files_dir):
@@ -236,8 +272,8 @@ def _cmpgen_namelists(self):
because that one will have compared the test's standard CaseDocs with the files
generated from here - and those two sets of namelists can be quite different.
"""
- caseroot = self._case.get_value('CASEROOT')
- casedocs = os.path.join(caseroot, 'CaseDocs')
+ caseroot = self._case.get_value("CASEROOT")
+ casedocs = os.path.join(caseroot, "CaseDocs")
if os.path.exists(casedocs):
shutil.rmtree(casedocs)
os.makedirs(casedocs)
@@ -245,12 +281,13 @@ def _cmpgen_namelists(self):
# case_cmpgen_namelists uses the existence of drv_in to decide whether namelists
# need to be regenerated. We do NOT want it to regenerate namelists, so we give it
# the file it wants.
- with open(os.path.join(casedocs, 'drv_in'), 'a') as drv_in:
+ with open(os.path.join(casedocs, "drv_in"), "a") as drv_in:
pass
- for onefile in _LILAC_RUNTIME_FILES + ['atm_driver_in']:
- safe_copy(os.path.join(self._atm_driver_rundir(), onefile),
- os.path.join(casedocs, onefile))
+ for onefile in _LILAC_RUNTIME_FILES + ["atm_driver_in"]:
+ safe_copy(
+ os.path.join(self._atm_driver_rundir(), onefile), os.path.join(casedocs, onefile)
+ )
success = self._case.case_cmpgen_namelists()
# The setting of the NLCOMP phase status in case_cmpgen_namelists doesn't work
@@ -259,8 +296,11 @@ def _cmpgen_namelists(self):
# overwriting whatever was set by case_cmpgen_namelists). So we need to set it
# here.
with self._test_status:
- self._test_status.set_status(NAMELIST_PHASE, TEST_PASS_STATUS if success else TEST_FAIL_STATUS,
- comments="(used lilac namelists)")
+ self._test_status.set_status(
+ NAMELIST_PHASE,
+ TEST_PASS_STATUS if success else TEST_FAIL_STATUS,
+ comments="(used lilac namelists)",
+ )
def _extract_var_from_namelist(self, nl_filename, varname):
"""Tries to find a variable named varname in the given file; returns its value
@@ -272,7 +312,7 @@ def _extract_var_from_namelist(self, nl_filename, varname):
match = re.search(r'^ *{} *= *[\'"]([^\'"]+)'.format(varname), line)
if match:
return match.group(1)
- expect(False, '{} not found in {}'.format(varname, nl_filename))
+ expect(False, "{} not found in {}".format(varname, nl_filename))
def _fill_in_variables_in_file(self, filepath, replacements, placeholders=None):
"""For the given file, make the given replacements
@@ -286,35 +326,37 @@ def _fill_in_variables_in_file(self, filepath, replacements, placeholders=None):
if placeholders is None:
placeholders = {}
- orig_filepath = '{}.orig'.format(filepath)
+ orig_filepath = "{}.orig".format(filepath)
if not os.path.exists(orig_filepath):
- shutil.copyfile(src=filepath,
- dst=orig_filepath)
+ shutil.copyfile(src=filepath, dst=orig_filepath)
os.remove(filepath)
counts = dict.fromkeys(replacements, 0)
with open(orig_filepath) as orig_file:
- with open(filepath, 'w') as new_file:
+ with open(filepath, "w") as new_file:
for orig_line in orig_file:
line = orig_line
for varname in replacements:
if varname in placeholders:
this_placeholder = placeholders[varname]
else:
- this_placeholder = 'FILL_THIS_IN'
+ this_placeholder = "FILL_THIS_IN"
line, replacement_done = self._fill_in_variable(
line=line,
varname=varname,
value=replacements[varname],
- placeholder=this_placeholder)
+ placeholder=this_placeholder,
+ )
if replacement_done:
counts[varname] += 1
break
new_file.write(line)
for varname in counts:
- expect(counts[varname] > 0,
- 'Did not find any instances of <{}> to replace in {}'.format(varname, filepath))
+ expect(
+ counts[varname] > 0,
+ "Did not find any instances of <{}> to replace in {}".format(varname, filepath),
+ )
def _fill_in_variable(self, line, varname, value, placeholder):
"""Fill in a placeholder variable in a config or namelist file
@@ -324,9 +366,11 @@ def _fill_in_variable(self, line, varname, value, placeholder):
line is for varname; otherwise returns line unchanged
- replacement_done is True if the replacement was done, otherwise False
"""
- if re.search(r'^ *{} *='.format(varname), line):
- expect(placeholder in line,
- 'Placeholder to replace ({}) not found in <{}>'.format(placeholder, line.strip()))
+ if re.search(r"^ *{} *=".format(varname), line):
+ expect(
+ placeholder in line,
+ "Placeholder to replace ({}) not found in <{}>".format(placeholder, line.strip()),
+ )
newline = line.replace(placeholder, value)
replacement_done = True
else:
@@ -335,13 +379,13 @@ def _fill_in_variable(self, line, varname, value, placeholder):
return (newline, replacement_done)
def _lilac_build_dir(self):
- return os.path.join(self._case.get_value('CASEROOT'), 'lilac_build')
+ return os.path.join(self._case.get_value("CASEROOT"), "lilac_build")
def _runtime_inputs_dir(self):
- return os.path.join(self._lilac_build_dir(), 'runtime_inputs')
+ return os.path.join(self._lilac_build_dir(), "runtime_inputs")
def _atm_driver_rundir(self):
- return os.path.join(self._case.get_value('CASEROOT'), 'lilac_atm_driver', 'run')
+ return os.path.join(self._case.get_value("CASEROOT"), "lilac_atm_driver", "run")
@staticmethod
def _run_build_cmd(cmd, exeroot, logfile):
@@ -363,6 +407,11 @@ def run_phase(self):
# case.get_mpirun_cmd creates a command that runs the executable given by
# case.run_exe. So it's important that (elsewhere in this test script) we create a
# link pointing from that to the atm_driver.exe executable.
+ #
+ # 2024/5/28 slevis: We added the load_env here to replace the
+ # behavior of the PBS -V directive that was removed from
+ # /ccs_config/machines/config_batch.xml
+ self._case.load_env(reset=True)
lid = new_lid()
os.environ["OMP_NUM_THREADS"] = str(self._case.thread_count)
cmd = self._case.get_mpirun_cmd(allow_unresolved_envvars=False)
@@ -378,9 +427,9 @@ def _link_to_output_files(self):
directory. But then we need to create these links afterwards for the sake of
baseline generation / comparison.
"""
- casename = self._case.get_value('CASE')
- rundir = self._case.get_value('RUNDIR')
- pattern = '{}*.nc'.format(casename)
+ casename = self._case.get_value("CASE")
+ rundir = self._case.get_value("RUNDIR")
+ pattern = "{}*.nc".format(casename)
# First remove any old files from the run directory
old_files = glob.glob(os.path.join(rundir, pattern))
diff --git a/cime_config/SystemTests/lreprstruct.py b/cime_config/SystemTests/lreprstruct.py
index 27dab77592..a03fb1815b 100644
--- a/cime_config/SystemTests/lreprstruct.py
+++ b/cime_config/SystemTests/lreprstruct.py
@@ -22,31 +22,54 @@
logger = logging.getLogger(__name__)
-class LREPRSTRUCT(SystemTestsCompareTwo):
+class LREPRSTRUCT(SystemTestsCompareTwo):
def __init__(self, case):
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = 'grain1',
- run_one_description = 'use a reproductive structure pool',
- run_two_description = 'use a single grain pool',
- ignore_fieldlist_diffs = True)
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="grain1",
+ run_one_description="use a reproductive structure pool",
+ run_two_description="use a single grain pool",
+ ignore_fieldlist_diffs=True,
+ )
def _case_one_setup(self):
# We don't really need a second grain pool for this test, but we might as well do
# this to further exercise the looping over different reproductive components.
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "for_testing_use_second_grain_pool=.true.")
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "for_testing_use_repr_structure_pool=.true.")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="for_testing_use_second_grain_pool=.true.",
+ )
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="for_testing_use_repr_structure_pool=.true.",
+ )
+
+ # Replace any GRAIN outputs with the same outputs for REPRODUCTIVE1 and REPRODUCTIVE2
+ user_nl_clm_path = os.path.join(self._get_caseroot(), "user_nl_clm")
+ with open(user_nl_clm_path) as f:
+ user_nl_clm_text = f.read()
+ for grain_output in re.findall("GRAIN\w*", user_nl_clm_text):
+ user_nl_clm_text = user_nl_clm_text.replace(
+ grain_output,
+ grain_output.replace("GRAIN", "REPRODUCTIVE1")
+ + "', '"
+ + grain_output.replace("GRAIN", "REPRODUCTIVE2"),
+ )
+ with open(user_nl_clm_path, "w") as f:
+ f.write(user_nl_clm_text)
def _case_two_setup(self):
# This is needed in the nearly-standard case to prevent grain from being used to
# replenish crop seed deficits, thus making grain act like the reproductive
# structure pools. (It wouldn't hurt to do this in case one as well, but it
# shouldn't be needed there, since we shouldn't have any grain there anyway.)
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "for_testing_no_crop_seed_replenishment=.true.")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="for_testing_no_crop_seed_replenishment=.true.",
+ )
diff --git a/cime_config/SystemTests/lvg.py b/cime_config/SystemTests/lvg.py
index 36fae196b2..d73f4e707b 100644
--- a/cime_config/SystemTests/lvg.py
+++ b/cime_config/SystemTests/lvg.py
@@ -16,22 +16,28 @@
logger = logging.getLogger(__name__)
-class LVG(SystemTestsCompareTwo):
+class LVG(SystemTestsCompareTwo):
def __init__(self, case):
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = 'more_virtual',
- run_one_description = 'standard set of virtual columns',
- run_two_description = 'add virtual columns over Antarctica')
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="more_virtual",
+ run_one_description="standard set of virtual columns",
+ run_two_description="add virtual columns over Antarctica",
+ )
def _case_one_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "glacier_region_behavior = 'single_at_atm_topo', 'virtual', 'virtual', 'multiple'")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="glacier_region_behavior = 'single_at_atm_topo', 'UNSET', 'virtual', 'multiple'",
+ )
def _case_two_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "glacier_region_behavior = 'single_at_atm_topo', 'virtual', 'virtual', 'virtual'")
-
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="glacier_region_behavior = 'single_at_atm_topo', 'UNSET', 'virtual', 'virtual'",
+ )
diff --git a/cime_config/SystemTests/lwiso.py b/cime_config/SystemTests/lwiso.py
index 1083e2ff36..37cfd42603 100644
--- a/cime_config/SystemTests/lwiso.py
+++ b/cime_config/SystemTests/lwiso.py
@@ -17,15 +17,18 @@
logger = logging.getLogger(__name__)
-class LWISO(SystemTestsCompareTwo):
+class LWISO(SystemTestsCompareTwo):
def __init__(self, case):
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = 'nowiso',
- run_one_description = 'water isotopes on',
- run_two_description = 'water isotopes off',
- ignore_fieldlist_diffs = True)
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="nowiso",
+ run_one_description="water isotopes on",
+ run_two_description="water isotopes off",
+ ignore_fieldlist_diffs=True,
+ )
def _case_one_setup(self):
# BUG(wjs, 2019-07-30, ESCOMP/ctsm#495) We currently can't turn on actual water
@@ -33,12 +36,15 @@ def _case_one_setup(self):
# enable_water_tracer_consistency_checks rather than enable_water_isotopes;
# eventually, though, we should change this to the latter. (See
# .)
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "enable_water_tracer_consistency_checks=.true.")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="enable_water_tracer_consistency_checks=.true.",
+ )
def _case_two_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "enable_water_tracer_consistency_checks=.false.")
-
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="enable_water_tracer_consistency_checks=.false.",
+ )
diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py
new file mode 100644
index 0000000000..3a083bc724
--- /dev/null
+++ b/cime_config/SystemTests/mksurfdataesmf.py
@@ -0,0 +1,156 @@
+"""
+This test passes if mksurfdata_esmf generates an fsurdat (surface dataset)
+and the CTSM completes a simulation with this fsurdat file.
+
+We test res = '10x15' because it uses a lower-res topography file instead of
+the 1-km topography raw dataset. The 1-km file causes the test to run out of
+memory on cheyenne.
+
+Currently casper complains that `git -C` is not a valid option.
+I added -C to the `git describe` in gen_mksurfdata_namelist for this
+system test to work.
+"""
+import os
+import sys
+import subprocess
+from datetime import datetime
+from CIME.SystemTests.system_tests_common import SystemTestsCommon
+from CIME.XML.standard_module_setup import *
+from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files
+
+logger = logging.getLogger(__name__)
+
+
+class MKSURFDATAESMF(SystemTestsCommon):
+ def __init__(self, case):
+ """
+ initialize an object interface to the SMS system test
+ """
+ SystemTestsCommon.__init__(self, case)
+
+ # Paths and strings needed throughout
+ ctsm_root = self._case.get_value("COMP_ROOT_DIR_LND")
+ self._tool_path = os.path.join(ctsm_root, "tools/mksurfdata_esmf")
+ self._tool_bld = os.path.join(self._get_caseroot(), "tool_bld")
+ time_stamp = datetime.today().strftime("%y%m%d")
+ self._res = "10x15" # see important comment in script's docstring
+ self._model_yr = "1850"
+ self._jobscript = os.path.join(
+ self._get_caseroot(), "mksurfdataesmf_test_jobscript_single.sh"
+ )
+ self._fsurdat_namelist = os.path.join(
+ self._get_caseroot(),
+ f"surfdata_{self._res}_hist_{self._model_yr}_78pfts_c{time_stamp}.namelist",
+ )
+ self._fsurdat_nc = os.path.join(
+ self._get_caseroot(),
+ f"surfdata_{self._res}_hist_{self._model_yr}_78pfts_c{time_stamp}.nc",
+ )
+ self._TestStatus_log_path = os.path.join(self._get_caseroot(), "TestStatus.log")
+
+ def build_phase(self, sharedlib_only=False, model_only=False):
+ """
+ Build executable that will generate fsurdat
+ Generate namelist for generating fsurdat
+ Generate jobscript that runs executable
+ Modify user_nl_clm to point to the generated fsurdat
+ """
+ # build_phase gets called twice:
+ # - once with sharedlib_only = True and
+ # - once with model_only = True
+ # Call the following steps only once during the test but do not skip
+ # if the test stops and gets restarted.
+ if sharedlib_only:
+ # Paths and strings
+ build_script_path = os.path.join(self._tool_path, "gen_mksurfdata_build")
+ nml_script_path = os.path.join(self._tool_path, "gen_mksurfdata_namelist")
+ gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single")
+ gen_mksurfdata_namelist = f"{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}"
+
+ if not os.path.exists(nml_script_path):
+ sys.exit(f"ERROR The build naemlist script {nml_script_path} does NOT exist")
+
+ if not os.path.exists(gen_jobscript_path):
+ sys.exit(f"ERROR The jobscript script {gen_jobscript_path} does NOT exist")
+
+ gen_mksurfdata_jobscript = (
+ f"{gen_jobscript_path} --number-of-nodes 1 --tasks-per-node 64 --namelist-file "
+ + f"{self._fsurdat_namelist} --bld-path {self._tool_bld} --jobscript-file {self._jobscript}"
+ )
+ if not os.path.exists(build_script_path):
+ sys.exit(f"ERROR The build script {build_script_path} does NOT exist")
+
+ # Rm tool_bld and build executable that will generate fsurdat
+ try:
+ subprocess.check_call(f"rm -rf {self._tool_bld}", shell=True)
+ except subprocess.CalledProcessError as e:
+ sys.exit(
+ f"{e} ERROR REMOVING {self._tool_bld}. DETAILS IN {self._TestStatus_log_path}"
+ )
+ try:
+ subprocess.check_call(f"{build_script_path} --blddir {self._tool_bld}", shell=True)
+ except subprocess.CalledProcessError as e:
+ print(f"build directory = {self._tool_bld}\n")
+ sys.exit(
+ f"{e} ERROR RUNNING {build_script_path} DETAILS IN {self._TestStatus_log_path}"
+ )
+
+ # Generate namelist for generating fsurdat (rm namelist if exists)
+ if os.path.exists(self._fsurdat_namelist):
+ os.remove(self._fsurdat_namelist)
+ try:
+ subprocess.check_call(gen_mksurfdata_namelist, shell=True)
+ except subprocess.CalledProcessError as e:
+ sys.exit(
+ f"{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}"
+ )
+
+ # Generate jobscript that will run the executable
+ if os.path.exists(self._jobscript):
+ os.remove(self._jobscript)
+ try:
+ subprocess.check_call(gen_mksurfdata_jobscript, shell=True)
+ except subprocess.CalledProcessError as e:
+ sys.exit(
+ f"{e} ERROR RUNNING {gen_mksurfdata_jobscript}. DETAILS IN {self._TestStatus_log_path}"
+ )
+ # Change self._jobscript to an executable file
+ subprocess.check_call(f"chmod a+x {self._jobscript}", shell=True)
+
+ # Call this step only once even if the test stops and gets restarted.
+ if not os.path.exists(os.path.join(self._get_caseroot(), "done_MKSURFDATAESMF_setup.txt")):
+ # Modify user_nl_clm to point to the generated fsurdat
+ self._modify_user_nl()
+ with open("done_MKSURFDATAESMF_setup.txt", "w") as fp:
+ pass
+
+ self.build_indv(sharedlib_only=sharedlib_only, model_only=model_only)
+
+ def run_phase(self):
+ """
+ Run executable to generate fsurdat
+ Submit CTSM run that uses fsurdat just generated
+ """
+
+ # Run executable to generate fsurdat (rm fsurdat if exists)
+ if os.path.exists(self._fsurdat_nc):
+ os.remove(self._fsurdat_nc)
+ try:
+ subprocess.check_call(self._jobscript, shell=True)
+ except subprocess.CalledProcessError as e:
+ sys.exit(f"{e} ERROR RUNNING {self._jobscript}; details in {self._TestStatus_log_path}")
+
+ # Submit CTSM run that uses fsurdat just generated
+ self.run_indv()
+
+ def _modify_user_nl(self):
+ """
+ Modify user_nl_clm to point to the generated fsurdat
+ """
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="fsurdat = '{}'".format(self._fsurdat_nc)
+ + "\n"
+ + "convert_ocean_to_land = .true.",
+ )
diff --git a/cime_config/SystemTests/pvt.py b/cime_config/SystemTests/pvt.py
new file mode 100644
index 0000000000..cf923dd334
--- /dev/null
+++ b/cime_config/SystemTests/pvt.py
@@ -0,0 +1,133 @@
+"""
+FATES land use potential vegetation spin up + transient test
+
+This is a FATES specific test:
+
+1) conduct a spinup with use_fates_potentialveg on
+ - write restart file
+ - use CLM_ACCELERATED_SPINUP?
+2) run a transient landuse case with use_fates_lupft
+ - start from the restart file generated in (1)
+"""
+from CIME.XML.standard_module_setup import *
+from CIME.SystemTests.system_tests_common import SystemTestsCommon
+from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files
+import shutil, glob, os
+
+logger = logging.getLogger(__name__)
+
+
+class PVT(SystemTestsCommon):
+ def __init__(self, case):
+ SystemTestsCommon.__init__(self, case)
+
+ # Do not allow PVT to be run with certain testmods
+ # Should this be targeted to a specific testmod for simplicity for now?
+ # Technically this could be run with the luh fates_harvest_modes
+ error_message = None
+ casebaseid = self._case.get_value("CASEBASEID")
+ casebaseid = casebaseid.split("-")[-1]
+ if casebaseid[0:10] != "FatesLUPFT":
+ error_message = f"Only call PVT with testmod FatesLUPFT. {casebaseid} selected."
+
+ # Only allow to run if resolution is 4x5 for now
+ # Other grid resolutions will be pre-processed and included in the namelist defaults at a future date.
+ # Potentially we could generate these on the fly although doing so would result in increased build time
+ lnd_grid = self._case.get_value("LND_GRID")
+ if lnd_grid != "4x5":
+ error_message = (
+ f"PVT can currently only be run with 4x5 resolution. {lnd_grid} selected."
+ )
+
+ if error_message is not None:
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ def run_phase(self):
+ # -------------------------------------------------------------------
+ # (1) Run FATES spin-up case in potential vegetation mode
+ # -------------------------------------------------------------------
+ orig_case = self._case
+ orig_casevar = self._case.get_value("CASE")
+ caseroot = self._case.get_value("CASEROOT")
+
+ # Set the run start date based on the desired starting reference case year
+ refcase_year = 1700
+ stop_n_pveg = 5
+ startyear_pveg = refcase_year - stop_n_pveg
+
+ # clone the main case to create spinup case
+ logger.info("PVT log: cloning setup")
+ clone_path = "{}.potveg".format(caseroot)
+ if os.path.exists(clone_path):
+ shutil.rmtree(clone_path)
+ logger.info("PVT log: cloning")
+ clone = self._case.create_clone(clone_path, keepexe=True)
+ logger.info("PVT log: cloning complete")
+
+ # setup the clone case
+ os.chdir(clone_path)
+ self._set_active_case(clone)
+
+ # set the clone case values
+ with clone:
+ clone.set_value("CLM_ACCELERATED_SPINUP", "off")
+ clone.set_value("STOP_N", stop_n_pveg)
+ clone.set_value("STOP_OPTION", "nyears")
+ clone.set_value("RUN_STARTDATE", "{}-01-01".format(startyear_pveg))
+
+ # Modify the spin up case to use the potential vegetation mode.
+ # Checks for incompatible cases and necessary mapping files are
+ # handled in the build case.
+ # Turn off fates_harvest_mode for the spin up.
+
+ logger.info("PVT log: modify user_nl_clm file for spin up run")
+ added_content = ["use_fates_potentialveg = .true.", "fates_harvest_mode = 'no_harvest'"]
+ append_to_user_nl_files(clone_path, "clm", added_content)
+
+ # Run the spin up case
+ # As per SSP test:
+ # "No history files expected, set suffix=None to avoid compare error"
+ logger.info("PVT log: starting spin-up run")
+ dout_sr = clone.get_value("DOUT_S_ROOT")
+ self._skip_pnl = False
+ self.run_indv(suffix=None, st_archive=True)
+
+ # -------------------------------------------------------------------
+ # (2) Run FATES transient case using restart file from spin-up
+ # -------------------------------------------------------------------
+ os.chdir(caseroot)
+ self._set_active_case(orig_case)
+
+ # Copy restart files from spin up to the transient case run directory
+ # obtain rpointer files and necessary restart files from short term archiving directory
+ rundir = self._case.get_value("RUNDIR")
+
+ refdate = str(refcase_year) + "-01-01-00000"
+ rest_path = os.path.join(dout_sr, "rest", "{}".format(refdate))
+
+ for item in glob.glob("{}/*{}*".format(rest_path, refdate)):
+ link_name = os.path.join(rundir, os.path.basename(item))
+ if os.path.islink(link_name) and os.readlink(link_name) == item:
+ # Link is already set up correctly: do nothing
+ # (os.symlink raises an exception if you try to replace an
+ # existing file)
+ pass
+ else:
+ os.symlink(item, link_name)
+
+ for item in glob.glob("{}/*rpointer*".format(rest_path)):
+ shutil.copy(item, rundir)
+
+ # Update run case settings
+ self._case.set_value("CLM_ACCELERATED_SPINUP", "off")
+ self._case.set_value("RUN_TYPE", "hybrid")
+ self._case.set_value("GET_REFCASE", False)
+ self._case.set_value("RUN_REFCASE", "{}.potveg".format(orig_casevar))
+ self._case.set_value("RUN_REFDATE", "{}-01-01".format(refcase_year))
+ self._case.set_value("RUN_STARTDATE", "{}-01-01".format(refcase_year))
+ self._case.set_value("DOUT_S", False)
+ self._case.flush()
+
+ # do the restart run (short term archiving is off)
+ self.run_indv()
diff --git a/cime_config/SystemTests/rxcropmaturity.py b/cime_config/SystemTests/rxcropmaturity.py
new file mode 100644
index 0000000000..fb254c408f
--- /dev/null
+++ b/cime_config/SystemTests/rxcropmaturity.py
@@ -0,0 +1,521 @@
+"""
+CTSM-specific test that first performs a GDD-generating run, then calls
+Python code to generate the maturity requirement file. This is then used
+in a sowing+maturity forced run, which finally is tested to ensure
+correct behavior.
+
+Currently only supports 0.9x1.25, 1.9x2.5, and 10x15 resolutions. Eventually,
+this test should be able to generate its own files at whatever resolution it's
+called at. Well, really, the ultimate goal would be to give CLM the files
+at the original resolution (for GGCMI phase 3, 0.5°) and have the stream
+code do the interpolation. However, that wouldn't act on harvest dates
+(which are needed for generate_gdds.py). I could have Python interpolate
+those, but this would cause a potential inconsistency.
+"""
+
+import os
+import re
+import systemtest_utils as stu
+import subprocess
+from CIME.SystemTests.system_tests_common import SystemTestsCommon
+from CIME.XML.standard_module_setup import *
+from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files
+from CIME.case import Case
+import shutil, glob
+
+logger = logging.getLogger(__name__)
+
+
+class RXCROPMATURITYSHARED(SystemTestsCommon):
+ def __init__(self, case):
+ # initialize an object interface to the SMS system test
+ SystemTestsCommon.__init__(self, case)
+
+ # Is this a real RXCROPMATURITY test or not?
+ casebaseid = self._case.get_value("CASEBASEID")
+ full_test = "RXCROPMATURITY_" in casebaseid
+ skipgen_test = "RXCROPMATURITYSKIPGEN_" in casebaseid
+
+ # Ensure run length is at least 5 years. Minimum to produce one complete growing season
+ # (i.e., two complete calendar years) actually 4 years, but that only gets you 1 season
+ # usable for GDD generation, so you can't check for season-to-season consistency.
+ stop_n = self._case.get_value("STOP_N")
+ stop_option = self._case.get_value("STOP_OPTION")
+ stop_n_orig = stop_n
+ stop_option_orig = stop_option
+ if "nsecond" in stop_option:
+ stop_n /= 60
+ stop_option = "nminutes"
+ if "nminute" in stop_option:
+ stop_n /= 60
+ stop_option = "nhours"
+ if "nhour" in stop_option:
+ stop_n /= 24
+ stop_option = "ndays"
+ if "nday" in stop_option:
+ stop_n /= 365
+ stop_option = "nyears"
+ if "nmonth" in stop_option:
+ stop_n /= 12
+ stop_option = "nyears"
+ error_message = None
+ if "nyear" not in stop_option:
+ error_message = (
+ f"STOP_OPTION ({stop_option_orig}) must be nsecond(s), nminute(s), "
+ + "nhour(s), nday(s), nmonth(s), or nyear(s)"
+ )
+ elif full_test and stop_n < 5:
+ error_message = (
+ "RXCROPMATURITY must be run for at least 5 years; you requested "
+ + f"{stop_n_orig} {stop_option_orig[1:]}"
+ )
+ elif skipgen_test and stop_n < 3:
+ # First year is discarded because crops are already in the ground at restart, and those
+ # aren't affected by the new crop calendar inputs. The second year is useable, but we
+ # need a third year so that all crops planted in the second year have a chance to
+ # finish.
+ error_message = (
+ "RXCROPMATURITYSKIPGEN (both-forced part) must be run for at least 3 years; you requested "
+ + f"{stop_n_orig} {stop_option_orig[1:]}"
+ )
+ if error_message is not None:
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ # Get the number of complete years that will be run
+ self._run_Nyears = int(stop_n)
+
+ # Only allow RXCROPMATURITY to be called with test cropMonthOutput
+ if casebaseid.split("-")[-1] != "cropMonthOutput":
+ error_message = (
+ "Only call RXCROPMATURITY with test cropMonthOutput "
+ + "to avoid potentially huge sets of daily outputs."
+ )
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ # Get files with prescribed sowing and harvest dates
+ self._get_rx_dates()
+
+ # Get cultivar maturity requirement file to fall back on if not generating it here
+ self._gdds_file = None
+ self._fallback_gdds_file = os.path.join(
+ os.path.dirname(self._sdatefile), "gdds_20230829_161011.nc"
+ )
+
+ # Which conda environment should we use?
+ self._get_conda_env()
+
+ def _run_phase(self, skip_gen=False):
+ # Modeling this after the SSP test, we create a clone to be the case whose outputs we don't
+ # want to be saved as baseline.
+
+ # -------------------------------------------------------------------
+ # (1) Set up GDD-generating run
+ # -------------------------------------------------------------------
+ # Create clone to be GDD-Generating case
+ logger.info("RXCROPMATURITY log: cloning setup")
+ case_rxboth = self._case
+ caseroot = self._case.get_value("CASEROOT")
+ clone_path = f"{caseroot}.gddgen"
+ self._path_gddgen = clone_path
+ if os.path.exists(self._path_gddgen):
+ shutil.rmtree(self._path_gddgen)
+ logger.info("RXCROPMATURITY log: cloning")
+ case_gddgen = self._case.create_clone(clone_path, keepexe=True)
+ logger.info("RXCROPMATURITY log: done cloning")
+
+ os.chdir(self._path_gddgen)
+ self._set_active_case(case_gddgen)
+
+ # Set up stuff that applies to both tests
+ self._setup_all()
+
+ # Add stuff specific to GDD-Generating run
+ logger.info("RXCROPMATURITY log: modify user_nl files: generate GDDs")
+ self._append_to_user_nl_clm(
+ [
+ "stream_fldFileName_cultivar_gdds = ''",
+ "generate_crop_gdds = .true.",
+ "use_mxmat = .false.",
+ " ",
+ "! (h2) Daily outputs for GDD generation and figure-making",
+ "hist_fincl3 = 'GDDACCUM', 'GDDHARV'",
+ "hist_nhtfrq(3) = -24",
+ "hist_mfilt(3) = 365",
+ "hist_type1d_pertape(3) = 'PFTS'",
+ "hist_dov2xy(3) = .false.",
+ ]
+ )
+
+ # If flanduse_timeseries is defined, we need to make a static version for this test. This
+ # should have every crop in most of the world.
+ self._get_flanduse_timeseries_in(case_gddgen)
+ if self._flanduse_timeseries_in is not None:
+
+ # Download files from the server, if needed
+ case_gddgen.check_all_input_data()
+
+ # Copy needed file from original to gddgen directory
+ shutil.copyfile(
+ os.path.join(caseroot, ".env_mach_specific.sh"),
+ os.path.join(self._path_gddgen, ".env_mach_specific.sh"),
+ )
+
+ # Make custom version of surface file
+ logger.info("RXCROPMATURITY log: run fsurdat_modifier")
+ self._run_fsurdat_modifier()
+
+ # -------------------------------------------------------------------
+ # (2) Perform GDD-generating run and generate prescribed GDDs file
+ # -------------------------------------------------------------------
+ logger.info("RXCROPMATURITY log: Start GDD-Generating run")
+
+ # As per SSP test:
+ # "No history files expected, set suffix=None to avoid compare error"
+ # We *do* expect history files here, but anyway. This works.
+ self._skip_pnl = False
+
+ # If not generating GDDs, only run a few days of this.
+ if skip_gen:
+ with Case(self._path_gddgen, read_only=False) as case:
+ case.set_value("STOP_N", 5)
+ case.set_value("STOP_OPTION", "ndays")
+
+ self.run_indv(suffix=None, st_archive=True)
+ if skip_gen:
+ # Interpolate an existing GDD file. Needed to check obedience to GDD inputs.
+ self._run_interpolate_gdds()
+ else:
+ self._run_generate_gdds(case_gddgen)
+
+ # -------------------------------------------------------------------
+ # (3) Set up and perform Prescribed Calendars run
+ # -------------------------------------------------------------------
+ os.chdir(caseroot)
+ self._set_active_case(case_rxboth)
+
+ # Set up stuff that applies to both tests
+ self._setup_all()
+
+ # Add stuff specific to Prescribed Calendars run
+ logger.info("RXCROPMATURITY log: modify user_nl files: Prescribed Calendars")
+ self._append_to_user_nl_clm(
+ [
+ "generate_crop_gdds = .false.",
+ f"stream_fldFileName_cultivar_gdds = '{self._gdds_file}'",
+ ]
+ )
+
+ self.run_indv()
+
+ # -------------------------------------------------------------------
+ # (4) Check Prescribed Calendars run
+ # -------------------------------------------------------------------
+ logger.info("RXCROPMATURITY log: output check: Prescribed Calendars")
+ self._run_check_rxboth_run(skip_gen)
+
+ # Get sowing and harvest dates for this resolution.
+ def _get_rx_dates(self):
+ # Eventually, I want to remove these hard-coded resolutions so that this test can generate
+ # its own sowing and harvest date files at whatever resolution is requested.
+ lnd_grid = self._case.get_value("LND_GRID")
+ input_data_root = self._case.get_value("DIN_LOC_ROOT")
+ processed_crop_dates_dir = f"{input_data_root}/lnd/clm2/cropdata/calendars/processed"
+ if lnd_grid == "10x15":
+ self._sdatefile = os.path.join(
+ processed_crop_dates_dir,
+ "sdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-f10_f10_mg37.2000-2000.20230330_165301.nc",
+ )
+ self._hdatefile = os.path.join(
+ processed_crop_dates_dir,
+ "hdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-f10_f10_mg37.2000-2000.20230330_165301.nc",
+ )
+ elif lnd_grid == "1.9x2.5":
+ self._sdatefile = os.path.join(
+ processed_crop_dates_dir,
+ "sdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-f19_g17.2000-2000.20230102_175625.nc",
+ )
+ self._hdatefile = os.path.join(
+ processed_crop_dates_dir,
+ "hdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-f19_g17.2000-2000.20230102_175625.nc",
+ )
+ elif lnd_grid == "0.9x1.25":
+ self._sdatefile = os.path.join(
+ processed_crop_dates_dir,
+ "sdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-f09_g17.2000-2000.20230520_134417.nc",
+ )
+ self._hdatefile = os.path.join(
+ processed_crop_dates_dir,
+ "hdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-f09_g17.2000-2000.20230520_134418.nc",
+ )
+ else:
+ error_message = "ERROR: RXCROPMATURITY currently only supports 0.9x1.25, 1.9x2.5, and 10x15 resolutions"
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ # Ensure files exist
+ error_message = None
+ if not os.path.exists(self._sdatefile):
+ error_message = f"ERROR: Sowing date file not found: {self._sdatefile}"
+ elif not os.path.exists(self._hdatefile):
+ error_message = f"ERROR: Harvest date file not found: {self._sdatefile}"
+ if error_message is not None:
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ def _setup_all(self):
+ logger.info("RXCROPMATURITY log: _setup_all start")
+
+ # Get some info
+ self._ctsm_root = self._case.get_value("COMP_ROOT_DIR_LND")
+ run_startdate = self._case.get_value("RUN_STARTDATE")
+ self._run_startyear = int(run_startdate.split("-")[0])
+
+ # Set sowing dates file (and other crop calendar settings) for all runs
+ logger.info("RXCROPMATURITY log: modify user_nl files: all tests")
+ self._modify_user_nl_allruns()
+ logger.info("RXCROPMATURITY log: _setup_all done")
+
+ # Make a surface dataset that has every crop in every gridcell
+ def _run_fsurdat_modifier(self):
+
+ # fsurdat should be defined. Where is it?
+ self._fsurdat_in = None
+ with open(self._lnd_in_path, "r") as lnd_in:
+ for line in lnd_in:
+ fsurdat_in = re.match(r" *fsurdat *= *'(.*)'", line)
+ if fsurdat_in:
+ self._fsurdat_in = fsurdat_in.group(1)
+ break
+ if self._fsurdat_in is None:
+ error_message = "fsurdat not defined"
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ # Where we will save the fsurdat version for this test
+ path, ext = os.path.splitext(self._fsurdat_in)
+ dir_in, filename_in_noext = os.path.split(path)
+ self._fsurdat_out = os.path.join(
+ self._path_gddgen, f"{filename_in_noext}.all_crops_everywhere{ext}"
+ )
+
+ # Make fsurdat for this test, if not already done
+ if not os.path.exists(self._fsurdat_out):
+ tool_path = os.path.join(
+ self._ctsm_root,
+ "tools",
+ "modify_input_files",
+ "fsurdat_modifier",
+ )
+
+ # Create configuration file for fsurdat_modifier
+ self._cfg_path = os.path.join(
+ self._path_gddgen,
+ "modify_fsurdat_allcropseverywhere.cfg",
+ )
+ self._create_config_file_evenlysplitcrop()
+
+ command = f"python3 {tool_path} {self._cfg_path} "
+ stu.run_python_script(
+ self._get_caseroot(),
+ self._this_conda_env,
+ command,
+ tool_path,
+ )
+
+ # Modify namelist
+ logger.info("RXCROPMATURITY log: modify user_nl files: new fsurdat")
+ self._append_to_user_nl_clm(
+ [
+ "fsurdat = '{}'".format(self._fsurdat_out),
+ "do_transient_crops = .false.",
+ "flanduse_timeseries = ''",
+ "use_init_interp = .true.",
+ ]
+ )
+
+ def _create_config_file_evenlysplitcrop(self):
+ """
+ Open the new and the template .cfg files
+ Loop line by line through the template .cfg file
+ When string matches, replace that line's content
+ """
+ cfg_template_path = os.path.join(
+ self._ctsm_root, "tools/modify_input_files/modify_fsurdat_template.cfg"
+ )
+
+ with open(self._cfg_path, "w", encoding="utf-8") as cfg_out:
+ # Copy template, replacing some lines
+ with open(cfg_template_path, "r", encoding="utf-8") as cfg_in:
+ for line in cfg_in:
+ if re.match(r" *evenly_split_cropland *=", line):
+ line = f"evenly_split_cropland = True"
+ elif re.match(r" *fsurdat_in *=", line):
+ line = f"fsurdat_in = {self._fsurdat_in}"
+ elif re.match(r" *fsurdat_out *=", line):
+ line = f"fsurdat_out = {self._fsurdat_out}"
+ elif re.match(r" *process_subgrid_section *=", line):
+ line = f"process_subgrid_section = True"
+ cfg_out.write(line)
+
+ # Add new lines
+ cfg_out.write("\n")
+ cfg_out.write("[modify_fsurdat_subgrid_fractions]\n")
+ cfg_out.write("PCT_CROP = 100.0\n")
+ cfg_out.write("PCT_NATVEG = 0.0\n")
+ cfg_out.write("PCT_GLACIER = 0.0\n")
+ cfg_out.write("PCT_WETLAND = 0.0\n")
+ cfg_out.write("PCT_LAKE = 0.0\n")
+ cfg_out.write("PCT_OCEAN = 0.0\n")
+ cfg_out.write("PCT_URBAN = 0.0 0.0 0.0\n")
+
+ def _run_check_rxboth_run(self, skip_gen):
+
+ output_dir = os.path.join(self._get_caseroot(), "run")
+
+ if skip_gen:
+ first_usable_year = self._run_startyear + 1
+ last_usable_year = first_usable_year
+ else:
+ first_usable_year = self._run_startyear + 2
+ last_usable_year = self._run_startyear + self._run_Nyears - 2
+
+ tool_path = os.path.join(
+ self._ctsm_root, "python", "ctsm", "crop_calendars", "check_rxboth_run.py"
+ )
+ command = (
+ f"python3 {tool_path} "
+ + f"--directory {output_dir} "
+ + f"-y1 {first_usable_year} "
+ + f"-yN {last_usable_year} "
+ + f"--rx-sdates-file {self._sdatefile} "
+ + f"--rx-gdds-file {self._gdds_file} "
+ )
+ stu.run_python_script(
+ self._get_caseroot(),
+ self._this_conda_env,
+ command,
+ tool_path,
+ )
+
+ def _modify_user_nl_allruns(self):
+ nl_additions = [
+ "cropcals_rx = .true.",
+ "cropcals_rx_adapt = .false.",
+ "stream_meshfile_cropcal = '{}'".format(self._case.get_value("LND_DOMAIN_MESH")),
+ "stream_fldFileName_swindow_start = '{}'".format(self._sdatefile),
+ "stream_fldFileName_swindow_end = '{}'".format(self._sdatefile),
+ "stream_year_first_cropcal_swindows = 2000",
+ "stream_year_last_cropcal_swindows = 2000",
+ "model_year_align_cropcal_swindows = 2000",
+ " ",
+ "! (h1) Annual outputs on sowing or harvest axis",
+ "hist_fincl2 = 'GRAINC_TO_FOOD_PERHARV', 'GRAINC_TO_FOOD_ANN', 'SDATES', 'SDATES_PERHARV', 'SYEARS_PERHARV', 'HDATES', 'GDDHARV_PERHARV', 'GDDACCUM_PERHARV', 'HUI_PERHARV', 'SOWING_REASON_PERHARV', 'HARVEST_REASON_PERHARV'",
+ "hist_nhtfrq(2) = 17520",
+ "hist_mfilt(2) = 999",
+ "hist_type1d_pertape(2) = 'PFTS'",
+ "hist_dov2xy(2) = .false.",
+ ]
+ self._append_to_user_nl_clm(nl_additions)
+
+ def _run_generate_gdds(self, case_gddgen):
+ self._generate_gdds_dir = os.path.join(self._path_gddgen, "generate_gdds_out")
+ os.makedirs(self._generate_gdds_dir)
+
+ # Get arguments to generate_gdds.py
+ dout_sr = case_gddgen.get_value("DOUT_S_ROOT")
+ input_dir = os.path.join(dout_sr, "lnd", "hist")
+ first_season = self._run_startyear + 2
+ last_season = self._run_startyear + self._run_Nyears - 2
+ sdates_file = self._sdatefile
+ hdates_file = self._hdatefile
+
+ # It'd be much nicer to call generate_gdds.main(), but I can't import generate_gdds.
+ # See https://github.com/ESCOMP/CTSM/issues/2603
+ tool_path = os.path.join(
+ self._ctsm_root, "python", "ctsm", "crop_calendars", "generate_gdds.py"
+ )
+ command = " ".join(
+ [
+ f"python3 {tool_path}",
+ f"--input-dir {input_dir}",
+ f"--first-season {first_season}",
+ f"--last-season {last_season}",
+ f"--sdates-file {sdates_file}",
+ f"--hdates-file {hdates_file}",
+ f"--output-dir generate_gdds_out",
+ f"--skip-crops miscanthus,irrigated_miscanthus,switchgrass,irrigated_switchgrass",
+ ]
+ )
+ stu.run_python_script(
+ self._get_caseroot(),
+ self._this_conda_env,
+ command,
+ tool_path,
+ )
+
+ # Where were the prescribed maturity requirements saved?
+ generated_gdd_files = glob.glob(os.path.join(self._generate_gdds_dir, "gdds_*.nc"))
+ if len(generated_gdd_files) != 1:
+ error_message = f"ERROR: Expected one matching prescribed maturity requirements file; found {len(generated_gdd_files)}: {generated_gdd_files}"
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+ self._gdds_file = generated_gdd_files[0]
+
+ def _run_interpolate_gdds(self):
+ # File where interpolated GDDs should be saved
+ self._gdds_file = os.path.join(self._get_caseroot(), "interpolated_gdds.nc")
+
+ # It'd be much nicer to call interpolate_gdds.main(), but I can't import interpolate_gdds.
+ # See https://github.com/ESCOMP/CTSM/issues/2603
+ tool_path = os.path.join(
+ self._ctsm_root, "python", "ctsm", "crop_calendars", "interpolate_gdds.py"
+ )
+ command = " ".join(
+ [
+ f"python3 {tool_path}",
+ f"--input-file {self._fallback_gdds_file}",
+ f"--target-file {self._sdatefile}",
+ f"--output-file {self._gdds_file}",
+ "--overwrite",
+ ]
+ )
+ stu.run_python_script(
+ self._get_caseroot(),
+ self._this_conda_env,
+ command,
+ tool_path,
+ )
+
+ def _get_conda_env(self):
+ conda_setup_commands = stu.cmds_to_setup_conda(self._get_caseroot())
+
+ # If npl conda environment is available, use that (It has dask, which
+ # enables chunking, which makes reading daily 1-degree netCDF files
+ # much more efficient.
+ if "npl " in os.popen(conda_setup_commands + "conda env list").read():
+ self._this_conda_env = "npl"
+ else:
+ self._this_conda_env = "ctsm_pylib"
+
+ def _append_to_user_nl_clm(self, additions):
+ caseroot = self._get_caseroot()
+ append_to_user_nl_files(caseroot=caseroot, component="clm", contents=additions)
+
+ # Is flanduse_timeseries defined? If so, where is it?
+ def _get_flanduse_timeseries_in(self, case):
+ case.create_namelists(component="lnd")
+ self._lnd_in_path = os.path.join(self._path_gddgen, "CaseDocs", "lnd_in")
+ self._flanduse_timeseries_in = None
+ with open(self._lnd_in_path, "r") as lnd_in:
+ for line in lnd_in:
+ flanduse_timeseries_in = re.match(r" *flanduse_timeseries *= *'(.*)'", line)
+ if flanduse_timeseries_in:
+ self._flanduse_timeseries_in = flanduse_timeseries_in.group(1)
+ break
+
+
+class RXCROPMATURITY(RXCROPMATURITYSHARED):
+ def run_phase(self):
+ self._run_phase()
diff --git a/cime_config/SystemTests/rxcropmaturityskipgen.py b/cime_config/SystemTests/rxcropmaturityskipgen.py
new file mode 100644
index 0000000000..409f2b9847
--- /dev/null
+++ b/cime_config/SystemTests/rxcropmaturityskipgen.py
@@ -0,0 +1,6 @@
+from rxcropmaturity import RXCROPMATURITYSHARED
+
+
+class RXCROPMATURITYSKIPGEN(RXCROPMATURITYSHARED):
+ def run_phase(self):
+ self._run_phase(skip_gen=True)
diff --git a/cime_config/SystemTests/soilstructud.py b/cime_config/SystemTests/soilstructud.py
index b454695f6e..42ffae54be 100644
--- a/cime_config/SystemTests/soilstructud.py
+++ b/cime_config/SystemTests/soilstructud.py
@@ -16,22 +16,28 @@
logger = logging.getLogger(__name__)
-class SOILSTRUCTUD(SystemTestsCompareTwo):
+class SOILSTRUCTUD(SystemTestsCompareTwo):
def __init__(self, case):
- SystemTestsCompareTwo.__init__(self, case,
- separate_builds = False,
- run_two_suffix = '4SL_2m',
- run_one_description = 'soil_layerstruct_userdefined',
- run_two_description = 'soil_layerstruct_predefined')
+ SystemTestsCompareTwo.__init__(
+ self,
+ case,
+ separate_builds=False,
+ run_two_suffix="4SL_2m",
+ run_one_description="soil_layerstruct_userdefined",
+ run_two_description="soil_layerstruct_predefined",
+ )
def _case_one_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "soil_layerstruct_userdefined_nlevsoi = 4,soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0")
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="soil_layerstruct_userdefined_nlevsoi = 4,soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0",
+ )
def _case_two_setup(self):
- append_to_user_nl_files(caseroot = self._get_caseroot(),
- component = "clm",
- contents = "soil_layerstruct_predefined = '4SL_2m'")
-
+ append_to_user_nl_files(
+ caseroot=self._get_caseroot(),
+ component="clm",
+ contents="soil_layerstruct_predefined = '4SL_2m'",
+ )
diff --git a/cime_config/SystemTests/ssp.py b/cime_config/SystemTests/ssp.py
index 26337d323d..bd554aeae9 100644
--- a/cime_config/SystemTests/ssp.py
+++ b/cime_config/SystemTests/ssp.py
@@ -18,8 +18,8 @@
logger = logging.getLogger(__name__)
-class SSP(SystemTestsCommon):
+class SSP(SystemTestsCommon):
def __init__(self, case):
"""
initialize an object interface to the SSP system test
@@ -48,10 +48,10 @@ def run_phase(self):
stop_n1 = int(stop_nf / 2)
stop_n2 = stop_nf - stop_n1
- #-------------------------------------------------------------------
+ # -------------------------------------------------------------------
# (1) do a spinup run in the main case in the cloned ref case
# (short term archiving is on)
- #-------------------------------------------------------------------
+ # -------------------------------------------------------------------
os.chdir(clone_path)
self._set_active_case(clone)
@@ -61,20 +61,24 @@ def run_phase(self):
with clone:
clone.set_value("CLM_ACCELERATED_SPINUP", "on")
- clone.set_value("STOP_N",stop_n1)
+ clone.set_value("STOP_N", stop_n1)
dout_sr = clone.get_value("DOUT_S_ROOT")
# No history files expected, set suffix=None to avoid compare error
self._skip_pnl = False
self.run_indv(suffix=None, st_archive=True)
- #-------------------------------------------------------------------
+ # -------------------------------------------------------------------
# (2) do a hybrid, non-spinup run in orig_case
- #-------------------------------------------------------------------
+ # -------------------------------------------------------------------
os.chdir(caseroot)
self._set_active_case(orig_case)
- refdate = run_cmd_no_fail(r'ls -1dt {}/rest/*-00000* | head -1 | sed "s/-00000.*//" | sed "s/^.*rest\///"'.format(dout_sr))
+ refdate = run_cmd_no_fail(
+ r'ls -1dt {}/rest/*-00000* | head -1 | sed "s/-00000.*//" | sed "s/^.*rest\///"'.format(
+ dout_sr
+ )
+ )
refsec = "00000"
# obtain rpointer files and necessary restart files from short term archiving directory
diff --git a/cime_config/SystemTests/sspmatrixcn.py b/cime_config/SystemTests/sspmatrixcn.py
new file mode 100644
index 0000000000..f4a09a277e
--- /dev/null
+++ b/cime_config/SystemTests/sspmatrixcn.py
@@ -0,0 +1,371 @@
+"""
+
+CTSM only test to do the CN-matrix spinup procedure
+
+This is a CLM specific test:
+Verifies that spinup works correctly
+this test is only valid for CLM compsets
+
+Step 0: Run a AD cold-start with matrix and matrix spinup off
+ Fast mode and fast-mode 2-loop spinup steps are now skipped
+ These were labeled as Step 1 and Step 2.
+Step 3: Run a slow-mode spinup
+Step 4: matrix Spinup off
+"""
+import shutil, glob, os, sys
+
+if __name__ == "__main__":
+ CIMEROOT = os.environ.get("CIMEROOT")
+ if CIMEROOT is None:
+ CIMEROOT = "../../cime"
+
+ sys.path.append(os.path.join(CIMEROOT, "scripts", "lib"))
+ sys.path.append(os.path.join(CIMEROOT, "scripts"))
+else:
+ from CIME.utils import append_testlog
+
+from CIME.XML.standard_module_setup import *
+from CIME.SystemTests.system_tests_common import SystemTestsCommon
+from CIME.SystemTests.test_utils import user_nl_utils
+
+
+logger = logging.getLogger(__name__)
+
+
+class SSPMATRIXCN(SystemTestsCommon):
+
+ # Class data
+ nyr_forcing = 2
+ # Get different integer multiples of the number of forcing years
+ full = nyr_forcing
+ twice = 2 * nyr_forcing
+ thrice = 3 * nyr_forcing
+ # Define the settings that will be used for each step
+ steps = ["0-AD", "1-SASU", "2-norm"]
+ desc = [
+ "Accell-Decomp(AD)-coldstart",
+ "slow-mode Semi-Analytic SpinUp(SASU)",
+ "normal",
+ ]
+ runtyp = ["startup", "hybrid", "branch"]
+ spin = ["on", "sasu", "off"]
+ stop_n = [5, thrice, thrice]
+ cold = [True, False, False]
+ iloop = [-999, -999, -999]
+ sasu = [-999, -999, -999]
+
+ def __init__(self, case=None):
+ """
+ initialize an object interface to the SSPMATRIXCN system test
+ """
+ expect(
+ len(self.steps) == len(self.sasu),
+ "length of steps must be the same as sasu",
+ )
+ expect(
+ len(self.steps) == len(self.spin),
+ "length of steps must be the same as spin",
+ )
+ expect(
+ len(self.steps) == len(self.desc),
+ "length of steps must be the same as desc",
+ )
+ expect(
+ len(self.steps) == len(self.cold),
+ "length of steps must be the same as cold",
+ )
+ expect(
+ len(self.steps) == len(self.runtyp),
+ "length of steps must be the same as runtyp",
+ )
+ expect(
+ len(self.steps) == len(self.iloop),
+ "length of steps must be the same as iloop",
+ )
+ expect(
+ len(self.steps) == len(self.stop_n),
+ "length of steps must be the same as stop_n",
+ )
+
+ if __name__ != "__main__":
+ SystemTestsCommon.__init__(self, case)
+ ystart = int(self._case.get_value("DATM_YR_START"))
+ yend = int(self._case.get_value("DATM_YR_END"))
+ self.comp = self._case.get_value("COMP_LND")
+ else:
+ self._case = None
+ self.comp = "clm"
+ ystart = 2000
+ yend = 2001
+
+ for n in range(len(self.steps)):
+ if n == 0:
+ expect(self.cold[n] == True, "First step MUST be a cold-start")
+ expect(self.runtyp[n] == "startup", "First step MUST be a startup")
+ else:
+ expect(self.cold[n] == False, "Other steps must NOT be a cold-start")
+ expect(self.runtyp[n] != "startup", "Other steps MUST NOT be a startup")
+
+ if self.spin[n] == "sasu":
+ expect(self.cold[n] == False, "SASU step should NOT be a cold-start")
+ if self.sasu[n] != -999:
+ expect(self.sasu[n] > 0, "SASU steps must set SASU cycle")
+ expect(
+ self.sasu[n] <= self.nyr_forcing,
+ "SASU cycles can't be greater than a full forcing cycle",
+ )
+
+ expect(
+ yend - ystart + 1 == self.nyr_forcing,
+ "Number of years run over MUST correspond to nyr_forcing",
+ )
+ self._testname = "SSPMATRIX"
+
+ def check_n(self, n):
+ "Check if n is within range"
+ expect(
+ ((n >= 0) and (n < self.n_steps())),
+ "Step number is out of range = " + str(n),
+ )
+
+ def __logger__(self, n=0):
+ "Log info on this step"
+
+ self.check_n(n)
+ msg = "Step {}: {}: doing a {} run for {} years".format(
+ self.steps[n], self.runtyp[n], self.desc[n], self.stop_n[n]
+ )
+ logger.info(msg)
+ logger.info(" spinup type: {}".format(self.spin[n]))
+ if __name__ != "__main__":
+ append_testlog(msg)
+ if n + 1 < self.n_steps():
+ logger.info(" writing restarts at end of run")
+ logger.info(" short term archiving is on ")
+
+ def n_steps(self):
+ "Total number of steps"
+
+ return len(self.steps)
+
+ def total_years(self):
+ "Total number of years needed to do the full spinup"
+
+ ysum = 0
+ for nyr in self.stop_n:
+ ysum = ysum + nyr
+
+ return ysum
+
+ def append_user_nl(self, caseroot, n=0):
+ "Append needed settings to the user_nl files"
+
+ self.check_n(n)
+ # For all set output to yearly
+ contents_to_append = "hist_nhtfrq = -8760"
+ contents_to_append = contents_to_append + ", hist_mfilt = " + str(self.nyr_forcing)
+ # For all but last step turn extra matrix output to off
+ b4last = self.n_steps() - 1
+ if n < b4last:
+ contents_to_append = contents_to_append + ", hist_wrt_matrixcn_diag = .False."
+ # For matrix spinup steps, set the matrix spinup and other variables associated with it
+ if self.spin[n] == "sasu":
+ contents_to_append = contents_to_append + ", nyr_forcing = " + str(self.nyr_forcing)
+ if self.sasu[n] != -999:
+ contents_to_append = contents_to_append + ", nyr_sasu = " + str(self.sasu[n])
+ if self.iloop[n] != -999:
+ contents_to_append = contents_to_append + ", iloop_avg = " + str(self.iloop[n])
+
+ # For cold start, run with matrix off
+ if self.cold[n]:
+ contents_to_append = contents_to_append + ", use_matrixcn = .False."
+ contents_to_append = contents_to_append + ", use_soil_matrixcn = .False."
+
+ # Always append to the end
+ user_nl_utils.append_to_user_nl_files(
+ caseroot=caseroot, component=self.comp, contents=contents_to_append
+ )
+
+ def run_phase(self):
+ "Run phase"
+
+ caseroot = self._case.get_value("CASEROOT")
+ orig_case = self._case
+ orig_casevar = self._case.get_value("CASE")
+
+ # Get a clone of each step except the last one
+ b4last = self.n_steps() - 1
+ for n in range(b4last):
+ #
+ # Clone the main case, and get it setup for the next step
+ #
+ clone_path = "{}.step{}".format(caseroot, self.steps[n])
+ if os.path.exists(clone_path):
+ shutil.rmtree(clone_path)
+ if n > 0:
+ del clone
+ self._set_active_case(orig_case)
+ clone = self._case.create_clone(clone_path, keepexe=True)
+ os.chdir(clone_path)
+ self._set_active_case(clone)
+
+ self.__logger__(n)
+
+ with clone:
+ clone.set_value("RUN_TYPE", self.runtyp[n])
+ clone.set_value("STOP_N", self.stop_n[n])
+
+ clone.set_value("CLM_ACCELERATED_SPINUP", self.spin[n])
+
+ if self.cold[n]:
+ clone.set_value("CLM_FORCE_COLDSTART", "on")
+ else:
+ clone.set_value("CLM_FORCE_COLDSTART", "off")
+
+ self.append_user_nl(clone_path, n)
+
+ dout_sr = clone.get_value("DOUT_S_ROOT")
+
+ self._skip_pnl = False
+ #
+ # Start up from the previous case
+ #
+ rundir = clone.get_value("RUNDIR")
+ with clone:
+ if n > 0:
+ clone.set_value("GET_REFCASE", False)
+ expect("refcase" in locals(), "refcase was NOT previously set")
+ clone.set_value("RUN_REFCASE", refcase)
+ expect("refdate" in locals(), "refdate was NOT previously set")
+ clone.set_value("RUN_STARTDATE", refdate)
+ clone.set_value("RUN_REFDATE", refdate)
+ for item in glob.glob("{}/*{}*".format(rest_path, refdate)):
+ linkfile = os.path.join(rundir, os.path.basename(item))
+ if os.path.exists(linkfile):
+ os.remove(linkfile)
+ if not os.path.isdir(rundir):
+ os.makedirs(rundir)
+ os.symlink(item, linkfile)
+
+ for item in glob.glob("{}/*rpointer*".format(rest_path)):
+ shutil.copy(item, rundir)
+
+ #
+ # Run the case (Archiving on)
+ #
+ self._case.flush()
+ self.run_indv(suffix="step{}".format(self.steps[n]), st_archive=True)
+
+ #
+ # Get the reference case from this step for the next step
+ #
+ refcase = clone.get_value("CASE")
+ refdate = run_cmd_no_fail(
+ r'ls -1dt {}/rest/*-00000* | head -1 | sed "s/-00000.*//" | sed "s/^.*rest\///"'.format(
+ dout_sr
+ )
+ )
+ refsec = "00000"
+ rest_path = os.path.join(dout_sr, "rest", "{}-{}".format(refdate, refsec))
+
+ #
+ # Last step in original case
+ #
+ n = self.n_steps() - 1
+ #
+ # Setup the case to run from the previous clone step
+ #
+ os.chdir(caseroot)
+ self._set_active_case(orig_case)
+ self.__logger__(n)
+ self._case.set_value("DOUT_S", False)
+ self._case.set_value("RUN_TYPE", self.runtyp[n])
+ self._case.set_value("STOP_N", self.stop_n[n])
+ rundir = self._case.get_value("RUNDIR")
+ self._case.set_value("GET_REFCASE", False)
+ expect("refcase" in locals(), "refcase was NOT previously set")
+ self._case.set_value("RUN_REFCASE", refcase)
+ expect("refdate" in locals(), "refdate was NOT previously set")
+ self._case.set_value("RUN_REFDATE", refdate)
+ self._case.set_value("RUN_STARTDATE", refdate)
+ for item in glob.glob("{}/*{}*".format(rest_path, refdate)):
+ linkfile = os.path.join(rundir, os.path.basename(item))
+ if os.path.exists(linkfile):
+ os.remove(linkfile)
+ os.symlink(item, linkfile)
+
+ for item in glob.glob("{}/*rpointer*".format(rest_path)):
+ shutil.copy(item, rundir)
+
+ self.append_user_nl(clone_path, n)
+ #
+ # Don't need to set COLDSTART or ACCEL_SPINUP
+ #
+
+ #
+ # Run the case (short term archiving is off)
+ #
+ self._case.flush()
+ self.run_indv(suffix="step{}".format(self.steps[n]), st_archive=False)
+
+
+#
+# Unit testing for above
+#
+import unittest
+from CIME.case import Case
+from CIME.utils import _LessThanFilter
+from argparse import RawTextHelpFormatter
+
+
+class test_ssp_matrixcn(unittest.TestCase):
+ def setUp(self):
+ self.ssp = SSPMATRIXCN()
+
+ def test_logger(self):
+ # Test the logger
+ stream_handler = logging.StreamHandler(sys.stdout)
+ logger.addHandler(stream_handler)
+ logger.level = logging.DEBUG
+ logger.info("nyr_forcing = {}".format(self.ssp.nyr_forcing))
+ for n in range(self.ssp.n_steps()):
+ self.ssp.__logger__(n)
+ if self.ssp.spin[n] == "sasu":
+ logger.info(" SASU spinup is .true.")
+ if self.ssp.sasu[n] != -999:
+ logger.info(" nyr_sasu = {}".format(self.ssp.sasu[n]))
+ if self.ssp.iloop[n] != -999:
+ logger.info(" iloop_avg = {}".format(self.ssp.iloop[n]))
+
+ logger.info("Total number of years {}".format(self.ssp.total_years()))
+ logger.removeHandler(stream_handler)
+
+ def test_n_steps(self):
+ self.assertTrue(self.ssp.n_steps() == 3)
+
+ def test_valid_n(self):
+ for n in range(self.ssp.n_steps()):
+ self.ssp.check_n(n)
+
+ def test_negative_n(self):
+ self.assertRaises(SystemExit, self.ssp.check_n, -1)
+
+ def test_n_too_big(self):
+ self.assertRaises(SystemExit, self.ssp.check_n, self.ssp.n_steps())
+
+ def test_append_user_nl_step2(self):
+ ufile = "user_nl_clm"
+ if not os.path.exists(ufile):
+ os.mknod(ufile)
+ else:
+ expect(0, ufile + " file already exists, not overwritting it")
+
+ self.ssp.append_user_nl(caseroot=".", n=2)
+ print(ufile + " for step 2")
+ log = open(ufile, "r").read()
+ print(log)
+ os.remove(ufile)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/cime_config/SystemTests/systemtest_utils.py b/cime_config/SystemTests/systemtest_utils.py
new file mode 100644
index 0000000000..c252f73251
--- /dev/null
+++ b/cime_config/SystemTests/systemtest_utils.py
@@ -0,0 +1,110 @@
+"""
+Reduce code duplication by putting reused functions here.
+"""
+
+import os, subprocess, re, glob
+from collections import OrderedDict
+
+
+def cmds_to_setup_conda(caseroot):
+ # Add specific commands needed on different machines to get conda available
+ # Use semicolon here since it's OK to fail
+ #
+ conda_setup_commands = ". " + caseroot + "/.env_mach_specific.sh; "
+ # Setting CONDA_PREFIX to empty ensures that this works even if called from
+ # a shell with a conda environment activated
+ conda_setup_commands += "CONDA_PREFIX=; "
+ # Execute the module unload/load when "which conda" fails
+ # eg on cheyenne
+ try:
+ subprocess.run("which conda", shell=True, check=True)
+ except subprocess.CalledProcessError:
+ # Remove python and add conda to environment for cheyennne
+ unload_python_load_conda = "module unload python; module load conda;"
+ # Make sure that adding this actually loads conda
+ subprocess.run(unload_python_load_conda + "which conda", shell=True, check=True)
+ # Save
+ conda_setup_commands += " " + unload_python_load_conda
+
+ return conda_setup_commands
+
+
+def cmds_to_run_via_conda(caseroot, conda_run_call, command):
+ # Run in the specified conda environment
+ conda_setup_commands = cmds_to_setup_conda(caseroot)
+ conda_setup_commands += " " + conda_run_call
+
+ # Finish with Python script call
+ command = conda_setup_commands + " " + command
+ print(f"command: {command}")
+
+ return command
+
+
+def run_python_script(caseroot, this_conda_env, command_in, tool_path):
+
+ # First, try with "conda run -n"
+ command = cmds_to_run_via_conda(caseroot, f"conda run -n {this_conda_env}", command_in)
+
+ # Run with logfile
+ tool_name = os.path.split(tool_path)[-1]
+ try:
+ with open(tool_name + ".log", "w") as f:
+ subprocess.run(
+ command, shell=True, check=True, text=True, stdout=f, stderr=subprocess.STDOUT
+ )
+ except subprocess.CalledProcessError as error:
+ # Retry with the original "conda activate" method
+ command = cmds_to_run_via_conda(
+ caseroot,
+ f"conda activate {this_conda_env} && ",
+ command_in,
+ )
+ try:
+ with open(tool_name + ".log2", "w") as f:
+ subprocess.run(
+ command, shell=True, check=True, text=True, stdout=f, stderr=subprocess.STDOUT
+ )
+ except subprocess.CalledProcessError as error:
+ print("ERROR while getting the conda environment and/or ")
+ print(f"running the {tool_name} tool: ")
+ print(f"(1) If your {this_conda_env} environment is out of date or you ")
+ print(f"have not created the {this_conda_env} environment, yet, you may ")
+ print("get past this error by running ./py_env_create ")
+ print("in your ctsm directory and trying this test again. ")
+ print("(2) If conda is not available, install and load conda, ")
+ print("run ./py_env_create, and then try this test again. ")
+ print("(3) If (1) and (2) are not the issue, then you may be ")
+ print(f"getting an error within {tool_name} itself. ")
+ print("Default error message: ")
+ print(error.output)
+ raise
+ except:
+ print(f"ERROR trying to run {tool_name}.")
+ raise
+ except:
+ print(f"ERROR trying to run {tool_name}.")
+ raise
+
+
+# Read a user_nl file and return the namelist option if found
+def find_user_nl_option(caseroot, component, namelist_option):
+
+ # This is a copy of the CIME _get_list_of_user_nl_files
+ # which could be used if this moved into the CIME project
+ file_pattern = "user_nl_" + component + "*"
+ file_list = glob.glob(os.path.join(caseroot, file_pattern))
+
+ # Check that there is at least one file
+ if len(file_list) == 0:
+ raise RuntimeError("No user_nl files found for component " + component)
+
+ # Read through the file list and look for a match and return the whole entry
+ output = OrderedDict()
+ for one_file in file_list:
+ with open(one_file, "r") as user_nl_file:
+ user_nl_text = user_nl_file.read()
+ reg = rf"{namelist_option}.*?(?=,|\n)"
+ find_out = re.findall(reg, user_nl_text)
+ output[one_file] = find_out
+ return output
diff --git a/cime_config/buildlib b/cime_config/buildlib
index 31b7fe3d38..0e253c9d98 100755
--- a/cime_config/buildlib
+++ b/cime_config/buildlib
@@ -27,19 +27,26 @@ def _write_ctsm_mk(gmake, gmake_opts, makefile, exeroot, libroot):
This file can be included by atmosphere model builds outside of cime.
"""
- cime_output_file = os.path.join(exeroot, 'cime_variables.mk')
+ cime_output_file = os.path.join(exeroot, "cime_variables.mk")
# Set COMP_NAME=driver because some link flags are set differently when COMP_NAME=driver, and
# those are the ones we want here.
- cmd = ("{gmake} write_include_and_link_flags OUTPUT_FILE={cime_output_file} "
- "COMP_NAME=driver {gmake_opts} -f {makefile} ").format(
- gmake=gmake, cime_output_file=cime_output_file, gmake_opts=gmake_opts, makefile=makefile)
+ cmd = (
+ "{gmake} write_include_and_link_flags OUTPUT_FILE={cime_output_file} "
+ "COMP_NAME=driver {gmake_opts} -f {makefile} "
+ ).format(
+ gmake=gmake,
+ cime_output_file=cime_output_file,
+ gmake_opts=gmake_opts,
+ makefile=makefile,
+ )
rc, out, err = run_cmd(cmd)
- logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n"%(cmd,out,err))
+ logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n" % (cmd, out, err))
expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))
- ctsm_mk_path = os.path.join(exeroot, 'ctsm.mk')
- with open(ctsm_mk_path, 'w') as ctsm_mk:
- ctsm_mk.write("""
+ ctsm_mk_path = os.path.join(exeroot, "ctsm.mk")
+ with open(ctsm_mk_path, "w") as ctsm_mk:
+ ctsm_mk.write(
+ """
# ======================================================================
# Include this file to get makefile variables needed to include / link
# LILAC/CTSM in an atmosphere model's build
@@ -54,13 +61,15 @@ def _write_ctsm_mk(gmake, gmake_opts, makefile, exeroot, libroot):
# should not be included directly in an atmosphere model's build.
# ======================================================================
-""")
+"""
+ )
with open(cime_output_file) as infile:
ctsm_mk.write(infile.read())
ctsm_bld_dir = os.path.abspath(os.path.join(libroot, os.pardir))
- with open(ctsm_mk_path, 'a') as ctsm_mk:
- ctsm_mk.write("""
+ with open(ctsm_mk_path, "a") as ctsm_mk:
+ ctsm_mk.write(
+ """
# ======================================================================
# The following settings are meant for internal use, and generally
# should not be included directly in an atmosphere model's build.
@@ -77,11 +86,15 @@ CTSM_INC = $(CTSM_BLD_DIR)/clm/obj
CTSM_INCLUDES = $(CIME_ESMF_F90COMPILEPATHS) -I$(CIME_CSM_SHR_INCLUDE) -I$(CTSM_INC)
CTSM_LIBS = -L$(CTSM_BLD_DIR)/lib -lclm $(CIME_ULIBS) $(CIME_SLIBS) $(CIME_MLIBS) $(CIME_F90_LDFLAGS)
-""".format(ctsm_bld_dir=ctsm_bld_dir))
+""".format(
+ ctsm_bld_dir=ctsm_bld_dir
+ )
+ )
+
###############################################################################
def _main_func():
-###############################################################################
+ ###############################################################################
caseroot, libroot, bldroot = parse_input(sys.argv)
@@ -96,77 +109,89 @@ def _main_func():
driver = case.get_value("COMP_INTERFACE").lower()
lilac_mode = case.get_value("LILAC_MODE")
- if lilac_mode == 'on':
+ if lilac_mode == "on":
driver = "lilac"
- #-------------------------------------------------------
+ # -------------------------------------------------------
# create Filepath file
- #-------------------------------------------------------
+ # -------------------------------------------------------
compname = case.get_value("COMP_LND")
- filepath_file = os.path.join(bldroot,"Filepath")
+ filepath_file = os.path.join(bldroot, "Filepath")
if not os.path.isfile(filepath_file):
caseroot = case.get_value("CASEROOT")
- expect( ((compname == "clm") or (compname == "ctsm")), "Unexpected COMP_LND name: %s" % (compname))
-
- paths = [os.path.join(caseroot,"SourceMods","src."+compname),
- os.path.join(lnd_root,"src","cpl",driver),
- os.path.join(lnd_root,"src","main"),
- os.path.join(lnd_root,"src","biogeophys"),
- os.path.join(lnd_root,"src","biogeochem"),
- os.path.join(lnd_root,"src","soilbiogeochem"),
- os.path.join(lnd_root,"src","dyn_subgrid"),
- os.path.join(lnd_root,"src","init_interp"),
- os.path.join(lnd_root,"src","self_tests"),
- os.path.join(lnd_root,"src","fates"),
- os.path.join(lnd_root,"src","fates","main"),
- os.path.join(lnd_root,"src","fates","biogeophys"),
- os.path.join(lnd_root,"src","fates","biogeochem"),
- os.path.join(lnd_root,"src","fates","fire"),
- os.path.join(lnd_root,"src","fates","parteh"),
- os.path.join(lnd_root,"src","utils"),
- os.path.join(lnd_root,"src","cpl"),
- os.path.join(lnd_root,"src","cpl","utils")]
-
- if lilac_mode == 'on':
- paths.append(os.path.join(lnd_root,"lilac","src"))
+ expect(
+ ((compname == "clm") or (compname == "ctsm")),
+ "Unexpected COMP_LND name: %s" % (compname),
+ )
+
+ paths = [
+ os.path.join(caseroot, "SourceMods", "src." + compname),
+ os.path.join(lnd_root, "src", "cpl", driver),
+ os.path.join(lnd_root, "src", "main"),
+ os.path.join(lnd_root, "src", "biogeophys"),
+ os.path.join(lnd_root, "src", "biogeochem"),
+ os.path.join(lnd_root, "src", "soilbiogeochem"),
+ os.path.join(lnd_root, "src", "dyn_subgrid"),
+ os.path.join(lnd_root, "src", "init_interp"),
+ os.path.join(lnd_root, "src", "self_tests"),
+ os.path.join(lnd_root, "src", "fates"),
+ os.path.join(lnd_root, "src", "fates", "main"),
+ os.path.join(lnd_root, "src", "fates", "biogeophys"),
+ os.path.join(lnd_root, "src", "fates", "biogeochem"),
+ os.path.join(lnd_root, "src", "fates", "fire"),
+ os.path.join(lnd_root, "src", "fates", "parteh"),
+ os.path.join(lnd_root, "src", "fates", "radiation"),
+ os.path.join(lnd_root, "src", "utils"),
+ os.path.join(lnd_root, "src", "cpl"),
+ os.path.join(lnd_root, "src", "cpl", "utils"),
+ ]
+
+ if lilac_mode == "on":
+ paths.append(os.path.join(lnd_root, "lilac", "src"))
# If we want to build with a real river model (e.g., MOSART), we'll need
# to use its directories in place of stub_rof
- paths.append(os.path.join(lnd_root,"lilac","stub_rof"))
+ paths.append(os.path.join(lnd_root, "lilac", "stub_rof"))
- if (driver == 'lilac' or driver == 'nuopc'):
- paths.append(os.path.join(lnd_root,"src","cpl","share_esmf"))
+ if driver == "lilac" or driver == "nuopc":
+ paths.append(os.path.join(lnd_root, "src", "cpl", "share_esmf"))
with open(filepath_file, "w") as filepath:
filepath.write("\n".join(paths))
filepath.write("\n")
- #-------------------------------------------------------
+ # -------------------------------------------------------
# create the library in libroot
- #-------------------------------------------------------
+ # -------------------------------------------------------
- complib = os.path.join(libroot,"lib%s.a"%(compname))
+ complib = os.path.join(libroot, "lib%s.a" % (compname))
- cmd = "{} complib -j {} COMP_NAME={} COMPLIB={} -f {} {}" \
- .format(gmake, gmake_j, compname, complib, makefile, gmake_opts)
+ cmd = "{} complib -j {} COMP_NAME={} COMPLIB={} -f {} {}".format(
+ gmake, gmake_j, compname, complib, makefile, gmake_opts
+ )
rc, out, err = run_cmd(cmd)
- logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n"%(cmd,out,err))
+ logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n" % (cmd, out, err))
expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))
# ------------------------------------------------------------------------
# for lilac usage, we need a file containing some Makefile variables (for the atmosphere model's build)
# ------------------------------------------------------------------------
- if lilac_mode == 'on':
- _write_ctsm_mk(gmake=gmake,
- gmake_opts=gmake_opts,
- makefile=makefile,
- exeroot=case.get_value("EXEROOT"),
- libroot=libroot)
+ if lilac_mode == "on":
+ _write_ctsm_mk(
+ gmake=gmake,
+ gmake_opts=gmake_opts,
+ makefile=makefile,
+ exeroot=case.get_value("EXEROOT"),
+ libroot=libroot,
+ )
+
###############################################################################
if __name__ == "__main__":
- logger.warning( "WARNING: buildlib is being called as a program rather than a subroutine as " +
- "it is expected to be in the CESM context" )
+ logger.warning(
+ "WARNING: buildlib is being called as a program rather than a subroutine as "
+ + "it is expected to be in the CESM context"
+ )
_main_func()
diff --git a/cime_config/buildnml b/cime_config/buildnml
old mode 100755
new mode 100644
index 4e04951474..6215379912
--- a/cime_config/buildnml
+++ b/cime_config/buildnml
@@ -3,7 +3,7 @@
"""
CTSM namelist creator
"""
-import sys, os, shutil
+import sys, os, shutil, re
_CIMEROOT = os.environ.get("CIMEROOT")
if _CIMEROOT is None:
@@ -12,10 +12,10 @@ if _CIMEROOT is None:
_LIBDIR = os.path.join(_CIMEROOT, "CIME", "Tools")
sys.path.append(_LIBDIR)
-from standard_script_setup import *
-from CIME.buildnml import create_namelist_infile, parse_input
-from CIME.case import Case
-from CIME.utils import expect, run_cmd
+from standard_script_setup import *
+from CIME.buildnml import create_namelist_infile, parse_input
+from CIME.case import Case
+from CIME.utils import expect, run_cmd
logger = logging.getLogger(__name__)
@@ -23,14 +23,15 @@ _config_cache_template = """
-Specifies CTSM physics
+Specifies CTSM physics
"""
+
###############################################################################
def buildnml(case, caseroot, compname):
-###############################################################################
- """Build the CTSM namelist """
+ ###############################################################################
+ """Build the CTSM namelist"""
# Build the component namelist
if compname != "ctsm" and compname != "clm":
@@ -41,6 +42,7 @@ def buildnml(case, caseroot, compname):
configuration = case.get_value("CLM_CONFIGURATION")
structure = case.get_value("CLM_STRUCTURE")
ccsm_co2_ppmv = case.get_value("CCSM_CO2_PPMV")
+ casename = case.get_value("CASE")
clm_co2_type = case.get_value("CLM_CO2_TYPE")
clm_namelist_opts = case.get_value("CLM_NAMELIST_OPTS")
clm_bldnml_opts = case.get_value("CLM_BLDNML_OPTS")
@@ -48,6 +50,20 @@ def buildnml(case, caseroot, compname):
clm_force_coldstart = case.get_value("CLM_FORCE_COLDSTART")
lnd_tuning_mode = case.get_value("LND_TUNING_MODE")
clm_accelerated_spinup = case.get_value("CLM_ACCELERATED_SPINUP")
+ comp_interface = case.get_value("COMP_INTERFACE")
+ lilac_mode = case.get_value("LILAC_MODE")
+ yr_start = case.get_value("DATM_YR_START")
+ yr_end = case.get_value("DATM_YR_END")
+
+ # For LILAC
+ if yr_start == None or lilac_mode == "on":
+ yr_start = "0"
+ yr_end = "0"
+
+ yr_start = int(yr_start)
+ yr_end = int(yr_end)
+
+ clm_usrdat_name = case.get_value("CLM_USRDAT_NAME")
comp_atm = case.get_value("COMP_ATM")
lnd_grid = case.get_value("LND_GRID")
ninst_lnd = case.get_value("NINST_LND")
@@ -57,28 +73,87 @@ def buildnml(case, caseroot, compname):
run_refcase = case.get_value("RUN_REFCASE")
run_refdate = case.get_value("RUN_REFDATE")
run_reftod = case.get_value("RUN_REFTOD")
+ start_tod = case.get_value("START_TOD")
glc_nec = case.get_value("GLC_NEC")
- cism_use_antarctica = case.get_value("CISM_USE_ANTARCTICA")
+ glc_use_antarctica = case.get_value("GLC_USE_ANTARCTICA")
mask = case.get_value("MASK_GRID")
driver = case.get_value("COMP_INTERFACE").lower()
# Create init_generated_files directory if not there
- newdir = os.path.join(rundir,"init_generated_files")
+ newdir = os.path.join(rundir, "init_generated_files")
if not os.path.exists(newdir):
os.mkdir(newdir)
# -----------------------------------------------------
# Error checking
# -----------------------------------------------------
- if ( clm_bldnml_opts.find("-namelist") >= 0 ):
- expect(False, "The -namelist option is NOT allowed to be part of CLM_BLDNML_OPTS, " + \
- "use the CLM_NAMELIST_OPTS option or add namelist items to user_nl_clm instead " );
+ if clm_bldnml_opts.find("-namelist") >= 0:
+ expect(
+ False,
+ "The -namelist option is NOT allowed to be part of CLM_BLDNML_OPTS, "
+ + "use the CLM_NAMELIST_OPTS option or add namelist items to user_nl_clm instead ",
+ )
+ #
+ # Warnings for land tuning modes
+ #
+ closest_tuning = {
+ "clm4_5_1PT": "clm4_5_CRUv7",
+ "clm4_5_QIAN": "clm4_5_CRUv7",
+ "clm4_5_NLDAS2": "clm4_5_CRUv7",
+ "clm4_5_ERA5": "clm4_5_CRUv7",
+ "clm5_0_1PT": "clm5_0_GSWP3v1",
+ "clm5_0_QIAN": "clm5_0_GSWP3v1",
+ "clm5_0_NLDAS2": "clm5_0_GSWP3v1",
+ "clm5_0_ERA5": "clm5_0_GSWP3v1",
+ "clm6_0_1PT": "clm6_0_GSWP3v1",
+ "clm6_0_QIAN": "clm6_0_GSWP3v1",
+ "clm6_0_NLDAS2": "clm6_0_GSWP3v1",
+ "clm6_0_ERA5": "clm6_0_GSWP3v1",
+ "clm6_0_CRUv7": "clm6_0_GSWP3v1",
+ }
+ for mode, closest in closest_tuning.items():
+ if lnd_tuning_mode == mode:
+ logger.warning(
+ "IMPORTANT NOTE: LND_TUNING_MODE is "
+ + lnd_tuning_mode
+ + " which does NOT have tuned settings, so using the closest option which is "
+ + closest
+ )
+ logger.warning(
+ " : To suppress this message explicitly set LND_TUNING_MODE="
+ + lnd_tuning_mode
+ + " for your case"
+ )
+ lnd_tuning_mode = closest
+
+ # CAM4 and CAM5 options are based on cam6 tuning
+ # (other than the Zender dust emission soil eroditability file which is specific
+ # to the CAM version)
+ tuning_based_on = {
+ "clm6_0_GSWP3v1": "clm5_0_GSWP3v1",
+ "clm6_0_cam6.0": "clm5_0_cam6.0",
+ "clm6_0_cam5.0": "clm5_0_cam6.0",
+ "clm6_0_cam4.0": "clm5_0_cam6.0",
+ "clm5_0_cam5.0": "clm5_0_cam6.0",
+ "clm5_0_cam4.0": "clm5_0_cam6.0",
+ "clm4_5_cam6.0": "clm5_0_cam6.0",
+ "clm4_5_cam5.0": "clm5_0_cam6.0",
+ "clm4_5_cam4.0": "clm5_0_cam6.0",
+ }
+ for mode, based_on in tuning_based_on.items():
+ if lnd_tuning_mode == mode:
+ logger.warning(
+ "NOTE: LND_TUNING_MODE is "
+ + lnd_tuning_mode
+ + " which is NOT tuned, but is based on "
+ + based_on
+ )
# -----------------------------------------------------
# Set ctsmconf
# -----------------------------------------------------
- ctsmconf = os.path.join(caseroot, "Buildconf", compname+"conf")
+ ctsmconf = os.path.join(caseroot, "Buildconf", compname + "conf")
if not os.path.isdir(ctsmconf):
os.makedirs(ctsmconf)
@@ -92,8 +167,8 @@ def buildnml(case, caseroot, compname):
clm_phys = case.get_value("CLM_PHYSICS_VERSION")
config_cache_text = _config_cache_template.format(clm_phys=clm_phys)
- config_cache_path = os.path.join(caseroot, "Buildconf", compname+"conf", "config_cache.xml")
- with open(config_cache_path, 'w') as config_cache_file:
+ config_cache_path = os.path.join(caseroot, "Buildconf", compname + "conf", "config_cache.xml")
+ with open(config_cache_path, "w") as config_cache_file:
config_cache_file.write(config_cache_text)
# -----------------------------------------------------
@@ -111,80 +186,120 @@ def buildnml(case, caseroot, compname):
startfile_type = "nrevsn"
if clm_force_coldstart == "on":
clm_force_coldstart = "off"
- logger.warning( "WARNING: You've turned on CLM_FORCE_COLDSTART for a branch run_type, which is a contradiction, the coldstart will be ignored\n" +
- " turn off CLM_FORCE_COLDSTART, or set RUN_TYPE=hybrid to get rid of this warning")
-
+ logger.warning(
+ "WARNING: You've turned on CLM_FORCE_COLDSTART for a branch run_type, which is a contradiction, the coldstart will be ignored\n"
+ + " turn off CLM_FORCE_COLDSTART, or set RUN_TYPE=hybrid to get rid of this warning"
+ )
- if (clm_force_coldstart == "on"):
- logger.warning( "WARNING: CLM is starting up from a cold state" )
+ if clm_force_coldstart == "on":
+ logger.warning("WARNING: CLM is starting up from a cold state")
start_type = "cold"
- if lnd_grid == 'T31':
- lnd_grid = '48x96'
- if lnd_grid == 'T42':
- lnd_grid = '64x128'
- if lnd_grid == 'T85':
- lnd_grid = '128x256'
- if lnd_grid == 'T341':
- lnd_grid = '512x1024'
+ if lnd_grid == "T31":
+ lnd_grid = "48x96"
+ if lnd_grid == "T42":
+ lnd_grid = "64x128"
+ if lnd_grid == "T85":
+ lnd_grid = "128x256"
+ if lnd_grid == "T341":
+ lnd_grid = "512x1024"
clmusr = ""
if lnd_grid == "CLM_USRDAT":
clm_usrdat_name = case.get_value("CLM_USRDAT_NAME")
- lnd_grid = clm_usrdat_name
- clmusr = " -clm_usr_name %s "%clm_usrdat_name
+ clmusr = " -clm_usr_name %s " % clm_usrdat_name
+ # Write warning about initial condition data
+ if (
+ "NEON" in clm_usrdat_name
+ or "PLUMBER2" in clm_usrdat_name
+ and clm_force_coldstart == "off"
+ ):
+ warning_init_conditions = False
+ if "NEON" in clm_usrdat_name:
+ if ("_transient" in clm_nml_use_case) and (
+ re.fullmatch(r"\w\w\w\w\.transient", casename) is None
+ or clm_usrdat_name is "NEON.PRISM"
+ ):
+ warning_init_conditions = True
+ if "PLUMBER2" in clm_usrdat_name:
+ if ("_transient" in clm_nml_use_case) and (
+ re.fullmatch(r"\w\w-\w\w\w\.transient", casename) is None
+ ):
+ warning_init_conditions = True
+ if warning_init_conditions == True:
+ logger.warning(
+ "WARNING: Do you have appropriate initial conditions for this simulation?"
+ + " Check that the finidat file used in the lnd_in namelist is appropriately spunup for your case"
+ )
if comp_atm != "datm":
nomeg = "-no-megan"
else:
nomeg = ""
- if cism_use_antarctica is None:
- # This is the case for compsets without CISM, where the CISM_USE_ANTARCTICA xml
+ if glc_use_antarctica is None:
+ # This is the case for compsets with SGLC where the GLC_USE_ANTARCTICA xml
# variable isn't defined
glc_use_antarctica_flag = ""
- elif isinstance(cism_use_antarctica, bool):
- if cism_use_antarctica:
+ elif isinstance(glc_use_antarctica, bool):
+ if glc_use_antarctica:
glc_use_antarctica_flag = "-glc_use_antarctica"
else:
glc_use_antarctica_flag = ""
else:
- expect(False, "Unexpected value for CISM_USE_ANTARCTICA: {}".format(cism_use_antarctica))
+ expect(
+ False,
+ "Unexpected value for GLC_USE_ANTARCTICA: {}".format(glc_use_antarctica),
+ )
if clm_nml_use_case != "UNSET":
- usecase = "-use_case %s" %clm_nml_use_case
+ usecase = "-use_case %s" % clm_nml_use_case
else:
usecase = ""
- if ( (mask != "null") and (mask != "UNSET") ):
- gridmask = "-mask %s" %mask
+ if (mask != "null") and (mask != "UNSET"):
+ gridmask = "-mask %s" % mask
else:
gridmask = ""
- start_ymd = run_startdate.replace('-','')
+ start_ymd = run_startdate.replace("-", "")
- if ('-01-01' in run_startdate) or ('-09-01' in run_startdate):
+ if ("-01-01" in run_startdate) or ("-09-01" in run_startdate):
ignore = "-ignore_ic_year"
else:
ignore = "-ignore_ic_date"
- tuning = "-lnd_tuning_mode %s "%lnd_tuning_mode
-
- spinup = "-clm_accelerated_spinup %s "%clm_accelerated_spinup
+ tuning = "-lnd_tuning_mode %s " % lnd_tuning_mode
+
+ #
+ # Spinup settings and specifics for SASU spinup
+ #
+ spinup = "-clm_accelerated_spinup %s " % clm_accelerated_spinup
+ if clm_accelerated_spinup == "sasu":
+ if (yr_start != None) and (yr_end != None):
+ nyr = yr_end - yr_start + 1
+ if (yr_end <= 0) or (yr_start <= 0):
+ logger.error("ERROR: Year start and end are both negative and should not be")
+ clm_namelist_opts = "nyr_forcing={} {}".format(nyr, clm_namelist_opts)
+ else:
+ logger.warning(
+ "WARNING: It does not make sense to do a SASU spinup with a prognostic atmosphere model"
+ )
+ logger.warning(" as it expects regular atmosphere forcing that is cycled over")
infile = os.path.join(ctsmconf, "namelist")
- inputdata_file = os.path.join(caseroot,"Buildconf","ctsm.input_data_list")
+ inputdata_file = os.path.join(caseroot, "Buildconf", "ctsm.input_data_list")
if driver == "nuopc":
lndfrac_setting = " "
else:
lnd_domain_path = case.get_value("LND_DOMAIN_PATH")
lnd_domain_file = case.get_value("LND_DOMAIN_FILE")
- lndfrac_file = os.path.join(lnd_domain_path,lnd_domain_file)
- lndfrac_setting = "-lnd_frac "+lndfrac_file
+ lndfrac_file = os.path.join(lnd_domain_path, lnd_domain_file)
+ lndfrac_setting = "-lnd_frac " + lndfrac_file
- config_cache_file = os.path.join(caseroot,"Buildconf", compname+"conf","config_cache.xml")
+ config_cache_file = os.path.join(caseroot, "Buildconf", compname + "conf", "config_cache.xml")
# -----------------------------------------------------
# Clear out old data
@@ -198,40 +313,64 @@ def buildnml(case, caseroot, compname):
# -----------------------------------------------------
ninst = int(ninst_lnd)
- for inst_counter in range(1, ninst+1):
+ for inst_counter in range(1, ninst + 1):
# determine instance string
inst_string = ""
if ninst > 1:
- inst_string = '_' + '%04d' % inst_counter
+ inst_string = "_" + "%04d" % inst_counter
# If multi-instance case does not have restart file, use
# single-case restart for each instance
rpointer = "rpointer.lnd"
- if (os.path.isfile(os.path.join(rundir,rpointer)) and
- (not os.path.isfile(os.path.join(rundir,rpointer + inst_string)))):
- shutil.copy(os.path.join(rundir, rpointer),
- os.path.join(rundir, rpointer + inst_string))
+ if os.path.isfile(os.path.join(rundir, rpointer)) and (
+ not os.path.isfile(os.path.join(rundir, rpointer + inst_string))
+ ):
+ shutil.copy(
+ os.path.join(rundir, rpointer),
+ os.path.join(rundir, rpointer + inst_string),
+ )
# -----------------------------------------------------
# call build-namelist
# -----------------------------------------------------
if run_type == "hybrid" or run_type == "branch":
- compnames = [ "clm4", "clm5", "clm2" ]
+ compnames = ["clm4", "clm5", "clm2"]
for comp in compnames:
- clm_startfile = "%s.%s%s.r.%s-%s.nc"%(run_refcase,comp,inst_string,run_refdate,run_reftod)
- if os.path.exists(os.path.join(rundir, clm_startfile)):
- break
- else:
- clm_startfile = "%s.%s.r.%s-%s.nc"%(run_refcase,comp,run_refdate,run_reftod)
- if os.path.exists(os.path.join(rundir, clm_startfile)):
- logger.warning( "WARNING: the start file being used for a multi-instance case is a single instance: "+clm_startfile )
+ if "PLUMBER2" in clm_usrdat_name:
+ # start_tod is supplied for PLUMBER cases
+ tod = start_tod
+ else:
+ # run_reftod is supplied for other cases
+ tod = run_reftod
+
+ clm_startfile = "%s.%s%s.r.%s-%s.nc" % (
+ run_refcase,
+ comp,
+ inst_string,
+ run_refdate,
+ tod,
+ )
+ if os.path.exists(os.path.join(rundir, clm_startfile)):
break
+ else:
+ clm_startfile = "%s.%s.r.%s-%s.nc" % (
+ run_refcase,
+ comp,
+ run_refdate,
+ run_reftod,
+ )
+ if os.path.exists(os.path.join(rundir, clm_startfile)):
+ logger.warning(
+ "WARNING: the start file being used for a multi-instance case is a single instance: "
+ + clm_startfile
+ )
+ break
if not os.path.exists(os.path.join(rundir, clm_startfile)):
- logger.warning( "WARNING: Could NOT find a start file to use using"+clm_startfile )
- clm_icfile = "%s = \'%s\'"%(startfile_type, clm_startfile)
+ logger.warning("WARNING: Could NOT find a start file named " + clm_startfile)
+ clm_icfile = "%s = '%s'" % (startfile_type, clm_startfile)
else:
clm_icfile = ""
@@ -243,25 +382,51 @@ def buildnml(case, caseroot, compname):
create_namelist_infile(case, user_nl_file, namelist_infile, "\n".join(infile_lines))
- cmd = os.path.join(lnd_root,"bld","build-namelist")
-
- command = ("%s -cimeroot %s -infile %s -csmdata %s -inputdata %s %s -namelist \"&clm_inparm start_ymd=%s %s/ \" "
- "%s %s -res %s %s -clm_start_type %s -envxml_dir %s "
- "-configuration %s -structure %s "
- "%s -glc_nec %s %s -co2_ppmv %s -co2_type %s -config %s -driver %s "
- "%s %s %s %s"
- %(cmd, _CIMEROOT, infile, din_loc_root, inputdata_file, ignore, start_ymd, clm_namelist_opts,
- nomeg, usecase, lnd_grid, clmusr, start_type, caseroot,
- configuration, structure,
- lndfrac_setting, glc_nec, glc_use_antarctica_flag, ccsm_co2_ppmv, clm_co2_type, config_cache_file, driver,
- clm_bldnml_opts, spinup, tuning, gridmask))
+ cmd = os.path.join(lnd_root, "bld", "build-namelist")
+
+ command = (
+ '%s -cimeroot %s -infile %s -csmdata %s -inputdata %s %s -namelist "&clm_inparm start_ymd=%s %s/ " '
+ "%s %s -res %s %s -clm_start_type %s -envxml_dir %s "
+ "-configuration %s -structure %s "
+ "%s -glc_nec %s %s -co2_ppmv %s -co2_type %s -config %s -driver %s "
+ "%s %s %s %s"
+ % (
+ cmd,
+ _CIMEROOT,
+ infile,
+ din_loc_root,
+ inputdata_file,
+ ignore,
+ start_ymd,
+ clm_namelist_opts,
+ nomeg,
+ usecase,
+ lnd_grid,
+ clmusr,
+ start_type,
+ caseroot,
+ configuration,
+ structure,
+ lndfrac_setting,
+ glc_nec,
+ glc_use_antarctica_flag,
+ ccsm_co2_ppmv,
+ clm_co2_type,
+ config_cache_file,
+ driver,
+ clm_bldnml_opts,
+ spinup,
+ tuning,
+ gridmask,
+ )
+ )
rc, out, err = run_cmd(command, from_dir=ctsmconf)
- expect(rc==0,"Command %s failed rc=%d\nout=%s\nerr=%s"%(cmd,rc,out,err))
+ expect(rc == 0, "Command %s failed rc=%d\nout=%s\nerr=%s" % (cmd, rc, out, err))
if out is not None:
- logger.debug(" %s"%out)
+ logger.debug(" %s" % out)
if err is not None:
- logger.debug(" %s"%err)
+ logger.debug(" %s" % err)
# -----------------------------------------------------
# copy resolved namelist to rundir
@@ -272,8 +437,9 @@ def buildnml(case, caseroot, compname):
file2 = os.path.join(rundir, "lnd_in")
if ninst > 1:
file2 += inst_string
- logger.debug("CTSM namelist copy: file1 %s file2 %s " %(file1, file2))
- shutil.copy(file1,file2)
+ logger.debug("CTSM namelist copy: file1 %s file2 %s " % (file1, file2))
+ shutil.copy(file1, file2)
+
###############################################################################
def _main_func():
@@ -281,9 +447,12 @@ def _main_func():
caseroot = parse_input(sys.argv)
with Case(caseroot) as case:
compname = case.get_value("COMP_LND")
- logger.warning( "WARNING: buildnml is being called a s program rather than a subroutine " +
- "as it is expected to be in the CESM context" )
+ logger.warning(
+ "WARNING: buildnml is being called a s program rather than a subroutine "
+ + "as it is expected to be in the CESM context"
+ )
buildnml(case, caseroot, compname)
+
if __name__ == "__main__":
_main_func()
diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml
index 7520050cf5..2506b8954a 100644
--- a/cime_config/config_component.xml
+++ b/cime_config/config_component.xml
@@ -1,4 +1,3 @@
-
@@ -16,7 +15,7 @@
clm4.5:
clm5.0:
- clm5.1:
+ clm6.0:
Satellite phenology:
Satellite phenology with VIC hydrology:
@@ -26,6 +25,7 @@
BGC (vert. resol. CN and methane) without anthropomorphic influences:
FATES (Functionally Assembled Terrestrial Ecosystem Simulator) Ecosystem Demography model:
Satellite phenology with FATES (Functionally Assembled Terrestrial Ecosystem Simulator) Ecosystem Demography model:
+ No Competition mode with FATES (Functionally Assembled Terrestrial Ecosystem Simulator) Ecosystem Demography model:
BGC (vert. resol. CN and methane) with dynamic vegetation:
BGC (vert. resol. CN and methane) with dynamic vegetation and prognostic crop:
BGC (vert. resol. CN and methane) with prognostic crop, with modifications appropriate for CMIP6 DECK experiments:
@@ -61,25 +61,85 @@
run_component_ctsm
env_run.xml
Tuning parameters and initial conditions should be optimized for what CLM model version and what meteorlogical forcing combination?
+ Options for all combinations of CLM physics and atm forcing are given. The buildnml and namelist_defaults will narrow it down to the ones
+ that have been tuned. The buildnml will also warn you if a tuning combination is based on another set.
+ Atm forcing options:
+ CRUv7
+ GSWP3
+ CAM4.0
+ CAM5.0
+ CAM6.0
+ CAM7.0
+ QIAN (not tuned)
+ 1PT (not tuned)
+ NLDAS2 (not tuned)
+ ERA5 (not tuned)
+ Other atm forcing options are invalid to run CLM and will result in an error.
UNSET
- clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_1_GSWP3v1
-
- clm4_5_CRUv7
- clm4_5_CRUv7
- clm4_5_GSWP3v1
- clm4_5_cam6.0
- clm5_0_CRUv7
- clm5_0_CRUv7
- clm5_0_GSWP3v1
- clm5_0_cam6.0
- clm5_1_GSWP3v1
+
+ clm5_0_cam6.0,clm5_0_cam7.0,clm5_0_cam5.0,clm5_0_cam4.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_QIAN,clm4_5_cam6.0,clm4_5_cam7.0,clm4_5_cam5.0,clm4_5_cam4.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm6_0_CRUv7,clm6_0_GSWP3v1,clm6_0_cam6.0,clm6_0_cam7.0,clm6_0_cam5.0,clm6_0_cam4.0,clm6_0_QIAN,clm6_0_1PT,clm6_0_NLDAS2,clm6_0_ERA5
+
+
+
+ clm4_5_CRUv7
+ clm4_5_CRUv7
+ clm4_5_CRUv7
+ clm4_5_GSWP3v1
+ clm4_5_cam6.0
+ clm4_5_cam4.0
+ clm4_5_cam5.0
+ clm4_5_cam6.0
+ clm4_5_cam7.0
+ clm4_5_cam5.0
+ clm4_5_QIAN
+ clm4_5_QIAN
+ clm4_5_1PT
+ clm4_5_NLDAS2
+ clm4_5_ERA5
+
+ clm5_0_CRUv7
+ clm5_0_CRUv7
+ clm5_0_GSWP3v1
+ clm5_0_GSWP3v1
+ clm5_0_cam6.0
+ clm5_0_cam4.0
+ clm5_0_cam5.0
+ clm5_0_cam6.0
+ clm5_0_cam7.0
+ clm5_0_cam6.0
+ clm5_0_QIAN
+ clm5_0_QIAN
+ clm5_0_1PT
+ clm5_0_NLDAS2
+ clm5_0_ERA5
+
+ clm6_0_CRUv7
+ clm6_0_CRUv7
+ clm6_0_GSWP3v1
+ clm6_0_GSWP3v1
+ clm6_0_cam6.0
+ clm6_0_cam4.0
+ clm6_0_cam5.0
+ clm6_0_cam6.0
+ clm6_0_cam7.0
+ clm6_0_cam7.0
+ clm6_0_QIAN
+ clm6_0_QIAN
+ clm6_0_1PT
+ clm6_0_NLDAS2
+ clm6_0_ERA5
+
+ INVALID_DATM_FORCING_FOR_RUNNING_CTSM
+ INVALID_DATM_FORCING_FOR_RUNNING_CTSM
+ INVALID_DATM_FORCING_FOR_RUNNING_CTSM
+ INVALID_DATM_FORCING_FOR_RUNNING_CTSM
char
- clm4_5,clm5_0,clm5_1
+ clm4_5,clm5_0,clm6_0
+ logical
+ TRUE,FALSE
+ TRUE
+
+ FALSE
+
+ run_component_cpl
+ env_run.xml
+ If CTSM will set the dust settings in drv_flds_in (TRUE), or if ATM (i.e. CAM) will - DO NOT EDIT (set by compset name)
+
+
char
clm,nwp
@@ -134,22 +207,24 @@
UNSET
- 2010_control
- 2000_control
- 1850_control
+ 2010_control
+ 2000_control
+ 1850_control
+ 1850_noanthro_control
1850_noanthro_control
- 20thC_transient
- 1850-2100_SSP5-8.5_transient
- 1850-2100_SSP1-2.6_transient
- 1850-2100_SSP3-7.0_transient
- 1850-2100_SSP5-3.4_transient
- 1850-2100_SSP2-4.5_transient
- 1850-2100_SSP1-1.9_transient
- 1850-2100_SSP4-3.4_transient
- 1850-2100_SSP4-6.0_transient
- 1850-2100_SSP5-8.5_transient
- 20thC_transient
- 1850-2100_SSP5-8.5_transient
+ 20thC_transient
+ 1850-2100_SSP5-8.5_transient
+ 1850-2100_SSP1-2.6_transient
+ 1850-2100_SSP3-7.0_transient
+ 1850-2100_SSP5-3.4_transient
+ 1850-2100_SSP2-4.5_transient
+ 1850-2100_SSP2-4.5_transient
+ 1850-2100_SSP1-1.9_transient
+ 1850-2100_SSP4-3.4_transient
+ 1850-2100_SSP4-6.0_transient
+ 1850-2100_SSP5-8.5_transient
+ 20thC_transient
+ 1850-2100_SSP5-8.5_transient
run_component_ctsm
env_run.xml
@@ -169,8 +244,9 @@
-bgc sp
-bgc bgc
-bgc bgc -crop
- -bgc fates -no-megan
- -bgc fates -no-megan
+ -bgc fates -nomeg
+ -bgc fates
+ -bgc fates
-bgc bgc -dynamic_vegetation
@@ -226,11 +302,11 @@
char
- on,off
+ on,sasu,off
off
run_component_ctsm
env_run.xml
- Turn on any settings for accellerating the model spinup.
+ Turn on any settings for accellerating the model spinup. SASU is to run the Semi-Analytic Spin-Up with the CN soil matrix method.
@@ -239,10 +315,14 @@
UNSET
run_component_ctsm
env_run.xml
- Dataset name for user-created datasets. This is used as the argument
- in Buildconf/clm.buildnml to build-namelist -clm_usr_name. An example of
- such a dataset would be 1x1pt_boulderCO_c090722. The default value is UNSET.
- This is an advanced flag and should only be used by expert users.
+ Resolution name for user-created resolutions. This is especially used
+ for single point and regional resolutions created via subset_data from
+ the global datasets. This should be set when you use CLM_USRDAT as the grid
+ to create_newcase. The default value is UNSET.
+ For NEON cases, this can be set to either NEON or NEON.PRISM, the latter of which would
+ use PRISM precipitation instead of the default NEON precipitation. NEON cases then also
+ use the variable NEONSITE to specify the exact site. PLUMBER cases use the variable
+ PLUMBER2SITE to specify the exact site.
@@ -267,7 +347,7 @@
cold start (finidat will be set to blanks).
A value of on forces the model to spin up from a cold-start
(arbitrary initial conditions). Setting this value in the xml file will take
- precedence over any settings for finidat in the $CASEROOT/user_nl_ctsm file.
+ precedence over any settings for finidat in the $CASEROOT/user_nl_clm file.
@@ -275,11 +355,16 @@
- $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_deck
- $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/fates_sp
- $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_nociso_deck
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/fates_sp
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/fates_nocomp
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_deck
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_nociso_deck
$COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_waccm_deck
$COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_waccm_nociso_deck
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_deck
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_nociso_deck
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_waccm_deck
+ $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_waccm_nociso_deck
run_component_ctsm
env_case.xml
@@ -288,10 +373,31 @@
char
+
ABBY,BLAN,CPER,DEJU,GRSM,HEAL,KONA,LENO,NIWO,ONAQ,PUUM,SERC,SRER,TALL,TREE,WOOD,
BARR,BONA,DCFS,DELA,GUAN,JERC,KONZ,MLBS,NOGP,ORNL,RMNP,SJER,STEI,TEAK,UKFS,WREF,
- BART,CLBJ,DSNY,HARV,JORN,LAJA,MOAB,OAES,OSBS,SCBI,SOAP,STER,TOOL,UNDE,YELL
+ BART,CLBJ,DSNY,HARV,JORN,LAJA,MOAB,OAES,OSBS,SCBI,SOAP,STER,TOOL,UNDE,YELL,
+ NEON_PRECIP.ABBY,NEON_PRECIP.BLAN,NEON_PRECIP.CPER,NEON_PRECIP.DEJU,NEON_PRECIP.GRSM,
+ NEON_PRECIP.HEAL,NEON_PRECIP.KONA,NEON_PRECIP.LENO,NEON_PRECIP.NIWO,NEON_PRECIP.ONAQ,
+ NEON_PRECIP.PUUM,NEON_PRECIP.SERC,NEON_PRECIP.SRER,NEON_PRECIP.TALL,NEON_PRECIP.TREE,
+ NEON_PRECIP.WOOD,NEON_PRECIP.BARR,NEON_PRECIP.BONA,NEON_PRECIP.DCFS,NEON_PRECIP.DELA,
+ NEON_PRECIP.GUAN,NEON_PRECIP.JERC,NEON_PRECIP.KONZ,NEON_PRECIP.MLBS,NEON_PRECIP.NOGP,
+ NEON_PRECIP.ORNL,NEON_PRECIP.RMNP,NEON_PRECIP.SJER,NEON_PRECIP.STEI,NEON_PRECIP.TEAK,
+ NEON_PRECIP.UKFS,NEON_PRECIP.WREF,NEON_PRECIP.BART,NEON_PRECIP.CLBJ,NEON_PRECIP.DSNY,
+ NEON_PRECIP.HARV,NEON_PRECIP.JORN,NEON_PRECIP.LAJA,NEON_PRECIP.MOAB,NEON_PRECIP.OAES,
+ NEON_PRECIP.OSBS,NEON_PRECIP.SCBI,NEON_PRECIP.SOAP,NEON_PRECIP.STER,NEON_PRECIP.TOOL,
+ NEON_PRECIP.UNDE,NEON_PRECIP.YELL,
+ PRISM_PRECIP.ABBY,PRISM_PRECIP.BLAN,PRISM_PRECIP.CPER,PRISM_PRECIP.GRSM,
+ PRISM_PRECIP.KONA,PRISM_PRECIP.LENO,PRISM_PRECIP.NIWO,PRISM_PRECIP.ONAQ,
+ PRISM_PRECIP.SERC,PRISM_PRECIP.SRER,PRISM_PRECIP.TALL,PRISM_PRECIP.TREE,
+ PRISM_PRECIP.WOOD,PRISM_PRECIP.DCFS,PRISM_PRECIP.DELA,PRISM_PRECIP.JERC,
+ PRISM_PRECIP.KONZ,PRISM_PRECIP.MLBS,PRISM_PRECIP.NOGP,PRISM_PRECIP.ORNL,
+ PRISM_PRECIP.RMNP,PRISM_PRECIP.SJER,PRISM_PRECIP.STEI,PRISM_PRECIP.TEAK,
+ PRISM_PRECIP.UKFS,PRISM_PRECIP.WREF,PRISM_PRECIP.BART,PRISM_PRECIP.CLBJ,
+ PRISM_PRECIP.DSNY,PRISM_PRECIP.HARV,PRISM_PRECIP.JORN,PRISM_PRECIP.MOAB,
+ PRISM_PRECIP.OAES,PRISM_PRECIP.OSBS,PRISM_PRECIP.SCBI,PRISM_PRECIP.SOAP,
+ PRISM_PRECIP.STER,PRISM_PRECIP.UNDE,PRISM_PRECIP.YELL,
run_component_ctsm
@@ -301,13 +407,35 @@
char
- v1,v2,latest
+ v1,v2,v3,latest
latest
run_component_ctsm
env_run.xml
Version id of Neon data
+
+ char
+
+
+ AR-SLu,AT-Neu,AU-ASM,AU-Cow,AU-Cpr,AU-Ctr,AU-Cum,AU-DaP,AU-DaS,AU-Dry,AU-Emr,AU-Gin,AU-GWW,AU-How,AU-Lit,
+ AU-Otw,AU-Rig,AU-Rob,AU-Sam,AU-Stp,AU-TTE,AU-Tum,AU-Whr,AU-Wrr,AU-Ync,BE-Bra,BE-Lon,BE-Vie,BR-Sa3,BW-Ma1,CA-NS1,
+ CA-NS2,CA-NS4,CA-NS5,CA-NS6,CA-NS7,CA-Qcu,CA-Qfo,CA-SF1,CA-SF2,CA-SF3,CH-Cha,CH-Dav,CH-Fru,CH-Oe1,CN-Cha,CN-Cng,
+ CN-Dan,CN-Din,CN-Du2,CN-HaM,CN-Qia,CZ-wet,DE-Bay,DE-Geb,DE-Gri,DE-Hai,DE-Kli,DE-Meh,DE-Obe,DE-Seh,DE-SfN,DE-Tha,
+ DE-Wet,DK-Fou,DK-Lva,DK-Ris,DK-Sor,DK-ZaH,ES-ES1,ES-ES2,ES-LgS,ES-LMa,ES-VDA,FI-Hyy,FI-Kaa,FI-Lom,FI-Sod,FR-Fon,
+ FR-Gri,FR-Hes,FR-LBr,FR-Lq1,FR-Lq2,FR-Pue,GF-Guy,HU-Bug,ID-Pag,IE-Ca1,IE-Dri,IT-Amp,IT-BCi,IT-CA1,IT-CA2,IT-CA3,
+ IT-Col,IT-Cpz,IT-Isp,IT-Lav,IT-LMa,IT-Mal,IT-MBo,IT-Noe,IT-Non,IT-PT1,IT-Ren,IT-Ro1,IT-Ro2,IT-SR2,IT-SRo,JP-SMF,
+ NL-Ca1,NL-Hor,NL-Loo,PL-wet,PT-Esp,PT-Mi1,PT-Mi2,RU-Che,RU-Fyo,RU-Zot,SD-Dem,SE-Deg,UK-Gri,UK-Ham,UK-PL3,US-AR1,
+ US-AR2,US-ARM,US-Aud,US-Bar,US-Bkg,US-Blo,US-Bo1,US-Cop,US-FPe,US-GLE,US-Goo,US-Ha1,US-Ho1,US-KS2,US-Los,US-Me2,
+ US-Me4,US-Me6,US-MMS,US-MOz,US-Myb,US-Ne1,US-Ne2,US-Ne3,US-NR1,US-PFa,US-Prr,US-SP1,US-SP2,US-SP3,US-SRG,US-SRM,
+ US-Syv,US-Ton,US-Tw4,US-Twt,US-UMB,US-Var,US-WCr,US-Whs,US-Wkg,ZA-Kru,ZM-Mon,
+
+
+ run_component_ctsm
+ env_run.xml
+ Name of site for PLUMBER tower data
+
+
=========================================
CLM naming conventions
diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml
index 649306b05a..8ab6254029 100644
--- a/cime_config/config_compsets.xml
+++ b/cime_config/config_compsets.xml
@@ -13,8 +13,8 @@
TIME_ATM[%phys]_LND[%phys]_ICE[%phys]_OCN[%phys]_ROF[%phys]_GLC[%phys]_WAV[%phys][_BGC%phys]
Where for the CAM specific compsets below the following is supported
TIME = Time period (e.g. 2000, HIST, SSP585...)
- ATM = [CAM40, CAM50, CAM55]
- LND = [CLM45, CLM50, CLM51, SLND]
+ ATM = [CAM40, CAM50, CAM60]
+ LND = [CLM45, CLM50, CLM60, SLND]
ICE = [CICE, DICE, SICE]
OCN = [DOCN, ,AQUAP, SOCN]
ROF = [RTM, SROF]
@@ -37,18 +37,28 @@
- I1PtClm51Bgc
- 2000_DATM%1PT_CLM51%BGC_SICE_SOCN_SROF_SGLC_SWAV
+ I1PtClm60Bgc
+ 2000_DATM%1PT_CLM60%BGC_SICE_SOCN_SROF_SGLC_SWAV
- IHist1PtClm51Bgc
- HIST_DATM%1PT_CLM51%BGC_SICE_SOCN_SROF_SGLC_SWAV
+ I1PtClm60Fates
+ 2000_DATM%1PT_CLM60%FATES_SICE_SOCN_SROF_SGLC_SWAV
- I1PtClm51SpRs
- 2000_DATM%1PT_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV
+ IHist1PtClm60Bgc
+ HIST_DATM%1PT_CLM60%BGC_SICE_SOCN_SROF_SGLC_SWAV
+
+
+
+ IHist1PtClm60Fates
+ HIST_DATM%1PT_CLM60%FATES_SICE_SOCN_SROF_SGLC_SWAV
+
+
+
+ I1PtClm60SpRs
+ 2000_DATM%1PT_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV
@@ -73,16 +83,22 @@
I2000Clm50SpRs
2000_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+
+ I2000Clm60SpRs
+ 2000_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV
+
- I2000Clm51Sp
- 2000_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV
+ I2000Clm60Sp
+ 2000_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
- I2000Clm51SpRs
- 2000_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV
+ I2000Clm60SpRs
+ 2000_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV
@@ -118,13 +134,13 @@
- I2000Clm51BgcCrop
- 2000_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+ I2000Clm60BgcCrop
+ 2000_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
- I2000Clm51Bgc
- 2000_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV
+ I2000Clm60Bgc
+ 2000_DATM%GSWP3v1_CLM60%BGC_SICE_SOCN_MOSART_SGLC_SWAV
@@ -142,6 +158,11 @@
+
+ I1850Clm60SpCru
+ 1850_DATM%CRUv7_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
I1850Clm50BgcCrop
1850_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
@@ -150,33 +171,52 @@
- I1850Clm51BgcCrop
- 1850_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+ I1850Clm60BgcCrop
+ 1850_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
+
+
+ I1850Clm60BgcCrop
+ 1850_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
- I1850Clm51Sp
- 1850_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV
+ I1850Clm60Sp
+ 1850_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
- I1850Clm51Bgc
- 1850_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV
+ I1850Clm60Bgc
+ 1850_DATM%GSWP3v1_CLM60%BGC_SICE_SOCN_MOSART_SGLC_SWAV
+
I1850Clm50BgcCropCmip6
1850_DATM%GSWP3v1_CLM50%BGC-CROP-CMIP6DECK_SICE_SOCN_MOSART_SGLC_SWAV
+
+ I1850Clm60BgcCropCmip6
+ 1850_DATM%GSWP3v1_CLM60%BGC-CROP-CMIP6DECK_SICE_SOCN_MOSART_SGLC_SWAV
+
+
I1850Clm50BgcCropCmip6waccm
1850_DATM%GSWP3v1_CLM50%BGC-CROP-CMIP6WACCMDECK_SICE_SOCN_MOSART_SGLC_SWAV
+
+ I1850Clm60BgcCropCmip6waccm
+ 1850_DATM%GSWP3v1_CLM60%BGC-CROP-CMIP6WACCMDECK_SICE_SOCN_MOSART_SGLC_SWAV
+
+
I1850Clm50BgcCropCru
1850_DATM%CRUv7_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
@@ -184,9 +224,19 @@
+
+
+ I1850Clm60BgcCropCru
+ 1850_DATM%CRUv7_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
+
+ I2000Clm60BgcCropQianRs
+ 2000_DATM%QIA_CLM60%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV
+
I2000Clm50BgcCropQianRs
2000_DATM%QIA_CLM50%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV
@@ -195,6 +245,10 @@
I2000Clm45BgcCropQianRs
2000_DATM%QIA_CLM45%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV
+
+ I2000Clm50FatesQian
+ 2000_DATM%QIA_CLM50%FATES_SICE_SOCN_MOSART_SGLC_SWAV
+
I2000Clm50BgcCruRs
@@ -209,8 +263,8 @@
- I2000Clm51Fates
- 2000_DATM%GSWP3v1_CLM51%FATES_SICE_SOCN_MOSART_SGLC_SWAV
+ I2000Clm60Fates
+ 2000_DATM%GSWP3v1_CLM60%FATES_SICE_SOCN_MOSART_SGLC_SWAV
I2000Clm50Fates
@@ -221,12 +275,12 @@
2000_DATM%CRUv7_CLM50%FATES_SICE_SOCN_SROF_SGLC_SWAV
- I2000Clm51FatesSpCruRsGs
- 2000_DATM%CRUv7_CLM51%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV
+ I2000Clm60FatesSpCruRsGs
+ 2000_DATM%CRUv7_CLM60%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV
- I2000Clm51FatesSpRsGs
- 2000_DATM%GSWP3v1_CLM51%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV
+ I2000Clm60FatesSpRsGs
+ 2000_DATM%GSWP3v1_CLM60%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV
I2000Clm50FatesCru
@@ -238,8 +292,8 @@
2000_DATM%GSWP3v1_CLM50%FATES_SICE_SOCN_SROF_SGLC_SWAV
- I2000Clm51FatesRs
- 2000_DATM%GSWP3v1_CLM51%FATES_SICE_SOCN_SROF_SGLC_SWAV
+ I2000Clm60FatesRs
+ 2000_DATM%GSWP3v1_CLM60%FATES_SICE_SOCN_SROF_SGLC_SWAV
@@ -247,16 +301,29 @@
1850_DATM%GSWP3v1_CLM50%BGC_SICE_SOCN_MOSART_SGLC_SWAV
+
+ I1850Clm60BgcNoAnthro
+ 1850_DATM%GSWP3v1_CLM60%BGC-NOANTHRO_SICE_SOCN_RTM_SGLC_SWAV
+
+
+
+
+ I1850Clm60SpNoAnthro
+ 1850_DATM%GSWP3v1_CLM60%SP-NOANTHRO_SICE_SOCN_RTM_SGLC_SWAV
+
+
+
I1850Clm50BgcNoAnthro
- 1850_DATM%GSWP3v1_CLM50%BGC-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV
+ 1850_DATM%GSWP3v1_CLM50%BGC-NOANTHRO_SICE_SOCN_RTM_SGLC_SWAV
I1850Clm50SpNoAnthro
- 1850_DATM%GSWP3v1_CLM50%SP-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV
+ 1850_DATM%GSWP3v1_CLM50%SP-NOANTHRO_SICE_SOCN_RTM_SGLC_SWAV
+
IHistClm50BgcCrop
HIST_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
@@ -265,29 +332,31 @@
- I1850Clm51Bgc
- 1850_DATM%GSWP3v1_CLM50%BGC_SICE_SOCN_MOSART_SGLC_SWAV
+ I1850Clm60SpNoAnthro
+ 1850_DATM%GSWP3v1_CLM60%SP-NOANTHRO_SICE_SOCN_RTM_SGLC_SWAV
+
-
- I1850Clm51SpNoAnthro
- 1850_DATM%GSWP3v1_CLM51%SP-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV
-
+ IHistClm60Sp
+ HIST_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
+
- IHistClm51Sp
- HIST_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV
+ IHistClm60SpRs
+ HIST_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV
- IHistClm51Bgc
- HIST_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV
+ IHistClm60Bgc
+ HIST_DATM%GSWP3v1_CLM60%BGC_SICE_SOCN_MOSART_SGLC_SWAV
- IHistClm51BgcCrop
- HIST_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+ IHistClm60BgcCrop
+ HIST_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
@@ -304,6 +373,11 @@
+
+ IHistClm60SpCru
+ HIST_DATM%CRUv7_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
IHistClm50Bgc
HIST_DATM%GSWP3v1_CLM50%BGC_SICE_SOCN_MOSART_SGLC_SWAV
@@ -322,7 +396,14 @@
HIST_DATM%QIA_CLM50%BGC_SICE_SOCN_SROF_SGLC_SWAV
-
+
+ IHistClm60BgcQianRs
+ HIST_DATM%QIA_CLM60%BGC_SICE_SOCN_SROF_SGLC_SWAV
+
+
+
ISSP585Clm50BgcCrop
SSP585_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
@@ -363,14 +444,24 @@
SSP534_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+
+
+ ISSP585Clm60BgcCrop
+ SSP585_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV
+
-
+
+
IHistClm50BgcCropQianRs
HIST_DATM%QIA_CLM50%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV
+
+ IHistClm60BgcCropQianRs
+ HIST_DATM%QIA_CLM60%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV
+
@@ -513,7 +604,9 @@
2000_DATM%CRUv7_CLM45%SP-VIC_SICE_SOCN_RTM_SGLC_SWAV
-
+
I1850Clm50SpG
@@ -530,12 +623,6 @@
1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_MOSART_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV
-
-
- I1850Clm50SpRsGag
- 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV
-
-
IHistClm50SpG
HIST_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV
@@ -551,13 +638,43 @@
HIST_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV
-
+
+ I1850Clm60BgcCropG
+ 1850_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV
+
+
+
+
+
+
+ IHistClm60BgcCropG
+ HIST_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV
+
+
+
+
+
+
+
+ I1850Clm50SpRsGag
+ 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV
+
+
+
+ I1850Clm60SpRs
+ 1850_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV
+
+
+
+
+ both purposes.)
+-->
I2000Ctsm50NwpSpAsRs
2000_SATM_CLM50%NWP-SP_SICE_SOCN_SROF_SGLC_SWAV
diff --git a/cime_config/config_pes.xml b/cime_config/config_pes.xml
index aad134be86..17e2947d7f 100644
--- a/cime_config/config_pes.xml
+++ b/cime_config/config_pes.xml
@@ -7,34 +7,34 @@
none
- -1
- -1
- -1
- -1
- -1
- -1
- -1
- -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
@@ -44,34 +44,34 @@
none
- -1
- -9
- -9
- -9
- -9
- -9
- -9
- -9
+ -1
+ -9
+ -9
+ -9
+ -9
+ -9
+ -9
+ -9
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
@@ -91,24 +91,61 @@
-4
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -1
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
@@ -118,34 +155,34 @@
none
- -2
- -2
- -2
- -2
- -2
- -2
- -2
- -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
@@ -155,34 +192,34 @@
none
- 180
- 180
- 180
- 180
- 180
- 180
- 180
- 180
+ 180
+ 180
+ 180
+ 180
+ 180
+ 180
+ 180
+ 180
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
@@ -192,7 +229,7 @@
none
- -1
+ -1
-40
-40
-40
@@ -202,24 +239,24 @@
-40
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
@@ -262,18 +299,18 @@
-
+
none
-1
- -11
- -11
- -11
- -11
- -11
- -11
- -11
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
1
@@ -298,86 +335,86 @@
-
-
-
- none
+
+
+
+ Much lower core count f19 layout, mainly for testing
- -4
- -4
- -4
- -4
- -4
- -4
- -4
- -4
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
-
-
+
+
none
- -1
- -50
- -50
- -50
- -50
- -50
- -50
- -50
+ -1
+ -11
+ -11
+ -11
+ -11
+ -11
+ -11
+ -11
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
-
-
- Much lower core count f09 layout, mainly for testing
+
+
+ none
- -1
+ -4
-4
-4
-4
@@ -410,18 +447,18 @@
-
+
none
-1
- -11
- -11
- -11
- -11
- -11
- -11
- -11
+ -50
+ -50
+ -50
+ -50
+ -50
+ -50
+ -50
1
@@ -446,130 +483,1322 @@
-
-
+
+
none
- -8
- -8
- -8
- -8
- -8
- -8
- -8
- -8
+ -1
+ -14
+ -14
+ -14
+ -14
+ -14
+ -14
+ -14
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
-
-
-
-
- none
+
+
+
+
+ Much lower core count f09 layout, mainly for testing
+
+ -1
+ -5
+ -5
+ -5
+ -5
+ -5
+ -5
+ -5
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ Much lower core count f09 layout, mainly for testing
+
+ -1
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -11
+ -11
+ -11
+ -11
+ -11
+ -11
+ -11
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -1
+ -21
+ -21
+ -21
+ -21
+ -21
+ -21
+ -21
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -16
+ -16
+ -16
+ -16
+ -16
+ -16
+ -16
+ -16
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -1
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -1
+ -20
+ -20
+ -20
+ -20
+ -20
+ -20
+ -20
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -70
+ -70
+ -70
+ -70
+ -70
+ -70
+ -70
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -70
+ -70
+ -70
+ -70
+ -70
+ -70
+ -70
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -70
+ -70
+ -70
+ -70
+ -70
+ -70
+ -70
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -16
+ -16
+ -16
+ -16
+ -16
+ -16
+ -16
+ -16
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -32
+ -32
+ -32
+ -32
+ -32
+ -32
+ -32
+ -32
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -24
+ -24
+ -24
+ -24
+ -24
+ -24
+ -24
+ -24
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+ -48
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -96
+ -96
+ -96
+ -96
+ -96
+ -96
+ -96
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ 5
+ 5
+ 5
+ 5
+ 5
+ 5
+ 5
+ 5
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+ 1>
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+
+
+ 1>
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+ 1>
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ none
+
+ -1
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
+
+ -1
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+
+
+
+
+
+
+
+ none
- -16
- -16
- -16
- -16
- -16
- -16
- -16
- -16
+ -1
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
+ -12
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
-
-
+
+
none
- -4
- -4
- -4
- -4
- -4
- -4
- -4
- -4
+ -1
+ -36
+ -36
+ -36
+ -36
+ -36
+ -36
+ -36
+ -36
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ 0
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
-
+
none
- -12
- -12
- -12
- -12
- -12
- -12
- -12
- -12
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
1
@@ -594,19 +1823,19 @@
-
+
none
-1
- -70
- -70
- -70
- -70
- -70
- -70
- -70
+ -50
+ -50
+ -50
+ -50
+ -50
+ -50
+ -50
1
@@ -631,130 +1860,56 @@
-
-
-
- none
-
- -12
- -12
- -12
- -12
- -12
- -12
- -12
- -12
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
+
-
- none
-
- -1
- -70
- -70
- -70
- -70
- -70
- -70
- -70
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
-
-
-
-
-
-
-
- none
-
- -12
- -12
- -12
- -12
- -12
- -12
- -12
- -12
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
+
+ Much lower core count nldas2 layout, mainly for testing
+
+ -1
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
-
-
+
+
none
-1
- -70
- -70
- -70
- -70
- -70
- -70
- -70
+ -14
+ -14
+ -14
+ -14
+ -14
+ -14
+ -14
1
@@ -776,96 +1931,22 @@
-1
-1
-
-
-
-
-
-
- none
-
- -16
- -16
- -16
- -16
- -16
- -16
- -16
- -16
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- -32
- -32
- -32
- -32
- -32
- -32
- -32
- -32
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- -12
- -12
- -12
- -12
- -12
- -12
- -12
- -12
+
+
+
+
+
+
+ Much lower core count nldas2 layout, mainly for testing
+
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
1
@@ -890,19 +1971,19 @@
-
-
+
+
- none
+ Need at least 4 nodes to default to normal queue
-1
- -48
- -48
- -48
- -48
- -48
- -48
- -48
+ -3
+ -3
+ -3
+ -3
+ -3
+ -3
+ -3
1
@@ -927,56 +2008,19 @@
-
-
-
- none
-
- -24
- -24
- -24
- -24
- -24
- -24
- -24
- -24
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
+
+
+
none
-1
- -48
- -48
- -48
- -48
- -48
- -48
- -48
+ -7
+ -7
+ -7
+ -7
+ -7
+ -7
+ -7
1
@@ -1001,19 +2045,19 @@
-
-
+
+
- none
+ Need at least 2 nodes to devel queue
- -48
- -48
- -48
- -48
- -48
- -48
- -48
- -48
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
1
@@ -1038,19 +2082,20 @@
-
-
-
+
+
+
+
none
- -1
- -96
- -96
- -96
- -96
- -96
- -96
- -96
+ -2
+ -7
+ -7
+ -7
+ -7
+ -7
+ -7
+ -7
1
@@ -1064,292 +2109,32 @@
0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
-
-
-
-
-
-
-
- none
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- 5
- 5
- 5
- 5
- 5
- 5
- 5
- 5
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- -4
- -4
- -4
- -4
- -4
- -4
- -4
- -4
- -4
-
-
- 1>
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- -2
- -2
- -2
- -2
- -2
- -2
- -2
- -2
- -2
-
-
- 1>
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+
-
+
none
-
- -1
- -1
- -1
- -1
- -1
- -1
- -1
- -1
- -1
-
-
- 1>
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- -4
- -4
- -4
- -4
- -4
- -4
- -4
- -4
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
-
-
-
-
-
-
-
- none
-
- -1
- -50
- -50
- -50
- -50
- -50
- -50
- -50
-
-
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
-
-
- 0
- -1
- -1
- -1
- -1
- -1
- -1
- -1
-
-
-
-
-
-
-
- Much lower core count nldas2 layout, mainly for testing
-1
- -4
- -4
- -4
- -4
- -4
- -4
- -4
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
+ -1
1
@@ -1374,5 +2159,4 @@
-
diff --git a/cime_config/config_tests.xml b/cime_config/config_tests.xml
index 0307ee7ef5..12859b9131 100644
--- a/cime_config/config_tests.xml
+++ b/cime_config/config_tests.xml
@@ -15,6 +15,16 @@ This defines various CTSM-specific system tests
FALSE
+
+ Build and run the mksurfdata_esmf tool to generate a new fsurdat; then run the CTSM with this fsurdat
+ 1
+ FALSE
+ FALSE
+ never
+ $STOP_OPTION
+ $STOP_N
+
+
Run the CTSM with an fsurdat generated by the fsurdat_modify tool
1
@@ -113,6 +123,38 @@ This defines various CTSM-specific system tests
$STOP_N
+
+ FATES potential vegetarion spin-up + land use transient run test
+ 1
+ ndays
+ startup
+ 4
+ FALSE
+ FALSE
+ $STOP_OPTION
+ $STOP_N
+
+
+
+ Generate prescribed maturity requirements, then test with them
+ 1
+ FALSE
+ FALSE
+ never
+ $STOP_OPTION
+ $STOP_N
+
+
+
+ As RXCROPMATURITY but don't actually generate GDDs. Allows short testing with existing GDD inputs.
+ 1
+ FALSE
+ FALSE
+ never
+ $STOP_OPTION
+ $STOP_N
+
+
+
+
+
+ FAIL
+ CDEPS/#243
+
+
+
+
+
+ FAIL
+ #2787
+ The issue shows how to fix it.
+
+
+
+
+ FAIL
+ #2787
+ The issue shows how to fix it.
+
+
+
+
+ FAIL
+ #2787
+ The issue shows how to fix it.
+
+
-
+
+
+ FAIL
+ #2780
+ Crashes in the matrix solver.
+
+
+
+
+ FAIL
+ #2780
+ Crashes in the matrix solver.
+
+
+
+ FAIL
+ #2780
+ Crashes in the matrix solver.
+
+
+
+
+
+ FAIL
+ #2619
+ This failure relates to the following REP failure.
+
+
+
+
+ FAIL
+ #2619
+ This failure relates to the preceding ERP failure.
+
+
+
+
+ FAIL
+ #2619
+ This failure relates to the preceding ERP failure.
+
+
+
+
+
+ FAIL
+ #2542
+
+
+
+
+
FAIL
#1733
-
+
+
+ FAIL
+ #2310
+
+
+
+
+
+ FAIL
+ #2310
+
FAIL
- #1844
+ #2310
+
+
+
+
+
+ FAIL
+ #2310
+
+
+ FAIL
+ #2310
+
+
+
+
+
+ FAIL
+ #2310
+
+
+ FAIL
+ #2310
+
+
+
+
+
+ FAIL
+ #2310
+
+
+ FAIL
+ #2310
+
+
+
+
+
+ FAIL
+ #2453
+
+
+
+
+
+ FAIL
+ #2454
+
+
+
+
+
+ FAIL
+ #2454
+
+
+
+
+
+ FAIL
+ #2310
+
+
+ FAIL
+ #2310
+
+
+
+
+
+ FAIL
+ #2310
+
+
+ FAIL
+ #2310
-
+
+
+ FAIL
+ #2653
+
+
+
+
+
+ FAIL
+ FATES#1216
+
+
+
+
+
+ FAIL
+ #2321
+
+
+
+
+
+ FAIL
+ #2261
+
+
+
+
+
+ PEND
+ FATES#983
+ This job should time out on izumi, seems to be hanging on history output.
+
+
+
+
+
+ FAIL
+ FATES#1089
+
+
+
+
+
+ FAIL
+ FATES#1089
+
+
+
+
+
+ FAIL
+ #2325
+
+
+
+
FAIL
- #667
+ #2325
+
+
+
+
+
+ FAIL
+ #2325
+
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2861
+
+
+
+
+
+ FAIL
+ #2310
+
+
+
+
+
+ FAIL
+ #2810
+
+
+
+
+
+ FAIL
+ #2810
+
+
+
+
+
+
+
+ FAIL
+ MOSART#91
diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml
index dedf27350e..db00b605b6 100644
--- a/cime_config/testdefs/testlist_clm.xml
+++ b/cime_config/testdefs/testlist_clm.xml
@@ -1,2557 +1,4043 @@
+
-
+
+
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
-
+
-
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
+
+
-
+
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
-
-
+
-
+
-
+
-
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
+
+
+
-
+
-
+
-
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
+
-
+
-
+
+
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
+
-
+
-
+
+
-
+
-
+
+
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
-
-
+
-
+
-
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
-
+
-
+
-
+
-
-
+
-
-
+
-
+
-
+
+
-
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
-
+
+
-
-
+
-
+
+
+
-
+
-
+
+
-
-
+
-
+
+
-
-
+
-
+
+
+
-
+
-
+
+
-
+
-
-
-
-
+
+
-
+
-
+
+
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
-
+
-
-
+
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
+
+
-
+
-
-
+
-
-
+
+
+
-
+
-
-
+
-
-
+
+
+
-
+
-
-
+
-
+
+
+
-
+
-
+
-
+
+
+
-
+
-
-
+
-
+
+
+
-
+
-
+
-
+
+
+
-
+
-
+
-
+
+
+
-
+
+
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
+
-
+
-
+
+
-
+
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
+
-
-
+
-
+
-
-
+
+
+
-
+
-
+
+
+
+
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
+
-
+
-
+
-
+
-
+
+
-
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
-
+
-
+
-
-
+
-
+
-
+
-
-
+
+
-
+
-
+
+
-
+
-
+
-
-
+
-
+
-
+
+
-
-
+
-
+
-
+
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
+
-
+
+
+
+
-
-
+
-
+
-
+
+
+
-
+
-
+
-
+
-
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
-
-
-
+
+
-
+
-
-
+
+
-
+
-
+
+
-
+
-
+
-
+
-
-
+
+
+
-
+
-
+
-
-
+
-
+
+
+
-
+
-
+
-
-
+
-
+
-
+
+
-
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
-
+
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
-
+
-
+
+
+
-
-
+
+
-
+
-
+
-
-
+
-
+
-
+
+
-
-
+
-
+
-
+
-
-
+
-
+
-
+
-
-
-
+
+
-
+
-
+
-
-
-
+
+
-
+
-
+
-
-
+
-
+
+
-
+
-
+
-
+
-
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
-
+
-
-
+
-
+
+
-
+
-
-
+
+
-
+
+
-
+
-
+
-
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
-
+
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
+
+
-
+
-
+
+
-
-
+
+
+
-
+
-
+
+
-
-
+
+
+
-
+
-
+
+
-
+
-
+
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
-
+
-
-
-
-
+
+
-
+
-
-
+
-
+
+
-
+
-
-
-
-
-
-
+
+
+
-
+
-
-
+
-
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
-
-
-
+
+
+
-
+
-
-
-
+
-
+
+
-
+
-
+
+
-
+
-
-
+
+
-
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
+
+
-
-
-
+
-
+
-
-
-
+
-
-
+
-
-
-
+
-
+
+
-
-
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
-
+
-
-
-