Skip to content

Commit 5c40b26

Browse files
authored
Merge pull request #331 from rgknox/rgknox-allocation-integrator
Now that this has passed all tests and we understand all the reasons why it gives answer changes, pulling. Thanks @rgknox!
2 parents 1a3be63 + 78fbc4a commit 5c40b26

18 files changed

+2326
-1310
lines changed

biogeochem/EDCanopyStructureMod.F90

Lines changed: 99 additions & 107 deletions
Large diffs are not rendered by default.

biogeochem/EDCohortDynamicsMod.F90

Lines changed: 102 additions & 269 deletions
Large diffs are not rendered by default.

biogeochem/EDMortalityFunctionsMod.F90

Lines changed: 96 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,37 @@ module EDMortalityFunctionsMod
44
! Functions that control mortality.
55
! ============================================================================
66

7-
use FatesConstantsMod, only : r8 => fates_r8
8-
use FatesGlobals , only : fates_log
9-
use EDPftvarcon , only : EDPftvarcon_inst
10-
use EDTypesMod , only : ed_cohort_type
11-
use FatesConstantsMod, only : itrue,ifalse
12-
use FatesAllometryMod, only : bleaf
13-
use EDParamsMod , only : ED_val_stress_mort
14-
use FatesInterfaceMod, only : hlm_use_ed_prescribed_phys
15-
use FatesInterfaceMod, only : bc_in_type
16-
17-
implicit none
18-
private
19-
20-
21-
public :: mortality_rates
7+
use FatesConstantsMod , only : r8 => fates_r8
8+
use FatesGlobals , only : fates_log
9+
use EDPftvarcon , only : EDPftvarcon_inst
10+
use EDTypesMod , only : ed_cohort_type
11+
use EDTypesMod , only : ed_site_type
12+
use EDTypesMod , only : ed_patch_type
13+
use FatesConstantsMod , only : itrue,ifalse
14+
use FatesAllometryMod , only : bleaf
15+
use EDParamsMod , only : ED_val_stress_mort
16+
use FatesInterfaceMod , only : bc_in_type
17+
use FatesInterfaceMod , only : hlm_use_ed_prescribed_phys
18+
use FatesInterfaceMod , only : hlm_freq_day
19+
use EDLoggingMortalityMod , only : LoggingMortality_frac
20+
use EDParamsMod , only : fates_mortality_disturbance_fraction
21+
use FatesInterfaceMod , only : bc_in_type
22+
23+
24+
implicit none
25+
private
26+
27+
28+
public :: mortality_rates
29+
public :: Mortality_Derivative
30+
31+
logical :: DEBUG_growth = .false.
32+
33+
! ============================================================================
34+
! 10/30/09: Created by Rosie Fisher
35+
! 02/20/18: Refactored Ryan Knox
36+
! ============================================================================
2237

23-
logical :: DEBUG_growth = .false.
24-
25-
! ============================================================================
26-
! 10/30/09: Created by Rosie Fisher
27-
! ============================================================================
2838

2939
contains
3040

@@ -55,6 +65,10 @@ subroutine mortality_rates( cohort_in,bc_in,cmort,hmort,bmort,frmort )
5565
real(r8),parameter :: frost_mort_scaler = 3.0_r8 ! Scaling factor for freezing mortality
5666
real(r8),parameter :: frost_mort_buffer = 5.0_r8 ! 5deg buffer for freezing mortality
5767

68+
logical, parameter :: test_zero_mortality = .false. ! Developer test which
69+
! may help to debug carbon imbalances
70+
! and the like
71+
5872
if (hlm_use_ed_prescribed_phys .eq. ifalse) then
5973

6074
! 'Background' mortality (can vary as a function of
@@ -72,7 +86,7 @@ subroutine mortality_rates( cohort_in,bc_in,cmort,hmort,bmort,frmort )
7286

7387
! Carbon Starvation induced mortality.
7488
if ( cohort_in%dbh > 0._r8 ) then
75-
call bleaf(cohort_in%dbh,cohort_in%hite,cohort_in%pft,cohort_in%canopy_trim,b_leaf)
89+
call bleaf(cohort_in%dbh,cohort_in%pft,cohort_in%canopy_trim,b_leaf)
7690
if( b_leaf > 0._r8 .and. cohort_in%bstore <= b_leaf )then
7791
frac = cohort_in%bstore/ b_leaf
7892
cmort = max(0.0_r8,ED_val_stress_mort*(1.0_r8 - frac))
@@ -111,8 +125,68 @@ subroutine mortality_rates( cohort_in,bc_in,cmort,hmort,bmort,frmort )
111125
frmort = 0._r8
112126
endif
113127

128+
if (test_zero_mortality) then
129+
cmort = 0.0_r8
130+
hmort = 0.0_r8
131+
frmort = 0.0_r8
132+
bmort = 0.0_r8
133+
end if
134+
135+
return
114136
end subroutine mortality_rates
115137

116-
! ============================================================================
138+
! ============================================================================
139+
140+
subroutine Mortality_Derivative( currentSite, currentCohort, bc_in)
141+
142+
!
143+
! !DESCRIPTION:
144+
! Calculate the change in number density per unit time from the contributing
145+
! rates. These rates are not disturbance-inducing rates (that is handled
146+
! elsewhere).
147+
!
148+
! !USES:
149+
150+
!
151+
! !ARGUMENTS
152+
type(ed_site_type), intent(inout), target :: currentSite
153+
type(ed_cohort_type),intent(inout), target :: currentCohort
154+
type(bc_in_type), intent(in) :: bc_in
155+
!
156+
! !LOCAL VARIABLES:
157+
real(r8) :: cmort ! starvation mortality rate (fraction per year)
158+
real(r8) :: bmort ! background mortality rate (fraction per year)
159+
real(r8) :: hmort ! hydraulic failure mortality rate (fraction per year)
160+
real(r8) :: frmort ! freezing mortality rate (fraction per year)
161+
real(r8) :: dndt_logging ! Mortality rate (per day) associated with the a logging event
162+
integer :: ipft ! local copy of the pft index
163+
!----------------------------------------------------------------------
164+
165+
ipft = currentCohort%pft
166+
167+
! Mortality for trees in the understorey.
168+
!if trees are in the canopy, then their death is 'disturbance'. This probably needs a different terminology
169+
call mortality_rates(currentCohort,bc_in,cmort,hmort,bmort,frmort)
170+
call LoggingMortality_frac(ipft, currentCohort%dbh, &
171+
currentCohort%lmort_direct, &
172+
currentCohort%lmort_collateral, &
173+
currentCohort%lmort_infra )
174+
175+
if (currentCohort%canopy_layer > 1)then
176+
177+
! Include understory logging mortality rates not associated with disturbance
178+
dndt_logging = (currentCohort%lmort_direct + &
179+
currentCohort%lmort_collateral + &
180+
currentCohort%lmort_infra)/hlm_freq_day
181+
182+
currentCohort%dndt = -1.0_r8 * (cmort+hmort+bmort+frmort+dndt_logging) * currentCohort%n
183+
else
184+
currentCohort%dndt = -(1.0_r8 - fates_mortality_disturbance_fraction) &
185+
* (cmort+hmort+bmort+frmort) * currentCohort%n
186+
endif
187+
188+
return
189+
190+
end subroutine Mortality_Derivative
117191

118192
end module EDMortalityFunctionsMod

biogeochem/EDPatchDynamicsMod.F90

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,8 @@ subroutine spawn_patches( currentSite, bc_in)
432432
nc%n * ED_val_understorey_death / hlm_freq_day
433433
currentSite%imort_carbonflux = currentSite%imort_carbonflux + &
434434
(nc%n * ED_val_understorey_death / hlm_freq_day ) * &
435-
currentCohort%b * g_per_kg * days_per_sec * years_per_day * ha_per_m2
436-
435+
currentCohort%b_total() * g_per_kg * days_per_sec * years_per_day * ha_per_m2
436+
437437
! Step 2: Apply survivor ship function based on the understory death fraction
438438
! remaining of understory plants of those that are knocked over by the overstorey trees dying...
439439
nc%n = nc%n * (1.0_r8 - ED_val_understorey_death)
@@ -556,7 +556,8 @@ subroutine spawn_patches( currentSite, bc_in)
556556
nc%n * logging_coll_under_frac / hlm_freq_day
557557
currentSite%imort_carbonflux = currentSite%imort_carbonflux + &
558558
(nc%n * logging_coll_under_frac/ hlm_freq_day ) * &
559-
currentCohort%b * g_per_kg * days_per_sec * years_per_day * ha_per_m2
559+
currentCohort%b_total() * g_per_kg * days_per_sec * years_per_day * ha_per_m2
560+
560561

561562
! Step 2: Apply survivor ship function based on the understory death fraction
562563

@@ -956,14 +957,14 @@ subroutine fire_litter_fluxes(currentSite, cp_target, new_patch_target, patch_si
956957

957958
call carea_allom(currentCohort%dbh,currentCohort%n,currentSite%spread,currentCohort%pft,currentCohort%c_area)
958959
if(EDPftvarcon_inst%woody(currentCohort%pft) == 1)then
959-
burned_leaves = (currentCohort%bl+currentCohort%bsw) * currentCohort%cfa
960+
burned_leaves = min(currentCohort%bl, (currentCohort%bl+currentCohort%bsw) * currentCohort%cfa)
960961
else
961-
burned_leaves = (currentCohort%bl+currentCohort%bsw) * currentPatch%burnt_frac_litter(6)
962+
burned_leaves = min(currentCohort%bl, (currentCohort%bl+currentCohort%bsw) * currentPatch%burnt_frac_litter(6))
962963
endif
963964
if (burned_leaves > 0.0_r8) then
964965

965-
currentCohort%balive = max(currentCohort%br,currentCohort%balive - burned_leaves)
966-
currentCohort%bl = max(0.00001_r8, currentCohort%bl - burned_leaves)
966+
currentCohort%bl = currentCohort%bl - burned_leaves
967+
967968
!KgC/gridcell/day
968969
currentSite%flux_out = currentSite%flux_out + burned_leaves * currentCohort%n * &
969970
patch_site_areadis/currentPatch%area * AREA
@@ -1337,7 +1338,6 @@ subroutine fuse_patches( csite, bc_in )
13371338
integer :: fuse_flag !do patches get fused (1) or not (0).
13381339
!---------------------------------------------------------------------
13391340

1340-
!maxpatch = 4
13411341
maxpatch = maxPatchesPerSite
13421342

13431343
currentSite => csite

0 commit comments

Comments
 (0)