Skip to content

Commit 4b7293d

Browse files
committed
Resolved conflict in inventory init between phen refactor and allowing pft=0
2 parents 5420fb6 + 30a9310 commit 4b7293d

File tree

6 files changed

+213
-134
lines changed

6 files changed

+213
-134
lines changed

biogeochem/EDCohortDynamicsMod.F90

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module EDCohortDynamicsMod
1414
use FatesConstantsMod , only : itrue,ifalse
1515
use FatesConstantsMod , only : fates_unset_r8
1616
use FatesConstantsMod , only : nearzero
17+
use FatesConstantsMod , only : calloc_abs_error
1718
use FatesInterfaceMod , only : hlm_days_per_year
1819
use FatesInterfaceMod , only : nleafage
1920
use EDPftvarcon , only : EDPftvarcon_inst
@@ -47,6 +48,10 @@ module EDCohortDynamicsMod
4748
use FatesSizeAgeTypeIndicesMod, only : sizetype_class_index
4849
use FatesAllometryMod , only : bleaf
4950
use FatesAllometryMod , only : bfineroot
51+
use FatesAllometryMod , only : bsap_allom
52+
use FatesAllometryMod , only : bagw_allom
53+
use FatesAllometryMod , only : bbgw_allom
54+
use FatesAllometryMod , only : bdead_allom
5055
use FatesAllometryMod , only : h_allom
5156
use FatesAllometryMod , only : carea_allom
5257
use FatesAllometryMod , only : ForceDBH
@@ -93,6 +98,7 @@ module EDCohortDynamicsMod
9398
public :: count_cohorts
9499
public :: InitPRTCohort
95100
public :: UpdateCohortBioPhysRates
101+
public :: EvaluateAndCorrectDBH
96102

97103
logical, parameter :: debug = .false. ! local debug flag
98104

@@ -1706,4 +1712,90 @@ end subroutine UpdateCohortBioPhysRates
17061712

17071713
! ============================================================================
17081714

1715+
1716+
subroutine EvaluateAndCorrectDBH(currentCohort,delta_dbh,delta_hite)
1717+
1718+
! -----------------------------------------------------------------------------------
1719+
! If the current diameter of a plant is somehow less than what is allometrically
1720+
! consistent with stuctural biomass (or, in the case of grasses, leaf biomass)
1721+
! then correct (increase) the dbh to match that.
1722+
! -----------------------------------------------------------------------------------
1723+
1724+
! argument
1725+
type(ed_cohort_type),intent(inout) :: currentCohort
1726+
real(r8),intent(out) :: delta_dbh
1727+
real(r8),intent(out) :: delta_hite
1728+
1729+
! locals
1730+
real(r8) :: dbh
1731+
real(r8) :: canopy_trim
1732+
integer :: ipft
1733+
real(r8) :: sapw_area
1734+
real(r8) :: target_sapw_c
1735+
real(r8) :: target_agw_c
1736+
real(r8) :: target_bgw_c
1737+
real(r8) :: target_struct_c
1738+
real(r8) :: target_leaf_c
1739+
real(r8) :: struct_c
1740+
real(r8) :: hite_out
1741+
real(r8) :: leaf_c
1742+
1743+
dbh = currentCohort%dbh
1744+
ipft = currentCohort%pft
1745+
canopy_trim = currentCohort%canopy_trim
1746+
1747+
delta_dbh = 0._r8
1748+
delta_hite = 0._r8
1749+
1750+
if( EDPftvarcon_inst%woody(ipft) == itrue) then
1751+
1752+
struct_c = currentCohort%prt%GetState(struct_organ, all_carbon_elements)
1753+
1754+
! Target sapwood biomass according to allometry and trimming [kgC]
1755+
call bsap_allom(dbh,ipft,canopy_trim,sapw_area,target_sapw_c)
1756+
1757+
! Target total above ground biomass in woody/fibrous tissues [kgC]
1758+
call bagw_allom(dbh,ipft,target_agw_c)
1759+
1760+
! Target total below ground biomass in woody/fibrous tissues [kgC]
1761+
call bbgw_allom(dbh,ipft,target_bgw_c)
1762+
1763+
! Target total dead (structrual) biomass [kgC]
1764+
call bdead_allom( target_agw_c, target_bgw_c, target_sapw_c, ipft, target_struct_c)
1765+
1766+
! ------------------------------------------------------------------------------------
1767+
! If structure is larger than target, then we need to correct some integration errors
1768+
! by slightly increasing dbh to match it.
1769+
! For grasses, if leaf biomass is larger than target, then we reset dbh to match
1770+
! -----------------------------------------------------------------------------------
1771+
1772+
if( (struct_c - target_struct_c ) > calloc_abs_error ) then
1773+
call ForceDBH( ipft, canopy_trim, dbh, hite_out, bdead=struct_c )
1774+
delta_dbh = dbh - currentCohort%dbh
1775+
delta_hite = hite_out - currentCohort%hite
1776+
currentCohort%dbh = dbh
1777+
currentCohort%hite = hite_out
1778+
end if
1779+
1780+
else
1781+
1782+
! This returns the sum of leaf carbon over all (age) bins
1783+
leaf_c = currentCohort%prt%GetState(leaf_organ, all_carbon_elements)
1784+
1785+
! Target leaf biomass according to allometry and trimming
1786+
call bleaf(dbh,ipft,canopy_trim,target_leaf_c)
1787+
1788+
if( ( leaf_c - target_leaf_c ) > calloc_abs_error ) then
1789+
call ForceDBH( ipft, canopy_trim, dbh, hite_out, bl=leaf_c )
1790+
delta_dbh = dbh - currentCohort%dbh
1791+
delta_hite = hite_out - currentCohort%hite
1792+
currentCohort%dbh = dbh
1793+
currentCohort%hite = hite_out
1794+
end if
1795+
1796+
end if
1797+
return
1798+
end subroutine EvaluateAndCorrectDBH
1799+
1800+
17091801
end module EDCohortDynamicsMod

biogeochem/EDPhysiologyMod.F90

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,10 @@ subroutine seeds_in( currentSite, cp_pnt )
987987
EDPftvarcon_inst%seed_rain(p) !KgC/m2/year
988988
currentSite%seed_rain_flux(p) = currentSite%seed_rain_flux(p) + &
989989
EDPftvarcon_inst%seed_rain(p) * currentPatch%area/AREA !KgC/m2/year
990+
991+
currentSite%flux_in = currentSite%flux_in + &
992+
EDPftvarcon_inst%seed_rain(p) * currentPatch%area * hlm_freq_day
993+
990994
enddo
991995

992996

biogeochem/FatesAllometryMod.F90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,7 @@ end function decay_coeff_kn
22002200

22012201
! =====================================================================================
22022202

2203+
22032204
subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bl )
22042205

22052206
! =========================================================================

main/EDMainMod.F90

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module EDMainMod
2424
use EDCohortDynamicsMod , only : fuse_cohorts
2525
use EDCohortDynamicsMod , only : sort_cohorts
2626
use EDCohortDynamicsMod , only : count_cohorts
27+
use EDCohortDynamicsMod , only : EvaluateAndCorrectDBH
2728
use EDPatchDynamicsMod , only : disturbance_rates
2829
use EDPatchDynamicsMod , only : fuse_patches
2930
use EDPatchDynamicsMod , only : spawn_patches
@@ -273,7 +274,9 @@ subroutine ed_integrate_state_variables(currentSite, bc_in )
273274
real(r8) :: hite_old ! height of plant before daily PRT [m]
274275
logical :: is_drought ! logical for if the plant (site) is in a drought state
275276
real(r8) :: leaf_c
276-
277+
real(r8) :: delta_dbh ! correction for dbh
278+
real(r8) :: delta_hite ! correction for hite
279+
277280
!-----------------------------------------------------------------------
278281

279282
small_no = 0.0000000000_r8 ! Obviously, this is arbitrary. RF - changed to zero
@@ -317,8 +320,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in )
317320
! Apply Plant Allocation and Reactive Transport
318321
! -----------------------------------------------------------------------------
319322

320-
hite_old = currentCohort%hite
321-
dbh_old = currentCohort%dbh
323+
322324

323325
! -----------------------------------------------------------------------------
324326
! Identify the net carbon gain for this dynamics interval
@@ -380,6 +382,15 @@ subroutine ed_integrate_state_variables(currentSite, bc_in )
380382
currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top,7 )
381383

382384

385+
! If the current diameter of a plant is somehow less than what is consistent
386+
! with what is allometrically consistent with the stuctural biomass, then
387+
! correct the dbh to match.
388+
389+
call EvaluateAndCorrectDBH(currentCohort,delta_dbh,delta_hite)
390+
391+
hite_old = currentCohort%hite
392+
dbh_old = currentCohort%dbh
393+
383394
! Conduct Growth (parteh)
384395
call currentCohort%prt%DailyPRT()
385396
call currentCohort%prt%CheckMassConservation(ft,5)

main/FatesInventoryInitMod.F90

Lines changed: 82 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ subroutine set_inventory_edcohort_type1(csite,bc_in,css_file_unit,npatches, &
809809
real(r8) :: b_dead
810810
real(r8) :: b_store
811811
real(r8) :: a_sapwood ! area of sapwood at reference height [m2]
812+
integer :: i_pft, ncohorts_to_create
812813

813814

814815
character(len=128),parameter :: wr_fmt = &
@@ -857,9 +858,9 @@ subroutine set_inventory_edcohort_type1(csite,bc_in,css_file_unit,npatches, &
857858
call endrun(msg=errMsg(sourcefile, __LINE__))
858859
end if
859860

860-
if (c_pft <= 0 ) then
861+
if (c_pft < 0 ) then
861862
write(fates_log(), *) 'inventory pft: ',c_pft
862-
write(fates_log(), *) 'The inventory produced a cohort with <=0 pft index'
863+
write(fates_log(), *) 'The inventory produced a cohort with <0 pft index'
863864
call endrun(msg=errMsg(sourcefile, __LINE__))
864865
end if
865866

@@ -886,64 +887,91 @@ subroutine set_inventory_edcohort_type1(csite,bc_in,css_file_unit,npatches, &
886887
write(fates_log(), *) 'The inventory produced a cohort with very large density /m2'
887888
call endrun(msg=errMsg(sourcefile, __LINE__))
888889
end if
889-
890-
allocate(temp_cohort) ! A temporary cohort is needed because we want to make
891-
! use of the allometry functions
892-
! Don't need to allocate leaf age classes (not used)
893890

894-
temp_cohort%pft = c_pft
895-
temp_cohort%n = c_nplant * cpatch%area
896-
temp_cohort%dbh = c_dbh
897-
call h_allom(c_dbh,c_pft,temp_cohort%hite)
898-
temp_cohort%canopy_trim = 1.0_r8
891+
if (c_pft .eq. 0 ) then
892+
write(fates_log(), *) 'inventory pft: ',c_pft
893+
write(fates_log(), *) 'SPECIAL CASE TRIGGERED: PFT == 0 and therefore this subroutine'
894+
write(fates_log(), *) 'will assign a cohort with n = n_orig/numpft to every cohort in range 1 to numpft'
895+
ncohorts_to_create = numpft
896+
else
897+
ncohorts_to_create = 1
898+
end if
899899

900-
! Calculate total above-ground biomass from allometry
900+
do i_pft = 1,ncohorts_to_create
901+
allocate(temp_cohort) ! A temporary cohort is needed because we want to make
902+
! use of the allometry functions
903+
! Don't need to allocate leaf age classes (not used)
901904

902-
call bagw_allom(temp_cohort%dbh,c_pft,b_agw)
903-
! Calculate coarse root biomass from allometry
904-
call bbgw_allom(temp_cohort%dbh,c_pft,b_bgw)
905-
906-
! Calculate the leaf biomass (calculates a maximum first, then applies canopy trim
907-
! and sla scaling factors)
908-
call bleaf(temp_cohort%dbh,c_pft,temp_cohort%canopy_trim,b_leaf)
909-
910-
! Calculate fine root biomass
911-
call bfineroot(temp_cohort%dbh,c_pft,temp_cohort%canopy_trim,b_fineroot)
912-
913-
! Calculate sapwood biomass
914-
call bsap_allom(temp_cohort%dbh,c_pft,temp_cohort%canopy_trim, a_sapwood, b_sapwood)
915-
916-
call bdead_allom( b_agw, b_bgw, b_sapwood, c_pft, b_dead )
905+
if (c_pft .ne. 0 ) then
906+
! normal case: assign each cohort to its specified PFT
907+
temp_cohort%pft = c_pft
908+
else
909+
! special case, make an identical cohort for each PFT
910+
temp_cohort%pft = i_pft
911+
endif
917912

918-
call bstore_allom(temp_cohort%dbh, c_pft, temp_cohort%canopy_trim, b_store)
919-
920-
temp_cohort%laimemory = 0._r8
921-
cstatus = leaves_on
922-
923-
if( EDPftvarcon_inst%season_decid(c_pft) == itrue .and. &
924-
any(csite%cstatus == [phen_cstat_nevercold,phen_cstat_iscold])) then
925-
temp_cohort%laimemory = b_leaf
926-
b_leaf = 0._r8
927-
cstatus = leaves_off
928-
endif
929-
930-
if ( EDPftvarcon_inst%stress_decid(c_pft) == itrue .and. &
931-
any(csite%dstatus == [phen_dstat_timeoff,phen_dstat_moistoff])) then
932-
temp_cohort%laimemory = b_leaf
933-
b_leaf = 0._r8
934-
cstatus = leaves_off
935-
endif
936-
937-
! Since spread is a canopy level calculation, we need to provide an initial guess here.
938-
call create_cohort(csite, cpatch, c_pft, temp_cohort%n, temp_cohort%hite, temp_cohort%dbh, &
939-
b_leaf, b_fineroot, b_sapwood, b_dead, b_store, &
940-
temp_cohort%laimemory, cstatus, rstatus, temp_cohort%canopy_trim, &
941-
1, csite%spread, equal_leaf_aclass, bc_in)
913+
temp_cohort%n = c_nplant * cpatch%area / real(ncohorts_to_create,r8)
914+
temp_cohort%dbh = c_dbh
942915

943-
944-
deallocate(temp_cohort) ! get rid of temporary cohort
916+
call h_allom(c_dbh,temp_cohort%pft,temp_cohort%hite)
917+
temp_cohort%canopy_trim = 1.0_r8
918+
919+
! Calculate total above-ground biomass from allometry
920+
921+
call bagw_allom(temp_cohort%dbh,temp_cohort%pft,b_agw)
922+
! Calculate coarse root biomass from allometry
923+
call bbgw_allom(temp_cohort%dbh,temp_cohort%pft,b_bgw)
924+
925+
! Calculate the leaf biomass (calculates a maximum first, then applies canopy trim
926+
! and sla scaling factors)
927+
call bleaf(temp_cohort%dbh,temp_cohort%pft,temp_cohort%canopy_trim,b_leaf)
928+
929+
! Calculate fine root biomass
930+
call bfineroot(temp_cohort%dbh,temp_cohort%pft,temp_cohort%canopy_trim,b_fineroot)
931+
932+
! Calculate sapwood biomass
933+
call bsap_allom(temp_cohort%dbh,temp_cohort%pft,temp_cohort%canopy_trim, a_sapwood, b_sapwood)
934+
935+
call bdead_allom( b_agw, b_bgw, b_sapwood, temp_cohort%pft, b_dead )
936+
937+
call bstore_allom(temp_cohort%dbh, temp_cohort%pft, temp_cohort%canopy_trim, b_store)
938+
939+
temp_cohort%laimemory = 0._r8
940+
cstatus = leaves_on
941+
942+
943+
if( EDPftvarcon_inst%season_decid(temp_cohort%pft) == itrue .and. &
944+
any(csite%cstatus == [phen_cstat_nevercold,phen_cstat_iscold])) then
945+
temp_cohort%laimemory = b_leaf
946+
b_leaf = 0._r8
947+
cstatus = leaves_off
948+
endif
949+
950+
if ( EDPftvarcon_inst%stress_decid(temp_cohort%pft) == itrue .and. &
951+
any(csite%dstatus == [phen_dstat_timeoff,phen_dstat_moistoff])) then
952+
temp_cohort%laimemory = b_leaf
953+
b_leaf = 0._r8
954+
cstatus = leaves_off
955+
endif
956+
957+
! Since spread is a canopy level calculation, we need to provide an initial guess here.
958+
if( debug_inv) then
959+
write(fates_log(),*) 'calling create_cohort: ', temp_cohort%pft, temp_cohort%n, &
960+
temp_cohort%hite, temp_cohort%dbh, &
961+
b_leaf, b_fineroot, b_sapwood, b_dead, b_store, &
962+
temp_cohort%laimemory, cstatus, rstatus, temp_cohort%canopy_trim, &
963+
1, csite%spread
964+
endif
965+
966+
call create_cohort(csite, cpatch, temp_cohort%pft, temp_cohort%n, temp_cohort%hite, &
967+
temp_cohort%dbh, b_leaf, b_fineroot, b_sapwood, b_dead, b_store, &
968+
temp_cohort%laimemory, cstatus, rstatus, temp_cohort%canopy_trim, &
969+
1, csite%spread, equal_leaf_aclass, bc_in)
970+
971+
deallocate(temp_cohort) ! get rid of temporary cohort
972+
end do
945973

946974
return
947-
end subroutine set_inventory_edcohort_type1
975+
end subroutine set_inventory_edcohort_type1
948976

949977
end module FatesInventoryInitMod

0 commit comments

Comments
 (0)