diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index 03b2ac4cda..06f5556155 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -59,6 +59,9 @@ module EDLoggingMortalityMod character(len=*), parameter, private :: sourcefile = & __FILE__ + + + real(r8), public, parameter :: logging_export_frac = 0.8_r8 public :: LoggingMortality_frac public :: logging_litter_fluxes @@ -170,6 +173,8 @@ subroutine LoggingMortality_frac( pft_i, dbh, canopy_layer, lmort_direct, & real(r8), parameter :: adjustment = 1.0 ! adjustment for mortality rates if (logging_time) then + + if(EDPftvarcon_inst%woody(pft_i) == 1)then ! only set logging rates for trees ! Pass logging rates to cohort level @@ -192,8 +197,14 @@ subroutine LoggingMortality_frac( pft_i, dbh, canopy_layer, lmort_direct, & ! Collateral damage to smaller plants below the canopy layer ! will be applied via "understory_death" via the disturbance algorithm + ! Important: Degredation rates really only have an impact when + ! applied to the canopy layer. So we don't add to degredation + ! for collateral damage, even understory collateral damage. + if (canopy_layer .eq. 1) then lmort_collateral = logging_collateral_frac * adjustment + else + lmort_collateral = 0._r8 endif else @@ -202,6 +213,7 @@ subroutine LoggingMortality_frac( pft_i, dbh, canopy_layer, lmort_direct, & lmort_infra = 0.0_r8 l_degrad = 0.0_r8 end if + else lmort_direct = 0.0_r8 lmort_collateral = 0.0_r8 @@ -309,10 +321,19 @@ subroutine logging_litter_fluxes(currentSite, currentPatch, newPatch, patch_site (currentCohort%lmort_collateral + currentCohort%lmort_infra) else + + ! This routine is only called during disturbance. The litter + ! fluxes from non-disturbance generating mortality are + ! handled in EDPhysiology. Disturbance generating mortality + ! are those cohorts in the top canopy layer, or those + ! plants that were impacted. Thus, no direct dead can occur + ! here, and indirect are impacts. + if(EDPftvarcon_inst%woody(currentCohort%pft) == 1)then direct_dead = 0.0_r8 - indirect_dead = logging_coll_under_frac * currentCohort%n * & - (patch_site_areadis/currentPatch%area) !kgC/site/day + indirect_dead = logging_coll_under_frac * & + (1._r8-currentPatch%fract_ldist_not_harvested) * currentCohort%n * & + (patch_site_areadis/currentPatch%area) !kgC/site/day else ! If the cohort of interest is grass, it will not experience ! any mortality associated with the logging disturbance diff --git a/biogeochem/EDMortalityFunctionsMod.F90 b/biogeochem/EDMortalityFunctionsMod.F90 index d527b59b0b..eed631046a 100644 --- a/biogeochem/EDMortalityFunctionsMod.F90 +++ b/biogeochem/EDMortalityFunctionsMod.F90 @@ -200,15 +200,18 @@ subroutine Mortality_Derivative( currentSite, currentCohort, bc_in) currentCohort%lmort_infra, & currentCohort%l_degrad) + + + if (currentCohort%canopy_layer > 1)then - ! Include understory logging mortality rates not associated with disturbance dndt_logging = (currentCohort%lmort_direct + & currentCohort%lmort_collateral + & currentCohort%lmort_infra)/hlm_freq_day - currentCohort%dndt = -1.0_r8 * (cmort+hmort+bmort+frmort+dndt_logging) * currentCohort%n else + ! Mortality from logging in the canopy is ONLY disturbance generating, don't + ! update number densities via non-disturbance inducing death currentCohort%dndt = -(1.0_r8 - fates_mortality_disturbance_fraction) & * (cmort+hmort+bmort+frmort) * currentCohort%n endif diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 7969773b8a..5b2cb684c4 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -20,6 +20,7 @@ module EDPatchDynamicsMod use EDTypesMod , only : dtype_ilog use EDTypesMod , only : dtype_ifire use EDTypesMod , only : ican_upper + use EDTypesMod , only : lg_sf use FatesInterfaceMod , only : hlm_use_planthydro use FatesInterfaceMod , only : hlm_numSWb use FatesInterfaceMod , only : bc_in_type @@ -151,7 +152,7 @@ subroutine disturbance_rates( site_in, bc_in) call LoggingMortality_frac(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_layer, & lmort_direct,lmort_collateral,lmort_infra,l_degrad ) - currentCohort%lmort_direct = lmort_direct + currentCohort%lmort_direct = lmort_direct currentCohort%lmort_collateral = lmort_collateral currentCohort%lmort_infra = lmort_infra currentCohort%l_degrad = l_degrad @@ -186,7 +187,7 @@ subroutine disturbance_rates( site_in, bc_in) ! Logging Disturbance Rate currentPatch%disturbance_rates(dtype_ilog) = currentPatch%disturbance_rates(dtype_ilog) + & - min(1.0_r8, currentCohort%lmort_direct + & + min(1.0_r8, currentCohort%lmort_direct + & currentCohort%lmort_collateral + & currentCohort%lmort_infra + & currentCohort%l_degrad ) * & @@ -226,7 +227,7 @@ subroutine disturbance_rates( site_in, bc_in) ! to still diagnose and track the non-disturbance rate ! ------------------------------------------------------------------------------------------ - + ! DISTURBANCE IS LOGGING if (currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifall) .and. & currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifire) ) then @@ -245,7 +246,7 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort => currentCohort%taller enddo !currentCohort - ! DISTURBANCE IS FIRE + ! DISTURBANCE IS FIRE elseif (currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ifall) .and. & currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ilog) ) then @@ -275,7 +276,7 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort => currentCohort%taller enddo !currentCohort - else ! If fire and loggin are not greater than treefall, just set disturbance rate to tree-fall + else ! If fire and logging are not greater than treefall, just set disturbance rate to tree-fall ! which is most likely a 0.0 currentPatch%disturbance_rate = currentPatch%disturbance_rates(dtype_ifall) @@ -477,6 +478,8 @@ subroutine spawn_patches( currentSite, bc_in) call logging_litter_fluxes(currentSite, currentPatch, new_patch, patch_site_areadis) + if(debug) write(fates_log(),*) "Logging disturbance generated:",patch_site_areadis + elseif ((currentPatch%disturbance_rates(dtype_ifire) > & currentPatch%disturbance_rates(dtype_ifall)) .and. & (currentPatch%disturbance_rates(dtype_ifire) > & @@ -681,7 +684,7 @@ subroutine spawn_patches( currentSite, bc_in) nc%lmort_infra = currentCohort%lmort_infra - ! Logging is the dominant disturbance + ! Logging is the dominant disturbance elseif ((currentPatch%disturbance_rates(dtype_ilog) > & currentPatch%disturbance_rates(dtype_ifall)) .and. & (currentPatch%disturbance_rates(dtype_ilog) > & @@ -756,7 +759,7 @@ subroutine spawn_patches( currentSite, bc_in) ! LOGGING SURVIVORSHIP OF UNDERSTORY PLANTS IS SET AS A NEW PARAMETER ! in the fatesparameter files nc%n = nc%n * (1.0_r8 - & - currentPatch%fract_ldist_not_harvested * logging_coll_under_frac) + (1.0_r8-currentPatch%fract_ldist_not_harvested) * logging_coll_under_frac) ! Step 3: Reduce the number count of cohorts in the ! original/donor/non-disturbed patch to reflect the area change @@ -1085,7 +1088,7 @@ subroutine fire_litter_fluxes(currentSite, cp_target, new_patch_target, patch_si !************************************/ do c = 1,ncwd burned_litter = new_patch%cwd_ag(c) * patch_site_areadis/new_patch%area * & - currentPatch%burnt_frac_litter(c+1) !kG/m2/day + currentPatch%burnt_frac_litter(c) !kG/m2/day new_patch%cwd_ag(c) = new_patch%cwd_ag(c) - burned_litter currentSite%flux_out = currentSite%flux_out + burned_litter * new_patch%area !kG/site/day currentSite%total_burn_flux_to_atm = currentSite%total_burn_flux_to_atm + & @@ -1240,7 +1243,7 @@ subroutine fire_litter_fluxes(currentSite, cp_target, new_patch_target, patch_si if(EDPftvarcon_inst%woody(currentCohort%pft) == 1)then burned_leaves = leaf_c * currentCohort%fraction_crown_burned else - burned_leaves = leaf_c * currentPatch%burnt_frac_litter(6) + burned_leaves = leaf_c * currentPatch%burnt_frac_litter(lg_sf) endif if (burned_leaves > 0.0_r8) then diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 5f3c8c842f..be78f4776f 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -49,6 +49,8 @@ module EDPhysiologyMod use FatesGlobals , only : fates_log use FatesGlobals , only : endrun => fates_endrun use EDParamsMod , only : fates_mortality_disturbance_fraction + use EDLoggingMortalityMod , only : logging_export_frac + !use EDParamsMod , only : logging_export_frac use FatesPlantHydraulicsMod , only : AccumulateMortalityWaterStorage @@ -1262,120 +1264,136 @@ subroutine CWD_Input( currentSite, currentPatch) (1.0_r8-EDPftvarcon_inst%allom_agb_frac(currentCohort%pft)) enddo - !if (currentCohort%canopy_layer > 1)then - - ! ================================================ - ! Litter fluxes for understorey mortality. KgC/m2/year - ! ================================================ - - ! Total number of dead understory (n/m2) - dead_n = -1.0_r8 * currentCohort%dndt / currentPatch%area - - ! Total number of dead understory from direct logging - ! (it is possible that large harvestable trees are in the understory) - dead_n_dlogging = ( currentCohort%lmort_direct) * & - currentCohort%n/hlm_freq_day/currentPatch%area - - ! Total number of dead understory from indirect logging - dead_n_ilogging = ( currentCohort%lmort_collateral + currentCohort%lmort_infra) * & - currentCohort%n/hlm_freq_day/currentPatch%area - - dead_n_natural = dead_n - dead_n_dlogging - dead_n_ilogging - - - currentPatch%leaf_litter_in(pft) = currentPatch%leaf_litter_in(pft) + & - (leaf_c)* dead_n - ! %n has not been updated due to mortality yet, thus - ! the litter flux has already been counted since it captured - ! the losses of live trees and those flagged for death - - currentPatch%root_litter_in(pft) = currentPatch%root_litter_in(pft) + & + ! ================================================ + ! Litter fluxes for understorey mortality. KgC/m2/year + ! ================================================ + + ! Total number of dead understory (n/m2) + dead_n = -1.0_r8 * currentCohort%dndt / currentPatch%area + + if(currentCohort%canopy_layer > 1)then + + ! Total number of dead understory from direct logging + ! (it is possible that large harvestable trees are in the understory) + dead_n_dlogging = ( currentCohort%lmort_direct) * & + currentCohort%n/hlm_freq_day/currentPatch%area + + ! Total number of dead understory from indirect logging + dead_n_ilogging = ( currentCohort%lmort_collateral + currentCohort%lmort_infra) * & + currentCohort%n/hlm_freq_day/currentPatch%area + + else + + ! All mortality from logging in the canopy is + ! is disturbance generating + + dead_n_dlogging = 0._r8 + dead_n_ilogging = 0._r8 + + end if + + dead_n_natural = dead_n - dead_n_dlogging - dead_n_ilogging + + + currentPatch%leaf_litter_in(pft) = currentPatch%leaf_litter_in(pft) + & + (leaf_c)* dead_n + + ! %n has not been updated due to mortality yet, thus + ! the litter flux has already been counted since it captured + ! the losses of live trees and those flagged for death + + currentPatch%root_litter_in(pft) = currentPatch%root_litter_in(pft) + & (fnrt_c + store_c*(1._r8-EDPftvarcon_inst%allom_frbstor_repro(pft)) ) * dead_n - ! Update diagnostics that track resource management - currentSite%resources_management%delta_litter_stock = & - currentSite%resources_management%delta_litter_stock + & - (leaf_c + fnrt_c + store_c ) * & - (dead_n_ilogging+dead_n_dlogging) * & - hlm_freq_day * currentPatch%area - - ! Update diagnostics that track resource management - currentSite%resources_management%delta_biomass_stock = & - currentSite%resources_management%delta_biomass_stock + & - (leaf_c + fnrt_c + store_c ) * & - (dead_n_ilogging+dead_n_dlogging) * & - hlm_freq_day * currentPatch%area - - if( hlm_use_planthydro == itrue ) then - !call AccumulateMortalityWaterStorage(currentSite,currentCohort,dead_n) - call AccumulateMortalityWaterStorage(currentSite,currentCohort,& - -1.0_r8 * currentCohort%dndt * hlm_freq_day) - end if - + ! Update diagnostics that track resource management + currentSite%resources_management%delta_litter_stock = & + currentSite%resources_management%delta_litter_stock + & + (leaf_c + fnrt_c + store_c ) * & + (dead_n_ilogging+dead_n_dlogging) * & + hlm_freq_day * currentPatch%area + + ! Update diagnostics that track resource management + currentSite%resources_management%delta_biomass_stock = & + currentSite%resources_management%delta_biomass_stock + & + (leaf_c + fnrt_c + store_c ) * & + (dead_n_ilogging+dead_n_dlogging) * & + hlm_freq_day * currentPatch%area + + if( hlm_use_planthydro == itrue ) then + !call AccumulateMortalityWaterStorage(currentSite,currentCohort,dead_n) + call AccumulateMortalityWaterStorage(currentSite,currentCohort,& + -1.0_r8 * currentCohort%dndt * hlm_freq_day) + end if + - do c = 1,ncwd + do c = 1,ncwd - currentPatch%cwd_BG_in(c) = currentPatch%cwd_BG_in(c) + (struct_c + sapw_c) * & - SF_val_CWD_frac(c) * dead_n * (1.0_r8-EDPftvarcon_inst%allom_agb_frac(currentCohort%pft)) - - ! Send AGB component of boles from non direct-logging activities to AGB litter pool - if (c==ncwd) then - - currentPatch%cwd_AG_in(c) = currentPatch%cwd_AG_in(c) + (struct_c + sapw_c) * & - SF_val_CWD_frac(c) * (dead_n_natural+dead_n_ilogging) * & - EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) - - else - - currentPatch%cwd_AG_in(c) = currentPatch%cwd_AG_in(c) + (struct_c + sapw_c) * & - SF_val_CWD_frac(c) * dead_n * & - EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) - - ! Send AGB component of boles from direct-logging activities to export/harvest pool - ! Generate trunk product (kgC/day/site) - trunk_product = (struct_c + sapw_c) * & - SF_val_CWD_frac(c) * dead_n_dlogging * EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) * & - hlm_freq_day * currentPatch%area + currentPatch%cwd_BG_in(c) = currentPatch%cwd_BG_in(c) + (struct_c + sapw_c) * & + SF_val_CWD_frac(c) * dead_n * (1.0_r8-EDPftvarcon_inst%allom_agb_frac(currentCohort%pft)) + + ! Send AGB component of boles from non direct-logging activities to AGB litter pool + if (c==ncwd) then + + ! CWD contributed by indirect damage + currentPatch%cwd_AG_in(c) = currentPatch%cwd_AG_in(c) + (struct_c + sapw_c) * & + SF_val_CWD_frac(c) * (dead_n_natural+ dead_n_ilogging) * & + EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) + + ! CWD contributed by logged boles due to losses in transportation + currentPatch%cwd_AG_in(c) = currentPatch%cwd_AG_in(c) + & + (1.0_r8 - logging_export_frac) * (struct_c + sapw_c) * SF_val_CWD_frac(c) * & + dead_n_dlogging * EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) + + ! Send AGB component of boles from direct-logging activities to + ! export/harvest pool + ! Generate trunk product (kgC/day/site) + trunk_product = logging_export_frac * (struct_c + sapw_c) * & + SF_val_CWD_frac(c) * dead_n_dlogging * EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) * & + hlm_freq_day * currentPatch%area + + currentSite%flux_out = currentSite%flux_out + trunk_product + + ! Update diagnostics that track resource management + currentSite%resources_management%trunk_product_site = & + currentSite%resources_management%trunk_product_site + & + trunk_product - currentSite%flux_out = currentSite%flux_out + trunk_product - - ! Update diagnostics that track resource management - currentSite%resources_management%trunk_product_site = & - currentSite%resources_management%trunk_product_site + & - trunk_product - ! Update diagnostics that track resource management - currentSite%resources_management%trunk_product_site = & - currentSite%resources_management%trunk_product_site + & - trunk_product - end if - - ! Update diagnostics that track resource management - currentSite%resources_management%delta_litter_stock = & - currentSite%resources_management%delta_litter_stock + & - (struct_c + sapw_c) * & - SF_val_CWD_frac(c) * (dead_n_natural+dead_n_ilogging) * & - hlm_freq_day * currentPatch%area - ! Update diagnostics that track resource management - currentSite%resources_management%delta_biomass_stock = & - currentSite%resources_management%delta_biomass_stock + & - (struct_c + sapw_c) * & - SF_val_CWD_frac(c) * dead_n * & - hlm_freq_day * currentPatch%area - - if (currentPatch%cwd_AG_in(c) < 0.0_r8)then - write(fates_log(),*) 'negative CWD in flux',currentPatch%cwd_AG_in(c), & - (struct_c + sapw_c), dead_n - endif - - end do - ! Update diagnostics that track resource management - currentSite%resources_management%delta_individual = & - currentSite%resources_management%delta_individual + & - (dead_n_dlogging+dead_n_ilogging) * hlm_freq_day * currentPatch%area - - !endif !canopy layer + else + + currentPatch%cwd_AG_in(c) = currentPatch%cwd_AG_in(c) + (struct_c + sapw_c) * & + SF_val_CWD_frac(c) * dead_n * & + EDPftvarcon_inst%allom_agb_frac(currentCohort%pft) + + end if + + ! Update diagnostics that track resource management + currentSite%resources_management%delta_litter_stock = & + currentSite%resources_management%delta_litter_stock + & + (struct_c + sapw_c) * & + SF_val_CWD_frac(c) * (dead_n_natural+dead_n_ilogging) * & + hlm_freq_day * currentPatch%area + + ! Update diagnostics that track resource management + currentSite%resources_management%delta_biomass_stock = & + currentSite%resources_management%delta_biomass_stock + & + (struct_c + sapw_c) * & + SF_val_CWD_frac(c) * dead_n * & + hlm_freq_day * currentPatch%area + + if (currentPatch%cwd_AG_in(c) < 0.0_r8)then + write(fates_log(),*) 'negative CWD in flux',currentPatch%cwd_AG_in(c), & + (struct_c + sapw_c), dead_n, dead_n_natural, dead_n_ilogging, dead_n_dlogging + call endrun(msg=errMsg(sourcefile, __LINE__)) + endif + + end do + ! Update diagnostics that track resource management + currentSite%resources_management%delta_individual = & + currentSite%resources_management%delta_individual + & + (dead_n_dlogging+dead_n_ilogging) * hlm_freq_day * currentPatch%area + - currentCohort => currentCohort%taller + currentCohort => currentCohort%taller enddo ! end loop over cohorts do p = 1,numpft @@ -1487,9 +1505,9 @@ subroutine cwd_out( currentSite, currentPatch, bc_in ) do c = 1,ncwd currentPatch%cwd_ag_out(c) = max(0.0_r8, currentPatch%cwd_ag(c) * & - SF_val_max_decomp(c+1) * currentPatch%fragmentation_scaler ) + SF_val_max_decomp(c) * currentPatch%fragmentation_scaler ) currentPatch%cwd_bg_out(c) = max(0.0_r8, currentPatch%cwd_bg(c) * & - SF_val_max_decomp(c+1) * currentPatch%fragmentation_scaler ) + SF_val_max_decomp(c) * currentPatch%fragmentation_scaler ) enddo ! this is the rate at which dropped leaves stop being part of the burnable pool and begin to be part of the diff --git a/fire/SFMainMod.F90 b/fire/SFMainMod.F90 index 505437634d..80897f1c6c 100644 --- a/fire/SFMainMod.F90 +++ b/fire/SFMainMod.F90 @@ -122,9 +122,9 @@ subroutine fire_danger_index ( currentSite, bc_in) real(r8) :: rainfall ! daily precip in mm/day real(r8) :: rh ! daily rh - real yipsolon; !intermediate varable for dewpoint calculation - real dewpoint; !dewpoint in K - real d_NI; !daily change in Nesterov Index. C^2 + real yipsolon; !intermediate varable for dewpoint calculation + real dewpoint; !dewpoint in K + real d_NI; !daily change in Nesterov Index. C^2 integer :: iofp ! index of oldest the fates patch ! NOTE that the boundary conditions of temperature, precipitation and relative humidity @@ -149,7 +149,7 @@ subroutine fire_danger_index ( currentSite, bc_in) d_NI = 0.0_r8 !check endif endif - currentSite%acc_NI = currentSite%acc_NI + d_NI !Accumulate Nesterov index over the fire season. + currentSite%acc_NI = currentSite%acc_NI + d_NI !Accumulate Nesterov index over the fire season. end subroutine fire_danger_index @@ -189,11 +189,11 @@ subroutine charecteristics_of_fuel ( currentSite ) enddo ! There are SIX fuel classes - ! 1) Leaf litter, 2:5) four CWD_AG pools (twig, s branch, l branch, trunk) and 6) live grass + ! 1:4) four CWD_AG pools (twig, s branch, l branch, trunk), 5) dead leaves and 6) live grass ! NCWD =4 NFSC = 6 - ! dl_sf = 1, tw_sf = 2, lb_sf = 4, tr_sf = 5, lg_sf = 6, + ! tw_sf = 1, lb_sf = 3, tr_sf = 4, dl_sf = 5, lg_sf = 6, - ! zero fire arrays. + ! zero fire arrays. currentPatch%fuel_eff_moist = 0.0_r8 currentPatch%fuel_bulkd = 0.0_r8 !this is kgBiomass/m2 for use in rate of spread equations currentPatch%fuel_sav = 0.0_r8 @@ -233,12 +233,12 @@ subroutine charecteristics_of_fuel ( currentSite ) MEF(1:nfsc) = 0.524_r8 - 0.066_r8 * log10(SF_val_SAV(1:nfsc)) !--- weighted average of relative moisture content--- - ! Equation 6 in Thonicke et al. 2010. across leaves,twig, small branch, and large branch + ! Equation 6 in Thonicke et al. 2010. across twig, small branch, large branch, and dead leaves ! dead leaves and twigs included in 1hr pool per Thonicke (2010) ! Calculate fuel moisture for trunks to hold value for fuel consumption - alpha_FMC(dl_sf:tr_sf) = SF_val_SAV(dl_sf:tr_sf)/SF_val_drying_ratio + alpha_FMC(tw_sf:dl_sf) = SF_val_SAV(tw_sf:dl_sf)/SF_val_drying_ratio - fuel_moisture(dl_sf:tr_sf) = exp(-1.0_r8 * alpha_FMC(dl_sf:tr_sf) * currentSite%acc_NI) + fuel_moisture(tw_sf:dl_sf) = exp(-1.0_r8 * alpha_FMC(tw_sf:dl_sf) * currentSite%acc_NI) if(write_SF == itrue)then if ( hlm_masterproc == itrue ) write(fates_log(),*) 'ff3 ',currentPatch%fuel_frac @@ -253,19 +253,19 @@ subroutine charecteristics_of_fuel ( currentSite ) ! live grass moisture content depends on upper soil layer fuel_moisture(lg_sf) = max(0.0_r8, 10.0_r8/9._r8 * timeav_swc - 1.0_r8/9.0_r8) - ! Average properties over the first four litter pools (dead leaves, twigs, s branches, l branches) - currentPatch%fuel_bulkd = sum(currentPatch%fuel_frac(dl_sf:lb_sf) * SF_val_FBD(dl_sf:lb_sf)) - currentPatch%fuel_sav = sum(currentPatch%fuel_frac(dl_sf:lb_sf) * SF_val_SAV(dl_sf:lb_sf)) - currentPatch%fuel_mef = sum(currentPatch%fuel_frac(dl_sf:lb_sf) * MEF(dl_sf:lb_sf)) - currentPatch%fuel_eff_moist = sum(currentPatch%fuel_frac(dl_sf:lb_sf) * fuel_moisture(dl_sf:lb_sf)) + ! Average properties over the first three litter pools (twigs, s branches, l branches) + currentPatch%fuel_bulkd = sum(currentPatch%fuel_frac(tw_sf:lb_sf) * SF_val_FBD(tw_sf:lb_sf)) + currentPatch%fuel_sav = sum(currentPatch%fuel_frac(tw_sf:lb_sf) * SF_val_SAV(tw_sf:lb_sf)) + currentPatch%fuel_mef = sum(currentPatch%fuel_frac(tw_sf:lb_sf) * MEF(tw_sf:lb_sf)) + currentPatch%fuel_eff_moist = sum(currentPatch%fuel_frac(tw_sf:lb_sf) * fuel_moisture(tw_sf:lb_sf)) if(write_sf == itrue)then if ( hlm_masterproc == itrue ) write(fates_log(),*) 'ff4 ',currentPatch%fuel_eff_moist endif - ! Add on properties of live grass multiplied by grass fraction. (6) - currentPatch%fuel_bulkd = currentPatch%fuel_bulkd + currentPatch%fuel_frac(lg_sf) * SF_val_FBD(lg_sf) - currentPatch%fuel_sav = currentPatch%fuel_sav + currentPatch%fuel_frac(lg_sf) * SF_val_SAV(lg_sf) - currentPatch%fuel_mef = currentPatch%fuel_mef + currentPatch%fuel_frac(lg_sf) * MEF(lg_sf) - currentPatch%fuel_eff_moist = currentPatch%fuel_eff_moist + currentPatch%fuel_frac(lg_sf) * fuel_moisture(lg_sf) + ! Add on properties of dead leaves and live grass pools (5 & 6) + currentPatch%fuel_bulkd = currentPatch%fuel_bulkd + sum(currentPatch%fuel_frac(dl_sf:lg_sf) * SF_val_FBD(dl_sf:lg_sf)) + currentPatch%fuel_sav = currentPatch%fuel_sav + sum(currentPatch%fuel_frac(dl_sf:lg_sf) * SF_val_SAV(dl_sf:lg_sf)) + currentPatch%fuel_mef = currentPatch%fuel_mef + sum(currentPatch%fuel_frac(dl_sf:lg_sf) * MEF(dl_sf:lg_sf)) + currentPatch%fuel_eff_moist = currentPatch%fuel_eff_moist+ sum(currentPatch%fuel_frac(dl_sf:lg_sf) * fuel_moisture(dl_sf:lg_sf)) ! Correct averaging for the fact that we are not using the trunks pool for fire ROS and intensity (5) ! Consumption of fuel in trunk pool does not influence fire ROS or intensity (Pyne 1996) @@ -274,12 +274,13 @@ subroutine charecteristics_of_fuel ( currentSite ) currentPatch%fuel_mef = currentPatch%fuel_mef * (1.0_r8/(1.0_r8-currentPatch%fuel_frac(tr_sf))) currentPatch%fuel_eff_moist = currentPatch%fuel_eff_moist * (1.0_r8/(1.0_r8-currentPatch%fuel_frac(tr_sf))) - ! Pass litter moisture into the fuel burning routine + ! Pass litter moisture into the fuel burning routine (all fuels: twigs,s branch,l branch,trunk,dead leaves,live grass) ! (wo/me term in Thonicke et al. 2010) - currentPatch%litter_moisture(dl_sf:lb_sf) = fuel_moisture(dl_sf:lb_sf)/MEF(dl_sf:lb_sf) + currentPatch%litter_moisture(tw_sf:lb_sf) = fuel_moisture(tw_sf:lb_sf)/MEF(tw_sf:lb_sf) currentPatch%litter_moisture(tr_sf) = fuel_moisture(tr_sf)/MEF(tr_sf) - currentPatch%litter_moisture(lg_sf) = fuel_moisture(lg_sf)/MEF(lg_sf) - + currentPatch%litter_moisture(dl_sf) = fuel_moisture(dl_sf)/MEF(dl_sf) + currentPatch%litter_moisture(lg_sf) = fuel_moisture(lg_sf)/MEF(lg_sf) + else if(write_SF == itrue)then @@ -334,8 +335,8 @@ subroutine wind_effect ( currentSite, bc_in) type(ed_cohort_type), pointer :: currentCohort real(r8) :: total_grass_area ! per patch,in m2 - real(r8) :: tree_fraction ! site level. no units - real(r8) :: grass_fraction ! site level. no units + real(r8) :: tree_fraction ! site level. no units + real(r8) :: grass_fraction ! site level. no units real(r8) :: bare_fraction ! site level. no units integer :: iofp ! index of oldest fates patch @@ -569,9 +570,9 @@ subroutine ground_fuel_consumption ( currentSite ) type(ed_patch_type), pointer :: currentPatch - real(r8) :: moist !effective fuel moisture - real(r8) :: tau_b(nfsc) !lethal heating rates for each fuel class (min) - real(r8) :: fc_ground(nfsc) !propn of fuel consumed + real(r8) :: moist ! effective fuel moisture + real(r8) :: tau_b(nfsc) ! lethal heating rates for each fuel class (min) + real(r8) :: fc_ground(nfsc) ! proportion of fuel consumed integer :: c @@ -611,8 +612,8 @@ subroutine ground_fuel_consumption ( currentSite ) currentPatch%burnt_frac_litter = currentPatch%burnt_frac_litter * (1.0_r8-SF_val_miner_total) !---Calculate amount of fuel burnt.--- - FC_ground(dl_sf) = currentPatch%burnt_frac_litter(dl_sf) * sum(currentPatch%leaf_litter) FC_ground(tw_sf:tr_sf) = currentPatch%burnt_frac_litter(tw_sf:tr_sf) * currentPatch%CWD_AG + FC_ground(dl_sf) = currentPatch%burnt_frac_litter(dl_sf) * sum(currentPatch%leaf_litter) FC_ground(lg_sf) = currentPatch%burnt_frac_litter(lg_sf) * currentPatch%livegrass ! Following used for determination of cambial kill follows from Peterson & Ryan (1986) scheme @@ -644,7 +645,7 @@ subroutine fire_intensity ( currentSite ) !***************************************************************** !returns the updated currentPatch%FI value for each patch. - !currentPatch%FI average fire intensity of flaming front during day. Backward ROS plays no role here. kJ/m/s or kW/m. + !currentPatch%FI avg fire intensity of flaming front during day. Backward ROS plays no role here. kJ/m/s or kW/m. !currentSite%FDI probability that an ignition will start a fire !currentPatch%ROS_front forward ROS (m/min) !currentPatch%TFC_ROS total fuel consumed by flaming front (kgC/m2) @@ -817,11 +818,11 @@ subroutine crown_scorching ( currentSite ) type(ed_patch_type), pointer :: currentPatch type(ed_cohort_type), pointer :: currentCohort - real(r8) :: f_ag_bmass !fraction of a tree cohort's above-ground biomass as a proportion of total patch ag tree biomass. - real(r8) :: tree_ag_biomass !total amount of above-ground tree biomass in patch. kgC/m2 - real(r8) :: leaf_c ! leaf carbon [kg] - real(r8) :: sapw_c ! sapwood carbon [kg] - real(r8) :: struct_c ! structure carbon [kg] + real(r8) :: f_ag_bmass ! fraction of tree cohort's above-ground biomass as a proportion of total patch ag tree biomass + real(r8) :: tree_ag_biomass ! total amount of above-ground tree biomass in patch. kgC/m2 + real(r8) :: leaf_c ! leaf carbon [kg] + real(r8) :: sapw_c ! sapwood carbon [kg] + real(r8) :: struct_c ! structure carbon [kg] currentPatch => currentSite%oldest_patch; diff --git a/main/EDParamsMod.F90 b/main/EDParamsMod.F90 index f94cdccad2..15103cdd29 100644 --- a/main/EDParamsMod.F90 +++ b/main/EDParamsMod.F90 @@ -117,6 +117,9 @@ module EDParamsMod real(r8),protected :: logging_dbhmax_infra ! "Tree diameter, above which infrastructure from logging does not impact damage or mortality. character(len=param_string_length),parameter :: logging_name_dbhmax_infra = "fates_logging_dbhmax_infra" + +! real(r8),protected :: logging_export_frac ! "fraction of trunk product being shipped offsite, the leftovers will be left onsite as large CWD +! character(len=param_string_length),parameter :: logging_name_export_frac ="fates_logging_export_frac" public :: FatesParamsInit public :: FatesRegisterParams @@ -169,6 +172,7 @@ subroutine FatesParamsInit() logging_mechanical_frac = nan logging_event_code = nan logging_dbhmax_infra = nan +! logging_export_frac = nan end subroutine FatesParamsInit @@ -258,7 +262,7 @@ subroutine FatesRegisterParams(fates_params) call fates_params%RegisterParameter(name=ED_name_canopy_closure_thresh, dimension_shape=dimension_shape_1d, & dimension_names=dim_names) - + call fates_params%RegisterParameter(name=hydr_name_kmax_rsurf, dimension_shape=dimension_shape_1d, & dimension_names=dim_names) @@ -292,6 +296,9 @@ subroutine FatesRegisterParams(fates_params) call fates_params%RegisterParameter(name=logging_name_dbhmax_infra, dimension_shape=dimension_shape_1d, & dimension_names=dim_names) +! call fates_params%RegisterParameter(name=logging_export_frac, dimension_shape=dimension_shape_1d, & +! dimension_names=dim_names) + ! non-scalar parameters call fates_params%RegisterParameter(name=ED_name_history_sizeclass_bin_edges, dimension_shape=dimension_shape_1d, & dimension_names=dim_names_sizeclass) @@ -413,6 +420,9 @@ subroutine FatesReceiveParams(fates_params) call fates_params%RetreiveParameter(name=logging_name_dbhmax_infra, & data=logging_dbhmax_infra) +! call fates_params%RetreiveParameter(name=logging_name_export_frac, & +! data=logging_export_frac) + ! parameters that are arrays of size defined within the params file and thus need allocating as well call fates_params%RetreiveParameterAllocate(name=ED_name_history_sizeclass_bin_edges, & data=ED_val_history_sizeclass_bin_edges) @@ -471,6 +481,7 @@ subroutine FatesReportParams(is_master) write(fates_log(),fmt0) 'logging_mechanical_frac = ',logging_mechanical_frac write(fates_log(),fmt0) 'logging_event_code = ',logging_event_code write(fates_log(),fmt0) 'logging_dbhmax_infra = ',logging_dbhmax_infra +! write(fates_log(),fmt0) 'logging_export_frac = ',logging_export_frac write(fates_log(),*) '------------------------------------------------------' end if diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 633e365678..6ee6eaa1c2 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -45,8 +45,8 @@ module EDTypesMod integer, parameter :: n_rad_stream_types = 2 ! The number of radiation streams used (direct/diffuse) - integer, parameter :: idirect = 1 ! This is the array index for direct radiation - integer, parameter :: idiffuse = 2 ! This is the array index for diffuse radiation + integer, parameter :: idirect = 1 ! This is the array index for direct radiation + integer, parameter :: idiffuse = 2 ! This is the array index for diffuse radiation ! TODO: we use this cp_maxSWb only because we have a static array q(size=2) of @@ -133,11 +133,12 @@ module EDTypesMod ! SPITFIRE integer, parameter :: NCWD = 4 ! number of coarse woody debris pools (twig,s branch,l branch, trunk) integer , parameter :: NFSC = NCWD+2 ! number fuel size classes (4 cwd size classes, leaf litter, and grass) + integer, parameter :: tw_sf = 1 ! array index of twig pool for spitfire + integer, parameter :: lb_sf = 3 ! array index of large branch pool for spitfire + integer, parameter :: tr_sf = 4 ! array index of dead trunk pool for spitfire + integer, parameter :: dl_sf = 5 ! array index of dead leaf pool for spitfire (dead grass and dead leaves) integer, parameter :: lg_sf = 6 ! array index of live grass pool for spitfire - integer, parameter :: dl_sf = 1 ! array index of dead leaf pool for spitfire (dead grass and dead leaves) - integer, parameter :: tw_sf = 2 ! array index of twig pool for spitfire - integer, parameter :: tr_sf = 5 ! array index of dead trunk pool for spitfire - integer, parameter :: lb_sf = 4 ! array index of large branch pool for spitfire + real(r8), parameter :: fire_threshold = 50.0_r8 ! threshold for fires that spread or go out. KWm-2 (Pyne 1986) ! PATCH FUSION @@ -315,7 +316,8 @@ module EDTypesMod real(r8) :: lmort_collateral ! collaterally damaged rate fraction /per logging activity real(r8) :: lmort_infra ! mechanically damaged rate fraction /per logging activity real(r8) :: l_degrad ! rate of trees that are not killed but suffer from forest degradation - ! (i.e. they are moved to newly-anthro-disturbed secondary forest patch). fraction /per logging activity + ! (i.e. they are moved to newly-anthro-disturbed secondary + ! forest patch). fraction /per logging activity ! NITROGEN POOLS ! ---------------------------------------------------------------------------------- diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 39787c469f..8d15d9e56a 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -1121,23 +1121,23 @@ data: fates_z0mr = 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055 ; - fates_FBD = 4, 15.4, 16.8, 19.6, 999, 4 ; + fates_FBD = 15.4, 16.8, 19.6, 999, 4, 4 ; - fates_low_moisture_Coeff = 1.15, 1.12, 1.09, 0.98, 0.8, 1.15 ; + fates_low_moisture_Coeff = 1.12, 1.09, 0.98, 0.8, 1.15, 1.15; - fates_low_moisture_Slope = 0.62, 0.62, 0.72, 0.85, 0.8, 0.62 ; + fates_low_moisture_Slope = 0.62, 0.72, 0.85, 0.8, 0.62, 0.62; - fates_max_decomp = 1, 0.52, 0.383, 0.383, 0.19, 999 ; + fates_max_decomp = 0.52, 0.383, 0.383, 0.19, 1, 999 ; - fates_mid_moisture = 0.8, 0.72, 0.51, 0.38, 1, 0.8 ; + fates_mid_moisture = 0.72, 0.51, 0.38, 1, 0.8, 0.8 ; - fates_mid_moisture_Coeff = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; + fates_mid_moisture_Coeff = 2.35, 1.47, 1.06, 0.8, 3.2, 3.2 ; - fates_mid_moisture_Slope = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; + fates_mid_moisture_Slope = 2.35, 1.47, 1.06, 0.8, 3.2, 3.2 ; - fates_min_moisture = 0.24, 0.18, 0.12, 0, 0, 0.24 ; + fates_min_moisture = 0.18, 0.12, 0, 0, 0.24, 0.24 ; - fates_SAV = 66, 13, 3.58, 0.98, 0.2, 66 ; + fates_SAV = 13, 3.58, 0.98, 0.2, 66, 66; fates_CWD_frac = 0.045, 0.075, 0.21, 0.67 ;