diff --git a/biogeochem/FatesSoilBGCFluxMod.F90 b/biogeochem/FatesSoilBGCFluxMod.F90 index 8b6aad7542..8109b2c027 100644 --- a/biogeochem/FatesSoilBGCFluxMod.F90 +++ b/biogeochem/FatesSoilBGCFluxMod.F90 @@ -218,7 +218,7 @@ subroutine UnPackNutrientAquisitionBCs(sites, bc_in, nitr_suppl, phos_suppl) pft = ccohort%pft fnrt_c = ccohort%prt%GetState(fnrt_organ, carbon12_element) ccohort%daily_p_demand = fnrt_c * EDPftvarcon_inst%vmax_p(pft) * sec_per_day - ccohort%daily_p_gain = fnrt_c * EDPftvarcon_inst%vmax_p(pft) * sec_per_day * EDPftvarcon_inst%prescribed_nuptake(pft) + ccohort%daily_p_gain = fnrt_c * EDPftvarcon_inst%vmax_p(pft) * sec_per_day * EDPftvarcon_inst%prescribed_puptake(pft) ccohort => ccohort%shorter end do cpatch => cpatch%younger diff --git a/main/EDInitMod.F90 b/main/EDInitMod.F90 index 684ae8fb6c..121313825f 100644 --- a/main/EDInitMod.F90 +++ b/main/EDInitMod.F90 @@ -22,6 +22,7 @@ module EDInitMod use FatesInterfaceTypesMod , only : hlm_is_restart use FatesInterfaceTypesMod , only : hlm_current_tod use FatesInterfaceTypesMod , only : hlm_regeneration_model + use FatesInterfaceTypesMod , only : hlm_use_dbh_init use EDPftvarcon , only : EDPftvarcon_inst use PRTParametersMod , only : prt_params use EDCohortDynamicsMod , only : create_cohort, fuse_cohorts @@ -111,6 +112,11 @@ module EDInitMod logical :: debug = .false. integer :: istat ! return status code + + real(r8),parameter :: undamaged_crown = 1.0_r8 ! Assume on initialization the plants + ! are not damaged + real(r8),parameter :: untrimmed = 1.0_r8 ! Initialize plants as untrimmed + character(len=255) :: smsg ! Message string for deallocation errors character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -1169,7 +1175,6 @@ subroutine init_cohorts(site_in, patch_in, bc_in) integer :: use_pft_local(numpft) ! determine whether this PFT is used for this patch and site integer :: crown_damage ! crown damage class of the cohort [1 = undamaged, >1 = damaged] real(r8) :: l2fr ! leaf to fineroot biomass ratio [kg kg-1] - real(r8) :: canopy_trim ! fraction of the maximum leaf biomass that we are targeting [0-1] real(r8) :: cohort_n ! cohort density real(r8) :: dbh ! cohort dbh [cm] real(r8) :: height ! cohort height [m] @@ -1196,7 +1201,8 @@ subroutine init_cohorts(site_in, patch_in, bc_in) real(r8) :: fnrt_drop_fraction ! fraction of fine roots to absciss when leaves absciss integer, parameter :: recruitstatus = 0 ! whether the newly created cohorts are recruited or initialized real(r8),parameter :: zero_co_age = 0._r8 ! The age of a newly recruited cohort is zero - !------------------------------------------------------------------------------------- + + !------------------------------------------------------------------------------------- patch_in%tallest => null() patch_in%shortest => null() @@ -1204,7 +1210,7 @@ subroutine init_cohorts(site_in, patch_in, bc_in) ! if any pfts are starting with a non-recruitment size then the whole site ! needs the inventory type of spread do pft = 1, numpft - if (EDPftvarcon_inst%initd(pft) < 0.0_r8) then + if (hlm_use_dbh_init .eq. itrue)then site_in%spread = init_spread_inventory end if end do @@ -1217,6 +1223,7 @@ subroutine init_cohorts(site_in, patch_in, bc_in) ! 3. biogeog = false. nocomp = true : patch level filter ! 4. biogeog = true. nocomp = true : patch and site level filter ! in principle this could be a patch level variable. + do pft = 1, numpft ! first turn every PFT ON, unless we are in a special case use_pft_local(pft) = itrue ! Case 1 @@ -1235,11 +1242,12 @@ subroutine init_cohorts(site_in, patch_in, bc_in) endif end do + + + pft_loop: do pft = 1, numpft if_use_this_pft: if (use_pft_local(pft) .eq. itrue) then l2fr = prt_params%allom_l2fr(pft) - canopy_trim = 1.0_r8 - crown_damage = 1 ! Assume no damage to begin with c_area = fates_unset_r8 ! retrieve drop fraction of non-leaf tissues for phenology initialization @@ -1295,98 +1303,35 @@ subroutine init_cohorts(site_in, patch_in, bc_in) end select phen_select end if if_spmode - ! If EDPftvarcon_inst%initd is positive, then it is interpreted as - ! initial recruit density (stems/m2) - ! If EDPftvarcon_inss%initd is negative, then it is interpreted as - ! the initial DBH of the plant, and that the canopy is closed - ! at one layer. However, this is only possible in nocomp since - ! each PFT has its own patch area, and we don't have to assume - ! the differences in coverage. - - if_fullfates: if (hlm_use_nocomp .eq. ifalse) then - - cohort_n = EDPftvarcon_inst%initd(pft)*patch_in%area - height = EDPftvarcon_inst%hgt_min(pft) - - ! calculate the plant diameter from height - call h2d_allom(height, pft, dbh) - - call bleaf(dbh, pft, crown_damage, canopy_trim, efleaf_coh, c_leaf) - - else ! We are in a nocomp simulation - - ! interpret as initial density and calculate diameter - if_init_dens: if (EDPftvarcon_inst%initd(pft) > nearzero) then - - cohort_n = EDPftvarcon_inst%initd(pft)*patch_in%area - ! in nocomp mode we only have one PFT per patch - - ! as opposed to numpft's. So we should up the initial density - ! to compensate (otherwise runs are very hard to compare) - ! this multiplies it by the number of PFTs there would have been in - ! the single shared patch in competition mode. - ! n.b. that this is the same as currentcohort%n = initd(pft) &AREA - cohort_n = cohort_n*sum(site_in%use_this_pft) - - height = EDPftvarcon_inst%hgt_min(pft) - - ! calculate the plant diameter from height - call h2d_allom(height, pft, dbh) - - else ! interpret as initial diameter and calculate density - - dbh = abs(EDPftvarcon_inst%initd(pft)) - - ! calculate crown area of a single plant - call carea_allom(dbh, 1.0_r8, site_in%spread, pft, crown_damage, & - c_area) - - ! calculate initial density required to close canopy - cohort_n = patch_in%area/c_area - - ! calculate height from diameter - call h_allom(dbh, pft, height) - - endif if_init_dens - - ! Calculate the leaf biomass from allometry - ! (calculates a maximum first, then applies canopy trim) - call bleaf(dbh, pft, crown_damage, canopy_trim, efleaf_coh, c_leaf) - - ! If we are in SP mode we ignore the initial values and read in height, - ! which is used to calcualte n. - ! h, dbh, leafc, n from SP values or from small initial size - if (hlm_use_sp .eq. itrue) then - ! At this point, we do not know the bc_in values of tlai tsai and htop, - ! so this is initializing to an arbitrary value for the very first timestep. - ! Not sure if there's a way around this or not. - height = 0.5_r8 - call calculate_SP_properties(height, 0.2_r8, 0.1_r8, & - patch_in%area, pft, crown_damage, 1, & - EDPftvarcon_inst%vcmax25top(pft, 1), c_leaf, dbh, & - cohort_n, c_area) - endif ! sp mode - - endif if_fullfates - + ! Initialize cohort abundance, size and leaf mass + ! (we also include leaf mass because this is an output + ! from the SP init algorithm) + call ColdInitDBHAndNumDense(patch_in%area, & ! in + sum(site_in%use_this_pft), & ! in + sum(use_pft_local), & ! in + pft, & ! in + efleaf_coh, & ! in + dbh, & ! out + height, & ! out + n_plant, & ! out + c_leaf) ! out + ! calculate total above-ground biomass from allometry - call bagw_allom(dbh, pft, crown_damage, efstem_coh, c_agw) + call bagw_allom(dbh, pft, undamaged_crown, efstem_coh, c_agw) ! calculate coarse root biomass from allometry call bbgw_allom(dbh, pft, efstem_coh, c_bgw) ! Calculate fine root biomass from allometry ! (calculates a maximum and then trimming value) - call bfineroot(dbh, pft, canopy_trim, l2fr, effnrt_coh, c_fnrt) + call bfineroot(dbh, pft, untrimmed, l2fr, effnrt_coh, c_fnrt) ! Calculate sapwood biomass - call bsap_allom(dbh, pft, crown_damage, canopy_trim, efstem_coh, & + call bsap_allom(dbh, pft, undamaged_crown, untrimmed, efstem_coh, & a_sapw, c_sapw) call bdead_allom(c_agw, c_bgw, c_sapw, pft, c_struct) - call bstore_allom(dbh, pft, crown_damage, canopy_trim, c_store) - - if (debug) write(fates_log(),*) 'EDInitMod.F90 call create_cohort ' + call bstore_allom(dbh, pft, undamaged_crown, untrimmed, c_store) ! -------------------------------------------------------------------------------- ! Initialize the mass of every element in every organ of the organ @@ -1450,7 +1395,7 @@ subroutine init_cohorts(site_in, patch_in, bc_in) call create_cohort(site_in, patch_in, pft, cohort_n, & height, zero_co_age, dbh, prt, efleaf_coh, & effnrt_coh, efstem_coh, leaf_status, recruitstatus, & - canopy_trim, c_area, 1, crown_damage, site_in%spread, bc_in) + untrimmed, c_area, 1, undamaged_crown, site_in%spread, bc_in) endif if_use_this_pft enddo pft_loop @@ -1464,6 +1409,119 @@ subroutine init_cohorts(site_in, patch_in, bc_in) end subroutine init_cohorts + + ! ================================================================================= + + + subroutine ColdInitDBHAndNumDense(patch_area, spread, num_pft_in_site, & + num_pft_in_patch, pft, dbh, height, n_plant, c_leaf) + + ! This routine returns the plant density and size + ! for a cold-started plant. + ! If EDPftvarcon_inst%initd is positive, then it is interpreted as + ! initial recruit density (stems/m2) + ! If EDPftvarcon_inss%initd is negative, then it is interpreted as + ! the initial DBH of the plant, and that the canopy is closed + ! at one layer. However, this is only possible in nocomp since + ! each PFT has its own patch area, and we don't have to assume + ! the differences in coverage. + + ! Arguments + real(r8), intent(in) :: patch_area ! The area of this patch (m2) + real(r8), intent(in) :: spread ! Crown spread, currently init_spread + integer, intent(in) :: num_pft_in_site ! number of pfts that exist at this site + integer, intent(in) :: num_pft_in_patch ! number of pfts coexisting in this patch + integer, intent(in) :: pft ! pft index of this cohort + real(r8), intent(in) :: efleaf ! amount of leaf flushing (0-1) + real(r8), intent(out) :: dbh ! diameter (cm) + real(r8), intent(out) :: n_plant ! number of plants (plants/patch) + real(r8), intent(out) :: c_leaf ! leaf biomass, SP seems to have + ! its own algorithm here, so we + ! don't necessarily rely on the allometry equations + + real(r8) :: height + real(r8) :: c_area_plant ! crown area per plant (m2) + real(r8) :: c_area_co ! crown area of cohort (m2) + + + real(r8),parameter :: nominal_sp_height = 0.5_r8 ! nominal height (dummy) for SP + real(r8),parameter :: nominal_sp_tlai = 0.2_r8 ! nominal TLAI for SP + real(r8),parameter :: nominal_sp_tsai = 0.1_r8 ! nominal TSAI for SP + integer, parameter :: upper_canopy = 1 ! initializing a single canopy layer + real(r8),parameter :: unit_plant_dense = 1.0 ! used to get crown-area per plant (1. plant/m2) + + + if_sp: if (hlm_use_sp .eq. itrue) then + + ! If we are in SP mode we ignore the initial values and read in height, + ! which is used to calculate plant density. + ! h, dbh, leafc, n from SP values or from small initial size + ! At this point, we do not know the bc_in values of tlai tsai and htop, + ! so this is initializing to an arbitrary value for the very first timestep. + ! Not sure if there's a way around this or not. + + height = nominal_sp_height + + call calculate_SP_properties(height, & ! in + nominal_sp_tlai, & ! in + nominal_sp_tsai, & ! in + patch_area, & ! in + pft, & ! in + undamaged_crown, & ! in + upper_canopy, & ! in + EDPftvarcon_inst%vcmax25top(pft, 1), & !in + c_leaf, & ! out + dbh, & ! out + cohort_n, & ! out + c_area_co) ! out + else + + ! interpret as initial density and calculate diameter + if_init_dens: if (hlm_use_dbh_init.eq.ifalse)then + + n_plant = EDPftvarcon_inst%initd(pft)*patch_area + + ! For no-comp, we should up the initial density + ! to compensate (otherwise runs are very hard to compare) + ! this multiplies it by the number of PFTs there would have been in + ! the single shared patch in competition mode. + ! n.b. that this is the same as currentcohort%n = initd(pft) &AREA + if(hlm_use_nocomp.eq.itrue)then + n_plant = n_plant*real(num_pft_in_site,r8) + end if + + height = EDPftvarcon_inst%hgt_min(pft) + + ! calculate the plant diameter from height + call h2d_allom(height, pft, dbh) + + else ! interpret as initial diameter and calculate density + + dbh = EDPftvarcon_inst%initdbh(pft) + + ! calculate crown area of a single plant + call carea_allom(dbh, unit_plant_dense, spread, pft, undamaged_crown, c_area_plant) + + ! calculate initial density required to close canopy + ! If we are in "full-fates/non-nocomp" mode, then we + ! simply assume equal canopy area for each cohort + plant_n = (patch_area/real(num_pft_in_patch),r8)/c_area_plant + + ! calculate height from diameter + call h_allom(dbh, pft, height) + + endif if_init_dens + + ! Calculate the leaf biomass from allometry + ! (calculates a maximum first, then applies canopy trim) + call bleaf(dbh, pft, undamaged_crown, untrimmed, efleaf, c_leaf) + + end if if_sp + + end subroutine ColdInitDBHAndNumDense + + + ! ====================================================================================== end module EDInitMod diff --git a/main/EDPftvarcon.F90 b/main/EDPftvarcon.F90 index 3387845914..ad9ce3bda2 100644 --- a/main/EDPftvarcon.F90 +++ b/main/EDPftvarcon.F90 @@ -60,8 +60,10 @@ module EDPftvarcon real(r8), allocatable :: displar(:) ! ratio of displacement height to canopy top height real(r8), allocatable :: bark_scaler(:) ! scaler from dbh to bark thickness. For fire model. real(r8), allocatable :: crown_kill(:) ! scaler on fire death. For fire model. - real(r8), allocatable :: initd(:) ! initial seedling density [/m2] (positive values) - ! or -dbh [cm] (negative values) + real(r8), allocatable :: initd(:) ! initial seedling density [/m2] + real(r8), allocatable :: initdbh(:) ! initial seedling dbh [cm] + ! alternative to initd for nocomp + ! used only when use_dbh_init and use_nocomp are both true real(r8), allocatable :: init_seed(:) ! Initial seed bank [kg/m2] ! For SP: this is unused ! For Nocomp: This only applies the seed from the @@ -349,6 +351,10 @@ subroutine TransferParamsPFT(pstruct) allocate(EDPftvarcon_inst%initd(numpft)) EDPftvarcon_inst%initd(:) = param_p%r_data_1d(:) + param_p => pstruct%GetParamFromName('fates_recruit_init_dbh') + allocate(EDPftvarcon_inst%initdbh(numpft)) + EDPftvarcon_inst%initdbh(:) = param_p%r_data_1d(:) + param_p => pstruct%GetParamFromName('fates_recruit_init_seed') allocate(EDPftvarcon_inst%init_seed(numpft)) EDPftvarcon_inst%init_seed(:) = param_p%r_data_1d(:) @@ -851,6 +857,7 @@ subroutine FatesReportPFTParams(is_master) write(fates_log(),fmt0) 'bark_scaler = ',EDPftvarcon_inst%bark_scaler write(fates_log(),fmt0) 'crown_kill = ',EDPftvarcon_inst%crown_kill write(fates_log(),fmt0) 'initd = ',EDPftvarcon_inst%initd + write(fates_log(),fmt0) 'initdbh = ',EDPftvarcon_inst%initdbh write(fates_log(),fmt0) 'init_seed = ',EDPftvarcon_inst%init_seed write(fates_log(),fmt0) 'seed_suppl = ',EDPftvarcon_inst%seed_suppl write(fates_log(),fmt0) 'lf_flab = ',EDPftvarcon_inst%lf_flab @@ -957,6 +964,7 @@ subroutine FatesCheckParams(is_master) use FatesInterfaceTypesMod, only : hlm_use_fixed_biogeog,hlm_use_sp, hlm_name use FatesInterfaceTypesMod, only : hlm_use_inventory_init use FatesInterfaceTypesMod, only : hlm_use_nocomp + use FatesInterfaceTypesMod, only : hlm_use_dbh_init use EDParamsMod , only : max_nocomp_pfts_by_landuse, maxpatches_by_landuse use FatesConstantsMod , only : n_landuse_cats @@ -1259,30 +1267,46 @@ subroutine FatesCheckParams(is_master) ! Check that in initial density is not equal to zero in a cold-start run !----------------------------------------------------------------------------------- + if ( EDPftvarcon_inst%initd(ipft) < -nearzero ) then + write(fates_log(),*) ' Option to use negative values for initial density' + write(fates_log(),*) ' has been depricated. Set use_fates_dbh_init to true' + write(fates_log(),*) ' to initialize with dbh in nocomp mode. The corresponding' + write(fates_log(),*) ' is called fates_recruit_init_dbh' + write(fates_log(),*) ' Aborting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + if ( hlm_use_inventory_init == ifalse .and. & - abs( EDPftvarcon_inst%initd(ipft) ) < nearzero ) then + EDPftvarcon_inst%initd(ipft) < nearzero ) then - write(fates_log(),*) ' In a cold start run initial density cannot be zero.' - write(fates_log(),*) ' For a bare ground run set to initial recruit density.' + write(fates_log(),*) ' In a cold start run initial density cannot be zero' + write(fates_log(),*) ' without inventory initialization.' write(fates_log(),*) ' If no-comp is on it is possible to initialize with larger ' - write(fates_log(),*) ' plants by setting fates_recruit_init_density to a negative number' - write(fates_log(),*) ' which will be interpreted as (absolute) initial dbh. ' + write(fates_log(),*) ' plants by setting use_fates_dbh_init to true' + write(fates_log(),*) ' so that initial dbh parameter is used instead of density. ' write(fates_log(),*) ' Aborting' call endrun(msg=errMsg(sourcefile, __LINE__)) end if - if ( hlm_use_nocomp .eq. ifalse .and. EDPftvarcon_inst%initd(ipft) < -nearzero ) then - write(fates_log(),*) ' When not in a noncomp configuration, FATES does not' - write(fates_log(),*) ' know how to interpret a negative %initd (number density)' - write(fates_log(),*) ' on a cold-start. In nocomp with a negative, we assume the absolute' - write(fates_log(),*) ' value of the %inidt parameter is the initial plant size.' - write(fates_log(),*) ' And since the fractional area of each PFT is known from' - write(fates_log(),*) ' the surface file, we can derive a number density from this' - write(fates_log(),*) ' However, we do not have a hypothesis to do this in full FATES.' - write(fates_log(),*) ' Aborting' - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if + + + + if (hlm_use_dbh_init .eq. itrue) then + if (EDPftvarcon_inst%initdbh(ipft) < nearzero) then + write(fates_log(),*) ' You are running in nocomp mode using initial dbh instead of density.' + write(fates_log(),*) ' In a cold start run initial dbh cannot be less or equal zero.' + write(fates_log(),*) ' Aborting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + endif + if (EDPftvarcon_inst%init_seed(ipft) < nearzero) then + write(fates_log(),*) ' You are running in nocomp mode using initial dbh instead of density.' + write(fates_log(),*) ' In a cold start run initial seed cannot equal zero ' + write(fates_log(),*) ' Otherwize mass-balance will not be conserved.' + write(fates_log(),*) ' Aborting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + endif + endif if ( EDPftvarcon_inst%init_seed(ipft) < 0._r8) then write(fates_log(),*) ' Initial seed pool fates_init_seed can not be negative.' diff --git a/main/FatesInterfaceMod.F90 b/main/FatesInterfaceMod.F90 index bede720f14..7460427b9d 100644 --- a/main/FatesInterfaceMod.F90 +++ b/main/FatesInterfaceMod.F90 @@ -1575,6 +1575,7 @@ subroutine set_fates_ctrlparms(tag,ival,rval,cval) hlm_use_nocomp = unset_int hlm_use_sp = unset_int hlm_use_inventory_init = unset_int + hlm_use_dbh_init = unset_int hlm_inventory_ctrl_file = 'unset' hlm_hist_level_dynam = unset_int hlm_hist_level_hifrq = unset_int @@ -1683,6 +1684,14 @@ subroutine set_fates_ctrlparms(tag,ival,rval,cval) call endrun(msg=errMsg(sourcefile, __LINE__)) end if + if ( .not.((hlm_use_dbh_init.eq.itrue).or.(hlm_use_dbh_init.eq.ifalse)) ) then + write(fates_log(), *) 'The Fates dbh init flag must be 0 or 1, exiting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + elseif ((hlm_use_dbh_init .eq. itrue) .and. (hlm_use_nocomp .eq. ifalse)) then + write(fates_log(), *) 'The Fates dbh init can only be ON in NOCOMP mode, exiting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + if(hlm_ivis .ne. ivis) then write(fates_log(), *) 'FATES assumption about the index of visible shortwave' write(fates_log(), *) 'radiation is different from the HLM, exiting' @@ -2191,6 +2200,12 @@ subroutine set_fates_ctrlparms(tag,ival,rval,cval) write(fates_log(),*) 'Transfering hlm_use_inventory_init= ',ival,' to FATES' end if + case('use_dbh_init') + hlm_use_dbh_init = ival + if (fates_global_verbose()) then + write(fates_log(),*) 'Transfering hlm_use_dbh_init= ',ival,' to FATES' + end if + case('hist_hifrq_dimlevel') hlm_hist_level_hifrq = ival if (fates_global_verbose()) then diff --git a/main/FatesInterfaceTypesMod.F90 b/main/FatesInterfaceTypesMod.F90 index d750c55020..dcaf9cd972 100644 --- a/main/FatesInterfaceTypesMod.F90 +++ b/main/FatesInterfaceTypesMod.F90 @@ -211,6 +211,11 @@ module FatesInterfaceTypesMod ! This need only be defined when ! hlm_use_inventory_init = 1 + integer, public :: hlm_use_dbh_init ! Flag to use fates_recruit_init_dbh + ! instead of fates_recruit_init_density + ! only works in nocomp mode + ! 1 = TRUE, 0 = FALSE + integer, public :: hlm_use_fixed_biogeog ! Flag to use FATES fixed biogeography mode ! 1 = TRUE, 0 = FALSE diff --git a/parameter_files/fates_params_default.json b/parameter_files/fates_params_default.json index 1e799f8f1f..34bc923af4 100644 --- a/parameter_files/fates_params_default.json +++ b/parameter_files/fates_params_default.json @@ -1269,10 +1269,17 @@ "units": "m", "data": [1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 0.2, 0.2, 0.2, 0.8, 0.8, 0.11, 0.2, 0.2] }, + "fates_recruit_init_dbh": { + "dtype": "float", + "dims": ["fates_pft"], + "long_name": "initial seedling dbh for a cold-start near-bare-ground simulation. Can only to be used in nocomp mode. To use it set use_dbh_init to true", + "units": "cm", + "data": [ 1, 1, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 0.1, 0.1] + }, "fates_recruit_init_density": { "dtype": "float", "dims": ["fates_pft"], - "long_name": "initial seedling density for a cold-start near-bare-ground simulation. If negative sets initial tree dbh - only to be used in nocomp mode", + "long_name": "initial seedling density for a cold-start near-bare-ground simulation.", "units": "stems/m2", "data": [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.16, 0.2, 0.2, 0.2, 0.2] },