From bd411029a935cf8c7ad3d5363c358c2e897eceaa Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 8 Apr 2026 10:55:25 -0700 Subject: [PATCH 01/30] update fates commit --- components/elm/src/external_models/fates | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index 5869e048634d..336b87f29e3d 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit 5869e048634d9a4d71a71c6cb54bc1625fa8e487 +Subproject commit 336b87f29e3d57d19cdd8625e57985502da1d913 From bd5248676754ae937ed44d15c1e3a19256efcfc2 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Apr 2026 11:08:17 -0700 Subject: [PATCH 02/30] register nlevgrnd to pass to fates for initialization --- components/elm/src/main/elmfates_interfaceMod.F90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index b69ab053ea65..f53dabbf5a3d 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -87,6 +87,7 @@ module ELMFatesInterfaceMod use elm_varpar , only : ivis use elm_varpar , only : inir use elm_varpar , only : nlevsoi + use elm_varpar , only : nlevgrnd use elm_varpar , only : nlevdecomp use elm_varpar , only : nlevdecomp_full use elm_varpar , only : i_met_lit, i_cel_lit, i_lig_lit @@ -4053,6 +4054,8 @@ subroutine RegisterInterfaceVariablesInit(this, nc) ! Register and initialize the boundary condition variables ! Global variables + call this%fates(nc)%registry(r)%Register(key=hlm_fates_nlevground, & + data=nlevgrnd, hlm_flag=.true.) call this%fates(nc)%registry(r)%Register(key=hlm_fates_decomp, & data=nlevdecomp, hlm_flag=.true.) call this%fates(nc)%registry(r)%Register(key=hlm_fates_decomp_max, & From a4b45cffe2bd775b8e1f6aa5d00e23080ffe4036 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Apr 2026 13:42:29 -0700 Subject: [PATCH 03/30] remove assignment of unused boundary conditions --- components/elm/src/main/elmfates_interfaceMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index f53dabbf5a3d..77d33293e7e9 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -3146,8 +3146,6 @@ subroutine wrap_update_hifrq_hist(this, bounds_clump ) do s = 1, this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) this%fates(nc)%bc_in(s)%tot_het_resp = hr(c) - this%fates(nc)%bc_in(s)%tot_somc = totsomc(c) - this%fates(nc)%bc_in(s)%tot_litc = totlitc(c) end do ! Update history variables that track these variables From d3f14d48c7a021fb76fd18525c3c7c9a1e93d29f Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 23 Apr 2026 15:57:12 -0700 Subject: [PATCH 04/30] add subgrid type argument to max thaw fates interface registration --- components/elm/src/main/elmfates_interfaceMod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 77d33293e7e9..a442d709d0e2 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -4152,7 +4152,7 @@ end subroutine RegisterInterfaceVariablesInit subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst) - use FatesInterfaceParametersMod, only : hlm_fates_thaw_max_depth_index + use FatesInterfaceParametersMod class(hlm_fates_interface_type), intent(inout) :: this integer, intent(in) :: nc @@ -4169,7 +4169,9 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst) c = this%fates(nc)%registry(r)%GetColumnIndex() call this%fates(nc)%registry(r)%Register(key=hlm_fates_thaw_max_depth_index, & - data=canopystate_inst%altmax_lastyear_indx_col(c), hlm_flag=.true.) + data=canopystate_inst%altmax_lastyear_indx_col(c), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) end do end subroutine RegisterInterfaceVariablesColdStart From 8599cc23ee9adeac95fe396f3e3add86263571e8 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 29 Apr 2026 10:57:52 -0700 Subject: [PATCH 05/30] move effective porosity to coldstart interface proc --- components/elm/src/external_models/fates | 2 +- .../elm/src/main/elmfates_interfaceMod.F90 | 21 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index 336b87f29e3d..80c3bb38302d 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit 336b87f29e3d57d19cdd8625e57985502da1d913 +Subproject commit 80c3bb38302de7daf5375c2a789dd31cfbbd292d diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index a442d709d0e2..ee9f206dce37 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -38,8 +38,8 @@ module ELMFatesInterfaceMod use CanopyStateType , only : canopystate_type use TemperatureType , only : temperature_type use EnergyFluxType , only : energyflux_type - use SoilStateType , only : soilstate_type + use elm_varctl , only : iulog use elm_varctl , only : use_fates use elm_varctl , only : use_vertsoilc @@ -1979,7 +1979,7 @@ subroutine restart( this, bounds_proc, ncid, flag, & ! Register interface variables handled normally during cold start - call this%RegisterInterfaceVariablesColdStart(nc, canopystate_inst) + call this%RegisterInterfaceVariablesColdStart(nc, canopystate_inst, soilstate_inst) ! Update the interface variables call this%fates(nc)%UpdateInterfaceVariables(restarting=.true.) @@ -2151,7 +2151,7 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in if ( this%fates(nc)%nsites>0 ) then ! Register interface variables - call this%RegisterInterfaceVariablesColdStart(nc, canopystate_inst) + call this%RegisterInterfaceVariablesColdStart(nc, canopystate_inst, soilstate_inst) ! Update the interface variables call this%fates(nc)%UpdateInterfaceVariables(initialize=.true.) @@ -2514,7 +2514,6 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & do j = 1,nlevsoil this%fates(nc)%bc_in(s)%tempk_sl(j) = t_soisno(c,j) this%fates(nc)%bc_in(s)%h2o_liqvol_sl(j) = h2osoi_liqvol(c,j) - this%fates(nc)%bc_in(s)%eff_porosity_sl(j) = eff_porosity(c,j) this%fates(nc)%bc_in(s)%watsat_sl(j) = watsat(c,j) end do @@ -2522,12 +2521,14 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & this%fates(nc)%bc_in(s)%filter_btran = .false. this%fates(nc)%bc_in(s)%tempk_sl(:) = -999._r8 this%fates(nc)%bc_in(s)%h2o_liqvol_sl(:) = -999._r8 - this%fates(nc)%bc_in(s)%eff_porosity_sl(:) = -999._r8 this%fates(nc)%bc_in(s)%watsat_sl(:) = -999._r8 end if end do + ! Update the interface variables that work on the model time step now + call this%fates(nc)%UpdateInterfaceVariablesTimeStep() + ! ------------------------------------------------------------------------------- ! This function evaluates the ground layer to determine if ! root water uptake can happen, and soil suction should even @@ -3681,8 +3682,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & soilstate_inst%bsw_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%h2o_liq_sisl(1:nlevsoil) = & col_ws%h2osoi_liq(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%eff_porosity_sl(1:nlevsoil) = & - soilstate_inst%eff_porosity_col(c,1:nlevsoil) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno p = ifp+col_pp%pfti(c) @@ -4150,13 +4149,14 @@ end subroutine RegisterInterfaceVariablesInit ! ====================================================================================== -subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst) +subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soilstate_inst) use FatesInterfaceParametersMod class(hlm_fates_interface_type), intent(inout) :: this integer, intent(in) :: nc type(canopystate_type), intent(inout) :: canopystate_inst + type(soilstate_type), intent(inout) :: soilstate_inst ! Locals integer :: r ! register index @@ -4172,6 +4172,11 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst) data=canopystate_inst%altmax_lastyear_indx_col(c), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_effective_porosity, & + data=soilstate_inst%eff_porosity_col(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) + end do end subroutine RegisterInterfaceVariablesColdStart From b6044e50d3dd88f4e3b487b9d0a9c9d2692ae1bb Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 29 Apr 2026 10:41:15 -0700 Subject: [PATCH 06/30] add watsat_col to the coldstart interface proc --- components/elm/src/main/elmfates_interfaceMod.F90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index ee9f206dce37..824719017b40 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2471,7 +2471,6 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & associate(& sucsat => soilstate_inst%sucsat_col , & ! Input: [real(r8) (:,:) ] minimum soil suction (mm) - watsat => soilstate_inst%watsat_col , & ! Input: [real(r8) (:,:) ] volumetric soil water at saturation (porosity) bsw => soilstate_inst%bsw_col , & ! Input: [real(r8) (:,:) ] Clapp and Hornberger "b" eff_porosity => soilstate_inst%eff_porosity_col , & ! Input: [real(r8) (:,:) ] effective porosity = porosity - vol_ice t_soisno => col_es%t_soisno , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) @@ -2514,14 +2513,12 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & do j = 1,nlevsoil this%fates(nc)%bc_in(s)%tempk_sl(j) = t_soisno(c,j) this%fates(nc)%bc_in(s)%h2o_liqvol_sl(j) = h2osoi_liqvol(c,j) - this%fates(nc)%bc_in(s)%watsat_sl(j) = watsat(c,j) end do else this%fates(nc)%bc_in(s)%filter_btran = .false. this%fates(nc)%bc_in(s)%tempk_sl(:) = -999._r8 this%fates(nc)%bc_in(s)%h2o_liqvol_sl(:) = -999._r8 - this%fates(nc)%bc_in(s)%watsat_sl(:) = -999._r8 end if end do @@ -4144,7 +4141,7 @@ subroutine RegisterInterfaceVariablesInit(this, nc) subgrid_type=registry_var_intid_column) end if end do - + end subroutine RegisterInterfaceVariablesInit ! ====================================================================================== @@ -4176,6 +4173,10 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils data=soilstate_inst%eff_porosity_col(c,:), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_water_saturation, & + data=soilstate_inst%watsat_col(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) end do From e2c83ffcb1db0c789947c6229e8a92219eeb637d Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 23 Apr 2026 15:59:58 -0700 Subject: [PATCH 07/30] add heterotrophic respiration to the fates interface registration and update call --- components/elm/src/main/elmfates_interfaceMod.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 824719017b40..bf7f295264e1 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -3140,11 +3140,8 @@ subroutine wrap_update_hifrq_hist(this, bounds_clump ) nc = bounds_clump%clump_index dtime = real(get_step_size(),r8) - ! Summarize Net Fluxes - do s = 1, this%fates(nc)%nsites - c = this%f2hmap(nc)%fcolumn(s) - this%fates(nc)%bc_in(s)%tot_het_resp = hr(c) - end do + ! Update model timestep (hifreq) interface variables for fates history + call this%fates(nc)%UpdateInterfaceVariablesTimeStep(update_history=.true.) ! Update history variables that track these variables call fates_hist%update_history_hifrq(nc, & @@ -4068,6 +4065,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) end if ! Variables that do not need to accumulate + call this%fates(nc)%registry(r)%Register(key=hlm_fates_heterotrophic_respiration, & + data=col_cf%hr(c), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_level, & data=col_pp%nlevbed(c), hlm_flag=.true., & subgrid_type=registry_var_intid_column) From 12e397d315ca583e384337ed196f77df3805bfd2 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 23 Apr 2026 16:34:35 -0700 Subject: [PATCH 08/30] remove max rooting depth assignment in elmfates interface This has been moved to the fates-side interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index bf7f295264e1..54393e4d2161 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1296,9 +1296,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & this%fates(nc)%bc_in(s)%h2o_liqvol_sl(1:nlevsoil) = & col_ws%h2osoi_vol(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%max_rooting_depth_index_col = & - min(nlevsoil, canopystate_inst%altmax_lastyear_indx_col(c)) - do j = 1,nlevsoil this%fates(nc)%bc_in(s)%tempk_sl(j) = col_es%t_soisno(c,j) end do @@ -1990,8 +1987,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & do s = 1,this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - this%fates(nc)%bc_in(s)%max_rooting_depth_index_col = & - min(this%fates(nc)%bc_in(s)%nlevsoil, canopystate_inst%altmax_lastyear_indx_col(c)) ! When restarting the model, this subroutine has several ! procedures that are incremental or don't need to be performed for @@ -2259,8 +2254,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in do s = 1,this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - this%fates(nc)%bc_in(s)%max_rooting_depth_index_col = this%fates(nc)%bc_in(s)%nlevdecomp - call ed_update_site(this%fates(nc)%sites(s), & this%fates(nc)%bc_in(s), & From f8aab62ebbd89036df4c2e1e806172590dfad2bd Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 7 May 2026 15:43:42 -0700 Subject: [PATCH 09/30] add snow_depth to the fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 54393e4d2161..d267e642e202 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1574,7 +1574,6 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & z0m => frictionvel_inst%z0m_patch , & ! Output: [real(r8) (:) ] momentum roughness length (m) displa => canopystate_inst%displa_patch, & dleaf_patch => canopystate_inst%dleaf_patch, & - snow_depth => col_ws%snow_depth, & frac_sno_eff => col_ws%frac_sno_eff, & frac_veg_nosno_alb => canopystate_inst%frac_veg_nosno_alb_patch) @@ -1583,7 +1582,6 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & ! -------------------------------------------------------------------------------- do s=1,this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - this%fates(nc)%bc_in(s)%snow_depth_si = snow_depth(c) this%fates(nc)%bc_in(s)%frac_sno_eff_si = frac_sno_eff(c) end do @@ -4070,6 +4068,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_decomp_frac_temperature, & data=col_cf%t_scalar(c,:), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_snow_depth, & + data=col_ws%snow_depth(c), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & From 8163bbc111d9bafebc019b7b5e9c1389fbf282b1 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 12 May 2026 16:32:47 -0700 Subject: [PATCH 10/30] add fraction of ground covered by snow to the fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index d267e642e202..613e268245a3 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1580,11 +1580,6 @@ subroutine wrap_update_hlmfates_dyn(this, nc, bounds_clump, & ! Process input boundary conditions to FATES ! -------------------------------------------------------------------------------- - do s=1,this%fates(nc)%nsites - c = this%f2hmap(nc)%fcolumn(s) - this%fates(nc)%bc_in(s)%frac_sno_eff_si = frac_sno_eff(c) - end do - ! Only update the fates internal snow burial if this is not a restart if (.not. is_initing_from_restart) then call UpdateFatesAvgSnowDepth(this%fates(nc)%sites,this%fates(nc)%bc_in) @@ -4071,6 +4066,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_snow_depth, & data=col_ws%snow_depth(c), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_snow_cover_frac, & + data=col_ws%frac_sno_eff(c), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & From 0d60a5561abc58aa3658461b2e2027583d50629f Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 12 May 2026 18:23:17 -0700 Subject: [PATCH 11/30] add h2o_liqvol into the fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 613e268245a3..a040048860d3 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1292,10 +1292,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - ! Soil water - this%fates(nc)%bc_in(s)%h2o_liqvol_sl(1:nlevsoil) = & - col_ws%h2osoi_vol(c,1:nlevsoil) - do j = 1,nlevsoil this%fates(nc)%bc_in(s)%tempk_sl(j) = col_es%t_soisno(c,j) end do @@ -2498,13 +2494,11 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & this%fates(nc)%bc_in(s)%filter_btran = .true. do j = 1,nlevsoil this%fates(nc)%bc_in(s)%tempk_sl(j) = t_soisno(c,j) - this%fates(nc)%bc_in(s)%h2o_liqvol_sl(j) = h2osoi_liqvol(c,j) end do else this%fates(nc)%bc_in(s)%filter_btran = .false. this%fates(nc)%bc_in(s)%tempk_sl(:) = -999._r8 - this%fates(nc)%bc_in(s)%h2o_liqvol_sl(:) = -999._r8 end if end do @@ -4008,10 +4002,16 @@ subroutine RegisterInterfaceVariablesInit(this, nc) integer :: r ! Register index integer :: p ! HLM patch index integer :: c ! Column index + integer :: lb ! Local lower bounds logical :: is_bareground ! Is this register associated with a bareground patch logical :: is_first ! Is this register associated with the first patch on the column, landunit, etc ! This is necessary to ensure that accumulation variables are zero'd properly + ! Set the local lower bound to be one. This is a workaround to address the fact that + ! some HLM arrays have lower bounds that are less than 1, but fates does not currently + ! use these lower bounds. + lb = 1 + ! Iterate over the number of vegetated patches do r = 1, this%fates(nc)%npatches p = this%fates(nc)%registry(r)%GetHLMPatchIndex() @@ -4069,6 +4069,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_snow_cover_frac, & data=col_ws%frac_sno_eff(c), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_h2o_liquid, & + data=col_ws%h2osoi_liqvol(c,lb:), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & From 6a3b0cadd0bd04ab8ec3133299164ad22487ffa5 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 13 May 2026 14:34:44 -0700 Subject: [PATCH 12/30] add soil temperature to the fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index a040048860d3..7de4fa1ad2a3 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1291,10 +1291,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & end if nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - - do j = 1,nlevsoil - this%fates(nc)%bc_in(s)%tempk_sl(j) = col_es%t_soisno(c,j) - end do call get_active_suction_layers(this%fates(nc)%nsites, & this%fates(nc)%sites, & @@ -2490,15 +2486,9 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & ! Check to see if this column is in the exposed veg filter if( any(filterc==c) )then - this%fates(nc)%bc_in(s)%filter_btran = .true. - do j = 1,nlevsoil - this%fates(nc)%bc_in(s)%tempk_sl(j) = t_soisno(c,j) - end do - else this%fates(nc)%bc_in(s)%filter_btran = .false. - this%fates(nc)%bc_in(s)%tempk_sl(:) = -999._r8 end if end do @@ -4072,6 +4062,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_h2o_liquid, & data=col_ws%h2osoi_liqvol(c,lb:), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_temperature, & + data=col_es%t_soisno(c,lb:), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & From 0c423203f0bb7d71657f13c3fd48b3c905b37107 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 13 May 2026 15:04:58 -0700 Subject: [PATCH 13/30] remove redundant passing of t_soisno to fates --- components/elm/src/main/elmfates_interfaceMod.F90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 7de4fa1ad2a3..6b0497f50d72 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2630,11 +2630,6 @@ subroutine wrap_photosynthesis(this, bounds_clump, fn, filterp, & c = this%f2hmap(nc)%fcolumn(s) t = col_pp%topounit(c) - nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - - do j = 1,nlevsoil - this%fates(nc)%bc_in(s)%t_soisno_sl(j) = t_soisno(c,j) ! soil temperature (Kelvin) - end do this%fates(nc)%bc_in(s)%forc_pbot = forc_pbot(t) ! atmospheric pressure (Pa) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno @@ -4066,6 +4061,13 @@ subroutine RegisterInterfaceVariablesInit(this, nc) data=col_es%t_soisno(c,lb:), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + ! Register variables related to plant hydraulics if necessary + if (use_fates_planthydro) then + call this%fates(nc)%registry(r)%Register(key=hlm_fates_liquid_water, & + data=col_ws%h2osoi_liq(c,lb:), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) + end if + ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & data=col_cf%decomp_cpools_sourcesink(c,1:nlevdecomp,i_cel_lit), & From fcc784d33a36e0fc8bdddd9215c4560e287b8a4d Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 13 May 2026 16:06:45 -0700 Subject: [PATCH 14/30] add min of soil potential to fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 6b0497f50d72..1597e547c0de 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -3629,8 +3629,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & c = this%f2hmap(nc)%fcolumn(s) nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - this%fates(nc)%bc_in(s)%smpmin_si = & - soilstate_inst%smpmin_col(c) this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & soilstate_inst%watsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & @@ -4168,6 +4166,13 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils hlm_flag=.true., & subgrid_type=registry_var_intid_column) + if (use_fates_planthydro) then + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_potential_min, & + data=soilstate_inst%smpmin_col(c), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) + end if + end do end subroutine RegisterInterfaceVariablesColdStart From 07053104c3f4269ffdf04229162bc29a26e70d72 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 14 May 2026 16:15:15 -0700 Subject: [PATCH 15/30] add h2osoi_liq to the fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 1597e547c0de..aae758ec72ef 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1341,7 +1341,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = soilstate_inst%watmin_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = soilstate_inst%sucsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = soilstate_inst%bsw_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%h2o_liq_sisl(1:nlevsoil) = col_ws%h2osoi_liq(c,1:nlevsoil) end if ! get the harvest data, which is by gridcell @@ -2033,9 +2032,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & soilstate_inst%bsw_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%h2o_liq_sisl(1:nlevsoil) = & - col_ws%h2osoi_liq(c,1:nlevsoil) - end do call RestartHydrStates(this%fates(nc)%sites, & @@ -2189,9 +2185,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & soilstate_inst%bsw_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%h2o_liq_sisl(1:nlevsoil) = & - col_ws%h2osoi_liq(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%hksat_sisl(1:nlevsoil) = & soilstate_inst%hksat_col(c,1:nlevsoil) @@ -3637,8 +3630,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & soilstate_inst%sucsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & soilstate_inst%bsw_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%h2o_liq_sisl(1:nlevsoil) = & - col_ws%h2osoi_liq(c,1:nlevsoil) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno p = ifp+col_pp%pfti(c) From bfb039d9252651844919904254db0c0e5c47b6e3 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 22 May 2026 10:17:43 -0700 Subject: [PATCH 16/30] add saturated soil conductivity to fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index aae758ec72ef..12717397fb09 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1336,7 +1336,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & end if ! SP if(use_fates_planthydro)then - this%fates(nc)%bc_in(s)%hksat_sisl(1:nlevsoil) = soilstate_inst%hksat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = soilstate_inst%watsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = soilstate_inst%watmin_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = soilstate_inst%sucsat_col(c,1:nlevsoil) @@ -2017,9 +2016,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & do s = 1,this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - this%fates(nc)%bc_in(s)%hksat_sisl(1:nlevsoil) = & - soilstate_inst%hksat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & soilstate_inst%watsat_col(c,1:nlevsoil) @@ -2185,9 +2181,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & soilstate_inst%bsw_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%hksat_sisl(1:nlevsoil) = & - soilstate_inst%hksat_col(c,1:nlevsoil) - do j = 1, nlevsoil vol_ice = min(soilstate_inst%watsat_col(c,j), & col_ws%h2osoi_ice(c,j)/(col_pp%dz(c,j)*denice)) @@ -4162,6 +4155,10 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils data=soilstate_inst%smpmin_col(c), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_saturated_hydr_cond, & + data=soilstate_inst%hksat_col(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) end if end do From 1137814d098d1c839a356fdc5e225d65d27ff493 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 22 May 2026 09:51:01 -0700 Subject: [PATCH 17/30] add clapp and hornberger to fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 12717397fb09..c1f5fb49f583 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1339,7 +1339,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = soilstate_inst%watsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = soilstate_inst%watmin_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = soilstate_inst%sucsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = soilstate_inst%bsw_col(c,1:nlevsoil) end if ! get the harvest data, which is by gridcell @@ -2025,9 +2024,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = & soilstate_inst%sucsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & - soilstate_inst%bsw_col(c,1:nlevsoil) - end do call RestartHydrStates(this%fates(nc)%sites, & @@ -2178,9 +2174,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = & soilstate_inst%sucsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & - soilstate_inst%bsw_col(c,1:nlevsoil) - do j = 1, nlevsoil vol_ice = min(soilstate_inst%watsat_col(c,j), & col_ws%h2osoi_ice(c,j)/(col_pp%dz(c,j)*denice)) @@ -3621,8 +3614,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & soilstate_inst%watmin_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = & soilstate_inst%sucsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%bsw_sisl(1:nlevsoil) = & - soilstate_inst%bsw_col(c,1:nlevsoil) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno p = ifp+col_pp%pfti(c) @@ -4159,6 +4150,10 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils data=soilstate_inst%hksat_col(c,:), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_clapp_hornberger_b, & + data=soilstate_inst%bsw_col(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) end if end do From 53835e2affaaa5ae63d0a28114a0673d3a5a57f6 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 22 May 2026 10:01:18 -0700 Subject: [PATCH 18/30] add minimum soil suction to fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index c1f5fb49f583..50be3e612b09 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1338,7 +1338,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & if(use_fates_planthydro)then this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = soilstate_inst%watsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = soilstate_inst%watmin_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = soilstate_inst%sucsat_col(c,1:nlevsoil) end if ! get the harvest data, which is by gridcell @@ -2021,9 +2020,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & soilstate_inst%watmin_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = & - soilstate_inst%sucsat_col(c,1:nlevsoil) - end do call RestartHydrStates(this%fates(nc)%sites, & @@ -2171,9 +2167,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & soilstate_inst%watmin_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = & - soilstate_inst%sucsat_col(c,1:nlevsoil) - do j = 1, nlevsoil vol_ice = min(soilstate_inst%watsat_col(c,j), & col_ws%h2osoi_ice(c,j)/(col_pp%dz(c,j)*denice)) @@ -3612,8 +3605,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & soilstate_inst%watsat_col(c,1:nlevsoil) this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & soilstate_inst%watmin_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%sucsat_sisl(1:nlevsoil) = & - soilstate_inst%sucsat_col(c,1:nlevsoil) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno p = ifp+col_pp%pfti(c) @@ -4154,6 +4145,10 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils data=soilstate_inst%bsw_col(c,:), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_suction_min, & + data=soilstate_inst%sucsat_col(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) end if end do From ea8c7ab49a309f22c42aca7a112e8f11eaf15d20 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 22 May 2026 10:38:22 -0700 Subject: [PATCH 19/30] add minimum volumetric soil water to fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 50be3e612b09..016caf473a0a 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1337,7 +1337,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & if(use_fates_planthydro)then this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = soilstate_inst%watsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = soilstate_inst%watmin_col(c,1:nlevsoil) end if ! get the harvest data, which is by gridcell @@ -2017,9 +2016,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & soilstate_inst%watsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & - soilstate_inst%watmin_col(c,1:nlevsoil) - end do call RestartHydrStates(this%fates(nc)%sites, & @@ -2164,9 +2160,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & soilstate_inst%watsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & - soilstate_inst%watmin_col(c,1:nlevsoil) - do j = 1, nlevsoil vol_ice = min(soilstate_inst%watsat_col(c,j), & col_ws%h2osoi_ice(c,j)/(col_pp%dz(c,j)*denice)) @@ -3603,8 +3596,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & soilstate_inst%watsat_col(c,1:nlevsoil) - this%fates(nc)%bc_in(s)%watres_sisl(1:nlevsoil) = & - soilstate_inst%watmin_col(c,1:nlevsoil) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno p = ifp+col_pp%pfti(c) @@ -4149,6 +4140,10 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils data=soilstate_inst%sucsat_col(c,:), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_water_vol_min, & + data=soilstate_inst%watmin_col(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) end if end do From db326ce1bda6e6547c2f62f75b553a51ca3bdece Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 22 May 2026 10:53:34 -0700 Subject: [PATCH 20/30] remove redundant fates boundary condition using watsat_col --- .../elm/src/main/elmfates_interfaceMod.F90 | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 016caf473a0a..37be64dcd868 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1335,10 +1335,6 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & end do ! p end if ! SP - if(use_fates_planthydro)then - this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = soilstate_inst%watsat_col(c,1:nlevsoil) - end if - ! get the harvest data, which is by gridcell ! for now there is one veg column per gridcell, so store all harvest data in each site ! this will eventually change @@ -2010,14 +2006,6 @@ subroutine restart( this, bounds_proc, ncid, flag, & ! ------------------------------------------------------------------------ if (use_fates_planthydro) then - do s = 1,this%fates(nc)%nsites - c = this%f2hmap(nc)%fcolumn(s) - nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & - soilstate_inst%watsat_col(c,1:nlevsoil) - - end do - call RestartHydrStates(this%fates(nc)%sites, & this%fates(nc)%nsites, & this%fates(nc)%bc_in, & @@ -2157,9 +2145,6 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in c = this%f2hmap(nc)%fcolumn(s) nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & - soilstate_inst%watsat_col(c,1:nlevsoil) - do j = 1, nlevsoil vol_ice = min(soilstate_inst%watsat_col(c,j), & col_ws%h2osoi_ice(c,j)/(col_pp%dz(c,j)*denice)) @@ -3592,10 +3577,6 @@ subroutine wrap_hydraulics_drive(this, bounds_clump, & do s = 1, this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - nlevsoil = this%fates(nc)%bc_in(s)%nlevsoil - - this%fates(nc)%bc_in(s)%watsat_sisl(1:nlevsoil) = & - soilstate_inst%watsat_col(c,1:nlevsoil) do ifp = 1, this%fates(nc)%sites(s)%youngest_patch%patchno p = ifp+col_pp%pfti(c) From f4bfafea24c2d422f7882bbed1dcf3b89a0659df Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 2 Jun 2026 16:02:15 -0700 Subject: [PATCH 21/30] add new gpp variable to hold incoming fates values This is to facilitate associating a single elm variable with the fates gpp_site variable through the fates interface registry. Alternatively, the nep value could have been associated with a new variable on the fates side. --- components/elm/src/data_types/ColumnDataType.F90 | 7 +++++++ components/elm/src/external_models/fates | 2 +- components/elm/src/main/elmfates_interfaceMod.F90 | 11 +++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index 6582814c416c..9e5c7cbc0075 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -657,6 +657,7 @@ module ColumnDataType real(r8), pointer :: rr_vr (:,:) => null() ! column (gC/m2/s) root respiration (fine root MR + total root GR) (p2c) real(r8), pointer :: ar (:) => null() ! column (gC/m2/s) autotrophic respiration (MR + GR) (p2c) real(r8), pointer :: gpp (:) => null() ! column (gC/m2/s) GPP flux before downregulation (p2c) + real(r8), pointer :: gpp_fates (:) => null() ! column (gC/m2/s) GPP flux from FATES real(r8), pointer :: npp (:) => null() ! column (gC/m2/s) net primary production (p2c) real(r8), pointer :: fire_closs_p2c (:) => null() ! column (gC/m2/s) patch2col averaged column-level fire C loss (p2c) real(r8), pointer :: fire_closs (:) => null() ! column (gC/m2/s) total patch-level fire C loss @@ -6262,6 +6263,7 @@ subroutine col_cf_init(this, begc, endc, carbon_type) allocate(this%rr_vr(begc:endc,1:nlevdecomp_full)); this%rr_vr(:,:) = spval allocate(this%ar (begc:endc)) ; this%ar (:) = spval allocate(this%gpp (begc:endc)) ; this%gpp (:) = spval + allocate(this%gpp_fates (begc:endc)) ; this%gpp_fates (:) = spval allocate(this%npp (begc:endc)) ; this%npp (:) = spval allocate(this%fire_closs_p2c (begc:endc)) ; this%fire_closs_p2c (:) = spval allocate(this%fire_closs (begc:endc)) ; this%fire_closs (:) = spval @@ -7981,6 +7983,10 @@ subroutine col_cf_setvalues ( this, num_column, filter_column, value_column) this%vegfire(i) = value_column this%wood_harvestc(i) = value_column this%hrv_xsmrpool_to_atm(i) = value_column + + ! Zero fates column fluxes + this%gpp_fates(i) = value_column + end do if(use_crop) then @@ -8034,6 +8040,7 @@ subroutine col_cf_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) do fc = 1,num_soilc c = filter_soilc(fc) this%gpp(c) = 0._r8 + this%gpp_fates(c) = 0._r8 this%ar(c) = 0._r8 this%npp(c) = 0._r8 this%vegfire(c) = 0._r8 diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index 80c3bb38302d..ea8802282efd 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit 80c3bb38302de7daf5375c2a789dd31cfbbd292d +Subproject commit ea8802282efd89621648433607426ed1c0f14b9e diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 37be64dcd868..a5e0828c5735 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2749,7 +2749,8 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) nee => col_cf%nee , & nbp => col_cf%nbp , & product_closs => col_cf%product_closs , & - hr => col_cf%hr) + hr => col_cf%hr, & + gpp_fates => col_cf%gpp_fates) nc = bounds_clump%clump_index ! Loop over columns @@ -2757,7 +2758,7 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) c = filterc(icc) s = this%f2hmap(nc)%hsites(c) - nep(c) = this%fates(nc)%bc_out(s)%gpp_site*g_per_kg & + nep(c) = gpp_fates(c) & - this%fates(nc)%bc_out(s)%ar_site*g_per_kg & - hr(c) @@ -4004,6 +4005,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) subgrid_type=registry_var_intid_column) end if + call this%fates(nc)%registry(r)%Register(key=hlm_fates_gpp, data=col_cf%gpp_fates(c), & + hlm_flag=.true., subgrid_type=registry_var_intid_column) + ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & data=col_cf%decomp_cpools_sourcesink(c,1:nlevdecomp,i_cel_lit), & @@ -4017,6 +4021,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) data=col_cf%decomp_cpools_sourcesink(c,1:nlevdecomp,i_met_lit), & hlm_flag=.true., accumulate=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_gpp, data=col_cf%gpp_fates(c), & + hlm_flag=.true., accumulate=.true., & + subgrid_type=registry_var_intid_column) ! Pass is_first option to assure HLM updates are zero'd call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_total, & From 004d98bae055bcf717f5cdaad3438f829dca0f90 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 2 Jun 2026 17:05:01 -0700 Subject: [PATCH 22/30] add new aresp fates variable and add to fates interface registry --- components/elm/src/data_types/ColumnDataType.F90 | 4 ++++ components/elm/src/external_models/fates | 2 +- components/elm/src/main/elmfates_interfaceMod.F90 | 14 +++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index 9e5c7cbc0075..c28c06c023c8 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -656,6 +656,7 @@ module ColumnDataType real(r8), pointer :: rr (:) => null() ! column (gC/m2/s) root respiration (fine root MR + total root GR) (p2c) real(r8), pointer :: rr_vr (:,:) => null() ! column (gC/m2/s) root respiration (fine root MR + total root GR) (p2c) real(r8), pointer :: ar (:) => null() ! column (gC/m2/s) autotrophic respiration (MR + GR) (p2c) + real(r8), pointer :: ar_fates (:) => null() ! column (gC/m2/s) autotrophic respiration from FATES real(r8), pointer :: gpp (:) => null() ! column (gC/m2/s) GPP flux before downregulation (p2c) real(r8), pointer :: gpp_fates (:) => null() ! column (gC/m2/s) GPP flux from FATES real(r8), pointer :: npp (:) => null() ! column (gC/m2/s) net primary production (p2c) @@ -6262,6 +6263,7 @@ subroutine col_cf_init(this, begc, endc, carbon_type) allocate(this%rr (begc:endc)) ; this%rr (:) = spval allocate(this%rr_vr(begc:endc,1:nlevdecomp_full)); this%rr_vr(:,:) = spval allocate(this%ar (begc:endc)) ; this%ar (:) = spval + allocate(this%ar_fates (begc:endc)) ; this%ar_fates (:) = spval allocate(this%gpp (begc:endc)) ; this%gpp (:) = spval allocate(this%gpp_fates (begc:endc)) ; this%gpp_fates (:) = spval allocate(this%npp (begc:endc)) ; this%npp (:) = spval @@ -7986,6 +7988,7 @@ subroutine col_cf_setvalues ( this, num_column, filter_column, value_column) ! Zero fates column fluxes this%gpp_fates(i) = value_column + this%ar_fates(i) = value_column end do @@ -8042,6 +8045,7 @@ subroutine col_cf_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) this%gpp(c) = 0._r8 this%gpp_fates(c) = 0._r8 this%ar(c) = 0._r8 + this%ar_fates(c) = 0._r8 this%npp(c) = 0._r8 this%vegfire(c) = 0._r8 this%wood_harvestc(c) = 0._r8 diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index ea8802282efd..5ba4ac0b9872 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit ea8802282efd89621648433607426ed1c0f14b9e +Subproject commit 5ba4ac0b9872fd3427cc83348aafc31cee611403 diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index a5e0828c5735..da4ef12e6af0 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2750,7 +2750,8 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) nbp => col_cf%nbp , & product_closs => col_cf%product_closs , & hr => col_cf%hr, & - gpp_fates => col_cf%gpp_fates) + gpp_fates => col_cf%gpp_fates, & + ar_fates => col_cf%ar_fates) nc = bounds_clump%clump_index ! Loop over columns @@ -2758,9 +2759,7 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) c = filterc(icc) s = this%f2hmap(nc)%hsites(c) - nep(c) = gpp_fates(c) & - - this%fates(nc)%bc_out(s)%ar_site*g_per_kg & - - hr(c) + nep(c) = gpp_fates(c) - ar_fates(c) - hr(c) nbp(c) = nep(c) & - this%fates(nc)%bc_out(s)%grazing_closs_to_atm_si*g_per_kg & @@ -4005,9 +4004,6 @@ subroutine RegisterInterfaceVariablesInit(this, nc) subgrid_type=registry_var_intid_column) end if - call this%fates(nc)%registry(r)%Register(key=hlm_fates_gpp, data=col_cf%gpp_fates(c), & - hlm_flag=.true., subgrid_type=registry_var_intid_column) - ! Variables that need to accumulate call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_cellulose, & data=col_cf%decomp_cpools_sourcesink(c,1:nlevdecomp,i_cel_lit), & @@ -4024,6 +4020,10 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_gpp, data=col_cf%gpp_fates(c), & hlm_flag=.true., accumulate=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_ar, data=col_cf%ar_fates(c), & + hlm_flag=.true., accumulate=.true., & + subgrid_type=registry_var_intid_column) + ! Pass is_first option to assure HLM updates are zero'd call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_total, & From 4a7800e03d6c3c17ad37f4c8d44c2cecd6c006e5 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 3 Jun 2026 11:49:20 -0700 Subject: [PATCH 23/30] add grazing loss diagnostic from fates via interface registry --- components/elm/src/data_types/ColumnDataType.F90 | 4 ++++ components/elm/src/external_models/fates | 2 +- components/elm/src/main/elmfates_interfaceMod.F90 | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index c28c06c023c8..2f88c9c946d1 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -644,6 +644,7 @@ module ColumnDataType real(r8), pointer :: nep (:) => null() ! (gC/m2/s) net ecosystem production, excludes fire, landuse, and harvest flux, positive for sink real(r8), pointer :: nbp (:) => null() ! (gC/m2/s) net biome production, includes fire, landuse, and harvest flux, positive for sink real(r8), pointer :: nee (:) => null() ! (gC/m2/s) net ecosystem exchange of carbon, includes fire, landuse, harvest, and hrv_xsmrpool flux, positive for source + real(r8), pointer :: grazing_loss_atm_fates (:) => null() ! (gC/m2/s) loss of carbon to atmosphere from grazing in FATES real(r8), pointer :: cinputs (:) => null() ! column-level C inputs (gC/m2/s) real(r8), pointer :: coutputs (:) => null() ! column-level C outputs (gC/m2/s) ! CLAMP summary (diagnostic) flux variables, not involved in mass balance @@ -6253,6 +6254,7 @@ subroutine col_cf_init(this, begc, endc, carbon_type) allocate(this%nep (begc:endc)) ; this%nep (:) = spval allocate(this%nbp (begc:endc)) ; this%nbp (:) = spval allocate(this%nee (begc:endc)) ; this%nee (:) = spval + allocate(this%grazing_loss_atm_fates (begc:endc)) ; this%grazing_loss_atm_fates (:) = spval allocate(this%cinputs (begc:endc)) ; this%cinputs (:) = spval allocate(this%coutputs (begc:endc)) ; this%coutputs (:) = spval allocate(this%bgc_cpool_ext_inputs_vr (begc:endc, 1:nlevdecomp_full,ndecomp_pools)) ; this%bgc_cpool_ext_inputs_vr(:,:,:) = spval @@ -7989,6 +7991,7 @@ subroutine col_cf_setvalues ( this, num_column, filter_column, value_column) ! Zero fates column fluxes this%gpp_fates(i) = value_column this%ar_fates(i) = value_column + this%grazing_loss_atm_fates(i)= value_column end do @@ -8052,6 +8055,7 @@ subroutine col_cf_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) this%fire_closs_p2c(c) = 0._r8 !this%litfall(c) = 0._r8 (overwritten) this%hrv_xsmrpool_to_atm(c) = 0._r8 + this%grazing_loss_atm_fates(c) = 0._r8 end do diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index 5ba4ac0b9872..e7d3c81ddc14 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit 5ba4ac0b9872fd3427cc83348aafc31cee611403 +Subproject commit e7d3c81ddc14b663cfb2403be089a202d2341a21 diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index da4ef12e6af0..414f6b024fa8 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2751,7 +2751,8 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) product_closs => col_cf%product_closs , & hr => col_cf%hr, & gpp_fates => col_cf%gpp_fates, & - ar_fates => col_cf%ar_fates) + ar_fates => col_cf%ar_fates, & + grazing_loss_atm_fates => col_cf%grazing_loss_atm_fates) nc = bounds_clump%clump_index ! Loop over columns @@ -2762,7 +2763,7 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) nep(c) = gpp_fates(c) - ar_fates(c) - hr(c) nbp(c) = nep(c) & - - this%fates(nc)%bc_out(s)%grazing_closs_to_atm_si*g_per_kg & + - grazing_loss_atm_fates(c) & - this%fates(nc)%bc_out(s)%fire_closs_to_atm_si*g_per_kg & - product_closs(c) @@ -4023,6 +4024,10 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_ar, data=col_cf%ar_fates(c), & hlm_flag=.true., accumulate=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_grazing_loss_atm, & + data=col_cf%grazing_loss_atm_fates(c), & + hlm_flag=.true., accumulate=.true., & + subgrid_type=registry_var_intid_column) ! Pass is_first option to assure HLM updates are zero'd From 3f1b3fa497fe51647e2ef7203d65f82d1a7c1b72 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 3 Jun 2026 15:50:26 -0700 Subject: [PATCH 24/30] add fire carbon loss diagnostic variable and update via fates interface registry --- components/elm/src/data_types/ColumnDataType.F90 | 4 ++++ components/elm/src/external_models/fates | 2 +- components/elm/src/main/elmfates_interfaceMod.F90 | 13 +++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index 2f88c9c946d1..34801197d34b 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -645,6 +645,7 @@ module ColumnDataType real(r8), pointer :: nbp (:) => null() ! (gC/m2/s) net biome production, includes fire, landuse, and harvest flux, positive for sink real(r8), pointer :: nee (:) => null() ! (gC/m2/s) net ecosystem exchange of carbon, includes fire, landuse, harvest, and hrv_xsmrpool flux, positive for source real(r8), pointer :: grazing_loss_atm_fates (:) => null() ! (gC/m2/s) loss of carbon to atmosphere from grazing in FATES + real(r8), pointer :: fire_loss_atm_fates (:) => null() ! (gC/m2/s) loss of carbon to atmosphere from fire in FATES real(r8), pointer :: cinputs (:) => null() ! column-level C inputs (gC/m2/s) real(r8), pointer :: coutputs (:) => null() ! column-level C outputs (gC/m2/s) ! CLAMP summary (diagnostic) flux variables, not involved in mass balance @@ -6255,6 +6256,7 @@ subroutine col_cf_init(this, begc, endc, carbon_type) allocate(this%nbp (begc:endc)) ; this%nbp (:) = spval allocate(this%nee (begc:endc)) ; this%nee (:) = spval allocate(this%grazing_loss_atm_fates (begc:endc)) ; this%grazing_loss_atm_fates (:) = spval + allocate(this%fire_loss_atm_fates (begc:endc)) ; this%fire_loss_atm_fates (:) = spval allocate(this%cinputs (begc:endc)) ; this%cinputs (:) = spval allocate(this%coutputs (begc:endc)) ; this%coutputs (:) = spval allocate(this%bgc_cpool_ext_inputs_vr (begc:endc, 1:nlevdecomp_full,ndecomp_pools)) ; this%bgc_cpool_ext_inputs_vr(:,:,:) = spval @@ -7992,6 +7994,7 @@ subroutine col_cf_setvalues ( this, num_column, filter_column, value_column) this%gpp_fates(i) = value_column this%ar_fates(i) = value_column this%grazing_loss_atm_fates(i)= value_column + this%fire_loss_atm_fates(i) = value_column end do @@ -8056,6 +8059,7 @@ subroutine col_cf_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) !this%litfall(c) = 0._r8 (overwritten) this%hrv_xsmrpool_to_atm(c) = 0._r8 this%grazing_loss_atm_fates(c) = 0._r8 + this%fire_loss_atm_fates(c) = 0._r8 end do diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index e7d3c81ddc14..ca12ac4a0ac3 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit e7d3c81ddc14b663cfb2403be089a202d2341a21 +Subproject commit ca12ac4a0ac36e49bfc8175a70846d1a8475d4dd diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 414f6b024fa8..0979f3552fbf 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2752,8 +2752,9 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) hr => col_cf%hr, & gpp_fates => col_cf%gpp_fates, & ar_fates => col_cf%ar_fates, & - grazing_loss_atm_fates => col_cf%grazing_loss_atm_fates) - + grazing_loss_atm_fates => col_cf%grazing_loss_atm_fates, & + fire_loss_atm_fates => col_cf%fire_loss_atm_fates) + nc = bounds_clump%clump_index ! Loop over columns do icc = 1,fc @@ -2764,7 +2765,7 @@ subroutine wrap_FatesAtmosphericCarbonFluxes(this, bounds_clump, fc, filterc) nbp(c) = nep(c) & - grazing_loss_atm_fates(c) & - - this%fates(nc)%bc_out(s)%fire_closs_to_atm_si*g_per_kg & + - fire_loss_atm_fates(c) & - product_closs(c) nee(c) = -nbp(c) @@ -4028,7 +4029,11 @@ subroutine RegisterInterfaceVariablesInit(this, nc) data=col_cf%grazing_loss_atm_fates(c), & hlm_flag=.true., accumulate=.true., & subgrid_type=registry_var_intid_column) - + call this%fates(nc)%registry(r)%Register(key=hlm_fates_fire_loss_atm, & + data=col_cf%fire_loss_atm_fates(c), & + hlm_flag=.true., accumulate=.true., & + subgrid_type=registry_var_intid_column) + ! Pass is_first option to assure HLM updates are zero'd call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_carbon_total, & From 7d5eb599e826c0c79b6d73153137a6e4b46b8098 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 5 Jun 2026 10:18:52 -0700 Subject: [PATCH 25/30] add totvegc to fates interface registry --- components/elm/src/main/elmfates_interfaceMod.F90 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 0979f3552fbf..b42d71737fa9 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2799,7 +2799,8 @@ subroutine wrap_FatesCarbonStocks(this, bounds_clump, fc, filterc) totecosysc => col_cs%totecosysc, & totlitc => col_cs%totlitc, & totsomc => col_cs%totsomc, & - totprodc => col_cs%totprodc) + totprodc => col_cs%totprodc, & + totvegc => col_cs%totvegc) nc = bounds_clump%clump_index ! Loop over columns @@ -2808,7 +2809,7 @@ subroutine wrap_FatesCarbonStocks(this, bounds_clump, fc, filterc) s = this%f2hmap(nc)%hsites(c) totecosysc(c) = totsomc(c) + totlitc(c) + totprodc(c) + & - this%fates(nc)%bc_out(s)%veg_c_si + & + totvegc(c) + & this%fates(nc)%bc_out(s)%litter_cwd_c_si + & this%fates(nc)%bc_out(s)%seed_c_si @@ -3998,6 +3999,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_temperature, & data=col_es%t_soisno(c,lb:), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_veg_carbon_total, & + data=col_cs%totvegc(c), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Register variables related to plant hydraulics if necessary if (use_fates_planthydro) then From 0b57a9fc30630351ad1b982c940eb2bb46ef9433 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jun 2026 12:13:16 -0700 Subject: [PATCH 26/30] add litter plus coarse woody debris fates variable --- components/elm/src/data_types/ColumnDataType.F90 | 3 +++ components/elm/src/main/elmfates_interfaceMod.F90 | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index 34801197d34b..9c907523329b 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -211,6 +211,7 @@ module ColumnDataType real(r8), pointer :: cwdc (:) => null() ! (gC/m2) Diagnostic: coarse woody debris C real(r8), pointer :: ctrunc (:) => null() ! (gC/m2) column-level sink for C truncation real(r8), pointer :: totlitc (:) => null() ! (gC/m2) total litter carbon + real(r8), pointer :: totlitc_cwd_fates (:) => null() ! (gC/m2) total litter carbon + coarse woody debris, FATES real(r8), pointer :: totsomc (:) => null() ! (gC/m2) total soil organic matter carbon real(r8), pointer :: som1c (:) => null() real(r8), pointer :: som2c (:) => null() @@ -2193,6 +2194,7 @@ subroutine col_cs_init(this, begc, endc, carbon_type, ratio, c12_carbonstate_var allocate(this%totlitc_1m (begc:endc)) ; this%totlitc_1m (:) = spval allocate(this%totsomc_1m (begc:endc)) ; this%totsomc_1m (:) = spval allocate(this%totlitc (begc:endc)) ; this%totlitc (:) = spval + allocate(this%totlitc_cwd_fates (begc:endc)) ; this%totlitc_cwd_fates (:) = spval allocate(this%totsomc (begc:endc)) ; this%totsomc (:) = spval !----------------------------------------------------------------------- @@ -3309,6 +3311,7 @@ subroutine col_cs_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) this%totvegc(c) = 0._r8 this%totvegc_abg(c) = 0._r8 this%cropseedc_deficit(c) = 0._r8 + this%totlitc_cwd_fates(c) = 0._r8 end do return diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index b42d71737fa9..8b0ff0885b5d 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2800,7 +2800,8 @@ subroutine wrap_FatesCarbonStocks(this, bounds_clump, fc, filterc) totlitc => col_cs%totlitc, & totsomc => col_cs%totsomc, & totprodc => col_cs%totprodc, & - totvegc => col_cs%totvegc) + totvegc => col_cs%totvegc, & + litt_cwdc => col_cs%totlitc_cwd_fates) nc = bounds_clump%clump_index ! Loop over columns @@ -2809,8 +2810,7 @@ subroutine wrap_FatesCarbonStocks(this, bounds_clump, fc, filterc) s = this%f2hmap(nc)%hsites(c) totecosysc(c) = totsomc(c) + totlitc(c) + totprodc(c) + & - totvegc(c) + & - this%fates(nc)%bc_out(s)%litter_cwd_c_si + & + totvegc(c) + litt_cwdc(c) + & this%fates(nc)%bc_out(s)%seed_c_si end do @@ -4002,6 +4002,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_veg_carbon_total, & data=col_cs%totvegc(c), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_cwd_carbon_total, & + data=col_cs%totlitc_cwd_fates(c), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Register variables related to plant hydraulics if necessary if (use_fates_planthydro) then From 08c12e9c6994d91824b8e3ab7d70b7f51a9f0d78 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jun 2026 12:41:03 -0700 Subject: [PATCH 27/30] add fates seed carbon variable This will be used via the fates interface registry --- components/elm/src/data_types/ColumnDataType.F90 | 3 +++ components/elm/src/main/elmfates_interfaceMod.F90 | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index 9c907523329b..a6a06d33a4a0 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -200,6 +200,7 @@ module ColumnDataType real(r8), pointer :: ctrunc_vr (:,:) => null() ! (gC/m3) vertically-resolved column-level sink for C truncation real(r8), pointer :: frootc (:) => null() ! (gC/m2) column-level C pool for fine root real(r8), pointer :: seedc (:) => null() ! (gC/m2) column-level pool for seeding new Patches + real(r8), pointer :: seedc_fates (:) => null() ! (gC/m2) column-level seed carbon from FATES real(r8), pointer :: prod1c (:) => null() ! (gC/m2) crop product C pool, 1-year lifespan real(r8), pointer :: prod10c (:) => null() ! (gC/m2) wood product C pool, 10-year lifespan real(r8), pointer :: prod100c (:) => null() ! (gC/m2) wood product C pool, 100-year lifespan @@ -2158,6 +2159,7 @@ subroutine col_cs_init(this, begc, endc, carbon_type, ratio, c12_carbonstate_var allocate(this%fuelc_crop (begc:endc)) ; this%fuelc_crop (:) = spval allocate(this%frootc (begc:endc)) ; this%frootc (:) = spval allocate(this%seedc (begc:endc)) ; this%seedc (:) = spval + allocate(this%seedc_fates (begc:endc)) ; this%seedc_fates (:) = spval allocate(this%prod1c (begc:endc)) ; this%prod1c (:) = spval allocate(this%prod10c (begc:endc)) ; this%prod10c (:) = spval allocate(this%prod100c (begc:endc)) ; this%prod100c (:) = spval @@ -3312,6 +3314,7 @@ subroutine col_cs_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) this%totvegc_abg(c) = 0._r8 this%cropseedc_deficit(c) = 0._r8 this%totlitc_cwd_fates(c) = 0._r8 + this%seedc_fates(c) = 0._r8 end do return diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 8b0ff0885b5d..c92f049191d9 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2801,7 +2801,8 @@ subroutine wrap_FatesCarbonStocks(this, bounds_clump, fc, filterc) totsomc => col_cs%totsomc, & totprodc => col_cs%totprodc, & totvegc => col_cs%totvegc, & - litt_cwdc => col_cs%totlitc_cwd_fates) + litt_cwdc => col_cs%totlitc_cwd_fates, & + seedc => col_cs%seedc_fates) nc = bounds_clump%clump_index ! Loop over columns @@ -2810,8 +2811,8 @@ subroutine wrap_FatesCarbonStocks(this, bounds_clump, fc, filterc) s = this%f2hmap(nc)%hsites(c) totecosysc(c) = totsomc(c) + totlitc(c) + totprodc(c) + & - totvegc(c) + litt_cwdc(c) + & - this%fates(nc)%bc_out(s)%seed_c_si + totvegc(c) + litt_cwdc(c) + seedc(c) + end do @@ -4005,6 +4006,9 @@ subroutine RegisterInterfaceVariablesInit(this, nc) call this%fates(nc)%registry(r)%Register(key=hlm_fates_litter_cwd_carbon_total, & data=col_cs%totlitc_cwd_fates(c), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_seed_carbon_total, & + data=col_cs%seedc_fates(c), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) ! Register variables related to plant hydraulics if necessary if (use_fates_planthydro) then From 9d3e3e8ba028c40450a8268c5cdd372adba2030c Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jun 2026 10:07:12 -0700 Subject: [PATCH 28/30] add fates decomposer biomass carbon state variable --- components/elm/src/biogeochem/AllocationMod.F90 | 3 ++- components/elm/src/data_types/ColumnDataType.F90 | 3 +++ components/elm/src/main/elmfates_interfaceMod.F90 | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/components/elm/src/biogeochem/AllocationMod.F90 b/components/elm/src/biogeochem/AllocationMod.F90 index db273ceedafd..c937bdd69405 100644 --- a/components/elm/src/biogeochem/AllocationMod.F90 +++ b/components/elm/src/biogeochem/AllocationMod.F90 @@ -24,6 +24,7 @@ module AllocationMod use LandunitType , only : lun_pp use ColumnType , only : col_pp use ColumnDataType , only : col_ws + use ColumnDataType , only : col_cs use ColumnDataType , only : col_cf, c13_col_cf, c14_col_cf use ColumnDataType , only : col_ns, col_nf, col_ps, col_pf use VegetationType , only : veg_pp @@ -1318,7 +1319,7 @@ subroutine Allocation2_ResolveNPLimit (bounds, num_soilc, filter_soilc , & else !(ECA) - decompmicc(fc,:) = elm_fates%fates(ci)%bc_out(s)%decompmicc(:) ! Should be (nlevdecomp) + decompmicc(fc,:) = col_cs%decompmicc_fates(fc,:) end if end do diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index a6a06d33a4a0..d3ace0b17e40 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -209,6 +209,7 @@ module ColumnDataType real(r8), pointer :: totpftc (:) => null() ! (gC/m2) total patch-level carbon, including cpool averaged to column (p2c) real(r8), pointer :: decomp_cpools_1m (:,:) => null() ! (gC/m2) Diagnostic: decomposing (litter, cwd, soil) c pools to 1 meter real(r8), pointer :: decomp_cpools (:,:) => null() ! (gC/m2) decomposing (litter, cwd, soil) c pools + real(r8), pointer :: decompmicc_fates (:,:) => null() ! (gC/m3) microbial decomposer biomass per decomp level, FATES real(r8), pointer :: cwdc (:) => null() ! (gC/m2) Diagnostic: coarse woody debris C real(r8), pointer :: ctrunc (:) => null() ! (gC/m2) column-level sink for C truncation real(r8), pointer :: totlitc (:) => null() ! (gC/m2) total litter carbon @@ -2191,6 +2192,7 @@ subroutine col_cs_init(this, begc, endc, carbon_type, ratio, c12_carbonstate_var allocate(this%decomp_cpools_vr (begc:endc,1:nlevdecomp_full,1:ndecomp_pools)) ; this%decomp_cpools_vr (:,:,:) = spval allocate(this%ctrunc_vr (begc:endc,1:nlevdecomp_full)) ; this%ctrunc_vr (:,:) = spval allocate(this%decomp_som2c_vr (begc:endc,1:nlevdecomp_full)) ; this%decomp_som2c_vr (:,:) = spval + allocate(this%decompmicc_fates (begc:endc,1:nlevdecomp_full)) ; this%decompmicc_fates (:,:) = spval allocate(this%decomp_cpools_1m (begc:endc,1:ndecomp_pools)) ; this%decomp_cpools_1m (:,:) = spval allocate(this%decomp_cpools (begc:endc,1:ndecomp_pools)) ; this%decomp_cpools (:,:) = spval allocate(this%totlitc_1m (begc:endc)) ; this%totlitc_1m (:) = spval @@ -3315,6 +3317,7 @@ subroutine col_cs_zero_forfates_veg(this, bounds, num_soilc, filter_soilc) this%cropseedc_deficit(c) = 0._r8 this%totlitc_cwd_fates(c) = 0._r8 this%seedc_fates(c) = 0._r8 + this%decompmicc_fates(c,:) = 0.0_r8 end do return diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index c92f049191d9..cc292ba91dde 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -4010,6 +4010,12 @@ subroutine RegisterInterfaceVariablesInit(this, nc) data=col_cs%seedc_fates(c), hlm_flag=.true., & subgrid_type=registry_var_intid_column) + if(trim(nu_com)=='ECA') then + call this%fates(nc)%registry(r)%Register(key=hlm_fates_decomposer_biomass, & + data=col_cs%decompmicc_fates(c,:), hlm_flag=.true., & + subgrid_type=registry_var_intid_column) + end if + ! Register variables related to plant hydraulics if necessary if (use_fates_planthydro) then call this%fates(nc)%registry(r)%Register(key=hlm_fates_liquid_water, & From 1e3ea5afa27d6531b6049b736b94a06fb6fa007d Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jun 2026 15:29:20 -0700 Subject: [PATCH 29/30] add soil suction potential variable for fates interface registry --- components/elm/src/biogeophys/SoilStateType.F90 | 2 ++ .../elm/src/main/elmfates_interfaceMod.F90 | 16 +++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/elm/src/biogeophys/SoilStateType.F90 b/components/elm/src/biogeophys/SoilStateType.F90 index ff4a100141ed..b4b8141efe5f 100644 --- a/components/elm/src/biogeophys/SoilStateType.F90 +++ b/components/elm/src/biogeophys/SoilStateType.F90 @@ -61,6 +61,7 @@ module SoilStateType real(r8), pointer :: watmin_col (:,:) ! col minimum volumetric soil water (nlevsoi) real(r8), pointer :: sucsat_col (:,:) ! col minimum soil suction (mm) (nlevgrnd) real(r8), pointer :: sucmin_col (:,:) ! col minimum allowable soil liquid suction pressure (mm) [Note: sucmin_col is a negative value, while sucsat_col is a positive quantity] + real(r8), pointer :: sucpot_col_fates (:,:) ! col soil suction potential (mm) [Note: sucpot_col is a negative value, while sucsat_col is a positive quantity] real(r8), pointer :: soilbeta_col (:) ! col factor that reduces ground evaporation L&P1992(-) real(r8), pointer :: soilalpha_col (:) ! col factor that reduces ground saturated specific humidity (-) real(r8), pointer :: soilalpha_u_col (:) ! col urban factor that reduces ground saturated specific humidity (-) @@ -165,6 +166,7 @@ subroutine InitAllocate(this, bounds) allocate(this%watmin_col (begc:endc,nlevgrnd)) ; this%watmin_col (:,:) = spval allocate(this%sucsat_col (begc:endc,nlevgrnd)) ; this%sucsat_col (:,:) = spval allocate(this%sucmin_col (begc:endc,nlevgrnd)) ; this%sucmin_col (:,:) = spval + allocate(this%sucpot_col_fates (begc:endc,nlevgrnd)) ; this%sucpot_col_fates (:,:) = spval allocate(this%soilbeta_col (begc:endc)) ; this%soilbeta_col (:) = spval allocate(this%soilalpha_col (begc:endc)) ; this%soilalpha_col (:) = spval allocate(this%soilalpha_u_col (begc:endc)) ; this%soilalpha_u_col (:) = spval diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index cc292ba91dde..810ac233d3c9 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -1217,7 +1217,7 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & integer :: nc ! clump index integer :: nlevsoil ! number of soil layers at the site integer :: ier ! allocate status code - real(r8) :: s_node, smp_node ! local for relative water content and potential + real(r8) :: s_node ! local for relative water content and potential logical :: nitr_suppl,phos_suppl ! Is ELM currently supplementing N or P? real(r8), pointer :: lnfm24(:) ! 24-hour averaged lightning data real(r8), pointer :: gdp_lf_col(:) ! gdp data @@ -1303,8 +1303,7 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & call soil_water_retention_curve%soil_suction(soilstate_inst%sucsat_col(c,j), & s_node, & soilstate_inst%bsw_col(c,j), & - smp_node) - this%fates(nc)%bc_in(s)%smp_sl(j) = smp_node + soilstate_inst%sucpot_col_fates(c,j)) end if end do @@ -2387,7 +2386,6 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve ! local variables - real(r8) :: smp_node ! Soil suction potential, negative, [mm] real(r8) :: s_node integer :: s integer :: c @@ -2474,11 +2472,7 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & call soil_water_retention_curve%soil_suction( soilstate_inst%sucsat_col(c,j), & s_node, & soilstate_inst%bsw_col(c,j), & - smp_node) - - ! Non-fates places a maximum (which is a negative upper bound) on smp - - this%fates(nc)%bc_in(s)%smp_sl(j) = smp_node + soilstate_inst%sucpot_col_fates(c,j)) end if end do end do @@ -4137,6 +4131,10 @@ subroutine RegisterInterfaceVariablesColdStart(this, nc, canopystate_inst, soils data=soilstate_inst%watsat_col(c,:), & hlm_flag=.true., & subgrid_type=registry_var_intid_column) + call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_suction_potential, & + data=soilstate_inst%sucpot_col_fates(c,:), & + hlm_flag=.true., & + subgrid_type=registry_var_intid_column) if (use_fates_planthydro) then call this%fates(nc)%registry(r)%Register(key=hlm_fates_soil_potential_min, & From acfcc930203effa339f53b080c38137a05c812bd Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Mon, 15 Jun 2026 15:47:43 -0700 Subject: [PATCH 30/30] call single fates interface variable procedure to update soil suction potential --- components/elm/src/main/elmfates_interfaceMod.F90 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 810ac233d3c9..599ab4979880 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -2371,7 +2371,7 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & ! ! --------------------------------------------------------------------------------- - + use FatesInterfaceParametersMod, only: hlm_fates_soil_suction_potential implicit none @@ -2477,6 +2477,9 @@ subroutine wrap_btran(this,bounds_clump,fn,filterc,soilstate_inst, & end do end do + ! Update the soil suction potential interface variable only + call this%fates(nc)%UpdateInterfaceVariable(key=hlm_fates_soil_suction_potential) + ! ------------------------------------------------------------------------------- ! Suction and active uptake layers calculated, lets calculate uptake (btran) ! This will calculate internals, as well as output boundary conditions: