Skip to content

Commit 552e9de

Browse files
authored
Merge pull request #525 from rgknox/xuchongang/HYDRO_UPDATE
fixes to hydraulics
2 parents f1d4bc5 + 5dbff93 commit 552e9de

File tree

5 files changed

+210
-104
lines changed

5 files changed

+210
-104
lines changed

biogeophys/FatesPlantHydraulicsMod.F90

Lines changed: 134 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ module FatesPlantHydraulicsMod
4040
use FatesConstantsMod, only : cm2_per_m2
4141
use FatesConstantsMod, only : g_per_kg
4242

43-
use EDParamsMod , only : hydr_kmax_rsurf
44-
43+
use EDParamsMod , only : hydr_kmax_rsurf1
44+
! use EDParamsMod , only : hydr_kmax_rsurf2
45+
4546
use EDTypesMod , only : ed_site_type
4647
use EDTypesMod , only : ed_patch_type
4748
use EDTypesMod , only : ed_cohort_type
@@ -141,6 +142,7 @@ module FatesPlantHydraulicsMod
141142
public :: CopyCohortHydraulics
142143
public :: FuseCohortHydraulics
143144
public :: updateSizeDepTreeHydProps
145+
public :: updateWaterDepTreeHydProps
144146
public :: updateSizeDepTreeHydStates
145147
public :: initTreeHydStates
146148
public :: updateSizeDepRhizHydProps
@@ -150,6 +152,7 @@ module FatesPlantHydraulicsMod
150152
public :: SavePreviousRhizVolumes
151153
public :: UpdateTreeHydrNodes
152154
public :: UpdateTreeHydrLenVolCond
155+
public :: UpdateWaterDepTreeHydrCond
153156
public :: ConstrainRecruitNumber
154157

155158
!------------------------------------------------------------------------------
@@ -325,7 +328,8 @@ subroutine initTreeHydStates(site_p, cc_p, bc_in)
325328
! watsat(c,j), watres(c,j), alpha_VG(c,j), n_VG(c,j), m_VG(c,j), l_VG(c,j), &
326329
! smp)
327330
!ccohort_hydr%psi_aroot(j) = smp
328-
ccohort_hydr%psi_aroot(j) = csite%si_hydr%psisoi_liq_innershell(j)
331+
!ccohort_hydr%psi_aroot(j) = csite%si_hydr%psisoi_liq_innershell(j)
332+
ccohort_hydr%psi_aroot(j) = -0.2_r8 !do not assume the equalibrium between soil and root
329333

330334
call th_from_psi(ft, 4, ccohort_hydr%psi_aroot(j), ccohort_hydr%th_aroot(j), csite%si_hydr, bc_in )
331335
end do
@@ -346,6 +350,7 @@ subroutine initTreeHydStates(site_p, cc_p, bc_in)
346350
!hydrostatic equilibrium with the water potential immediately below
347351
dz = ccohort_hydr%z_node_ag(n_hypool_ag) - ccohort_hydr%z_node_troot(1)
348352
ccohort_hydr%psi_ag(n_hypool_ag) = ccohort_hydr%psi_troot(1) - 1.e-6_r8*denh2o*grav*dz
353+
if (ccohort_hydr%psi_ag(n_hypool_ag)>0.0_r8) ccohort_hydr%psi_ag(n_hypool_ag) = -0.01_r8
349354
call th_from_psi(ft, 2, ccohort_hydr%psi_ag(n_hypool_ag), ccohort_hydr%th_ag(n_hypool_ag), csite%si_hydr, bc_in)
350355
do k=n_hypool_ag-1, 1, -1
351356
dz = ccohort_hydr%z_node_ag(k) - ccohort_hydr%z_node_ag(k+1)
@@ -543,9 +548,44 @@ subroutine updateSizeDepTreeHydProps(currentSite,ccohort,bc_in)
543548
! volumes, and UpdateTreeHydrNodes is called prior to this.
544549

545550
call UpdateTreeHydrLenVolCond(ccohort,nlevsoi_hyd,bc_in)
551+
552+
end subroutine updateSizeDepTreeHydProps
553+
554+
! =====================================================================================
555+
556+
subroutine updateWaterDepTreeHydProps(currentSite,ccohort,bc_in)
557+
558+
559+
! DESCRIPTION: Updates absorbing root length (total and its vertical distribution)
560+
! as well as the consequential change in the size of the 'representative' rhizosphere
561+
! shell radii, volumes, and compartment volumes of plant tissues
562+
563+
! !USES:
564+
use shr_sys_mod , only : shr_sys_abort
565+
566+
! ARGUMENTS:
567+
type(ed_site_type) , intent(in) :: currentSite ! Site stuff
568+
type(ed_cohort_type) , intent(inout) :: ccohort ! current cohort pointer
569+
type(bc_in_type) , intent(in) :: bc_in ! Boundary Conditions
570+
571+
! Locals
572+
integer :: nlevsoi_hyd ! Number of total soil layers
573+
type(ed_cohort_hydr_type), pointer :: ccohort_hydr
574+
integer :: ft
575+
576+
nlevsoi_hyd = currentSite%si_hydr%nlevsoi_hyd
577+
ccohort_hydr => ccohort%co_hydr
578+
ft = ccohort%pft
546579

580+
! This updates plant compartment volumes, lengths and
581+
! maximum conductances. Make sure for already
582+
! initialized vegetation, that SavePreviousCompartment
583+
! volumes, and UpdateTreeHydrNodes is called prior to this.
547584

548-
end subroutine updateSizeDepTreeHydProps
585+
call UpdateWaterDepTreeHydrCond(currentSite,ccohort,nlevsoi_hyd,bc_in)
586+
587+
588+
end subroutine updateWaterDepTreeHydProps
549589

550590
! =====================================================================================
551591

@@ -616,7 +656,6 @@ subroutine UpdateTreeHydrLenVolCond(ccohort,nlevsoi_hyd,bc_in)
616656
! hydraulic conductance [kg s-1 MPa-1]
617657
real(r8) :: kmax_tot ! total tree (leaf to root tip)
618658
! hydraulic conductance [kg s-1 MPa-1]
619-
620659
real(r8),parameter :: taper_exponent = 1._r8/3._r8 ! Savage et al. (2010) xylem taper exponent [-]
621660

622661
ccohort_hydr => ccohort%co_hydr
@@ -810,10 +849,84 @@ subroutine UpdateTreeHydrLenVolCond(ccohort,nlevsoi_hyd,bc_in)
810849
ccohort_hydr%kmax_treebg_layer(j) = rootfr*ccohort_hydr%kmax_treebg_tot
811850
end do
812851
end if
852+
813853
end if !check for bleaf
814854

815855
end subroutine UpdateTreeHydrLenVolCond
856+
857+
858+
859+
!=====================================================================================
816860

861+
subroutine UpdateWaterDepTreeHydrCond(currentSite,ccohort,nlevsoi_hyd,bc_in)
862+
863+
! -----------------------------------------------------------------------------------
864+
! This subroutine calculates update the conductivity for the soil-root interface,
865+
! depending on the plant water uptake/loss.
866+
! we assume that the conductivitity for water uptake is larger than
867+
! water loss due to composite regulation of resistance the roots
868+
! hydraulic vs osmostic with and without transpiration
869+
! Steudle, E. Water uptake by roots: effects of water deficit.
870+
! J Exp Bot 51, 1531-1542, doi:DOI 10.1093/jexbot/51.350.1531 (2000).
871+
! -----------------------------------------------------------------------------------
872+
873+
! Arguments
874+
type(ed_site_type) , intent(in) :: currentSite ! Site target
875+
type(ed_cohort_type),intent(inout) :: ccohort ! cohort target
876+
integer,intent(in) :: nlevsoi_hyd ! number of soil hydro layers
877+
type(bc_in_type) , intent(in) :: bc_in ! Boundary Conditions
878+
879+
type(ed_cohort_hydr_type),pointer :: ccohort_hydr ! Plant hydraulics structure
880+
type(ed_site_hydr_type),pointer :: csite_hydr
881+
882+
integer :: j,k
883+
real(r8) :: hksat_s ! hksat converted to units of 10^6sec
884+
real(r8) :: kmax_root_surf_total ! maximum conducitivity for total root surface(kg water/Mpa/s)
885+
real(r8) :: kmax_soil_total ! maximum conducitivity for from root surface to soil shell(kg water/Mpa/s)
886+
! which is equiv to [kg m-1 s-1 MPa-1]
887+
real(r8) :: kmax_root_surf ! maximum conducitivity for unit root surface (kg water/m2 root area/Mpa/s)
888+
889+
! (RGK 4-2019) THE FOLLOWING SHOULD BE ADDED TO THE PARAMETER FILE IN NEXT GROUPING
890+
real(r8), parameter :: hydr_kmax_rsurf2 = 0.0001_r8 ! kg water/m2 root area/Mpa/s
891+
892+
893+
ccohort_hydr => ccohort%co_hydr
894+
csite_hydr => currentSite%si_hydr
895+
k = 1 !only for the first soil shell
896+
do j=1, nlevsoi_hyd
897+
898+
hksat_s = bc_in%hksat_sisl(j) * 1.e-3_r8 * 1/grav * 1.e6_r8
899+
if(ccohort_hydr%psi_aroot(j)<csite_hydr%psisoi_liq_innershell(j))then
900+
kmax_root_surf = hydr_kmax_rsurf1
901+
else
902+
kmax_root_surf = hydr_kmax_rsurf2
903+
endif
904+
kmax_root_surf_total = kmax_root_surf*2._r8*pi_const *csite_hydr%rs1(j)* &
905+
csite_hydr%l_aroot_layer(j)
906+
if(csite_hydr%r_node_shell(j,1) <= csite_hydr%rs1(j)) then
907+
!csite_hydr%kmax_upper_shell(j,k) = large_kmax_bound
908+
!csite_hydr%kmax_bound_shell(j,k) = large_kmax_bound
909+
!csite_hydr%kmax_lower_shell(j,k) = large_kmax_bound
910+
ccohort_hydr%kmax_innershell(j) = kmax_root_surf_total
911+
912+
else
913+
914+
kmax_soil_total = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
915+
log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
916+
917+
!csite_hydr%kmax_upper_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
918+
! log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
919+
!csite_hydr%kmax_bound_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
920+
! log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
921+
!csite_hydr%kmax_lower_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
922+
! log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
923+
924+
ccohort_hydr%kmax_innershell(j) = (1._r8/kmax_root_surf_total + &
925+
1._r8/kmax_soil_total)**(-1._r8)
926+
end if
927+
end do
928+
929+
end subroutine UpdateWaterDepTreeHydrCond
817930

818931
! =====================================================================================
819932
subroutine updateSizeDepTreeHydStates(currentSite,ccohort)
@@ -951,6 +1064,7 @@ subroutine CopyCohortHydraulics(newCohort, oldCohort)
9511064
! quantities indexed by soil layer
9521065
ncohort_hydr%z_node_aroot = ocohort_hydr%z_node_aroot
9531066
ncohort_hydr%kmax_treebg_layer = ocohort_hydr%kmax_treebg_layer
1067+
ncohort_hydr%kmax_innershell = ocohort_hydr%kmax_innershell
9541068
ncohort_hydr%v_aroot_layer_init = ocohort_hydr%v_aroot_layer_init
9551069
ncohort_hydr%v_aroot_layer = ocohort_hydr%v_aroot_layer
9561070
ncohort_hydr%l_aroot_layer = ocohort_hydr%l_aroot_layer
@@ -1609,11 +1723,7 @@ subroutine UpdateSizeDepRhizVolLenCon(currentSite, bc_in)
16091723
real(r8) :: large_kmax_bound = 1.e4_r8 ! for replacing kmax_bound_shell wherever the
16101724
! innermost shell radius is less than the assumed
16111725
! absorbing root radius rs1
1612-
real(r8) :: kmax_root_surf ! maximum conducitivity for unit root surface
1613-
! (kg water/m2 root area/Mpa/s)
16141726
! 1.e-5_r8 from Rudinger et al 1994
1615-
real(r8) :: kmax_root_surf_total !maximum conducitivity for total root surface(kg water/Mpa/s)
1616-
real(r8) :: kmax_soil_total !maximum conducitivity for total root surface(kg water/Mpa/s)
16171727
integer :: nlevsoi_hyd
16181728

16191729
!-----------------------------------------------------------------------
@@ -1633,7 +1743,7 @@ subroutine UpdateSizeDepRhizVolLenCon(currentSite, bc_in)
16331743
enddo !cohort
16341744
cPatch => cPatch%older
16351745
enddo !patch
1636-
kmax_root_surf = hydr_kmax_rsurf
1746+
16371747
csite_hydr%l_aroot_1D = sum( csite_hydr%l_aroot_layer(:))
16381748

16391749
! update outer radii of column-level rhizosphere shells (same across patches and cohorts)
@@ -1646,6 +1756,9 @@ subroutine UpdateSizeDepRhizVolLenCon(currentSite, bc_in)
16461756
enddo
16471757
call shellGeom( csite_hydr%l_aroot_1D, csite_hydr%rs1(1), AREA, sum(bc_in%dz_sisl(1:nlevsoi_hyd)), &
16481758
csite_hydr%r_out_shell_1D(:), csite_hydr%r_node_shell_1D(:), csite_hydr%v_shell_1D(:))
1759+
1760+
!update the conductitivity for first soil shell is done at subroutine UpdateWaterDepTreeHydrCond
1761+
!which is dependant on whether it is water uptake or loss for every 30 minutes
16491762

16501763
do j = 1,csite_hydr%nlevsoi_hyd
16511764

@@ -1654,50 +1767,8 @@ subroutine UpdateSizeDepRhizVolLenCon(currentSite, bc_in)
16541767
! proceed only if the total absorbing root length (site-level) has changed in this layer
16551768
if( csite_hydr%l_aroot_layer(j) /= csite_hydr%l_aroot_layer_init(j) ) then
16561769

1657-
do k = 1,nshell
1658-
if(k == 1) then
1659-
kmax_root_surf_total = kmax_root_surf*2._r8*pi_const *csite_hydr%rs1(j)* &
1660-
csite_hydr%l_aroot_layer(j)
1661-
if(csite_hydr%r_node_shell(j,k) <= csite_hydr%rs1(j)) then
1662-
!csite_hydr%kmax_upper_shell(j,k) = large_kmax_bound
1663-
!csite_hydr%kmax_bound_shell(j,k) = large_kmax_bound
1664-
!csite_hydr%kmax_lower_shell(j,k) = large_kmax_bound
1665-
csite_hydr%kmax_upper_shell(j,k) = kmax_root_surf_total
1666-
csite_hydr%kmax_bound_shell(j,k) = kmax_root_surf_total
1667-
csite_hydr%kmax_lower_shell(j,k) = kmax_root_surf_total
1668-
1669-
else
1670-
1671-
kmax_soil_total = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
1672-
log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
1673-
1674-
!csite_hydr%kmax_upper_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
1675-
! log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
1676-
!csite_hydr%kmax_bound_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
1677-
! log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
1678-
!csite_hydr%kmax_lower_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
1679-
! log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s
1680-
1681-
csite_hydr%kmax_upper_shell(j,k) = (1._r8/kmax_root_surf_total + &
1682-
1._r8/kmax_soil_total)**(-1._r8)
1683-
csite_hydr%kmax_bound_shell(j,k) = (1._r8/kmax_root_surf_total + &
1684-
1._r8/kmax_soil_total)**(-1._r8)
1685-
csite_hydr%kmax_lower_shell(j,k) = (1._r8/kmax_root_surf_total + &
1686-
1._r8/kmax_soil_total)**(-1._r8)
1687-
end if
1688-
if(j == 1) then
1689-
if(csite_hydr%r_node_shell(j,k) <= csite_hydr%rs1(j)) then
1690-
csite_hydr%kmax_upper_shell_1D(k) = csite_hydr%kmax_upper_shell(1,k)
1691-
csite_hydr%kmax_bound_shell_1D(k) = csite_hydr%kmax_bound_shell(1,k)
1692-
csite_hydr%kmax_lower_shell_1D(k) = csite_hydr%kmax_lower_shell(1,k)
1693-
else
1694-
csite_hydr%kmax_upper_shell_1D(k) = csite_hydr%kmax_upper_shell(1,k)
1695-
csite_hydr%kmax_bound_shell_1D(k) = csite_hydr%kmax_bound_shell(1,k)
1696-
csite_hydr%kmax_lower_shell_1D(k) = csite_hydr%kmax_lower_shell(1,k)
1697-
end if
1698-
end if
1699-
else
1700-
csite_hydr%kmax_upper_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
1770+
do k = 2,nshell
1771+
csite_hydr%kmax_upper_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
17011772
log(csite_hydr%r_node_shell(j,k)/csite_hydr%r_out_shell(j,k-1))*hksat_s
17021773
csite_hydr%kmax_bound_shell(j,k) = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / &
17031774
log(csite_hydr%r_node_shell(j,k)/csite_hydr%r_node_shell(j,k-1))*hksat_s
@@ -1711,16 +1782,14 @@ subroutine UpdateSizeDepRhizVolLenCon(currentSite, bc_in)
17111782
csite_hydr%kmax_lower_shell_1D(k) = 2._r8*pi_const*csite_hydr%l_aroot_1D / &
17121783
log(csite_hydr%r_out_shell_1D( k)/csite_hydr%r_node_shell_1D(k ))*hksat_s
17131784
end if
1714-
end if
17151785
enddo ! loop over rhizosphere shells
17161786
end if !has l_aroot_layer changed?
17171787
enddo ! loop over soil layers
17181788

17191789

1720-
17211790
return
17221791
end subroutine UpdateSizeDepRhizVolLenCon
1723-
1792+
17241793

17251794
! =====================================================================================
17261795

@@ -2445,7 +2514,7 @@ subroutine hydraulics_bc ( nsites, sites,bc_in,bc_out,dtime )
24452514
! [mm H2O/cohort/s] = [mm H2O / patch / s] / [cohort/patch]
24462515
!! qflx_tran_veg_patch_coh = qflx_trans_patch_vol * qflx_rel_tran_coh
24472516

2448-
2517+
call updateWaterDepTreeHydProps(sites(s),ccohort,bc_in(s))
24492518

24502519
if(site_hydr%nlevsoi_hyd > 1) then
24512520
! BUCKET APPROXIMATION OF THE SOIL-ROOT HYDRAULIC GRADIENT (weighted average across layers)
@@ -2516,6 +2585,9 @@ subroutine hydraulics_bc ( nsites, sites,bc_in,bc_out,dtime )
25162585
kmax_lower( 1 : n_hypool_ag ) = ccohort_hydr%kmax_lower(:)
25172586
kmax_upper(( n_hypool_ag+1) ) = ccohort_hydr%kmax_upper_troot
25182587
if(site_hydr%nlevsoi_hyd == 1) then
2588+
site_hydr%kmax_upper_shell_1D(1) = ccohort_hydr%kmax_innershell(1)
2589+
site_hydr%kmax_lower_shell_1D(1) = ccohort_hydr%kmax_innershell(1)
2590+
site_hydr%kmax_bound_shell_1D(1) = ccohort_hydr%kmax_innershell(1)
25192591
!! estimate troot-aroot and aroot-radial components as a residual:
25202592
!! 25% each of total (surface of aroots to leaves) resistance
25212593
kmax_bound(( n_hypool_ag+1):(n_hypool_ag+2 )) = 2._r8 * ccohort_hydr%kmax_treebg_tot
@@ -2645,11 +2717,14 @@ subroutine hydraulics_bc ( nsites, sites,bc_in,bc_out,dtime )
26452717
v_node_1l((n_hypool_ag+n_hypool_troot+1) ) = ccohort_hydr%v_aroot_layer(j)
26462718
v_node_1l((n_hypool_tot-nshell+1):(n_hypool_tot)) = site_hydr%v_shell(j,:) * &
26472719
ccohort_hydr%l_aroot_layer(j)/bc_in(s)%dz_sisl(j)
2720+
site_hydr%kmax_bound_shell(j,1)=ccohort_hydr%kmax_innershell(j)
2721+
site_hydr%kmax_upper_shell(j,1)=ccohort_hydr%kmax_innershell(j)
2722+
site_hydr%kmax_lower_shell(j,1)=ccohort_hydr%kmax_innershell(j)
26482723
kmax_bound_1l(:) = 0._r8
26492724
kmax_bound_shell_1l(:) = site_hydr%kmax_bound_shell(j,:) * &
26502725
ccohort_hydr%l_aroot_layer(j) / site_hydr%l_aroot_layer(j)
26512726

2652-
2727+
26532728
! transporting-to-absorbing root conductance: factor of 2 means one-half of the total
26542729
! belowground resistance in layer j
26552730
kmax_bound_1l((n_hypool_ag+1)) = 2._r8 * ccohort_hydr%kmax_treebg_layer(j)

0 commit comments

Comments
 (0)