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' diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index c4c056195d..167ded8c62 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -351,6 +351,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 +0.21d00 +0.33d00 +75.d00 +1050.d00 +0.5d00 +0.28d00 + .false. .true. @@ -504,10 +519,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/ctsm60_params.c240208.nc -lnd/clm2/paramdata/ctsm51_params.c240208.nc -lnd/clm2/paramdata/clm50_params.c240208.nc -lnd/clm2/paramdata/clm45_params.c240208.nc +lnd/clm2/paramdata/ctsm60_params.c240814.nc +lnd/clm2/paramdata/ctsm51_params.c240814.nc +lnd/clm2/paramdata/clm50_params.c240814.nc +lnd/clm2/paramdata/clm45_params.c240814.nc diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 4c80f78fd3..4cc50da391 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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' diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm index 3c686f08b9..3462b802c7 100644 --- a/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/ciso_cwd_hr/user_nl_clm @@ -1,2 +1,2 @@ -paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm51_ciso_cwd_hr_params.c240208.nc' +paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm51_ciso_cwd_hr_params.c240814.nc' hist_fincl1 = 'CWDC_HR','C13_CWDC_HR','C14_CWDC_HR','CWD_HR_L2','CWD_HR_L2_vr','CWD_HR_L3','CWD_HR_L3_vr' diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm index df20ced9e8..4bfc0520f8 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm @@ -1,2 +1,2 @@ use_soil_matrixcn = .true. -paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_params_cn30.c240625.nc' +paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_params_cn30.c240814.nc' 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) diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index c5deb1e86a..0274fcc87f 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -922,7 +922,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/CNFUNMod.F90 b/src/biogeochem/CNFUNMod.F90 index dde666c1f7..a6614fe4b9 100644 --- a/src/biogeochem/CNFUNMod.F90 +++ b/src/biogeochem/CNFUNMod.F90 @@ -53,7 +53,6 @@ module CNFUNMod public:: CNFUN ! Run FUN type, private :: params_type - real(r8) :: ndays_on ! number of days to complete leaf onset real(r8) :: ndays_off ! number of days to complete leaf offset end type params_type @@ -64,7 +63,6 @@ module CNFUNMod ! ! !PRIVATE DATA MEMBERS: real(r8) :: dt ! decomp timestep (seconds) - real(r8) :: ndays_on ! number of days to complete onset real(r8) :: ndays_off ! number of days to complete offset integer, private, parameter :: COST_METHOD = 2 !new way of doing the N uptake @@ -104,11 +102,6 @@ subroutine readParams ( ncid ) ! read in parameters - tString='ndays_on' - call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) - if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) - params_inst%ndays_on=tempr - tString='ndays_off' call ncd_io(varname=trim(tString),data=tempr, flag='read', ncid=ncid, readvar=readv) if ( .not. readv ) call endrun( msg=trim(errCode)//trim(tString)//errMsg(sourcefile, __LINE__)) @@ -172,7 +165,6 @@ subroutine CNFUNInit (bounds,cnveg_state_inst,cnveg_carbonstate_inst,cnveg_nitro timestep_fun = real(secspday * fun_period) nstep_fun = int(secspday * dayspyr / dt) - ndays_on = params_inst%ndays_on ndays_off = params_inst%ndays_off !-------------------------------------------------------------------- diff --git a/src/biogeochem/CNFireFactoryMod.F90 b/src/biogeochem/CNFireFactoryMod.F90 index dbd9b70d15..876e28a5e3 100644 --- a/src/biogeochem/CNFireFactoryMod.F90 +++ b/src/biogeochem/CNFireFactoryMod.F90 @@ -95,6 +95,7 @@ subroutine create_cnfire_method( NLFilename, cnfire_method ) use CNFireLi2014Mod , only : cnfire_li2014_type use CNFireLi2016Mod , only : cnfire_li2016_type use CNFireLi2021Mod , only : cnfire_li2021_type + use CNFireLi2024Mod , only : cnfire_li2024_type use decompMod , only : bounds_type ! ! !ARGUMENTS: @@ -115,6 +116,8 @@ subroutine create_cnfire_method( NLFilename, cnfire_method ) allocate(cnfire_li2016_type :: cnfire_method) case ("li2021gswpfrc") allocate(cnfire_li2021_type :: cnfire_method) + case ("li2024gswpfrc") + allocate(cnfire_li2024_type :: cnfire_method) case default write(iulog,*) subname//' ERROR: unknown method: ', fire_method diff --git a/src/biogeochem/CNFireLi2014Mod.F90 b/src/biogeochem/CNFireLi2014Mod.F90 index 6bfa17a143..fcd27a7951 100644 --- a/src/biogeochem/CNFireLi2014Mod.F90 +++ b/src/biogeochem/CNFireLi2014Mod.F90 @@ -88,7 +88,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 @@ -99,6 +99,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 @@ -121,6 +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 ! 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 7bbb183860..955d7fe398 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 ! 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 86d5cc235d..6d504a1e26 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 ! 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/CNFireLi2024Mod.F90 b/src/biogeochem/CNFireLi2024Mod.F90 new file mode 100644 index 0000000000..503ed28488 --- /dev/null +++ b/src/biogeochem/CNFireLi2024Mod.F90 @@ -0,0 +1,658 @@ +module CNFireLi2024Mod + +#include "shr_assert.h" + + !----------------------------------------------------------------------- + ! !DESCRIPTION: + ! module for fire dynamics + ! created in Nov, 2012 and revised in Apr, 2013 by F. Li and S. Levis + ! based on Li et al. (2012a,b; 2013) + ! revised in Apr, 2014 according to Li et al.(2014) + ! revised in May, 2015, according to Li et al. (2015, in prep.) + ! Fire-related parameters were calibrated or tuned in May, 2015 based on the + ! 20th Century transient simulations at f19_g16 with a CLM4.5 version + ! (clm50fire), CRUNCEPv5, and climatological lightning data. + ! + ! !USES: + use shr_kind_mod , only : r8 => 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, & + 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 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_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 + 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 + 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:) + ! + ! !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 + croplive => crop_inst%croplive_patch & ! Input: [logical (:) ] flag, true if planted, not harvested + ) + + 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.2_r8+0.8_r8*exp(-1._r8*SHR_CONST_PI*(hdmlf/400._r8)) + + ! calculate impact of GDP on ag. fire + fgdp = 0.05_r8+0.95_r8*exp(-1._r8*SHR_CONST_PI*(gdp_lf(c)/20._r8)) + + ! calculate burned area + if((use_crop .and. (.not. croplive(p))) & + .or. (.not. use_crop)) then + burndate(p) = kda + baf_crop(c) = baf_crop(c)+cropfire_a1 / secsphr * fhd * fgdp * patch%wtcol(p) + 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 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/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90 index 2ce7f029da..73eadbb1a9 100644 --- a/src/biogeochem/CNPhenologyMod.F90 +++ b/src/biogeochem/CNPhenologyMod.F90 @@ -94,7 +94,6 @@ module CNPhenologyMod real(r8) :: crit_dayl_lat_slope ! Slope of time for critical day length with latitude (sec/deg) ! (Birch et. all 2021 it was 720 see line below) ! 15hr-11hr/(65N-45N)=linear slope = 720 min/latitude (Birch et. al 2021) - real(r8) :: ndays_on ! number of days to complete leaf onset real(r8) :: ndays_off ! number of days to complete leaf offset real(r8) :: fstor2tran ! fraction of storage to move to transfer for each onset real(r8) :: crit_onset_fdd ! critical number of freezing days to set gdd counter @@ -113,7 +112,6 @@ module CNPhenologyMod real(r8) :: dt ! time step delta t (seconds) real(r8) :: fracday ! dtime as a fraction of day real(r8) :: crit_dayl ! critical daylength for offset (seconds) - real(r8) :: ndays_on ! number of days to complete onset real(r8) :: ndays_off ! number of days to complete offset real(r8) :: fstor2tran ! fraction of storage to move to transfer on each onset real(r8) :: crit_onset_fdd ! critical number of freezing days @@ -279,7 +277,6 @@ subroutine CNPhenologySetParams( ) params_inst%crit_dayl = 39200._r8 ! Seconds params_inst%crit_dayl_at_high_lat = 54000._r8 ! Seconds params_inst%crit_dayl_lat_slope = 720._r8 ! Seconds / degree - params_inst%ndays_on = 15._r8 ! Days params_inst%ndays_off = 30._r8 ! Days params_inst%fstor2tran = 0.5 ! Fraction params_inst%crit_onset_fdd = 15._r8 ! Days @@ -313,7 +310,6 @@ subroutine readParams ( ncid ) call readNcdioScalar(ncid, 'crit_dayl', subname, params_inst%crit_dayl) call readNcdioScalar(ncid, 'crit_dayl_at_high_lat', subname, params_inst%crit_dayl_at_high_lat) call readNcdioScalar(ncid, 'crit_dayl_lat_slope', subname, params_inst%crit_dayl_lat_slope) - call readNcdioScalar(ncid, 'ndays_on', subname, params_inst%ndays_on) call readNcdioScalar(ncid, 'ndays_off', subname, params_inst%ndays_off) call readNcdioScalar(ncid, 'fstor2tran', subname, params_inst%fstor2tran) call readNcdioScalar(ncid, 'crit_onset_fdd', subname, params_inst%crit_onset_fdd) @@ -474,7 +470,6 @@ subroutine CNPhenologyInit(bounds) crit_dayl=params_inst%crit_dayl ! Set constants for CNSeasonDecidPhenology and CNStressDecidPhenology - ndays_on=params_inst%ndays_on ndays_off=params_inst%ndays_off ! set transfer parameters @@ -885,6 +880,8 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & woody => pftcon%woody , & ! Input: binary flag for woody lifeform (1=woody, 0=not woody) season_decid => pftcon%season_decid , & ! Input: binary flag for seasonal-deciduous leaf habit (0 or 1) season_decid_temperate => pftcon%season_decid_temperate , & ! Input: binary flag for seasonal-deciduous temperate leaf habit (0 or 1) + crit_onset_gdd_sf => pftcon%crit_onset_gdd_sf , & ! Input: scale factor for crit_onset_gdd (unitless) + ndays_on => pftcon%ndays_on , & ! Input: number of days to complete leaf onset (days t_soisno => temperature_inst%t_soisno_col , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) soila10 => temperature_inst%soila10_col , & ! Input: [real(r8) (:) ] @@ -1019,7 +1016,8 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & lgsf(p) = 0._r8 ! onset gdd sum from Biome-BGC, v4.1.2 - crit_onset_gdd = exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) - SHR_CONST_TKFRZ)) + crit_onset_gdd = crit_onset_gdd_sf(ivt(p)) * exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) & + - SHR_CONST_TKFRZ)) ! set flag for solstice period (winter->summer = 1, summer->winter = 0) if (dayl(g) >= prev_dayl(g)) then @@ -1112,7 +1110,8 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & onset_gddflag(p) = 0.0_r8 onset_gdd(p) = 0.0_r8 do_onset = .false. - onset_counter(p) = ndays_on * secspday + onset_counter(p) = ndays_on(ivt(p)) * secspday + ! move all the storage pools into transfer pools, ! where they will be transfered to displayed growth over the onset period. @@ -1402,7 +1401,10 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & stress_decid => pftcon%stress_decid , & ! Input: binary flag for stress-deciduous leaf habit (0 or 1) leafcn => pftcon%leafcn , & ! Input: leaf C:N (gC/gN) frootcn => pftcon%frootcn , & ! Input: fine root C:N (gC/gN) - + + crit_onset_gdd_sf => pftcon%crit_onset_gdd_sf , & ! Input: scale factor for crit_onset_gdd (unitless) + ndays_on => pftcon%ndays_on , & ! Input: number of days to complete leaf onset (days) + soilpsi => soilstate_inst%soilpsi_col , & ! Input: [real(r8) (:,:) ] soil water potential in each soil layer (MPa) t_soisno => temperature_inst%t_soisno_col , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd) @@ -1535,8 +1537,8 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & psi = soilpsi(c, phenology_soil_layer) ! onset gdd sum from Biome-BGC, v4.1.2 - crit_onset_gdd = exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) - SHR_CONST_TKFRZ)) - + crit_onset_gdd = crit_onset_gdd_sf(ivt(p)) * exp(4.8_r8 + 0.13_r8*(annavg_t2m(p) & + - SHR_CONST_TKFRZ)) ! update offset_counter and test for the end of the offset period if (offset_flag(p) == 1._r8) then @@ -1676,7 +1678,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & onset_fdd(p) = 0._r8 onset_gdd(p) = 0._r8 onset_swi(p) = 0._r8 - onset_counter(p) = ndays_on * secspday + onset_counter(p) = ndays_on(ivt(p)) * secspday ! call subroutine to move all the storage pools into transfer pools, ! where they will be transfered to displayed growth over the onset period. 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:) diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 0c0570c577..340a799908 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 @@ -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 0b4366a0cb..f65c8c7f47 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -59,6 +59,7 @@ 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: @@ -1218,6 +1219,38 @@ subroutine control_print () 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) ! @@ -1268,6 +1301,10 @@ 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) + ! 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) diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index b91c3439aa..64383e7a7c 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -47,6 +47,8 @@ module initVerticalMod type, private :: params_type real(r8) :: slopebeta ! exponent for microtopography pdf sigma (unitless) real(r8) :: slopemax ! max topographic slope for microtopography pdf sigma (unitless) + real(r8) :: zbedrock ! parameter to substitute for zbedrock (m) + real(r8) :: zbedrock_sf ! parameter to scale zbedrock (m) end type params_type type(params_type), private :: params_inst ! @@ -79,6 +81,9 @@ subroutine readParams( ncid ) ! Max topographic slope for microtopography pdf sigma (unitless) call readNcdioScalar(ncid, 'slopemax', subname, params_inst%slopemax) + call readNcdioScalar(ncid, 'zbedrock', subname, params_inst%zbedrock) + call readNcdioScalar(ncid, 'zbedrock_sf', subname, params_inst%zbedrock_sf) + end subroutine readParams !------------------------------------------------------------------------ @@ -447,6 +452,12 @@ subroutine initVertical(bounds, glc_behavior, thick_wall, thick_roof) call endrun( 'ERROR:: zbedrock not found on surface data set, and use_bedrock is true.'//errmsg(sourcefile, __LINE__) ) end if end if + if (params_inst%zbedrock>=0._r8) then + zbedrock_in(:) = params_inst%zbedrock + end if + if (params_inst%zbedrock_sf/=1._r8) then + zbedrock_in(:) = params_inst%zbedrock_sf*zbedrock_in(:) + end if ! if use_bedrock = false, set zbedrock to lowest layer bottom interface else diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90 index 7988b57e75..b987879c03 100644 --- a/src/main/pftconMod.F90 +++ b/src/main/pftconMod.F90 @@ -162,6 +162,8 @@ module pftconMod real(r8), allocatable :: taper (:) ! tapering ratio of height:radius_breast_height real(r8), allocatable :: rstem_per_dbh (:) ! stem resistance per dbh (s/m/m) real(r8), allocatable :: wood_density (:) ! wood density (kg/m3) + real(r8), allocatable :: crit_onset_gdd_sf(:)! scale factor for crit_onset_gdd + real(r8), allocatable :: ndays_on(:) ! number of days to complete leaf onset ! crop @@ -502,6 +504,8 @@ subroutine InitAllocate (this) allocate( this%taper (0:mxpft) ) allocate( this%rstem_per_dbh (0:mxpft) ) allocate( this%wood_density (0:mxpft) ) + allocate( this%crit_onset_gdd_sf (0:mxpft) ) + allocate( this%ndays_on (0:mxpft) ) end subroutine InitAllocate @@ -843,6 +847,11 @@ subroutine InitRead(this) call ncd_io('season_decid_temperate', this%season_decid_temperate, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) + call ncd_io('crit_onset_gdd_sf', this%crit_onset_gdd_sf, 'read', ncid, readvar=readv, posNOTonfile=.true.) + if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) + + call ncd_io('ndays_on', this%ndays_on, 'read', ncid, readvar=readv, posNOTonfile=.true.) + if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) call ncd_io('pftpar20', this%pftpar20, 'read', ncid, readvar=readv, posNOTonfile=.true.) if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__)) @@ -1585,6 +1594,8 @@ subroutine Clean(this) deallocate( this%rstem_per_dbh) deallocate( this%wood_density) deallocate( this%taper) + deallocate( this%crit_onset_gdd_sf) + deallocate( this%ndays_on) end subroutine Clean end module pftconMod