From d5c1ed5e02cdad854d6e75bcb100588e7f7ed21f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 9 Feb 2022 16:18:14 -0700 Subject: [PATCH 01/27] Changes to get FATES and carbon_only tests pass with MIMICS active --- src/biogeochem/CNDriverMod.F90 | 1 + src/biogeochem/EDBGCDynMod.F90 | 1 + .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 70 +++++++++++++++++-- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index 45119a452a..534ba38002 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -320,6 +320,7 @@ subroutine CNDriverNoLeaching(bounds, soilstate_inst, temperature_inst, ch4_inst, soilbiogeochem_carbonflux_inst) else if (decomp_method == mimics_decomp) then call decomp_rates_mimics(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & soilstate_inst, temperature_inst, cnveg_carbonflux_inst, ch4_inst, & soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst) end if diff --git a/src/biogeochem/EDBGCDynMod.F90 b/src/biogeochem/EDBGCDynMod.F90 index 754f7ff4a0..c315410c2d 100644 --- a/src/biogeochem/EDBGCDynMod.F90 +++ b/src/biogeochem/EDBGCDynMod.F90 @@ -184,6 +184,7 @@ subroutine EDBGCDyn(bounds, & soilstate_inst, temperature_inst, ch4_inst, soilbiogeochem_carbonflux_inst) else if (decomp_method == mimics_decomp) then call decomp_rates_mimics(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & soilstate_inst, temperature_inst, cnveg_carbonflux_inst, ch4_inst, & soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst) end if diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 677aa4b04d..4196a0718b 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -752,6 +752,7 @@ end subroutine init_decompcascade_mimics !----------------------------------------------------------------------- subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & soilstate_inst, temperature_inst, cnveg_carbonflux_inst, & ch4_inst, soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst) ! @@ -763,9 +764,12 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & use clm_time_manager , only : get_curr_days_per_year use clm_varcon , only : secspday, secsphr, tfrz use clm_varcon , only : g_to_mg, cm3_to_m3 + use clm_varctl , only : cnallocate_carbon_only ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches integer , intent(in) :: num_soilc ! number of soil columns in filter integer , intent(in) :: filter_soilc(:) ! filter for soil columns type(soilstate_type) , intent(in) :: soilstate_inst @@ -846,13 +850,17 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & real(r8):: spinup_geogterm_s3(bounds%begc:bounds%endc) ! geographically-varying spinup term for s3 real(r8):: spinup_geogterm_m1(bounds%begc:bounds%endc) ! geographically-varying spinup term for m1 real(r8):: spinup_geogterm_m2(bounds%begc:bounds%endc) ! geographically-varying spinup term for m2 + real(r8):: ligninNratioAvg_local(bounds%begc:bounds%endc) ! local column-level lignin to nitrogen ratio + real(r8):: annsum_npp_col_local(bounds%begc:bounds%endc) ! local annual sum of NPP at the column level + real(r8):: ligninNratio(bounds%begp:bounds%endp) ! local patch-level lignin to nitrogen ratio + real(r8):: annsum_npp(bounds%begp:bounds%endp) ! local annual sum of NPP at the patch level + integer :: counter(bounds%begc:bounds%endc) ! local counter in loop + real(r8):: ligninNratioAvg_scalar ! lignin to nitrogen ratio, scalar in column-level loop + real(r8):: annsum_npp_col_scalar ! annual sum of NPP, scalar in column-level loop !----------------------------------------------------------------------- associate( & - ligninNratioAvg => cnveg_carbonflux_inst%ligninNratioAvg_col , & ! Input: [real(r8) (:) ] column-level lignin to nitrogen ratio - annsum_npp_col => cnveg_carbonflux_inst%annsum_npp_col , & ! Input: [real(r8) (:) ] annual sum of NPP at the column level (gC/m2/yr) - rf_cwdl2 => CNParamsShareInst%rf_cwdl2 , & ! Input: [real(r8) ] respiration fraction in CWD to litter2 transition (frac) minpsi => CNParamsShareInst%minpsi , & ! Input: [real(r8) ] minimum soil suction (mm) maxpsi => CNParamsShareInst%maxpsi , & ! Input: [real(r8) ] maximum soil suction (mm) @@ -1100,10 +1108,62 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & mimics_cn_r = params_inst%mimics_cn_r mimics_cn_k = params_inst%mimics_cn_k + ! Local column-level ligninNratioAvg and annsum_npp_col because these are + ! not available when use_fates = .true. or when carbon_only = .true. + if (use_fates .or. cnallocate_carbon_only()) then + ! Initialize + do fc = 1,num_soilc + c = filter_soilc(fc) + ligninNratioAvg_local(c) = 0._r8 + annsum_npp_col_local(c) = 0._r8 + counter(c) = 0 + end do + + ! Sum over p + ! TODO Not tested, yet +! do fp = 1, num_soilp + +! p = filter_soilp(fp) +! c = patch%column(p) + + ! TODO Obtain values by pft from + ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf + ! TODO Move values by pft to the params files? +! if (patch%itype(p) = noveg) then +! ligninNratio(p) = 0._r8 +! annsum_npp(p) = 0._r8 +! else if (patch%itype(p) = nbrdlf_evr_trp_tree) then +! ligninNratio(p) = +! annsum_npp(p) = +! else if (patch%itype(p) = ... +! end if + +! ligninNratioAvg_local(c) = ligninNratio(p) * patch%wtcol(p) + ligninNratioAvg_local(c) +! annsum_npp_col_local(c) = annsum_npp(p) * patch%wtcol(p) + annsum_npp_col_local(c) +! counter(c) = counter(c) + 1 + +! end do ! p loop + + ! Calculate the column-level averages +! do fc = 1,num_soilc +! c = filter_soilc(fc) +! ligninNratioAvg_local(c) = ligninNratioAvg_local(c) / counter(c) +! annsum_npp_col_local(c) = annsum_npp_col_local(c) / counter(c) +! end do + end if ! use_fates or carbon_only + ! calculate rates for all litter and som pools do fc = 1,num_soilc c = filter_soilc(fc) + if (use_fates .or. cnallocate_carbon_only()) then + ligninNratioAvg_scalar = ligninNratioAvg_local(c) + annsum_npp_col_scalar = annsum_npp_col_local(c) + else + ligninNratioAvg_scalar = cnveg_carbonflux_inst%ligninNratioAvg_col(c) + annsum_npp_col_scalar = cnveg_carbonflux_inst%annsum_npp_col(c) + end if + ! Time-dependent params from Wieder et al. 2015 & testbed code ! Set limits on Lignin:N to keep fmet > 0.2 @@ -1111,10 +1171,10 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! TODO Check for high-freq variations in ligninNratioAvg. To avoid, ! replace pool_to_litter terms with ann or other long term mean ! in CNVegCarbonFluxType. - fmet = mimics_fmet_p1 * (mimics_fmet_p2 - mimics_fmet_p3 * min(mimics_fmet_p4, ligninNratioAvg(c))) + fmet = mimics_fmet_p1 * (mimics_fmet_p2 - mimics_fmet_p3 * min(mimics_fmet_p4, ligninNratioAvg_scalar)) tau_mod = min(mimics_tau_mod_max, max(mimics_tau_mod_min, & sqrt(mimics_tau_mod_factor * & - annsum_npp_col(c)))) + annsum_npp_col_scalar))) ! tau_m1 is tauR and tau_m2 is tauK in Wieder et al. 2015 ! tau ends up in units of per hour but is expected From 28a0406ba603decaba342895543666700b047da0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 13 Feb 2022 18:25:33 -0700 Subject: [PATCH 02/27] Access the FATES copy of annsum_npp in FATES-MIMICS simulations --- src/biogeochem/CNDriverMod.F90 | 6 +- src/biogeochem/CNVegetationFacade.F90 | 6 +- src/biogeochem/EDBGCDynMod.F90 | 10 +-- src/main/clm_driver.F90 | 6 +- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 65 ++++++++++--------- 5 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index 534ba38002..ec54afea45 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -42,6 +42,7 @@ module CNDriverMod use SaturatedExcessRunoffMod , only : saturated_excess_runoff_type use ActiveLayerMod , only : active_layer_type use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type + use CLMFatesInterfaceMod , only : hlm_fates_interface_type ! ! !PUBLIC TYPES: implicit none @@ -95,7 +96,7 @@ subroutine CNDriverNoLeaching(bounds, c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_state_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - active_layer_inst, & + active_layer_inst, clm_fates, & atm2lnd_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, & wateratm2lndbulk_inst, canopystate_inst, soilstate_inst, temperature_inst, & soil_water_retention_curve, crop_inst, ch4_inst, & @@ -196,6 +197,7 @@ subroutine CNDriverNoLeaching(bounds, class(nutrient_competition_method_type) , intent(inout) :: nutrient_competition_method class(fire_method_type) , intent(inout) :: cnfire_method logical , intent(in) :: dribble_crophrv_xsmrpool_2atm + type(hlm_fates_interface_type) , intent(inout) :: clm_fates ! ! !LOCAL VARIABLES: real(r8):: cn_decomp_pools(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_pools) @@ -320,7 +322,7 @@ subroutine CNDriverNoLeaching(bounds, soilstate_inst, temperature_inst, ch4_inst, soilbiogeochem_carbonflux_inst) else if (decomp_method == mimics_decomp) then call decomp_rates_mimics(bounds, num_soilc, filter_soilc, & - num_soilp, filter_soilp, & + num_soilp, filter_soilp, clm_fates, & soilstate_inst, temperature_inst, cnveg_carbonflux_inst, ch4_inst, & soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst) end if diff --git a/src/biogeochem/CNVegetationFacade.F90 b/src/biogeochem/CNVegetationFacade.F90 index 457f5818ec..63af9162b8 100644 --- a/src/biogeochem/CNVegetationFacade.F90 +++ b/src/biogeochem/CNVegetationFacade.F90 @@ -95,6 +95,7 @@ module CNVegetationFacade use CNPrecisionControlMod , only: CNPrecisionControl use SoilBiogeochemPrecisionControlMod , only: SoilBiogeochemPrecisionControl use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type + use CLMFatesInterfaceMod , only : hlm_fates_interface_type ! implicit none private @@ -887,7 +888,7 @@ subroutine EcosystemDynamicsPreDrainage(this, bounds, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_state_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - active_layer_inst, & + active_layer_inst, clm_fates, & atm2lnd_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, & wateratm2lndbulk_inst, canopystate_inst, soilstate_inst, temperature_inst, & soil_water_retention_curve, crop_inst, ch4_inst, & @@ -942,6 +943,7 @@ subroutine EcosystemDynamicsPreDrainage(this, bounds, & type(energyflux_type) , intent(in) :: energyflux_inst class(nutrient_competition_method_type) , intent(inout) :: nutrient_competition_method type(fireemis_type) , intent(inout) :: fireemis_inst + type(hlm_fates_interface_type) , intent(inout) :: clm_fates ! ! !LOCAL VARIABLES: @@ -969,7 +971,7 @@ subroutine EcosystemDynamicsPreDrainage(this, bounds, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_state_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - active_layer_inst, & + active_layer_inst, clm_fates, & atm2lnd_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, & wateratm2lndbulk_inst, canopystate_inst, soilstate_inst, temperature_inst, & soil_water_retention_curve, crop_inst, ch4_inst, & diff --git a/src/biogeochem/EDBGCDynMod.F90 b/src/biogeochem/EDBGCDynMod.F90 index c315410c2d..43183b146b 100644 --- a/src/biogeochem/EDBGCDynMod.F90 +++ b/src/biogeochem/EDBGCDynMod.F90 @@ -27,6 +27,7 @@ module EDBGCDynMod use atm2lndType , only : atm2lnd_type use SoilStateType , only : soilstate_type use ch4Mod , only : ch4_type + use CLMFatesInterfaceMod , only : hlm_fates_interface_type ! public :: EDBGCDynInit ! BGC dynamics: initialization @@ -44,7 +45,7 @@ subroutine EDBGCDyn(bounds, & num_soilc, filter_soilc, num_soilp, filter_soilp, num_pcropp, filter_pcropp, doalb, & cnveg_carbonflux_inst, cnveg_carbonstate_inst, & soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst, & - soilbiogeochem_state_inst, & + soilbiogeochem_state_inst, clm_fates, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & c13_soilbiogeochem_carbonstate_inst, c13_soilbiogeochem_carbonflux_inst, & c14_soilbiogeochem_carbonstate_inst, c14_soilbiogeochem_carbonflux_inst, & @@ -108,6 +109,7 @@ subroutine EDBGCDyn(bounds, & type(temperature_type) , intent(inout) :: temperature_inst type(crop_type) , intent(in) :: crop_inst type(ch4_type) , intent(in) :: ch4_inst + type(hlm_fates_interface_type) , intent(inout) :: clm_fates ! ! !LOCAL VARIABLES: real(r8):: cn_decomp_pools(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_pools) @@ -184,7 +186,7 @@ subroutine EDBGCDyn(bounds, & soilstate_inst, temperature_inst, ch4_inst, soilbiogeochem_carbonflux_inst) else if (decomp_method == mimics_decomp) then call decomp_rates_mimics(bounds, num_soilc, filter_soilc, & - num_soilp, filter_soilp, & + num_soilp, filter_soilp, clm_fates, & soilstate_inst, temperature_inst, cnveg_carbonflux_inst, ch4_inst, & soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst) end if @@ -267,7 +269,7 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so c13_soilbiogeochem_carbonflux_inst, c13_soilbiogeochem_carbonstate_inst, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - clm_fates, nc) + nc) ! ! !DESCRIPTION: ! Call to all CN and SoilBiogeochem summary routines @@ -277,7 +279,6 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so use clm_varpar , only: ndecomp_cascade_transitions use CNPrecisionControlMod , only: CNPrecisionControl use SoilBiogeochemPrecisionControlMod , only: SoilBiogeochemPrecisionControl - use CLMFatesInterfaceMod , only: hlm_fates_interface_type ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -293,7 +294,6 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so type(soilbiogeochem_carbonstate_type) , intent(inout) :: c14_soilbiogeochem_carbonstate_inst type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst - type(hlm_fates_interface_type) , intent(inout) :: clm_fates integer , intent(in) :: nc ! thread index ! ! !LOCAL VARIABLES: diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index 132e58b02f..7c3f61ad89 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -992,7 +992,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_state_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - active_layer_inst, & + active_layer_inst, clm_fates, & atm2lnd_inst, water_inst%waterstatebulk_inst, & water_inst%waterdiagnosticbulk_inst, water_inst%waterfluxbulk_inst, & water_inst%wateratm2lndbulk_inst, canopystate_inst, soilstate_inst, temperature_inst, & @@ -1083,7 +1083,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro bgc_vegetation_inst%cnveg_carbonflux_inst, & bgc_vegetation_inst%cnveg_carbonstate_inst, & soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst, & - soilbiogeochem_state_inst, & + soilbiogeochem_state_inst, clm_fates, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & c13_soilbiogeochem_carbonstate_inst, c13_soilbiogeochem_carbonflux_inst, & c14_soilbiogeochem_carbonstate_inst, c14_soilbiogeochem_carbonflux_inst, & @@ -1097,7 +1097,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro c13_soilbiogeochem_carbonflux_inst, c13_soilbiogeochem_carbonstate_inst, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - clm_fates, nc) + nc) call clm_fates%wrap_update_hifrq_hist(bounds_clump, & soilbiogeochem_carbonflux_inst, & diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 4196a0718b..dd3c0a8ae2 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -29,6 +29,7 @@ module SoilBiogeochemDecompCascadeMIMICSMod use ColumnType , only : col use GridcellType , only : grc use SoilBiogeochemStateType , only : get_spinup_latitude_term + use CLMFatesInterfaceMod , only : hlm_fates_interface_type ! implicit none @@ -752,7 +753,7 @@ end subroutine init_decompcascade_mimics !----------------------------------------------------------------------- subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & - num_soilp, filter_soilp, & + num_soilp, filter_soilp, clm_fates, & soilstate_inst, temperature_inst, cnveg_carbonflux_inst, & ch4_inst, soilbiogeochem_carbonflux_inst, soilbiogeochem_carbonstate_inst) ! @@ -764,7 +765,8 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & use clm_time_manager , only : get_curr_days_per_year use clm_varcon , only : secspday, secsphr, tfrz use clm_varcon , only : g_to_mg, cm3_to_m3 - use clm_varctl , only : cnallocate_carbon_only + use subgridAveMod , only : p2c + use PatchType , only : patch ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -778,6 +780,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & type(ch4_type) , intent(in) :: ch4_inst type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst type(soilbiogeochem_carbonstate_type), intent(in) :: soilbiogeochem_carbonstate_inst + type(hlm_fates_interface_type) , intent(inout) :: clm_fates ! ! !LOCAL VARIABLES: real(r8), parameter :: eps = 1.e-6_r8 @@ -811,7 +814,9 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & real(r8):: term_2 ! real(r8):: t_soi_degC ! real(r8):: decomp_depth_efolding ! (meters) e-folding depth for reduction in decomposition [ - integer :: c, fc, j, k, l + integer :: p, fp, c, fc, j, k, l, s ! indices + integer :: pf ! fates patch index + integer :: nc ! clump index real(r8):: days_per_year ! days per year real(r8):: depth_scalar(bounds%begc:bounds%endc,1:nlevdecomp) real(r8):: w_d_o_scalars ! product of w_scalar * depth_scalar * o_scalar @@ -854,13 +859,13 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & real(r8):: annsum_npp_col_local(bounds%begc:bounds%endc) ! local annual sum of NPP at the column level real(r8):: ligninNratio(bounds%begp:bounds%endp) ! local patch-level lignin to nitrogen ratio real(r8):: annsum_npp(bounds%begp:bounds%endp) ! local annual sum of NPP at the patch level - integer :: counter(bounds%begc:bounds%endc) ! local counter in loop real(r8):: ligninNratioAvg_scalar ! lignin to nitrogen ratio, scalar in column-level loop real(r8):: annsum_npp_col_scalar ! annual sum of NPP, scalar in column-level loop !----------------------------------------------------------------------- associate( & + rf_cwdl2 => CNParamsShareInst%rf_cwdl2 , & ! Input: [real(r8) ] respiration fraction in CWD to litter2 transition (frac) minpsi => CNParamsShareInst%minpsi , & ! Input: [real(r8) ] minimum soil suction (mm) maxpsi => CNParamsShareInst%maxpsi , & ! Input: [real(r8) ] maximum soil suction (mm) @@ -1108,60 +1113,59 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & mimics_cn_r = params_inst%mimics_cn_r mimics_cn_k = params_inst%mimics_cn_k - ! Local column-level ligninNratioAvg and annsum_npp_col because these are - ! not available when use_fates = .true. or when carbon_only = .true. - if (use_fates .or. cnallocate_carbon_only()) then + ! Local column-level ligninNratioAvg because + ! not available when use_fates = .true. + ! Also get FATES copy of annsum_npp for FATES cases + if (use_fates) then ! Initialize do fc = 1,num_soilc c = filter_soilc(fc) ligninNratioAvg_local(c) = 0._r8 annsum_npp_col_local(c) = 0._r8 - counter(c) = 0 end do ! Sum over p - ! TODO Not tested, yet -! do fp = 1, num_soilp + nc = bounds%clump_index + do fp = 1, num_soilp + + p = filter_soilp(fp) + c = patch%column(p) -! p = filter_soilp(fp) -! c = patch%column(p) + pf = p - col%patchi(c) + s = clm_fates%f2hmap(nc)%hsites(c) + annsum_npp(p) = clm_fates%fates(nc)%bc_out(s)%annsum_npp_pa(pf) ! TODO Obtain values by pft from ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf ! TODO Move values by pft to the params files? ! if (patch%itype(p) = noveg) then -! ligninNratio(p) = 0._r8 -! annsum_npp(p) = 0._r8 + ligninNratio(p) = 0._r8 ! else if (patch%itype(p) = nbrdlf_evr_trp_tree) then ! ligninNratio(p) = -! annsum_npp(p) = ! else if (patch%itype(p) = ... ! end if -! ligninNratioAvg_local(c) = ligninNratio(p) * patch%wtcol(p) + ligninNratioAvg_local(c) -! annsum_npp_col_local(c) = annsum_npp(p) * patch%wtcol(p) + annsum_npp_col_local(c) -! counter(c) = counter(c) + 1 - -! end do ! p loop + end do ! p loop ! Calculate the column-level averages -! do fc = 1,num_soilc -! c = filter_soilc(fc) -! ligninNratioAvg_local(c) = ligninNratioAvg_local(c) / counter(c) -! annsum_npp_col_local(c) = annsum_npp_col_local(c) / counter(c) -! end do - end if ! use_fates or carbon_only + call p2c(bounds, num_soilc, filter_soilc, & + ligninNratio(bounds%begp:bounds%endp), & + ligninNratioAvg_local(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + annsum_npp(bounds%begp:bounds%endp), & + annsum_npp_col_local(bounds%begc:bounds%endc)) + end if ! use_fates ! calculate rates for all litter and som pools do fc = 1,num_soilc c = filter_soilc(fc) - if (use_fates .or. cnallocate_carbon_only()) then + if (use_fates) then ligninNratioAvg_scalar = ligninNratioAvg_local(c) - annsum_npp_col_scalar = annsum_npp_col_local(c) + annsum_npp_col_scalar = max(0._r8, annsum_npp_col_local(c)) else ligninNratioAvg_scalar = cnveg_carbonflux_inst%ligninNratioAvg_col(c) - annsum_npp_col_scalar = cnveg_carbonflux_inst%annsum_npp_col(c) + annsum_npp_col_scalar = max(0._r8, cnveg_carbonflux_inst%annsum_npp_col(c)) end if ! Time-dependent params from Wieder et al. 2015 & testbed code @@ -1173,8 +1177,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! in CNVegCarbonFluxType. fmet = mimics_fmet_p1 * (mimics_fmet_p2 - mimics_fmet_p3 * min(mimics_fmet_p4, ligninNratioAvg_scalar)) tau_mod = min(mimics_tau_mod_max, max(mimics_tau_mod_min, & - sqrt(mimics_tau_mod_factor * & - annsum_npp_col_scalar))) + sqrt(mimics_tau_mod_factor * annsum_npp_col_scalar))) ! tau_m1 is tauR and tau_m2 is tauK in Wieder et al. 2015 ! tau ends up in units of per hour but is expected From a16cc85ac5e7feb0b2c2f20a6ca23e3676237cb7 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 13 Feb 2022 22:03:27 -0700 Subject: [PATCH 03/27] Calc. ligninNratioAvg(c) from values by pft when use_fates = .true. Values by pft from Table 1 in Brovkin et al. (2012): https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf This hardwiring will become unnecessary when we calc. ligninNratioAvg the same way for FATES and non FATES cases. --- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 65 ++++++++++++++++--- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index dd3c0a8ae2..51f112adcf 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -767,6 +767,19 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & use clm_varcon , only : g_to_mg, cm3_to_m3 use subgridAveMod , only : p2c use PatchType , only : patch + use pftconMod , only : nmillet, nirrig_millet, & + nsorghum, nirrig_sorghum, & + nsugarcane, nirrig_sugarcane, & + ntmp_corn, nirrig_tmp_corn, & + ntrp_corn, nirrig_trp_corn, & + nswitchgrass, nirrig_switchgrass, & + nmiscanthus, nirrig_miscanthus, & + ndllf_evr_brl_tree, ndllf_dcd_brl_tree, & + nbrdlf_dcd_brl_tree, nbrdlf_dcd_brl_shrub, & + nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, & + nbrdlf_dcd_tmp_tree, nbrdlf_dcd_tmp_shrub, & + nbrdlf_evr_tmp_tree, nbrdlf_evr_shrub, & + ndllf_evr_tmp_tree, nc4_grass, noveg ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -1124,7 +1137,8 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & annsum_npp_col_local(c) = 0._r8 end do - ! Sum over p + ! Loop over p to get FATES copy of annsum_npp and local ligninNratio, + ! both for use_fates = .true. nc = bounds%clump_index do fp = 1, num_soilp @@ -1135,15 +1149,50 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & s = clm_fates%f2hmap(nc)%hsites(c) annsum_npp(p) = clm_fates%fates(nc)%bc_out(s)%annsum_npp_pa(pf) - ! TODO Obtain values by pft from + ! Values by pft from Table 1 in Brovkin et al. (2012): ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf - ! TODO Move values by pft to the params files? -! if (patch%itype(p) = noveg) then + ! TODO Move to the params files? Though this hardwiring will become + ! unnecessary when we calc. ligninNratioAvg the same way for FATES + ! and non FATES cases. + if (patch%itype(p) == noveg) then ligninNratio(p) = 0._r8 -! else if (patch%itype(p) = nbrdlf_evr_trp_tree) then -! ligninNratio(p) = -! else if (patch%itype(p) = ... -! end if + else if (patch%itype(p) == nbrdlf_evr_trp_tree) then + ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 + else if (patch%itype(p) == nbrdlf_dcd_trp_tree) then + ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 + else if (patch%itype(p) == ndllf_evr_tmp_tree) then + ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 + else if (patch%itype(p) == nbrdlf_evr_tmp_tree .or. & + patch%itype(p) == nbrdlf_evr_shrub) then + ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 + else if (patch%itype(p) == nbrdlf_dcd_tmp_tree .or. & + patch%itype(p) == nbrdlf_dcd_tmp_shrub) then + ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 + else if (patch%itype(p) == ndllf_evr_brl_tree .or. & + patch%itype(p) == ndllf_dcd_brl_tree) then + ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 + else if (patch%itype(p) == nbrdlf_dcd_brl_tree .or. & + patch%itype(p) == nbrdlf_dcd_brl_shrub) then + ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 + else if (patch%itype(p) == nc4_grass .or. & ! all c4 grasses/crops + patch%itype(p) == nmiscanthus .or. & + patch%itype(p) == nirrig_miscanthus .or. & + patch%itype(p) == nswitchgrass .or. & + patch%itype(p) == nirrig_switchgrass .or. & + patch%itype(p) == ntrp_corn .or. & + patch%itype(p) == nirrig_trp_corn .or. & + patch%itype(p) == ntmp_corn .or. & + patch%itype(p) == nirrig_tmp_corn .or. & + patch%itype(p) == nsugarcane .or. & + patch%itype(p) == nirrig_sugarcane .or. & + patch%itype(p) == nsorghum .or. & + patch%itype(p) == nirrig_sorghum .or. & + patch%itype(p) == nmillet .or. & + patch%itype(p) == nirrig_millet) then + ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 + else ! all c3 grasses/crops + pfts that do not fit above categories + ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 + end if end do ! p loop From 41802c2bc46849945e3b7920b8a46e1011c8d8a5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 15 Feb 2022 11:42:36 -0700 Subject: [PATCH 04/27] Check that FATES-MIMICS cases set use_lch4 = .true., else fail --- bld/CLMBuildNamelist.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 30809918ee..b02d9178af 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -901,6 +901,12 @@ sub setup_cmdl_bgc { $log->warning("$var normally use_nitrif_denitrif should only be FALSE if FATES is on, it has NOT been validated for being off for BGC mode" ); } } + # if MIMICS is on and use_fates = .true. then use_lch4 must = .true. + if ( (! &value_is_true($nl_flags->{'use_lch4'})) && &value_is_true($nl_flags->{'use_fates'}) ) { + if ( $soil_decomp_method eq "MIMICSWieder2015" ) { + $log->warning("If MIMICS is on and use_fates = .true. then use_lch4 must be .true. and currently it's not" ); + } + } } # # Set FUN for BGC From bea8e4ada145f8630567dd42a671081b1b2e9c03 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 25 Feb 2022 12:41:22 -0700 Subject: [PATCH 05/27] Replaced if-statement with select case statement as per EK's review Not tested; I will post info about testing next. --- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 50 +++++++------------ 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 51f112adcf..1a4f8959f4 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -1151,48 +1151,34 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! Values by pft from Table 1 in Brovkin et al. (2012): ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf - ! TODO Move to the params files? Though this hardwiring will become - ! unnecessary when we calc. ligninNratioAvg the same way for FATES - ! and non FATES cases. - if (patch%itype(p) == noveg) then + ! Not moving to the params files at this time: Hardwiring will + ! become unnecessary when we calc. ligninNratioAvg the same way for + ! FATES and non FATES cases. + select case (patch%itype(p)) + case (noveg) ligninNratio(p) = 0._r8 - else if (patch%itype(p) == nbrdlf_evr_trp_tree) then + case (nbrdlf_evr_trp_tree) ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 - else if (patch%itype(p) == nbrdlf_dcd_trp_tree) then + case (nbrdlf_dcd_trp_tree) ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 - else if (patch%itype(p) == ndllf_evr_tmp_tree) then + case (ndllf_evr_tmp_tree) ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 - else if (patch%itype(p) == nbrdlf_evr_tmp_tree .or. & - patch%itype(p) == nbrdlf_evr_shrub) then + case (nbrdlf_evr_tmp_tree, nbrdlf_evr_shrub) ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 - else if (patch%itype(p) == nbrdlf_dcd_tmp_tree .or. & - patch%itype(p) == nbrdlf_dcd_tmp_shrub) then + case (nbrdlf_dcd_tmp_tree, nbrdlf_dcd_tmp_shrub) ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 - else if (patch%itype(p) == ndllf_evr_brl_tree .or. & - patch%itype(p) == ndllf_dcd_brl_tree) then + case (ndllf_evr_brl_tree, ndllf_dcd_brl_tree) ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 - else if (patch%itype(p) == nbrdlf_dcd_brl_tree .or. & - patch%itype(p) == nbrdlf_dcd_brl_shrub) then + case (nbrdlf_dcd_brl_tree, nbrdlf_dcd_brl_shrub) ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 - else if (patch%itype(p) == nc4_grass .or. & ! all c4 grasses/crops - patch%itype(p) == nmiscanthus .or. & - patch%itype(p) == nirrig_miscanthus .or. & - patch%itype(p) == nswitchgrass .or. & - patch%itype(p) == nirrig_switchgrass .or. & - patch%itype(p) == ntrp_corn .or. & - patch%itype(p) == nirrig_trp_corn .or. & - patch%itype(p) == ntmp_corn .or. & - patch%itype(p) == nirrig_tmp_corn .or. & - patch%itype(p) == nsugarcane .or. & - patch%itype(p) == nirrig_sugarcane .or. & - patch%itype(p) == nsorghum .or. & - patch%itype(p) == nirrig_sorghum .or. & - patch%itype(p) == nmillet .or. & - patch%itype(p) == nirrig_millet) then + case (nc4_grass, nmiscanthus, nirrig_miscanthus, nswitchgrass, & + nirrig_switchgrass, ntrp_corn, nirrig_trp_corn, ntmp_corn, & + nirrig_tmp_corn, nsugarcane, nirrig_sugarcane, nsorghum, & + nirrig_sorghum, nmillet, nirrig_millet) ! all c4 plants ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 - else ! all c3 grasses/crops + pfts that do not fit above categories + case default ! all pfts/cfts that do not fit above categories ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 - end if + end select end do ! p loop From c0747afddaca4bfa6771cc654d2028499eae4a0b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 25 Feb 2022 15:21:28 -0700 Subject: [PATCH 06/27] Get select case statmt to compile by changing case options to constants --- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index c0031ff2cc..1c1b9e8a4e 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -767,19 +767,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & use clm_varcon , only : g_to_mg, cm3_to_m3 use subgridAveMod , only : p2c use PatchType , only : patch - use pftconMod , only : nmillet, nirrig_millet, & - nsorghum, nirrig_sorghum, & - nsugarcane, nirrig_sugarcane, & - ntmp_corn, nirrig_tmp_corn, & - ntrp_corn, nirrig_trp_corn, & - nswitchgrass, nirrig_switchgrass, & - nmiscanthus, nirrig_miscanthus, & - ndllf_evr_brl_tree, ndllf_dcd_brl_tree, & - nbrdlf_dcd_brl_tree, nbrdlf_dcd_brl_shrub, & - nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, & - nbrdlf_dcd_tmp_tree, nbrdlf_dcd_tmp_shrub, & - nbrdlf_evr_tmp_tree, nbrdlf_evr_shrub, & - ndllf_evr_tmp_tree, nc4_grass, noveg + use pftconMod , only : pftname ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -1154,30 +1142,37 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! Not moving to the params files at this time: Hardwiring will ! become unnecessary when we calc. ligninNratioAvg the same way for ! FATES and non FATES cases. - select case (patch%itype(p)) - case (noveg) - ligninNratio(p) = 0._r8 - case (nbrdlf_evr_trp_tree) - ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 - case (nbrdlf_dcd_trp_tree) - ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 - case (ndllf_evr_tmp_tree) - ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 - case (nbrdlf_evr_tmp_tree, nbrdlf_evr_shrub) - ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 - case (nbrdlf_dcd_tmp_tree, nbrdlf_dcd_tmp_shrub) - ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 - case (ndllf_evr_brl_tree, ndllf_dcd_brl_tree) - ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 - case (nbrdlf_dcd_brl_tree, nbrdlf_dcd_brl_shrub) - ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 - case (nc4_grass, nmiscanthus, nirrig_miscanthus, nswitchgrass, & - nirrig_switchgrass, ntrp_corn, nirrig_trp_corn, ntmp_corn, & - nirrig_tmp_corn, nsugarcane, nirrig_sugarcane, nsorghum, & - nirrig_sorghum, nmillet, nirrig_millet) ! all c4 plants - ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 - case default ! all pfts/cfts that do not fit above categories - ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 + select case (pftname(patch%itype(p))) + case ('not_vegetated') + ligninNratio(p) = 0._r8 + case ('broadleaf_evergreen_tropical_tree') + ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 + case ('broadleaf_deciduous_tropical_tree') + ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 + case ('needleleaf_evergreen_temperate_tree') + ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 + case ('broadleaf_evergreen_temperate_tree', & + 'broadleaf_evergreen_shrub') + ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 + case ('broadleaf_deciduous_temperate_tree', & + 'broadleaf_deciduous_temperate_shrub') + ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 + case ('needleleaf_evergreen_boreal_tree', & + 'needleleaf_deciduous_boreal_tree') + ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 + case ('broadleaf_deciduous_boreal_tree', & + 'broadleaf_deciduous_boreal_shrub') + ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 + case ('c4_grass', 'miscanthus', 'irrigated_miscanthus', & + 'switchgrass', 'irrigated_switchgrass', & + 'tropical_corn', 'irrigated_tropical_corn', & + 'temperate_corn', 'irrigated_temperate_corn', & + 'sugarcane', 'irrigated_sugarcane', & + 'sorghum', 'irrigated_sorghum', & + 'millet', 'irrigated_millet') ! all c4 + ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 + case default ! all pfts/cfts that do not fit above categories + ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 end select end do ! p loop From 098e86f3b8e8e8cd01c443090c647b95da179549 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 25 Feb 2022 17:59:55 -0700 Subject: [PATCH 07/27] Update Fates testmod to run w MIMICS. First draft of ChangeLog updates. --- cime_config/testdefs/testlist_clm.xml | 8 +- .../include_user_mods | 1 + .../user_nl_clm | 0 doc/ChangeLog | 80 +++++++++++++++++++ doc/ChangeSum | 1 + 5 files changed, 86 insertions(+), 4 deletions(-) rename cime_config/testdefs/testmods_dirs/clm/{FatesColdDefSizeAgeMort => mimicsFatesColdDefSizeAgeMort}/include_user_mods (61%) rename cime_config/testdefs/testmods_dirs/clm/{FatesColdDefSizeAgeMort => mimicsFatesColdDefSizeAgeMort}/user_nl_clm (100%) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 9c32bd09d1..bf06bc2c43 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2033,13 +2033,13 @@ - + - + @@ -2342,14 +2342,14 @@ - + - + diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/include_user_mods similarity index 61% rename from cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods rename to cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/include_user_mods index 1f2c03aebe..d24a9168fa 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/include_user_mods @@ -1 +1,2 @@ ../FatesColdDef +../mimics diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/user_nl_clm similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/user_nl_clm rename to cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/user_nl_clm diff --git a/doc/ChangeLog b/doc/ChangeLog index 4aa053c9cb..cb7ceabeaa 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,84 @@ =============================================================== +Tag name: ctsm5.1.dev083 +Originator(s): slevis (Samuel Levis) +Date: Fri Feb 25 17:23:32 MST 2022 +One-line Summary: Get FATES-MIMICS to work + +Purpose and description of changes +---------------------------------- + + 1) FATES didn't have access to the ligninNratioAvg calculated for MIMICS. + I updated MIMICS to assign hardwired values of ligninNratioAvg from Table 1 in + Brovkin et al. (2012) when running with FATES: + https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf + This is a temporary solution until FATES gets updated to have access to + the same ligninNratioAvg calculation as non FATES cases. + + 2) FATES has it's own calculation of annsum_npp_col, also needed in MIMICS. + I updated MIMICS to use the FATES variable when running with FATES. + + +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.] + +[ ] clm5_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed or introduced +------------------------ +Issues fixed (include CTSM Issue #): #1636 + + +Notes of particular relevance for users +--------------------------------------- +Caveats for users (e.g., need to interpolate initial conditions): + MIMICS-FATES now do work together, but only as long as use_lch4 = .true. + + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + To avoid adding a new test to confirm that MIMICS-FATES works, I modified the + existing testmod FatesColdDefSizeAgeMort to mimicsFatesColdDefSizeAgeMort. + I picked this one because it seems to be used in one test (maybe two?), while + other Fates testmods are used in many more tests. + + +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): + + cheyenne ---- + izumi ------- + + +Answer changes +-------------- + +Changes answers relative to baseline: NO + + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/1643 + +=============================================================== +=============================================================== Tag name: ctsm5.1.dev081 Originator(s): swensosc (Sean Swenson) Date: Thu Feb 24 21:33:35 MST 2022 diff --git a/doc/ChangeSum b/doc/ChangeSum index 146f690647..5c4df37b3e 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.1.dev083 slevis 02/25/2022 Get FATES-MIMICS to work ctsm5.1.dev081 swensosc 02/24/2022 Do not subtract irrigation from QRUNOFF diagnostic ctsm5.1.dev080 sacks 02/24/2022 Use avg days per year when converting param units ctsm5.1.dev079 sacks 02/24/2022 Changes to CropPhenology timing From 86d18b21ba06e23d0af60ec3b548780abe285f9a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 25 Feb 2022 18:45:32 -0700 Subject: [PATCH 08/27] Update ChangeLog with test-suite results cheyenne PASS izumi OK --- doc/ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index cb7ceabeaa..c94be60869 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -62,8 +62,8 @@ Testing summary: regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): - cheyenne ---- - izumi ------- + cheyenne ---- PASS + izumi ------- OK Answer changes From e52992c790006c96d9e7e0e6c0727f61a9415369 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 12 Mar 2022 18:08:06 -0700 Subject: [PATCH 09/27] Error check in the fortran to ensure MIMICS-FATES sets use_lch4 = .true. --- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 1c1b9e8a4e..dce35266a6 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -1116,8 +1116,9 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! Local column-level ligninNratioAvg because ! not available when use_fates = .true. - ! Also get FATES copy of annsum_npp for FATES cases - if (use_fates) then + ! Also get FATES copy of annsum_npp for FATES cases, which is available + ! only when use_lch4 = .true. at the same time. + if (use_fates .and. use_lch4) then ! Initialize do fc = 1,num_soilc c = filter_soilc(fc) @@ -1184,6 +1185,10 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & call p2c(bounds, num_soilc, filter_soilc, & annsum_npp(bounds%begp:bounds%endp), & annsum_npp_col_local(bounds%begc:bounds%endc)) + else + call endrun(msg='ERROR: soil_decomp_method = "MIMICSWieder2015 '// & + 'will work with use_fates = .true. only if use_lch4 = .true. ' & + errMsg(sourcefile, __LINE__)) end if ! use_fates ! calculate rates for all litter and som pools From d95a71623115455b223e3aa5387a646045dc757c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 12 Mar 2022 18:27:50 -0700 Subject: [PATCH 10/27] Reverted my mods to FATES test and added new FATES test --- cime_config/testdefs/testlist_clm.xml | 17 +++++++++++++---- .../include_user_mods | 0 .../user_nl_clm | 0 .../clm/mimicsFatesColdDef/include_user_mods | 2 ++ .../clm/mimicsFatesColdDef/shell_commands | 1 + 5 files changed, 16 insertions(+), 4 deletions(-) rename cime_config/testdefs/testmods_dirs/clm/{mimicsFatesColdDefSizeAgeMort => FatesColdDefSizeAgeMort}/include_user_mods (100%) rename cime_config/testdefs/testmods_dirs/clm/{mimicsFatesColdDefSizeAgeMort => FatesColdDefSizeAgeMort}/user_nl_clm (100%) create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/shell_commands diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index bf06bc2c43..86a1efe37d 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2033,13 +2033,22 @@ - + - + + + + + + + + + + @@ -2342,14 +2351,14 @@ - + - + diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/include_user_mods rename to cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/user_nl_clm similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDefSizeAgeMort/user_nl_clm rename to cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/include_user_mods new file mode 100644 index 0000000000..0194535a44 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/include_user_mods @@ -0,0 +1,2 @@ +../Fates +../mimics diff --git a/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/shell_commands b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/shell_commands new file mode 100644 index 0000000000..2a9f09bd75 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/mimicsFatesColdDef/shell_commands @@ -0,0 +1 @@ +./xmlchange CLM_FORCE_COLDSTART="on" From a8057f9859b69173c336c78f0db4b2f6814d3a04 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 12 Mar 2022 18:47:28 -0700 Subject: [PATCH 11/27] Update ChangeLog about my mods to the tests (see previous commit) --- doc/ChangeLog | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index c94be60869..2d8772f10b 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -49,10 +49,7 @@ Caveats for users (e.g., need to interpolate initial conditions): Notes of particular relevance for developers: --------------------------------------------- Changes to tests or testing: - To avoid adding a new test to confirm that MIMICS-FATES works, I modified the - existing testmod FatesColdDefSizeAgeMort to mimicsFatesColdDefSizeAgeMort. - I picked this one because it seems to be used in one test (maybe two?), while - other Fates testmods are used in many more tests. + To confirm that MIMICS-FATES works, I added the testmod mimicsFatesColdDef. Testing summary: From 04383047fa0d94af1ce8bce7e0282e01e162ab87 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 18 Mar 2022 12:24:28 -0600 Subject: [PATCH 12/27] Added fates_and_lch4_if: construct around if statement for clarity --- src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index dce35266a6..9a999d03e8 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -1118,7 +1118,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! not available when use_fates = .true. ! Also get FATES copy of annsum_npp for FATES cases, which is available ! only when use_lch4 = .true. at the same time. - if (use_fates .and. use_lch4) then + fates_and_lch4_if: if (use_fates .and. use_lch4) then ! Initialize do fc = 1,num_soilc c = filter_soilc(fc) @@ -1189,7 +1189,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & call endrun(msg='ERROR: soil_decomp_method = "MIMICSWieder2015 '// & 'will work with use_fates = .true. only if use_lch4 = .true. ' & errMsg(sourcefile, __LINE__)) - end if ! use_fates + end if fates_and_lch4_if ! calculate rates for all litter and som pools do fc = 1,num_soilc From ffa084a43187418a5c486b2a8e10c61eb5b175ec Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 4 Apr 2022 16:31:22 -0600 Subject: [PATCH 13/27] Made the fates_and_lch4_if into nested if statements for clearer code ...in the process of correcting the corresponding else that triggers an error and aborts --- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 142 +++++++++--------- 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 9a999d03e8..8debe1c8c0 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -1118,78 +1118,80 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! not available when use_fates = .true. ! Also get FATES copy of annsum_npp for FATES cases, which is available ! only when use_lch4 = .true. at the same time. - fates_and_lch4_if: if (use_fates .and. use_lch4) then - ! Initialize - do fc = 1,num_soilc - c = filter_soilc(fc) - ligninNratioAvg_local(c) = 0._r8 - annsum_npp_col_local(c) = 0._r8 - end do + fates_if: if (use_fates) then + lch4_if: if (use_lch4) then + ! Initialize + do fc = 1,num_soilc + c = filter_soilc(fc) + ligninNratioAvg_local(c) = 0._r8 + annsum_npp_col_local(c) = 0._r8 + end do - ! Loop over p to get FATES copy of annsum_npp and local ligninNratio, - ! both for use_fates = .true. - nc = bounds%clump_index - do fp = 1, num_soilp - - p = filter_soilp(fp) - c = patch%column(p) - - pf = p - col%patchi(c) - s = clm_fates%f2hmap(nc)%hsites(c) - annsum_npp(p) = clm_fates%fates(nc)%bc_out(s)%annsum_npp_pa(pf) - - ! Values by pft from Table 1 in Brovkin et al. (2012): - ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf - ! Not moving to the params files at this time: Hardwiring will - ! become unnecessary when we calc. ligninNratioAvg the same way for - ! FATES and non FATES cases. - select case (pftname(patch%itype(p))) - case ('not_vegetated') - ligninNratio(p) = 0._r8 - case ('broadleaf_evergreen_tropical_tree') - ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 - case ('broadleaf_deciduous_tropical_tree') - ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 - case ('needleleaf_evergreen_temperate_tree') - ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 - case ('broadleaf_evergreen_temperate_tree', & - 'broadleaf_evergreen_shrub') - ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 - case ('broadleaf_deciduous_temperate_tree', & - 'broadleaf_deciduous_temperate_shrub') - ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 - case ('needleleaf_evergreen_boreal_tree', & - 'needleleaf_deciduous_boreal_tree') - ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 - case ('broadleaf_deciduous_boreal_tree', & - 'broadleaf_deciduous_boreal_shrub') - ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 - case ('c4_grass', 'miscanthus', 'irrigated_miscanthus', & - 'switchgrass', 'irrigated_switchgrass', & - 'tropical_corn', 'irrigated_tropical_corn', & - 'temperate_corn', 'irrigated_temperate_corn', & - 'sugarcane', 'irrigated_sugarcane', & - 'sorghum', 'irrigated_sorghum', & - 'millet', 'irrigated_millet') ! all c4 - ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 - case default ! all pfts/cfts that do not fit above categories - ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 - end select - - end do ! p loop - - ! Calculate the column-level averages - call p2c(bounds, num_soilc, filter_soilc, & - ligninNratio(bounds%begp:bounds%endp), & - ligninNratioAvg_local(bounds%begc:bounds%endc)) - call p2c(bounds, num_soilc, filter_soilc, & - annsum_npp(bounds%begp:bounds%endp), & - annsum_npp_col_local(bounds%begc:bounds%endc)) - else - call endrun(msg='ERROR: soil_decomp_method = "MIMICSWieder2015 '// & - 'will work with use_fates = .true. only if use_lch4 = .true. ' & + ! Loop over p: get FATES copy of annsum_npp and local ligninNratio, + ! both for use_fates = .true. + nc = bounds%clump_index + do fp = 1, num_soilp + + p = filter_soilp(fp) + c = patch%column(p) + + pf = p - col%patchi(c) + s = clm_fates%f2hmap(nc)%hsites(c) + annsum_npp(p) = clm_fates%fates(nc)%bc_out(s)%annsum_npp_pa(pf) + + ! Values by pft from Table 1 in Brovkin et al. (2012): + ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf + ! Not moving to the params files at this time: Hardwiring will + ! become unnec. when we calc. ligninNratioAvg the same way for + ! FATES and non FATES cases. + select case (pftname(patch%itype(p))) + case ('not_vegetated') + ligninNratio(p) = 0._r8 + case ('broadleaf_evergreen_tropical_tree') + ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 + case ('broadleaf_deciduous_tropical_tree') + ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 + case ('needleleaf_evergreen_temperate_tree') + ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 + case ('broadleaf_evergreen_temperate_tree', & + 'broadleaf_evergreen_shrub') + ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 + case ('broadleaf_deciduous_temperate_tree', & + 'broadleaf_deciduous_temperate_shrub') + ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 + case ('needleleaf_evergreen_boreal_tree', & + 'needleleaf_deciduous_boreal_tree') + ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 + case ('broadleaf_deciduous_boreal_tree', & + 'broadleaf_deciduous_boreal_shrub') + ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 + case ('c4_grass', 'miscanthus', 'irrigated_miscanthus', & + 'switchgrass', 'irrigated_switchgrass', & + 'tropical_corn', 'irrigated_tropical_corn', & + 'temperate_corn', 'irrigated_temperate_corn', & + 'sugarcane', 'irrigated_sugarcane', & + 'sorghum', 'irrigated_sorghum', & + 'millet', 'irrigated_millet') ! all c4 + ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 + case default ! all pfts/cfts that do not fit above categories + ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 + end select + + end do ! p loop + + ! Calculate the column-level averages + call p2c(bounds, num_soilc, filter_soilc, & + ligninNratio(bounds%begp:bounds%endp), & + ligninNratioAvg_local(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + annsum_npp(bounds%begp:bounds%endp), & + annsum_npp_col_local(bounds%begc:bounds%endc)) + else + call endrun(msg='ERROR: soil_decomp_method = MIMICSWieder2015 '// & + 'will work with use_fates = .true. only if use_lch4 = .true. '// & errMsg(sourcefile, __LINE__)) - end if fates_and_lch4_if + end if lch4_if + end if fates_if ! calculate rates for all litter and som pools do fc = 1,num_soilc From 50f4af3ad0a33e0842ec12a2e893e79e60bacd5a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 25 Apr 2022 12:38:31 -0600 Subject: [PATCH 14/27] Update FATES-MIMICS to use FATES copy of ligninNratio Test runs but COMPARE_base_rest fails: ERS_Ld30.f45_f45_mg37.I2000Clm50FatesRs.cheyenne_intel.clm-mimicsFatesColdDef --- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 49 ++----------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 8debe1c8c0..d629d6f5af 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -1114,10 +1114,9 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & mimics_cn_r = params_inst%mimics_cn_r mimics_cn_k = params_inst%mimics_cn_k - ! Local column-level ligninNratioAvg because - ! not available when use_fates = .true. - ! Also get FATES copy of annsum_npp for FATES cases, which is available - ! only when use_lch4 = .true. at the same time. + ! Local column-level annsum_npp and ligninNratioAvg. + ! Use FATES copies of both variables for FATES-MIMICS cases. + ! The FATES copy of annsum_npp is available when also use_lch4 = .true. fates_if: if (use_fates) then lch4_if: if (use_lch4) then ! Initialize @@ -1127,8 +1126,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & annsum_npp_col_local(c) = 0._r8 end do - ! Loop over p: get FATES copy of annsum_npp and local ligninNratio, - ! both for use_fates = .true. + ! Loop over p: get FATES copies of annsum_npp & local ligninNratio nc = bounds%clump_index do fp = 1, num_soilp @@ -1138,44 +1136,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & pf = p - col%patchi(c) s = clm_fates%f2hmap(nc)%hsites(c) annsum_npp(p) = clm_fates%fates(nc)%bc_out(s)%annsum_npp_pa(pf) - - ! Values by pft from Table 1 in Brovkin et al. (2012): - ! https://bg.copernicus.org/articles/9/565/2012/bg-9-565-2012.pdf - ! Not moving to the params files at this time: Hardwiring will - ! become unnec. when we calc. ligninNratioAvg the same way for - ! FATES and non FATES cases. - select case (pftname(patch%itype(p))) - case ('not_vegetated') - ligninNratio(p) = 0._r8 - case ('broadleaf_evergreen_tropical_tree') - ligninNratio(p) = 18.7_r8 ! 17.8 / 0.95 - case ('broadleaf_deciduous_tropical_tree') - ligninNratio(p) = 8.9_r8 ! 14.5 / 1.63 - case ('needleleaf_evergreen_temperate_tree') - ligninNratio(p) = 33.4_r8 ! 24.4 / 0.73 - case ('broadleaf_evergreen_temperate_tree', & - 'broadleaf_evergreen_shrub') - ligninNratio(p) = 24.4_r8 ! 21.0 / 0.86 - case ('broadleaf_deciduous_temperate_tree', & - 'broadleaf_deciduous_temperate_shrub') - ligninNratio(p) = 16.6_r8 ! 16.9 / 1.02 - case ('needleleaf_evergreen_boreal_tree', & - 'needleleaf_deciduous_boreal_tree') - ligninNratio(p) = 26.7_r8 ! 25.6 / 0.96 - case ('broadleaf_deciduous_boreal_tree', & - 'broadleaf_deciduous_boreal_shrub') - ligninNratio(p) = 25.1_r8 ! 22.3 / 0.89 - case ('c4_grass', 'miscanthus', 'irrigated_miscanthus', & - 'switchgrass', 'irrigated_switchgrass', & - 'tropical_corn', 'irrigated_tropical_corn', & - 'temperate_corn', 'irrigated_temperate_corn', & - 'sugarcane', 'irrigated_sugarcane', & - 'sorghum', 'irrigated_sorghum', & - 'millet', 'irrigated_millet') ! all c4 - ligninNratio(p) = 24.1_r8 ! 23.4 / 0.97 - case default ! all pfts/cfts that do not fit above categories - ligninNratio(p) = 12.1_r8 ! 16.6 / 1.37 - end select + ligninNratio(p) = clm_fates%fates(nc)%bc_out(s)%litt_flux_ligc_per_n(pf) end do ! p loop From 922aaf2e890b70776b00011381b416868510b86c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 25 Apr 2022 13:35:50 -0600 Subject: [PATCH 15/27] Revert a testmod change I had made for testing FATES-MIMICS I had mostly reverted the corresponding test to how it was before this PR but had missed this... --- .../testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods | 1 - 1 file changed, 1 deletion(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods index d24a9168fa..1f2c03aebe 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdDefSizeAgeMort/include_user_mods @@ -1,2 +1 @@ ../FatesColdDef -../mimics From dd240188bf23f3ae067e58e44aa45ac03d2e58ba Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 25 Apr 2022 18:33:38 -0600 Subject: [PATCH 16/27] Corrected to receive FATES variable litt_flux_ligc_per_n as site level This eliminates the need for changes on the FATES side and it also eliminates the restart test failure. --- src/main/clm_initializeMod.F90 | 2 +- src/main/clm_instMod.F90 | 3 +- .../SoilBiogeochemCarbonFluxType.F90 | 4 +++ .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 34 ++++++++----------- src/utils/clmfates_interfaceMod.F90 | 29 ++++++++++++---- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 73ec4ffd58..0d4407c689 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -646,7 +646,7 @@ subroutine initialize2(ni,nj) end if call clm_fates%init_coldstart(water_inst%waterstatebulk_inst, & water_inst%waterdiagnosticbulk_inst, canopystate_inst, & - soilstate_inst) + soilstate_inst, soilbiogeochem_carbonflux_inst) end if ! topo_glc_mec was allocated in initialize1, but needed to be kept around through diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index a593664217..eda8df8c7c 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -591,7 +591,8 @@ subroutine clm_instRest(bounds, ncid, flag, writing_finidat_interp_dest_file) waterstatebulk_inst=water_inst%waterstatebulk_inst, & canopystate_inst=canopystate_inst, & soilstate_inst=soilstate_inst, & - active_layer_inst=active_layer_inst) + active_layer_inst=active_layer_inst, & + soilbiogeochem_carbonflux_inst=soilbiogeochem_carbonflux_inst) end if diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index 343c30eb42..c9480ea175 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -31,6 +31,7 @@ module SoilBiogeochemCarbonFluxType real(r8), pointer :: decomp_cascade_ctransfer_vr_col (:,:,:) ! vertically-resolved C transferred along deomposition cascade (gC/m3/s) real(r8), pointer :: decomp_cascade_ctransfer_col (:,:) ! vertically-integrated (diagnostic) C transferred along decomposition cascade (gC/m2/s) real(r8), pointer :: cn_col (:,:) ! (gC/gN) C:N ratio by pool + real(r8), pointer :: litr_lig_c_to_n_col (:) ! (gC/gN) lignin C:N ratio; FATES equivalent of cnveg_carbonflux_inst%ligninNratioAvg_col because FATES doesn't have access to cnveg_carbonflux_inst; could reduce duplication by consolidating cnveg_carbonflux_inst%ligninNratioAvg_col into this one real(r8), pointer :: rf_decomp_cascade_col (:,:,:) ! (frac) respired fraction in decomposition step real(r8), pointer :: pathfrac_decomp_cascade_col (:,:,:) ! (frac) what fraction of C passes from donor to receiver pool through a given transition real(r8), pointer :: decomp_k_col (:,:,:) ! rate coefficient for decomposition (1./sec) @@ -131,6 +132,8 @@ subroutine InitAllocate(this, bounds) allocate(this%cn_col(begc:endc,1:ndecomp_pools)) this%cn_col(:,:)= spval + allocate(this%litr_lig_c_to_n_col(begc:endc)) + this%litr_lig_c_to_n_col(:)= spval allocate(this%rf_decomp_cascade_col(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions)) this%rf_decomp_cascade_col(:,:,:) = nan @@ -774,6 +777,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column) this%cwdhr_col(i) = value_column this%michr_col(i) = value_column this%soilc_change_col(i) = value_column + this%litr_lig_c_to_n_col(i) = value_column end do ! NOTE: do not zero the fates to BGC C flux variables since they need to persist from the daily fates timestep s to the half-hourly BGC timesteps. I.e. FATES_c_to_litr_lab_c_col, FATES_c_to_litr_cel_c_col, FATES_c_to_litr_lig_c_col diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index d629d6f5af..5261a6eb83 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -856,9 +856,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & real(r8):: spinup_geogterm_s3(bounds%begc:bounds%endc) ! geographically-varying spinup term for s3 real(r8):: spinup_geogterm_m1(bounds%begc:bounds%endc) ! geographically-varying spinup term for m1 real(r8):: spinup_geogterm_m2(bounds%begc:bounds%endc) ! geographically-varying spinup term for m2 - real(r8):: ligninNratioAvg_local(bounds%begc:bounds%endc) ! local column-level lignin to nitrogen ratio real(r8):: annsum_npp_col_local(bounds%begc:bounds%endc) ! local annual sum of NPP at the column level - real(r8):: ligninNratio(bounds%begp:bounds%endp) ! local patch-level lignin to nitrogen ratio real(r8):: annsum_npp(bounds%begp:bounds%endp) ! local annual sum of NPP at the patch level real(r8):: ligninNratioAvg_scalar ! lignin to nitrogen ratio, scalar in column-level loop real(r8):: annsum_npp_col_scalar ! annual sum of NPP, scalar in column-level loop @@ -1114,19 +1112,17 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & mimics_cn_r = params_inst%mimics_cn_r mimics_cn_k = params_inst%mimics_cn_k - ! Local column-level annsum_npp and ligninNratioAvg. - ! Use FATES copies of both variables for FATES-MIMICS cases. - ! The FATES copy of annsum_npp is available when also use_lch4 = .true. + ! If FATES-MIMICS, then use FATES copies of annsum_npp & ligninNratio. + ! The FATES copy of annsum_npp is available when use_lch4 = .true., so + ! we limit FATES-MIMICS to if (use_lch4). + ! The FATES copy of annsum_npp is calculated at the patch level, so we + ! obtain it in the next patch loop. + ! The FATES copy of ligninNratio is calculated at the site/column level, + ! so we obtain it in the next column loop. fates_if: if (use_fates) then lch4_if: if (use_lch4) then - ! Initialize - do fc = 1,num_soilc - c = filter_soilc(fc) - ligninNratioAvg_local(c) = 0._r8 - annsum_npp_col_local(c) = 0._r8 - end do - ! Loop over p: get FATES copies of annsum_npp & local ligninNratio + ! Loop over p to get FATES copy of annsum_npp nc = bounds%clump_index do fp = 1, num_soilp @@ -1136,14 +1132,13 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & pf = p - col%patchi(c) s = clm_fates%f2hmap(nc)%hsites(c) annsum_npp(p) = clm_fates%fates(nc)%bc_out(s)%annsum_npp_pa(pf) - ligninNratio(p) = clm_fates%fates(nc)%bc_out(s)%litt_flux_ligc_per_n(pf) + + ! Initialize local column-level annsum_npp before averaging + annsum_npp_col_local(c) = 0._r8 end do ! p loop - ! Calculate the column-level averages - call p2c(bounds, num_soilc, filter_soilc, & - ligninNratio(bounds%begp:bounds%endp), & - ligninNratioAvg_local(bounds%begc:bounds%endc)) + ! Calculate the column-level average call p2c(bounds, num_soilc, filter_soilc, & annsum_npp(bounds%begp:bounds%endp), & annsum_npp_col_local(bounds%begc:bounds%endc)) @@ -1159,7 +1154,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & c = filter_soilc(fc) if (use_fates) then - ligninNratioAvg_scalar = ligninNratioAvg_local(c) + ligninNratioAvg_scalar = soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) annsum_npp_col_scalar = max(0._r8, annsum_npp_col_local(c)) else ligninNratioAvg_scalar = cnveg_carbonflux_inst%ligninNratioAvg_col(c) @@ -1173,7 +1168,8 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! TODO Check for high-freq variations in ligninNratioAvg. To avoid, ! replace pool_to_litter terms with ann or other long term mean ! in CNVegCarbonFluxType. - fmet = mimics_fmet_p1 * (mimics_fmet_p2 - mimics_fmet_p3 * min(mimics_fmet_p4, ligninNratioAvg_scalar)) + fmet = mimics_fmet_p1 * (mimics_fmet_p2 - mimics_fmet_p3 * & + min(mimics_fmet_p4, ligninNratioAvg_scalar)) tau_mod = min(mimics_tau_mod_max, max(mimics_tau_mod_min, & sqrt(mimics_tau_mod_factor * annsum_npp_col_scalar))) diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index 0b8d66b76f..6737f70dfe 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -1015,7 +1015,9 @@ subroutine dynamics_driv(this, nc, bounds_clump, & call this%wrap_update_hlmfates_dyn(nc, & bounds_clump, & waterdiagnosticbulk_inst, & - canopystate_inst, .false.) + canopystate_inst, & + soilbiogeochem_carbonflux_inst, & + .false.) ! --------------------------------------------------------------------------------- ! Part IV: @@ -1038,7 +1040,8 @@ end subroutine dynamics_driv ! ------------------------------------------------------------------------------------ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & - waterdiagnosticbulk_inst, canopystate_inst, is_initing_from_restart) + waterdiagnosticbulk_inst, canopystate_inst, & + soilbiogeochem_carbonflux_inst, is_initing_from_restart) ! --------------------------------------------------------------------------------- ! This routine handles the updating of vegetation canopy diagnostics, (such as lai) @@ -1052,6 +1055,7 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & integer , intent(in) :: nc type(waterdiagnosticbulk_type) , intent(inout) :: waterdiagnosticbulk_inst type(canopystate_type) , intent(inout) :: canopystate_inst + type(soilbiogeochem_carbonflux_type), intent(inout) :: soilbiogeochem_carbonflux_inst ! is this being called during a read from restart sequence (if so then use the restarted fates ! snow depth variable rather than the CLM variable). @@ -1106,6 +1110,15 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & this%f2hmap(nc)%fcolumn, & this%fates(nc)%bc_out ) + !------------------------------------------------------------------------ + ! Get FATES calculation of ligninNratio + !------------------------------------------------------------------------ + do s = 1, this%fates(nc)%nsites + c = this%f2hmap(nc)%fcolumn(s) + soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) = & + this%fates(nc)%bc_out(s)%litt_flux_ligc_per_n + end do + !--------------------------------------------------------------------------------- ! CHANGING STORED WATER DURING PLANT DYNAMICS IS NOT FULLY IMPLEMENTED ! LEAVING AS A PLACE-HOLDER FOR NOW. @@ -1236,7 +1249,7 @@ end subroutine wrap_update_hlmfates_dyn subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & waterstatebulk_inst, canopystate_inst, soilstate_inst, & - active_layer_inst) + active_layer_inst, soilbiogeochem_carbonflux_inst) ! --------------------------------------------------------------------------------- ! The ability to restart the model is handled through three different types of calls @@ -1273,6 +1286,7 @@ subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & type(canopystate_type) , intent(inout) :: canopystate_inst type(soilstate_type) , intent(inout) :: soilstate_inst type(active_layer_type) , intent(in) :: active_layer_inst + type(soilbiogeochem_carbonflux_type), intent(inout) :: soilbiogeochem_carbonflux_inst ! Locals type(bounds_type) :: bounds_clump @@ -1547,7 +1561,8 @@ subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & ! Update diagnostics of FATES ecosystem structure used in HLM. ! ------------------------------------------------------------------------ call this%wrap_update_hlmfates_dyn(nc,bounds_clump, & - waterdiagnosticbulk_inst,canopystate_inst, .true.) + waterdiagnosticbulk_inst,canopystate_inst, & + soilbiogeochem_carbonflux_inst, .true.) ! ------------------------------------------------------------------------ ! Update the 3D patch level radiation absorption fractions @@ -1583,7 +1598,7 @@ end subroutine restart !===================================================================================== subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, & - canopystate_inst, soilstate_inst) + canopystate_inst, soilstate_inst, soilbiogeochem_carbonflux_inst) ! Arguments @@ -1592,6 +1607,7 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, & type(waterdiagnosticbulk_type) , intent(inout) :: waterdiagnosticbulk_inst type(canopystate_type) , intent(inout) :: canopystate_inst type(soilstate_type) , intent(inout) :: soilstate_inst + type(soilbiogeochem_carbonflux_type), intent(inout) :: soilbiogeochem_carbonflux_inst ! locals integer :: nclumps @@ -1724,7 +1740,8 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, & ! Update diagnostics of FATES ecosystem structure used in HLM. ! ------------------------------------------------------------------------ call this%wrap_update_hlmfates_dyn(nc,bounds_clump, & - waterdiagnosticbulk_inst,canopystate_inst, .false.) + waterdiagnosticbulk_inst,canopystate_inst, & + soilbiogeochem_carbonflux_inst, .false.) ! ------------------------------------------------------------------------ ! Update history IO fields that depend on ecosystem dynamics From cd42ddfc4fc26b07fdf4d8f4b883e051bb2c79b9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 26 Apr 2022 19:00:50 -0600 Subject: [PATCH 17/27] Consolidating ligninNratioAvg var from cnveg_carbonflux to ... ... soilbiogeochem_carbonflux to avoid duplication --- src/biogeochem/CNDriverMod.F90 | 32 ++++-- src/biogeochem/CNVegCarbonFluxType.F90 | 72 +------------- src/biogeochem/EDBGCDynMod.F90 | 32 +++++- src/main/clm_driver.F90 | 4 +- .../SoilBiogeochemCarbonFluxType.F90 | 98 ++++++++++++++++--- .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 11 +-- 6 files changed, 147 insertions(+), 102 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index b4a35cf699..84c9a340d6 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -1031,12 +1031,14 @@ subroutine CNDriverSummarizeFluxes(bounds, & type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst ! ! !LOCAL VARIABLES: + integer :: begp,endp integer :: begc,endc integer :: begg,endg character(len=*), parameter :: subname = 'CNDriverSummarizeFluxes' !----------------------------------------------------------------------- + begp = bounds%begp; endp= bounds%endp begc = bounds%begc; endc= bounds%endc begg = bounds%begg; endg = bounds%endg @@ -1046,12 +1048,30 @@ subroutine CNDriverSummarizeFluxes(bounds, & ! soilbiogeochem carbon/nitrogen flux summary ! ---------------------------------------------- - call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) + call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & + cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & + soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & + soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) if ( use_c13 ) then - call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) + call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & + c13_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + c13_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & + c13_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & + c13_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) end if if ( use_c14 ) then - call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) + call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & + c14_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + c14_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & + c14_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & + c14_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) end if call soilbiogeochem_nitrogenflux_inst%Summary(bounds, num_soilc, filter_soilc) @@ -1067,8 +1087,6 @@ subroutine CNDriverSummarizeFluxes(bounds, & soilbiogeochem_lithr_col=soilbiogeochem_carbonflux_inst%lithr_col(begc:endc), & soilbiogeochem_decomp_cascade_ctransfer_col=& soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & - soilbiogeochem_cwdc_col=soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_cwdn_col=soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc), & product_closs_grc=c_products_inst%product_loss_grc(begg:endg)) if ( use_c13 ) then @@ -1079,8 +1097,6 @@ subroutine CNDriverSummarizeFluxes(bounds, & soilbiogeochem_lithr_col=c13_soilbiogeochem_carbonflux_inst%lithr_col(begc:endc), & soilbiogeochem_decomp_cascade_ctransfer_col=& c13_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & - soilbiogeochem_cwdc_col=c13_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_cwdn_col=soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc), & product_closs_grc=c13_products_inst%product_loss_grc(begg:endg)) end if @@ -1092,8 +1108,6 @@ subroutine CNDriverSummarizeFluxes(bounds, & soilbiogeochem_lithr_col=c14_soilbiogeochem_carbonflux_inst%lithr_col(begc:endc), & soilbiogeochem_decomp_cascade_ctransfer_col=& c14_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & - soilbiogeochem_cwdc_col=c14_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_cwdn_col=soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc), & product_closs_grc=c14_products_inst%product_loss_grc(begg:endg)) end if call t_stopf('CNvegCflux_summary') diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90 index cce46f080c..1d153f4b0a 100644 --- a/src/biogeochem/CNVegCarbonFluxType.F90 +++ b/src/biogeochem/CNVegCarbonFluxType.F90 @@ -11,7 +11,7 @@ module CNVegCarbonFluxType use decompMod , only : bounds_type use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools - use clm_varpar , only : nlevdecomp_full, nlevdecomp, i_litr_min, i_litr_max, i_cwdl2 + use clm_varpar , only : nlevdecomp_full, nlevdecomp, i_litr_min, i_litr_max use clm_varcon , only : spval, dzsoi_decomp use clm_varctl , only : use_cndv, use_c13, use_nitrif_denitrif, use_crop use clm_varctl , only : use_grainproduct @@ -338,9 +338,6 @@ module CNVegCarbonFluxType real(r8), pointer :: nbp_grc (:) ! (gC/m2/s) net biome production, includes fire, landuse, harvest and hrv_xsmrpool flux, positive for sink (same as net carbon exchange between land and atmosphere) real(r8), pointer :: nee_grc (:) ! (gC/m2/s) net ecosystem exchange of carbon, includes fire and hrv_xsmrpool, excludes landuse and harvest flux, positive for source - ! Plant C to N ratios - real(r8), pointer :: ligninNratioAvg_col(:) ! Average of leaf, fine root, and CWD lignin to N ratio - ! Dynamic landcover fluxnes real(r8), pointer :: landuseflux_grc(:) ! (gC/m2/s) dwt_conv_cflux+product_closs real(r8), pointer :: npp_Nactive_patch (:) ! C used by mycorrhizal uptake (gC/m2/s) @@ -709,8 +706,6 @@ subroutine InitAllocate(this, bounds, carbon_type) allocate(this%annsum_npp_col (begc:endc)) ; this%annsum_npp_col (:) = nan allocate(this%lag_npp_col (begc:endc)) ; this%lag_npp_col (:) = spval - allocate(this%ligninNratioAvg_col (begc:endc)) ; this%ligninNratioAvg_col (:) = nan - allocate(this%nep_col (begc:endc)) ; this%nep_col (:) = nan allocate(this%nbp_grc (begg:endg)) ; this%nbp_grc (:) = nan allocate(this%nee_grc (begg:endg)) ; this%nee_grc (:) = nan @@ -3439,12 +3434,10 @@ subroutine InitCold(this, bounds) if (lun%ifspecial(l)) then this%annsum_npp_col(c) = spval - this%ligninNratioAvg_col(c) = spval end if if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then this%annsum_npp_col(c) = 0._r8 - this%ligninNratioAvg_col(c) = 0._r8 end if end do @@ -3670,11 +3663,6 @@ subroutine RestartBulkOnly ( this, bounds, ncid, flag ) long_name='', units='', & interpinic_flag='interp', readvar=readvar, data=this%annsum_npp_col) - call restartvar(ncid=ncid, flag=flag, varname='ligninNratioAvg', xtype=ncd_double, & - dim1name='column', & - long_name='', units='', & - interpinic_flag='interp', readvar=readvar, data=this%ligninNratioAvg_col) - call restartvar(ncid=ncid, flag=flag, varname='tempsum_litfall', xtype=ncd_double, & dim1name='pft', & long_name='', units='', & @@ -4108,7 +4096,6 @@ subroutine Summary_carbonflux(this, & bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, isotope, & soilbiogeochem_hr_col, soilbiogeochem_cwdhr_col, soilbiogeochem_lithr_col, & soilbiogeochem_decomp_cascade_ctransfer_col, & - soilbiogeochem_cwdc_col, soilbiogeochem_cwdn_col, & product_closs_grc) ! ! !DESCRIPTION: @@ -4119,8 +4106,8 @@ subroutine Summary_carbonflux(this, & use clm_varcon , only: secspday use clm_varctl , only: nfix_timeconst, carbon_resp_opt use subgridAveMod , only: p2c, c2g - use SoilBiogeochemDecompCascadeConType , only: decomp_cascade_con, mimics_decomp, decomp_method - use CNSharedParamsMod , only: use_fun, CNParamsShareInst + use SoilBiogeochemDecompCascadeConType , only: decomp_cascade_con + use CNSharedParamsMod , only: use_fun ! ! !ARGUMENTS: class(cnveg_carbonflux_type) :: this @@ -4134,8 +4121,6 @@ subroutine Summary_carbonflux(this, & real(r8) , intent(in) :: soilbiogeochem_cwdhr_col(bounds%begc:) real(r8) , intent(in) :: soilbiogeochem_lithr_col(bounds%begc:) real(r8) , intent(in) :: soilbiogeochem_decomp_cascade_ctransfer_col(bounds%begc:,1:) - real(r8) , intent(in) :: soilbiogeochem_cwdc_col(bounds%begc:) - real(r8) , intent(in) :: soilbiogeochem_cwdn_col(bounds%begc:) real(r8) , intent(in) :: product_closs_grc(bounds%begg:) ! ! !LOCAL VARIABLES: @@ -4143,13 +4128,6 @@ subroutine Summary_carbonflux(this, & integer :: fp,fc ! lake filter indices real(r8) :: nfixlags, dtime ! temp variables for making lagged npp real(r8) :: maxdepth ! depth to integrate soil variables - real(r8) :: ligninNratio_cwd ! lignin to N ratio of CWD - real(r8) :: ligninNratio_leaf_patch(bounds%begp:bounds%endp) ! lignin to N ratio of leaves, patch level - real(r8) :: ligninNratio_froot_patch(bounds%begp:bounds%endp) ! lignin to N ratio of fine roots, patch level - real(r8) :: ligninNratio_leaf_col(bounds%begc:bounds%endc) ! lignin to N ratio of leaves, column level - real(r8) :: ligninNratio_froot_col(bounds%begc:bounds%endc) ! lignin to N ratio of fine roots, column level - real(r8) :: leafc_to_litter_col(bounds%begc:bounds%endc) ! leaf C to litter C, column level - real(r8) :: frootc_to_litter_col(bounds%begc:bounds%endc) ! fine root C to litter C, column level real(r8) :: nep_grc(bounds%begg:bounds%endg) ! nep_col averaged to gridcell real(r8) :: fire_closs_grc(bounds%begg:bounds%endg) ! fire_closs_col averaged to gridcell real(r8) :: hrv_xsmrpool_to_atm_grc(bounds%begg:bounds%endg) ! hrv_xsmrpool_to_atm_col averaged to gridcell (gC/m2/s) @@ -4539,17 +4517,6 @@ subroutine Summary_carbonflux(this, & this%hrv_gresp_storage_to_litter_patch(p) + & this%hrv_gresp_xfer_to_litter_patch(p) - if (decomp_method == mimics_decomp) then - ! Calculate ligninNratio for leaves and fine roots - associate(ivt => patch%itype) ! Input: [integer (:)] patch plant type - ligninNratio_leaf_patch(p) = pftcon%lf_flig(ivt(p)) * & - pftcon%lflitcn(ivt(p)) * & - this%leafc_to_litter_patch(p) - ligninNratio_froot_patch(p) = pftcon%fr_flig(ivt(p)) * & - pftcon%frootcn(ivt(p)) * & - this%frootc_to_litter_patch(p) - end associate - end if end do ! end of patches loop !------------------------------------------------ @@ -4594,39 +4561,6 @@ subroutine Summary_carbonflux(this, & this%gpp_patch(bounds%begp:bounds%endp), & this%gpp_col(bounds%begc:bounds%endc)) - if (decomp_method == mimics_decomp) then - call p2c(bounds, num_soilc, filter_soilc, & - ligninNratio_leaf_patch(bounds%begp:bounds%endp), & - ligninNratio_leaf_col(bounds%begc:bounds%endc)) - call p2c(bounds, num_soilc, filter_soilc, & - ligninNratio_froot_patch(bounds%begp:bounds%endp), & - ligninNratio_froot_col(bounds%begc:bounds%endc)) - call p2c(bounds, num_soilc, filter_soilc, & - this%leafc_to_litter_patch(bounds%begp:bounds%endp), & - leafc_to_litter_col(bounds%begc:bounds%endc)) - call p2c(bounds, num_soilc, filter_soilc, & - this%frootc_to_litter_patch(bounds%begp:bounds%endp), & - frootc_to_litter_col(bounds%begc:bounds%endc)) - - ! Calculate ligninNratioAve - do fc = 1,num_soilc - c = filter_soilc(fc) - if (soilbiogeochem_cwdn_col(c) > 0._r8) then - ligninNratio_cwd = CNParamsShareInst%cwd_flig * & - (soilbiogeochem_cwdc_col(c) / soilbiogeochem_cwdn_col(c)) * & - soilbiogeochem_decomp_cascade_ctransfer_col(c,i_cwdl2) - else - ligninNratio_cwd = 0._r8 - end if - this%ligninNratioAvg_col(c) = & - (ligninNratio_leaf_col(c) + ligninNratio_froot_col(c) + & - ligninNratio_cwd) / & - max(1.0e-3_r8, leafc_to_litter_col(c) + & - frootc_to_litter_col(c) + & - soilbiogeochem_decomp_cascade_ctransfer_col(c,i_cwdl2)) - end do - end if - ! this code is to calculate an exponentially-relaxed npp value for use in NDynamics code if ( trim(isotope) == 'bulk') then diff --git a/src/biogeochem/EDBGCDynMod.F90 b/src/biogeochem/EDBGCDynMod.F90 index 366dace9a5..74db7e22f3 100644 --- a/src/biogeochem/EDBGCDynMod.F90 +++ b/src/biogeochem/EDBGCDynMod.F90 @@ -267,7 +267,8 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so c13_soilbiogeochem_carbonflux_inst, c13_soilbiogeochem_carbonstate_inst, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - nc) + cnveg_carbonflux_inst, & + c13_cnveg_carbonflux_inst, c14_cnveg_carbonflux_inst, nc) ! ! !DESCRIPTION: ! Call to all CN and SoilBiogeochem summary routines @@ -292,13 +293,18 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so type(soilbiogeochem_carbonstate_type) , intent(inout) :: c14_soilbiogeochem_carbonstate_inst type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst + type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst + type(cnveg_carbonflux_type) , intent(inout) :: c13_cnveg_carbonflux_inst + type(cnveg_carbonflux_type) , intent(inout) :: c14_cnveg_carbonflux_inst integer , intent(in) :: nc ! thread index ! ! !LOCAL VARIABLES: + integer :: begp,endp integer :: begc,endc !----------------------------------------------------------------------- begc = bounds%begc; endc= bounds%endc + begp = bounds%begp; endp= bounds%endp ! Call to all summary routines @@ -330,12 +336,30 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so ! soilbiogeochem carbon/nitrogen flux summary ! ---------------------------------------------- - call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) + call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & + cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & + soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & + soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) if ( use_c13 ) then - call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) + call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & + c13_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + c13_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & + c13_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & + c13_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) end if if ( use_c14 ) then - call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) + call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & + num_soilp, filter_soilp, & + c14_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + c14_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & + c14_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & + c14_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) end if ! call soilbiogeochem_nitrogenflux_inst%Summary(bounds, num_soilc, filter_soilc) diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index 21aafa1614..f2d0fb949e 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -1096,7 +1096,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro c13_soilbiogeochem_carbonflux_inst, c13_soilbiogeochem_carbonstate_inst, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - nc) + bgc_vegetation_inst%cnveg_carbonflux_inst, & + bgc_vegetation_inst%c13_cnveg_carbonflux_inst, & + bgc_vegetation_inst%c14_cnveg_carbonflux_inst, nc) call clm_fates%wrap_update_hifrq_hist(bounds_clump, & soilbiogeochem_carbonflux_inst, & diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index c9480ea175..7f0bcbd483 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -4,11 +4,13 @@ module SoilBiogeochemCarbonFluxType use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) use decompMod , only : bounds_type use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevcan - use clm_varpar , only : nlevdecomp_full, nlevgrnd, nlevdecomp, nlevsoi + use clm_varpar , only : nlevdecomp_full, nlevgrnd, nlevdecomp, nlevsoi, i_cwdl2 use clm_varcon , only : spval, ispval, dzsoi_decomp + use pftconMod , only : pftcon use landunit_varcon , only : istsoil, istcrop, istdlak use ch4varcon , only : allowlakeprod - use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con + use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, mimics_decomp, decomp_method + use PatchType , only : patch use ColumnType , only : col use LandunitType , only : lun use clm_varctl , only : use_fates @@ -31,7 +33,7 @@ module SoilBiogeochemCarbonFluxType real(r8), pointer :: decomp_cascade_ctransfer_vr_col (:,:,:) ! vertically-resolved C transferred along deomposition cascade (gC/m3/s) real(r8), pointer :: decomp_cascade_ctransfer_col (:,:) ! vertically-integrated (diagnostic) C transferred along decomposition cascade (gC/m2/s) real(r8), pointer :: cn_col (:,:) ! (gC/gN) C:N ratio by pool - real(r8), pointer :: litr_lig_c_to_n_col (:) ! (gC/gN) lignin C:N ratio; FATES equivalent of cnveg_carbonflux_inst%ligninNratioAvg_col because FATES doesn't have access to cnveg_carbonflux_inst; could reduce duplication by consolidating cnveg_carbonflux_inst%ligninNratioAvg_col into this one + real(r8), pointer :: litr_lig_c_to_n_col (:) ! (gC/gN) Average of leaf, fine root, and CWD lignin C:N ratio real(r8), pointer :: rf_decomp_cascade_col (:,:,:) ! (frac) respired fraction in decomposition step real(r8), pointer :: pathfrac_decomp_cascade_col (:,:,:) ! (frac) what fraction of C passes from donor to receiver pool through a given transition real(r8), pointer :: decomp_k_col (:,:,:) ! rate coefficient for decomposition (1./sec) @@ -132,8 +134,6 @@ subroutine InitAllocate(this, bounds) allocate(this%cn_col(begc:endc,1:ndecomp_pools)) this%cn_col(:,:)= spval - allocate(this%litr_lig_c_to_n_col(begc:endc)) - this%litr_lig_c_to_n_col(:)= spval allocate(this%rf_decomp_cascade_col(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions)) this%rf_decomp_cascade_col(:,:,:) = nan @@ -173,6 +173,8 @@ subroutine InitAllocate(this, bounds) this%FATES_c_to_litr_lig_c_col(begc:endc,1:nlevdecomp_full) = 0._r8 endif + allocate(this%litr_lig_c_to_n_col(begc:endc)) + this%litr_lig_c_to_n_col(:)= 0._r8 end subroutine InitAllocate @@ -709,7 +711,12 @@ subroutine Restart(this, bounds, ncid, flag) this%FATES_c_to_litr_c_col(:,:,3) = this%FATES_c_to_litr_lig_c_col(:,:) end if - + + call restartvar(ncid=ncid, flag=flag, varname='ligninNratioAvg', xtype=ncd_double, & + dim1name='column', & + long_name='', units='', & + interpinic_flag='interp', readvar=readvar, data=this%litr_lig_c_to_n_col) + end subroutine Restart !----------------------------------------------------------------------- @@ -777,7 +784,6 @@ subroutine SetValues ( this, num_column, filter_column, value_column) this%cwdhr_col(i) = value_column this%michr_col(i) = value_column this%soilc_change_col(i) = value_column - this%litr_lig_c_to_n_col(i) = value_column end do ! NOTE: do not zero the fates to BGC C flux variables since they need to persist from the daily fates timestep s to the half-hourly BGC timesteps. I.e. FATES_c_to_litr_lab_c_col, FATES_c_to_litr_cel_c_col, FATES_c_to_litr_lig_c_col @@ -785,21 +791,43 @@ subroutine SetValues ( this, num_column, filter_column, value_column) end subroutine SetValues !----------------------------------------------------------------------- - subroutine Summary(this, bounds, num_soilc, filter_soilc) + subroutine Summary(this, bounds, & + num_soilc, filter_soilc, num_soilp, filter_soilp, & + leafc_to_litter_patch, frootc_to_litter_patch, & + soilbiogeochem_decomp_cascade_ctransfer_col, & + soilbiogeochem_cwdc_col, soilbiogeochem_cwdn_col) ! ! !DESCRIPTION: - ! On the radiation time step, column-level carbon summary calculations + ! On the radiation time step, carbon summary calculations ! ! !USES: + use subgridAveMod, only: p2c + use CNSharedParamsMod, only: CNParamsShareInst + ! !ARGUMENTS: class(soilbiogeochem_carbonflux_type) :: this type(bounds_type) , intent(in) :: bounds integer , intent(in) :: num_soilc ! number of soil columns in filter integer , intent(in) :: filter_soilc(:) ! filter for soil columns + integer , intent(in) :: num_soilp ! number of patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for patches + real(r8) , intent(in) :: leafc_to_litter_patch(bounds%begp:) + real(r8) , intent(in) :: frootc_to_litter_patch(bounds%begp:) + real(r8) , intent(in) :: soilbiogeochem_cwdc_col(bounds%begc:) + real(r8) , intent(in) :: soilbiogeochem_cwdn_col(bounds%begc:) + real(r8) , intent(in) :: soilbiogeochem_decomp_cascade_ctransfer_col(bounds%begc:,1:) ! ! !LOCAL VARIABLES: - integer :: c,j,k,l - integer :: fc + integer :: c,j,k,l,p + integer :: fc, fp + real(r8) :: ligninNratio_cwd ! lignin to N ratio of CWD + real(r8) :: ligninNratio_leaf_patch(bounds%begp:bounds%endp) ! lignin to N ratio of leaves, patch level + real(r8) :: ligninNratio_froot_patch(bounds%begp:bounds%endp) ! lignin to N ratio of fine roots, patch level + real(r8) :: ligninNratio_leaf_col(bounds%begc:bounds%endc) ! lignin to N ratio of leaves, column level + real(r8) :: ligninNratio_froot_col(bounds%begc:bounds%endc) ! lignin to N ratio of fine roots, column level + real(r8) :: leafc_to_litter_col(bounds%begc:bounds%endc) ! leaf C to litter C, column level + real(r8) :: frootc_to_litter_col(bounds%begc:bounds%endc) ! fine root C to litter C, column level + !----------------------------------------------------------------------- do fc = 1,num_soilc @@ -920,6 +948,54 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc) end do + ! Calculate ligninNratio + ! FATES does its own calculation + if (.not. use_fates .and. decomp_method == mimics_decomp) then + do fp = 1,num_soilp + p = filter_soilp(fp) + + associate(ivt => patch%itype) ! Input: [integer (:)] patch plant type + ligninNratio_leaf_patch(p) = pftcon%lf_flig(ivt(p)) * & + pftcon%lflitcn(ivt(p)) * & + leafc_to_litter_patch(p) + ligninNratio_froot_patch(p) = pftcon%fr_flig(ivt(p)) * & + pftcon%frootcn(ivt(p)) * & + frootc_to_litter_patch(p) + end associate + end do + + call p2c(bounds, num_soilc, filter_soilc, & + ligninNratio_leaf_patch(bounds%begp:bounds%endp), & + ligninNratio_leaf_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + ligninNratio_froot_patch(bounds%begp:bounds%endp), & + ligninNratio_froot_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + leafc_to_litter_patch(bounds%begp:bounds%endp), & + leafc_to_litter_col(bounds%begc:bounds%endc)) + call p2c(bounds, num_soilc, filter_soilc, & + frootc_to_litter_patch(bounds%begp:bounds%endp), & + frootc_to_litter_col(bounds%begc:bounds%endc)) + + ! Calculate ligninNratioAve + do fc = 1,num_soilc + c = filter_soilc(fc) + if (soilbiogeochem_cwdn_col(c) > 0._r8) then + ligninNratio_cwd = CNParamsShareInst%cwd_flig * & + (soilbiogeochem_cwdc_col(c) / soilbiogeochem_cwdn_col(c)) * & + soilbiogeochem_decomp_cascade_ctransfer_col(c,i_cwdl2) + else + ligninNratio_cwd = 0._r8 + end if + this%litr_lig_c_to_n_col(c) = & + (ligninNratio_leaf_col(c) + ligninNratio_froot_col(c) + & + ligninNratio_cwd) / & + max(1.0e-3_r8, leafc_to_litter_col(c) + & + frootc_to_litter_col(c) + & + soilbiogeochem_decomp_cascade_ctransfer_col(c,i_cwdl2)) + end do + end if + end subroutine Summary end module SoilBiogeochemCarbonFluxType diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 5261a6eb83..85cf4da5e8 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -879,6 +879,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & w_scalar => soilbiogeochem_carbonflux_inst%w_scalar_col , & ! Output: [real(r8) (:,:) ] soil water scalar for decomp o_scalar => soilbiogeochem_carbonflux_inst%o_scalar_col , & ! Output: [real(r8) (:,:) ] fraction by which decomposition is limited by anoxia cn_col => soilbiogeochem_carbonflux_inst%cn_col , & ! Output: [real(r8) (:,:) ] C:N ratio + ligninNratioAvg => soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col, & ! Input: [real(r8) (:) ] C:N ratio of litter lignin decomp_k => soilbiogeochem_carbonflux_inst%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate for decomposition (1./sec) spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool ) @@ -1112,13 +1113,9 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & mimics_cn_r = params_inst%mimics_cn_r mimics_cn_k = params_inst%mimics_cn_k - ! If FATES-MIMICS, then use FATES copies of annsum_npp & ligninNratio. + ! If FATES-MIMICS, then use FATES copy of annsum_npp. ! The FATES copy of annsum_npp is available when use_lch4 = .true., so ! we limit FATES-MIMICS to if (use_lch4). - ! The FATES copy of annsum_npp is calculated at the patch level, so we - ! obtain it in the next patch loop. - ! The FATES copy of ligninNratio is calculated at the site/column level, - ! so we obtain it in the next column loop. fates_if: if (use_fates) then lch4_if: if (use_lch4) then @@ -1154,10 +1151,8 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & c = filter_soilc(fc) if (use_fates) then - ligninNratioAvg_scalar = soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) annsum_npp_col_scalar = max(0._r8, annsum_npp_col_local(c)) else - ligninNratioAvg_scalar = cnveg_carbonflux_inst%ligninNratioAvg_col(c) annsum_npp_col_scalar = max(0._r8, cnveg_carbonflux_inst%annsum_npp_col(c)) end if @@ -1169,7 +1164,7 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & ! replace pool_to_litter terms with ann or other long term mean ! in CNVegCarbonFluxType. fmet = mimics_fmet_p1 * (mimics_fmet_p2 - mimics_fmet_p3 * & - min(mimics_fmet_p4, ligninNratioAvg_scalar)) + min(mimics_fmet_p4, ligninNratioAvg(c))) tau_mod = min(mimics_tau_mod_max, max(mimics_tau_mod_min, & sqrt(mimics_tau_mod_factor * annsum_npp_col_scalar))) From eadb090ef9dc5c2b9e8b2eb74dbecc912ec9d1ce Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 26 Apr 2022 19:13:23 -0600 Subject: [PATCH 18/27] Update ChangeLog --- doc/ChangeLog | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 3f9b33868d..cc8505500a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,17 +1,15 @@ =============================================================== Tag name: ctsm5.1.dev092 Originator(s): slevis (Samuel Levis) -Date: Mon Apr 25 09:57:03 MDT 2022 +Date: Tue Apr 26 19:09:48 MDT 2022 One-line Summary: Modifications for FATES-MIMICS to work Purpose and description of changes ---------------------------------- 1) For FATES-MIMICS cases, use ligninNratioAvg calculated by FATES. - - 2) FATES has it's own calculation of annsum_npp_col, also needed in MIMICS. - I updated MIMICS to use the FATES variable when running with FATES. - + 2) For FATES-MIMICS cases, use annsum_npp_col calculated by FATES. + 3) Small modification to allow carbon-only to work with MIMICS. Significant changes to scientifically-supported configurations -------------------------------------------------------------- @@ -34,19 +32,16 @@ Bugs fixed or introduced ------------------------ Issues fixed (include CTSM Issue #): #1636 - Notes of particular relevance for users --------------------------------------- Caveats for users (e.g., need to interpolate initial conditions): MIMICS-FATES now do work together, but only as long as use_lch4 = .true. - Notes of particular relevance for developers: --------------------------------------------- Changes to tests or testing: To confirm that MIMICS-FATES works, I added the testmod mimicsFatesColdDef. - Testing summary: ---------------- From f704b400304608e20ef174a9c57ca29ff8086e57 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 26 Apr 2022 19:14:07 -0600 Subject: [PATCH 19/27] Update ChangeSum --- doc/ChangeSum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ChangeSum b/doc/ChangeSum index 2e02af16d6..7be43e3926 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.1.dev092 slevis 04/25/2022 Modifications for FATES-MIMICS to work + ctsm5.1.dev092 slevis 04/26/2022 Modifications for FATES-MIMICS to work ctsm5.1.dev091 rgknox 04/22/2022 clm decomp method is now passed to fates to enabled mimics coupling ctsm5.1.dev090 samrabin 03/31/2022 Fix misleading name of "gddplant" ctsm5.1.dev089 sacks 03/31/2022 For CLM45 apply peaklai to aleaf in grainfill From c4708e9dfaaf3f1967596fef911a9aa0fe09340b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 27 Apr 2022 10:01:25 -0600 Subject: [PATCH 20/27] Update comments about microbial C heterotrophic resp. per @wwieder Tangential to this PR: It affects comments, plus makes the CWD HR history variable active, so Will and I decided to slide it in --- .../SoilBiogeochemCarbonFluxType.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index 7f0bcbd483..bf7422e264 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -50,10 +50,10 @@ module SoilBiogeochemCarbonFluxType real(r8), pointer :: fphr_col (:,:) ! fraction of potential heterotrophic respiration real(r8), pointer :: hr_col (:) ! (gC/m2/s) total heterotrophic respiration - real(r8), pointer :: michr_col (:) ! (gC/m2/s) microbial heterotrophic respiration - real(r8), pointer :: cwdhr_col (:) ! (gC/m2/s) coarse woody debris heterotrophic respiration - real(r8), pointer :: lithr_col (:) ! (gC/m2/s) litter heterotrophic respiration - real(r8), pointer :: somhr_col (:) ! (gC/m2/s) soil organic matter heterotrophic res + real(r8), pointer :: michr_col (:) ! (gC/m2/s) microbial heterotrophic respiration: donor-pool based definition, so expect it to be zero with MIMICS; microbial decomposition is responsible for heterotrophic respiration of donor pools (litter and soil), but in the accounting we assign it to the donor pool for consistency with CENTURY + real(r8), pointer :: cwdhr_col (:) ! (gC/m2/s) coarse woody debris heterotrophic respiration: donor-pool based definition + real(r8), pointer :: lithr_col (:) ! (gC/m2/s) litter heterotrophic respiration: donor-pool based definition + real(r8), pointer :: somhr_col (:) ! (gC/m2/s) soil organic matter heterotrophic res: donor-pool based definition real(r8), pointer :: soilc_change_col (:) ! (gC/m2/s) FUN used soil C ! fluxes to receive carbon inputs from FATES @@ -231,13 +231,13 @@ subroutine InitHistory(this, bounds, carbon_type) this%michr_col(begc:endc) = spval call hist_addfld1d (fname='MICC_HR', units='gC/m^2/s', & - avgflag='A', long_name='microbial C heterotrophic respiration', & - ptr_col=this%michr_col) + avgflag='A', long_name='microbial C heterotrophic respiration: donor-pool based, so expect zero with MIMICS', & + ptr_col=this%michr_col, default='inactive') this%cwdhr_col(begc:endc) = spval call hist_addfld1d (fname='CWDC_HR', units='gC/m^2/s', & avgflag='A', long_name='cwd C heterotrophic respiration', & - ptr_col=this%cwdhr_col, default='inactive') + ptr_col=this%cwdhr_col) this%lithr_col(begc:endc) = spval call hist_addfld1d (fname='LITTERC_HR', units='gC/m^2/s', & From 79a4ec3a3288a9d0672dd51697bb788bc6ba2e2b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 27 Apr 2022 13:21:25 -0600 Subject: [PATCH 21/27] Corrections needed for failing tests to pass --- src/biogeochem/CNDriverMod.F90 | 18 +++++----- src/biogeochem/EDBGCDynMod.F90 | 34 +++---------------- src/main/clm_driver.F90 | 4 +-- .../SoilBiogeochemCarbonFluxType.F90 | 18 +++++----- 4 files changed, 23 insertions(+), 51 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index 84c9a340d6..74332c1173 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -1050,28 +1050,28 @@ subroutine CNDriverSummarizeFluxes(bounds, & call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & num_soilp, filter_soilp, & - cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & - cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc), & + leafc_to_litter_patch=cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + frootc_to_litter_patch=cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp)) if ( use_c13 ) then call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & num_soilp, filter_soilp, & - c13_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & - c13_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & c13_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & c13_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc), & + leafc_to_litter_patch=c13_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + frootc_to_litter_patch=c13_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp)) end if if ( use_c14 ) then call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & num_soilp, filter_soilp, & - c14_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & - c14_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & c14_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & c14_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) + soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc), & + leafc_to_litter_patch=c14_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & + frootc_to_litter_patch=c14_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp)) end if call soilbiogeochem_nitrogenflux_inst%Summary(bounds, num_soilc, filter_soilc) diff --git a/src/biogeochem/EDBGCDynMod.F90 b/src/biogeochem/EDBGCDynMod.F90 index 74db7e22f3..c3958d472d 100644 --- a/src/biogeochem/EDBGCDynMod.F90 +++ b/src/biogeochem/EDBGCDynMod.F90 @@ -117,11 +117,9 @@ subroutine EDBGCDyn(bounds, & real(r8):: pmnf_decomp_cascade(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_cascade_transitions) !potential mineral N flux, from one pool to another real(r8):: p_decomp_npool_to_din(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_cascade_transitions) ! potential flux to dissolved inorganic N real(r8):: p_decomp_cn_gain(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_pools) ! C:N ratio of the flux gained by the receiver pool - integer :: begp,endp integer :: begc,endc !----------------------------------------------------------------------- - begp = bounds%begp; endp = bounds%endp begc = bounds%begc; endc = bounds%endc associate( & @@ -267,8 +265,7 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so c13_soilbiogeochem_carbonflux_inst, c13_soilbiogeochem_carbonstate_inst, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - cnveg_carbonflux_inst, & - c13_cnveg_carbonflux_inst, c14_cnveg_carbonflux_inst, nc) + nc) ! ! !DESCRIPTION: ! Call to all CN and SoilBiogeochem summary routines @@ -293,18 +290,13 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so type(soilbiogeochem_carbonstate_type) , intent(inout) :: c14_soilbiogeochem_carbonstate_inst type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst - type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst - type(cnveg_carbonflux_type) , intent(inout) :: c13_cnveg_carbonflux_inst - type(cnveg_carbonflux_type) , intent(inout) :: c14_cnveg_carbonflux_inst integer , intent(in) :: nc ! thread index ! ! !LOCAL VARIABLES: - integer :: begp,endp integer :: begc,endc !----------------------------------------------------------------------- begc = bounds%begc; endc= bounds%endc - begp = bounds%begp; endp= bounds%endp ! Call to all summary routines @@ -336,30 +328,12 @@ subroutine EDBGCDynSummary(bounds, num_soilc, filter_soilc, num_soilp, filter_so ! soilbiogeochem carbon/nitrogen flux summary ! ---------------------------------------------- - call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & - num_soilp, filter_soilp, & - cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & - cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & - soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & - soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) + call soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) if ( use_c13 ) then - call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & - num_soilp, filter_soilp, & - c13_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & - c13_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & - c13_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & - c13_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) + call c13_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) end if if ( use_c14 ) then - call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc, & - num_soilp, filter_soilp, & - c14_cnveg_carbonflux_inst%leafc_to_litter_patch(begp:endp), & - c14_cnveg_carbonflux_inst%frootc_to_litter_patch(begp:endp), & - c14_soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_col(begc:endc,1:ndecomp_cascade_transitions), & - c14_soilbiogeochem_carbonstate_inst%cwdc_col(begc:endc), & - soilbiogeochem_nitrogenstate_inst%cwdn_col(begc:endc)) + call c14_soilbiogeochem_carbonflux_inst%Summary(bounds, num_soilc, filter_soilc) end if ! call soilbiogeochem_nitrogenflux_inst%Summary(bounds, num_soilc, filter_soilc) diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index f2d0fb949e..21aafa1614 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -1096,9 +1096,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro c13_soilbiogeochem_carbonflux_inst, c13_soilbiogeochem_carbonstate_inst, & c14_soilbiogeochem_carbonflux_inst, c14_soilbiogeochem_carbonstate_inst, & soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst, & - bgc_vegetation_inst%cnveg_carbonflux_inst, & - bgc_vegetation_inst%c13_cnveg_carbonflux_inst, & - bgc_vegetation_inst%c14_cnveg_carbonflux_inst, nc) + nc) call clm_fates%wrap_update_hifrq_hist(bounds_clump, & soilbiogeochem_carbonflux_inst, & diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index bf7422e264..fa16c1c907 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -793,9 +793,9 @@ end subroutine SetValues !----------------------------------------------------------------------- subroutine Summary(this, bounds, & num_soilc, filter_soilc, num_soilp, filter_soilp, & - leafc_to_litter_patch, frootc_to_litter_patch, & soilbiogeochem_decomp_cascade_ctransfer_col, & - soilbiogeochem_cwdc_col, soilbiogeochem_cwdn_col) + soilbiogeochem_cwdc_col, soilbiogeochem_cwdn_col, & + leafc_to_litter_patch, frootc_to_litter_patch) ! ! !DESCRIPTION: ! On the radiation time step, carbon summary calculations @@ -809,13 +809,13 @@ subroutine Summary(this, bounds, & type(bounds_type) , intent(in) :: bounds integer , intent(in) :: num_soilc ! number of soil columns in filter integer , intent(in) :: filter_soilc(:) ! filter for soil columns - integer , intent(in) :: num_soilp ! number of patches in filter - integer , intent(in) :: filter_soilp(:) ! filter for patches - real(r8) , intent(in) :: leafc_to_litter_patch(bounds%begp:) - real(r8) , intent(in) :: frootc_to_litter_patch(bounds%begp:) - real(r8) , intent(in) :: soilbiogeochem_cwdc_col(bounds%begc:) - real(r8) , intent(in) :: soilbiogeochem_cwdn_col(bounds%begc:) - real(r8) , intent(in) :: soilbiogeochem_decomp_cascade_ctransfer_col(bounds%begc:,1:) + integer, intent(in), optional :: num_soilp ! number of patches in filter + integer, intent(in), optional :: filter_soilp(:) ! filter for patches + real(r8), intent(in), optional :: soilbiogeochem_cwdc_col(bounds%begc:) + real(r8), intent(in), optional :: soilbiogeochem_cwdn_col(bounds%begc:) + real(r8), intent(in), optional :: soilbiogeochem_decomp_cascade_ctransfer_col(bounds%begc:,1:) + real(r8), intent(in), optional :: leafc_to_litter_patch(bounds%begp:) + real(r8), intent(in), optional :: frootc_to_litter_patch(bounds%begp:) ! ! !LOCAL VARIABLES: integer :: c,j,k,l,p From 1a4bb3f0b278c11a660a1f81dd06418818ae22f0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 27 Apr 2022 19:14:46 -0600 Subject: [PATCH 22/27] Fix for restart test that wasn't passing --- src/main/clm_varctl.F90 | 1 + .../SoilBiogeochemDecompCascadeMIMICSMod.F90 | 1 - src/utils/clmfates_interfaceMod.F90 | 27 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index fc1a464dea..8bb270bb5d 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -34,6 +34,7 @@ module clm_varctl ! Type of run integer, public :: nsrest = iundef + logical, public :: copy_fates_var = .false. ! True if prefer to copy var from FATES to CTSM in clmfates_interface logical, public :: is_cold_start = .false. logical, public :: is_interpolated_start = .false. ! True if we're starting from initial conditions that have been run through init_interp diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 index 85cf4da5e8..f820db01b6 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 @@ -858,7 +858,6 @@ subroutine decomp_rates_mimics(bounds, num_soilc, filter_soilc, & real(r8):: spinup_geogterm_m2(bounds%begc:bounds%endc) ! geographically-varying spinup term for m2 real(r8):: annsum_npp_col_local(bounds%begc:bounds%endc) ! local annual sum of NPP at the column level real(r8):: annsum_npp(bounds%begp:bounds%endp) ! local annual sum of NPP at the patch level - real(r8):: ligninNratioAvg_scalar ! lignin to nitrogen ratio, scalar in column-level loop real(r8):: annsum_npp_col_scalar ! annual sum of NPP, scalar in column-level loop !----------------------------------------------------------------------- diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index 6737f70dfe..dd96590416 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -45,7 +45,7 @@ module CLMFatesInterfaceMod use TemperatureType , only : temperature_type use EnergyFluxType , only : energyflux_type use SoilStateType , only : soilstate_type - use clm_varctl , only : iulog + use clm_varctl , only : iulog, copy_fates_var use clm_varctl , only : fates_parteh_mode use clm_varctl , only : use_fates use clm_varctl , only : fates_spitfire_mode @@ -80,7 +80,7 @@ module CLMFatesInterfaceMod use SoilBiogeochemCarbonFluxType, only : soilbiogeochem_carbonflux_type use SoilBiogeochemCarbonStateType, only : soilbiogeochem_carbonstate_type use FrictionVelocityMod , only : frictionvel_type - use clm_time_manager , only : is_restart + use clm_time_manager , only : is_restart, is_first_restart_step use ncdio_pio , only : file_desc_t, ncd_int, ncd_double use restUtilMod, only : restartvar use clm_time_manager , only : get_curr_days_per_year, & @@ -1111,13 +1111,26 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & this%fates(nc)%bc_out ) !------------------------------------------------------------------------ - ! Get FATES calculation of ligninNratio + ! FATES calculation of ligninNratio !------------------------------------------------------------------------ - do s = 1, this%fates(nc)%nsites - c = this%f2hmap(nc)%fcolumn(s) - soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) = & + ! If it's the first timestep of a restart and copy_fates_var = .false. + ! (this will happen in the first timestep of any restart) + ! then skip this variable because a more accurate value was obtained + ! from the restart file. + ! I had hoped that is_first_restart_step() alone would suffice here, but + ! is_first_restart_step() remained true for the whole first day in my + ! test. Hence I added the check for copy_fates_var which changes to + ! .true. the first time that we come through this code in a restart. + !------------------------------------------------------------------------ + if (is_first_restart_step() .and. .not. copy_fates_var) then + copy_fates_var = .true. + else + do s = 1, this%fates(nc)%nsites + c = this%f2hmap(nc)%fcolumn(s) + soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) = & this%fates(nc)%bc_out(s)%litt_flux_ligc_per_n - end do + end do + end if !--------------------------------------------------------------------------------- ! CHANGING STORED WATER DURING PLANT DYNAMICS IS NOT FULLY IMPLEMENTED From e5c0d80dab438bff3afb12bdd40a8701c99275ec Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 29 Apr 2022 15:38:41 -0600 Subject: [PATCH 23/27] Make my restart-fix workaround thread-safe --- src/main/clm_varctl.F90 | 1 - src/utils/clmfates_interfaceMod.F90 | 34 ++++++++++++++++------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 8bb270bb5d..fc1a464dea 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -34,7 +34,6 @@ module clm_varctl ! Type of run integer, public :: nsrest = iundef - logical, public :: copy_fates_var = .false. ! True if prefer to copy var from FATES to CTSM in clmfates_interface logical, public :: is_cold_start = .false. logical, public :: is_interpolated_start = .false. ! True if we're starting from initial conditions that have been run through init_interp diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index dd96590416..6b650dcaf1 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -45,7 +45,7 @@ module CLMFatesInterfaceMod use TemperatureType , only : temperature_type use EnergyFluxType , only : energyflux_type use SoilStateType , only : soilstate_type - use clm_varctl , only : iulog, copy_fates_var + use clm_varctl , only : iulog use clm_varctl , only : fates_parteh_mode use clm_varctl , only : use_fates use clm_varctl , only : fates_spitfire_mode @@ -233,6 +233,7 @@ module CLMFatesInterfaceMod private :: GetAndSetTime logical :: debug = .false. + logical, allocatable :: copy_fates_var(:) ! True if prefer to copy var from FATES to CTSM in clmfates_interface character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -541,21 +542,19 @@ subroutine init(this, bounds_proc ) allocate(this%fates(nclumps)) allocate(this%f2hmap(nclumps)) - if(debug)then write(iulog,*) 'clm_fates%init(): allocating for ',nclumps,' threads' end if - nclumps = get_proc_clumps() - !$OMP PARALLEL DO PRIVATE (nc,bounds_clump,nmaxcol,s,c,l,g,collist,pi,pf,ft) do nc = 1,nclumps - call get_clump_bounds(nc, bounds_clump) nmaxcol = bounds_clump%endc - bounds_clump%begc + 1 allocate(collist(1:nmaxcol)) + allocate(copy_fates_var(1:nmaxcol)) + copy_fates_var(:) = .false. ! .false. when starting any run ! Allocate the mapping that points columns to FATES sites, 0 is NA allocate(this%f2hmap(nc)%hsites(bounds_clump%begc:bounds_clump%endc)) @@ -1113,24 +1112,29 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & !------------------------------------------------------------------------ ! FATES calculation of ligninNratio !------------------------------------------------------------------------ - ! If it's the first timestep of a restart and copy_fates_var = .false. + ! If it's the first timestep of a restart and copy_fates_var(c) = .false. ! (this will happen in the first timestep of any restart) ! then skip this variable because a more accurate value was obtained ! from the restart file. - ! I had hoped that is_first_restart_step() alone would suffice here, but + ! Note 1. I had hoped is_first_restart_step() alone would suffice, but ! is_first_restart_step() remained true for the whole first day in my - ! test. Hence I added the check for copy_fates_var which changes to + ! test. Hence I added the check for copy_fates_var(c) which changes to ! .true. the first time that we come through this code in a restart. + ! Note 2. copy_fates_var is a column-level array to make thread-safe. + ! Note 3. This if statement is a workaround for restart tests to pass. + ! Ideally, the fates variable would have the correct value at restart, + ! but rgknox explains that accomplishing this is more complex given the + ! current FATES treatment of other litter fluxes passed to the CTSM. !------------------------------------------------------------------------ - if (is_first_restart_step() .and. .not. copy_fates_var) then - copy_fates_var = .true. - else - do s = 1, this%fates(nc)%nsites - c = this%f2hmap(nc)%fcolumn(s) + do s = 1, this%fates(nc)%nsites + c = this%f2hmap(nc)%fcolumn(s) + if (is_first_restart_step() .and. .not. copy_fates_var(c)) then + copy_fates_var(c) = .true. + else soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) = & this%fates(nc)%bc_out(s)%litt_flux_ligc_per_n - end do - end if + end if + end do !--------------------------------------------------------------------------------- ! CHANGING STORED WATER DURING PLANT DYNAMICS IS NOT FULLY IMPLEMENTED From 6794fa31157423517f1b7b75807f541173a350c0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 30 Apr 2022 08:59:29 -0600 Subject: [PATCH 24/27] Updates to get threaded test to PASS ERP_P144x2_Ld30.f45_f45_mg37.I2000Clm50FatesRs.cheyenne_intel.clm-mimicsFatesColdDef --- src/main/ColumnType.F90 | 4 ++++ src/utils/clmfates_interfaceMod.F90 | 13 ++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/ColumnType.F90 b/src/main/ColumnType.F90 index 5f57b3ed23..66f37a9616 100644 --- a/src/main/ColumnType.F90 +++ b/src/main/ColumnType.F90 @@ -49,6 +49,8 @@ module ColumnType logical , pointer :: active (:) ! true=>do computations on this column logical , pointer :: type_is_dynamic (:) ! true=>itype can change throughout the run + logical , pointer :: copy_fates_var (:) ! .true. -> copy variable from FATES to CTSM in clmfates_interface + ! .false. -> do not copy in clmfates_interface and use value already in memory logical , pointer :: is_fates (:) ! .true. -> this is a fates column ! .false. -> this is NOT a fates column @@ -120,6 +122,7 @@ subroutine Init(this, begc, endc) allocate(this%type_is_dynamic(begc:endc)) ; this%type_is_dynamic(:) = .false. allocate(this%is_fates(begc:endc)) ; this%is_fates(:) = .false. + allocate(this%copy_fates_var(begc:endc)) ; this%copy_fates_var(:) = .false. ! The following is set in initVerticalMod allocate(this%snl (begc:endc)) ; this%snl (:) = ispval !* cannot be averaged up @@ -159,6 +162,7 @@ subroutine Clean(this) deallocate(this%itype ) deallocate(this%lun_itype ) deallocate(this%active ) + deallocate(this%copy_fates_var) deallocate(this%is_fates ) deallocate(this%type_is_dynamic) deallocate(this%snl ) diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index 6b650dcaf1..fe13974a1f 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -233,7 +233,6 @@ module CLMFatesInterfaceMod private :: GetAndSetTime logical :: debug = .false. - logical, allocatable :: copy_fates_var(:) ! True if prefer to copy var from FATES to CTSM in clmfates_interface character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -546,15 +545,13 @@ subroutine init(this, bounds_proc ) write(iulog,*) 'clm_fates%init(): allocating for ',nclumps,' threads' end if - !$OMP PARALLEL DO PRIVATE (nc,bounds_clump,nmaxcol,s,c,l,g,collist,pi,pf,ft) do nc = 1,nclumps call get_clump_bounds(nc, bounds_clump) + nmaxcol = bounds_clump%endc - bounds_clump%begc + 1 allocate(collist(1:nmaxcol)) - allocate(copy_fates_var(1:nmaxcol)) - copy_fates_var(:) = .false. ! .false. when starting any run ! Allocate the mapping that points columns to FATES sites, 0 is NA allocate(this%f2hmap(nc)%hsites(bounds_clump%begc:bounds_clump%endc)) @@ -583,6 +580,8 @@ subroutine init(this, bounds_proc ) end if endif + col%copy_fates_var(c) = .false. + enddo if(debug)then @@ -1112,7 +1111,7 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & !------------------------------------------------------------------------ ! FATES calculation of ligninNratio !------------------------------------------------------------------------ - ! If it's the first timestep of a restart and copy_fates_var(c) = .false. + ! If it's the first timestep of a restart & copy_fates_var(c) = .false. ! (this will happen in the first timestep of any restart) ! then skip this variable because a more accurate value was obtained ! from the restart file. @@ -1128,8 +1127,8 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & !------------------------------------------------------------------------ do s = 1, this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - if (is_first_restart_step() .and. .not. copy_fates_var(c)) then - copy_fates_var(c) = .true. + if (is_first_restart_step() .and. .not. col%copy_fates_var(c)) then + col%copy_fates_var(c) = .true. else soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) = & this%fates(nc)%bc_out(s)%litt_flux_ligc_per_n From 611fb16912ba134b2f2d9af05adcda7f3b635875 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 3 May 2022 12:05:52 -0600 Subject: [PATCH 25/27] Make copy_fates_var local to clmfates_interface module --- src/main/ColumnType.F90 | 4 ---- src/utils/clmfates_interfaceMod.F90 | 11 +++++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/ColumnType.F90 b/src/main/ColumnType.F90 index 66f37a9616..5f57b3ed23 100644 --- a/src/main/ColumnType.F90 +++ b/src/main/ColumnType.F90 @@ -49,8 +49,6 @@ module ColumnType logical , pointer :: active (:) ! true=>do computations on this column logical , pointer :: type_is_dynamic (:) ! true=>itype can change throughout the run - logical , pointer :: copy_fates_var (:) ! .true. -> copy variable from FATES to CTSM in clmfates_interface - ! .false. -> do not copy in clmfates_interface and use value already in memory logical , pointer :: is_fates (:) ! .true. -> this is a fates column ! .false. -> this is NOT a fates column @@ -122,7 +120,6 @@ subroutine Init(this, begc, endc) allocate(this%type_is_dynamic(begc:endc)) ; this%type_is_dynamic(:) = .false. allocate(this%is_fates(begc:endc)) ; this%is_fates(:) = .false. - allocate(this%copy_fates_var(begc:endc)) ; this%copy_fates_var(:) = .false. ! The following is set in initVerticalMod allocate(this%snl (begc:endc)) ; this%snl (:) = ispval !* cannot be averaged up @@ -162,7 +159,6 @@ subroutine Clean(this) deallocate(this%itype ) deallocate(this%lun_itype ) deallocate(this%active ) - deallocate(this%copy_fates_var) deallocate(this%is_fates ) deallocate(this%type_is_dynamic) deallocate(this%snl ) diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index fe13974a1f..c2e2e9a52e 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -233,6 +233,8 @@ module CLMFatesInterfaceMod private :: GetAndSetTime logical :: debug = .false. + logical, private, allocatable :: copy_fates_var(:) ! .true. -> copy variable from FATES to CTSM in clmfates_interface + ! .false. -> do not copy in clmfates_interface and use value already in memory character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -545,6 +547,9 @@ subroutine init(this, bounds_proc ) write(iulog,*) 'clm_fates%init(): allocating for ',nclumps,' threads' end if + allocate(copy_fates_var(bounds_proc%begc:bounds_proc%endc)) + copy_fates_var(:) = .false. + !$OMP PARALLEL DO PRIVATE (nc,bounds_clump,nmaxcol,s,c,l,g,collist,pi,pf,ft) do nc = 1,nclumps call get_clump_bounds(nc, bounds_clump) @@ -580,8 +585,6 @@ subroutine init(this, bounds_proc ) end if endif - col%copy_fates_var(c) = .false. - enddo if(debug)then @@ -1127,8 +1130,8 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & !------------------------------------------------------------------------ do s = 1, this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - if (is_first_restart_step() .and. .not. col%copy_fates_var(c)) then - col%copy_fates_var(c) = .true. + if (is_first_restart_step() .and. .not. copy_fates_var(c)) then + copy_fates_var(c) = .true. else soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col(c) = & this%fates(nc)%bc_out(s)%litt_flux_ligc_per_n From 08f3a3ca151251e2d258a779c9f2fc6a62c2f04d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 3 May 2022 12:20:03 -0600 Subject: [PATCH 26/27] The new test added with this PR now also tests threading I changed it from izumi to cheyenne because I wasn't sure whether it would be ok on izumi. I put it on the aux_clm and fates test lists. --- cime_config/testdefs/testlist_clm.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 1e537d8ac6..2e936274c4 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -1961,13 +1961,14 @@ - + - + + - + From 28acc2f06d5f66c830c9fce3dd554ea0813de8c9 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 3 May 2022 21:51:53 -0600 Subject: [PATCH 27/27] Update date on changelog add description of issue --- doc/ChangeLog | 5 +++-- doc/ChangeSum | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 5ea63851d0..556d144a99 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.1.dev093 Originator(s): slevis (Samuel Levis) -Date: Sat Apr 30 09:17:33 MDT 2022 +Date: Tue May 3 21:50:20 MDT 2022 One-line Summary: Modifications for FATES-MIMICS to work Purpose and description of changes @@ -30,7 +30,8 @@ Does this tag change answers significantly for any of the following physics conf Bugs fixed or introduced ------------------------ -Issues fixed (include CTSM Issue #): #1636 +Issues fixed (include CTSM Issue #): + Fixes #1636 -- FATES tests fail with MIMICS active Notes of particular relevance for users --------------------------------------- diff --git a/doc/ChangeSum b/doc/ChangeSum index 6934c21bb5..68a63f6f09 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.1.dev093 slevis 04/30/2022 Modifications for FATES-MIMICS to work + ctsm5.1.dev093 slevis 05/03/2022 Modifications for FATES-MIMICS to work ctsm5.1.dev092 sacks 04/29/2022 Refactor NutrientCompetition / CNAllocation to provide hooks for AgSys ctsm5.1.dev091 rgknox 04/22/2022 clm decomp method is now passed to fates to enabled mimics coupling ctsm5.1.dev090 samrabin 03/31/2022 Fix misleading name of "gddplant"