From 732e822ef8b3e203d57bff948a31b5551aa26306 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 14 Jun 2023 16:19:12 -0700 Subject: [PATCH 01/33] Add fates luh2 land use module --- src/dyn_subgrid/dynFATESLandUseChangeMod.F90 | 194 +++++++++++++++++++ src/dyn_subgrid/dynSubgridDriverMod.F90 | 14 +- src/main/clm_initializeMod.F90 | 10 +- src/main/clm_varctl.F90 | 22 ++- src/main/controlMod.F90 | 6 + src/main/histFileMod.F90 | 11 ++ src/utils/clmfates_interfaceMod.F90 | 67 ++++++- 7 files changed, 300 insertions(+), 24 deletions(-) create mode 100644 src/dyn_subgrid/dynFATESLandUseChangeMod.F90 diff --git a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 new file mode 100644 index 0000000000..6329eaba47 --- /dev/null +++ b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 @@ -0,0 +1,194 @@ +module dynFATESLandUseChangeMod + +#include "shr_assert.h" + + !--------------------------------------------------------------------------- + ! !DESCRIPTION: + ! Handle reading of the land use harmonization (LUH2) dataset + + ! !USES: + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_log_mod , only : errMsg => shr_log_errMsg + use decompMod , only : bounds_type, BOUNDS_LEVEL_PROC + use abortutils , only : endrun + use dynFileMod , only : dyn_file_type + use dynVarTimeUninterpMod , only : dyn_var_time_uninterp_type + use clm_varcon , only : grlnd + use clm_varctl , only : iulog + + implicit none + + private + + real(r8), allocatable, public :: landuse_transitions(:,:) + real(r8), allocatable, public :: landuse_states(:,:) + + integer, public, parameter :: num_landuse_transition_vars = 108 + integer, public, parameter :: num_landuse_state_vars = 12 + + type(dyn_file_type), target :: dynFatesLandUse_file + + ! Land use name arrays + character(len=5), public, parameter :: landuse_state_varnames(num_landuse_state_vars) = & + [character(len=5) :: 'primf','primn','secdf','secdn','pastr','range', & + 'urban','c3ann','c4ann','c3per','c4per','c3nfx'] + + character(len=14), public, parameter :: landuse_transition_varnames(num_landuse_transition_vars) = & + [character(len=14) :: 'primf_to_secdn','primf_to_pastr','primf_to_range','primf_to_urban', & + 'primf_to_c3ann','primf_to_c4ann','primf_to_c3per','primf_to_c4per','primf_to_c3nfx', & + 'primn_to_secdf','primn_to_pastr','primn_to_range','primn_to_urban', & + 'primn_to_c3ann','primn_to_c4ann','primn_to_c3per','primn_to_c4per','primn_to_c3nfx', & + 'secdf_to_secdn','secdf_to_pastr','secdf_to_range','secdf_to_urban', & + 'secdf_to_c3ann','secdf_to_c4ann','secdf_to_c3per','secdf_to_c4per','secdf_to_c3nfx', & + 'secdn_to_secdf','secdn_to_pastr','secdn_to_range','secdn_to_urban', & + 'secdn_to_c3ann','secdn_to_c4ann','secdn_to_c3per','secdn_to_c4per','secdn_to_c3nfx', & + 'pastr_to_secdf','pastr_to_secdn','pastr_to_range','pastr_to_urban', & + 'pastr_to_c3ann','pastr_to_c4ann','pastr_to_c3per','pastr_to_c4per','pastr_to_c3nfx', & + 'range_to_secdf','range_to_secdn','range_to_pastr','range_to_urban', & + 'range_to_c3ann','range_to_c4ann','range_to_c3per','range_to_c4per','range_to_c3nfx', & + 'urban_to_secdf','urban_to_secdn','urban_to_pastr','urban_to_range', & + 'urban_to_c3ann','urban_to_c4ann','urban_to_c3per','urban_to_c4per','urban_to_c3nfx', & + 'c3ann_to_c4ann','c3ann_to_c3per','c3ann_to_c4per','c3ann_to_c3nfx', & + 'c3ann_to_secdf','c3ann_to_secdn','c3ann_to_pastr','c3ann_to_range','c3ann_to_urban', & + 'c4ann_to_c3ann','c4ann_to_c3per','c4ann_to_c4per','c4ann_to_c3nfx', & + 'c4ann_to_secdf','c4ann_to_secdn','c4ann_to_pastr','c4ann_to_range','c4ann_to_urban', & + 'c3per_to_c3ann','c3per_to_c4ann','c3per_to_c4per','c3per_to_c3nfx', & + 'c3per_to_secdf','c3per_to_secdn','c3per_to_pastr','c3per_to_range','c3per_to_urban', & + 'c4per_to_c3ann','c4per_to_c4ann','c4per_to_c3per','c4per_to_c3nfx', & + 'c4per_to_secdf','c4per_to_secdn','c4per_to_pastr','c4per_to_range','c4per_to_urban', & + 'c3nfx_to_c3ann','c3nfx_to_c4ann','c3nfx_to_c3per','c3nfx_to_c4per', & + 'c3nfx_to_secdf','c3nfx_to_secdn','c3nfx_to_pastr','c3nfx_to_range','c3nfx_to_urban'] + + type(dyn_var_time_uninterp_type) :: landuse_transition_vars(num_landuse_transition_vars) ! value of each landuse variable + type(dyn_var_time_uninterp_type) :: landuse_state_vars(num_landuse_state_vars) ! value of each landuse variable + + public :: dynFatesLandUseInit + public :: dynFatesLandUseInterp + +contains + + !----------------------------------------------------------------------- + subroutine dynFatesLandUseInit(bounds, landuse_filename) + + ! !DESCRIPTION: + ! Initialize data structures for land use information. + + ! !USES: + use clm_varctl , only : use_cn, use_fates_luh + use dynVarTimeUninterpMod , only : dyn_var_time_uninterp_type + use dynTimeInfoMod , only : YEAR_POSITION_START_OF_TIMESTEP + use dynTimeInfoMod , only : YEAR_POSITION_END_OF_TIMESTEP + + ! !ARGUMENTS: + type(bounds_type), intent(in) :: bounds ! proc-level bounds + character(len=*) , intent(in) :: landuse_filename ! name of file containing land use information + + ! !LOCAL VARIABLES + integer :: varnum, i ! counter for harvest variables + integer :: landuse_shape(1) ! land use shape + integer :: num_points ! number of spatial points + integer :: ier ! error code + real(r8), allocatable :: this_data(:) ! data for a single harvest variable + ! + character(len=*), parameter :: subname = 'dynFatesLandUseInit' + !----------------------------------------------------------------------- + + SHR_ASSERT_ALL(bounds%level == BOUNDS_LEVEL_PROC, subname // ': argument must be PROC-level bounds') + + if (use_cn) return ! Use this as a protection in lieu of build namelist check? + + ! Allocate and initialize the land use arrays + allocate(landuse_states(num_landuse_state_vars,bounds%begg:bounds%endg),stat=ier) + if (ier /= 0) then + call endrun(msg=' allocation error for landuse_states'//errMsg(__FILE__, __LINE__)) + end if + allocate(landuse_transitions(num_landuse_transition_vars,bounds%begg:bounds%endg),stat=ier) + if (ier /= 0) then + call endrun(msg=' allocation error for landuse_transitions'//errMsg(__FILE__, __LINE__)) + end if + + landuse_states = 0._r8 + landuse_transitions = 0._r8 + + if (use_fates_luh) then + + ! Generate the dyn_file_type object + ! TO DO: check whether to initialize with start or end + dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_START_OF_TIMESTEP) + ! dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP) + + ! Get initial land use data + num_points = (bounds%endg - bounds%begg + 1) + landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor? + do varnum = 1, num_landuse_transition_vars + landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( & + dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), & + dim1name=grlnd, conversion_factor=1.0_r8, & + do_check_sums_equal_1=.false., data_shape=landuse_shape) + end do + do varnum = 1, num_landuse_state_vars + landuse_state_vars(varnum) = dyn_var_time_uninterp_type( & + dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), & + dim1name=grlnd, conversion_factor=1.0_r8, & + do_check_sums_equal_1=.false., data_shape=landuse_shape) + end do + end if + + ! Since fates needs state data during initialization, make sure to call + ! the interpolation routine at the start + call dynFatesLandUseInterp(bounds,init_state=.true.) + + end subroutine dynFatesLandUseInit + + + !----------------------------------------------------------------------- + subroutine dynFatesLandUseInterp(bounds, init_state) + + use dynTimeInfoMod , only : time_info_type + use clm_varctl , only : use_cn + + ! !ARGUMENTS: + type(bounds_type), intent(in) :: bounds ! proc-level bounds + logical, optional, intent(in) :: init_state ! fates needs state for initialization + + ! !LOCAL VARIABLES: + integer :: varnum + integer :: i + logical :: init_flag + real(r8), allocatable :: this_data(:) + character(len=*), parameter :: subname = 'dynFatesLandUseInterp' + !----------------------------------------------------------------------- + SHR_ASSERT_ALL(bounds%level == BOUNDS_LEVEL_PROC, subname // ': argument must be PROC-level bounds') + + ! This shouldn't be called by cn currently, but return if it is + if (use_cn) return ! Use this as a protection in lieu of build namelist check? + + init_flag = .false. + if (present(init_state)) then + init_flag = init_state + end if + + ! input land use data for current year are stored in year+1 in the file + call dynFatesLandUse_file%time_info%set_current_year_get_year(1) + + if (dynFatesLandUse_file%time_info%is_before_time_series() .and. .not.(init_flag)) then + ! Reset the land use transitions to zero for safety + landuse_transitions(1:num_landuse_transition_vars,bounds%begg:bounds%endg) = 0._r8 + landuse_states(1:num_landuse_state_vars,bounds%begg:bounds%endg) = 0._r8 + else + ! Right now we don't account for the topounits + allocate(this_data(bounds%begg:bounds%endg)) + do varnum = 1, num_landuse_transition_vars + call landuse_transition_vars(varnum)%get_current_data(this_data) + landuse_transitions(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg) + end do + do varnum = 1, num_landuse_state_vars + call landuse_state_vars(varnum)%get_current_data(this_data) + landuse_states(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg) + end do + deallocate(this_data) + end if + + end subroutine dynFatesLandUseInterp + +end module dynFATESLandUseChangeMod diff --git a/src/dyn_subgrid/dynSubgridDriverMod.F90 b/src/dyn_subgrid/dynSubgridDriverMod.F90 index dada3e9975..c15a23b577 100644 --- a/src/dyn_subgrid/dynSubgridDriverMod.F90 +++ b/src/dyn_subgrid/dynSubgridDriverMod.F90 @@ -201,10 +201,11 @@ subroutine dynSubgrid_driver(bounds_proc, ! OUTSIDE any loops over clumps in the driver. ! ! !USES: - use clm_varctl , only : use_cn, use_fates - use dynInitColumnsMod , only : initialize_new_columns - use dynConsBiogeophysMod , only : dyn_hwcontent_init, dyn_hwcontent_final - use dynEDMod , only : dyn_ED + use clm_varctl , only : use_cn, use_fates, use_fates_luh + use dynInitColumnsMod , only : initialize_new_columns + use dynConsBiogeophysMod , only : dyn_hwcontent_init, dyn_hwcontent_final + use dynEDMod , only : dyn_ED + use dynFATESLandUseChangeMod, only : dynFatesLandUseInterp ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds_proc ! processor-level bounds @@ -288,6 +289,11 @@ subroutine dynSubgrid_driver(bounds_proc, if (get_do_transient_urban()) then call dynurban_interp(bounds_proc) end if + + if (use_fates_luh) then + call dynFatesLandUseInterp + end if + ! ========================================================================== ! Do land cover change that does not require I/O ! ========================================================================== diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 7988fbfc7b..1a04c10749 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -132,7 +132,7 @@ subroutine initialize2(ni,nj) use clm_varpar , only : natpft_size,cft_size use clm_varctl , only : fsurdat use clm_varctl , only : finidat, finidat_interp_source, finidat_interp_dest, fsurdat - use clm_varctl , only : use_cn, use_fates + use clm_varctl , only : use_cn, use_fates, use_fates_luh use clm_varctl , only : use_crop, ndep_from_cpl, fates_spitfire_mode use clm_varorb , only : eccen, mvelpp, lambm0, obliqr use landunit_varcon , only : landunit_varcon_init, max_lunit, numurbl @@ -140,7 +140,7 @@ subroutine initialize2(ni,nj) use decompInitMod , only : decompInit_clumps, decompInit_glcp use domainMod , only : domain_check, ldomain, domain_init use surfrdMod , only : surfrd_get_data - use controlMod , only : NLFilename + use controlMod , only : NLFilename, fluh_timeseries use initGridCellsMod , only : initGridCells use ch4varcon , only : ch4conrd use UrbanParamsType , only : UrbanInput, IsSimpleBuildTemp @@ -172,6 +172,7 @@ subroutine initialize2(ni,nj) use CNSharedParamsMod , only : CNParamsSetSoilDepth use NutrientCompetitionFactoryMod , only : create_nutrient_competition_method use FATESFireFactoryMod , only : scalar_lightning + use dynFATESLandUseChangeMod , only : dynFatesLandUseInit ! ! !ARGUMENTS integer, intent(in) :: ni, nj ! global grid sizes @@ -403,6 +404,11 @@ subroutine initialize2(ni,nj) call dynSubgrid_init(bounds_proc, glc_behavior, crop_inst) call t_stopf('init_dyn_subgrid') + ! Initialize fates LUH2 usage + if (use_fates_luh) then + call dynFatesLandUseInit(bounds_proc, fluh_timeseries) + end if + ! Initialize baseline water and energy states needed for dynamic subgrid operation ! This will be overwritten by the restart file, but needs to be done for a cold start ! case. diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 9be9af2f73..8dbb4afc64 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -258,17 +258,19 @@ module clm_varctl integer, public :: fates_spitfire_mode = 0 ! 0 for no fire; 1 for constant ignitions; > 1 for external data (lightning and/or anthropogenic ignitions) ! see bld/namelist_files/namelist_definition_clm4_5.xml for details - logical, public :: use_fates_tree_damage = .false. ! true => turn on tree damage module - logical, public :: use_fates_logging = .false. ! true => turn on logging module - logical, public :: use_fates_planthydro = .false. ! true => turn on fates hydro + logical, public :: use_fates_tree_damage = .false. ! true => turn on tree damage module + logical, public :: use_fates_logging = .false. ! true => turn on logging module + logical, public :: use_fates_planthydro = .false. ! true => turn on fates hydro logical, public :: use_fates_cohort_age_tracking = .false. ! true => turn on cohort age tracking - logical, public :: use_fates_ed_st3 = .false. ! true => static stand structure - logical, public :: use_fates_ed_prescribed_phys = .false. ! true => prescribed physiology - logical, public :: use_fates_inventory_init = .false. ! true => initialize fates from inventory - logical, public :: use_fates_fixed_biogeog = .false. ! true => use fixed biogeography mode - logical, public :: use_fates_nocomp = .false. ! true => use no comopetition mode - logical, public :: use_fates_sp = .false. ! true => use FATES satellite phenology mode - character(len=256), public :: fates_inventory_ctrl_filename = '' ! filename for inventory control + logical, public :: use_fates_ed_st3 = .false. ! true => static stand structure + logical, public :: use_fates_ed_prescribed_phys = .false. ! true => prescribed physiology + logical, public :: use_fates_inventory_init = .false. ! true => initialize fates from inventory + logical, public :: use_fates_fixed_biogeog = .false. ! true => use fixed biogeography mode + logical, public :: use_fates_nocomp = .false. ! true => use no comopetition mode + logical, public :: use_fates_sp = .false. ! true => use FATES satellite phenology mode + logical, public :: use_fates_luh = .false. ! true => use FATES satellite phenology mode + character(len=256), public :: fluh_timeseries = '' ! filename for inventory control + character(len=256), public :: fates_inventory_ctrl_filename = '' ! filename for inventory control !---------------------------------------------------------- ! LUNA switches diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index a07228aa0d..3b669063fe 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -228,6 +228,8 @@ subroutine control_init(dtime) use_fates_fixed_biogeog, & use_fates_nocomp, & use_fates_sp, & + use_fates_luh, & + fluh_timeseries, & fates_inventory_ctrl_filename, & fates_parteh_mode, & use_fates_tree_damage @@ -714,8 +716,10 @@ subroutine control_spmd() call mpi_bcast (use_fates_fixed_biogeog, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_nocomp, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_sp, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (use_fates_luh, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (fates_inventory_ctrl_filename, len(fates_inventory_ctrl_filename), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_paramfile, len(fates_paramfile) , MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (fluh_timeseries, len(fates_paramfile) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_parteh_mode, 1, MPI_INTEGER, 0, mpicom, ier) ! flexibleCN nitrogen model @@ -1058,6 +1062,8 @@ subroutine control_print () write(iulog, *) ' use_fates_fixed_biogeog = ', use_fates_fixed_biogeog write(iulog, *) ' use_fates_nocomp = ', use_fates_nocomp write(iulog, *) ' use_fates_sp = ', use_fates_sp + write(iulog, *) ' use_fates_luh= ', use_fates_sp + write(iulog, *) ' fluh_timeseries = ',fluh_timeseries write(iulog, *) ' fates_inventory_ctrl_filename = ',fates_inventory_ctrl_filename end if end subroutine control_print diff --git a/src/main/histFileMod.F90 b/src/main/histFileMod.F90 index d5175342f0..97597fee71 100644 --- a/src/main/histFileMod.F90 +++ b/src/main/histFileMod.F90 @@ -26,6 +26,7 @@ module histFileMod use FatesInterfaceTypesMod , only : nlevsclass, nlevage, nlevcoage use FatesInterfaceTypesMod , only : nlevheight use FatesInterfaceTypesMod , only : nlevdamage + use FatesConstantsMod , only : n_landuse_cats use EDTypesMod , only : nfsc use FatesLitterMod , only : ncwd use PRTGenericMod , only : num_elements_fates => num_elements @@ -2469,6 +2470,8 @@ subroutine htape_create (t, histrest) call ncd_defdim(lnfid, 'fates_levelage', num_elements_fates * nlevage, dimid) call ncd_defdim(lnfid, 'fates_levagefuel', nlevage * nfsc, dimid) call ncd_defdim(lnfid, 'fates_levclscpf', nclmax*nlevsclass*numpft_fates, dimid) + call ncd_defdim(lnfid, 'fates_levlanduse', n_landuse_cats, dimid) + call ncd_defdim(lnfid, 'fates_levlulu', n_landuse_cats * n_landuse_cats, dimid) end if if ( .not. lhistrest )then @@ -3021,6 +3024,7 @@ subroutine htape_timeconst(t, mode) use FatesInterfaceTypesMod, only : fates_hdim_scmap_levcdpf use FatesInterfaceTypesMod, only : fates_hdim_cdmap_levcdpf use FatesInterfaceTypesMod, only : fates_hdim_pftmap_levcdpf + use FatesInterfaceTypesMod, only : fates_hdim_levlanduse ! @@ -3149,6 +3153,8 @@ subroutine htape_timeconst(t, mode) long_name='FATES pft index of the combined damage-size-PFT dimension', ncid=nfid(t)) call ncd_defvar(varname='fates_levcdam', xtype=tape(t)%ncprec, dim1name='fates_levcdam', & long_name='FATES damage class lower bound', units='unitless', ncid=nfid(t)) + call ncd_defvar(varname='fates_levlanduse',xtype=ncd_int, dim1name='fates_levlanduse', & + long_name='FATES land use label', ncid=nfid(t)) end if @@ -3198,6 +3204,7 @@ subroutine htape_timeconst(t, mode) call ncd_io(varname='fates_scmap_levcdpf',data=fates_hdim_scmap_levcdpf, ncid=nfid(t), flag='write') call ncd_io(varname='fates_cdmap_levcdpf',data=fates_hdim_cdmap_levcdpf, ncid=nfid(t), flag='write') call ncd_io(varname='fates_pftmap_levcdpf',data=fates_hdim_pftmap_levcdpf, ncid=nfid(t), flag='write') + call ncd_io(varname='fates_levlanduse',data=fates_hdim_levlanduse, ncid=nfid(t), flag='write') end if endif @@ -5515,6 +5522,10 @@ subroutine hist_addfld2d (fname, type2d, units, avgflag, long_name, type1d_out, num2d = nlevage*nfsc case('fates_levclscpf') num2d = nclmax * nclmax * numpft_fates + case ('fates_levlanduse') + num2d = n_landuse_cats + case ('fates_levlulu') + num2d = n_landuse_cats * n_landuse_cats case('cft') if (cft_size > 0) then num2d = cft_size diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index c169d710ef..142348b444 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -60,6 +60,7 @@ module CLMFatesInterfaceMod use clm_varctl , only : use_fates_fixed_biogeog use clm_varctl , only : use_fates_nocomp use clm_varctl , only : use_fates_sp + use clm_varctl , only : use_fates_luh use clm_varctl , only : fates_inventory_ctrl_filename use clm_varctl , only : use_nitrif_denitrif use clm_varctl , only : use_lch4 @@ -129,6 +130,7 @@ module CLMFatesInterfaceMod use PRTGenericMod , only : num_elements use FatesInterfaceTypesMod, only : hlm_stepsize use FatesInterfaceTypesMod, only : fates_maxPatchesPerSite + use FatesInterfaceTypesMod, only : hlm_num_luh2_states use EDMainMod , only : ed_ecosystem_dynamics use EDMainMod , only : ed_update_site use EDInitMod , only : zero_site @@ -159,6 +161,12 @@ module CLMFatesInterfaceMod use FatesConstantsMod , only : hlm_harvest_area_fraction use FatesConstantsMod , only : hlm_harvest_carbon use perf_mod , only : t_startf, t_stopf + + use dynFATESLandUseChangeMod, only : num_landuse_transition_vars, num_landuse_state_vars + use dynFATESLandUseChangeMod, only : landuse_transitions, landuse_states + use dynFATESLandUseChangeMod, only : landuse_transition_varnames, landuse_state_varnames + use dynFATESLandUseChangeMod, only : dynFatesLandUseInterp + implicit none type, public :: f2hmap_type @@ -353,6 +361,9 @@ subroutine CLMFatesGlobals2() integer :: pass_is_restart integer :: pass_cohort_age_tracking integer :: pass_tree_damage + integer :: pass_use_luh + integer :: pass_num_luh_states + integer :: pass_num_luh_transitions call t_startf('fates_globals2') @@ -491,6 +502,19 @@ subroutine CLMFatesGlobals2() call set_fates_ctrlparms('num_lu_harvest_cats',ival=pass_num_lu_harvest_cats) call set_fates_ctrlparms('use_logging',ival=pass_logging) + if(use_fates_luh) then + pass_use_luh = 1 + pass_num_luh_states = num_landuse_state_vars + pass_num_luh_transitions = num_landuse_transition_vars + else + pass_use_luh = 0 + pass_num_luh_states = 0 + pass_num_luh_transitions = 0 + end if + call set_fates_ctrlparms('use_luh2',ival=pass_use_luh) + call set_fates_ctrlparms('num_luh2_states',ival=pass_num_luh_states) + call set_fates_ctrlparms('num_luh2_transitions',ival=pass_num_luh_transitions) + if(use_fates_inventory_init) then pass_inventory_init = 1 else @@ -693,7 +717,9 @@ subroutine init(this, bounds_proc ) ndecomp = col%nbedrock(c) - call allocate_bcin(this%fates(nc)%bc_in(s),col%nbedrock(c),ndecomp, num_harvest_inst,surfpft_lb,surfpft_ub) + call allocate_bcin(this%fates(nc)%bc_in(s),col%nbedrock(c),ndecomp, & + num_harvest_inst, num_landuse_state_vars, num_landuse_transition_vars, & + surfpft_lb,surfpft_ub) call allocate_bcout(this%fates(nc)%bc_out(s),col%nbedrock(c),ndecomp) call zero_bcs(this%fates(nc),s) @@ -996,10 +1022,15 @@ subroutine dynamics_driv(this, nc, bounds_clump, & write(iulog,*) harvest_units call endrun(msg=errMsg(sourcefile, __LINE__)) end if - - endif + if (use_fates_luh) then + this%fates(nc)%bc_in(s)%hlm_luh_states = landuse_states(:,g) + this%fates(nc)%bc_in(s)%hlm_luh_state_names = landuse_state_varnames + this%fates(nc)%bc_in(s)%hlm_luh_transitions = landuse_transitions(:,g) + this%fates(nc)%bc_in(s)%hlm_luh_transition_names = landuse_transition_varnames + end if + end do ! Nutrient uptake fluxes have been accumulating with each short @@ -1703,9 +1734,9 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, & real(r8) :: vol_ice real(r8) :: eff_porosity integer :: nlevsoil ! Number of soil layers at each site - integer :: j + integer :: i, j integer :: s - integer :: c + integer :: c, g integer :: p ! HLM patch index integer :: ft ! plant functional type @@ -1795,6 +1826,18 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, & call HydrSiteColdStart(this%fates(nc)%sites,this%fates(nc)%bc_in) end if + do s = 1,this%fates(nc)%nsites + c = this%f2hmap(nc)%fcolumn(s) + g = col_pp%gridcell(c) + + if (use_fates_luh) then + this%fates(nc)%bc_in(s)%hlm_luh_states = landuse_states(:,g) + this%fates(nc)%bc_in(s)%hlm_luh_state_names = landuse_state_varnames + this%fates(nc)%bc_in(s)%hlm_luh_transitions = landuse_transitions(:,g) + this%fates(nc)%bc_in(s)%hlm_luh_transition_names = landuse_transition_varnames + end if + end do + ! Newly initialized patches need a starting temperature call init_patches(this%fates(nc)%nsites, this%fates(nc)%sites, & this%fates(nc)%bc_in) @@ -2750,6 +2793,7 @@ subroutine init_history_io(this,bounds_proc) use FatesIOVariableKindMod, only : site_height_r8, site_elem_r8, site_elpft_r8 use FatesIOVariableKindMod, only : site_elcwd_r8, site_elage_r8, site_agefuel_r8 use FatesIOVariableKindMod, only : site_cdpf_r8, site_cdsc_r8, site_clscpf_r8 + use FatesIOVariableKindMod, only : site_landuse_r8, site_lulu_r8 use FatesIODimensionsMod, only : fates_bounds_type @@ -2852,7 +2896,8 @@ subroutine init_history_io(this,bounds_proc) site_can_r8,site_cnlf_r8, site_cnlfpft_r8, site_scag_r8, & site_scagpft_r8, site_agepft_r8, site_elem_r8, site_elpft_r8, & site_elcwd_r8, site_elage_r8, site_agefuel_r8, & - site_cdsc_r8, site_cdpf_r8) + site_cdsc_r8, site_cdpf_r8, & + site_landuse_r8, site_lulu_r8) d_index = fates_hist%dim_kinds(dk_index)%dim2_index @@ -3145,7 +3190,8 @@ subroutine hlm_bounds_to_fates_bounds(hlm, fates) use FatesLitterMod, only : ncwd use EDtypesMod, only : nlevleaf, nclmax use FatesInterfaceTypesMod, only : numpft_fates => numpft - + use FatesConstantsMod, only : n_landuse_cats + implicit none @@ -3234,7 +3280,12 @@ subroutine hlm_bounds_to_fates_bounds(hlm, fates) fates%clscpf_begin = 1 fates%clscpf_end = numpft_fates * nlevsclass * nclmax - + + fates%landuse_begin = 1 + fates%landuse_end = n_landuse_cats + + fates%lulu_begin = 1 + fates%lulu_end = n_landuse_cats * n_landuse_cats call t_stopf('fates_hlm2fatesbnds') From f90a6819a817fba2b60224b3e4c5b87309acab5c Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 14 Jun 2023 16:57:08 -0700 Subject: [PATCH 02/33] add fates luh2 namelist definition and defaults --- bld/namelist_files/namelist_defaults_ctsm.xml | 6 ++++++ bld/namelist_files/namelist_definition_ctsm.xml | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 6bb5d60aa7..4a036b63bd 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1514,6 +1514,11 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP5-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + + +lnd/clm2/luh/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c230415.nc + .true. .true. @@ -2669,6 +2674,7 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 .false. .false. .false. +.false. 1 .true. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index f51c577c09..a5c7d0a075 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -718,6 +718,21 @@ Full pathname to the inventory initialization control file. (Only relevant if FATES is on). + + +If TRUE, enable use of land use state and transition data from luh_timeseries file. +(Only valid for fates land use change runs, where there is a luh_timeseries file.) +(Also, only valid for use_fates = true and is incompatible with transient runs currently.) + + + + +Full pathname of unified land use harmonization data file. This causes the land-use +types to vary over time. + + Toggle to turn on the LUNA model, to effect Photosynthesis by leaf Nitrogen From 6fe7eecc2ba895d0ea5f0e8080ff53401a051e8a Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 20 Jun 2023 10:59:55 -0700 Subject: [PATCH 03/33] update build namelist logic for fates luh mode --- bld/CLMBuildNamelist.pm | 25 ++++++++++++++----- .../namelist_definition_ctsm.xml | 2 ++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 02d9799487..16afd715da 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -773,8 +773,9 @@ sub setup_cmdl_fates_mode { } else { # dis-allow fates specific namelist items with non-fates runs my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", - "use_fates_cohort_age_tracking", - "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","use_fates_sp","fates_inventory_ctrl_filename","use_fates_logging","fates_parteh_mode","use_fates_tree_damage" ); + "use_fates_cohort_age_tracking","use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp", + "use_fates_sp","fates_inventory_ctrl_filename","use_fates_logging","fates_parteh_mode", + "use_fates_tree_damage","use_fates_luh","fluh_timeseries" ); # dis-allow fates specific namelist items with non-fates runs foreach my $var ( @list ) { if ( defined($nl->get_value($var)) ) { @@ -4181,8 +4182,8 @@ sub setup_logic_fates { if (&value_is_true( $nl_flags->{'use_fates'}) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", - "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp", - "use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage" ); + "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","use_fates_logging", + "fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage","use_fates_luh" ); foreach my $var ( @list ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'}, 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} ); @@ -4203,14 +4204,14 @@ sub setup_logic_fates { # spit-fire can't be on with FATES SP mode is active if ( $nl->get_value('fates_spitfire_mode') > 0 ) { $log->fatal_error('fates_spitfire_mode can NOT be set to greater than 0 when use_fates_sp is true'); + } } - } } my $var = "use_fates_inventory_init"; if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { $var = "fates_inventory_ctrl_filename"; - my $fname = substr $nl->get_value($var), 1, -1; # ignore first and last positions of string because those are quote characters + my $fname = substr $nl->get_value($var), 1, -1; # ignore first and last positions of string because those are quote characters if ( ! defined($nl->get_value($var)) ) { $log->fatal_error("$var is required when use_fates_inventory_init is set" ); } elsif ( ! -f "$fname" ) { @@ -4218,6 +4219,18 @@ sub setup_logic_fates { } } } + my $var = "use_fates_luh"; + if ( defined($nl->get_value($var)) ) { + if ( &value_is_true($nl->get_value($var)) ) { + $var = "fluh_timeseries"; + my $fname = substr $nl->get_value($var), 1, -1; # ignore first and last positions of string because those are quote characters + if ( ! defined($nl->get_value($var)) ) { + $log->fatal_error("$var is required when use_fates_luh is set" ); + } elsif ( ! -f "$fname" ) { + $log->fatal_error("$fname does NOT point to a valid filename" ); + } + } + } } } diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index a5c7d0a075..5e1698bc06 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -731,6 +731,8 @@ If TRUE, enable use of land use state and transition data from luh_timeseries fi input_pathname="abs" group="elm_inparm" valid_values="" > Full pathname of unified land use harmonization data file. This causes the land-use types to vary over time. +(Required, if use_fates_luh=T) +(Only relevant if FATES is on). Date: Wed, 21 Jun 2023 09:22:17 -0700 Subject: [PATCH 04/33] change call for setting time --- src/dyn_subgrid/dynFATESLandUseChangeMod.F90 | 44 ++++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 index 6329eaba47..2180572c0a 100644 --- a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 +++ b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 @@ -112,26 +112,26 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename) if (use_fates_luh) then - ! Generate the dyn_file_type object - ! TO DO: check whether to initialize with start or end - dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_START_OF_TIMESTEP) - ! dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP) - - ! Get initial land use data - num_points = (bounds%endg - bounds%begg + 1) - landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor? - do varnum = 1, num_landuse_transition_vars - landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( & - dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), & - dim1name=grlnd, conversion_factor=1.0_r8, & - do_check_sums_equal_1=.false., data_shape=landuse_shape) - end do - do varnum = 1, num_landuse_state_vars - landuse_state_vars(varnum) = dyn_var_time_uninterp_type( & - dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), & - dim1name=grlnd, conversion_factor=1.0_r8, & - do_check_sums_equal_1=.false., data_shape=landuse_shape) - end do + ! Generate the dyn_file_type object + ! TO DO: check whether to initialize with start or end + ! dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_START_OF_TIMESTEP) + dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP) + + ! Get initial land use data + num_points = (bounds%endg - bounds%begg + 1) + landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor? + do varnum = 1, num_landuse_transition_vars + landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( & + dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), & + dim1name=grlnd, conversion_factor=1.0_r8, & + do_check_sums_equal_1=.false., data_shape=landuse_shape) + end do + do varnum = 1, num_landuse_state_vars + landuse_state_vars(varnum) = dyn_var_time_uninterp_type( & + dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), & + dim1name=grlnd, conversion_factor=1.0_r8, & + do_check_sums_equal_1=.false., data_shape=landuse_shape) + end do end if ! Since fates needs state data during initialization, make sure to call @@ -168,8 +168,8 @@ subroutine dynFatesLandUseInterp(bounds, init_state) init_flag = init_state end if - ! input land use data for current year are stored in year+1 in the file - call dynFatesLandUse_file%time_info%set_current_year_get_year(1) + ! Get the current year + call dynFatesLandUse_file%time_info%set_current_year() if (dynFatesLandUse_file%time_info%is_before_time_series() .and. .not.(init_flag)) then ! Reset the land use transitions to zero for safety From 90b6050be73000efa63899b4ab0326462e6a9958 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 21 Jun 2023 16:27:07 -0600 Subject: [PATCH 05/33] correct bad copies --- src/dyn_subgrid/dynSubgridDriverMod.F90 | 2 +- src/utils/clmfates_interfaceMod.F90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dyn_subgrid/dynSubgridDriverMod.F90 b/src/dyn_subgrid/dynSubgridDriverMod.F90 index c15a23b577..e5ca3f002e 100644 --- a/src/dyn_subgrid/dynSubgridDriverMod.F90 +++ b/src/dyn_subgrid/dynSubgridDriverMod.F90 @@ -291,7 +291,7 @@ subroutine dynSubgrid_driver(bounds_proc, end if if (use_fates_luh) then - call dynFatesLandUseInterp + call dynFatesLandUseInterp(bounds_proc) end if ! ========================================================================== diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index 142348b444..c136523518 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -1828,7 +1828,7 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, & do s = 1,this%fates(nc)%nsites c = this%f2hmap(nc)%fcolumn(s) - g = col_pp%gridcell(c) + g = col%gridcell(c) if (use_fates_luh) then this%fates(nc)%bc_in(s)%hlm_luh_states = landuse_states(:,g) From 3bbbc53590a480a73c541d4454818102a591d255 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Nov 2023 12:40:59 -0800 Subject: [PATCH 06/33] update fates setup loging to use remove_leading_and_trailing_quotes function --- bld/CLMBuildNamelist.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 3dec1dffbc..bc9f443399 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4406,7 +4406,7 @@ sub setup_logic_fates { if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { $var = "fates_inventory_ctrl_filename"; - my $fname = substr $nl->get_value($var), 1, -1; # ignore first and last positions of string because those are quote characters + my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); if ( ! defined($nl->get_value($var)) ) { $log->fatal_error("$var is required when use_fates_inventory_init is set" ); } elsif ( ! -f "$fname" ) { @@ -4418,7 +4418,7 @@ sub setup_logic_fates { if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { $var = "fluh_timeseries"; - my $fname = substr $nl->get_value($var), 1, -1; # ignore first and last positions of string because those are quote characters + my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); if ( ! defined($nl->get_value($var)) ) { $log->fatal_error("$var is required when use_fates_luh is set" ); } elsif ( ! -f "$fname" ) { From 96b827c90568af10f420530f31b1d765d16c061c Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Nov 2023 12:41:58 -0800 Subject: [PATCH 07/33] add test to check for namelist build error conditions --- bld/unit_testers/build-namelist_test.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 4c717a58bf..13b6cd879e 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -1061,6 +1061,16 @@ sub cat_and_create_namelistinfile { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm4_5", }, + "useinventorybutnotfile" =>{ options=>"-bgc fates -envxml_dir . -no-megan", + namelst=>"use_fates_luh=.true.", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm4_5", + }, + "inventoryfileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan", + namelst=>"use_fates_luh=.true., fluh_timeseries='zztop'", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm4_5", + }, "useMEGANwithFATES" =>{ options=>"-bgc fates -envxml_dir . -megan", namelst=>"", GLC_TWO_WAY_COUPLING=>"FALSE", From f795147d6d1c61df54e88bd603cf5f818200013a Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Nov 2023 12:48:12 -0800 Subject: [PATCH 08/33] define LUH acronym --- bld/namelist_files/namelist_definition_ctsm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 4d82faa658..4f63e98fd4 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -780,7 +780,7 @@ Full pathname to the inventory initialization control file. -If TRUE, enable use of land use state and transition data from luh_timeseries file. +If TRUE, enable use of land use harmonization (LUH) state and transition data from luh_timeseries file. (Only valid for fates land use change runs, where there is a luh_timeseries file.) (Also, only valid for use_fates = true and is incompatible with transient runs currently.) @@ -788,7 +788,7 @@ If TRUE, enable use of land use state and transition data from luh_timeseries fi -Full pathname of unified land use harmonization data file. This causes the land-use +Full pathname of unified land use harmonization (LUH) data file. This causes the land-use types to vary over time. (Required, if use_fates_luh=T) (Only relevant if FATES is on). From 042b7ef27d660a9b6e544c99bb4a44a6e5ac69e5 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Nov 2023 12:50:33 -0800 Subject: [PATCH 09/33] remove erroneous comment in use_fates_luh namelist option --- bld/namelist_files/namelist_definition_ctsm.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 4f63e98fd4..8f854a674e 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -781,7 +781,6 @@ Full pathname to the inventory initialization control file. If TRUE, enable use of land use harmonization (LUH) state and transition data from luh_timeseries file. -(Only valid for fates land use change runs, where there is a luh_timeseries file.) (Also, only valid for use_fates = true and is incompatible with transient runs currently.) From 87b149f86fe87a0e07ef627d64febb304306fd7a Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Nov 2023 13:48:30 -0800 Subject: [PATCH 10/33] add clarifying comments for the fates landuse timeseries module --- src/dyn_subgrid/dynFATESLandUseChangeMod.F90 | 36 ++++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 index 2180572c0a..45f4340d6a 100644 --- a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 +++ b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 @@ -20,12 +20,17 @@ module dynFATESLandUseChangeMod private + ! Yearly landuse transition rate (fraction of gridcell), landuse transition name x gridcell real(r8), allocatable, public :: landuse_transitions(:,:) + + ! Landuse state at beginning of year (fraction of gridcell), landuse state name x gridcell real(r8), allocatable, public :: landuse_states(:,:) + ! Number of landuse transition and state names integer, public, parameter :: num_landuse_transition_vars = 108 integer, public, parameter :: num_landuse_state_vars = 12 + ! landuse filename type(dyn_file_type), target :: dynFatesLandUse_file ! Land use name arrays @@ -112,9 +117,8 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename) if (use_fates_luh) then - ! Generate the dyn_file_type object - ! TO DO: check whether to initialize with start or end - ! dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_START_OF_TIMESTEP) + ! Generate the dyn_file_type object. Note that the land use data being read in is for the + ! transitions occuring within the current year dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP) ! Get initial land use data @@ -144,6 +148,16 @@ end subroutine dynFatesLandUseInit !----------------------------------------------------------------------- subroutine dynFatesLandUseInterp(bounds, init_state) + + ! !DESCRIPTION: + ! Get landuse state and transition rate data + ! + ! Note that the landuse state and transition rates are stored as fractions + ! of a gridcell for a given year, which is constant throughout the year. + ! This routine does not interpolate the rate at this time; any interpolation + ! is handled by FATES. + + ! !USES: use dynTimeInfoMod , only : time_info_type use clm_varctl , only : use_cn @@ -152,17 +166,16 @@ subroutine dynFatesLandUseInterp(bounds, init_state) logical, optional, intent(in) :: init_state ! fates needs state for initialization ! !LOCAL VARIABLES: - integer :: varnum - integer :: i - logical :: init_flag - real(r8), allocatable :: this_data(:) + integer :: varnum ! variable number index + logical :: init_flag ! local variable to take optional argument value + real(r8), allocatable :: this_data(:) ! temporary array to take get_current_date results + character(len=*), parameter :: subname = 'dynFatesLandUseInterp' !----------------------------------------------------------------------- SHR_ASSERT_ALL(bounds%level == BOUNDS_LEVEL_PROC, subname // ': argument must be PROC-level bounds') - ! This shouldn't be called by cn currently, but return if it is - if (use_cn) return ! Use this as a protection in lieu of build namelist check? - + ! Determine if the optional initialization state flag is present and if so + ! set the init_flag to that optional input value init_flag = .false. if (present(init_state)) then init_flag = init_state @@ -176,7 +189,8 @@ subroutine dynFatesLandUseInterp(bounds, init_state) landuse_transitions(1:num_landuse_transition_vars,bounds%begg:bounds%endg) = 0._r8 landuse_states(1:num_landuse_state_vars,bounds%begg:bounds%endg) = 0._r8 else - ! Right now we don't account for the topounits + ! Loop through all variables on the data file and put data into the temporary array + ! then update the global state and transitions array. allocate(this_data(bounds%begg:bounds%endg)) do varnum = 1, num_landuse_transition_vars call landuse_transition_vars(varnum)%get_current_data(this_data) From b06181632f3e7609d6a71fd3b55fa0b4fe5fc800 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 15 Nov 2023 15:20:03 -0800 Subject: [PATCH 11/33] trim filename strings in control mod diagnostic output --- src/main/controlMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 1e20b8b6f2..eeb1e6847d 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -1157,10 +1157,10 @@ subroutine control_print () write(iulog, *) ' use_fates_nocomp = ', use_fates_nocomp write(iulog, *) ' use_fates_sp = ', use_fates_sp write(iulog, *) ' use_fates_luh= ', use_fates_sp - write(iulog, *) ' fluh_timeseries = ',fluh_timeseries + write(iulog, *) ' fluh_timeseries = ', trim(fluh_timeseries) write(iulog, *) ' fates_seeddisp_cadence = ', fates_seeddisp_cadence write(iulog, *) ' fates_seeddisp_cadence: 0, 1, 2, 3 => off, daily, monthly, or yearly dispersal' - write(iulog, *) ' fates_inventory_ctrl_filename = ',fates_inventory_ctrl_filename + write(iulog, *) ' fates_inventory_ctrl_filename = ', trim(fates_inventory_ctrl_filename) end if end subroutine control_print From 1f44adf93e0a61d15e3dd83db6af6c832924f777 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 29 Nov 2023 23:23:12 -0700 Subject: [PATCH 12/33] update fates parameter file name in defaults --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index ced8e15d13..5053a481df 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -492,7 +492,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/fates_params_api.25.5.0_12pft_c230628.nc +lnd/clm2/paramdata/fates_params_api.32.0.0_12pft_c231130.nc From fd7373d2b7387023756716197ca2f4abb390b7fa Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 30 Nov 2023 09:29:10 -0700 Subject: [PATCH 13/33] remove obsolete disturbance variables from base fates testmod --- cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm index 03ed340cbb..f7b62048ef 100644 --- a/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm @@ -16,10 +16,8 @@ hist_fincl1 = 'FATES_NCOHORTS', 'FATES_TRIMMING', 'FATES_AREA_PLANTS', 'FATES_SAPWOODC', 'FATES_LEAFC', 'FATES_FROOTC', 'FATES_REPROC', 'FATES_STRUCTC', 'FATES_NONSTRUCTC', 'FATES_VEGC_ABOVEGROUND', 'FATES_CANOPY_VEGC', 'FATES_USTORY_VEGC', 'FATES_PRIMARY_PATCHFUSION_ERR', -'FATES_DISTURBANCE_RATE_P2P', 'FATES_DISTURBANCE_RATE_P2S', -'FATES_DISTURBANCE_RATE_S2S', 'FATES_DISTURBANCE_RATE_FIRE', +'FATES_HARVEST_CARBON_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL', -'FATES_DISTURBANCE_RATE_POTENTIAL', 'FATES_HARVEST_CARBON_FLUX', 'FATES_STOMATAL_COND', 'FATES_LBLAYER_COND', 'FATES_NPP', 'FATES_GPP', 'FATES_AUTORESP', 'FATES_GROWTH_RESP', 'FATES_MAINT_RESP', 'FATES_GPP_CANOPY', 'FATES_AUTORESP_CANOPY', 'FATES_GPP_USTORY', 'FATES_AUTORESP_USTORY', From 97a93b7b5953e177d4f04cb4d55c139cb7f80b59 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 30 Nov 2023 09:38:29 -0700 Subject: [PATCH 14/33] add landuse site level variables to default fates testmod --- cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm index f7b62048ef..406fb598f6 100644 --- a/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm @@ -26,4 +26,5 @@ hist_fincl1 = 'FATES_NCOHORTS', 'FATES_TRIMMING', 'FATES_AREA_PLANTS', 'FATES_NEP', 'FATES_HET_RESP', 'FATES_FIRE_CLOSS', 'FATES_FIRE_FLUX_EL', 'FATES_CBALANCE_ERROR', 'FATES_ERROR_EL', 'FATES_LEAF_ALLOC', 'FATES_SEED_ALLOC', 'FATES_STEM_ALLOC', 'FATES_FROOT_ALLOC', -'FATES_CROOT_ALLOC', 'FATES_STORE_ALLOC' +'FATES_CROOT_ALLOC', 'FATES_STORE_ALLOC', +'FATES_PATCHAREA_LU', 'FATES_DISTURBANCE_RATE_MATRIX_LULU' From c2455923458f2c788d373c0ba7117c4d15264518 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 30 Nov 2023 15:10:40 -0700 Subject: [PATCH 15/33] remove obsolete disturbance variables from excluded output of fates_sp usersmod --- cime_config/usermods_dirs/fates_sp/user_nl_clm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cime_config/usermods_dirs/fates_sp/user_nl_clm b/cime_config/usermods_dirs/fates_sp/user_nl_clm index 0df139403d..093ecd7eda 100644 --- a/cime_config/usermods_dirs/fates_sp/user_nl_clm +++ b/cime_config/usermods_dirs/fates_sp/user_nl_clm @@ -21,9 +21,8 @@ hist_fexcl1 = 'FATES_TRIMMING', 'FATES_COLD_STATUS', 'FATES_GDD', 'FATES_NCHILLD 'FATES_SEEDS_IN_EXTERN_EL', 'FATES_SEED_GERM_EL', 'FATES_SEED_DECAY_EL', 'FATES_STOREC', 'FATES_VEGC', 'FATES_SAPWOODC', 'FATES_FROOTC', 'FATES_REPROC', 'FATES_STRUCTC', 'FATES_NONSTRUCTC', 'FATES_VEGC_ABOVEGROUND', 'FATES_CANOPY_VEGC', 'FATES_USTORY_VEGC', 'FATES_PRIMARY_PATCHFUSION_ERR', - 'FATES_DISTURBANCE_RATE_P2P', 'FATES_DISTURBANCE_RATE_P2S', 'FATES_DISTURBANCE_RATE_S2S', 'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL', - 'FATES_DISTURBANCE_RATE_POTENTIAL', 'FATES_HARVEST_CARBON_FLUX', 'FATES_GPP_CANOPY', 'FATES_AUTORESP_CANOPY', + 'FATES_HARVEST_CARBON_FLUX', 'FATES_GPP_CANOPY', 'FATES_AUTORESP_CANOPY', 'FATES_GPP_USTORY', 'FATES_AUTORESP_USTORY', 'FATES_CROWNAREA_CL', 'FATES_DEMOTION_CARBONFLUX', 'FATES_PROMOTION_CARBONFLUX', 'FATES_MORTALITY_CFLUX_CANOPY', 'FATES_MORTALITY_CFLUX_USTORY', 'FATES_DDBH_CANOPY_SZ', 'FATES_DDBH_USTORY_SZ', 'FATES_BASALAREA_SZ', From 8c0b078de072713d038b229febea83d1b06a2bb7 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 30 Nov 2023 15:54:04 -0700 Subject: [PATCH 16/33] add luh2 testmod --- cime_config/testdefs/testlist_clm.xml | 9 +++++++++ .../testmods_dirs/clm/FatesColdLUH2/include_user_mods | 1 + .../testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm | 1 + 3 files changed, 11 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 85fdd0bb9c..88d9fbbc88 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2177,6 +2177,15 @@ + + + + + + + + + diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/include_user_mods new file mode 100644 index 0000000000..14f7591b72 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/include_user_mods @@ -0,0 +1 @@ +../FatesCold diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm new file mode 100644 index 0000000000..854c21407f --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm @@ -0,0 +1 @@ +use_fates_luh = .true. From a0f8ff9d43f88776c877861154ac878e9b6f7753 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 11:45:08 -0700 Subject: [PATCH 17/33] change location of luh2 fates data and make sure default is available --- bld/CLMBuildNamelist.pm | 1 + bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index b2178f1ca1..26e132d4fb 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4368,6 +4368,7 @@ sub setup_logic_fates { if (&value_is_true( $nl_flags->{'use_fates'}) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","fates_seeddisp_cadence", "use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage","use_fates_luh" ); diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 5053a481df..f16b04988c 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1548,7 +1548,7 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 lnd/clm2/luh/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c230415.nc + use_crop=".false." >lnd/clm2/surfdata_map/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc .true. From bb23a70ca53ce36be9f8acbbaaf5324ae3ba92af Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 12:54:30 -0800 Subject: [PATCH 18/33] replace use statements from the fluh_timeseries default setting --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index f16b04988c..614873dc2c 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1547,8 +1547,8 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 -lnd/clm2/surfdata_map/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc +lnd/clm2/surfdata_map/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc .true. From e2716ca65a7e4f6c5614ea077e24c40c110f67cf Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 12:55:55 -0800 Subject: [PATCH 19/33] add build subdirectory for fates landuse timeseries default file --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 614873dc2c..32ce121845 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1548,7 +1548,7 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 lnd/clm2/surfdata_map/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc + >lnd/clm2/surfdata_map/sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc .true. From ffac03f29f4765dfa1916d61cccc6a24d0151f93 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 12:57:41 -0800 Subject: [PATCH 20/33] add fates to the build tag subdirectory name --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 32ce121845..d7301197e2 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1548,7 +1548,7 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 lnd/clm2/surfdata_map/sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc + >lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc .true. From be78a0bbec8ad11c8012f2d0b75ac40f056ff8a3 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 14:43:45 -0800 Subject: [PATCH 21/33] add resolution to the add_default call for the fates landuse timeseries --- bld/CLMBuildNamelist.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 26e132d4fb..bb6be82bea 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4368,7 +4368,7 @@ sub setup_logic_fates { if (&value_is_true( $nl_flags->{'use_fates'}) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>"4x5"); my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","fates_seeddisp_cadence", "use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage","use_fates_luh" ); From 3def7e304610fee86ad704158e54228cd4c1e0ec Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 15:42:22 -0800 Subject: [PATCH 22/33] correct descriptions and diagnostic write --- src/main/clm_varctl.F90 | 4 ++-- src/main/controlMod.F90 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 7498597b34..e0d142bffd 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -310,8 +310,8 @@ module clm_varctl logical, public :: use_fates_inventory_init = .false. ! true => initialize fates from inventory logical, public :: use_fates_fixed_biogeog = .false. ! true => use fixed biogeography mode logical, public :: use_fates_nocomp = .false. ! true => use no comopetition mode - logical, public :: use_fates_luh = .false. ! true => use FATES satellite phenology mode - character(len=256), public :: fluh_timeseries = '' ! filename for inventory control + logical, public :: use_fates_luh = .false. ! true => use FATES landuse data mode + character(len=256), public :: fluh_timeseries = '' ! filename for fates landuse timeseries data character(len=256), public :: fates_inventory_ctrl_filename = '' ! filename for inventory control ! FATES SP AND FATES BGC are MUTUTALLY EXCLUSIVE, THEY CAN'T BOTH BE ON diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index eeb1e6847d..44efec4eeb 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -1156,7 +1156,7 @@ subroutine control_print () write(iulog, *) ' use_fates_fixed_biogeog = ', use_fates_fixed_biogeog write(iulog, *) ' use_fates_nocomp = ', use_fates_nocomp write(iulog, *) ' use_fates_sp = ', use_fates_sp - write(iulog, *) ' use_fates_luh= ', use_fates_sp + write(iulog, *) ' use_fates_luh= ', use_fates_luh write(iulog, *) ' fluh_timeseries = ', trim(fluh_timeseries) write(iulog, *) ' fates_seeddisp_cadence = ', fates_seeddisp_cadence write(iulog, *) ' fates_seeddisp_cadence: 0, 1, 2, 3 => off, daily, monthly, or yearly dispersal' From e8b0508890d5c4be573e00f4e3e9b48d0e02a4cf Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 1 Dec 2023 16:08:11 -0800 Subject: [PATCH 23/33] correct hlm group name in namelist definition --- bld/namelist_files/namelist_definition_ctsm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 4f26dc5dff..408a037737 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -779,14 +779,14 @@ Full pathname to the inventory initialization control file. + group="clm_inparm" valid_values="" > If TRUE, enable use of land use harmonization (LUH) state and transition data from luh_timeseries file. (Also, only valid for use_fates = true and is incompatible with transient runs currently.) + input_pathname="abs" group="clm_inparm" valid_values="" > Full pathname of unified land use harmonization (LUH) data file. This causes the land-use types to vary over time. (Required, if use_fates_luh=T) From 1a1ec94c71ce67eb3ba490d06643dbed4325a661 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 12 Dec 2023 15:06:22 -0700 Subject: [PATCH 24/33] remove wood product flux from fates carbon balance check --- src/biogeochem/CNBalanceCheckMod.F90 | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90 index 35efd2e9aa..8801efdf72 100644 --- a/src/biogeochem/CNBalanceCheckMod.F90 +++ b/src/biogeochem/CNBalanceCheckMod.F90 @@ -258,7 +258,6 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & real(r8) :: hrv_xsmrpool_amount_left_to_dribble(bounds%begg:bounds%endg) real(r8) :: gru_conv_cflux_amount_left_to_dribble(bounds%begg:bounds%endg) real(r8) :: dwt_conv_cflux_amount_left_to_dribble(bounds%begg:bounds%endg) - real(r8) :: fates_woodproduct_flux ! Total carbon wood products flux from FATES to CLM [gC/m2/s] !----------------------------------------------------------------------- @@ -309,11 +308,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & s = clm_fates%f2hmap(ic)%hsites(c) - - fates_woodproduct_flux = clm_fates%fates(ic)%bc_out(s)%hrv_deadstemc_to_prod10c + & - clm_fates%fates(ic)%bc_out(s)%hrv_deadstemc_to_prod100c - - col_cinputs = fates_litter_flux(c) + fates_woodproduct_flux + col_cinputs = fates_litter_flux(c) ! calculate total column-level outputs ! fates has already exported burn losses and fluxes to the atm @@ -372,7 +367,6 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, & write(iulog,*)'--- Inputs ---' if( col%is_fates(c) ) then write(iulog,*)'fates litter_flux = ',fates_litter_flux(c)*dt - write(iulog,*)'fates wood product flux = ',fates_woodproduct_flux*dt else write(iulog,*)'gpp = ',gpp(c)*dt end if From 67426be73889944e2df64bd83b911d700efcd167 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 14 Dec 2023 11:36:37 -0700 Subject: [PATCH 25/33] update externals with fates landuse tag --- Externals_CLM.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals_CLM.cfg b/Externals_CLM.cfg index 5f8e8d2441..dc1bc3f0e7 100644 --- a/Externals_CLM.cfg +++ b/Externals_CLM.cfg @@ -2,7 +2,7 @@ local_path = src/fates protocol = git repo_url = https://github.com/NGEET/fates -tag = sci.1.68.2_api.31.0.0 +tag = sci.1.70.0_api.32.0.0 required = True [externals_description] From 225f0926866be7b26ff9fde438529784f91d17ab Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 15 Dec 2023 15:09:25 -0700 Subject: [PATCH 26/33] Update the default fates paramfile A newer parameter file was generated that reduces the maximum number of fates patches for the default configuration. This avoids misalignment between the default surface datasets. --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 2dfde24737..d8b33ab579 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -492,7 +492,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/fates_params_api.32.0.0_12pft_c231130.nc +lnd/clm2/paramdata/fates_params_api.32.0.0_12pft_c231215.nc From 809ef0893c7d6b9f065188c18e1495e8f3368ede Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Fri, 15 Dec 2023 13:16:05 -0700 Subject: [PATCH 27/33] Pass surfpft bounds as input argumment The wt_nat_patch array is allocated using surfpft bounds. While surfpft and natpft will typically match, this isn't the case for fates currently. As such the nag compiler will complain if the input array has lower bounds for its dimensions than the dummy argument bounds. --- src/main/surfrdMod.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 78c9d8492e..23e96e7c1a 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -723,6 +723,7 @@ subroutine surfrd_veg_all(begg, endg, ncid, ns, actual_numcft) ! !USES: use clm_varctl , only : create_crop_landunit, use_fates, n_dom_pfts use clm_varpar , only : natpft_lb, natpft_ub, natpft_size, cft_size, cft_lb, cft_ub + use clm_varpar , only : surfpft_lb, surfpft_ub use clm_instur , only : wt_lunit, wt_nat_patch, wt_cft, fert_cft use landunit_varcon , only : istsoil, istcrop use surfrdUtilsMod , only : convert_cft_to_pft @@ -851,7 +852,7 @@ subroutine surfrd_veg_all(begg, endg, ncid, ns, actual_numcft) ! - Pfts could be up to 16 before collapsing if create_crop_landunit = .F. ! TODO Add the same call to subroutine dynpft_interp for transient runs - call collapse_to_dominant(wt_nat_patch(begg:endg,:), natpft_lb, natpft_ub, & + call collapse_to_dominant(wt_nat_patch(begg:endg,:), surfpft_lb, surfpft_ub, & begg, endg, n_dom_pfts) end subroutine surfrd_veg_all From aa463cf2b36886e624996b1a3a9fd534246d5078 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Mon, 18 Dec 2023 15:43:24 -0700 Subject: [PATCH 28/33] add fates luh2 test to derecho --- cime_config/testdefs/testlist_clm.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 7e4adb7df1..dec8cf49d8 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2903,6 +2903,7 @@ + From 8bd8bfeac7207c891dec28c61292bc7c0a598321 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Mon, 18 Dec 2023 18:35:23 -0800 Subject: [PATCH 29/33] update changelog --- doc/ChangeLog | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 97 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index 67564b6dd0..e515165dc0 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,100 @@ =============================================================== +Tag name: ctsm5.1.dev160 +Originator(s): glemieux (Gregory Lemieux, LBNL, glemieux@lbl.gov) +Date: Mon Dec 18 18:32:23 MST 2023 +One-line Summary: FATES landuse version 1 + +Purpose and description of changes +---------------------------------- + +This tag enables FATES to utilize the state and transitions data +from the Land Use Harmonization (https://luh.umd.edu/) data sets. +This data has been preprocessed using tooling provided by FATES via +a separate pull request (FATES#1032). A new module has been added +to the dyn_subgrid directory that largely adapts the dynHarvest +module to import and read this minimially processed data, which is +data is passed to fates. + + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[ ] clm5_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed or introduced +------------------------ +CTSM issues fixed (include CTSM Issue #): + #1077 -- Read in full LUH2 dataset for use by FATES + #2283 -- fates wood product flux not being correctly reported during CBalanceCheck endrun diagnostic output + +Notes of particular relevance for users +--------------------------------------- +Changes made to namelist defaults (e.g., changed parameter values): + New namelist item: fluh_timeseries and use_fates_luh + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + FATES landuse testmod, FatesColdLUH2, added + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - PASS + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- PASS + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--) + derecho ----- OK + izumi ------- OK + + +Answer changes +-------------- + +Changes answers relative to baseline: yes, for FATES only + + Summarize any changes to answers, i.e., + - what code configurations: FATES + - what platforms/compilers: ALL + - nature of change (roundoff; larger than roundoff/same climate; new climate): larger than roundoff + + The fates tag update incorporates bug fixes and hydraulic mortality fixes, as well as the + restructured disturbance code necessary to accomodate the new landuse transitions capability. + As such, small differences were observed in testmods that engaged specific disturbance modes + or were long enough to trigger other default disturbances (e.g. fire) + +Other details +------------- + +List any externals directories updated (cime, rtm, mosart, cism, fates, etc.): + fates: sci.1.69.0_api.31.0.0 -> fates-sci.1.70.0_api.32.0.0 + +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/2076 + https://github.com/NGEET/fates/pull/1040 + +=============================================================== +=============================================================== Tag name: ctsm5.1.dev159 Originator(s): multiple (slevis (Sam Levis), afoster (Adrianna Foster), erik (Erik Kluzek), wwieder (Will Wieder), glemieux (Greg Lemieux), oleson (Keith Oleson), sacks (Bill Sacks), samrabin (Sam Rabin), santos (Sean Patrick Santos)) Date: Tue 12 Dec 2023 11:10:26 AM MST diff --git a/doc/ChangeSum b/doc/ChangeSum index 4b82850d85..97d4c2269c 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.1.dev160 glemieux 12/18/2023 FATES landuse version 1 ctsm5.1.dev159 multiple 12/12/2023 Various BFB fixes and updates ctsm5.1.dev158 erik 12/07/2023 First tag with testing moved to Derecho and working PE-layouts for Derecho ctsm5.1.dev157 samrabin 12/05/2023 Update Externals to work on Derecho From 225a510c2a328380b5bf965e9ed5d832d03905bc Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 30 Dec 2023 18:08:16 -0700 Subject: [PATCH 30/33] Change LUH2 test to f09 so there won't be a LUH2 timeseries file for it --- bld/unit_testers/build-namelist_test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 0c7a49d8b5..9b579dd9ce 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -1061,7 +1061,7 @@ sub cat_and_create_namelistinfile { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm4_5", }, - "useinventorybutnotfile" =>{ options=>"-bgc fates -envxml_dir . -no-megan", + "useinventorybutnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan", namelst=>"use_fates_luh=.true.", GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm4_5", From 6747e8c30652bee5ebb7922c3e653aefad0b5bfa Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 30 Dec 2023 18:09:39 -0700 Subject: [PATCH 31/33] Only get a default luh timeseries file if you need one, and ask for one at the model resolution and sim_year_range --- bld/CLMBuildNamelist.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index bb6be82bea..4df42d5e74 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4368,7 +4368,6 @@ sub setup_logic_fates { if (&value_is_true( $nl_flags->{'use_fates'}) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>"4x5"); my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","fates_seeddisp_cadence", "use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage","use_fates_luh" ); @@ -4418,6 +4417,7 @@ sub setup_logic_fates { if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { $var = "fluh_timeseries"; + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>$nl_flags->{'res'}, 'sim_year_range'=>$nl_flags->{'sim_year_range'}, nofail=>1 ); my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); if ( ! defined($nl->get_value($var)) ) { $log->fatal_error("$var is required when use_fates_luh is set" ); From 4e059c794e7781fb232372f304e539b33f872242 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 30 Dec 2023 23:22:47 -0700 Subject: [PATCH 32/33] LUH file should be for 1850-2000, and add a case for constant until issue #2304 is resolved --- bld/namelist_files/namelist_defaults_ctsm.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index d8b33ab579..7891361238 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1574,7 +1574,11 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 -lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc + + +lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc From ebc5cd8806691b1a8930ebe09bdaf3d84acfd49f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 30 Dec 2023 23:30:03 -0700 Subject: [PATCH 33/33] Update change files --- doc/.ChangeLog_template | 4 ++-- doc/ChangeLog | 12 ++++++++---- doc/ChangeSum | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/.ChangeLog_template b/doc/.ChangeLog_template index bbd65c8c83..a1170a61cf 100644 --- a/doc/.ChangeLog_template +++ b/doc/.ChangeLog_template @@ -27,8 +27,8 @@ Does this tag change answers significantly for any of the following physics conf [ ] clm4_5 -Bugs fixed or introduced ------------------------- +Bugs fixed +---------- [Remove any lines that don't apply. Remove entire section if nothing applies.] CTSM issues fixed (include CTSM Issue #): diff --git a/doc/ChangeLog b/doc/ChangeLog index e515165dc0..925141f310 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.1.dev160 Originator(s): glemieux (Gregory Lemieux, LBNL, glemieux@lbl.gov) -Date: Mon Dec 18 18:32:23 MST 2023 +Date: Sat 30 Dec 2023 11:23:47 PM MST One-line Summary: FATES landuse version 1 Purpose and description of changes @@ -33,8 +33,8 @@ Does this tag change answers significantly for any of the following physics conf [ ] clm4_5 -Bugs fixed or introduced ------------------------- +Bugs fixed +---------- CTSM issues fixed (include CTSM Issue #): #1077 -- Read in full LUH2 dataset for use by FATES #2283 -- fates wood product flux not being correctly reported during CBalanceCheck endrun diagnostic output @@ -49,6 +49,10 @@ Notes of particular relevance for developers: Changes to tests or testing: FATES landuse testmod, FatesColdLUH2, added +IMPORTANT NOTE ON BASELINES: + FATES baseline tests have a change in namelists because the fluh_timeseries file is listed in the baselines + but was removed in a last minute change. Compare to baseline other than that change are exact though. + Testing summary: ---------------- @@ -56,7 +60,7 @@ Testing summary: build-namelist tests (if CLMBuildNamelist.pm has changed): - derecho - PASS + derecho - PASS (66 FATES tests differ because of new fates param file) regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): diff --git a/doc/ChangeSum b/doc/ChangeSum index 97d4c2269c..d9da687477 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.1.dev160 glemieux 12/18/2023 FATES landuse version 1 + ctsm5.1.dev160 glemieux 12/30/2023 FATES landuse version 1 ctsm5.1.dev159 multiple 12/12/2023 Various BFB fixes and updates ctsm5.1.dev158 erik 12/07/2023 First tag with testing moved to Derecho and working PE-layouts for Derecho ctsm5.1.dev157 samrabin 12/05/2023 Update Externals to work on Derecho