From 4156260a7de900cc83a9c248538a8d1512f2c8f9 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 21 Mar 2023 15:50:06 -0700 Subject: [PATCH 01/30] add logic to avoid rho and tau calculation when fates is on --- components/elm/src/main/elmfates_interfaceMod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 1b9d6c1ba490..520197de5765 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -360,6 +360,7 @@ subroutine ELMFatesGlobals1() call SetFatesGlobalElements1(use_fates,natpft_size,0,var_reader) natpft_size = fates_maxPatchesPerSite + !numpft = natpft_size - 1 # GML Todo: This was in landuse v2, not v1 max_patch_per_col= max(natpft_size, numcft, maxpatch_urb) return From 8771e50aa004afd616013a2246e90da57d15eb72 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 19 Sep 2023 15:50:39 -0700 Subject: [PATCH 02/30] Add fates landuse x pft API code Adds luh2 harvest data read to fates landuse module This will enables the use of the raw LUH2 harvest data when running with fates in land use mode + wood harvest mode --- components/elm/bld/ELMBuildNamelist.pm | 122 ++++++-- .../bld/namelist_files/namelist_defaults.xml | 20 +- .../namelist_files/namelist_definition.xml | 38 ++- .../testmods_dirs/elm/fates/user_nl_elm | 2 +- .../testmods_dirs/elm/fates_eca/user_nl_elm | 2 +- .../testmods_dirs/elm/fates_long/user_nl_elm | 2 +- .../testmods_dirs/elm/fates_rd/user_nl_elm | 2 +- .../dyn_subgrid/dynFATESLandUseChangeMod.F90 | 135 +++++++-- .../elm/src/dyn_subgrid/dynHarvestMod.F90 | 3 + .../src/dyn_subgrid/dynSubgridDriverMod.F90 | 22 +- components/elm/src/main/controlMod.F90 | 15 +- components/elm/src/main/elm_instMod.F90 | 4 +- components/elm/src/main/elm_varctl.F90 | 5 +- .../elm/src/main/elmfates_interfaceMod.F90 | 273 ++++++++++++++---- 14 files changed, 504 insertions(+), 141 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 67347728e0fd..05e19b9bbb4a 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -808,12 +808,28 @@ sub setup_cmdl_fates_mode { # The following variables may be set by the user and are compatible with use_fates # no need to set defaults, covered in a different routine - my @list = ( "fates_spitfire_mode", "use_vertsoilc", "use_century_decomp", "fates_seeddisp_cadence", - "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_sp", - "fates_inventory_ctrl_filename","use_fates_logging", "use_fates_tree_damage", - "use_fates_parteh_mode","use_fates_cohort_age_tracking","use_snicar_ad", "use_fates_luh", - "fluh_timeseries","fates_history_dimlevel"); + my @list = ( "fates_spitfire_mode", + "fates_harvest_mode", + "fates_history_dimlevel", + "fates_inventory_ctrl_filename", + "fates_seeddisp_cadence", + "use_century_decomp", + "use_fates_cohort_age_tracking", + "use_fates_ed_st3", + "use_fates_ed_prescribed_phys", + "use_fates_fixed_biogeog", + "use_fates_inventory_init", + "use_fates_luh", + "use_fates_lupft", + "use_fates_nocomp", + "use_fates_parteh_mode", + "use_fates_planthydro", + "use_fates_potentialveg", + "use_fates_sp", + "use_fates_tree_damage", + "use_snicar_ad", + "use_vertsoilc", + "fluh_timeseries"); foreach my $var ( @list ) { if ( defined($nl->get_value($var)) ) { $nl_flags->{$var} = $nl->get_value($var); @@ -841,17 +857,17 @@ sub setup_cmdl_fates_mode { if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); } - $var = "use_fates_cohort_age_tracking"; + $var = "fates_harvest_mode"; if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); } - $var = "use_fates_fixed_biogeog"; + $var = "use_fates_cohort_age_tracking"; if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); } - $var = "use_fates_logging"; + $var = "use_fates_fixed_biogeog"; if ( defined($nl->get_value($var)) ) { - fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); + fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); } $var = "fates_parteh_mode"; if ( defined($nl->get_value($var)) ) { @@ -877,6 +893,10 @@ sub setup_cmdl_fates_mode { if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); } + $var = "use_fates_lupft"; + if ( defined($nl->get_value($var)) ) { + fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); + } $var = "fates_inventory_ctrl_filename"; if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); @@ -2812,8 +2832,8 @@ sub setup_logic_do_harvest { if (string_is_undef_or_empty($nl->get_value('flanduse_timeseries'))) { $cannot_be_true = "$var can only be set to true when running a transient case (flanduse_timeseries non-blank)"; } - elsif (!( value_is_true($nl->get_value('use_cn')) || value_is_true($nl->get_value('use_fates')) )) { - $cannot_be_true = "$var can only be set to true when running with CN (use_cn == true) or when using FATES (use_fates == true)"; + elsif (!( value_is_true($nl->get_value('use_cn')))) { + $cannot_be_true = "$var can only be set to true when running with CN (use_cn == true)"; } if ($cannot_be_true) { @@ -3380,25 +3400,28 @@ sub setup_logic_fates { my ($test_files, $nl_flags, $definition, $defaults, $nl, $physv) = @_; if ( value_is_true( $nl_flags->{'use_fates'}) ) { - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_spitfire_mode', 'use_fates'=>$nl_flags->{'use_fates'} ); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_fixed_biogeog', 'use_fates'=>$nl_flags->{'use_fates'} ); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_logging', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_planthydro', 'use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'flandusepftdat', 'phys'=>$nl_flags->{'phys'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_harvest_mode', 'use_fates'=>$nl_flags->{'use_fates'} ); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_history_dimlevel', 'use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_inventory_ctrl_filename','use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_parteh_mode', 'use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_seeddisp_cadence', 'use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_spitfire_mode', 'use_fates'=>$nl_flags->{'use_fates'} ); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_cohort_age_tracking','use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_ed_st3', 'use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_ed_prescribed_phys', 'use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_fixed_biogeog', 'use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_inventory_init', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_inventory_ctrl_filename','use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_cohort_age_tracking','use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_planthydro', 'use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_sp', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_tree_damage', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_seeddisp_cadence', 'use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_luh', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_history_dimlevel','use_fates'=>$nl_flags->{'use_fates'}); - + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_lupft', 'use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_potentialveg', 'use_fates'=>$nl_flags->{'use_fates'}); + # For FATES SP mode make sure no-competion, and fixed-biogeography are also set # And also check for other settings that can't be trigged on as well my $var = "use_fates_sp"; @@ -3418,9 +3441,37 @@ sub setup_logic_fates { if (&value_is_true( $nl->get_value('use_fates_planthydro') )) { fatal_error('fates sp mode is currently not supported to work with fates hydro'); } + # FATES landuse can not be active with fates sp mode is active + if ( &value_is_true($nl->get_value('use_fates_luh')) ) { + fatal_error("use_fates_luh is can NOT be true when use_fates_sp is true" ); + } + } + } + # make sure that fates landuse x pft mode has the necessary run mode configurations + # and add the necessary landuse x pft static mapping data default if not defined + my $var = "use_fates_lupft"; + if ( defined($nl->get_value($var)) ) { + if ( &value_is_true($nl->get_value($var)) ) { + $var = "flandusepftdat"; + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, + 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>$nl_flags->{'res'}, nofail=>1 ); + my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); + if ( ! defined($nl->get_value($var)) ) { + fatal_error("$var is required when use_fates_lupft is set" ); + } elsif ( ! -f "$fname" ) { + fatal_error("$fname does NOT point to a valid filename" ); + } + # make sure that nocomp and fbg mode are enabled as well as use_fates_luh + #my @list = ( "use_fates_luh, use_fates_nocomp", "use_fates_fixed_biogeog" ); + #foreach my $var ( @list ) { + # if ( ! &value_is_true($nl->get_value($var)) ) { + # fatal_error("$var is required when use_fates_lupft is true" ); + # } + #} } } # check that fates landuse change mode has the necessary luh2 landuse timeseries data + # and add the default if not defined my $var = "use_fates_luh"; if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { @@ -3436,6 +3487,29 @@ sub setup_logic_fates { } } } + # check that fates landuse is on and harvest mode is off when potential veg switch is true + my $var = "use_potentialveg"; + if ( defined($nl->get_value($var)) ) { + if ( &value_is_true($nl->get_value($var)) ) { + if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { + fatal_error("use_fates_luh must be true when $var is true" ); + } + if ( $nl->get_value('fates_harvest_mode') ne "no_harvest") { + fatal_error("fates_harvest_mode must be off when $var is true" ); + } + } + } + # Check fates_harvest_mode compatibility + my $var = "fates_harvest_mode"; + if ( defined($nl->get_value($var)) ) { + # using fates_harvest mode with raw luh2 harvest data + if ( $nl->get_value($var) eq "luhdata_area" || $nl->get_value($var) eq "luhdata_mass" ) { + # Make sure that use_fates_luh is true when using raw fates luh2 harvest data + if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { + fatal_error("use_fates_luh is required to be true when $var is greater than 2" ); + } + } + } } } diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index 2fe8b19aaa87..6459605ff4dc 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -587,10 +587,12 @@ lnd/clm2/surfdata_map/surfdata_conusx4v1_simyr2000_c160503.nc lnd/clm2/surfdata_map/surfdata.pftdyn_ne30np4_rcp2.6_simyr1850-2100_c130524.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 + +lnd/clm2/surfdata_map/fates-sci.1.73.0_api.36.0.0/fates_landuse_pft_map_4x5_240206.nc @@ -2177,25 +2179,25 @@ this mask will have smb calculated over the entire global land surface 0 -.false. -.false. +no_harvest +2,2 + "/dev/null" +1 +0 .false. .false. .false. .false. -.false. .false. .false. -.false. -1 -0 +.false. +.false. +.false. .false. - "/dev/null" .true. .false. .true. .false. -2,2 .true. .true. .false. diff --git a/components/elm/bld/namelist_files/namelist_definition.xml b/components/elm/bld/namelist_files/namelist_definition.xml index a6d4e9eff3c0..c597d164661d 100644 --- a/components/elm/bld/namelist_files/namelist_definition.xml +++ b/components/elm/bld/namelist_files/namelist_definition.xml @@ -308,6 +308,18 @@ Allowed values are: 5 : use gross domestic production and population datasets to simulate anthropogenic fire supression + +Set FATES harvesting mode by setting fates_harvest_mode +Allowed values are: + no_harvest : no fates harvesting of any kind + event_code : fates logging via fates logging event codes only (via fates parameter file) + surfdata_file: fates harvest driven by HLM landuse timeseries data (dynHarvestMod) + luhdata_area : fates harvest driven by LUH2 raw harvest data, area-based (dynFATESLandUseChangeMod) + luhdata_mass : fates harvest driven by LUH2 raw harvest data, mass-based (dynFATESLandUseChangeMod) + + Switch deciding which nutrient model to use in FATES. @@ -339,11 +351,6 @@ Toggle to turn on FATES no competition mode (only relevant if FATES is being use Toggle to turn on FATES satellite phenology mode (only relevant if FATES is being used). - -Toggle to turn on the logging module (only relevant if FATES is being used). - - Toggle to turn on plant hydraulics (only relevant if FATES is on). @@ -382,12 +389,26 @@ Full pathname to the inventory initialization control file. + group="elm_inparm" valid_values="" value=".false."> If TRUE, enable use of land use state and transition data from luh_timeseries file. +This is enabled by default if fates_harvest_mode is set to use the raw LUH2 harvest +data (fates_harvest_mode >= 3) or if use_fates_lupft is true. (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.) + +If TRUE, enable use of fates land use x pft mapping data file. +(Only valid for use_fates = true and is incompatible with transient runs currently.) + + + +If TRUE, ignore the land-use state vector and transitions, and assert that all lands +are primary, and that there is no harvest. + + @@ -408,6 +429,11 @@ output level is not enabled. (Only relevant if FATES is on) + +Full pathname of fates landuse x pft data map. + + Toggle to turn on if Kennedy et al plant hydraulics model is used. diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates/user_nl_elm index cd078b90950c..575517b98fd2 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates/user_nl_elm @@ -16,7 +16,7 @@ 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_HARVEST_CARBON_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', +'FATES_HARVEST_WOODPROD_C_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL', 'FATES_STOMATAL_COND', 'FATES_LBLAYER_COND', 'FATES_NPP', 'FATES_GPP', 'FATES_AUTORESP', 'FATES_GROWTH_RESP', 'FATES_MAINT_RESP', 'FATES_GPP_CANOPY', diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_eca/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_eca/user_nl_elm index 8dfdff1ab8eb..bd31fbbc4b68 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_eca/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_eca/user_nl_elm @@ -21,7 +21,7 @@ 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_HARVEST_CARBON_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', +'FATES_HARVEST_WOODPROD_C_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL', 'FATES_STOMATAL_COND', 'FATES_LBLAYER_COND', 'FATES_NPP', 'FATES_GPP', 'FATES_AUTORESP', 'FATES_GROWTH_RESP', 'FATES_MAINT_RESP', 'FATES_GPP_CANOPY', diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_long/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_long/user_nl_elm index 4812969a278b..e8e22f163b05 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_long/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_long/user_nl_elm @@ -16,7 +16,7 @@ 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_HARVEST_CARBON_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', +'FATES_HARVEST_WOODPROD_C_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL', 'FATES_STOMATAL_COND', 'FATES_LBLAYER_COND', 'FATES_NPP', 'FATES_GPP', 'FATES_AUTORESP', 'FATES_GROWTH_RESP', 'FATES_MAINT_RESP', 'FATES_GPP_CANOPY', diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_rd/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_rd/user_nl_elm index 1e72d72d5712..263e4b5fad7c 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_rd/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_rd/user_nl_elm @@ -21,7 +21,7 @@ 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_HARVEST_CARBON_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', +'FATES_HARVEST_WOODPROD_C_FLUX', 'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL', 'FATES_STOMATAL_COND', 'FATES_LBLAYER_COND', 'FATES_NPP', 'FATES_GPP', 'FATES_AUTORESP', 'FATES_GROWTH_RESP', 'FATES_MAINT_RESP', 'FATES_GPP_CANOPY', diff --git a/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 index 53be7987182e..3d1b9ec50d61 100644 --- a/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 +++ b/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 @@ -9,6 +9,7 @@ module dynFATESLandUseChangeMod ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 use shr_log_mod , only : errMsg => shr_log_errMsg + use spmdMod , only : masterproc use decompMod , only : bounds_type, BOUNDS_LEVEL_PROC use abortutils , only : endrun use dynFileMod , only : dyn_file_type @@ -22,12 +23,36 @@ module dynFATESLandUseChangeMod real(r8), allocatable, public :: landuse_transitions(:,:) real(r8), allocatable, public :: landuse_states(:,:) + real(r8), allocatable, public :: landuse_harvest(:,:) integer, public, parameter :: num_landuse_transition_vars = 108 integer, public, parameter :: num_landuse_state_vars = 12 + integer, public, parameter :: num_landuse_harvest_vars = 5 + + ! Define the fates landuse namelist mode switch values + character(len=13), public, parameter :: fates_harvest_no_logging = 'no_harvest' + character(len=13), public, parameter :: fates_harvest_logging_only = 'event_code' + character(len=13), public, parameter :: fates_harvest_clmlanduse = 'surfdata_file' + character(len=13), public, parameter :: fates_harvest_luh_area = 'luhdata_area' + character(len=13), public, parameter :: fates_harvest_luh_mass = 'luhdata_mass' + + ! Define landuse harvest unit integer representation + integer, public, parameter :: landuse_harvest_area_units = 1 + integer, public, parameter :: landuse_harvest_mass_units = 2 + integer, public :: landuse_harvest_units type(dyn_file_type), target :: dynFatesLandUse_file + ! LUH2 raw wood harvest area fraction + character(len=10), target :: landuse_harvest_area_varnames(num_landuse_harvest_vars) = & + [character(len=10) :: 'primf_harv', 'primn_harv', 'secmf_harv', 'secyf_harv', 'secnf_harv'] + + ! LUH2 raw wood harvest biomass carbon + character(len=10), target :: landuse_harvest_mass_varnames(num_landuse_harvest_vars) = & + [character(len=10) :: 'primf_bioh', 'primn_bioh', 'secmf_bioh', 'secyf_bioh', 'secnf_bioh'] + + character(len=10), public, pointer :: landuse_harvest_varnames(:) => null() + ! Land use name arrays character(len=5), public, parameter :: landuse_state_varnames(num_landuse_state_vars) = & [character(len=5) :: 'primf', & ! forested primary land @@ -69,8 +94,9 @@ module dynFATESLandUseChangeMod '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 + type(dyn_var_time_uninterp_type) :: landuse_transition_vars(num_landuse_transition_vars) ! value of each transitions variable + type(dyn_var_time_uninterp_type) :: landuse_state_vars(num_landuse_state_vars) ! value of each state variable + type(dyn_var_time_uninterp_type) :: landuse_harvest_vars(num_landuse_harvest_vars) ! value of each harvest variable public :: dynFatesLandUseInit public :: dynFatesLandUseInterp @@ -84,14 +110,15 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename) ! Initialize data structures for land use information. ! !USES: - use elm_varctl , only : use_fates_luh + use elm_varctl , only : use_fates_luh, fates_harvest_mode + use elm_varctl , only : use_fates_potentialveg 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 + type(bounds_type), intent(in) :: bounds ! proc-level bounds + character(len=*) , intent(in) :: landuse_filename ! name of file containing landuse timeseries information (fates luh2) ! !LOCAL VARIABLES integer :: varnum, i ! counter for harvest variables @@ -114,37 +141,71 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename) if (ier /= 0) then call endrun(msg=' allocation error for landuse_transitions'//errMsg(__FILE__, __LINE__)) end if + allocate(landuse_harvest(num_landuse_harvest_vars,bounds%begg:bounds%endg),stat=ier) + if (ier /= 0) then + call endrun(msg=' allocation error for landuse_harvest'//errMsg(__FILE__, __LINE__)) + end if + ! Initialize the states, transitions and harvest mapping percentages as zero by defaut landuse_states = 0._r8 landuse_transitions = 0._r8 + landuse_harvest = 0._r8 + + ! Avoid initializing the landuse timeseries file if in fates potential vegetation mode + if (.not. use_fates_potentialveg) then + if (use_fates_luh) then + + ! Generate the dyn_file_type object + ! Start calls get_prev_date, whereas end calls get_curr_date + dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP) + + ! Get initial land use data from the fates luh2 timeseries dataset + 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 + + ! Get the harvest rate data from the fates luh2 timeseries dataset if enabled + if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area .or. & + trim(fates_harvest_mode) .eq. fates_harvest_luh_mass) then + + ! change the harvest varnames being used depending on the mode selected + if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area ) then + landuse_harvest_varnames => landuse_harvest_area_varnames + landuse_harvest_units = landuse_harvest_area_units + elseif (trim(fates_harvest_mode) .eq. fates_harvest_luh_mass ) then + landuse_harvest_varnames => landuse_harvest_mass_varnames + landuse_harvest_units = landuse_harvest_mass_units + else + call endrun(msg=' undefined fates harvest mode selected'//errMsg(__FILE__, __LINE__)) + end if + + do varnum = 1, num_landuse_harvest_vars + landuse_harvest_vars(varnum) = dyn_var_time_uninterp_type( & + dyn_file=dynFatesLandUse_file, varname=landuse_harvest_varnames(varnum), & + dim1name=grlnd, conversion_factor=1.0_r8, & + do_check_sums_equal_1=.false., data_shape=landuse_shape) + end do + end if + + 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.) - if (use_fates_luh) then - - ! 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 - 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 @@ -152,6 +213,7 @@ end subroutine dynFatesLandUseInit subroutine dynFatesLandUseInterp(bounds, init_state) use dynTimeInfoMod , only : time_info_type + use elm_varctl , only : fates_harvest_mode ! !ARGUMENTS: type(bounds_type), intent(in) :: bounds ! proc-level bounds @@ -171,13 +233,14 @@ 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 data for the current year + call dynFatesLandUse_file%time_info%set_current_year_get_year() 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 + landuse_harvest(1:num_landuse_harvest_vars,bounds%begg:bounds%endg) = 0._r8 else ! Right now we don't account for the topounits allocate(this_data(bounds%begg:bounds%endg)) @@ -189,9 +252,17 @@ subroutine dynFatesLandUseInterp(bounds, init_state) 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 + if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area .or. & + trim(fates_harvest_mode) .eq. fates_harvest_luh_mass) then + do varnum = 1, num_landuse_harvest_vars + call landuse_harvest_vars(varnum)%get_current_data(this_data) + landuse_harvest(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg) + end do + end if deallocate(this_data) end if end subroutine dynFatesLandUseInterp + end module dynFATESLandUseChangeMod diff --git a/components/elm/src/dyn_subgrid/dynHarvestMod.F90 b/components/elm/src/dyn_subgrid/dynHarvestMod.F90 index b30643e9757d..5256f415efe2 100644 --- a/components/elm/src/dyn_subgrid/dynHarvestMod.F90 +++ b/components/elm/src/dyn_subgrid/dynHarvestMod.F90 @@ -188,6 +188,9 @@ subroutine dynHarvest_interp_harvest_types(bounds) end do deallocate(this_data) end if + + ! FATES does not make use of the get_do_harvest mechanism. Make sure this is always false for fates runs. + if (use_fates) do_harvest = .false. end if end subroutine dynHarvest_interp_harvest_types diff --git a/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 b/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 index 8ac0cf4c45e7..6914e4d70c38 100644 --- a/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 +++ b/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 @@ -71,11 +71,13 @@ subroutine dynSubgrid_init(bounds, glc2lnd_vars, crop_vars) ! clumps - so this routine needs to be called from outside any loops over clumps. ! ! !USES: - use decompMod , only : bounds_type, BOUNDS_LEVEL_PROC - use decompMod , only : get_proc_clumps, get_clump_bounds - use dynpftFileMod , only : dynpft_init - use dynHarvestMod , only : dynHarvest_init - use dynpftFileMod , only : dynpft_interp + use decompMod , only : bounds_type, BOUNDS_LEVEL_PROC + use decompMod , only : get_proc_clumps, get_clump_bounds + use dynpftFileMod , only : dynpft_init + use dynHarvestMod , only : dynHarvest_init + use dynpftFileMod , only : dynpft_interp + use elm_varctl , only : fates_harvest_mode + use dynFATESLandUseChangeMod , only : fates_harvest_clmlanduse ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds ! processor-level bounds @@ -103,7 +105,7 @@ subroutine dynSubgrid_init(bounds, glc2lnd_vars, crop_vars) end if ! Initialize stuff for harvest (currently shares the flanduse_timeseries file) - if (get_do_harvest()) then + if (get_do_harvest() .or. fates_harvest_mode == fates_harvest_clmlanduse) then call dynHarvest_init(bounds, harvest_filename=get_flanduse_timeseries()) end if @@ -154,7 +156,8 @@ subroutine dynSubgrid_driver(bounds_proc, & ! ! !USES: use elm_varctl , only : use_cn, create_glacier_mec_landunit - use elm_varctl , only : use_fates, use_fates_luh + use elm_varctl , only : use_fates, use_fates_luh, fates_harvest_mode + use elm_varctl , only : use_fates_potentialveg use decompMod , only : bounds_type, get_proc_clumps, get_clump_bounds use decompMod , only : BOUNDS_LEVEL_PROC use dynInitColumnsMod , only : initialize_new_columns @@ -164,6 +167,7 @@ subroutine dynSubgrid_driver(bounds_proc, & use dynHarvestMod , only : dynHarvest_interp_harvest_types use dynFATESLandUseChangeMod, only : dynFatesLandUseInterp + use dynFATESLandUseChangeMod , only : fates_harvest_clmlanduse use dynEDMod , only : dyn_ED use reweightMod , only : reweight_wrapup @@ -244,11 +248,11 @@ subroutine dynSubgrid_driver(bounds_proc, & call dyncrop_interp(bounds_proc,crop_vars) end if - if (get_do_harvest()) then + if (get_do_harvest() .or. fates_harvest_mode == fates_harvest_clmlanduse) then call dynHarvest_interp_harvest_types(bounds_proc) end if - if (use_fates_luh) then + if (use_fates_luh .and. .not. use_fates_potentialveg) then call dynFatesLandUseInterp(bounds_proc) end if diff --git a/components/elm/src/main/controlMod.F90 b/components/elm/src/main/controlMod.F90 index 8f763a9ebd4d..1e200ce045c0 100755 --- a/components/elm/src/main/controlMod.F90 +++ b/components/elm/src/main/controlMod.F90 @@ -250,7 +250,7 @@ subroutine control_init( ) namelist /elm_inparm / use_c13, use_c14 namelist /elm_inparm/ fates_paramfile, use_fates, & - fates_spitfire_mode, use_fates_logging, & + fates_spitfire_mode, fates_harvest_mode, & use_fates_planthydro, use_fates_ed_st3, & use_fates_cohort_age_tracking, & use_fates_ed_prescribed_phys, & @@ -260,7 +260,10 @@ subroutine control_init( ) use_fates_nocomp, & use_fates_sp, & use_fates_luh, & + use_fates_lupft, & + use_fates_potentialveg, & fluh_timeseries, & + flandusepftdat, & fates_parteh_mode, & fates_seeddisp_cadence, & use_fates_tree_damage, & @@ -802,9 +805,10 @@ subroutine control_spmd() call mpi_bcast (fates_spitfire_mode, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (fates_harvest_mode, len(fates_harvest_mode), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_paramfile, len(fates_paramfile) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fluh_timeseries, len(fluh_timeseries) , MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (use_fates_logging, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (flandusepftdat, len(flandusepftdat) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (use_fates_planthydro, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_cohort_age_tracking, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_ed_st3, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -812,6 +816,8 @@ subroutine control_spmd() 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 (use_fates_lupft, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (use_fates_potentialveg, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_ed_prescribed_phys, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_inventory_init, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (fates_inventory_ctrl_filename, len(fates_inventory_ctrl_filename), & @@ -1217,9 +1223,10 @@ subroutine control_print () write(iulog, *) ' use_fates = ', use_fates if (use_fates) then write(iulog, *) ' fates_spitfire_mode = ', fates_spitfire_mode - write(iulog, *) ' use_fates_logging = ', use_fates_logging + write(iulog, *) ' fates_harvest_mode = ', fates_harvest_mode write(iulog, *) ' fates_paramfile = ', fates_paramfile write(iulog, *) ' fluh_timeseries = ', fluh_timeseries + write(iulog, *) ' flandusepftdat = ', flandusepftdat write(iulog, *) ' use_fates_planthydro = ', use_fates_planthydro write(iulog, *) ' use_fates_tree_damage = ', use_fates_tree_damage write(iulog, *) ' use_fates_cohort_age_tracking = ',use_fates_cohort_age_tracking @@ -1231,6 +1238,8 @@ 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_luh + write(iulog, *) ' use_fates_lupft = ', use_fates_lupft + write(iulog, *) ' use_fates_potentialveg = ', use_fates_potentialveg write(iulog, *) ' fates_inventory_ctrl_filename = ',fates_inventory_ctrl_filename write(iulog, *) ' fates_seeddisp_cadence = ', fates_seeddisp_cadence write(iulog, *) ' fates_seeddisp_cadence: 0, 1, 2, 3 => off, daily, monthly, or yearly dispersal' diff --git a/components/elm/src/main/elm_instMod.F90 b/components/elm/src/main/elm_instMod.F90 index b8afca87e241..6e41290d9c7c 100644 --- a/components/elm/src/main/elm_instMod.F90 +++ b/components/elm/src/main/elm_instMod.F90 @@ -145,6 +145,8 @@ subroutine elm_inst_biogeochem(bounds_proc) ! initialize biogeochemical variables use elm_varcon , only : c13ratio, c14ratio use histFileMod , only : hist_printflds + use elm_varctl , only : flandusepftdat + implicit none type(bounds_type), intent(in) :: bounds_proc @@ -245,7 +247,7 @@ subroutine elm_inst_biogeochem(bounds_proc) ! Initialize the Functionaly Assembled Terrestrial Ecosystem Simulator (FATES) if (use_fates) then - call alm_fates%init(bounds_proc) + call alm_fates%init(bounds_proc, flandusepftdat) end if call hist_printflds() diff --git a/components/elm/src/main/elm_varctl.F90 b/components/elm/src/main/elm_varctl.F90 index 7fa580b19f28..39740277e1ce 100644 --- a/components/elm/src/main/elm_varctl.F90 +++ b/components/elm/src/main/elm_varctl.F90 @@ -221,8 +221,8 @@ module elm_varctl logical, public :: use_fates = .false. ! true => use ED integer, public :: fates_spitfire_mode = 0 ! 0 for no fire; 1 for constant ignitions + character(len=13), public :: fates_harvest_mode = '' ! five different harvest modes; see namelist_definitions logical, public :: use_fates_fixed_biogeog = .false. ! true => use fixed biogeography mode - 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_tree_damage = .false. ! true => turn on tree damage module @@ -232,7 +232,10 @@ module elm_varctl logical, public :: use_fates_nocomp = .false. ! true => no competition mode logical, public :: use_fates_sp = .false. ! true => FATES satellite phenology mode logical, public :: use_fates_luh = .false. ! true => FATES land use transitions mode + logical, public :: use_fates_lupft = .false. ! true => FATES land use x pft mode + logical, public :: use_fates_potentialveg = .false. ! true => FATES potential veg only character(len=256), public :: fluh_timeseries = '' ! filename for land use harmonization data + character(len=256), public :: flandusepftdat = '' ! filename for fates landuse x pft data character(len=256), public :: fates_inventory_ctrl_filename = '' ! filename for inventory control integer, public :: fates_parteh_mode = -9 ! 1 => carbon only ! 2 => C+N+P (not enabled yet) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 520197de5765..0c67c0e82262 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -44,18 +44,21 @@ module ELMFatesInterfaceMod use elm_varctl , only : use_fates use elm_varctl , only : use_vertsoilc use elm_varctl , only : fates_spitfire_mode + use elm_varctl , only : fates_harvest_mode use elm_varctl , only : fates_parteh_mode use elm_varctl , only : fates_seeddisp_cadence use elm_varctl , only : use_fates_planthydro use elm_varctl , only : use_fates_cohort_age_tracking use elm_varctl , only : use_fates_ed_st3 use elm_varctl , only : use_fates_ed_prescribed_phys - use elm_varctl , only : use_fates_logging use elm_varctl , only : use_fates_inventory_init use elm_varctl , only : use_fates_fixed_biogeog use elm_varctl , only : use_fates_nocomp use elm_varctl , only : use_fates_sp use elm_varctl , only : use_fates_luh + use elm_varctl , only : use_fates_lupft + use elm_varctl , only : use_fates_potentialveg + use elm_varctl , only : flandusepftdat use elm_varctl , only : use_fates_tree_damage use elm_varctl , only : nsrest, nsrBranch use elm_varctl , only : fates_inventory_ctrl_filename @@ -172,14 +175,23 @@ module ELMFatesInterfaceMod use dynHarvestMod , only : num_harvest_vars, harvest_varnames, wood_harvest_units use dynHarvestMod , only : harvest_rates ! these are dynamic in space and time - use dynSubgridControlMod , only : get_do_harvest ! this gets the namelist value use FatesConstantsMod , only : hlm_harvest_area_fraction use FatesConstantsMod , only : hlm_harvest_carbon - 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 + use dynFATESLandUseChangeMod, only : num_landuse_transition_vars + use dynFATESLandUseChangeMod, only : num_landuse_state_vars + use dynFATESLandUseChangeMod, only : num_landuse_harvest_vars + use dynFATESLandUseChangeMod, only : landuse_transitions + use dynFATESLandUseChangeMod, only : landuse_states + use dynFATESLandUseChangeMod, only : landuse_harvest + use dynFATESLandUseChangeMod, only : landuse_transition_varnames + use dynFATESLandUseChangeMod, only : landuse_state_varnames + use dynFATESLandUseChangeMod, only : landuse_harvest_varnames + use dynFATESLandUseChangeMod, only : landuse_harvest_units + use dynFATESLandUseChangeMod, only : fates_harvest_no_logging + use dynFATESLandUseChangeMod, only : fates_harvest_clmlanduse + use dynFATESLandUseChangeMod, only : fates_harvest_luh_area + use dynFATESLandUseChangeMod, only : fates_harvest_luh_mass use FatesInterfaceTypesMod , only : bc_in_type, bc_out_type @@ -282,6 +294,8 @@ module ELMFatesInterfaceMod character(len=*), parameter, private :: sourcefile = & __FILE__ + integer, parameter :: num_landuse_pft_vars = 4 + public :: ELMFatesGlobals1 public :: ELMFatesGlobals2 public :: ELMFatesTimesteps @@ -389,12 +403,14 @@ subroutine ELMFatesGlobals2() integer :: pass_inventory_init integer :: pass_is_restart integer :: pass_cohort_age_tracking - integer :: pass_num_lu_harvest_types + integer :: pass_num_lu_harvest_cats integer :: pass_lu_harvest integer :: pass_tree_damage integer :: pass_use_luh + integer :: pass_use_potentialveg integer :: pass_num_luh_states integer :: pass_num_luh_transitions + integer :: pass_lupftdat ! ---------------------------------------------------------------------------------- ! FATES lightning definitions ! 1 : use a global constant lightning rate found in fates_params. @@ -440,7 +456,7 @@ subroutine ELMFatesGlobals2() end if call set_fates_ctrlparms('use_tree_damage',ival=pass_tree_damage) - if((trim(nu_com).eq.'ECA') .or. (trim(nu_com).eq.'MIC')) then + if((trim(nu_com)=='ECA') .or. (trim(nu_com)=='MIC')) then call set_fates_ctrlparms('nu_com',cval='ECA') else call set_fates_ctrlparms('nu_com',cval='RD') @@ -464,7 +480,7 @@ subroutine ELMFatesGlobals2() call set_fates_ctrlparms('nitrogen_spec',ival=1) call set_fates_ctrlparms('phosphorus_spec',ival=1) - if(is_restart() .or. nsrest .eq. nsrBranch) then + if(is_restart() .or. nsrest == nsrBranch) then pass_is_restart = 1 else pass_is_restart = 0 @@ -507,26 +523,30 @@ subroutine ELMFatesGlobals2() call set_fates_ctrlparms('sf_successful_ignitions_def',ival=successful_ignitions) call set_fates_ctrlparms('sf_anthro_ignitions_def',ival=anthro_ignitions) - ! check fates logging namelist value first because hlm harvest overrides it - if(use_fates_logging) then - pass_logging = 1 - else - pass_logging = 0 + ! FATES logging and harvest modes + pass_logging = 0 + pass_lu_harvest = 0 + pass_num_lu_harvest_cats = 0 + if (trim(fates_harvest_mode) /= fates_harvest_no_logging) then + pass_logging = 1 ! Time driven logging, without landuse harvest + ! CLM landuse timeseries driven harvest rates + if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then + pass_num_lu_harvest_cats = num_harvest_vars + pass_lu_harvest = 1 + + ! LUH2 landuse timeseries driven harvest rates + else if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. & + trim(fates_harvest_mode) == fates_harvest_luh_mass) then + pass_lu_harvest = 1 + pass_num_lu_harvest_cats = num_landuse_harvest_vars + end if end if - if(get_do_harvest()) then - pass_logging = 1 - pass_num_lu_harvest_types = num_harvest_vars - pass_lu_harvest = 1 - else - pass_lu_harvest = 0 - pass_num_lu_harvest_types = 0 - end if call set_fates_ctrlparms('use_lu_harvest',ival=pass_lu_harvest) - call set_fates_ctrlparms('num_lu_harvest_cats',ival=pass_num_lu_harvest_types) + 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 + 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 @@ -535,10 +555,18 @@ subroutine ELMFatesGlobals2() 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_potentialveg ) then + pass_use_potentialveg = 1 + else + pass_use_potentialveg = 0 + end if + call set_fates_ctrlparms('use_fates_potentialveg',ival=pass_use_potentialveg) + if(use_fates_ed_st3) then pass_ed_st3 = 1 else @@ -690,7 +718,7 @@ end subroutine ELMFatesTimesteps ! ==================================================================================== - subroutine init(this, bounds_proc ) + subroutine init(this, bounds_proc, flandusepftdat) ! --------------------------------------------------------------------------------- ! This initializes the hlm_fates_interface_type @@ -722,6 +750,7 @@ subroutine init(this, bounds_proc ) ! Input Arguments class(hlm_fates_interface_type), intent(inout) :: this type(bounds_type),intent(in) :: bounds_proc + character(len=*), intent(in) :: flandusepftdat ! local variables integer :: nclumps ! Number of threads @@ -740,6 +769,9 @@ subroutine init(this, bounds_proc ) integer :: ndecomp integer :: numg + real(r8), allocatable :: landuse_pft_map(:,:,:) + real(r8), allocatable :: landuse_bareground(:) + ! Initialize the FATES communicators with the HLM ! This involves to stages ! 1) allocate the vectors @@ -765,6 +797,12 @@ subroutine init(this, bounds_proc ) write(iulog,*) 'alm_fates%init(): allocating for ',nclumps,' threads' end if + ! Retrieve the landuse x pft static data if the optional switch has been set + if (use_fates_fixed_biogeog .and. use_fates_luh) call GetLandusePFTData(bounds_proc, flandusepftdat, & + landuse_pft_map, landuse_bareground) + + nclumps = get_proc_clumps() + !$OMP PARALLEL DO PRIVATE (nc,bounds_clump,nmaxcol,s,c,l,g,collist,pi,pf,ft) do nc = 1,nclumps @@ -883,17 +921,25 @@ subroutine init(this, bounds_proc ) endif endif - ! initialize static layers for reduced complexity FATES versions from HLM - this%fates(nc)%bc_in(s)%pft_areafrac(:)=0._r8 - do m = surfpft_lb,surfpft_ub - ft = m-surfpft_lb - this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,t,m) - end do + if (use_fates_fixed_biogeog) then + ! Transfer the landuse x pft data to fates via bc_in if landuse mode engaged + if (use_fates_luh) then + this%fates(nc)%bc_in(s)%pft_areafrac_lu(:,1:num_landuse_pft_vars) = landuse_pft_map(g,:,1:num_landuse_pft_vars) + this%fates(nc)%bc_in(s)%baregroundfrac = landuse_bareground(g) + else + ! initialize static layers for reduced complexity FATES versions from HLM + this%fates(nc)%bc_in(s)%pft_areafrac(:)=0._r8 + do m = surfpft_lb,surfpft_ub + ft = m-surfpft_lb + this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,t,m) + end do - if(abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub))-1.0_r8).gt.1.0e-9)then - write(iulog,*) 'pft_area error in interfc ',s, sum(this%fates(nc)%bc_in(s)%pft_areafrac(:))-1.0_r8 - call endrun(msg=errMsg(sourcefile, __LINE__)) - endif + if(abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub))-1.0_r8).gt.1.0e-9)then + write(iulog,*) 'pft_area error in interfc ',s, sum(this%fates(nc)%bc_in(s)%pft_areafrac(:))-1.0_r8 + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + end if + end if end do @@ -912,7 +958,6 @@ subroutine init(this, bounds_proc ) call endrun(msg=errMsg(sourcefile, __LINE__)) end if - ! Set patch itypes on natural veg columns to nonsense ! This will force a crash if the model outside of FATES tries to think ! of the patch as a PFT. @@ -935,6 +980,12 @@ subroutine init(this, bounds_proc ) ! Fire data to send to FATES call create_fates_fire_data_method( this%fates_fire_data_method ) + ! deallocate the local landuse x pft array + if (use_fates_fixed_biogeog .and. use_fates_luh) then + deallocate(landuse_pft_map) + deallocate(landuse_bareground) + end if + end subroutine init ! =================================================================================== @@ -1047,7 +1098,7 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & lnfm24 = this%fates_fire_data_method%GetLight24() end if - if (fates_spitfire_mode .eq. anthro_suppression) then + if (fates_spitfire_mode == anthro_suppression) then allocate(gdp_lf_col(bounds_clump%begc:bounds_clump%endc), stat=ier) if (ier /= 0) then call endrun(msg="allocation error for gdp"//& @@ -1067,13 +1118,13 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & this%fates(nc)%bc_in(s)%lightning24(ifp) = lnfm24(g) * 24._r8 ! #/km2/hr to #/km2/day - if (fates_spitfire_mode .ge. anthro_ignitions) then + if (fates_spitfire_mode >= anthro_ignitions) then this%fates(nc)%bc_in(s)%pop_density(ifp) = this%fates_fire_data_method%forc_hdm(g) end if end do ! ifp - if (fates_spitfire_mode .eq. anthro_suppression) then + if (fates_spitfire_mode == anthro_suppression) then ! Placeholder for future fates use of gdp - comment out before integration !this%fates(nc)%bc_in(s)%gdp = gdp_lf_col(c) ! k US$/capita(g) end if @@ -1152,10 +1203,15 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & ! for now there is one veg column per gridcell, so store all harvest data in each site ! this will eventually change ! the harvest data are zero if today is before the start of the harvest time series - if (get_do_harvest()) then + if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then this%fates(nc)%bc_in(s)%hlm_harvest_rates = harvest_rates(:,g) this%fates(nc)%bc_in(s)%hlm_harvest_catnames = harvest_varnames this%fates(nc)%bc_in(s)%hlm_harvest_units = wood_harvest_units + else if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. & + trim(fates_harvest_mode) == fates_harvest_luh_mass) then + this%fates(nc)%bc_in(s)%hlm_harvest_rates = landuse_harvest(:,g) + this%fates(nc)%bc_in(s)%hlm_harvest_catnames = landuse_harvest_varnames + this%fates(nc)%bc_in(s)%hlm_harvest_units = landuse_harvest_units end if this%fates(nc)%bc_in(s)%site_area=col_pp%wtgcell(c)*grc_pp%area(g)*m2_per_km2 @@ -1913,7 +1969,6 @@ end subroutine restart subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_inst) - ! Arguments class(hlm_fates_interface_type), intent(inout) :: this type(canopystate_type) , intent(inout) :: canopystate_inst @@ -2016,17 +2071,26 @@ subroutine init_coldstart(this, canopystate_inst, soilstate_inst, frictionvel_in 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) + ! Transfer initial values to fates + if (use_fates_luh) then + do s = 1,this%fates(nc)%nsites + c = this%f2hmap(nc)%fcolumn(s) + g = col_pp%gridcell(c) + + 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 + + if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. & + trim(fates_harvest_mode) == fates_harvest_luh_mass) then + this%fates(nc)%bc_in(s)%hlm_harvest_rates = landuse_harvest(:,g) + this%fates(nc)%bc_in(s)%hlm_harvest_catnames = landuse_harvest_varnames + this%fates(nc)%bc_in(s)%hlm_harvest_units = landuse_harvest_units + end if - 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 + end do + end if ! Initialize patches call init_patches(this%fates(nc)%nsites, this%fates(nc)%sites, & @@ -3609,6 +3673,111 @@ subroutine GetAndSetTime() end subroutine GetAndSetTime - !----------------------------------------------------------------------- +! ====================================================================================== + + subroutine GetLandusePFTData(bounds, landuse_pft_file, landuse_pft_map, landuse_bareground) + + ! !DESCRIPTION: + ! Read in static landuse x pft file + + ! !USES: + use fileutils , only : getfil + use ncdio_pio , only : file_desc_t, ncd_io, ncd_inqdlen + use ncdio_pio , only : ncd_pio_openfile, ncd_pio_closefile + use decompMod , only : BOUNDS_LEVEL_PROC + use elm_varcon, only : grlnd + use FatesConstantsMod, only : fates_unset_r8 + + + ! !ARGUMENTS: + type(bounds_type), intent(in) :: bounds ! proc-level bounds + character(len=*) , intent(in) :: landuse_pft_file ! name of file containing static landuse x pft information + real(r8), allocatable, intent(inout) :: landuse_pft_map(:,:,:) + real(r8), allocatable, intent(inout) :: landuse_bareground(:) + + ! !LOCAL VARIABLES + integer :: varnum ! variable number + integer :: dimid, dimlen ! dimension id number and length + integer :: ier ! error id + character(len=256) :: locfn ! local file name + type(file_desc_t) :: ncid ! netcdf id + real(r8), pointer :: arraylocal(:,:) ! local array for reading fraction data + real(r8), pointer :: arraylocal_bareground(:) ! local array for reading bareground data + logical :: readvar ! true => variable is on dataset + !character(len=16), parameter :: grlnd = 'lndgrid' ! name of lndgrid + + integer, parameter :: dim_landuse_pft = 14 + + ! Land use name arrays + character(len=10), parameter :: landuse_pft_map_varnames(num_landuse_pft_vars) = & + [character(len=10) :: 'frac_primr','frac_secnd','frac_pastr','frac_range'] !need to move 'frac_surf' to a different variable + + character(len=*), parameter :: subname = 'GetLandusePFTData' + + !----------------------------------------------------------------------- + + ! Check to see if the landuse file name has been provided + ! Note: getfile checks this as well + if (masterproc) then + write(iulog,*) 'Attempting to read landuse x pft data .....' + if (landuse_pft_file == ' ') then + write(iulog,*)'landuse_pft_file must be specified' + call endrun(msg=errMsg(__FILE__, __LINE__)) + endif + endif + + ! Initialize the landuse x pft arrays and initialize to unset + allocate(landuse_pft_map(bounds%begg:bounds%endg,dim_landuse_pft,num_landuse_pft_vars),stat=ier) + if (ier /= 0) then + call endrun(msg=' allocation error for landuse_pft_map'//errMsg(__FILE__, __LINE__)) + end if + landuse_pft_map = fates_unset_r8 + + allocate(landuse_bareground(bounds%begg:bounds%endg),stat=ier) + if (ier /= 0) then + call endrun(msg=' allocation error for landuse_bareground'//errMsg(__FILE__, __LINE__)) + end if + landuse_bareground = fates_unset_r8 + + + ! Get the local filename and open the file + call getfil(landuse_pft_file, locfn, 0) + call ncd_pio_openfile (ncid, trim(locfn), 0) + + ! Check that natpft dimension on the file matches the target array dimensions + call ncd_inqdlen(ncid, dimid, dimlen, 'natpft') + if (dimlen /= dim_landuse_pft) then + write(iulog,*) 'natpft dimensions on the landuse x pft file do not match target array size' + call endrun(msg=errMsg(__FILE__, __LINE__)) + end if + + ! Allocate a temporary array since ncdio expects a pointer + allocate(arraylocal(bounds%begg:bounds%endg,dim_landuse_pft)) + allocate(arraylocal_bareground(bounds%begg:bounds%endg)) + + ! Read the landuse x pft data from file + do varnum = 1, num_landuse_pft_vars + call ncd_io(ncid=ncid, varname=landuse_pft_map_varnames(varnum), flag='read', & + data=arraylocal, dim1name=grlnd, readvar=readvar) + if (.not. readvar) & + call endrun(msg='ERROR: '//trim(landuse_pft_map_varnames(varnum))// & + ' NOT on landuse x pft file'//errMsg(__FILE__, __LINE__)) + landuse_pft_map(bounds%begg:bounds%endg,:,varnum) = arraylocal(bounds%begg:bounds%endg,:) + end do + + ! Read the bareground data from file. This is per gridcell only. + call ncd_io(ncid=ncid, varname='frac_brgnd', flag='read', & + data=arraylocal_bareground, dim1name=grlnd, readvar=readvar) + if (.not. readvar) call endrun(msg='ERROR: frac_brgnd NOT on landuse x pft file'//errMsg(__FILE__, __LINE__)) + landuse_bareground(bounds%begg:bounds%endg) = arraylocal_bareground(bounds%begg:bounds%endg) + + ! Deallocate the temporary local array point and close the file + deallocate(arraylocal) + deallocate(arraylocal_bareground) + call ncd_pio_closefile(ncid) + + ! Check that sums equal to unity + + end subroutine GetLandusePFTData end module ELMFatesInterfaceMod From d6ce03784ae7e395ff335e8c6f0267fd7c963446 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Mon, 8 Jul 2024 15:16:44 -0700 Subject: [PATCH 03/30] update fates submodule --- components/elm/src/external_models/fates | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index b8e4eee5ed46..fd7f3438c2ff 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit b8e4eee5ed46daf5c9e710e9ebbe6d20464adbc8 +Subproject commit fd7f3438c2ff821672b703050e7011f293649ee9 From e1f94eb048d9e0797a04f59451fce9a3a99778c4 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 10:42:34 -0700 Subject: [PATCH 04/30] remove out-of-date comment Checking the FATES land use x pft data is handled on the FATES side --- components/elm/src/main/elmfates_interfaceMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 0c67c0e82262..5eb0734084de 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -3776,8 +3776,6 @@ subroutine GetLandusePFTData(bounds, landuse_pft_file, landuse_pft_map, landuse_ deallocate(arraylocal_bareground) call ncd_pio_closefile(ncid) - ! Check that sums equal to unity - end subroutine GetLandusePFTData end module ELMFatesInterfaceMod From b17befff23cb4364e50cb9703efbf8da5946943e Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 11:16:47 -0700 Subject: [PATCH 05/30] change fates_harvest_mode option name This corrects a misnamed harvest option --- .../elm/bld/namelist_files/namelist_definition.xml | 8 +++++--- .../testmods_dirs/elm/fates_cold_landuse/user_nl_elm | 2 +- .../elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 | 10 +++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_definition.xml b/components/elm/bld/namelist_files/namelist_definition.xml index c597d164661d..7b6c75f17f0b 100644 --- a/components/elm/bld/namelist_files/namelist_definition.xml +++ b/components/elm/bld/namelist_files/namelist_definition.xml @@ -308,16 +308,18 @@ Allowed values are: 5 : use gross domestic production and population datasets to simulate anthropogenic fire supression - + valid_values="no_harvest,event_code,landuse_timeseries,luhdata_area,luhdata_mass" > Set FATES harvesting mode by setting fates_harvest_mode Allowed values are: no_harvest : no fates harvesting of any kind event_code : fates logging via fates logging event codes only (via fates parameter file) - surfdata_file: fates harvest driven by HLM landuse timeseries data (dynHarvestMod) + landuse_timeseries: fates harvest driven by HLM landuse timeseries data (dynHarvestMod) luhdata_area : fates harvest driven by LUH2 raw harvest data, area-based (dynFATESLandUseChangeMod) luhdata_mass : fates harvest driven by LUH2 raw harvest data, mass-based (dynFATESLandUseChangeMod) +Note that the landuse_timeseries option is not the same as the FATES fluh_timeseries data file. +This option is older than the luhdata options and may be depricated at some point in the future. Date: Tue, 9 Jul 2024 11:21:34 -0700 Subject: [PATCH 06/30] add clarifying language to FATES namelist options --- .../namelist_files/namelist_definition.xml | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_definition.xml b/components/elm/bld/namelist_files/namelist_definition.xml index 7b6c75f17f0b..c5c7e324f9e1 100644 --- a/components/elm/bld/namelist_files/namelist_definition.xml +++ b/components/elm/bld/namelist_files/namelist_definition.xml @@ -393,22 +393,25 @@ Full pathname to the inventory initialization control file. If TRUE, enable use of land use state and transition data from luh_timeseries file. -This is enabled by default if fates_harvest_mode is set to use the raw LUH2 harvest -data (fates_harvest_mode >= 3) or if use_fates_lupft is true. -(Only valid for fates land use change runs, where there is a luh_timeseries file.) +This is enabled by default if fates_harvest_mode is set to use the raw LUH2 harvest data (Also, only valid for use_fates = true and is incompatible with transient runs currently.) -If TRUE, enable use of fates land use x pft mapping data file. +If TRUE, enable use of fates land use x pft mapping data file. This mode +requires the use of the land use x pft association static data map file. See the +flandusepftdat definition entry in this file for more information. (Only valid for use_fates = true and is incompatible with transient runs currently.) If TRUE, ignore the land-use state vector and transitions, and assert that all lands -are primary, and that there is no harvest. +are primary, and that there is no harvest. This mode is only relevant for FATES +spin-up workflows that are intending to use the spin-up restart output to start a +FATES land use transient case using the use_fates_lupft namelist option. The option +should be set to true for the spin-up case and false for the transient case. @@ -434,6 +437,13 @@ output level is not enabled. Full pathname of fates landuse x pft data map. +The file associates land use types with pfts across a static global map. +This file is necessary for running FATES with use_fates_luh, +use_fates_nocomp, and use_fates_fixedbiogeo engaged (note that use_fates_lupft +is provided as a namelist option to engage all necessary options). The file is output +by the FATES land use data tool (https://github.com/NGEET/tools-fates-landusedata) +which processes the raw land use data from the THEMIS tool data sets +(https://doi.org/10.5065/29s7-7b41) Date: Tue, 9 Jul 2024 11:24:22 -0700 Subject: [PATCH 07/30] rename clmlanduse to hlmlanduse --- .../elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 | 2 +- components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 | 8 ++++---- components/elm/src/main/elmfates_interfaceMod.F90 | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 index e4143283ef5d..04f76767f546 100644 --- a/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 +++ b/components/elm/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 @@ -32,7 +32,7 @@ module dynFATESLandUseChangeMod ! Define the fates landuse namelist mode switch values character(len=18), public, parameter :: fates_harvest_no_logging = 'no_harvest' character(len=18), public, parameter :: fates_harvest_logging_only = 'event_code' - character(len=18), public, parameter :: fates_harvest_clmlanduse = 'landuse_timeseries' + character(len=18), public, parameter :: fates_harvest_hlmlanduse = 'landuse_timeseries' character(len=18), public, parameter :: fates_harvest_luh_area = 'luhdata_area' character(len=18), public, parameter :: fates_harvest_luh_mass = 'luhdata_mass' diff --git a/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 b/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 index 6914e4d70c38..7335d47fb099 100644 --- a/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 +++ b/components/elm/src/dyn_subgrid/dynSubgridDriverMod.F90 @@ -77,7 +77,7 @@ subroutine dynSubgrid_init(bounds, glc2lnd_vars, crop_vars) use dynHarvestMod , only : dynHarvest_init use dynpftFileMod , only : dynpft_interp use elm_varctl , only : fates_harvest_mode - use dynFATESLandUseChangeMod , only : fates_harvest_clmlanduse + use dynFATESLandUseChangeMod , only : fates_harvest_hlmlanduse ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds ! processor-level bounds @@ -105,7 +105,7 @@ subroutine dynSubgrid_init(bounds, glc2lnd_vars, crop_vars) end if ! Initialize stuff for harvest (currently shares the flanduse_timeseries file) - if (get_do_harvest() .or. fates_harvest_mode == fates_harvest_clmlanduse) then + if (get_do_harvest() .or. fates_harvest_mode == fates_harvest_hlmlanduse) then call dynHarvest_init(bounds, harvest_filename=get_flanduse_timeseries()) end if @@ -167,7 +167,7 @@ subroutine dynSubgrid_driver(bounds_proc, & use dynHarvestMod , only : dynHarvest_interp_harvest_types use dynFATESLandUseChangeMod, only : dynFatesLandUseInterp - use dynFATESLandUseChangeMod , only : fates_harvest_clmlanduse + use dynFATESLandUseChangeMod , only : fates_harvest_hlmlanduse use dynEDMod , only : dyn_ED use reweightMod , only : reweight_wrapup @@ -248,7 +248,7 @@ subroutine dynSubgrid_driver(bounds_proc, & call dyncrop_interp(bounds_proc,crop_vars) end if - if (get_do_harvest() .or. fates_harvest_mode == fates_harvest_clmlanduse) then + if (get_do_harvest() .or. fates_harvest_mode == fates_harvest_hlmlanduse) then call dynHarvest_interp_harvest_types(bounds_proc) end if diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 5eb0734084de..51fa36a747c7 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -189,7 +189,7 @@ module ELMFatesInterfaceMod use dynFATESLandUseChangeMod, only : landuse_harvest_varnames use dynFATESLandUseChangeMod, only : landuse_harvest_units use dynFATESLandUseChangeMod, only : fates_harvest_no_logging - use dynFATESLandUseChangeMod, only : fates_harvest_clmlanduse + use dynFATESLandUseChangeMod, only : fates_harvest_hlmlanduse use dynFATESLandUseChangeMod, only : fates_harvest_luh_area use dynFATESLandUseChangeMod, only : fates_harvest_luh_mass @@ -530,7 +530,7 @@ subroutine ELMFatesGlobals2() if (trim(fates_harvest_mode) /= fates_harvest_no_logging) then pass_logging = 1 ! Time driven logging, without landuse harvest ! CLM landuse timeseries driven harvest rates - if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then + if (trim(fates_harvest_mode) == fates_harvest_hlmlanduse) then pass_num_lu_harvest_cats = num_harvest_vars pass_lu_harvest = 1 @@ -1203,7 +1203,7 @@ subroutine dynamics_driv(this, bounds_clump, top_as_inst, & ! for now there is one veg column per gridcell, so store all harvest data in each site ! this will eventually change ! the harvest data are zero if today is before the start of the harvest time series - if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then + if (trim(fates_harvest_mode) == fates_harvest_hlmlanduse) then this%fates(nc)%bc_in(s)%hlm_harvest_rates = harvest_rates(:,g) this%fates(nc)%bc_in(s)%hlm_harvest_catnames = harvest_varnames this%fates(nc)%bc_in(s)%hlm_harvest_units = wood_harvest_units From c1bf03015ea0fc47779c09fce9458c7fa0e897c8 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 11:40:42 -0700 Subject: [PATCH 08/30] add new fates luh2 tests and update existing --- .../testdefs/testmods_dirs/elm/fates_cold_luh2/README | 2 ++ .../testdefs/testmods_dirs/elm/fates_cold_luh2/user_nl_elm | 4 ++++ .../elm/fates_cold_luh2harvestarea/include_user_mods | 1 + .../testmods_dirs/elm/fates_cold_luh2harvestarea/user_nl_elm | 1 + .../elm/fates_cold_luh2harvestmass/include_user_mods | 1 + .../testmods_dirs/elm/fates_cold_luh2harvestmass/user_nl_elm | 1 + 6 files changed, 10 insertions(+) create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/README create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/include_user_mods create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/user_nl_elm create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/include_user_mods create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/user_nl_elm diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/README b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/README new file mode 100644 index 000000000000..79d6511d1728 --- /dev/null +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/README @@ -0,0 +1,2 @@ +Currently the FATES LUH2 category of test mods currently only supports +4x5 grid resolutions. diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/user_nl_elm index 854c21407f1a..3f089bcf49d2 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2/user_nl_elm @@ -1 +1,5 @@ use_fates_luh = .true. +use_fates_nocomp = .true. +use_fates_fixed_biogeog = .true. +use_fates_sp = .false. +use_fates_potentialveg = .false. diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/include_user_mods b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/include_user_mods new file mode 100644 index 000000000000..9474118e0370 --- /dev/null +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/include_user_mods @@ -0,0 +1 @@ +../fates_cold_luh2 diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/user_nl_elm new file mode 100644 index 000000000000..426b41b49e59 --- /dev/null +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestarea/user_nl_elm @@ -0,0 +1 @@ +fates_harvest_mode = 'luhdata_area' diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/include_user_mods b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/include_user_mods new file mode 100644 index 000000000000..9474118e0370 --- /dev/null +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/include_user_mods @@ -0,0 +1 @@ +../fates_cold_luh2 diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/user_nl_elm new file mode 100644 index 000000000000..7b6bc24f5a79 --- /dev/null +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_luh2harvestmass/user_nl_elm @@ -0,0 +1 @@ +fates_harvest_mode = 'luhdata_mass' From 4420c0d7b32173b1dc3cf4491ac9d8b95afd5738 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 11:42:05 -0700 Subject: [PATCH 09/30] change logging test to use replacement fates harvest mode --- .../testdefs/testmods_dirs/elm/fates_cold_logging/user_nl_elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_logging/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_logging/user_nl_elm index 3b74a4fd3798..d2079d9e4386 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_logging/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/fates_cold_logging/user_nl_elm @@ -1 +1 @@ -use_fates_logging= .true. +fates_harvest_mode = 'event_code' From 8bd03727dc1c4e2d2a8690602f4ef1027149c588 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 11:52:29 -0700 Subject: [PATCH 10/30] add new fates test mods to test list This also adds a new fates_landuse test list that is inherited by the fates test list --- cime_config/tests.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cime_config/tests.py b/cime_config/tests.py index 657c944204b1..28b53e0405ab 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -435,21 +435,30 @@ }, #fates testmod coverage + "fates_landuse" : { + "time" : "00:40:00", + "tests" : ( + "ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_logging", + "ERS_D_Ld30.f45_g37.IELMFATES.elm-fates_cold_landuse", + "ERS_D_Ld30.f45_g37.IELMFATES.elm-fates_cold_luh2", + "ERS_D_Ld30.f45_g37.IELMFATES.elm-fates_cold_luh2harvestarea", + "ERS_D_Ld30.f45_g37.IELMFATES.elm-fates_cold_luh2harvestmass", + ) + }, + #fates testmod coverage "fates" : { - "inherit" : ("fates_long_tests", "fates_elm_developer"), + "inherit" : ("fates_long_tests", "fates_elm_developer", "fates_landuse"), "tests" : ( "ERP_Ld15.ne4pg2_ne4pg2.IELMFATES.elm-fates_cold_allvars", "ERP_Ld3.f09_g16.IELMFATES.elm-fates_cold", "ERP_D_Ld3.f19_g16.IELMFATES.elm-fates_cold", "ERS_D_Ld3_PS.f09_g16.IELMFATES.elm-fates_cold", "ERS_D_Ld5.f45_g37.IELMFATES.elm-fates_cold", - "ERS_D_Ld30.f45_g37.IELMFATES.elm-fates_cold_landuse", "ERS_Ld30.f45_g37.IELMFATES.elm-fates_satphen", "ERS_Ld30.f45_g37.IELMFATES.elm-fates_cold_fixedbiogeo", "ERS_Ld30.f45_g37.IELMFATES.elm-fates_cold_nocomp", "ERS_Ld30.f45_g37.IELMFATES.elm-fates_cold_nocomp_fixedbiogeo", "ERS_Ld60.f45_g37.IELMFATES.elm-fates", - "ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_logging", "ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_nofire", "ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_st3", "ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_pphys", From 512c499e5472225e065125654b2f374eddbb9b01 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 13:38:49 -0700 Subject: [PATCH 11/30] add trim to the write statement output --- components/elm/src/main/controlMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/elm/src/main/controlMod.F90 b/components/elm/src/main/controlMod.F90 index 1e200ce045c0..c1e72662d5e7 100755 --- a/components/elm/src/main/controlMod.F90 +++ b/components/elm/src/main/controlMod.F90 @@ -1225,8 +1225,8 @@ subroutine control_print () write(iulog, *) ' fates_spitfire_mode = ', fates_spitfire_mode write(iulog, *) ' fates_harvest_mode = ', fates_harvest_mode write(iulog, *) ' fates_paramfile = ', fates_paramfile - write(iulog, *) ' fluh_timeseries = ', fluh_timeseries - write(iulog, *) ' flandusepftdat = ', flandusepftdat + write(iulog, *) ' fluh_timeseries = ', trim(fluh_timeseries) + write(iulog, *) ' flandusepftdat = ', trim(flandusepftdat) write(iulog, *) ' use_fates_planthydro = ', use_fates_planthydro write(iulog, *) ' use_fates_tree_damage = ', use_fates_tree_damage write(iulog, *) ' use_fates_cohort_age_tracking = ',use_fates_cohort_age_tracking From 6c1cb2e9f9dd4d3feb4129f81558d6e0cd1bbe44 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 13:56:18 -0700 Subject: [PATCH 12/30] minor change in call to GetLandusePFTData --- components/elm/src/main/elmfates_interfaceMod.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 51fa36a747c7..521c20cde297 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -798,8 +798,9 @@ subroutine init(this, bounds_proc, flandusepftdat) end if ! Retrieve the landuse x pft static data if the optional switch has been set - if (use_fates_fixed_biogeog .and. use_fates_luh) call GetLandusePFTData(bounds_proc, flandusepftdat, & - landuse_pft_map, landuse_bareground) + if (use_fates_fixed_biogeog .and. use_fates_luh) then + call GetLandusePFTData(bounds_proc, flandusepftdat, landuse_pft_map, landuse_bareground) + end if nclumps = get_proc_clumps() From 27003a03fa8beaadcfb48f95d2d718c303e24efc Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 15:09:05 -0700 Subject: [PATCH 13/30] update fates parameter file --- components/elm/bld/namelist_files/namelist_defaults.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index 6459605ff4dc..ea44826fb351 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -134,7 +134,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/fates_params_api.35.0.0_12pft_c240326.nc +lnd/clm2/paramdata/fates_params_api.36.0.0_12pft_c240517.nc lnd/clm2/paramdata/CNP_parameters_c131108.nc From 7b3f8fa926cf139ab14cc362c093244db3796dd7 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Tue, 9 Jul 2024 15:16:52 -0700 Subject: [PATCH 14/30] refactor fates build namelist options --- components/elm/bld/ELMBuildNamelist.pm | 53 +++++++++++++++----------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 05e19b9bbb4a..241f2f6b99bb 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -808,12 +808,14 @@ sub setup_cmdl_fates_mode { # The following variables may be set by the user and are compatible with use_fates # no need to set defaults, covered in a different routine - my @list = ( "fates_spitfire_mode", + my @list = ( "flandusepftdat", + "fluh_timeseries", "fates_harvest_mode", "fates_history_dimlevel", "fates_inventory_ctrl_filename", + "fates_parteh_mode", "fates_seeddisp_cadence", - "use_century_decomp", + "fates_spitfire_mode", "use_fates_cohort_age_tracking", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", @@ -822,14 +824,13 @@ sub setup_cmdl_fates_mode { "use_fates_luh", "use_fates_lupft", "use_fates_nocomp", - "use_fates_parteh_mode", "use_fates_planthydro", "use_fates_potentialveg", "use_fates_sp", "use_fates_tree_damage", + "use_century_decomp", "use_snicar_ad", - "use_vertsoilc", - "fluh_timeseries"); + "use_vertsoilc"); foreach my $var ( @list ) { if ( defined($nl->get_value($var)) ) { $nl_flags->{$var} = $nl->get_value($var); @@ -3403,24 +3404,30 @@ sub setup_logic_fates { add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'flandusepftdat', 'phys'=>$nl_flags->{'phys'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_harvest_mode', 'use_fates'=>$nl_flags->{'use_fates'} ); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_history_dimlevel', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_inventory_ctrl_filename','use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_parteh_mode', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_seeddisp_cadence', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_spitfire_mode', 'use_fates'=>$nl_flags->{'use_fates'} ); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_cohort_age_tracking','use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_ed_st3', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_ed_prescribed_phys', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_fixed_biogeog', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_inventory_init', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_planthydro', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_sp', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_tree_damage', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_luh', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_lupft', 'use_fates'=>$nl_flags->{'use_fates'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_potentialveg', 'use_fates'=>$nl_flags->{'use_fates'}); + + my @list = ( "fates_harvest_mode", + "fates_history_dimlevel", + "fates_inventory_ctrl_filename", + "fates_parteh_mode", + "fates_seeddisp_cadence", + "fates_spitfire_mode", + "use_fates_cohort_age_tracking", + "use_fates_ed_st3", + "use_fates_ed_prescribed_phys", + "use_fates_fixed_biogeog", + "use_fates_inventory_init", + "use_fates_luh", + "use_fates_lupft", + "use_fates_nocomp", + "use_fates_planthydro", + "use_fates_potentialveg", + "use_fates_sp", + "use_fates_tree_damage"); + + foreach my $var (@list) { + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,'use_fates'=>$nl_flags->{'use_fates'}, + 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} ); + } # For FATES SP mode make sure no-competion, and fixed-biogeography are also set # And also check for other settings that can't be trigged on as well From f636d9be39d825a3129e8ae3a7e3b57830c115af Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 13:00:21 -0700 Subject: [PATCH 15/30] correct how fates sp mode value is passed to add_default for building namelists --- components/elm/bld/ELMBuildNamelist.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 241f2f6b99bb..0d0f6b0532ad 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3401,6 +3401,8 @@ sub setup_logic_fates { my ($test_files, $nl_flags, $definition, $defaults, $nl, $physv) = @_; if ( value_is_true( $nl_flags->{'use_fates'}) ) { + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_sp','use_fates'=>$nl_flags->{'use_fates'}); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'flandusepftdat', 'phys'=>$nl_flags->{'phys'}); @@ -3421,12 +3423,11 @@ sub setup_logic_fates { "use_fates_nocomp", "use_fates_planthydro", "use_fates_potentialveg", - "use_fates_sp", "use_fates_tree_damage"); foreach my $var (@list) { add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,'use_fates'=>$nl_flags->{'use_fates'}, - 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} ); + 'use_fates_sp'=>$nl->get_value('use_fates_sp') ); } # For FATES SP mode make sure no-competion, and fixed-biogeography are also set From 342e6f5b3ece02d6e58593f0b2b37f25f31e2e45 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 13:38:38 -0700 Subject: [PATCH 16/30] update fates build namelist add_default calls for modes that depend on other modes --- components/elm/bld/ELMBuildNamelist.pm | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 0d0f6b0532ad..189d62a6fe68 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3401,12 +3401,12 @@ sub setup_logic_fates { my ($test_files, $nl_flags, $definition, $defaults, $nl, $physv) = @_; if ( value_is_true( $nl_flags->{'use_fates'}) ) { - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_sp','use_fates'=>$nl_flags->{'use_fates'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'flandusepftdat', 'phys'=>$nl_flags->{'phys'}); + # add other fates modes whose defaults don't depend on other modes my @list = ( "fates_harvest_mode", "fates_history_dimlevel", "fates_inventory_ctrl_filename", @@ -3416,20 +3416,29 @@ sub setup_logic_fates { "use_fates_cohort_age_tracking", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", - "use_fates_fixed_biogeog", "use_fates_inventory_init", - "use_fates_luh", - "use_fates_lupft", - "use_fates_nocomp", + "use_fates_lupft", "use_fates_planthydro", - "use_fates_potentialveg", + "use_fates_potentialveg", + "use_fates_sp", "use_fates_tree_damage"); foreach my $var (@list) { - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,'use_fates'=>$nl_flags->{'use_fates'}, - 'use_fates_sp'=>$nl->get_value('use_fates_sp') ); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,'use_fates'=>$nl_flags->{'use_fates'}); } + # Add defaults for fates modes that depend on previously set fates modes. See namelist defaults file for list. + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_luh', 'use_fates'=>$nl_flags->{'use_fates'}, + 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), + 'use_fates_potentialveg'=>$nl->get_value('use_fates_potentialveg'), + 'fates_harvest_mode'=>$nl->get_value('fates_harvest_mode') ); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'}, + 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), + 'use_fates_sp'=>$nl->get_value('use_fates_sp') ); + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_fixed_biogeog', 'use_fates'=>$nl_flags->{'use_fates'}, + 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), + 'use_fates_sp'=>$nl->get_value('use_fates_sp') ); + # For FATES SP mode make sure no-competion, and fixed-biogeography are also set # And also check for other settings that can't be trigged on as well my $var = "use_fates_sp"; From df1901d2e2f7280e1278ced4d40dc741b041a77b Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 13:54:40 -0700 Subject: [PATCH 17/30] add graceful failures to the fates build namelist for land use --- components/elm/bld/ELMBuildNamelist.pm | 84 ++++++++++++++++++-------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 189d62a6fe68..e6e512db3738 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -898,6 +898,10 @@ sub setup_cmdl_fates_mode { if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); } + $var = "use_fates_potentialveg"; + if ( defined($nl->get_value($var)) ) { + fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); + } $var = "fates_inventory_ctrl_filename"; if ( defined($nl->get_value($var)) ) { fatal_error("$var is being set, but can ONLY be set when -bgc fates option is used.\n"); @@ -3469,22 +3473,12 @@ sub setup_logic_fates { my $var = "use_fates_lupft"; if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { - $var = "flandusepftdat"; - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, - 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>$nl_flags->{'res'}, nofail=>1 ); - my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); - if ( ! defined($nl->get_value($var)) ) { - fatal_error("$var is required when use_fates_lupft is set" ); - } elsif ( ! -f "$fname" ) { - fatal_error("$fname does NOT point to a valid filename" ); + my @list = ( "use_fates_luh", "use_fates_nocomp", "use_fates_fixed_biogeog" ); + foreach my $var ( @list ) { + if ( ! &value_is_true($nl->get_value($var)) ) { + fatal_error("$var is required when use_fates_lupft is true" ); + } } - # make sure that nocomp and fbg mode are enabled as well as use_fates_luh - #my @list = ( "use_fates_luh, use_fates_nocomp", "use_fates_fixed_biogeog" ); - #foreach my $var ( @list ) { - # if ( ! &value_is_true($nl->get_value($var)) ) { - # fatal_error("$var is required when use_fates_lupft is true" ); - # } - #} } } # check that fates landuse change mode has the necessary luh2 landuse timeseries data @@ -3492,18 +3486,38 @@ 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"; - add_default($test_files, $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)) ) { - fatal_error("$var is required when use_fates_luh is set" ); - } elsif ( ! -f "$fname" ) { - fatal_error("$fname does NOT point to a valid filename" ); + $var = "use_fates_potentialveg"; + if ( defined($nl->get_value($var)) ) { + if ( ! &value_is_true($nl->get_value($var)) ) { + $var = "fluh_timeseries"; + add_default($test_files, $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)) ) { + fatal_error("$var is required when use_fates_luh is set" ); + } elsif ( ! -f "$fname" ) { + fatal_error("$fname does NOT point to a valid filename" ); + } + } + } + $var = "use_fates_fixed_biogeog"; + if ( defined($nl->get_value($var)) ) { + if ( &value_is_true($nl->get_value($var)) ) { + $var = "flandusepftdat"; + add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'}, + 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>$nl_flags->{'res'}, nofail=>1 ); + my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); + if ( ! defined($nl->get_value($var)) ) { + fatal_error("$var is required when use_fates_luh and use_fates_fixed_biogeog is set" ); + } elsif ( ! -f "$fname" ) { + fatal_error("$var does NOT point to a valid filename" ); + } + } } } } + # check that fates landuse is on and harvest mode is off when potential veg switch is true my $var = "use_potentialveg"; if ( defined($nl->get_value($var)) ) { @@ -3511,8 +3525,13 @@ sub setup_logic_fates { if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { fatal_error("use_fates_luh must be true when $var is true" ); } - if ( $nl->get_value('fates_harvest_mode') ne "no_harvest") { - fatal_error("fates_harvest_mode must be off when $var is true" ); + my $var = remove_leading_and_trailing_quotes($nl->get_value('fates_harvest_mode')); + if ( $var ne 'no_harvest') { + fatal_error("fates_harvest_mode set to $var. It must set to no_harvest when use_potential_veg is true." ); + } + my $var = "fluh_timeseries"; + if ( defined($nl->get_value($var)) ) { + fatal_error("fluh_timeseries can not be defined when use_fates_potentialveg is true" ); } } } @@ -3520,11 +3539,24 @@ sub setup_logic_fates { my $var = "fates_harvest_mode"; if ( defined($nl->get_value($var)) ) { # using fates_harvest mode with raw luh2 harvest data + my $mode = remove_leading_and_trailing_quotes($nl->get_value($var)); if ( $nl->get_value($var) eq "luhdata_area" || $nl->get_value($var) eq "luhdata_mass" ) { # Make sure that use_fates_luh is true when using raw fates luh2 harvest data if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { fatal_error("use_fates_luh is required to be true when $var is greater than 2" ); } + } elsif ( $mode eq 'landuse_timeseries' ) { + # Check to make sure that the user set the flanduse_timeseries file + # Since the flanduse_timeseries logic checking is upstream of the fates logic, + # don't add the default here. The onus is on the user to match the correct timeseries + # data to the correct surface dataset resolution + my $var = "flanduse_timeseries"; + my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); + if ( ! defined($nl->get_value($var)) ) { + fatal_error("$var is required when fates_harvest_mode is landuse_timeseries" ); + } elsif ( ! -f "$fname" ) { + fatal_error("$var does NOT point to a valid filename" ); + } } } } From 4bb13ed5b433ab7aaaea0806dbf14186fe06d46c Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 16:03:54 -0700 Subject: [PATCH 18/30] correct add default call for use_fates_luh option --- components/elm/bld/ELMBuildNamelist.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index e6e512db3738..4acb05a737ff 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3491,8 +3491,8 @@ sub setup_logic_fates { if ( ! &value_is_true($nl->get_value($var)) ) { $var = "fluh_timeseries"; add_default($test_files, $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 ); + 'use_fates'=>$nl_flags->{'use_fates'}, 'hgrid'=>$nl_flags->{'res'}, + 'sim_year_range'=>$nl_flags->{'sim_year_range'} ); my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) ); if ( ! defined($nl->get_value($var)) ) { fatal_error("$var is required when use_fates_luh is set" ); From e43b5545956028d876ab7ee977db9eda7c66f1f5 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 16:26:27 -0700 Subject: [PATCH 19/30] correct graceful failure write statement --- components/elm/bld/ELMBuildNamelist.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 4acb05a737ff..db7d2df9385f 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3497,7 +3497,7 @@ sub setup_logic_fates { if ( ! defined($nl->get_value($var)) ) { fatal_error("$var is required when use_fates_luh is set" ); } elsif ( ! -f "$fname" ) { - fatal_error("$fname does NOT point to a valid filename" ); + fatal_error("$var does NOT point to a valid filename" ); } } } From 52f1bd1fb7f38130ef5dc2912b6a18a61cc54304 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 16:44:10 -0700 Subject: [PATCH 20/30] fix use_fates_potentialveg call in build namelist --- components/elm/bld/ELMBuildNamelist.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index db7d2df9385f..23d3ff459c43 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3519,7 +3519,7 @@ sub setup_logic_fates { } # check that fates landuse is on and harvest mode is off when potential veg switch is true - my $var = "use_potentialveg"; + my $var = "use_fates_potentialveg"; if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { @@ -3527,7 +3527,7 @@ sub setup_logic_fates { } my $var = remove_leading_and_trailing_quotes($nl->get_value('fates_harvest_mode')); if ( $var ne 'no_harvest') { - fatal_error("fates_harvest_mode set to $var. It must set to no_harvest when use_potential_veg is true." ); + fatal_error("fates_harvest_mode set to $var. It must set to no_harvest when use_fates_potential_veg is true." ); } my $var = "fluh_timeseries"; if ( defined($nl->get_value($var)) ) { From 1414a18c7de316d15a97743ca895ae37994243c8 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 17:06:50 -0700 Subject: [PATCH 21/30] add namelist check allowing empty string for fluh_timeseries --- components/elm/bld/ELMBuildNamelist.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 23d3ff459c43..12850e79be25 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3529,12 +3529,16 @@ sub setup_logic_fates { if ( $var ne 'no_harvest') { fatal_error("fates_harvest_mode set to $var. It must set to no_harvest when use_fates_potential_veg is true." ); } + # it is ok for fluh_timeseries to be defined as long as the string is empty my $var = "fluh_timeseries"; if ( defined($nl->get_value($var)) ) { - fatal_error("fluh_timeseries can not be defined when use_fates_potentialveg is true" ); + if (! string_is_undef_or_empty($nl->get_value($var))) { + fatal_error("fluh_timeseries can not be set when use_fates_potentialveg is true" ); + } } } } + # Check fates_harvest_mode compatibility my $var = "fates_harvest_mode"; if ( defined($nl->get_value($var)) ) { From 0c94275bfc491c2ed57706907d4693f616bb1879 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 10 Jul 2024 17:38:20 -0700 Subject: [PATCH 22/30] do not add default for fates landuse files prior to checks --- components/elm/bld/ELMBuildNamelist.pm | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 12850e79be25..db745e9ca452 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3407,8 +3407,6 @@ sub setup_logic_fates { if ( value_is_true( $nl_flags->{'use_fates'}) ) { add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fluh_timeseries', 'phys'=>$nl_flags->{'phys'}); - add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'flandusepftdat', 'phys'=>$nl_flags->{'phys'}); # add other fates modes whose defaults don't depend on other modes my @list = ( "fates_harvest_mode", From 348dc469b5c5fa7099892692d1a5eb7437737a42 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 11 Jul 2024 10:03:19 -0700 Subject: [PATCH 23/30] whitespace fixes in elm build namelist --- components/elm/bld/ELMBuildNamelist.pm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index db745e9ca452..8fa8bd66217b 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -813,7 +813,7 @@ sub setup_cmdl_fates_mode { "fates_harvest_mode", "fates_history_dimlevel", "fates_inventory_ctrl_filename", - "fates_parteh_mode", + "fates_parteh_mode", "fates_seeddisp_cadence", "fates_spitfire_mode", "use_fates_cohort_age_tracking", @@ -3412,17 +3412,17 @@ sub setup_logic_fates { my @list = ( "fates_harvest_mode", "fates_history_dimlevel", "fates_inventory_ctrl_filename", - "fates_parteh_mode", + "fates_parteh_mode", "fates_seeddisp_cadence", "fates_spitfire_mode", "use_fates_cohort_age_tracking", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", "use_fates_inventory_init", - "use_fates_lupft", + "use_fates_lupft", "use_fates_planthydro", - "use_fates_potentialveg", - "use_fates_sp", + "use_fates_potentialveg", + "use_fates_sp", "use_fates_tree_damage"); foreach my $var (@list) { @@ -3484,7 +3484,7 @@ sub setup_logic_fates { my $var = "use_fates_luh"; if ( defined($nl->get_value($var)) ) { if ( &value_is_true($nl->get_value($var)) ) { - $var = "use_fates_potentialveg"; + $var = "use_fates_potentialveg"; if ( defined($nl->get_value($var)) ) { if ( ! &value_is_true($nl->get_value($var)) ) { $var = "fluh_timeseries"; @@ -3497,7 +3497,7 @@ sub setup_logic_fates { } elsif ( ! -f "$fname" ) { fatal_error("$var does NOT point to a valid filename" ); } - } + } } $var = "use_fates_fixed_biogeog"; if ( defined($nl->get_value($var)) ) { @@ -3532,7 +3532,7 @@ sub setup_logic_fates { if ( defined($nl->get_value($var)) ) { if (! string_is_undef_or_empty($nl->get_value($var))) { fatal_error("fluh_timeseries can not be set when use_fates_potentialveg is true" ); - } + } } } } From 229fb934978bfa8682a8eaf1e81eaab07ee6ce4d Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 11 Jul 2024 10:57:23 -0700 Subject: [PATCH 24/30] add constant simyear range until transient compset working for fates --- components/elm/bld/namelist_files/namelist_defaults.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index ea44826fb351..b0407480d686 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -591,6 +591,9 @@ lnd/clm2/surfdata_map/surfdata_conusx4v1_simyr2000_c160503.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 +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.73.0_api.36.0.0/fates_landuse_pft_map_4x5_240206.nc From ebf6dd816f04608d9539e3850ed654d1d98fcaf6 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 11 Jul 2024 11:49:46 -0700 Subject: [PATCH 25/30] correct flandusepftdat default location name --- components/elm/bld/namelist_files/namelist_defaults.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index b0407480d686..b44205224bc2 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -595,7 +595,7 @@ lnd/clm2/surfdata_map/surfdata_conusx4v1_simyr2000_c160503.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 -lnd/clm2/surfdata_map/fates-sci.1.73.0_api.36.0.0/fates_landuse_pft_map_4x5_240206.nc +lnd/clm2/surfdata_map/fates-sci.1.77.0_api.36.0.0/fates_landuse_pft_map_4x5_240206.nc From 09d0bf3caf9aa97e673636e3496131deae483de6 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 11 Jul 2024 13:32:48 -0700 Subject: [PATCH 26/30] correct fates harvest mode namelist check --- components/elm/bld/ELMBuildNamelist.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 8fa8bd66217b..be56d998acda 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3542,7 +3542,7 @@ sub setup_logic_fates { if ( defined($nl->get_value($var)) ) { # using fates_harvest mode with raw luh2 harvest data my $mode = remove_leading_and_trailing_quotes($nl->get_value($var)); - if ( $nl->get_value($var) eq "luhdata_area" || $nl->get_value($var) eq "luhdata_mass" ) { + if ( $mode eq "luhdata_area" || $mode eq "luhdata_mass" ) { # Make sure that use_fates_luh is true when using raw fates luh2 harvest data if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { fatal_error("use_fates_luh is required to be true when $var is greater than 2" ); From e565c34c35ac1ecff0bfb5c33ede48c3aecab0ee Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Thu, 11 Jul 2024 16:11:40 -0700 Subject: [PATCH 27/30] remove old comment from elmfates_interfaceMod --- components/elm/src/main/elmfates_interfaceMod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/components/elm/src/main/elmfates_interfaceMod.F90 b/components/elm/src/main/elmfates_interfaceMod.F90 index 521c20cde297..a20444d67582 100644 --- a/components/elm/src/main/elmfates_interfaceMod.F90 +++ b/components/elm/src/main/elmfates_interfaceMod.F90 @@ -374,7 +374,6 @@ subroutine ELMFatesGlobals1() call SetFatesGlobalElements1(use_fates,natpft_size,0,var_reader) natpft_size = fates_maxPatchesPerSite - !numpft = natpft_size - 1 # GML Todo: This was in landuse v2, not v1 max_patch_per_col= max(natpft_size, numcft, maxpatch_urb) return From 1b0772c6d0b35597423aadb410fbb05e70db10bc Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Sat, 13 Jul 2024 12:33:45 -0700 Subject: [PATCH 28/30] correct how harvest mode setting is passed to add_default for fates landuse --- components/elm/bld/ELMBuildNamelist.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index be56d998acda..11f733882f00 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3433,7 +3433,7 @@ sub setup_logic_fates { add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_luh', 'use_fates'=>$nl_flags->{'use_fates'}, 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), 'use_fates_potentialveg'=>$nl->get_value('use_fates_potentialveg'), - 'fates_harvest_mode'=>$nl->get_value('fates_harvest_mode') ); + 'fates_harvest_mode'=>remove_leading_and_trailing_quotes($nl->get_value('fates_harvest_mode')) ); add_default($test_files, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'}, 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), 'use_fates_sp'=>$nl->get_value('use_fates_sp') ); From 6d21ce5657efeab9d7f6f63f1b72b15fafd18c00 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Sat, 13 Jul 2024 12:46:40 -0700 Subject: [PATCH 29/30] reinstate default settings for various fates modes --- components/elm/bld/ELMBuildNamelist.pm | 2 +- components/elm/bld/namelist_files/namelist_defaults.xml | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 11f733882f00..68afd92e132d 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -3545,7 +3545,7 @@ sub setup_logic_fates { if ( $mode eq "luhdata_area" || $mode eq "luhdata_mass" ) { # Make sure that use_fates_luh is true when using raw fates luh2 harvest data if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) { - fatal_error("use_fates_luh is required to be true when $var is greater than 2" ); + fatal_error("use_fates_luh is required to be true when $var is luhdata_mass or luhdata_area" ); } } elsif ( $mode eq 'landuse_timeseries' ) { # Check to make sure that the user set the flanduse_timeseries file diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index b44205224bc2..316292219861 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -2195,11 +2195,17 @@ this mask will have smb calculated over the entire global land surface .false. .false. .false. +.true. +.true. +.true. +.true. .false. .false. .true. +.true. .false. .true. +.true. .false. .true. .true. From ee9cd552b5eb71744b22b1c63b952f51a75202f8 Mon Sep 17 00:00:00 2001 From: Gregory Lemieux Date: Wed, 17 Jul 2024 12:44:54 -0700 Subject: [PATCH 30/30] update fates to sci.1.77.1_api.36.0.0 --- components/elm/src/external_models/fates | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/external_models/fates b/components/elm/src/external_models/fates index fd7f3438c2ff..1982b0032c3c 160000 --- a/components/elm/src/external_models/fates +++ b/components/elm/src/external_models/fates @@ -1 +1 @@ -Subproject commit fd7f3438c2ff821672b703050e7011f293649ee9 +Subproject commit 1982b0032c3cab6278892eccb85f643114ffb1af