diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 0cf46943f4..f3b0fd8d0c 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -524,9 +524,9 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/ctsm60_params_nfix.c241119.nc -lnd/clm2/paramdata/clm50_params_nfix.c241119.nc -lnd/clm2/paramdata/clm45_params_nfix.c241119.nc +lnd/clm2/paramdata/ctsm60_params.c250311.nc +lnd/clm2/paramdata/clm50_params.c250311.nc +lnd/clm2/paramdata/clm45_params.c250311.nc diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm index f3df7203d7..6caaaa7018 100644 --- a/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm @@ -1,2 +1,2 @@ -paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_ciso_cwd_hr_params_nfix.c241119.nc' +paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_ciso_cwd_hr_params.c250311.nc' hist_fincl1 = 'CWDC_HR','C13_CWDC_HR','C14_CWDC_HR','CWD_HR_L2','CWD_HR_L2_vr','CWD_HR_L3','CWD_HR_L3_vr' diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm index d982aea0f0..2a1a84fb8c 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm @@ -1,2 +1,2 @@ use_soil_matrixcn = .true. -paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_params_cn30.c241119.nc' +paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_params_cn30.c250311.nc' diff --git a/doc/ChangeLog b/doc/ChangeLog index 184168ed02..b5f05295f7 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,82 @@ =============================================================== +Tag name: ctsm5.3.033 +Originator(s): wwieder, slevis (Will Wieder, Sam Levis, UCAR/TSS) +Date: Wed 19 Mar 2025 02:43:55 PM MDT +One-line Summary: Add new mimics_fi param = frac of litter inputs bypassing litter pools + +Purpose and description of changes +---------------------------------- + + Summary from the PR: removes NPP control on turnover + fixes density dependent control on turnover + adds litterfall fluxes that bypass litter pools, directly contributing to SOM + + This PR also addresses the issue of varying microbial turnover with depth. + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[ ] clm6_0 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Fixes #2361 MIMICS todo list + Fixes #2248 Should microbial turnover vary with depth in MIMICS? + +Notes of particular relevance for users +--------------------------------------- +Changes made to namelist defaults (e.g., changed parameter values): + Updated values in the default mimics parameters + +Changes to the datasets (e.g., parameter, surface or initial files): + New parameter files + +Notes of particular relevance for developers: +--------------------------------------------- + +Testing summary: +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- + +Changes answers relative to baseline: Yes + + Summarize any changes to answers, i.e., + - what code configurations: MIMICS + - what platforms/compilers: All + - nature of change: Larger than roundoff/same climate + + Soil C stocks will change in mimics cases with these code and parameter updates. + + Also, three ciso_cwd_hr tests show diffs because the most recent previous ciso paramfile had roundoff diffs from the rest of the paramfiles for no reason that wwieder and slevis could identify. The new ciso paramfile does not have such diffs. + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/2365 MIMICS updates + +=============================================================== +=============================================================== Tag name: ctsm5.3.032 Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310) Date: Mon 17 Mar 2025 09:49:08 AM MDT diff --git a/doc/ChangeSum b/doc/ChangeSum index e3e6f0fb74..6e5f622cdd 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.3.033 multiple 03/19/2025 Add new mimics_fi param = frac of litter inputs bypassing litter pools ctsm5.3.032 slevis 03/17/2025 Add option to use CRUJRA2024 with clm6 and clm5 ctsm5.3.031 slevis 03/13/2025 Merge b4b-dev ctsm5.3.030 samrabin 03/07/2025 Fix FATES branch runs diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90 index 093e83172a..70f0b86a53 100644 --- a/src/biogeochem/CNCStateUpdate1Mod.F90 +++ b/src/biogeochem/CNCStateUpdate1Mod.F90 @@ -9,6 +9,7 @@ module CNCStateUpdate1Mod use clm_varpar , only : ndecomp_cascade_transitions, nlevdecomp use clm_time_manager , only : get_step_size_real use clm_varpar , only : i_litr_min, i_litr_max, i_cwd + use clm_varpar , only : i_met_lit, i_str_lit, i_phys_som, i_chem_som use pftconMod , only : npcropmin, nc3crop, pftcon use abortutils , only : endrun use decompMod , only : bounds_type @@ -17,7 +18,7 @@ module CNCStateUpdate1Mod use CropType , only : crop_type use CropReprPoolsMod , only : nrepr, repr_grain_min, repr_grain_max use CropReprPoolsMod , only : repr_structure_min, repr_structure_max - use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn + use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, decomp_method, mimics_decomp, use_soil_matrixcn use SoilBiogeochemCarbonFluxType , only : soilbiogeochem_carbonflux_type use SoilBiogeochemCarbonStateType , only : soilbiogeochem_carbonstate_type use PatchType , only : patch @@ -170,6 +171,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & associate( & ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + mimics_fi => pftcon%mimics_fi , & ! Input: MIMICS parameter fi woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) cascade_donor_pool => decomp_cascade_con%cascade_donor_pool , & ! Input: [integer (:) ] which pool is C taken from for a given decomposition step @@ -206,10 +208,21 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, & ! if (.not. use_soil_matrixcn) then ! phenology and dynamic land cover fluxes - do i = i_litr_min, i_litr_max - cf_soil%decomp_cpools_sourcesink_col(c,j,i) = & - cf_veg%phenology_c_to_litr_c_col(c,j,i) * dt - end do + if (decomp_method == mimics_decomp) then + do i = i_litr_min, i_litr_max ! in MIMICS these are 1 and 2 + cf_soil%decomp_cpools_sourcesink_col(c,j,i) = (1 - mimics_fi(i)) * & + cf_veg%phenology_c_to_litr_c_col(c,j,i) * dt + end do + cf_soil%decomp_cpools_sourcesink_col(c,j,i_phys_som) = mimics_fi(1) * & + cf_veg%phenology_c_to_litr_c_col(c,j,i_met_lit) * dt + cf_soil%decomp_cpools_sourcesink_col(c,j,i_chem_som) = mimics_fi(2) * & + cf_veg%phenology_c_to_litr_c_col(c,j,i_str_lit) * dt + else + do i = i_litr_min, i_litr_max + cf_soil%decomp_cpools_sourcesink_col(c,j,i) = & + cf_veg%phenology_c_to_litr_c_col(c,j,i) * dt + end do + end if ! NOTE(wjs, 2017-01-02) This used to be set to a non-zero value, but the ! terms have been moved to CStateUpdateDynPatch. I think this is zeroed every diff --git a/src/biogeochem/CNNStateUpdate1Mod.F90 b/src/biogeochem/CNNStateUpdate1Mod.F90 index 21b5d335b7..742afa77dd 100644 --- a/src/biogeochem/CNNStateUpdate1Mod.F90 +++ b/src/biogeochem/CNNStateUpdate1Mod.F90 @@ -12,8 +12,9 @@ module CNNStateUpdate1Mod use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevdecomp use clm_varpar , only : i_litr_min, i_litr_max, i_cwd + use clm_varpar , only : i_met_lit, i_str_lit, i_phys_som, i_chem_som use clm_varctl , only : iulog, use_nitrif_denitrif - use SoilBiogeochemDecompCascadeConType, only : use_soil_matrixcn + use SoilBiogeochemDecompCascadeConType, only : decomp_method, mimics_decomp, use_soil_matrixcn use CNSharedParamsMod , only : use_matrixcn use clm_varcon , only : nitrif_n2o_loss_frac use pftconMod , only : npcropmin, pftcon @@ -129,6 +130,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & associate( & ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type + mimics_fi => pftcon%mimics_fi , & ! Input: MIMICS parameter fi woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) nf_veg => cnveg_nitrogenflux_inst , & ! Input: @@ -163,10 +165,21 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & ! State update without the matrix solution ! if (.not. use_soil_matrixcn) then ! to be consistent with C - do i = i_litr_min, i_litr_max - nf_soil%decomp_npools_sourcesink_col(c,j,i) = & - nf_veg%phenology_n_to_litr_n_col(c,j,i) * dt - end do + if (decomp_method == mimics_decomp) then + do i = i_litr_min, i_litr_max ! in MIMICS these are 1 and 2 + nf_soil%decomp_npools_sourcesink_col(c,j,i) = (1 - mimics_fi(i)) * & + nf_veg%phenology_n_to_litr_n_col(c,j,i) * dt + end do + nf_soil%decomp_npools_sourcesink_col(c,j,i_phys_som) = mimics_fi(1) * & + nf_veg%phenology_n_to_litr_n_col(c,j,i_met_lit) * dt + nf_soil%decomp_npools_sourcesink_col(c,j,i_chem_som) = mimics_fi(2) * & + nf_veg%phenology_n_to_litr_n_col(c,j,i_str_lit) * dt + else + do i = i_litr_min, i_litr_max + nf_soil%decomp_npools_sourcesink_col(c,j,i) = & + nf_veg%phenology_n_to_litr_n_col(c,j,i) * dt + end do + end if ! NOTE(wjs, 2017-01-02) This used to be set to a non-zero value, but the ! terms have been moved to CStateUpdateDynPatch. I think this is zeroed every diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index 4456ab16af..9ac4b197a0 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -82,6 +82,9 @@ module clm_varpar integer, public :: i_litr_min = -9 ! min index of litter pools; overwritten in SoilBiogeochemDecompCascade*Mod integer, public :: i_litr_max = -9 ! max index of litter pools; overwritten in SoilBiogeochemDecompCascade*Mod integer, public :: i_met_lit = -9 ! index of metabolic litter pool; overwritten in SoilBiogeochemDecompCascade*Mod + integer, public :: i_str_lit = -9 ! index of structural litter pool; overwritten in SoilBiogeochemDecompCascade*Mod + integer, public :: i_phys_som = -9 ! index of physically protected Soil Organic Matter (SOM); overwritten in SoilBiogeochemDecompCascade*Mod + integer, public :: i_chem_som = -9 ! index of chemically protected Soil Organic Matter (SOM); overwritten in SoilBiogeochemDecompCascade*Mod integer, public :: i_cop_mic = -9 ! index of copiotrophic microbial pool; overwritten in SoilBiogeochemDecompCascade*Mod integer, public :: i_oli_mic = -9 ! index of oligotrophic microbial pool; overwritten in SoilBiogeochemDecompCascade*Mod integer, public :: i_cwd = -9 ! index of cwd pool; overwritten in SoilBiogeochemDecompCascade*Mod diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index b987879c03..b48ef92a43 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -165,6 +165,9 @@ module pftconMod real(r8), allocatable :: crit_onset_gdd_sf(:)! scale factor for crit_onset_gdd real(r8), allocatable :: ndays_on(:) ! number of days to complete leaf onset + ! MIMICS + real(r8), allocatable :: mimics_fi(:) + ! crop ! These arrays give information about the merge of unused crop types to the types CLM @@ -504,6 +507,7 @@ subroutine InitAllocate (this) allocate( this%taper (0:mxpft) ) allocate( this%rstem_per_dbh (0:mxpft) ) allocate( this%wood_density (0:mxpft) ) + allocate( this%mimics_fi(2) ) allocate( this%crit_onset_gdd_sf (0:mxpft) ) allocate( this%ndays_on (0:mxpft) ) @@ -1095,6 +1099,9 @@ subroutine InitRead(this) ! ! clm 5 nitrogen variables ! + call ncd_io('mimics_fi',this%mimics_fi, 'read', ncid, readvar=readv) + if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) + if (use_flexibleCN) then call ncd_io('i_vcad', this%i_vcad, 'read', ncid, readvar=readv) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) @@ -1132,6 +1139,7 @@ subroutine InitRead(this) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) call ncd_io('wood_density',this%wood_density, 'read', ncid, readvar=readv) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) + else this%dbh = 0.0_r8 this%fbw = 0.0_r8 @@ -1594,6 +1602,7 @@ subroutine Clean(this) deallocate( this%rstem_per_dbh) deallocate( this%wood_density) deallocate( this%taper) + deallocate( this%mimics_fi) deallocate( this%crit_onset_gdd_sf) deallocate( this%ndays_on) end subroutine Clean diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index e9bb60bcec..c9eb91bfa8 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -10,7 +10,7 @@ module SoilBiogeochemDecompCascadeMIMICSMod use shr_const_mod , only : SHR_CONST_TKFRZ use shr_log_mod , only : errMsg => shr_log_errMsg use clm_varpar , only : nlevdecomp, ndecomp_pools_max - use clm_varpar , only : i_met_lit, i_cop_mic, i_oli_mic, i_cwd + use clm_varpar , only : i_phys_som, i_chem_som, i_str_lit, i_met_lit, i_cop_mic, i_oli_mic, i_cwd use clm_varpar , only : i_litr_min, i_litr_max, i_cwdl2 use clm_varctl , only : iulog, spinup_state, anoxia, use_lch4, use_fates use clm_varcon , only : zsoi @@ -48,10 +48,7 @@ module SoilBiogeochemDecompCascadeMIMICSMod real(r8), private, allocatable :: fphys_m1(:,:) real(r8), private, allocatable :: fphys_m2(:,:) real(r8), private, allocatable :: p_scalar(:,:) - integer, private :: i_phys_som ! index of physically protected Soil Organic Matter (SOM) - integer, private :: i_chem_som ! index of chemically protected SOM integer, private :: i_avl_som ! index of available (aka active) SOM - integer, private :: i_str_lit ! index of structural litter pool integer, private :: i_l1m1 ! indices of transitions, eg l1m1: litter 1 -> first microbial pool integer, private :: i_l1m2 integer, private :: i_l2m1 @@ -1293,14 +1290,14 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, & decomp_k(c,j,i_chem_som) = (term_1 + term_2) * w_d_o_scalars ! Currently, mimics_densdep = 1 so as to have no effect - decomp_k(c,j,i_cop_mic) = tau_m1 * & - m1_conc**(mimics_densdep - 1.0_r8) * w_d_o_scalars + decomp_k(c,j,i_cop_mic) = tau_m1 * m1_conc**(mimics_densdep) + favl = min(1.0_r8, max(0.0_r8, 1.0_r8 - fphys_m1(c,j) - fchem_m1)) pathfrac_decomp_cascade(c,j,i_m1s1) = favl pathfrac_decomp_cascade(c,j,i_m1s2) = fchem_m1 - decomp_k(c,j,i_oli_mic) = tau_m2 * & - m2_conc**(mimics_densdep - 1.0_r8) * w_d_o_scalars + decomp_k(c,j,i_oli_mic) = tau_m2 * m2_conc**(mimics_densdep) + favl = min(1.0_r8, max(0.0_r8, 1.0_r8 - fphys_m2(c,j) - fchem_m2)) pathfrac_decomp_cascade(c,j,i_m2s1) = favl pathfrac_decomp_cascade(c,j,i_m2s2) = fchem_m2