Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
b5c814d
add subroutine to calculate canopy fuel load and fuel bulk density
XiulinGao Mar 9, 2025
9d8a397
add canopy base height to fuel type
XiulinGao Mar 9, 2025
fcf52e2
add equation to calculate passive crown fire intensity
XiulinGao Mar 9, 2025
a96a027
add subroutine to update canopy fuel characteristics
XiulinGao Mar 9, 2025
8c5bd5b
correct for canopy fuel load calculation;
XiulinGao Mar 9, 2025
a1e83ed
bug fix
XiulinGao Mar 9, 2025
021b2eb
add relevant equations for calculating crowning index
XiulinGao Mar 10, 2025
6d26c1d
add more equations for crown fire
XiulinGao Mar 13, 2025
b0d6ac9
add a subroutine for checking if a passive or active crown fire presents
XiulinGao Mar 13, 2025
65232d0
remove local vars that are not used
XiulinGao Mar 13, 2025
282e30d
typo fix
XiulinGao Mar 13, 2025
da83563
cohort crown frac burnt given passive and active crown fire
XiulinGao Mar 13, 2025
a50a8cf
add crown fire switch as a ED param
XiulinGao Mar 13, 2025
e0d3ffc
add passive and active crown fire tag at patch
XiulinGao Mar 13, 2025
2085b0b
add hist vars related to crown fire
XiulinGao Mar 13, 2025
53b2afb
change crown fire switch name in param file
XiulinGao Mar 13, 2025
8332b09
fix burn window calculation for hist var
XiulinGao Mar 13, 2025
8c14669
fix rxfire mort dimenson index bug
XiulinGao Mar 13, 2025
b66f9ac
update burn window every time
XiulinGao Mar 14, 2025
b71003d
add crown fire stwitch during check of crown fire
XiulinGao Mar 14, 2025
a676b9c
bug fix
XiulinGao Mar 14, 2025
f7c97f8
bug fix again
XiulinGao Mar 14, 2025
e01a44a
typo fix
XiulinGao Mar 14, 2025
973b333
typo fix
XiulinGao Mar 14, 2025
e697124
correct calculation of canopy fuel load density and in-code documenta…
XiulinGao Mar 14, 2025
b16c77e
initialize crown fire flag at the beginning
XiulinGao Mar 14, 2025
9f204ad
update crown fire flag each time
XiulinGao Mar 14, 2025
f865885
initialize patch level canopy fuel traits each time
XiulinGao Mar 14, 2025
bf6abd4
restrict CBD to 0 if max_height - canopy_base_height is near zero
XiulinGao Mar 14, 2025
b613345
initialize canopy base height
XiulinGao Mar 14, 2025
f925455
print out some diagnostic variables during run time
XiulinGao Mar 14, 2025
e3503b0
print out more diagnostic variables
XiulinGao Mar 14, 2025
dfa06c1
update calculation of CBD and add a model to calculate live fuel mois…
XiulinGao Mar 29, 2025
59590a1
add relevant site or cohort level vars for LFMC calculation
XiulinGao Mar 29, 2025
262ee9b
add canopy water content as hist var
XiulinGao Mar 29, 2025
7da4fec
arg declare
XiulinGao Mar 30, 2025
807fefd
add testing parameter for LFMC
XiulinGao Mar 30, 2025
f4b4fc0
zero LFMC each day
XiulinGao Mar 30, 2025
6528c5e
update patch level LFMC calculation
XiulinGao Mar 30, 2025
e83afaa
calculate volumetric SWC including top soil layer
XiulinGao Mar 30, 2025
868993c
correct calculation of 1m biomass bin using adjusted CWD fraction
XiulinGao Apr 6, 2025
9e6d95b
correct searching for canopy base and top height
XiulinGao Apr 6, 2025
4c1629b
test LFMC calculation using matric potential
XiulinGao Apr 7, 2025
e852c47
calculate 10 day soil matric potential for LFMC independently
XiulinGao Apr 7, 2025
ea3a9db
parameter declare
XiulinGao Apr 7, 2025
da91690
Revert "parameter declare"
XiulinGao Apr 14, 2025
eafc78e
Revert "calculate 10 day soil matric potential for LFMC independently"
XiulinGao Apr 14, 2025
09e10a6
remove volumetric soil water content for LFMC calculation and update …
XiulinGao Apr 23, 2025
1241288
update parameter name and in-code documentation for LFMC model
XiulinGao Jun 6, 2025
50ccd8d
remove TorchingIndex fun that is not used
XiulinGao Jun 6, 2025
08d4f2e
move all crown fire equations to its own moduel and make ROS_active c…
XiulinGao Jun 7, 2025
73ac376
add SPITFIRE equations that used in crown fire
XiulinGao Jun 7, 2025
b9f6e50
calculate crown damage for crown fire and surface fire differently
XiulinGao Jun 7, 2025
ec333ce
change local variable of canopy fraction burned for crown fire to pat…
XiulinGao Jun 8, 2025
f08cdfa
remove the reference to torching index fun which been removed already
XiulinGao Jun 10, 2025
a04d574
change to subroutine to calculate crown fire behavior using fuel mode…
XiulinGao Jun 10, 2025
d65ba31
calculate leaf water content when fates-hydro is on
XiulinGao Jul 24, 2025
3cfbcc3
variable declare
XiulinGao Jul 24, 2025
f2f7c49
correct calculation of crown fire intensity
XiulinGao Jul 29, 2025
47d8d6a
calculating crown fire canopy fraction burned using updated FI instea…
XiulinGao Aug 1, 2025
944b394
syntex error
XiulinGao Aug 1, 2025
b8e8900
correct calculation of ROS active
XiulinGao Aug 31, 2025
fcceefc
further modularize crown fire code
XiulinGao Sep 28, 2025
00651af
specify the lower bound of biom_matrix array to be 0
XiulinGao Sep 30, 2025
bab02dd
merge into Main
XiulinGao Sep 30, 2025
a499634
merge conflict
XiulinGao Oct 1, 2025
7a7e315
add functional test for crown fire
XiulinGao Oct 1, 2025
e644081
fix input argument bug
XiulinGao Oct 1, 2025
11dd671
remove diagnose print message
XiulinGao Oct 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions biogeochem/FatesCohortMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ module FatesCohortMod
real(r8) :: rx_cambial_mort ! cambial kill mortality due to prescribed fire
real(r8) :: rx_crown_mort ! crown fire mortality due to prescribed fire
real(r8) :: rx_fire_mort ! post-fire mortality due to prescribed fire
real(r8) :: lfmc ! live fuel moisture content [%]
real(r8) :: canopy_fuel_1h ! leaf + 1 hour woody live fuel [kg biomass]

!---------------------------------------------------------------------------

Expand Down Expand Up @@ -464,6 +466,8 @@ subroutine NanValues(this)
this%rx_cambial_mort = nan
this%rx_crown_mort = nan
this%rx_fire_mort = nan
this%lfmc = nan
this%canopy_fuel_1h = nan

end subroutine NanValues

Expand Down Expand Up @@ -556,6 +560,8 @@ subroutine ZeroValues(this)
this%rx_cambial_mort = 0._r8
this%rx_crown_mort = 0._r8
this%rx_fire_mort = 0._r8
this%lfmc = 0._r8
this%canopy_fuel_1h = 0._r8

end subroutine ZeroValues

Expand Down Expand Up @@ -807,6 +813,8 @@ subroutine Copy(this, copyCohort)
copyCohort%rx_cambial_mort = this%rx_cambial_mort
copyCohort%rx_crown_mort = this%rx_crown_mort
copyCohort%rx_fire_mort = this%rx_fire_mort
copyCohort%lfmc = this%lfmc
copyCohort%canopy_fuel_1h = this%canopy_fuel_1h

! HYDRAULICS
if (hlm_use_planthydro .eq. itrue) then
Expand Down Expand Up @@ -1151,6 +1159,8 @@ subroutine Dump(this)
write(fates_log(),*) 'cohort%rx_crown_mort = ', this%rx_crown_mort
write(fates_log(),*) 'cohort%rx_cambial_mort = ', this%rx_cambial_mort
write(fates_log(),*) 'cohort%rx_fire_mort = ', this%rx_fire_mort
write(fates_log(),*) 'cohort%lfmc = ', this%lfmc
write(fates_log(),*) 'cohort%canopy_fuel_1h = ', this%canopy_fuel_1h
write(fates_log(),*) 'cohort%size_class = ', this%size_class
write(fates_log(),*) 'cohort%size_by_pft_class = ', this%size_by_pft_class

Expand Down
7 changes: 7 additions & 0 deletions biogeochem/FatesPatchMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ module FatesPatchMod
! fire effects
real(r8) :: scorch_ht(maxpft) ! scorch height [m]
real(r8) :: tfc_ros ! total intensity-relevant fuel consumed - no trunks [kgC/m2 of burned ground/day]

! crown fire
integer :: passive_crown_fire ! is there a passive crown fire [1=yes; 0=no]
integer :: active_crown_fire ! is there an active crown fire [1=yes; 0=no]

!---------------------------------------------------------------------------

! PLANT HYDRAULICS (not currently used in hydraulics RGK 03-2018)
Expand Down Expand Up @@ -537,6 +542,8 @@ subroutine NanValues(this)
this%fire = fates_unset_int
this%nonrx_fire = fates_unset_int
this%rx_fire = fates_unset_int
this%passive_crown_fire = fates_unset_int
this%active_crown_fire = fates_unset_int
this%nonrx_fi = nan
this%nonrx_frac_burnt = nan
this%rx_fi = nan
Expand Down
1 change: 1 addition & 0 deletions fire/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ list(APPEND fates_sources
FatesFuelMod.F90
FatesFuelClassesMod.F90
SFEquationsMod.F90
CrownFireEquationsMod.F90
)

sourcelist_to_parent(fates_sources)
384 changes: 384 additions & 0 deletions fire/CrownFireEquationsMod.F90

Large diffs are not rendered by default.

135 changes: 133 additions & 2 deletions fire/FatesFuelMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module FatesFuelMod
use FatesConstantsMod, only : nearzero
use SFNesterovMod, only : nesterov_index
use SFFireWeatherMod, only : fire_weather
use FatesLitterMod, only : ncwd
use FatesGlobals, only : fates_log
use FatesGlobals, only : endrun => fates_endrun
use shr_log_mod, only : errMsg => shr_log_errMsg
Expand All @@ -23,6 +24,11 @@ module FatesFuelMod
real(r8) :: bulk_density_notrunks ! weighted average of bulk density across non-trunk fuel classes [kg/m3]
real(r8) :: SAV_notrunks ! weighted average of surface area to volume ratio across non-trunk fuel classes [/cm]
real(r8) :: MEF_notrunks ! weighted average of moisture of extinction across non-trunk fuel classes [m3/m3]
real(r8) :: canopy_fuel_load ! patch level total canopy fuel load [kg biomass]
real(r8) :: canopy_base_height ! patch level canopy base height at which biomass density > minimum density required for canopy fire spread [m]
real(r8) :: canopy_bulk_density ! patch level canopy fuel bulk density [kg biomass m-3]
real(r8) :: canopy_water_content ! patch level canopy water content [%]


contains

Expand All @@ -34,8 +40,11 @@ module FatesFuelMod
procedure :: UpdateFuelMoisture
procedure :: AverageBulkDensity_NoTrunks
procedure :: AverageSAV_NoTrunks
procedure :: CalculateCanopyFuelLoad
procedure :: CalculateCanopyBulkDensity
procedure :: CalculateFuelBurnt
procedure :: CalculateResidenceTime
procedure :: CanopyWaterContent

end type fuel_type

Expand All @@ -58,6 +67,10 @@ subroutine Init(this)
this%bulk_density_notrunks = 0.0_r8
this%SAV_notrunks = 0.0_r8
this%MEF_notrunks = 0.0_r8
this%canopy_fuel_load = 0.0_r8
this%canopy_base_height = 0.0_r8
this%canopy_bulk_density = 0.0_r8
this%canopy_water_content = 0.0_r8

end subroutine Init

Expand Down Expand Up @@ -99,7 +112,15 @@ subroutine Fuse(this, self_area, donor_area, donor_fuel)
this%bulk_density_notrunks = this%bulk_density_notrunks*self_weight + &
donor_fuel%bulk_density_notrunks*donor_weight
this%SAV_notrunks = this%SAV_notrunks*self_weight + donor_fuel%SAV_notrunks*donor_weight
this%MEF_notrunks = this%MEF_notrunks*self_weight + donor_fuel%MEF_notrunks*donor_weight
this%MEF_notrunks = this%MEF_notrunks*self_weight + donor_fuel%MEF_notrunks*donor_weight
this%canopy_fuel_load = this%canopy_fuel_load*self_weight + &
donor_fuel%canopy_fuel_load*donor_weight
this%canopy_base_height = this%canopy_base_height*self_weight + &
donor_fuel%canopy_base_height*donor_weight
this%canopy_bulk_density = this%canopy_bulk_density*self_weight + &
donor_fuel%canopy_bulk_density*donor_weight
this%canopy_water_content = this%canopy_water_content*self_weight + &
donor_fuel%canopy_water_content*donor_weight

end subroutine Fuse

Expand Down Expand Up @@ -377,7 +398,117 @@ subroutine AverageSAV_NoTrunks(this, sav_fuel)
end subroutine AverageSAV_NoTrunks

!---------------------------------------------------------------------------------------


subroutine CalculateCanopyFuelLoad(this, leaf_c, woody_c, &
cwd_frac_adj, canopy_fuel_1h)
! DESCRIPTION:
! Calculate canopy fuel load by summing up leaf biomass and 1 hour woody biomass
! XLG: I did not change how Sam L. calculate canopy fuel load here except
! switch to the adjusted CWD instead of using the default parameter
! Seems only including leaf biomass is recommend by Gruz et al. 2003:
! https://www.sierraforestlegacy.org/Resources/Conservation/FireForestEcology/FireScienceResearch/FireEcology/FireEcology-Cruz03.pdf

! ARGUMENTS:
class(fuel_type), intent(inout) :: this ! fuel class
real(r8), intent(in) :: leaf_c ! leaf biomass of each cohort [kg biomass]
real(r8), intent(in) :: woody_c ! 1-hour woody fuels [kg biomass]
real(r8), intent(in) :: cwd_frac_adj(ncwd) ! adjusted coarse woody debris fraction [fraction]
real(r8), intent(out) :: canopy_fuel_1h ! leaf + 1-hour woody biomass of current cohort [kg biomass]

! calculate canopy fuel load for FATES crown fire
canopy_fuel_1h = woody_c * cwd_frac_adj(1) + leaf_c
this%canopy_fuel_load = this%canopy_fuel_load + canopy_fuel_1h


end subroutine CalculateCanopyFuelLoad


!---------------------------------------------------------------------------------------
subroutine CalculateCanopyBulkDensity(this, biom_matrix, max_height)
! DESCRIPTION:
! Calculate canopy fuel bulk density [kg biomass / m3] by searching for
! the canopy height (canopy base height CBH) at which canopy fuel bed density
! is > minimum canopy fuel density [0.011 kg biomass/m3] for propogating canopy fire;
! CBD is then calculated as canopy fuel load devided by
! crown depth ( CD= max. canopy height - CBH).
! XLG: one modification I made compare to Sam L. version is that I recalculate
! canopy fuel load after knowing CD by excluding fuels below CBH. As if including
! fuels below CBH then we are artificially "condense" canopy fuel bed by deviding total
! fuel load by an average, shallower CD.

! ARGUMENTS:
class(fuel_type), intent(inout) :: this ! fuel class
real(r8), intent(in) :: biom_matrix(0:) ! 1m biomass bin (kg/m3) in the vertical space to sort the canopy fule
! across cohorts, used to search for CBH
real(r8), intent(in) :: max_height ! the max. cohort height at current patch [m]

! Locals:
real(r8) :: canopy_top_height ! the highest point at which biomass density is > minimum canopy fuel density [m]
integer :: ih ! biomass bin counter

! Params:
real(r8), parameter :: min_density_canopy_fuel = 0.011_r8 ! minimum canopy fuel density for propogating canopy fire
! vertically through canopy.
! Scott and Reinhardt 2001 RMRS-RP-29

! loop from 1m to 70m to find CBH
do ih=0,int(max_height)
if (biom_matrix(ih) > min_density_canopy_fuel) then
this%canopy_base_height = dble(ih) + 1.0_r8 ! the dimension index of biom_matrix is a ronded-down integer of cohort height
! add 1 to be conservative when searching for CBH

exit
else ! when this is an open stand that there is no such a height, use max_height
this%canopy_base_height = max_height
end if
end do

! now loop from top to bottom to find the highest point at which the minimum bulk density is met
! XLG: I modified the way how canopy bulk density is calculated by reducing the maximum canopy height
! to the highest point where the minimum bulk density is met.

do ih = int(max_height), 0, -1
if (biom_matrix(ih) > min_density_canopy_fuel) then
canopy_top_height = dble(ih) + 1.0_r8
exit
else
canopy_top_height = max_height
end if
end do

! XLG: We now only calculate canopy bulk density for fuels between
! canopy base and top height
if ((canopy_top_height - this%canopy_base_height) > nearzero) then
this%canopy_bulk_density = sum(biom_matrix(int(this%canopy_base_height-1.0_r8):int(canopy_top_height-1.0_r8))) / &
(canopy_top_height - this%canopy_base_height)
else
this%canopy_bulk_density = 0.0_r8
end if


end subroutine CalculateCanopyBulkDensity

!---------------------------------------------------------------------------------------

subroutine CanopyWaterContent(this, co_cwc, co_fuel)
! DESCRIPTION:
! Calculates live canopy water content
! as sum of fuel load weighted cohort level live fuel moisture content
!
! ARGUMENTS
class(fuel_type), intent(inout) :: this ! fuel class
real(r8), intent(in) :: co_cwc ! coohort live fuel moisture content [%]
real(r8), intent(in) :: co_fuel ! cohort canopy fuel, only 1 hour woody + leaf

this%canopy_water_content = this%canopy_water_content + &
co_cwc * co_fuel/this%canopy_fuel_load


end subroutine CanopyWaterContent

!---------------------------------------------------------------------------------------


subroutine CalculateFuelBurnt(this, fuel_consumed)
! DESCRIPTION:
! Calculates the fraction and total amount of fuel burnt
Expand Down
Loading