diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 222ef378..40337326 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -5,3 +5,4 @@ | james-bruten-mo | James Bruten | Met Office | 2025-12-09 | | ppharris | Phil Harris | UKCEH | 2025-12-18 | | maggiehendry | Maggie Hendry | Met Office | 2026-01-26 | +| OliPerkins1987 | Ol Perkins | University of East Anglia / King's London | 2026-02-03 | diff --git a/src/control/shared/fire_vars_mod.F90 b/src/control/shared/fire_vars_mod.F90 index b0bf4f8b..f92d2da2 100644 --- a/src/control/shared/fire_vars_mod.F90 +++ b/src/control/shared/fire_vars_mod.F90 @@ -44,12 +44,38 @@ MODULE fire_vars_mod ! The population density (ppl/km2) REAL(KIND=real_jlslsm), ALLOCATABLE :: wealth_index(:) ! The Human Develoment Index (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_arable_ba(:) + ! WHAM! crop residue burning (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_pasture_ba(:) + ! WHAM! pastoral burning (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_other_man(:) + ! WHAM! vegetation management burning (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_other_ag(:) + ! WHAM! other agricultural burning (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_ignitions(:) + ! WHAM! unmanaged fire counts (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_escaped(:) + ! Escaped prescribed fires (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_suppression(:) + ! WHAM! fire suppression intensity (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: road_density(:) + ! Road density (m / km-2) REAL(KIND=real_jlslsm), ALLOCATABLE :: flammability_ft(:,:) ! PFT-specific flammability REAL(KIND=real_jlslsm), ALLOCATABLE :: burnt_area(:) ! Gridbox mean burnt area fraction (/s) REAL(KIND=real_jlslsm), ALLOCATABLE :: burnt_area_ft(:,:) ! PFT burnt area fraction (/s) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_ba(:) + ! Gridbox mean BA from wham managed fires (/s) (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: wham_ba_ft(:,:) + ! proportion of burnt area from managed fire (1) + REAL(KIND=real_jlslsm), ALLOCATABLE :: intensity_ft(:,:) + ! PFT-specific fireline intensity + REAL(KIND=real_jlslsm), ALLOCATABLE :: intensity_clim(:,:) + ! PFT-specific impact of climate on fireline intensity + REAL(KIND=real_jlslsm), ALLOCATABLE :: intensity_wham(:,:) + ! PFT-specific impact of management on fireline intensity REAL(KIND=real_jlslsm), ALLOCATABLE :: emitted_carbon(:) ! Gridbox mean emitted carbon (kgC/m2/s) REAL(KIND=real_jlslsm), ALLOCATABLE :: emitted_carbon_ft(:,:) @@ -176,9 +202,22 @@ MODULE fire_vars_mod REAL(KIND=real_jlslsm), POINTER :: flash_rate(:) REAL(KIND=real_jlslsm), POINTER :: pop_den(:) REAL(KIND=real_jlslsm), POINTER :: wealth_index(:) + REAL(KIND=real_jlslsm), POINTER :: wham_arable_ba(:) + REAL(KIND=real_jlslsm), POINTER :: wham_pasture_ba(:) + REAL(KIND=real_jlslsm), POINTER :: wham_other_man(:) + REAL(KIND=real_jlslsm), POINTER :: wham_other_ag(:) + REAL(KIND=real_jlslsm), POINTER :: wham_ignitions(:) + REAL(KIND=real_jlslsm), POINTER :: wham_escaped(:) + REAL(KIND=real_jlslsm), POINTER :: wham_suppression(:) + REAL(KIND=real_jlslsm), POINTER :: road_density(:) REAL(KIND=real_jlslsm), POINTER :: flammability_ft(:,:) REAL(KIND=real_jlslsm), POINTER :: burnt_area(:) REAL(KIND=real_jlslsm), POINTER :: burnt_area_ft(:,:) + REAL(KIND=real_jlslsm), POINTER :: wham_ba(:) + REAL(KIND=real_jlslsm), POINTER :: wham_ba_ft(:,:) + REAL(KIND=real_jlslsm), POINTER :: intensity_ft(:,:) + REAL(KIND=real_jlslsm), POINTER :: intensity_clim(:,:) + REAL(KIND=real_jlslsm), POINTER :: intensity_wham(:,:) REAL(KIND=real_jlslsm), POINTER :: emitted_carbon(:) REAL(KIND=real_jlslsm), POINTER :: emitted_carbon_ft(:,:) REAL(KIND=real_jlslsm), POINTER :: emitted_carbon_DPM(:) @@ -336,7 +375,20 @@ SUBROUTINE fire_vars_alloc(land_pts,npft, fire_vars_data) ALLOCATE(fire_vars_data%pop_den(land_pts)) ALLOCATE(fire_vars_data%wealth_index(land_pts)) ALLOCATE(fire_vars_data%flash_rate(land_pts)) +ALLOCATE(fire_vars_data%wham_arable_ba(land_pts)) +ALLOCATE(fire_vars_data%wham_pasture_ba(land_pts)) +ALLOCATE(fire_vars_data%wham_other_man(land_pts)) +ALLOCATE(fire_vars_data%wham_other_ag(land_pts)) +ALLOCATE(fire_vars_data%wham_ignitions(land_pts)) +ALLOCATE(fire_vars_data%wham_escaped(land_pts)) +ALLOCATE(fire_vars_data%wham_suppression(land_pts)) +ALLOCATE(fire_vars_data%road_density(land_pts)) ALLOCATE(fire_vars_data%flammability_ft(land_pts,npft)) +ALLOCATE(fire_vars_data%wham_ba(land_pts)) +ALLOCATE(fire_vars_data%wham_ba_ft(land_pts,npft)) +ALLOCATE(fire_vars_data%intensity_ft(land_pts,npft)) +ALLOCATE(fire_vars_data%intensity_clim(land_pts,npft)) +ALLOCATE(fire_vars_data%intensity_wham(land_pts,npft)) fire_vars_data%burnt_area(:) = 0.0 fire_vars_data%burnt_area_ft(:,:) = 0.0 @@ -402,8 +454,21 @@ SUBROUTINE fire_vars_alloc(land_pts,npft, fire_vars_data) fire_vars_data%fire_em_DMS_RPM(:) = 0.0 fire_vars_data%pop_den(:) = 0.0 fire_vars_data%wealth_index(:) = 0.0 +fire_vars_data%wham_arable_ba(:) = 0.0 +fire_vars_data%wham_pasture_ba(:) = 0.0 +fire_vars_data%wham_other_man(:) = 0.0 +fire_vars_data%wham_other_ag(:) = 0.0 +fire_vars_data%wham_ignitions(:) = 0.0 +fire_vars_data%wham_escaped(:) = 0.0 +fire_vars_data%wham_suppression(:) = 0.0 +fire_vars_data%road_density(:) = 0.0 fire_vars_data%flash_rate(:) = 0.0 fire_vars_data%flammability_ft(:,:) = 0.0 +fire_vars_data%wham_ba(:) = 0.0 +fire_vars_data%wham_ba_ft(:,:) = 0.0 +fire_vars_data%intensity_ft(:,:) = 0.0 +fire_vars_data%intensity_clim(:,:) = 0.0 +fire_vars_data%intensity_wham(:,:) = 0.0 IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -499,8 +564,21 @@ SUBROUTINE fire_vars_dealloc(fire_vars_data) DEALLOCATE(fire_vars_data%fire_em_DMS_RPM) DEALLOCATE(fire_vars_data%pop_den) DEALLOCATE(fire_vars_data%wealth_index) +DEALLOCATE(fire_vars_data%wham_arable_ba) +DEALLOCATE(fire_vars_data%wham_pasture_ba) +DEALLOCATE(fire_vars_data%wham_other_man) +DEALLOCATE(fire_vars_data%wham_other_ag) +DEALLOCATE(fire_vars_data%wham_ignitions) +DEALLOCATE(fire_vars_data%wham_escaped) +DEALLOCATE(fire_vars_data%wham_suppression) +DEALLOCATE(fire_vars_data%road_density) DEALLOCATE(fire_vars_data%flash_rate) DEALLOCATE(fire_vars_data%flammability_ft) +DEALLOCATE(fire_vars_data%wham_ba) +DEALLOCATE(fire_vars_data%wham_ba_ft) +DEALLOCATE(fire_vars_data%intensity_ft) +DEALLOCATE(fire_vars_data%intensity_clim) +DEALLOCATE(fire_vars_data%intensity_wham) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -595,8 +673,21 @@ SUBROUTINE fire_vars_assoc(fire_vars, fire_vars_data) fire_vars%fire_em_DMS_RPM => fire_vars_data%fire_em_DMS_RPM fire_vars%pop_den => fire_vars_data%pop_den fire_vars%wealth_index => fire_vars_data%wealth_index +fire_vars%wham_arable_ba => fire_vars_data%wham_arable_ba +fire_vars%wham_pasture_ba => fire_vars_data%wham_pasture_ba +fire_vars%wham_other_man => fire_vars_data%wham_other_man +fire_vars%wham_other_ag => fire_vars_data%wham_other_ag +fire_vars%wham_ignitions => fire_vars_data%wham_ignitions +fire_vars%wham_escaped => fire_vars_data%wham_escaped +fire_vars%wham_suppression => fire_vars_data%wham_suppression +fire_vars%road_density => fire_vars_data%road_density fire_vars%flash_rate => fire_vars_data%flash_rate fire_vars%flammability_ft => fire_vars_data%flammability_ft +fire_vars%wham_ba => fire_vars_data%wham_ba +fire_vars%wham_ba_ft => fire_vars_data%wham_ba_ft +fire_vars%intensity_ft => fire_vars_data%intensity_ft +fire_vars%intensity_clim => fire_vars_data%intensity_clim +fire_vars%intensity_wham => fire_vars_data%intensity_wham IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN @@ -688,8 +779,21 @@ SUBROUTINE fire_vars_nullify(fire_vars) NULLIFY(fire_vars%fire_em_DMS_RPM) NULLIFY(fire_vars%pop_den) NULLIFY(fire_vars%wealth_index) +NULLIFY(fire_vars%wham_arable_ba) +NULLIFY(fire_vars%wham_pasture_ba) +NULLIFY(fire_vars%wham_other_man) +NULLIFY(fire_vars%wham_other_ag) +NULLIFY(fire_vars%wham_ignitions) +NULLIFY(fire_vars%wham_escaped) +NULLIFY(fire_vars%wham_suppression) +NULLIFY(fire_vars%road_density) NULLIFY(fire_vars%flash_rate) NULLIFY(fire_vars%flammability_ft) +NULLIFY(fire_vars%wham_ba) +NULLIFY(fire_vars%wham_ba_ft) +NULLIFY(fire_vars%intensity_ft) +NULLIFY(fire_vars%intensity_clim) +NULLIFY(fire_vars%intensity_wham) IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN diff --git a/src/control/shared/jules_vegetation_mod.F90 b/src/control/shared/jules_vegetation_mod.F90 index c92fcfda..df6f0f22 100644 --- a/src/control/shared/jules_vegetation_mod.F90 +++ b/src/control/shared/jules_vegetation_mod.F90 @@ -157,12 +157,19 @@ MODULE jules_vegetation_mod l_trif_fire = .FALSE., & ! Switch used to control whether interactive fire is used ! T => if l_inferno is also true, g_burn is calculated in INFERNO -! and passed to TRIFFID to calculate emissions and vegetation - ! dynamics - ! T => if l_inferno is false, interactive fire is calculated via -! ancillary if provided, and is 0 if not provided - ! F => g_burn is calculated via ancillary if provided, and is 0 if -! not provided + ! and passed to TRIFFID to calculate emissions and vegetation + ! dynamics + ! T => if l_inferno is false, interactive fire is calculated via + ! ancillary if provided, and is 0 if not provided + ! F => g_burn is calculated via ancillary if provided, and is 0 if + ! not provided + l_inferno_wham = .FALSE., & + ! Switch used to control whether INFERNO is run using inputs from the + ! WHAM! agent-based model of human fire use & mgmt. + ! T => managed fire inputs, ignitions & suppression should come from + ! WHAM!, and ignition_method should be set to 4 (int) + ! F => managed fire is not included, and ignitions are derived from + ! population density & HDI l_use_pft_psi = .FALSE., & ! Switch used to control what parameters are used in the calculation ! of the soil moisture stress factor @@ -239,6 +246,13 @@ MODULE jules_vegetation_mod ! IGNITION_METHOD=2:Constant (Human - 1.5 per km2 per s) ! Varying (Lightning - see Pechony and Shindell,2009) ! IGNITION_METHOD=3:Vary Human and Lightning (Pechony and Shindell,2009) + ! IGNITION_METHOD=4:Use WHAM! ignitions (Perkins et al., 2024, GMD) + fire_mortality_method = 1, & + ! Switch for the method of calculation for fire mortality + ! fire_mortality_method = 1: uniform mortality per PFT (per Burton 2019) + ! fire_mortality_method = 2: mortality per PFT adjusted for soil moisture + ! fire_mortality_method = 3: explicit fireline intensity-based mortality + ! (see Perkins et al., 2026) fsmc_shape = 0, & ! shape of the soil moisture stress function fsmc ! 0: piece-wise linear in vol. soil moisture. @@ -259,6 +273,7 @@ MODULE jules_vegetation_mod INTEGER, PARAMETER :: ignition_constant = 1 INTEGER, PARAMETER :: ignition_vary_natural = 2 INTEGER, PARAMETER :: ignition_vary_natural_human = 3 +INTEGER, PARAMETER :: ignition_wham = 4 INTEGER :: & phenol_period = imdi, & @@ -344,7 +359,8 @@ MODULE jules_vegetation_mod l_bvoc_emis, l_o3_damage, can_model, can_rad_mod, ilayers, & frac_min, frac_seed, pow, l_landuse, l_leaf_n_resp_fix, l_stem_resp_fix, & l_nitrogen, l_vegcan_soilfx, l_trif_crop, l_trif_fire, & - l_inferno, ignition_method, l_vegdrag_pft, l_rsl_scalar, & + l_inferno, l_inferno_wham, ignition_method, fire_mortality_method, & + l_vegdrag_pft, l_rsl_scalar, & cd_leaf, c1_usuh, c2_usuh, c3_usuh, dsj_coef, dsv_coef, jv25_coef, & act_j_coef, act_v_coef, & n_alloc_jmax, n_alloc_vcmax, n_day_photo_acclim, & @@ -778,10 +794,11 @@ SUBROUTINE check_jules_vegetation() ! Check a suitable ignition_method was given IF ( ignition_method /= ignition_constant .AND. & ignition_method /= ignition_vary_natural .AND. & - ignition_method /= ignition_vary_natural_human ) THEN + ignition_method /= ignition_vary_natural_human .AND. & + ignition_method /= ignition_wham ) THEN errcode = 101 CALL ereport("check_jules_vegetation", errcode, & - 'ignition_method must be 1, 2 or 3') + 'ignition_method must be 1, 2, 3 or 4') END IF IF ( fsmc_shape == 1 .AND. .NOT. l_use_pft_psi ) THEN @@ -1029,6 +1046,7 @@ SUBROUTINE read_nml_jules_vegetation (unitnumber) INTEGER :: can_rad_mod INTEGER :: ilayers INTEGER :: ignition_method + INTEGER :: fire_mortality_method INTEGER :: photo_acclim_model INTEGER :: photo_act_model INTEGER :: photo_jv_model @@ -1074,6 +1092,7 @@ SUBROUTINE read_nml_jules_vegetation (unitnumber) LOGICAL :: l_scale_resp_pm LOGICAL :: l_vegcan_soilfx LOGICAL :: l_inferno + LOGICAL :: l_inferno_wham LOGICAL :: l_vegdrag_pft(npft_max) LOGICAL :: l_rsl_scalar LOGICAL :: l_spec_veg_z0 @@ -1103,6 +1122,7 @@ SUBROUTINE read_nml_jules_vegetation (unitnumber) my_nml % can_rad_mod = can_rad_mod my_nml % ilayers = ilayers my_nml % ignition_method = ignition_method + my_nml % fire_mortality_method = fire_mortality_method my_nml % photo_acclim_model = photo_acclim_model my_nml % photo_act_model = photo_act_model my_nml % photo_jv_model = photo_jv_model @@ -1148,6 +1168,7 @@ SUBROUTINE read_nml_jules_vegetation (unitnumber) my_nml % l_scale_resp_pm = l_scale_resp_pm my_nml % l_vegcan_soilfx = l_vegcan_soilfx my_nml % l_inferno = l_inferno + my_nml % l_inferno_wham = l_inferno_wham my_nml % l_vegdrag_pft = l_vegdrag_pft my_nml % l_rsl_scalar = l_rsl_scalar my_nml % l_spec_veg_z0 = l_spec_veg_z0 @@ -1166,6 +1187,7 @@ SUBROUTINE read_nml_jules_vegetation (unitnumber) can_rad_mod = my_nml % can_rad_mod ilayers = my_nml % ilayers ignition_method = my_nml % ignition_method + fire_mortality_method = my_nml % fire_mortality_method photo_acclim_model = my_nml % photo_acclim_model photo_act_model = my_nml % photo_act_model photo_jv_model = my_nml % photo_jv_model @@ -1211,6 +1233,7 @@ SUBROUTINE read_nml_jules_vegetation (unitnumber) l_scale_resp_pm = my_nml % l_scale_resp_pm l_vegcan_soilfx = my_nml % l_vegcan_soilfx l_inferno = my_nml % l_inferno + l_inferno_wham = my_nml % l_inferno_wham l_vegdrag_pft = my_nml % l_vegdrag_pft l_rsl_scalar = my_nml % l_rsl_scalar l_spec_veg_z0 = my_nml % l_spec_veg_z0 diff --git a/src/control/shared/surf_couple_extra_mod.F90 b/src/control/shared/surf_couple_extra_mod.F90 index ca35dc00..5ac7d798 100644 --- a/src/control/shared/surf_couple_extra_mod.F90 +++ b/src/control/shared/surf_couple_extra_mod.F90 @@ -64,6 +64,9 @@ SUBROUTINE surf_couple_extra( & stf_sub_surf_roff, & fexp_soilt, gamtot_soilt, ti_mean_soilt, ti_sig_soilt, & flash_rate_ancil, pop_den_ancil, wealth_index_ancil, & + wham_arable_ba_ancil, wham_pasture_ba_ancil, wham_other_man_ancil, & + wham_other_ag_ancil,wham_ignitions_ancil, wham_suppression_ancil, & + road_density_ancil, wham_escaped_ancil, & a_fsat_soilt, c_fsat_soilt, a_fwet_soilt, c_fwet_soilt, & ntype, & delta_lambda, delta_phi, xx_cos_theta_latitude, & @@ -212,8 +215,8 @@ SUBROUTINE surf_couple_extra( & l_crop, l_fao_ref_evapotranspiration, & #endif l_triffid, l_trif_eq, l_phenol, phenol_period, triffid_period, & - l_inferno, ignition_method, & - ignition_vary_natural, ignition_vary_natural_human, & + l_inferno, l_inferno_wham, ignition_method, fire_mortality_method, & + ignition_vary_natural, ignition_vary_natural_human, ignition_wham, & l_acclim, n_day_photo_acclim, l_red USE jules_irrig_mod, ONLY: l_irrig_dmd @@ -344,6 +347,14 @@ SUBROUTINE surf_couple_extra( & flash_rate_ancil(row_length,rows), & pop_den_ancil(row_length,rows), & wealth_index_ancil(row_length,rows), & + wham_arable_ba_ancil(row_length,rows), & + wham_pasture_ba_ancil(row_length,rows), & + wham_other_man_ancil(row_length,rows), & + wham_other_ag_ancil(row_length, rows), & + wham_ignitions_ancil(row_length,rows), & + wham_escaped_ancil(row_length, rows), & + wham_suppression_ancil(row_length,rows), & + road_density_ancil(row_length,rows), & u_s_std_surft(land_pts, nsurft), & !River routing @@ -534,7 +545,7 @@ SUBROUTINE surf_couple_extra( & END DO END IF - ! Compress pop_den and flash rate fields to land points if required. + ! Compress ignition fields to land points if required. ! In the UM the ancils are 2D fields. IF (l_inferno) THEN IF (ignition_method == ignition_vary_natural) THEN @@ -553,6 +564,30 @@ SUBROUTINE surf_couple_extra( & fire_vars%wealth_index(l) = wealth_index_ancil(i,j) END DO END IF + IF (ignition_method == ignition_wham) THEN + DO l = 1, land_pts + j = (ainfo%land_index(l) - 1) / row_length + 1 + i = ainfo%land_index(l) - (j-1) * row_length + fire_vars%flash_rate(l) = flash_rate_ancil(i,j) + fire_vars%wham_ignitions(l) = wham_ignitions_ancil(i, j) + fire_vars%wham_suppression(l)= wham_suppression_ancil(i, j) + END DO + END IF + + ! Set up WHAM managed burned area if it is being used + IF (l_inferno_wham) THEN + DO l = 1, land_pts + j = (ainfo%land_index(l) - 1) / row_length + 1 + i = ainfo%land_index(l) - (j-1) * row_length + fire_vars%wham_arable_ba(l) = wham_arable_ba_ancil(i,j) + fire_vars%wham_pasture_ba(l) = wham_pasture_ba_ancil(i,j) + fire_vars%wham_other_man(l) = wham_other_man_ancil(i,j) + fire_vars%wham_other_ag(l) = wham_other_ag_ancil(i,j) + fire_vars%wham_escaped(l) = wham_escaped_ancil(i, j) + fire_vars%road_density(l) = road_density_ancil(i, j) + END DO + END IF + END IF #endif @@ -1044,12 +1079,12 @@ SUBROUTINE surf_couple_extra( & c_soil_dpm_gb, c_soil_rpm_gb) CALL inferno_io( sf_diag%t1p5m_surft, sf_diag%q1p5m_surft, pstar_gb, & - psparms%sthu_soilt, sm_levels, & + psparms%sthu_soilt, toppdm%fsat_soilt, sm_levels, & ainfo%frac_surft, c_soil_dpm_gb, c_soil_rpm_gb, & progs%canht_pft, & - ls_rain_gb, con_rain_gb, & + ls_rain_gb, con_rain_gb, u_1_gb, v_1_gb, & fire_vars, & - land_pts, ignition_method, & + land_pts, ignition_method, fire_mortality_method, & nsurft, asteps_since_triffid, & ! New Arguments to replace USE statements ! TRIF_VARS_MOD diff --git a/src/control/standalone/control.F90 b/src/control/standalone/control.F90 index 0542a79b..474ed16a 100644 --- a/src/control/standalone/control.F90 +++ b/src/control/standalone/control.F90 @@ -405,6 +405,14 @@ SUBROUTINE control ( & flash_rate_ancil(row_length,rows), & pop_den_ancil(row_length,rows), & wealth_index_ancil(row_length,rows), & + wham_arable_ba_ancil(row_length,rows), & + wham_pasture_ba_ancil(row_length,rows), & + wham_other_man_ancil(row_length,rows), & + wham_other_ag_ancil(row_length,rows), & + wham_ignitions_ancil(row_length,rows), & + wham_escaped_ancil(row_length,rows), & + wham_suppression_ancil(row_length,rows), & + road_density_ancil(row_length,rows), & inlandout_atm_gb(land_pts), & delta_lambda, & delta_phi, & @@ -877,6 +885,9 @@ SUBROUTINE control ( & stf_sub_surf_roff, & toppdm%fexp_soilt, toppdm%gamtot_soilt, toppdm%ti_mean_soilt, & toppdm%ti_sig_soilt, flash_rate_ancil, pop_den_ancil, wealth_index_ancil, & + wham_arable_ba_ancil, wham_pasture_ba_ancil, wham_other_man_ancil, & + wham_other_ag_ancil, wham_ignitions_ancil, wham_suppression_ancil, & + road_density_ancil, wham_escaped_ancil, & toppdm%a_fsat_soilt, toppdm%c_fsat_soilt, toppdm%a_fwet_soilt, & toppdm%c_fwet_soilt,ntype, & delta_lambda, delta_phi, xx_cos_theta_latitude, & diff --git a/src/initialisation/standalone/init_vegetation.F90 b/src/initialisation/standalone/init_vegetation.F90 index a37df63b..ad70133b 100644 --- a/src/initialisation/standalone/init_vegetation.F90 +++ b/src/initialisation/standalone/init_vegetation.F90 @@ -36,10 +36,12 @@ SUBROUTINE init_vegetation(nml_dir) photo_act_pft, photo_act_gb, photo_jv_model, & jv_scale, jv_ntotal, stomata_model, & stomata_jacobs, stomata_medlyn, stomata_sox, & - l_inferno, l_trif_eq, triffid_period, & - ignition_method, check_jules_vegetation, & + l_inferno, l_inferno_wham, & + l_trif_eq, triffid_period, & + ignition_method, fire_mortality_method, & + check_jules_vegetation, & ignition_constant, ignition_vary_natural, & - ignition_vary_natural_human + ignition_vary_natural_human, ignition_wham USE logging_mod, ONLY: log_info, log_error, log_fatal @@ -188,6 +190,9 @@ SUBROUTINE init_vegetation(nml_dir) ELSE IF (ignition_method == ignition_vary_natural_human ) THEN CALL log_info("init_vegetation", & "Fully prescribed ignitions (INFERNO)") + ELSE IF (ignition_method == ignition_wham) THEN + CALL log_info("init_vegetation", & + "Ignitions taken from WHAM agent based model") END IF END IF diff --git a/src/initialisation/standalone/params/init_pftparm.inc b/src/initialisation/standalone/params/init_pftparm.inc index 816c4cb1..e2e18453 100644 --- a/src/initialisation/standalone/params/init_pftparm.inc +++ b/src/initialisation/standalone/params/init_pftparm.inc @@ -46,9 +46,9 @@ USE pftparm, ONLY: & fef_co, fef_co2, fef_nox, & fef_oc, fef_so2, fef_c2h4, & fef_c2h6, fef_c3h8, fef_hcho, & - fef_mecho, fef_nh3, & - fef_dms, fire_mort, fl_o3_ct, & - fsmc_of, fsmc_p0, sug_g0, & + fef_mecho, fef_nh3, fef_dms, & + fire_mort, fl_o3_ct, fsmc_of, & + fsmc_p0, fuel_type, sug_g0, & g1_stomata, g_leaf_0, glmin, & gpp_st, sug_grec, gsoil_f, & hw_sw, ief, infil_f, & @@ -75,7 +75,7 @@ USE jules_vegetation_mod, ONLY: can_rad_mod, l_crop, l_trait_phys, & photo_farquhar, photo_model, & stomata_jacobs, stomata_medlyn, stomata_sox, & stomata_model, l_spec_veg_z0, l_sugar, & - l_scale_resp_pm + l_scale_resp_pm, l_inferno_wham USE jules_radiation_mod, ONLY: l_spec_albedo, l_albedo_obs, l_snow_albedo @@ -629,6 +629,12 @@ IF ( l_trif_fire ) THEN CALL log_error(routinename, "No value for fire_mort") END IF END IF +IF ( l_trif_fire ) THEN + IF ( ANY( fuel_type(:) < 0 ) ) THEN + ERROR = 1 + CALL log_error(routinename, "No value for fuel_type") + END IF +END IF IF ( l_o3_damage ) THEN IF ( ANY( ABS( fl_o3_ct(:) - rmdi ) < EPSILON(1.0) ) ) THEN diff --git a/src/io/model_interface/extract_var.inc b/src/io/model_interface/extract_var.inc index 49d27599..70578c28 100644 --- a/src/io/model_interface/extract_var.inc +++ b/src/io/model_interface/extract_var.inc @@ -2840,6 +2840,28 @@ CASE ( 'burnt_area' ) cube_land = cube_from_array(fire_vars%burnt_area_ft) cube = map_from_land(cube_land) + ! WHAM integration variables +CASE ( 'wham_ba_gb' ) + cube_land = cube_from_array(fire_vars%wham_ba) + cube = map_from_land(cube_land) + +CASE ( 'wham_ba_ft' ) + cube_land = cube_from_array(fire_vars%wham_ba_ft) + cube = map_from_land(cube_land) + + ! Fire intensity variables +CASE ( 'fire_intensity_ft' ) + cube_land = cube_from_array(fire_vars%intensity_ft) + cube = map_from_land(cube_land) + +CASE ( 'fire_intensity_clim' ) + cube_land = cube_from_array(fire_vars%intensity_clim) + cube = map_from_land(cube_land) + +CASE ( 'fire_intensity_wham' ) + cube_land = cube_from_array(fire_vars%intensity_wham) + cube = map_from_land(cube_land) + CASE ( 'emitted_carbon_gb' ) cube_land = cube_from_array(fire_vars%emitted_carbon) cube = map_from_land(cube_land) diff --git a/src/io/model_interface/model_interface_mod.F90 b/src/io/model_interface/model_interface_mod.F90 index b3c63407..b226b7db 100644 --- a/src/io/model_interface/model_interface_mod.F90 +++ b/src/io/model_interface/model_interface_mod.F90 @@ -176,7 +176,7 @@ MODULE model_interface_mod ! Array holding the metadata for all model variables that we can use for input ! or output. The CABLE land surface model adds 10 prognostics for tiled ! soil/snow prognostics. -INTEGER, PARAMETER :: n_vars = 722 +INTEGER, PARAMETER :: n_vars = 735 TYPE(var_metadata) :: metadata(n_vars) ! Include the metadata DATA statement diff --git a/src/io/model_interface/populate_var.inc b/src/io/model_interface/populate_var.inc index 4dc4976c..f0bdd01b 100644 --- a/src/io/model_interface/populate_var.inc +++ b/src/io/model_interface/populate_var.inc @@ -2804,6 +2804,70 @@ CASE ( 'wealth_index' ) fire_vars%wealth_index(:) = const_val END IF +CASE ( 'wham_arable_ba' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_arable_ba) + ELSE + fire_vars%wham_arable_ba(:) = const_val + END IF + +CASE ( 'wham_pasture_ba' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_pasture_ba) + ELSE + fire_vars%wham_pasture_ba(:) = const_val + END IF + +CASE ( 'wham_other_man' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_other_man) + ELSE + fire_vars%wham_other_man(:) = const_val + END IF + +CASE ( 'wham_other_ag' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_other_ag) + ELSE + fire_vars%wham_other_ag(:) = const_val + END IF + +CASE ( 'wham_ignitions' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_ignitions) + ELSE + fire_vars%wham_ignitions(:) = const_val + END IF + +CASE ( 'wham_escaped' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_escaped) + ELSE + fire_vars%wham_escaped(:) = const_val + END IF + +CASE ( 'wham_suppression' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%wham_suppression) + ELSE + fire_vars%wham_suppression(:) = const_val + END IF + +CASE ( 'road_density' ) + IF ( PRESENT(cube) ) THEN + cube_land = map_to_land(cube) + CALL cube_get_data(cube_land, fire_vars%road_density) + ELSE + fire_vars%road_density(:) = const_val + END IF + !----------------------------------------------------------------------------- ! Variables for thermal acclimation of photosynthesis. !----------------------------------------------------------------------------- diff --git a/src/io/model_interface/variable_metadata.inc b/src/io/model_interface/variable_metadata.inc index 0efd8ac3..e99b8a1d 100644 --- a/src/io/model_interface/variable_metadata.inc +++ b/src/io/model_interface/variable_metadata.inc @@ -9354,4 +9354,173 @@ DATA metadata(722) / var_metadata( & ! Units "kg s-1" & ) / +!----------------------------------------------------------------------------- +! Metadata for wham_arable_ba +!----------------------------------------------------------------------------- +DATA metadata(723) / var_metadata( & +! String identifier + 'wham_arable_ba', & +! Variable type + var_type_surface, & +! Long name + "Managed fire burnt area fraction (arable)", & +! Units + "fraction of gridbox per month" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_pasture_ba +!----------------------------------------------------------------------------- +DATA metadata(724) / var_metadata( & +! String identifier + 'wham_pasture_ba', & +! Variable type + var_type_surface, & +! Long name + "Managed fire burnt area fraction (pasture)", & +! Units + "fraction of gridbox per month" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_other_man +!----------------------------------------------------------------------------- +DATA metadata(725) / var_metadata( & +! String identifier + 'wham_other_man', & +! Variable type + var_type_surface, & +! Long name + "Vegetation management fire fraction", & +! Units + "fraction of gridbox per month" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_ignitions +!----------------------------------------------------------------------------- +DATA metadata(726) / var_metadata( & +! String identifier + 'wham_ignitions', & +! Variable type + var_type_surface, & +! Long name + "Unmanaged fires from WHAM ABM", & +! Units + "km-2 yr-1" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_suppression +!----------------------------------------------------------------------------- +DATA metadata(727) / var_metadata( & +! String identifier + 'wham_suppression', & +! Variable type + var_type_surface, & +! Long name + "Fire suppression from WHAM ABM", & +! Units + "Dimensionless" & + ) / +!----------------------------------------------------------------------------- +! Metadata for road_density +!----------------------------------------------------------------------------- +DATA metadata(728) / var_metadata( & +! String identifier + 'road_density', & +! Variable type + var_type_surface, & +! Long name + "Road density", & +! Units + "km / km-2" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham burnt area proportion +!----------------------------------------------------------------------------- +DATA metadata(729)/var_metadata( & +! String identifier + 'wham_ba_gb', & +! Variable type + var_type_surface, & +! Long name + "wham burnt area fraction", & +! Units + "grid box fraction /s" & + )/ +!----------------------------------------------------------------------------- +! Metadata for wham burnt area proportion +!----------------------------------------------------------------------------- +DATA metadata(730)/var_metadata( & +! String identifier + 'wham_ba_ft', & +! Variable type + var_type_pft, & +! Long name + "wham burnt area per pft", & +! Units + "Dimensionless" & + )/ +!----------------------------------------------------------------------------- +! Metadata for normalised fireline intensity +!----------------------------------------------------------------------------- +DATA metadata(731)/var_metadata( & +! String identifier + 'fire_intensity_ft', & +! Variable type + var_type_pft, & +! Long name + "Normalised fireline intensity", & +! Units + "Dimensionless" & + )/ +!----------------------------------------------------------------------------- +! Metadata for wham_other_man +!----------------------------------------------------------------------------- +DATA metadata(732) / var_metadata( & +! String identifier + 'wham_other_ag', & +! Variable type + var_type_surface, & +! Long name + "WHAM other agricultural burnt fraction", & +! Units + "fraction of gridbox per month" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_escaped +!----------------------------------------------------------------------------- +DATA metadata(733) / var_metadata( & +! String identifier + 'wham_escaped', & +! Variable type + var_type_surface, & +! Long name + "WHAM escaped prescribed fires", & +! Units + "fraction of gridbox per month" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_escaped +!----------------------------------------------------------------------------- +DATA metadata(734) / var_metadata( & +! String identifier + 'fire_intensity_clim', & +! Variable type + var_type_pft, & +! Long name + "Impact of climate on fireline intensity", & +! Units + "Dimensionless" & + ) / +!----------------------------------------------------------------------------- +! Metadata for wham_escaped +!----------------------------------------------------------------------------- +DATA metadata(735) / var_metadata( & +! String identifier + 'fire_intensity_wham', & +! Variable type + var_type_pft, & +! Long name + "Impact of mgmt on fireline intensity", & +! Units + "Dimensionless" & + ) / #endif diff --git a/src/science/fire/inferno_io_mod.F90 b/src/science/fire/inferno_io_mod.F90 index 1fb36dda..eb53bec4 100644 --- a/src/science/fire/inferno_io_mod.F90 +++ b/src/science/fire/inferno_io_mod.F90 @@ -20,6 +20,8 @@ MODULE inferno_io_mod USE um_types, ONLY: real_jlslsm +USE conversions_mod, ONLY: s_in_day => rsec_per_day + IMPLICIT NONE INTEGER(KIND=jpim), PARAMETER, PRIVATE :: zhook_in = 0 @@ -29,16 +31,17 @@ MODULE inferno_io_mod CONTAINS SUBROUTINE inferno_io( & - t1p5m_tile, q1p5m_tile, pstar, sthu_soilt & -, sm_levels, frac, c_soil_dpm_gb, c_soil_rpm_gb, canht, ls_rain, con_rain & -, fire_vars & -, land_pts, ignition_method, nsurft, asteps_since_triffid & + t1p5m_tile, q1p5m_tile, pstar, sthu_soilt, fsat_soilt & +, sm_levels, frac, c_soil_dpm_gb, c_soil_rpm_gb, canht & +, ls_rain, con_rain, u_1_gb, v_1_gb, fire_vars & +, land_pts, ignition_method, fire_mortality_method & +, nsurft, asteps_since_triffid & ! New Arguments to replace USE statements ! TRIF_VARS_MOD , g_burn_pft_acc ) USE inferno_mod, ONLY: & - calc_flam, calc_ignitions, calc_burnt_area, & + calc_flam, calc_ignitions, calc_burnt_area, calc_intensity, & calc_emitted_carbon, calc_emitted_carbon_soil, calc_emission USE yomhook, ONLY: lhook, dr_hook @@ -50,15 +53,15 @@ SUBROUTINE inferno_io( & ! PFT Emission factors from namelists ccleaf_min, ccleaf_max, ccwood_min, ccwood_max, & ! PFT Combustion completeness from namelists - avg_ba, fire_mort - ! Average Burned Area per PFT, and fire mortality rate + avg_ba, fire_mort, fuel_type + ! Average Burned Area per PFT, baseline fire mortality, fuel_type USE qsat_mod, ONLY: qsat_wat USE jules_surface_types_mod, ONLY: npft USE parkind1, ONLY: jprb -USE jules_vegetation_mod, ONLY: l_trif_fire +USE jules_vegetation_mod, ONLY: l_trif_fire, l_inferno_wham USE timestep_mod, ONLY: timestep USE calc_c_comps_triffid_mod, ONLY: calc_c_comps_triffid @@ -83,13 +86,15 @@ SUBROUTINE inferno_io( & ! INTEGER, INTENT(IN) :: & - land_pts, sm_levels, ignition_method, asteps_since_triffid, nsurft + land_pts, sm_levels, ignition_method, fire_mortality_method, & + asteps_since_triffid, nsurft REAL(KIND=real_jlslsm), INTENT(IN) :: & t1p5m_tile(land_pts,nsurft), & q1p5m_tile(land_pts,nsurft), & pstar(land_pts), & sthu_soilt(land_pts,nsoilt,sm_levels), & + fsat_soilt(land_pts, nsoilt, sm_levels), & frac(land_pts,nsurft), & c_soil_dpm_gb(land_pts), & ! Gridbox soil C in the Decomposable Plant Material pool (kg m-2). @@ -97,7 +102,11 @@ SUBROUTINE inferno_io( & ! Gridbox soil C in the Resistant Plant Material pool (kg m-2). canht(land_pts,npft), & ls_rain(land_pts), & - con_rain(land_pts) + con_rain(land_pts), & + u_1_gb(land_pts), & + ! Wind-speed southerly (m/s-1) + v_1_gb(land_pts) + ! Wind-speed westerly (m/s-1) TYPE(fire_vars_type), INTENT(IN OUT) :: fire_vars @@ -118,7 +127,9 @@ SUBROUTINE inferno_io( & inferno_rhum(land_pts), & ! The Relative Humidity (%) inferno_sm(land_pts), & - ! The Soil Moisture (Fraction of saturation) + ! The Soil Moisture (volumetric water content) + inferno_fsat(land_pts), & + ! The Soil Moisture (fractional saturation) inferno_rain(land_pts), & ! The total rainfall (kg/m2/s) inferno_fuel(land_pts), & @@ -139,10 +150,20 @@ SUBROUTINE inferno_io( & ! The amount of RPM that is available to burn (kgC.m-2) ls_rain_filtered(land_pts), & ! Large scale rain from input after filtering negative values - con_rain_filtered(land_pts) + con_rain_filtered(land_pts), & ! Convective rain from input after filtering negative values - - + wind_speed(land_pts), & + ! Wind speed (m s-1) + fuel_mort(land_pts), & + ! The combined grid-box impact of all PFTs on intensity + forest_wham(land_pts), & + ! does the tree cover cause WHAM AFTs to manage land as forest? + other_ba(land_pts), & + ! The tree-cover adjusted managed fire in non-agricultural areas + human_ignitions(land_pts) + ! The summed human ignitions accounting for dynamic land cover change + + REAL(KIND=real_jlslsm) , PARAMETER :: & fef_co2_dpm = 1637.0, fef_co_dpm = 89.0, & fef_ch4_dpm = 3.92, fef_nox_dpm = 2.51, & @@ -164,12 +185,20 @@ SUBROUTINE inferno_io( & ! HARDCODED Emission factors for RPM in g kg-1 pmtofuel = 0.7, & ! Plant Material that is available as fuel (on the surface) - fuel_low = 0.02, fuel_high = 0.2 + fuel_low = 0.02, fuel_high = 0.2, & ! Fuel availability high/low threshold + mort_c = -1.18735, & + ! Intercept for calculating grid box fuel fire intensity + intensity_scaling = 0.20, & + ! linear relationship of fire intensity to veg mortality + is_forest = 0.50 + ! point where pixel is considered (tropical) forest for WHAM mgmt REAL(KIND=real_jlslsm) , PARAMETER :: & - rain_tolerance = 1.0e-18 ! kg/m2/s - ! Tolerance number to filter non-physical rain values + s_in_month = 2.6280288e6, & + rain_tolerance = 1.0e-18 + ! Tolerance number to filter non-physical rain values (kg/m2/s) + INTEGER :: i, l ! counters for loops @@ -187,8 +216,13 @@ SUBROUTINE inferno_io( & inferno_temp(:) = 0.0 inferno_rhum(:) = 0.0 inferno_sm(:) = 0.0 +inferno_fsat(:) = 0.0 inferno_rain(:) = 0.0 inferno_fuel(:) = 0.0 +forest_wham(:) = 0.0 +other_ba(:) = 0.0 +human_ignitions(:) = 0.0 + ! Work variables qsat(:) = 0.0 lai_bal_inf(:,:)= 0.0 @@ -200,6 +234,11 @@ SUBROUTINE inferno_io( & fire_vars%flammability_ft(:,:) = 0.0 fire_vars%burnt_area(:) = 0.0 fire_vars%burnt_area_ft(:,:) = 0.0 +fire_vars%wham_ba(:) = 0.0 +fire_vars%wham_ba_ft(:,:) = 0.0 +fire_vars%intensity_ft(:, :) = 0.0 +fire_vars%intensity_clim(:, :) = 0.0 +fire_vars%intensity_wham(:, :) = 0.0 fire_vars%emitted_carbon(:) = 0.0 fire_vars%emitted_carbon_ft(:,:)= 0.0 fire_vars%emitted_carbon_DPM(:) = 0.0 @@ -274,6 +313,9 @@ SUBROUTINE inferno_io( & ! Soil Humidity (inferno_sm) inferno_sm(:) = (sthu_soilt(:,1,1)) +! Soil Moisture saturation (inferno_fsat) +inferno_fsat(:) = (fsat_soilt(:, 1, 1)) + ! Rainfall (inferno_rain) ! Rain fall values have a significant impact in the calculation @@ -307,6 +349,46 @@ SUBROUTINE inferno_io( & END DO END DO +!--------------------------------------------------------------- +! Calculate wind speed (using pythagoros theorem) +!--------------------------------------------------------------- + +wind_speed(:) = SQRT(u_1_gb(:)**2.0 + v_1_gb(:)**2.0) + + +!--------------------------------------------------------------- +! Feedback of tree cover on WHAM mgmt decisions +!--------------------------------------------------------------- + +other_ba(:) = fire_vars%wham_other_man(:) +human_ignitions(:) = fire_vars%wham_escaped(:) + +! calculate coverage of tropical tree PFTs +DO i = 1, npft + + !! remove prescribed fire in tropical forests + IF (fuel_type(i) == 1 .OR. fuel_type(i) == 2) THEN + + forest_wham(:) = forest_wham(:) + frac(:, i) + + END IF + +END DO + +! reduce prescribed fire in tropical forests +WHERE (forest_wham > is_forest) + + other_ba(:) = fire_vars%wham_other_man(:) - & + (0.5 * forest_wham(:) * fire_vars%wham_other_man(:)) + human_ignitions(:) = fire_vars%wham_escaped(:) - & + (0.5 * forest_wham(:) * fire_vars%wham_escaped(:)) + +END WHERE + +!sum other fire types & adjust ignitions with escaped managed fires +other_ba(:) = other_ba(:) + fire_vars%wham_other_ag(:) +human_ignitions(:) = fire_vars%wham_ignitions(:) + human_ignitions(:) + !--------------------------------------------------------------- ! Fire calculations - per PFT !--------------------------------------------------------------- @@ -347,15 +429,17 @@ SUBROUTINE inferno_io( & CALL qsat_wat(qsat(l), inferno_temp(l), pstar(l)) inferno_rhum(l) = q1p5m_tile(l,i) / qsat(l) * 100.0 - + IF (inferno_rhum(l) < 0.0) inferno_rhum(l) = 0.0 + ! Relative Humidity should be constrained to 0-100 - IF ((inferno_rhum(l)>100.0) .OR. (inferno_rhum(l)<0.0 )) CYCLE + IF ((inferno_rhum(l)>100.0)) CYCLE ! If all these checks are passes, start fire calculations CALL calc_ignitions( & !Point intent(IN) fire_vars%pop_den(l), fire_vars%flash_rate(l), & - fire_vars%wealth_index(l), ignition_method, & + fire_vars%wealth_index(l), human_ignitions(l), & + fire_vars%wham_suppression(l), ignition_method, & !Point intent(OUT) ignitions(l)) @@ -369,8 +453,11 @@ SUBROUTINE inferno_io( & CALL calc_burnt_area( & !Point INTENT(IN) fire_vars%flammability_ft(l,i), ignitions(l), avg_ba(i), & + fire_vars%road_density(l), fire_vars%wham_arable_ba(l), & + fire_vars%wham_pasture_ba(l), other_ba(l), i, & !Point INTENT(OUT) - fire_vars%burnt_area_ft(l,i)) + fire_vars%burnt_area_ft(l,i), fire_vars%wham_ba_ft(l, i)) + END DO CALL calc_emitted_carbon( & @@ -435,21 +522,124 @@ SUBROUTINE inferno_io( & END DO -DO i = 1, npft - DO l = 1, land_pts +!--------------------------------------------------------------- - ! Convert burnt_area into disturbance rate and accumulate to TRIFFID timestep - ! Accumulate to TRIFFID timestep - IF (l_trif_fire) THEN - ! Reset accumulation on first step after TRIFFID - IF (asteps_since_triffid == 1) g_burn_pft_acc(l,i) = 0.0 - g_burn_pft_acc(l,i) = g_burn_pft_acc(l,i) & - + (fire_vars%burnt_area_ft(l,i) * timestep) * fire_mort(i) +! Fire mortality calculations - per pft + +!--------------------------------------------------------------- + +IF (l_inferno_wham) THEN + + fire_vars%wham_ba(:) = SUM(fire_vars%wham_ba_ft & + * fire_vars%burnt_area_ft * frac(:, 1:npft), dim=2) + +ELSE + + fire_vars%wham_ba(:) = 0.0 - END IF +END IF +!--------------------------------------------------------------- +! Calculate combined impact of fuels on intensity & mortality +!--------------------------------------------------------------- + +fuel_mort = MATMUL(frac(:, 1:npft), LOG(fire_mort) - mort_c) +fuel_mort = EXP(fuel_mort + mort_c) + + +!--------------------------------------------------------------- +! Loop over PFTs and allocate mortality +! fire_mortality_method = 1: uniform mortality per PFT +! fire_mortality_method = 2: mortality per PFT adjusted for soil moisture +! fire_mortality_method = 3: explicit fire intensity-based mortality +!--------------------------------------------------------------- + +IF (l_trif_fire) THEN + + DO i = 1, npft + DO l = 1, land_pts + + IF (fire_mortality_method == 1) THEN + + !! simple mortality as a mean per pft + fire_vars%intensity_ft(l, i) = fire_mort(i) + + ELSE IF (fire_mortality_method == 2) THEN + + !! adjust vegetation mort for moisture content + fire_vars%intensity_ft(l, i) = (1 - inferno_fsat(l)) * fire_mort(i) + + ELSE IF (fire_mortality_method == 3) THEN + + ! Relative Humidity should be constrained to 0-100 + IF ((inferno_rhum(l)>100.0)) CYCLE + + ! No intensity if flammability == 0.0 + ! IF (fire_vars%flammability_ft(l,i) == 0.0) CYCLE + + !! explicit fire line intensity + CALL calc_intensity( & + !Point INTENT(IN) + inferno_rhum(l), inferno_fsat(l), wind_speed(l), dpm_fuel(l)/pmtofuel, & + fire_vars%wham_ba(l), fire_vars%road_density(l), & + fire_vars%pop_den(l), fuel_mort(l), fire_mort(i), fuel_type(i), i, & + !Point INTENT(OUT) + fire_vars%intensity_ft(l, i), fire_vars%intensity_clim(l, i), & + fire_vars%intensity_wham(l, i)) + + + END IF + + ! Convert burnt_area into disturbance rate and accumulate to TRIFFID timestep + ! Accumulate to TRIFFID timestep + ! Reset accumulation on first step after TRIFFID + IF (asteps_since_triffid == 1) g_burn_pft_acc(l,i) = 0.0 + + IF (fire_mortality_method == 3) THEN + + !Adjust intensity for targeted prescribed fire mortality + + IF (l_inferno_wham .AND. (fuel_type(i) == 3) ) THEN + g_burn_pft_acc(l,i) = g_burn_pft_acc(l,i) & + + ((fire_vars%intensity_ft(l, i)) & + * fire_vars%burnt_area_ft(l,i) * timestep) * intensity_scaling + !+ 0.05 * frac(l, i) * other_ba(l)/s_in_month + + ELSE IF (l_inferno_wham .AND. (fuel_type(i) == 4) ) THEN + g_burn_pft_acc(l,i) = g_burn_pft_acc(l,i) & + + ((fire_vars%intensity_ft(l, i)) & + * fire_vars%burnt_area_ft(l,i) * timestep) * intensity_scaling & + + 0.1 * frac(l, i) * other_ba(l)/s_in_month + + ELSE IF (l_inferno_wham .AND. (fuel_type(i) == 7) ) THEN + g_burn_pft_acc(l,i) = g_burn_pft_acc(l,i) & + + ((fire_vars%intensity_ft(l, i)) & + * fire_vars%burnt_area_ft(l,i) * timestep) * intensity_scaling & + + 0.1 * frac(l, i) * other_ba(l)/s_in_month + + ELSE + g_burn_pft_acc(l,i) = g_burn_pft_acc(l,i) & + + ((fire_vars%intensity_ft(l, i)) & + * fire_vars%burnt_area_ft(l,i) * timestep) * intensity_scaling + + END IF + + ELSE + + g_burn_pft_acc(l,i) = g_burn_pft_acc(l,i) & + + ((fire_vars%intensity_ft(l, i)) & + * fire_vars%burnt_area_ft(l,i) * timestep) + + END IF + + ! Multiply intensity by burned area for meaningful reporting + fire_vars%intensity_ft(l, i) = fire_vars%intensity_ft(l, i) & + * fire_vars%burnt_area_ft(l,i) + + END DO END DO -END DO +END IF + !--------------------------------------------------------------- ! In addition we diagnose the soil carbon (DPM and RPM only). diff --git a/src/science/fire/inferno_mod.F90 b/src/science/fire/inferno_mod.F90 index 3a7d18ff..b6d74732 100644 --- a/src/science/fire/inferno_mod.F90 +++ b/src/science/fire/inferno_mod.F90 @@ -39,7 +39,7 @@ MODULE inferno_mod PRIVATE ! Default everything as being private, unlock as needed -PUBLIC :: calc_ignitions, calc_flam, calc_burnt_area, & +PUBLIC :: calc_ignitions, calc_flam, calc_burnt_area, calc_intensity, & calc_emitted_carbon, calc_emitted_carbon_soil, & calc_emission, calc_soil_carbon_pools @@ -63,7 +63,8 @@ MODULE inferno_mod SUBROUTINE calc_ignitions( & ! Point intent(IN) - pop_den_l, flash_rate_l, wealth_index_l, ignition_method, & + pop_den_l, flash_rate_l, wealth_index_l, & + wham_ignitions_l, wham_suppression_l, ignition_method, & ! Point intent(OUT) ignitions_l) @@ -82,7 +83,7 @@ SUBROUTINE calc_ignitions( & USE yomhook, ONLY: lhook, dr_hook USE parkind1, ONLY: jprb USE jules_vegetation_mod, ONLY: ignition_constant, ignition_vary_natural, & - ignition_vary_natural_human + ignition_vary_natural_human, ignition_wham IMPLICIT NONE @@ -91,15 +92,20 @@ SUBROUTINE calc_ignitions( & ! The integer defining the method used for ignitions: ! 1 = constant, ! 2 = constant (Anthropogenic) + Varying (lightning), - ! 3 = Varying (Anthropogenic and lightning) + ! 3 = Varying (Anthropogenic and lightning), + ! 4 = WHAM! (Outputs of WHAM! agent-based model) REAL(KIND=real_jlslsm), INTENT(IN) :: & flash_rate_l, & ! The Cloud to Ground lightning flash rate (flashes/km2) pop_den_l, & ! The population density (ppl/km2) - wealth_index_l - ! The Human Development Index (1) + wealth_index_l, & + ! The Human Development Index (1) + wham_ignitions_l, & + ! unmanaged fires from the WHAM abm (fires/km2/month) + wham_suppression_l + ! fire suppression intensity from the WHAM abm (1) REAL(KIND=real_jlslsm), INTENT(OUT) :: & ignitions_l @@ -113,9 +119,15 @@ SUBROUTINE calc_ignitions( & non_sup_frac_l ! Fraction of fire ignition non suppressed by humans -REAL(KIND=real_jlslsm), PARAMETER :: & - tune_MODIS = 7.7 +REAL(KIND=real_jlslsm), PARAMETER :: & + tune_MODIS = 7.7, & ! Parameter originally used by P&S (2009) to match MODIS + tune_lightning_GFED5 = 0.55, & + ! Lightning parameter from calibration in Perkins et al., (2025) + scale_wham_GFED5 = 425.0, & + ! scale WHAM! unmanaged fires to GFED5, also from Perkins (2025) + wham_background_rate = 0.047 + ! misc ignitions, also from Perkins (fires/km2/yr) REAL(KIND=jprb) :: zhook_handle CHARACTER(LEN=*), PARAMETER :: RoutineName = "CALC_IGNITIONS" @@ -156,6 +168,22 @@ SUBROUTINE calc_ignitions( & ! Tune ignitions to MODIS data (see Pechony and Shindell, 2009) ignitions_l = ignitions_l * tune_MODIS + +ELSE IF (ignition_method == ignition_wham) THEN + + nat_ign_l = (1 - wham_suppression_l * 0.9) * flash_rate_l / m2_in_km2 / s_in_day + ! lightning ignitions multiplied by WHAM! representation of fire suppression + + non_sup_frac_l = (wham_background_rate/12 * (1-wham_suppression_l * 0.9)) + wham_ignitions_l + ! wham_background_rate is an annual baseline of misc. ignitions; + ! other ignitions are monthly + + man_ign_l = non_sup_frac_l / m2_in_km2 / s_in_month + ! WHAM! ignitions as a prescribed forcing + + ignitions_l = (tune_lightning_GFED5 * nat_ign_l) + (man_ign_l * scale_WHAM_GFED5) + ! sum WHAM! ignitions + END IF IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) @@ -268,8 +296,10 @@ END SUBROUTINE calc_flam SUBROUTINE calc_burnt_area( & ! Point INTENT(IN) flam_l, ignitions_l, avg_ba_i, & + road_density_l, wham_arable_ba_l, & + wham_pasture_ba_l, wham_other_ba_l, ipft, & ! Point INTENT(OUT) - burnt_area_i_l) + burnt_area_i_l, wham_frac_i_l) ! ! Description: @@ -286,31 +316,279 @@ SUBROUTINE calc_burnt_area( & USE yomhook, ONLY: lhook, dr_hook USE parkind1, ONLY: jprb +USE jules_surface_types_mod, ONLY: npft +USE trif, ONLY: crop +USE jules_vegetation_mod, ONLY: l_inferno_wham + IMPLICIT NONE +INTEGER , INTENT(IN) :: & + ipft + ! Index of current PFT + REAL(KIND=real_jlslsm) , INTENT(IN) :: & flam_l, & ! Flammability (depends on weather and vegetation) ignitions_l, & ! Fire ignitions (ignitions/m2/s) - avg_ba_i + avg_ba_i, & ! The average burned area (m2) for this PFT - -REAL(KIND=real_jlslsm) , INTENT(OUT) :: & - burnt_area_i_l + road_density_l, & + ! Road density function to contstrain fire size (Perkins 2025) + wham_arable_ba_l, & + ! Prescribed cropland burnt area (frac of gridbox per year) from WHAM + wham_pasture_ba_l, & + ! Prescribed pasture burnt area (frac of gridbox per year) from WHAM + wham_other_ba_l + ! Prescribed burnt area for other vegetation from WHAM + +REAL , INTENT(OUT) :: & + burnt_area_i_l, & ! The burnt area (fraction of PFT per s) + wham_frac_i_l + ! The proprtion of burnt area generated by small human fires (WHAM) + +! Parameter for impact of roads (fragmentation) on burned area +REAL, PARAMETER :: & + road_par=7.5, & + ! sets impact of road density fragmentation on fire size + tune_GFED5=0.82 + ! tune to GFED burned area + +REAL & + wham_man_i_l, & + ! intermediate variable for calculting wham managed contribution to BA + f_road_density_l, & + ! impact of road density on fire size + ba_per_fire + ! ba per pft adjusted for road density REAL(KIND=jprb) :: zhook_handle CHARACTER(LEN=*), PARAMETER :: RoutineName = "CALC_BURNT_AREA" IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) -burnt_area_i_l = flam_l * ignitions_l * avg_ba_i +IF (.NOT. l_inferno_wham) THEN + + burnt_area_i_l = flam_l * ignitions_l * avg_ba_i + wham_man_i_l = 0. + +ELSE + + IF (crop(ipft) == 1) THEN + + wham_man_i_l = wham_arable_ba_l / s_in_month + + ELSE IF (crop(ipft) == 2) THEN + + wham_man_i_l = wham_pasture_ba_l / s_in_month + + ELSE + + wham_man_i_l = wham_other_ba_l / s_in_month * 1.25 + + END IF + + !! calculate burned area per unmanaged fire accounting for fragmentation (roads) + !! NB for crop pfts, avg_ba_i is usually set to 0.0 with WHAM integration + f_road_density_l = MAX(0.1, MIN(1.0-(LOG(road_density_l)/road_par), 1.0)) + ba_per_fire = avg_ba_i * f_road_density_l + + !! combine managed (WHAM) and unmanaged (INFERNO) BA fractions + burnt_area_i_l = flam_l * ignitions_l * ba_per_fire + wham_man_i_l + wham_frac_i_l = MERGE(wham_man_i_l / burnt_area_i_l, 0.0, burnt_area_i_l > 0.0) + + ! temporary experiment with scaling factor + burnt_area_i_l = burnt_area_i_l * tune_GFED5 + +END IF IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) RETURN END SUBROUTINE calc_burnt_area + +SUBROUTINE calc_intensity( & + ! Point INTENT(IN) + rhum_l, sm_l, wind_speed_l, dpm_fuel_l, & + wham_man_l, road_density_l, popd_l, & + mort_l, avg_mort_i, fuel_type_i, ipft, & + ! Point INTENT(OUT) + intensity_il, fi_clim_il, fi_wham_il) + +! +! Description: +! Calculate the normalised fire line intensity +! +! Method: +! Combines fuel load & dryness with controls on +! fire spread & human management to project fire line intensity - +! FRP / sqrt(fire size) - normalised to 0-1. +! +! Code Owner: Please refer to ModuleLeaders.txt +! +! Code Description: +! Language: Fortran 90 + +USE yomhook, ONLY: lhook, dr_hook +USE parkind1, ONLY: jprb + +USE jules_surface_types_mod, ONLY: npft +USE jules_vegetation_mod, ONLY: l_inferno_wham + +IMPLICIT NONE + +INTEGER , INTENT(IN) :: & + fuel_type_i, & + ! The fuel type of the current PFT + ipft + ! Index of current PFT + +REAL , INTENT(IN) :: & + rhum_l, & + ! The relative humidity + sm_l, & + ! The INFERNO soil moisture fraction (fsat's 1st level) + wind_speed_l, & + ! Wind speed (m s-1) + dpm_fuel_l, & + ! Decomposable soil carbon - a proxy for dead, combustible fuels + wham_man_l, & + ! The managed burned area fraction of the pixel + road_density_l, & + ! The road density (m / m2 -1) + popd_l, & + ! The population density / km2 + mort_l, & + ! The combined effect of avg PFT mortality + avg_mort_i + ! The PFT-specific mortality parameter + + +REAL , INTENT(OUT) :: & + intensity_il, & + ! normalised fire line intensity (0-1) + fi_clim_il, & + ! climate impact on fire intensity [diagnostic] + fi_wham_il + ! WHAM impact on fire intensity [diagnostic] + +REAL & + fi_rhum_l, & + ! dependence of intensity on relative humidity + fi_sm_l, & + ! dependence of intensity on soil moisture + fi_pft_il, & + ! Combined impact of PFTs & management + fi_fuel_il, & + ! Impact of fuel & fragmentation on fi + frag_il + ! Impact of roads in fragmenting fuels + + +REAL, PARAMETER :: & + rhum_ceiling = 1.3127, & + ! sets the upper limit for the impact of rel. hum. + rhum_thresh_1 = 0.6, & + ! 1st threshold to the relative humidity + rhum_thresh_2 = 0.9, & + ! 2nd threshold to the relative humidity + rhum_slope_1 = 3, & + ! rate of decline due to relative humidity after threshold + rhum_slope_2 = 0.174, & + !rate of decline of RH overall + sm_thresh = 0.015, & + ! soil moisture threshold + sm_slope = 5, & + ! rate of soil moisture decay + wind_slope = 0.1, & + ! slope of wind impact on intensity + wham_slope = -17.5, & + ! rate of decay of management on FI + wham_offset = 0.0, & + ! offset applied to wham decay function + fuel_slope = 1.66, & + ! impact of dead fuel accumulation on intensity + frag_slope = 0.05, & + ! rate of impact of road density [or popd] on intensity + frag_thresh = 5, & + ! threshold for impact of road density [or popd] + frag_offset = 0.1 + ! offset for impact of road density [or popd if not using WHAM!] + + +REAL(KIND=jprb) :: zhook_handle +CHARACTER(LEN=*), PARAMETER :: RoutineName = "CALC_INTENSITY" + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) + +!------------------------------------------------------------------------- +! Climate factors +!------------------------------------------------------------------------- + +! Linear decay of intensity after a threshold RH +fi_rhum_l = (rhum_l/100) +fi_rhum_l = rhum_ceiling - (rhum_slope_1 * (fi_rhum_l - rhum_thresh_1)) - (fi_rhum_l * rhum_slope_2) +IF ((rhum_l/100) < rhum_thresh_1) fi_rhum_l = rhum_ceiling - rhum_slope_2 * (rhum_l/100) +IF ((rhum_l/100) > rhum_thresh_2) fi_rhum_l = rhum_ceiling - rhum_ceiling * (rhum_l/100) + +! Exponential decay of intensity after a threshold moisture content +fi_sm_l = EXP(-sm_slope * (sm_l - sm_thresh)) +IF (sm_l < sm_thresh) fi_sm_l = 1.0 + +! Combined impact of climatological factors +fi_clim_il = MAX(0.0, fi_rhum_l) * fi_sm_l * (wind_slope * wind_speed_l) + +!------------------------------------------------------------------------- +! PFTs & human mgmt +!------------------------------------------------------------------------- + +IF (l_inferno_wham) THEN + + fi_wham_il = EXP(wham_man_l * wham_slope * s_in_month * 12.0) + wham_offset + fi_pft_il = ((mort_l + avg_mort_i) / 2) * fi_wham_il + +ELSE + + fi_pft_il = ((mort_l + avg_mort_i) / 2) + +END IF + +!------------------------------------------------------------------------- +! Fuel fragmentation +!------------------------------------------------------------------------- + +IF (l_inferno_wham) THEN + + frag_il = SQRT(road_density_l) + frag_il = EXP(-frag_slope * (frag_il - frag_thresh)) + frag_offset + IF (SQRT(road_density_l) < frag_thresh) frag_il = 1.0 + frag_offset + + fi_fuel_il = frag_il + +ELSE + + frag_il = SQRT(popd_l) + frag_il = EXP(-frag_slope * (frag_il - frag_thresh)) + frag_offset + IF (SQRT(popd_l) < frag_thresh) frag_il = 1.0 + frag_offset + + fi_fuel_il = frag_il + +END IF + +!------------------------------------------------------------------------- +! Combined calculation +!------------------------------------------------------------------------- + +intensity_il = SQRT(MAX(0.0, (fi_fuel_il * fi_pft_il * fi_clim_il))) + +IF (lhook) CALL dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) +RETURN +END SUBROUTINE calc_intensity + + + + SUBROUTINE calc_emitted_carbon( & ! Array INTENT(IN) land_pts, burnt_area_i, sm, leaf_i, wood_i, & diff --git a/src/science/params/pftparm_io_mod.F90 b/src/science/params/pftparm_io_mod.F90 index 8de2ac1c..214223a1 100644 --- a/src/science/params/pftparm_io_mod.F90 +++ b/src/science/params/pftparm_io_mod.F90 @@ -38,7 +38,8 @@ MODULE pftparm_io INTEGER :: & c3_io(npft_max) = imdi, & - orient_io(npft_max) = imdi + orient_io(npft_max) = imdi, & + fuel_type_io(npft_max) = imdi REAL(KIND=real_jlslsm) :: & a_wl_io(npft_max) = rmdi, & @@ -175,9 +176,9 @@ MODULE pftparm_io fef_co2_io, fef_nox_io, fef_oc_io, & fef_c2h4_io, fef_c2h6_io, fef_c3h8_io, & fef_hcho_io, fef_mecho_io, & - fef_nh3_io, fef_dms_io, & - fef_so2_io, fd_io, fire_mort_io, & - fl_o3_ct_io, fsmc_of_io, fsmc_p0_io, & + fef_nh3_io, fef_dms_io, fef_so2_io, & + fd_io, fire_mort_io, fl_o3_ct_io, & + fsmc_of_io, fsmc_p0_io, fuel_type_io, & sug_g0_io, g1_stomata_io, g_leaf_0_io, & glmin_io, gpp_st_io, sug_grec_io, & gsoil_f_io, hw_sw_io, ief_io, & @@ -332,6 +333,8 @@ SUBROUTINE print_nlist_jules_pftparm() CALL jules_print('pftparm_io',lineBuffer) WRITE(lineBuffer,*)' fsmc_p0_io = ',fsmc_p0_io CALL jules_print('pftparm_io',lineBuffer) +WRITE(lineBuffer,*)' fuel_type_io = ',fuel_type_io +CALL jules_print('pftparm_io',lineBuffer) WRITE(lineBuffer,*)' sug_g0_io = ',sug_g0_io CALL jules_print('pftparm_io',lineBuffer) WRITE(lineBuffer,*)' g1_stomata_io = ',g1_stomata_io @@ -462,6 +465,7 @@ SUBROUTINE read_nml_jules_pftparm (unitnumber) SEQUENCE INTEGER :: c3_io(npft_max) INTEGER :: orient_io(npft_max) + INTEGER :: fuel_type_io(npft_max) REAL(KIND=real_jlslsm) :: a_wl_io(npft_max) REAL(KIND=real_jlslsm) :: a_ws_io(npft_max) REAL(KIND=real_jlslsm) :: act_jmax_io(npft_max) @@ -649,6 +653,7 @@ SUBROUTINE read_nml_jules_pftparm (unitnumber) my_nml % fl_o3_ct_io = fl_o3_ct_io my_nml % fsmc_of_io = fsmc_of_io my_nml % fsmc_p0_io = fsmc_p0_io + my_nml % fuel_type_io = fuel_type_io my_nml % sug_g0_io = sug_g0_io my_nml % g1_stomata_io = g1_stomata_io my_nml % g_leaf_0_io = g_leaf_0_io @@ -765,6 +770,7 @@ SUBROUTINE read_nml_jules_pftparm (unitnumber) fl_o3_ct_io = my_nml % fl_o3_ct_io fsmc_of_io = my_nml % fsmc_of_io fsmc_p0_io = my_nml % fsmc_p0_io + fuel_type_io = my_nml % fuel_type_io g1_stomata_io = my_nml % g1_stomata_io sug_g0_io = my_nml % sug_g0_io g_leaf_0_io = my_nml % g_leaf_0_io @@ -854,8 +860,8 @@ SUBROUTINE init_pftparm_allocated() fef_oc, fef_so2, fef_c2h4, & fef_c2h6, fef_c3h8, fef_hcho, & fef_mecho, fef_nh3, & - fef_dms, fire_mort, & - fl_o3_ct, fsmc_of, fsmc_p0, & + fef_dms, fire_mort, fl_o3_ct, & + fsmc_of, fsmc_p0, fuel_type, & sug_g0, g1_stomata, g_leaf_0, & glmin, gpp_st, sug_grec, & gsoil_f, hw_sw, ief, & @@ -1001,7 +1007,8 @@ SUBROUTINE init_pftparm_allocated() ccleaf_min(:) = ccleaf_min_io(1:npft) ccwood_max(:) = ccwood_max_io(1:npft) ccwood_min(:) = ccwood_min_io(1:npft) -fire_mort(:) = fire_mort_io(1:npft) +fire_mort(:) = fire_mort_io(1:npft) +fuel_type(:) = fuel_type_io(1:npft) ! INFERNO emission parameters fef_bc(:) = fef_bc_io(1:npft) diff --git a/src/science/params/pftparm_mod.F90 b/src/science/params/pftparm_mod.F90 index 8b848c83..9cc4a025 100644 --- a/src/science/params/pftparm_mod.F90 +++ b/src/science/params/pftparm_mod.F90 @@ -300,6 +300,12 @@ MODULE pftparm !----------------------------------------------------------------------------- ! Parameters for INFERNO combustion !----------------------------------------------------------------------------- + +INTEGER, ALLOCATABLE :: & + fuel_type(:) + ! PFT fuel type for management decisions + + REAL(KIND=real_jlslsm), ALLOCATABLE :: & avg_ba(:) & ! Average PFT Burnt Area per fire @@ -599,6 +605,7 @@ SUBROUTINE pftparm_alloc(npft) ALLOCATE( ccwood_min(npft)) ALLOCATE( ccwood_max(npft)) ALLOCATE( fire_mort(npft)) +ALLOCATE( fuel_type(npft)) avg_ba(:) = 0.0 ccleaf_min(:) = 0.0 @@ -606,6 +613,7 @@ SUBROUTINE pftparm_alloc(npft) ccwood_min(:) = 0.0 ccwood_max(:) = 0.0 fire_mort(:) = 0.0 +fuel_type(:) = 0.0 ! INFERNO emission parameters ALLOCATE( fef_bc(npft))