From 38926beaa6623270bf54ae9a2efdaa19305366a1 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Wed, 7 Aug 2024 12:40:02 -0600 Subject: [PATCH 01/11] Copy CNFireLi2021Mod.F90 to new CNFireLi2024Mod.F90. Includes new fire_method li2024gswpfrc. --- bld/namelist_files/namelist_defaults_ctsm.xml | 15 + .../namelist_definition_ctsm.xml | 3 +- src/biogeochem/CNFireFactoryMod.F90 | 3 + src/biogeochem/CNFireLi2024Mod.F90 | 658 ++++++++++++++++++ 4 files changed, 678 insertions(+), 1 deletion(-) create mode 100644 src/biogeochem/CNFireLi2024Mod.F90 diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 655e97c47c..a7e59935a4 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -319,6 +319,21 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.5d00 0.28d00 +30.0d00 +80.0d00 +0.85d00 +0.98d00 +0.025d00 +0.09d-4 +0.010d00 +0.17d-3 +1.6d-4 +0.33d00 +75.d00 +1050.d00 +0.5d00 +0.28d00 + .false. .true. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 37c457141c..6b70c117e5 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -252,13 +252,14 @@ formulation (1). + group="cnfire_inparm" valid_values="nofire,li2014qianfrc,li2016crufrc,li2021gswpfrc,li2024gswpfrc" > The method type to use for CNFire nofire: Turn fire effects off li2014qianfrc: Reference paper Li, et. al.(2014) tuned with QIAN atmospheric forcing li2016crufrc: Reference paper Li, et. al.(2016) tuned with CRU-NCEP atmospheric forcing li2021gswpfrc: Reference paper Li, et. al.(2021?) tuned with GSWP3 atmospheric forcing +li2024gswpfrc: No reference paper yet shr_kind_r8, CL => shr_kind_CL + use shr_const_mod , only : SHR_CONST_PI,SHR_CONST_TKFRZ + use shr_infnan_mod , only : shr_infnan_isnan + use clm_varctl , only : iulog + use clm_varpar , only : nlevdecomp, ndecomp_pools, nlevdecomp_full, nlevgrnd + use clm_varcon , only : dzsoi_decomp + use pftconMod , only : noveg, pftcon + use abortutils , only : endrun + use decompMod , only : bounds_type + use subgridAveMod , only : p2c + use atm2lndType , only : atm2lnd_type + use CNDVType , only : dgvs_type + use CNVegStateType , only : cnveg_state_type + use CNVegCarbonStateType , only : cnveg_carbonstate_type, spinup_factor_deadwood + use CNVegCarbonFluxType , only : cnveg_carbonflux_type + use CNVegNitrogenStateType , only : cnveg_nitrogenstate_type + use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type + use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con + use EnergyFluxType , only : energyflux_type + use SaturatedExcessRunoffMod , only : saturated_excess_runoff_type + use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type + use Wateratm2lndBulkType , only : wateratm2lndbulk_type + use WaterStateBulkType , only : waterstatebulk_type + use SoilStateType , only : soilstate_type + use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type + use GridcellType , only : grc + use ColumnType , only : col + use PatchType , only : patch + use SoilBiogeochemStateType , only : get_spinup_latitude_term + use FireMethodType , only : fire_method_type + use CNFireBaseMod , only : cnfire_base_type, cnfire_const, cnfire_params + ! + implicit none + private + ! + ! !PUBLIC TYPES: + public :: cnfire_li2024_type + ! + type, extends(cnfire_base_type) :: cnfire_li2024_type + private + contains + ! + ! !PUBLIC MEMBER FUNCTIONS: + procedure, public :: need_lightning_and_popdens + procedure, public :: CNFireArea ! Calculate fire area + end type cnfire_li2024_type + + ! + ! !PRIVATE MEMBER DATA: + !----------------------------------------------------------------------- + + character(len=*), parameter, private :: sourcefile = & + __FILE__ + +contains + + !----------------------------------------------------------------------- + function need_lightning_and_popdens(this) + ! !ARGUMENTS: + class(cnfire_li2024_type), intent(in) :: this + logical :: need_lightning_and_popdens ! function result + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'need_lightning_and_popdens' + !----------------------------------------------------------------------- + + need_lightning_and_popdens = .true. + end function need_lightning_and_popdens + + !----------------------------------------------------------------------- + subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, & + num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & + atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, waterdiagnosticbulk_inst, & + wateratm2lndbulk_inst, waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & + cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + ! + ! !DESCRIPTION: + ! Computes column-level burned area + ! + ! !USES: + use clm_time_manager , only: get_step_size_real, get_curr_days_per_year, get_curr_date, get_nstep + use clm_varcon , only: secspday, secsphr + use clm_varctl , only: spinup_state + use pftconMod , only: nc4_grass, nc3crop, ndllf_evr_tmp_tree + use pftconMod , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, nbrdlf_evr_shrub + use dynSubgridControlMod , only : run_has_transient_landcover + ! + ! !ARGUMENTS: + class(cnfire_li2024_type) :: this + type(bounds_type) , intent(in) :: bounds + integer , intent(in) :: num_soilc ! number of soil columns in filter + integer , intent(in) :: filter_soilc(:) ! filter for soil columns + integer , intent(in) :: num_soilp ! number of soil patches in filter + integer , intent(in) :: filter_soilp(:) ! filter for soil patches + integer , intent(in) :: num_exposedvegp ! number of points in filter_exposedvegp + integer , intent(in) :: filter_exposedvegp(:) ! patch filter for non-snow-covered veg + integer , intent(in) :: num_noexposedvegp ! number of points in filter_noexposedvegp + integer , intent(in) :: filter_noexposedvegp(:) ! patch filter where frac_veg_nosno is 0 + type(atm2lnd_type) , intent(in) :: atm2lnd_inst + type(energyflux_type) , intent(in) :: energyflux_inst + type(saturated_excess_runoff_type) , intent(in) :: saturated_excess_runoff_inst + type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst + type(wateratm2lndbulk_type) , intent(in) :: wateratm2lndbulk_inst + type(waterstatebulk_type) , intent(in) :: waterstatebulk_inst + type(soilstate_type) , intent(in) :: soilstate_inst + class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve + type(cnveg_state_type) , intent(inout) :: cnveg_state_inst + type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + real(r8) , intent(in) :: totlitc_col(bounds%begc:) + real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) + real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) + ! + ! !LOCAL VARIABLES: + ! + integer :: g,l,c,p,pi,j,fc,fp,kyr, kmo, kda, mcsec ! index variables + real(r8) :: dt ! time step variable (s) + real(r8) :: dayspyr ! days per year + real(r8) :: cli ! effect of climate on deforestation fires (0-1) + real(r8) :: cri ! thresholds used for cli, (mm/d), see Eq.(7) in Li et al.(2013) + real(r8) :: fb ! availability of fuel for regs A and C + real(r8) :: fhd ! impact of hd on agricultural fire + real(r8) :: fgdp ! impact of gdp on agricultural fire + real(r8) :: fire_m ! combustability of fuel for fire occurrence + real(r8) :: spread_m ! combustability of fuel for fire spread + real(r8) :: Lb_lf ! length-to-breadth ratio added by Lifang + integer :: i_cwd ! cwd pool + real(r8) :: lh ! anthro. ignitions (count/km2/hr) + real(r8) :: fs ! hd-dependent fires suppression (0-1) + real(r8) :: ig ! total ignitions (count/km2/hr) + real(r8) :: hdmlf ! human density + real(r8) :: arh, arh30 !combustability of fuel related to RH and RH30 + real(r8) :: afuel !weight for arh and arh30 + real(r8) :: btran_col(bounds%begc:bounds%endc) + logical :: transient_landcover ! whether this run has any prescribed transient landcover + real(r8), target :: prec60_col_target(bounds%begc:bounds%endc) + real(r8), target :: prec10_col_target(bounds%begc:bounds%endc) + real(r8), target :: rh30_col_target(bounds%begc:bounds%endc) + real(r8), pointer :: prec60_col(:) + real(r8), pointer :: prec10_col(:) + real(r8), pointer :: rh30_col(:) + !----------------------------------------------------------------------- + + SHR_ASSERT_ALL_FL((ubound(totlitc_col) == (/bounds%endc/)), sourcefile, __LINE__) + SHR_ASSERT_ALL_FL((ubound(decomp_cpools_vr_col) == (/bounds%endc,nlevdecomp_full,ndecomp_pools/)), sourcefile, __LINE__) + SHR_ASSERT_ALL_FL((ubound(t_soi17cm_col) == (/bounds%endc/)), sourcefile, __LINE__) + + associate( & + totlitc => totlitc_col , & ! Input: [real(r8) (:) ] (gC/m2) total lit C (column-level mean) + decomp_cpools_vr => decomp_cpools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) VR decomp. (litter, cwd, soil) + tsoi17 => t_soi17cm_col , & ! Input: [real(r8) (:) ] (K) soil T for top 0.17 m + + lfuel => cnfire_const%lfuel , & ! Input: [real(r8) ] (gC/m2) Lower threshold of fuel mass + ufuel => cnfire_const%ufuel , & ! Input: [real(r8) ] (gC/m2) Upper threshold of fuel mass + rh_hgh => cnfire_const%rh_hgh , & ! Input: [real(r8) ] (%) High relative humidity + rh_low => cnfire_const%rh_low , & ! Input: [real(r8) ] (%) Low relative humidity + cli_scale => cnfire_const%cli_scale , & ! Input: [real(r8) ] (/d) global constant for deforestation fires + cropfire_a1 => cnfire_const%cropfire_a1 , & ! Input: [real(r8) ] (/hr) a1 parameter for cropland fire + non_boreal_peatfire_c => cnfire_const%non_boreal_peatfire_c , & ! Input: [real(r8) ] (/hr) c parameter for non-boreal peatland fire + pot_hmn_ign_counts_alpha => cnfire_const%pot_hmn_ign_counts_alpha , & ! Input: [real(r8) ] (/person/month) Potential human ignition counts + boreal_peatfire_c => cnfire_const%boreal_peatfire_c , & ! Input: [real(r8) ] (/hr) c parameter for boreal peatland fire + + fsr_pft => pftcon%fsr_pft , & ! Input: + fd_pft => pftcon%fd_pft , & ! Input: + rswf_min => pftcon%rswf_min , & ! Input: + rswf_max => pftcon%rswf_max , & ! Input: + btran2 => this%cnfire_base_type%btran2_patch , & ! Input: [real(r8) (:) ] root zone soil wetness + fsat => saturated_excess_runoff_inst%fsat_col , & ! Input: [real(r8) (:) ] fractional area with water table at surface + wf2 => waterdiagnosticbulk_inst%wf2_col , & ! Input: [real(r8) (:) ] soil water as frac. of whc for top 0.17 m + + is_cwd => decomp_cascade_con%is_cwd , & ! Input: [logical (:) ] TRUE => pool is a cwd pool + spinup_factor => decomp_cascade_con%spinup_factor , & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool + + forc_rh => wateratm2lndbulk_inst%forc_rh_grc , & ! Input: [real(r8) (:) ] relative humidity + forc_wind => atm2lnd_inst%forc_wind_grc , & ! Input: [real(r8) (:) ] atmospheric wind speed (m/s) + forc_t => atm2lnd_inst%forc_t_downscaled_col , & ! Input: [real(r8) (:) ] downscaled atmospheric temperature (Kelvin) + forc_rain => wateratm2lndbulk_inst%forc_rain_downscaled_col , & ! Input: [real(r8) (:) ] downscaled rain + forc_snow => wateratm2lndbulk_inst%forc_snow_downscaled_col , & ! Input: [real(r8) (:) ] downscaled snow + prec60 => wateratm2lndbulk_inst%prec60_patch , & ! Input: [real(r8) (:) ] 60-day running mean of tot. precipitation + prec10 => wateratm2lndbulk_inst%prec10_patch , & ! Input: [real(r8) (:) ] 10-day running mean of tot. precipitation + rh30 => wateratm2lndbulk_inst%rh30_patch , & ! Input: [real(r8) (:) ] 10-day running mean of tot. precipitation + dwt_smoothed => cnveg_state_inst%dwt_smoothed_patch , & ! Input: [real(r8) (:) ] change in patch weight (-1 to 1) on the gridcell, smoothed over the year + cropf_col => cnveg_state_inst%cropf_col , & ! Input: [real(r8) (:) ] cropland fraction in veg column + gdp_lf => this%gdp_lf_col , & ! Input: [real(r8) (:) ] gdp data + peatf_lf => this%peatf_lf_col , & ! Input: [real(r8) (:) ] peatland fraction data + abm_lf => this%abm_lf_col , & ! Input: [integer (:) ] prescribed crop fire time + baf_crop => cnveg_state_inst%baf_crop_col , & ! Output: [real(r8) (:) ] burned area fraction for cropland (/sec) + baf_peatf => cnveg_state_inst%baf_peatf_col , & ! Output: [real(r8) (:) ] burned area fraction for peatland (/sec) + burndate => cnveg_state_inst%burndate_patch , & ! Output: [integer (:) ] burn date for crop + fbac => cnveg_state_inst%fbac_col , & ! Output: [real(r8) (:) ] total burned area out of conversion (/sec) + fbac1 => cnveg_state_inst%fbac1_col , & ! Output: [real(r8) (:) ] burned area out of conversion region due to land use fire + farea_burned => cnveg_state_inst%farea_burned_col , & ! Output: [real(r8) (:) ] total fractional area burned (/sec) + nfire => cnveg_state_inst%nfire_col , & ! Output: [real(r8) (:) ] fire counts (count/km2/sec), valid only in Reg. C + fsr_col => cnveg_state_inst%fsr_col , & ! Output: [real(r8) (:) ] fire spread rate at column level + fd_col => cnveg_state_inst%fd_col , & ! Output: [real(r8) (:) ] fire duration rate at column level + lgdp_col => cnveg_state_inst%lgdp_col , & ! Output: [real(r8) (:) ] gdp limitation factor for nfire + lgdp1_col => cnveg_state_inst%lgdp1_col , & ! Output: [real(r8) (:) ] gdp limitation factor for baf per fire + lpop_col => cnveg_state_inst%lpop_col , & ! Output: [real(r8) (:) ] pop limitation factor for baf per fire + lfwt => cnveg_state_inst%lfwt_col , & ! Output: [real(r8) (:) ] fractional coverage of non-crop and non-bare-soil Patches + trotr1_col => cnveg_state_inst%trotr1_col , & ! Output: [real(r8) (:) ] patch weight of BET on the column (0-1) + trotr2_col => cnveg_state_inst%trotr2_col , & ! Output: [real(r8) (:) ] patch weight of BDT on the column (0-1) + dtrotr_col => cnveg_state_inst%dtrotr_col , & ! Output: [real(r8) (:) ] decreased frac. coverage of BET+BDT on grid for dt + lfc => cnveg_state_inst%lfc_col , & ! Output: [real(r8) (:) ] conversion area frac. of BET+BDT that haven't burned before + wtlf => cnveg_state_inst%wtlf_col , & ! Output: [real(r8) (:) ] fractional coverage of non-crop Patches + + totvegc => cnveg_carbonstate_inst%totvegc_col , & ! Input: [real(r8) (:) ] totvegc at column level + deadcrootc => cnveg_carbonstate_inst%deadcrootc_patch , & ! Input: [real(r8) (:) ] (gC/m2) dead coarse root C + deadcrootc_storage => cnveg_carbonstate_inst%deadcrootc_storage_patch , & ! Input: [real(r8) (:) ] (gC/m2) dead coarse root C storage + deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! Input: [real(r8) (:) ] (gC/m2) dead coarse root C transfer + deadstemc => cnveg_carbonstate_inst%deadstemc_patch , & ! Input: [real(r8) (:) ] (gC/m2) dead stem root C + frootc => cnveg_carbonstate_inst%frootc_patch , & ! Input: [real(r8) (:) ] (gC/m2) fine root C + frootc_storage => cnveg_carbonstate_inst%frootc_storage_patch , & ! Input: [real(r8) (:) ] (gC/m2) fine root C storage + frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! Input: [real(r8) (:) ] (gC/m2) fine root C transfer + livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! Input: [real(r8) (:) ] (gC/m2) live coarse root C + livecrootc_storage => cnveg_carbonstate_inst%livecrootc_storage_patch , & ! Input: [real(r8) (:) ] (gC/m2) live coarse root C storage + livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! Input: [real(r8) (:) ] (gC/m2) live coarse root C transfer + leafc => cnveg_carbonstate_inst%leafc_patch , & ! Input: [real(r8) (:) ] (gC/m2) leaf C + leafc_storage => cnveg_carbonstate_inst%leafc_storage_patch , & ! Input: [real(r8) (:) ] (gC/m2) leaf C storage + leafc_xfer => cnveg_carbonstate_inst%leafc_xfer_patch , & ! Input: [real(r8) (:) ] (gC/m2) leaf C transfer + rootc_col => cnveg_carbonstate_inst%rootc_col , & ! Output: [real(r8) (:) ] root carbon + leafc_col => cnveg_carbonstate_inst%leafc_col , & ! Output: [real(r8) (:) ] leaf carbon at column level + deadstemc_col => cnveg_carbonstate_inst%deadstemc_col , & ! Output: [real(r8) (:) ] deadstem carbon at column level + fuelc => cnveg_carbonstate_inst%fuelc_col , & ! Output: [real(r8) (:) ] fuel load coutside cropland + fuelc_crop => cnveg_carbonstate_inst%fuelc_crop_col & ! Output: [real(r8) (:) ] fuel load for cropland + ) + + transient_landcover = run_has_transient_landcover() + + !pft to column average + prec10_col =>prec10_col_target + call p2c(bounds, num_soilc, filter_soilc, & + prec10(bounds%begp:bounds%endp), & + prec10_col(bounds%begc:bounds%endc)) + + prec60_col =>prec60_col_target + call p2c(bounds, num_soilc, filter_soilc, & + prec60(bounds%begp:bounds%endp), & + prec60_col(bounds%begc:bounds%endc)) + + rh30_col =>rh30_col_target + call p2c(bounds, num_soilc, filter_soilc, & + rh30(bounds%begp:bounds%endp), & + rh30_col(bounds%begc:bounds%endc)) + + call p2c(bounds, num_soilc, filter_soilc, & + leafc(bounds%begp:bounds%endp), & + leafc_col(bounds%begc:bounds%endc)) + + call p2c(bounds, num_soilc, filter_soilc, & + deadstemc(bounds%begp:bounds%endp), & + deadstemc_col(bounds%begc:bounds%endc)) + + call get_curr_date (kyr, kmo, kda, mcsec) + dayspyr = get_curr_days_per_year() + ! Get model step size + dt = get_step_size_real() + ! + ! On first time-step, just set area burned to zero and exit + ! + if ( get_nstep() == 0 )then + do fc = 1,num_soilc + c = filter_soilc(fc) + farea_burned(c) = 0._r8 + baf_crop(c) = 0._r8 + baf_peatf(c) = 0._r8 + fbac(c) = 0._r8 + fbac1(c) = 0._r8 + cropf_col(c) = 0._r8 + end do + return + end if + ! + ! Calculate fraction of crop (cropf_col) and non-crop and non-bare-soil + ! vegetation (lfwt) in vegetated column + ! + do fc = 1,num_soilc + c = filter_soilc(fc) + cropf_col(c) = 0._r8 + lfwt(c) = 0._r8 + end do + do fp = 1, num_soilp + p = filter_soilp(fp) + c = patch%column(p) + ! For crop veg types + if( patch%itype(p) > nc4_grass )then + cropf_col(c) = cropf_col(c) + patch%wtcol(p) + end if + ! For natural vegetation (non-crop and non-bare-soil) + if( patch%itype(p) >= ndllf_evr_tmp_tree .and. patch%itype(p) <= nc4_grass )then + lfwt(c) = lfwt(c) + patch%wtcol(p) + end if + end do + ! + ! Calculate crop fuel + ! + do fc = 1,num_soilc + c = filter_soilc(fc) + fuelc_crop(c)=0._r8 + end do + do fp = 1, num_soilp + p = filter_soilp(fp) + c = patch%column(p) + ! For crop PFTs, fuel load includes leaf and litter; only + ! column-level litter carbon + ! is available, so we use leaf carbon to estimate the + ! litter carbon for crop PFTs + if( patch%itype(p) > nc4_grass .and. patch%wtcol(p) > 0._r8 .and. leafc_col(c) > 0._r8 )then + fuelc_crop(c)=fuelc_crop(c) + (leafc(p) + leafc_storage(p) + & + leafc_xfer(p))*patch%wtcol(p)/cropf_col(c) + & + totlitc(c)*leafc(p)/leafc_col(c)*patch%wtcol(p)/cropf_col(c) + end if + end do + ! + ! Calculate noncrop column variables + ! + do fc = 1,num_soilc + c = filter_soilc(fc) + fsr_col(c) = 0._r8 + fd_col(c) = 0._r8 + rootc_col(c) = 0._r8 + lgdp_col(c) = 0._r8 + lgdp1_col(c) = 0._r8 + lpop_col(c) = 0._r8 + btran_col(c) = 0._r8 + wtlf(c) = 0._r8 + trotr1_col(c)= 0._r8 + trotr2_col(c)= 0._r8 + if (transient_landcover) then + dtrotr_col(c)=0._r8 + end if + end do + + ! This subroutine calculates btran2 + call this%CNFire_calc_fire_root_wetness_Li2021(bounds, & + num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & + waterstatebulk_inst, soilstate_inst, soil_water_retention_curve) + do fp = 1, num_exposedvegp + p = filter_exposedvegp(fp) + c = patch%column(p) + ! For non-crop -- natural vegetation and bare-soil + if( patch%itype(p) < nc3crop .and. cropf_col(c) < 1.0_r8 )then + btran_col(c) = btran_col(c)+max(0._r8, min(1._r8, & + (btran2(p)-rswf_min(patch%itype(p)))/(rswf_max(patch%itype(p)) & + -rswf_min(patch%itype(p)))))*patch%wtcol(p) + wtlf(c) = wtlf(c)+patch%wtcol(p) + end if + end do + + do fp = 1, num_soilp + p = filter_soilp(fp) + c = patch%column(p) + g = col%gridcell(c) + + ! For non-crop -- natural vegetation and bare-soil + if( patch%itype(p) < nc3crop .and. cropf_col(c) < 1.0_r8 )then + + ! NOTE(wjs, 2016-12-15) These calculations of the fraction of evergreen + ! and deciduous tropical trees (used to determine if a column is + ! tropical closed forest) use the current fractions. However, I think + ! they are used in code that applies to land cover change. Note that + ! land cover change is currently generated on the first time step of the + ! year (even though the fire code sees the annually-smoothed dwt). Thus, + ! I think that, for this to be totally consistent, this code should + ! consider the fractional coverage of each PFT prior to the relevant + ! land cover change event. (These fractions could be computed in the + ! code that handles land cover change, so that the fire code remains + ! agnostic to exactly how and when land cover change happens.) + ! + ! For example, if a year started with fractional coverages of + ! nbrdlf_evr_trp_tree = 0.35 and nbrdlf_dcd_trp_tree = 0.35, but then + ! the start-of-year land cover change reduced both of these to 0.2: The + ! current code would consider the column to NOT be tropical closed + ! forest (because nbrdlf_evr_trp_tree+nbrdlf_dcd_trp_tree < 0.6), + ! whereas in fact the land cover change occurred when the column *was* + ! tropical closed forest. + if( patch%itype(p) == nbrdlf_evr_trp_tree .and. patch%wtcol(p) > 0._r8 )then + trotr1_col(c)=trotr1_col(c)+patch%wtcol(p) + end if + if( patch%itype(p) == nbrdlf_dcd_trp_tree .and. patch%wtcol(p) > 0._r8 )then + trotr2_col(c)=trotr2_col(c)+patch%wtcol(p) + end if + + if (transient_landcover) then + if( patch%itype(p) == nbrdlf_evr_trp_tree .or. patch%itype(p) == nbrdlf_dcd_trp_tree )then + if(dwt_smoothed(p) < 0._r8)then + ! Land cover change in CLM happens all at once on the first time + ! step of the year. However, the fire code needs deforestation + ! rates throughout the year, in order to combine these + ! deforestation rates with the current season's climate. So we + ! use a smoothed version of dwt. + ! + ! This isn't ideal, because the carbon stocks that the fire code + ! is operating on will have decreased by the full annual amount + ! before the fire code does anything. But the biggest effect of + ! these deforestation fires is as a trigger for other fires, and + ! the C fluxes are merely diagnostic so don't need to be + ! conservative, so this isn't a big issue. + ! + ! (Actually, it would be even better if the fire code had a + ! realistic breakdown of annual deforestation into the + ! different seasons. But having deforestation spread evenly + ! throughout the year is much better than having it all + ! concentrated on January 1.) + dtrotr_col(c)=dtrotr_col(c)-dwt_smoothed(p) + end if + end if + end if + rootc_col(c) = rootc_col(c) + (frootc(p) + frootc_storage(p) + & + frootc_xfer(p) + deadcrootc(p) * spinup_factor_deadwood + & + deadcrootc_storage(p) + deadcrootc_xfer(p) + & + livecrootc(p)+livecrootc_storage(p) + & + livecrootc_xfer(p))*patch%wtcol(p) + + fsr_col(c) = fsr_col(c) + fsr_pft(patch%itype(p))*patch%wtcol(p)/(1.0_r8-cropf_col(c)) + + hdmlf=this%forc_hdm(g) + + ! all these constants are in Li et al. BG (2012a,b;2013) + + if( hdmlf > 0.1_r8 )then + ! For NOT bare-soil + if( patch%itype(p) /= noveg )then + ! For shrub and grass (crop already excluded above) + if( patch%itype(p) >= nbrdlf_evr_shrub )then !for shurb and grass + lgdp_col(c) = lgdp_col(c) + (0.1_r8 + 0.9_r8* & + exp(-1._r8*SHR_CONST_PI* & + (gdp_lf(c)/8._r8)**0.5_r8))*patch%wtcol(p) & + /(1.0_r8 - cropf_col(c)) + lgdp1_col(c) = lgdp1_col(c) + (0.2_r8 + 0.8_r8* & + exp(-1._r8*SHR_CONST_PI* & + (gdp_lf(c)/7._r8)))*patch%wtcol(p)/(1._r8 - cropf_col(c)) + lpop_col(c) = lpop_col(c) + (0.2_r8 + 0.8_r8* & + exp(-1._r8*SHR_CONST_PI* & + (hdmlf/450._r8)**0.5_r8))*patch%wtcol(p)/(1._r8 - cropf_col(c)) + else ! for trees + if( gdp_lf(c) > 20._r8 )then + lgdp_col(c) =lgdp_col(c)+cnfire_const%occur_hi_gdp_tree*patch%wtcol(p)/(1._r8 - cropf_col(c)) + lgdp1_col(c) =lgdp1_col(c)+0.62_r8*patch%wtcol(p)/(1._r8 - cropf_col(c)) + else + if( gdp_lf(c) > 8._r8 )then + lgdp_col(c)=lgdp_col(c)+0.79_r8*patch%wtcol(p)/(1._r8 - cropf_col(c)) + lgdp1_col(c)=lgdp1_col(c)+0.83_r8*patch%wtcol(p)/(1._r8 - cropf_col(c)) + else + lgdp_col(c) = lgdp_col(c)+patch%wtcol(p)/(1._r8 - cropf_col(c)) + lgdp1_col(c)=lgdp1_col(c)+patch%wtcol(p)/(1._r8 - cropf_col(c)) + end if + end if + lpop_col(c) = lpop_col(c) + (0.4_r8 + 0.6_r8* & + exp(-1._r8*SHR_CONST_PI* & + (hdmlf/125._r8)))*patch%wtcol(p)/(1._r8 -cropf_col(c)) + end if + end if + else + lgdp_col(c) = lgdp_col(c)+patch%wtcol(p)/(1.0_r8 - cropf_col(c)) + lgdp1_col(c) = lgdp1_col(c)+patch%wtcol(p)/(1.0_r8 -cropf_col(c)) + lpop_col(c) = lpop_col(c)+patch%wtcol(p)/(1.0_r8 -cropf_col(c)) + end if + + fd_col(c) = fd_col(c) + fd_pft(patch%itype(p)) * patch%wtcol(p) * secsphr / (1.0_r8-cropf_col(c)) + end if + end do + + ! estimate annual decreased fractional coverage of BET+BDT + ! land cover conversion in CLM4.5 is the same for each timestep except for the beginning + + if (transient_landcover) then + do fc = 1,num_soilc + c = filter_soilc(fc) + if( dtrotr_col(c) > 0._r8 )then + if( kmo == 1 .and. kda == 1 .and. mcsec == 0)then + lfc(c) = 0._r8 + end if + if( kmo == 1 .and. kda == 1 .and. mcsec == dt)then + lfc(c) = dtrotr_col(c)*dayspyr*secspday/dt + end if + else + lfc(c)=0._r8 + end if + end do + end if + ! + ! calculate burned area fraction in cropland + ! + do fc = 1,num_soilc + c = filter_soilc(fc) + baf_crop(c)=0._r8 + end do + + do fp = 1,num_soilp + p = filter_soilp(fp) + if( kmo == 1 .and. kda == 1 .and. mcsec == 0 )then + burndate(p) = 10000 ! init. value; actual range [0 365] + end if + end do + + do fp = 1, num_soilp + p = filter_soilp(fp) + c = patch%column(p) + g = col%gridcell(c) + + ! For crop + if( forc_t(c) >= SHR_CONST_TKFRZ .and. patch%itype(p) > nc4_grass .and. & + kmo == abm_lf(c) .and. & + burndate(p) >= 999 .and. patch%wtcol(p) > 0._r8 )then ! catch crop burn time + + hdmlf = this%forc_hdm(g) + + ! calculate human density impact on ag. fire + fhd = 0.04_r8+0.96_r8*exp(-1._r8*SHR_CONST_PI*(hdmlf/350._r8)**0.5_r8) + + ! calculate impact of GDP on ag. fire + fgdp = 0.01_r8+0.99_r8*exp(-1._r8*SHR_CONST_PI*(gdp_lf(c)/10._r8)) + + ! calculate burned area + fb = max(0.0_r8,min(1.0_r8,(fuelc_crop(c)-lfuel)/(ufuel-lfuel))) + + ! crop fire only for generic crop types at this time + ! managed crops are treated as grasses if crop model is turned on + baf_crop(c) = baf_crop(c) + cropfire_a1/secsphr*fhd*fgdp*patch%wtcol(p) + if( fb*fhd*fgdp*patch%wtcol(p) > 0._r8)then + burndate(p)=kda + end if + end if + end do + ! + ! calculate peatland fire + ! + do fc = 1, num_soilc + c = filter_soilc(fc) + g= col%gridcell(c) + if(grc%latdeg(g) < cnfire_const%borealat )then + baf_peatf(c) = non_boreal_peatfire_c/secsphr*max(0._r8, & + min(1._r8,(4.0_r8-prec60_col(c)*secspday)/ & + 4.0_r8))**2*peatf_lf(c)*(1._r8-fsat(c)) + else + baf_peatf(c) = boreal_peatfire_c/secsphr*exp(-SHR_CONST_PI*(max(wf2(c),0._r8)/0.3_r8))* & + max(0._r8,min(1._r8,(tsoi17(c)-SHR_CONST_TKFRZ)/10._r8))*peatf_lf(c)* & + (1._r8-fsat(c)) + end if + end do + ! + ! calculate other fires + ! + + ! Set the number of timesteps for e-folding. + ! When the simulation has run fewer than this number of steps, + ! re-scale the e-folding time to get a stable early estimate. + + ! find which pool is the cwd pool + i_cwd = 0 + do l = 1, ndecomp_pools + if ( is_cwd(l) ) then + i_cwd = l + endif + end do + + ! + ! begin column loop to calculate fractional area affected by fire + ! + do fc = 1, num_soilc + c = filter_soilc(fc) + g = col%gridcell(c) + hdmlf=this%forc_hdm(g) + nfire(c) = 0._r8 + if( cropf_col(c) < 1._r8 )then + fuelc(c) = totlitc(c)+totvegc(c)-rootc_col(c)-fuelc_crop(c)*cropf_col(c) + if (spinup_state == 2) then + fuelc(c) = fuelc(c) + ((spinup_factor_deadwood - 1._r8)*deadstemc_col(c)) + do j = 1, nlevdecomp + fuelc(c) = fuelc(c)+decomp_cpools_vr(c,j,i_cwd) * dzsoi_decomp(j) * spinup_factor(i_cwd) & + * get_spinup_latitude_term(grc%latdeg(col%gridcell(c))) + end do + else + do j = 1, nlevdecomp + fuelc(c) = fuelc(c)+decomp_cpools_vr(c,j,i_cwd) * dzsoi_decomp(j) + end do + end if + fuelc(c) = fuelc(c)/(1._r8-cropf_col(c)) + fb = max(0.0_r8,min(1.0_r8,(fuelc(c)-lfuel)/(ufuel-lfuel))) + if (trotr1_col(c)+trotr2_col(c)<=0.6_r8) then + afuel =min(1._r8,max(0._r8,(fuelc(c)-2500._r8)/(5000._r8-2500._r8))) + arh=1._r8-max(0._r8, min(1._r8,(forc_rh(g)-rh_low)/(rh_hgh-rh_low))) + arh30=1._r8-max(cnfire_params%prh30, min(1._r8,rh30_col(c)/90._r8)) + if (forc_rh(g) < rh_hgh.and. wtlf(c) > 0._r8 .and. tsoi17(c)> SHR_CONST_TKFRZ)then + fire_m = ((afuel*arh30+(1._r8-afuel)*arh)**1.5_r8) & + *((1._r8-btran_col(c)/wtlf(c))**0.5_r8) + else + fire_m = 0._r8 + end if + lh = pot_hmn_ign_counts_alpha*6.8_r8*hdmlf**(0.43_r8)/30._r8/24._r8 + fs = 1._r8-(0.01_r8+0.98_r8*exp(-0.025_r8*hdmlf)) + ig = (lh+this%forc_lnfm(g)/(5.16_r8+2.16_r8* & + cos(SHR_CONST_PI/180._r8*3*min(60._r8,abs(grc%latdeg(g)))))* & + cnfire_params%ignition_efficiency)*(1._r8-fs)*(1._r8-cropf_col(c)) + nfire(c) = ig/secsphr*fb*fire_m*lgdp_col(c) !fire counts/km2/sec + Lb_lf = 1._r8+10._r8*(1._r8-EXP(-0.06_r8*forc_wind(g))) + spread_m = fire_m**0.5_r8 + farea_burned(c) = min(1._r8,(cnfire_const%g0*spread_m*fsr_col(c)* & + fd_col(c)/1000._r8)**2*lgdp1_col(c)* & + lpop_col(c)*nfire(c)*SHR_CONST_PI*Lb_lf+ & + baf_crop(c)+baf_peatf(c)) ! fraction (0-1) per sec + else + farea_burned(c)=min(1._r8,baf_crop(c)+baf_peatf(c)) + end if + ! + ! if landuse change data is used, calculate deforestation fires and + ! add it in the total of burned area fraction + ! + if (transient_landcover) then + if( trotr1_col(c)+trotr2_col(c) > 0.6_r8 )then + if(( kmo == 1 .and. kda == 1 .and. mcsec == 0) .or. & + dtrotr_col(c) <=0._r8 )then + fbac1(c) = 0._r8 + farea_burned(c) = baf_crop(c)+baf_peatf(c) + else + cri = (4.0_r8*trotr1_col(c)+1.8_r8*trotr2_col(c))/(trotr1_col(c)+trotr2_col(c)) + cli = (max(0._r8,min(1._r8,(cri-prec60_col(c)*secspday)/cri))**0.5)* & + (max(0._r8,min(1._r8,(cri-prec10_col(c)*secspday)/cri))**0.5)* & + (15._r8*min(0.0016_r8,dtrotr_col(c)/dt*dayspyr*secspday)+0.009_r8)* & + max(0._r8,min(1._r8,(0.25_r8-(forc_rain(c)+forc_snow(c))*secsphr)/0.25_r8)) + farea_burned(c) = fb*cli*(cli_scale/secspday)+baf_crop(c)+baf_peatf(c) + ! burned area out of conversion region due to land use fire + fbac1(c) = max(0._r8,fb*cli*(cli_scale/secspday) - 2.0_r8*lfc(c)/dt) + end if + ! total burned area out of conversion + fbac(c) = fbac1(c)+baf_crop(c)+baf_peatf(c) + else + fbac(c) = farea_burned(c) + end if + end if + + else + farea_burned(c) = min(1._r8,baf_crop(c)+baf_peatf(c)) + end if + + end do ! end of column loop + + end associate + + end subroutine CNFireArea + +end module CNFireLi2024Mod From 5b95a3e6a658e20e80b3869df823c81636067304 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Wed, 7 Aug 2024 13:06:36 -0600 Subject: [PATCH 02/11] Fix bugs and develop crop fire modeling In the CNFireLi2024Mod.F90, (1) fixed the bug described in https://github.com/ESCOMP/CTSM/issues/2566 to avoid incorrect accumulation of baf_crop and ensure that crop fires do not occur during the crop growing season; (2) confined crop fires to periods after harvest and before planting when crop module is active; (3) removed the dependency of baf_crop on fuel availability; (4) improved the modeling of the influence of socio-economic factors on crop burned area; (5) recalibrated the cropfire_a1 constant based on GFED5 crop burned area; (6) modify the declaration of CNFireArea in these F90 files to include the variable crop_inst, declare the variable crop_inst, and import and utilize crop_type from the module CropType. In addition, the modules CNDriverMod.F90, CNFireLi2014Mod.F90, CNFireLi2016Mod.F90, CNFireLi2021Mod.F90, CNFireNoFireMod.F90, FATESFireBase.F90, and FireMethodType.F90 include the subroutine CNFireArea. (6) is implemented in these modules. (Original commit by Fang Li, lifang@mail.iap.ac.cn.) --- src/biogeochem/CNDriverMod.F90 | 2 +- src/biogeochem/CNFireLi2014Mod.F90 | 4 +++- src/biogeochem/CNFireLi2016Mod.F90 | 4 +++- src/biogeochem/CNFireLi2021Mod.F90 | 4 +++- src/biogeochem/CNFireLi2024Mod.F90 | 26 +++++++++++++------------- src/biogeochem/CNFireNoFireMod.F90 | 4 +++- src/biogeochem/FATESFireBase.F90 | 5 ++++- src/main/FireMethodType.F90 | 4 +++- 8 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index b23019eb23..ee97bcc360 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -936,7 +936,7 @@ subroutine CNDriverNoLeaching(bounds, num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, waterdiagnosticbulk_inst, wateratm2lndbulk_inst, & waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, & + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, & totlitc_col=soilbiogeochem_carbonstate_inst%totlitc_col(begc:endc), & decomp_cpools_vr_col=soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools), & t_soi17cm_col=temperature_inst%t_soi17cm_col(begc:endc)) diff --git a/src/biogeochem/CNFireLi2014Mod.F90 b/src/biogeochem/CNFireLi2014Mod.F90 index 6ea21a530b..cb41230a10 100644 --- a/src/biogeochem/CNFireLi2014Mod.F90 +++ b/src/biogeochem/CNFireLi2014Mod.F90 @@ -87,7 +87,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, waterdiagnosticbulk_inst, & wateratm2lndbulk_inst, waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area @@ -98,6 +98,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ use pftconMod , only: nc4_grass, nc3crop, ndllf_evr_tmp_tree use pftconMod , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, nbrdlf_evr_shrub use dynSubgridControlMod , only: run_has_transient_landcover + use CropType , only: crop_type ! ! !ARGUMENTS: class(cnfire_li2014_type) :: this @@ -120,6 +121,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/biogeochem/CNFireLi2016Mod.F90 b/src/biogeochem/CNFireLi2016Mod.F90 index 7bbb183860..6021901a28 100644 --- a/src/biogeochem/CNFireLi2016Mod.F90 +++ b/src/biogeochem/CNFireLi2016Mod.F90 @@ -89,7 +89,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, waterdiagnosticbulk_inst, & wateratm2lndbulk_inst, waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area @@ -101,6 +101,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ use pftconMod , only: nc4_grass, nc3crop, ndllf_evr_tmp_tree use pftconMod , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, nbrdlf_evr_shrub use dynSubgridControlMod , only : run_has_transient_landcover + use CropType , only: crop_type ! ! !ARGUMENTS: class(cnfire_li2016_type) :: this @@ -123,6 +124,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/biogeochem/CNFireLi2021Mod.F90 b/src/biogeochem/CNFireLi2021Mod.F90 index 86d5cc235d..74f553eb5c 100644 --- a/src/biogeochem/CNFireLi2021Mod.F90 +++ b/src/biogeochem/CNFireLi2021Mod.F90 @@ -89,7 +89,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, waterdiagnosticbulk_inst, & wateratm2lndbulk_inst, waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area @@ -101,6 +101,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ use pftconMod , only: nc4_grass, nc3crop, ndllf_evr_tmp_tree use pftconMod , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, nbrdlf_evr_shrub use dynSubgridControlMod , only : run_has_transient_landcover + use CropType , only: crop_type ! ! !ARGUMENTS: class(cnfire_li2021_type) :: this @@ -123,6 +124,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/biogeochem/CNFireLi2024Mod.F90 b/src/biogeochem/CNFireLi2024Mod.F90 index 9908732018..6d3bf6657a 100644 --- a/src/biogeochem/CNFireLi2024Mod.F90 +++ b/src/biogeochem/CNFireLi2024Mod.F90 @@ -89,7 +89,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, & atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, waterdiagnosticbulk_inst, & wateratm2lndbulk_inst, waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area @@ -97,10 +97,11 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ ! !USES: use clm_time_manager , only: get_step_size_real, get_curr_days_per_year, get_curr_date, get_nstep use clm_varcon , only: secspday, secsphr - use clm_varctl , only: spinup_state + use clm_varctl , only: spinup_state, use_crop use pftconMod , only: nc4_grass, nc3crop, ndllf_evr_tmp_tree use pftconMod , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, nbrdlf_evr_shrub use dynSubgridControlMod , only : run_has_transient_landcover + use CropType , only: crop_type ! ! !ARGUMENTS: class(cnfire_li2024_type) :: this @@ -123,6 +124,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) @@ -237,7 +239,8 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ leafc_col => cnveg_carbonstate_inst%leafc_col , & ! Output: [real(r8) (:) ] leaf carbon at column level deadstemc_col => cnveg_carbonstate_inst%deadstemc_col , & ! Output: [real(r8) (:) ] deadstem carbon at column level fuelc => cnveg_carbonstate_inst%fuelc_col , & ! Output: [real(r8) (:) ] fuel load coutside cropland - fuelc_crop => cnveg_carbonstate_inst%fuelc_crop_col & ! Output: [real(r8) (:) ] fuel load for cropland + fuelc_crop => cnveg_carbonstate_inst%fuelc_crop_col , & ! Output: [real(r8) (:) ] fuel load for cropland + croplive => crop_inst%croplive_patch & ! Input: [logical (:) ] flag, true if planted, not harvested ) transient_landcover = run_has_transient_landcover() @@ -522,21 +525,18 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ hdmlf = this%forc_hdm(g) ! calculate human density impact on ag. fire - fhd = 0.04_r8+0.96_r8*exp(-1._r8*SHR_CONST_PI*(hdmlf/350._r8)**0.5_r8) + fhd = 0.2_r8+0.8_r8*exp(-1._r8*SHR_CONST_PI*(hdmlf/400._r8)) ! calculate impact of GDP on ag. fire - fgdp = 0.01_r8+0.99_r8*exp(-1._r8*SHR_CONST_PI*(gdp_lf(c)/10._r8)) + fgdp = 0.05_r8+0.95_r8*exp(-1._r8*SHR_CONST_PI*(gdp_lf(c)/20._r8)) ! calculate burned area - fb = max(0.0_r8,min(1.0_r8,(fuelc_crop(c)-lfuel)/(ufuel-lfuel))) - - ! crop fire only for generic crop types at this time - ! managed crops are treated as grasses if crop model is turned on - baf_crop(c) = baf_crop(c) + cropfire_a1/secsphr*fhd*fgdp*patch%wtcol(p) - if( fb*fhd*fgdp*patch%wtcol(p) > 0._r8)then - burndate(p)=kda + if((use_crop .and. (.not. croplive(p))) & + .or. (.not. use_crop)) then + burndate(p) = kda + baf_crop(c) = baf_crop(c)+0.21_r8 / secsphr * fhd * fgdp * patch%wtcol(p) end if - end if + end if end do ! ! calculate peatland fire diff --git a/src/biogeochem/CNFireNoFireMod.F90 b/src/biogeochem/CNFireNoFireMod.F90 index 0dc1ee39d1..6785faa851 100644 --- a/src/biogeochem/CNFireNoFireMod.F90 +++ b/src/biogeochem/CNFireNoFireMod.F90 @@ -62,13 +62,14 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, & waterdiagnosticbulk_inst, wateratm2lndbulk_inst, & waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area ! ! !USES: use subgridAveMod , only : p2c + use CropType , only : crop_type ! ! !ARGUMENTS: class(cnfire_nofire_type) :: this @@ -91,6 +92,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/biogeochem/FATESFireBase.F90 b/src/biogeochem/FATESFireBase.F90 index a47ff2e8c4..59279d7625 100644 --- a/src/biogeochem/FATESFireBase.F90 +++ b/src/biogeochem/FATESFireBase.F90 @@ -206,7 +206,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, & waterdiagnosticbulk_inst, wateratm2lndbulk_inst, & waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area (NOT USED FOR FATES) @@ -220,6 +220,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ use SoilStateType , only : soilstate_type use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type use atm2lndType , only : atm2lnd_type + use CropType , only: crop_type ! ! !ARGUMENTS: class(fates_fire_base_type) :: this @@ -242,6 +243,8 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst + real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/main/FireMethodType.F90 b/src/main/FireMethodType.F90 index 63c05821b7..978450e65f 100644 --- a/src/main/FireMethodType.F90 +++ b/src/main/FireMethodType.F90 @@ -119,7 +119,7 @@ subroutine CNFireArea_interface (this, bounds, num_soilc, filter_soilc, num_soil atm2lnd_inst, energyflux_inst, saturated_excess_runoff_inst, & waterdiagnosticbulk_inst, wateratm2lndbulk_inst, & waterstatebulk_inst, soilstate_inst, soil_water_retention_curve, & - cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) + crop_inst, cnveg_state_inst, cnveg_carbonstate_inst, totlitc_col, decomp_cpools_vr_col, t_soi17cm_col) ! ! !DESCRIPTION: ! Computes column-level burned area @@ -137,6 +137,7 @@ subroutine CNFireArea_interface (this, bounds, num_soilc, filter_soilc, num_soil use SoilWaterRetentionCurveMod , only : soil_water_retention_curve_type use CNVegStateType , only : cnveg_state_type use CNVegCarbonStateType , only : cnveg_carbonstate_type + use CropType , only : crop_type import :: fire_method_type ! ! !ARGUMENTS: @@ -160,6 +161,7 @@ subroutine CNFireArea_interface (this, bounds, num_soilc, filter_soilc, num_soil class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst + type(crop_type) , intent(in) :: crop_inst real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) From 412bb3e1bb1df35fb2503acf4a86f0256fbaa77e Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Wed, 7 Aug 2024 13:16:09 -0600 Subject: [PATCH 03/11] change the cropfire_a1 to 0.21 in namelist_defaults. (Original commit by Fang Li, lifang@mail.iap.ac.cn.) --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- src/biogeochem/CNFireLi2024Mod.F90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index a7e59935a4..b301bcfb28 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -327,7 +327,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.09d-4 0.010d00 0.17d-3 -1.6d-4 +0.21d00 0.33d00 75.d00 1050.d00 diff --git a/src/biogeochem/CNFireLi2024Mod.F90 b/src/biogeochem/CNFireLi2024Mod.F90 index 6d3bf6657a..503ed28488 100644 --- a/src/biogeochem/CNFireLi2024Mod.F90 +++ b/src/biogeochem/CNFireLi2024Mod.F90 @@ -534,7 +534,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ if((use_crop .and. (.not. croplive(p))) & .or. (.not. use_crop)) then burndate(p) = kda - baf_crop(c) = baf_crop(c)+0.21_r8 / secsphr * fhd * fgdp * patch%wtcol(p) + baf_crop(c) = baf_crop(c)+cropfire_a1 / secsphr * fhd * fgdp * patch%wtcol(p) end if end if end do From 1041a7c93b27dc45a4c1587b02da5c1dac04b7cd Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 8 Aug 2024 11:09:21 -0600 Subject: [PATCH 04/11] Add testmods and tests for all fire methods. --- cime_config/testdefs/testlist_clm.xml | 40 +++++++++++++++++++ .../clm/FireLi2014Qian/include_user_mods | 1 + .../clm/FireLi2014Qian/user_nl_clm | 1 + .../clm/FireLi2016Cru/include_user_mods | 1 + .../clm/FireLi2016Cru/user_nl_clm | 1 + .../clm/FireLi2021GSWP/include_user_mods | 1 + .../clm/FireLi2021GSWP/user_nl_clm | 1 + .../clm/FireLi2024GSWP/include_user_mods | 1 + .../clm/FireLi2024GSWP/user_nl_clm | 1 + 9 files changed, 48 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/user_nl_clm create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/user_nl_clm create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/user_nl_clm create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/user_nl_clm diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 1ac2334ba8..36da30043c 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -3070,5 +3070,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/user_nl_clm new file mode 100644 index 0000000000..3e05de8cad --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2014Qian/user_nl_clm @@ -0,0 +1 @@ +fire_method = 'li2014qianfrc' diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/user_nl_clm new file mode 100644 index 0000000000..eecbd5b2d9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2016Cru/user_nl_clm @@ -0,0 +1 @@ +fire_method = 'li2016crufrc' diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/user_nl_clm new file mode 100644 index 0000000000..8703daf6f8 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2021GSWP/user_nl_clm @@ -0,0 +1 @@ +fire_method = 'li2021gswpfrc' diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/user_nl_clm new file mode 100644 index 0000000000..7926de5891 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FireLi2024GSWP/user_nl_clm @@ -0,0 +1 @@ +fire_method = 'li2024gswpfrc' From b0c986cd9af32e300118eac565acb5582a32ec8d Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 11 Jun 2024 14:45:11 -0600 Subject: [PATCH 05/11] Functionize check_missing_initdata_status(). --- src/main/clm_initializeMod.F90 | 12 +---------- src/main/controlMod.F90 | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 9bf0cc59a2..8b03531000 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -520,17 +520,7 @@ subroutine initialize2(ni,nj) else if (trim(finidat) == trim(finidat_interp_dest)) then ! Check to see if status file for finidat exists - klen = len_trim(finidat_interp_dest) - 3 ! remove the .nc - locfn = finidat_interp_dest(1:klen)//'.status' - inquire(file=trim(locfn), exist=lexists) - if (.not. lexists) then - if (masterproc) then - write(iulog,'(a)')' failed to find file '//trim(locfn) - write(iulog,'(a)')' this indicates a problem in creating '//trim(finidat_interp_dest) - write(iulog,'(a)')' remove '//trim(finidat_interp_dest)//' and try again' - end if - call endrun() - end if + call check_missing_initdata_status(finidat_interp_dest) end if if (masterproc) then write(iulog,'(a)')'Reading initial conditions from file '//trim(finidat) diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index f876e97176..8712e6cf50 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -62,6 +62,7 @@ module controlMod ! ! ! !PRIVATE MEMBER FUNCTIONS: + private :: check_missing_initdata_status ! check for missing finidat_interp_dest .status file private :: apply_use_init_interp ! apply the use_init_interp namelist option, if set ! ! !PRIVATE TYPES: @@ -1220,6 +1221,38 @@ subroutine control_print () end if end subroutine control_print + + !----------------------------------------------------------------------- + subroutine check_missing_initdata_status(finidat_interp_dest) + ! + ! !DESCRIPTION: + ! Checks that the finidat_interp_dest .status file was written (i.e., that write of + ! finidat_interp_dest succeeded) + ! + ! !ARGUMENTS: + character(len=*), intent(in) :: finidat_interp_dest + ! + ! !LOCAL VARIABLES: + logical :: lexists + integer :: klen + character(len=SHR_KIND_CL) :: status_file + character(len=*), parameter :: subname = 'check_missing_initdata_status' + !----------------------------------------------------------------------- + + klen = len_trim(finidat_interp_dest) - 3 ! remove the .nc + status_file = finidat_interp_dest(1:klen)//'.status' + inquire(file=trim(status_file), exist=lexists) + if (.not. lexists) then + if (masterproc) then + write(iulog,'(a)')' failed to find file '//trim(status_file) + write(iulog,'(a)')' this indicates a problem in creating '//trim(finidat_interp_dest) + write(iulog,'(a)')' remove '//trim(finidat_interp_dest)//' and try again' + end if + call endrun(subname//': finidat_interp_dest file exists but is probably bad') + end if + + end subroutine check_missing_initdata_status + !----------------------------------------------------------------------- subroutine apply_use_init_interp(finidat_interp_dest, finidat, finidat_interp_source) @@ -1271,6 +1304,11 @@ subroutine apply_use_init_interp(finidat_interp_dest, finidat, finidat_interp_so inquire(file=trim(finidat_interp_dest), exist=lexists) if (lexists) then + + ! Check that the status file also exists (i.e., that finidat_interp_dest was written successfully) + call check_missing_initdata_status(finidat_interp_dest) + + write(iulog, *) 'ssr apply_use_init_interp: point 3' ! open the input file and check for the name of the input source file status = nf90_open(trim(finidat_interp_dest), 0, ncid) if (status /= nf90_noerr) call handle_err(status) From 4d17ba36020e9740b0090d62027e67374e4368a0 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 11 Jun 2024 14:47:57 -0600 Subject: [PATCH 06/11] Remove troubleshooting printout. --- src/cpl/nuopc/lnd_comp_nuopc.F90 | 1 - src/main/controlMod.F90 | 5 ----- 2 files changed, 6 deletions(-) diff --git a/src/cpl/nuopc/lnd_comp_nuopc.F90 b/src/cpl/nuopc/lnd_comp_nuopc.F90 index 3852a1bf1b..b9c2eeb784 100644 --- a/src/cpl/nuopc/lnd_comp_nuopc.F90 +++ b/src/cpl/nuopc/lnd_comp_nuopc.F90 @@ -626,7 +626,6 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) version_in=model_version, & hostname_in=hostname, & username_in=username) - call initialize1(dtime=dtime_sync) ! --------------------- diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 8712e6cf50..e3badbd7bd 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -571,7 +571,6 @@ subroutine control_init(dtime) ! ---------------------------------------------------------------------- ! Read in other namelists for other modules ! ---------------------------------------------------------------------- - call mpi_bcast (use_init_interp, 1, MPI_LOGICAL, 0, mpicom, ierr) if (use_init_interp) then call initInterp_readnl( NLFilename ) @@ -581,7 +580,6 @@ subroutine control_init(dtime) !For future version, I suggest to put the following two calls inside their !own modules, which are called from their own initializing methods call init_hydrology( NLFilename ) - call soil_resistance_readnl ( NLFilename ) call CanopyFluxesReadNML ( NLFilename ) call CanopyHydrology_readnl ( NLFilename ) @@ -594,7 +592,6 @@ subroutine control_init(dtime) ! ---------------------------------------------------------------------- ! Broadcast all control information if appropriate ! ---------------------------------------------------------------------- - call control_spmd() ! ---------------------------------------------------------------------- @@ -1307,8 +1304,6 @@ subroutine apply_use_init_interp(finidat_interp_dest, finidat, finidat_interp_so ! Check that the status file also exists (i.e., that finidat_interp_dest was written successfully) call check_missing_initdata_status(finidat_interp_dest) - - write(iulog, *) 'ssr apply_use_init_interp: point 3' ! open the input file and check for the name of the input source file status = nf90_open(trim(finidat_interp_dest), 0, ncid) if (status /= nf90_noerr) call handle_err(status) From 1a79cdb474eb5fe68cc2e7cd4529522a5c2ad818 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 11 Jun 2024 14:52:38 -0600 Subject: [PATCH 07/11] Final cleanup. --- src/cpl/nuopc/lnd_comp_nuopc.F90 | 1 + src/main/controlMod.F90 | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cpl/nuopc/lnd_comp_nuopc.F90 b/src/cpl/nuopc/lnd_comp_nuopc.F90 index b9c2eeb784..3852a1bf1b 100644 --- a/src/cpl/nuopc/lnd_comp_nuopc.F90 +++ b/src/cpl/nuopc/lnd_comp_nuopc.F90 @@ -626,6 +626,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) version_in=model_version, & hostname_in=hostname, & username_in=username) + call initialize1(dtime=dtime_sync) ! --------------------- diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index e3badbd7bd..c7025c5718 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -571,6 +571,7 @@ subroutine control_init(dtime) ! ---------------------------------------------------------------------- ! Read in other namelists for other modules ! ---------------------------------------------------------------------- + call mpi_bcast (use_init_interp, 1, MPI_LOGICAL, 0, mpicom, ierr) if (use_init_interp) then call initInterp_readnl( NLFilename ) @@ -580,6 +581,7 @@ subroutine control_init(dtime) !For future version, I suggest to put the following two calls inside their !own modules, which are called from their own initializing methods call init_hydrology( NLFilename ) + call soil_resistance_readnl ( NLFilename ) call CanopyFluxesReadNML ( NLFilename ) call CanopyHydrology_readnl ( NLFilename ) @@ -592,6 +594,7 @@ subroutine control_init(dtime) ! ---------------------------------------------------------------------- ! Broadcast all control information if appropriate ! ---------------------------------------------------------------------- + call control_spmd() ! ---------------------------------------------------------------------- @@ -1218,7 +1221,7 @@ subroutine control_print () end if end subroutine control_print - + !----------------------------------------------------------------------- subroutine check_missing_initdata_status(finidat_interp_dest) ! @@ -1302,8 +1305,9 @@ subroutine apply_use_init_interp(finidat_interp_dest, finidat, finidat_interp_so inquire(file=trim(finidat_interp_dest), exist=lexists) if (lexists) then - ! Check that the status file also exists (i.e., that finidat_interp_dest was written successfully) - call check_missing_initdata_status(finidat_interp_dest) + ! Check that the status file also exists (i.e., that finidat_interp_dest was written successfully) + call check_missing_initdata_status(finidat_interp_dest) + ! open the input file and check for the name of the input source file status = nf90_open(trim(finidat_interp_dest), 0, ncid) if (status /= nf90_noerr) call handle_err(status) From 5e7e5b591d627e13854245f82a7e7b7246981f38 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Tue, 11 Jun 2024 15:08:10 -0600 Subject: [PATCH 08/11] Add a missing use statement. --- src/main/clm_initializeMod.F90 | 2 +- src/main/controlMod.F90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 8b03531000..6e80869833 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -174,7 +174,7 @@ subroutine initialize2(ni,nj) use SatellitePhenologyMod , only : SatellitePhenologyInit, readAnnualVegetation, interpMonthlyVeg, SatellitePhenology use SnowSnicarMod , only : SnowAge_init, SnowOptics_init use lnd2atmMod , only : lnd2atm_minimal - use controlMod , only : NLFilename + use controlMod , only : NLFilename, check_missing_initdata_status use clm_instMod , only : clm_fates use BalanceCheckMod , only : BalanceCheckInit use CNSharedParamsMod , only : CNParamsSetSoilDepth diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index c7025c5718..1af68b0af6 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -59,10 +59,10 @@ module controlMod public :: control_setNL ! Set namelist filename public :: control_init ! initial run control information public :: control_print ! print run control information + public :: check_missing_initdata_status ! check for missing finidat_interp_dest .status file ! ! ! !PRIVATE MEMBER FUNCTIONS: - private :: check_missing_initdata_status ! check for missing finidat_interp_dest .status file private :: apply_use_init_interp ! apply the use_init_interp namelist option, if set ! ! !PRIVATE TYPES: From ea69fffb308e4d132c184d4a5fe5e95f133d7b00 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Mon, 12 Aug 2024 08:52:34 -0600 Subject: [PATCH 09/11] Remove broken assign-to-project workflow. --- .github/workflows/assign-to-project.yml | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .github/workflows/assign-to-project.yml diff --git a/.github/workflows/assign-to-project.yml b/.github/workflows/assign-to-project.yml deleted file mode 100644 index 225c223bde..0000000000 --- a/.github/workflows/assign-to-project.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Auto Assign to Project(s) - -on: - issues: - types: [opened, labeled] - pull_request: - types: [opened, labeled] - issue_comment: - types: [created] - -jobs: - assign_high_priority: - runs-on: ubuntu-latest - name: Assign to High Priority project - steps: - - name: Assign issues and pull requests with priority-high label to project 25 - uses: srggrs/assign-one-project-github-action@1.3.1 - if: | - contains(github.event.issue.labels.*.name, 'priority: high') || - contains(github.event.pull_request.labels.*.name, 'priority: high') - with: - project: 'https://github.com/ESCOMP/CTSM/projects/25' - column_name: 'Needs triage' From 2797829a586b13ba9db4f7266d33e034d60c7976 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Mon, 12 Aug 2024 11:12:21 -0600 Subject: [PATCH 10/11] Add comment explaining dummy use of crop_inst. --- src/biogeochem/CNFireLi2014Mod.F90 | 2 +- src/biogeochem/CNFireLi2016Mod.F90 | 2 +- src/biogeochem/CNFireLi2021Mod.F90 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/biogeochem/CNFireLi2014Mod.F90 b/src/biogeochem/CNFireLi2014Mod.F90 index a11e9d5edc..fcd27a7951 100644 --- a/src/biogeochem/CNFireLi2014Mod.F90 +++ b/src/biogeochem/CNFireLi2014Mod.F90 @@ -122,7 +122,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(crop_type) , intent(in) :: crop_inst + type(crop_type) , intent(in) :: crop_inst ! Dummy argument; not used in this version of CNFireArea real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/biogeochem/CNFireLi2016Mod.F90 b/src/biogeochem/CNFireLi2016Mod.F90 index 6021901a28..955d7fe398 100644 --- a/src/biogeochem/CNFireLi2016Mod.F90 +++ b/src/biogeochem/CNFireLi2016Mod.F90 @@ -124,7 +124,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(crop_type) , intent(in) :: crop_inst + type(crop_type) , intent(in) :: crop_inst ! Dummy argument; not used in this version of CNFireArea real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) diff --git a/src/biogeochem/CNFireLi2021Mod.F90 b/src/biogeochem/CNFireLi2021Mod.F90 index 74f553eb5c..6d504a1e26 100644 --- a/src/biogeochem/CNFireLi2021Mod.F90 +++ b/src/biogeochem/CNFireLi2021Mod.F90 @@ -124,7 +124,7 @@ subroutine CNFireArea (this, bounds, num_soilc, filter_soilc, num_soilp, filter_ class(soil_water_retention_curve_type), intent(in) :: soil_water_retention_curve type(cnveg_state_type) , intent(inout) :: cnveg_state_inst type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst - type(crop_type) , intent(in) :: crop_inst + type(crop_type) , intent(in) :: crop_inst ! Dummy argument; not used in this version of CNFireArea real(r8) , intent(in) :: totlitc_col(bounds%begc:) real(r8) , intent(in) :: decomp_cpools_vr_col(bounds%begc:,1:,1:) real(r8) , intent(in) :: t_soi17cm_col(bounds%begc:) From 4f56ffcbbdd1d841de9edf5f67e625428282073d Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Fri, 16 Aug 2024 11:09:17 -0600 Subject: [PATCH 11/11] Update ChangeLog and ChangeSum. --- doc/ChangeLog | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 76 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index 5850069532..7a6d764c14 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,79 @@ =============================================================== +Tag name: ctsm5.2.023 +Originator(s): samrabin (Sam Rabin, UCAR/TSS, samrabin@ucar.edu) +Date: Fri Aug 16 11:00:32 MDT 2024 +One-line Summary: Merge b4b-dev + +Purpose and description of changes +---------------------------------- + +Brings in 3 PRs from b4b-dev to master: +- Always check finidat_interp_dest.status (ESCOMP/CTSM#2679; Sam Rabin) +- Remove broken assign-to-project Github workflow (ESCOMP/CTSM#2683; Sam Rabin) +- [Fang summer '24 PR 1.1] Fix bugs and develop crop fire modeling (ESCOMP/CTSM#2684; Fang Li and Sam Rabin) + + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + +[ ] clm6_0 + +[ ] clm5_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- + +List of CTSM issues fixed: +- Resolves ESCOMP/CTSM#2562: Fix or disable "Assign to High Priority project" workflow +- Resolves ESCOMP/CTSM#2566: bug in crop fire modeling +- Resolves ESCOMP/CTSM#2596: Check of finidat_interp_dest.status isn't reached + +Notes of particular relevance for users +--------------------------------------- + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): +- Adds new fire_method option li2024gswpfrc; default hasn't changed. + + +Notes of particular relevance for developers: +--------------------------------------------- +NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide + +Changes to tests or testing: Adds 4 tests: +- SMS_D_Ld65.f10_f10_mg37.I2000Clm50BgcCru.derecho_gnu.clm-FireLi2016Cru +- SMS_D_Ld65.f10_f10_mg37.I2000Clm45BgcCropQianRs.derecho_intel.clm-FireLi2014Qian +- SMS_D_Ld65.f10_f10_mg37.I2000Clm50BgcCrop.izumi_intel.clm-FireLi2021GSWP +- SMS_D_Ld65.f10_f10_mg37.I2000Clm60BgcCrop.izumi_nag.clm-FireLi2024GSWP + +Testing summary: +---------------- + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Other details +------------- + +Pull Requests that document the changes: +- Always check finidat_interp_dest.status (ESCOMP/CTSM#2679; Sam Rabin): https://github.com/ESCOMP/CTSM/pull/2679 +- Remove broken assign-to-project Github workflow (ESCOMP/CTSM#2683; Sam Rabin): https://github.com/ESCOMP/CTSM/pull/2683 +- [Fang summer '24 PR 1.1] Fix bugs and develop crop fire modeling (ESCOMP/CTSM#2684; Fang Li and Sam Rabin): https://github.com/ESCOMP/CTSM/pull/2684 + + +=============================================================== +=============================================================== Tag name: ctsm5.2.022 Originator(s): samrabin (Sam Rabin, UCAR/TSS, samrabin@ucar.edu) Date: Wed Aug 14 12:24:27 MDT 2024 diff --git a/doc/ChangeSum b/doc/ChangeSum index 61bf4985de..176ac066d2 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.2.023 samrabin 08/16/2024 Merge b4b-dev ctsm5.2.022 samrabin 08/14/2024 Rework crop_calendars suite and cropMonthOutput ctsm5.2.021 rgknox 08/13/2024 Adding on-the-fly parameter settings for prescribed N and P in FATES ctsm5.2.020 slevis 08/12/2024 MEGAN updates (MEGAN-CLM6)