From 815ed35618781dee8b4f1eccd66a38fe122802a8 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 8 Oct 2018 15:03:00 -0700 Subject: [PATCH 01/78] Changed DEBUG logicals to lowercase (debug). Resolved Conflicts: biogeochem/EDCanopyStructureMod.F90 biogeochem/EDPhysiologyMod.F90 biogeophys/EDSurfaceAlbedoMod.F90 --- biogeochem/EDCanopyStructureMod.F90 | 8 ++--- biogeochem/EDCohortDynamicsMod.F90 | 22 ++++++------ biogeochem/EDMortalityFunctionsMod.F90 | 1 - biogeochem/EDPhysiologyMod.F90 | 22 ++++++------ biogeophys/EDAccumulateFluxesMod.F90 | 4 +-- biogeophys/EDSurfaceAlbedoMod.F90 | 24 ++++++------- biogeophys/FatesPlantRespPhotosynthMod.F90 | 38 ++++++++++---------- fire/SFMainMod.F90 | 26 +++++++------- main/EDInitMod.F90 | 4 +-- main/EDMainMod.F90 | 6 ++-- main/FatesRestartInterfaceMod.F90 | 40 +++++++++++----------- 11 files changed, 97 insertions(+), 98 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index cd7a652470..ce251583c7 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -33,7 +33,7 @@ module EDCanopyStructureMod public :: canopy_summarization public :: update_hlm_dynamics - logical, parameter :: DEBUG=.false. + logical, parameter :: debug=.false. character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -909,7 +909,7 @@ subroutine canopy_summarization( nsites, sites, bc_in ) !---------------------------------------------------------------------- - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'in canopy_summarization' endif @@ -1193,12 +1193,12 @@ subroutine leaf_area_profile( currentSite , snow_depth_si, frac_sno_eff_si) ! no m2 of leaf per m2 of ground in each height class ! FIX(SPM,032414) these should be uncommented this and double check - if ( DEBUG ) write(fates_log(), *) 'leaf_area_profile()', currentPatch%elai_profile(1,ft,iv) + if ( debug ) write(fates_log(), *) 'leaf_area_profile()', currentPatch%elai_profile(1,ft,iv) currentPatch%elai_profile(1,ft,iv) = currentPatch%tlai_profile(1,ft,iv) * fraction_exposed currentPatch%esai_profile(1,ft,iv) = currentPatch%tsai_profile(1,ft,iv) * fraction_exposed - if ( DEBUG ) write(fates_log(), *) 'leaf_area_profile()', currentPatch%elai_profile(1,ft,iv) + if ( debug ) write(fates_log(), *) 'leaf_area_profile()', currentPatch%elai_profile(1,ft,iv) enddo ! (iv) hite bins diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index a5bdfb70a7..2c7c9a349d 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -54,7 +54,7 @@ module EDCohortDynamicsMod public :: tree_lai public :: tree_sai - logical, parameter :: DEBUG = .false. ! local debug flag + logical, parameter :: debug = .false. ! local debug flag character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -430,7 +430,7 @@ subroutine terminate_cohorts( currentSite, patchptr, level ) ! Check if number density is so low is breaks math (level 1) if (currentcohort%n < min_n_safemath .and. level == 1) then terminate = 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'terminating cohorts 0',currentCohort%n/currentPatch%area,currentCohort%dbh endif endif @@ -444,7 +444,7 @@ subroutine terminate_cohorts( currentSite, patchptr, level ) (currentCohort%dbh < 0.00001_r8.and.currentCohort%bstore < 0._r8) ) then terminate = 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'terminating cohorts 1',currentCohort%n/currentPatch%area,currentCohort%dbh endif endif @@ -452,7 +452,7 @@ subroutine terminate_cohorts( currentSite, patchptr, level ) ! In the third canopy layer if (currentCohort%canopy_layer > nclmax ) then terminate = 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'terminating cohorts 2', currentCohort%canopy_layer endif endif @@ -461,7 +461,7 @@ subroutine terminate_cohorts( currentSite, patchptr, level ) if ( (currentCohort%bsw+currentCohort%bl+currentCohort%br) < 1e-10_r8 .or. & currentCohort%bstore < 1e-10_r8) then terminate = 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'terminating cohorts 3', & currentCohort%bsw,currentCohort%bl,currentCohort%br,currentCohort%bstore endif @@ -470,7 +470,7 @@ subroutine terminate_cohorts( currentSite, patchptr, level ) ! Total cohort biomass is negative if ( (currentCohort%b_total()) < 0._r8) then terminate = 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'terminating cohorts 4', & currentCohort%bsw, & currentCohort%bl, & @@ -576,7 +576,7 @@ subroutine fuse_cohorts(patchptr, bc_in) real(r8) :: diff real(r8) :: dynamic_fusion_tolerance - logical, parameter :: FUSE_DEBUG = .false. ! This debug is over-verbose + logical, parameter :: fuse_debug = .false. ! This debug is over-verbose ! and gets its own flag !---------------------------------------------------------------------- @@ -640,7 +640,7 @@ subroutine fuse_cohorts(patchptr, bc_in) newn = currentCohort%n + nextc%n fusion_took_place = 1 - if ( FUSE_DEBUG .and. currentCohort%isnew ) then + if ( fuse_debug .and. currentCohort%isnew ) then write(fates_log(),*) 'Fusing Two Cohorts' write(fates_log(),*) 'newn: ',newn write(fates_log(),*) 'Cohort I, Cohort II' @@ -1107,8 +1107,8 @@ subroutine copy_cohort( currentCohort,copyc ) n%npp_tstep = o%npp_tstep n%npp_acc = o%npp_acc - if ( DEBUG ) write(fates_log(),*) 'EDcohortDyn Ia ',o%npp_acc - if ( DEBUG ) write(fates_log(),*) 'EDcohortDyn Ib ',o%resp_acc + if ( debug ) write(fates_log(),*) 'EDcohortDyn Ia ',o%npp_acc + if ( debug ) write(fates_log(),*) 'EDcohortDyn Ib ',o%resp_acc n%resp_tstep = o%resp_tstep n%resp_acc = o%resp_acc @@ -1173,7 +1173,7 @@ subroutine copy_cohort( currentCohort,copyc ) n%dbdeaddt = o%dbdeaddt n%dbstoredt = o%dbstoredt - if ( DEBUG ) write(fates_log(),*) 'EDCohortDyn dpstoredt ',o%dbstoredt + if ( debug ) write(fates_log(),*) 'EDCohortDyn dpstoredt ',o%dbstoredt ! FIRE n%cfa = o%cfa diff --git a/biogeochem/EDMortalityFunctionsMod.F90 b/biogeochem/EDMortalityFunctionsMod.F90 index 4e84928361..045887c084 100644 --- a/biogeochem/EDMortalityFunctionsMod.F90 +++ b/biogeochem/EDMortalityFunctionsMod.F90 @@ -28,7 +28,6 @@ module EDMortalityFunctionsMod public :: mortality_rates public :: Mortality_Derivative - logical :: DEBUG_growth = .false. ! ============================================================================ ! 10/30/09: Created by Rosie Fisher diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 23f2a90a25..9dbb52b73f 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -72,7 +72,7 @@ module EDPhysiologyMod public :: flux_into_litter_pools - logical, parameter :: DEBUG = .false. ! local debug flag + logical, parameter :: debug = .false. ! local debug flag character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -225,7 +225,7 @@ subroutine trim_canopy( currentSite ) if (currentCohort%year_net_uptake(z) < currentCohort%leaf_cost)then if (currentCohort%canopy_trim > EDPftvarcon_inst%trim_limit(ipft))then - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'trimming leaves', & currentCohort%canopy_trim,currentCohort%leaf_cost endif @@ -250,7 +250,7 @@ subroutine trim_canopy( currentSite ) currentCohort%canopy_trim = currentCohort%canopy_trim + EDPftvarcon_inst%trim_inc(ipft) endif - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'trimming',currentCohort%canopy_trim endif @@ -373,7 +373,7 @@ subroutine phenology( currentSite, bc_in ) currentSite%status = 2 !alter status of site to 'leaves on' ! NOTE(bja, 2015-01) should leafondate = model_day to be consistent with leaf off? currentSite%leafondate = t !record leaf on date - if ( DEBUG ) write(fates_log(),*) 'leaves on' + if ( debug ) write(fates_log(),*) 'leaves on' endif !ncd endif !status endif !GDD @@ -393,7 +393,7 @@ subroutine phenology( currentSite, bc_in ) if (currentSite%status == 2)then currentSite%status = 1 !alter status of site to 'leaves on' currentSite%leafoffdate = hlm_model_day !record leaf off date - if ( DEBUG ) write(fates_log(),*) 'leaves off' + if ( debug ) write(fates_log(),*) 'leaves off' endif endif endif @@ -403,7 +403,7 @@ subroutine phenology( currentSite, bc_in ) if(currentSite%status == 2)then currentSite%status = 1 !alter status of site to 'leaves on' currentSite%leafoffdate = hlm_model_day !record leaf off date - if ( DEBUG ) write(fates_log(),*) 'leaves off' + if ( debug ) write(fates_log(),*) 'leaves off' endif endif @@ -554,11 +554,11 @@ subroutine phenology_leafonoff(currentSite) endif - if ( DEBUG ) write(fates_log(),*) 'EDPhysMod 1 ',currentCohort%bstore + if ( debug ) write(fates_log(),*) 'EDPhysMod 1 ',currentCohort%bstore currentCohort%bstore = currentCohort%bstore - currentCohort%bl ! Drain store - if ( DEBUG ) write(fates_log(),*) 'EDPhysMod 2 ',currentCohort%bstore + if ( debug ) write(fates_log(),*) 'EDPhysMod 2 ',currentCohort%bstore currentCohort%laimemory = 0.0_r8 @@ -594,11 +594,11 @@ subroutine phenology_leafonoff(currentSite) currentCohort%bl = currentCohort%bstore * store_output endif - if ( DEBUG ) write(fates_log(),*) 'EDPhysMod 3 ',currentCohort%bstore + if ( debug ) write(fates_log(),*) 'EDPhysMod 3 ',currentCohort%bstore currentCohort%bstore = currentCohort%bstore - currentCohort%bl ! empty store - if ( DEBUG ) write(fates_log(),*) 'EDPhysMod 4 ',currentCohort%bstore + if ( debug ) write(fates_log(),*) 'EDPhysMod 4 ',currentCohort%bstore currentCohort%laimemory = 0.0_r8 @@ -1677,7 +1677,7 @@ subroutine recruitment( currentSite, currentPatch, bc_in ) if (temp_cohort%n > 0.0_r8 )then - if ( DEBUG ) write(fates_log(),*) 'EDPhysiologyMod.F90 call create_cohort ' + if ( debug ) write(fates_log(),*) 'EDPhysiologyMod.F90 call create_cohort ' call create_cohort(currentPatch, temp_cohort%pft, temp_cohort%n, temp_cohort%hite, temp_cohort%dbh, & b_leaf, b_fineroot, b_sapwood, temp_cohort%bdead, temp_cohort%bstore, & temp_cohort%laimemory, cohortstatus, temp_cohort%canopy_trim, currentPatch%NCL_p, & diff --git a/biogeophys/EDAccumulateFluxesMod.F90 b/biogeophys/EDAccumulateFluxesMod.F90 index f782a21979..f421c5594e 100644 --- a/biogeophys/EDAccumulateFluxesMod.F90 +++ b/biogeophys/EDAccumulateFluxesMod.F90 @@ -18,7 +18,7 @@ module EDAccumulateFluxesMod ! public :: AccumulateFluxes_ED - logical :: DEBUG = .false. ! for debugging this module + logical :: debug = .false. ! for debugging this module character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -72,7 +72,7 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) ! Accumulate fluxes from hourly to daily values. ! _tstep fluxes are KgC/indiv/timestep _acc are KgC/indiv/day - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'EDAccumFlux 64 ',ccohort%npp_tstep write(fates_log(),*) 'EDAccumFlux 66 ',ccohort%gpp_tstep diff --git a/biogeophys/EDSurfaceAlbedoMod.F90 b/biogeophys/EDSurfaceAlbedoMod.F90 index 396f54e008..b8b9f10ee6 100644 --- a/biogeophys/EDSurfaceAlbedoMod.F90 +++ b/biogeophys/EDSurfaceAlbedoMod.F90 @@ -33,7 +33,7 @@ module EDSurfaceRadiationMod public :: ED_Norman_Radiation ! Surface albedo and two-stream fluxes public :: ED_SunShadeFracs - logical :: DEBUG = .false. ! for debugging this module + logical :: debug = .false. ! for debugging this module real(r8), public :: albice(maxSWb) = & ! albedo land ice by waveband (1=vis, 2=nir) @@ -700,7 +700,7 @@ subroutine ED_Norman_Radiation (nsites, sites, bc_in, bc_out ) if (ib == 1) then ! only set the absorbed PAR for the visible light band. do iv = 1, currentPatch%nrad(L,ft) if (radtype==1) then - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'EDsurfAlb 730 ',Abs_dif_z(ft,iv),currentPatch%f_sun(L,ft,iv) write(fates_log(),*) 'EDsurfAlb 731 ', currentPatch%fabd_sha_z(L,ft,iv), & currentPatch%fabd_sun_z(L,ft,iv) @@ -716,7 +716,7 @@ subroutine ED_Norman_Radiation (nsites, sites, bc_in, bc_out ) currentPatch%fabi_sun_z(L,ft,iv) = Abs_dif_z(ft,iv) * & currentPatch%f_sun(L,ft,iv) endif - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'EDsurfAlb 740 ', currentPatch%fabd_sha_z(L,ft,iv), & currentPatch%fabd_sun_z(L,ft,iv) endif @@ -947,7 +947,7 @@ subroutine ED_SunShadeFracs(nsites, sites,bc_in,bc_out) ifp=ifp+1 - if( DEBUG ) write(fates_log(),*) 'edsurfRad_5600',ifp,s,cpatch%NCL_p,numpft + if( debug ) write(fates_log(),*) 'edsurfRad_5600',ifp,s,cpatch%NCL_p,numpft ! zero out various datas cpatch%ed_parsun_z(:,:,:) = 0._r8 @@ -970,7 +970,7 @@ subroutine ED_SunShadeFracs(nsites, sites,bc_in,bc_out) do CL = 1, cpatch%NCL_p do FT = 1,numpft - if( DEBUG ) write(fates_log(),*) 'edsurfRad_5601',CL,FT,cpatch%nrad(CL,ft) + if( debug ) write(fates_log(),*) 'edsurfRad_5601',CL,FT,cpatch%nrad(CL,ft) do iv = 1, cpatch%nrad(CL,ft) !NORMAL CASE. @@ -980,8 +980,8 @@ subroutine ED_SunShadeFracs(nsites, sites,bc_in,bc_out) cpatch%ed_laisun_z(CL,ft,iv) = cpatch%elai_profile(CL,ft,iv) * & cpatch%f_sun(CL,ft,iv) - if ( DEBUG ) write(fates_log(),*) 'edsurfRad 570 ',cpatch%elai_profile(CL,ft,iv) - if ( DEBUG ) write(fates_log(),*) 'edsurfRad 571 ',cpatch%f_sun(CL,ft,iv) + if ( debug ) write(fates_log(),*) 'edsurfRad 570 ',cpatch%elai_profile(CL,ft,iv) + if ( debug ) write(fates_log(),*) 'edsurfRad 571 ',cpatch%f_sun(CL,ft,iv) cpatch%ed_laisha_z(CL,ft,iv) = cpatch%elai_profile(CL,ft,iv) * & (1._r8 - cpatch%f_sun(CL,ft,iv)) @@ -1015,16 +1015,16 @@ subroutine ED_SunShadeFracs(nsites, sites,bc_in,bc_out) ! If sun/shade big leaf code, nrad=1 and fluxes from SurfaceAlbedo ! are canopy integrated so that layer values equal big leaf values. - if ( DEBUG ) write(fates_log(),*) 'edsurfRad 645 ',cpatch%NCL_p,numpft + if ( debug ) write(fates_log(),*) 'edsurfRad 645 ',cpatch%NCL_p,numpft do CL = 1, cpatch%NCL_p do FT = 1,numpft - if ( DEBUG ) write(fates_log(),*) 'edsurfRad 649 ',cpatch%nrad(CL,ft) + if ( debug ) write(fates_log(),*) 'edsurfRad 649 ',cpatch%nrad(CL,ft) do iv = 1, cpatch%nrad(CL,ft) - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'edsurfRad 653 ', cpatch%ed_parsun_z(CL,ft,iv) write(fates_log(),*) 'edsurfRad 654 ', bc_in(s)%solad_parb(ifp,ipar) write(fates_log(),*) 'edsurfRad 655 ', bc_in(s)%solai_parb(ifp,ipar) @@ -1036,13 +1036,13 @@ subroutine ED_SunShadeFracs(nsites, sites,bc_in,bc_out) bc_in(s)%solad_parb(ifp,ipar)*cpatch%fabd_sun_z(CL,ft,iv) + & bc_in(s)%solai_parb(ifp,ipar)*cpatch%fabi_sun_z(CL,ft,iv) - if ( DEBUG )write(fates_log(),*) 'edsurfRad 663 ', cpatch%ed_parsun_z(CL,ft,iv) + if ( debug )write(fates_log(),*) 'edsurfRad 663 ', cpatch%ed_parsun_z(CL,ft,iv) cpatch%ed_parsha_z(CL,ft,iv) = & bc_in(s)%solad_parb(ifp,ipar)*cpatch%fabd_sha_z(CL,ft,iv) + & bc_in(s)%solai_parb(ifp,ipar)*cpatch%fabi_sha_z(CL,ft,iv) - if ( DEBUG ) write(fates_log(),*) 'edsurfRad 669 ', cpatch%ed_parsha_z(CL,ft,iv) + if ( debug ) write(fates_log(),*) 'edsurfRad 669 ', cpatch%ed_parsha_z(CL,ft,iv) end do !iv end do !FT diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 5aeee1f1be..8568af225e 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -45,7 +45,7 @@ module FATESPlantRespPhotosynthMod ! maximum stomatal resistance [s/m] (used across several procedures) real(r8),parameter :: rsmax0 = 2.e4_r8 - logical :: DEBUG = .false. + logical :: debug = .false. contains @@ -557,11 +557,11 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) ! calcualate some fluxes that are sums and nets of the base fluxes ! ------------------------------------------------------------------ - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 904 ', currentCohort%resp_m - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 905 ', currentCohort%rdark - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 906 ', currentCohort%livestem_mr - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 907 ', currentCohort%livecroot_mr - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 908 ', currentCohort%froot_mr + if ( debug ) write(fates_log(),*) 'EDPhoto 904 ', currentCohort%resp_m + if ( debug ) write(fates_log(),*) 'EDPhoto 905 ', currentCohort%rdark + if ( debug ) write(fates_log(),*) 'EDPhoto 906 ', currentCohort%livestem_mr + if ( debug ) write(fates_log(),*) 'EDPhoto 907 ', currentCohort%livecroot_mr + if ( debug ) write(fates_log(),*) 'EDPhoto 908 ', currentCohort%froot_mr @@ -581,9 +581,9 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) currentCohort%gpp_tstep = currentCohort%gpp_tstep * dtime currentCohort%ts_net_uptake = currentCohort%ts_net_uptake * dtime - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 911 ', currentCohort%gpp_tstep - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 912 ', currentCohort%resp_tstep - if ( DEBUG ) write(fates_log(),*) 'EDPhoto 913 ', currentCohort%resp_m + if ( debug ) write(fates_log(),*) 'EDPhoto 911 ', currentCohort%gpp_tstep + if ( debug ) write(fates_log(),*) 'EDPhoto 912 ', currentCohort%resp_tstep + if ( debug ) write(fates_log(),*) 'EDPhoto 913 ', currentCohort%resp_m currentCohort%resp_g = EDPftvarcon_inst%grperc(ft) * & (max(0._r8,currentCohort%gpp_tstep - & @@ -788,13 +788,13 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in else ! day time (a little bit more complicated ...) -! if ( DEBUG ) write(fates_log(),*) 'EDphot 594 ',laisun_lsl -! if ( DEBUG ) write(fates_log(),*) 'EDphot 595 ',laisha_lsl +! if ( debug ) write(fates_log(),*) 'EDphot 594 ',laisun_lsl +! if ( debug ) write(fates_log(),*) 'EDphot 595 ',laisha_lsl !is there leaf area? - (NV can be larger than 0 with only stem area if deciduous) if ( laisun_lsl + laisha_lsl > 0._r8 ) then -! if ( DEBUG ) write(fates_log(),*) '600 in laisun, laisha loop ' +! if ( debug ) write(fates_log(),*) '600 in laisun, laisha loop ' !Loop aroun shaded and unshaded leaves psn_out = 0._r8 ! psn is accumulated across sun and shaded leaves. @@ -945,9 +945,9 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in ! Convert gs_mol (umol H2O/m**2/s) to gs (m/s) and then to rs (s/m) gs = gs_mol / cf -! if ( DEBUG ) write(fates_log(),*) 'EDPhoto 737 ', psn_out -! if ( DEBUG ) write(fates_log(),*) 'EDPhoto 738 ', agross -! if ( DEBUG ) write(fates_log(),*) 'EDPhoto 739 ', f_sun_lsl +! if ( debug ) write(fates_log(),*) 'EDPhoto 737 ', psn_out +! if ( debug ) write(fates_log(),*) 'EDPhoto 738 ', agross +! if ( debug ) write(fates_log(),*) 'EDPhoto 739 ', f_sun_lsl ! Accumulate total photosynthesis umol/m2 ground/s-1. ! weight per unit sun and sha leaves. @@ -962,9 +962,9 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in 1._r8/(min(1._r8/gs, rsmax0)) * (1.0_r8-f_sun_lsl) end if -! if ( DEBUG ) write(fates_log(),*) 'EDPhoto 758 ', psn_out -! if ( DEBUG ) write(fates_log(),*) 'EDPhoto 759 ', agross -! if ( DEBUG ) write(fates_log(),*) 'EDPhoto 760 ', f_sun_lsl +! if ( debug ) write(fates_log(),*) 'EDPhoto 758 ', psn_out +! if ( debug ) write(fates_log(),*) 'EDPhoto 759 ', agross +! if ( debug ) write(fates_log(),*) 'EDPhoto 760 ', f_sun_lsl ! Make sure iterative solution is correct if (gs_mol < 0._r8) then @@ -1082,7 +1082,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv rdark = rdark * umolC_to_kgC gpp = gpp * umolC_to_kgC - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'EDPhoto 816 ', gpp write(fates_log(),*) 'EDPhoto 817 ', psn_llz(1:nv) write(fates_log(),*) 'EDPhoto 820 ', nv diff --git a/fire/SFMainMod.F90 b/fire/SFMainMod.F90 index fd1f50e0fd..eb9b400353 100644 --- a/fire/SFMainMod.F90 +++ b/fire/SFMainMod.F90 @@ -45,7 +45,7 @@ module SFMainMod public :: post_fire_mortality integer :: write_SF = 0 ! for debugging - logical :: DEBUG = .false. ! for debugging + logical :: debug = .false. ! for debugging ! ============================================================================ ! ============================================================================ @@ -343,7 +343,7 @@ subroutine wind_effect ( currentSite, bc_in) currentCohort => currentPatch%tallest do while(associated(currentCohort)) - if (DEBUG) write(fates_log(),*) 'SF currentCohort%c_area ',currentCohort%c_area + if (debug) write(fates_log(),*) 'SF currentCohort%c_area ',currentCohort%c_area if(EDPftvarcon_inst%woody(currentCohort%pft) == 1)then currentPatch%total_tree_area = currentPatch%total_tree_area + currentCohort%c_area else @@ -354,7 +354,7 @@ subroutine wind_effect ( currentSite, bc_in) tree_fraction = tree_fraction + min(currentPatch%area,currentPatch%total_tree_area)/AREA grass_fraction = grass_fraction + min(currentPatch%area,total_grass_area)/AREA - if(DEBUG)then + if(debug)then write(fates_log(),*) 'SF currentPatch%area ',currentPatch%area write(fates_log(),*) 'SF currentPatch%total_area ',currentPatch%total_tree_area write(fates_log(),*) 'SF total_grass_area ',tree_fraction,grass_fraction @@ -430,9 +430,9 @@ subroutine rate_of_spread ( currentSite ) ! ----start spreading--- - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) & + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) & 'SF - currentPatch%fuel_bulkd ',currentPatch%fuel_bulkd - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) & + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) & 'SF - SF_val_part_dens ',SF_val_part_dens ! beta = packing ratio (unitless) @@ -443,8 +443,8 @@ subroutine rate_of_spread ( currentSite ) ! packing ratio (unitless) beta_op = 0.200395_r8 *(currentPatch%fuel_sav**(-0.8189_r8)) - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - beta ',beta - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - beta_op ',beta_op + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - beta ',beta + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - beta_op ',beta_op beta_ratio = beta/beta_op !unitless if(write_sf == itrue)then @@ -467,13 +467,13 @@ subroutine rate_of_spread ( currentSite ) ! Equation A9 in Thonicke et al. 2010. e = 0.715_r8 * (exp(-0.01094_r8 * currentPatch%fuel_sav)) - if (DEBUG) then - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - c ',c - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - currentPatch%effect_wspeed ', & + if (debug) then + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - c ',c + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - currentPatch%effect_wspeed ', & currentPatch%effect_wspeed - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - b ',b - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - beta_ratio ',beta_ratio - if ( hlm_masterproc == itrue .and.DEBUG) write(fates_log(),*) 'SF - e ',e + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - b ',b + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - beta_ratio ',beta_ratio + if ( hlm_masterproc == itrue .and.debug) write(fates_log(),*) 'SF - e ',e endif ! Equation A5 in Thonicke et al. 2010 diff --git a/main/EDInitMod.F90 b/main/EDInitMod.F90 index 3661bede9e..af10d801a4 100644 --- a/main/EDInitMod.F90 +++ b/main/EDInitMod.F90 @@ -40,7 +40,7 @@ module EDInitMod implicit none private - logical :: DEBUG = .false. + logical :: debug = .false. character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -412,7 +412,7 @@ subroutine init_cohorts( patch_in, bc_in) cstatus = patch_in%siteptr%dstatus endif - if ( DEBUG ) write(fates_log(),*) 'EDInitMod.F90 call create_cohort ' + if ( debug ) write(fates_log(),*) 'EDInitMod.F90 call create_cohort ' call create_cohort(patch_in, pft, temp_cohort%n, temp_cohort%hite, temp_cohort%dbh, & b_leaf, b_fineroot, b_sapwood, temp_cohort%bdead, temp_cohort%bstore, & diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index 303b829cb9..3b7e1f1295 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -70,7 +70,7 @@ module EDMainMod private :: ed_total_balance_check private :: bypass_dynamics - logical :: DEBUG = .false. + logical :: debug = .false. character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -401,7 +401,7 @@ subroutine ed_update_site( currentSite, bc_in ) ! FIX(SPM,040314) why is this needed for BFB restarts? Look into this at some point cohort_number = count_cohorts(currentPatch) - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'tempCount ',cohort_number endif @@ -508,7 +508,7 @@ subroutine ed_total_balance_check (currentSite, call_index ) write(fates_log(),*) 'seeds',seed_stock write(fates_log(),*) 'previous total',currentSite%old_stock - if(DEBUG)then + if(debug)then change_in_stock = 0.0_r8 biomass_stock = 0.0_r8 litter_stock = 0.0_r8 diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index 685255a7a9..3c17949bf4 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -147,7 +147,7 @@ module FatesRestartInterfaceMod integer, parameter :: new_cohort = 1 ! Local debug flag - logical, parameter :: DEBUG=.false. + logical, parameter :: debug=.false. character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -1168,7 +1168,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) cohortsperpatch = cohortsperpatch + 1 totalCohorts = totalCohorts + 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CLTV io_idx_co ', io_idx_co write(fates_log(),*) 'CLTV lowerbound ', lbound(rio_npp_acc_co,1) write(fates_log(),*) 'CLTV upperbound ', ubound(rio_npp_acc_co,1) @@ -1225,7 +1225,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_isnew_co(io_idx_co) = old_cohort endif - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CLTV offsetNumCohorts II ',io_idx_co, & cohortsperpatch endif @@ -1246,7 +1246,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) ! set cohorts per patch for IO rio_ncohort_pa( io_idx_co_1st ) = cohortsperpatch - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'offsetNumCohorts III ' & ,io_idx_co,cohortsperpatch endif @@ -1269,9 +1269,9 @@ subroutine set_restart_vectors(this,nc,nsites,sites) io_idx_pa_cwd = io_idx_pa_cwd + 1 end do - if ( DEBUG ) write(fates_log(),*) 'CLTV io_idx_pa_sunz 1 ',io_idx_pa_sunz + if ( debug ) write(fates_log(),*) 'CLTV io_idx_pa_sunz 1 ',io_idx_pa_sunz - if ( DEBUG ) write(fates_log(),*) 'CLTV 1186 ',nlevleaf,numpft,nclmax + if ( debug ) write(fates_log(),*) 'CLTV 1186 ',nlevleaf,numpft,nclmax do k = 1,nlevleaf ! nlevleaf currently 40 do j = 1,numpft ! dependent on parameter file @@ -1286,7 +1286,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) end do end do - if ( DEBUG ) write(fates_log(),*) 'CLTV io_idx_pa_sunz 2 ',io_idx_pa_sunz + if ( debug ) write(fates_log(),*) 'CLTV io_idx_pa_sunz 2 ',io_idx_pa_sunz ! Set the first cohort index to the start of the next patch, increment @@ -1299,7 +1299,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) io_idx_co = io_idx_co_1st io_idx_pa_sunz = io_idx_co_1st - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CLTV io_idx_co_1st ', io_idx_co_1st write(fates_log(),*) 'CLTV numCohort ', cohortsperpatch write(fates_log(),*) 'CLTV totalCohorts ', totalCohorts @@ -1347,7 +1347,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) enddo - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CLTV total cohorts ',totalCohorts end if @@ -1453,7 +1453,7 @@ subroutine create_patchcohort_structure(this, nc, nsites, sites, bc_in) do idx_pa = 1,rio_npatch_si(io_idx_si) - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'create patch ',idx_pa write(fates_log(),*) 'idx_pa 1-cohortsperpatch : ', rio_ncohort_pa( io_idx_co_1st ) end if @@ -1501,7 +1501,7 @@ subroutine create_patchcohort_structure(this, nc, nsites, sites, bc_in) ! Solve for diameter from height call h2d_allom(temp_cohort%hite,ft,temp_cohort%dbh) - if (DEBUG) then + if (debug) then write(fates_log(),*) 'EDRestVectorMod.F90::createPatchCohortStructure call create_cohort ' end if @@ -1524,7 +1524,7 @@ subroutine create_patchcohort_structure(this, nc, nsites, sites, bc_in) ! if (idx_pa == 1) then ! nothing associated yet. first patch is pointed to by youngest and oldest - if ( DEBUG ) write(fates_log(),*) 'idx_pa = 1 ',idx_pa + if ( debug ) write(fates_log(),*) 'idx_pa = 1 ',idx_pa sites(s)%youngest_patch => newp sites(s)%oldest_patch => newp @@ -1535,7 +1535,7 @@ subroutine create_patchcohort_structure(this, nc, nsites, sites, bc_in) else if (idx_pa == 2) then ! add second patch to list - if ( DEBUG ) write(fates_log(),*) 'idx_pa = 2 ',idx_pa + if ( debug ) write(fates_log(),*) 'idx_pa = 2 ',idx_pa sites(s)%youngest_patch => newp sites(s)%youngest_patch%younger => null() @@ -1545,7 +1545,7 @@ subroutine create_patchcohort_structure(this, nc, nsites, sites, bc_in) else ! more than 2 patches, insert patch into youngest slot - if ( DEBUG ) write(fates_log(),*) 'idx_pa > 2 ',idx_pa + if ( debug ) write(fates_log(),*) 'idx_pa > 2 ',idx_pa newp%older => sites(s)%youngest_patch sites(s)%youngest_patch%younger => newp @@ -1745,7 +1745,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) cohortsperpatch = cohortsperpatch + 1 totalcohorts = totalcohorts + 1 - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CVTL io_idx_co ',io_idx_co endif @@ -1824,7 +1824,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) ! set cohorts per patch for IO - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CVTL III ' & ,io_idx_co,cohortsperpatch endif @@ -1848,7 +1848,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) io_idx_pa_cwd = io_idx_pa_cwd + 1 enddo - if ( DEBUG ) write(fates_log(),*) 'CVTL io_idx_pa_sunz 1 ',io_idx_pa_sunz + if ( debug ) write(fates_log(),*) 'CVTL io_idx_pa_sunz 1 ',io_idx_pa_sunz do k = 1,nlevleaf ! nlevleaf currently 40 do j = 1,numpft @@ -1863,7 +1863,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) end do end do - if ( DEBUG ) write(fates_log(),*) 'CVTL io_idx_pa_sunz 2 ',io_idx_pa_sunz + if ( debug ) write(fates_log(),*) 'CVTL io_idx_pa_sunz 2 ',io_idx_pa_sunz ! Now increment the position of the first cohort to that of the next ! patch @@ -1876,7 +1876,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) io_idx_co = io_idx_co_1st io_idx_pa_sunz = io_idx_co_1st - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CVTL io_idx_co_1st ', io_idx_co_1st write(fates_log(),*) 'CVTL cohortsperpatch ', cohortsperpatch write(fates_log(),*) 'CVTL totalCohorts ', totalCohorts @@ -1924,7 +1924,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) end do - if ( DEBUG ) then + if ( debug ) then write(fates_log(),*) 'CVTL total cohorts ',totalCohorts end if From e48065bcd435f7c91b446b10cbdcad750f83df34 Mon Sep 17 00:00:00 2001 From: Charles Koven Date: Fri, 16 Nov 2018 16:28:33 -0800 Subject: [PATCH 02/78] changed cohort fusion to conserve crown area --- biogeochem/EDCohortDynamicsMod.F90 | 37 +++++++++++-------- biogeochem/FatesAllometryMod.F90 | 59 ++++++++++++++++++++++-------- main/FatesConstantsMod.F90 | 2 +- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 71a1416cfc..6bef2c35ad 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -11,6 +11,7 @@ module EDCohortDynamicsMod use FatesConstantsMod , only : r8 => fates_r8 use FatesConstantsMod , only : fates_unset_int use FatesConstantsMod , only : itrue,ifalse + use FatesConstantsMod , only : fates_unset_r8 use FatesInterfaceMod , only : hlm_days_per_year use EDPftvarcon , only : EDPftvarcon_inst use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type @@ -729,6 +730,7 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) real(r8) :: newn real(r8) :: diff real(r8) :: dynamic_fusion_tolerance + real(r8) :: dbh integer :: largersc, smallersc, sc_i ! indices for tracking the growth flux caused by fusion real(r8) :: larger_n, smaller_n @@ -794,6 +796,7 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) if( currentCohort%isnew.eqv.nextc%isnew ) then newn = currentCohort%n + nextc%n + fusion_took_place = 1 if ( fuse_debug .and. currentCohort%isnew ) then @@ -822,26 +825,28 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%laimemory = (currentCohort%n*currentCohort%laimemory & + nextc%n*nextc%laimemory)/newn - currentCohort%dbh = (currentCohort%n*currentCohort%dbh & - + nextc%n*nextc%dbh)/newn - - call h_allom(currentCohort%dbh,currentCohort%pft,currentCohort%hite) - currentCohort%canopy_trim = (currentCohort%n*currentCohort%canopy_trim & + nextc%n*nextc%canopy_trim)/newn - ! ----------------------------------------------------------------- - ! If fusion pushed structural biomass to be larger than - ! the allometric target value derived by diameter, we - ! then increase diameter and height until the allometric - ! target matches actual bdead. (if it is the other way around - ! we then just let the carbon pools grow to fill-out allometry) - ! ----------------------------------------------------------------- + ! conserve total crown area during the fusion step, and then calculate dbh of the + ! fused cohort as that which conserves both crown area and the dbh to crown area allometry. + ! dbh will be updated in the next growth step in the (likely) event that dbh to structural + ! biomass allometry is exceeded. if using a capped crown area allometry and above the cap, + ! then calculate as the weighted average of fusing cohorts' dbh + + currentCohort%c_area = currentCohort%c_area + nextc%c_area + + call carea_allom(dbh,newn,currentSite%spread,currentCohort%pft,& + currentCohort%c_area,inverse=.true.) - if( EDPftvarcon_inst%woody(currentCohort%pft) == itrue ) then - call StructureResetOfDH( currentCohort%prt%GetState(struct_organ,all_carbon_elements), currentCohort%pft, & - currentCohort%canopy_trim, currentCohort%dbh, currentCohort%hite ) - end if + if (dbh .eq. fates_unset_r8) then + currentCohort%dbh = (currentCohort%n*currentCohort%dbh & + + nextc%n*nextc%dbh)/newn + else + currentCohort%dbh = dbh + endif + + call h_allom(currentCohort%dbh,currentCohort%pft,currentCohort%hite) call sizetype_class_index(currentCohort%dbh,currentCohort%pft, & currentCohort%size_class,currentCohort%size_by_pft_class) diff --git a/biogeochem/FatesAllometryMod.F90 b/biogeochem/FatesAllometryMod.F90 index 81881a190a..74f08b6072 100644 --- a/biogeochem/FatesAllometryMod.F90 +++ b/biogeochem/FatesAllometryMod.F90 @@ -90,6 +90,7 @@ module FatesAllometryMod use FatesConstantsMod, only : cm2_per_m2 use FatesConstantsMod, only : kg_per_Megag use FatesConstantsMod, only : calloc_abs_error + use FatesConstantsMod, only : fates_unset_r8 use shr_log_mod , only : errMsg => shr_log_errMsg use FatesGlobals , only : fates_log use FatesGlobals , only : endrun => fates_endrun @@ -448,15 +449,17 @@ end subroutine blmax_allom ! Generic crown area allometry wrapper ! ============================================================================ - subroutine carea_allom(d,nplant,site_spread,ipft,c_area) + subroutine carea_allom(d,nplant,site_spread,ipft,c_area,inverse) - real(r8),intent(in) :: d ! plant diameter [cm] + real(r8),intent(inout) :: d ! plant diameter [cm] real(r8),intent(in) :: site_spread ! site level spread factor (crowdedness) real(r8),intent(in) :: nplant ! number of plants [1/ha] integer(i4),intent(in) :: ipft ! PFT index - real(r8),intent(out) :: c_area ! crown area per cohort (m2) + real(r8),intent(inout) :: c_area ! crown area per cohort (m2) + logical,optional,intent(in) :: inverse! if true, calculate dbh from crown area instead of crown area from dbh real(r8) :: d_eff ! Effective diameter (cm) + logical :: do_inverse, capped_allom associate( dbh_maxh => EDPftvarcon_inst%allom_dbh_maxheight(ipft), & allom_lmode => EDPftvarcon_inst%allom_lmode(ipft), & @@ -465,24 +468,45 @@ subroutine carea_allom(d,nplant,site_spread,ipft,c_area) d2ca_min => EDPftvarcon_inst%allom_d2ca_coefficient_min(ipft), & d2ca_max => EDPftvarcon_inst%allom_d2ca_coefficient_max(ipft)) + if( .not. present(inverse) ) then + do_inverse = .false. + else + do_inverse = inverse + endif + + if (do_inverse) then + c_area = c_area / nplant + endif + select case(int(allom_lmode)) case(1) d_eff = min(d,dbh_maxh) - call carea_2pwr(d_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area) + call carea_2pwr(d_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) + capped_allom = .true. case(2) ! "2par_pwr") - call carea_2pwr(d,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area) + call carea_2pwr(d,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) + capped_allom = .false. case(3) d_eff = min(d,dbh_maxh) - call carea_2pwr(d_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area) + call carea_2pwr(d_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) + capped_allom = .true. case DEFAULT - write(fates_log(),*) 'An undefined leaf allometry was specified: ', & + write(fates_log(),*) 'An undefined leaf allometry was specified: ', & allom_lmode - write(fates_log(),*) 'Aborting' - call endrun(msg=errMsg(sourcefile, __LINE__)) - end select + write(fates_log(),*) 'Aborting' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end select + - c_area = c_area * nplant + if (capped_allom .and. do_inverse) then + if (d_eff .lt. dbh_maxh) then + d = d_eff + else + d = fates_unset_r8 + endif + endif + c_area = c_area * nplant end associate return @@ -1848,20 +1872,21 @@ end subroutine h2d_martcano ! ============================================================================= - subroutine carea_2pwr(d,spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area) + subroutine carea_2pwr(d,spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,inverse) ! ============================================================================ ! Calculate area of ground covered by entire cohort. (m2) ! Function of DBH (cm) canopy spread (m/cm) and number of individuals. ! ============================================================================ - real(r8),intent(in) :: d ! diameter [cm] + real(r8),intent(inout) :: d ! diameter [cm] real(r8),intent(in) :: spread ! site level relative spread score [0-1] real(r8),intent(in) :: d2bl_p2 ! parameter 2 in the diameter->bleaf allometry (exponent) real(r8),intent(in) :: d2bl_ediff ! area difference factor in the diameter-bleaf allometry (exponent) real(r8),intent(in) :: d2ca_min ! minimum diameter to crown area scaling factor real(r8),intent(in) :: d2ca_max ! maximum diameter to crown area scaling factor - real(r8),intent(out) :: c_area ! crown area for one plant [m2] + real(r8),intent(inout) :: c_area ! crown area for one plant [m2] + logical,intent(in) :: inverse ! if true, calculate dbh from crown area rather than its reverse real(r8) :: crown_area_to_dbh_exponent real(r8) :: spreadterm ! Effective 2bh to crown area scaling factor @@ -1885,7 +1910,11 @@ subroutine carea_2pwr(d,spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area) spreadterm = spread * d2ca_max + (1._r8 - spread) * d2ca_min - c_area = spreadterm * d ** crown_area_to_dbh_exponent + if ( .not. inverse) then + c_area = spreadterm * d ** crown_area_to_dbh_exponent + else + d = (c_area / spreadterm) ** (1./crown_area_to_dbh_exponent) + endif end subroutine carea_2pwr diff --git a/main/FatesConstantsMod.F90 b/main/FatesConstantsMod.F90 index f585c53915..eadc1df658 100644 --- a/main/FatesConstantsMod.F90 +++ b/main/FatesConstantsMod.F90 @@ -17,7 +17,7 @@ module FatesConstantsMod ! Unset and various other 'special' values integer, parameter :: fates_unset_int = -9999 - + real(fates_r8), parameter :: fates_unset_r8 = -9999._fates_r8 ! Integer equivalent of true (in case some compilers dont auto convert) integer, parameter :: itrue = 1 From 7cdca1363307e3657c893d67623ba8b37535cb6e Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 13 Dec 2018 12:30:43 -0800 Subject: [PATCH 03/78] Some minor syntax updates to inverse crown area allometry. Minor optimization to inverse crown area allometry. Implemented safer logic against a real. --- biogeochem/EDCohortDynamicsMod.F90 | 18 +++++---- biogeochem/FatesAllometryMod.F90 | 63 +++++++++++++++++------------- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 6bef2c35ad..30c6abd8e7 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -12,6 +12,7 @@ module EDCohortDynamicsMod use FatesConstantsMod , only : fates_unset_int use FatesConstantsMod , only : itrue,ifalse use FatesConstantsMod , only : fates_unset_r8 + use FatesConstantsMod , only : nearzero use FatesInterfaceMod , only : hlm_days_per_year use EDPftvarcon , only : EDPftvarcon_inst use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type @@ -820,7 +821,8 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) ! Fuse all mass pools - call currentCohort%prt%WeightedFusePRTVartypes(nextc%prt, currentCohort%n/newn ) + call currentCohort%prt%WeightedFusePRTVartypes(nextc%prt, & + currentCohort%n/newn ) currentCohort%laimemory = (currentCohort%n*currentCohort%laimemory & + nextc%n*nextc%laimemory)/newn @@ -828,18 +830,20 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%canopy_trim = (currentCohort%n*currentCohort%canopy_trim & + nextc%n*nextc%canopy_trim)/newn - ! conserve total crown area during the fusion step, and then calculate dbh of the - ! fused cohort as that which conserves both crown area and the dbh to crown area allometry. - ! dbh will be updated in the next growth step in the (likely) event that dbh to structural - ! biomass allometry is exceeded. if using a capped crown area allometry and above the cap, - ! then calculate as the weighted average of fusing cohorts' dbh + ! conserve total crown area during the fusion step, and then calculate + ! dbh of the fused cohort as that which conserves both crown area and + ! the dbh to crown area allometry. dbh will be updated in the next + ! growth step in the (likely) event that dbh to structural iomass + ! allometry is exceeded. if using a capped crown area allometry and + ! above the cap, then calculate as the weighted average of fusing + ! cohorts' dbh currentCohort%c_area = currentCohort%c_area + nextc%c_area call carea_allom(dbh,newn,currentSite%spread,currentCohort%pft,& currentCohort%c_area,inverse=.true.) - if (dbh .eq. fates_unset_r8) then + if (abs(dbh-fates_unset_r8) EDPftvarcon_inst%allom_dbh_maxheight(ipft), & allom_lmode => EDPftvarcon_inst%allom_lmode(ipft), & @@ -472,23 +477,22 @@ subroutine carea_allom(d,nplant,site_spread,ipft,c_area,inverse) do_inverse = .false. else do_inverse = inverse - endif - - if (do_inverse) then - c_area = c_area / nplant + if (do_inverse) then + c_area = c_area / nplant + endif endif select case(int(allom_lmode)) case(1) - d_eff = min(d,dbh_maxh) - call carea_2pwr(d_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) + dbh_eff = min(dbh,dbh_maxh) + call carea_2pwr(dbh_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) capped_allom = .true. case(2) ! "2par_pwr") - call carea_2pwr(d,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) + call carea_2pwr(dbh,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) capped_allom = .false. case(3) - d_eff = min(d,dbh_maxh) - call carea_2pwr(d_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) + dbh_eff = min(dbh,dbh_maxh) + call carea_2pwr(dbh_eff,site_spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,do_inverse) capped_allom = .true. case DEFAULT write(fates_log(),*) 'An undefined leaf allometry was specified: ', & @@ -499,10 +503,15 @@ subroutine carea_allom(d,nplant,site_spread,ipft,c_area,inverse) if (capped_allom .and. do_inverse) then - if (d_eff .lt. dbh_maxh) then - d = d_eff + if (dbh_eff .lt. dbh_maxh) then + dbh = dbh_eff else - d = fates_unset_r8 + ! In this situation, we are signaling to the + ! calling routine that we we cannot calculate + ! dbh from crown area, because we have already + ! hit the area cap, and the two are not proportional + ! anymore. hopefully, the calling routine has an alternative + dbh = fates_unset_r8 endif endif @@ -1872,20 +1881,20 @@ end subroutine h2d_martcano ! ============================================================================= - subroutine carea_2pwr(d,spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,inverse) + subroutine carea_2pwr(dbh,spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,inverse) ! ============================================================================ ! Calculate area of ground covered by entire cohort. (m2) ! Function of DBH (cm) canopy spread (m/cm) and number of individuals. ! ============================================================================ - real(r8),intent(inout) :: d ! diameter [cm] + real(r8),intent(inout) :: dbh ! diameter at breast (refernce) height [cm] real(r8),intent(in) :: spread ! site level relative spread score [0-1] real(r8),intent(in) :: d2bl_p2 ! parameter 2 in the diameter->bleaf allometry (exponent) real(r8),intent(in) :: d2bl_ediff ! area difference factor in the diameter-bleaf allometry (exponent) real(r8),intent(in) :: d2ca_min ! minimum diameter to crown area scaling factor real(r8),intent(in) :: d2ca_max ! maximum diameter to crown area scaling factor - real(r8),intent(inout) :: c_area ! crown area for one plant [m2] + real(r8),intent(inout) :: c_area ! crown area for one plant [m2] logical,intent(in) :: inverse ! if true, calculate dbh from crown area rather than its reverse real(r8) :: crown_area_to_dbh_exponent @@ -1911,9 +1920,9 @@ subroutine carea_2pwr(d,spread,d2bl_p2,d2bl_ediff,d2ca_min,d2ca_max,c_area,inver spreadterm = spread * d2ca_max + (1._r8 - spread) * d2ca_min if ( .not. inverse) then - c_area = spreadterm * d ** crown_area_to_dbh_exponent + c_area = spreadterm * dbh ** crown_area_to_dbh_exponent else - d = (c_area / spreadterm) ** (1./crown_area_to_dbh_exponent) + dbh = (c_area / spreadterm) ** (1./crown_area_to_dbh_exponent) endif end subroutine carea_2pwr From 569840318bc6f9c347d03806f50394dbc48a4f3e Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Mon, 17 Dec 2018 16:29:53 -0800 Subject: [PATCH 04/78] first attempt to put in a patch disturbance labelling system that tracks primary and secondary forest separately --- biogeochem/EDPatchDynamicsMod.F90 | 423 ++++++++++++++++++------------ main/EDMainMod.F90 | 6 + main/EDTypesMod.F90 | 4 + main/FatesConstantsMod.F90 | 4 + main/FatesHistoryInterfaceMod.F90 | 45 +++- main/FatesRestartInterfaceMod.F90 | 27 +- 6 files changed, 339 insertions(+), 170 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 98546557e3..e8fb3b30f5 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -10,6 +10,7 @@ module EDPatchDynamicsMod use EDtypesMod , only : ncwd, n_dbh_bins, area, patchfusion_dbhbin_loweredges use EDtypesMod , only : force_patchfuse_min_biomass use EDTypesMod , only : maxPatchesPerSite + use EDTypesMod , only : maxPatchesPerSite_by_disttype use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type use EDTypesMod , only : min_patch_area use EDTypesMod , only : nclmax @@ -37,6 +38,8 @@ module EDPatchDynamicsMod use FatesConstantsMod , only : days_per_sec use FatesConstantsMod , only : years_per_day use FatesConstantsMod , only : nearzero + use FatesConstantsMod , only : primaryforest, secondaryforest + use FatesConstantsMod , only : n_anthro_disturbance_categories use EDCohortDynamicsMod , only : InitPRTCohort @@ -309,12 +312,15 @@ subroutine spawn_patches( currentSite, bc_in) ! ! !LOCAL VARIABLES: type (ed_patch_type) , pointer :: new_patch + type (ed_patch_type) , pointer :: new_patch_primary + type (ed_patch_type) , pointer :: new_patch_secondary type (ed_patch_type) , pointer :: currentPatch type (ed_cohort_type), pointer :: currentCohort type (ed_cohort_type), pointer :: nc type (ed_cohort_type), pointer :: storesmallcohort - type (ed_cohort_type), pointer :: storebigcohort - real(r8) :: site_areadis ! total area disturbed in m2 per site per day + type (ed_cohort_type), pointer :: storebigcohort + real(r8) :: site_areadis_primary ! total area disturbed (to primary forest) in m2 per site per day + real(r8) :: site_areadis_secondary ! total area disturbed (to secondary forest) in m2 per site per day real(r8) :: patch_site_areadis ! total area disturbed in m2 per patch per day real(r8) :: age ! notional age of this patch in years integer :: tnull ! is there a tallest cohort? @@ -342,7 +348,8 @@ subroutine spawn_patches( currentSite, bc_in) currentSite%leaf_litter_burned = 0.0_r8 currentSite%total_burn_flux_to_atm = 0.0_r8 - site_areadis = 0.0_r8 + site_areadis_primary = 0.0_r8 + site_areadis_secondary = 0.0_r8 do while(associated(currentPatch)) !FIX(RF,032414) Does using the max(fire,mort) actually make sense here? @@ -351,33 +358,71 @@ subroutine spawn_patches( currentSite, bc_in) call endrun(msg=errMsg(sourcefile, __LINE__)) end if - site_areadis = site_areadis + currentPatch%area * currentPatch%disturbance_rate + if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .and. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) then + + site_areadis_primary = site_areadis_primary + currentPatch%area * currentPatch%disturbance_rate + else + site_areadis_secondary = site_areadis_secondary + currentPatch%area * currentPatch%disturbance_rate + endif + currentPatch => currentPatch%older enddo ! end loop over patches. sum area disturbed for all patches. - if (site_areadis > 0.0_r8) then + if ( (site_areadis_primary + site_areadis_secondary) > 0.0_r8) then cwd_ag_local = 0.0_r8 cwd_bg_local = 0.0_r8 leaf_litter_local = 0.0_r8 root_litter_local = 0.0_r8 age = 0.0_r8 - allocate(new_patch) - call create_patch(currentSite, new_patch, age, site_areadis, & - cwd_ag_local, cwd_bg_local, leaf_litter_local, & - root_litter_local, bc_in%nlevsoil) - - new_patch%tallest => null() - new_patch%shortest => null() + ! create two empty patches, to absorb newly disturbed primary and secondary forest area + if ( site_areadis_primary .gt. 0.0_r8) then + allocate(new_patch_primary) + call create_patch(currentSite, new_patch_primary, age, site_areadis_primary, & + cwd_ag_local, cwd_bg_local, leaf_litter_local, & + root_litter_local, bc_in%nlevsoil, primaryforest) + new_patch_primary%tallest => null() + new_patch_primary%shortest => null() + endif + if ( site_areadis_secondary .gt. 0.0_r8) then + allocate(new_patch_secondary) + call create_patch(currentSite, new_patch_secondary, age, site_areadis_secondary, & + cwd_ag_local, cwd_bg_local, leaf_litter_local, & + root_litter_local, bc_in%nlevsoil, secondaryforest) + new_patch_secondary%tallest => null() + new_patch_secondary%shortest => null() + endif + currentPatch => currentSite%oldest_patch ! loop round all the patches that contribute surviving indivduals and litter pools to the new patch. do while(associated(currentPatch)) + ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land + if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .and. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) then + new_patch => new_patch_primary + else + new_patch => new_patch_secondary + endif + ! This is the amount of patch area that is disturbed, and donated by the donor patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate + ! for the secondary forest case, if the dominant disturbance from this patch is non-anthropogenic, + ! we need to average in the time-since-anthropogenic-disturbance from the donor patch into that of the receiver patch + if ( currentPatch%anthro_disturbance_label .eq. secondaryforest .and. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .and. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) then + + new_patch%age_since_anthro_disturbance = new_patch%age_since_anthro_disturbance + & + currentPatch%age_since_anthro_disturbance * (patch_site_areadis / site_areadis_secondary) + endif + call average_patch_properties(currentPatch, new_patch, patch_site_areadis) if (currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifall) .and. & @@ -704,22 +749,43 @@ subroutine spawn_patches( currentSite, bc_in) !*************************/ - !** INSERT NEW PATCH INTO LINKED LIST - !**********`***************/ - currentPatch => currentSite%youngest_patch - new_patch%older => currentPatch - new_patch%younger => NULL() - currentPatch%younger => new_patch - currentSite%youngest_patch => new_patch + !** INSERT NEW PATCH(ES) INTO LINKED LIST + !**********`***************/ + + if ( site_areadis_primary .gt. 0.0_r8) then + currentPatch => currentSite%youngest_patch + new_patch_primary%older => currentPatch + new_patch_primary%younger => NULL() + currentPatch%younger => new_patch_primary + currentSite%youngest_patch => new_patch_primary + endif + + if ( site_areadis_secondary .gt. 0.0_r8) then + currentPatch => currentSite%youngest_patch + new_patch_secondary%older => currentPatch + new_patch_secondary%younger=> NULL() + currentPatch%younger => new_patch_secondary + currentSite%youngest_patch => new_patch_secondary + endif ! sort out the cohorts, since some of them may be so small as to need removing. ! the first call to terminate cohorts removes sparse number densities, ! the second call removes for all other reasons (sparse culling must happen ! before fusion) - call terminate_cohorts(currentSite, new_patch, 1) - call fuse_cohorts(currentSite,new_patch, bc_in) - call terminate_cohorts(currentSite, new_patch, 2) - call sort_cohorts(new_patch) + + if ( site_areadis_primary .gt. 0.0_r8) then + call terminate_cohorts(currentSite, new_patch_primary, 1) + call fuse_cohorts(currentSite,new_patch_primary, bc_in) + call terminate_cohorts(currentSite, new_patch_primary, 2) + call sort_cohorts(new_patch_primary) + endif + + if ( site_areadis_secondary .gt. 0.0_r8) then + call terminate_cohorts(currentSite, new_patch_secondary, 1) + call fuse_cohorts(currentSite,new_patch_secondary, bc_in) + call terminate_cohorts(currentSite, new_patch_secondary, 2) + call sort_cohorts(new_patch_secondary) + endif endif !end new_patch area @@ -1249,7 +1315,7 @@ end subroutine mortality_litter_fluxes ! ============================================================================ subroutine create_patch(currentSite, new_patch, age, areap,cwd_ag_local,cwd_bg_local, & - leaf_litter_local,root_litter_local,nlevsoil) + leaf_litter_local,root_litter_local,nlevsoil,label) ! ! !DESCRIPTION: ! Set default values for creating a new patch @@ -1266,6 +1332,7 @@ subroutine create_patch(currentSite, new_patch, age, areap,cwd_ag_local,cwd_bg_l real(r8), intent(in) :: root_litter_local(:) ! initial value of root litter. KgC/m2 real(r8), intent(in) :: leaf_litter_local(:) ! initial value of leaf litter. KgC/m2 integer, intent(in) :: nlevsoil ! number of soil layers + integer, intent(in) :: label ! anthropogenic disturbance label ! ! !LOCAL VARIABLES: !--------------------------------------------------------------------- @@ -1297,6 +1364,14 @@ subroutine create_patch(currentSite, new_patch, age, areap,cwd_ag_local,cwd_bg_l new_patch%cwd_bg = cwd_bg_local new_patch%leaf_litter = leaf_litter_local new_patch%root_litter = root_litter_local + + ! assign anthropgenic disturbance category and label + new_patch%anthro_disturbance_label = label + if (label .eq. secondaryforest) then + new_patch%age_since_anthro_disturbance = age + else + new_patch%age_since_anthro_disturbance = -1._r8 ! replace with fates_unset_r8 when possible + endif !zeroing things because of the surfacealbedo problem... shouldnt really be necesary new_patch%cwd_ag_in(:) = 0._r8 @@ -1477,9 +1552,10 @@ subroutine fuse_patches( csite, bc_in ) integer :: ft,z !counters for pft and height class real(r8) :: norm !normalized difference between biomass profiles real(r8) :: profiletol !tolerance of patch fusion routine. Starts off high and is reduced if there are too many patches. - integer :: nopatches !number of patches presently in gridcell + integer :: nopatches(n_anthro_disturbance_categories) !number of patches presently in gridcell integer :: iterate !switch of patch reduction iteration scheme. 1 to keep going, 0 to stop - integer :: fuse_flag !do patches get fused (1) or not (0). + integer :: fuse_flag !do patches get fused (1) or not (0). + integer :: i_disttype !iterator over anthropogenic disturbance categories ! !--------------------------------------------------------------------- @@ -1487,163 +1563,182 @@ subroutine fuse_patches( csite, bc_in ) profiletol = ED_val_patch_fusion_tol - nopatches = 0 + nopatches_primary = 0 + nopatches_secondary = 0 currentPatch => currentSite%youngest_patch do while(associated(currentPatch)) - nopatches = nopatches +1 + nopatches(currentPatch%anthro_disturbance_label) = & + nopatches(currentPatch%anthro_disturbance_label) + 1 currentPatch => currentPatch%older enddo - !---------------------------------------------------------------------! - ! We only really care about fusing patches if nopatches > 1 ! - !---------------------------------------------------------------------! - iterate = 1 !---------------------------------------------------------------------! - ! Keep doing this until nopatches >= maxPatchesPerSite ! - !---------------------------------------------------------------------! + ! iterate over anthropogenic disturbance categories + !---------------------------------------------------------------------! - do while(iterate == 1) - !---------------------------------------------------------------------! - ! Calculate the biomass profile of each patch ! - !---------------------------------------------------------------------! - currentPatch => currentSite%youngest_patch - do while(associated(currentPatch)) - call patch_pft_size_profile(currentPatch) - currentPatch => currentPatch%older - enddo + do i_disttype = 1, n_anthro_disturbance_categories !---------------------------------------------------------------------! - ! Loop round current & target (currentPatch,tpp) patches to assess combinations ! - !---------------------------------------------------------------------! - currentPatch => currentSite%youngest_patch - do while(associated(currentPatch)) - tpp => currentSite%youngest_patch - do while(associated(tpp)) - - if(.not.associated(currentPatch))then - write(fates_log(),*) 'ED: issue with currentPatch' - endif + ! We only really care about fusing patches if nopatches > 1 ! + !---------------------------------------------------------------------! - if(associated(tpp).and.associated(currentPatch))then + iterate = 1 - !-------------------------------------------------------------------------------------------- - ! The default is to fuse the patches, unless some criteria is met which keeps them separated. - ! there are multiple criteria which all need to be met to keep them distinct: - ! (a) one of them is younger than the max age at which we force fusion; - ! (b) there is more than a threshold (tiny) amount of biomass in at least one of the patches; - ! (c) for at least one pft x size class, where there is biomass in that class in at least one patch, - ! and the normalized difference between the patches exceeds a threshold. - !-------------------------------------------------------------------------------------------- - - fuse_flag = 1 - if(currentPatch%patchno /= tpp%patchno) then !these should be the same patch + !---------------------------------------------------------------------! + ! Keep doing this until nopatches >= maxPatchesPerSite ! + !---------------------------------------------------------------------! - !----------------------------------------------------------------------------------- - ! check to see if both patches are older than the age at which we force them to fuse - !----------------------------------------------------------------------------------- - - if ( tpp%age .le. max_age_of_second_oldest_patch .or. & - currentPatch%age .le. max_age_of_second_oldest_patch ) then + do while(iterate == 1) + !---------------------------------------------------------------------! + ! Calculate the biomass profile of each patch ! + !---------------------------------------------------------------------! + currentPatch => currentSite%youngest_patch + do while(associated(currentPatch)) + call patch_pft_size_profile(currentPatch) + currentPatch => currentPatch%older + enddo - - !--------------------------------------------------------------------------------------------------------- - ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, - ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be - ! distinguished from each other. but if force_patchfuse_min_biomass is too big, it takes too long for the - ! youngest patch to build up enough biomass to be its own distinct entity, which leads to large oscillations - ! in the patch dynamics and dependent variables. - !--------------------------------------------------------------------------------------------------------- - - if(sum(currentPatch%pft_agb_profile(:,:)) > force_patchfuse_min_biomass .or. & - sum(tpp%pft_agb_profile(:,:)) > force_patchfuse_min_biomass ) then - - !---------------------------------------------------------------------! - ! Calculate the difference criteria for each pft and dbh class ! - !---------------------------------------------------------------------! - - do ft = 1,numpft ! loop over pfts - do z = 1,n_dbh_bins ! loop over hgt bins - - !---------------------------------- - !is there biomass in this category? - !---------------------------------- - - if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8 .or. & - tpp%pft_agb_profile(ft,z) > 0.0_r8)then - - !------------------------------------------------------------------------------------- - ! what is the relative difference in biomass i nthis category between the two patches? - !------------------------------------------------------------------------------------- - - norm = abs(currentPatch%pft_agb_profile(ft,z) - & - tpp%pft_agb_profile(ft,z))/(0.5_r8 * & - &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) - - !---------------------------------------------------------------------! - ! Look for differences in profile biomass, above the minimum biomass ! - !---------------------------------------------------------------------! - - if(norm > profiletol)then - - fuse_flag = 0 !do not fuse - keep apart. - - endif ! profile tol - endif ! biomass(ft,z) .gt. 0 - enddo !ht bins - enddo ! PFT - endif ! sum(biomass(:,:) .gt. force_patchfuse_min_biomass - endif ! maxage - - !-------------------------------------------------------------------------! - ! Call the patch fusion routine if there is not a meaningful difference ! - ! any of the pft x height categories ! - ! or both are older than forced fusion age ! - !-------------------------------------------------------------------------! - - if(fuse_flag == 1)then - tmpptr => currentPatch%older - call fuse_2_patches(csite, currentPatch, tpp) - call fuse_cohorts(csite,tpp, bc_in) - call sort_cohorts(tpp) - currentPatch => tmpptr - else - ! write(fates_log(),*) 'patches not fused' - endif - endif !are both patches associated? - endif !are these different patches? - tpp => tpp%older - enddo !tpp loop + !---------------------------------------------------------------------! + ! Loop round current & target (currentPatch,tpp) patches to assess combinations ! + !---------------------------------------------------------------------! + currentPatch => currentSite%youngest_patch + do while(associated(currentPatch)) + tpp => currentSite%youngest_patch + do while(associated(tpp)) + + if(.not.associated(currentPatch))then + write(fates_log(),*) 'ED: issue with currentPatch' + endif - if(associated(currentPatch))then - currentPatch => currentPatch%older - else - currentPatch => null() - endif !associated currentPatch + if(associated(tpp).and.associated(currentPatch))then + + ! only fuse patches whose anthropogenic disturbance categroy matches taht of the outer loop that we are in + if ( tpp%anthro_disturbance_label .eq. i_disttype .and. & + currentPatch%anthro_disturbance_label .eq. i_disttype) then + + !-------------------------------------------------------------------------------------------- + ! The default is to fuse the patches, unless some criteria is met which keeps them separated. + ! there are multiple criteria which all need to be met to keep them distinct: + ! (a) one of them is younger than the max age at which we force fusion; + ! (b) there is more than a threshold (tiny) amount of biomass in at least one of the patches; + ! (c) for at least one pft x size class, where there is biomass in that class in at least one patch, + ! and the normalized difference between the patches exceeds a threshold. + !-------------------------------------------------------------------------------------------- + + fuse_flag = 1 + if(currentPatch%patchno /= tpp%patchno) then !these should be the same patch + + !----------------------------------------------------------------------------------- + ! check to see if both patches are older than the age at which we force them to fuse + !----------------------------------------------------------------------------------- + + if ( tpp%age .le. max_age_of_second_oldest_patch .or. & + currentPatch%age .le. max_age_of_second_oldest_patch ) then + + + !--------------------------------------------------------------------------------------------------------- + ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, + ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be + ! distinguished from each other. but if force_patchfuse_min_biomass is too big, it takes too long for the + ! youngest patch to build up enough biomass to be its own distinct entity, which leads to large oscillations + ! in the patch dynamics and dependent variables. + !--------------------------------------------------------------------------------------------------------- + + if(sum(currentPatch%pft_agb_profile(:,:)) > force_patchfuse_min_biomass .or. & + sum(tpp%pft_agb_profile(:,:)) > force_patchfuse_min_biomass ) then + + !---------------------------------------------------------------------! + ! Calculate the difference criteria for each pft and dbh class ! + !---------------------------------------------------------------------! + + do ft = 1,numpft ! loop over pfts + do z = 1,n_dbh_bins ! loop over hgt bins + + !---------------------------------- + !is there biomass in this category? + !---------------------------------- + + if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8 .or. & + tpp%pft_agb_profile(ft,z) > 0.0_r8)then + + !------------------------------------------------------------------------------------- + ! what is the relative difference in biomass i nthis category between the two patches? + !------------------------------------------------------------------------------------- + + norm = abs(currentPatch%pft_agb_profile(ft,z) - & + tpp%pft_agb_profile(ft,z))/(0.5_r8 * & + &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) + + !---------------------------------------------------------------------! + ! Look for differences in profile biomass, above the minimum biomass ! + !---------------------------------------------------------------------! + + if(norm > profiletol)then + + fuse_flag = 0 !do not fuse - keep apart. + + endif ! profile tol + endif ! biomass(ft,z) .gt. 0 + enddo !ht bins + enddo ! PFT + endif ! sum(biomass(:,:) .gt. force_patchfuse_min_biomass + endif ! maxage + + !-------------------------------------------------------------------------! + ! Call the patch fusion routine if there is not a meaningful difference ! + ! any of the pft x height categories ! + ! or both are older than forced fusion age ! + !-------------------------------------------------------------------------! + + if(fuse_flag == 1)then + tmpptr => currentPatch%older + call fuse_2_patches(csite, currentPatch, tpp) + call fuse_cohorts(csite,tpp, bc_in) + call sort_cohorts(tpp) + currentPatch => tmpptr + else + ! write(fates_log(),*) 'patches not fused' + endif + endif !are both patches the same anthropogenic disturbance category as the disturbance type loop iterator? + endif !are both patches associated? + endif !are these different patches? + tpp => tpp%older + enddo !tpp loop + + if(associated(currentPatch))then + currentPatch => currentPatch%older + else + currentPatch => null() + endif !associated currentPatch - enddo ! currentPatch loop + enddo ! currentPatch loop - !---------------------------------------------------------------------! - ! Is the number of patches larger than the maximum? ! - !---------------------------------------------------------------------! - nopatches = 0 - currentPatch => currentSite%youngest_patch - do while(associated(currentPatch)) - nopatches = nopatches +1 - currentPatch => currentPatch%older - enddo + !---------------------------------------------------------------------! + ! Is the number of patches larger than the maximum? ! + !---------------------------------------------------------------------! + nopatches(i_disttype) = 0 + currentPatch => currentSite%youngest_patch + do while(associated(currentPatch)) + if (currentPatch%anthro_disturbance_label .eq. i_disttype) then + nopatches(i_disttype) = nopatches(i_disttype) +1 + endif + currentPatch => currentPatch%older + enddo - if(nopatches > maxPatchesPerSite)then - iterate = 1 - profiletol = profiletol * patch_fusion_tolerance_relaxation_increment + if(nopatches(i_disttype) > maxPatchesPerSite_by_disttype(i_disttype))then + iterate = 1 + profiletol = profiletol * patch_fusion_tolerance_relaxation_increment - !---------------------------------------------------------------------! - ! Making profile tolerance larger means that more fusion will happen ! - !---------------------------------------------------------------------! - else - iterate = 0 - endif + !---------------------------------------------------------------------! + ! Making profile tolerance larger means that more fusion will happen ! + !---------------------------------------------------------------------! + else + iterate = 0 + endif + + enddo !do while nopatches>maxPatchesPerSite - enddo !do while nopatches>maxPatchesPerSite + end do ! i_disttype loop end subroutine fuse_patches diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index aca5a3df14..3f0c6a1585 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -42,6 +42,7 @@ module EDMainMod use EDTypesMod , only : do_ed_phenology use EDTypesMod , only : AREA use FatesConstantsMod , only : itrue,ifalse + use FatesConstantsMod , only : primaryforest, secondaryforest use FatesPlantHydraulicsMod , only : do_growthrecruiteffects use FatesPlantHydraulicsMod , only : updateSizeDepTreeHydProps use FatesPlantHydraulicsMod , only : updateSizeDepTreeHydStates @@ -285,6 +286,11 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) currentPatch%patchno,currentPatch%area endif + ! add age increment to secondary forest patches as well + if (currentPatch%anthro_disturbance_label .eq. secondaryforest) then + currentPatch%age_since_anthro_disturbance = currentPatch%age_since_anthro_disturbance + hlm_freq_day + endif + ! check to see if the patch has moved to the next age class currentPatch%age_class = get_age_class_index(currentPatch%age) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 16bd7db647..1717132b59 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -11,11 +11,13 @@ module EDTypesMod use PRTGenericMod, only : leaf_organ, fnrt_organ, sapw_organ use PRTGenericMod, only : repro_organ, store_organ, struct_organ use PRTGenericMod, only : all_carbon_elements + use FatesConstantsMod, only : n_anthro_disturbance_categories implicit none save integer, parameter :: maxPatchesPerSite = 10 ! maximum number of patches to live on a site + integer, parameter :: maxPatchesPerSite_by_disttype(n_anthro_disturbance_categories) = (/ 5, 5 /) !!! MUST SUM TO maxPatchesPerSite !!! integer, parameter :: maxCohortsPerPatch = 160 ! maximum number of cohorts per patch integer, parameter :: nclmax = 2 ! Maximum number of canopy layers @@ -321,6 +323,8 @@ module EDTypesMod real(r8) :: area ! patch area: m2 integer :: countcohorts ! Number of cohorts in patch integer :: ncl_p ! Number of occupied canopy layers + integer :: anthro_disturbance_label ! patch label for anthropogenic disturbance classification + real(r8) :: age_since_anthro_disturbance ! average age for secondary forest since last anthropogenic disturbance ! LEAF ORGANIZATION real(r8) :: pft_agb_profile(maxpft,n_dbh_bins) ! binned above ground biomass, for patch fusion: KgC/m2 diff --git a/main/FatesConstantsMod.F90 b/main/FatesConstantsMod.F90 index f585c53915..2c2de48572 100644 --- a/main/FatesConstantsMod.F90 +++ b/main/FatesConstantsMod.F90 @@ -25,6 +25,10 @@ module FatesConstantsMod ! Integer equivalent of false (in case come compilers dont auto convert) integer, parameter :: ifalse = 0 + ! Labels for patch disturbance history + integer, parameter :: n_anthro_disturbance_categories = 2 + integer, parameter :: primaryforest = 1 + integer, parameter :: secondaryforest = 2 ! Error Tolerances diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 29e063822a..4b348b5363 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -33,6 +33,7 @@ module FatesHistoryInterfaceMod use FatesConstantsMod , only : sec_per_day use FatesConstantsMod , only : days_per_year use FatesConstantsMod , only : years_per_day + use FatesConstantsMod , only : secondaryforest use PRTGenericMod , only : leaf_organ, fnrt_organ, sapw_organ use PRTGenericMod , only : struct_organ, store_organ, repro_organ @@ -151,6 +152,7 @@ module FatesHistoryInterfaceMod integer, private :: ih_froot_mr_si integer, private :: ih_livestem_mr_si integer, private :: ih_livecroot_mr_si + integer, private :: ih_fraction_secondary_forest_si ! Indices to (site x scpf) variables integer, private :: ih_nplant_si_scpf @@ -301,6 +303,8 @@ module FatesHistoryInterfaceMod integer, private :: ih_biomass_si_age integer, private :: ih_c_stomata_si_age integer, private :: ih_c_lblayer_si_age + integer, private :: ih_agesince_anthrodist_si_age + integer, private :: ih_secondaryforest_area_si_age ! indices to (site x height) variables integer, private :: ih_canopy_height_dist_si_height @@ -1300,6 +1304,7 @@ subroutine update_history_dyn(this,nc,nsites,sites) integer :: ican, ileaf, cnlf_indx ! iterators for leaf and canopy level integer :: height_bin_max, height_bin_min ! which height bin a given cohort's canopy is in integer :: i_heightbin ! iterator for height bins + integer :: ageclass_since_anthrodist ! what is the equivalent age class for time-since-anthropogenic-disturbance of secondary forest real(r8) :: n_density ! individual of cohort per m2. real(r8) :: n_perm2 ! individuals per m2 for the whole column @@ -1494,6 +1499,9 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_npatches_si_age => this%hvars(ih_npatches_si_age)%r82d, & hio_zstar_si_age => this%hvars(ih_zstar_si_age)%r82d, & hio_biomass_si_age => this%hvars(ih_biomass_si_age)%r82d, & + hio_fraction_secondary_forest_si => this%hvars(ih_fraction_secondary_forest_si)%r81d, & + hio_agesince_anthrodist_si_age => this%hvars(ih_agesince_anthrodist_si_age)%r81d, & + hio_secondaryforest_area_si_age => this%hvars(ih_secondaryforest_area_si_age)%r81d, & hio_canopy_height_dist_si_height => this%hvars(ih_canopy_height_dist_si_height)%r82d, & hio_leaf_height_dist_si_height => this%hvars(ih_leaf_height_dist_si_height)%r82d, & hio_litter_moisture_si_fuel => this%hvars(ih_litter_moisture_si_fuel)%r82d, & @@ -1569,6 +1577,22 @@ subroutine update_history_dyn(this,nc,nsites,sites) + cpatch%zstar * cpatch%area * AREA_INV endif + ! some diagnostics on secondary forest area and its age distribution + if ( cpatch%anthro_disturbance_label .eq. secondaryforest ) then + hio_fraction_secondary_forest_si(io_si) = hio_fraction_secondary_forest_si(io_si) + & + cpatch%area * AREA_INV + + ageclass_since_anthrodist = get_age_class_index(cpatch%age_since_anthro_disturbance) + + hio_agesince_anthrodist_si_age(io_si,ageclass_since_anthrodist) = & + hio_agesince_anthrodist_si_age(io_si,ageclass_since_anthrodist) & + + cpatch%area * AREA_INV + + hio_secondaryforest_area_si_age(io_si,cpatch%age_class) = & + hio_secondaryforest_area_si_age(io_si,cpatch%age_class) & + + cpatch%area * AREA_INV + endif + ccohort => cpatch%shortest do while(associated(ccohort)) @@ -2389,7 +2413,6 @@ subroutine update_history_prod(this,nc,nsites,sites,dt_tstep) hio_c_lblayer_si(io_si) = hio_c_lblayer_si(io_si) + & cpatch%c_lblayer * cpatch%total_canopy_area - ccohort => cpatch%shortest do while(associated(ccohort)) @@ -2463,8 +2486,6 @@ subroutine update_history_prod(this,nc,nsites,sites,dt_tstep) hio_ar_frootm_si_scpf(io_si,scpf) = hio_ar_frootm_si_scpf(io_si,scpf) + & ccohort%froot_mr * n_perm2 * sec_per_day * days_per_year - - ! accumulate fluxes per patch age bin hio_gpp_si_age(io_si,cpatch%age_class) = hio_gpp_si_age(io_si,cpatch%age_class) & @@ -3208,6 +3229,24 @@ subroutine define_history_vars(this, initialize_variables) avgflag='A', vtype=site_age_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_biomass_si_age ) + ! Secondary forest area and age diagnostics + + call this%set_history_var(vname='SECONDARY_FOREST_FRACTION', units='m2/m2', & + long='Secondary forest fraction', use_default='inactive', & + avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & + ivar=ivar, initialize=initialize_variables, index = ih_fraction_secondary_forest_si ) + + call this%set_history_var(vname='SECONDARY_AREA_BY_AGE_SINCE_ANTHRO_DIST', units='m2/m2', & + long='Secondary forest patch area age distribution since anthropgenic disturbance', use_default='inactive', & + avgflag='A', vtype=site_age_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & + ivar=ivar, initialize=initialize_variables, index = ih_agesince_anthrodist_si_age ) + + call this%set_history_var(vname='SECONDARY_AREA_PATCH_AGE_DIST', units='m2/m2', & + long='Secondary forest patch area age distribution since any kind of disturbance', use_default='inactive', & + avgflag='A', vtype=site_age_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & + ivar=ivar, initialize=initialize_variables, index = ih_secondaryforest_area_si_age ) + + ! Fire Variables call this%set_history_var(vname='FIRE_NESTEROV_INDEX', units='none', & diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index a710fd922e..8504e2d439 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -7,6 +7,7 @@ module FatesRestartInterfaceMod use FatesConstantsMod , only : fates_long_string_length use FatesConstantsMod , only : itrue use FatesConstantsMod , only : ifalse + use FatesConstantsMod , only : primaryforest use FatesGlobals , only : fates_log use FatesGlobals , only : endrun => fates_endrun use FatesIODimensionsMod, only : fates_io_dimension_type @@ -129,7 +130,9 @@ module FatesRestartInterfaceMod integer, private :: ir_livegrass_pa integer, private :: ir_age_pa integer, private :: ir_area_pa - + integer, private :: ir_agesinceanthrodist_pa + integer, private :: ir_patchdistturbcat_pa + integer, private :: ir_watermem_siwm integer, private :: ir_prt_base ! Base index for all PRT variables @@ -819,6 +822,16 @@ subroutine define_restart_vars(this, initialize_variables) long_name='age of the ED patch', units='yr', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_age_pa ) + call this%set_restart_var(vname='fates_age_since_anthro_dist', vtype=cohort_r8, & + long_name='age of the ED patch since last anthropogenic disturbance', & + units='yr', flushval = flushzero, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, & + index = ir_agesinceanthrodist_pa ) + + call this%set_restart_var(vname='fates_patchdistturbcat', vtype=cohort_int, & + long_name='Disturbance label of patch', units='yr', flushval = flushzero, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_patchdistturbcat_pa ) + call this%set_restart_var(vname='fates_area', vtype=cohort_r8, & long_name='are of the ED patch', units='m2', flushval = flushzero, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_area_pa ) @@ -1149,6 +1162,8 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_spread_si => this%rvars(ir_spread_si)%r81d, & rio_livegrass_pa => this%rvars(ir_livegrass_pa)%r81d, & rio_age_pa => this%rvars(ir_age_pa)%r81d, & + rio_patchdistturbcat_pa => this%rvars(ir_patchdistturbcat_pa)%int1d, & + rio_agesinceanthrodist_pa => this%rvars(ir_agesinceanthrodist_pa)%r81d, & rio_area_pa => this%rvars(ir_area_pa)%r81d, & rio_watermem_siwm => this%rvars(ir_watermem_siwm)%r81d ) @@ -1294,6 +1309,8 @@ subroutine set_restart_vectors(this,nc,nsites,sites) ! rio_livegrass_pa(io_idx_co_1st) = cpatch%livegrass rio_age_pa(io_idx_co_1st) = cpatch%age + rio_patchdistturbcat_pa(io_idx_co_1st) = cpatch%anthro_disturbance_label + rio_agesinceanthrodist_pa(io_idx_co_1st) = cpatch%age_since_anthro_disturbance rio_area_pa(io_idx_co_1st) = cpatch%area ! set cohorts per patch for IO @@ -1516,7 +1533,7 @@ subroutine create_patchcohort_structure(this, nc, nsites, sites, bc_in) ! make new patch call create_patch(sites(s), newp, patch_age, area, & cwd_ag_local, cwd_bg_local, & - leaf_litter_local, root_litter_local,bc_in(s)%nlevsoil ) + leaf_litter_local, root_litter_local,bc_in(s)%nlevsoil, primaryforest) ! give this patch a unique patch number newp%patchno = idx_pa @@ -1725,6 +1742,8 @@ subroutine get_restart_vectors(this, nc, nsites, sites) rio_spread_si => this%rvars(ir_spread_si)%r81d, & rio_livegrass_pa => this%rvars(ir_livegrass_pa)%r81d, & rio_age_pa => this%rvars(ir_age_pa)%r81d, & + rio_patchdistturbcat_pa => this%rvars(ir_patchdistturbcat_pa)%int1d, & + rio_agesinceanthrodist_pa => this%rvars(ir_agesinceanthrodist_pa)%r81d, & rio_area_pa => this%rvars(ir_area_pa)%r81d, & rio_watermem_siwm => this%rvars(ir_watermem_siwm)%r81d ) @@ -1853,7 +1872,9 @@ subroutine get_restart_vectors(this, nc, nsites, sites) ! deal with patch level fields here ! cpatch%livegrass = rio_livegrass_pa(io_idx_co_1st) - cpatch%age = rio_age_pa(io_idx_co_1st) + cpatch%age = rio_age_pa(io_idx_co_1st) + cpatch%anthro_disturbance_label = rio_patchdistturbcat_pa(io_idx_co_1st) + cpatch%age_since_anthro_disturbance = rio_agesinceanthrodist_pa(io_idx_co_1st) cpatch%area = rio_area_pa(io_idx_co_1st) cpatch%age_class = get_age_class_index(cpatch%age) From 030b00f99639a847118cc95d6d33c5d03572094f Mon Sep 17 00:00:00 2001 From: Charles Koven Date: Tue, 18 Dec 2018 12:35:34 -0800 Subject: [PATCH 05/78] compile-time bugfixes on prior --- biogeochem/EDPatchDynamicsMod.F90 | 3 +-- main/EDInitMod.F90 | 3 ++- main/EDTypesMod.F90 | 4 ++-- main/FatesHistoryInterfaceMod.F90 | 4 ++-- main/FatesInventoryInitMod.F90 | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index e8fb3b30f5..00e513bb67 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1563,8 +1563,7 @@ subroutine fuse_patches( csite, bc_in ) profiletol = ED_val_patch_fusion_tol - nopatches_primary = 0 - nopatches_secondary = 0 + nopatches(1:n_anthro_disturbance_categories) = 0 currentPatch => currentSite%youngest_patch do while(associated(currentPatch)) nopatches(currentPatch%anthro_disturbance_label) = & diff --git a/main/EDInitMod.F90 b/main/EDInitMod.F90 index 696ba70a72..304da29003 100644 --- a/main/EDInitMod.F90 +++ b/main/EDInitMod.F90 @@ -7,6 +7,7 @@ module EDInitMod use FatesConstantsMod , only : r8 => fates_r8 use FatesConstantsMod , only : ifalse use FatesConstantsMod , only : itrue + use FatesConstantsMod , only : primaryforest use FatesGlobals , only : endrun => fates_endrun use EDTypesMod , only : nclmax use FatesGlobals , only : fates_log @@ -322,7 +323,7 @@ subroutine init_patches( nsites, sites, bc_in) ! make new patch... call create_patch(sites(s), newp, age, AREA, & cwd_ag_local, cwd_bg_local, leaf_litter_local, & - root_litter_local, bc_in(s)%nlevsoil ) + root_litter_local, bc_in(s)%nlevsoil, primaryforest ) sitep => sites(s) call init_cohorts(sitep, newp, bc_in(s)) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 1717132b59..3586821007 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -16,8 +16,8 @@ module EDTypesMod implicit none save - integer, parameter :: maxPatchesPerSite = 10 ! maximum number of patches to live on a site - integer, parameter :: maxPatchesPerSite_by_disttype(n_anthro_disturbance_categories) = (/ 5, 5 /) !!! MUST SUM TO maxPatchesPerSite !!! + integer, parameter :: maxPatchesPerSite = 14 ! maximum number of patches to live on a site + integer, parameter :: maxPatchesPerSite_by_disttype(n_anthro_disturbance_categories) = (/ 10, 4 /) !!! MUST SUM TO maxPatchesPerSite !!! integer, parameter :: maxCohortsPerPatch = 160 ! maximum number of cohorts per patch integer, parameter :: nclmax = 2 ! Maximum number of canopy layers diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 4b348b5363..43fd21caef 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -1500,8 +1500,8 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_zstar_si_age => this%hvars(ih_zstar_si_age)%r82d, & hio_biomass_si_age => this%hvars(ih_biomass_si_age)%r82d, & hio_fraction_secondary_forest_si => this%hvars(ih_fraction_secondary_forest_si)%r81d, & - hio_agesince_anthrodist_si_age => this%hvars(ih_agesince_anthrodist_si_age)%r81d, & - hio_secondaryforest_area_si_age => this%hvars(ih_secondaryforest_area_si_age)%r81d, & + hio_agesince_anthrodist_si_age => this%hvars(ih_agesince_anthrodist_si_age)%r82d, & + hio_secondaryforest_area_si_age => this%hvars(ih_secondaryforest_area_si_age)%r82d, & hio_canopy_height_dist_si_height => this%hvars(ih_canopy_height_dist_si_height)%r82d, & hio_leaf_height_dist_si_height => this%hvars(ih_leaf_height_dist_si_height)%r82d, & hio_litter_moisture_si_fuel => this%hvars(ih_litter_moisture_si_fuel)%r82d, & diff --git a/main/FatesInventoryInitMod.F90 b/main/FatesInventoryInitMod.F90 index 5c682a9f02..4ee9f9ff36 100644 --- a/main/FatesInventoryInitMod.F90 +++ b/main/FatesInventoryInitMod.F90 @@ -34,6 +34,7 @@ module FatesInventoryInitMod use EDTypesMod , only : ed_cohort_type use EDTypesMod , only : area use EDPftvarcon , only : EDPftvarcon_inst + use FatesConstantsMod, only : primaryforest implicit none @@ -254,7 +255,7 @@ subroutine initialize_sites_by_inventory(nsites,sites,bc_in) call create_patch(sites(s), newpatch, age_init, area_init, & cwd_ag_init, cwd_bg_init, & - leaf_litter_init, root_litter_init, bc_in(s)%nlevsoil ) + leaf_litter_init, root_litter_init, bc_in(s)%nlevsoil, primaryforest ) if( inv_format_list(invsite) == 1 ) then call set_inventory_edpatch_type1(newpatch,pss_file_unit,ipa,ios,patch_name) From 32880fa06fd83ad88987e8d4f5f74d352662d2e6 Mon Sep 17 00:00:00 2001 From: Charles Koven Date: Wed, 19 Dec 2018 10:16:52 -0800 Subject: [PATCH 06/78] some more bugfixes and diagnostics on secondary forest tracking --- biogeochem/EDLoggingMortalityMod.F90 | 2 +- biogeochem/EDPatchDynamicsMod.F90 | 19 +++++++++++------ main/FatesHistoryInterfaceMod.F90 | 32 ++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index 4976d3ab55..d42f67ba74 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -112,7 +112,7 @@ subroutine IsItLoggingTime(is_master,currentSite) else if(icode < 0 .and. icode > -366) then ! Logging event every year on specific day of year - if(hlm_day_of_year .eq. icode ) then + if(hlm_day_of_year .eq. abs(icode) ) then logging_time = .true. end if diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 00e513bb67..6cb47ec4d4 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -358,9 +358,11 @@ subroutine spawn_patches( currentSite, bc_in) call endrun(msg=errMsg(sourcefile, __LINE__)) end if + ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land + ! receiver patch is primary forest only if both the donor patch is primary forest and the dominant disturbance type is not logging if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) then + (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire)) ) then site_areadis_primary = site_areadis_primary + currentPatch%area * currentPatch%disturbance_rate else @@ -379,6 +381,7 @@ subroutine spawn_patches( currentSite, bc_in) age = 0.0_r8 ! create two empty patches, to absorb newly disturbed primary and secondary forest area + ! first create patch to receive primary forest area if ( site_areadis_primary .gt. 0.0_r8) then allocate(new_patch_primary) call create_patch(currentSite, new_patch_primary, age, site_areadis_primary, & @@ -388,6 +391,7 @@ subroutine spawn_patches( currentSite, bc_in) new_patch_primary%shortest => null() endif + ! next create patch to receive secondary forest area if ( site_areadis_secondary .gt. 0.0_r8) then allocate(new_patch_secondary) call create_patch(currentSite, new_patch_secondary, age, site_areadis_secondary, & @@ -402,9 +406,10 @@ subroutine spawn_patches( currentSite, bc_in) do while(associated(currentPatch)) ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land + ! receiver patch is primary forest only if both the donor patch is primary forest and the dominant disturbance type is not logging if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) then + (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) ) then new_patch => new_patch_primary else new_patch => new_patch_secondary @@ -413,11 +418,11 @@ subroutine spawn_patches( currentSite, bc_in) ! This is the amount of patch area that is disturbed, and donated by the donor patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate - ! for the secondary forest case, if the dominant disturbance from this patch is non-anthropogenic, + ! for the case where the donating patch is secondary forest, if the dominant disturbance from this patch is non-anthropogenic, ! we need to average in the time-since-anthropogenic-disturbance from the donor patch into that of the receiver patch if ( currentPatch%anthro_disturbance_label .eq. secondaryforest .and. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) then + (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) ) then new_patch%age_since_anthro_disturbance = new_patch%age_since_anthro_disturbance + & currentPatch%age_since_anthro_disturbance * (patch_site_areadis / site_areadis_secondary) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 43fd21caef..1e99ebc592 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -153,6 +153,8 @@ module FatesHistoryInterfaceMod integer, private :: ih_livestem_mr_si integer, private :: ih_livecroot_mr_si integer, private :: ih_fraction_secondary_forest_si + integer, private :: ih_biomass_secondary_forest_si + integer, private :: ih_woodproduct_si ! Indices to (site x scpf) variables integer, private :: ih_nplant_si_scpf @@ -1499,9 +1501,11 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_npatches_si_age => this%hvars(ih_npatches_si_age)%r82d, & hio_zstar_si_age => this%hvars(ih_zstar_si_age)%r82d, & hio_biomass_si_age => this%hvars(ih_biomass_si_age)%r82d, & - hio_fraction_secondary_forest_si => this%hvars(ih_fraction_secondary_forest_si)%r81d, & - hio_agesince_anthrodist_si_age => this%hvars(ih_agesince_anthrodist_si_age)%r82d, & - hio_secondaryforest_area_si_age => this%hvars(ih_secondaryforest_area_si_age)%r82d, & + hio_fraction_secondary_forest_si => this%hvars(ih_fraction_secondary_forest_si)%r81d, & + hio_biomass_secondary_forest_si => this%hvars(ih_biomass_secondary_forest_si)%r81d, & + hio_woodproduct_si => this%hvars(ih_woodproduct_si)%r81d, & + hio_agesince_anthrodist_si_age => this%hvars(ih_agesince_anthrodist_si_age)%r82d, & + hio_secondaryforest_area_si_age => this%hvars(ih_secondaryforest_area_si_age)%r82d, & hio_canopy_height_dist_si_height => this%hvars(ih_canopy_height_dist_si_height)%r82d, & hio_leaf_height_dist_si_height => this%hvars(ih_leaf_height_dist_si_height)%r82d, & hio_litter_moisture_si_fuel => this%hvars(ih_litter_moisture_si_fuel)%r82d, & @@ -1549,6 +1553,9 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_seed_bank_si(io_si) = sum(sites(s)%seed_bank) * g_per_kg hio_canopy_spread_si(io_si) = sites(s)%spread + + ! track total wood product accumulation at the site level + hio_woodproduct_si(io_si) = sites(s)%resources_management%trunk_product_site * AREA_INV ipa = 0 cpatch => sites(s)%oldest_patch @@ -1714,6 +1721,12 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_biomass_si_age(io_si,cpatch%age_class) = hio_biomass_si_age(io_si,cpatch%age_class) & + total_c * ccohort%n * AREA_INV + ! track the total biomass on all secondary lands + if ( cpatch%anthro_disturbance_label .eq. secondaryforest ) then + hio_biomass_secondary_forest_si(io_si) = hio_biomass_secondary_forest_si(io_si) + & + total_c * ccohort%n * AREA_INV + endif + ! Site by Size-Class x PFT (SCPF) ! ------------------------------------------------------------------------ @@ -3236,7 +3249,18 @@ subroutine define_history_vars(this, initialize_variables) avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_fraction_secondary_forest_si ) - call this%set_history_var(vname='SECONDARY_AREA_BY_AGE_SINCE_ANTHRO_DIST', units='m2/m2', & + call this%set_history_var(vname='WOOD_PRODUCT', units='kgC/m2', & + long='Total wood product from logging', use_default='inactive', & + avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & + ivar=ivar, initialize=initialize_variables, index = ih_woodproduct_si ) + + call this%set_history_var(vname='SECONDARY_FOREST_BIOMASS', units='kgC/m2', & + long='Biomass on secondary lands (per total site area, mult by SECONDARY_FOREST_FRACTION to get per secondary forest area)',& + use_default='inactive', & + avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & + ivar=ivar, initialize=initialize_variables, index = ih_biomass_secondary_forest_si ) + + call this%set_history_var(vname='SECONDARY_AREA_AGE_ANTHRO_DIST', units='m2/m2', & long='Secondary forest patch area age distribution since anthropgenic disturbance', use_default='inactive', & avgflag='A', vtype=site_age_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_agesince_anthrodist_si_age ) From 284a49a640cd96dd89d8b9c9b7804c864edaf356 Mon Sep 17 00:00:00 2001 From: Charles Koven Date: Thu, 20 Dec 2018 09:28:14 -0800 Subject: [PATCH 07/78] fixing units of wood product pool to be consistent with other pools --- main/FatesHistoryInterfaceMod.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 1e99ebc592..5cff6c0851 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -1555,7 +1555,8 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_canopy_spread_si(io_si) = sites(s)%spread ! track total wood product accumulation at the site level - hio_woodproduct_si(io_si) = sites(s)%resources_management%trunk_product_site * AREA_INV + hio_woodproduct_si(io_si) = sites(s)%resources_management%trunk_product_site & + * AREA_INV * g_per_kg ipa = 0 cpatch => sites(s)%oldest_patch @@ -3249,7 +3250,7 @@ subroutine define_history_vars(this, initialize_variables) avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_fraction_secondary_forest_si ) - call this%set_history_var(vname='WOOD_PRODUCT', units='kgC/m2', & + call this%set_history_var(vname='WOOD_PRODUCT', units='gC/m2', & long='Total wood product from logging', use_default='inactive', & avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_woodproduct_si ) From eb4e9011959197b32d2cf66875c64687bd135655 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Mon, 7 Jan 2019 16:56:47 -0700 Subject: [PATCH 08/78] calculate D13C from leaf internal CO2 concentration --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 37 ++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 4b181ed7b3..817976e390 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -150,6 +150,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) ! (umol CO2/m**2/s) real(r8) :: kp_z ! leaf layer initial slope of CO2 response ! curve (C4 plants) + real(r8) :: c13disc_z(nclmax,maxpft,nlevleaf) ! carbon 13 in newly assimilated carbon at leaf level real(r8) :: mm_kco2 ! Michaelis-Menten constant for CO2 (Pa) real(r8) :: mm_ko2 ! Michaelis-Menten constant for O2 (Pa) @@ -518,7 +519,8 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) lmr_z(iv,ft,cl), & ! in currentPatch%psn_z(cl,ft,iv), & ! out rs_z(iv,ft,cl), & ! out - anet_av_z(iv,ft,cl)) ! out + anet_av_z(iv,ft,cl), & ! out + c13disc_z(cl,ft,iv)) ! out rate_mask_z(iv,ft,cl) = .true. end if @@ -531,6 +533,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) currentCohort%rdark = 0.0_r8 currentCohort%resp_m = 0.0_r8 currentCohort%ts_net_uptake = 0.0_r8 + currentCohort%c13disc_clm = 0.0_r8 ! --------------------------------------------------------------- ! Part VII: Transfer leaf flux rates (like maintenance respiration, @@ -545,6 +548,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) lmr_z(1:nv,ft,cl), & !in rs_z(1:nv,ft,cl), & !in currentPatch%elai_profile(cl,ft,1:nv), & !in + c13disc_z(cl, ft, 1:nv), & !in currentCohort%c_area, & !in currentCohort%n, & !in bc_in(s)%rb_pa(ifp), & !in @@ -871,7 +875,8 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in real(r8), intent(out) :: psn_out ! carbon assimilated in this leaf layer umolC/m2/s real(r8), intent(out) :: rstoma_out ! stomatal resistance (1/gs_lsl) (s/m) real(r8), intent(out) :: anet_av_out ! net leaf photosynthesis (umol CO2/m**2/s) - ! averaged over sun and shade leaves. + ! averaged over sun and shade leaves. + real(r8), intent(out) :: c13disc_z ! carbon 13 in newly assimilated carbon ! Locals ! ------------------------------------------------------------------------ @@ -941,6 +946,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in anet_av_out = -lmr psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) + c13disc_z = 1.0_r8 !carbon 13 discrimination in night time carbon flux, value from CLM else ! day time (a little bit more complicated ...) @@ -1100,7 +1106,17 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in ! Convert gs_mol (umol /m**2/s) to gs (m/s) and then to rs (s/m) gs = gs_mol / cf - + + ! estimate carbon 13 discrimination in leaf level carbon flux Liang WEI and Hang ZHOU 2018, based on + ! Ubierna and Farquhar, 2014 doi:10.1111/pce.12346, using the simplified model: + ! $\Delta ^{13} C = \alpha_s + (b - \alpha_s) \cdot \frac{C_i}{C_a}$ + ! just hard code b and \alpha_s for now, might move to parameter set in future + ! b = 27.0 alpha_s = 4.4 + ! TODO, not considering C4 or CAM right now, may need to address this + ! note co2_inter_c is intracelluar CO2, not intercelluar + c13disc_z = 4.4_r8 + (27.0_r8 - 4.4_r8) * min (can_co2_ppress, max (co2_inter_c, 0._r8)) / can_co2_ppress + + ! if ( debug ) write(fates_log(),*) 'EDPhoto 737 ', psn_out ! if ( debug ) write(fates_log(),*) 'EDPhoto 738 ', agross ! if ( debug ) write(fates_log(),*) 'EDPhoto 739 ', f_sun_lsl @@ -1148,6 +1164,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in ! (leaves are off, or have reduced to 0) psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) + c13disc_z = 0.0_r8 end if !is there leaf area? @@ -1198,6 +1215,9 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv real(r8), intent(out) :: gpp ! GPP (kgC/indiv/s) real(r8), intent(out) :: rdark ! Dark Leaf Respiration (kgC/indiv/s) real(r8), intent(out) :: cohort_eleaf_area ! Effective leaf area of the cohort [m2] + real(r8), intent(out) :: c13disc_clm ! unpacked Cohort level c13 discrimination + real(r8) :: sum_weight ! sum of weight for unpacking d13c flux (c13disc_z) from + ! (canopy_layer, pft, leaf_layer) matrix to cohort (c13disc_clm) ! GPP IN THIS SUBROUTINE IS A RATE. THE CALLING ARGUMENT IS GPP_TSTEP. AFTER THIS ! CALL THE RATE WILL BE MULTIPLIED BY THE INTERVAL TO GIVE THE INTEGRATED QUANT. @@ -1239,6 +1259,17 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv rdark = rdark + lmr_llz(il) * cohort_layer_eleaf_area end do + + + if (nv > 1) then + ! cohort%c13disc_clm as weighted mean of d13c flux at all related leave layers + sum_weight = sum(psn_llz(1:nv-1) * elai_llz(1:nv-1)) + if (sum_weight .eq. 0.0_r8) then + c13disc_clm = 0.0 + else + c13disc_clm = sum(c13disc_llz(1:nv-1) * psn_llz(1:nv-1) * elai_llz(1:nv-1)) / sum_weight + end if + end if ! ----------------------------------------------------------------------------------- ! We DO NOT normalize g_sb_laweight. From 51bdff2c40c915d7c6ca93da1158f7637e7f8556 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Tue, 8 Jan 2019 10:15:32 -0700 Subject: [PATCH 09/78] add D13C component to EDTypes Mod --- main/EDTypesMod.F90 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 8f9457ed10..f3e898ff7a 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -237,6 +237,11 @@ module EDTypesMod real(r8) :: resp_tstep ! Autotrophic respiration (see above *) real(r8) :: resp_acc real(r8) :: resp_acc_hold + + ! carbon 13c discrimination + real(r8) :: c13disc_clm ! carbon 13 discrimination in new synthesized carbon: part-per-mil, at each indiv/timestep + real(r8) :: c13disc_acc ! carbon 13 discrimination in new synthesized carbon: part-per-mil, at each indiv/day, at the end of a day + real(r8) :: ts_net_uptake(nlevleaf) ! Net uptake of leaf layers: kgC/m2/timestep real(r8) :: year_net_uptake(nlevleaf) ! Net uptake of leaf layers: kgC/m2/year From 0f05d81f2a7608bfa849b7a43c30661b200b2b06 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Tue, 8 Jan 2019 14:53:25 -0700 Subject: [PATCH 10/78] calculate accumulated D13C and add D13C to output --- biogeochem/EDCohortDynamicsMod.F90 | 18 ++++++++++++++++++ biogeophys/EDAccumulateFluxesMod.F90 | 8 ++++++++ main/FatesHistoryInterfaceMod.F90 | 23 ++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 088ca1eabf..5771da09da 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -434,6 +434,9 @@ subroutine nan_cohort(cc_p) currentCohort%resp_acc_hold = nan ! RESP: kgC/indiv/year currentCohort%resp_tstep = nan ! RESP: kgC/indiv/timestep currentCohort%resp_acc = nan ! RESP: kGC/cohort/day + + currentCohort%c13disc_clm = nan ! C13 discrimination, per mil at indiv/timestep + currentCohort%c13disc_acc = nan ! C13 discrimination, per mil at indiv/timestep at indiv/daily at the end of a day !RESPIRATION currentCohort%rdark = nan @@ -524,6 +527,8 @@ subroutine zero_cohort(cc_p) currentcohort%prom_weight = 0._r8 currentcohort%crownfire_mort = 0._r8 currentcohort%cambial_mort = 0._r8 + currentCohort%c13disc_clm = 0._r8 + currentCohort%c13disc_acc = 0._r8 end subroutine zero_cohort @@ -869,6 +874,15 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%canopy_trim = (currentCohort%n*currentCohort%canopy_trim & + nextc%n*nextc%canopy_trim)/newn + + ! c13disc_acc calculation; weighted mean by GPP + if ((currentCohort%n * currentCohort%gpp_acc + nextc%n * nextc%gpp_acc) .eq. 0.0_r8) then + currentCohort%c13disc_acc = 0.0_r8 + else + currentCohort%c13disc_acc = (currentCohort%n * currentCohort%gpp_acc * currentCohort%c13disc_acc + & + nextc%n * nextc%gpp_acc * nextc%c13disc_acc)/ & + (currentCohort%n * currentCohort%gpp_acc + nextc%n * nextc%gpp_acc) + endif ! ----------------------------------------------------------------- ! If fusion pushed structural biomass to be larger than @@ -1335,6 +1349,10 @@ subroutine copy_cohort( currentCohort,copyc ) n%year_net_uptake = o%year_net_uptake n%ts_net_uptake = o%ts_net_uptake + ! C13 discrimination + n%c13disc_clm = o%c13disc_clm + n%c13disc_acc = o%c13disc_acc + !RESPIRATION n%rdark = o%rdark n%resp_m = o%resp_m diff --git a/biogeophys/EDAccumulateFluxesMod.F90 b/biogeophys/EDAccumulateFluxesMod.F90 index f421c5594e..43e53bfa5f 100644 --- a/biogeophys/EDAccumulateFluxesMod.F90 +++ b/biogeophys/EDAccumulateFluxesMod.F90 @@ -83,6 +83,14 @@ subroutine AccumulateFluxes_ED(nsites, sites, bc_in, bc_out, dt_time) ccohort%npp_acc = ccohort%npp_acc + ccohort%npp_tstep ccohort%gpp_acc = ccohort%gpp_acc + ccohort%gpp_tstep ccohort%resp_acc = ccohort%resp_acc + ccohort%resp_tstep + + ! weighted mean of D13C by gpp + if((ccohort%gpp_acc + ccohort%gpp_tstep) .eq. 0.0_r8) then + ccohort%c13disc_acc = 0.0_r8 + else + ccohort%c13disc_acc = ((ccohort%c13disc_acc * ccohort%gpp_acc) + (ccohort%c13disc_clm * ccohort%gpp_tstep)) / & + (ccohort%gpp_acc + ccohort%gpp_tstep) + endif !----- THE FOLLOWING IS ONLY IMPLEMENTED TEMPORARILY FOR B4B reproducibility !----- ALSO, THERE IS NO REASON TO USE THE ISNEW FLAG HERE diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 9913aeca3f..47b9c58bf6 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -210,6 +210,8 @@ module FatesHistoryInterfaceMod integer, private :: ih_ar_agsapm_si_scpf integer, private :: ih_ar_crootm_si_scpf integer, private :: ih_ar_frootm_si_scpf + + integer, private :: ih_c13disc_si_scpf ! indices to (site x scls) variables @@ -1318,6 +1320,8 @@ subroutine update_history_dyn(this,nc,nsites,sites) real(r8) :: npp_partition_error ! a check that the NPP partitions sum to carbon allocation real(r8) :: frac_canopy_in_bin ! fraction of a leaf's canopy that is within a given height bin real(r8) :: binbottom,bintop ! edges of height bins + + real(r8) :: gpp_cached ! variable used to cache gpp value in previous time step; for C13 discrimination ! The following are all carbon states, turnover and net allocation flux variables ! the organs of relevance should be self explanatory @@ -1444,7 +1448,9 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_m5_si_scls => this%hvars(ih_m5_si_scls)%r82d, & hio_m6_si_scls => this%hvars(ih_m6_si_scls)%r82d, & hio_m7_si_scls => this%hvars(ih_m7_si_scls)%r82d, & - hio_m8_si_scls => this%hvars(ih_m8_si_scls)%r82d, & + hio_m8_si_scls => this%hvars(ih_m8_si_scls)%r82d, & + + hio_c13disc_si_scpf => this%hvars(ih_c13disc_si_scpf)%r82d, & hio_ba_si_scls => this%hvars(ih_ba_si_scls)%r82d, & hio_agb_si_scls => this%hvars(ih_agb_si_scls)%r82d, & @@ -1795,6 +1801,16 @@ subroutine update_history_dyn(this,nc,nsites,sites) (ccohort%lmort_direct+ccohort%lmort_collateral+ccohort%lmort_infra) * ccohort%n hio_m8_si_scls(io_si,scls) = hio_m8_si_scls(io_si,scls) + & ccohort%frmort*ccohort%n + + !C13 discrimination + if(gpp_cached + ccohort%gpp_acc_hold>0._r8)then + hio_c13disc_si_scpf(io_si,scpf) = ((hio_c13disc_si_scpf(io_si,scpf) * gpp_cached) + & + (ccohort%c13disc_acc * ccohort%gpp_acc_hold)) / (gpp_cached + ccohort%gpp_acc_hold) + else + hio_c13disc_si_scpf(io_si,scpf) = 0.0_r8 + endif + + ! basal area [m2/ha] hio_ba_si_scpf(io_si,scpf) = hio_ba_si_scpf(io_si,scpf) + & @@ -3973,6 +3989,11 @@ subroutine define_history_vars(this, initialize_variables) avgflag='A', vtype=site_size_pft_r8, hlms='CLM:ALM', flushval=0.0_r8, & upfreq=1, ivar=ivar, initialize=initialize_variables, index = ih_mortality_canopy_si_scpf ) + call this%set_history_var(vname='C13disc_SCPF', units = 'per mil', & + long='C13 discrimination by pft/size',use_default='inactive', & + avgflag='A', vtype=site_size_pft_r8, hlms='CLM:ALM', flushval=0.0_r8, & + upfreq=1, ivar=ivar, initialize=initialize_variables, index = ih_c13disc_si_scpf ) + call this%set_history_var(vname='BSTOR_CANOPY_SCPF', units = 'kgC/ha', & long='biomass carbon in storage pools of canopy plants by pft/size', use_default='inactive', & avgflag='A', vtype=site_size_pft_r8, hlms='CLM:ALM', flushval=0.0_r8, & From 3145044e5027ee90ca71593c8c35efd5857577fc Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Thu, 10 Jan 2019 14:53:32 -0700 Subject: [PATCH 11/78] add varibles for accumulated D13C flux --- parameter_files/fates_params_hydro_default.cdl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parameter_files/fates_params_hydro_default.cdl b/parameter_files/fates_params_hydro_default.cdl index e6e3adfbec..21333fe8be 100644 --- a/parameter_files/fates_params_hydro_default.cdl +++ b/parameter_files/fates_params_hydro_default.cdl @@ -923,11 +923,11 @@ data: fates_pft_used = 1, 1 ; - fates_phen_evergreen = 1, 1 ; + fates_phen_evergreen = 1, 0 ; fates_phen_season_decid = 0, 0 ; - fates_phen_stress_decid = 0, 0 ; + fates_phen_stress_decid = 0, 1 ; fates_prescribed_mortality_canopy = 0.0194, 0.0194 ; From 766e65699cabfd55ebfd68b3bc2304c106925028 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Tue, 15 Jan 2019 10:39:26 -0700 Subject: [PATCH 12/78] change the value of d13 discrimination during the night --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 817976e390..877d24250c 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -946,7 +946,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in anet_av_out = -lmr psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) - c13disc_z = 1.0_r8 !carbon 13 discrimination in night time carbon flux, value from CLM + c13disc_z = 0.0_r8 !carbon 13 discrimination in night time carbon flux, note value of 1.0 is used in CLM else ! day time (a little bit more complicated ...) From 6bb1b3cb8ea9b152452db320d36a9784b74cbacd Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Tue, 15 Jan 2019 16:03:57 -0700 Subject: [PATCH 13/78] resolving issue after merge --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 877d24250c..7d51d4031c 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -556,6 +556,7 @@ subroutine FatesPlantRespPhotosynthDrive (nsites, sites,bc_in,bc_out,dtime) currentCohort%g_sb_laweight, & !out currentCohort%gpp_tstep, & !out currentCohort%rdark, & !out + currentCohort%c13disc_clm, & !out cohort_eleaf_area) !out ! Net Uptake does not need to be scaled, just transfer directly @@ -820,8 +821,9 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in lmr, & ! in psn_out, & ! out rstoma_out, & ! out - anet_av_out) ! out - + anet_av_out, & ! out + c13disc_z) ! out + ! ------------------------------------------------------------------------------------ ! This subroutine calculates photosynthesis and stomatal conductance within each leaf ! sublayer. @@ -1181,6 +1183,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv lmr_llz, & ! in lmr_z(1:currentCohort%nv,ft,cl) rs_llz, & ! in rs_z(1:currentCohort%nv,ft,cl) elai_llz, & ! in %elai_profile(cl,ft,1:currentCohort%nv) + c13disc_llz, & ! in c13disc_z(cl, ft, 1:currentCohort%nv) c_area, & ! in currentCohort%c_area nplant, & ! in currentCohort%n rb, & ! in bc_in(s)%rb_pa(ifp) @@ -1188,6 +1191,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv g_sb_laweight, & ! out currentCohort%g_sb_laweight [m/s] [m2-leaf] gpp, & ! out currentCohort%gpp_tstep rdark, & ! out currentCohort%rdark + c13disc_clm, & ! out currentCohort%c13disc_clm cohort_eleaf_area ) ! out [m2] ! ------------------------------------------------------------------------------------ @@ -1206,6 +1210,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv real(r8), intent(in) :: lmr_llz(nv) ! layer dark respiration rate [umolC/m2leaf/s] real(r8), intent(in) :: rs_llz(nv) ! leaf layer stomatal resistance [s/m] real(r8), intent(in) :: elai_llz(nv) ! exposed LAI per layer [m2 leaf/ m2 pft footprint] + real(r8), intent(in) :: c13disc_llz(nv) ! leaf layer c13 discrimination, weighted mean real(r8), intent(in) :: c_area ! crown area m2/m2 real(r8), intent(in) :: nplant ! indiv/m2 real(r8), intent(in) :: rb ! leaf boundary layer resistance (s/m) From 9c37d0dca048b80d3009eaf885338feb00a0410e Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Thu, 17 Jan 2019 10:09:21 -0700 Subject: [PATCH 14/78] fixed issue in merging master and D13C component --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 2 ++ main/FatesHistoryInterfaceMod.F90 | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 7d51d4031c..e8b7bd4605 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -1166,6 +1166,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in ! (leaves are off, or have reduced to 0) psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) + c13disc_z = 0.0_r8 end if !is there leaf area? @@ -1265,6 +1266,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv end do + if (nv > 1) then ! cohort%c13disc_clm as weighted mean of d13c flux at all related leave layers diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 47b9c58bf6..d74e0979ac 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -1450,7 +1450,7 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_m7_si_scls => this%hvars(ih_m7_si_scls)%r82d, & hio_m8_si_scls => this%hvars(ih_m8_si_scls)%r82d, & - hio_c13disc_si_scpf => this%hvars(ih_c13disc_si_scpf)%r82d, & + hio_c13disc_si_scpf => this%hvars(ih_c13disc_si_scpf)%r82d, & hio_ba_si_scls => this%hvars(ih_ba_si_scls)%r82d, & hio_agb_si_scls => this%hvars(ih_agb_si_scls)%r82d, & @@ -1758,6 +1758,8 @@ subroutine update_history_dyn(this,nc,nsites,sites) associate( scpf => ccohort%size_by_pft_class, & scls => ccohort%size_class ) + + gpp_cached = hio_gpp_si_scpf(io_si,scpf) hio_gpp_si_scpf(io_si,scpf) = hio_gpp_si_scpf(io_si,scpf) + & n_perm2*ccohort%gpp_acc_hold ! [kgC/m2/yr] @@ -1803,7 +1805,7 @@ subroutine update_history_dyn(this,nc,nsites,sites) ccohort%frmort*ccohort%n !C13 discrimination - if(gpp_cached + ccohort%gpp_acc_hold>0._r8)then + if(gpp_cached + ccohort%gpp_acc_hold > 0.0_r8)then hio_c13disc_si_scpf(io_si,scpf) = ((hio_c13disc_si_scpf(io_si,scpf) * gpp_cached) + & (ccohort%c13disc_acc * ccohort%gpp_acc_hold)) / (gpp_cached + ccohort%gpp_acc_hold) else From 8ab4c78a86eb0eb256415f701c02cb41e987c45e Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Mon, 7 Jan 2019 16:56:47 -0700 Subject: [PATCH 15/78] calculate the the D13C from leaf Ci --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index e8b7bd4605..0bcf95aa09 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -948,7 +948,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in anet_av_out = -lmr psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) - c13disc_z = 0.0_r8 !carbon 13 discrimination in night time carbon flux, note value of 1.0 is used in CLM + c13disc_z = 1.0_r8 !carbon 13 discrimination in night time carbon flux, value from CLM else ! day time (a little bit more complicated ...) @@ -1166,7 +1166,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in ! (leaves are off, or have reduced to 0) psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) - + c13disc_z = 0.0_r8 end if !is there leaf area? @@ -1266,7 +1266,6 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv end do - if (nv > 1) then ! cohort%c13disc_clm as weighted mean of d13c flux at all related leave layers @@ -1274,8 +1273,9 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv if (sum_weight .eq. 0.0_r8) then c13disc_clm = 0.0 else - c13disc_clm = sum(c13disc_llz(1:nv-1) * psn_llz(1:nv-1) * elai_llz(1:nv-1)) / sum_weight - end if + c13disc_clm = sum(c13disc_llz(1:nv-1) * psn_llz(1:nv-1) * elai_llz(1:nv-1)) / sum_weight + end if + end if ! ----------------------------------------------------------------------------------- From 17ef9fddac6a81bb5d26f7c13d8184644695cfb6 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Mon, 7 Jan 2019 17:35:57 -0700 Subject: [PATCH 16/78] clean the codes for D13C during rebase --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 0bcf95aa09..9782ee70d9 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -823,7 +823,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in rstoma_out, & ! out anet_av_out, & ! out c13disc_z) ! out - + ! ------------------------------------------------------------------------------------ ! This subroutine calculates photosynthesis and stomatal conductance within each leaf ! sublayer. From a42b48a0670d08c0e468c7ae691fbf4bf22289e8 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Tue, 8 Jan 2019 14:53:25 -0700 Subject: [PATCH 17/78] add the D13C to the FATES output --- main/FatesHistoryInterfaceMod.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index d74e0979ac..06a74075fe 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -1449,9 +1449,9 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_m6_si_scls => this%hvars(ih_m6_si_scls)%r82d, & hio_m7_si_scls => this%hvars(ih_m7_si_scls)%r82d, & hio_m8_si_scls => this%hvars(ih_m8_si_scls)%r82d, & - hio_c13disc_si_scpf => this%hvars(ih_c13disc_si_scpf)%r82d, & + hio_ba_si_scls => this%hvars(ih_ba_si_scls)%r82d, & hio_agb_si_scls => this%hvars(ih_agb_si_scls)%r82d, & hio_biomass_si_scls => this%hvars(ih_biomass_si_scls)%r82d, & @@ -1806,6 +1806,7 @@ subroutine update_history_dyn(this,nc,nsites,sites) !C13 discrimination if(gpp_cached + ccohort%gpp_acc_hold > 0.0_r8)then + hio_c13disc_si_scpf(io_si,scpf) = ((hio_c13disc_si_scpf(io_si,scpf) * gpp_cached) + & (ccohort%c13disc_acc * ccohort%gpp_acc_hold)) / (gpp_cached + ccohort%gpp_acc_hold) else From f603ab1ca235268fc7bc954615a5c018ad3392f4 Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Tue, 15 Jan 2019 10:39:26 -0700 Subject: [PATCH 18/78] change the value of d13 discrimination during the night --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 9782ee70d9..d5643a84db 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -948,7 +948,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in anet_av_out = -lmr psn_out = 0._r8 rstoma_out = min(rsmax0, 1._r8/bbb * cf) - c13disc_z = 1.0_r8 !carbon 13 discrimination in night time carbon flux, value from CLM + c13disc_z = 0.0_r8 !carbon 13 discrimination in night time carbon flux, note value of 1.0 is used in CLM else ! day time (a little bit more complicated ...) From 3a67d5b2014d88aadbb8c9cbec380bb3934aedbf Mon Sep 17 00:00:00 2001 From: Chonggang Xu Date: Wed, 16 Jan 2019 12:01:45 -0700 Subject: [PATCH 19/78] fix calulating aggreated D13C --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index d5643a84db..02ffd2321c 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -1263,10 +1263,11 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv ! Dark respiration ! [umolC/m2leaf/s] * [m2 leaf] (This is the cohort group sum) rdark = rdark + lmr_llz(il) * cohort_layer_eleaf_area - + end do + if (nv > 1) then ! cohort%c13disc_clm as weighted mean of d13c flux at all related leave layers sum_weight = sum(psn_llz(1:nv-1) * elai_llz(1:nv-1)) @@ -1278,6 +1279,7 @@ subroutine ScaleLeafLayerFluxToCohort(nv, & ! in currentCohort%nv end if + ! ----------------------------------------------------------------------------------- ! We DO NOT normalize g_sb_laweight. ! The units that we are passing back are [m/s] * [m2 effective leaf] From 8e94d3c7af965ce8ffabd511458a624126100f16 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 22 Jan 2019 15:16:19 -0800 Subject: [PATCH 20/78] Moved a patch pointer to inside some logic preventing it pointing to a null() --- biogeochem/EDPatchDynamicsMod.F90 | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index e7db3e9880..4ccb383f7a 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -413,15 +413,6 @@ subroutine spawn_patches( currentSite, bc_in) ! loop round all the patches that contribute surviving indivduals and litter pools to the new patch. do while(associated(currentPatch)) - ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land - ! receiver patch is primary forest only if both the donor patch is primary forest and the dominant disturbance type is not logging - if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & - (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) ) then - new_patch => new_patch_primary - else - new_patch => new_patch_secondary - endif ! This is the amount of patch area that is disturbed, and donated by the donor patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate @@ -429,6 +420,17 @@ subroutine spawn_patches( currentSite, bc_in) if (patch_site_areadis > nearzero ) then + ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land + ! receiver patch is primary forest only if both the donor patch is primary forest and the dominant disturbance type is not logging + if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & + (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & + currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) ) then + new_patch => new_patch_primary + else + new_patch => new_patch_secondary + endif + + ! for the case where the donating patch is secondary forest, if the dominant disturbance from this patch is non-anthropogenic, ! we need to average in the time-since-anthropogenic-disturbance from the donor patch into that of the receiver patch if ( currentPatch%anthro_disturbance_label .eq. secondaryforest .and. & From 7d49bef8337204fdeca11ca08a938283b8c50bdb Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Sat, 16 Feb 2019 14:32:24 -0800 Subject: [PATCH 21/78] reincorporated old conservation-of-dbh logic as an option in a case select --- biogeochem/EDCohortDynamicsMod.F90 | 96 +++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 006090dc6d..5dcb3b02a0 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -91,6 +91,12 @@ module EDCohortDynamicsMod character(len=*), parameter, private :: sourcefile = & __FILE__ + + integer, parameter, private :: conserve_crownarea_and_number_not_dbh = 1 + integer, parameter, private :: conserve_dbh_and_number_not_crownarea = 2 + + integer, parameter, private :: cohort_fusion_conservation_method = conserve_crownarea_and_number_not_dbh + ! 10/30/09: Created by Rosie Fisher !-------------------------------------------------------------------------------------! @@ -870,27 +876,77 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%canopy_trim = (currentCohort%n*currentCohort%canopy_trim & + nextc%n*nextc%canopy_trim)/newn - ! conserve total crown area during the fusion step, and then calculate - ! dbh of the fused cohort as that which conserves both crown area and - ! the dbh to crown area allometry. dbh will be updated in the next - ! growth step in the (likely) event that dbh to structural iomass - ! allometry is exceeded. if using a capped crown area allometry and - ! above the cap, then calculate as the weighted average of fusing - ! cohorts' dbh - - currentCohort%c_area = currentCohort%c_area + nextc%c_area - - call carea_allom(dbh,newn,currentSite%spread,currentCohort%pft,& - currentCohort%c_area,inverse=.true.) - - if (abs(dbh-fates_unset_r8) Date: Wed, 20 Feb 2019 21:59:43 -0800 Subject: [PATCH 22/78] added some comments to help explain whats going on here. --- main/FatesHistoryInterfaceMod.F90 | 65 +++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 9913aeca3f..921fd35607 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -45,8 +45,65 @@ module FatesHistoryInterfaceMod ! These variables hold the index of the history output structure so we don't ! have to constantly do name lookup when we want to populate the dataset ! These indices are set during "define_history_vars()" call to "set_history_var()" - ! during the initialize phase. Definitions are not provide, for an explanation of + ! during the initialize phase. Definitions are not provided, for an explanation of ! the variable go to its registry. (IH_ signifies "index history") + ! + ! Because of the complex sub-gridscale structure of FATES, in which multiple patches and cohorts + ! exist within a gridcell, along with vertical gradients within and between canopy layers, as well + ! as distinct classes such as PFTs or fuel size bins, there are multiple different dimensions in + ! which it is possible to output history variables to better understand what's going on. + ! + ! a key point is that, while the number of patches or cohorts can in principle be large, and the age + ! and size indices of a given patch or cohort can be finely resolved, we collapse these continuously- + ! varying indices into bins of time-invariant width for the purposes of history outputting. This is + ! because a given patch or cohort may not persist across a given interval of history averaging, so + ! it is better to output all patches of cohorts whose index is within a given interval along the size + ! or age bin. + ! + ! Another particularity of the issue of FATES shifting its subgrid structure frequently and possibly having + ! multiple (or zero) patches or cohorts within a given bin is that, if you want to output an average + ! quantities across some dimension, such as a mean carbon flux across patch area of a given age, in general + ! it is better to output both the numerator and denominator of the averaging calculation separately, + ! rather than the average itself, and then calculate the average in post-processing. So, e.g. + ! this means outputting both the patch area and the product of the flux within each patch and the patch area + ! as separate variables. Doing this allows conservation even when the weights are changing rapidly and + ! simplifies the logic when the number of patches or cohorts may be anywhere from zero to a large number. + ! + ! So what this means is that anything that is disaggregated at the patch area requires outputting the patch age + ! distribution (in units of patch area / site area) as the denominator of the average and then calculating the numerator of + ! the average as XXX times the patch area so (so in units of XXX * patch area / site area). For cohort-level quantities, + ! this requires outputting the number density (in units of individuals per site area), etc. + ! + ! For reference, some standardized abbreviations of the FATES dimensions are listed here: + ! scls = size-class dimension + ! pft = the pft dimension + ! age = the age bin dimension + ! height = the height bin dimension + ! cwdsc = the coarse woody debris size class dimension + ! + ! Since the netcdf interface can only handle variables with a certain number of dimensions, + ! we have create some "multiplexed" dimensions that combine two or more dimensions into a + ! single dimension. Examples of these are the following: + ! scpf = size class x PFT + ! cnlf = canopy layer x leaf layer + ! cnlfpft = canopy layer x leaf layer x PFT + ! scag = size class bin x age bin + ! scagpft = size class bin x age bin x PFT + ! agepft = age bin x PFT + ! + ! A recipe for adding a new history variable to this module: + ! (1) decide what time frequency it makes sense to update the variable at, and what dimension(s) + ! you want to output the variable on + ! (2) add the ih_ integer variable in the immediately following section of the module. Use the suffix as outlined + ! above for the dimension you are using. + ! (3) define a corresponding hio_ variable by associating it to the ih_ variable in the associate section + ! of the subroutine that corresponds to the time-updating frequency that you've chosen + ! (i.e. if half-hourly, then work in subroutine update_history_prod; if daily, then work in subroutine update_history_dyn) + ! (4) within that subroutine, add the logic that passes the information from the fates-native variable + ! (possibly on a patch or cohort structure) to the history hio_ variable that you've associated to. + ! (5) add the variable name, metadata, units, dimension, updating frequency, the ih_ variable index, etc via a call + ! to the set_history_var method in the subroutine define_history_vars. + ! ! Indices to 1D Patch variables @@ -158,8 +215,8 @@ module FatesHistoryInterfaceMod integer, private :: ih_h2oveg_growturn_err_si integer, private :: ih_h2oveg_pheno_err_si integer, private :: ih_h2oveg_hydro_err_si - - ! Indices to (site x scpf) variables + + ! Indices to (site x scpf [multiplexed size- and age- bins]) variables integer, private :: ih_nplant_si_scpf integer, private :: ih_gpp_si_scpf integer, private :: ih_npp_totl_si_scpf @@ -212,7 +269,7 @@ module FatesHistoryInterfaceMod integer, private :: ih_ar_frootm_si_scpf - ! indices to (site x scls) variables + ! indices to (site x scls [size class bins]) variables integer, private :: ih_ba_si_scls integer, private :: ih_nplant_si_scls integer, private :: ih_nplant_canopy_si_scls From 6c2ce195f7d5022453cede94e811770b6d1da7bb Mon Sep 17 00:00:00 2001 From: rosiealice Date: Thu, 21 Feb 2019 02:38:14 -0700 Subject: [PATCH 23/78] modified smoothing parameters to 0.999 --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index aee00f745c..8337a4b67c 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -926,10 +926,10 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in real(r8),parameter,dimension(0:1) :: quant_eff = [0.05_r8,0.0_r8] ! empirical curvature parameter for ac, aj photosynthesis co-limitation - real(r8),parameter,dimension(0:1) :: theta_cj = [0.80_r8,0.98_r8] + real(r8),parameter,dimension(0:1) :: theta_cj = [0.999_r8,0.999_r8] ! empirical curvature parameter for ap photosynthesis co-limitation - real(r8),parameter :: theta_ip = 0.95_r8 + real(r8),parameter :: theta_ip = 0.9999_r8 associate( bb_slope => EDPftvarcon_inst%BB_slope) ! slope of BB relationship From 9e8354e740f4f59ee578cc468ef0fcd3205e30b4 Mon Sep 17 00:00:00 2001 From: rosiealice Date: Thu, 21 Feb 2019 03:15:38 -0700 Subject: [PATCH 24/78] added comment --- biogeophys/FatesPlantRespPhotosynthMod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/biogeophys/FatesPlantRespPhotosynthMod.F90 b/biogeophys/FatesPlantRespPhotosynthMod.F90 index 8337a4b67c..f56eea19cf 100644 --- a/biogeophys/FatesPlantRespPhotosynthMod.F90 +++ b/biogeophys/FatesPlantRespPhotosynthMod.F90 @@ -925,11 +925,13 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in ! quantum efficiency, used only for C4 (mol CO2 / mol photons) (index 0) real(r8),parameter,dimension(0:1) :: quant_eff = [0.05_r8,0.0_r8] - ! empirical curvature parameter for ac, aj photosynthesis co-limitation + ! empirical curvature parameter for ac, aj photosynthesis co-limitation. + ! Changed theta_cj and theta_ip to 0.999 to effectively remove smoothing logic + ! following Anthony Walker's findings from MAAT. real(r8),parameter,dimension(0:1) :: theta_cj = [0.999_r8,0.999_r8] ! empirical curvature parameter for ap photosynthesis co-limitation - real(r8),parameter :: theta_ip = 0.9999_r8 + real(r8),parameter :: theta_ip = 0.999_r8 associate( bb_slope => EDPftvarcon_inst%BB_slope) ! slope of BB relationship From 8cba913ae2c81bbafd20c4344d1eae6e713c35dc Mon Sep 17 00:00:00 2001 From: rosiealice Date: Thu, 21 Feb 2019 08:01:31 -0700 Subject: [PATCH 25/78] removed extra patch loop for seed rain --- biogeochem/EDPhysiologyMod.F90 | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 80738a1bd8..747879ce08 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -888,19 +888,15 @@ subroutine seeds_in( currentSite, cp_pnt ) endif - currentPatch => currentSite%oldest_patch - - do while(associated(currentPatch)) - if (external_recruitment == 1) then !external seed rain - needed to prevent extinction - do p = 1,numpft - currentPatch%seeds_in(p) = currentPatch%seeds_in(p) + & + if (external_recruitment == 1) then !external seed rain - needed to prevent extinction + do p = 1,numpft + currentPatch%seeds_in(p) = currentPatch%seeds_in(p) + & EDPftvarcon_inst%seed_rain(p) !KgC/m2/year - currentSite%seed_rain_flux(p) = currentSite%seed_rain_flux(p) + & + currentSite%seed_rain_flux(p) = currentSite%seed_rain_flux(p) + & EDPftvarcon_inst%seed_rain(p) * currentPatch%area/AREA !KgC/m2/year - enddo - endif - currentPatch => currentPatch%younger - enddo + enddo + endif + end subroutine seeds_in From 149d6baa300d0ffe6ab89c8a2988a74d9b0976e7 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 21 Feb 2019 10:07:25 -0800 Subject: [PATCH 26/78] Shortened line lengths in FatesHistoryInterfaceMod --- main/FatesHistoryInterfaceMod.F90 | 57 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 921fd35607..2c5de7f766 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -53,25 +53,27 @@ module FatesHistoryInterfaceMod ! as distinct classes such as PFTs or fuel size bins, there are multiple different dimensions in ! which it is possible to output history variables to better understand what's going on. ! - ! a key point is that, while the number of patches or cohorts can in principle be large, and the age - ! and size indices of a given patch or cohort can be finely resolved, we collapse these continuously- - ! varying indices into bins of time-invariant width for the purposes of history outputting. This is - ! because a given patch or cohort may not persist across a given interval of history averaging, so - ! it is better to output all patches of cohorts whose index is within a given interval along the size - ! or age bin. + ! a key point is that, while the number of patches or cohorts can in principle be large, and + ! the age and size indices of a given patch or cohort can be finely resolved, we collapse these + ! continuously varying indices into bins of time-invariant width for the purposes of history + ! outputting. This is because a given patch or cohort may not persist across a given interval + ! of history averaging, so it is better to output all patches of cohorts whose index is within + ! a given interval along the size or age bin. ! - ! Another particularity of the issue of FATES shifting its subgrid structure frequently and possibly having - ! multiple (or zero) patches or cohorts within a given bin is that, if you want to output an average - ! quantities across some dimension, such as a mean carbon flux across patch area of a given age, in general - ! it is better to output both the numerator and denominator of the averaging calculation separately, - ! rather than the average itself, and then calculate the average in post-processing. So, e.g. - ! this means outputting both the patch area and the product of the flux within each patch and the patch area - ! as separate variables. Doing this allows conservation even when the weights are changing rapidly and - ! simplifies the logic when the number of patches or cohorts may be anywhere from zero to a large number. + ! Another particularity of the issue of FATES shifting its subgrid structure frequently + ! and possibly having multiple (or zero) patches or cohorts within a given bin is that, if you + ! want to output an average quantities across some dimension, such as a mean carbon flux across + ! patch area of a given age, in general it is better to output both the numerator and denominator + ! of the averaging calculation separately, rather than the average itself, and then calculate + ! the average in post-processing. So, e.g. this means outputting both the patch area and the + ! product of the flux within each patch and the patch area as separate variables. Doing this + ! allows conservation even when the weights are changing rapidly and simplifies the logic when + ! the number of patches or cohorts may be anywhere from zero to a large number. ! - ! So what this means is that anything that is disaggregated at the patch area requires outputting the patch age - ! distribution (in units of patch area / site area) as the denominator of the average and then calculating the numerator of - ! the average as XXX times the patch area so (so in units of XXX * patch area / site area). For cohort-level quantities, + ! So what this means is that anything that is disaggregated at the patch area requires + ! outputting the patch age distribution (in units of patch area / site area) as the denominator + ! of the average and then calculating the numerator of the average as XXX times the patch + ! area so (so in units of XXX * patch area / site area). For cohort-level quantities, ! this requires outputting the number density (in units of individuals per site area), etc. ! ! For reference, some standardized abbreviations of the FATES dimensions are listed here: @@ -94,15 +96,18 @@ module FatesHistoryInterfaceMod ! A recipe for adding a new history variable to this module: ! (1) decide what time frequency it makes sense to update the variable at, and what dimension(s) ! you want to output the variable on - ! (2) add the ih_ integer variable in the immediately following section of the module. Use the suffix as outlined - ! above for the dimension you are using. - ! (3) define a corresponding hio_ variable by associating it to the ih_ variable in the associate section - ! of the subroutine that corresponds to the time-updating frequency that you've chosen - ! (i.e. if half-hourly, then work in subroutine update_history_prod; if daily, then work in subroutine update_history_dyn) - ! (4) within that subroutine, add the logic that passes the information from the fates-native variable - ! (possibly on a patch or cohort structure) to the history hio_ variable that you've associated to. - ! (5) add the variable name, metadata, units, dimension, updating frequency, the ih_ variable index, etc via a call - ! to the set_history_var method in the subroutine define_history_vars. + ! (2) add the ih_ integer variable in the immediately following section of the module. + ! use the suffix as outlined above for the dimension you are using. + ! (3) define a corresponding hio_ variable by associating it to the ih_ variable + ! in the associate section of the subroutine that corresponds to the time-updating + ! frequency that you've chosen + ! (i.e. if half-hourly, then work in subroutine update_history_prod; if daily, + ! then work in subroutine update_history_dyn) + ! (4) within that subroutine, add the logic that passes the information from the + ! fates-native variable (possibly on a patch or cohort structure) to the history + ! hio_ variable that you've associated to. + ! (5) add the variable name, metadata, units, dimension, updating frequency, the ih_ variable + ! index, etc via a call to the set_history_var method in the subroutine define_history_vars. ! ! Indices to 1D Patch variables From 080c6e6ee2cbe83f900e08c4aa6e2df16508c531 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Thu, 21 Feb 2019 17:18:09 -0800 Subject: [PATCH 27/78] started to add in the degradation of forest associated with non-clearcut logging --- biogeochem/EDCohortDynamicsMod.F90 | 22 ++++++++++------------ biogeochem/EDLoggingMortalityMod.F90 | 9 ++++++++- biogeochem/EDPatchDynamicsMod.F90 | 5 +++-- main/EDTypesMod.F90 | 8 +++++--- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 999708e81a..4c0b410d7b 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -505,9 +505,12 @@ subroutine nan_cohort(cc_p) ! ALLOCATION currentCohort%dmort = nan ! proportional mortality rate. (year-1) + + ! logging currentCohort%lmort_direct = nan currentCohort%lmort_infra = nan currentCohort%lmort_collateral = nan + currentCohort%l_degrad = nan currentCohort%seed_prod = nan ! reproduction seed and clonal: KgC/indiv/year @@ -579,6 +582,7 @@ subroutine zero_cohort(cc_p) currentCohort%lmort_direct = 0._r8 currentCohort%lmort_infra = 0._r8 currentCohort%lmort_collateral = 0._r8 + currentCohort%l_degrad = 0._r8 currentCohort%leaf_cost = 0._r8 currentcohort%excl_weight = 0._r8 currentcohort%prom_weight = 0._r8 @@ -1021,12 +1025,6 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%dmort = (currentCohort%n*currentCohort%dmort + & nextc%n*nextc%dmort)/newn - currentCohort%lmort_direct = (currentCohort%n*currentCohort%lmort_direct + & - nextc%n*nextc%lmort_direct)/newn - currentCohort%lmort_infra = (currentCohort%n*currentCohort%lmort_infra + & - nextc%n*nextc%lmort_infra)/newn - currentCohort%lmort_collateral = (currentCohort%n*currentCohort%lmort_collateral + & - nextc%n*nextc%lmort_collateral)/newn currentCohort%fire_mort = (currentCohort%n*currentCohort%fire_mort + & nextc%n*nextc%fire_mort)/newn @@ -1044,7 +1042,9 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) nextc%n*nextc%lmort_collateral)/newn currentCohort%lmort_infra = (currentCohort%n*currentCohort%lmort_infra + & nextc%n*nextc%lmort_infra)/newn - + currentCohort%l_degrad = (currentCohort%n*currentCohort%l_degrad + & + nextc%n*nextc%l_degrad)/newn + ! biomass and dbh tendencies currentCohort%ddbhdt = (currentCohort%n*currentCohort%ddbhdt + & nextc%n*nextc%ddbhdt)/newn @@ -1415,9 +1415,6 @@ subroutine copy_cohort( currentCohort,copyc ) ! ALLOCATION n%dmort = o%dmort - n%lmort_direct = o%lmort_direct - n%lmort_infra = o%lmort_infra - n%lmort_collateral= o%lmort_collateral n%seed_prod = o%seed_prod n%treelai = o%treelai n%treesai = o%treesai @@ -1430,9 +1427,10 @@ subroutine copy_cohort( currentCohort,copyc ) n%frmort = o%frmort ! logging mortalities, Yi Xu - n%lmort_direct=o%lmort_direct + n%lmort_direct =o%lmort_direct n%lmort_collateral =o%lmort_collateral - n%lmort_infra =o%lmort_infra + n%lmort_infra =o%lmort_infra + n%l_degrad =o%l_degrad ! Flags n%isnew = o%isnew diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index d42f67ba74..019cb319a6 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -151,7 +151,7 @@ end subroutine IsItLoggingTime ! ====================================================================================== - subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmort_infra ) + subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmort_infra,l_degrad ) ! Arguments integer, intent(in) :: pft_i ! pft index @@ -159,6 +159,7 @@ subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmor real(r8), intent(out) :: lmort_direct ! direct (harvestable) mortality fraction real(r8), intent(out) :: lmort_collateral ! collateral damage mortality fraction real(r8), intent(out) :: lmort_infra ! infrastructure mortality fraction + real(r8), intent(out) :: l_degrad ! fraction of trees that are not killed but suffer from forest degradation (i.e. they are moved to newly-anthro-disturbed secondary forest patch) ! Parameters real(r8), parameter :: adjustment = 1.0 ! adjustment for mortality rates @@ -171,15 +172,19 @@ subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmor if (dbh >= logging_dbhmin ) then lmort_direct = logging_direct_frac * adjustment lmort_collateral = logging_collateral_frac * adjustment + l_degrad = 0._r8 else lmort_direct = 0.0_r8 lmort_collateral = 0.0_r8 + l_degrad = logging_collateral_frac * adjustment end if if (dbh >= logging_dbhmax_infra) then lmort_infra = 0.0_r8 + l_degrad = logging_mechanical_frac * adjustment else lmort_infra = logging_mechanical_frac * adjustment + l_degrad = 0.0_r8 end if !damage rates for size class < & > threshold_size need to be specified seperately @@ -190,11 +195,13 @@ subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmor lmort_direct = 0.0_r8 lmort_collateral = 0.0_r8 lmort_infra = 0.0_r8 + l_degrad = 0.0_r8 end if else lmort_direct = 0.0_r8 lmort_collateral = 0.0_r8 lmort_infra = 0.0_r8 + l_degrad = 0.0_r8 end if end subroutine LoggingMortality_frac diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index cbcdbae36b..12ce008b64 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -117,6 +117,7 @@ subroutine disturbance_rates( site_in, bc_in) real(r8) :: lmort_direct real(r8) :: lmort_collateral real(r8) :: lmort_infra + real(r8) :: l_degrad ! fraction of trees that are not killed but suffer from forest degradation (i.e. they are moved to newly-anthro-disturbed secondary forest patch) integer :: threshold_sizeclass @@ -145,12 +146,12 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort%frmort = frmort call LoggingMortality_frac(currentCohort%pft, currentCohort%dbh, & - lmort_direct,lmort_collateral,lmort_infra ) + lmort_direct,lmort_collateral,lmort_infra,l_degrad ) currentCohort%lmort_direct = lmort_direct currentCohort%lmort_collateral = lmort_collateral currentCohort%lmort_infra = lmort_infra - + currentCohort%l_degrad = l_degrad currentCohort => currentCohort%taller end do diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index a9cdb12148..f384e7eba2 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -298,9 +298,11 @@ module EDTypesMod ! Logging Mortality Rate ! Yi Xu & M. Huang - real(r8) :: lmort_direct ! directly logging rate %/per logging activity - real(r8) :: lmort_collateral ! collaterally damaged rate %/per logging activity - real(r8) :: lmort_infra ! mechanically damaged rate %/per logging activity + real(r8) :: lmort_direct ! directly logging rate fraction /per logging activity + real(r8) :: lmort_collateral ! collaterally damaged rate fraction /per logging activity + real(r8) :: lmort_infra ! mechanically damaged rate fraction /per logging activity + real(r8) :: l_degrad ! rate of trees that are not killed but suffer from forest degradation + ! (i.e. they are moved to newly-anthro-disturbed secondary forest patch). fraction /per logging activity ! NITROGEN POOLS ! ---------------------------------------------------------------------------------- From 0fd992d262be132397dfe6ad5806551c2e12875f Mon Sep 17 00:00:00 2001 From: rosiealice Date: Fri, 22 Feb 2019 02:46:31 -0700 Subject: [PATCH 28/78] removed external recruitment flag. Will enable seed rain --- biogeochem/EDPhysiologyMod.F90 | 11 ++++------- main/EDTypesMod.F90 | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 747879ce08..d6c5c37e62 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -27,7 +27,6 @@ module EDPhysiologyMod use EDTypesMod , only : numWaterMem use EDTypesMod , only : dl_sf, dinc_ed - use EDTypesMod , only : external_recruitment use EDTypesMod , only : ncwd use EDTypesMod , only : nlevleaf use EDTypesMod , only : senes @@ -888,14 +887,12 @@ subroutine seeds_in( currentSite, cp_pnt ) endif - if (external_recruitment == 1) then !external seed rain - needed to prevent extinction - do p = 1,numpft - currentPatch%seeds_in(p) = currentPatch%seeds_in(p) + & + do p = 1,numpft + currentPatch%seeds_in(p) = currentPatch%seeds_in(p) + & EDPftvarcon_inst%seed_rain(p) !KgC/m2/year - currentSite%seed_rain_flux(p) = currentSite%seed_rain_flux(p) + & + currentSite%seed_rain_flux(p) = currentSite%seed_rain_flux(p) + & EDPftvarcon_inst%seed_rain(p) * currentPatch%area/AREA !KgC/m2/year - enddo - endif + enddo end subroutine seeds_in diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index ee2e574310..35fc6e393f 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -116,7 +116,6 @@ module EDTypesMod integer, parameter :: numWaterMem = 10 ! watermemory saved as site level var ! BIOLOGY/BIOGEOCHEMISTRY - integer , parameter :: external_recruitment = 0 ! external recruitment flag 1=yes integer , parameter :: SENES = 10 ! Window of time over which we track temp for cold sensecence (days) real(r8), parameter :: dinc_ed = 1.0_r8 ! size of VAI bins (LAI+SAI) [CHANGE THIS NAME WITH NEXT INTERFACE ! UPDATE] From 4809a747f857f96a3381e21f5736f7d2579d1aa3 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Fri, 22 Feb 2019 15:58:33 -0800 Subject: [PATCH 29/78] i think this should now transfer the non-harveted trees to a secondary forest patch as well --- biogeochem/EDPatchDynamicsMod.F90 | 52 +++++++++++++++++++++---------- main/EDTypesMod.F90 | 1 + 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 12ce008b64..600e605dad 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -118,7 +118,7 @@ subroutine disturbance_rates( site_in, bc_in) real(r8) :: lmort_collateral real(r8) :: lmort_infra real(r8) :: l_degrad ! fraction of trees that are not killed but suffer from forest degradation (i.e. they are moved to newly-anthro-disturbed secondary forest patch) - + real(r8) :: dist_rate_ldist_notharvested integer :: threshold_sizeclass !---------------------------------------------------------------------------------------------- @@ -168,6 +168,8 @@ subroutine disturbance_rates( site_in, bc_in) currentPatch%disturbance_rates(dtype_ifall) = 0.0_r8 currentPatch%disturbance_rates(dtype_ilog) = 0.0_r8 currentPatch%disturbance_rates(dtype_ifire) = 0.0_r8 + + dist_rate_ldist_notharvested = 0.0_r8 currentCohort => currentPatch%shortest do while(associated(currentCohort)) @@ -183,13 +185,22 @@ subroutine disturbance_rates( site_in, bc_in) currentPatch%disturbance_rates(dtype_ilog) = currentPatch%disturbance_rates(dtype_ilog) + & min(1.0_r8, currentCohort%lmort_direct + & currentCohort%lmort_collateral + & - currentCohort%lmort_infra ) * & + currentCohort%lmort_infra + & + currentCohort%l_degrad ) * & currentCohort%c_area/currentPatch%area + ! Non-harvested part of the logging disturbance rate + dist_rate_ldist_notharvested = dist_rate_ldist_notharvested + currentCohort%l_degrad * currentCohort%c_area/currentPatch%area + endif currentCohort => currentCohort%taller enddo !currentCohort + ! fraction of the logging disturbance rate that is non-harvested + if (currentPatch%disturbance_rates(dtype_ilog) .gt. nearzero) then + currentPatch%fract_ldist_not_harvested = dist_rate_ldist_notharvested / currentPatch%disturbance_rates(dtype_ilog) + endif + ! Fire Disturbance Rate ! Fudge - fires can't burn the whole patch, as this causes /0 errors. ! This is accumulating the daily fires over the whole 30 day patch generation phase. @@ -247,6 +258,7 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort%lmort_direct = 0.0_r8 currentCohort%lmort_collateral = 0.0_r8 currentCohort%lmort_infra = 0.0_r8 + currentCohort%l_degrad = 0.0_r8 end if ! This may be counter-intuitive, but the diagnostic fire-mortality rate @@ -270,6 +282,7 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort%lmort_direct = 0.0_r8 currentCohort%lmort_collateral = 0.0_r8 currentCohort%lmort_infra = 0.0_r8 + currentCohort%l_degrad = 0.0_r8 end if currentCohort => currentCohort%taller enddo !currentCohort @@ -514,6 +527,7 @@ subroutine spawn_patches( currentSite, bc_in) nc%lmort_direct = nan nc%lmort_collateral = nan nc%lmort_infra = nan + nc%l_degrad = nan else ! small trees @@ -649,22 +663,26 @@ subroutine spawn_patches( currentSite, bc_in) ! If this cohort is in the upper canopy. It generated if(currentCohort%canopy_layer == 1)then - ! Trees generating this disturbance are not there by definition - nc%n = 0.0_r8 + ! calculate the survivorship of disturbed trees because non-harvested + nc%n = (fractcurrentCohort%l_degrad / (currentCohort%l_degrad + & + currentCohort%lmort_direct + currentCohort%lmort_collateral + currentCohort%lmort_infra) ) * & + currentCohort%n * patch_site_areadis/currentPatch%area ! Reduce counts in the existing/donor patch according to the logging rate currentCohort%n = currentCohort%n * (1.0_r8 - min(1.0_r8,(currentCohort%lmort_direct + & currentCohort%lmort_collateral + & currentCohort%lmort_infra))) - ! The mortality diagnostics are set to nan because the cohort should dissappear - nc%cmort = nan - nc%hmort = nan - nc%bmort = nan - nc%frmort = nan - nc%lmort_direct = nan - nc%lmort_collateral = nan - nc%lmort_infra = nan + nc%cmort = currentCohort%cmort + nc%hmort = currentCohort%hmort + nc%bmort = currentCohort%bmort + nc%frmort = currentCohort%frmort + nc%dmort = currentCohort%dmort + + ! since these are the ones that weren't logged, set the logging mortality rates as zero + nc%lmort_direct = 0._r8 + nc%lmort_collateral = 0._r8 + nc%lmort_infra = 0._r8 else @@ -686,9 +704,9 @@ subroutine spawn_patches( currentSite, bc_in) ! the number density. currentSite%imort_rate(currentCohort%size_class, currentCohort%pft) = & currentSite%imort_rate(currentCohort%size_class, currentCohort%pft) + & - nc%n * logging_coll_under_frac / hlm_freq_day + nc%n * currentPatch%fract_ldist_not_harvested * logging_coll_under_frac / hlm_freq_day currentSite%imort_carbonflux = currentSite%imort_carbonflux + & - (nc%n * logging_coll_under_frac/ hlm_freq_day ) * & + (nc%n * currentPatch%fract_ldist_not_harvested * logging_coll_under_frac/ hlm_freq_day ) * & total_c * g_per_kg * days_per_sec * years_per_day * ha_per_m2 @@ -696,7 +714,7 @@ subroutine spawn_patches( currentSite, bc_in) ! remaining of understory plants of those that are knocked over by the overstorey trees dying... ! LOGGING SURVIVORSHIP OF UNDERSTORY PLANTS IS SET AS A NEW PARAMETER in the fatesparameter files - nc%n = nc%n * (1.0_r8 - logging_coll_under_frac) + nc%n = nc%n * (1.0_r8 - currentPatch%fract_ldist_not_harvested * logging_coll_under_frac) ! Step 3: Reduce the number count of cohorts in the original/donor/non-disturbed patch ! to reflect the area change @@ -791,6 +809,7 @@ subroutine spawn_patches( currentSite, bc_in) !zero disturbance rate trackers currentPatch%disturbance_rate = 0._r8 currentPatch%disturbance_rates = 0._r8 + currentPatch%fract_ldist_not_harvested = 0._r8 currentPatch => currentPatch%younger @@ -1515,7 +1534,8 @@ subroutine zero_patch(cp_p) ! DISTURBANCE currentPatch%disturbance_rates = 0._r8 - currentPatch%disturbance_rate = 0._r8 + currentPatch%disturbance_rate = 0._r8 + currentPatch%fract_ldist_not_harvested = 0._r8 ! LITTER currentPatch%cwd_ag(:) = 0.0_r8 ! above ground coarse woody debris gc/m2. diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index f384e7eba2..6323430bea 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -470,6 +470,7 @@ module EDTypesMod ! 2) fire: fraction/day ! 3) logging mortatliy real(r8) :: disturbance_rate ! larger effective disturbance rate: fraction/day + real(r8) :: fract_ldist_not_harvested ! fraction of logged area that is canopy trees that weren't harvested ! LITTER AND COARSE WOODY DEBRIS ! Pools of litter (non respiring) From 3f1a5c2a5640d80902feb9a9a22830d60a52790a Mon Sep 17 00:00:00 2001 From: Charles Koven Date: Sat, 23 Feb 2019 21:54:37 -0800 Subject: [PATCH 30/78] bugfixes on prior --- biogeochem/EDLoggingMortalityMod.F90 | 7 +++---- biogeochem/EDMortalityFunctionsMod.F90 | 3 ++- biogeochem/EDPatchDynamicsMod.F90 | 9 +++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index 019cb319a6..2f58c4c997 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -175,16 +175,15 @@ subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmor l_degrad = 0._r8 else lmort_direct = 0.0_r8 - lmort_collateral = 0.0_r8 - l_degrad = logging_collateral_frac * adjustment + lmort_collateral = 0.0_r8 !!!CDK note: this should really be logging_collateral_frac * adjustment. keeping as-is for now fr consistency. + l_degrad = logging_direct_frac * adjustment end if if (dbh >= logging_dbhmax_infra) then lmort_infra = 0.0_r8 - l_degrad = logging_mechanical_frac * adjustment + l_degrad = l_degrad + logging_mechanical_frac * adjustment else lmort_infra = logging_mechanical_frac * adjustment - l_degrad = 0.0_r8 end if !damage rates for size class < & > threshold_size need to be specified seperately diff --git a/biogeochem/EDMortalityFunctionsMod.F90 b/biogeochem/EDMortalityFunctionsMod.F90 index 130a269593..6f36258406 100644 --- a/biogeochem/EDMortalityFunctionsMod.F90 +++ b/biogeochem/EDMortalityFunctionsMod.F90 @@ -197,7 +197,8 @@ subroutine Mortality_Derivative( currentSite, currentCohort, bc_in) call LoggingMortality_frac(ipft, currentCohort%dbh, & currentCohort%lmort_direct, & currentCohort%lmort_collateral, & - currentCohort%lmort_infra ) + currentCohort%lmort_infra, & + currentCohort%l_degrad) if (currentCohort%canopy_layer > 1)then diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 600e605dad..7453bd6624 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -664,14 +664,15 @@ subroutine spawn_patches( currentSite, bc_in) if(currentCohort%canopy_layer == 1)then ! calculate the survivorship of disturbed trees because non-harvested - nc%n = (fractcurrentCohort%l_degrad / (currentCohort%l_degrad + & - currentCohort%lmort_direct + currentCohort%lmort_collateral + currentCohort%lmort_infra) ) * & - currentCohort%n * patch_site_areadis/currentPatch%area + nc%n = currentCohort%n * currentCohort%l_degrad + ! nc%n = (currentCohort%l_degrad / (currentCohort%l_degrad + & + ! currentCohort%lmort_direct + currentCohort%lmort_collateral + currentCohort%lmort_infra) ) * & + ! currentCohort%n * patch_site_areadis/currentPatch%area ! Reduce counts in the existing/donor patch according to the logging rate currentCohort%n = currentCohort%n * (1.0_r8 - min(1.0_r8,(currentCohort%lmort_direct + & currentCohort%lmort_collateral + & - currentCohort%lmort_infra))) + currentCohort%lmort_infra + currentCohort%l_degrad))) nc%cmort = currentCohort%cmort nc%hmort = currentCohort%hmort From 51aa0b00215c2bf19cb36758ffb763348f644beb Mon Sep 17 00:00:00 2001 From: Charles Koven Date: Sun, 24 Feb 2019 19:05:42 -0800 Subject: [PATCH 31/78] changing logging collateral mortality logic to be based on canopy layer rather than dbh --- biogeochem/EDLoggingMortalityMod.F90 | 11 +++++++---- biogeochem/EDMortalityFunctionsMod.F90 | 2 +- biogeochem/EDPatchDynamicsMod.F90 | 8 +++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index 2f58c4c997..367f3e868d 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -151,11 +151,13 @@ end subroutine IsItLoggingTime ! ====================================================================================== - subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmort_infra,l_degrad ) + subroutine LoggingMortality_frac( pft_i, dbh, canopy_layer, lmort_direct, & + lmort_collateral, lmort_infra, l_degrad ) ! Arguments integer, intent(in) :: pft_i ! pft index real(r8), intent(in) :: dbh ! diameter at breast height (cm) + integer, intent(in) :: canopy_layer ! canopy layer of this cohort real(r8), intent(out) :: lmort_direct ! direct (harvestable) mortality fraction real(r8), intent(out) :: lmort_collateral ! collateral damage mortality fraction real(r8), intent(out) :: lmort_infra ! infrastructure mortality fraction @@ -171,11 +173,9 @@ subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmor if (dbh >= logging_dbhmin ) then lmort_direct = logging_direct_frac * adjustment - lmort_collateral = logging_collateral_frac * adjustment l_degrad = 0._r8 else lmort_direct = 0.0_r8 - lmort_collateral = 0.0_r8 !!!CDK note: this should really be logging_collateral_frac * adjustment. keeping as-is for now fr consistency. l_degrad = logging_direct_frac * adjustment end if @@ -187,8 +187,11 @@ subroutine LoggingMortality_frac( pft_i, dbh, lmort_direct,lmort_collateral,lmor end if !damage rates for size class < & > threshold_size need to be specified seperately - ! Collateral damage to smaller plants below the direct logging size threshold + ! Collateral damage to smaller plants below the canopy layer ! will be applied via "understory_death" via the disturbance algorithm + if (canopy_layer .eq. 1) then + lmort_collateral = logging_collateral_frac * adjustment + endif else lmort_direct = 0.0_r8 diff --git a/biogeochem/EDMortalityFunctionsMod.F90 b/biogeochem/EDMortalityFunctionsMod.F90 index 6f36258406..d527b59b0b 100644 --- a/biogeochem/EDMortalityFunctionsMod.F90 +++ b/biogeochem/EDMortalityFunctionsMod.F90 @@ -194,7 +194,7 @@ subroutine Mortality_Derivative( currentSite, currentCohort, bc_in) ! Mortality for trees in the understorey. !if trees are in the canopy, then their death is 'disturbance'. This probably needs a different terminology call mortality_rates(currentCohort,bc_in,cmort,hmort,bmort,frmort) - call LoggingMortality_frac(ipft, currentCohort%dbh, & + call LoggingMortality_frac(ipft, currentCohort%dbh, currentCohort%canopy_layer, & currentCohort%lmort_direct, & currentCohort%lmort_collateral, & currentCohort%lmort_infra, & diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 7453bd6624..e74e578592 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -145,7 +145,7 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort%hmort = hmort currentCohort%frmort = frmort - call LoggingMortality_frac(currentCohort%pft, currentCohort%dbh, & + call LoggingMortality_frac(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_layer, & lmort_direct,lmort_collateral,lmort_infra,l_degrad ) currentCohort%lmort_direct = lmort_direct @@ -190,7 +190,8 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort%c_area/currentPatch%area ! Non-harvested part of the logging disturbance rate - dist_rate_ldist_notharvested = dist_rate_ldist_notharvested + currentCohort%l_degrad * currentCohort%c_area/currentPatch%area + dist_rate_ldist_notharvested = dist_rate_ldist_notharvested + currentCohort%l_degrad * & + currentCohort%c_area/currentPatch%area endif currentCohort => currentCohort%taller @@ -198,7 +199,8 @@ subroutine disturbance_rates( site_in, bc_in) ! fraction of the logging disturbance rate that is non-harvested if (currentPatch%disturbance_rates(dtype_ilog) .gt. nearzero) then - currentPatch%fract_ldist_not_harvested = dist_rate_ldist_notharvested / currentPatch%disturbance_rates(dtype_ilog) + currentPatch%fract_ldist_not_harvested = dist_rate_ldist_notharvested / & + currentPatch%disturbance_rates(dtype_ilog) endif ! Fire Disturbance Rate From a6305b1f88b064cb3088e103777a240302b615c8 Mon Sep 17 00:00:00 2001 From: rgknox Date: Mon, 25 Feb 2019 09:49:41 -0800 Subject: [PATCH 32/78] Increased the number of maximum leaf layers back up, to 30. Was creating crashes. --- main/EDTypesMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index ee2e574310..682df90aae 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -24,7 +24,7 @@ module EDTypesMod ! to understory layers (all layers that ! are not the top canopy layer) - integer, parameter :: nlevleaf = 20 ! number of leaf layers in canopy layer + integer, parameter :: nlevleaf = 30 ! number of leaf layers in canopy layer integer, parameter :: maxpft = 15 ! maximum number of PFTs allowed ! the parameter file may determine that fewer ! are used, but this helps allocate scratch From 8e426a8261458d29c44ce515cd9068757d45e517 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Wed, 27 Feb 2019 10:01:29 -0800 Subject: [PATCH 33/78] Changed default seed_rain to maintain behavior with base --- parameter_files/fates_params_14pfts.cdl | 3 +-- parameter_files/fates_params_coastal_veg.cdl | 2 +- parameter_files/fates_params_default.cdl | 2 +- parameter_files/fates_params_hydro_default.cdl | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/parameter_files/fates_params_14pfts.cdl b/parameter_files/fates_params_14pfts.cdl index d1a79ad235..d734f7a3b9 100644 --- a/parameter_files/fates_params_14pfts.cdl +++ b/parameter_files/fates_params_14pfts.cdl @@ -1136,8 +1136,7 @@ data: fates_seed_germination_timescale = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_seed_rain = 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, - 0.28, 0.28, 0.28, 0.28, 0.28 ; + fates_seed_rain = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; fates_smpsc = -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000, -255000 ; diff --git a/parameter_files/fates_params_coastal_veg.cdl b/parameter_files/fates_params_coastal_veg.cdl index d2bb4c2e3b..f0dbceb285 100644 --- a/parameter_files/fates_params_coastal_veg.cdl +++ b/parameter_files/fates_params_coastal_veg.cdl @@ -846,7 +846,7 @@ data: fates_seed_germination_timescale = 0.5, 0.5 ; - fates_seed_rain = 0.28, 0.28 ; + fates_seed_rain = 0, 0 ; fates_smpsc = -255000, -255000 ; diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 18bea2e032..a4b4ab4530 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -979,7 +979,7 @@ data: fates_seed_germination_timescale = 0.5, 0.5 ; - fates_seed_rain = 0.28, 0.28 ; + fates_seed_rain = 0.0, 0.0 ; fates_smpsc = -255000, -255000 ; diff --git a/parameter_files/fates_params_hydro_default.cdl b/parameter_files/fates_params_hydro_default.cdl index d421573e4c..79bfd0b0d3 100644 --- a/parameter_files/fates_params_hydro_default.cdl +++ b/parameter_files/fates_params_hydro_default.cdl @@ -979,7 +979,7 @@ data: fates_seed_germination_timescale = 0.5, 0.5 ; - fates_seed_rain = 0.28, 0.28 ; + fates_seed_rain = 0, 0 ; fates_smpsc = -255000, -255000 ; From e3a3b75db37c6dde149260a6e88005e1674048ff Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 14:43:18 -0700 Subject: [PATCH 34/78] Updating some error diagnostics and the precision thresholds for demotion/promotion --- biogeochem/EDCanopyStructureMod.F90 | 43 ++++++++++++++++++++--------- biogeochem/EDCohortDynamicsMod.F90 | 4 +-- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index a1326d482c..099d63e3bf 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -56,8 +56,14 @@ module EDCanopyStructureMod character(len=*), parameter, private :: sourcefile = & __FILE__ - real(r8), parameter :: area_target_precision = 1.0E-11_r8 ! Area conservation must be within this tolerance - real(r8), parameter :: area_check_precision = 1.0E-9_r8 ! Area conservation checks must be within this tolerance + real(r8), parameter :: area_target_precision = 1.0E-11_r8 ! Area conservation + ! will attempt to reduce errors + ! below this level + + real(r8), parameter :: area_check_precision = 1.0E-6_r8 ! Area conservation checks must + ! be within this absolute tolerance + real(r8), parameter :: area_check_rel_precision = 1.0E-3_r8 ! Area conservation checks must + ! be within this relative tolerance real(r8), parameter :: similar_height_tol = 1.0E-3_r8 ! I think trees that differ by 1mm ! can be roughly considered the same right? @@ -242,7 +248,8 @@ subroutine canopy_structure( currentSite , bc_in ) area_not_balanced = .false. do i_lyr = 1,z call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer(i_lyr)) - if( (arealayer(i_lyr)-currentPatch%area)/currentPatch%area > area_check_precision )then + if( ((arealayer(i_lyr)-currentPatch%area)/currentPatch%area > area_check_rel_precision) .or. & + ((arealayer(i_lyr)-currentPatch%area) > area_check_precision ) ) then area_not_balanced = .true. endif enddo @@ -258,6 +265,7 @@ subroutine canopy_structure( currentSite , bc_in ) do i_lyr = 1,z write(fates_log(),*) 'layer: ',i_lyr,' area: ',arealayer(i_lyr) write(fates_log(),*) 'rel error: ',(arealayer(i_lyr)-currentPatch%area)/currentPatch%area + write(fates_log(),*) 'abs error: ',arealayer(i_lyr)-currentPatch%area enddo write(fates_log(),*) 'lat:',currentSite%lat write(fates_log(),*) 'lon:',currentSite%lon @@ -363,7 +371,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) demote_area = arealayer - currentPatch%area - if ( demote_area/currentPatch%area > area_target_precision ) then + if ( demote_area > nearzero ) then ! Is this layer currently over-occupied? ! In that case, we need to work out which cohorts to demote. @@ -493,7 +501,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) enddo exceedance_counter = 0 - do while(remainder_area/demote_area > area_target_precision ) + do while(remainder_area > area_target_precision ) ! Keep attempting to add exceedance to members that have not ! lost more area than they started with.. @@ -527,6 +535,13 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) if( currentCohort%excl_weight < (currentCohort%c_area-nearzero) ) then sumweights = sumweights + currentCohort%excl_weight end if + + elseif(currentCohort%excl_weight > (currentCohort%c_area+area_target_precision) ) then + write(fates_log(),*) 'more area than the cohort wants to be domoted' + write(fates_log(),*) 'loss:',currentCohort%excl_weight + write(fates_log(),*) 'existing area:',currentCohort%c_area + write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) end if end if currentCohort => currentCohort%shorter @@ -542,7 +557,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) write(fates_log(),*) 'remainder_area:',remainder_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if - + end do end if @@ -629,6 +644,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) write(fates_log(),*) 'more area than the cohort has is being demoted' write(fates_log(),*) 'loss:',cc_loss write(fates_log(),*) 'existing area:',currentCohort%c_area + write(fates_log(),*) 'excess: ',cc_loss - currentCohort%c_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if @@ -702,7 +718,8 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer) - if ( abs(arealayer - currentPatch%area)/arealayer > area_target_precision ) then + if ( (abs(arealayer - currentPatch%area)/arealayer > area_check_rel_precision ) .or. & + (abs(arealayer - currentPatch%area) > area_check_precision) ) then write(fates_log(),*) 'demotion did not trim area within tolerance' write(fates_log(),*) 'arealayer:',arealayer write(fates_log(),*) 'patch%area:',currentPatch%area @@ -712,7 +729,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) end if - + return end subroutine DemoteFromLayer @@ -770,7 +787,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! how much do we need to gain? promote_area = currentPatch%area - arealayer_current - if( promote_area/currentPatch%area > area_target_precision ) then + if( promote_area > nearzero ) then if(arealayer_below <= promote_area ) then @@ -930,7 +947,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) enddo exceedance_counter = 0 - do while(remainder_area/promote_area > area_target_precision ) + do while(remainder_area > area_target_precision ) sumweights = 0.0_r8 remainder_area_hold = remainder_area @@ -1076,14 +1093,14 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer_current) - if ( abs(arealayer_current - currentPatch%area)/arealayer_current & - > area_target_precision ) then + if ((abs(arealayer_current - currentPatch%area)/arealayer_current > area_check_rel_precision ) .or. & + (abs(arealayer_current - currentPatch%area) > area_check_precision) ) then write(fates_log(),*) 'promotion did not bring area within tolerance' write(fates_log(),*) 'arealayer:',arealayer_current write(fates_log(),*) 'patch%area:',currentPatch%area call endrun(msg=errMsg(sourcefile, __LINE__)) end if - + end if end if diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 0f9faaf5d6..d7b82a0530 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -103,7 +103,7 @@ module EDCohortDynamicsMod integer, parameter, private :: conserve_crownarea_and_number_not_dbh = 1 integer, parameter, private :: conserve_dbh_and_number_not_crownarea = 2 - integer, parameter, private :: cohort_fusion_conservation_method = conserve_crownarea_and_number_not_dbh + integer, parameter, private :: cohort_fusion_conservation_method = conserve_dbh_and_number_not_crownarea ! 10/30/09: Created by Rosie Fisher !-------------------------------------------------------------------------------------! @@ -1003,7 +1003,7 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) call carea_allom(currentCohort%dbh,newn,currentSite%spread,currentCohort%pft,& currentCohort%c_area,inverse=.false.) ! - case(default) + case default write(fates_log(),*) 'FATES: Invalid choice for cohort_fusion_conservation_method' call endrun(msg=errMsg(sourcefile, __LINE__)) end select From 4b6a363e9040ecde23e660a42495aee9aada7bf0 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 14:43:18 -0700 Subject: [PATCH 35/78] Added some updates to area threshold checks in promotion/demotion, updated error messages --- biogeochem/EDCanopyStructureMod.F90 | 43 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index a1326d482c..099d63e3bf 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -56,8 +56,14 @@ module EDCanopyStructureMod character(len=*), parameter, private :: sourcefile = & __FILE__ - real(r8), parameter :: area_target_precision = 1.0E-11_r8 ! Area conservation must be within this tolerance - real(r8), parameter :: area_check_precision = 1.0E-9_r8 ! Area conservation checks must be within this tolerance + real(r8), parameter :: area_target_precision = 1.0E-11_r8 ! Area conservation + ! will attempt to reduce errors + ! below this level + + real(r8), parameter :: area_check_precision = 1.0E-6_r8 ! Area conservation checks must + ! be within this absolute tolerance + real(r8), parameter :: area_check_rel_precision = 1.0E-3_r8 ! Area conservation checks must + ! be within this relative tolerance real(r8), parameter :: similar_height_tol = 1.0E-3_r8 ! I think trees that differ by 1mm ! can be roughly considered the same right? @@ -242,7 +248,8 @@ subroutine canopy_structure( currentSite , bc_in ) area_not_balanced = .false. do i_lyr = 1,z call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer(i_lyr)) - if( (arealayer(i_lyr)-currentPatch%area)/currentPatch%area > area_check_precision )then + if( ((arealayer(i_lyr)-currentPatch%area)/currentPatch%area > area_check_rel_precision) .or. & + ((arealayer(i_lyr)-currentPatch%area) > area_check_precision ) ) then area_not_balanced = .true. endif enddo @@ -258,6 +265,7 @@ subroutine canopy_structure( currentSite , bc_in ) do i_lyr = 1,z write(fates_log(),*) 'layer: ',i_lyr,' area: ',arealayer(i_lyr) write(fates_log(),*) 'rel error: ',(arealayer(i_lyr)-currentPatch%area)/currentPatch%area + write(fates_log(),*) 'abs error: ',arealayer(i_lyr)-currentPatch%area enddo write(fates_log(),*) 'lat:',currentSite%lat write(fates_log(),*) 'lon:',currentSite%lon @@ -363,7 +371,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) demote_area = arealayer - currentPatch%area - if ( demote_area/currentPatch%area > area_target_precision ) then + if ( demote_area > nearzero ) then ! Is this layer currently over-occupied? ! In that case, we need to work out which cohorts to demote. @@ -493,7 +501,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) enddo exceedance_counter = 0 - do while(remainder_area/demote_area > area_target_precision ) + do while(remainder_area > area_target_precision ) ! Keep attempting to add exceedance to members that have not ! lost more area than they started with.. @@ -527,6 +535,13 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) if( currentCohort%excl_weight < (currentCohort%c_area-nearzero) ) then sumweights = sumweights + currentCohort%excl_weight end if + + elseif(currentCohort%excl_weight > (currentCohort%c_area+area_target_precision) ) then + write(fates_log(),*) 'more area than the cohort wants to be domoted' + write(fates_log(),*) 'loss:',currentCohort%excl_weight + write(fates_log(),*) 'existing area:',currentCohort%c_area + write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) end if end if currentCohort => currentCohort%shorter @@ -542,7 +557,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) write(fates_log(),*) 'remainder_area:',remainder_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if - + end do end if @@ -629,6 +644,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) write(fates_log(),*) 'more area than the cohort has is being demoted' write(fates_log(),*) 'loss:',cc_loss write(fates_log(),*) 'existing area:',currentCohort%c_area + write(fates_log(),*) 'excess: ',cc_loss - currentCohort%c_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if @@ -702,7 +718,8 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer) - if ( abs(arealayer - currentPatch%area)/arealayer > area_target_precision ) then + if ( (abs(arealayer - currentPatch%area)/arealayer > area_check_rel_precision ) .or. & + (abs(arealayer - currentPatch%area) > area_check_precision) ) then write(fates_log(),*) 'demotion did not trim area within tolerance' write(fates_log(),*) 'arealayer:',arealayer write(fates_log(),*) 'patch%area:',currentPatch%area @@ -712,7 +729,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) end if - + return end subroutine DemoteFromLayer @@ -770,7 +787,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! how much do we need to gain? promote_area = currentPatch%area - arealayer_current - if( promote_area/currentPatch%area > area_target_precision ) then + if( promote_area > nearzero ) then if(arealayer_below <= promote_area ) then @@ -930,7 +947,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) enddo exceedance_counter = 0 - do while(remainder_area/promote_area > area_target_precision ) + do while(remainder_area > area_target_precision ) sumweights = 0.0_r8 remainder_area_hold = remainder_area @@ -1076,14 +1093,14 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer_current) - if ( abs(arealayer_current - currentPatch%area)/arealayer_current & - > area_target_precision ) then + if ((abs(arealayer_current - currentPatch%area)/arealayer_current > area_check_rel_precision ) .or. & + (abs(arealayer_current - currentPatch%area) > area_check_precision) ) then write(fates_log(),*) 'promotion did not bring area within tolerance' write(fates_log(),*) 'arealayer:',arealayer_current write(fates_log(),*) 'patch%area:',currentPatch%area call endrun(msg=errMsg(sourcefile, __LINE__)) end if - + end if end if From fb9aaf3cc54eaa22dcbe5b968406493ff9c59b99 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 15:35:42 -0800 Subject: [PATCH 36/78] Added new algorithm for scaling promotion/demotion weights to within cohort crown areas --- biogeochem/EDCanopyStructureMod.F90 | 303 +++++++++++++++------------- 1 file changed, 167 insertions(+), 136 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index 099d63e3bf..261b890771 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -349,20 +349,17 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) real(r8) :: sapw_c ! sapwood carbon [kg] real(r8) :: store_c ! storage carbon [kg] real(r8) :: struct_c ! structure carbon [kg] - real(r8) :: lossarea + real(r8) :: scale_factor ! for prob. exclusion - scales weight to a fraction + real(r8) :: scale_factor_min ! "" minimum before exeedance of 1 + real(r8) :: scale_factor_res ! "" applied to residual areas + real(r8) :: area_res ! residual area to demote after weakest cohort hits max real(r8) :: newarea real(r8) :: demote_area - real(r8) :: remainder_area - real(r8) :: remainder_area_hold real(r8) :: sumweights - real(r8) :: sumweights_old real(r8) :: sumequal ! for rank-ordered same-size cohorts ! this tallies their excluded area real(r8) :: arealayer ! the area of the current canopy layer - integer :: exceedance_counter ! when seeking to rebalance demotion exceedance - ! keep a loop counter to check for hangs logical :: tied_size_with_neighbors - type(ed_cohort_type), pointer :: cohort_tosearch_relative_to, cohort_tocompare_to real(r8) :: total_crownarea_of_tied_cohorts ! First, determine how much total canopy area we have in this layer @@ -393,8 +390,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) ! inverse size to a constant power ! ---------------------------------------------------------- - currentCohort%excl_weight = & - currentCohort%n/(currentCohort%hite**ED_val_comp_excln) + currentCohort%excl_weight = 1._r8 / (currentCohort%hite**ED_val_comp_excln) sumweights = sumweights + currentCohort%excl_weight else @@ -481,87 +477,104 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) ! area of those cohorts that have not reached their total canopy area ! yet. + + + if (ED_val_comp_excln .ge. 0.0_r8 ) then - remainder_area = 0.0_r8 - sumweights_old = 0.0_r8 + scale_factor_min = 1.e10_r8 + scale_factor = 0._r8 currentCohort => currentPatch%tallest do while (associated(currentCohort)) if(currentCohort%canopy_layer == i_lyr) then - currentCohort%excl_weight = demote_area*currentCohort%excl_weight/sumweights - if( currentCohort%excl_weight > currentCohort%c_area ) then - remainder_area = remainder_area + currentCohort%excl_weight-currentCohort%c_area - currentCohort%excl_weight = currentCohort%c_area - else - sumweights_old = sumweights_old + currentCohort%excl_weight - end if + + currentCohort%excl_weight = currentCohort%excl_weight/sumweights + if( 1._r8/currentCohort%excl_weight < scale_factor_min ) & + scale_factor_min = 1._r8/currentCohort%excl_weight + + scale_factor = scale_factor + currentCohort%excl_weight * currentCohort%c_area + endif currentCohort => currentCohort%shorter enddo - exceedance_counter = 0 - do while(remainder_area > area_target_precision ) - - ! Keep attempting to add exceedance to members that have not - ! lost more area than they started with.. - - sumweights = 0.0_r8 - remainder_area_hold = remainder_area - currentCohort => currentPatch%tallest - do while (associated(currentCohort)) - if(currentCohort%canopy_layer == i_lyr)then - if ( currentCohort%excl_weight < (currentCohort%c_area-nearzero) ) then + ! This is the factor by which we need to multiply + ! the demotion probabilities, so the sum result equals + ! the total amount to demote + scale_factor = demote_area/scale_factor + - ! Calculate how much exceeded demotion from filled - ! cohorts must be transferred to this cohort - ! Two requirements: 1) the tacked-on demotion can not also - ! exceed this cohort's area. And, 2) the tacked-on - ! demotion can't exceed the amount left + if(scale_factor <= scale_factor_min) then - cc_loss = min(remainder_area, & - remainder_area_hold * currentCohort%excl_weight/sumweights_old, & - currentCohort%c_area-currentCohort%excl_weight) + ! Trivial case, all of the demotion fractions + ! are less than 1. + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + if(currentCohort%canopy_layer == i_lyr) then + currentCohort%excl_weight = currentCohort%c_area * currentCohort%excl_weight * scale_factor + + if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%excl_weight < 0._r8) ) then + write(fates_log(),*) 'exclusion area too big (1)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight + write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if - ! Reduce the remainder_area - remainder_area = remainder_area - cc_loss + endif + currentCohort => currentCohort%shorter + enddo + + else - ! Update this cohorts exclusion - currentCohort%excl_weight = currentCohort%excl_weight + cc_loss - - ! Update the sum of weights for cohorts where exceedance can - ! still be spread to - if( currentCohort%excl_weight < (currentCohort%c_area-nearzero) ) then - sumweights = sumweights + currentCohort%excl_weight - end if + ! Non-trivial case, at least 1 cohort's demotion + ! rate would exceed its area, given the trivial scale factor + + area_res = 0._r8 + scale_factor_res = 0._r8 + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + if(currentCohort%canopy_layer == i_lyr) then + area_res = area_res + & + currentCohort%c_area*currentCohort%excl_weight*scale_factor_min + scale_factor_res = scale_factor_res + & + currentCohort%c_area * (1._r8 - (currentCohort%excl_weight * scale_factor_min)) + endif + currentCohort => currentCohort%shorter + enddo + + area_res = demote_area - area_res + + scale_factor_res = area_residual / scale_factor_res + + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + if(currentCohort%canopy_layer == i_lyr) then + + currentCohort%excl_weight = currentCohort%c_area * & + (currentCohort%excl_weight * scale_factor_min + & + (1._r8 - (currentCohort%excl_weight*scale_factor_min) ) * scale_factor_res) - elseif(currentCohort%excl_weight > (currentCohort%c_area+area_target_precision) ) then - write(fates_log(),*) 'more area than the cohort wants to be domoted' - write(fates_log(),*) 'loss:',currentCohort%excl_weight - write(fates_log(),*) 'existing area:',currentCohort%c_area + if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%excl_weight < 0._r8) ) then + write(fates_log(),*) 'exclusion area error (2)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if - end if - currentCohort => currentCohort%shorter - end do - ! Update the sum of weights for the next loop - sumweights_old = sumweights - - exceedance_counter = exceedance_counter + 1 - if( exceedance_counter > 100 ) then - write(fates_log(),*) 'It is taking a long time to distribute demotion exceedance' - write(fates_log(),*) '(ie greater than c_area) to neighbors... exiting' - write(fates_log(),*) 'sumweights:',sumweights - write(fates_log(),*) 'remainder_area:',remainder_area - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if - - end do - end if + endif + currentCohort => currentCohort%shorter + enddo + + end if + end if + ! Weights have been calculated. Now move them to the lower layer currentCohort => currentPatch%tallest @@ -757,16 +770,15 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) type(ed_cohort_type), pointer :: nextc ! the next cohort, or used for looping ! cohorts against the current - + real(r8) :: scale_factor ! for prob. exclusion - scales weight to a fraction + real(r8) :: scale_factor_min ! "" minimum before exeedance of 1 + real(r8) :: scale_factor_res ! "" applied to residual areas + real(r8) :: area_res ! residual area to demote after weakest cohort hits max real(r8) :: promote_area real(r8) :: newarea real(r8) :: sumweights - real(r8) :: sumweights_old real(r8) :: sumequal ! for tied cohorts, the sum of weights in ! their group - integer :: exceedance_counter - real(r8) :: remainder_area - real(r8) :: remainder_area_hold real(r8) :: cc_gain ! cohort crown area gain in promotion (m2) real(r8) :: arealayer_current ! area (m2) of the current canopy layer real(r8) :: arealayer_below ! area (m2) of the layer below the current layer @@ -777,7 +789,6 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) real(r8) :: struct_c ! structure carbon [kg] logical :: tied_size_with_neighbors - type(ed_cohort_type), pointer :: cohort_tosearch_relative_to, cohort_tocompare_to real(r8) :: total_crownarea_of_tied_cohorts call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer_current) @@ -840,7 +851,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) if (ED_val_comp_excln .ge. 0.0_r8 ) then ! normal (stochastic) case, as above. - currentCohort%prom_weight = currentCohort%n*currentCohort%hite**ED_val_comp_excln + currentCohort%prom_weight = currentCohort%hite**ED_val_comp_excln sumweights = sumweights + currentCohort%prom_weight else @@ -923,84 +934,104 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! And then a few rounds where we pre-calculate the promotion areas ! and adjust things if the promoted area wants to be greater than ! what is available. - if (ED_val_comp_excln .ge. 0.0_r8 ) then - remainder_area = 0.0_r8 - sumweights_old = 0.0_r8 - - currentCohort => currentPatch%tallest !start from the tallest cohort + scale_factor_min = 1.e10_r8 + scale_factor = 0._r8 + currentCohort => currentPatch%tallest do while (associated(currentCohort)) - if(currentCohort%canopy_layer == i_lyr+1) then !still looking at the layer beneath. - - currentCohort%prom_weight = promote_area*currentCohort%prom_weight/sumweights + + if(currentCohort%canopy_layer == (i_lyr+1) ) then - if( currentCohort%prom_weight > currentCohort%c_area ) then - remainder_area = remainder_area + currentCohort%prom_weight-currentCohort%c_area - currentCohort%prom_weight = currentCohort%c_area - else - sumweights_old = sumweights_old + currentCohort%prom_weight - end if + currentCohort%prom_weight = currentCohort%prom_weight/sumweights + if( 1._r8/currentCohort%prom_weight < scale_factor_min ) & + scale_factor_min = 1._r8/currentCohort%prom_weight + + scale_factor = scale_factor + currentCohort%prom_weight * currentCohort%c_area endif currentCohort => currentCohort%shorter enddo - - exceedance_counter = 0 - do while(remainder_area > area_target_precision ) + + ! This is the factor by which we need to multiply + ! the demotion probabilities, so the sum result equals + ! the total amount to demote + scale_factor = promote_area/scale_factor + + + if(scale_factor <= scale_factor_min) then + + ! Trivial case, all of the demotion fractions + ! are less than 1. - sumweights = 0.0_r8 - remainder_area_hold = remainder_area currentCohort => currentPatch%tallest - do while (associated(currentCohort)) - if(currentCohort%canopy_layer == i_lyr+1)then - - if ( currentCohort%prom_weight < (currentCohort%c_area-nearzero) ) then - - ! Calculate how much exceeded promotion from filled - ! cohorts must be transferred to this cohort - ! Two requirements: 1) the tacked-on promotion can not also - ! exceed this cohort's area. And, 2) the tacked-on - ! promotion can't exceed the amount left - ! This is how promotion is transferred from this cohort - - cc_gain = min(remainder_area, & - remainder_area_hold * currentCohort%prom_weight/sumweights_old, & - currentCohort%c_area-currentCohort%prom_weight) - - - ! Reduce the remainder_area - remainder_area = remainder_area - cc_gain - - ! Update this cohort's promotion - currentCohort%prom_weight = currentCohort%prom_weight + cc_gain - - ! Update the sum of weights for cohorts where exceedance can - ! still be spread to - if( currentCohort%prom_weight < (currentCohort%c_area-nearzero) ) then - sumweights = sumweights + currentCohort%prom_weight - end if - + do while (associated(currentCohort)) + if(currentCohort%canopy_layer == (i_lyr+1) ) then + currentCohort%prom_weight = currentCohort%c_area * currentCohort%prom_weight * scale_factor + + if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%prom_weight < 0._r8) ) then + write(fates_log(),*) 'exclusion area too big (1)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight + write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) end if - end if - currentCohort => currentCohort%shorter - end do - sumweights_old = sumweights + + endif + currentCohort => currentCohort%shorter + enddo - exceedance_counter = exceedance_counter + 1 - if( exceedance_counter > 100 ) then - write(fates_log(),*) 'It is taking a long time to distribute promotion exceedance' - write(fates_log(),*) '(ie greater than c_area) to neighbors... exiting' - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if + else - end do + ! Non-trivial case, at least 1 cohort's demotion + ! rate would exceed its area, given the trivial scale factor + + area_res = 0._r8 + scale_factor_res = 0._r8 + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + if(currentCohort%canopy_layer == (i_lyr+1) ) then + area_res = area_res + & + currentCohort%c_area*currentCohort%prom_weight*scale_factor_min + scale_factor_res = scale_factor_res + & + currentCohort%c_area * (1._r8 - (currentCohort%prom_weight * scale_factor_min)) + endif + currentCohort => currentCohort%shorter + enddo + + area_res = promote_area - area_res + + scale_factor_res = area_residual / scale_factor_res + + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + if(currentCohort%canopy_layer == (i_lyr+1)) then + + currentCohort%prom_weight = currentCohort%c_area * & + (currentCohort%prom_weight * scale_factor_min + & + (1._r8 - (currentCohort%prom_weight*scale_factor_min) ) * scale_factor_res) + + if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%prom_weight < 0._r8) ) then + write(fates_log(),*) 'exclusion area error (2)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight + write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + + endif + currentCohort => currentCohort%shorter + enddo + + end if end if + currentCohort => currentPatch%tallest do while (associated(currentCohort)) - !All the trees in this layer need to promote some area upwards... From 7ff6e9d281ad4a14ab4e520b4e377eb463b48ff6 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 15:49:11 -0800 Subject: [PATCH 37/78] Small fixes and checks to the updated promotion/demotion logic --- biogeochem/EDCanopyStructureMod.F90 | 40 ++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index 261b890771..a03902fbd3 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -548,7 +548,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) area_res = demote_area - area_res - scale_factor_res = area_residual / scale_factor_res + scale_factor_res = area_res / scale_factor_res currentCohort => currentPatch%tallest do while (associated(currentCohort)) @@ -575,6 +575,24 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) end if + + ! lets perform a check and see if the demotions meet the demand + sumweights = 0._r8 + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + sumweights = sumweights + currentCohort%excl_weight + currentCohort => currentCohort%shorter + end do + + if (abs(sumweights - demote_area) > area_check_precision ) then + write(fates_log(),*) 'demotions dont add up' + write(fates_log(),*) 'sum demotions: ',sumweights + write(fates_log(),*) 'area needed to be demoted: ',demote_area + write(fates_log(),*) 'excess: ',sumweights - demote_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + + ! Weights have been calculated. Now move them to the lower layer currentCohort => currentPatch%tallest @@ -1002,7 +1020,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) area_res = promote_area - area_res - scale_factor_res = area_residual / scale_factor_res + scale_factor_res = area_res / scale_factor_res currentCohort => currentPatch%tallest do while (associated(currentCohort)) @@ -1029,7 +1047,23 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) end if - + + ! lets perform a check and see if the promotions meet the demand + sumweights = 0._r8 + currentCohort => currentPatch%tallest + do while (associated(currentCohort)) + sumweights = sumweights + currentCohort%prom_weight + currentCohort => currentCohort%shorter + end do + + if (abs(sumweights - promote_area) > area_check_precision ) then + write(fates_log(),*) 'promotions dont add up' + write(fates_log(),*) 'sum promotions: ',sumweights + write(fates_log(),*) 'area needed to be promoted: ',promote_area + write(fates_log(),*) 'excess: ',sumweights - promote_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + currentCohort => currentPatch%tallest do while (associated(currentCohort)) From f2896038819f0845e08eb443f0b52bf3eefd1329 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 20:15:26 -0700 Subject: [PATCH 38/78] Various fixes to promotion/demotion. Notably, fixed filter on zeroing out cohorts that surpass maxlayers during demotion. --- biogeochem/EDCanopyStructureMod.F90 | 126 ++++++++++++++++++---------- 1 file changed, 84 insertions(+), 42 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index a03902fbd3..b53cfb0074 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -195,6 +195,10 @@ subroutine canopy_structure( currentSite , bc_in ) ! the layers below. ! --------------------------------------------------------------------------- + ! Its possible that before we even enter this scheme + ! some cohort numbers are very low. Terminate them. + call terminate_cohorts(currentSite, currentPatch, 1) + ! Calculate how many layers we have in this canopy ! This also checks the understory to see if its crown ! area is large enough to warrant a temporary sub-understory layer @@ -204,7 +208,8 @@ subroutine canopy_structure( currentSite , bc_in ) call DemoteFromLayer(currentSite, currentPatch, i_lyr) end do - ! Remove cohorts that are incredibly sparse + ! After demotions, we may then again have cohorts that are very very + ! very sparse, remove them call terminate_cohorts(currentSite, currentPatch, 1) call fuse_cohorts(currentSite, currentPatch, bc_in) @@ -368,7 +373,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) demote_area = arealayer - currentPatch%area - if ( demote_area > nearzero ) then + if ( demote_area > area_target_precision ) then ! Is this layer currently over-occupied? ! In that case, we need to work out which cohorts to demote. @@ -380,6 +385,13 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call carea_allom(currentCohort%dbh,currentCohort%n, & currentSite%spread,currentCohort%pft,currentCohort%c_area) + + if(currentCohort%c_area<0._r8)then + write(fates_log(),*) 'negative c_area stage 1d: ',currentCohort%dbh,i_lyr,currentCohort%n, & + currentSite%spread,currentCohort%pft,currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + if( currentCohort%canopy_layer == i_lyr)then @@ -473,12 +485,8 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) ! If this is probabalistic demotion, we need to do a round of normalization. ! And then a few rounds where we pre-calculate the demotion areas ! and adjust things if the demoted area wants to be greater than - ! what is available. sumweights_old is used to sum up the exclusion - ! area of those cohorts that have not reached their total canopy area - ! yet. - - - + ! what is available. The math is too hard to explain here, see + ! the tech note section on promotion/demotion. if (ED_val_comp_excln .ge. 0.0_r8 ) then @@ -519,6 +527,10 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) (currentCohort%excl_weight < 0._r8) ) then write(fates_log(),*) 'exclusion area too big (1)' write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'dbh: ',currentCohort%dbh + write(fates_log(),*) 'n: ',currentCohort%n + write(fates_log(),*) 'spread: ',currentSite%spread + write(fates_log(),*) 'pft: ',currentCohort%pft write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area call endrun(msg=errMsg(sourcefile, __LINE__)) @@ -580,7 +592,9 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) sumweights = 0._r8 currentCohort => currentPatch%tallest do while (associated(currentCohort)) - sumweights = sumweights + currentCohort%excl_weight + if(currentCohort%canopy_layer == i_lyr) then + sumweights = sumweights + currentCohort%excl_weight + end if currentCohort => currentCohort%shorter end do @@ -596,17 +610,16 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) ! Weights have been calculated. Now move them to the lower layer currentCohort => currentPatch%tallest - do while (associated(currentCohort)) - - cc_loss = currentCohort%excl_weight - - leaf_c = currentCohort%prt%GetState(leaf_organ,all_carbon_elements) - store_c = currentCohort%prt%GetState(store_organ,all_carbon_elements) - fnrt_c = currentCohort%prt%GetState(fnrt_organ,all_carbon_elements) - sapw_c = currentCohort%prt%GetState(sapw_organ,all_carbon_elements) - struct_c = currentCohort%prt%GetState(struct_organ,all_carbon_elements) + do while (associated(currentCohort)) - if(currentCohort%canopy_layer == i_lyr .and. cc_loss>nearzero )then + if(currentCohort%canopy_layer == i_lyr )then + + cc_loss = currentCohort%excl_weight + leaf_c = currentCohort%prt%GetState(leaf_organ,all_carbon_elements) + store_c = currentCohort%prt%GetState(store_organ,all_carbon_elements) + fnrt_c = currentCohort%prt%GetState(fnrt_organ,all_carbon_elements) + sapw_c = currentCohort%prt%GetState(sapw_organ,all_carbon_elements) + struct_c = currentCohort%prt%GetState(struct_organ,all_carbon_elements) if ( (cc_loss-currentCohort%c_area) > -nearzero .and. & (cc_loss-currentCohort%c_area) < area_target_precision ) then @@ -622,7 +635,8 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) currentSite%demotion_carbonflux = currentSite%demotion_carbonflux + & (leaf_c + store_c + fnrt_c + sapw_c + struct_c) * currentCohort%n - elseif(cc_loss > nearzero .and. cc_loss < currentCohort%c_area )then + elseif( (cc_loss < currentCohort%c_area) .and. & + (cc_loss > area_target_precision) ) then ! If only part of the cohort is demoted ! then it must be split (little more complicated) @@ -631,6 +645,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) ! conserve total number density of the original. The copy ! remains in the upper-story. The original is the one ! demoted to the understory + allocate(copyc) @@ -639,10 +654,21 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call InitHydrCohort(currentSite,copyc) endif call copy_cohort(currentCohort, copyc) - + + if(currentCohort%n < 0._r8) then + write(fates_log(),*) 'negatives (0_?): ',currentCohort%n,currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + newarea = currentCohort%c_area - cc_loss copyc%n = currentCohort%n*newarea/currentCohort%c_area currentCohort%n = currentCohort%n - copyc%n + + if(copyc%n < 0._r8 .or. currentCohort%n < 0._r8) then + write(fates_log(),*) 'negatives?: ',newarea,cc_loss,copyc%n,currentCohort%n,currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + copyc%canopy_layer = i_lyr !the taller cohort is the copy @@ -659,6 +685,16 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call carea_allom(currentCohort%dbh,currentCohort%n,currentSite%spread, & currentCohort%pft,currentCohort%c_area) + ! Calculate how much area loss from recalculation + if( abs(copyc%c_area-newarea)>area_target_precision .or. & + abs(currentCohort%c_area-cc_loss)>area_target_precision) then + write(fates_log(),*) 'recalculation losses?',newarea-copyc%c_area,newarea, & + copyc%c_area,currentCohort%c_area-cc_loss,currentCohort%c_area,& + cc_loss + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + + !----------- Insert copy into linked list ------------------------! copyc%shorter => currentCohort if(associated(currentCohort%taller))then @@ -681,7 +717,8 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) end if ! kill the ones which go into canopy layers that are not allowed - if(i_lyr+1 > nclmax)then + + if(currentCohort%canopy_layer>nclmax )then ! put the litter from the terminated cohorts into the fragmenting pools do i_cwd=1,ncwd @@ -754,7 +791,9 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) write(fates_log(),*) 'demotion did not trim area within tolerance' write(fates_log(),*) 'arealayer:',arealayer write(fates_log(),*) 'patch%area:',currentPatch%area - write(fates_log(),*) 'error:',abs(arealayer - currentPatch%area) + write(fates_log(),*) 'ilayer: ',i_lyr + write(fates_log(),*) 'bias:',arealayer - currentPatch%area + write(fates_log(),*) 'demote_area:',demote_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if @@ -816,7 +855,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! how much do we need to gain? promote_area = currentPatch%area - arealayer_current - if( promote_area > nearzero ) then + if( promote_area > area_target_precision ) then if(arealayer_below <= promote_area ) then @@ -1052,7 +1091,9 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) sumweights = 0._r8 currentCohort => currentPatch%tallest do while (associated(currentCohort)) - sumweights = sumweights + currentCohort%prom_weight + if(currentCohort%canopy_layer == (i_lyr+1)) then + sumweights = sumweights + currentCohort%prom_weight + end if currentCohort => currentCohort%shorter end do @@ -1069,29 +1110,29 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) !All the trees in this layer need to promote some area upwards... - if(currentCohort%canopy_layer == i_lyr+1)then - - cc_gain = currentCohort%prom_weight + if( (currentCohort%canopy_layer == i_lyr+1) ) then + + cc_gain = currentCohort%prom_weight + leaf_c = currentCohort%prt%GetState(leaf_organ,all_carbon_elements) + store_c = currentCohort%prt%GetState(store_organ,all_carbon_elements) + fnrt_c = currentCohort%prt%GetState(fnrt_organ,all_carbon_elements) + sapw_c = currentCohort%prt%GetState(sapw_organ,all_carbon_elements) + struct_c = currentCohort%prt%GetState(struct_organ,all_carbon_elements) if ( (cc_gain-currentCohort%c_area) > -nearzero .and. & (cc_gain-currentCohort%c_area) < area_target_precision ) then - + currentCohort%canopy_layer = i_lyr ! keep track of number and biomass of promoted cohort currentSite%promotion_rate(currentCohort%size_class) = & currentSite%promotion_rate(currentCohort%size_class) + currentCohort%n - leaf_c = currentCohort%prt%GetState(leaf_organ,all_carbon_elements) - store_c = currentCohort%prt%GetState(store_organ,all_carbon_elements) - fnrt_c = currentCohort%prt%GetState(fnrt_organ,all_carbon_elements) - sapw_c = currentCohort%prt%GetState(sapw_organ,all_carbon_elements) - struct_c = currentCohort%prt%GetState(struct_organ,all_carbon_elements) - currentSite%promotion_carbonflux = currentSite%promotion_carbonflux + & (leaf_c + fnrt_c + store_c + sapw_c + struct_c) * currentCohort%n - elseif ( cc_gain > nearzero .and. cc_gain < currentCohort%c_area) then + elseif ( (cc_gain < currentCohort%c_area) .and. & + (cc_gain > area_target_precision) ) then allocate(copyc) @@ -1112,6 +1153,13 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! number of individuals in cohort remaining in understorey currentCohort%n = currentCohort%n - copyc%n + + if(copyc%n < 0._r8 .or. currentCohort%n < 0._r8) then + write(fates_log(),*) 'negatives (2)?: ',newarea,cc_gain,copyc%n,currentCohort%n + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + + currentCohort%canopy_layer = i_lyr + 1 ! keep current cohort in the understory. copyc%canopy_layer = i_lyr ! promote copy to the higher canopy layer. @@ -1119,12 +1167,6 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) currentSite%promotion_rate(copyc%size_class) = & currentSite%promotion_rate(copyc%size_class) + copyc%n - leaf_c = copyc%prt%GetState(leaf_organ,all_carbon_elements) - store_c = copyc%prt%GetState(store_organ,all_carbon_elements) - fnrt_c = copyc%prt%GetState(fnrt_organ,all_carbon_elements) - sapw_c = copyc%prt%GetState(sapw_organ,all_carbon_elements) - struct_c = copyc%prt%GetState(struct_organ,all_carbon_elements) - currentSite%promotion_carbonflux = currentSite%promotion_carbonflux + & (leaf_c + fnrt_c + store_c + sapw_c + struct_c) * copyc%n From bcc719d38b50fdbcb4569b07aa83118c50e052fb Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 23:18:36 -0700 Subject: [PATCH 39/78] Expanded leaf layers to 30 --- main/EDTypesMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index c6a22ad6b1..4fc7ee7d71 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -24,7 +24,7 @@ module EDTypesMod ! to understory layers (all layers that ! are not the top canopy layer) - integer, parameter :: nlevleaf = 20 ! number of leaf layers in canopy layer + integer, parameter :: nlevleaf = 30 ! number of leaf layers in canopy layer integer, parameter :: maxpft = 15 ! maximum number of PFTs allowed ! the parameter file may determine that fewer ! are used, but this helps allocate scratch From 999122741844beb905c3c4695dfee24349bef240 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Feb 2019 23:22:07 -0700 Subject: [PATCH 40/78] Changed flag back to conservation of crown area --- biogeochem/EDCohortDynamicsMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 7066224beb..ccde161014 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -103,7 +103,7 @@ module EDCohortDynamicsMod integer, parameter, private :: conserve_crownarea_and_number_not_dbh = 1 integer, parameter, private :: conserve_dbh_and_number_not_crownarea = 2 - integer, parameter, private :: cohort_fusion_conservation_method = conserve_dbh_and_number_not_crownarea + integer, parameter, private :: cohort_fusion_conservation_method = conserve_crownarea_and_number_not_dbh ! 10/30/09: Created by Rosie Fisher !-------------------------------------------------------------------------------------! From fdebaa755c77cf68e1ac63019b8b0b596203e54e Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 1 Mar 2019 13:49:00 -0700 Subject: [PATCH 41/78] increased number of leaf levels to 40 after overflows --- main/EDTypesMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 4fc7ee7d71..b04cea860e 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -24,7 +24,7 @@ module EDTypesMod ! to understory layers (all layers that ! are not the top canopy layer) - integer, parameter :: nlevleaf = 30 ! number of leaf layers in canopy layer + integer, parameter :: nlevleaf = 40 ! number of leaf layers in canopy layer integer, parameter :: maxpft = 15 ! maximum number of PFTs allowed ! the parameter file may determine that fewer ! are used, but this helps allocate scratch From 53775ba321ebd7379133a4bb2a951c0e4c38359f Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 1 Mar 2019 15:30:29 -0800 Subject: [PATCH 42/78] Minor comment updates --- biogeochem/EDCanopyStructureMod.F90 | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index b53cfb0074..da5ea89ec2 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -398,8 +398,11 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) if (ED_val_comp_excln .ge. 0.0_r8 ) then ! ---------------------------------------------------------- - ! normal (stochastic) case. weight cohort demotion by - ! inverse size to a constant power + ! Stochastic method. + ! Weight cohort demotion by inverse size to a constant power. + ! In this hypothesis, it is assumed that even the tallest + ! cohorts have a chance (although smaller) of being forced + ! to the understory. ! ---------------------------------------------------------- currentCohort%excl_weight = 1._r8 / (currentCohort%hite**ED_val_comp_excln) @@ -510,13 +513,13 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) ! This is the factor by which we need to multiply ! the demotion probabilities, so the sum result equals ! the total amount to demote + scale_factor = demote_area/scale_factor if(scale_factor <= scale_factor_min) then - ! Trivial case, all of the demotion fractions - ! are less than 1. + ! Trivial case, all of the demotion fractions are less than 1. currentCohort => currentPatch%tallest do while (associated(currentCohort)) @@ -588,7 +591,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) end if - ! lets perform a check and see if the demotions meet the demand + ! perform a check and see if the demotions meet the demand sumweights = 0._r8 currentCohort => currentPatch%tallest do while (associated(currentCohort)) @@ -907,7 +910,11 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) if(currentCohort%canopy_layer == i_lyr+1)then !look at the cohorts in the canopy layer below... if (ED_val_comp_excln .ge. 0.0_r8 ) then - ! normal (stochastic) case, as above. + + ! ------------------------------------------------------------------ + ! Stochastic case, as above (in demotion portion of code) + ! ------------------------------------------------------------------ + currentCohort%prom_weight = currentCohort%hite**ED_val_comp_excln sumweights = sumweights + currentCohort%prom_weight else @@ -991,6 +998,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! And then a few rounds where we pre-calculate the promotion areas ! and adjust things if the promoted area wants to be greater than ! what is available. + if (ED_val_comp_excln .ge. 0.0_r8 ) then scale_factor_min = 1.e10_r8 @@ -1028,7 +1036,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & (currentCohort%prom_weight < 0._r8) ) then - write(fates_log(),*) 'exclusion area too big (1)' + write(fates_log(),*) 'promotion area too big (1)' write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area @@ -1071,7 +1079,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & (currentCohort%prom_weight < 0._r8) ) then - write(fates_log(),*) 'exclusion area error (2)' + write(fates_log(),*) 'promotion area error (2)' write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area From 9c282067775bb44ba67748b78c016a2f78aac3b3 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 4 Mar 2019 12:15:32 -0700 Subject: [PATCH 43/78] Updated diagnostics on LAI exceedance check --- biogeochem/EDCohortDynamicsMod.F90 | 2 +- biogeochem/FatesAllometryMod.F90 | 10 ++++++++++ main/EDTypesMod.F90 | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index ccde161014..7066224beb 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -103,7 +103,7 @@ module EDCohortDynamicsMod integer, parameter, private :: conserve_crownarea_and_number_not_dbh = 1 integer, parameter, private :: conserve_dbh_and_number_not_crownarea = 2 - integer, parameter, private :: cohort_fusion_conservation_method = conserve_crownarea_and_number_not_dbh + integer, parameter, private :: cohort_fusion_conservation_method = conserve_dbh_and_number_not_crownarea ! 10/30/09: Created by Rosie Fisher !-------------------------------------------------------------------------------------! diff --git a/biogeochem/FatesAllometryMod.F90 b/biogeochem/FatesAllometryMod.F90 index ea11b292ad..94bdc6c715 100644 --- a/biogeochem/FatesAllometryMod.F90 +++ b/biogeochem/FatesAllometryMod.F90 @@ -744,8 +744,18 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_la write(fates_log(),*) 'The leaf and stem are predicted for a cohort, maxed out the array size' write(fates_log(),*) 'lai: ',treelai write(fates_log(),*) 'sai: ',tree_sai + write(fates_log(),*) 'target_lai: ',target_lai write(fates_log(),*) 'lai+sai: ',treelai+tree_sai write(fates_log(),*) 'nlevleaf,dinc_ed,nlevleaf*dinc_ed :',nlevleaf,dinc_ed,nlevleaf*dinc_ed + write(fates_log(),*) 'pft: ',pft + write(fates_log(),*) 'n: ',nplant + write(fates_log(),*) 'c_area: ',c_area + write(fates_log(),*) 'dbh: ',dbh + write(fates_log(),*) 'canopy_trim: ',canopy_trim + write(fates_log(),*) 'target_bleaf: ',target_bleaf + write(fates_log(),*) 'canopy layer: ',cl + write(fates_log(),*) 'canopy_tlai: ',canopy_lai(:) + write(fates_log(),*) 'vcmax25top: ',vcmax25top call endrun(msg=errMsg(sourcefile, __LINE__)) end if diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index b04cea860e..4fc7ee7d71 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -24,7 +24,7 @@ module EDTypesMod ! to understory layers (all layers that ! are not the top canopy layer) - integer, parameter :: nlevleaf = 40 ! number of leaf layers in canopy layer + integer, parameter :: nlevleaf = 30 ! number of leaf layers in canopy layer integer, parameter :: maxpft = 15 ! maximum number of PFTs allowed ! the parameter file may determine that fewer ! are used, but this helps allocate scratch From 7e1b7d41b348cbfb76295c64926522c024175320 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 4 Mar 2019 17:22:50 -0700 Subject: [PATCH 44/78] adding a lai check function --- biogeochem/EDCohortDynamicsMod.F90 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 7066224beb..2b736ada24 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -1022,6 +1022,13 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) call endrun(msg=errMsg(sourcefile, __LINE__)) end select + + ! Perform check on LAI (specifically, see if LAI is greater than target) + call check_lai(leaf_c, currentCohort%dbh,currentCohort%pft, currentCohort%c_area, & + currentCohort%n, currentCohort%canopy_layer, & + currentPatch%canopy_layer_tlai,currentCohort%vcmax25top, 0 ) + + call sizetype_class_index(currentCohort%dbh,currentCohort%pft, & currentCohort%size_class,currentCohort%size_by_pft_class) From 5ad22a1b636b741a2d87084816f9eb1cf232223d Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 4 Mar 2019 16:41:35 -0800 Subject: [PATCH 45/78] Updating diagnostics in tree_sai --- biogeochem/EDCohortDynamicsMod.F90 | 15 ++++++++++----- biogeochem/EDPhysiologyMod.F90 | 3 ++- biogeochem/FatesAllometryMod.F90 | 7 +++++-- main/EDMainMod.F90 | 12 ++++++++++-- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 2b736ada24..577e25d1b1 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -277,7 +277,7 @@ subroutine create_cohort(currentSite, patchptr, pft, nn, hite, dbh, bleaf, bfine new_cohort%treesai = tree_sai(new_cohort%pft, new_cohort%dbh, new_cohort%canopy_trim, & new_cohort%c_area, new_cohort%n, new_cohort%canopy_layer, & - patchptr%canopy_layer_tlai, new_cohort%treelai,new_cohort%vcmax25top ) + patchptr%canopy_layer_tlai, new_cohort%treelai,new_cohort%vcmax25top,2 ) new_cohort%lai = new_cohort%treelai * new_cohort%c_area/patchptr%area @@ -1022,11 +1022,16 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) call endrun(msg=errMsg(sourcefile, __LINE__)) end select + + leaf_c = currentCohort%prt%GetState(leaf_organ, all_carbon_elements) + + currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, currentCohort%n, & + currentCohort%canopy_layer, currentPatch%canopy_layer_tlai, & + currentCohort%vcmax25top) + currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & + currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & + currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top,1 ) - ! Perform check on LAI (specifically, see if LAI is greater than target) - call check_lai(leaf_c, currentCohort%dbh,currentCohort%pft, currentCohort%c_area, & - currentCohort%n, currentCohort%canopy_layer, & - currentPatch%canopy_layer_tlai,currentCohort%vcmax25top, 0 ) call sizetype_class_index(currentCohort%dbh,currentCohort%pft, & diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 80738a1bd8..1e4a69d0cd 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -259,7 +259,8 @@ subroutine trim_canopy( currentSite ) currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & - currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top ) + currentPatch%canopy_layer_tlai, currentCohort%treelai, & + currentCohort%vcmax25top,0 ) currentCohort%nv = ceiling((currentCohort%treelai+currentCohort%treesai)/dinc_ed) diff --git a/biogeochem/FatesAllometryMod.F90 b/biogeochem/FatesAllometryMod.F90 index 94bdc6c715..0a6edd9909 100644 --- a/biogeochem/FatesAllometryMod.F90 +++ b/biogeochem/FatesAllometryMod.F90 @@ -712,7 +712,8 @@ end function tree_lai ! ============================================================================ - real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_lai, treelai, vcmax25top ) + real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, & + canopy_lai, treelai, vcmax25top, call_id ) ! ============================================================================ ! SAI of individual trees is a function of the LAI of individual trees @@ -728,7 +729,8 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_la ! each canopy layer real(r8), intent(in) :: treelai ! tree LAI for checking purposes only real(r8), intent(in) :: vcmax25top ! maximum carboxylation rate at top of crown - + integer,intent(in) :: call_id ! flag specifying where this is called + ! from real(r8) :: target_bleaf real(r8) :: target_lai @@ -748,6 +750,7 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, canopy_la write(fates_log(),*) 'lai+sai: ',treelai+tree_sai write(fates_log(),*) 'nlevleaf,dinc_ed,nlevleaf*dinc_ed :',nlevleaf,dinc_ed,nlevleaf*dinc_ed write(fates_log(),*) 'pft: ',pft + write(fates_log(),*) 'call id: ',call_id write(fates_log(),*) 'n: ',nplant write(fates_log(),*) 'c_area: ',c_area write(fates_log(),*) 'dbh: ',dbh diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index cc366cc0fe..dae9699c30 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -48,7 +48,7 @@ module EDMainMod use FatesPlantHydraulicsMod , only : updateSizeDepTreeHydStates use FatesPlantHydraulicsMod , only : initTreeHydStates use FatesPlantHydraulicsMod , only : updateSizeDepRhizHydProps - use FatesAllometryMod , only : h_allom + use FatesAllometryMod , only : h_allom,tree_sai,tree_lai use FatesPlantHydraulicsMod , only : updateSizeDepRhizHydStates use EDLoggingMortalityMod , only : IsItLoggingTime use FatesGlobals , only : endrun => fates_endrun @@ -265,6 +265,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) real(r8) :: cohort_biomass_store ! remembers the biomass in the cohort for balance checking real(r8) :: dbh_old ! dbh of plant before daily PRT [cm] real(r8) :: hite_old ! height of plant before daily PRT [m] + real(r8) :: leaf_c !----------------------------------------------------------------------- @@ -353,7 +354,14 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) ! routine is also called following fusion call UpdateCohortBioPhysRates(currentCohort) - + leaf_c = currentCohort%prt%GetState(leaf_organ, all_carbon_elements) + currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, currentCohort%n, & + currentCohort%canopy_layer, currentPatch%canopy_layer_tlai, & + currentCohort%vcmax25top) + currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & + currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & + currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top,3 ) + ! Transfer all reproductive tissues into seed production call PRTReproRelease(currentCohort%prt,repro_organ,carbon12_element, & 1.0_r8, currentCohort%seed_prod) From 3204b39ee2e98c6866674b234395809198ffdf0e Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Wed, 6 Mar 2019 13:42:37 -0700 Subject: [PATCH 46/78] Now tying allometry in grasses to root biomass. ie if root biomass exceeds its target, dbh will increase to match. This will allow grasses to not force growth, and should reduce divergence from allometries. --- biogeochem/EDCanopyStructureMod.F90 | 3 +- biogeochem/EDCohortDynamicsMod.F90 | 10 +- biogeochem/EDPhysiologyMod.F90 | 1 - biogeochem/FatesAllometryMod.F90 | 151 ++++++++++++++++++--------- main/EDMainMod.F90 | 19 ++++ parteh/PRTAllometricCarbonMod.F90 | 156 +++++++++++++++++----------- 6 files changed, 223 insertions(+), 117 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index c7ffec0b06..16108301f9 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -1553,7 +1553,8 @@ subroutine leaf_area_profile( currentSite , snow_depth_si, frac_sno_eff_si) currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & - currentPatch%canopy_layer_tlai, currentCohort%treelai ,currentCohort%vcmax25top) + currentPatch%canopy_layer_tlai, currentCohort%treelai , & + currentCohort%vcmax25top,4) currentCohort%lai = currentCohort%treelai *currentCohort%c_area/currentPatch%total_canopy_area currentCohort%sai = currentCohort%treesai *currentCohort%c_area/currentPatch%total_canopy_area diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 577e25d1b1..5bdd971c97 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -49,7 +49,7 @@ module EDCohortDynamicsMod use FatesAllometryMod , only : bfineroot use FatesAllometryMod , only : h_allom use FatesAllometryMod , only : carea_allom - use FatesAllometryMod , only : StructureResetOfDH + use FatesAllometryMod , only : ForceDBH use FatesAllometryMod , only : tree_lai, tree_sai use PRTGenericMod, only : prt_carbon_allom_hyp @@ -103,7 +103,7 @@ module EDCohortDynamicsMod integer, parameter, private :: conserve_crownarea_and_number_not_dbh = 1 integer, parameter, private :: conserve_dbh_and_number_not_crownarea = 2 - integer, parameter, private :: cohort_fusion_conservation_method = conserve_dbh_and_number_not_crownarea + integer, parameter, private :: cohort_fusion_conservation_method = conserve_crownarea_and_number_not_dbh ! 10/30/09: Created by Rosie Fisher !-------------------------------------------------------------------------------------! @@ -1010,8 +1010,10 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) ! ----------------------------------------------------------------- ! if( EDPftvarcon_inst%woody(currentCohort%pft) == itrue ) then - call StructureResetOfDH( currentCohort%prt%GetState(struct_organ,all_carbon_elements), currentCohort%pft, & - currentCohort%canopy_trim, currentCohort%dbh, currentCohort%hite ) + call ForceDBH( currentCohort%pft, currentCohort%canopy_trim, & + currentCohort%dbh, currentCohort%hite, & + bdead = currentCohort%prt%GetState(struct_organ,all_carbon_elements)) + end if ! call carea_allom(currentCohort%dbh,newn,currentSite%spread,currentCohort%pft,& diff --git a/biogeochem/EDPhysiologyMod.F90 b/biogeochem/EDPhysiologyMod.F90 index 1e4a69d0cd..50973ec892 100644 --- a/biogeochem/EDPhysiologyMod.F90 +++ b/biogeochem/EDPhysiologyMod.F90 @@ -60,7 +60,6 @@ module EDPhysiologyMod use FatesAllometryMod , only : bbgw_allom use FatesAllometryMod , only : carea_allom use FatesAllometryMod , only : CheckIntegratedAllometries - use FatesAllometryMod , only : StructureResetOfDH use PRTGenericMod, only : prt_carbon_allom_hyp use PRTGenericMod, only : leaf_organ diff --git a/biogeochem/FatesAllometryMod.F90 b/biogeochem/FatesAllometryMod.F90 index 0a6edd9909..2fefc3fd18 100644 --- a/biogeochem/FatesAllometryMod.F90 +++ b/biogeochem/FatesAllometryMod.F90 @@ -91,6 +91,7 @@ module FatesAllometryMod use FatesConstantsMod, only : kg_per_Megag use FatesConstantsMod, only : calloc_abs_error use FatesConstantsMod, only : fates_unset_r8 + use FatesConstantsMod, only : itrue use shr_log_mod , only : errMsg => shr_log_errMsg use FatesGlobals , only : fates_log use FatesGlobals , only : endrun => fates_endrun @@ -116,7 +117,8 @@ module FatesAllometryMod public :: carea_allom ! Generic crown area wrapper public :: bstore_allom ! Generic maximum storage carbon wrapper public :: decay_coeff_kn - public :: StructureResetOfDH ! Method to set DBH to sync with structure biomass + public :: ForceDBH ! Method to set DBH to sync with structure + ! or fineroot biomass public :: CheckIntegratedAllometries public :: CrownDepth public :: set_root_fraction ! Generic wrapper to calculate normalized @@ -731,7 +733,7 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, & real(r8), intent(in) :: vcmax25top ! maximum carboxylation rate at top of crown integer,intent(in) :: call_id ! flag specifying where this is called ! from - + real(r8) :: h real(r8) :: target_bleaf real(r8) :: target_lai @@ -741,8 +743,10 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, & tree_sai = EDPftvarcon_inst%allom_sai_scaler(pft) * target_lai - if( (treelai + tree_sai) > (nlevleaf*dinc_ed) )then + + call h_allom(dbh,pft,h) + write(fates_log(),*) 'The leaf and stem are predicted for a cohort, maxed out the array size' write(fates_log(),*) 'lai: ',treelai write(fates_log(),*) 'sai: ',tree_sai @@ -753,7 +757,8 @@ real(r8) function tree_sai( pft, dbh, canopy_trim, c_area, nplant, cl, & write(fates_log(),*) 'call id: ',call_id write(fates_log(),*) 'n: ',nplant write(fates_log(),*) 'c_area: ',c_area - write(fates_log(),*) 'dbh: ',dbh + write(fates_log(),*) 'dbh: ',dbh,' dbh_max: ',EDPftvarcon_inst%allom_dbh_maxheight(pft) + write(fates_log(),*) 'h: ',h write(fates_log(),*) 'canopy_trim: ',canopy_trim write(fates_log(),*) 'target_bleaf: ',target_bleaf write(fates_log(),*) 'canopy layer: ',cl @@ -2195,90 +2200,140 @@ end function decay_coeff_kn ! ===================================================================================== - subroutine StructureResetOfDH( bdead, ipft, canopy_trim, d, h ) + subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bfnrt ) ! ========================================================================= - ! This subroutine estimates the diameter based on the structural biomass - ! using the allometric functions. Since allometry is specified with diameter + ! This subroutine estimates the diameter based on either the structural biomass + ! (if woody) or the fine root biomass (if a grass) using the allometric + ! functions. Since allometry is specified with diameter ! as the independant variable, we must do this through a search algorithm. ! Here, we keep searching until the difference between actual structure and ! the predicted structure based on the searched diameter is within a tolerance. - ! T ! ============================================================================ use FatesConstantsMod , only : calloc_abs_error ! Arguments - real(r8),intent(in) :: bdead ! actual bdead [kgC] + integer(i4),intent(in) :: ipft ! PFT index real(r8),intent(in) :: canopy_trim real(r8),intent(inout) :: d ! plant diameter [cm] real(r8),intent(out) :: h ! plant height + real(r8),intent(in),optional :: bdead ! Structural biomass + real(r8),intent(in),optional :: bfnrt ! Fine root biomass + ! Locals real(r8) :: bt_sap,dbt_sap_dd ! target sap wood at current d real(r8) :: bt_agw,dbt_agw_dd ! target AG wood at current d real(r8) :: bt_bgw,dbt_bgw_dd ! target BG wood at current d real(r8) :: bt_dead,dbt_dead_dd ! target struct wood at current d + real(r8) :: bt_fnrt,dbt_fnrt_dd ! target fineroot at current d real(r8) :: at_sap ! sapwood area (dummy) m2 real(r8) :: dd ! diameter increment for each step real(r8) :: d_try ! trial diameter real(r8) :: bt_dead_try ! trial structure biomasss real(r8) :: dbt_dead_dd_try ! trial structural derivative + real(r8) :: bt_fnrt_try ! trial fineroot biomass + real(r8) :: dbt_fnrt_dd_try ! trial fineroot derivative real(r8) :: step_frac ! step fraction integer :: counter real(r8), parameter :: step_frac0 = 0.9_r8 integer, parameter :: max_counter = 200 + + ! Do reduce "if" calls, we break this call into two parts + if ( EDPftvarcon_inst%woody(ipft) == itrue ) then - call bsap_allom(d,ipft,canopy_trim,at_sap,bt_sap,dbt_sap_dd) - call bagw_allom(d,ipft,bt_agw,dbt_agw_dd) - call bbgw_allom(d,ipft,bt_bgw,dbt_bgw_dd) - call bdead_allom(bt_agw,bt_bgw, bt_sap, ipft, bt_dead, dbt_agw_dd, & - dbt_bgw_dd, dbt_sap_dd, dbt_dead_dd) - - ! This calculates a diameter increment based on the difference - ! in structural mass and the target mass, and sets it to a fraction - ! of the diameter increment - counter = 0 - step_frac = step_frac0 - do while( (bdead-bt_dead) > calloc_abs_error .and. dbt_dead_dd>0.0_r8) - - ! vulnerable to div0 - dd = step_frac*(bdead-bt_dead)/dbt_dead_dd - d_try = d + dd - - call bsap_allom(d_try,ipft,canopy_trim,at_sap,bt_sap,dbt_sap_dd) - call bagw_allom(d_try,ipft,bt_agw,dbt_agw_dd) - call bbgw_allom(d_try,ipft,bt_bgw,dbt_bgw_dd) - call bdead_allom(bt_agw,bt_bgw, bt_sap, ipft, bt_dead_try, dbt_agw_dd, & - dbt_bgw_dd, dbt_sap_dd, dbt_dead_dd_try) - - ! Prevent overshooting - if(bt_dead_try > (bdead+calloc_abs_error)) then - step_frac = step_frac*0.5_r8 - else - step_frac = step_frac0 - d = d_try - bt_dead = bt_dead_try - dbt_dead_dd = dbt_dead_dd_try + if(.not.present(bdead)) then + write(fates_log(),*) 'woody plants must use structure for dbh reset' + call endrun(msg=errMsg(sourcefile, __LINE__)) end if - counter = counter + 1 - if (counter>max_counter) then - write(fates_log(),*) 'Having trouble converging on dbh reset' + + call bsap_allom(d,ipft,canopy_trim,at_sap,bt_sap,dbt_sap_dd) + call bagw_allom(d,ipft,bt_agw,dbt_agw_dd) + call bbgw_allom(d,ipft,bt_bgw,dbt_bgw_dd) + call bdead_allom(bt_agw,bt_bgw, bt_sap, ipft, bt_dead, dbt_agw_dd, & + dbt_bgw_dd, dbt_sap_dd, dbt_dead_dd) + + ! This calculates a diameter increment based on the difference + ! in structural mass and the target mass, and sets it to a fraction + ! of the diameter increment + counter = 0 + step_frac = step_frac0 + do while( (bdead-bt_dead) > calloc_abs_error .and. dbt_dead_dd>0.0_r8) + + ! vulnerable to div0 + dd = step_frac*(bdead-bt_dead)/dbt_dead_dd + d_try = d + dd + + call bsap_allom(d_try,ipft,canopy_trim,at_sap,bt_sap,dbt_sap_dd) + call bagw_allom(d_try,ipft,bt_agw,dbt_agw_dd) + call bbgw_allom(d_try,ipft,bt_bgw,dbt_bgw_dd) + call bdead_allom(bt_agw,bt_bgw, bt_sap, ipft, bt_dead_try, dbt_agw_dd, & + dbt_bgw_dd, dbt_sap_dd, dbt_dead_dd_try) + + ! Prevent overshooting + if(bt_dead_try > (bdead+calloc_abs_error)) then + step_frac = step_frac*0.5_r8 + else + step_frac = step_frac0 + d = d_try + bt_dead = bt_dead_try + dbt_dead_dd = dbt_dead_dd_try + end if + counter = counter + 1 + if (counter>max_counter) then + write(fates_log(),*) 'Having trouble converging on dbh reset' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + end do + + + else + + if(.not.present(bfnrt)) then + write(fates_log(),*) 'grasses must use fine-root for dbh reset' call endrun(msg=errMsg(sourcefile, __LINE__)) end if - end do + + call bfineroot(d,ipft,canopy_trim,bt_fnrt,dbt_fnrt_dd) + + counter = 0 + step_frac = step_frac0 + do while( (bfnrt-bt_fnrt) > calloc_abs_error .and. dbt_fnrt_dd>0.0_r8) + + dd = step_frac*(bfnrt-bt_fnrt)/dbt_fnrt_dd + d_try = d + dd + + call bfineroot(d_try,ipft,canopy_trim,bt_fnrt_try,dbt_fnrt_dd_try) + + ! Prevent overshooting + if(bt_fnrt_try > (bfnrt+calloc_abs_error)) then + step_frac = step_frac*0.5_r8 + else + step_frac = step_frac0 + d = d_try + bt_fnrt = bt_fnrt_try + dbt_fnrt_dd = dbt_fnrt_dd_try + end if + counter = counter + 1 + if (counter>max_counter) then + write(fates_log(),*) 'Having trouble converging on dbh reset' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + end do + + end if call h_allom(d,ipft,h) if(counter>10)then - write(fates_log(),*) 'dbh counter: ',counter + write(fates_log(),*) 'dbh counter: ',counter,EDPftvarcon_inst%woody(ipft) end if - ! At this point, the diameter, height and their target structural biomass - ! should be pretty close to and greater than actual + return - end subroutine StructureResetOfDH + end subroutine ForceDBH ! ========================================================================= diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index dae9699c30..f9ee74af22 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -339,11 +339,30 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) currentSite%flux_in = currentSite%flux_in + currentCohort%npp_acc * currentCohort%n + + leaf_c = currentCohort%prt%GetState(leaf_organ, all_carbon_elements) + currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, currentCohort%n, & + currentCohort%canopy_layer, currentPatch%canopy_layer_tlai, & + currentCohort%vcmax25top) + currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & + currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & + currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top,6 ) + + ! Conducte Maintenance Turnover (parteh) call currentCohort%prt%CheckMassConservation(ft,3) call PRTMaintTurnover(currentCohort%prt,ft,currentSite%is_drought) call currentCohort%prt%CheckMassConservation(ft,4) + leaf_c = currentCohort%prt%GetState(leaf_organ, all_carbon_elements) + currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, currentCohort%n, & + currentCohort%canopy_layer, currentPatch%canopy_layer_tlai, & + currentCohort%vcmax25top) + currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & + currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & + currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top,7 ) + + ! Conduct Growth (parteh) call currentCohort%prt%DailyPRT() call currentCohort%prt%CheckMassConservation(ft,5) diff --git a/parteh/PRTAllometricCarbonMod.F90 b/parteh/PRTAllometricCarbonMod.F90 index 43f250183f..cffd717d40 100644 --- a/parteh/PRTAllometricCarbonMod.F90 +++ b/parteh/PRTAllometricCarbonMod.F90 @@ -34,7 +34,7 @@ module PRTAllometricCarbonMod use FatesAllometryMod , only : bagw_allom use FatesAllometryMod , only : h_allom use FatesAllometryMod , only : CheckIntegratedAllometries - use FatesAllometryMod , only : StructureResetOfDH + use FatesAllometryMod , only : ForceDBH use FatesGlobals , only : endrun => fates_endrun use FatesGlobals , only : fates_log @@ -336,6 +336,7 @@ subroutine DailyPRTAllometricCarbon(this) real(r8) :: repro_c0 ! "" real(r8) :: struct_c0 ! "" + logical :: grow_struct logical :: grow_leaf ! Are leaves at allometric target and should be grown? logical :: grow_fnrt ! Are fine-roots at allometric target and should be grown? logical :: grow_sapw ! Is sapwood at allometric target and should be grown? @@ -441,55 +442,84 @@ subroutine DailyPRTAllometricCarbon(this) ! ----------------------------------------------------------------------------------- ! II. Calculate target size of the biomass compartment for a given dbh. ! ----------------------------------------------------------------------------------- - - ! Target sapwood biomass and deriv. according to allometry and trimming [kgC, kgC/cm] - call bsap_allom(dbh,ipft,canopy_trim,sapw_area,target_sapw_c) - - ! Target total above ground deriv. biomass in woody/fibrous tissues [kgC, kgC/cm] - call bagw_allom(dbh,ipft,target_agw_c) - ! Target total below ground deriv. biomass in woody/fibrous tissues [kgC, kgC/cm] - call bbgw_allom(dbh,ipft,target_bgw_c) + if( EDPftvarcon_inst%woody(ipft) == itrue) then - ! Target total dead (structrual) biomass and deriv. [kgC, kgC/cm] - call bdead_allom( target_agw_c, target_bgw_c, target_sapw_c, ipft, target_struct_c) + + ! Target sapwood biomass according to allometry and trimming [kgC] + call bsap_allom(dbh,ipft,canopy_trim,sapw_area,target_sapw_c) + + ! Target total above ground biomass in woody/fibrous tissues [kgC] + call bagw_allom(dbh,ipft,target_agw_c) + + ! Target total below ground biomass in woody/fibrous tissues [kgC] + call bbgw_allom(dbh,ipft,target_bgw_c) + + ! Target total dead (structrual) biomass [kgC] + call bdead_allom( target_agw_c, target_bgw_c, target_sapw_c, ipft, target_struct_c) + + ! ------------------------------------------------------------------------------------ + ! If structure is larger than target, then we need to correct some integration errors + ! by slightly increasing dbh to match it. + ! For grasses, if leaf biomass is larger than target, then we reset dbh to match + ! ----------------------------------------------------------------------------------- + + if( (struct_c - target_struct_c ) > calloc_abs_error ) then + + call ForceDBH( ipft, canopy_trim, dbh, hite_out, bdead=struct_c ) + + ! Set the structural target biomass to the current structural boimass [kgC] + target_struct_c = struct_c + ! Target sapwood biomass according to allometry and trimming [kgC] + call bsap_allom(dbh,ipft,canopy_trim,sapw_area,target_sapw_c) + + end if + + + ! Target leaf biomass according to allometry and trimming + call bleaf(dbh,ipft,canopy_trim,target_leaf_c) + + ! Target fine-root biomass and deriv. according to allometry and trimming [kgC, kgC/cm] + call bfineroot(dbh,ipft,canopy_trim,target_fnrt_c) + + ! Target storage carbon [kgC,kgC/cm] + call bstore_allom(dbh,ipft,canopy_trim,target_store_c) + + else - ! ------------------------------------------------------------------------------------ - ! If structure is larger than target, then we need to correct some integration errors - ! by slightly increasing dbh to match it. - ! For grasses, if leaf biomass is larger than target, then we reset dbh to match - ! ----------------------------------------------------------------------------------- - if( (( struct_c - target_struct_c ) > calloc_abs_error) .and. & - (EDPftvarcon_inst%woody(ipft) == itrue) ) then + ! Target fine-root biomass and deriv. according to + ! allometry and trimming [kgC] + call bfineroot(dbh,ipft,canopy_trim,target_fnrt_c) - call StructureResetOfDH( struct_c, ipft, & - canopy_trim, dbh, hite_out ) + if( (fnrt_c - target_fnrt_c ) > calloc_abs_error ) then + + call ForceDBH( ipft, canopy_trim, dbh, hite_out, bfnrt=fnrt_c ) + + target_fnrt_c = fnrt_c + + end if - ! Target sapwood biomass and deriv. according to allometry and trimming [kgC, kgC/cm] + ! Target sapwood biomass according to allometry and trimming [kgC] call bsap_allom(dbh,ipft,canopy_trim,sapw_area,target_sapw_c) - ! Target total above ground deriv. biomass in woody/fibrous tissues [kgC, kgC/cm] + ! Target total above ground biomass in woody/fibrous tissues [kgC] call bagw_allom(dbh,ipft,target_agw_c) - - ! Target total below ground deriv. biomass in woody/fibrous tissues [kgC, kgC/cm] - call bbgw_allom(dbh,ipft,target_bgw_c) - - ! Target total dead (structrual) biomass and deriv. [kgC, kgC/cm] - call bdead_allom( target_agw_c, target_bgw_c, target_sapw_c, ipft, target_struct_c) - end if - - ! Target leaf biomass according to allometry and trimming - call bleaf(dbh,ipft,canopy_trim,target_leaf_c) + ! Target total below ground biomass in woody/fibrous tissues [kgC] + call bbgw_allom(dbh,ipft,target_bgw_c) - ! Target fine-root biomass and deriv. according to allometry and trimming [kgC, kgC/cm] - call bfineroot(dbh,ipft,canopy_trim,target_fnrt_c) + ! Target total dead (structrual) biomass and [kgC] + call bdead_allom( target_agw_c, target_bgw_c, target_sapw_c, ipft, target_struct_c) + + ! Target leaf biomass according to allometry and trimming + call bleaf(dbh,ipft,canopy_trim,target_leaf_c) - ! Target storage carbon [kgC,kgC/cm] - call bstore_allom(dbh,ipft,canopy_trim,target_store_c) + ! Target storage carbon [kgC] + call bstore_allom(dbh,ipft,canopy_trim,target_store_c) - + + end if ! ----------------------------------------------------------------------------------- @@ -667,32 +697,24 @@ subroutine DailyPRTAllometricCarbon(this) ! allow actual pools to be above the target, and in these cases, it sends ! a false on the "grow_<>" flag, allowing the plant to grow into these pools. ! It also checks to make sure that structural biomass is not above the target. - if ( EDPftvarcon_inst%woody(ipft) == itrue ) then - - - if( (target_store_c - store_c)>calloc_abs_error) then - write(fates_log(),*) 'storage is not on-allometry at the growth step' - write(fates_log(),*) 'exiting' - write(fates_log(),*) 'cbal: ',carbon_balance - write(fates_log(),*) 'near-zero',nearzero - write(fates_log(),*) 'store_c: ',store_c - write(fates_log(),*) 'target c: ',target_store_c - write(fates_log(),*) 'store_c0:', store_c0 - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if - - call TargetAllometryCheck(sum(leaf_c(1:nleafage)), fnrt_c, sapw_c, & - store_c, struct_c, & - target_leaf_c, target_fnrt_c, & - target_sapw_c, target_store_c, target_struct_c, & - grow_leaf, grow_fnrt, grow_sapw, grow_store) - else ! for grasses - grow_leaf = .true. - grow_fnrt = .true. - grow_sapw = .true. - grow_store = .true. + if( (target_store_c - store_c)>calloc_abs_error) then + write(fates_log(),*) 'storage is not on-allometry at the growth step' + write(fates_log(),*) 'exiting' + write(fates_log(),*) 'cbal: ',carbon_balance + write(fates_log(),*) 'near-zero',nearzero + write(fates_log(),*) 'store_c: ',store_c + write(fates_log(),*) 'target c: ',target_store_c + write(fates_log(),*) 'store_c0:', store_c0 + call endrun(msg=errMsg(sourcefile, __LINE__)) end if + + + call TargetAllometryCheck(sum(leaf_c(1:nleafage)), fnrt_c, sapw_c, & + store_c, struct_c, & + target_leaf_c, target_fnrt_c, & + target_sapw_c, target_store_c, target_struct_c, & + grow_struct, grow_leaf, grow_fnrt, grow_sapw, grow_store) ! -------------------------------------------------------------------------------- ! The numerical integration of growth requires that the instantaneous state @@ -729,7 +751,7 @@ subroutine DailyPRTAllometricCarbon(this) c_mask(fnrt_c_id) = grow_fnrt c_mask(sapw_c_id) = grow_sapw c_mask(store_c_id) = grow_store - c_mask(struct_c_id) = .true. ! Always increment dead on growth step + c_mask(struct_c_id) = grow_struct c_mask(repro_c_id) = .true. ! Always calculate reproduction on growth c_mask(dbh_id) = .true. ! Always increment dbh on growth step @@ -1045,7 +1067,7 @@ end function AllomCGrowthDeriv subroutine TargetAllometryCheck(bleaf,bfroot,bsap,bstore,bdead, & bt_leaf,bt_froot,bt_sap,bt_store,bt_dead, & - grow_leaf,grow_froot,grow_sapw,grow_store) + grow_dead,grow_leaf,grow_froot,grow_sapw,grow_store) ! Arguments real(r8),intent(in) :: bleaf !actual @@ -1062,6 +1084,7 @@ subroutine TargetAllometryCheck(bleaf,bfroot,bsap,bstore,bdead, & logical,intent(out) :: grow_froot logical,intent(out) :: grow_sapw logical,intent(out) :: grow_store + logical,intent(out) :: grow_dead if( (bt_leaf - bleaf)>calloc_abs_error) then write(fates_log(),*) 'leaves are not on-allometry at the growth step' @@ -1108,7 +1131,14 @@ subroutine TargetAllometryCheck(bleaf,bfroot,bsap,bstore,bdead, & write(fates_log(),*) 'structure not on-allometry at the growth step' write(fates_log(),*) 'exiting',bdead,bt_dead call endrun(msg=errMsg(sourcefile, __LINE__)) + elseif( (bdead-bt_dead)> calloc_abs_error) then + grow_dead = .false. + else + grow_dead = .true. end if + + + return end subroutine TargetAllometryCheck ! ===================================================================================== From 6b22ae78a9db2f88a6cc3da28a51b77a4de92244 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 7 Mar 2019 17:19:21 -0700 Subject: [PATCH 47/78] Reduced number of canopy layers back to 2 in attempts to avoid canopy radiation errors. Also, made provisions to forcefully terminate patches that have super small areas, even if they want to fuse with the youngest patch. --- biogeochem/EDCanopyStructureMod.F90 | 5 +++-- biogeochem/EDPatchDynamicsMod.F90 | 24 +++++++++++++----------- main/EDTypesMod.F90 | 7 ++++++- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index 16108301f9..59b0173ce8 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -60,9 +60,9 @@ module EDCanopyStructureMod ! will attempt to reduce errors ! below this level - real(r8), parameter :: area_check_precision = 1.0E-6_r8 ! Area conservation checks must + real(r8), parameter :: area_check_precision = 1.0E-7_r8 ! Area conservation checks must ! be within this absolute tolerance - real(r8), parameter :: area_check_rel_precision = 1.0E-3_r8 ! Area conservation checks must + real(r8), parameter :: area_check_rel_precision = 1.0E-4_r8 ! Area conservation checks must ! be within this relative tolerance real(r8), parameter :: similar_height_tol = 1.0E-3_r8 ! I think trees that differ by 1mm @@ -796,6 +796,7 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) write(fates_log(),*) 'patch%area:',currentPatch%area write(fates_log(),*) 'ilayer: ',i_lyr write(fates_log(),*) 'bias:',arealayer - currentPatch%area + write(fates_log(),*) 'rel bias:',(arealayer - currentPatch%area)/arealayer write(fates_log(),*) 'demote_area:',demote_area call endrun(msg=errMsg(sourcefile, __LINE__)) end if diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 7803d8c7b6..174d97d159 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -12,6 +12,7 @@ module EDPatchDynamicsMod use EDTypesMod , only : maxPatchesPerSite use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type use EDTypesMod , only : min_patch_area + use EDTypesMod , only : min_patch_area_forced use EDTypesMod , only : nclmax use EDTypesMod , only : maxpft use EDTypesMod , only : dtype_ifall @@ -1887,7 +1888,15 @@ subroutine terminate_patches(currentSite) if(currentPatch%area <= min_patch_area)then - if ( .not.associated(currentPatch,currentSite%youngest_patch) ) then + ! Even if the patch area is small, avoid fusing it into its neighbor + ! if it is the youngest of all patches. We do this in attempts to maintain + ! a discrete patch for very young patches + ! However, if the patch to be fused is excessivlely small, then fuse + ! at all costs. If it is not fused, it will make + + + if ( .not.associated(currentPatch,currentSite%youngest_patch) .or. & + currentPatch%area <= min_patch_area_forced ) then if(associated(currentPatch%older) )then @@ -1908,7 +1917,7 @@ subroutine terminate_patches(currentSite) ! This logic checks to make sure that the younger patch is not the youngest ! patch. As mentioned earlier, we try not to fuse it. - elseif( .not. associated(currentPatch%younger,currentSite%youngest_patch) ) then + elseif( associated(currentPatch%younger) ) then if(debug) & write(fates_log(),*) 'fusing to younger patch because oldest one is too small', & @@ -1928,16 +1937,9 @@ subroutine terminate_patches(currentSite) enddo !check area is not exceeded - areatot = 0._r8 - currentPatch => currentSite%oldest_patch - do while(associated(currentPatch)) - areatot = areatot + currentPatch%area - currentPatch => currentPatch%younger - if((areatot-area) > 0.0000001_r8)then - write(fates_log(),*) 'ED: areatot too large. end terminate', areatot - endif - enddo + call check_patch_area( currentSite ) + return end subroutine terminate_patches ! ===================================================================================== diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 4fc7ee7d71..834873813e 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -18,7 +18,7 @@ module EDTypesMod integer, parameter :: maxPatchesPerSite = 10 ! maximum number of patches to live on a site integer, parameter :: maxCohortsPerPatch = 100 ! maximum number of cohorts per patch - integer, parameter :: nclmax = 3 ! Maximum number of canopy layers + integer, parameter :: nclmax = 2 ! Maximum number of canopy layers integer, parameter :: ican_upper = 1 ! Nominal index for the upper canopy integer, parameter :: ican_ustory = 2 ! Nominal index for diagnostics that refer ! to understory layers (all layers that @@ -151,6 +151,11 @@ module EDTypesMod real(r8), parameter :: min_npm2 = 1.0E-7_r8 ! minimum cohort number density per m2 before termination real(r8), parameter :: min_patch_area = 0.01_r8 ! smallest allowable patch area before termination + real(r8), parameter :: min_patch_area_forced = 0.0001_r8 ! patch termination will not fuse the youngest patch + ! if the area is less than min_patch_area. + ! however, it is allowed to fuse the youngest patch + ! if the fusion area is less than min_patch_area_forced + real(r8), parameter :: min_nppatch = min_npm2*min_patch_area ! minimum number of cohorts per patch (min_npm2*min_patch_area) real(r8), parameter :: min_n_safemath = 1.0E-12_r8 ! in some cases, we want to immediately remove super small ! number densities of cohorts to prevent FPEs From 84deff5b18e63244f511b0a76b4784f818fa3009 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 8 Mar 2019 12:43:55 -0700 Subject: [PATCH 48/78] Fix so can compile with nag on hobart --- biogeophys/FatesPlantHydraulicsMod.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/biogeophys/FatesPlantHydraulicsMod.F90 b/biogeophys/FatesPlantHydraulicsMod.F90 index 86ffe14b5a..b55f827dd9 100644 --- a/biogeophys/FatesPlantHydraulicsMod.F90 +++ b/biogeophys/FatesPlantHydraulicsMod.F90 @@ -965,11 +965,11 @@ subroutine updateSizeDepRhizHydProps(currentSite, bc_in ) kmax_soil_total = 2._r8*pi_const*csite_hydr%l_aroot_layer(j) / & log(csite_hydr%r_node_shell(j,k)/csite_hydr%rs1(j))*hksat_s csite_hydr%kmax_upper_shell(j,k) = (1._r8/kmax_root_surf_total + & - 1._r8/kmax_soil_total)**-1._r8 + 1._r8/kmax_soil_total)**(-1) csite_hydr%kmax_bound_shell(j,k) = (1._r8/kmax_root_surf_total + & - 1._r8/kmax_soil_total)**-1._r8 + 1._r8/kmax_soil_total)**(-1) csite_hydr%kmax_lower_shell(j,k) = (1._r8/kmax_root_surf_total + & - 1._r8/kmax_soil_total)**-1._r8 + 1._r8/kmax_soil_total)**(-1) end if if(j == 1) then if(csite_hydr%r_node_shell(j,k) <= csite_hydr%rs1(j)) then @@ -980,11 +980,11 @@ subroutine updateSizeDepRhizHydProps(currentSite, bc_in ) kmax_soil_total = 2._r8*pi_const*csite_hydr%l_aroot_1D / & log(csite_hydr%r_node_shell_1D(k)/csite_hydr%rs1(j))*hksat_s csite_hydr%kmax_upper_shell_1D(k) = (1._r8/kmax_root_surf_total + & - 1._r8/kmax_soil_total)**-1._r8 + 1._r8/kmax_soil_total)**(-1) csite_hydr%kmax_bound_shell_1D(k) = (1._r8/kmax_root_surf_total + & - 1._r8/kmax_soil_total)**-1._r8 + 1._r8/kmax_soil_total)**(-1) csite_hydr%kmax_lower_shell_1D(k) = (1._r8/kmax_root_surf_total + & - 1._r8/kmax_soil_total)**-1._r8 + 1._r8/kmax_soil_total)**(-1) end if end if else From bc933893864c80d8bdc3e0133cabc0469723237c Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 8 Mar 2019 12:50:32 -0700 Subject: [PATCH 49/78] Changed logic to patch termination to ensure no super small patches escape detection and fusion --- biogeochem/EDPatchDynamicsMod.F90 | 36 ++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 174d97d159..a7403a17d8 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1538,7 +1538,7 @@ subroutine fuse_patches( csite, bc_in ) ! Keep doing this until nopatches >= maxPatchesPerSite ! !---------------------------------------------------------------------! - do while(iterate == 1) + do while(iterate == 1 .and. nopatches>1) !---------------------------------------------------------------------! ! Calculate the biomass profile of each patch ! !---------------------------------------------------------------------! @@ -1556,10 +1556,6 @@ subroutine fuse_patches( csite, bc_in ) tpp => currentSite%youngest_patch do while(associated(tpp)) - if(.not.associated(currentPatch))then - write(fates_log(),*) 'ED: issue with currentPatch' - endif - if(associated(tpp).and.associated(currentPatch))then !-------------------------------------------------------------------------------------------- @@ -1893,11 +1889,15 @@ subroutine terminate_patches(currentSite) ! a discrete patch for very young patches ! However, if the patch to be fused is excessivlely small, then fuse ! at all costs. If it is not fused, it will make - + if ( currentPatch%area <= min_patch_area_forced ) & + write(fates_log(),*) 'small area: ',currentPatch%area,currentSite%lat,currentSite%lon if ( .not.associated(currentPatch,currentSite%youngest_patch) .or. & currentPatch%area <= min_patch_area_forced ) then + if ( currentPatch%area <= min_patch_area_forced ) & + write(fates_log(),*) 'small area(2): ',currentPatch%area,currentSite%lat,currentSite%lon + if(associated(currentPatch%older) )then if(debug) & @@ -1905,12 +1905,18 @@ subroutine terminate_patches(currentSite) currentPatch%area, & currentPatch%older%area + if ( currentPatch%area <= min_patch_area_forced ) & + write(fates_log(),*) 'small area(3): ',currentPatch%area,currentSite%lat,currentSite%lon + ! We set a pointer to this patch, because ! it will be returned by the subroutine as de-referenced olderPatch => currentPatch%older call fuse_2_patches(currentSite, olderPatch, currentPatch) + if ( currentPatch%area <= min_patch_area_forced ) & + write(fates_log(),*) 'small area(4): ',currentPatch%area,currentSite%lat,currentSite%lon + ! The fusion process has updated the "older" pointer on currentPatch ! for us. @@ -1923,17 +1929,31 @@ subroutine terminate_patches(currentSite) write(fates_log(),*) 'fusing to younger patch because oldest one is too small', & currentPatch%area + if ( currentPatch%area <= min_patch_area_forced ) & + write(fates_log(),*) 'small area(5): ',currentPatch%area,currentSite%lat,currentSite%lon + youngerPatch => currentPatch%younger call fuse_2_patches(currentSite, youngerPatch, currentPatch) + if ( currentPatch%area <= min_patch_area_forced ) & + write(fates_log(),*) 'small area(6): ',currentPatch%area,currentSite%lat,currentSite%lon + ! The fusion process has updated the "younger" pointer on currentPatch endif endif endif - - currentPatch => currentPatch%older + ! It is possible that an incredibly small patch just fused into another incredibly + ! small patch, resulting in an incredibly small patch. It is also possible that this + ! resulting incredibly small patch is the oldest patch. If this was true than + ! we would had been at the end of the loop, and left with an incredibly small patch. + ! Think this is impossible? No, this really happens, especially when we have fires. + ! So, we don't move forward until we have merged enough area into this thing. + + if(currentPatch%area > min_patch_area_forced)then + currentPatch => currentPatch%older + end if enddo !check area is not exceeded From b141f29f77773cd7948721d3be4cd7959886b8e5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 8 Mar 2019 13:11:19 -0700 Subject: [PATCH 50/78] Put arguments in right order so will compiler with nag on hobart --- biogeochem/FatesAllometryMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeochem/FatesAllometryMod.F90 b/biogeochem/FatesAllometryMod.F90 index c09274b985..c13637891f 100644 --- a/biogeochem/FatesAllometryMod.F90 +++ b/biogeochem/FatesAllometryMod.F90 @@ -1808,8 +1808,8 @@ subroutine set_root_fraction(root_fraction, ft, zi, lowerb, icontext ) ! !ARGUMENTS real(r8),intent(inout) :: root_fraction(:) integer, intent(in) :: ft - real(r8),intent(in) :: zi(lowerb:) integer,intent(in) :: lowerb + real(r8),intent(in) :: zi(lowerb:) integer,intent(in) :: icontext ! Parameters From 5f7214e7a5e7c24d99b919e2b0c5f1ad81b7d32e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 9 Mar 2019 12:40:07 -0700 Subject: [PATCH 51/78] Fix some issues so will compile on nag, get the order of arguments correct --- biogeophys/FatesPlantHydraulicsMod.F90 | 2 +- main/FatesRestartInterfaceMod.F90 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/biogeophys/FatesPlantHydraulicsMod.F90 b/biogeophys/FatesPlantHydraulicsMod.F90 index f32177a4de..2792d02c7f 100644 --- a/biogeophys/FatesPlantHydraulicsMod.F90 +++ b/biogeophys/FatesPlantHydraulicsMod.F90 @@ -208,8 +208,8 @@ subroutine RestartHydrStates(sites,nsites,bc_in,bc_out) ! information that relies on these key states, as well as other vegetation ! states such as carbon pools and plant geometry. - type(ed_site_type) , intent(inout), target :: sites(nsites) integer , intent(in) :: nsites + type(ed_site_type) , intent(inout), target :: sites(nsites) type(bc_in_type) , intent(in) :: bc_in(nsites) type(bc_out_type) , intent(inout) :: bc_out(nsites) diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index fb9b316f45..7b9f5ba3a2 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -1267,8 +1267,8 @@ subroutine GetCohortRealVector(this, state_vector, len_state_vector, & ! and pulls from the different associated restart variables class(fates_restart_interface_type) , intent(inout) :: this - real(r8),intent(inout) :: state_vector(len_state_vector) integer,intent(in) :: len_state_vector + real(r8),intent(inout) :: state_vector(len_state_vector) integer,intent(in) :: variable_index_base integer,intent(in) :: co_global_index @@ -1292,8 +1292,8 @@ subroutine SetCohortRealVector(this, state_vector, len_state_vector, & ! and pushes into the restart arrays the different associated restart variables class(fates_restart_interface_type) , intent(inout) :: this - real(r8),intent(in) :: state_vector(len_state_vector) integer,intent(in) :: len_state_vector + real(r8),intent(in) :: state_vector(len_state_vector) integer,intent(in) :: variable_index_base integer,intent(in) :: co_global_index From 0bbb5f0e9df2b06a16a63a699ace8b3be4cda8c6 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 9 Mar 2019 13:21:08 -0700 Subject: [PATCH 52/78] Add public attributed needed by nag compiler --- main/FatesInterfaceMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/FatesInterfaceMod.F90 b/main/FatesInterfaceMod.F90 index 5c7586db17..1ae7ead63f 100644 --- a/main/FatesInterfaceMod.F90 +++ b/main/FatesInterfaceMod.F90 @@ -253,7 +253,7 @@ module FatesInterfaceMod integer, protected :: nlevsclass ! The total number of cohort size class bins output to history integer, protected :: nlevage ! The total number of patch age bins output to history integer, protected :: nlevheight ! The total number of height bins output to history - integer, protected :: nleafage ! The total number of leaf age classes + integer, public, protected :: nleafage ! The total number of leaf age classes ! ------------------------------------------------------------------------------------- ! Structured Boundary Conditions (SITE/PATCH SCALE) From 519edeeb2b1b59ee4765f0d55464b4abe1e43752 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 9 Mar 2019 14:25:24 -0700 Subject: [PATCH 53/78] Make default private, and explicitly type public things as public --- main/FatesInterfaceMod.F90 | 296 +++++++++++++++++++------------------ 1 file changed, 150 insertions(+), 146 deletions(-) diff --git a/main/FatesInterfaceMod.F90 b/main/FatesInterfaceMod.F90 index 1ae7ead63f..b080894d38 100644 --- a/main/FatesInterfaceMod.F90 +++ b/main/FatesInterfaceMod.F90 @@ -43,12 +43,16 @@ module FatesInterfaceMod implicit none + private ! By default everything is private + public :: FatesInterfaceInit public :: set_fates_ctrlparms public :: SetFatesTime public :: set_fates_global_elements public :: FatesReportParameters public :: InitPARTEHGlobals + public :: allocate_bcin + public :: allocate_bcout character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -59,113 +63,113 @@ module FatesInterfaceMod ! ------------------------------------------------------------------------------------- - integer, protected :: hlm_numSWb ! Number of broad-bands in the short-wave radiation - ! specturm to track - ! (typically 2 as a default, VIS/NIR, in ED variants <2016) + integer, public, protected :: hlm_numSWb ! Number of broad-bands in the short-wave radiation + ! specturm to track + ! (typically 2 as a default, VIS/NIR, in ED variants <2016) - integer, protected :: hlm_ivis ! The HLMs assumption of the array index associated with the - ! visible portion of the spectrum in short-wave radiation arrays + integer, public, protected :: hlm_ivis ! The HLMs assumption of the array index associated with the + ! visible portion of the spectrum in short-wave radiation arrays - integer, protected :: hlm_inir ! The HLMs assumption of the array index associated with the - ! NIR portion of the spectrum in short-wave radiation arrays + integer, public, protected :: hlm_inir ! The HLMs assumption of the array index associated with the + ! NIR portion of the spectrum in short-wave radiation arrays - integer, protected :: hlm_numlevgrnd ! Number of ground layers - ! NOTE! SOIL LAYERS ARE NOT A GLOBAL, THEY - ! ARE VARIABLE BY SITE + integer, public, protected :: hlm_numlevgrnd ! Number of ground layers + ! NOTE! SOIL LAYERS ARE NOT A GLOBAL, THEY + ! ARE VARIABLE BY SITE - integer, protected :: hlm_is_restart ! Is the HLM signalling that this is a restart - ! type simulation? - ! 1=TRUE, 0=FALSE + integer, public, protected :: hlm_is_restart ! Is the HLM signalling that this is a restart + ! type simulation? + ! 1=TRUE, 0=FALSE - character(len=16), protected :: hlm_name ! This character string passed by the HLM - ! is used during the processing of IO data, - ! so that FATES knows which IO variables it - ! should prepare. For instance - ! ATS, ALM and CLM will only want variables - ! specficially packaged for them. - ! This string sets which filter is enacted. + character(len=16), public, protected :: hlm_name ! This character string passed by the HLM + ! is used during the processing of IO data, + ! so that FATES knows which IO variables it + ! should prepare. For instance + ! ATS, ALM and CLM will only want variables + ! specficially packaged for them. + ! This string sets which filter is enacted. - real(r8), protected :: hlm_hio_ignore_val ! This value can be flushed to history - ! diagnostics, such that the - ! HLM will interpret that the value should not - ! be included in the average. + real(r8), public, protected :: hlm_hio_ignore_val ! This value can be flushed to history + ! diagnostics, such that the + ! HLM will interpret that the value should not + ! be included in the average. - integer, protected :: hlm_masterproc ! Is this the master processor, typically useful - ! for knowing if the current machine should be - ! printing out messages to the logs or terminals - ! 1 = TRUE (is master) 0 = FALSE (is not master) - - integer, protected :: hlm_ipedof ! The HLM pedotransfer index - ! this is only used by the plant hydraulics - ! submodule to check and/or enable consistency - ! between the pedotransfer functions of the HLM - ! and how it moves and stores water in its - ! rhizosphere shells + integer, public, protected :: hlm_masterproc ! Is this the master processor, typically useful + ! for knowing if the current machine should be + ! printing out messages to the logs or terminals + ! 1 = TRUE (is master) 0 = FALSE (is not master) + + integer, public, protected :: hlm_ipedof ! The HLM pedotransfer index + ! this is only used by the plant hydraulics + ! submodule to check and/or enable consistency + ! between the pedotransfer functions of the HLM + ! and how it moves and stores water in its + ! rhizosphere shells - integer, protected :: hlm_max_patch_per_site ! The HLM needs to exchange some patch - ! level quantities with FATES - ! FATES does not dictate those allocations - ! since it happens pretty early in - ! the model initialization sequence. - ! So we want to at least query it, - ! compare it to our maxpatchpersite, - ! and gracefully halt if we are over-allocating - - integer, protected :: hlm_parteh_mode ! This flag signals which Plant Allocation and Reactive - ! Transport (exensible) Hypothesis (PARTEH) to use - - - integer, protected :: hlm_use_vertsoilc ! This flag signals whether or not the - ! host model is using vertically discretized - ! soil carbon - ! 1 = TRUE, 0 = FALSE + integer, public, protected :: hlm_max_patch_per_site ! The HLM needs to exchange some patch + ! level quantities with FATES + ! FATES does not dictate those allocations + ! since it happens pretty early in + ! the model initialization sequence. + ! So we want to at least query it, + ! compare it to our maxpatchpersite, + ! and gracefully halt if we are over-allocating + + integer, public, protected :: hlm_parteh_mode ! This flag signals which Plant Allocation and Reactive + ! Transport (exensible) Hypothesis (PARTEH) to use + + + integer, public, protected :: hlm_use_vertsoilc ! This flag signals whether or not the + ! host model is using vertically discretized + ! soil carbon + ! 1 = TRUE, 0 = FALSE - integer, protected :: hlm_use_spitfire ! This flag signals whether or not to use SPITFIRE - ! 1 = TRUE, 0 = FALSE - - - integer, protected :: hlm_use_logging ! This flag signals whether or not to use - ! the logging module - - integer, protected :: hlm_use_planthydro ! This flag signals whether or not to use - ! plant hydraulics (bchristo/xu methods) - ! 1 = TRUE, 0 = FALSE - ! THIS IS CURRENTLY NOT SUPPORTED - - integer, protected :: hlm_use_ed_st3 ! This flag signals whether or not to use - ! (ST)atic (ST)and (ST)ructure mode (ST3) - ! Essentially, this gives us the ability - ! to turn off "dynamics", ie growth, disturbance - ! recruitment and mortality. - ! (EXPERIMENTAL!!!!! - RGK 07-2017) - ! 1 = TRUE, 0 = FALSE - ! default should be FALSE (dynamics on) - ! cannot be true with prescribed_phys - - integer, protected :: hlm_use_ed_prescribed_phys ! This flag signals whether or not to use - ! prescribed physiology, somewhat the opposite - ! to ST3, in this case can turn off - ! fast processes like photosynthesis and respiration - ! and prescribe NPP - ! (NOT CURRENTLY IMPLEMENTED - PLACEHOLDER) - ! 1 = TRUE, 0 = FALSE - ! default should be FALSE (biophysics on) - ! cannot be true with st3 mode - - integer, protected :: hlm_use_inventory_init ! Initialize this simulation from - ! an inventory file. If this is toggled on - ! an inventory control file must be specified - ! as well. - ! 1 = TRUE, 0 = FALSE + integer, public, protected :: hlm_use_spitfire ! This flag signals whether or not to use SPITFIRE + ! 1 = TRUE, 0 = FALSE + + + integer, public, protected :: hlm_use_logging ! This flag signals whether or not to use + ! the logging module + + integer, public, protected :: hlm_use_planthydro ! This flag signals whether or not to use + ! plant hydraulics (bchristo/xu methods) + ! 1 = TRUE, 0 = FALSE + ! THIS IS CURRENTLY NOT SUPPORTED + + integer, public, protected :: hlm_use_ed_st3 ! This flag signals whether or not to use + ! (ST)atic (ST)and (ST)ructure mode (ST3) + ! Essentially, this gives us the ability + ! to turn off "dynamics", ie growth, disturbance + ! recruitment and mortality. + ! (EXPERIMENTAL!!!!! - RGK 07-2017) + ! 1 = TRUE, 0 = FALSE + ! default should be FALSE (dynamics on) + ! cannot be true with prescribed_phys + + integer, public, protected :: hlm_use_ed_prescribed_phys ! This flag signals whether or not to use + ! prescribed physiology, somewhat the opposite + ! to ST3, in this case can turn off + ! fast processes like photosynthesis and respiration + ! and prescribe NPP + ! (NOT CURRENTLY IMPLEMENTED - PLACEHOLDER) + ! 1 = TRUE, 0 = FALSE + ! default should be FALSE (biophysics on) + ! cannot be true with st3 mode + + integer, public, protected :: hlm_use_inventory_init ! Initialize this simulation from + ! an inventory file. If this is toggled on + ! an inventory control file must be specified + ! as well. + ! 1 = TRUE, 0 = FALSE - character(len=256), protected :: hlm_inventory_ctrl_file ! This is the full path to the - ! inventory control file that - ! specifieds the availabel inventory datasets - ! there locations and their formats - ! This need only be defined when - ! hlm_use_inventory_init = 1 + character(len=256), public, protected :: hlm_inventory_ctrl_file ! This is the full path to the + ! inventory control file that + ! specifieds the availabel inventory datasets + ! there locations and their formats + ! This need only be defined when + ! hlm_use_inventory_init = 1 ! ------------------------------------------------------------------------------------- ! Parameters that are dictated by FATES and known to be required knowledge @@ -174,19 +178,19 @@ module FatesInterfaceMod ! Variables mostly used for dimensioning host land model (HLM) array spaces - integer, protected :: fates_maxElementsPerPatch ! maxElementsPerPatch is the value that is ultimately - ! used to set the size of the largest arrays necessary - ! in things like restart files (probably hosted by the - ! HLM). The size of these arrays are not a parameter - ! because it is simply the maximum of several different - ! dimensions. It is possible that this would be the - ! maximum number of cohorts per patch, but - ! but it could be other things. - - integer, protected :: fates_maxElementsPerSite ! This is the max number of individual items one can store per - ! each grid cell and effects the striding in the ED restart - ! data as some fields are arrays where each array is - ! associated with one cohort + integer, public, protected :: fates_maxElementsPerPatch ! maxElementsPerPatch is the value that is ultimately + ! used to set the size of the largest arrays necessary + ! in things like restart files (probably hosted by the + ! HLM). The size of these arrays are not a parameter + ! because it is simply the maximum of several different + ! dimensions. It is possible that this would be the + ! maximum number of cohorts per patch, but + ! but it could be other things. + + integer, public, protected :: fates_maxElementsPerSite ! This is the max number of individual items one can store per + ! each grid cell and effects the striding in the ED restart + ! data as some fields are arrays where each array is + ! associated with one cohort ! ------------------------------------------------------------------------------------- ! These vectors are used for history output mapping @@ -197,27 +201,27 @@ module FatesInterfaceMod ! well. ! ------------------------------------------------------------------------------------- - real(r8), allocatable :: fates_hdim_levsclass(:) ! plant size class lower bound dimension - integer , allocatable :: fates_hdim_pfmap_levscpf(:) ! map of pfts into size-class x pft dimension - integer , allocatable :: fates_hdim_scmap_levscpf(:) ! map of size-class into size-class x pft dimension - real(r8), allocatable :: fates_hdim_levage(:) ! patch age lower bound dimension - real(r8), allocatable :: fates_hdim_levheight(:) ! height lower bound dimension - integer , allocatable :: fates_hdim_levpft(:) ! plant pft dimension - integer , allocatable :: fates_hdim_levfuel(:) ! fire fuel class dimension - integer , allocatable :: fates_hdim_levcwdsc(:) ! cwd class dimension - integer , allocatable :: fates_hdim_levcan(:) ! canopy-layer dimension - integer , allocatable :: fates_hdim_canmap_levcnlf(:) ! canopy-layer map into the canopy-layer x leaf-layer dim - integer , allocatable :: fates_hdim_lfmap_levcnlf(:) ! leaf-layer map into the can-layer x leaf-layer dimension - integer , allocatable :: fates_hdim_canmap_levcnlfpf(:) ! can-layer map into the can-layer x pft x leaf-layer dim - integer , allocatable :: fates_hdim_lfmap_levcnlfpf(:) ! leaf-layer map into the can-layer x pft x leaf-layer dim - integer , allocatable :: fates_hdim_pftmap_levcnlfpf(:) ! pft map into the canopy-layer x pft x leaf-layer dim - integer , allocatable :: fates_hdim_scmap_levscag(:) ! map of size-class into size-class x patch age dimension - integer , allocatable :: fates_hdim_agmap_levscag(:) ! map of patch-age into size-class x patch age dimension - integer , allocatable :: fates_hdim_scmap_levscagpft(:) ! map of size-class into size-class x patch age x pft dimension - integer , allocatable :: fates_hdim_agmap_levscagpft(:) ! map of patch-age into size-class x patch age x pft dimension - integer , allocatable :: fates_hdim_pftmap_levscagpft(:) ! map of pft into size-class x patch age x pft dimension - integer , allocatable :: fates_hdim_agmap_levagepft(:) ! map of patch-age into patch age x pft dimension - integer , allocatable :: fates_hdim_pftmap_levagepft(:) ! map of pft into patch age x pft dimension + real(r8), public, allocatable :: fates_hdim_levsclass(:) ! plant size class lower bound dimension + integer , public, allocatable :: fates_hdim_pfmap_levscpf(:) ! map of pfts into size-class x pft dimension + integer , public, allocatable :: fates_hdim_scmap_levscpf(:) ! map of size-class into size-class x pft dimension + real(r8), public, allocatable :: fates_hdim_levage(:) ! patch age lower bound dimension + real(r8), public, allocatable :: fates_hdim_levheight(:) ! height lower bound dimension + integer , public, allocatable :: fates_hdim_levpft(:) ! plant pft dimension + integer , public, allocatable :: fates_hdim_levfuel(:) ! fire fuel class dimension + integer , public, allocatable :: fates_hdim_levcwdsc(:) ! cwd class dimension + integer , public, allocatable :: fates_hdim_levcan(:) ! canopy-layer dimension + integer , public, allocatable :: fates_hdim_canmap_levcnlf(:) ! canopy-layer map into the canopy-layer x leaf-layer dim + integer , public, allocatable :: fates_hdim_lfmap_levcnlf(:) ! leaf-layer map into the can-layer x leaf-layer dimension + integer , public, allocatable :: fates_hdim_canmap_levcnlfpf(:) ! can-layer map into the can-layer x pft x leaf-layer dim + integer , public, allocatable :: fates_hdim_lfmap_levcnlfpf(:) ! leaf-layer map into the can-layer x pft x leaf-layer dim + integer , public, allocatable :: fates_hdim_pftmap_levcnlfpf(:) ! pft map into the canopy-layer x pft x leaf-layer dim + integer , public, allocatable :: fates_hdim_scmap_levscag(:) ! map of size-class into size-class x patch age dimension + integer , public, allocatable :: fates_hdim_agmap_levscag(:) ! map of patch-age into size-class x patch age dimension + integer , public, allocatable :: fates_hdim_scmap_levscagpft(:) ! map of size-class into size-class x patch age x pft dimension + integer , public, allocatable :: fates_hdim_agmap_levscagpft(:) ! map of patch-age into size-class x patch age x pft dimension + integer , public, allocatable :: fates_hdim_pftmap_levscagpft(:) ! map of pft into size-class x patch age x pft dimension + integer , public, allocatable :: fates_hdim_agmap_levagepft(:) ! map of patch-age into patch age x pft dimension + integer , public, allocatable :: fates_hdim_pftmap_levagepft(:) ! map of pft into patch age x pft dimension ! ------------------------------------------------------------------------------------ ! DYNAMIC BOUNDARY CONDITIONS @@ -229,18 +233,18 @@ module FatesInterfaceMod ! It is assumed that all of the sites on a given machine will be synchronous. ! It is also assumed that the HLM will control time. ! ------------------------------------------------------------------------------------- - integer, protected :: hlm_current_year ! Current year - integer, protected :: hlm_current_month ! month of year - integer, protected :: hlm_current_day ! day of month - integer, protected :: hlm_current_tod ! time of day (seconds past 0Z) - integer, protected :: hlm_current_date ! time of day (seconds past 0Z) - integer, protected :: hlm_reference_date ! YYYYMMDD - real(r8), protected :: hlm_model_day ! elapsed days between current date and ref - integer, protected :: hlm_day_of_year ! The integer day of the year - integer, protected :: hlm_days_per_year ! The HLM controls time, some HLMs may - ! include a leap - real(r8), protected :: hlm_freq_day ! fraction of year for daily time-step - ! (1/days_per_year_, this is a frequency + integer, public, protected :: hlm_current_year ! Current year + integer, public, protected :: hlm_current_month ! month of year + integer, public, protected :: hlm_current_day ! day of month + integer, public, protected :: hlm_current_tod ! time of day (seconds past 0Z) + integer, public, protected :: hlm_current_date ! time of day (seconds past 0Z) + integer, public, protected :: hlm_reference_date ! YYYYMMDD + real(r8), public, protected :: hlm_model_day ! elapsed days between current date and ref + integer, public, protected :: hlm_day_of_year ! The integer day of the year + integer, public, protected :: hlm_days_per_year ! The HLM controls time, some HLMs may + ! include a leap + real(r8), public, protected :: hlm_freq_day ! fraction of year for daily time-step + ! (1/days_per_year_, this is a frequency ! ------------------------------------------------------------------------------------- @@ -249,11 +253,11 @@ module FatesInterfaceMod ! ! ------------------------------------------------------------------------------------- - integer, protected :: numpft ! The total number of PFTs defined in the simulation - integer, protected :: nlevsclass ! The total number of cohort size class bins output to history - integer, protected :: nlevage ! The total number of patch age bins output to history - integer, protected :: nlevheight ! The total number of height bins output to history - integer, public, protected :: nleafage ! The total number of leaf age classes + integer, public, protected :: numpft ! The total number of PFTs defined in the simulation + integer, public, protected :: nlevsclass ! The total number of cohort size class bins output to history + integer, public, protected :: nlevage ! The total number of patch age bins output to history + integer, public, protected :: nlevheight ! The total number of height bins output to history + integer, public, protected :: nleafage ! The total number of leaf age classes ! ------------------------------------------------------------------------------------- ! Structured Boundary Conditions (SITE/PATCH SCALE) From 5b41ed61baaabf637c2340ed13a815a2e7baaf0d Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Mon, 11 Mar 2019 17:07:56 -0700 Subject: [PATCH 54/78] Syntax fix on select case --- biogeochem/EDCohortDynamicsMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 0f9faaf5d6..cd88956da7 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -1003,7 +1003,7 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) call carea_allom(currentCohort%dbh,newn,currentSite%spread,currentCohort%pft,& currentCohort%c_area,inverse=.false.) ! - case(default) + case default write(fates_log(),*) 'FATES: Invalid choice for cohort_fusion_conservation_method' call endrun(msg=errMsg(sourcefile, __LINE__)) end select From 668e3de6f4d1c43d9b0a677f4a12d9bc9b0e8f14 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Wed, 13 Mar 2019 10:59:19 -0700 Subject: [PATCH 55/78] Added a re-calculation of crown areas prior to crown fusion --- biogeochem/EDCohortDynamicsMod.F90 | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index cd88956da7..58f9689c97 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -844,7 +844,8 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) logical, parameter :: fuse_debug = .false. ! This debug is over-verbose ! and gets its own flag - + real(r8) :: next_c_area + real(r8) :: curr_c_area !---------------------------------------------------------------------- !set initial fusion tolerance @@ -961,7 +962,16 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) ! cohorts' dbh ! ----------------------------------------------------------------- ! - currentCohort%c_area = currentCohort%c_area + nextc%c_area + call carea_allom(currentCohort%dbh,currentCohort%n, & + currentSite%spread,currentCohort%pft,& + curr_c_area,inverse=.false.) + + call carea_allom(nextc%dbh,nextc%n, & + currentSite%spread,nextc%pft,& + next_c_area,inverse=.false.) + + !currentCohort%c_area = currentCohort%c_area + nextc%c_area + currentCohort%c_area = curr_c_area + next_c_area ! call carea_allom(dbh,newn,currentSite%spread,currentCohort%pft,& currentCohort%c_area,inverse=.true.) @@ -969,6 +979,17 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) if (abs(dbh-fates_unset_r8) Date: Wed, 13 Mar 2019 11:07:47 -0700 Subject: [PATCH 56/78] Cleaned up some temporary diagnostics related to crown fusion --- biogeochem/EDCohortDynamicsMod.F90 | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index d589888484..69770aa7ba 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -849,8 +849,7 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) logical, parameter :: fuse_debug = .false. ! This debug is over-verbose ! and gets its own flag - real(r8) :: next_c_area - real(r8) :: curr_c_area + !---------------------------------------------------------------------- !set initial fusion tolerance @@ -942,15 +941,15 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%canopy_trim = (currentCohort%n*currentCohort%canopy_trim & + nextc%n*nextc%canopy_trim)/newn - ! c13disc_acc calculation; weighted mean by GPP - if ((currentCohort%n * currentCohort%gpp_acc + nextc%n * nextc%gpp_acc) .eq. 0.0_r8) then - currentCohort%c13disc_acc = 0.0_r8 - else - currentCohort%c13disc_acc = (currentCohort%n * currentCohort%gpp_acc * currentCohort%c13disc_acc + & - nextc%n * nextc%gpp_acc * nextc%c13disc_acc)/ & - (currentCohort%n * currentCohort%gpp_acc + nextc%n * nextc%gpp_acc) - endif - + ! c13disc_acc calculation; weighted mean by GPP + if ((currentCohort%n * currentCohort%gpp_acc + nextc%n * nextc%gpp_acc) .eq. 0.0_r8) then + currentCohort%c13disc_acc = 0.0_r8 + else + currentCohort%c13disc_acc = (currentCohort%n * currentCohort%gpp_acc * currentCohort%c13disc_acc + & + nextc%n * nextc%gpp_acc * nextc%c13disc_acc)/ & + (currentCohort%n * currentCohort%gpp_acc + nextc%n * nextc%gpp_acc) + endif + select case(cohort_fusion_conservation_method) ! ! ----------------------------------------------------------------- @@ -978,14 +977,14 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) ! call carea_allom(currentCohort%dbh,currentCohort%n, & currentSite%spread,currentCohort%pft,& - curr_c_area,inverse=.false.) - + currentCohort%c_area,inverse=.false.) + call carea_allom(nextc%dbh,nextc%n, & currentSite%spread,nextc%pft,& - next_c_area,inverse=.false.) + nextc%c_area,inverse=.false.) - !currentCohort%c_area = currentCohort%c_area + nextc%c_area - currentCohort%c_area = curr_c_area + next_c_area + currentCohort%c_area = currentCohort%c_area + nextc%c_area + ! call carea_allom(dbh,newn,currentSite%spread,currentCohort%pft,& currentCohort%c_area,inverse=.true.) From 86a3b28cb47e0be1e93ada3b41fb56549c7fbad9 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Wed, 13 Mar 2019 11:19:20 -0700 Subject: [PATCH 57/78] Updated structure reset to use the new caling convention of forcedbh --- biogeochem/EDCohortDynamicsMod.F90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 69770aa7ba..50c046ba33 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -994,10 +994,11 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) + nextc%n*nextc%dbh)/newn if( EDPftvarcon_inst%woody(currentCohort%pft) == itrue ) then - call StructureResetOfDH( & - currentCohort%prt%GetState(struct_organ,all_carbon_elements), & - currentCohort%pft, & - currentCohort%canopy_trim, currentCohort%dbh, currentCohort%hite ) + + call ForceDBH( currentCohort%pft, currentCohort%canopy_trim, & + currentCohort%dbh, currentCohort%hite, & + bdead = currentCohort%prt%GetState(struct_organ,all_carbon_elements)) + end if ! call carea_allom(currentCohort%dbh,newn,currentSite%spread,currentCohort%pft,& From d6c81e044203102d08872ec77f04db6b19465858 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 15 Mar 2019 13:58:37 -0600 Subject: [PATCH 58/78] Fixed a diagnostic in LAI during fusion and changed forced dbh resets to use leaves instead of fineroots for grasses --- biogeochem/EDCohortDynamicsMod.F90 | 38 ++++++++++++++++++++++-------- biogeochem/FatesAllometryMod.F90 | 30 +++++++++++------------ parteh/PRTAllometricCarbonMod.F90 | 18 +++++++------- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/biogeochem/EDCohortDynamicsMod.F90 b/biogeochem/EDCohortDynamicsMod.F90 index 50c046ba33..a92deeb5b6 100644 --- a/biogeochem/EDCohortDynamicsMod.F90 +++ b/biogeochem/EDCohortDynamicsMod.F90 @@ -838,8 +838,9 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) integer :: nocohorts real(r8) :: newn real(r8) :: diff - real(r8) :: leaf_c_next ! Leaf carbon * plant density of current (for weighting) - real(r8) :: leaf_c_curr ! Leaf carbon * plant density of next (for weighting) + real(r8) :: leaf_c_next ! Leaf carbon * plant density of current (for weighting) + real(r8) :: leaf_c_curr ! Leaf carbon * plant density of next (for weighting) + real(r8) :: leaf_c_target real(r8) :: dynamic_fusion_tolerance real(r8) :: dbh real(r8) :: leaf_c ! leaf carbon [kg] @@ -935,6 +936,10 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) call currentCohort%prt%WeightedFusePRTVartypes(nextc%prt, & currentCohort%n/newn ) + ! Leaf biophysical rates (use leaf mass weighting) + ! ----------------------------------------------------------------- + call UpdateCohortBioPhysRates(currentCohort) + currentCohort%laimemory = (currentCohort%n*currentCohort%laimemory & + nextc%n*nextc%laimemory)/newn @@ -996,8 +1001,8 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) if( EDPftvarcon_inst%woody(currentCohort%pft) == itrue ) then call ForceDBH( currentCohort%pft, currentCohort%canopy_trim, & - currentCohort%dbh, currentCohort%hite, & - bdead = currentCohort%prt%GetState(struct_organ,all_carbon_elements)) + currentCohort%dbh, currentCohort%hite, & + bdead = currentCohort%prt%GetState(struct_organ,all_carbon_elements)) end if ! @@ -1007,6 +1012,7 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) else currentCohort%dbh = dbh endif + ! call h_allom(currentCohort%dbh,currentCohort%pft,currentCohort%hite) ! @@ -1045,14 +1051,29 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) call endrun(msg=errMsg(sourcefile, __LINE__)) end select + + ! If fusion forces the actual leaf biomass to be unreasonably + ! greater than the target (ie 25%), reset the DBH + +! call bleaf(currentCohort%dbh,currentCohort%pft, & +! currentCohort%canopy_trim,leaf_c_target) - leaf_c = currentCohort%prt%GetState(leaf_organ, all_carbon_elements) + leaf_c = currentCohort%prt%GetState(leaf_organ,all_carbon_elements) + +! if (leaf_c > leaf_c_target*1.25_r8) then +! call ForceDBH( currentCohort%pft, currentCohort%canopy_trim, & +! currentCohort%dbh, currentCohort%hite, & +! bl = leaf_c) +! call carea_allom(currentCohort%dbh,newn,currentSite%spread,currentCohort%pft, & +! currentCohort%c_area,inverse=.false.) +! end if + - currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, currentCohort%n, & + currentCohort%treelai = tree_lai(leaf_c, currentCohort%pft, currentCohort%c_area, newn, & currentCohort%canopy_layer, currentPatch%canopy_layer_tlai, & currentCohort%vcmax25top) currentCohort%treesai = tree_sai(currentCohort%pft, currentCohort%dbh, currentCohort%canopy_trim, & - currentCohort%c_area, currentCohort%n, currentCohort%canopy_layer, & + currentCohort%c_area, newn, currentCohort%canopy_layer, & currentPatch%canopy_layer_tlai, currentCohort%treelai,currentCohort%vcmax25top,1 ) @@ -1069,9 +1090,6 @@ subroutine fuse_cohorts(currentSite, currentPatch, bc_in) currentCohort%canopy_layer_yesterday = (currentCohort%n*currentCohort%canopy_layer_yesterday + & nextc%n*nextc%canopy_layer_yesterday)/newn - ! Leaf biophysical rates (use leaf mass weighting) - ! ----------------------------------------------------------------- - call UpdateCohortBioPhysRates(currentCohort) ! keep track of the size class bins so that we can monitor growth fluxes ! compare the values. if they are the same, then nothing needs to be done. if not, track the diagnostic flux diff --git a/biogeochem/FatesAllometryMod.F90 b/biogeochem/FatesAllometryMod.F90 index 2fefc3fd18..e7470b076c 100644 --- a/biogeochem/FatesAllometryMod.F90 +++ b/biogeochem/FatesAllometryMod.F90 @@ -2200,11 +2200,11 @@ end function decay_coeff_kn ! ===================================================================================== - subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bfnrt ) + subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bl ) ! ========================================================================= ! This subroutine estimates the diameter based on either the structural biomass - ! (if woody) or the fine root biomass (if a grass) using the allometric + ! (if woody) or the leaf biomass using the allometric ! functions. Since allometry is specified with diameter ! as the independant variable, we must do this through a search algorithm. ! Here, we keep searching until the difference between actual structure and @@ -2220,7 +2220,7 @@ subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bfnrt ) real(r8),intent(inout) :: d ! plant diameter [cm] real(r8),intent(out) :: h ! plant height real(r8),intent(in),optional :: bdead ! Structural biomass - real(r8),intent(in),optional :: bfnrt ! Fine root biomass + real(r8),intent(in),optional :: bl ! Leaf biomass ! Locals @@ -2228,14 +2228,14 @@ subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bfnrt ) real(r8) :: bt_agw,dbt_agw_dd ! target AG wood at current d real(r8) :: bt_bgw,dbt_bgw_dd ! target BG wood at current d real(r8) :: bt_dead,dbt_dead_dd ! target struct wood at current d - real(r8) :: bt_fnrt,dbt_fnrt_dd ! target fineroot at current d + real(r8) :: bt_leaf,dbt_leaf_dd ! target leaf at current d real(r8) :: at_sap ! sapwood area (dummy) m2 real(r8) :: dd ! diameter increment for each step real(r8) :: d_try ! trial diameter real(r8) :: bt_dead_try ! trial structure biomasss real(r8) :: dbt_dead_dd_try ! trial structural derivative - real(r8) :: bt_fnrt_try ! trial fineroot biomass - real(r8) :: dbt_fnrt_dd_try ! trial fineroot derivative + real(r8) :: bt_leaf_try ! trial leaf biomass + real(r8) :: dbt_leaf_dd_try ! trial leaf derivative real(r8) :: step_frac ! step fraction integer :: counter real(r8), parameter :: step_frac0 = 0.9_r8 @@ -2291,30 +2291,30 @@ subroutine ForceDBH( ipft, canopy_trim, d, h, bdead, bfnrt ) else - if(.not.present(bfnrt)) then - write(fates_log(),*) 'grasses must use fine-root for dbh reset' + if(.not.present(bl)) then + write(fates_log(),*) 'grasses must use leaf for dbh reset' call endrun(msg=errMsg(sourcefile, __LINE__)) end if - call bfineroot(d,ipft,canopy_trim,bt_fnrt,dbt_fnrt_dd) + call bleaf(d,ipft,canopy_trim,bt_leaf,dbt_leaf_dd) counter = 0 step_frac = step_frac0 - do while( (bfnrt-bt_fnrt) > calloc_abs_error .and. dbt_fnrt_dd>0.0_r8) + do while( (bl-bt_leaf) > calloc_abs_error .and. dbt_leaf_dd>0.0_r8) - dd = step_frac*(bfnrt-bt_fnrt)/dbt_fnrt_dd + dd = step_frac*(bl-bt_leaf)/dbt_leaf_dd d_try = d + dd - call bfineroot(d_try,ipft,canopy_trim,bt_fnrt_try,dbt_fnrt_dd_try) + call bleaf(d_try,ipft,canopy_trim,bt_leaf_try,dbt_leaf_dd_try) ! Prevent overshooting - if(bt_fnrt_try > (bfnrt+calloc_abs_error)) then + if(bt_leaf_try > (bl+calloc_abs_error)) then step_frac = step_frac*0.5_r8 else step_frac = step_frac0 d = d_try - bt_fnrt = bt_fnrt_try - dbt_fnrt_dd = dbt_fnrt_dd_try + bt_leaf = bt_leaf_try + dbt_leaf_dd = dbt_leaf_dd_try end if counter = counter + 1 if (counter>max_counter) then diff --git a/parteh/PRTAllometricCarbonMod.F90 b/parteh/PRTAllometricCarbonMod.F90 index cffd717d40..3a443c9050 100644 --- a/parteh/PRTAllometricCarbonMod.F90 +++ b/parteh/PRTAllometricCarbonMod.F90 @@ -488,18 +488,21 @@ subroutine DailyPRTAllometricCarbon(this) else - ! Target fine-root biomass and deriv. according to - ! allometry and trimming [kgC] - call bfineroot(dbh,ipft,canopy_trim,target_fnrt_c) + ! Target leaf biomass according to allometry and trimming + call bleaf(dbh,ipft,canopy_trim,target_leaf_c) - if( (fnrt_c - target_fnrt_c ) > calloc_abs_error ) then + + if( ( sum(leaf_c) - target_leaf_c ) > calloc_abs_error ) then - call ForceDBH( ipft, canopy_trim, dbh, hite_out, bfnrt=fnrt_c ) + call ForceDBH( ipft, canopy_trim, dbh, hite_out, bl=sum(leaf_c) ) - target_fnrt_c = fnrt_c + target_leaf_c = sum(leaf_c) end if + ! Target fine-root biomass and deriv. according to allometry and trimming [kgC, kgC/cm] + call bfineroot(dbh,ipft,canopy_trim,target_fnrt_c) + ! Target sapwood biomass according to allometry and trimming [kgC] call bsap_allom(dbh,ipft,canopy_trim,sapw_area,target_sapw_c) @@ -512,9 +515,6 @@ subroutine DailyPRTAllometricCarbon(this) ! Target total dead (structrual) biomass and [kgC] call bdead_allom( target_agw_c, target_bgw_c, target_sapw_c, ipft, target_struct_c) - ! Target leaf biomass according to allometry and trimming - call bleaf(dbh,ipft,canopy_trim,target_leaf_c) - ! Target storage carbon [kgC] call bstore_allom(dbh,ipft,canopy_trim,target_store_c) From 4a7968e2b942ae722c382a4bb39b5d978d42bd02 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Mon, 25 Mar 2019 22:09:52 -0700 Subject: [PATCH 59/78] updated python scripts to (a) allow reshaping parameter files and (b) sort latest parameter files --- tools/modify_fates_paramfile.py | 124 +++++++++++++++++++++++++++++--- tools/ncvarsort.py | 17 +++-- 2 files changed, 124 insertions(+), 17 deletions(-) diff --git a/tools/modify_fates_paramfile.py b/tools/modify_fates_paramfile.py index a9dd688b0d..39f6b2a2bf 100755 --- a/tools/modify_fates_paramfile.py +++ b/tools/modify_fates_paramfile.py @@ -24,6 +24,7 @@ import sys import datetime import time +import numpy as np # ======================================================================================== # ======================================================================================== @@ -39,10 +40,11 @@ def main(): parser.add_argument('--allPFTs', '--allpfts', dest='allpfts', help="apply to all PFT indices. Cannot use at same time as --pft argument.", action="store_true") parser.add_argument('--fin', '--input', dest='inputfname', type=str, help="Input filename. Required.", required=True) parser.add_argument('--fout','--output', dest='outputfname', type=str, help="Output filename. Required.", required=True) - parser.add_argument('--val', '--value', dest='val', type=float, help="New value of PFT variable. Required.", required=True) + parser.add_argument('--val', '--value', dest='val', type=str, help="New value of PFT variable. Must be interpretable as either a real number or a comma-separated list of real numbers. Required.", required=True) parser.add_argument('--O','--overwrite', dest='overwrite', help="If present, automatically overwrite the output file.", action="store_true") parser.add_argument('--silent', '--s', dest='silent', help="prevent writing of output.", action="store_true") parser.add_argument('--nohist', dest='nohist', help="prevent recording of the edit in the history attribute of the output file", action="store_true") + parser.add_argument('--changeshape', dest='changeshape', help="allow script to change shape of specified variable, and all other variables with the relevant dimension, if necessary", action="store_true") # args = parser.parse_args() # @@ -50,6 +52,20 @@ def main(): tempdir = tempfile.mkdtemp() tempfilename = os.path.join(tempdir, 'temp_fates_param_file.nc') # + try: + outputval = float(args.val) + if args.changeshape: + raise Exception + except: + try: + #print('output variable not interpretable as real. trying array') + outputval = np.fromstring(args.val, sep=',', dtype=np.float32) + if len(outputval) == 0: + raise RuntimeError('output variable needs to have size greater than zero') + except: + raise RuntimeError('output variable not interpretable as real or array') + # + # try: shutil.copyfile(args.inputfname, tempfilename) # @@ -61,7 +77,7 @@ def main(): ndim_file = len(var.dimensions) ispftvar = False # for purposes of current state of this script, assume 1D - if ndim_file > 1: + if ndim_file > 2: raise ValueError('variable dimensionality is too high for this script') if ndim_file < 1: raise ValueError('variable dimensionality is too low for this script. FATES assumes even scalars have a 1-length dimension') @@ -69,12 +85,83 @@ def main(): if var.dimensions[i] == 'fates_pft': ispftvar = True npft_file = var.shape[i] - pftdim = 0 + pftdim = i + otherdimpresent = False elif var.dimensions[i] == 'fates_scalar': npft_file = None pftdim = None + otherdimpresent = False + elif var.dimensions[i] in ['fates_history_age_bins','fates_history_size_bins','fates_history_height_bins','fates_NCWD','fates_litterclass','fates_leafage_class','fates_prt_organs','fates_hydr_organs','fates_variants']: + otherdimpresent = True + otherdimname = var.dimensions[i] + otherdimlength = var.shape[i] else: raise ValueError('variable is not on either the PFT or scalar dimension') + # + if args.changeshape: + ### if we are allowing the script to change the shape of the variable, then we need to figure out if that's really a thing that needs to happen. + ### first identify what dimension we would change the shape of if we had to. + length_specified = len(outputval) + if length_specified != otherdimlength: + ### ok, we find ourselves in the situation where we need to rewrite the netcdf from scratch with its revised shape. + ### close the file that's open and start over. + ncfile.close() + os.remove(tempfilename) + ncfile = nc.netcdf_file(tempfilename, 'w') + ncfile_old = nc.netcdf_file(args.inputfname, 'r') + # + try: + ncfile.history = ncfile_old.history + except: + print('no history') + # + ### copy over and, when needed, modify the dimensions + for name, dimlength in ncfile_old.dimensions.items(): + #print(name, dimlength) + if name != otherdimname: + ncfile.createDimension(name, dimlength) + else: + ncfile.createDimension(name, length_specified) + #print(name, length_specified) + # + ### copy over and, when needed, modify the variables + for name, variable in ncfile_old.variables.items(): + variabledims = variable.dimensions + #print(name, variabledims) + x = ncfile.createVariable(name, variable.data.dtype, variable.dimensions) + try: + x.units = variable.units + except: + print('no units') + try: + x.long_name = variable.long_name + except: + print('no long name') + # + if len(variable.dimensions) > 0: + if not otherdimname in variable.dimensions: + x[:] = variable[:] + else: + if len(variable.dimensions) == 1: + if length_specified > otherdimlength: + x[0:otherdimlength] = variable[0:otherdimlength] + x[otherdimlength:length_specified] = 0 + else: + x[0:length_specified] = variable[0:length_specified] + elif len(variable.dimensions) == 2: + if length_specified > otherdimlength: + x[0:otherdimlength,:] = variable[0:otherdimlength,:] + x[otherdimlength:length_specified,:] = 0 + else: + x[0:length_specified,:] = variable[0:length_specified,:] + else: + x = variable.data + # + var = ncfile.variables[args.varname] + else: + # declare as none for now + ncfile_old = None + # if (args.pftnum == None and ispftvar) and not args.allpfts: raise ValueError('pft value is missing but variable has pft dimension.') if (args.pftnum != None) and args.allpfts: @@ -86,17 +173,32 @@ def main(): raise ValueError('PFT specified ('+str(args.pftnum)+') is larger than the number of PFTs in the file ('+str(npft_file)+').') if pftdim == 0: if not args.silent: - print('replacing prior value of variable '+args.varname+', for PFT '+str(args.pftnum)+', which was '+str(var[args.pftnum-1])+', with new value of '+str(args.val)) - var[args.pftnum-1] = args.val + print('replacing prior value of variable '+args.varname+', for PFT '+str(args.pftnum)+', which was '+str(var[args.pftnum-1])+', with new value of '+str(outputval)) + var[args.pftnum-1] = outputval + if pftdim == 1: + if not args.silent: + print('replacing prior value of variable '+args.varname+', for PFT '+str(args.pftnum)+', which was '+str(var[:,args.pftnum-1])+', with new value of '+str(outputval)) + var[:,args.pftnum-1] = outputval elif args.allpfts and ispftvar: if pftdim == 0: if not args.silent: - print('replacing prior values of variable '+args.varname+', for all PFTs, which were '+str(var[:])+', with new value of '+str(args.val)) - var[:] = args.val + print('replacing prior values of variable '+args.varname+', for all PFTs, which were '+str(var[:])+', with new value of '+str(outputval)) + var[:] = outputval + if pftdim == 1: + if not args.silent: + print('replacing prior values of variable '+args.varname+', for all PFTs, which were '+str(var[:])+', with new value of '+str(outputval)) + var[:] = outputval elif args.pftnum == None and not ispftvar: - if not args.silent: - print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(args.val)) - var[:] = args.val + if not otherdimpresent: + if not args.silent: + print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(outputval)) + var[:] = outputval + else: + #print(var.shape) + #print(outputval.shape) + if not args.silent: + print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(outputval)) + var[:] = outputval else: raise ValueError('Nothing happened somehow.') # @@ -110,6 +212,8 @@ def main(): ncfile.history = newhiststr # ncfile.close() + if type(ncfile_old) != type(None): + ncfile_old.close() # # # now move file from temporary location to final location diff --git a/tools/ncvarsort.py b/tools/ncvarsort.py index ffd7c0916c..73ef630cbf 100644 --- a/tools/ncvarsort.py +++ b/tools/ncvarsort.py @@ -23,7 +23,7 @@ def clobber(filename): # make empty lists to hold the variable names in. the first of these is a list of sub-lists, # one for each type of variable (based on dimensionality). # the second is the master list that will contain all variables. -varnames_list = [[],[],[],[],[],[],[],[],[]] +varnames_list = [[],[],[],[],[],[],[],[],[],[]] varnames_list_sorted = [] # sort the variables by dimensionality, but mix the PFT x other dimension in with the regular PFT-indexed variables @@ -32,12 +32,15 @@ def clobber(filename): (u'fates_history_age_bins',):2, (u'fates_scalar',):3, (u'fates_pft', u'fates_string_length'):4, - (u'fates_pft',):5, - (u'fates_variants', u'fates_pft'):5, - (u'fates_hydr_organs', u'fates_pft'):5, - (u'fates_litterclass',):6, - (u'fates_NCWD',):7, - ():8} + (u'fates_prt_organs', u'fates_string_length'):5, + (u'fates_pft',):6, + (u'fates_variants', u'fates_pft'):6, + (u'fates_hydr_organs', u'fates_pft'):6, + (u'fates_leafage_class', u'fates_pft'):6, + (u'fates_prt_organs', u'fates_pft'):6, + (u'fates_litterclass',):7, + (u'fates_NCWD',):8, + ():9} # go through each of the variables and assign it to one of the sub-lists based on its dimensionality for v_name, varin in dsin.variables.iteritems(): From 01fceb2673d85090d0eba6e86577ee256d3d0ed9 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Tue, 26 Mar 2019 09:57:05 -0700 Subject: [PATCH 60/78] bugfix on shape-changing modifications and also added ability to modify true scalar variables --- tools/modify_fates_paramfile.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/modify_fates_paramfile.py b/tools/modify_fates_paramfile.py index 39f6b2a2bf..f827c50d52 100755 --- a/tools/modify_fates_paramfile.py +++ b/tools/modify_fates_paramfile.py @@ -51,6 +51,7 @@ def main(): # work with the file in some random temporary place so that if something goes wrong, then nothing happens to original file and it doesn't make a persistent output file tempdir = tempfile.mkdtemp() tempfilename = os.path.join(tempdir, 'temp_fates_param_file.nc') + ncfile_old = None # try: outputval = float(args.val) @@ -79,8 +80,6 @@ def main(): # for purposes of current state of this script, assume 1D if ndim_file > 2: raise ValueError('variable dimensionality is too high for this script') - if ndim_file < 1: - raise ValueError('variable dimensionality is too low for this script. FATES assumes even scalars have a 1-length dimension') for i in range(ndim_file): if var.dimensions[i] == 'fates_pft': ispftvar = True @@ -155,7 +154,7 @@ def main(): else: x[0:length_specified,:] = variable[0:length_specified,:] else: - x = variable.data + x.assignValue(float(variable.data)) # var = ncfile.variables[args.varname] else: @@ -188,7 +187,7 @@ def main(): if not args.silent: print('replacing prior values of variable '+args.varname+', for all PFTs, which were '+str(var[:])+', with new value of '+str(outputval)) var[:] = outputval - elif args.pftnum == None and not ispftvar: + elif args.pftnum == None and not ispftvar and ndim_file > 0: if not otherdimpresent: if not args.silent: print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(outputval)) @@ -199,6 +198,10 @@ def main(): if not args.silent: print('replacing prior value of variable '+args.varname+', which was '+str(var[:])+', with new value of '+str(outputval)) var[:] = outputval + elif ndim_file < 1: + if not args.silent: + print('replacing prior value of scalar variable '+args.varname+', which was '+str(var.data)+', with new value of '+str(outputval)) + var.assignValue(outputval) else: raise ValueError('Nothing happened somehow.') # From ba7033eefd04f37185bc84e39c3fb624cee8c627 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Tue, 26 Mar 2019 10:56:28 -0700 Subject: [PATCH 61/78] updated all three python scripts --- tools/FatesPFTIndexSwapper.py | 12 +-- tools/modify_fates_paramfile.py | 11 ++ tools/ncvarsort.py | 174 ++++++++++++++++++-------------- 3 files changed, 114 insertions(+), 83 deletions(-) mode change 100644 => 100755 tools/ncvarsort.py diff --git a/tools/FatesPFTIndexSwapper.py b/tools/FatesPFTIndexSwapper.py index 3ef7deb044..63825b6784 100755 --- a/tools/FatesPFTIndexSwapper.py +++ b/tools/FatesPFTIndexSwapper.py @@ -45,27 +45,27 @@ def usage(): print('') print('=======================================================================') print('') - print(' python FatesPFTIndexSwapper.py -h --pft-indices ') - print(' --fin ') - print(' --fout ') + print(' python FatesPFTIndexSwapper.py -h --pft-indices= ') + print(' --fin= ') + print(' --fout=') print('') print('') print(' -h --help ') print(' print this help message') print('') print('') - print(' --pft-indices ') + print(' --pft-indices=') print(' This is a comma delimited list of integer positions of the PFTs') print(' to be copied into the new file. Note that first pft position') print(' is treated as 1 (not C or python like), and any order or multiples') print(' of indices can be chosen') print('') print('') - print(' --fin ') + print(' --fin=') print(' This is the full path to the netcdf file you are basing off of') print('') print('') - print(' --fout ') + print(' --fout=') print(' This is the full path to the netcdf file you are writing to.') print('') print('') diff --git a/tools/modify_fates_paramfile.py b/tools/modify_fates_paramfile.py index f827c50d52..e79240035d 100755 --- a/tools/modify_fates_paramfile.py +++ b/tools/modify_fates_paramfile.py @@ -103,6 +103,13 @@ def main(): length_specified = len(outputval) if length_specified != otherdimlength: ### ok, we find ourselves in the situation where we need to rewrite the netcdf from scratch with its revised shape. + # + # first lets chech to make sure the dimension we are changing can be changed without breaking things. + plastic_dimensions_list = ['fates_history_age_bins','fates_history_size_bins','fates_history_height_bins','fates_leafage_class'] + if otherdimname not in plastic_dimensions_list: + raise ValueError('asking to change the shape of a dimension, '+otherdimname+', that will probably break things') + else: + print('WARNING: we need to change the dimension of '+otherdimname) ### close the file that's open and start over. ncfile.close() os.remove(tempfilename) @@ -143,15 +150,19 @@ def main(): else: if len(variable.dimensions) == 1: if length_specified > otherdimlength: + print('WARNING: Variable '+name+' has a dimension that has been reshaped. New length is longer than old, so its been filled in with zeros.') x[0:otherdimlength] = variable[0:otherdimlength] x[otherdimlength:length_specified] = 0 else: + print('WARNING: Variable '+name+' has a dimension that has been reshaped. New length is shorter than old, so its been truncated.') x[0:length_specified] = variable[0:length_specified] elif len(variable.dimensions) == 2: if length_specified > otherdimlength: + print('WARNING: Variable '+name+' has a dimension that has been reshaped. New length is longer than old, so its been filled in with zeros.') x[0:otherdimlength,:] = variable[0:otherdimlength,:] x[otherdimlength:length_specified,:] = 0 else: + print('WARNING: Variable '+name+' has a dimension that has been reshaped. New length is shorter than old, so its been truncated.') x[0:length_specified,:] = variable[0:length_specified,:] else: x.assignValue(float(variable.data)) diff --git a/tools/ncvarsort.py b/tools/ncvarsort.py old mode 100644 new mode 100755 index 73ef630cbf..c2047cdf51 --- a/tools/ncvarsort.py +++ b/tools/ncvarsort.py @@ -1,87 +1,107 @@ +#!/usr/bin/env python + +#### this script sorts a FATES parameter file. It accepts the following flags +# --input or --fin: input filename. +# --output or --fout: output filename. If missing, will assume its directly modifying the input file, and will prompt unless -O is specified + from netCDF4 import Dataset import sys import os +import argparse # program sorts the variables based on the provided list, and pulls them one at a time # from an existing file and adds them to a new file in the sorted order. # input/output based on code here: https://gist.github.com/guziy/8543562 -def clobber(filename): - try: - print('replacing file: '+filename) - os.remove(filename) - except: - print('file does not exist: '+filename) - -### modify the paths below to point to the new and old file names -fnamein = 'fates_params_default.nc' -fnameout = 'fates_params_default_sorted.nc' - -# open the input dataset -dsin = Dataset(fnamein) - -# make empty lists to hold the variable names in. the first of these is a list of sub-lists, -# one for each type of variable (based on dimensionality). -# the second is the master list that will contain all variables. -varnames_list = [[],[],[],[],[],[],[],[],[],[]] -varnames_list_sorted = [] - -# sort the variables by dimensionality, but mix the PFT x other dimension in with the regular PFT-indexed variables -dimtype_sortorder_dict = {(u'fates_history_height_bins',):0, - (u'fates_history_size_bins',):1, - (u'fates_history_age_bins',):2, - (u'fates_scalar',):3, - (u'fates_pft', u'fates_string_length'):4, - (u'fates_prt_organs', u'fates_string_length'):5, - (u'fates_pft',):6, - (u'fates_variants', u'fates_pft'):6, - (u'fates_hydr_organs', u'fates_pft'):6, - (u'fates_leafage_class', u'fates_pft'):6, - (u'fates_prt_organs', u'fates_pft'):6, - (u'fates_litterclass',):7, - (u'fates_NCWD',):8, - ():9} - -# go through each of the variables and assign it to one of the sub-lists based on its dimensionality -for v_name, varin in dsin.variables.iteritems(): - sortorder = dimtype_sortorder_dict[varin.dimensions] - # if a KeyError, it means that the parameter has a dimension which isn't in dimtype_sortorder_dict. need to add it. - varnames_list[sortorder].append(v_name) - -# go through each of the lists and sort the variable names alphabetically, -# and put them into a master list of all variables. -for i in range(len(varnames_list)): - varnames_list[i] = sorted(varnames_list[i], key=lambda L: (L.lower(), L)) - varnames_list_sorted.extend(varnames_list[i]) - -# open the output filename, deleting it if it exists already. -clobber(fnameout) -dsout = Dataset(fnameout, "w", format="NETCDF3_CLASSIC") - -#Copy dimensions -for dname, the_dim in dsin.dimensions.iteritems(): - print dname, len(the_dim) - dsout.createDimension(dname, len(the_dim) if not the_dim.isunlimited() else None) - -print - -# go through each variable in the order of the sorted master list, and copy the variable -# as well as all metadata to the new file. -for i in range(len(varnames_list_sorted)): - v_name = varnames_list_sorted[i] - varin = dsin.variables[v_name] - outVar = dsout.createVariable(v_name, varin.datatype, varin.dimensions) - print v_name - - # Copy variable attributes - outVar.setncatts({k: varin.getncattr(k) for k in varin.ncattrs()}) - - # copy data from input file to output file - outVar[:] = varin[:] +def main(): + parser = argparse.ArgumentParser(description='Parse command line arguments to this script.') + # + parser.add_argument('--fin', '--input', dest='fnamein', type=str, help="Input filename. Required.", required=True) + parser.add_argument('--fout','--output', dest='fnameout', type=str, help="Output filename. Required.", required=True) + parser.add_argument('--O','--overwrite', dest='overwrite', help="If present, automatically overwrite the output file.", action="store_true") + # + args = parser.parse_args() + # + # open the input dataset + dsin = Dataset(args.fnamein) + # + # make empty lists to hold the variable names in. the first of these is a list of sub-lists, + # one for each type of variable (based on dimensionality). + # the second is the master list that will contain all variables. + varnames_list = [[],[],[],[],[],[],[],[],[],[]] + varnames_list_sorted = [] + # + # sort the variables by dimensionality, but mix the PFT x other dimension in with the regular PFT-indexed variables + dimtype_sortorder_dict = {(u'fates_history_height_bins',):0, + (u'fates_history_size_bins',):1, + (u'fates_history_age_bins',):2, + (u'fates_scalar',):3, + (u'fates_pft', u'fates_string_length'):4, + (u'fates_prt_organs', u'fates_string_length'):5, + (u'fates_pft',):6, + (u'fates_variants', u'fates_pft'):6, + (u'fates_hydr_organs', u'fates_pft'):6, + (u'fates_leafage_class', u'fates_pft'):6, + (u'fates_prt_organs', u'fates_pft'):6, + (u'fates_litterclass',):7, + (u'fates_NCWD',):8, + ():9} + # + # go through each of the variables and assign it to one of the sub-lists based on its dimensionality + for v_name, varin in dsin.variables.iteritems(): + sortorder = dimtype_sortorder_dict[varin.dimensions] + # if a KeyError, it means that the parameter has a dimension which isn't in dimtype_sortorder_dict. need to add it. + varnames_list[sortorder].append(v_name) + # + # go through each of the lists and sort the variable names alphabetically, + # and put them into a master list of all variables. + for i in range(len(varnames_list)): + varnames_list[i] = sorted(varnames_list[i], key=lambda L: (L.lower(), L)) + varnames_list_sorted.extend(varnames_list[i]) + # + # open the output filename, deleting it if it exists already. + if os.path.isfile(args.fnameout): + if args.fnameout == args.fnamein: + raise ValueError('Error: output file name is the same as the input file name.') + elif args.overwrite: + print('replacing file: '+args.fnameout) + os.remove(args.fnameout) + else: + raise ValueError('Output file already exists and overwrite flag not specified for filename: '+args.fnameout) + # + dsout = Dataset(args.fnameout, "w", format="NETCDF3_CLASSIC") + # + #Copy dimensions + for dname, the_dim in dsin.dimensions.iteritems(): + print dname, len(the_dim) + dsout.createDimension(dname, len(the_dim) if not the_dim.isunlimited() else None) + # + print + # + # go through each variable in the order of the sorted master list, and copy the variable + # as well as all metadata to the new file. + for i in range(len(varnames_list_sorted)): + v_name = varnames_list_sorted[i] + varin = dsin.variables[v_name] + outVar = dsout.createVariable(v_name, varin.datatype, varin.dimensions) + print v_name + # + # Copy variable attributes + outVar.setncatts({k: varin.getncattr(k) for k in varin.ncattrs()}) + # + # copy data from input file to output file + outVar[:] = varin[:] + # + # copy global attributes + dsout.setncatts({k: dsin.getncattr(k) for k in dsin.ncattrs()}) + # + # close the output file + dsout.close() + dsin.close() -# copy global attributes -dsout.setncatts({k: dsin.getncattr(k) for k in dsin.ncattrs()}) +# ======================================================================================= +# This is the actual call to main + +if __name__ == "__main__": + main() -# close the output file -dsout.close() -dsin.close() From 7d5b83ff35bf7cff9d79c0e17f47081badf3ab92 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Tue, 26 Mar 2019 14:26:23 -0700 Subject: [PATCH 62/78] bugfix and line lengths --- biogeochem/EDLoggingMortalityMod.F90 | 5 ++++- biogeochem/EDPatchDynamicsMod.F90 | 5 ----- main/EDMainMod.F90 | 9 ++++++--- main/EDTypesMod.F90 | 3 ++- main/FatesHistoryInterfaceMod.F90 | 9 ++++++--- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/biogeochem/EDLoggingMortalityMod.F90 b/biogeochem/EDLoggingMortalityMod.F90 index 367f3e868d..03b2ac4cda 100644 --- a/biogeochem/EDLoggingMortalityMod.F90 +++ b/biogeochem/EDLoggingMortalityMod.F90 @@ -161,7 +161,10 @@ subroutine LoggingMortality_frac( pft_i, dbh, canopy_layer, lmort_direct, & real(r8), intent(out) :: lmort_direct ! direct (harvestable) mortality fraction real(r8), intent(out) :: lmort_collateral ! collateral damage mortality fraction real(r8), intent(out) :: lmort_infra ! infrastructure mortality fraction - real(r8), intent(out) :: l_degrad ! fraction of trees that are not killed but suffer from forest degradation (i.e. they are moved to newly-anthro-disturbed secondary forest patch) + real(r8), intent(out) :: l_degrad ! fraction of trees that are not killed + ! but suffer from forest degradation (i.e. they + ! are moved to newly-anthro-disturbed secondary + ! forest patch) ! Parameters real(r8), parameter :: adjustment = 1.0 ! adjustment for mortality rates diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index e74e578592..56a28e85c2 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -435,11 +435,6 @@ subroutine spawn_patches( currentSite, bc_in) if (patch_site_areadis > nearzero ) then - allocate(nc) - if(hlm_use_planthydro.eq.itrue) call InitHydrCohort(CurrentSite,nc) - call InitPRTCohort(nc) - call zero_cohort(nc) - ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land ! receiver patch is primary forest only if both the donor patch is primary forest and the dominant disturbance type is not logging if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index 0bdcbf0434..bbb0c54dbd 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -289,7 +289,8 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) ! add age increment to secondary forest patches as well if (currentPatch%anthro_disturbance_label .eq. secondaryforest) then - currentPatch%age_since_anthro_disturbance = currentPatch%age_since_anthro_disturbance + hlm_freq_day + currentPatch%age_since_anthro_disturbance = & + currentPatch%age_since_anthro_disturbance + hlm_freq_day endif ! check to see if the patch has moved to the next age class @@ -404,8 +405,10 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) enddo do ft = 1,numpft - currentPatch%leaf_litter(ft) = currentPatch%leaf_litter(ft) + currentPatch%dleaf_litter_dt(ft)* hlm_freq_day - currentPatch%root_litter(ft) = currentPatch%root_litter(ft) + currentPatch%droot_litter_dt(ft)* hlm_freq_day + currentPatch%leaf_litter(ft) = currentPatch%leaf_litter(ft) + & + currentPatch%dleaf_litter_dt(ft)* hlm_freq_day + currentPatch%root_litter(ft) = currentPatch%root_litter(ft) + & + currentPatch%droot_litter_dt(ft)* hlm_freq_day enddo do c = 1,ncwd diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 162f8c9f44..418a8f27de 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -17,7 +17,8 @@ module EDTypesMod save integer, parameter :: maxPatchesPerSite = 14 ! maximum number of patches to live on a site - integer, parameter :: maxPatchesPerSite_by_disttype(n_anthro_disturbance_categories) = (/ 10, 4 /) !!! MUST SUM TO maxPatchesPerSite !!! + integer, parameter :: maxPatchesPerSite_by_disttype(n_anthro_disturbance_categories) = & + (/ 10, 4 /) !!! MUST SUM TO maxPatchesPerSite !!! integer, parameter :: maxCohortsPerPatch = 100 ! maximum number of cohorts per patch integer, parameter :: nclmax = 3 ! Maximum number of canopy layers diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 5537053bdd..2789233c33 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -1382,7 +1382,8 @@ subroutine update_history_dyn(this,nc,nsites,sites) integer :: ican, ileaf, cnlf_indx ! iterators for leaf and canopy level integer :: height_bin_max, height_bin_min ! which height bin a given cohort's canopy is in integer :: i_heightbin ! iterator for height bins - integer :: ageclass_since_anthrodist ! what is the equivalent age class for time-since-anthropogenic-disturbance of secondary forest + integer :: ageclass_since_anthrodist ! what is the equivalent age class for + ! time-since-anthropogenic-disturbance of secondary forest real(r8) :: n_density ! individual of cohort per m2. real(r8) :: n_perm2 ! individuals per m2 for the whole column @@ -3440,12 +3441,14 @@ subroutine define_history_vars(this, initialize_variables) ivar=ivar, initialize=initialize_variables, index = ih_biomass_secondary_forest_si ) call this%set_history_var(vname='SECONDARY_AREA_AGE_ANTHRO_DIST', units='m2/m2', & - long='Secondary forest patch area age distribution since anthropgenic disturbance', use_default='inactive', & + long='Secondary forest patch area age distribution since anthropgenic disturbance', & + use_default='inactive', & avgflag='A', vtype=site_age_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_agesince_anthrodist_si_age ) call this%set_history_var(vname='SECONDARY_AREA_PATCH_AGE_DIST', units='m2/m2', & - long='Secondary forest patch area age distribution since any kind of disturbance', use_default='inactive', & + long='Secondary forest patch area age distribution since any kind of disturbance', & + use_default='inactive', & avgflag='A', vtype=site_age_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_secondaryforest_area_si_age ) From 120635f36ab43acf42767870bd9991f2a6a63d6b Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 26 Mar 2019 15:48:16 -0700 Subject: [PATCH 63/78] Reduced line lengths --- biogeochem/EDPatchDynamicsMod.F90 | 184 +++++++++++++++++++----------- 1 file changed, 118 insertions(+), 66 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 56a28e85c2..4cdeed82b8 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -117,7 +117,9 @@ subroutine disturbance_rates( site_in, bc_in) real(r8) :: lmort_direct real(r8) :: lmort_collateral real(r8) :: lmort_infra - real(r8) :: l_degrad ! fraction of trees that are not killed but suffer from forest degradation (i.e. they are moved to newly-anthro-disturbed secondary forest patch) + real(r8) :: l_degrad ! fraction of trees that are not killed but suffer from forest + ! degradation (i.e. they are moved to newly-anthro-disturbed + ! secondary forest patch) real(r8) :: dist_rate_ldist_notharvested integer :: threshold_sizeclass @@ -242,9 +244,9 @@ subroutine disturbance_rates( site_in, bc_in) currentCohort => currentCohort%taller enddo !currentCohort - + ! DISTURBANCE IS FIRE elseif (currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ilog) ) then ! DISTURBANCE IS FIRE + currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ilog) ) then currentPatch%disturbance_rate = currentPatch%disturbance_rates(dtype_ifire) @@ -426,7 +428,8 @@ subroutine spawn_patches( currentSite, bc_in) endif currentPatch => currentSite%oldest_patch - ! loop round all the patches that contribute surviving indivduals and litter pools to the new patch. + ! loop round all the patches that contribute surviving indivduals and litter + ! pools to the new patch. do while(associated(currentPatch)) @@ -435,36 +438,48 @@ subroutine spawn_patches( currentSite, bc_in) if (patch_site_areadis > nearzero ) then - ! figure out whether the receiver patch for disturbance from this patch will be primary or secondary land - ! receiver patch is primary forest only if both the donor patch is primary forest and the dominant disturbance type is not logging + ! figure out whether the receiver patch for disturbance from this patch + ! will be primary or secondary land receiver patch is primary forest + ! only if both the donor patch is primary forest and the dominant + ! disturbance type is not logging if (currentPatch%anthro_disturbance_label .eq. primaryforest .and. & - (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) ) then + ((currentPatch%disturbance_rates(dtype_ilog) .lt. & + currentPatch%disturbance_rates(dtype_ifall)) .or. & + (currentPatch%disturbance_rates(dtype_ilog) .lt. & + currentPatch%disturbance_rates(dtype_ifire)))) then new_patch => new_patch_primary else new_patch => new_patch_secondary endif - ! for the case where the donating patch is secondary forest, if the dominant disturbance from this patch is non-anthropogenic, - ! we need to average in the time-since-anthropogenic-disturbance from the donor patch into that of the receiver patch + ! for the case where the donating patch is secondary forest, if + ! the dominant disturbance from this patch is non-anthropogenic, + ! we need to average in the time-since-anthropogenic-disturbance + ! from the donor patch into that of the receiver patch if ( currentPatch%anthro_disturbance_label .eq. secondaryforest .and. & - (currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifall) .or. & - currentPatch%disturbance_rates(dtype_ilog) .lt. currentPatch%disturbance_rates(dtype_ifire) ) ) then - + ((currentPatch%disturbance_rates(dtype_ilog) .lt. & + currentPatch%disturbance_rates(dtype_ifall)) .or. & + (currentPatch%disturbance_rates(dtype_ilog) .lt. & + currentPatch%disturbance_rates(dtype_ifire)))) then + new_patch%age_since_anthro_disturbance = new_patch%age_since_anthro_disturbance + & currentPatch%age_since_anthro_disturbance * (patch_site_areadis / site_areadis_secondary) endif call average_patch_properties(currentPatch, new_patch, patch_site_areadis) - if (currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifire) ) then + if ((currentPatch%disturbance_rates(dtype_ilog) > & + currentPatch%disturbance_rates(dtype_ifall)) .and. & + (currentPatch%disturbance_rates(dtype_ilog) > & + currentPatch%disturbance_rates(dtype_ifire)) ) then call logging_litter_fluxes(currentSite, currentPatch, new_patch, patch_site_areadis) - elseif (currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ilog) ) then + elseif ((currentPatch%disturbance_rates(dtype_ifire) > & + currentPatch%disturbance_rates(dtype_ifall)) .and. & + (currentPatch%disturbance_rates(dtype_ifire) > & + currentPatch%disturbance_rates(dtype_ilog)) ) then call fire_litter_fluxes(currentSite, currentPatch, new_patch, patch_site_areadis) @@ -502,8 +517,10 @@ subroutine spawn_patches( currentSite, bc_in) ! treefall mortality is the dominant disturbance - if(currentPatch%disturbance_rates(dtype_ifall) > currentPatch%disturbance_rates(dtype_ifire) .and. & - currentPatch%disturbance_rates(dtype_ifall) > currentPatch%disturbance_rates(dtype_ilog))then + if((currentPatch%disturbance_rates(dtype_ifall) > & + currentPatch%disturbance_rates(dtype_ifire)) .and. & + (currentPatch%disturbance_rates(dtype_ifall) > & + currentPatch%disturbance_rates(dtype_ilog)))then if(currentCohort%canopy_layer == 1)then @@ -517,7 +534,8 @@ subroutine spawn_patches( currentSite, bc_in) nc%n = 0.0_r8 ! kill all of the trees who caused the disturbance. - nc%cmort = nan ! The mortality diagnostics are set to nan because the cohort should dissappear + nc%cmort = nan ! The mortality diagnostics are set to nan + ! because the cohort should dissappear nc%hmort = nan nc%bmort = nan nc%frmort = nan @@ -532,15 +550,21 @@ subroutine spawn_patches( currentSite, bc_in) ! Survivorship of undestory woody plants. Two step process. - ! Step 1: Reduce current number of plants to reflect the change in area. - ! The number density per square are doesn't change, but since the patch is smaller - ! and cohort counts are absolute, reduce this number. + ! Step 1: Reduce current number of plants to reflect the + ! change in area. + ! The number density per square are doesn't change, + ! but since the patch is smaller and cohort counts + ! are absolute, reduce this number. + nc%n = currentCohort%n * patch_site_areadis/currentPatch%area - ! because the mortality rate due to impact for the cohorts which had been in the understory and are now in the newly- - ! disturbed patch is very high, passing the imort directly to history results in large numerical errors, on account - ! of the sharply reduced number densities. so instead pass this info via a site-level diagnostic variable before reducing - ! the number density. + ! because the mortality rate due to impact for the cohorts which + ! had been in the understory and are now in the newly- + ! disturbed patch is very high, passing the imort directly to history + ! results in large numerical errors, on account of the sharply + ! reduced number densities. so instead pass this info via a + ! site-level diagnostic variable before reducing the number density. + currentSite%imort_rate(currentCohort%size_class, currentCohort%pft) = & currentSite%imort_rate(currentCohort%size_class, currentCohort%pft) + & nc%n * ED_val_understorey_death / hlm_freq_day @@ -552,7 +576,8 @@ subroutine spawn_patches( currentSite, bc_in) total_c * g_per_kg * days_per_sec * years_per_day * ha_per_m2 ! Step 2: Apply survivor ship function based on the understory death fraction - ! remaining of understory plants of those that are knocked over by the overstorey trees dying... + ! remaining of understory plants of those that are knocked over + ! by the overstorey trees dying... nc%n = nc%n * (1.0_r8 - ED_val_understorey_death) ! since the donor patch split and sent a fraction of its members @@ -600,8 +625,10 @@ subroutine spawn_patches( currentSite, bc_in) endif ! Fire is the dominant disturbance - elseif (currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ifire) > currentPatch%disturbance_rates(dtype_ilog)) then !fire + elseif ((currentPatch%disturbance_rates(dtype_ifire) > & + currentPatch%disturbance_rates(dtype_ifall)) .and. & + (currentPatch%disturbance_rates(dtype_ifire) > & + currentPatch%disturbance_rates(dtype_ilog))) then !fire ! Number of members in the new patch, before we impose fire survivorship nc%n = currentCohort%n * patch_site_areadis/currentPatch%area @@ -654,8 +681,10 @@ subroutine spawn_patches( currentSite, bc_in) ! Logging is the dominant disturbance - elseif (currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifall) .and. & - currentPatch%disturbance_rates(dtype_ilog) > currentPatch%disturbance_rates(dtype_ifire)) then ! Logging + elseif ((currentPatch%disturbance_rates(dtype_ilog) > & + currentPatch%disturbance_rates(dtype_ifall)) .and. & + (currentPatch%disturbance_rates(dtype_ilog) > & + currentPatch%disturbance_rates(dtype_ifire))) then ! Logging ! If this cohort is in the upper canopy. It generated if(currentCohort%canopy_layer == 1)then @@ -663,13 +692,15 @@ subroutine spawn_patches( currentSite, bc_in) ! calculate the survivorship of disturbed trees because non-harvested nc%n = currentCohort%n * currentCohort%l_degrad ! nc%n = (currentCohort%l_degrad / (currentCohort%l_degrad + & - ! currentCohort%lmort_direct + currentCohort%lmort_collateral + currentCohort%lmort_infra) ) * & + ! currentCohort%lmort_direct + currentCohort%lmort_collateral + + ! currentCohort%lmort_infra) ) * & ! currentCohort%n * patch_site_areadis/currentPatch%area ! Reduce counts in the existing/donor patch according to the logging rate - currentCohort%n = currentCohort%n * (1.0_r8 - min(1.0_r8,(currentCohort%lmort_direct + & - currentCohort%lmort_collateral + & - currentCohort%lmort_infra + currentCohort%l_degrad))) + currentCohort%n = currentCohort%n * & + (1.0_r8 - min(1.0_r8,(currentCohort%lmort_direct + & + currentCohort%lmort_collateral + & + currentCohort%lmort_infra + currentCohort%l_degrad))) nc%cmort = currentCohort%cmort nc%hmort = currentCohort%hmort @@ -677,7 +708,8 @@ subroutine spawn_patches( currentSite, bc_in) nc%frmort = currentCohort%frmort nc%dmort = currentCohort%dmort - ! since these are the ones that weren't logged, set the logging mortality rates as zero + ! since these are the ones that weren't logged, + ! set the logging mortality rates as zero nc%lmort_direct = 0._r8 nc%lmort_collateral = 0._r8 nc%lmort_infra = 0._r8 @@ -691,34 +723,44 @@ subroutine spawn_patches( currentSite, bc_in) ! Survivorship of undestory woody plants. Two step process. - ! Step 1: Reduce current number of plants to reflect the change in area. - ! The number density per square are doesn't change, but since the patch is smaller + ! Step 1: Reduce current number of plants to reflect the + ! change in area. + ! The number density per square are doesn't change, + ! but since the patch is smaller ! and cohort counts are absolute, reduce this number. nc%n = currentCohort%n * patch_site_areadis/currentPatch%area - ! because the mortality rate due to impact for the cohorts which had been in the understory and are now in the newly- - ! disturbed patch is very high, passing the imort directly to history results in large numerical errors, on account - ! of the sharply reduced number densities. so instead pass this info via a site-level diagnostic variable before reducing + ! because the mortality rate due to impact for the cohorts which had + ! been in the understory and are now in the newly- + ! disturbed patch is very high, passing the imort directly to + ! history results in large numerical errors, on account + ! of the sharply reduced number densities. so instead pass this info + ! via a site-level diagnostic variable before reducing ! the number density. currentSite%imort_rate(currentCohort%size_class, currentCohort%pft) = & currentSite%imort_rate(currentCohort%size_class, currentCohort%pft) + & - nc%n * currentPatch%fract_ldist_not_harvested * logging_coll_under_frac / hlm_freq_day + nc%n * currentPatch%fract_ldist_not_harvested * & + logging_coll_under_frac / hlm_freq_day + currentSite%imort_carbonflux = currentSite%imort_carbonflux + & - (nc%n * currentPatch%fract_ldist_not_harvested * logging_coll_under_frac/ hlm_freq_day ) * & + (nc%n * currentPatch%fract_ldist_not_harvested * & + logging_coll_under_frac/ hlm_freq_day ) * & total_c * g_per_kg * days_per_sec * years_per_day * ha_per_m2 ! Step 2: Apply survivor ship function based on the understory death fraction - ! remaining of understory plants of those that are knocked over by the overstorey trees dying... - ! LOGGING SURVIVORSHIP OF UNDERSTORY PLANTS IS SET AS A NEW PARAMETER in the fatesparameter files - nc%n = nc%n * (1.0_r8 - currentPatch%fract_ldist_not_harvested * logging_coll_under_frac) + ! remaining of understory plants of those that are knocked + ! over by the overstorey trees dying... + ! LOGGING SURVIVORSHIP OF UNDERSTORY PLANTS IS SET AS A NEW PARAMETER + ! in the fatesparameter files + nc%n = nc%n * (1.0_r8 - & + currentPatch%fract_ldist_not_harvested * logging_coll_under_frac) - ! Step 3: Reduce the number count of cohorts in the original/donor/non-disturbed patch - ! to reflect the area change + ! Step 3: Reduce the number count of cohorts in the + ! original/donor/non-disturbed patch to reflect the area change currentCohort%n = currentCohort%n * (1._r8 - patch_site_areadis/currentPatch%area) - nc%cmort = currentCohort%cmort nc%hmort = currentCohort%hmort nc%bmort = currentCohort%bmort @@ -730,7 +772,8 @@ subroutine spawn_patches( currentSite, bc_in) else - ! grass is not killed by mortality disturbance events. Just move it into the new patch area. + ! grass is not killed by mortality disturbance events. + ! Just move it into the new patch area. ! Just split the grass into the existing and new patch structures nc%n = currentCohort%n * patch_site_areadis/currentPatch%area @@ -772,7 +815,8 @@ subroutine spawn_patches( currentSite, bc_in) nc%shorter => null() endif nc%patchptr => new_patch - call insert_cohort(nc, new_patch%tallest, new_patch%shortest, tnull, snull, storebigcohort, storesmallcohort) + call insert_cohort(nc, new_patch%tallest, new_patch%shortest, & + tnull, snull, storebigcohort, storesmallcohort) new_patch%tallest => storebigcohort new_patch%shortest => storesmallcohort @@ -960,7 +1004,8 @@ subroutine average_patch_properties( currentPatch, newPatch, patch_site_areadis integer :: c,p ! counters for PFT and litter size class. !--------------------------------------------------------------------- - patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate ! how much land is disturbed in this donor patch? + ! how much land is disturbed in this donor patch? + patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate do c = 1,ncwd !move litter pool en mass into the new patch. newPatch%cwd_ag(c) = newPatch%cwd_ag(c) + currentPatch%cwd_ag(c) * patch_site_areadis/newPatch%area @@ -973,9 +1018,11 @@ subroutine average_patch_properties( currentPatch, newPatch, patch_site_areadis newPatch%leaf_litter(p) = newPatch%leaf_litter(p) + & currentPatch%leaf_litter(p) * patch_site_areadis/newPatch%area - ! The fragmentation/decomposition flux from donor patches has already occured in existing patches. However - ! some of their area has been carved out for this new patches which is receiving donations. - ! Lets maintain conservation on that pre-existing mass flux in these newly disturbed patches + ! The fragmentation/decomposition flux from donor patches has already + ! occured in existing patches. However some of their area has been + ! carved out for this new patches which is receiving donations. + ! Lets maintain conservation on that pre-existing mass flux in + ! these newly disturbed patches newPatch%root_litter_out(p) = newPatch%root_litter_out(p) + & currentPatch%root_litter_out(p) * patch_site_areadis/newPatch%area @@ -1013,7 +1060,7 @@ subroutine fire_litter_fluxes(currentSite, cp_target, new_patch_target, patch_si real(r8) :: bstem ! amount of above ground stem biomass per cohort kgC.(goes into CWG_AG) real(r8) :: dead_tree_density ! no trees killed by fire per m2 reaL(r8) :: burned_litter ! amount of each litter pool burned by fire. kgC/m2/day - real(r8) :: burned_leaves ! amount of tissue consumed by fire for leaves. KgC/individual/day + real(r8) :: burned_leaves ! amount of tissue consumed by fire for leaves. KgC/individual/day real(r8) :: leaf_burn_frac ! fraction of leaves burned real(r8) :: leaf_c ! leaf carbon [kg] real(r8) :: fnrt_c ! fineroot carbon [kg] @@ -1027,8 +1074,10 @@ subroutine fire_litter_fluxes(currentSite, cp_target, new_patch_target, patch_si currentPatch => cp_target new_patch => new_patch_target - if ( currentPatch%fire == 1 ) then !only do this if there was a fire in this actual patch. - patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate ! how much land is disturbed in this donor patch? + if ( currentPatch%fire == 1 ) then !only do this if there was a fire in this actual patch. + + ! how much land is disturbed in this donor patch? + patch_site_areadis = currentPatch%area * currentPatch%disturbance_rate !************************************/ !PART 1) Burn the fractions of existing litter in the new patch that were consumed by the fire. @@ -1704,13 +1753,16 @@ subroutine fuse_patches( csite, bc_in ) currentPatch%age .le. max_age_of_second_oldest_patch ) then - !--------------------------------------------------------------------------------------------------------- - ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, - ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be - ! distinguished from each other. but if force_patchfuse_min_biomass is too big, it takes too long for the - ! youngest patch to build up enough biomass to be its own distinct entity, which leads to large oscillations - ! in the patch dynamics and dependent variables. - !--------------------------------------------------------------------------------------------------------- + !------------------------------------------------------------ + ! the next bit of logic forces fusion of two patches which + ! both have tiny biomass densities. without this, + ! fates gives a bunch of really young patches which all have + ! almost no biomass and so don't need to be distinguished + ! from each other. but if force_patchfuse_min_biomass is too big, + ! it takes too long for the youngest patch to build up enough + ! biomass to be its own distinct entity, which leads to large + ! oscillations in the patch dynamics and dependent variables. + !------------------------------------------------------------ if(sum(currentPatch%pft_agb_profile(:,:)) > force_patchfuse_min_biomass .or. & sum(tpp%pft_agb_profile(:,:)) > force_patchfuse_min_biomass ) then From 2bfdb1d99e864ec52d1aec3c680638b2deefea8e Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 26 Mar 2019 17:58:15 -0600 Subject: [PATCH 64/78] Added a check on the number of loops allowed to catch super-small patches --- biogeochem/EDPatchDynamicsMod.F90 | 43 +++++++++++++++++++------------ 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index a7403a17d8..9834e9da72 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1875,10 +1875,15 @@ subroutine terminate_patches(currentSite) type(ed_patch_type), pointer :: currentPatch type(ed_patch_type), pointer :: olderPatch type(ed_patch_type), pointer :: youngerPatch + integer, parameter :: max_cycles = 10 ! After 10 loops through + ! You should had fused + integer :: count_cycles real(r8) areatot ! variable for checking whether the total patch area is wrong. !--------------------------------------------------------------------- + count_cycles = 0 + currentPatch => currentSite%youngest_patch do while(associated(currentPatch)) @@ -1889,15 +1894,10 @@ subroutine terminate_patches(currentSite) ! a discrete patch for very young patches ! However, if the patch to be fused is excessivlely small, then fuse ! at all costs. If it is not fused, it will make - if ( currentPatch%area <= min_patch_area_forced ) & - write(fates_log(),*) 'small area: ',currentPatch%area,currentSite%lat,currentSite%lon if ( .not.associated(currentPatch,currentSite%youngest_patch) .or. & currentPatch%area <= min_patch_area_forced ) then - if ( currentPatch%area <= min_patch_area_forced ) & - write(fates_log(),*) 'small area(2): ',currentPatch%area,currentSite%lat,currentSite%lon - if(associated(currentPatch%older) )then if(debug) & @@ -1905,18 +1905,12 @@ subroutine terminate_patches(currentSite) currentPatch%area, & currentPatch%older%area - if ( currentPatch%area <= min_patch_area_forced ) & - write(fates_log(),*) 'small area(3): ',currentPatch%area,currentSite%lat,currentSite%lon - ! We set a pointer to this patch, because ! it will be returned by the subroutine as de-referenced olderPatch => currentPatch%older call fuse_2_patches(currentSite, olderPatch, currentPatch) - if ( currentPatch%area <= min_patch_area_forced ) & - write(fates_log(),*) 'small area(4): ',currentPatch%area,currentSite%lat,currentSite%lon - ! The fusion process has updated the "older" pointer on currentPatch ! for us. @@ -1928,16 +1922,10 @@ subroutine terminate_patches(currentSite) if(debug) & write(fates_log(),*) 'fusing to younger patch because oldest one is too small', & currentPatch%area - - if ( currentPatch%area <= min_patch_area_forced ) & - write(fates_log(),*) 'small area(5): ',currentPatch%area,currentSite%lat,currentSite%lon youngerPatch => currentPatch%younger call fuse_2_patches(currentSite, youngerPatch, currentPatch) - if ( currentPatch%area <= min_patch_area_forced ) & - write(fates_log(),*) 'small area(6): ',currentPatch%area,currentSite%lat,currentSite%lon - ! The fusion process has updated the "younger" pointer on currentPatch endif @@ -1953,7 +1941,28 @@ subroutine terminate_patches(currentSite) if(currentPatch%area > min_patch_area_forced)then currentPatch => currentPatch%older + count_cycles = 0 + else + count_cycles = count_cycles + 1 end if + + if(count_cycles > max_cycles) then + write(fates_log(),*) 'FATES is having difficulties fusing very small patches.' + write(fates_log(),*) 'It is possible that a either a secondary or primary' + write(fates_log(),*) 'patch has become the only patch of its kind, and it is' + write(fates_log(),*) 'is very very small. You can test your luck by' + write(fates_log(),*) 'disabling the endrun statement following this message.' + write(fates_log(),*) 'FATES may or may not continue to operate within error' + write(fates_log(),*) 'tolerances, but will generate another fail if it does not.' + call endrun(msg=errMsg(sourcefile, __LINE__)) + + ! Note to user. If you DO decide to remove the end-run above this line + ! Make sure that you keep the pointer below this line, or you will get + ! an infinite loop. + currentPatch => currentPatch%older + count_cycles = 0 + end if + enddo !check area is not exceeded From 19bcfb3f0906880b556681461e7a275410e27dca Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Wed, 27 Mar 2019 16:44:16 -0600 Subject: [PATCH 65/78] Removed unnecessary error checks, and bound others behind logical constants --- biogeochem/EDCanopyStructureMod.F90 | 131 ++++++++++++---------------- 1 file changed, 57 insertions(+), 74 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index 59b0173ce8..02eb8ab563 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -386,12 +386,13 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call carea_allom(currentCohort%dbh,currentCohort%n, & currentSite%spread,currentCohort%pft,currentCohort%c_area) - if(currentCohort%c_area<0._r8)then - write(fates_log(),*) 'negative c_area stage 1d: ',currentCohort%dbh,i_lyr,currentCohort%n, & - currentSite%spread,currentCohort%pft,currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + if(debug) then + if(currentCohort%c_area<0._r8)then + write(fates_log(),*) 'negative c_area stage 1d: ',currentCohort%dbh,i_lyr,currentCohort%n, & + currentSite%spread,currentCohort%pft,currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if - if( currentCohort%canopy_layer == i_lyr)then @@ -525,17 +526,19 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) if(currentCohort%canopy_layer == i_lyr) then currentCohort%excl_weight = currentCohort%c_area * currentCohort%excl_weight * scale_factor - if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & - (currentCohort%excl_weight < 0._r8) ) then - write(fates_log(),*) 'exclusion area too big (1)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'dbh: ',currentCohort%dbh - write(fates_log(),*) 'n: ',currentCohort%n - write(fates_log(),*) 'spread: ',currentSite%spread - write(fates_log(),*) 'pft: ',currentCohort%pft - write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight - write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + if(debug) then + if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%excl_weight < 0._r8) ) then + write(fates_log(),*) 'exclusion area too big (1)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'dbh: ',currentCohort%dbh + write(fates_log(),*) 'n: ',currentCohort%n + write(fates_log(),*) 'spread: ',currentSite%spread + write(fates_log(),*) 'pft: ',currentCohort%pft + write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight + write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if endif @@ -572,14 +575,16 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) currentCohort%excl_weight = currentCohort%c_area * & (currentCohort%excl_weight * scale_factor_min + & (1._r8 - (currentCohort%excl_weight*scale_factor_min) ) * scale_factor_res) - - if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & - (currentCohort%excl_weight < 0._r8) ) then - write(fates_log(),*) 'exclusion area error (2)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight - write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + + if(debug)then + if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%excl_weight < 0._r8) ) then + write(fates_log(),*) 'exclusion area error (2)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight + write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if endif @@ -658,21 +663,10 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) endif call copy_cohort(currentCohort, copyc) - if(currentCohort%n < 0._r8) then - write(fates_log(),*) 'negatives (0_?): ',currentCohort%n,currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if - newarea = currentCohort%c_area - cc_loss copyc%n = currentCohort%n*newarea/currentCohort%c_area currentCohort%n = currentCohort%n - copyc%n - if(copyc%n < 0._r8 .or. currentCohort%n < 0._r8) then - write(fates_log(),*) 'negatives?: ',newarea,cc_loss,copyc%n,currentCohort%n,currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if - - copyc%canopy_layer = i_lyr !the taller cohort is the copy ! Demote the current cohort to the understory. @@ -688,16 +682,6 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) call carea_allom(currentCohort%dbh,currentCohort%n,currentSite%spread, & currentCohort%pft,currentCohort%c_area) - ! Calculate how much area loss from recalculation - if( abs(copyc%c_area-newarea)>area_target_precision .or. & - abs(currentCohort%c_area-cc_loss)>area_target_precision) then - write(fates_log(),*) 'recalculation losses?',newarea-copyc%c_area,newarea, & - copyc%c_area,currentCohort%c_area-cc_loss,currentCohort%c_area,& - cc_loss - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if - - !----------- Insert copy into linked list ------------------------! copyc%shorter => currentCohort if(associated(currentCohort%taller))then @@ -1034,14 +1018,16 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) do while (associated(currentCohort)) if(currentCohort%canopy_layer == (i_lyr+1) ) then currentCohort%prom_weight = currentCohort%c_area * currentCohort%prom_weight * scale_factor - - if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & - (currentCohort%prom_weight < 0._r8) ) then - write(fates_log(),*) 'promotion area too big (1)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight - write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + + if(debug)then + if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%prom_weight < 0._r8) ) then + write(fates_log(),*) 'promotion area too big (1)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight + write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if endif @@ -1078,15 +1064,17 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) (currentCohort%prom_weight * scale_factor_min + & (1._r8 - (currentCohort%prom_weight*scale_factor_min) ) * scale_factor_res) - if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & - (currentCohort%prom_weight < 0._r8) ) then - write(fates_log(),*) 'promotion area error (2)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight - write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + if(debug)then + if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%prom_weight < 0._r8) ) then + write(fates_log(),*) 'promotion area error (2)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight + write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if - + endif currentCohort => currentCohort%shorter enddo @@ -1106,12 +1094,14 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) currentCohort => currentCohort%shorter end do - if (abs(sumweights - promote_area) > area_check_precision ) then - write(fates_log(),*) 'promotions dont add up' - write(fates_log(),*) 'sum promotions: ',sumweights - write(fates_log(),*) 'area needed to be promoted: ',promote_area - write(fates_log(),*) 'excess: ',sumweights - promote_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + if(debug)then + if (abs(sumweights - promote_area) > area_check_precision ) then + write(fates_log(),*) 'promotions dont add up' + write(fates_log(),*) 'sum promotions: ',sumweights + write(fates_log(),*) 'area needed to be promoted: ',promote_area + write(fates_log(),*) 'excess: ',sumweights - promote_area + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if end if currentCohort => currentPatch%tallest @@ -1162,13 +1152,6 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) ! number of individuals in cohort remaining in understorey currentCohort%n = currentCohort%n - copyc%n - - if(copyc%n < 0._r8 .or. currentCohort%n < 0._r8) then - write(fates_log(),*) 'negatives (2)?: ',newarea,cc_gain,copyc%n,currentCohort%n - call endrun(msg=errMsg(sourcefile, __LINE__)) - end if - - currentCohort%canopy_layer = i_lyr + 1 ! keep current cohort in the understory. copyc%canopy_layer = i_lyr ! promote copy to the higher canopy layer. From a1eff334855d017ce0290b51a7000ee6adcb20ec Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Wed, 27 Mar 2019 15:56:07 -0700 Subject: [PATCH 66/78] Reduced some line lengths --- biogeochem/EDCanopyStructureMod.F90 | 96 ++++++++++++++++------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index 02eb8ab563..c027cfdc16 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -167,10 +167,6 @@ subroutine canopy_structure( currentSite , bc_in ) ! Perform numerical checks on some cohort and patch structures ! ------------------------------------------------------------------------------ -! call val_check_ed_vars(currentPatch,'co_n:co_dbh:pa_area',return_code) -! ! No need to make error message, already generated in math_check_ed_vars -! if(return_code>0) call endrun(msg=errMsg(sourcefile, __LINE__)) - ! canopy layer has a special bounds check currentCohort => currentPatch%tallest do while (associated(currentCohort)) @@ -253,7 +249,7 @@ subroutine canopy_structure( currentSite , bc_in ) area_not_balanced = .false. do i_lyr = 1,z call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer(i_lyr)) - if( ((arealayer(i_lyr)-currentPatch%area)/currentPatch%area > area_check_rel_precision) .or. & + if( ((arealayer(i_lyr)-currentPatch%area)/currentPatch%area > area_check_rel_precision) .or. & ((arealayer(i_lyr)-currentPatch%area) > area_check_precision ) ) then area_not_balanced = .true. endif @@ -557,9 +553,11 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) do while (associated(currentCohort)) if(currentCohort%canopy_layer == i_lyr) then area_res = area_res + & - currentCohort%c_area*currentCohort%excl_weight*scale_factor_min + currentCohort%c_area * currentCohort%excl_weight * & + scale_factor_min scale_factor_res = scale_factor_res + & - currentCohort%c_area * (1._r8 - (currentCohort%excl_weight * scale_factor_min)) + currentCohort%c_area * & + (1._r8 - (currentCohort%excl_weight * scale_factor_min)) endif currentCohort => currentCohort%shorter enddo @@ -577,15 +575,18 @@ subroutine DemoteFromLayer(currentSite,currentPatch,i_lyr) (1._r8 - (currentCohort%excl_weight*scale_factor_min) ) * scale_factor_res) if(debug)then - if((currentCohort%excl_weight > (currentCohort%c_area+area_target_precision)) .or. & + if((currentCohort%excl_weight > & + (currentCohort%c_area+area_target_precision)) .or. & (currentCohort%excl_weight < 0._r8) ) then - write(fates_log(),*) 'exclusion area error (2)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'currentCohort%excl_weight: ',currentCohort%excl_weight - write(fates_log(),*) 'excess: ',currentCohort%excl_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + write(fates_log(),*) 'exclusion area error (2)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%excl_weight: ', & + currentCohort%excl_weight + write(fates_log(),*) 'excess: ', & + currentCohort%excl_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) end if - end if + end if endif currentCohort => currentCohort%shorter @@ -1017,18 +1018,22 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) currentCohort => currentPatch%tallest do while (associated(currentCohort)) if(currentCohort%canopy_layer == (i_lyr+1) ) then - currentCohort%prom_weight = currentCohort%c_area * currentCohort%prom_weight * scale_factor + currentCohort%prom_weight = currentCohort%c_area * & + currentCohort%prom_weight * scale_factor if(debug)then - if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & - (currentCohort%prom_weight < 0._r8) ) then - write(fates_log(),*) 'promotion area too big (1)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight - write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + if((currentCohort%prom_weight > & + (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%prom_weight < 0._r8) ) then + write(fates_log(),*) 'promotion area too big (1)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%prom_weight: ', & + currentCohort%prom_weight + write(fates_log(),*) 'excess: ', & + currentCohort%prom_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) end if - end if + end if endif currentCohort => currentCohort%shorter @@ -1047,7 +1052,8 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) area_res = area_res + & currentCohort%c_area*currentCohort%prom_weight*scale_factor_min scale_factor_res = scale_factor_res + & - currentCohort%c_area * (1._r8 - (currentCohort%prom_weight * scale_factor_min)) + currentCohort%c_area * & + (1._r8 - (currentCohort%prom_weight * scale_factor_min)) endif currentCohort => currentCohort%shorter enddo @@ -1062,16 +1068,20 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) currentCohort%prom_weight = currentCohort%c_area * & (currentCohort%prom_weight * scale_factor_min + & - (1._r8 - (currentCohort%prom_weight*scale_factor_min) ) * scale_factor_res) + (1._r8 - (currentCohort%prom_weight*scale_factor_min) ) * & + scale_factor_res) if(debug)then - if((currentCohort%prom_weight > (currentCohort%c_area+area_target_precision)) .or. & - (currentCohort%prom_weight < 0._r8) ) then - write(fates_log(),*) 'promotion area error (2)' - write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area - write(fates_log(),*) 'currentCohort%prom_weight: ',currentCohort%prom_weight - write(fates_log(),*) 'excess: ',currentCohort%prom_weight - currentCohort%c_area - call endrun(msg=errMsg(sourcefile, __LINE__)) + if((currentCohort%prom_weight > & + (currentCohort%c_area+area_target_precision)) .or. & + (currentCohort%prom_weight < 0._r8) ) then + write(fates_log(),*) 'promotion area error (2)' + write(fates_log(),*) 'currentCohort%c_area: ',currentCohort%c_area + write(fates_log(),*) 'currentCohort%prom_weight: ', & + currentCohort%prom_weight + write(fates_log(),*) 'excess: ', & + currentCohort%prom_weight - currentCohort%c_area + call endrun(msg=errMsg(sourcefile, __LINE__)) end if end if @@ -1192,7 +1202,8 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) call CanopyLayerArea(currentPatch,currentSite%spread,i_lyr,arealayer_current) - if ((abs(arealayer_current - currentPatch%area)/arealayer_current > area_check_rel_precision ) .or. & + if ((abs(arealayer_current - currentPatch%area)/arealayer_current > & + area_check_rel_precision ) .or. & (abs(arealayer_current - currentPatch%area) > area_check_precision) ) then write(fates_log(),*) 'promotion did not bring area within tolerance' write(fates_log(),*) 'arealayer:',arealayer_current @@ -1252,7 +1263,8 @@ subroutine canopy_spread( currentSite ) enddo !currentPatch - !If the canopy area is approaching closure, squash the tree canopies and make them taller and thinner + ! If the canopy area is approaching closure, + ! squash the tree canopies and make them taller and thinner if( sitelevel_canopyarea/AREA .gt. ED_val_canopy_closure_thresh ) then currentSite%spread = currentSite%spread - inc else @@ -1290,15 +1302,15 @@ subroutine canopy_summarization( nsites, sites, bc_in ) type (ed_patch_type) , pointer :: currentPatch type (ed_cohort_type) , pointer :: currentCohort integer :: s - integer :: ft ! plant functional type + integer :: ft ! plant functional type integer :: ifp - integer :: patchn ! identification number for each patch. - real(r8) :: canopy_leaf_area ! total amount of leaf area in the vegetated area. m2. - real(r8) :: leaf_c ! leaf carbon [kg] - real(r8) :: fnrt_c ! fineroot carbon [kg] - real(r8) :: sapw_c ! sapwood carbon [kg] - real(r8) :: store_c ! storage carbon [kg] - real(r8) :: struct_c ! structure carbon [kg] + integer :: patchn ! identification number for each patch. + real(r8) :: canopy_leaf_area ! total amount of leaf area in the vegetated area. m2. + real(r8) :: leaf_c ! leaf carbon [kg] + real(r8) :: fnrt_c ! fineroot carbon [kg] + real(r8) :: sapw_c ! sapwood carbon [kg] + real(r8) :: store_c ! storage carbon [kg] + real(r8) :: struct_c ! structure carbon [kg] !---------------------------------------------------------------------- if ( debug ) then From 6f5c2fe3e926a4db0314fff15291a5632a64cb2e Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Mar 2019 11:13:46 -0700 Subject: [PATCH 67/78] Converted default to the sorted 12 pft --- parameter_files/fates_params_default.cdl | 1095 ++++++++++++---------- 1 file changed, 587 insertions(+), 508 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 18bea2e032..ed852884e4 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -1,93 +1,132 @@ -netcdf fates_params.2trop { +netcdf fates_params_12pft_sorted { dimensions: fates_NCWD = 4 ; fates_history_age_bins = 7 ; fates_history_height_bins = 6 ; fates_history_size_bins = 13 ; fates_hydr_organs = 4 ; - fates_prt_organs = 6 ; - fates_leafage_class = 2; + fates_leafage_class = 2 ; fates_litterclass = 6 ; - fates_pft = 2 ; + fates_pft = 12 ; + fates_prt_organs = 6 ; fates_scalar = 1 ; fates_string_length = 60 ; fates_variants = 2 ; variables: + float fates_history_height_bin_edges(fates_history_height_bins) ; + fates_history_height_bin_edges:units = "m" ; + fates_history_height_bin_edges:long_name = "Lower edges for height bins used in height-resolved history output" ; float fates_history_sizeclass_bin_edges(fates_history_size_bins) ; fates_history_sizeclass_bin_edges:units = "cm" ; fates_history_sizeclass_bin_edges:long_name = "Lower edges for DBH size class bins used in size-resolved cohort history output" ; float fates_history_ageclass_bin_edges(fates_history_age_bins) ; fates_history_ageclass_bin_edges:units = "yr" ; fates_history_ageclass_bin_edges:long_name = "Lower edges for age class bins used in age-resolved patch history output" ; - float fates_FBD(fates_litterclass) ; - fates_FBD:units = "NA" ; - fates_FBD:long_name = "spitfire parameter related to fuel bulk density, see SFMain.F90" ; - float fates_SAV(fates_litterclass) ; - fates_SAV:units = "NA" ; - fates_SAV:long_name = "spitfire parameter related to surface area to volume ratio, see SFMain.F90" ; - float fates_history_height_bin_edges(fates_history_height_bins) ; - fates_history_height_bin_edges:units = "m" ; - fates_history_height_bin_edges:long_name = "Lower edges for height bins used in height-resolved history output" ; - float fates_low_moisture_Coeff(fates_litterclass) ; - fates_low_moisture_Coeff:units = "NA" ; - fates_low_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_low_moisture_Slope(fates_litterclass) ; - fates_low_moisture_Slope:units = "NA" ; - fates_low_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_max_decomp(fates_litterclass) ; - fates_max_decomp:units = "kgC/m2/yr ?" ; - fates_max_decomp:long_name = "maximum rate of litter & CWD transfer from non-decomposing class into decomposing class" ; - float fates_mid_moisture(fates_litterclass) ; - fates_mid_moisture:units = "NA" ; - fates_mid_moisture:long_name = "spitfire litter moisture threshold to be considered medium dry" ; - float fates_mid_moisture_Coeff(fates_litterclass) ; - fates_mid_moisture_Coeff:units = "NA" ; - fates_mid_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_mid_moisture_Slope(fates_litterclass) ; - fates_mid_moisture_Slope:units = "NA" ; - fates_mid_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_min_moisture(fates_litterclass) ; - fates_min_moisture:units = "NA" ; - fates_min_moisture:long_name = "spitfire litter moisture threshold to be considered very dry" ; - float fates_hydr_avuln_node(fates_hydr_organs, fates_pft) ; - fates_hydr_avuln_node:units = "unitless" ; - fates_hydr_avuln_node:long_name = "xylem vulnerability curve shape parameter" ; - float fates_hydr_epsil_node(fates_hydr_organs, fates_pft) ; - fates_hydr_epsil_node:units = "MPa" ; - fates_hydr_epsil_node:long_name = "bulk elastic modulus" ; - float fates_hydr_fcap_node(fates_hydr_organs, fates_pft) ; - fates_hydr_fcap_node:units = "unitless" ; - fates_hydr_fcap_node:long_name = "fraction of (1-resid_node) that is capillary in source" ; - float fates_hydr_kmax_node(fates_hydr_organs, fates_pft) ; - fates_hydr_kmax_node:units = "kgMPa/m/s" ; - fates_hydr_kmax_node:long_name = "maximum xylem conductivity per unit conducting xylem area" ; - float fates_hydr_p50_node(fates_hydr_organs, fates_pft) ; - fates_hydr_p50_node:units = "MPa" ; - fates_hydr_p50_node:long_name = "xylem water potential at 50% loss of conductivity" ; - float fates_hydr_pinot_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pinot_node:units = "MPa" ; - fates_hydr_pinot_node:long_name = "osmotic potential at full turgor" ; - float fates_hydr_pitlp_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pitlp_node:units = "MPa" ; - fates_hydr_pitlp_node:long_name = "turgor loss point" ; - float fates_hydr_resid_node(fates_hydr_organs, fates_pft) ; - fates_hydr_resid_node:units = "fraction" ; - fates_hydr_resid_node:long_name = "residual fraction" ; - float fates_hydr_thetas_node(fates_hydr_organs, fates_pft) ; - fates_hydr_thetas_node:units = "cm3/cm3" ; - fates_hydr_thetas_node:long_name = "saturated water content" ; - float fates_CWD_frac(fates_NCWD) ; - fates_CWD_frac:units = "fraction" ; - fates_CWD_frac:long_name = "fraction of woody (bdead+bsw) biomass destined for CWD pool" ; + float fates_base_mr_20(fates_scalar) ; + fates_base_mr_20:units = "gC/gN/s" ; + fates_base_mr_20:long_name = "Base maintenance respiration rate for plant tissues, using Ryan 1991" ; + float fates_bbopt_c3(fates_scalar) ; + fates_bbopt_c3:units = "umol H2O/m**2/s" ; + fates_bbopt_c3:long_name = "Ball-Berry minimum unstressed leaf conductance for C3" ; + float fates_bbopt_c4(fates_scalar) ; + fates_bbopt_c4:units = "umol H2O/m**2/s" ; + fates_bbopt_c4:long_name = "Ball-Berry minimum unstressed leaf conductance for C4" ; + float fates_canopy_closure_thresh(fates_scalar) ; + fates_canopy_closure_thresh:units = "unitless" ; + fates_canopy_closure_thresh:long_name = "tree canopy coverage at which crown area allometry changes from savanna to forest value" ; + float fates_cohort_fusion_tol(fates_scalar) ; + fates_cohort_fusion_tol:units = "unitless" ; + fates_cohort_fusion_tol:long_name = "minimum fraction in difference in dbh between cohorts" ; + float fates_comp_excln(fates_scalar) ; + fates_comp_excln:units = "none" ; + fates_comp_excln:long_name = "weighting factor (exponent on dbh) for canopy layer exclusion and promotion" ; + float fates_cwd_fcel(fates_scalar) ; + fates_cwd_fcel:units = "unitless" ; + fates_cwd_fcel:long_name = "Cellulose fraction for CWD" ; + float fates_cwd_flig(fates_scalar) ; + fates_cwd_flig:units = "unitless" ; + fates_cwd_flig:long_name = "Lignin fraction of coarse woody debris" ; + float fates_fire_nignitions(fates_scalar) ; + fates_fire_nignitions:units = "/m2 (?)" ; + fates_fire_nignitions:long_name = "number of daily ignitions (nfires = nignitions*FDI*area_scaling)" ; + float fates_hydr_kmax_rsurf(fates_scalar) ; + fates_hydr_kmax_rsurf:units = "kg water/m2 root area/Mpa/s" ; + fates_hydr_kmax_rsurf:long_name = "maximum conducitivity for unit root surface" ; + float fates_hydr_psi0(fates_scalar) ; + fates_hydr_psi0:units = "MPa" ; + fates_hydr_psi0:long_name = "sapwood water potential at saturation" ; + float fates_hydr_psicap(fates_scalar) ; + fates_hydr_psicap:units = "MPa" ; + fates_hydr_psicap:long_name = "sapwood water potential at which capillary reserves exhausted" ; + float fates_init_litter(fates_scalar) ; + fates_init_litter:units = "NA" ; + fates_init_litter:long_name = "Initialization value for litter pool in cold-start (NOT USED)" ; + float fates_logging_coll_under_frac(fates_scalar) ; + fates_logging_coll_under_frac:units = "fraction" ; + fates_logging_coll_under_frac:long_name = "Fraction of stems killed in the understory when logging generates disturbance" ; + float fates_logging_collateral_frac(fates_scalar) ; + fates_logging_collateral_frac:units = "fraction" ; + fates_logging_collateral_frac:long_name = "Fraction of large stems in upperstory that die from logging collateral damage" ; + float fates_logging_dbhmax_infra(fates_scalar) ; + fates_logging_dbhmax_infra:units = "cm" ; + fates_logging_dbhmax_infra:long_name = "Tree diameter, above which infrastructure from logging does not impact damage or mortality." ; + float fates_logging_dbhmin(fates_scalar) ; + fates_logging_dbhmin:units = "cm" ; + fates_logging_dbhmin:long_name = "Minimum dbh at which logging is applied" ; + float fates_logging_direct_frac(fates_scalar) ; + fates_logging_direct_frac:units = "fraction" ; + fates_logging_direct_frac:long_name = "Fraction of stems logged directly per event" ; + float fates_logging_event_code(fates_scalar) ; + fates_logging_event_code:units = "unitless" ; + fates_logging_event_code:long_name = "Integer code that options how logging events are structured" ; + float fates_logging_mechanical_frac(fates_scalar) ; + fates_logging_mechanical_frac:units = "fraction" ; + fates_logging_mechanical_frac:long_name = "Fraction of stems killed due infrastructure an other mechanical means" ; + float fates_mort_disturb_frac(fates_scalar) ; + fates_mort_disturb_frac:units = "fraction" ; + fates_mort_disturb_frac:long_name = "fraction of canopy mortality that results in disturbance (i.e. transfer of area from new to old patch)" ; + float fates_mort_understorey_death(fates_scalar) ; + fates_mort_understorey_death:units = "fraction" ; + fates_mort_understorey_death:long_name = "fraction of plants in understorey cohort impacted by overstorey tree-fall" ; + float fates_patch_fusion_tol(fates_scalar) ; + fates_patch_fusion_tol:units = "unitless" ; + fates_patch_fusion_tol:long_name = "minimum fraction in difference in profiles between patches" ; + float fates_phen_a(fates_scalar) ; + fates_phen_a:units = "none" ; + fates_phen_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; + float fates_phen_b(fates_scalar) ; + fates_phen_b:units = "none" ; + fates_phen_b:long_name = "GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd)" ; + float fates_phen_c(fates_scalar) ; + fates_phen_c:units = "none" ; + fates_phen_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; + float fates_phen_chiltemp(fates_scalar) ; + fates_phen_chiltemp:units = "degrees C" ; + fates_phen_chiltemp:long_name = "chilling day counting threshold" ; + float fates_phen_coldtemp(fates_scalar) ; + fates_phen_coldtemp:units = "degrees C" ; + fates_phen_coldtemp:long_name = "temperature exceedance to flag a cold-day for temperature leaf drop" ; + float fates_phen_doff_time(fates_scalar) ; + fates_phen_doff_time:units = "days" ; + fates_phen_doff_time:long_name = "day threshold compared against days since leaves became off-allometry" ; + float fates_phen_drought_threshold(fates_scalar) ; + fates_phen_drought_threshold:units = "m3/m3" ; + fates_phen_drought_threshold:long_name = "liquid volume in soil layer, threashold for drought phenology" ; + float fates_phen_mindayson(fates_scalar) ; + fates_phen_mindayson:units = "days" ; + fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; + float fates_phen_ncolddayslim(fates_scalar) ; + fates_phen_ncolddayslim:units = "days" ; + fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; + float fates_soil_salinity(fates_scalar) ; + fates_soil_salinity:units = "ppt" ; + fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; char fates_pftname(fates_pft, fates_string_length) ; fates_pftname:units = "unitless - string" ; fates_pftname:long_name = "Description of plant type" ; - char fates_prt_organ_name(fates_prt_organs, fates_string_length) ; + char fates_prt_organ_name(fates_prt_organs, fates_string_length) ; fates_prt_organ_name:units = "unitless - string" ; fates_prt_organ_name:long_name = "Plant organ name (order must match PRTGenericMod.F90)" ; - float fates_rootprof_beta(fates_variants, fates_pft) ; - fates_rootprof_beta:units = "unitless" ; - fates_rootprof_beta:long_name = "Rooting beta parameter, for C and N vertical discretization (NOT USED BY DEFAULT)" ; float fates_alloc_storage_cushion(fates_pft) ; fates_alloc_storage_cushion:units = "fraction" ; fates_alloc_storage_cushion:long_name = "maximum size of storage C pool, relative to maximum size of leaf C pool" ; @@ -145,6 +184,9 @@ variables: float fates_allom_fmode(fates_pft) ; fates_allom_fmode:units = "index" ; fates_allom_fmode:long_name = "fine root biomass allometry function index" ; + float fates_allom_frbstor_repro(fates_pft) ; + fates_allom_frbstor_repro:units = "fraction" ; + fates_allom_frbstor_repro:long_name = "fraction of bstore goes to reproduction after plant dies" ; float fates_allom_hmode(fates_pft) ; fates_allom_hmode:units = "index" ; fates_allom_hmode:long_name = "height allometry function index" ; @@ -169,53 +211,9 @@ variables: float fates_allom_stmode(fates_pft) ; fates_allom_stmode:units = "index" ; fates_allom_stmode:long_name = "storage allometry function index" ; - float fates_allom_frbstor_repro(fates_pft) ; - fates_allom_frbstor_repro:units = "fraction" ; - fates_allom_frbstor_repro:long_name = "fraction of bstore goes to reproduction after plant dies" ; float fates_branch_turnover(fates_pft) ; fates_branch_turnover:units = "yr-1" ; fates_branch_turnover:long_name = "turnover time of branches" ; - - float fates_prt_nitr_stoich_p1(fates_prt_organs,fates_pft) ; - fates_prt_nitr_stoich_p1:units = "(gN/gC)" ; - fates_prt_nitr_stoich_p1:long_name = "nitrogen stoichiometry, parameter 1" ; - - float fates_prt_nitr_stoich_p2(fates_prt_organs,fates_pft) ; - fates_prt_nitr_stoich_p2:units = "(gN/gC)" ; - fates_prt_nitr_stoich_p2:long_name = "nitrogen stoichiometry, parameter 2" ; - - float fates_prt_phos_stoich_p1(fates_prt_organs,fates_pft) ; - fates_prt_phos_stoich_p1:units = "(gP/gC)" ; - fates_prt_phos_stoich_p1:long_name = "phosphorous stoichiometry, parameter 1" ; - - float fates_prt_phos_stoich_p2(fates_prt_organs,fates_pft) ; - fates_prt_phos_stoich_p2:units = "(gP/gC)" ; - fates_prt_phos_stoich_p2:long_name = "phosphorous stoichiometry, parameter 2" ; - - float fates_prt_alloc_priority(fates_prt_organs,fates_pft) ; - fates_prt_alloc_priority:units = "index (0-fates_prt_organs)" ; - fates_prt_alloc_priority:long_name = "Priority order for allocation" ; - - float fates_phenflush_fraction(fates_pft) ; - fates_phenflush_fraction:units = "fraction" ; - fates_phenflush_fraction:long_name = "Upon bud-burst, the maximum fraction of storage carbon used for flushing leaves" ; - - float fates_turnover_retrans_mode(fates_pft) ; - fates_turnover_retrans_mode:units = "index" ; - fates_turnover_retrans_mode:long_name = "retranslocation method for leaf/fineroot turnover" ; - - float fates_turnover_carb_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_carb_retrans:units = "-" ; - fates_turnover_carb_retrans:long_name = "retranslocation fraction of carbon in turnover" ; - - float fates_turnover_nitr_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_nitr_retrans:units = "-" ; - fates_turnover_nitr_retrans:long_name = "retranslocation fraction of nitrogen in turnover" ; - - float fates_turnover_phos_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_phos_retrans:units = "-" ; - fates_turnover_phos_retrans:long_name = "retranslocation fraction of phosphorous in turnover " ; - float fates_c2b(fates_pft) ; fates_c2b:units = "ratio" ; fates_c2b:long_name = "Carbon to biomass multiplier of bulk structural tissues" ; @@ -249,12 +247,36 @@ variables: float fates_hydr_avuln_gs(fates_pft) ; fates_hydr_avuln_gs:units = "unitless" ; fates_hydr_avuln_gs:long_name = "shape parameter for stomatal control of water vapor exiting leaf" ; + float fates_hydr_avuln_node(fates_hydr_organs, fates_pft) ; + fates_hydr_avuln_node:units = "unitless" ; + fates_hydr_avuln_node:long_name = "xylem vulnerability curve shape parameter" ; + float fates_hydr_epsil_node(fates_hydr_organs, fates_pft) ; + fates_hydr_epsil_node:units = "MPa" ; + fates_hydr_epsil_node:long_name = "bulk elastic modulus" ; + float fates_hydr_fcap_node(fates_hydr_organs, fates_pft) ; + fates_hydr_fcap_node:units = "unitless" ; + fates_hydr_fcap_node:long_name = "fraction of (1-resid_node) that is capillary in source" ; + float fates_hydr_kmax_node(fates_hydr_organs, fates_pft) ; + fates_hydr_kmax_node:units = "kgMPa/m/s" ; + fates_hydr_kmax_node:long_name = "maximum xylem conductivity per unit conducting xylem area" ; float fates_hydr_p50_gs(fates_pft) ; fates_hydr_p50_gs:units = "MPa" ; fates_hydr_p50_gs:long_name = "water potential at 50% loss of stomatal conductance" ; + float fates_hydr_p50_node(fates_hydr_organs, fates_pft) ; + fates_hydr_p50_node:units = "MPa" ; + fates_hydr_p50_node:long_name = "xylem water potential at 50% loss of conductivity" ; float fates_hydr_p_taper(fates_pft) ; fates_hydr_p_taper:units = "unitless" ; fates_hydr_p_taper:long_name = "xylem taper exponent" ; + float fates_hydr_pinot_node(fates_hydr_organs, fates_pft) ; + fates_hydr_pinot_node:units = "MPa" ; + fates_hydr_pinot_node:long_name = "osmotic potential at full turgor" ; + float fates_hydr_pitlp_node(fates_hydr_organs, fates_pft) ; + fates_hydr_pitlp_node:units = "MPa" ; + fates_hydr_pitlp_node:long_name = "turgor loss point" ; + float fates_hydr_resid_node(fates_hydr_organs, fates_pft) ; + fates_hydr_resid_node:units = "fraction" ; + fates_hydr_resid_node:long_name = "residual fraction" ; float fates_hydr_rfrac_stem(fates_pft) ; fates_hydr_rfrac_stem:units = "fraction" ; fates_hydr_rfrac_stem:long_name = "fraction of total tree resistance from troot to canopy" ; @@ -264,6 +286,9 @@ variables: float fates_hydr_srl(fates_pft) ; fates_hydr_srl:units = "m g-1" ; fates_hydr_srl:long_name = "specific root length" ; + float fates_hydr_thetas_node(fates_hydr_organs, fates_pft) ; + fates_hydr_thetas_node:units = "cm3/cm3" ; + fates_hydr_thetas_node:long_name = "saturated water content" ; float fates_leaf_BB_slope(fates_pft) ; fates_leaf_BB_slope:units = "unitless" ; fates_leaf_BB_slope:long_name = "stomatal slope parameter, as per Ball-Berry" ; @@ -342,12 +367,12 @@ variables: float fates_mort_freezetol(fates_pft) ; fates_mort_freezetol:units = "NA" ; fates_mort_freezetol:long_name = "minimum temperature tolerance (NOT USED)" ; + float fates_mort_hf_flc_threshold(fates_pft) ; + fates_mort_hf_flc_threshold:units = "fraction" ; + fates_mort_hf_flc_threshold:long_name = "plant fractional loss of conductivity at which drought mortality begins for hydraulic model" ; float fates_mort_hf_sm_threshold(fates_pft) ; fates_mort_hf_sm_threshold:units = "unitless" ; fates_mort_hf_sm_threshold:long_name = "soil moisture (btran units) at which drought mortality begins for non-hydraulic model" ; - float fates_mort_hf_flc_threshold(fates_pft) ; - fates_mort_hf_flc_threshold:units = "fraction" ; - fates_mort_hf_flc_threshold:long_name = "plant fractional loss of conductivity at which drought mortality begins for hydraulic model" ; float fates_mort_scalar_coldstress(fates_pft) ; fates_mort_scalar_coldstress:units = "1/yr" ; fates_mort_scalar_coldstress:long_name = "maximum mortality rate from cold stress" ; @@ -369,6 +394,9 @@ variables: float fates_phen_stress_decid(fates_pft) ; fates_phen_stress_decid:units = "logical flag" ; fates_phen_stress_decid:long_name = "Binary flag for stress-deciduous leaf habit" ; + float fates_phenflush_fraction(fates_pft) ; + fates_phenflush_fraction:units = "fraction" ; + fates_phenflush_fraction:long_name = "Upon bud-burst, the maximum fraction of storage carbon used for flushing leaves" ; float fates_prescribed_mortality_canopy(fates_pft) ; fates_prescribed_mortality_canopy:units = "1/yr" ; fates_prescribed_mortality_canopy:long_name = "mortality rate of canopy trees for prescribed physiology mode" ; @@ -384,6 +412,21 @@ variables: float fates_prescribed_recruitment(fates_pft) ; fates_prescribed_recruitment:units = "n/yr" ; fates_prescribed_recruitment:long_name = "recruitment rate for prescribed physiology mode" ; + float fates_prt_alloc_priority(fates_prt_organs, fates_pft) ; + fates_prt_alloc_priority:units = "index (0-fates_prt_organs)" ; + fates_prt_alloc_priority:long_name = "Priority order for allocation" ; + float fates_prt_nitr_stoich_p1(fates_prt_organs, fates_pft) ; + fates_prt_nitr_stoich_p1:units = "(gN/gC)" ; + fates_prt_nitr_stoich_p1:long_name = "nitrogen stoichiometry, parameter 1" ; + float fates_prt_nitr_stoich_p2(fates_prt_organs, fates_pft) ; + fates_prt_nitr_stoich_p2:units = "(gN/gC)" ; + fates_prt_nitr_stoich_p2:long_name = "nitrogen stoichiometry, parameter 2" ; + float fates_prt_phos_stoich_p1(fates_prt_organs, fates_pft) ; + fates_prt_phos_stoich_p1:units = "(gP/gC)" ; + fates_prt_phos_stoich_p1:long_name = "phosphorous stoichiometry, parameter 1" ; + float fates_prt_phos_stoich_p2(fates_prt_organs, fates_pft) ; + fates_prt_phos_stoich_p2:units = "(gP/gC)" ; + fates_prt_phos_stoich_p2:long_name = "phosphorous stoichiometry, parameter 2" ; float fates_recruit_hgt_min(fates_pft) ; fates_recruit_hgt_min:units = "m" ; fates_recruit_hgt_min:long_name = "the minimum height (ie starting height) of a newly recruited plant" ; @@ -405,15 +448,15 @@ variables: float fates_root_long(fates_pft) ; fates_root_long:units = "yr" ; fates_root_long:long_name = "root longevity (alternatively, turnover time)" ; - float fates_senleaf_long_fdrought(fates_pft) ; - fates_senleaf_long_fdrought:units = "unitless[0-1]" ; - fates_senleaf_long_fdrought:long_name = "multiplication factor for leaf longevity of senescent leaves during drought" ; float fates_roota_par(fates_pft) ; fates_roota_par:units = "1/m" ; fates_roota_par:long_name = "CLM rooting distribution parameter" ; float fates_rootb_par(fates_pft) ; fates_rootb_par:units = "1/m" ; fates_rootb_par:long_name = "CLM rooting distribution parameter" ; + float fates_rootprof_beta(fates_variants, fates_pft) ; + fates_rootprof_beta:units = "unitless" ; + fates_rootprof_beta:long_name = "Rooting beta parameter, for C and N vertical discretization (NOT USED BY DEFAULT)" ; float fates_seed_alloc(fates_pft) ; fates_seed_alloc:units = "fraction" ; fates_seed_alloc:long_name = "fraction of available carbon balance allocated to seeds" ; @@ -432,6 +475,9 @@ variables: float fates_seed_rain(fates_pft) ; fates_seed_rain:units = "KgC/m2/yr" ; fates_seed_rain:long_name = "External seed rain from outside site (non-mass conserving)" ; + float fates_senleaf_long_fdrought(fates_pft) ; + fates_senleaf_long_fdrought:units = "unitless[0-1]" ; + fates_senleaf_long_fdrought:long_name = "multiplication factor for leaf longevity of senescent leaves during drought" ; float fates_smpsc(fates_pft) ; fates_smpsc:units = "mm" ; fates_smpsc:long_name = "Soil water potential at full stomatal closure" ; @@ -456,6 +502,18 @@ variables: float fates_trim_limit(fates_pft) ; fates_trim_limit:units = "m2/m2" ; fates_trim_limit:long_name = "Arbitrary limit to reductions in leaf area with stress" ; + float fates_turnover_carb_retrans(fates_prt_organs, fates_pft) ; + fates_turnover_carb_retrans:units = "-" ; + fates_turnover_carb_retrans:long_name = "retranslocation fraction of carbon in turnover" ; + float fates_turnover_nitr_retrans(fates_prt_organs, fates_pft) ; + fates_turnover_nitr_retrans:units = "-" ; + fates_turnover_nitr_retrans:long_name = "retranslocation fraction of nitrogen in turnover" ; + float fates_turnover_phos_retrans(fates_prt_organs, fates_pft) ; + fates_turnover_phos_retrans:units = "-" ; + fates_turnover_phos_retrans:long_name = "retranslocation fraction of phosphorous in turnover, parameter 1" ; + float fates_turnover_retrans_mode(fates_pft) ; + fates_turnover_retrans_mode:units = "index" ; + fates_turnover_retrans_mode:long_name = "retranslocation method for leaf/fineroot turnover" ; float fates_wood_density(fates_pft) ; fates_wood_density:units = "g/cm3" ; fates_wood_density:long_name = "mean density of woody tissue in plant" ; @@ -465,102 +523,36 @@ variables: float fates_z0mr(fates_pft) ; fates_z0mr:units = "unitless" ; fates_z0mr:long_name = "Ratio of momentum roughness length to canopy top height" ; - float fates_base_mr_20(fates_scalar) ; - fates_base_mr_20:units = "gC/gN/s" ; - fates_base_mr_20:long_name = "Base maintenance respiration rate for plant tissues, using Ryan 1991" ; - float fates_bbopt_c3(fates_scalar) ; - fates_bbopt_c3:units = "umol H2O/m**2/s" ; - fates_bbopt_c3:long_name = "Ball-Berry minimum unstressed leaf conductance for C3" ; - float fates_bbopt_c4(fates_scalar) ; - fates_bbopt_c4:units = "umol H2O/m**2/s" ; - fates_bbopt_c4:long_name = "Ball-Berry minimum unstressed leaf conductance for C4" ; - float fates_canopy_closure_thresh(fates_scalar) ; - fates_canopy_closure_thresh:units = "unitless" ; - fates_canopy_closure_thresh:long_name = "tree canopy coverage at which crown area allometry changes from savanna to forest value" ; - float fates_cohort_fusion_tol(fates_scalar) ; - fates_cohort_fusion_tol:units = "unitless" ; - fates_cohort_fusion_tol:long_name = "minimum fraction in difference in dbh between cohorts" ; - float fates_comp_excln(fates_scalar) ; - fates_comp_excln:units = "none" ; - fates_comp_excln:long_name = "weighting factor (exponent on dbh) for canopy layer exclusion and promotion" ; - float fates_cwd_fcel(fates_scalar) ; - fates_cwd_fcel:units = "unitless" ; - fates_cwd_fcel:long_name = "Cellulose fraction for CWD" ; - float fates_cwd_flig(fates_scalar) ; - fates_cwd_flig:units = "unitless" ; - fates_cwd_flig:long_name = "Lignin fraction of coarse woody debris" ; - float fates_fire_nignitions(fates_scalar) ; - fates_fire_nignitions:units = "/m2 (?)" ; - fates_fire_nignitions:long_name = "number of daily ignitions (nfires = nignitions*FDI*area_scaling)" ; - float fates_hydr_kmax_rsurf(fates_scalar) ; - fates_hydr_kmax_rsurf:units = "kg water/m2 root area/Mpa/s" ; - fates_hydr_kmax_rsurf:long_name = "maximum conducitivity for unit root surface" ; - float fates_hydr_psi0(fates_scalar) ; - fates_hydr_psi0:units = "MPa" ; - fates_hydr_psi0:long_name = "sapwood water potential at saturation" ; - float fates_hydr_psicap(fates_scalar) ; - fates_hydr_psicap:units = "MPa" ; - fates_hydr_psicap:long_name = "sapwood water potential at which capillary reserves exhausted" ; - float fates_init_litter(fates_scalar) ; - fates_init_litter:units = "NA" ; - fates_init_litter:long_name = "Initialization value for litter pool in cold-start (NOT USED)" ; - float fates_logging_coll_under_frac(fates_scalar) ; - fates_logging_coll_under_frac:units = "fraction" ; - fates_logging_coll_under_frac:long_name = "Fraction of stems killed in the understory when logging generates disturbance" ; - float fates_logging_collateral_frac(fates_scalar) ; - fates_logging_collateral_frac:units = "fraction" ; - fates_logging_collateral_frac:long_name = "Fraction of large stems in upperstory that die from logging collateral damage" ; - float fates_logging_dbhmax_infra(fates_scalar) ; - fates_logging_dbhmax_infra:units = "cm" ; - fates_logging_dbhmax_infra:long_name = "Tree diameter, above which infrastructure from logging does not impact damage or mortality." ; - float fates_logging_dbhmin(fates_scalar) ; - fates_logging_dbhmin:units = "cm" ; - fates_logging_dbhmin:long_name = "Minimum dbh at which logging is applied" ; - float fates_logging_direct_frac(fates_scalar) ; - fates_logging_direct_frac:units = "fraction" ; - fates_logging_direct_frac:long_name = "Fraction of stems logged directly per event" ; - float fates_logging_event_code(fates_scalar) ; - fates_logging_event_code:units = "unitless" ; - fates_logging_event_code:long_name = "Integer code that options how logging events are structured" ; - float fates_logging_mechanical_frac(fates_scalar) ; - fates_logging_mechanical_frac:units = "fraction" ; - fates_logging_mechanical_frac:long_name = "Fraction of stems killed due infrastructure an other mechanical means" ; - float fates_mort_disturb_frac(fates_scalar) ; - fates_mort_disturb_frac:units = "fraction" ; - fates_mort_disturb_frac:long_name = "fraction of canopy mortality that results in disturbance (i.e. transfer of area from new to old patch)" ; - float fates_mort_understorey_death(fates_scalar) ; - fates_mort_understorey_death:units = "fraction" ; - fates_mort_understorey_death:long_name = "fraction of plants in understorey cohort impacted by overstorey tree-fall" ; - float fates_patch_fusion_tol(fates_scalar) ; - fates_patch_fusion_tol:units = "unitless" ; - fates_patch_fusion_tol:long_name = "minimum fraction in difference in profiles between patches" ; - float fates_phen_a(fates_scalar) ; - fates_phen_a:units = "none" ; - fates_phen_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_b(fates_scalar) ; - fates_phen_b:units = "none" ; - fates_phen_b:long_name = "GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_c(fates_scalar) ; - fates_phen_c:units = "none" ; - fates_phen_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_chiltemp(fates_scalar) ; - fates_phen_chiltemp:units = "degrees C" ; - fates_phen_chiltemp:long_name = "chilling day counting threshold" ; - float fates_phen_coldtemp(fates_scalar) ; - fates_phen_coldtemp:units = "degrees C" ; - fates_phen_coldtemp:long_name = "temperature exceedance to flag a cold-day for temperature leaf drop" ; - float fates_phen_doff_time(fates_scalar) ; - fates_phen_doff_time:units = "days" ; - fates_phen_doff_time:long_name = "day threshold compared against days since leaves became off-allometry" ; - float fates_phen_drought_threshold(fates_scalar) ; - fates_phen_drought_threshold:units = "m3/m3" ; - fates_phen_drought_threshold:long_name = "liquid volume in soil layer, threashold for drought phenology" ; - float fates_phen_mindayson(fates_scalar) ; - fates_phen_mindayson:units = "days" ; - fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; - float fates_phen_ncolddayslim(fates_scalar) ; - fates_phen_ncolddayslim:units = "days" ; - fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; + float fates_FBD(fates_litterclass) ; + fates_FBD:units = "NA" ; + fates_FBD:long_name = "spitfire parameter related to fuel bulk density, see SFMain.F90" ; + float fates_low_moisture_Coeff(fates_litterclass) ; + fates_low_moisture_Coeff:units = "NA" ; + fates_low_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; + float fates_low_moisture_Slope(fates_litterclass) ; + fates_low_moisture_Slope:units = "NA" ; + fates_low_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; + float fates_max_decomp(fates_litterclass) ; + fates_max_decomp:units = "kgC/m2/yr ?" ; + fates_max_decomp:long_name = "maximum rate of litter & CWD transfer from non-decomposing class into decomposing class" ; + float fates_mid_moisture(fates_litterclass) ; + fates_mid_moisture:units = "NA" ; + fates_mid_moisture:long_name = "spitfire litter moisture threshold to be considered medium dry" ; + float fates_mid_moisture_Coeff(fates_litterclass) ; + fates_mid_moisture_Coeff:units = "NA" ; + fates_mid_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; + float fates_mid_moisture_Slope(fates_litterclass) ; + fates_mid_moisture_Slope:units = "NA" ; + fates_mid_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; + float fates_min_moisture(fates_litterclass) ; + fates_min_moisture:units = "NA" ; + fates_min_moisture:long_name = "spitfire litter moisture threshold to be considered very dry" ; + float fates_SAV(fates_litterclass) ; + fates_SAV:units = "NA" ; + fates_SAV:long_name = "spitfire parameter related to surface area to volume ratio, see SFMain.F90" ; + float fates_CWD_frac(fates_NCWD) ; + fates_CWD_frac:units = "fraction" ; + fates_CWD_frac:long_name = "fraction of woody (bdead+bsw) biomass destined for CWD pool" ; float fates_drying_ratio ; fates_drying_ratio:units = "NA" ; fates_drying_ratio:long_name = "spitfire parameter, fire drying ratio for fuel moisture, alpha_FMC EQ 6 Thonicke et al 2010" ; @@ -591,481 +583,570 @@ variables: float fates_part_dens ; fates_part_dens:units = "kg/m2" ; fates_part_dens:long_name = "spitfire parameter, oven dry particle density, Table A1 Thonicke et al 2010" ; - float fates_soil_salinity(fates_scalar) ; - fates_soil_salinity:units = "ppt" ; - fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; // global attributes: - :history = "This file was made from FatesPFTIndexSwapper.py \n", - " Input File = fates_params_13pfts.c180315.nc \n", - " Indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13] \n", - " Wed Feb 28 13:43:44 PST 2018 Values from Jennifer Holms 13pft test file fates_params.c170929_13pfts.nc were then manually converted over into positions 2-13, position 1 kept the tropical broadleaf evergreen. Wed Mar 7 15:53:33 PST 2018 (RGK) added fates_logging_dbhmax_infra, fates_maintresp_reduction_curvature, fates_maintresp_reduction_intercept, and fates_leaf_clumping_index. CHanged fates_clone_alloc to fates_seed_alloc_mature. Updated minimum grass sizes per J Shuman notes. Set grass AGB intercepts and latosa to zero. Updated clumping to have more substanteated starter values per suggestions by Shawn Serbin.\n", - " Thu Mar 15 13:48:11 PDT 2018 Added C4 plants via suggestions by @huitang_earth.\n", - " Mon Mar 19 19:05:44 EDT 2018 forced all plants to be evergreen till carbon-imbalances are fixed.\n", - " Mon Mar 19 19:05:44 EDT 2018 added entry for fates_history_height_bin_edges.\n", - " Thu Apr 12 14:18:46 PDT 2018 updated names on CN recruitment parameters. -- fates_params_14pft.c180412.nc -- \n", - " This file was made then modified wih FatesPFTIndexSwapper.py to reduce to 2 tropical pfts again. \n", - " Indices = [1, 1] \n", - " Wed Aug 29 12:14:41 PDT 2018: (RGK) Updated latosa to la_per_sa (inverts units, invert defaults also)\n" ; + :history = "This file was made from FatesPFTIndexSwapper.py \n", + " Input File = fates_params_14pft.nc \n", + " Indices = [1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14]" ; data: + fates_history_height_bin_edges = 0, 0.1, 0.3, 1, 3, 10 ; + fates_history_sizeclass_bin_edges = 0, 5, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100 ; fates_history_ageclass_bin_edges = 0, 1, 2, 5, 10, 20, 50 ; - fates_FBD = 4, 15.4, 16.8, 19.6, 999, 4 ; + fates_base_mr_20 = 2.52e-06 ; - fates_SAV = 66, 13, 3.58, 0.98, 0.2, 66 ; + fates_bbopt_c3 = 10000 ; - fates_history_height_bin_edges = 0, 0.1, 0.3, 1, 3, 10 ; + fates_bbopt_c4 = 40000 ; - fates_low_moisture_Coeff = 1.15, 1.12, 1.09, 0.98, 0.8, 1.15 ; + fates_canopy_closure_thresh = 0.8 ; - fates_low_moisture_Slope = 0.62, 0.62, 0.72, 0.85, 0.8, 0.62 ; + fates_cohort_fusion_tol = 0.08 ; - fates_max_decomp = 1, 0.52, 0.383, 0.383, 0.19, 999 ; + fates_comp_excln = 3 ; - fates_mid_moisture = 0.8, 0.72, 0.51, 0.38, 1, 0.8 ; + fates_cwd_fcel = 0.76 ; - fates_mid_moisture_Coeff = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; + fates_cwd_flig = 0.24 ; - fates_mid_moisture_Slope = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; + fates_fire_nignitions = 15 ; - fates_min_moisture = 0.24, 0.18, 0.12, 0, 0, 0.24 ; + fates_hydr_kmax_rsurf = 0.001 ; - fates_hydr_avuln_node = - 2, 2, - 2, 2, - 2, 2, - 2, 2 ; + fates_hydr_psi0 = 0 ; - fates_hydr_epsil_node = - 12, 12, - 10, 10, - 10, 10, - 8, 8 ; + fates_hydr_psicap = -0.6 ; - fates_hydr_fcap_node = - 0, 0, - 0.08, 0.08, - 0.08, 0.08, - 0, 0 ; + fates_init_litter = 0.05 ; - fates_hydr_kmax_node = - -999, -999, - 3, 3, - -999, -999, - -999, -999 ; + fates_logging_coll_under_frac = 0.55983 ; - fates_hydr_p50_node = - -2.25, -2.25, - -2.25, -2.25, - -2.25, -2.25, - -2.25, -2.25 ; + fates_logging_collateral_frac = 0.05 ; - fates_hydr_pinot_node = - -1.465984, -1.465984, - -1.228070, -1.228070, - -1.228070, -1.228070, - -1.043478, -1.043478 ; + fates_logging_dbhmax_infra = 35 ; - fates_hydr_pitlp_node = - -1.67, -1.67, - -1.4, -1.4, - -1.4, -1.4, - -1.2, -1.2 ; + fates_logging_dbhmin = 50 ; - fates_hydr_resid_node = - 0.25, 0.25, - 0.325, 0.325, - 0.325, 0.325, - 0.15, 0.15 ; + fates_logging_direct_frac = 0.15 ; - fates_hydr_thetas_node = - 0.65, 0.65, - 0.65, 0.65, - 0.65, 0.65, - 0.75, 0.75 ; + fates_logging_event_code = -30 ; - fates_CWD_frac = 0.045, 0.075, 0.21, 0.67 ; + fates_logging_mechanical_frac = 0.05 ; - fates_pftname = - "broadleaf_evergreen_tropical_tree ", - "broadleaf_evergreen_tropical_tree " ; + fates_mort_disturb_frac = 1 ; - fates_prt_organ_name = - "leaf ", - "fine root ", - "sapwood ", - "storage ", - "reproduction ", - "structure "; + fates_mort_understorey_death = 0.55983 ; - fates_rootprof_beta = - 0.976, 0.976, - _, _ ; + fates_patch_fusion_tol = 0.05 ; - fates_alloc_storage_cushion = 2, 2 ; + fates_phen_a = -68 ; - fates_allom_agb1 = 0.06896, 0.06896 ; + fates_phen_b = 638 ; - fates_allom_agb2 = 0.572, 0.572 ; + fates_phen_c = -0.001 ; - fates_allom_agb3 = 1.94, 1.94 ; + fates_phen_chiltemp = 5 ; - fates_allom_agb4 = 0.931, 0.931 ; + fates_phen_coldtemp = 7.5 ; - fates_allom_agb_frac = 0.6, 0.6 ; + fates_phen_doff_time = 100 ; - fates_allom_amode = 1, 1 ; + fates_phen_drought_threshold = 0.15 ; - fates_allom_blca_expnt_diff = 0, 0 ; + fates_phen_mindayson = 30 ; - fates_allom_cmode = 1, 1 ; + fates_phen_ncolddayslim = 5 ; - fates_allom_d2bl1 = 0.07, 0.07 ; + fates_soil_salinity = 0.4 ; - fates_allom_d2bl2 = 1.3, 1.3 ; + fates_pftname = + "broadleaf_evergreen_tropical_tree ", + "needleleaf_evergreen_temperate_tree ", + "needleleaf_deciduous_boreal_tree ", + "broadleaf_evergreen_temperate_tree ", + "broadleaf_deciduous_tropical_tree ", + "broadleaf_deciduous_temperate_tree ", + "broadleaf_evergreen_temperate_shrub ", + "broadleaf_deciduous_temperate_shrub ", + "broadleaf_deciduous_boreal_shrub ", + "arctic_c3_grass ", + "cool_c3_grass ", + "c4_grass " ; + + fates_prt_organ_name = + "leaf ", + "fine root ", + "sapwood ", + "storage ", + "reproduction ", + "structure " ; - fates_allom_d2bl3 = 0.55, 0.55 ; + fates_alloc_storage_cushion = 2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, + 1.2, 1.2, 1.2 ; - fates_allom_d2ca_coefficient_max = 0.6568464, 0.6568464 ; + fates_allom_agb1 = 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, + 0.06896, 0.06896, 0.06896, 0.01, 0.01, 0.01 ; - fates_allom_d2ca_coefficient_min = 0.3381119, 0.3381119 ; + fates_allom_agb2 = 0.572, 0.572, 0.572, 0.572, 0.572, 0.572, 0.572, 0.572, + 0.572, 0.572, 0.572, 0.572 ; - fates_allom_d2h1 = 0.64, 0.64 ; + fates_allom_agb3 = 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, + 1.94, 1.94, 1.94 ; - fates_allom_d2h2 = 0.37, 0.37 ; + fates_allom_agb4 = 0.931, 0.931, 0.931, 0.931, 0.931, 0.931, 0.931, 0.931, + 0.931, 0.931, 0.931, 0.931 ; - fates_allom_d2h3 = -999.9, -999.9 ; + fates_allom_agb_frac = 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, + 0.6, 0.6 ; - fates_allom_dbh_maxheight = 150, 150 ; + fates_allom_amode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_allom_fmode = 1, 1 ; + fates_allom_blca_expnt_diff = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - fates_allom_hmode = 1, 1 ; + fates_allom_cmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_allom_l2fr = 1, 1 ; + fates_allom_d2bl1 = 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07 ; - fates_allom_la_per_sa_int = 1000.0, 1000.0 ; + fates_allom_d2bl2 = 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, + 1.3 ; - fates_allom_la_per_sa_slp = 0.0, 0.0 ; + fates_allom_d2bl3 = 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, + 0.55, 0.55, 0.55 ; - fates_allom_lmode = 1, 1 ; + fates_allom_d2ca_coefficient_max = 0.6568464, 0.6568464, 0.6568464, + 0.6568464, 0.6568464, 0.6568464, 0.6568464, 0.6568464, 0.6568464, + 0.6568464, 0.6568464, 0.6568464 ; - fates_allom_sai_scaler = 0.10, 0.10 ; + fates_allom_d2ca_coefficient_min = 0.3381119, 0.3381119, 0.3381119, + 0.3381119, 0.3381119, 0.3381119, 0.3381119, 0.3381119, 0.3381119, + 0.3381119, 0.3381119, 0.3381119 ; - fates_allom_smode = 1, 1 ; + fates_allom_d2h1 = 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, + 0.64, 0.64, 0.64 ; - fates_allom_stmode = 1, 1 ; - - fates_allom_frbstor_repro = 0.0, 0.0; + fates_allom_d2h2 = 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, + 0.37, 0.37, 0.37 ; - fates_branch_turnover = 50, 50 ; + fates_allom_d2h3 = -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, + -999.9, -999.9, -999.9, -999.9, -999.9 ; - fates_prt_nitr_stoich_p1 = - 0.033, 0.033, - 0.024, 0.024, - 0.0047, 0.0047, - 0.0047, 0.0047, - 0.0, 0.0, - 0.0047, 0.0047; + fates_allom_dbh_maxheight = 150, 90, 90, 90, 90, 90, 3, 3, 2, 1.47, 1.47, + 1.47 ; - fates_prt_nitr_stoich_p2 = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; + fates_allom_fmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_prt_phos_stoich_p1 = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; + fates_allom_frbstor_repro = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - fates_prt_phos_stoich_p2 = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; + fates_allom_hmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_prt_alloc_priority = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; + fates_allom_l2fr = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_phenflush_fraction = - 0.5, 0.5; + fates_allom_la_per_sa_int = 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, + 1000, 1000, 1000, 1000 ; - fates_turnover_retrans_mode = - 1, 1; + fates_allom_la_per_sa_slp = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - fates_turnover_carb_retrans = - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00; + fates_allom_lmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_turnover_nitr_retrans = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; + fates_allom_sai_scaler = 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, + 0.1, 0.1 ; - fates_turnover_phos_retrans = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; + fates_allom_smode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_c2b = 2, 2 ; + fates_allom_stmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_displar = 0.67, 0.67 ; + fates_branch_turnover = 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0 ; - fates_fire_alpha_SH = 0.2, 0.2 ; + fates_c2b = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; - fates_fire_bark_scaler = 0.07, 0.07 ; + fates_displar = 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, + 0.67, 0.67 ; - fates_fire_crown_depth_frac = 0.5, 0.5 ; + fates_fire_alpha_SH = 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, + 0.2 ; - fates_fire_crown_kill = 0.775, 0.775 ; + fates_fire_bark_scaler = 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, + 0.07, 0.07, 0.07, 0.07 ; - fates_fr_fcel = 0.5, 0.5 ; + fates_fire_crown_depth_frac = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.95, 0.95, + 0.95, 1, 1, 1 ; - fates_fr_flab = 0.25, 0.25 ; + fates_fire_crown_kill = 0.775, 0.775, 0.775, 0.775, 0.775, 0.775, 0.775, + 0.775, 0.775, 0.775, 0.775, 0.775 ; - fates_fr_flig = 0.25, 0.25 ; + fates_fr_fcel = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_grperc = 0.11, 0.11 ; + fates_fr_flab = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, + 0.25, 0.25 ; - fates_hydr_avuln_gs = 2.5, 2.5 ; + fates_fr_flig = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, + 0.25, 0.25 ; - fates_hydr_p50_gs = -1.5, -1.5 ; + fates_grperc = 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, + 0.11, 0.11 ; - fates_hydr_p_taper = 0.333, 0.333 ; + fates_hydr_avuln_gs = 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, + 2.5 ; - fates_hydr_rfrac_stem = 0.625, 0.625 ; + fates_hydr_avuln_node = + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; - fates_hydr_rs2 = 0.0001, 0.0001 ; + fates_hydr_epsil_node = + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ; - fates_hydr_srl = 25, 25 ; + fates_hydr_fcap_node = + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, + 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - fates_leaf_BB_slope = 8, 8 ; + fates_hydr_kmax_node = + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 ; - fates_leaf_c3psn = 1, 1 ; + fates_hydr_p50_gs = -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, + -1.5, -1.5, -1.5 ; - fates_leaf_clumping_index = 0.85, 0.85 ; + fates_hydr_p50_node = + -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, + -2.25, -2.25, + -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, + -2.25, -2.25, + -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, + -2.25, -2.25, + -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, + -2.25, -2.25 ; + + fates_hydr_p_taper = 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333 ; - fates_leaf_diameter = 0.04, 0.04 ; + fates_hydr_pinot_node = + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 ; - fates_leaf_jmaxha = 43540, 43540 ; + fates_hydr_pitlp_node = + -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, + -1.67, -1.67, + -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, + -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, + -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2 ; - fates_leaf_jmaxhd = 152040, 152040 ; + fates_hydr_resid_node = + 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, + 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, + 0.325, 0.325, + 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, + 0.325, 0.325, + 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15 ; - fates_leaf_jmaxse = 495, 495 ; + fates_hydr_rfrac_stem = 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.625, 0.625, 0.625, 0.625, 0.625 ; - fates_leaf_long = 0.75, 0.75, - 0.75, 0.75 ; + fates_hydr_rs2 = 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, + 0.0001, 0.0001, 0.0001, 0.0001, 0.0001 ; + fates_hydr_srl = 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25 ; - fates_leaf_slamax = 0.0954, 0.0954 ; + fates_hydr_thetas_node = + 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, + 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, + 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, + 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75 ; - fates_leaf_slatop = 0.012, 0.012 ; + fates_leaf_BB_slope = 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ; - fates_leaf_stor_priority = 0.8, 0.8 ; + fates_leaf_c3psn = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 ; - fates_leaf_tpuha = 53100, 53100 ; + fates_leaf_clumping_index = 0.85, 0.85, 0.8, 0.85, 0.85, 0.9, 0.85, 0.9, + 0.9, 0.75, 0.75, 0.75 ; - fates_leaf_tpuhd = 150650, 150650 ; + fates_leaf_diameter = 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, + 0.04, 0.04, 0.04 ; - fates_leaf_tpuse = 490, 490 ; + fates_leaf_jmaxha = 43540, 43540, 43540, 43540, 43540, 43540, 43540, 43540, + 43540, 43540, 43540, 43540 ; - fates_leaf_vcmax25top = 50, 50, - 50, 50; + fates_leaf_jmaxhd = 152040, 152040, 152040, 152040, 152040, 152040, 152040, + 152040, 152040, 152040, 152040, 152040 ; - fates_leaf_vcmaxha = 65330, 65330 ; + fates_leaf_jmaxse = 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, + 495 ; - fates_leaf_vcmaxhd = 149250, 149250 ; + fates_leaf_long = + 0.75, 2, 0.5, 0.75, 0.5, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.5, + 0.75, 2, 0.5, 0.75, 0.5, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_leaf_vcmaxse = 485, 485 ; + fates_leaf_slamax = 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.012, + 0.03, 0.03, 0.03, 0.03, 0.03 ; - fates_leaf_xl = 0.1, 0.1 ; + fates_leaf_slatop = 0.012, 0.01, 0.024, 0.012, 0.03, 0.03, 0.012, 0.03, + 0.03, 0.03, 0.03, 0.03 ; - fates_lf_fcel = 0.5, 0.5 ; + fates_leaf_stor_priority = 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, + 0.8, 0.8 ; - fates_lf_flab = 0.25, 0.25 ; + fates_leaf_tpuha = 53100, 53100, 53100, 53100, 53100, 53100, 53100, 53100, + 53100, 53100, 53100, 53100 ; - fates_lf_flig = 0.25, 0.25 ; + fates_leaf_tpuhd = 150650, 150650, 150650, 150650, 150650, 150650, 150650, + 150650, 150650, 150650, 150650, 150650 ; - fates_maintresp_reduction_curvature = 0.01, 0.01 ; + fates_leaf_tpuse = 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490 ; - fates_maintresp_reduction_intercept = 1, 1 ; + fates_leaf_vcmax25top = + 50, 65, 39, 62, 41, 58, 62, 54, 54, 78, 78, 78, + 50, 65, 39, 62, 41, 58, 62, 54, 54, 78, 78, 78 ; - fates_mort_bmort = 0.014, 0.014 ; + fates_leaf_vcmaxha = 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, + 65330, 65330, 65330, 65330 ; - fates_mort_freezetol = 2.5, 2.5 ; + fates_leaf_vcmaxhd = 149250, 149250, 149250, 149250, 149250, 149250, 149250, + 149250, 149250, 149250, 149250, 149250 ; - fates_mort_hf_sm_threshold = 1e-06, 1e-06 ; - - fates_mort_hf_flc_threshold = 0.5, 0.5 ; + fates_leaf_vcmaxse = 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, + 485 ; - fates_mort_scalar_coldstress = 3, 3 ; + fates_leaf_xl = 0.1, 0.01, 0.01, 0.1, 0.01, 0.25, 0.01, 0.25, 0.25, -0.3, + -0.3, -0.3 ; - fates_mort_scalar_cstarvation = 0.6, 0.6 ; + fates_lf_fcel = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_mort_scalar_hydrfailure = 0.6, 0.6 ; + fates_lf_flab = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, + 0.25, 0.25 ; - fates_pft_used = 1, 1 ; + fates_lf_flig = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, + 0.25, 0.25 ; - fates_phen_evergreen = 1, 1 ; + fates_maintresp_reduction_curvature = 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ; - fates_phen_season_decid = 0, 0 ; + fates_maintresp_reduction_intercept = 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1 ; - fates_phen_stress_decid = 0, 0 ; + fates_mort_bmort = 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, + 0.014, 0.014, 0.014, 0.014 ; - fates_prescribed_mortality_canopy = 0.0194, 0.0194 ; + fates_mort_freezetol = 2.5, -55, -80, -30, 2.5, -30, -60, -10, -80, -80, + -80, -80 ; - fates_prescribed_mortality_understory = 0.025, 0.025 ; + fates_mort_hf_flc_threshold = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, + 0.5, 0.5, 0.5 ; - fates_prescribed_npp_canopy = 0.4, 0.4 ; + fates_mort_hf_sm_threshold = 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, + 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06 ; - fates_prescribed_npp_understory = 0.03125, 0.03125 ; + fates_mort_scalar_coldstress = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ; - fates_prescribed_recruitment = 0.02, 0.02 ; + fates_mort_scalar_cstarvation = 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, + 0.6, 0.6, 0.6 ; - fates_recruit_hgt_min = 1.25, 1.25 ; + fates_mort_scalar_hydrfailure = 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, + 0.6, 0.6, 0.6 ; - fates_recruit_initd = 0.2, 0.2 ; + fates_pft_used = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_rholnir = 0.45, 0.45 ; + fates_phen_evergreen = 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 ; - fates_rholvis = 0.1, 0.1 ; + fates_phen_season_decid = 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 ; - fates_rhosnir = 0.39, 0.39 ; + fates_phen_stress_decid = 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 ; - fates_rhosvis = 0.16, 0.16 ; + fates_phenflush_fraction = _, _, 0.5, _, 0.5, 0.5, _, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_senleaf_long_fdrought = 1.0, 1.0 ; + fates_prescribed_mortality_canopy = 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, + 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, 0.0194 ; - fates_root_long = 1, 1 ; + fates_prescribed_mortality_understory = 0.025, 0.025, 0.025, 0.025, 0.025, + 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025 ; - fates_roota_par = 7, 7 ; + fates_prescribed_npp_canopy = 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, + 0.4, 0.4, 0.4 ; - fates_rootb_par = 1, 1 ; + fates_prescribed_npp_understory = 0.03125, 0.03125, 0.03125, 0.03125, + 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125 ; - fates_seed_alloc = 0.1, 0.1 ; + fates_prescribed_recruitment = 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, + 0.02, 0.02, 0.02, 0.02, 0.02 ; - fates_seed_alloc_mature = 0, 0 ; + fates_prt_alloc_priority = + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_seed_dbh_repro_threshold = 150, 150 ; + fates_prt_nitr_stoich_p1 = + 0.033, 0.029, 0.04, 0.033, 0.04, 0.04, 0.033, 0.04, 0.04, 0.04, 0.04, 0.04, + 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, + 0.024, 0.024, + 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, + 0.0047, 0.0047, 0.0047, + 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, + 0.0047, 0.0047, 0.0047, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, + 0.0047, 0.0047, 0.0047 ; - fates_seed_decay_turnover = 0.51, 0.51 ; + fates_prt_nitr_stoich_p2 = + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_seed_germination_timescale = 0.5, 0.5 ; + fates_prt_phos_stoich_p1 = + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_seed_rain = 0.28, 0.28 ; + fates_prt_phos_stoich_p2 = + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_smpsc = -255000, -255000 ; + fates_recruit_hgt_min = 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 0.75, 0.75, + 0.75, 0.75, 0.75, 0.75 ; - fates_smpso = -66000, -66000 ; + fates_recruit_initd = 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 20, 20, 20 ; - fates_taulnir = 0.25, 0.25 ; + fates_rholnir = 0.45, 0.35, 0.35, 0.45, 0.45, 0.45, 0.35, 0.45, 0.45, 0.35, + 0.35, 0.35 ; - fates_taulvis = 0.05, 0.05 ; + fates_rholvis = 0.1, 0.07, 0.07, 0.1, 0.1, 0.1, 0.07, 0.1, 0.1, 0.1, 0.1, 0.1 ; - fates_tausnir = 0.001, 0.001 ; + fates_rhosnir = 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.53, + 0.53, 0.53 ; - fates_tausvis = 0.001, 0.001 ; + fates_rhosvis = 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.31, + 0.31, 0.31 ; - fates_trim_inc = 0.03, 0.03 ; + fates_root_long = 1, 2, 1, 1.5, 1, 1, 1.5, 1, 1, 1, 1, 1 ; - fates_trim_limit = 0.3, 0.3 ; + fates_roota_par = 7, 7, 7, 7, 6, 6, 7, 7, 7, 11, 11, 11 ; - fates_wood_density = 0.7, 0.7 ; + fates_rootb_par = 1, 2, 2, 1, 2, 2, 1.5, 1.5, 1.5, 2, 2, 2 ; - fates_woody = 1, 1 ; + fates_rootprof_beta = + 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, + 0.976, 0.976, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_z0mr = 0.055, 0.055 ; + fates_seed_alloc = 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ; - fates_base_mr_20 = 2.52e-06 ; + fates_seed_alloc_mature = 0, 0, 0, 0, 0, 0, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9 ; - fates_bbopt_c3 = 10000 ; + fates_seed_dbh_repro_threshold = 150, 90, 90, 90, 90, 90, 3, 3, 2, 1.47, + 1.47, 1.47 ; - fates_bbopt_c4 = 40000 ; + fates_seed_decay_turnover = 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, + 0.51, 0.51, 0.51, 0.51 ; - fates_canopy_closure_thresh = 0.8 ; + fates_seed_germination_timescale = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, + 0.5, 0.5, 0.5, 0.5 ; - fates_cohort_fusion_tol = 0.08 ; + fates_seed_rain = 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, + 0.28, 0.28, 0.28 ; - fates_comp_excln = 3 ; + fates_senleaf_long_fdrought = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_cwd_fcel = 0.76 ; + fates_smpsc = -255000, -255000, -255000, -255000, -255000, -255000, -255000, + -255000, -255000, -255000, -255000, -255000 ; - fates_cwd_flig = 0.24 ; + fates_smpso = -66000, -66000, -66000, -66000, -66000, -66000, -66000, + -66000, -66000, -66000, -66000, -66000 ; - fates_fire_nignitions = 15 ; - - fates_hydr_kmax_rsurf = 20; + fates_taulnir = 0.25, 0.1, 0.1, 0.25, 0.25, 0.25, 0.1, 0.25, 0.25, 0.34, + 0.34, 0.34 ; - fates_hydr_psi0 = 0 ; + fates_taulvis = 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, + 0.05, 0.05 ; - fates_hydr_psicap = -0.6 ; + fates_tausnir = 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, + 0.001, 0.25, 0.25, 0.25 ; - fates_init_litter = 0.05 ; + fates_tausvis = 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, + 0.001, 0.12, 0.12, 0.12 ; - fates_logging_coll_under_frac = 0.55983 ; + fates_trim_inc = 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, + 0.03, 0.03 ; - fates_logging_collateral_frac = 0.05 ; + fates_trim_limit = 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3 ; - fates_logging_dbhmax_infra = 35 ; + fates_turnover_carb_retrans = + 0.025, 0.025, 0.05, 0.025, 0.05, 0.05, 0.025, 0.05, 0.05, 0.05, 0.05, 0.05, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - fates_logging_dbhmin = 50 ; + fates_turnover_nitr_retrans = + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_logging_direct_frac = 0.15 ; + fates_turnover_phos_retrans = + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_logging_event_code = -30 ; + fates_turnover_retrans_mode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_logging_mechanical_frac = 0.05 ; + fates_wood_density = 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, + 0.7 ; - fates_mort_disturb_frac = 1 ; + fates_woody = 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ; - fates_mort_understorey_death = 0.55983 ; + fates_z0mr = 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, + 0.055, 0.055, 0.055 ; - fates_patch_fusion_tol = 0.05 ; + fates_FBD = 4, 15.4, 16.8, 19.6, 999, 4 ; - fates_phen_a = -68 ; + fates_low_moisture_Coeff = 1.15, 1.12, 1.09, 0.98, 0.8, 1.15 ; - fates_phen_b = 638 ; + fates_low_moisture_Slope = 0.62, 0.62, 0.72, 0.85, 0.8, 0.62 ; - fates_phen_c = -0.001 ; + fates_max_decomp = 1, 0.52, 0.383, 0.383, 0.19, 999 ; - fates_phen_chiltemp = 5 ; + fates_mid_moisture = 0.8, 0.72, 0.51, 0.38, 1, 0.8 ; - fates_phen_coldtemp = 7.5 ; + fates_mid_moisture_Coeff = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - fates_phen_doff_time = 100 ; + fates_mid_moisture_Slope = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - fates_phen_drought_threshold = 0.15 ; + fates_min_moisture = 0.24, 0.18, 0.12, 0, 0, 0.24 ; - fates_phen_mindayson = 30 ; + fates_SAV = 66, 13, 3.58, 0.98, 0.2, 66 ; - fates_phen_ncolddayslim = 5 ; + fates_CWD_frac = 0.045, 0.075, 0.21, 0.67 ; fates_drying_ratio = 13000 ; @@ -1086,6 +1167,4 @@ data: fates_miner_total = 0.055 ; fates_part_dens = 513 ; - - fates_soil_salinity = 0.4 ; } From 9bf86524d8e8c5d6a1f1bf5e3af38f14686724f6 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Mar 2019 11:18:35 -0700 Subject: [PATCH 68/78] removed other pft files --- parameter_files/fates_params_14pfts.cdl | 1215 ----------------- parameter_files/fates_params_coastal_veg.cdl | 958 ------------- .../fates_params_hydro_default.cdl | 1091 --------------- 3 files changed, 3264 deletions(-) delete mode 100644 parameter_files/fates_params_14pfts.cdl delete mode 100644 parameter_files/fates_params_coastal_veg.cdl delete mode 100644 parameter_files/fates_params_hydro_default.cdl diff --git a/parameter_files/fates_params_14pfts.cdl b/parameter_files/fates_params_14pfts.cdl deleted file mode 100644 index d1a79ad235..0000000000 --- a/parameter_files/fates_params_14pfts.cdl +++ /dev/null @@ -1,1215 +0,0 @@ -netcdf fates_params_default_sorted { -dimensions: - fates_pft = 14 ; - fates_history_age_bins = 7 ; - fates_history_size_bins = 13 ; - fates_history_height_bins = 6 ; - fates_hydr_organs = 4 ; - fates_leafage_class = 2; - fates_NCWD = 4 ; - fates_litterclass = 6 ; - fates_scalar = 1 ; - fates_string_length = 60 ; - fates_variants = 2 ; - fates_prt_organs = 6 ; -variables: - float fates_history_height_bin_edges(fates_history_height_bins) ; - fates_history_height_bin_edges:units = "m" ; - fates_history_height_bin_edges:long_name = "Lower edges for height bins used in height-resolved history output" ; - float fates_history_sizeclass_bin_edges(fates_history_size_bins) ; - fates_history_sizeclass_bin_edges:units = "cm" ; - fates_history_sizeclass_bin_edges:long_name = "Lower edges for DBH size class bins used in size-resolved cohort history output" ; - float fates_history_ageclass_bin_edges(fates_history_age_bins) ; - fates_history_ageclass_bin_edges:units = "yr" ; - fates_history_ageclass_bin_edges:long_name = "Lower edges for age class bins used in age-resolved patch history output" ; - float fates_base_mr_20(fates_scalar) ; - fates_base_mr_20:units = "gC/gN/s" ; - fates_base_mr_20:long_name = "Base maintenance respiration rate for plant tissues, using Ryan 1991" ; - float fates_bbopt_c3(fates_scalar) ; - fates_bbopt_c3:units = "umol H2O/m**2/s" ; - fates_bbopt_c3:long_name = "Ball-Berry minimum unstressed leaf conductance for C3" ; - float fates_bbopt_c4(fates_scalar) ; - fates_bbopt_c4:units = "umol H2O/m**2/s" ; - fates_bbopt_c4:long_name = "Ball-Berry minimum unstressed leaf conductance for C4" ; - float fates_canopy_closure_thresh(fates_scalar) ; - fates_canopy_closure_thresh:units = "unitless" ; - fates_canopy_closure_thresh:long_name = "tree canopy coverage at which crown area allometry changes from savanna to forest value" ; - float fates_cohort_fusion_tol(fates_scalar) ; - fates_cohort_fusion_tol:units = "unitless" ; - fates_cohort_fusion_tol:long_name = "minimum fraction in difference in dbh between cohorts" ; - float fates_comp_excln(fates_scalar) ; - fates_comp_excln:units = "none" ; - fates_comp_excln:long_name = "weighting factor (exponent on dbh) for canopy layer exclusion and promotion" ; - float fates_cwd_fcel(fates_scalar) ; - fates_cwd_fcel:units = "unitless" ; - fates_cwd_fcel:long_name = "Cellulose fraction for CWD" ; - float fates_cwd_flig(fates_scalar) ; - fates_cwd_flig:units = "unitless" ; - fates_cwd_flig:long_name = "Lignin fraction of coarse woody debris" ; - float fates_fire_nignitions(fates_scalar) ; - fates_fire_nignitions:units = "/m2 (?)" ; - fates_fire_nignitions:long_name = "number of daily ignitions (nfires = nignitions*FDI*area_scaling)" ; - float fates_hydr_kmax_rsurf(fates_scalar) ; - fates_hydr_kmax_rsurf:units = "kg water/m2 root area/Mpa/s" ; - fates_hydr_kmax_rsurf:long_name = "maximum conducitivity for unit root surface" ; - float fates_hydr_psi0(fates_scalar) ; - fates_hydr_psi0:units = "MPa" ; - fates_hydr_psi0:long_name = "sapwood water potential at saturation" ; - float fates_hydr_psicap(fates_scalar) ; - fates_hydr_psicap:units = "MPa" ; - fates_hydr_psicap:long_name = "sapwood water potential at which capillary reserves exhausted" ; - float fates_init_litter(fates_scalar) ; - fates_init_litter:units = "NA" ; - fates_init_litter:long_name = "Initialization value for litter pool in cold-start (NOT USED)" ; - float fates_logging_coll_under_frac(fates_scalar) ; - fates_logging_coll_under_frac:units = "fraction" ; - fates_logging_coll_under_frac:long_name = "Fraction of stems killed in the understory when logging generates disturbance" ; - float fates_logging_collateral_frac(fates_scalar) ; - fates_logging_collateral_frac:units = "fraction" ; - fates_logging_collateral_frac:long_name = "Fraction of large stems in upperstory that die from logging collateral damage" ; - float fates_logging_dbhmax_infra(fates_scalar) ; - fates_logging_dbhmax_infra:units = "cm" ; - fates_logging_dbhmax_infra:long_name = "Tree diameter, above which infrastructure from logging does not impact damage or mortality." ; - float fates_logging_dbhmin(fates_scalar) ; - fates_logging_dbhmin:units = "cm" ; - fates_logging_dbhmin:long_name = "Minimum dbh at which logging is applied" ; - float fates_logging_direct_frac(fates_scalar) ; - fates_logging_direct_frac:units = "fraction" ; - fates_logging_direct_frac:long_name = "Fraction of stems logged directly per event" ; - float fates_logging_event_code(fates_scalar) ; - fates_logging_event_code:units = "unitless" ; - fates_logging_event_code:long_name = "Integer code that options how logging events are structured" ; - float fates_logging_mechanical_frac(fates_scalar) ; - fates_logging_mechanical_frac:units = "fraction" ; - fates_logging_mechanical_frac:long_name = "Fraction of stems killed due infrastructure an other mechanical means" ; - float fates_mort_disturb_frac(fates_scalar) ; - fates_mort_disturb_frac:units = "fraction" ; - fates_mort_disturb_frac:long_name = "fraction of canopy mortality that results in disturbance (i.e. transfer of area from new to old patch)" ; - float fates_mort_understorey_death(fates_scalar) ; - fates_mort_understorey_death:units = "fraction" ; - fates_mort_understorey_death:long_name = "fraction of plants in understorey cohort impacted by overstorey tree-fall" ; - float fates_patch_fusion_tol(fates_scalar) ; - fates_patch_fusion_tol:units = "unitless" ; - fates_patch_fusion_tol:long_name = "minimum fraction in difference in profiles between patches" ; - float fates_phen_a(fates_scalar) ; - fates_phen_a:units = "none" ; - fates_phen_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_b(fates_scalar) ; - fates_phen_b:units = "none" ; - fates_phen_b:long_name = "GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_c(fates_scalar) ; - fates_phen_c:units = "none" ; - fates_phen_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_chiltemp(fates_scalar) ; - fates_phen_chiltemp:units = "degrees C" ; - fates_phen_chiltemp:long_name = "chilling day counting threshold" ; - float fates_phen_coldtemp(fates_scalar) ; - fates_phen_coldtemp:units = "degrees C" ; - fates_phen_coldtemp:long_name = "temperature exceedance to flag a cold-day for temperature leaf drop" ; - float fates_phen_doff_time(fates_scalar) ; - fates_phen_doff_time:units = "days" ; - fates_phen_doff_time:long_name = "day threshold compared against days since leaves became off-allometry" ; - float fates_phen_drought_threshold(fates_scalar) ; - fates_phen_drought_threshold:units = "m3/m3" ; - fates_phen_drought_threshold:long_name = "liquid volume in soil layer, threashold for drought phenology" ; - float fates_phen_mindayson(fates_scalar) ; - fates_phen_mindayson:units = "days" ; - fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; - float fates_phen_ncolddayslim(fates_scalar) ; - fates_phen_ncolddayslim:units = "days" ; - fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; - char fates_pftname(fates_pft, fates_string_length) ; - fates_pftname:units = "unitless - string" ; - fates_pftname:long_name = "Description of plant type" ; - char fates_prt_organ_name(fates_prt_organs, fates_string_length) ; - fates_prt_organ_name:units = "unitless - string" ; - fates_prt_organ_name:long_name = "Plant organ name (order must match PRTGenericMod.F90)" ; - float fates_alloc_storage_cushion(fates_pft) ; - fates_alloc_storage_cushion:units = "fraction" ; - fates_alloc_storage_cushion:long_name = "maximum size of storage C pool, relative to maximum size of leaf C pool" ; - float fates_allom_frbstor_repro(fates_pft) ; - fates_allom_frbstor_repro:units = "fraction" ; - fates_allom_frbstor_repro:long_name = "fraction of bstore goes to reproduction after plant dies" ; - float fates_allom_agb1(fates_pft) ; - fates_allom_agb1:units = "variable" ; - fates_allom_agb1:long_name = "Parameter 1 for agb allometry" ; - float fates_allom_agb2(fates_pft) ; - fates_allom_agb2:units = "variable" ; - fates_allom_agb2:long_name = "Parameter 2 for agb allometry" ; - float fates_allom_agb3(fates_pft) ; - fates_allom_agb3:units = "variable" ; - fates_allom_agb3:long_name = "Parameter 3 for agb allometry" ; - float fates_allom_agb4(fates_pft) ; - fates_allom_agb4:units = "variable" ; - fates_allom_agb4:long_name = "Parameter 4 for agb allometry" ; - float fates_allom_agb_frac(fates_pft) ; - fates_allom_agb_frac:units = "fraction" ; - fates_allom_agb_frac:long_name = "Fraction of woody biomass that is above ground" ; - float fates_allom_amode(fates_pft) ; - fates_allom_amode:units = "index" ; - fates_allom_amode:long_name = "AGB allometry function index" ; - float fates_allom_blca_expnt_diff(fates_pft) ; - fates_allom_blca_expnt_diff:units = "unitless" ; - fates_allom_blca_expnt_diff:long_name = "difference between allometric DBH:bleaf and DBH:crown area exponents" ; - float fates_allom_cmode(fates_pft) ; - fates_allom_cmode:units = "index" ; - fates_allom_cmode:long_name = "coarse root biomass allometry function index" ; - float fates_allom_d2bl1(fates_pft) ; - fates_allom_d2bl1:units = "variable" ; - fates_allom_d2bl1:long_name = "Parameter 1 for d2bl allometry" ; - float fates_allom_d2bl2(fates_pft) ; - fates_allom_d2bl2:units = "variable" ; - fates_allom_d2bl2:long_name = "Parameter 2 for d2bl allometry" ; - float fates_allom_d2bl3(fates_pft) ; - fates_allom_d2bl3:units = "unitless" ; - fates_allom_d2bl3:long_name = "Parameter 3 for d2bl allometry" ; - float fates_allom_d2ca_coefficient_max(fates_pft) ; - fates_allom_d2ca_coefficient_max:units = "m2 cm^(-1/beta)" ; - fates_allom_d2ca_coefficient_max:long_name = "max (savanna) dbh to area multiplier factor where: area = n*d2ca_coeff*dbh^beta" ; - float fates_allom_d2ca_coefficient_min(fates_pft) ; - fates_allom_d2ca_coefficient_min:units = "m2 cm^(-1/beta)" ; - fates_allom_d2ca_coefficient_min:long_name = "min (forest) dbh to area multiplier factor where: area = n*d2ca_coeff*dbh^beta" ; - float fates_allom_d2h1(fates_pft) ; - fates_allom_d2h1:units = "variable" ; - fates_allom_d2h1:long_name = "Parameter 1 for d2h allometry (intercept, or c)" ; - float fates_allom_d2h2(fates_pft) ; - fates_allom_d2h2:units = "variable" ; - fates_allom_d2h2:long_name = "Parameter 2 for d2h allometry (slope, or m)" ; - float fates_allom_d2h3(fates_pft) ; - fates_allom_d2h3:units = "variable" ; - fates_allom_d2h3:long_name = "Parameter 3 for d2h allometry (optional)" ; - float fates_allom_dbh_maxheight(fates_pft) ; - fates_allom_dbh_maxheight:units = "cm" ; - fates_allom_dbh_maxheight:long_name = "the diameter (if any) corresponding to maximum height, diameters may increase beyond this" ; - float fates_allom_fmode(fates_pft) ; - fates_allom_fmode:units = "index" ; - fates_allom_fmode:long_name = "fine root biomass allometry function index" ; - float fates_allom_hmode(fates_pft) ; - fates_allom_hmode:units = "index" ; - fates_allom_hmode:long_name = "height allometry function index" ; - float fates_allom_l2fr(fates_pft) ; - fates_allom_l2fr:units = "gC/gC" ; - fates_allom_l2fr:long_name = "Allocation parameter: fine root C per leaf C" ; - float fates_allom_la_per_sa_int(fates_pft) ; - fates_allom_la_per_sa_int:units = "m2/cm2" ; - fates_allom_la_per_sa_int:long_name = "Leaf area per sapwood area, intercept" ; - float fates_allom_la_per_sa_slp(fates_pft) ; - fates_allom_la_per_sa_slp:units = "m2/cm2/m" ; - fates_allom_la_per_sa_slp:long_name = "Leaf area per sapwood area rate of change with height, slope (optional)" ; - float fates_allom_lmode(fates_pft) ; - fates_allom_lmode:units = "index" ; - fates_allom_lmode:long_name = "leaf biomass allometry function index" ; - float fates_allom_sai_scaler(fates_pft) ; - fates_allom_sai_scaler:units = "m2/m2" ; - fates_allom_sai_scaler:long_name = "allometric ratio of SAI per LAI" ; - float fates_allom_smode(fates_pft) ; - fates_allom_smode:units = "index" ; - fates_allom_smode:long_name = "sapwood allometry function index" ; - float fates_allom_stmode(fates_pft) ; - fates_allom_stmode:units = "index" ; - fates_allom_stmode:long_name = "storage allometry function index" ; - float fates_branch_turnover(fates_pft) ; - fates_branch_turnover:units = "yr-1" ; - fates_branch_turnover:long_name = "turnover time of branches" ; - - float fates_prt_nitr_stoich_p1(fates_prt_organs,fates_pft) ; - fates_prt_nitr_stoich_p1:units = "(gN/gC)" ; - fates_prt_nitr_stoich_p1:long_name = "nitrogen stoichiometry, parameter 1" ; - - float fates_prt_nitr_stoich_p2(fates_prt_organs,fates_pft) ; - fates_prt_nitr_stoich_p2:units = "(gN/gC)" ; - fates_prt_nitr_stoich_p2:long_name = "nitrogen stoichiometry, parameter 2" ; - - float fates_prt_phos_stoich_p1(fates_prt_organs,fates_pft) ; - fates_prt_phos_stoich_p1:units = "(gP/gC)" ; - fates_prt_phos_stoich_p1:long_name = "phosphorous stoichiometry, parameter 1" ; - - float fates_prt_phos_stoich_p2(fates_prt_organs,fates_pft) ; - fates_prt_phos_stoich_p2:units = "(gP/gC)" ; - fates_prt_phos_stoich_p2:long_name = "phosphorous stoichiometry, parameter 2" ; - - float fates_prt_alloc_priority(fates_prt_organs,fates_pft) ; - fates_prt_alloc_priority:units = "index (0-fates_prt_organs)" ; - fates_prt_alloc_priority:long_name = "Priority order for allocation" ; - - float fates_phenflush_fraction(fates_pft) ; - fates_phenflush_fraction:units = "fraction" ; - fates_phenflush_fraction:long_name = "Upon bud-burst, the maximum fraction of storage carbon used for flushing leaves" ; - - float fates_turnover_retrans_mode(fates_pft) ; - fates_turnover_retrans_mode:units = "index" ; - fates_turnover_retrans_mode:long_name = "retranslocation method for leaf/fineroot turnover" ; - - float fates_turnover_carb_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_carb_retrans:units = "-" ; - fates_turnover_carb_retrans:long_name = "retranslocation fraction of carbon in turnover" ; - - float fates_turnover_nitr_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_nitr_retrans:units = "-" ; - fates_turnover_nitr_retrans:long_name = "retranslocation fraction of nitrogen in turnover" ; - - float fates_turnover_phos_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_phos_retrans:units = "-" ; - fates_turnover_phos_retrans:long_name = "retranslocation fraction of phosphorous in turnover, parameter 1" ; - - float fates_c2b(fates_pft) ; - fates_c2b:units = "ratio" ; - fates_c2b:long_name = "Carbon to biomass multiplier of bulk structural tissues" ; - float fates_displar(fates_pft) ; - fates_displar:units = "unitless" ; - fates_displar:long_name = "Ratio of displacement height to canopy top height" ; - float fates_fire_alpha_SH(fates_pft) ; - fates_fire_alpha_SH:units = "NA" ; - fates_fire_alpha_SH:long_name = "spitfire parameter, alpha scorch height, Equation 16 Thonicke et al 2010" ; - float fates_fire_bark_scaler(fates_pft) ; - fates_fire_bark_scaler:units = "fraction" ; - fates_fire_bark_scaler:long_name = "the thickness of a cohorts bark as a fraction of its dbh" ; - float fates_fire_crown_depth_frac(fates_pft) ; - fates_fire_crown_depth_frac:units = "fraction" ; - fates_fire_crown_depth_frac:long_name = "the depth of a cohorts crown as a fraction of its height" ; - float fates_fire_crown_kill(fates_pft) ; - fates_fire_crown_kill:units = "NA" ; - fates_fire_crown_kill:long_name = "fire parameter, see equation 22 in Thonicke et al 2010" ; - float fates_fr_fcel(fates_pft) ; - fates_fr_fcel:units = "fraction" ; - fates_fr_fcel:long_name = "Fine root litter cellulose fraction" ; - float fates_fr_flab(fates_pft) ; - fates_fr_flab:units = "fraction" ; - fates_fr_flab:long_name = "Fine root litter labile fraction" ; - float fates_fr_flig(fates_pft) ; - fates_fr_flig:units = "fraction" ; - fates_fr_flig:long_name = "Fine root litter lignin fraction" ; - float fates_grperc(fates_pft) ; - fates_grperc:units = "unitless" ; - fates_grperc:long_name = "Growth respiration factor" ; - float fates_hydr_avuln_gs(fates_pft) ; - fates_hydr_avuln_gs:units = "unitless" ; - fates_hydr_avuln_gs:long_name = "shape parameter for stomatal control of water vapor exiting leaf" ; - float fates_hydr_avuln_node(fates_hydr_organs, fates_pft) ; - fates_hydr_avuln_node:units = "unitless" ; - fates_hydr_avuln_node:long_name = "xylem vulnerability curve shape parameter" ; - float fates_hydr_epsil_node(fates_hydr_organs, fates_pft) ; - fates_hydr_epsil_node:units = "MPa" ; - fates_hydr_epsil_node:long_name = "bulk elastic modulus" ; - float fates_hydr_fcap_node(fates_hydr_organs, fates_pft) ; - fates_hydr_fcap_node:units = "unitless" ; - fates_hydr_fcap_node:long_name = "fraction of (1-resid_node) that is capillary in source" ; - float fates_hydr_kmax_node(fates_hydr_organs, fates_pft) ; - fates_hydr_kmax_node:units = "kgMPa/m/s" ; - fates_hydr_kmax_node:long_name = "maximum xylem conductivity per unit conducting xylem area" ; - float fates_hydr_p50_gs(fates_pft) ; - fates_hydr_p50_gs:units = "MPa" ; - fates_hydr_p50_gs:long_name = "water potential at 50% loss of stomatal conductance" ; - float fates_hydr_p50_node(fates_hydr_organs, fates_pft) ; - fates_hydr_p50_node:units = "MPa" ; - fates_hydr_p50_node:long_name = "xylem water potential at 50% loss of conductivity" ; - float fates_hydr_p_taper(fates_pft) ; - fates_hydr_p_taper:units = "unitless" ; - fates_hydr_p_taper:long_name = "xylem taper exponent" ; - float fates_hydr_pinot_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pinot_node:units = "MPa" ; - fates_hydr_pinot_node:long_name = "osmotic potential at full turgor" ; - float fates_hydr_pitlp_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pitlp_node:units = "MPa" ; - fates_hydr_pitlp_node:long_name = "turgor loss point" ; - float fates_hydr_resid_node(fates_hydr_organs, fates_pft) ; - fates_hydr_resid_node:units = "fraction" ; - fates_hydr_resid_node:long_name = "residual fraction" ; - float fates_hydr_rfrac_stem(fates_pft) ; - fates_hydr_rfrac_stem:units = "fraction" ; - fates_hydr_rfrac_stem:long_name = "fraction of total tree resistance from troot to canopy" ; - float fates_hydr_rs2(fates_pft) ; - fates_hydr_rs2:units = "m" ; - fates_hydr_rs2:long_name = "absorbing root radius" ; - float fates_hydr_srl(fates_pft) ; - fates_hydr_srl:units = "m g-1" ; - fates_hydr_srl:long_name = "specific root length" ; - float fates_hydr_thetas_node(fates_hydr_organs, fates_pft) ; - fates_hydr_thetas_node:units = "cm3/cm3" ; - fates_hydr_thetas_node:long_name = "saturated water content" ; - float fates_leaf_BB_slope(fates_pft) ; - fates_leaf_BB_slope:units = "unitless" ; - fates_leaf_BB_slope:long_name = "stomatal slope parameter, as per Ball-Berry" ; - float fates_leaf_c3psn(fates_pft) ; - fates_leaf_c3psn:units = "flag" ; - fates_leaf_c3psn:long_name = "Photosynthetic pathway (1=c3, 0=c4)" ; - float fates_leaf_clumping_index(fates_pft) ; - fates_leaf_clumping_index:units = "fraction (0-1)" ; - fates_leaf_clumping_index:long_name = "factor describing how much self-occlusion of leaf scattering elements decreases light interception" ; - float fates_leaf_diameter(fates_pft) ; - fates_leaf_diameter:units = "m" ; - fates_leaf_diameter:long_name = "Characteristic leaf dimension" ; - float fates_leaf_jmaxha(fates_pft) ; - fates_leaf_jmaxha:units = "J/mol" ; - fates_leaf_jmaxha:long_name = "activation energy for jmax" ; - float fates_leaf_jmaxhd(fates_pft) ; - fates_leaf_jmaxhd:units = "J/mol" ; - fates_leaf_jmaxhd:long_name = "deactivation energy for jmax" ; - float fates_leaf_jmaxse(fates_pft) ; - fates_leaf_jmaxse:units = "J/mol/K" ; - fates_leaf_jmaxse:long_name = "entropy term for jmax" ; - float fates_leaf_long(fates_leafage_class,fates_pft) ; - fates_leaf_long:units = "yr" ; - fates_leaf_long:long_name = "Leaf longevity (ie turnover timescale)" ; - float fates_leaf_slamax(fates_pft) ; - fates_leaf_slamax:units = "m^2/gC" ; - fates_leaf_slamax:long_name = "Maximum Specific Leaf Area (SLA), even if under a dense canopy" ; - float fates_leaf_slatop(fates_pft) ; - fates_leaf_slatop:units = "m^2/gC" ; - fates_leaf_slatop:long_name = "Specific Leaf Area (SLA) at top of canopy, projected area basis" ; - float fates_leaf_stor_priority(fates_pft) ; - fates_leaf_stor_priority:units = "unitless" ; - fates_leaf_stor_priority:long_name = "factor governing priority of replacing storage with NPP" ; - float fates_leaf_tpuha(fates_pft) ; - fates_leaf_tpuha:units = "J/mol" ; - fates_leaf_tpuha:long_name = "activation energy for tpu" ; - float fates_leaf_tpuhd(fates_pft) ; - fates_leaf_tpuhd:units = "J/mol" ; - fates_leaf_tpuhd:long_name = "deactivation energy for tpu" ; - float fates_leaf_tpuse(fates_pft) ; - fates_leaf_tpuse:units = "J/mol/K" ; - fates_leaf_tpuse:long_name = "entropy term for tpu" ; - float fates_leaf_vcmax25top(fates_leafage_class,fates_pft) ; - fates_leaf_vcmax25top:units = "umol CO2/m^2/s" ; - fates_leaf_vcmax25top:long_name = "maximum carboxylation rate of Rub. at 25C, canopy top" ; - float fates_leaf_vcmaxha(fates_pft) ; - fates_leaf_vcmaxha:units = "J/mol" ; - fates_leaf_vcmaxha:long_name = "activation energy for vcmax" ; - float fates_leaf_vcmaxhd(fates_pft) ; - fates_leaf_vcmaxhd:units = "J/mol" ; - fates_leaf_vcmaxhd:long_name = "deactivation energy for vcmax" ; - float fates_leaf_vcmaxse(fates_pft) ; - fates_leaf_vcmaxse:units = "J/mol/K" ; - fates_leaf_vcmaxse:long_name = "entropy term for vcmax" ; - float fates_leaf_xl(fates_pft) ; - fates_leaf_xl:units = "unitless" ; - fates_leaf_xl:long_name = "Leaf/stem orientation index" ; - float fates_lf_fcel(fates_pft) ; - fates_lf_fcel:units = "fraction" ; - fates_lf_fcel:long_name = "Leaf litter cellulose fraction" ; - float fates_lf_flab(fates_pft) ; - fates_lf_flab:units = "fraction" ; - fates_lf_flab:long_name = "Leaf litter labile fraction" ; - float fates_lf_flig(fates_pft) ; - fates_lf_flig:units = "fraction" ; - fates_lf_flig:long_name = "Leaf litter lignin fraction" ; - float fates_maintresp_reduction_curvature(fates_pft) ; - fates_maintresp_reduction_curvature:units = "unitless (0-1)" ; - fates_maintresp_reduction_curvature:long_name = "curvature of MR reduction as f(carbon storage), 1=linear, 0=very curved" ; - float fates_maintresp_reduction_intercept(fates_pft) ; - fates_maintresp_reduction_intercept:units = "unitless (0-1)" ; - fates_maintresp_reduction_intercept:long_name = "intercept of MR reduction as f(carbon storage), 0=no throttling, 1=max throttling" ; - float fates_mort_bmort(fates_pft) ; - fates_mort_bmort:units = "1/yr" ; - fates_mort_bmort:long_name = "background mortality rate" ; - float fates_mort_freezetol(fates_pft) ; - fates_mort_freezetol:units = "NA" ; - fates_mort_freezetol:long_name = "minimum temperature tolerance (NOT USED)" ; - float fates_mort_hf_sm_threshold(fates_pft) ; - fates_mort_hf_sm_threshold:units = "unitless" ; - fates_mort_hf_sm_threshold:long_name = "soil moisture (btran units) at which drought mortality begins for non-hydraulic model" ; - float fates_mort_hf_flc_threshold(fates_pft) ; - fates_mort_hf_flc_threshold:units = "fraction" ; - fates_mort_hf_flc_threshold:long_name = "plant fractional loss of conductivity at which drought mortality begins for hydraulic model" ; - float fates_mort_scalar_coldstress(fates_pft) ; - fates_mort_scalar_coldstress:units = "1/yr" ; - fates_mort_scalar_coldstress:long_name = "maximum mortality rate from cold stress" ; - float fates_mort_scalar_cstarvation(fates_pft) ; - fates_mort_scalar_cstarvation:units = "1/yr" ; - fates_mort_scalar_cstarvation:long_name = "maximum mortality rate from carbon starvation" ; - float fates_mort_scalar_hydrfailure(fates_pft) ; - fates_mort_scalar_hydrfailure:units = "1/yr" ; - fates_mort_scalar_hydrfailure:long_name = "maximum mortality rate from hydraulic failure" ; - float fates_pft_used(fates_pft) ; - fates_pft_used:units = "0 = off (dont use), 1 = on (use)" ; - fates_pft_used:long_name = "Switch to turn on and off PFTs (also see fates_initd for cold-start)" ; - float fates_phen_evergreen(fates_pft) ; - fates_phen_evergreen:units = "logical flag" ; - fates_phen_evergreen:long_name = "Binary flag for evergreen leaf habit" ; - float fates_phen_season_decid(fates_pft) ; - fates_phen_season_decid:units = "logical flag" ; - fates_phen_season_decid:long_name = "Binary flag for seasonal-deciduous leaf habit" ; - float fates_phen_stress_decid(fates_pft) ; - fates_phen_stress_decid:units = "logical flag" ; - fates_phen_stress_decid:long_name = "Binary flag for stress-deciduous leaf habit" ; - float fates_prescribed_mortality_canopy(fates_pft) ; - fates_prescribed_mortality_canopy:units = "1/yr" ; - fates_prescribed_mortality_canopy:long_name = "mortality rate of canopy trees for prescribed physiology mode" ; - float fates_prescribed_mortality_understory(fates_pft) ; - fates_prescribed_mortality_understory:units = "1/yr" ; - fates_prescribed_mortality_understory:long_name = "mortality rate of understory trees for prescribed physiology mode" ; - float fates_prescribed_npp_canopy(fates_pft) ; - fates_prescribed_npp_canopy:units = "gC / m^2 / yr" ; - fates_prescribed_npp_canopy:long_name = "NPP per unit crown area of canopy trees for prescribed physiology mode" ; - float fates_prescribed_npp_understory(fates_pft) ; - fates_prescribed_npp_understory:units = "gC / m^2 / yr" ; - fates_prescribed_npp_understory:long_name = "NPP per unit crown area of understory trees for prescribed physiology mode" ; - float fates_prescribed_recruitment(fates_pft) ; - fates_prescribed_recruitment:units = "n/yr" ; - fates_prescribed_recruitment:long_name = "recruitment rate for prescribed physiology mode" ; - float fates_recruit_hgt_min(fates_pft) ; - fates_recruit_hgt_min:units = "m" ; - fates_recruit_hgt_min:long_name = "the minimum height (ie starting height) of a newly recruited plant" ; - float fates_recruit_initd(fates_pft) ; - fates_recruit_initd:units = "stems/m2" ; - fates_recruit_initd:long_name = "initial seedling density for a cold-start near-bare-ground simulation" ; - float fates_rholnir(fates_pft) ; - fates_rholnir:units = "fraction" ; - fates_rholnir:long_name = "Leaf reflectance: near-IR" ; - float fates_rholvis(fates_pft) ; - fates_rholvis:units = "fraction" ; - fates_rholvis:long_name = "Leaf reflectance: visible" ; - float fates_rhosnir(fates_pft) ; - fates_rhosnir:units = "fraction" ; - fates_rhosnir:long_name = "Stem reflectance: near-IR" ; - float fates_rhosvis(fates_pft) ; - fates_rhosvis:units = "fraction" ; - fates_rhosvis:long_name = "Stem reflectance: visible" ; - float fates_root_long(fates_pft) ; - fates_root_long:units = "yr" ; - fates_root_long:long_name = "root longevity (alternatively, turnover time)" ; - float fates_senleaf_long_fdrought(fates_pft) ; - fates_senleaf_long_fdrought:units = "unitless[0-1]" ; - fates_senleaf_long_fdrought:long_name = "multiplication factor for leaf longevity of senescent leaves during drought" ; - float fates_roota_par(fates_pft) ; - fates_roota_par:units = "1/m" ; - fates_roota_par:long_name = "CLM rooting distribution parameter" ; - float fates_rootb_par(fates_pft) ; - fates_rootb_par:units = "1/m" ; - fates_rootb_par:long_name = "CLM rooting distribution parameter" ; - float fates_rootprof_beta(fates_variants, fates_pft) ; - fates_rootprof_beta:units = "unitless" ; - fates_rootprof_beta:long_name = "Rooting beta parameter, for C and N vertical discretization (NOT USED BY DEFAULT)" ; - float fates_seed_alloc(fates_pft) ; - fates_seed_alloc:units = "fraction" ; - fates_seed_alloc:long_name = "fraction of available carbon balance allocated to seeds" ; - float fates_seed_alloc_mature(fates_pft) ; - fates_seed_alloc_mature:units = "fraction" ; - fates_seed_alloc_mature:long_name = "fraction of available carbon balance allocated to seeds in mature plants (adds to fates_seed_alloc)" ; - float fates_seed_dbh_repro_threshold(fates_pft) ; - fates_seed_dbh_repro_threshold:units = "cm" ; - fates_seed_dbh_repro_threshold:long_name = "the diameter (if any) where the plant will start extra clonal allocation to the seed pool" ; - float fates_seed_decay_turnover(fates_pft) ; - fates_seed_decay_turnover:units = "1/yr" ; - fates_seed_decay_turnover:long_name = "turnover time for seeds with respect to germination" ; - float fates_seed_germination_timescale(fates_pft) ; - fates_seed_germination_timescale:units = "1/yr" ; - fates_seed_germination_timescale:long_name = "turnover time for seeds with respect to decay" ; - float fates_seed_rain(fates_pft) ; - fates_seed_rain:units = "KgC/m2/yr" ; - fates_seed_rain:long_name = "External seed rain from outside site (non-mass conserving)" ; - float fates_smpsc(fates_pft) ; - fates_smpsc:units = "mm" ; - fates_smpsc:long_name = "Soil water potential at full stomatal closure" ; - float fates_smpso(fates_pft) ; - fates_smpso:units = "mm" ; - fates_smpso:long_name = "Soil water potential at full stomatal opening" ; - float fates_taulnir(fates_pft) ; - fates_taulnir:units = "fraction" ; - fates_taulnir:long_name = "Leaf transmittance: near-IR" ; - float fates_taulvis(fates_pft) ; - fates_taulvis:units = "fraction" ; - fates_taulvis:long_name = "Leaf transmittance: visible" ; - float fates_tausnir(fates_pft) ; - fates_tausnir:units = "fraction" ; - fates_tausnir:long_name = "Stem transmittance: near-IR" ; - float fates_tausvis(fates_pft) ; - fates_tausvis:units = "fraction" ; - fates_tausvis:long_name = "Stem transmittance: visible" ; - float fates_trim_inc(fates_pft) ; - fates_trim_inc:units = "m2/m2" ; - fates_trim_inc:long_name = "Arbitrary incremental change in trimming function." ; - float fates_trim_limit(fates_pft) ; - fates_trim_limit:units = "m2/m2" ; - fates_trim_limit:long_name = "Arbitrary limit to reductions in leaf area with stress" ; - float fates_wood_density(fates_pft) ; - fates_wood_density:units = "g/cm3" ; - fates_wood_density:long_name = "mean density of woody tissue in plant" ; - float fates_woody(fates_pft) ; - fates_woody:units = "logical flag" ; - fates_woody:long_name = "Binary woody lifeform flag" ; - float fates_z0mr(fates_pft) ; - fates_z0mr:units = "unitless" ; - fates_z0mr:long_name = "Ratio of momentum roughness length to canopy top height" ; - float fates_FBD(fates_litterclass) ; - fates_FBD:units = "NA" ; - fates_FBD:long_name = "spitfire parameter related to fuel bulk density, see SFMain.F90" ; - float fates_low_moisture_Coeff(fates_litterclass) ; - fates_low_moisture_Coeff:units = "NA" ; - fates_low_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_low_moisture_Slope(fates_litterclass) ; - fates_low_moisture_Slope:units = "NA" ; - fates_low_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_max_decomp(fates_litterclass) ; - fates_max_decomp:units = "kgC/m2/yr ?" ; - fates_max_decomp:long_name = "maximum rate of litter & CWD transfer from non-decomposing class into decomposing class" ; - float fates_mid_moisture(fates_litterclass) ; - fates_mid_moisture:units = "NA" ; - fates_mid_moisture:long_name = "spitfire litter moisture threshold to be considered medium dry" ; - float fates_mid_moisture_Coeff(fates_litterclass) ; - fates_mid_moisture_Coeff:units = "NA" ; - fates_mid_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_mid_moisture_Slope(fates_litterclass) ; - fates_mid_moisture_Slope:units = "NA" ; - fates_mid_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_min_moisture(fates_litterclass) ; - fates_min_moisture:units = "NA" ; - fates_min_moisture:long_name = "spitfire litter moisture threshold to be considered very dry" ; - float fates_SAV(fates_litterclass) ; - fates_SAV:units = "NA" ; - fates_SAV:long_name = "spitfire parameter related to surface area to volume ratio, see SFMain.F90" ; - float fates_CWD_frac(fates_NCWD) ; - fates_CWD_frac:units = "fraction" ; - fates_CWD_frac:long_name = "fraction of woody (bdead+bsw) biomass destined for CWD pool" ; - float fates_drying_ratio ; - fates_drying_ratio:units = "NA" ; - fates_drying_ratio:long_name = "spitfire parameter, fire drying ratio for fuel moisture, alpha_FMC EQ 6 Thonicke et al 2010" ; - float fates_durat_slope ; - fates_durat_slope:units = "NA" ; - fates_durat_slope:long_name = "spitfire parameter, fire max duration slope, Equation 14 Thonicke et al 2010" ; - float fates_fdi_a ; - fates_fdi_a:units = "NA" ; - fates_fdi_a:long_name = "spitfire parameter (unknown) " ; - float fates_fdi_alpha ; - fates_fdi_alpha:units = "NA" ; - fates_fdi_alpha:long_name = "spitfire parameter, EQ 7 Venevsky et al. GCB 2002,(modified EQ 8 Thonicke et al. 2010) " ; - float fates_fdi_b ; - fates_fdi_b:units = "NA" ; - fates_fdi_b:long_name = "spitfire parameter (unknown) " ; - float fates_fuel_energy ; - fates_fuel_energy:units = "kJ/kg" ; - fates_fuel_energy:long_name = "pitfire parameter, heat content of fuel" ; - float fates_max_durat ; - fates_max_durat:units = "minutes" ; - fates_max_durat:long_name = "spitfire parameter, fire maximum duration, Equation 14 Thonicke et al 2010" ; - float fates_miner_damp ; - fates_miner_damp:units = "NA" ; - fates_miner_damp:long_name = "spitfire parameter, mineral-dampening coefficient EQ A1 Thonicke et al 2010 " ; - float fates_miner_total ; - fates_miner_total:units = "fraction" ; - fates_miner_total:long_name = "spitfire parameter, total mineral content, Table A1 Thonicke et al 2010" ; - float fates_part_dens ; - fates_part_dens:units = "kg/m2" ; - fates_part_dens:long_name = "spitfire parameter, oven dry particle density, Table A1 Thonicke et al 2010" ; - float fates_soil_salinity(fates_scalar) ; - fates_soil_salinity:units = "ppt" ; - fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; - -// global attributes: - :history = "This file was made from FatesPFTIndexSwapper.py \n", - " Input File = fates_params_13pfts.c180315.nc \n", - " Indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13] \n", - " Wed Feb 28 13:43:44 PST 2018 Values from Jennifer Holms 13pft test file fates_params.c170929_13pfts.nc were then manually converted over into positions 2-13, position 1 kept the tropical broadleaf evergreen. Wed Mar 7 15:53:33 PST 2018 (RGK) added fates_logging_dbhmax_infra, fates_maintresp_reduction_curvature, fates_maintresp_reduction_intercept, and fates_leaf_clumping_index. CHanged fates_clone_alloc to fates_seed_alloc_mature. Updated minimum grass sizes per J Shuman notes. Set grass AGB intercepts and latosa to zero. Updated clumping to have more substanteated starter values per suggestions by Shawn Serbin.\n", - " Thu Mar 15 13:48:11 PDT 2018 Added C4 plants via suggestions by @huitang_earth.\n", - " Mon Mar 19 19:05:44 EDT 2018 forced all plants to be evergreen till carbon-imbalances are fixed.\n", - " Mon Mar 19 19:05:44 EDT 2018 added entry for fates_history_height_bin_edges.\n", - " Thu Apr 12 14:18:46 PDT 2018 updated names on CN recruitment parameters. -- fates_params_14pft.c180412.nc -- \n", - " Wed Aug 29 12:14:41 PDT 2018: (RGK) Updated latosa to la_per_sa (inverts units, invert defaults also)\n" ; - -data: - - fates_history_height_bin_edges = 0, 0.1, 0.3, 1, 3, 10 ; - - fates_history_sizeclass_bin_edges = 0, 5, 10, 15, 20, 30, 40, 50, 60, 70, - 80, 90, 100 ; - - fates_history_ageclass_bin_edges = 0, 1, 2, 5, 10, 20, 50 ; - - fates_base_mr_20 = 2.52e-06 ; - - fates_bbopt_c3 = 10000 ; - - fates_bbopt_c4 = 40000 ; - - fates_canopy_closure_thresh = 0.8 ; - - fates_cohort_fusion_tol = 0.08 ; - - fates_comp_excln = 3 ; - - fates_cwd_fcel = 0.76 ; - - fates_cwd_flig = 0.24 ; - - fates_fire_nignitions = 15 ; - - fates_hydr_kmax_rsurf = 0.001; - - fates_hydr_psi0 = 0 ; - - fates_hydr_psicap = -0.6 ; - - fates_init_litter = 0.05 ; - - fates_logging_coll_under_frac = 0.55983 ; - - fates_logging_collateral_frac = 0.05 ; - - fates_logging_dbhmax_infra = 35 ; - - fates_logging_dbhmin = 50 ; - - fates_logging_direct_frac = 0.15 ; - - fates_logging_event_code = -30 ; - - fates_logging_mechanical_frac = 0.05 ; - - fates_mort_disturb_frac = 1 ; - - fates_mort_understorey_death = 0.55983 ; - - fates_patch_fusion_tol = 0.05 ; - - fates_phen_a = -68 ; - - fates_phen_b = 638 ; - - fates_phen_c = -0.001 ; - - fates_phen_chiltemp = 5 ; - - fates_phen_coldtemp = 7.5 ; - - fates_phen_doff_time = 100 ; - - fates_phen_drought_threshold = 0.15 ; - - fates_phen_mindayson = 30 ; - - fates_phen_ncolddayslim = 5 ; - - fates_pftname = - "broadleaf_evergreen_tropical_tree ", - "needleleaf_evergreen_temperate_tree ", - "needleleaf_evergreen_boreal_tree ", - "needleleaf_deciduous_boreal_tree ", - "broadleaf_evergreen_temperate_tree ", - "broadleaf_deciduous_tropical_tree ", - "broadleaf_deciduous_temperate_tree ", - "broadleaf_deciduous_boreal_tree ", - "broadleaf_evergreen_temperate_shrub ", - "broadleaf_deciduous_temperate_shrub ", - "broadleaf_deciduous_boreal_shrub ", - "arctic_c3_grass ", - "cool_c3_grass ", - "c4_grass " ; - - fates_prt_organ_name = - "leaf ", - "fine root ", - "sapwood ", - "storage ", - "reproduction ", - "structure "; - - fates_allom_frbstor_repro = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - - fates_alloc_storage_cushion = 2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, - 1.2, 1.2, 1.2, 1.2, 1.2 ; - - fates_allom_agb1 = 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, - 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, 0.01, 0.01, 0.01 ; - - fates_allom_agb2 = 0.572, 0.572, 0.572, 0.572, 0.572, 0.572, 0.572, 0.572, - 0.572, 0.572, 0.572, 0.572, 0.572, 0.572 ; - - fates_allom_agb3 = 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, 1.94, - 1.94, 1.94, 1.94, 1.94, 1.94 ; - - fates_allom_agb4 = 0.931, 0.931, 0.931, 0.931, 0.931, 0.931, 0.931, 0.931, - 0.931, 0.931, 0.931, 0.931, 0.931, 0.931 ; - - fates_allom_agb_frac = 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, - 0.6, 0.6, 0.6, 0.6 ; - - fates_allom_amode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_blca_expnt_diff = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - - fates_allom_cmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_d2bl1 = 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, - 0.07, 0.07, 0.07, 0.07, 0.07 ; - - fates_allom_d2bl2 = 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, - 1.3, 1.3, 1.3 ; - - fates_allom_d2bl3 = 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, - 0.55, 0.55, 0.55, 0.55, 0.55 ; - - fates_allom_d2ca_coefficient_max = 0.6568464, 0.6568464, 0.6568464, - 0.6568464, 0.6568464, 0.6568464, 0.6568464, 0.6568464, 0.6568464, - 0.6568464, 0.6568464, 0.6568464, 0.6568464, 0.6568464 ; - - fates_allom_d2ca_coefficient_min = 0.3381119, 0.3381119, 0.3381119, - 0.3381119, 0.3381119, 0.3381119, 0.3381119, 0.3381119, 0.3381119, - 0.3381119, 0.3381119, 0.3381119, 0.3381119, 0.3381119 ; - - fates_allom_d2h1 = 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, 0.64, - 0.64, 0.64, 0.64, 0.64, 0.64 ; - - fates_allom_d2h2 = 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, 0.37, - 0.37, 0.37, 0.37, 0.37, 0.37 ; - - fates_allom_d2h3 = -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, - -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9 ; - - fates_allom_dbh_maxheight = 150, 90, 90, 90, 90, 90, 90, 90, 3, 3, 2, 1.47, - 1.47, 1.47 ; - - fates_allom_fmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_hmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_l2fr = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_la_per_sa_int = 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, - 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0 ; - - fates_allom_la_per_sa_slp = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - - fates_allom_lmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_sai_scaler = 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, - 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ; - - fates_allom_smode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_allom_stmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_branch_turnover = 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0 ; - - fates_prt_nitr_stoich_p1 = - 0.033, 0.029, 0.025, 0.04, 0.033, 0.04, 0.04, 0.04, 0.033, 0.04, 0.04, 0.04, 0.04, 0.04, - 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, - 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, - 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047; - - fates_prt_nitr_stoich_p2 = - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _; - - fates_prt_phos_stoich_p1 = - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _; - - fates_prt_phos_stoich_p2 = - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _; - - fates_prt_alloc_priority = - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _; - - fates_phenflush_fraction = - _, _, _, 0.5, _, 0.5, 0.5, 0.5, _, 0.5, 0.5, 0.5, 0.5, 0.5; - - fates_turnover_retrans_mode = - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1; - - fates_turnover_carb_retrans = - 0.025, 0.025, 0.025, 0.05, 0.025, 0.05, 0.05, 0.05, 0.025, 0.05, 0.05, 0.05, 0.05, 0.05, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00; - - - fates_turnover_nitr_retrans = - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _; - - fates_turnover_phos_retrans = - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _, _, _, _, _, _; - - fates_c2b = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; - - fates_displar = 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, 0.67, - 0.67, 0.67, 0.67, 0.67 ; - - fates_fire_alpha_SH = 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, - 0.2, 0.2, 0.2 ; - - fates_fire_bark_scaler = 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, - 0.07, 0.07, 0.07, 0.07, 0.07, 0.07 ; - - fates_fire_crown_depth_frac = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.95, - 0.95, 0.95, 1, 1, 1 ; - - fates_fire_crown_kill = 0.775, 0.775, 0.775, 0.775, 0.775, 0.775, 0.775, - 0.775, 0.775, 0.775, 0.775, 0.775, 0.775, 0.775 ; - - fates_fr_fcel = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5 ; - - fates_fr_flab = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, - 0.25, 0.25, 0.25, 0.25 ; - - fates_fr_flig = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, - 0.25, 0.25, 0.25, 0.25 ; - - fates_grperc = 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, - 0.11, 0.11, 0.11, 0.11 ; - - fates_hydr_avuln_gs = 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, - 2.5, 2.5, 2.5 ; - - fates_hydr_avuln_node = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; - - fates_hydr_epsil_node = - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ; - - fates_hydr_fcap_node = - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, - 0.08, 0.08, - 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, - 0.08, 0.08, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; - - fates_hydr_kmax_node = - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999 ; - - fates_hydr_p50_gs = -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, - -1.5, -1.5, -1.5, -1.5, -1.5 ; - - fates_hydr_p50_node = - -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, -2.25, - -2.25, -2.25, -2.25, -2.25 ; - - fates_hydr_p_taper = 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, - 0.333, 0.333, 0.333, 0.333, 0.333, 0.333 ; - - fates_hydr_pinot_node = - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999 ; - - fates_hydr_pitlp_node = - -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, - -1.67, -1.67, -1.67, -1.67, - -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, - -1.4, -1.4, - -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, -1.4, - -1.4, -1.4, - -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, - -1.2, -1.2 ; - - fates_hydr_resid_node = - 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, - 0.25, 0.25, - 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, - 0.325, 0.325, 0.325, 0.325, - 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, 0.325, - 0.325, 0.325, 0.325, 0.325, - 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, - 0.15, 0.15 ; - - fates_hydr_rfrac_stem = 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, - 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625 ; - - fates_hydr_rs2 = 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, - 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001 ; - - fates_hydr_srl = 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25 ; - - fates_hydr_thetas_node = - 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, - 0.65, 0.65, - 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, - 0.65, 0.65, - 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65, - 0.65, 0.65, - 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, - 0.75, 0.75 ; - - fates_leaf_BB_slope = 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ; - - fates_leaf_c3psn = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 ; - - fates_leaf_clumping_index = 0.85, 0.85, 0.675, 0.8, 0.85, 0.85, 0.9, 0.75, - 0.85, 0.9, 0.9, 0.75, 0.75, 0.75 ; - - fates_leaf_diameter = 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, - 0.04, 0.04, 0.04, 0.04, 0.04 ; - - fates_leaf_jmaxha = 43540, 43540, 43540, 43540, 43540, 43540, 43540, 43540, - 43540, 43540, 43540, 43540, 43540, 43540 ; - - fates_leaf_jmaxhd = 152040, 152040, 152040, 152040, 152040, 152040, 152040, - 152040, 152040, 152040, 152040, 152040, 152040, 152040 ; - - fates_leaf_jmaxse = 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, - 495, 495, 495 ; - - fates_leaf_long = 0.75, 2, 3.0, 0.5, 0.75, 0.5, 0.5, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.5, - 0.75, 2, 3.0, 0.5, 0.75, 0.5, 0.5, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.5; - - fates_leaf_slamax = 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, - 0.012, 0.03, 0.03, 0.03, 0.03, 0.03 ; - - fates_leaf_slatop = 0.012, 0.01, 0.008, 0.024, 0.012, 0.03, 0.03, 0.03, - 0.012, 0.03, 0.03, 0.03, 0.03, 0.03 ; - - fates_leaf_stor_priority = 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, - 0.8, 0.8, 0.8, 0.8 ; - - fates_leaf_tpuha = 53100, 53100, 53100, 53100, 53100, 53100, 53100, 53100, - 53100, 53100, 53100, 53100, 53100, 53100 ; - - fates_leaf_tpuhd = 150650, 150650, 150650, 150650, 150650, 150650, 150650, - 150650, 150650, 150650, 150650, 150650, 150650, 150650 ; - - fates_leaf_tpuse = 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, - 490, 490, 490 ; - - fates_leaf_vcmax25top = 50, 65, 63, 39, 62, 41, 58, 58, 62, 54, 54, 78, 78, 78, - 50, 65, 63, 39, 62, 41, 58, 58, 62, 54, 54, 78, 78, 78 ; - - fates_leaf_vcmaxha = 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, - 65330, 65330, 65330, 65330, 65330, 65330 ; - - fates_leaf_vcmaxhd = 149250, 149250, 149250, 149250, 149250, 149250, 149250, - 149250, 149250, 149250, 149250, 149250, 149250, 149250 ; - - fates_leaf_vcmaxse = 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - 485, 485, 485 ; - - fates_leaf_xl = 0.1, 0.01, 0.01, 0.01, 0.1, 0.01, 0.25, 0.25, 0.01, 0.25, - 0.25, -0.3, -0.3, -0.3 ; - - fates_lf_fcel = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5 ; - - fates_lf_flab = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, - 0.25, 0.25, 0.25, 0.25 ; - - fates_lf_flig = 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, - 0.25, 0.25, 0.25, 0.25 ; - - fates_maintresp_reduction_curvature = 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, - 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ; - - fates_maintresp_reduction_intercept = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1 ; - - fates_mort_bmort = 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, 0.014, - 0.014, 0.014, 0.014, 0.014, 0.014, 0.014 ; - - fates_mort_freezetol = 2.5, -55, -80, -80, -30, 2.5, -30, -80, -60, -10, - -80, -80, -80, -80 ; - - fates_mort_hf_sm_threshold = 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, - 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06, 1e-06 ; - - fates_mort_hf_flc_threshold = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - - fates_mort_scalar_coldstress = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ; - - fates_mort_scalar_cstarvation = 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, - 0.6, 0.6, 0.6, 0.6, 0.6 ; - - fates_mort_scalar_hydrfailure = 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, - 0.6, 0.6, 0.6, 0.6, 0.6 ; - - fates_pft_used = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - - fates_phen_evergreen = 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 ; - - fates_phen_season_decid = 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 ; - - fates_phen_stress_decid = 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 ; - - fates_prescribed_mortality_canopy = 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, - 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, 0.0194, 0.0194 ; - - fates_prescribed_mortality_understory = 0.025, 0.025, 0.025, 0.025, 0.025, - 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025 ; - - fates_prescribed_npp_canopy = 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, - 0.4, 0.4, 0.4, 0.4, 0.4 ; - - fates_prescribed_npp_understory = 0.03125, 0.03125, 0.03125, 0.03125, - 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, - 0.03125, 0.03125 ; - - fates_prescribed_recruitment = 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, - 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02 ; - - fates_recruit_hgt_min = 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, - 0.75, 0.75, 0.75, 0.75, 0.75, 0.75 ; - - fates_recruit_initd = 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, - 20, 20, 20 ; - - fates_rholnir = 0.45, 0.35, 0.35, 0.35, 0.45, 0.45, 0.45, 0.45, 0.35, 0.45, - 0.45, 0.35, 0.35, 0.35 ; - - fates_rholvis = 0.1, 0.07, 0.07, 0.07, 0.1, 0.1, 0.1, 0.1, 0.07, 0.1, 0.1, - 0.1, 0.1, 0.1 ; - - fates_rhosnir = 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, 0.39, - 0.39, 0.53, 0.53, 0.53 ; - - fates_rhosvis = 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, - 0.16, 0.31, 0.31, 0.31 ; - - fates_senleaf_long_fdrought = 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0 ; - - fates_root_long = 1, 2, 3, 1, 1.5, 1, 1, 1, 1.5, 1, 1, 1, 1, 1 ; - - fates_roota_par = 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 11, 11, 11 ; - - fates_rootb_par = 1, 2, 2, 2, 1, 2, 2, 2, 1.5, 1.5, 1.5, 2, 2, 2 ; - - fates_rootprof_beta = - 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, 0.976, - 0.976, 0.976, 0.976, 0.976, - _, _, _, _, _, _, _, _, _, _, _, _, _, _ ; - - fates_seed_alloc = 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, - 0.1, 0.1, 0.1 ; - - fates_seed_alloc_mature = 0, 0, 0, 0, 0, 0, 0, 0, 0.9, 0.9, 0.9, 0.9, 0.9, - 0.9 ; - - fates_seed_dbh_repro_threshold = 150, 90, 90, 90, 90, 90, 90, 90, 3, 3, 2, - 1.47, 1.47, 1.47 ; - - fates_seed_decay_turnover = 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, 0.51, - 0.51, 0.51, 0.51, 0.51, 0.51, 0.51 ; - - fates_seed_germination_timescale = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - - fates_seed_rain = 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, - 0.28, 0.28, 0.28, 0.28, 0.28 ; - - fates_smpsc = -255000, -255000, -255000, -255000, -255000, -255000, -255000, - -255000, -255000, -255000, -255000, -255000, -255000, -255000 ; - - fates_smpso = -66000, -66000, -66000, -66000, -66000, -66000, -66000, - -66000, -66000, -66000, -66000, -66000, -66000, -66000 ; - - fates_taulnir = 0.25, 0.1, 0.1, 0.1, 0.25, 0.25, 0.25, 0.25, 0.1, 0.25, - 0.25, 0.34, 0.34, 0.34 ; - - fates_taulvis = 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, - 0.05, 0.05, 0.05, 0.05 ; - - fates_tausnir = 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, - 0.001, 0.001, 0.001, 0.25, 0.25, 0.25 ; - - fates_tausvis = 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, - 0.001, 0.001, 0.001, 0.12, 0.12, 0.12 ; - - fates_trim_inc = 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, - 0.03, 0.03, 0.03, 0.03 ; - - fates_trim_limit = 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, - 0.3, 0.3, 0.3 ; - - fates_wood_density = 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, - 0.7, 0.7, 0.7 ; - - fates_woody = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ; - - fates_z0mr = 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, - 0.055, 0.055, 0.055, 0.055, 0.055 ; - - fates_FBD = 4, 15.4, 16.8, 19.6, 999, 4 ; - - fates_low_moisture_Coeff = 1.15, 1.12, 1.09, 0.98, 0.8, 1.15 ; - - fates_low_moisture_Slope = 0.62, 0.62, 0.72, 0.85, 0.8, 0.62 ; - - fates_max_decomp = 1, 0.52, 0.383, 0.383, 0.19, 999 ; - - fates_mid_moisture = 0.8, 0.72, 0.51, 0.38, 1, 0.8 ; - - fates_mid_moisture_Coeff = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - - fates_mid_moisture_Slope = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - - fates_min_moisture = 0.24, 0.18, 0.12, 0, 0, 0.24 ; - - fates_SAV = 66, 13, 3.58, 0.98, 0.2, 66 ; - - fates_CWD_frac = 0.045, 0.075, 0.21, 0.67 ; - - fates_drying_ratio = 13000 ; - - fates_durat_slope = -11.06 ; - - fates_fdi_a = 17.62 ; - - fates_fdi_alpha = 0.00037 ; - - fates_fdi_b = 243.12 ; - - fates_fuel_energy = 18000 ; - - fates_max_durat = 240 ; - - fates_miner_damp = 0.41739 ; - - fates_miner_total = 0.055 ; - - fates_part_dens = 513 ; - - fates_soil_salinity = 0.4; -} diff --git a/parameter_files/fates_params_coastal_veg.cdl b/parameter_files/fates_params_coastal_veg.cdl deleted file mode 100644 index d2bb4c2e3b..0000000000 --- a/parameter_files/fates_params_coastal_veg.cdl +++ /dev/null @@ -1,958 +0,0 @@ -netcdf fates_params.2trop { -dimensions: - fates_NCWD = 4 ; - fates_history_age_bins = 7 ; - fates_history_height_bins = 6 ; - fates_history_size_bins = 13 ; - fates_hydr_organs = 4 ; - fates_litterclass = 6 ; - fates_pft = 2 ; - fates_scalar = 1 ; - fates_string_length = 60 ; - fates_variants = 2 ; -variables: - float fates_history_sizeclass_bin_edges(fates_history_size_bins) ; - fates_history_sizeclass_bin_edges:units = "cm" ; - fates_history_sizeclass_bin_edges:long_name = "Lower edges for DBH size class bins used in size-resolved cohort history output" ; - float fates_history_ageclass_bin_edges(fates_history_age_bins) ; - fates_history_ageclass_bin_edges:units = "yr" ; - fates_history_ageclass_bin_edges:long_name = "Lower edges for age class bins used in age-resolved patch history output" ; - float fates_FBD(fates_litterclass) ; - fates_FBD:units = "NA" ; - fates_FBD:long_name = "spitfire parameter related to fuel bulk density, see SFMain.F90" ; - float fates_SAV(fates_litterclass) ; - fates_SAV:units = "NA" ; - fates_SAV:long_name = "spitfire parameter related to surface area to volume ratio, see SFMain.F90" ; - float fates_history_height_bin_edges(fates_history_height_bins) ; - fates_history_height_bin_edges:units = "m" ; - fates_history_height_bin_edges:long_name = "Lower edges for height bins used in height-resolved history output" ; - float fates_low_moisture_Coeff(fates_litterclass) ; - fates_low_moisture_Coeff:units = "NA" ; - fates_low_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_low_moisture_Slope(fates_litterclass) ; - fates_low_moisture_Slope:units = "NA" ; - fates_low_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_max_decomp(fates_litterclass) ; - fates_max_decomp:units = "kgC/m2/yr ?" ; - fates_max_decomp:long_name = "maximum rate of litter & CWD transfer from non-decomposing class into decomposing class" ; - float fates_mid_moisture(fates_litterclass) ; - fates_mid_moisture:units = "NA" ; - fates_mid_moisture:long_name = "spitfire litter moisture threshold to be considered medium dry" ; - float fates_mid_moisture_Coeff(fates_litterclass) ; - fates_mid_moisture_Coeff:units = "NA" ; - fates_mid_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_mid_moisture_Slope(fates_litterclass) ; - fates_mid_moisture_Slope:units = "NA" ; - fates_mid_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_min_moisture(fates_litterclass) ; - fates_min_moisture:units = "NA" ; - fates_min_moisture:long_name = "spitfire litter moisture threshold to be considered very dry" ; - float fates_hydr_avuln_node(fates_hydr_organs, fates_pft) ; - fates_hydr_avuln_node:units = "unitless" ; - fates_hydr_avuln_node:long_name = "xylem vulnerability curve shape parameter" ; - float fates_hydr_epsil_node(fates_hydr_organs, fates_pft) ; - fates_hydr_epsil_node:units = "MPa" ; - fates_hydr_epsil_node:long_name = "bulk elastic modulus" ; - float fates_hydr_fcap_node(fates_hydr_organs, fates_pft) ; - fates_hydr_fcap_node:units = "unitless" ; - fates_hydr_fcap_node:long_name = "fraction of (1-resid_node) that is capillary in source" ; - float fates_hydr_kmax_node(fates_hydr_organs, fates_pft) ; - fates_hydr_kmax_node:units = "kgMPa/m/s" ; - fates_hydr_kmax_node:long_name = "maximum xylem conductivity per unit conducting xylem area" ; - float fates_hydr_p50_node(fates_hydr_organs, fates_pft) ; - fates_hydr_p50_node:units = "MPa" ; - fates_hydr_p50_node:long_name = "xylem water potential at 50% loss of conductivity" ; - float fates_hydr_pinot_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pinot_node:units = "MPa" ; - fates_hydr_pinot_node:long_name = "osmotic potential at full turgor" ; - float fates_hydr_pitlp_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pitlp_node:units = "MPa" ; - fates_hydr_pitlp_node:long_name = "turgor loss point" ; - float fates_hydr_resid_node(fates_hydr_organs, fates_pft) ; - fates_hydr_resid_node:units = "fraction" ; - fates_hydr_resid_node:long_name = "residual fraction" ; - float fates_hydr_thetas_node(fates_hydr_organs, fates_pft) ; - fates_hydr_thetas_node:units = "cm3/cm3" ; - fates_hydr_thetas_node:long_name = "saturated water content" ; - float fates_CWD_frac(fates_NCWD) ; - fates_CWD_frac:units = "fraction" ; - fates_CWD_frac:long_name = "fraction of woody (bdead+bsw) biomass destined for CWD pool" ; - char fates_pftname(fates_pft, fates_string_length) ; - fates_pftname:units = "unitless - string" ; - fates_pftname:long_name = "Description of plant type" ; - float fates_rootprof_beta(fates_variants, fates_pft) ; - fates_rootprof_beta:units = "unitless" ; - fates_rootprof_beta:long_name = "Rooting beta parameter, for C and N vertical discretization (NOT USED BY DEFAULT)" ; - float fates_alloc_storage_cushion(fates_pft) ; - fates_alloc_storage_cushion:units = "fraction" ; - fates_alloc_storage_cushion:long_name = "maximum size of storage C pool, relative to maximum size of leaf C pool" ; - float fates_allom_agb1(fates_pft) ; - fates_allom_agb1:units = "variable" ; - fates_allom_agb1:long_name = "Parameter 1 for agb allometry" ; - float fates_allom_agb2(fates_pft) ; - fates_allom_agb2:units = "variable" ; - fates_allom_agb2:long_name = "Parameter 2 for agb allometry" ; - float fates_allom_agb3(fates_pft) ; - fates_allom_agb3:units = "variable" ; - fates_allom_agb3:long_name = "Parameter 3 for agb allometry" ; - float fates_allom_agb4(fates_pft) ; - fates_allom_agb4:units = "variable" ; - fates_allom_agb4:long_name = "Parameter 4 for agb allometry" ; - float fates_allom_agb_frac(fates_pft) ; - fates_allom_agb_frac:units = "fraction" ; - fates_allom_agb_frac:long_name = "Fraction of woody biomass that is above ground" ; - float fates_allom_amode(fates_pft) ; - fates_allom_amode:units = "index" ; - fates_allom_amode:long_name = "AGB allometry function index" ; - float fates_allom_blca_expnt_diff(fates_pft) ; - fates_allom_blca_expnt_diff:units = "unitless" ; - fates_allom_blca_expnt_diff:long_name = "difference between allometric DBH:bleaf and DBH:crown area exponents" ; - float fates_allom_cmode(fates_pft) ; - fates_allom_cmode:units = "index" ; - fates_allom_cmode:long_name = "coarse root biomass allometry function index" ; - float fates_allom_d2bl1(fates_pft) ; - fates_allom_d2bl1:units = "variable" ; - fates_allom_d2bl1:long_name = "Parameter 1 for d2bl allometry (intercept)" ; - float fates_allom_d2bl2(fates_pft) ; - fates_allom_d2bl2:units = "variable" ; - fates_allom_d2bl2:long_name = "Parameter 2 for d2bl allometry (slope)" ; - float fates_allom_d2bl3(fates_pft) ; - fates_allom_d2bl3:units = "unitless" ; - fates_allom_d2bl3:long_name = "Parameter 3 for d2bl allometry (optional)" ; - float fates_allom_d2ca_coefficient_max(fates_pft) ; - fates_allom_d2ca_coefficient_max:units = "m2 cm^(-1/beta)" ; - fates_allom_d2ca_coefficient_max:long_name = "max (savanna) dbh to area multiplier factor where: area = n*d2ca_coeff*dbh^beta" ; - float fates_allom_d2ca_coefficient_min(fates_pft) ; - fates_allom_d2ca_coefficient_min:units = "m2 cm^(-1/beta)" ; - fates_allom_d2ca_coefficient_min:long_name = "min (forest) dbh to area multiplier factor where: area = n*d2ca_coeff*dbh^beta" ; - float fates_allom_d2h1(fates_pft) ; - fates_allom_d2h1:units = "variable" ; - fates_allom_d2h1:long_name = "Parameter 1 for d2h allometry (intercept, or c)" ; - float fates_allom_d2h2(fates_pft) ; - fates_allom_d2h2:units = "variable" ; - fates_allom_d2h2:long_name = "Parameter 2 for d2h allometry (slope, or m)" ; - float fates_allom_d2h3(fates_pft) ; - fates_allom_d2h3:units = "variable" ; - fates_allom_d2h3:long_name = "Parameter 3 for d2h allometry (optional)" ; - float fates_allom_dbh_maxheight(fates_pft) ; - fates_allom_dbh_maxheight:units = "cm" ; - fates_allom_dbh_maxheight:long_name = "the diameter (if any) corresponding to maximum height, diameters may increase beyond this" ; - float fates_allom_fmode(fates_pft) ; - fates_allom_fmode:units = "index" ; - fates_allom_fmode:long_name = "fine root biomass allometry function index" ; - float fates_allom_hmode(fates_pft) ; - fates_allom_hmode:units = "index" ; - fates_allom_hmode:long_name = "height allometry function index" ; - float fates_allom_l2fr(fates_pft) ; - fates_allom_l2fr:units = "gC/gC" ; - fates_allom_l2fr:long_name = "Allocation parameter: fine root C per leaf C" ; - float fates_allom_latosa_int(fates_pft) ; - fates_allom_latosa_int:units = "ratio" ; - fates_allom_latosa_int:long_name = "Leaf area to sap area ratio, intercept [m2/cm2]" ; - float fates_allom_latosa_slp(fates_pft) ; - fates_allom_latosa_slp:units = "unitless" ; - fates_allom_latosa_slp:long_name = "Leaf area to sap area ratio, slope (optional)" ; - float fates_allom_lmode(fates_pft) ; - fates_allom_lmode:units = "index" ; - fates_allom_lmode:long_name = "leaf biomass allometry function index" ; - float fates_allom_sai_scaler(fates_pft) ; - fates_allom_sai_scaler:units = "m2/gC" ; - fates_allom_sai_scaler:long_name = "allometric ratio of SAI to target bleaf" ; - float fates_allom_smode(fates_pft) ; - fates_allom_smode:units = "index" ; - fates_allom_smode:long_name = "sapwood allometry function index" ; - float fates_allom_stmode(fates_pft) ; - fates_allom_stmode:units = "index" ; - fates_allom_stmode:long_name = "storage allometry function index" ; - float fates_allom_frbstor_repro(fates_pft) ; - fates_allom_frbstor_repro:units = "fraction" ; - fates_allom_frbstor_repro:long_name = "fraction of bstore goes to reproduction after plant dies" ; - float fates_branch_turnover(fates_pft) ; - fates_branch_turnover:units = "yr-1" ; - fates_branch_turnover:long_name = "turnover time of branches" ; - float fates_c2b(fates_pft) ; - fates_c2b:units = "ratio" ; - fates_c2b:long_name = "Carbon to biomass multiplier of bulk structural tissues" ; - float fates_displar(fates_pft) ; - fates_displar:units = "unitless" ; - fates_displar:long_name = "Ratio of displacement height to canopy top height" ; - float fates_fire_alpha_SH(fates_pft) ; - fates_fire_alpha_SH:units = "NA" ; - fates_fire_alpha_SH:long_name = "spitfire parameter, alpha scorch height, Equation 16 Thonicke et al 2010" ; - float fates_fire_bark_scaler(fates_pft) ; - fates_fire_bark_scaler:units = "fraction" ; - fates_fire_bark_scaler:long_name = "the thickness of a cohorts bark as a fraction of its dbh" ; - float fates_fire_crown_depth_frac(fates_pft) ; - fates_fire_crown_depth_frac:units = "fraction" ; - fates_fire_crown_depth_frac:long_name = "the depth of a cohorts crown as a fraction of its height" ; - float fates_fire_crown_kill(fates_pft) ; - fates_fire_crown_kill:units = "NA" ; - fates_fire_crown_kill:long_name = "fire parameter, see equation 22 in Thonicke et al 2010" ; - float fates_fr_fcel(fates_pft) ; - fates_fr_fcel:units = "fraction" ; - fates_fr_fcel:long_name = "Fine root litter cellulose fraction" ; - float fates_fr_flab(fates_pft) ; - fates_fr_flab:units = "fraction" ; - fates_fr_flab:long_name = "Fine root litter labile fraction" ; - float fates_fr_flig(fates_pft) ; - fates_fr_flig:units = "fraction" ; - fates_fr_flig:long_name = "Fine root litter lignin fraction" ; - float fates_froot_cn_ratio(fates_pft) ; - fates_froot_cn_ratio:units = "gC/gN" ; - fates_froot_cn_ratio:long_name = "Fine root C:N" ; - float fates_grperc(fates_pft) ; - fates_grperc:units = "unitless" ; - fates_grperc:long_name = "Growth respiration factor" ; - float fates_hydr_avuln_gs(fates_pft) ; - fates_hydr_avuln_gs:units = "unitless" ; - fates_hydr_avuln_gs:long_name = "shape parameter for stomatal control of water vapor exiting leaf" ; - float fates_hydr_p50_gs(fates_pft) ; - fates_hydr_p50_gs:units = "MPa" ; - fates_hydr_p50_gs:long_name = "water potential at 50% loss of stomatal conductance" ; - float fates_hydr_p_taper(fates_pft) ; - fates_hydr_p_taper:units = "unitless" ; - fates_hydr_p_taper:long_name = "xylem taper exponent" ; - float fates_hydr_rfrac_stem(fates_pft) ; - fates_hydr_rfrac_stem:units = "fraction" ; - fates_hydr_rfrac_stem:long_name = "fraction of total tree resistance from troot to canopy" ; - float fates_hydr_rs2(fates_pft) ; - fates_hydr_rs2:units = "mm" ; - fates_hydr_rs2:long_name = "absorbing root radius" ; - float fates_hydr_srl(fates_pft) ; - fates_hydr_srl:units = "m g-1" ; - fates_hydr_srl:long_name = "specific root length" ; - float fates_leaf_BB_slope(fates_pft) ; - fates_leaf_BB_slope:units = "unitless" ; - fates_leaf_BB_slope:long_name = "stomatal slope parameter, as per Ball-Berry" ; - float fates_leaf_c3psn(fates_pft) ; - fates_leaf_c3psn:units = "flag" ; - fates_leaf_c3psn:long_name = "Photosynthetic pathway (1=c3, 0=c4)" ; - float fates_leaf_clumping_index(fates_pft) ; - fates_leaf_clumping_index:units = "fraction (0-1)" ; - fates_leaf_clumping_index:long_name = "factor describing how much self-occlusion of leaf scattering elements decreases light interception" ; - float fates_leaf_cn_ratio(fates_pft) ; - fates_leaf_cn_ratio:units = "gC/gN" ; - fates_leaf_cn_ratio:long_name = "Leaf C:N" ; - float fates_leaf_diameter(fates_pft) ; - fates_leaf_diameter:units = "m" ; - fates_leaf_diameter:long_name = "Characteristic leaf dimension" ; - float fates_leaf_jmaxha(fates_pft) ; - fates_leaf_jmaxha:units = "J/mol" ; - fates_leaf_jmaxha:long_name = "activation energy for jmax" ; - float fates_leaf_jmaxhd(fates_pft) ; - fates_leaf_jmaxhd:units = "J/mol" ; - fates_leaf_jmaxhd:long_name = "deactivation energy for jmax" ; - float fates_leaf_jmaxse(fates_pft) ; - fates_leaf_jmaxse:units = "J/mol/K" ; - fates_leaf_jmaxse:long_name = "entropy term for jmax" ; - float fates_leaf_long(fates_pft) ; - fates_leaf_long:units = "yr" ; - fates_leaf_long:long_name = "Leaf longevity (ie turnover timescale)" ; - float fates_leaf_slatop(fates_pft) ; - fates_leaf_slatop:units = "m^2/gC" ; - fates_leaf_slatop:long_name = "Specific Leaf Area (SLA) at top of canopy, projected area basis" ; - float fates_leaf_stor_priority(fates_pft) ; - fates_leaf_stor_priority:units = "unitless" ; - fates_leaf_stor_priority:long_name = "factor governing priority of replacing storage with NPP" ; - float fates_leaf_tpuha(fates_pft) ; - fates_leaf_tpuha:units = "J/mol" ; - fates_leaf_tpuha:long_name = "activation energy for tpu" ; - float fates_leaf_tpuhd(fates_pft) ; - fates_leaf_tpuhd:units = "J/mol" ; - fates_leaf_tpuhd:long_name = "deactivation energy for tpu" ; - float fates_leaf_tpuse(fates_pft) ; - fates_leaf_tpuse:units = "J/mol/K" ; - fates_leaf_tpuse:long_name = "entropy term for tpu" ; - float fates_leaf_vcmax25top(fates_pft) ; - fates_leaf_vcmax25top:units = "umol CO2/m^2/s" ; - fates_leaf_vcmax25top:long_name = "maximum carboxylation rate of Rub. at 25C, canopy top" ; - float fates_leaf_vcmaxha(fates_pft) ; - fates_leaf_vcmaxha:units = "J/mol" ; - fates_leaf_vcmaxha:long_name = "activation energy for vcmax" ; - float fates_leaf_vcmaxhd(fates_pft) ; - fates_leaf_vcmaxhd:units = "J/mol" ; - fates_leaf_vcmaxhd:long_name = "deactivation energy for vcmax" ; - float fates_leaf_vcmaxse(fates_pft) ; - fates_leaf_vcmaxse:units = "J/mol/K" ; - fates_leaf_vcmaxse:long_name = "entropy term for vcmax" ; - float fates_leaf_xl(fates_pft) ; - fates_leaf_xl:units = "unitless" ; - fates_leaf_xl:long_name = "Leaf/stem orientation index" ; - float fates_lf_fcel(fates_pft) ; - fates_lf_fcel:units = "fraction" ; - fates_lf_fcel:long_name = "Leaf litter cellulose fraction" ; - float fates_lf_flab(fates_pft) ; - fates_lf_flab:units = "fraction" ; - fates_lf_flab:long_name = "Leaf litter labile fraction" ; - float fates_lf_flig(fates_pft) ; - fates_lf_flig:units = "fraction" ; - fates_lf_flig:long_name = "Leaf litter lignin fraction" ; - float fates_maintresp_reduction_curvature(fates_pft) ; - fates_maintresp_reduction_curvature:units = "unitless (0-1)" ; - fates_maintresp_reduction_curvature:long_name = "curvature of MR reduction as f(carbon storage), 1=linear, 0=very curved" ; - float fates_maintresp_reduction_intercept(fates_pft) ; - fates_maintresp_reduction_intercept:units = "unitless (0-1)" ; - fates_maintresp_reduction_intercept:long_name = "intercept of MR reduction as f(carbon storage), 0=no throttling, 1=max throttling" ; - float fates_mort_bmort(fates_pft) ; - fates_mort_bmort:units = "1/yr" ; - fates_mort_bmort:long_name = "background mortality rate" ; - float fates_mort_freezetol(fates_pft) ; - fates_mort_freezetol:units = "NA" ; - fates_mort_freezetol:long_name = "minimum temperature tolerance (NOT USED)" ; - float fates_mort_hf_sm_threshold(fates_pft) ; - fates_mort_hf_sm_threshold:units = "unitless" ; - fates_mort_hf_sm_threshold:long_name = "soil moisture (btran units) at which drought mortality begins for non-hydraulic model" ; - float fates_mort_scalar_coldstress(fates_pft) ; - fates_mort_scalar_coldstress:units = "1/yr" ; - fates_mort_scalar_coldstress:long_name = "maximum mortality rate from cold stress" ; - float fates_mort_scalar_cstarvation(fates_pft) ; - fates_mort_scalar_cstarvation:units = "1/yr" ; - fates_mort_scalar_cstarvation:long_name = "maximum mortality rate from carbon starvation" ; - float fates_mort_scalar_hydrfailure(fates_pft) ; - fates_mort_scalar_hydrfailure:units = "1/yr" ; - fates_mort_scalar_hydrfailure:long_name = "maximum mortality rate from hydraulic failure" ; - float fates_pft_used(fates_pft) ; - fates_pft_used:units = "0 = off (dont use), 1 = on (use)" ; - fates_pft_used:long_name = "Switch to turn on and off PFTs (also see fates_initd for cold-start)" ; - float fates_phen_evergreen(fates_pft) ; - fates_phen_evergreen:units = "logical flag" ; - fates_phen_evergreen:long_name = "Binary flag for evergreen leaf habit" ; - float fates_phen_season_decid(fates_pft) ; - fates_phen_season_decid:units = "logical flag" ; - fates_phen_season_decid:long_name = "Binary flag for seasonal-deciduous leaf habit" ; - float fates_phen_stress_decid(fates_pft) ; - fates_phen_stress_decid:units = "logical flag" ; - fates_phen_stress_decid:long_name = "Binary flag for stress-deciduous leaf habit" ; - float fates_prescribed_mortality_canopy(fates_pft) ; - fates_prescribed_mortality_canopy:units = "1/yr" ; - fates_prescribed_mortality_canopy:long_name = "mortality rate of canopy trees for prescribed physiology mode" ; - float fates_prescribed_mortality_understory(fates_pft) ; - fates_prescribed_mortality_understory:units = "1/yr" ; - fates_prescribed_mortality_understory:long_name = "mortality rate of understory trees for prescribed physiology mode" ; - float fates_prescribed_npp_canopy(fates_pft) ; - fates_prescribed_npp_canopy:units = "gC / m^2 / yr" ; - fates_prescribed_npp_canopy:long_name = "NPP per unit crown area of canopy trees for prescribed physiology mode" ; - float fates_prescribed_npp_understory(fates_pft) ; - fates_prescribed_npp_understory:units = "gC / m^2 / yr" ; - fates_prescribed_npp_understory:long_name = "NPP per unit crown area of understory trees for prescribed physiology mode" ; - float fates_prescribed_recruitment(fates_pft) ; - fates_prescribed_recruitment:units = "n/yr" ; - fates_prescribed_recruitment:long_name = "recruitment rate for prescribed physiology mode" ; - float fates_recruit_hgt_min(fates_pft) ; - fates_recruit_hgt_min:units = "m" ; - fates_recruit_hgt_min:long_name = "the minimum height (ie starting height) of a newly recruited plant" ; - float fates_recruit_initd(fates_pft) ; - fates_recruit_initd:units = "stems/m2" ; - fates_recruit_initd:long_name = "initial seedling density for a cold-start near-bare-ground simulation" ; - float fates_rholnir(fates_pft) ; - fates_rholnir:units = "fraction" ; - fates_rholnir:long_name = "Leaf reflectance: near-IR" ; - float fates_rholvis(fates_pft) ; - fates_rholvis:units = "fraction" ; - fates_rholvis:long_name = "Leaf reflectance: visible" ; - float fates_rhosnir(fates_pft) ; - fates_rhosnir:units = "fraction" ; - fates_rhosnir:long_name = "Stem reflectance: near-IR" ; - float fates_rhosvis(fates_pft) ; - fates_rhosvis:units = "fraction" ; - fates_rhosvis:long_name = "Stem reflectance: visible" ; - float fates_root_long(fates_pft) ; - fates_root_long:units = "yr" ; - fates_root_long:long_name = "root longevity (alternatively, turnover time)" ; - float fates_roota_par(fates_pft) ; - fates_roota_par:units = "1/m" ; - fates_roota_par:long_name = "CLM rooting distribution parameter" ; - float fates_rootb_par(fates_pft) ; - fates_rootb_par:units = "1/m" ; - fates_rootb_par:long_name = "CLM rooting distribution parameter" ; - float fates_seed_alloc(fates_pft) ; - fates_seed_alloc:units = "fraction" ; - fates_seed_alloc:long_name = "fraction of available carbon balance allocated to seeds" ; - float fates_seed_alloc_mature(fates_pft) ; - fates_seed_alloc_mature:units = "fraction" ; - fates_seed_alloc_mature:long_name = "fraction of available carbon balance allocated to seeds in mature plants (adds to fates_seed_alloc)" ; - float fates_seed_dbh_repro_threshold(fates_pft) ; - fates_seed_dbh_repro_threshold:units = "cm" ; - fates_seed_dbh_repro_threshold:long_name = "the diameter (if any) where the plant will start extra clonal allocation to the seed pool (NOT USED YET)" ; - float fates_seed_decay_turnover(fates_pft) ; - fates_seed_decay_turnover:units = "1/yr" ; - fates_seed_decay_turnover:long_name = "turnover time for seeds with respect to germination" ; - float fates_seed_germination_timescale(fates_pft) ; - fates_seed_germination_timescale:units = "1/yr" ; - fates_seed_germination_timescale:long_name = "turnover time for seeds with respect to decay" ; - float fates_seed_rain(fates_pft) ; - fates_seed_rain:units = "KgC/m2/yr" ; - fates_seed_rain:long_name = "External seed rain from outside site (non-mass conserving)" ; - float fates_smpsc(fates_pft) ; - fates_smpsc:units = "mm" ; - fates_smpsc:long_name = "Soil water potential at full stomatal closure" ; - float fates_smpso(fates_pft) ; - fates_smpso:units = "mm" ; - fates_smpso:long_name = "Soil water potential at full stomatal opening" ; - float fates_taulnir(fates_pft) ; - fates_taulnir:units = "fraction" ; - fates_taulnir:long_name = "Leaf transmittance: near-IR" ; - float fates_taulvis(fates_pft) ; - fates_taulvis:units = "fraction" ; - fates_taulvis:long_name = "Leaf transmittance: visible" ; - float fates_tausnir(fates_pft) ; - fates_tausnir:units = "fraction" ; - fates_tausnir:long_name = "Stem transmittance: near-IR" ; - float fates_tausvis(fates_pft) ; - fates_tausvis:units = "fraction" ; - fates_tausvis:long_name = "Stem transmittance: visible" ; - float fates_trim_inc(fates_pft) ; - fates_trim_inc:units = "m2/m2" ; - fates_trim_inc:long_name = "Arbitrary incremental change in trimming function." ; - float fates_trim_limit(fates_pft) ; - fates_trim_limit:units = "m2/m2" ; - fates_trim_limit:long_name = "Arbitrary limit to reductions in leaf area with stress" ; - float fates_wood_density(fates_pft) ; - fates_wood_density:units = "g/cm3" ; - fates_wood_density:long_name = "mean density of woody tissue in plant" ; - float fates_woody(fates_pft) ; - fates_woody:units = "logical flag" ; - fates_woody:long_name = "Binary woody lifeform flag" ; - float fates_z0mr(fates_pft) ; - fates_z0mr:units = "unitless" ; - fates_z0mr:long_name = "Ratio of momentum roughness length to canopy top height" ; - float fates_base_mr_20(fates_scalar) ; - fates_base_mr_20:units = "gC/gN/s" ; - fates_base_mr_20:long_name = "Base maintenance respiration rate for plant tissues, using Ryan 1991" ; - float fates_bbopt_c3(fates_scalar) ; - fates_bbopt_c3:units = "umol H2O/m**2/s" ; - fates_bbopt_c3:long_name = "Ball-Berry minimum unstressed leaf conductance for C3" ; - float fates_bbopt_c4(fates_scalar) ; - fates_bbopt_c4:units = "umol H2O/m**2/s" ; - fates_bbopt_c4:long_name = "Ball-Berry minimum unstressed leaf conductance for C4" ; - float fates_canopy_closure_thresh(fates_scalar) ; - fates_canopy_closure_thresh:units = "unitless" ; - fates_canopy_closure_thresh:long_name = "tree canopy coverage at which crown area allometry changes from savanna to forest value" ; - float fates_cohort_fusion_tol(fates_scalar) ; - fates_cohort_fusion_tol:units = "unitless" ; - fates_cohort_fusion_tol:long_name = "minimum fraction in difference in dbh between cohorts" ; - float fates_comp_excln(fates_scalar) ; - fates_comp_excln:units = "none" ; - fates_comp_excln:long_name = "weighting factor (exponent on dbh) for canopy layer exclusion and promotion" ; - float fates_cwd_fcel(fates_scalar) ; - fates_cwd_fcel:units = "unitless" ; - fates_cwd_fcel:long_name = "Cellulose fraction for CWD" ; - float fates_cwd_flig(fates_scalar) ; - fates_cwd_flig:units = "unitless" ; - fates_cwd_flig:long_name = "Lignin fraction of coarse woody debris" ; - float fates_fire_nignitions(fates_scalar) ; - fates_fire_nignitions:units = "/m2 (?)" ; - fates_fire_nignitions:long_name = "number of daily ignitions (nfires = nignitions*FDI*area_scaling)" ; - float fates_hydr_kmax_rsurf(fates_scalar) ; - fates_hydr_kmax_rsurf:units = "kg water/m2 root area/Mpa/s" ; - fates_hydr_kmax_rsurf:long_name = "maximum conducitivity for unit root surface" ; - float fates_hydr_psi0(fates_scalar) ; - fates_hydr_psi0:units = "MPa" ; - fates_hydr_psi0:long_name = "sapwood water potential at saturation" ; - float fates_hydr_psicap(fates_scalar) ; - fates_hydr_psicap:units = "MPa" ; - fates_hydr_psicap:long_name = "sapwood water potential at which capillary reserves exhausted" ; - float fates_init_litter(fates_scalar) ; - fates_init_litter:units = "NA" ; - fates_init_litter:long_name = "Initialization value for litter pool in cold-start (NOT USED)" ; - float fates_logging_coll_under_frac(fates_scalar) ; - fates_logging_coll_under_frac:units = "fraction" ; - fates_logging_coll_under_frac:long_name = "Fraction of stems killed in the understory when logging generates disturbance" ; - float fates_logging_collateral_frac(fates_scalar) ; - fates_logging_collateral_frac:units = "fraction" ; - fates_logging_collateral_frac:long_name = "Fraction of large stems in upperstory that die from logging collateral damage" ; - float fates_logging_dbhmax_infra(fates_scalar) ; - fates_logging_dbhmax_infra:units = "cm" ; - fates_logging_dbhmax_infra:long_name = "Tree diameter, above which infrastructure from logging does not impact damage or mortality." ; - float fates_logging_dbhmin(fates_scalar) ; - fates_logging_dbhmin:units = "cm" ; - fates_logging_dbhmin:long_name = "Minimum dbh at which logging is applied" ; - float fates_logging_direct_frac(fates_scalar) ; - fates_logging_direct_frac:units = "fraction" ; - fates_logging_direct_frac:long_name = "Fraction of stems logged directly per event" ; - float fates_logging_event_code(fates_scalar) ; - fates_logging_event_code:units = "unitless" ; - fates_logging_event_code:long_name = "Integer code that options how logging events are structured" ; - float fates_logging_mechanical_frac(fates_scalar) ; - fates_logging_mechanical_frac:units = "fraction" ; - fates_logging_mechanical_frac:long_name = "Fraction of stems killed due infrastructure an other mechanical means" ; - float fates_mort_disturb_frac(fates_scalar) ; - fates_mort_disturb_frac:units = "fraction" ; - fates_mort_disturb_frac:long_name = "fraction of canopy mortality that results in disturbance (i.e. transfer of area from new to old patch)" ; - float fates_mort_understorey_death(fates_scalar) ; - fates_mort_understorey_death:units = "fraction" ; - fates_mort_understorey_death:long_name = "fraction of plants in understorey cohort impacted by overstorey tree-fall" ; - float fates_patch_fusion_tol(fates_scalar) ; - fates_patch_fusion_tol:units = "unitless" ; - fates_patch_fusion_tol:long_name = "minimum fraction in difference in profiles between patches" ; - float fates_phen_a(fates_scalar) ; - fates_phen_a:units = "none" ; - fates_phen_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_b(fates_scalar) ; - fates_phen_b:units = "none" ; - fates_phen_b:long_name = "GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_c(fates_scalar) ; - fates_phen_c:units = "none" ; - fates_phen_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_chiltemp(fates_scalar) ; - fates_phen_chiltemp:units = "degrees C" ; - fates_phen_chiltemp:long_name = "chilling day counting threshold" ; - float fates_phen_coldtemp(fates_scalar) ; - fates_phen_coldtemp:units = "degrees C" ; - fates_phen_coldtemp:long_name = "temperature exceedance to flag a cold-day for temperature leaf drop" ; - float fates_phen_doff_time(fates_scalar) ; - fates_phen_doff_time:units = "days" ; - fates_phen_doff_time:long_name = "day threshold compared against days since leaves became off-allometry" ; - float fates_phen_drought_threshold(fates_scalar) ; - fates_phen_drought_threshold:units = "m3/m3" ; - fates_phen_drought_threshold:long_name = "liquid volume in soil layer, threashold for drought phenology" ; - float fates_phen_mindayson(fates_scalar) ; - fates_phen_mindayson:units = "days" ; - fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; - float fates_phen_ncolddayslim(fates_scalar) ; - fates_phen_ncolddayslim:units = "days" ; - fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; - float fates_drying_ratio ; - fates_drying_ratio:units = "NA" ; - fates_drying_ratio:long_name = "spitfire parameter, fire drying ratio for fuel moisture, alpha_FMC EQ 6 Thonicke et al 2010" ; - float fates_durat_slope ; - fates_durat_slope:units = "NA" ; - fates_durat_slope:long_name = "spitfire parameter, fire max duration slope, Equation 14 Thonicke et al 2010" ; - float fates_fdi_a ; - fates_fdi_a:units = "NA" ; - fates_fdi_a:long_name = "spitfire parameter (unknown) " ; - float fates_fdi_alpha ; - fates_fdi_alpha:units = "NA" ; - fates_fdi_alpha:long_name = "spitfire parameter, EQ 7 Venevsky et al. GCB 2002,(modified EQ 8 Thonicke et al. 2010) " ; - float fates_fdi_b ; - fates_fdi_b:units = "NA" ; - fates_fdi_b:long_name = "spitfire parameter (unknown) " ; - float fates_fuel_energy ; - fates_fuel_energy:units = "kJ/kg" ; - fates_fuel_energy:long_name = "pitfire parameter, heat content of fuel" ; - float fates_max_durat ; - fates_max_durat:units = "minutes" ; - fates_max_durat:long_name = "spitfire parameter, fire maximum duration, Equation 14 Thonicke et al 2010" ; - float fates_miner_damp ; - fates_miner_damp:units = "NA" ; - fates_miner_damp:long_name = "spitfire parameter, mineral-dampening coefficient EQ A1 Thonicke et al 2010 " ; - float fates_miner_total ; - fates_miner_total:units = "fraction" ; - fates_miner_total:long_name = "spitfire parameter, total mineral content, Table A1 Thonicke et al 2010" ; - float fates_part_dens ; - fates_part_dens:units = "kg/m2" ; - fates_part_dens:long_name = "spitfire parameter, oven dry particle density, Table A1 Thonicke et al 2010" ; - float fates_soil_salinity(fates_scalar) ; - fates_soil_salinity:units = "ppt" ; - fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; - -// global attributes: - :history = "This file was made from FatesPFTIndexSwapper.py \n", - " Input File = fates_params_13pfts.c180315.nc \n", - " Indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13] \n", - " Wed Feb 28 13:43:44 PST 2018 Values from Jennifer Holms 13pft test file fates_params.c170929_13pfts.nc were then manually converted over into positions 2-13, position 1 kept the tropical broadleaf evergreen. Wed Mar 7 15:53:33 PST 2018 (RGK) added fates_logging_dbhmax_infra, fates_maintresp_reduction_curvature, fates_maintresp_reduction_intercept, and fates_leaf_clumping_index. CHanged fates_clone_alloc to fates_seed_alloc_mature. Updated minimum grass sizes per J Shuman notes. Set grass AGB intercepts and latosa to zero. Updated clumping to have more substanteated starter values per suggestions by Shawn Serbin.\n", - " Thu Mar 15 13:48:11 PDT 2018 Added C4 plants via suggestions by @huitang_earth.\n", - " Mon Mar 19 19:05:44 EDT 2018 forced all plants to be evergreen till carbon-imbalances are fixed.\n", - " Mon Mar 19 19:05:44 EDT 2018 added entry for fates_history_height_bin_edges.\n", - " Thu Apr 12 14:18:46 PDT 2018 updated names on CN recruitment parameters. -- fates_params_14pft.c180412.nc -- \n", - " This file was made then modified wih FatesPFTIndexSwapper.py to reduce to 2 tropical pfts again. \n", - " Indices = [1, 1]" ; -data: - - fates_history_sizeclass_bin_edges = 0, 0.05, 0.1, 0.15, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, - 0.80, 0.90, 1.0 ; - - fates_history_ageclass_bin_edges = 0, 1, 2, 5, 10, 20, 50 ; - - fates_FBD = 4, 15.4, 16.8, 19.6, 999, 4 ; - - fates_SAV = 66, 13, 3.58, 0.98, 0.2, 66 ; - - fates_history_height_bin_edges = 0, 0.1, 0.3, 0.5, 1, 2 ; - - fates_low_moisture_Coeff = 1.15, 1.12, 1.09, 0.98, 0.8, 1.15 ; - - fates_low_moisture_Slope = 0.62, 0.62, 0.72, 0.85, 0.8, 0.62 ; - - fates_max_decomp = 1, 0.52, 0.383, 0.383, 0.19, 999 ; - - fates_mid_moisture = 0.8, 0.72, 0.51, 0.38, 1, 0.8 ; - - fates_mid_moisture_Coeff = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - - fates_mid_moisture_Slope = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - - fates_min_moisture = 0.24, 0.18, 0.12, 0, 0, 0.24 ; - - fates_hydr_avuln_node = - 2, 2, - 2, 2, - 2, 2, - 2, 2 ; - - fates_hydr_epsil_node = - 12, 12, - 10, 10, - 10, 10, - 8, 8 ; - - fates_hydr_fcap_node = - 0, 0, - 0.08, 0.08, - 0.08, 0.08, - 0, 0 ; - - fates_hydr_kmax_node = - -999, -999, - 3, 3, - -999, -999, - -999, -999 ; - - fates_hydr_p50_node = - -2.25, -2.25, - -2.25, -2.25, - -2.25, -2.25, - -2.25, -2.25 ; - - fates_hydr_pinot_node = - -999, -999, - -999, -999, - -999, -999, - -999, -999 ; - - fates_hydr_pitlp_node = - -1.67, -1.67, - -1.4, -1.4, - -1.4, -1.4, - -1.2, -1.2 ; - - fates_hydr_resid_node = - 0.25, 0.25, - 0.325, 0.325, - 0.325, 0.325, - 0.15, 0.15 ; - - fates_hydr_thetas_node = - 0.65, 0.65, - 0.65, 0.65, - 0.65, 0.65, - 0.75, 0.75 ; - - fates_CWD_frac = 0.045, 0.075, 0.21, 0.67 ; - - fates_pftname = - "Spartina alterniflora (short form) ", - "Spartina alterniflora (tall form) " ; - - fates_rootprof_beta = - 0.976, 0.976, - _, _ ; - - fates_alloc_storage_cushion = 5.25, 3.75 ; - - fates_allom_agb1 = 0.001928, 0.001928; - - fates_allom_agb2 = 1.9492, 1.9492 ; - - fates_allom_agb3 = 0.0, 0.0 ; - - fates_allom_agb4 = 0.0, 0.0 ; - - fates_allom_agb_frac = 1.0, 1.0 ; - - fates_allom_amode = 1, 1; - - fates_allom_blca_expnt_diff = 0, 0 ; - - fates_allom_cmode = 1, 1 ; - - fates_allom_d2bl1 = 0.000964, 0.000964; - - fates_allom_d2bl2 = 1.9492, 1.9492; - - fates_allom_d2bl3 = 0.0, 0.0 ; - - fates_allom_d2ca_coefficient_max = 0.03, 0.03 ; - - fates_allom_d2ca_coefficient_min = 0.01, 0.01 ; - - fates_allom_d2h1 = 1.0, 1.0 ; - - fates_allom_d2h2 = 1.0, 1.0 ; - - fates_allom_d2h3 = -999.9, -999.9 ; - - fates_allom_dbh_maxheight = 1, 1 ; - - fates_allom_fmode = 1, 1 ; - - fates_allom_hmode = 3, 3 ; - - fates_allom_l2fr = 0.75, 1.25; - - fates_allom_latosa_int = 0.001, 0.001 ; - - fates_allom_latosa_slp = 0, 0 ; - - fates_allom_lmode = 1, 1 ; - - fates_allom_sai_scaler = 0.0012, 0.0012 ; - - fates_allom_smode = 1, 1 ; - - fates_allom_stmode = 1, 1 ; - - fates_allom_frbstor_repro = 1.0, 1.0; - - fates_branch_turnover = 50, 50 ; - - fates_c2b = 2, 2 ; - - fates_displar = 0.67, 0.67 ; - - fates_fire_alpha_SH = 0.2, 0.2 ; - - fates_fire_bark_scaler = 0.07, 0.07 ; - - fates_fire_crown_depth_frac = 0.5, 0.5 ; - - fates_fire_crown_kill = 0.775, 0.775 ; - - fates_fr_fcel = 0.5, 0.5 ; - - fates_fr_flab = 0.25, 0.25 ; - - fates_fr_flig = 0.25, 0.25 ; - - fates_froot_cn_ratio = 42, 42 ; - - fates_grperc = 0.11, 0.11 ; - - fates_hydr_avuln_gs = 2.5, 2.5 ; - - fates_hydr_p50_gs = -1.5, -1.5 ; - - fates_hydr_p_taper = 0.333, 0.333 ; - - fates_hydr_rfrac_stem = 0.625, 0.625 ; - - fates_hydr_rs2 = 0.0001, 0.0001 ; - - fates_hydr_srl = 25, 25 ; - - fates_leaf_BB_slope = 8, 8 ; - - fates_leaf_c3psn = 0, 0; - - fates_leaf_clumping_index = 0.85, 0.85 ; - - fates_leaf_cn_ratio = 30, 30 ; - - fates_leaf_diameter = 0.04, 0.04 ; - - fates_leaf_jmaxha = 43540, 43540 ; - - fates_leaf_jmaxhd = 152040, 152040 ; - - fates_leaf_jmaxse = 495, 495 ; - - fates_leaf_long = 1.0, 1.0 ; - - fates_leaf_slatop = 0.016, 0.016 ; - - fates_leaf_stor_priority = 0.8, 0.8 ; - - fates_leaf_tpuha = 53100, 53100 ; - - fates_leaf_tpuhd = 150650, 150650 ; - - fates_leaf_tpuse = 490, 490 ; - - fates_leaf_vcmax25top = 70, 40 ; - - fates_leaf_vcmaxha = 65330, 65330 ; - - fates_leaf_vcmaxhd = 149250, 149250 ; - - fates_leaf_vcmaxse = 485, 485 ; - - fates_leaf_xl = 0.1, 0.1 ; - - fates_lf_fcel = 0.5, 0.5 ; - - fates_lf_flab = 0.25, 0.25 ; - - fates_lf_flig = 0.25, 0.25 ; - - fates_maintresp_reduction_curvature = 0.01, 0.01 ; - - fates_maintresp_reduction_intercept = 1, 1 ; - - fates_mort_bmort = 0.9, 0.9 ; - - fates_mort_freezetol = -25, -25 ; - - fates_mort_hf_sm_threshold = 1e-06, 1e-06 ; - - fates_mort_scalar_coldstress = 3, 3 ; - - fates_mort_scalar_cstarvation = 0.6, 0.6 ; - - fates_mort_scalar_hydrfailure = 0.6, 0.6 ; - - fates_pft_used = 1, 0 ; - - fates_phen_evergreen = 0, 0; - - fates_phen_season_decid = 1, 1 ; - - fates_phen_stress_decid = 0, 0 ; - - fates_prescribed_mortality_canopy = 0.0194, 0.0194 ; - - fates_prescribed_mortality_understory = 0.025, 0.025 ; - - fates_prescribed_npp_canopy = 0.4, 0.4 ; - - fates_prescribed_npp_understory = 0.03125, 0.03125 ; - - fates_prescribed_recruitment = 0.02, 0.02 ; - - fates_recruit_hgt_min = 0.05, 0.05 ; - - fates_recruit_initd = 10000000, 0 ; - - fates_rholnir = 0.45, 0.45 ; - - fates_rholvis = 0.1, 0.1 ; - - fates_rhosnir = 0.39, 0.39 ; - - fates_rhosvis = 0.16, 0.16 ; - - fates_root_long = 0.5, 1 ; - - fates_roota_par = 7, 7 ; - - fates_rootb_par = 1, 1 ; - - fates_seed_alloc = 0.1, 0.1 ; - - fates_seed_alloc_mature = 0, 0 ; - - fates_seed_dbh_repro_threshold = 150, 150 ; - - fates_seed_decay_turnover = 0.51, 0.51 ; - - fates_seed_germination_timescale = 0.5, 0.5 ; - - fates_seed_rain = 0.28, 0.28 ; - - fates_smpsc = -255000, -255000 ; - - fates_smpso = -66000, -66000 ; - - fates_taulnir = 0.25, 0.25 ; - - fates_taulvis = 0.05, 0.05 ; - - fates_tausnir = 0.001, 0.001 ; - - fates_tausvis = 0.001, 0.001 ; - - fates_trim_inc = 0.03, 0.03 ; - - fates_trim_limit = 0.3, 0.3 ; - - fates_wood_density = 0.01, 0.01 ; - - fates_woody = 1, 1 ; - - fates_z0mr = 0.055, 0.055 ; - - fates_base_mr_20 = 2.52e-06 ; - - fates_bbopt_c3 = 10000 ; - - fates_bbopt_c4 = 40000 ; - - fates_canopy_closure_thresh = 0.8 ; - - fates_cohort_fusion_tol = 0.08 ; - - fates_comp_excln = 3 ; - - fates_cwd_fcel = 0.76 ; - - fates_cwd_flig = 0.24 ; - - fates_fire_nignitions = 15 ; - - fates_hydr_kmax_rsurf = 0.001; - - fates_hydr_psi0 = 0 ; - - fates_hydr_psicap = -0.6 ; - - fates_init_litter = 0.05 ; - - fates_logging_coll_under_frac = 0.55983 ; - - fates_logging_collateral_frac = 0.05 ; - - fates_logging_dbhmax_infra = 35 ; - - fates_logging_dbhmin = 50 ; - - fates_logging_direct_frac = 0.15 ; - - fates_logging_event_code = -30 ; - - fates_logging_mechanical_frac = 0.05 ; - - fates_mort_disturb_frac = 1 ; - - fates_mort_understorey_death = 0.09 ; - - fates_patch_fusion_tol = 0.05 ; - - fates_phen_a = -68 ; - - fates_phen_b = 638 ; - - fates_phen_c = -0.001 ; - - fates_phen_chiltemp = 5 ; - - fates_phen_coldtemp = 7.5 ; - - fates_phen_doff_time = 100 ; - - fates_phen_drought_threshold = 0.15 ; - - fates_phen_mindayson = 30 ; - - fates_phen_ncolddayslim = 5 ; - - fates_drying_ratio = 13000 ; - - fates_durat_slope = -11.06 ; - - fates_fdi_a = 17.62 ; - - fates_fdi_alpha = 0.00037 ; - - fates_fdi_b = 243.12 ; - - fates_fuel_energy = 18000 ; - - fates_max_durat = 240 ; - - fates_miner_damp = 0.41739 ; - - fates_miner_total = 0.055 ; - - fates_part_dens = 513 ; - - fates_soil_salinity = 0.0 ; -} diff --git a/parameter_files/fates_params_hydro_default.cdl b/parameter_files/fates_params_hydro_default.cdl deleted file mode 100644 index a063abfa62..0000000000 --- a/parameter_files/fates_params_hydro_default.cdl +++ /dev/null @@ -1,1091 +0,0 @@ -netcdf fates_params.2trop { -dimensions: - fates_NCWD = 4 ; - fates_history_age_bins = 7 ; - fates_history_height_bins = 6 ; - fates_history_size_bins = 13 ; - fates_hydr_organs = 4 ; - fates_prt_organs = 6 ; - fates_leafage_class = 2; - fates_litterclass = 6 ; - fates_pft = 2 ; - fates_scalar = 1 ; - fates_string_length = 60 ; - fates_variants = 2 ; -variables: - float fates_history_sizeclass_bin_edges(fates_history_size_bins) ; - fates_history_sizeclass_bin_edges:units = "cm" ; - fates_history_sizeclass_bin_edges:long_name = "Lower edges for DBH size class bins used in size-resolved cohort history output" ; - float fates_history_ageclass_bin_edges(fates_history_age_bins) ; - fates_history_ageclass_bin_edges:units = "yr" ; - fates_history_ageclass_bin_edges:long_name = "Lower edges for age class bins used in age-resolved patch history output" ; - float fates_FBD(fates_litterclass) ; - fates_FBD:units = "NA" ; - fates_FBD:long_name = "spitfire parameter related to fuel bulk density, see SFMain.F90" ; - float fates_SAV(fates_litterclass) ; - fates_SAV:units = "NA" ; - fates_SAV:long_name = "spitfire parameter related to surface area to volume ratio, see SFMain.F90" ; - float fates_alpha_FMC(fates_litterclass) ; - fates_alpha_FMC:units = "NA" ; - fates_alpha_FMC:long_name = "spitfire parameter related to fuel moisture content, Equation 6 Thonicke et al 2010" ; - float fates_history_height_bin_edges(fates_history_height_bins) ; - fates_history_height_bin_edges:units = "m" ; - fates_history_height_bin_edges:long_name = "Lower edges for height bins used in height-resolved history output" ; - float fates_low_moisture_Coeff(fates_litterclass) ; - fates_low_moisture_Coeff:units = "NA" ; - fates_low_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_low_moisture_Slope(fates_litterclass) ; - fates_low_moisture_Slope:units = "NA" ; - fates_low_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_max_decomp(fates_litterclass) ; - fates_max_decomp:units = "kgC/m2/yr ?" ; - fates_max_decomp:long_name = "maximum rate of litter & CWD transfer from non-decomposing class into decomposing class" ; - float fates_mid_moisture(fates_litterclass) ; - fates_mid_moisture:units = "NA" ; - fates_mid_moisture:long_name = "spitfire litter moisture threshold to be considered medium dry" ; - float fates_mid_moisture_Coeff(fates_litterclass) ; - fates_mid_moisture_Coeff:units = "NA" ; - fates_mid_moisture_Coeff:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_mid_moisture_Slope(fates_litterclass) ; - fates_mid_moisture_Slope:units = "NA" ; - fates_mid_moisture_Slope:long_name = "spitfire parameter, equation B1 Thonicke et al 2010" ; - float fates_min_moisture(fates_litterclass) ; - fates_min_moisture:units = "NA" ; - fates_min_moisture:long_name = "spitfire litter moisture threshold to be considered very dry" ; - float fates_hydr_avuln_node(fates_hydr_organs, fates_pft) ; - fates_hydr_avuln_node:units = "unitless" ; - fates_hydr_avuln_node:long_name = "xylem vulnerability curve shape parameter" ; - float fates_hydr_epsil_node(fates_hydr_organs, fates_pft) ; - fates_hydr_epsil_node:units = "MPa" ; - fates_hydr_epsil_node:long_name = "bulk elastic modulus" ; - float fates_hydr_fcap_node(fates_hydr_organs, fates_pft) ; - fates_hydr_fcap_node:units = "unitless" ; - fates_hydr_fcap_node:long_name = "fraction of (1-resid_node) that is capillary in source" ; - float fates_hydr_kmax_node(fates_hydr_organs, fates_pft) ; - fates_hydr_kmax_node:units = "kgMPa/m/s" ; - fates_hydr_kmax_node:long_name = "maximum xylem conductivity per unit conducting xylem area" ; - float fates_hydr_p50_node(fates_hydr_organs, fates_pft) ; - fates_hydr_p50_node:units = "MPa" ; - fates_hydr_p50_node:long_name = "xylem water potential at 50% loss of conductivity" ; - float fates_hydr_pinot_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pinot_node:units = "MPa" ; - fates_hydr_pinot_node:long_name = "osmotic potential at full turgor" ; - float fates_hydr_pitlp_node(fates_hydr_organs, fates_pft) ; - fates_hydr_pitlp_node:units = "MPa" ; - fates_hydr_pitlp_node:long_name = "turgor loss point" ; - float fates_hydr_resid_node(fates_hydr_organs, fates_pft) ; - fates_hydr_resid_node:units = "fraction" ; - fates_hydr_resid_node:long_name = "residual fraction" ; - float fates_hydr_thetas_node(fates_hydr_organs, fates_pft) ; - fates_hydr_thetas_node:units = "cm3/cm3" ; - fates_hydr_thetas_node:long_name = "saturated water content" ; - float fates_CWD_frac(fates_NCWD) ; - fates_CWD_frac:units = "fraction" ; - fates_CWD_frac:long_name = "fraction of woody (bdead+bsw) biomass destined for CWD pool" ; - char fates_pftname(fates_pft, fates_string_length) ; - fates_pftname:units = "unitless - string" ; - fates_pftname:long_name = "Description of plant type" ; - char fates_prt_organ_name(fates_prt_organs, fates_string_length) ; - fates_prt_organ_name:units = "unitless - string" ; - fates_prt_organ_name:long_name = "Plant organ name (order must match PRTGenericMod.F90)" ; - float fates_rootprof_beta(fates_variants, fates_pft) ; - fates_rootprof_beta:units = "unitless" ; - fates_rootprof_beta:long_name = "Rooting beta parameter, for C and N vertical discretization (NOT USED BY DEFAULT)" ; - float fates_alloc_storage_cushion(fates_pft) ; - fates_alloc_storage_cushion:units = "fraction" ; - fates_alloc_storage_cushion:long_name = "maximum size of storage C pool, relative to maximum size of leaf C pool" ; - float fates_allom_agb1(fates_pft) ; - fates_allom_agb1:units = "variable" ; - fates_allom_agb1:long_name = "Parameter 1 for agb allometry" ; - float fates_allom_agb2(fates_pft) ; - fates_allom_agb2:units = "variable" ; - fates_allom_agb2:long_name = "Parameter 2 for agb allometry" ; - float fates_allom_agb3(fates_pft) ; - fates_allom_agb3:units = "variable" ; - fates_allom_agb3:long_name = "Parameter 3 for agb allometry" ; - float fates_allom_agb4(fates_pft) ; - fates_allom_agb4:units = "variable" ; - fates_allom_agb4:long_name = "Parameter 4 for agb allometry" ; - float fates_allom_agb_frac(fates_pft) ; - fates_allom_agb_frac:units = "fraction" ; - fates_allom_agb_frac:long_name = "Fraction of woody biomass that is above ground" ; - float fates_allom_amode(fates_pft) ; - fates_allom_amode:units = "index" ; - fates_allom_amode:long_name = "AGB allometry function index" ; - float fates_allom_blca_expnt_diff(fates_pft) ; - fates_allom_blca_expnt_diff:units = "unitless" ; - fates_allom_blca_expnt_diff:long_name = "difference between allometric DBH:bleaf and DBH:crown area exponents" ; - float fates_allom_cmode(fates_pft) ; - fates_allom_cmode:units = "index" ; - fates_allom_cmode:long_name = "coarse root biomass allometry function index" ; - float fates_allom_d2bl1(fates_pft) ; - fates_allom_d2bl1:units = "variable" ; - fates_allom_d2bl1:long_name = "Parameter 1 for d2bl allometry" ; - float fates_allom_d2bl2(fates_pft) ; - fates_allom_d2bl2:units = "variable" ; - fates_allom_d2bl2:long_name = "Parameter 2 for d2bl allometry" ; - float fates_allom_d2bl3(fates_pft) ; - fates_allom_d2bl3:units = "unitless" ; - fates_allom_d2bl3:long_name = "Parameter 3 for d2bl allometry" ; - float fates_allom_d2ca_coefficient_max(fates_pft) ; - fates_allom_d2ca_coefficient_max:units = "m2 cm^(-1/beta)" ; - fates_allom_d2ca_coefficient_max:long_name = "max (savanna) dbh to area multiplier factor where: area = n*d2ca_coeff*dbh^beta" ; - float fates_allom_d2ca_coefficient_min(fates_pft) ; - fates_allom_d2ca_coefficient_min:units = "m2 cm^(-1/beta)" ; - fates_allom_d2ca_coefficient_min:long_name = "min (forest) dbh to area multiplier factor where: area = n*d2ca_coeff*dbh^beta" ; - float fates_allom_d2h1(fates_pft) ; - fates_allom_d2h1:units = "variable" ; - fates_allom_d2h1:long_name = "Parameter 1 for d2h allometry (intercept, or c)" ; - float fates_allom_d2h2(fates_pft) ; - fates_allom_d2h2:units = "variable" ; - fates_allom_d2h2:long_name = "Parameter 2 for d2h allometry (slope, or m)" ; - float fates_allom_d2h3(fates_pft) ; - fates_allom_d2h3:units = "variable" ; - fates_allom_d2h3:long_name = "Parameter 3 for d2h allometry (optional)" ; - float fates_allom_dbh_maxheight(fates_pft) ; - fates_allom_dbh_maxheight:units = "cm" ; - fates_allom_dbh_maxheight:long_name = "the diameter (if any) corresponding to maximum height, diameters may increase beyond this" ; - float fates_allom_fmode(fates_pft) ; - fates_allom_fmode:units = "index" ; - fates_allom_fmode:long_name = "fine root biomass allometry function index" ; - float fates_allom_hmode(fates_pft) ; - fates_allom_hmode:units = "index" ; - fates_allom_hmode:long_name = "height allometry function index" ; - float fates_allom_l2fr(fates_pft) ; - fates_allom_l2fr:units = "gC/gC" ; - fates_allom_l2fr:long_name = "Allocation parameter: fine root C per leaf C" ; - float fates_allom_la_per_sa_int(fates_pft) ; - fates_allom_la_per_sa_int:units = "m2/cm2" ; - fates_allom_la_per_sa_int:long_name = "Leaf area per sapwood area, intercept" ; - float fates_allom_la_per_sa_slp(fates_pft) ; - fates_allom_la_per_sa_slp:units = "m2/cm2/m" ; - fates_allom_la_per_sa_slp:long_name = "Leaf area per sapwood area rate of change with height, slope (optional)" ; - float fates_allom_lmode(fates_pft) ; - fates_allom_lmode:units = "index" ; - fates_allom_lmode:long_name = "leaf biomass allometry function index" ; - float fates_allom_sai_scaler(fates_pft) ; - fates_allom_sai_scaler:units = "m2/m2" ; - fates_allom_sai_scaler:long_name = "allometric ratio of SAI per LAI" ; - float fates_allom_smode(fates_pft) ; - fates_allom_smode:units = "index" ; - fates_allom_smode:long_name = "sapwood allometry function index" ; - float fates_allom_stmode(fates_pft) ; - fates_allom_stmode:units = "index" ; - fates_allom_stmode:long_name = "storage allometry function index" ; - float fates_allom_frbstor_repro(fates_pft) ; - fates_allom_frbstor_repro:units = "fraction" ; - fates_allom_frbstor_repro:long_name = "fraction of bstore goes to reproduction after plant dies" ; - float fates_branch_turnover(fates_pft) ; - fates_branch_turnover:units = "yr-1" ; - fates_branch_turnover:long_name = "turnover time of branches" ; - - float fates_prt_nitr_stoich_p1(fates_prt_organs,fates_pft) ; - fates_prt_nitr_stoich_p1:units = "(gN/gC)" ; - fates_prt_nitr_stoich_p1:long_name = "nitrogen stoichiometry, parameter 1" ; - - float fates_prt_nitr_stoich_p2(fates_prt_organs,fates_pft) ; - fates_prt_nitr_stoich_p2:units = "(gN/gC)" ; - fates_prt_nitr_stoich_p2:long_name = "nitrogen stoichiometry, parameter 2" ; - - float fates_prt_phos_stoich_p1(fates_prt_organs,fates_pft) ; - fates_prt_phos_stoich_p1:units = "(gP/gC)" ; - fates_prt_phos_stoich_p1:long_name = "phosphorous stoichiometry, parameter 1" ; - - float fates_prt_phos_stoich_p2(fates_prt_organs,fates_pft) ; - fates_prt_phos_stoich_p2:units = "(gP/gC)" ; - fates_prt_phos_stoich_p2:long_name = "phosphorous stoichiometry, parameter 2" ; - - float fates_prt_alloc_priority(fates_prt_organs,fates_pft) ; - fates_prt_alloc_priority:units = "index (0-fates_prt_organs)" ; - fates_prt_alloc_priority:long_name = "Priority order for allocation" ; - - float fates_phenflush_fraction(fates_pft) ; - fates_phenflush_fraction:units = "fraction" ; - fates_phenflush_fraction:long_name = "Upon bud-burst, the maximum fraction of storage carbon used for flushing leaves" ; - - float fates_turnover_retrans_mode(fates_pft) ; - fates_turnover_retrans_mode:units = "index" ; - fates_turnover_retrans_mode:long_name = "retranslocation method for leaf/fineroot turnover" ; - - float fates_turnover_carb_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_carb_retrans:units = "-" ; - fates_turnover_carb_retrans:long_name = "retranslocation fraction of carbon in turnover" ; - - float fates_turnover_nitr_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_nitr_retrans:units = "-" ; - fates_turnover_nitr_retrans:long_name = "retranslocation fraction of nitrogen in turnover" ; - - float fates_turnover_phos_retrans(fates_prt_organs,fates_pft) ; - fates_turnover_phos_retrans:units = "-" ; - fates_turnover_phos_retrans:long_name = "retranslocation fraction of phosphorous in turnover " ; - - float fates_c2b(fates_pft) ; - fates_c2b:units = "ratio" ; - fates_c2b:long_name = "Carbon to biomass multiplier of bulk structural tissues" ; - float fates_displar(fates_pft) ; - fates_displar:units = "unitless" ; - fates_displar:long_name = "Ratio of displacement height to canopy top height" ; - float fates_fire_alpha_SH(fates_pft) ; - fates_fire_alpha_SH:units = "NA" ; - fates_fire_alpha_SH:long_name = "spitfire parameter, alpha scorch height, Equation 16 Thonicke et al 2010" ; - float fates_fire_bark_scaler(fates_pft) ; - fates_fire_bark_scaler:units = "fraction" ; - fates_fire_bark_scaler:long_name = "the thickness of a cohorts bark as a fraction of its dbh" ; - float fates_fire_crown_depth_frac(fates_pft) ; - fates_fire_crown_depth_frac:units = "fraction" ; - fates_fire_crown_depth_frac:long_name = "the depth of a cohorts crown as a fraction of its height" ; - float fates_fire_crown_kill(fates_pft) ; - fates_fire_crown_kill:units = "NA" ; - fates_fire_crown_kill:long_name = "fire parameter, see equation 22 in Thonicke et al 2010" ; - float fates_fr_fcel(fates_pft) ; - fates_fr_fcel:units = "fraction" ; - fates_fr_fcel:long_name = "Fine root litter cellulose fraction" ; - float fates_fr_flab(fates_pft) ; - fates_fr_flab:units = "fraction" ; - fates_fr_flab:long_name = "Fine root litter labile fraction" ; - float fates_fr_flig(fates_pft) ; - fates_fr_flig:units = "fraction" ; - fates_fr_flig:long_name = "Fine root litter lignin fraction" ; - float fates_grperc(fates_pft) ; - fates_grperc:units = "unitless" ; - fates_grperc:long_name = "Growth respiration factor" ; - float fates_hydr_avuln_gs(fates_pft) ; - fates_hydr_avuln_gs:units = "unitless" ; - fates_hydr_avuln_gs:long_name = "shape parameter for stomatal control of water vapor exiting leaf" ; - float fates_hydr_p50_gs(fates_pft) ; - fates_hydr_p50_gs:units = "MPa" ; - fates_hydr_p50_gs:long_name = "water potential at 50% loss of stomatal conductance" ; - float fates_hydr_p_taper(fates_pft) ; - fates_hydr_p_taper:units = "unitless" ; - fates_hydr_p_taper:long_name = "xylem taper exponent" ; - float fates_hydr_rfrac_stem(fates_pft) ; - fates_hydr_rfrac_stem:units = "fraction" ; - fates_hydr_rfrac_stem:long_name = "fraction of total tree resistance from troot to canopy" ; - float fates_hydr_rs2(fates_pft) ; - fates_hydr_rs2:units = "m" ; - fates_hydr_rs2:long_name = "absorbing root radius" ; - float fates_hydr_srl(fates_pft) ; - fates_hydr_srl:units = "m g-1" ; - fates_hydr_srl:long_name = "specific root length" ; - float fates_leaf_BB_slope(fates_pft) ; - fates_leaf_BB_slope:units = "unitless" ; - fates_leaf_BB_slope:long_name = "stomatal slope parameter, as per Ball-Berry" ; - float fates_leaf_c3psn(fates_pft) ; - fates_leaf_c3psn:units = "flag" ; - fates_leaf_c3psn:long_name = "Photosynthetic pathway (1=c3, 0=c4)" ; - float fates_leaf_clumping_index(fates_pft) ; - fates_leaf_clumping_index:units = "fraction (0-1)" ; - fates_leaf_clumping_index:long_name = "factor describing how much self-occlusion of leaf scattering elements decreases light interception" ; - float fates_leaf_diameter(fates_pft) ; - fates_leaf_diameter:units = "m" ; - fates_leaf_diameter:long_name = "Characteristic leaf dimension" ; - float fates_leaf_jmaxha(fates_pft) ; - fates_leaf_jmaxha:units = "J/mol" ; - fates_leaf_jmaxha:long_name = "activation energy for jmax" ; - float fates_leaf_jmaxhd(fates_pft) ; - fates_leaf_jmaxhd:units = "J/mol" ; - fates_leaf_jmaxhd:long_name = "deactivation energy for jmax" ; - float fates_leaf_jmaxse(fates_pft) ; - fates_leaf_jmaxse:units = "J/mol/K" ; - fates_leaf_jmaxse:long_name = "entropy term for jmax" ; - float fates_leaf_long(fates_leafage_class, fates_pft) ; - fates_leaf_long:units = "yr" ; - fates_leaf_long:long_name = "Leaf longevity (ie turnover timescale)" ; - float fates_leaf_slamax(fates_pft) ; - fates_leaf_slamax:units = "m^2/gC" ; - fates_leaf_slamax:long_name = "Maximum Specific Leaf Area (SLA), even if under a dense canopy" ; - float fates_leaf_slatop(fates_pft) ; - fates_leaf_slatop:units = "m^2/gC" ; - fates_leaf_slatop:long_name = "Specific Leaf Area (SLA) at top of canopy, projected area basis" ; - float fates_leaf_stor_priority(fates_pft) ; - fates_leaf_stor_priority:units = "unitless" ; - fates_leaf_stor_priority:long_name = "factor governing priority of replacing storage with NPP" ; - float fates_leaf_tpuha(fates_pft) ; - fates_leaf_tpuha:units = "J/mol" ; - fates_leaf_tpuha:long_name = "activation energy for tpu" ; - float fates_leaf_tpuhd(fates_pft) ; - fates_leaf_tpuhd:units = "J/mol" ; - fates_leaf_tpuhd:long_name = "deactivation energy for tpu" ; - float fates_leaf_tpuse(fates_pft) ; - fates_leaf_tpuse:units = "J/mol/K" ; - fates_leaf_tpuse:long_name = "entropy term for tpu" ; - float fates_leaf_vcmax25top(fates_leafage_class, fates_pft) ; - fates_leaf_vcmax25top:units = "umol CO2/m^2/s" ; - fates_leaf_vcmax25top:long_name = "maximum carboxylation rate of Rub. at 25C, canopy top" ; - float fates_leaf_vcmaxha(fates_pft) ; - fates_leaf_vcmaxha:units = "J/mol" ; - fates_leaf_vcmaxha:long_name = "activation energy for vcmax" ; - float fates_leaf_vcmaxhd(fates_pft) ; - fates_leaf_vcmaxhd:units = "J/mol" ; - fates_leaf_vcmaxhd:long_name = "deactivation energy for vcmax" ; - float fates_leaf_vcmaxse(fates_pft) ; - fates_leaf_vcmaxse:units = "J/mol/K" ; - fates_leaf_vcmaxse:long_name = "entropy term for vcmax" ; - float fates_leaf_xl(fates_pft) ; - fates_leaf_xl:units = "unitless" ; - fates_leaf_xl:long_name = "Leaf/stem orientation index" ; - float fates_lf_fcel(fates_pft) ; - fates_lf_fcel:units = "fraction" ; - fates_lf_fcel:long_name = "Leaf litter cellulose fraction" ; - float fates_lf_flab(fates_pft) ; - fates_lf_flab:units = "fraction" ; - fates_lf_flab:long_name = "Leaf litter labile fraction" ; - float fates_lf_flig(fates_pft) ; - fates_lf_flig:units = "fraction" ; - fates_lf_flig:long_name = "Leaf litter lignin fraction" ; - float fates_maintresp_reduction_curvature(fates_pft) ; - fates_maintresp_reduction_curvature:units = "unitless (0-1)" ; - fates_maintresp_reduction_curvature:long_name = "curvature of MR reduction as f(carbon storage), 1=linear, 0=very curved" ; - float fates_maintresp_reduction_intercept(fates_pft) ; - fates_maintresp_reduction_intercept:units = "unitless (0-1)" ; - fates_maintresp_reduction_intercept:long_name = "intercept of MR reduction as f(carbon storage), 0=no throttling, 1=max throttling" ; - float fates_mort_bmort(fates_pft) ; - fates_mort_bmort:units = "1/yr" ; - fates_mort_bmort:long_name = "background mortality rate" ; - float fates_mort_freezetol(fates_pft) ; - fates_mort_freezetol:units = "NA" ; - fates_mort_freezetol:long_name = "minimum temperature tolerance (NOT USED)" ; - float fates_mort_hf_sm_threshold(fates_pft) ; - fates_mort_hf_sm_threshold:units = "unitless" ; - fates_mort_hf_sm_threshold:long_name = "soil moisture (btran units) at which drought mortality begins for non-hydraulic model" ; - float fates_mort_hf_flc_threshold(fates_pft) ; - fates_mort_hf_flc_threshold:units = "fraction" ; - fates_mort_hf_flc_threshold:long_name = "plant fractional loss of conductivity at which drought mortality begins for hydraulic model" ; - float fates_mort_scalar_coldstress(fates_pft) ; - fates_mort_scalar_coldstress:units = "1/yr" ; - fates_mort_scalar_coldstress:long_name = "maximum mortality rate from cold stress" ; - float fates_mort_scalar_cstarvation(fates_pft) ; - fates_mort_scalar_cstarvation:units = "1/yr" ; - fates_mort_scalar_cstarvation:long_name = "maximum mortality rate from carbon starvation" ; - float fates_mort_scalar_hydrfailure(fates_pft) ; - fates_mort_scalar_hydrfailure:units = "1/yr" ; - fates_mort_scalar_hydrfailure:long_name = "maximum mortality rate from hydraulic failure" ; - float fates_pft_used(fates_pft) ; - fates_pft_used:units = "0 = off (dont use), 1 = on (use)" ; - fates_pft_used:long_name = "Switch to turn on and off PFTs (also see fates_initd for cold-start)" ; - float fates_phen_evergreen(fates_pft) ; - fates_phen_evergreen:units = "logical flag" ; - fates_phen_evergreen:long_name = "Binary flag for evergreen leaf habit" ; - float fates_phen_season_decid(fates_pft) ; - fates_phen_season_decid:units = "logical flag" ; - fates_phen_season_decid:long_name = "Binary flag for seasonal-deciduous leaf habit" ; - float fates_phen_stress_decid(fates_pft) ; - fates_phen_stress_decid:units = "logical flag" ; - fates_phen_stress_decid:long_name = "Binary flag for stress-deciduous leaf habit" ; - float fates_prescribed_mortality_canopy(fates_pft) ; - fates_prescribed_mortality_canopy:units = "1/yr" ; - fates_prescribed_mortality_canopy:long_name = "mortality rate of canopy trees for prescribed physiology mode" ; - float fates_prescribed_mortality_understory(fates_pft) ; - fates_prescribed_mortality_understory:units = "1/yr" ; - fates_prescribed_mortality_understory:long_name = "mortality rate of understory trees for prescribed physiology mode" ; - float fates_prescribed_npp_canopy(fates_pft) ; - fates_prescribed_npp_canopy:units = "gC / m^2 / yr" ; - fates_prescribed_npp_canopy:long_name = "NPP per unit crown area of canopy trees for prescribed physiology mode" ; - float fates_prescribed_npp_understory(fates_pft) ; - fates_prescribed_npp_understory:units = "gC / m^2 / yr" ; - fates_prescribed_npp_understory:long_name = "NPP per unit crown area of understory trees for prescribed physiology mode" ; - float fates_prescribed_recruitment(fates_pft) ; - fates_prescribed_recruitment:units = "n/yr" ; - fates_prescribed_recruitment:long_name = "recruitment rate for prescribed physiology mode" ; - float fates_recruit_hgt_min(fates_pft) ; - fates_recruit_hgt_min:units = "m" ; - fates_recruit_hgt_min:long_name = "the minimum height (ie starting height) of a newly recruited plant" ; - float fates_recruit_initd(fates_pft) ; - fates_recruit_initd:units = "stems/m2" ; - fates_recruit_initd:long_name = "initial seedling density for a cold-start near-bare-ground simulation" ; - float fates_rholnir(fates_pft) ; - fates_rholnir:units = "fraction" ; - fates_rholnir:long_name = "Leaf reflectance: near-IR" ; - float fates_rholvis(fates_pft) ; - fates_rholvis:units = "fraction" ; - fates_rholvis:long_name = "Leaf reflectance: visible" ; - float fates_rhosnir(fates_pft) ; - fates_rhosnir:units = "fraction" ; - fates_rhosnir:long_name = "Stem reflectance: near-IR" ; - float fates_rhosvis(fates_pft) ; - fates_rhosvis:units = "fraction" ; - fates_rhosvis:long_name = "Stem reflectance: visible" ; - float fates_root_long(fates_pft) ; - fates_root_long:units = "yr" ; - fates_root_long:long_name = "root longevity (alternatively, turnover time)" ; - float fates_roota_par(fates_pft) ; - fates_roota_par:units = "1/m" ; - fates_roota_par:long_name = "CLM rooting distribution parameter" ; - float fates_rootb_par(fates_pft) ; - fates_rootb_par:units = "1/m" ; - fates_rootb_par:long_name = "CLM rooting distribution parameter" ; - float fates_seed_alloc(fates_pft) ; - fates_seed_alloc:units = "fraction" ; - fates_seed_alloc:long_name = "fraction of available carbon balance allocated to seeds" ; - float fates_seed_alloc_mature(fates_pft) ; - fates_seed_alloc_mature:units = "fraction" ; - fates_seed_alloc_mature:long_name = "fraction of available carbon balance allocated to seeds in mature plants (adds to fates_seed_alloc)" ; - float fates_seed_dbh_repro_threshold(fates_pft) ; - fates_seed_dbh_repro_threshold:units = "cm" ; - fates_seed_dbh_repro_threshold:long_name = "the diameter (if any) where the plant will start extra clonal allocation to the seed pool" ; - float fates_seed_decay_turnover(fates_pft) ; - fates_seed_decay_turnover:units = "1/yr" ; - fates_seed_decay_turnover:long_name = "turnover time for seeds with respect to germination" ; - float fates_seed_germination_timescale(fates_pft) ; - fates_seed_germination_timescale:units = "1/yr" ; - fates_seed_germination_timescale:long_name = "turnover time for seeds with respect to decay" ; - float fates_seed_rain(fates_pft) ; - fates_seed_rain:units = "KgC/m2/yr" ; - fates_seed_rain:long_name = "External seed rain from outside site (non-mass conserving)" ; - float fates_smpsc(fates_pft) ; - fates_smpsc:units = "mm" ; - fates_smpsc:long_name = "Soil water potential at full stomatal closure" ; - float fates_smpso(fates_pft) ; - fates_smpso:units = "mm" ; - fates_smpso:long_name = "Soil water potential at full stomatal opening" ; - float fates_taulnir(fates_pft) ; - fates_taulnir:units = "fraction" ; - fates_taulnir:long_name = "Leaf transmittance: near-IR" ; - float fates_taulvis(fates_pft) ; - fates_taulvis:units = "fraction" ; - fates_taulvis:long_name = "Leaf transmittance: visible" ; - float fates_tausnir(fates_pft) ; - fates_tausnir:units = "fraction" ; - fates_tausnir:long_name = "Stem transmittance: near-IR" ; - float fates_tausvis(fates_pft) ; - fates_tausvis:units = "fraction" ; - fates_tausvis:long_name = "Stem transmittance: visible" ; - float fates_trim_inc(fates_pft) ; - fates_trim_inc:units = "m2/m2" ; - fates_trim_inc:long_name = "Arbitrary incremental change in trimming function." ; - float fates_trim_limit(fates_pft) ; - fates_trim_limit:units = "m2/m2" ; - fates_trim_limit:long_name = "Arbitrary limit to reductions in leaf area with stress" ; - float fates_wood_density(fates_pft) ; - fates_wood_density:units = "g/cm3" ; - fates_wood_density:long_name = "mean density of woody tissue in plant" ; - float fates_woody(fates_pft) ; - fates_woody:units = "logical flag" ; - fates_woody:long_name = "Binary woody lifeform flag" ; - float fates_z0mr(fates_pft) ; - fates_z0mr:units = "unitless" ; - fates_z0mr:long_name = "Ratio of momentum roughness length to canopy top height" ; - float fates_base_mr_20(fates_scalar) ; - fates_base_mr_20:units = "gC/gN/s" ; - fates_base_mr_20:long_name = "Base maintenance respiration rate for plant tissues, using Ryan 1991" ; - float fates_bbopt_c3(fates_scalar) ; - fates_bbopt_c3:units = "umol H2O/m**2/s" ; - fates_bbopt_c3:long_name = "Ball-Berry minimum unstressed leaf conductance for C3" ; - float fates_bbopt_c4(fates_scalar) ; - fates_bbopt_c4:units = "umol H2O/m**2/s" ; - fates_bbopt_c4:long_name = "Ball-Berry minimum unstressed leaf conductance for C4" ; - float fates_canopy_closure_thresh(fates_scalar) ; - fates_canopy_closure_thresh:units = "unitless" ; - fates_canopy_closure_thresh:long_name = "tree canopy coverage at which crown area allometry changes from savanna to forest value" ; - float fates_cohort_fusion_tol(fates_scalar) ; - fates_cohort_fusion_tol:units = "unitless" ; - fates_cohort_fusion_tol:long_name = "minimum fraction in difference in dbh between cohorts" ; - float fates_comp_excln(fates_scalar) ; - fates_comp_excln:units = "none" ; - fates_comp_excln:long_name = "weighting factor (exponent on dbh) for canopy layer exclusion and promotion" ; - float fates_cwd_fcel(fates_scalar) ; - fates_cwd_fcel:units = "unitless" ; - fates_cwd_fcel:long_name = "Cellulose fraction for CWD" ; - float fates_cwd_flig(fates_scalar) ; - fates_cwd_flig:units = "unitless" ; - fates_cwd_flig:long_name = "Lignin fraction of coarse woody debris" ; - float fates_fire_nignitions(fates_scalar) ; - fates_fire_nignitions:units = "/m2 (?)" ; - fates_fire_nignitions:long_name = "number of daily ignitions (nfires = nignitions*FDI*area_scaling)" ; - float fates_hydr_kmax_rsurf(fates_scalar) ; - fates_hydr_kmax_rsurf:units = "kg water/m2 root area/Mpa/s" ; - fates_hydr_kmax_rsurf:long_name = "maximum conducitivity for unit root surface" ; - float fates_hydr_psi0(fates_scalar) ; - fates_hydr_psi0:units = "MPa" ; - fates_hydr_psi0:long_name = "sapwood water potential at saturation" ; - float fates_hydr_psicap(fates_scalar) ; - fates_hydr_psicap:units = "MPa" ; - fates_hydr_psicap:long_name = "sapwood water potential at which capillary reserves exhausted" ; - float fates_init_litter(fates_scalar) ; - fates_init_litter:units = "NA" ; - fates_init_litter:long_name = "Initialization value for litter pool in cold-start (NOT USED)" ; - float fates_logging_coll_under_frac(fates_scalar) ; - fates_logging_coll_under_frac:units = "fraction" ; - fates_logging_coll_under_frac:long_name = "Fraction of stems killed in the understory when logging generates disturbance" ; - float fates_logging_collateral_frac(fates_scalar) ; - fates_logging_collateral_frac:units = "fraction" ; - fates_logging_collateral_frac:long_name = "Fraction of large stems in upperstory that die from logging collateral damage" ; - float fates_logging_dbhmax_infra(fates_scalar) ; - fates_logging_dbhmax_infra:units = "cm" ; - fates_logging_dbhmax_infra:long_name = "Tree diameter, above which infrastructure from logging does not impact damage or mortality." ; - float fates_logging_dbhmin(fates_scalar) ; - fates_logging_dbhmin:units = "cm" ; - fates_logging_dbhmin:long_name = "Minimum dbh at which logging is applied" ; - float fates_logging_direct_frac(fates_scalar) ; - fates_logging_direct_frac:units = "fraction" ; - fates_logging_direct_frac:long_name = "Fraction of stems logged directly per event" ; - float fates_logging_event_code(fates_scalar) ; - fates_logging_event_code:units = "unitless" ; - fates_logging_event_code:long_name = "Integer code that options how logging events are structured" ; - float fates_logging_mechanical_frac(fates_scalar) ; - fates_logging_mechanical_frac:units = "fraction" ; - fates_logging_mechanical_frac:long_name = "Fraction of stems killed due infrastructure an other mechanical means" ; - float fates_mort_disturb_frac(fates_scalar) ; - fates_mort_disturb_frac:units = "fraction" ; - fates_mort_disturb_frac:long_name = "fraction of canopy mortality that results in disturbance (i.e. transfer of area from new to old patch)" ; - float fates_mort_understorey_death(fates_scalar) ; - fates_mort_understorey_death:units = "fraction" ; - fates_mort_understorey_death:long_name = "fraction of plants in understorey cohort impacted by overstorey tree-fall" ; - float fates_patch_fusion_tol(fates_scalar) ; - fates_patch_fusion_tol:units = "unitless" ; - fates_patch_fusion_tol:long_name = "minimum fraction in difference in profiles between patches" ; - float fates_phen_a(fates_scalar) ; - fates_phen_a:units = "none" ; - fates_phen_a:long_name = "GDD accumulation function, intercept parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_b(fates_scalar) ; - fates_phen_b:units = "none" ; - fates_phen_b:long_name = "GDD accumulation function, multiplier parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_c(fates_scalar) ; - fates_phen_c:units = "none" ; - fates_phen_c:long_name = "GDD accumulation function, exponent parameter: gdd_thesh = a + b exp(c*ncd)" ; - float fates_phen_chiltemp(fates_scalar) ; - fates_phen_chiltemp:units = "degrees C" ; - fates_phen_chiltemp:long_name = "chilling day counting threshold" ; - float fates_phen_coldtemp(fates_scalar) ; - fates_phen_coldtemp:units = "degrees C" ; - fates_phen_coldtemp:long_name = "temperature exceedance to flag a cold-day for temperature leaf drop" ; - float fates_phen_doff_time(fates_scalar) ; - fates_phen_doff_time:units = "days" ; - fates_phen_doff_time:long_name = "day threshold compared against days since leaves became off-allometry" ; - float fates_phen_drought_threshold(fates_scalar) ; - fates_phen_drought_threshold:units = "m3/m3" ; - fates_phen_drought_threshold:long_name = "liquid volume in soil layer, threashold for drought phenology" ; - float fates_phen_mindayson(fates_scalar) ; - fates_phen_mindayson:units = "days" ; - fates_phen_mindayson:long_name = "day threshold compared against days since leaves became on-allometry" ; - float fates_phen_ncolddayslim(fates_scalar) ; - fates_phen_ncolddayslim:units = "days" ; - fates_phen_ncolddayslim:long_name = "day threshold exceedance for temperature leaf-drop" ; - float fates_durat_slope ; - fates_durat_slope:units = "NA" ; - fates_durat_slope:long_name = "spitfire parameter, fire max duration slope, Equation 14 Thonicke et al 2010" ; - float fates_fdi_a ; - fates_fdi_a:units = "NA" ; - fates_fdi_a:long_name = "spitfire parameter (unknown) " ; - float fates_fdi_alpha ; - fates_fdi_alpha:units = "NA" ; - fates_fdi_alpha:long_name = "spitfire parameter, EQ 7 Venevsky et al. GCB 2002,(modified EQ 8 Thonicke et al. 2010) " ; - float fates_fdi_b ; - fates_fdi_b:units = "NA" ; - fates_fdi_b:long_name = "spitfire parameter (unknown) " ; - float fates_fire_wind_max ; - fates_fire_wind_max:units = "m/min" ; - fates_fire_wind_max:long_name = "maximum wind speed expected by the fire model" ; - float fates_fuel_energy ; - fates_fuel_energy:units = "kJ/kg" ; - fates_fuel_energy:long_name = "pitfire parameter, heat content of fuel" ; - float fates_max_durat ; - fates_max_durat:units = "minutes" ; - fates_max_durat:long_name = "spitfire parameter, fire maximum duration, Equation 14 Thonicke et al 2010" ; - float fates_miner_damp ; - fates_miner_damp:units = "NA" ; - fates_miner_damp:long_name = "spitfire parameter, mineral-dampening coefficient EQ A1 Thonicke et al 2010 " ; - float fates_miner_total ; - fates_miner_total:units = "fraction" ; - fates_miner_total:long_name = "spitfire parameter, total mineral content, Table A1 Thonicke et al 2010" ; - float fates_part_dens ; - fates_part_dens:units = "kg/m2" ; - fates_part_dens:long_name = "spitfire parameter, oven dry particle density, Table A1 Thonicke et al 2010" ; - float fates_soil_salinity(fates_scalar) ; - fates_soil_salinity:units = "ppt" ; - fates_soil_salinity:long_name = "soil salinity used for model when not coupled to dynamic soil salinity" ; - - -// global attributes: - :history = "This file was made from FatesPFTIndexSwapper.py \n", - " Input File = fates_params_13pfts.c180315.nc \n", - " Indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13] \n", - " Wed Feb 28 13:43:44 PST 2018 Values from Jennifer Holms 13pft test file fates_params.c170929_13pfts.nc were then manually converted over into positions 2-13, position 1 kept the tropical broadleaf evergreen. Wed Mar 7 15:53:33 PST 2018 (RGK) added fates_logging_dbhmax_infra, fates_maintresp_reduction_curvature, fates_maintresp_reduction_intercept, and fates_leaf_clumping_index. CHanged fates_clone_alloc to fates_seed_alloc_mature. Updated minimum grass sizes per J Shuman notes. Set grass AGB intercepts and latosa to zero. Updated clumping to have more substanteated starter values per suggestions by Shawn Serbin.\n", - " Thu Mar 15 13:48:11 PDT 2018 Added C4 plants via suggestions by @huitang_earth.\n", - " Mon Mar 19 19:05:44 EDT 2018 forced all plants to be evergreen till carbon-imbalances are fixed.\n", - " Mon Mar 19 19:05:44 EDT 2018 added entry for fates_history_height_bin_edges.\n", - " Thu Apr 12 14:18:46 PDT 2018 updated names on CN recruitment parameters. -- fates_params_14pft.c180412.nc -- \n", - " This file was made then modified wih FatesPFTIndexSwapper.py to reduce to 2 tropical pfts again. \n", - " Indices = [1, 1] \n", - " Wed Aug 29 12:14:41 PDT 2018: (RGK) Updated latosa to la_per_sa (inverts units, invert defaults also)\n" ; -data: - - fates_history_sizeclass_bin_edges = 0, 5, 10, 15, 20, 30, 40, 50, 60, 70, - 80, 90, 100 ; - - fates_history_ageclass_bin_edges = 0, 1, 2, 5, 10, 20, 50 ; - - fates_FBD = 4, 15.4, 16.8, 19.6, 999, 4 ; - - fates_SAV = 66, 13, 3.58, 0.98, 0.2, 66 ; - - fates_alpha_FMC = 0.0050769, 0.001, 0.0002754, 7.54e-05, 1.54e-05, 999 ; - - fates_history_height_bin_edges = 0, 0.1, 0.3, 1, 3, 10 ; - - fates_low_moisture_Coeff = 1.15, 1.12, 1.09, 0.98, 0.8, 1.15 ; - - fates_low_moisture_Slope = 0.62, 0.62, 0.72, 0.85, 0.8, 0.62 ; - - fates_max_decomp = 1, 0.52, 0.383, 0.383, 0.19, 999 ; - - fates_mid_moisture = 0.8, 0.72, 0.51, 0.38, 1, 0.8 ; - - fates_mid_moisture_Coeff = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - - fates_mid_moisture_Slope = 3.2, 2.35, 1.47, 1.06, 0.8, 3.2 ; - - fates_min_moisture = 0.24, 0.18, 0.12, 0, 0, 0.24 ; - - fates_hydr_avuln_node = - 2, 2, - 2, 2, - 2, 2, - 2, 2 ; - - fates_hydr_epsil_node = - 12, 12, - 10, 10, - 10, 10, - 8, 8 ; - - fates_hydr_fcap_node = - 0, 0, - 0.08, 0.08, - 0.08, 0.08, - 0, 0 ; - - fates_hydr_kmax_node = - -999, -999, - 3, 3, - -999, -999, - -999, -999 ; - - fates_hydr_p50_node = - -2.25, -2.25, - -2.25, -2.25, - -2.25, -2.25, - -2.25, -2.25 ; - - fates_hydr_pinot_node = - -1.465984, -1.465984, - -1.228070, -1.228070, - -1.228070, -1.228070, - -1.043478, -1.043478 ; - - fates_hydr_pitlp_node = - -1.67, -1.67, - -1.4, -1.4, - -1.4, -1.4, - -1.2, -1.2 ; - - fates_hydr_resid_node = - 0.25, 0.25, - 0.325, 0.325, - 0.325, 0.325, - 0.15, 0.15 ; - - fates_hydr_thetas_node = - 0.65, 0.65, - 0.65, 0.65, - 0.65, 0.65, - 0.75, 0.75 ; - - fates_CWD_frac = 0.045, 0.075, 0.21, 0.67 ; - - fates_pftname = - "broadleaf_evergreen_tropical_tree ", - "broadleaf_evergreen_tropical_tree " ; - - fates_prt_organ_name = - "leaf ", - "fine root ", - "sapwood ", - "storage ", - "reproduction ", - "structure "; - - fates_rootprof_beta = - 0.976, 0.976, - _, _ ; - - fates_alloc_storage_cushion = 2, 2 ; - - fates_allom_agb1 = 0.06896, 0.06896 ; - - fates_allom_agb2 = 0.572, 0.572 ; - - fates_allom_agb3 = 1.94, 1.94 ; - - fates_allom_agb4 = 0.931, 0.931 ; - - fates_allom_agb_frac = 0.6, 0.6 ; - - fates_allom_amode = 1, 1 ; - - fates_allom_blca_expnt_diff = 0, 0 ; - - fates_allom_cmode = 1, 1 ; - - fates_allom_d2bl1 = 0.07, 0.07 ; - - fates_allom_d2bl2 = 1.3, 1.3 ; - - fates_allom_d2bl3 = 0.55, 0.55 ; - - fates_allom_d2ca_coefficient_max = 0.6568464, 0.6568464 ; - - fates_allom_d2ca_coefficient_min = 0.3381119, 0.3381119 ; - - fates_allom_d2h1 = 0.64, 0.64 ; - - fates_allom_d2h2 = 0.37, 0.37 ; - - fates_allom_d2h3 = -999.9, -999.9 ; - - fates_allom_dbh_maxheight = 150, 150 ; - - fates_allom_fmode = 1, 1 ; - - fates_allom_hmode = 1, 1 ; - - fates_allom_l2fr = 1, 1 ; - - fates_allom_la_per_sa_int = 0.8, 0.8 ; - - fates_allom_la_per_sa_slp = 0.0, 0.0 ; - - fates_allom_lmode = 1, 1 ; - - fates_allom_sai_scaler = 0.10, 0.10 ; - - fates_allom_smode = 1, 1 ; - - fates_allom_stmode = 1, 1 ; - - fates_allom_frbstor_repro = 0.0, 0.0; - - fates_branch_turnover = 50, 50 ; - - fates_prt_nitr_stoich_p1 = - 0.033, 0.033, - 0.024, 0.024, - 0.0000047, 0.0000047, - 0.0000047, 0.0000047, - 0.0, 0.0, - 0.0000047, 0.0000047; - - fates_prt_nitr_stoich_p2 = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; - - fates_prt_phos_stoich_p1 = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; - - fates_prt_phos_stoich_p2 = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; - - fates_prt_alloc_priority = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; - - fates_phenflush_fraction = - 0.5, 0.5; - - fates_turnover_retrans_mode = - 1, 1; - - fates_turnover_carb_retrans = - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00, - 0.00, 0.00; - - fates_turnover_nitr_retrans = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; - - fates_turnover_phos_retrans = - _, _, - _, _, - _, _, - _, _, - _, _, - _, _; - - fates_c2b = 2, 2 ; - - fates_displar = 0.67, 0.67 ; - - fates_fire_alpha_SH = 0.2, 0.2 ; - - fates_fire_bark_scaler = 0.07, 0.07 ; - - fates_fire_crown_depth_frac = 0.5, 0.5 ; - - fates_fire_crown_kill = 0.775, 0.775 ; - - fates_fr_fcel = 0.5, 0.5 ; - - fates_fr_flab = 0.25, 0.25 ; - - fates_fr_flig = 0.25, 0.25 ; - - fates_grperc = 0.11, 0.11 ; - - fates_hydr_avuln_gs = 2.5, 2.5 ; - - fates_hydr_p50_gs = -1.5, -1.5 ; - - fates_hydr_p_taper = 0.333, 0.333 ; - - fates_hydr_rfrac_stem = 0.625, 0.625 ; - - fates_hydr_rs2 = 0.0001, 0.0001 ; - - fates_hydr_srl = 25, 25 ; - - fates_leaf_BB_slope = 8, 8 ; - - fates_leaf_c3psn = 1, 1 ; - - fates_leaf_clumping_index = 0.85, 0.85 ; - - fates_leaf_diameter = 0.04, 0.04 ; - - fates_leaf_jmaxha = 43540, 43540 ; - - fates_leaf_jmaxhd = 152040, 152040 ; - - fates_leaf_jmaxse = 495, 495 ; - - fates_leaf_long = 0.75, 0.75, - 0.75, 0.75 ; - - fates_leaf_slamax = 0.0954, 0.0954 ; - - fates_leaf_slatop = 0.012, 0.012 ; - - fates_leaf_stor_priority = 0.8, 0.8 ; - - fates_leaf_tpuha = 53100, 53100 ; - - fates_leaf_tpuhd = 150650, 150650 ; - - fates_leaf_tpuse = 490, 490 ; - - fates_leaf_vcmax25top = 50, 50, - 50, 50; - - fates_leaf_vcmaxha = 65330, 65330 ; - - fates_leaf_vcmaxhd = 149250, 149250 ; - - fates_leaf_vcmaxse = 485, 485 ; - - fates_leaf_xl = 0.1, 0.1 ; - - fates_lf_fcel = 0.5, 0.5 ; - - fates_lf_flab = 0.25, 0.25 ; - - fates_lf_flig = 0.25, 0.25 ; - - fates_maintresp_reduction_curvature = 0.01, 0.01 ; - - fates_maintresp_reduction_intercept = 1, 1 ; - - fates_mort_bmort = 0.014, 0.014 ; - - fates_mort_freezetol = 2.5, 2.5 ; - - fates_mort_hf_sm_threshold = 1e-06, 1e-06 ; - - fates_mort_hf_flc_threshold = 0.5, 0.5 ; - - fates_mort_scalar_coldstress = 3, 3 ; - - fates_mort_scalar_cstarvation = 0.6, 0.6 ; - - fates_mort_scalar_hydrfailure = 0.6, 0.6 ; - - fates_pft_used = 1, 1 ; - - fates_phen_evergreen = 1, 0 ; - - fates_phen_season_decid = 0, 0 ; - - fates_phen_stress_decid = 0, 1 ; - - fates_prescribed_mortality_canopy = 0.0194, 0.0194 ; - - fates_prescribed_mortality_understory = 0.025, 0.025 ; - - fates_prescribed_npp_canopy = 0.4, 0.4 ; - - fates_prescribed_npp_understory = 0.03125, 0.03125 ; - - fates_prescribed_recruitment = 0.02, 0.02 ; - - fates_recruit_hgt_min = 1.25, 1.25 ; - - fates_recruit_initd = 0.2, 0.2 ; - - fates_rholnir = 0.45, 0.45 ; - - fates_rholvis = 0.1, 0.1 ; - - fates_rhosnir = 0.39, 0.39 ; - - fates_rhosvis = 0.16, 0.16 ; - - fates_root_long = 1, 1 ; - - fates_roota_par = 7, 7 ; - - fates_rootb_par = 1, 1 ; - - fates_seed_alloc = 0.1, 0.1 ; - - fates_seed_alloc_mature = 0, 0 ; - - fates_seed_dbh_repro_threshold = 150, 150 ; - - fates_seed_decay_turnover = 0.51, 0.51 ; - - fates_seed_germination_timescale = 0.5, 0.5 ; - - fates_seed_rain = 0.28, 0.28 ; - - fates_smpsc = -255000, -255000 ; - - fates_smpso = -66000, -66000 ; - - fates_taulnir = 0.25, 0.25 ; - - fates_taulvis = 0.05, 0.05 ; - - fates_tausnir = 0.001, 0.001 ; - - fates_tausvis = 0.001, 0.001 ; - - fates_trim_inc = 0.03, 0.03 ; - - fates_trim_limit = 0.3, 0.3 ; - - fates_wood_density = 0.7, 0.7 ; - - fates_woody = 1, 1 ; - - fates_z0mr = 0.055, 0.055 ; - - fates_base_mr_20 = 2.52e-06 ; - - fates_bbopt_c3 = 10000 ; - - fates_bbopt_c4 = 40000 ; - - fates_canopy_closure_thresh = 0.8 ; - - fates_cohort_fusion_tol = 0.05 ; - - fates_comp_excln = 3 ; - - fates_cwd_fcel = 0.76 ; - - fates_cwd_flig = 0.24 ; - - fates_fire_nignitions = 15 ; - - fates_hydr_kmax_rsurf = 20; - - fates_hydr_psi0 = 0 ; - - fates_hydr_psicap = -0.6 ; - - fates_init_litter = 0.05 ; - - fates_logging_coll_under_frac = 0.55983 ; - - fates_logging_collateral_frac = 0.05 ; - - fates_logging_dbhmax_infra = 35 ; - - fates_logging_dbhmin = 50 ; - - fates_logging_direct_frac = 0.15 ; - - fates_logging_event_code = -30 ; - - fates_logging_mechanical_frac = 0.05 ; - - fates_mort_disturb_frac = 1 ; - - fates_mort_understorey_death = 0.55983 ; - - fates_patch_fusion_tol = 0.05 ; - - fates_phen_a = -68 ; - - fates_phen_b = 638 ; - - fates_phen_c = -0.001 ; - - fates_phen_chiltemp = 5 ; - - fates_phen_coldtemp = 7.5 ; - - fates_phen_doff_time = 100 ; - - fates_phen_drought_threshold = 0.15 ; - - fates_phen_mindayson = 30 ; - - fates_phen_ncolddayslim = 5 ; - - fates_durat_slope = -11.06 ; - - fates_fdi_a = 17.62 ; - - fates_fdi_alpha = 0.00037 ; - - fates_fdi_b = 243.12 ; - - fates_fire_wind_max = 45.718 ; - - fates_fuel_energy = 18000 ; - - fates_max_durat = 240 ; - - fates_miner_damp = 0.41739 ; - - fates_miner_total = 0.055 ; - - fates_part_dens = 513 ; - - fates_soil_salinity = 0.4 ; -} From ea092e85bbb1ffb3610b57d5c24e3834f7c732eb Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Mar 2019 11:50:20 -0700 Subject: [PATCH 69/78] Updated default parameters per discussion issue 444 --- parameter_files/fates_params_default.cdl | 66 ++++++++++++------------ 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index ed852884e4..4ad704bad9 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -1,4 +1,4 @@ -netcdf fates_params_12pft_sorted { +netcdf fates_params_default { dimensions: fates_NCWD = 4 ; fates_history_age_bins = 7 ; @@ -587,7 +587,9 @@ variables: // global attributes: :history = "This file was made from FatesPFTIndexSwapper.py \n", " Input File = fates_params_14pft.nc \n", - " Indices = [1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14]" ; + " Indices = [1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14] \n", + " Migrating in parameters from hydro file, and discussion \n", + " See NGEET/fates issue 444" ; data: fates_history_height_bin_edges = 0, 0.1, 0.3, 1, 3, 10 ; @@ -615,7 +617,7 @@ data: fates_fire_nignitions = 15 ; - fates_hydr_kmax_rsurf = 0.001 ; + fates_hydr_kmax_rsurf = 20.0 ; fates_hydr_psi0 = 0 ; @@ -664,18 +666,18 @@ data: fates_soil_salinity = 0.4 ; fates_pftname = - "broadleaf_evergreen_tropical_tree ", - "needleleaf_evergreen_temperate_tree ", - "needleleaf_deciduous_boreal_tree ", - "broadleaf_evergreen_temperate_tree ", - "broadleaf_deciduous_tropical_tree ", - "broadleaf_deciduous_temperate_tree ", - "broadleaf_evergreen_temperate_shrub ", - "broadleaf_deciduous_temperate_shrub ", - "broadleaf_deciduous_boreal_shrub ", - "arctic_c3_grass ", - "cool_c3_grass ", - "c4_grass " ; + "broadleaf_evergreen_tropical_tree ", + "needleleaf_evergreen_extratrop_tree ", + "needleleaf_colddecid_extratrop_tree ", + "broadleaf_evergreen_extratrop_tree ", + "broadleaf_hydrodecid_tropical_tree ", + "broadleaf_colddecid_extratrop_tree ", + "broadleaf_evergreen_extratrop_shrub ", + "broadleaf_hydrodecid_extratrop_shrub ", + "broadleaf_colddecid_extratrop_shrub ", + "arctic_c3_grass ", + "cool_c3_grass ", + "c4_grass " ; fates_prt_organ_name = "leaf ", @@ -685,7 +687,7 @@ data: "reproduction ", "structure " ; - fates_alloc_storage_cushion = 2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, + fates_alloc_storage_cushion = 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2 ; fates_allom_agb1 = 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, 0.06896, @@ -735,8 +737,7 @@ data: fates_allom_d2h3 = -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9, -999.9 ; - fates_allom_dbh_maxheight = 150, 90, 90, 90, 90, 90, 3, 3, 2, 1.47, 1.47, - 1.47 ; + fates_allom_dbh_maxheight = 90, 90, 90, 90, 90, 90, 3, 3, 2, 0.35, 0.35, 0.35 ; fates_allom_fmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; @@ -746,8 +747,7 @@ data: fates_allom_l2fr = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_allom_la_per_sa_int = 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, - 1000, 1000, 1000, 1000 ; + fates_allom_la_per_sa_int = 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8; fates_allom_la_per_sa_slp = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; @@ -760,7 +760,7 @@ data: fates_allom_stmode = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; - fates_branch_turnover = 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0 ; + fates_branch_turnover = 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0 ; fates_c2b = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; @@ -834,10 +834,10 @@ data: 0.333, 0.333, 0.333, 0.333 ; fates_hydr_pinot_node = - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, - -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 ; + -1.465984, -1.465984, -1.465984, -1.465984, -1.465984, -1.465984, -1.465984, -1.465984, -1.465984, -1.465984,-1.465984, -1.465984, + -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, + -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, -1.22807, + -1.043478, -1.043478, -1.043478, -1.043478, -1.043478, -1.043478, -1.043478, -1.043478,-1.043478, -1.043478, -1.043478, -1.043478 ; fates_hydr_pitlp_node = -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, -1.67, @@ -941,7 +941,7 @@ data: 0.014, 0.014, 0.014, 0.014 ; fates_mort_freezetol = 2.5, -55, -80, -30, 2.5, -30, -60, -10, -80, -80, - -80, -80 ; + -20, 2.5 ; fates_mort_hf_flc_threshold = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; @@ -994,10 +994,8 @@ data: 0.033, 0.029, 0.04, 0.033, 0.04, 0.04, 0.033, 0.04, 0.04, 0.04, 0.04, 0.04, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, - 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, - 0.0047, 0.0047, 0.0047, - 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, - 0.0047, 0.0047, 0.0047, + 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, + 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 1.0e-8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047, 0.0047 ; @@ -1026,10 +1024,10 @@ data: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ ; - fates_recruit_hgt_min = 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 0.75, 0.75, - 0.75, 0.75, 0.75, 0.75 ; + fates_recruit_hgt_min = 1.3, 1.3, 1.3, 1.3, 1.3, 1.3, 0.75, 0.75, + 0.75, 0.125, 0.125, 0.125 ; - fates_recruit_initd = 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 20, 20, 20 ; + fates_recruit_initd = 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2 ; fates_rholnir = 0.45, 0.35, 0.35, 0.45, 0.45, 0.45, 0.35, 0.45, 0.45, 0.35, 0.35, 0.35 ; @@ -1095,7 +1093,7 @@ data: fates_trim_limit = 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3 ; fates_turnover_carb_retrans = - 0.025, 0.025, 0.05, 0.025, 0.05, 0.05, 0.025, 0.05, 0.05, 0.05, 0.05, 0.05, + 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From bc751bc6bfec8e9c9641e105695a2f4448af98cf Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Thu, 28 Mar 2019 12:01:51 -0700 Subject: [PATCH 70/78] Reduced leaf age bin to 1 for base default file --- parameter_files/fates_params_default.cdl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index 4ad704bad9..b07ed8b784 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -5,7 +5,7 @@ dimensions: fates_history_height_bins = 6 ; fates_history_size_bins = 13 ; fates_hydr_organs = 4 ; - fates_leafage_class = 2 ; + fates_leafage_class = 1 ; fates_litterclass = 6 ; fates_pft = 12 ; fates_prt_organs = 6 ; @@ -887,9 +887,7 @@ data: fates_leaf_jmaxse = 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495 ; - fates_leaf_long = - 0.75, 2, 0.5, 0.75, 0.5, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.5, - 0.75, 2, 0.5, 0.75, 0.5, 0.5, 0.75, 0.5, 0.5, 0.5, 0.5, 0.5 ; + fates_leaf_long = 1.5, 4, 1.0, 1.5, 1.0, 1.0, 1.5, 1.0, 1.0, 1.0, 1.0, 1.0 ; fates_leaf_slamax = 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.0954, 0.012, 0.03, 0.03, 0.03, 0.03, 0.03 ; @@ -908,9 +906,7 @@ data: fates_leaf_tpuse = 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 490 ; - fates_leaf_vcmax25top = - 50, 65, 39, 62, 41, 58, 62, 54, 54, 78, 78, 78, - 50, 65, 39, 62, 41, 58, 62, 54, 54, 78, 78, 78 ; + fates_leaf_vcmax25top = 50, 65, 39, 62, 41, 58, 62, 54, 54, 78, 78, 78 ; fates_leaf_vcmaxha = 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330, 65330 ; From 67df8c773c1a16714f372adb83e20a8e2c20cea5 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Thu, 28 Mar 2019 12:29:37 -0700 Subject: [PATCH 71/78] changed ncvarsort to use scipy netcdf --- tools/ncvarsort.py | 52 +++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/tools/ncvarsort.py b/tools/ncvarsort.py index c2047cdf51..6c56703d68 100755 --- a/tools/ncvarsort.py +++ b/tools/ncvarsort.py @@ -4,12 +4,12 @@ # --input or --fin: input filename. # --output or --fout: output filename. If missing, will assume its directly modifying the input file, and will prompt unless -O is specified -from netCDF4 import Dataset +from scipy.io import netcdf as nc import sys import os import argparse -# program sorts the variables based on the provided list, and pulls them one at a time +# program sorts the variables based on the provided list, and pulls them one at a time # from an existing file and adds them to a new file in the sorted order. # input/output based on code here: https://gist.github.com/guziy/8543562 @@ -18,14 +18,14 @@ def main(): # parser.add_argument('--fin', '--input', dest='fnamein', type=str, help="Input filename. Required.", required=True) parser.add_argument('--fout','--output', dest='fnameout', type=str, help="Output filename. Required.", required=True) - parser.add_argument('--O','--overwrite', dest='overwrite', help="If present, automatically overwrite the output file.", action="store_true") + parser.add_argument('--O','--overwrite', dest='overwrite', help="If present, automatically overwrite the output file.", action="store_true") # args = parser.parse_args() # # open the input dataset - dsin = Dataset(args.fnamein) + dsin = nc.netcdf_file(args.fnamein, 'r') # - # make empty lists to hold the variable names in. the first of these is a list of sub-lists, + # make empty lists to hold the variable names in. the first of these is a list of sub-lists, # one for each type of variable (based on dimensionality). # the second is the master list that will contain all variables. varnames_list = [[],[],[],[],[],[],[],[],[],[]] @@ -69,39 +69,53 @@ def main(): else: raise ValueError('Output file already exists and overwrite flag not specified for filename: '+args.fnameout) # - dsout = Dataset(args.fnameout, "w", format="NETCDF3_CLASSIC") + dsout = nc.netcdf_file(args.fnameout, "w") # #Copy dimensions for dname, the_dim in dsin.dimensions.iteritems(): - print dname, len(the_dim) - dsout.createDimension(dname, len(the_dim) if not the_dim.isunlimited() else None) - # + print dname, the_dim + dsout.createDimension(dname, the_dim ) + # print # + try: + dsout.history = dsin.history + except: + print('no history!') + # + # # go through each variable in the order of the sorted master list, and copy the variable # as well as all metadata to the new file. for i in range(len(varnames_list_sorted)): v_name = varnames_list_sorted[i] varin = dsin.variables[v_name] - outVar = dsout.createVariable(v_name, varin.datatype, varin.dimensions) + outVar = dsout.createVariable(v_name, varin.data.dtype, varin.dimensions) print v_name # - # Copy variable attributes - outVar.setncatts({k: varin.getncattr(k) for k in varin.ncattrs()}) + try: + outVar.units = varin.units + except: + print('----------no units!-----------') + try: + outVar.long_name = varin.long_name + except: + print('----------no long name!---------') # # copy data from input file to output file - outVar[:] = varin[:] - # - # copy global attributes - dsout.setncatts({k: dsin.getncattr(k) for k in dsin.ncattrs()}) + # + try: + outVar[:] = varin[:] + except: + # handle the case where there is a scalar + outVar.assignValue(varin.data) + # # # close the output file - dsout.close() dsin.close() + dsout.close() # ======================================================================================= # This is the actual call to main - + if __name__ == "__main__": main() - From d4964e56388cb3dba6d1b6953f0d0f614f08d315 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 5 Apr 2019 12:25:28 -0600 Subject: [PATCH 72/78] Moved some history diagnostic calculations to be valid for non-woody plants (nplant_si_scpf notably) --- main/FatesHistoryInterfaceMod.F90 | 67 +++++++++++++++++-------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index b71e7dcef7..8bd337a73a 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -1848,51 +1848,50 @@ subroutine update_history_dyn(this,nc,nsites,sites) hio_npp_stor_si_scpf(io_si,scpf) = hio_npp_stor_si_scpf(io_si,scpf) + & store_c_net_alloc*n_perm2 - ! Woody State Variables (basal area and number density and mortality) + ! Woody State Variables (basal area growth increment) if (EDPftvarcon_inst%woody(ft) == 1) then - - hio_m1_si_scpf(io_si,scpf) = hio_m1_si_scpf(io_si,scpf) + ccohort%bmort*ccohort%n - hio_m2_si_scpf(io_si,scpf) = hio_m2_si_scpf(io_si,scpf) + ccohort%hmort*ccohort%n - hio_m3_si_scpf(io_si,scpf) = hio_m3_si_scpf(io_si,scpf) + ccohort%cmort*ccohort%n - hio_m7_si_scpf(io_si,scpf) = hio_m7_si_scpf(io_si,scpf) + & - (ccohort%lmort_direct+ccohort%lmort_collateral+ccohort%lmort_infra) * ccohort%n - hio_m8_si_scpf(io_si,scpf) = hio_m8_si_scpf(io_si,scpf) + ccohort%frmort*ccohort%n - - hio_m1_si_scls(io_si,scls) = hio_m1_si_scls(io_si,scls) + ccohort%bmort*ccohort%n - hio_m2_si_scls(io_si,scls) = hio_m2_si_scls(io_si,scls) + ccohort%hmort*ccohort%n - hio_m3_si_scls(io_si,scls) = hio_m3_si_scls(io_si,scls) + ccohort%cmort*ccohort%n - hio_m7_si_scls(io_si,scls) = hio_m7_si_scls(io_si,scls) + & - (ccohort%lmort_direct+ccohort%lmort_collateral+ccohort%lmort_infra) * ccohort%n - hio_m8_si_scls(io_si,scls) = hio_m8_si_scls(io_si,scls) + & - ccohort%frmort*ccohort%n - - !C13 discrimination - if(gpp_cached + ccohort%gpp_acc_hold > 0.0_r8)then - - hio_c13disc_si_scpf(io_si,scpf) = ((hio_c13disc_si_scpf(io_si,scpf) * gpp_cached) + & - (ccohort%c13disc_acc * ccohort%gpp_acc_hold)) / (gpp_cached + ccohort%gpp_acc_hold) - else - hio_c13disc_si_scpf(io_si,scpf) = 0.0_r8 - endif - - ! basal area [m2/ha] hio_ba_si_scpf(io_si,scpf) = hio_ba_si_scpf(io_si,scpf) + & 0.25_r8*3.14159_r8*((dbh/100.0_r8)**2.0_r8)*ccohort%n + ! also by size class only hio_ba_si_scls(io_si,scls) = hio_ba_si_scls(io_si,scls) + & 0.25_r8*3.14159_r8*((dbh/100.0_r8)**2.0_r8)*ccohort%n - - ! number density [/ha] - hio_nplant_si_scpf(io_si,scpf) = hio_nplant_si_scpf(io_si,scpf) + ccohort%n - + ! growth increment hio_ddbh_si_scpf(io_si,scpf) = hio_ddbh_si_scpf(io_si,scpf) + & ccohort%ddbhdt*ccohort%n end if + hio_m1_si_scpf(io_si,scpf) = hio_m1_si_scpf(io_si,scpf) + ccohort%bmort*ccohort%n + hio_m2_si_scpf(io_si,scpf) = hio_m2_si_scpf(io_si,scpf) + ccohort%hmort*ccohort%n + hio_m3_si_scpf(io_si,scpf) = hio_m3_si_scpf(io_si,scpf) + ccohort%cmort*ccohort%n + hio_m7_si_scpf(io_si,scpf) = hio_m7_si_scpf(io_si,scpf) + & + (ccohort%lmort_direct+ccohort%lmort_collateral+ccohort%lmort_infra) * ccohort%n + hio_m8_si_scpf(io_si,scpf) = hio_m8_si_scpf(io_si,scpf) + ccohort%frmort*ccohort%n + + hio_m1_si_scls(io_si,scls) = hio_m1_si_scls(io_si,scls) + ccohort%bmort*ccohort%n + hio_m2_si_scls(io_si,scls) = hio_m2_si_scls(io_si,scls) + ccohort%hmort*ccohort%n + hio_m3_si_scls(io_si,scls) = hio_m3_si_scls(io_si,scls) + ccohort%cmort*ccohort%n + hio_m7_si_scls(io_si,scls) = hio_m7_si_scls(io_si,scls) + & + (ccohort%lmort_direct+ccohort%lmort_collateral+ccohort%lmort_infra) * ccohort%n + hio_m8_si_scls(io_si,scls) = hio_m8_si_scls(io_si,scls) + & + ccohort%frmort*ccohort%n + + !C13 discrimination + if(gpp_cached + ccohort%gpp_acc_hold > 0.0_r8)then + hio_c13disc_si_scpf(io_si,scpf) = ((hio_c13disc_si_scpf(io_si,scpf) * gpp_cached) + & + (ccohort%c13disc_acc * ccohort%gpp_acc_hold)) / (gpp_cached + ccohort%gpp_acc_hold) + else + hio_c13disc_si_scpf(io_si,scpf) = 0.0_r8 + endif + + ! number density [/ha] + hio_nplant_si_scpf(io_si,scpf) = hio_nplant_si_scpf(io_si,scpf) + ccohort%n + + hio_agb_si_scls(io_si,scls) = hio_agb_si_scls(io_si,scls) + & total_c * ccohort%n * EDPftvarcon_inst%allom_agb_frac(ccohort%pft) * AREA_INV @@ -3170,6 +3169,12 @@ subroutine update_history_hydraulics(this,nc,nsites,sites,dt_tstep) if(hlm_use_ed_st3.eq.ifalse) then do scpf=1,nlevsclass*numpft if( abs(hio_nplant_si_scpf(io_si, scpf)-ncohort_scpf(scpf)) > 1.0E-8_r8 ) then + write(fates_log(),*) 'numpft:',numpft + write(fates_log(),*) 'nlevsclass:',nlevsclass + write(fates_log(),*) 'scpf:',scpf + write(fates_log(),*) 'io_si:',io_si + write(fates_log(),*) 'hio_nplant_si_scpf:',hio_nplant_si_scpf(io_si, scpf) + write(fates_log(),*) 'ncohort_scpf:',ncohort_scpf(scpf) write(fates_log(),*) 'nplant check on hio_nplant_si_scpf fails during hydraulics history updates' call endrun(msg=errMsg(sourcefile, __LINE__)) end if From 813ac667a32b90fbe31567f4d7df12d36c9ea1f0 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 5 Apr 2019 13:20:59 -0600 Subject: [PATCH 73/78] Added the leaf area weighted total leaf conductance to the restart --- main/FatesRestartInterfaceMod.F90 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/FatesRestartInterfaceMod.F90 b/main/FatesRestartInterfaceMod.F90 index e926dbcc81..777562e50a 100644 --- a/main/FatesRestartInterfaceMod.F90 +++ b/main/FatesRestartInterfaceMod.F90 @@ -95,6 +95,7 @@ module FatesRestartInterfaceMod integer, private :: ir_canopy_trim_co integer, private :: ir_size_class_lasttimestep_co integer, private :: ir_dbh_co + integer, private :: ir_g_sb_laweight_co integer, private :: ir_height_co integer, private :: ir_laimemory_co integer, private :: ir_nplant_co @@ -799,6 +800,10 @@ subroutine define_restart_vars(this, initialize_variables) units='0/1', flushval = flushone, & hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_isnew_co ) + call this%set_restart_var(vname='fates_gsblaweight',vtype=cohort_r8, & + long_name='ed cohort - leaf-area weighted total stomatal+blayer conductance', & + units='[m/s]*[m2]', flushval = flushzero, & + hlms='CLM:ALM', initialize=initialize_variables, ivar=ivar, index = ir_g_sb_laweight_co) ! Mixed dimension variables using the cohort vector ! ----------------------------------------------------------------------------------- @@ -1453,6 +1458,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_canopy_trim_co => this%rvars(ir_canopy_trim_co)%r81d, & rio_size_class_lasttimestep => this%rvars(ir_size_class_lasttimestep_co)%int1d, & rio_dbh_co => this%rvars(ir_dbh_co)%r81d, & + rio_g_sb_laweight_co => this%rvars(ir_g_sb_laweight_co)%r81d, & rio_height_co => this%rvars(ir_height_co)%r81d, & rio_laimemory_co => this%rvars(ir_laimemory_co)%r81d, & rio_nplant_co => this%rvars(ir_nplant_co)%r81d, & @@ -1637,6 +1643,7 @@ subroutine set_restart_vectors(this,nc,nsites,sites) rio_dbh_co(io_idx_co) = ccohort%dbh rio_height_co(io_idx_co) = ccohort%hite rio_laimemory_co(io_idx_co) = ccohort%laimemory + rio_g_sb_laweight_co(io_idx_co)= ccohort%g_sb_laweight rio_nplant_co(io_idx_co) = ccohort%n rio_gpp_acc_co(io_idx_co) = ccohort%gpp_acc @@ -2160,6 +2167,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) rio_canopy_trim_co => this%rvars(ir_canopy_trim_co)%r81d, & rio_size_class_lasttimestep => this%rvars(ir_size_class_lasttimestep_co)%int1d, & rio_dbh_co => this%rvars(ir_dbh_co)%r81d, & + rio_g_sb_laweight_co => this%rvars(ir_g_sb_laweight_co)%r81d, & rio_height_co => this%rvars(ir_height_co)%r81d, & rio_laimemory_co => this%rvars(ir_laimemory_co)%r81d, & rio_nplant_co => this%rvars(ir_nplant_co)%r81d, & @@ -2305,6 +2313,7 @@ subroutine get_restart_vectors(this, nc, nsites, sites) ccohort%canopy_trim = rio_canopy_trim_co(io_idx_co) ccohort%size_class_lasttimestep = rio_size_class_lasttimestep(io_idx_co) ccohort%dbh = rio_dbh_co(io_idx_co) + ccohort%g_sb_laweight= rio_g_sb_laweight_co(io_idx_co) ccohort%hite = rio_height_co(io_idx_co) ccohort%laimemory = rio_laimemory_co(io_idx_co) ccohort%n = rio_nplant_co(io_idx_co) From f6734abc87077334a0c912e844905e11b24b4d2f Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 5 Apr 2019 13:29:21 -0700 Subject: [PATCH 74/78] Fixed comment typo --- biogeochem/EDCanopyStructureMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biogeochem/EDCanopyStructureMod.F90 b/biogeochem/EDCanopyStructureMod.F90 index c027cfdc16..8dd5e139c1 100644 --- a/biogeochem/EDCanopyStructureMod.F90 +++ b/biogeochem/EDCanopyStructureMod.F90 @@ -1041,7 +1041,7 @@ subroutine PromoteIntoLayer(currentSite,currentPatch,i_lyr) else - ! Non-trivial case, at least 1 cohort's demotion + ! Non-trivial case, at least 1 cohort's promotion ! rate would exceed its area, given the trivial scale factor area_res = 0._r8 From 9ccadb5965d36ed8a721233875cdda64dd377d17 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 5 Apr 2019 14:30:56 -0600 Subject: [PATCH 75/78] Fixed typo --- main/EDMainMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index cc366cc0fe..bf153b1940 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -338,7 +338,7 @@ subroutine ed_integrate_state_variables(currentSite, bc_in ) currentSite%flux_in = currentSite%flux_in + currentCohort%npp_acc * currentCohort%n - ! Conducte Maintenance Turnover (parteh) + ! Conduct Maintenance Turnover (parteh) call currentCohort%prt%CheckMassConservation(ft,3) call PRTMaintTurnover(currentCohort%prt,ft,currentSite%is_drought) call currentCohort%prt%CheckMassConservation(ft,4) From 092042b25d875c39588c1bb9053f43881251da3f Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Fri, 5 Apr 2019 17:47:54 -0600 Subject: [PATCH 76/78] Turned off phenology during ST3. Litter fluxes needed to be coded in for this to work correctly. --- main/EDMainMod.F90 | 8 ++++++-- main/EDTypesMod.F90 | 12 ------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index bf153b1940..508489a19f 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -134,11 +134,15 @@ subroutine ed_ecosystem_dynamics(currentSite, bc_in) call ed_total_balance_check(currentSite, 0) - - if (do_ed_phenology) then + + ! We do not allow phenology while in ST3 mode either, it is hypothetically + ! possible to allow this, but we have not plugged in the litter fluxes + ! of flushing or turning over leaves for non-dynamics runs + if (hlm_use_ed_st3.eq.ifalse) then call phenology(currentSite, bc_in ) end if + if (hlm_use_ed_st3.eq.ifalse) then ! Bypass if ST3 call fire_model(currentSite, bc_in) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index c6a22ad6b1..e766f88c97 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -77,18 +77,6 @@ module EDTypesMod ! its leaves and should not be trying to allocate ! towards any growth. - ! Switches that turn on/off ED dynamics process (names are self explanatory) - ! IMPORTANT NOTE!!! THESE SWITCHES ARE EXPERIMENTAL. - ! THEY SHOULD CORRECTLY TURN OFF OR ON THE PROCESS, BUT.. THERE ARE VARIOUS - ! ASPECTS REGARDING DIAGNOSING RATES AND HOW THEY ARE REPORTED WHEN THESE - ! PROCESSES ARE OFF THAT NEED TO BE DISCUSSED AND CONSIDERED. - ! TO-DO: THESE SHOULD BE PARAMETERS IN THE FILE OR NAMELIST - ADDING THESE - ! WAS OUTSIDE THE SCOPE OF THE VERY LARGE CHANGESET WHERE THESE WERE FIRST - ! INTRODUCED (RGK 03-2017) - - logical, parameter :: do_ed_phenology = .true. - - ! Flag to turn on/off salinity effects on the effective "btran" ! btran stress function. From 2cf5a492efcc73b3113723ede5bb9f1855daa170 Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Sat, 6 Apr 2019 14:53:56 -0600 Subject: [PATCH 77/78] Removed the global use of do_ed_phenology --- main/EDMainMod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/main/EDMainMod.F90 b/main/EDMainMod.F90 index d890063c32..ddfae275c0 100644 --- a/main/EDMainMod.F90 +++ b/main/EDMainMod.F90 @@ -40,7 +40,6 @@ module EDMainMod use EDtypesMod , only : ed_site_type use EDtypesMod , only : ed_patch_type use EDtypesMod , only : ed_cohort_type - use EDTypesMod , only : do_ed_phenology use EDTypesMod , only : AREA use FatesConstantsMod , only : itrue,ifalse use FatesPlantHydraulicsMod , only : do_growthrecruiteffects From 518c862fd0f957bbf5c4fa94dee12479f0503ebf Mon Sep 17 00:00:00 2001 From: Ryan Knox Date: Tue, 9 Apr 2019 22:56:52 -0600 Subject: [PATCH 78/78] Change fates default parameter file to have 0 seed rain (it is broken atm) --- parameter_files/fates_params_default.cdl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/parameter_files/fates_params_default.cdl b/parameter_files/fates_params_default.cdl index b07ed8b784..bebbe3f720 100644 --- a/parameter_files/fates_params_default.cdl +++ b/parameter_files/fates_params_default.cdl @@ -1060,8 +1060,7 @@ data: fates_seed_germination_timescale = 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ; - fates_seed_rain = 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, 0.28, - 0.28, 0.28, 0.28 ; + fates_seed_rain = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0; fates_senleaf_long_fdrought = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;