Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor spitfire fuel calculations #1247

Merged
merged 65 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
b47072f
get rid of unnused unit_test_shr
adrifoster Mar 20, 2024
902f842
code cleanup; add updatelivegrass subroutine
adrifoster Mar 20, 2024
f7258c6
code cleanup
adrifoster Mar 20, 2024
81835a7
call grass
adrifoster Mar 25, 2024
f103987
add sum loading
adrifoster Mar 26, 2024
187b2a4
get rid of sum_fuel
adrifoster Mar 26, 2024
0e74ffc
Merge branch 'main' into fire_refactor_fuel
adrifoster Apr 1, 2024
f4f940d
more updates
May 2, 2024
283a7a8
merge in upstream changes
May 2, 2024
3894aa1
merge in functional unit tests framework
May 2, 2024
a8a13af
change folder names
May 2, 2024
7cce284
remove old cmakelists
May 2, 2024
7396655
add fire test dir
May 2, 2024
861f84c
adding test file
May 2, 2024
0b66d3f
adding fire tests
May 3, 2024
6427692
Merge branch 'main' into fire_refactor_fuel
May 3, 2024
19f5237
testing
May 3, 2024
b57f581
Merge branch 'fire_weather_wind' into fire_refactor_fuel
May 3, 2024
e4be4c4
update fuel characteristics subroutine
May 6, 2024
2abf3de
merge in testing changes
May 6, 2024
7c84992
add files
May 6, 2024
7bf630b
get rid of patch-level variables moved into fuel class
May 7, 2024
a494d3b
Merge branch 'main' into fire_refactor_fuel
Jun 3, 2024
57df197
fix merge errors
Jun 3, 2024
50e4887
update graph
Jun 4, 2024
dfd7297
Merge branch 'main' into fire_refactor_fuel
Aug 30, 2024
ce55f1c
add rest of fuel models
Aug 30, 2024
d9ff87b
rename some things
Aug 30, 2024
ca3ed12
refactor
Aug 30, 2024
2263e6f
fix bugs
adrifoster Sep 4, 2024
b1500c9
updates
Sep 4, 2024
3cfb2b1
Merge branch 'fire_refactor_fuel' of https://github.com/adrifoster/fa…
Sep 4, 2024
4a16132
fix plotting
Sep 4, 2024
7b00ed3
fix b4b changes
adrifoster Sep 6, 2024
06070a3
Merge branch 'fire_refactor_fuel' of https://github.com/adrifoster/fa…
adrifoster Sep 6, 2024
20ceac2
remove space
Sep 9, 2024
d58d0b1
fix testing errors
Sep 10, 2024
c42cda9
updates
adrifoster Sep 11, 2024
bd213db
Merge branch 'fire_refactor_fuel' of https://github.com/adrifoster/fa…
adrifoster Sep 11, 2024
3d9d014
fixing errors
adrifoster Sep 12, 2024
59053b9
updates
adrifoster Sep 13, 2024
00d02de
fix parameter file
Sep 17, 2024
d072dc9
Merge branch 'fire_refactor_fuel' of https://github.com/adrifoster/fa…
adrifoster Sep 19, 2024
82b3f04
fix div zero issues
adrifoster Sep 24, 2024
b7f1a01
fix comments
adrifoster Sep 24, 2024
3136ebb
fuel plotting
Sep 24, 2024
981958d
Merge branch 'fire_refactor_fuel' of https://github.com/adrifoster/fa…
Sep 24, 2024
6eed280
updates for b4b testing
adrifoster Oct 2, 2024
817491b
update zero checking
adrifoster Oct 17, 2024
81d45c2
Merge branch 'main' into fire_refactor_fuel
adrifoster Oct 17, 2024
04d06d9
remove dbugging lines
adrifoster Oct 17, 2024
b5f3956
update nfsc variable name
Oct 29, 2024
195dce4
change total_loading to non_trunk_loading
Oct 29, 2024
6f6ac0b
other updates
Oct 29, 2024
b436783
updating variable names
Oct 29, 2024
0831336
updates to testing
Oct 30, 2024
920c549
big fixes
Oct 30, 2024
7fc2242
more updates
Oct 30, 2024
e0c7058
fix comment
Oct 31, 2024
de61028
Merge branch 'main' into fire_refactor_fuel
Oct 31, 2024
52842b3
fix variable names
adrifoster Nov 4, 2024
d422c12
Merge branch 'main' into fire_refactor_fuel
adrifoster Nov 4, 2024
fb6ab8c
Merge branch 'fire_refactor_fuel' of https://github.com/adrifoster/fa…
adrifoster Nov 8, 2024
128e0a9
fix class vs. type
adrifoster Nov 12, 2024
bdb253f
fix capitalization
adrifoster Nov 12, 2024
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
37 changes: 16 additions & 21 deletions biogeochem/EDPatchDynamicsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ module EDPatchDynamicsMod
use FatesConstantsMod , only : ican_upper
use PRTGenericMod , only : num_elements
use PRTGenericMod , only : element_list
use FatesLitterMod , only : lg_sf
use FatesLitterMod , only : dl_sf
use FatesFuelClassesMod , only : fuel_classes
use FatesConstantsMod , only : N_DIST_TYPES
use EDTypesMod , only : AREA_INV
use EDTypesMod , only : dump_site
Expand Down Expand Up @@ -764,11 +763,11 @@ subroutine spawn_patches( currentSite, bc_in)

! Transfer the litter existing already in the donor patch to the new patch
! This call will only transfer non-burned litter to new patch
! and burned litter to atmosphere. Thus it is important to zero burnt_frac_litter when
! and burned litter to atmosphere. Thus it is important to zero fuel%frac_burnt when
! fire is not the current disturbance regime.

if(i_disturbance_type .ne. dtype_ifire) then
currentPatch%burnt_frac_litter(:) = 0._r8
currentPatch%fuel%frac_burnt(:) = 0._r8
end if

call CopyPatchMeansTimers(currentPatch, newPatch)
Expand Down Expand Up @@ -1052,7 +1051,7 @@ subroutine spawn_patches( currentSite, bc_in)

! Grasses determine their fraction of leaves burned here

leaf_burn_frac = currentPatch%burnt_frac_litter(lg_sf)
leaf_burn_frac = currentPatch%fuel%frac_burnt(fuel_classes%live_grass())
endif

! Perform a check to make sure that spitfire gave
Expand Down Expand Up @@ -1720,7 +1719,7 @@ subroutine split_patch(currentSite, currentPatch, new_patch, fraction_to_keep, a

call TransLitterNewPatch( currentSite, currentPatch, new_patch, temp_area)

currentPatch%burnt_frac_litter(:) = 0._r8
currentPatch%fuel%frac_burnt(:) = 0._r8

! Next, we loop through the cohorts in the donor patch, copy them with
! area modified number density into the new-patch, and apply survivorship.
Expand Down Expand Up @@ -2075,10 +2074,10 @@ subroutine TransLitterNewPatch(currentSite, &

! Transfer above ground CWD
donatable_mass = curr_litt%ag_cwd(c) * patch_site_areadis * &
(1._r8 - currentPatch%burnt_frac_litter(c))
(1._r8 - currentPatch%fuel%frac_burnt(c))

burned_mass = curr_litt%ag_cwd(c) * patch_site_areadis * &
currentPatch%burnt_frac_litter(c)
currentPatch%fuel%frac_burnt(c)

new_litt%ag_cwd(c) = new_litt%ag_cwd(c) + donatable_mass*donate_m2
curr_litt%ag_cwd(c) = curr_litt%ag_cwd(c) + donatable_mass*retain_m2
Expand All @@ -2099,10 +2098,10 @@ subroutine TransLitterNewPatch(currentSite, &

! Transfer leaf fines
donatable_mass = curr_litt%leaf_fines(dcmpy) * patch_site_areadis * &
(1._r8 - currentPatch%burnt_frac_litter(dl_sf))
(1._r8 - currentPatch%fuel%frac_burnt(fuel_classes%dead_leaves()))

burned_mass = curr_litt%leaf_fines(dcmpy) * patch_site_areadis * &
currentPatch%burnt_frac_litter(dl_sf)
currentPatch%fuel%frac_burnt(fuel_classes%dead_leaves())

new_litt%leaf_fines(dcmpy) = new_litt%leaf_fines(dcmpy) + donatable_mass*donate_m2
curr_litt%leaf_fines(dcmpy) = curr_litt%leaf_fines(dcmpy) + donatable_mass*retain_m2
Expand Down Expand Up @@ -3252,6 +3251,8 @@ subroutine fuse_2_patches(csite, dp, rp)
do el = 1,num_elements
call rp%litter(el)%FuseLitter(rp%area,dp%area,dp%litter(el))
end do

call rp%fuel%Fuse(rp%area, dp%area, dp%fuel)

if ( rp%land_use_label .ne. dp%land_use_label) then
write(fates_log(),*) 'trying to fuse patches with different land_use_label values'
Expand Down Expand Up @@ -3282,22 +3283,17 @@ subroutine fuse_2_patches(csite, dp, rp)

call rp%tveg_longterm%FuseRMean(dp%tveg_longterm,rp%area*inv_sum_area)

rp%fuel_eff_moist = (dp%fuel_eff_moist*dp%area + rp%fuel_eff_moist*rp%area) * inv_sum_area
rp%livegrass = (dp%livegrass*dp%area + rp%livegrass*rp%area) * inv_sum_area
rp%sum_fuel = (dp%sum_fuel*dp%area + rp%sum_fuel*rp%area) * inv_sum_area
rp%fuel_bulkd = (dp%fuel_bulkd*dp%area + rp%fuel_bulkd*rp%area) * inv_sum_area
rp%fuel_sav = (dp%fuel_sav*dp%area + rp%fuel_sav*rp%area) * inv_sum_area
rp%fuel_mef = (dp%fuel_mef*dp%area + rp%fuel_mef*rp%area) * inv_sum_area
rp%ros_front = (dp%ros_front*dp%area + rp%ros_front*rp%area) * inv_sum_area
rp%tau_l = (dp%tau_l*dp%area + rp%tau_l*rp%area) * inv_sum_area
rp%fuel_frac(:) = (dp%fuel_frac(:)*dp%area + rp%fuel_frac(:)*rp%area) * inv_sum_area
rp%fuel%average_moisture = (dp%fuel%average_moisture*dp%area + rp%fuel%average_moisture*rp%area) * inv_sum_area
rp%fuel%effective_moisture = (dp%fuel%effective_moisture(:)*dp%area + rp%fuel%effective_moisture(:)*rp%area) * inv_sum_area
rp%livegrass = (dp%livegrass*dp%area + rp%livegrass*rp%area) * inv_sum_area
rp%ros_front = (dp%ros_front*dp%area + rp%ros_front*rp%area) * inv_sum_area
rp%tau_l = (dp%tau_l*dp%area + rp%tau_l*rp%area) * inv_sum_area
rp%tfc_ros = (dp%tfc_ros*dp%area + rp%tfc_ros*rp%area) * inv_sum_area
rp%fi = (dp%fi*dp%area + rp%fi*rp%area) * inv_sum_area
rp%fd = (dp%fd*dp%area + rp%fd*rp%area) * inv_sum_area
rp%ros_back = (dp%ros_back*dp%area + rp%ros_back*rp%area) * inv_sum_area
rp%scorch_ht(:) = (dp%scorch_ht(:)*dp%area + rp%scorch_ht(:)*rp%area) * inv_sum_area
rp%frac_burnt = (dp%frac_burnt*dp%area + rp%frac_burnt*rp%area) * inv_sum_area
rp%burnt_frac_litter(:) = (dp%burnt_frac_litter(:)*dp%area + rp%burnt_frac_litter(:)*rp%area) * inv_sum_area
rp%btran_ft(:) = (dp%btran_ft(:)*dp%area + rp%btran_ft(:)*rp%area) * inv_sum_area
rp%zstar = (dp%zstar*dp%area + rp%zstar*rp%area) * inv_sum_area
rp%c_stomata = (dp%c_stomata*dp%area + rp%c_stomata*rp%area) * inv_sum_area
Expand Down Expand Up @@ -3392,7 +3388,6 @@ subroutine fuse_2_patches(csite, dp, rp)
olderp%younger => null()
end if


if(associated(olderp))then
! Update the older patch's new younger patch (becuase it isn't dp anymore)
olderp%younger => youngerp
Expand Down
6 changes: 3 additions & 3 deletions biogeochem/EDPhysiologyMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module EDPhysiologyMod
use EDTypesMod , only : site_massbal_type
use EDTypesMod , only : numlevsoil_max
use EDTypesMod , only : numWaterMem
use FatesLitterMod , only : dl_sf
use FatesFuelClassesMod , only : fuel_classes
use EDParamsMod , only : dinc_vai, dlower_vai
use EDTypesMod , only : area_inv
use EDTypesMod , only : AREA
Expand Down Expand Up @@ -3261,11 +3261,11 @@ subroutine CWDOut( litt, fragmentation_scaler, nlev_eff_decomp )
do dcmpy = 1,ndcmpy

litt%leaf_fines_frag(dcmpy) = litt%leaf_fines(dcmpy) * &
years_per_day * SF_val_max_decomp(dl_sf) * fragmentation_scaler(soil_layer_index)
years_per_day * SF_val_max_decomp(fuel_classes%dead_leaves()) * fragmentation_scaler(soil_layer_index)

do ilyr = 1,nlev_eff_decomp
litt%root_fines_frag(dcmpy,ilyr) = litt%root_fines(dcmpy,ilyr) * &
years_per_day * SF_val_max_decomp(dl_sf) * fragmentation_scaler(ilyr)
years_per_day * SF_val_max_decomp(fuel_classes%dead_leaves()) * fragmentation_scaler(ilyr)
end do
enddo

Expand Down
12 changes: 0 additions & 12 deletions biogeochem/FatesLitterMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,6 @@ module FatesLitterMod
integer, public, parameter :: ilabile = 1 ! Array index for labile portion
integer, public, parameter :: icellulose = 2 ! Array index for cellulose portion
integer, public, parameter :: ilignin = 3 ! Array index for the lignin portion

! SPITFIRE

integer, parameter, public :: NFSC = NCWD+2 ! number fuel size classes (4 cwd size classes, leaf litter, and grass)
integer, parameter, public :: tw_sf = 1 ! array index of twig pool for spitfire
integer, parameter, public :: lb_sf = 3 ! array index of large branch pool for spitfire
integer, parameter, public :: tr_sf = 4 ! array index of dead trunk pool for spitfire
integer, parameter, public :: dl_sf = 5 ! array index of dead leaf pool for spitfire (dead grass and dead leaves)
integer, parameter, public :: lg_sf = 6 ! array index of live grass pool for spitfire



type, public :: litter_type

! This object is allocated for each element (C, N, P, etc) that we wish to track.
Expand Down
90 changes: 54 additions & 36 deletions biogeochem/FatesPatchMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ module FatesPatchMod
use FatesConstantsMod, only : primaryland, secondaryland
use FatesConstantsMod, only : n_landuse_cats
use FatesConstantsMod, only : TRS_regeneration
use FatesConstantsMod, only : itrue
use FatesConstantsMod, only : itrue, ifalse
use FatesGlobals, only : fates_log
use FatesGlobals, only : endrun => fates_endrun
use FatesUtilsMod, only : check_hlm_list
use FatesUtilsMod, only : check_var_real
use FatesCohortMod, only : fates_cohort_type
use FatesRunningMeanMod, only : rmean_type, rmean_arr_type
use FatesLitterMod, only : nfsc
use FatesFuelClassesMod, only : nfsc
use FatesLitterMod, only : litter_type
use FatesFuelMod, only : fuel_type
use PRTGenericMod, only : num_elements
use PRTGenericMod, only : element_list
use PRTGenericMod, only : carbon12_element
use PRTGenericMod, only : struct_organ, leaf_organ, sapw_organ
use PRTParametersMod, only : prt_params
use FatesConstantsMod, only : nocomp_bareground
use EDParamsMod, only : nlevleaf, nclmax, maxpft
Expand Down Expand Up @@ -195,24 +198,14 @@ module FatesPatchMod

! LITTER AND COARSE WOODY DEBRIS
type(litter_type), pointer :: litter(:) ! litter (leaf,fnrt,CWD and seeds) for different elements
type(fuel_type), pointer :: fuel ! fuel class
real(r8), allocatable :: fragmentation_scaler(:) ! scale rate of litter fragmentation based on soil layer [0-1]

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

! FUELS AND FIRE
! fuel characteristics
real(r8) :: sum_fuel ! total ground fuel related to ROS (omits 1000 hr fuels) [kgC/m2]
real(r8) :: fuel_frac(nfsc) ! fraction of each litter class in the ros_fuel [0-1]
real(r8) :: livegrass ! total aboveground grass biomass in patch [kgC/m2]
real(r8) :: fuel_bulkd ! average fuel bulk density of the ground fuel. [kg/m3]
! (incl. live grasses, omits 1000hr fuels)
real(r8) :: fuel_sav ! average surface area to volume ratio of the ground fuel [cm-1]
! (incl. live grasses, omits 1000hr fuels)
real(r8) :: fuel_mef ! average moisture of extinction factor
! of the ground fuel (incl. live grasses, omits 1000hr fuels)
real(r8) :: fuel_eff_moist ! effective avearage fuel moisture content of the ground fuel
! (incl. live grasses. omits 1000hr fuels)
real(r8) :: litter_moisture(nfsc) ! moisture of litter [m3/m3]

! fire spread
real(r8) :: ros_front ! rate of forward spread of fire [m/min]
Expand All @@ -221,13 +214,11 @@ module FatesPatchMod
real(r8) :: fi ! average fire intensity of flaming front [kJ/m/s] or [kW/m]
integer :: fire ! is there a fire? [1=yes; 0=no]
real(r8) :: fd ! fire duration [min]
real(r8) :: frac_burnt ! fraction of patch burnt by fire

! fire effects
real(r8) :: scorch_ht(maxpft) ! scorch height [m]
real(r8) :: frac_burnt ! fraction burnt [0-1/day]
real(r8) :: tfc_ros ! total intensity-relevant fuel consumed - no trunks [kgC/m2 of burned ground/day]
real(r8) :: burnt_frac_litter(nfsc) ! fraction of each litter pool burned, conditional on it being burned [0-1]

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

! PLANT HYDRAULICS (not currently used in hydraulics RGK 03-2018)
Expand All @@ -245,6 +236,7 @@ module FatesPatchMod
procedure :: InitLitter
procedure :: Create
procedure :: UpdateTreeGrassArea
procedure :: UpdateLiveGrass
procedure :: FreeMemory
procedure :: Dump
procedure :: CheckVars
Expand Down Expand Up @@ -506,25 +498,17 @@ subroutine NanValues(this)
this%fragmentation_scaler(:) = nan

! FUELS AND FIRE
this%sum_fuel = nan
this%fuel_frac(:) = nan
this%livegrass = nan
this%fuel_bulkd = nan
this%fuel_sav = nan
this%fuel_mef = nan
this%fuel_eff_moist = nan
this%litter_moisture(:) = nan
this%ros_front = nan
this%ros_back = nan
this%tau_l = nan
this%fi = nan
this%fire = fates_unset_int
this%fd = nan
this%scorch_ht(:) = nan
this%tfc_ros = nan
this%frac_burnt = nan
this%tfc_ros = nan
this%burnt_frac_litter(:) = nan


end subroutine NanValues

!===========================================================================
Expand Down Expand Up @@ -600,23 +584,15 @@ subroutine ZeroValues(this)
this%fragmentation_scaler(:) = 0.0_r8

! FIRE
this%sum_fuel = 0.0_r8
this%fuel_frac(:) = 0.0_r8
this%livegrass = 0.0_r8
this%fuel_bulkd = 0.0_r8
this%fuel_sav = 0.0_r8
this%fuel_mef = 0.0_r8
this%fuel_eff_moist = 0.0_r8
this%litter_moisture(:) = 0.0_r8
this%ros_front = 0.0_r8
this%ros_back = 0.0_r8
this%tau_l = 0.0_r8
this%fi = 0.0_r8
this%fd = 0.0_r8
this%scorch_ht(:) = 0.0_r8
this%frac_burnt = 0.0_r8
this%tfc_ros = 0.0_r8
this%burnt_frac_litter(:) = 0.0_r8
this%frac_burnt = 0.0_r8

end subroutine ZeroValues

Expand Down Expand Up @@ -738,6 +714,10 @@ subroutine Create(this, age, area, land_use_label, nocomp_pft, num_swb, num_pft,
! initialize litter
call this%InitLitter(num_pft, num_levsoil)

! initialize fuel
allocate(this%fuel)
call this%fuel%Init()

this%twostr%scelg => null() ! The radiation module will check if this
! is associated, since it is not, it will then
! initialize and allocate
Expand Down Expand Up @@ -802,6 +782,38 @@ end subroutine UpdateTreeGrassArea

!===========================================================================

subroutine UpdateLiveGrass(this)
!
! DESCRIPTION:
! Calculates the sum of live grass biomass [kgC/m2] on a patch

! ARGUMENTS:
class(fates_patch_type), intent(inout) :: this ! patch

! LOCALS:
real(r8) :: live_grass ! live grass [kgC/m2]
class(fates_cohort_type), pointer :: currentCohort ! cohort type

live_grass = 0.0_r8
currentCohort => this%tallest
do while(associated(currentCohort))
! for grasses sum all aboveground tissues
if (prt_params%woody(currentCohort%pft) == ifalse) then
live_grass = live_grass + &
(currentCohort%prt%GetState(leaf_organ, carbon12_element) + &
currentCohort%prt%GetState(sapw_organ, carbon12_element) + &
currentCohort%prt%GetState(struct_organ, carbon12_element))* &
currentCohort%n/this%area
endif
currentCohort => currentCohort%shorter
enddo

this%livegrass = live_grass

end subroutine UpdateLiveGrass

!===========================================================================

subroutine FreeMemory(this, regeneration_model, numpft)
!
! DESCRIPTION:
Expand Down Expand Up @@ -849,7 +861,13 @@ subroutine FreeMemory(this, regeneration_model, numpft)
write(fates_log(),*) 'dealloc008: fail on deallocate(this%litter):'//trim(smsg)
call endrun(msg=errMsg(sourcefile, __LINE__))
endif


deallocate(this%fuel, stat=istat, errmsg=smsg)
if (istat/=0) then
write(fates_log(),*) 'dealloc009: fail on deallocate patch fuel:'//trim(smsg)
call endrun(msg=errMsg(sourcefile, __LINE__))
endif

! deallocate the allocatable arrays
deallocate(this%tr_soil_dir, &
this%tr_soil_dif, &
Expand Down
2 changes: 2 additions & 0 deletions fire/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ list(APPEND fates_sources
SFParamsMod.F90
SFFireWeatherMod.F90
SFNesterovMod.F90
FatesFuelMod.F90
FatesFuelClassesMod.F90
)

sourcelist_to_parent(fates_sources)
Loading