diff --git a/.config_files.xml b/.config_files.xml
index e07f99db..22860601 100644
--- a/.config_files.xml
+++ b/.config_files.xml
@@ -5,19 +5,19 @@
charunset
- $SRCROOT
+ $SRCROOT$CIMEROOT/src/components/data_comps/dlnd$CIMEROOT/src/components/stub_comps/slnd$CIMEROOT/src/components/xcpl_comps/xlnd
diff --git a/.gitignore b/.gitignore
index 5f93baa3..85538e29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,8 @@ core.*
*.gz
*.log !run.log
*.pyc
+
+# buildnml testing
+cime_config/buildnml_test/run
+cime_config/buildnml_test/Buildconf
+cime_config/buildnml_test/buildnml.log
diff --git a/README b/README
index 45f7759c..ffaafcef 100644
--- a/README
+++ b/README
@@ -3,9 +3,7 @@ Important files in main directories:
=============================================================================================
Externals.cfg --------------- File for management of the main high level externals
-Externals_CLM.cfg ----------- File for management of the CLM specific externals (i.e. FATES)
-
-bld/configure --------------- Script to prepare CLM to be built.
+Externals_SLIM.cfg ---------- File for management of the SLIM specific externals (if any)
=============================================================================================
QUICKSTART: using the CPL7 scripts:
@@ -13,9 +11,9 @@ bld/configure --------------- Script to prepare CLM to be built.
cd cime/scripts
./create_newcase # get help on how to run create_newcase
- ./create_newcase --case testI --res f19_g16 --compset I2000Clm50BgcCrop --mach cheyenne
+ ./create_newcase --case testI --res f19_g17 --compset I2000SlimRsGs --mach cheyenne
# create new "I" case for cheyenne_intel at 1.9x2.5_gx1v7 res
- # "I2000Clm50BgcCrop" case is clm5_0 active, datm8, and inactive ice/ocn
+ # "I2000SlimRsGs" case is SLIM active, datm8, and inactive ice/ocn/glc/rof
cd testI
./case.setup # create the $CASE.run file
./case.build # build model and create namelists
diff --git a/bld/CESM_cppdefs b/bld/CESM_cppdefs
deleted file mode 100644
index 8d1c8b69..00000000
--- a/bld/CESM_cppdefs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm
deleted file mode 100644
index 70f3508a..00000000
--- a/bld/CLMBuildNamelist.pm
+++ /dev/null
@@ -1,1805 +0,0 @@
-# build-namelist
-#
-# This script builds the namelists for CLM
-#
-# The simplest use of build-namelist is to execute it from the build directory where configure
-# was run. By default it will use the config_cache.xml file that was written by configure to
-# determine the build time properties of the executable, and will write the files that contain
-# the output namelists in that same directory. But if multiple runs are to made using the
-# same executable, successive invocations of build-namelist will overwrite previously generated
-# namelist files. So generally the best strategy is to invoke build-namelist from the run
-# directory and use the -config option to provide the filepath of the config_cache.xml file.
-#
-#
-# Date Contributor Modification
-# -------------------------------------------------------------------------------------------
-# 2009-01-20 Vertenstein Original version
-# 2010-04-27 Kluzek Add ndep streams capability
-# 2011-07-25 Kluzek Add multiple ensemble's of namelists
-# 2012-03-23 Kluzek Add megan namelist and do checking on it
-# 2012-07-01 Kluzek Add some common CESM namelist options
-# 2013-12 Andre Refactor everything into subroutines
-# 2013-12 Muszala Add Ecosystem Demography functionality
-# 2017-08-17 Lague Add namelist options for simple land model (MML)
-#--------------------------------------------------------------------------------------------
-
-package CLMBuildNamelist;
-
-require 5;
-
-use strict;
-#use warnings;
-#use diagnostics;
-
-use Cwd qw(getcwd abs_path);
-use File::Basename qw(dirname);
-use English;
-use Getopt::Long;
-use IO::File;
-use File::Glob ':glob';
-
-#-------------------------------------------------------------------------------
-#
-# Define a small number of global variables
-#
-#-------------------------------------------------------------------------------
-
-(my $ProgName = $0) =~ s!(.*)/!!; # name of this script
-my $ProgDir = $1;
-$ProgName = "CLM " . "$ProgName";
-
-my $cwd = abs_path(getcwd()); # absolute path of the current working directory
-my $log; # Log messages object -- will be set in main, declaring it global here means it can be used everywhere
-
-#-------------------------------------------------------------------------------
-
-sub usage {
- die <1)
- and the filename entered is a directory to files of the
- form filepath/filepath and filepath/filepath_\$n where \$n
- is the ensemble member number. the "filepath/filepath"
- input namelist file is the master input namelist file
- that is applied to ALL ensemble members.
-
- (by default for CESM this is setup for files of the
- form \$CASEDIR/user_nl_clm/user_nl_clm_????)
- -inputdata "filepath" Writes out a list containing pathnames for required input datasets in
- file specified.
- -l_ncpl "LND_NCPL" Number of CLM coupling time-steps in a day.
- -mask "landmask" Type of land-mask (default, navy, gx3v5, gx1v5 etc.)
- "-mask list" to list valid land masks.
- -namelist "namelist" Specify namelist settings directly on the commandline by supplying
- a string containing FORTRAN namelist syntax, e.g.,
- -namelist "&clm_inparm dt=1800 /"
- -[no-]note Add note to output namelist [do NOT add note] about the
- arguments to build-namelist.
- -output_reals Output real parameters to the given output file.
- -rcp "value" Representative concentration pathway (rcp) to use for
- future scenarios.
- "-rcp list" to list valid rcp settings.
- -s Turns on silent mode - only fatal messages issued.
- -test Enable checking that input datasets exist on local filesystem.
- -use_case "case" Specify a use case which will provide default values.
- "-use_case list" to list valid use-cases.
- -verbose [or -v] Turn on verbose echoing of informational messages.
- -version Echo the SVN tag name used to check out this CLM distribution.
-
-
-Note: The precedence for setting the values of namelist variables is (highest to lowest):
- 0. namelist values set by specific command-line options, like, -d, -sim_year
- (i.e. compset choice and CLM_BLDNML_OPTS, LND_TUNING_MODE env_run variables)
- (NOTE: If you try to contradict these settings by methods below, an error will be triggered)
- 1. values set on the command-line using the -namelist option,
- (i.e. CLM_NAMELIST_OPTS env_run variable)
- 2. values read from the file(s) specified by -infile,
- (i.e. user_nl_clm files)
- 4. values set from a use-case scenario, e.g., -use_case
- (i.e. CLM_NML_USE_CASE env_run variable)
- 5. values from the namelist defaults file.
-EOF
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_commandline {
- # Process command-line options and return the hash
- my ($nl_flags) = @_;
-
- # Save the command line arguments to the script. NOTE: this must be
- # before GetOptions() is called because items are removed from from
- # the array!
- $nl_flags->{'cmdline'} = "@ARGV";
-
- my %opts = ( cimeroot => undef,
- config => "config_cache.xml",
- csmdata => undef,
- clm_demand => "null",
- help => 0,
- l_ncpl => undef,
- lnd_frac => undef,
- dir => "$cwd",
- rcp => "default",
- sim_year => "default",
- chk_res => undef,
- note => undef,
- output_reals_filename => undef,
- res => "default",
- silent => 0,
- ignore_warnings => 0,
- mask => "default",
- test => 0,
- bgc => "default",
- envxml_dir => ".",
- maxpft => "default",
- );
-
- GetOptions(
- "cimeroot=s" => \$opts{'cimeroot'},
- "clm_demand=s" => \$opts{'clm_demand'},
- "config=s" => \$opts{'config'},
- "csmdata=s" => \$opts{'csmdata'},
- "envxml_dir=s" => \$opts{'envxml_dir'},
- "ignore_warnings!" => \$opts{'ignore_warnings'},
- "chk_res!" => \$opts{'chk_res'},
- "note!" => \$opts{'note'},
- "d:s" => \$opts{'dir'},
- "h|help" => \$opts{'help'},
- "ignore_ic_date" => \$opts{'ignore_ic_date'},
- "ignore_ic_year" => \$opts{'ignore_ic_year'},
- "infile=s" => \$opts{'infile'},
- "lnd_frac=s" => \$opts{'lnd_frac'},
- "l_ncpl=i" => \$opts{'l_ncpl'},
- "inputdata=s" => \$opts{'inputdata'},
- "mask=s" => \$opts{'mask'},
- "namelist=s" => \$opts{'namelist'},
- "res=s" => \$opts{'res'},
- "rcp=s" => \$opts{'rcp'},
- "s|silent" => \$opts{'silent'},
- "sim_year=s" => \$opts{'sim_year'},
- "output_reals=s" => \$opts{'output_reals_filename'},
- "clm_start_type=s" => \$opts{'clm_start_type'},
- "test" => \$opts{'test'},
- "use_case=s" => \$opts{'use_case'},
- "bgc=s" => \$opts{'bgc'},
- "maxpft=i" => \$opts{'maxpft'},
- "v|verbose" => \$opts{'verbose'},
- "version" => \$opts{'version'},
- ) or usage();
-
- # Give usage message.
- usage() if $opts{'help'};
-
- # Check for unparsed arguments
- if (@ARGV) {
- print "ERROR: unrecognized arguments: @ARGV\n";
- usage();
- }
- return %opts;
-}
-
-#-------------------------------------------------------------------------------
-
-sub check_for_perl_utils {
-
- my $cfgdir = shift;
- my $opts_ref = shift;
-
- # Determine CIME root directory and perl5lib root directory
- my $cimeroot = $opts_ref->{'cimeroot'};
- if ( ! defined($cimeroot) ) {
- $cimeroot = "$cfgdir/../cime";
- if ( -d $cimeroot ) {
- } elsif ( -d "$cfgdir/../../../cime" ) {
- $cimeroot = "$cfgdir/../../../cime";
- } else {
- die <<"EOF";
-** Cannot find the root of the cime directory enter it using the -cimeroot option
- Did you run the checkout_externals scripts?
-EOF
- }
- }
-
- my $perl5lib_dir = "$cimeroot/utils/perl5lib";
-
- #-----------------------------------------------------------------------------
- # Add $perl5lib_dir to the list of paths that Perl searches for modules
- my @dirs = ( $ProgDir, $cfgdir, "$perl5lib_dir");
- unshift @INC, @dirs;
-
- require config_files::clm_phys_vers;
- require namelist_files::LogMessages;
-
- my $locallog = namelist_files::LogMessages->new( $ProgName, $opts_ref );
- # The XML::Lite module is required to parse the XML files.
- (-f "$perl5lib_dir/XML/Lite.pm") or
- $locallog->fatal_error("Cannot find perl module \"XML/Lite.pm\" in directory\n" .
- "\"$perl5lib_dir\"");
-
- # The Build::Config module provides utilities to access the configuration information
- # in the config_cache.xml file
- (-f "$perl5lib_dir/Build/Config.pm") or
- $locallog->fatal_error("Cannot find perl module \"Build/Config.pm\" in directory\n" .
- "\"$perl5lib_dir\"");
-
- # The Build::NamelistDefinition module provides utilities to validate that the output
- # namelists are consistent with the namelist definition file
- (-f "$perl5lib_dir/Build/NamelistDefinition.pm") or
- $locallog->fatal_error("Cannot find perl module \"Build/NamelistDefinition.pm\" in directory\n" .
- "\"$perl5lib_dir\"");
-
- # The Build::NamelistDefaults module provides a utility to obtain default values of namelist
- # variables based on finding a best fit with the attributes specified in the defaults file.
- (-f "$perl5lib_dir/Build/NamelistDefaults.pm") or
- $locallog->fatal_error("Cannot find perl module \"Build/NamelistDefaults.pm\" in directory\n" .
- "\"$perl5lib_dir\"");
-
- # The Build::Namelist module provides utilities to parse input namelists, to query and modify
- # namelists, and to write output namelists.
- (-f "$perl5lib_dir/Build/Namelist.pm") or
- $locallog->fatal_error("Cannot find perl module \"Build/Namelist.pm\" in directory\n" .
- "\"$perl5lib_dir\"");
-
-
- # required cesm perl modules
- require XML::Lite;
- require Build::Config;
- require Build::NamelistDefinition;
- require Build::NamelistDefaults;
- require Build::Namelist;
- require Config::SetupTools;
-}
-
-#-------------------------------------------------------------------------------
-
-sub read_configure_definition {
- # Read the configure definition and specific config_cache file for this case
- # configure are the build-time settings for CLM
- my ($cfgdir, $opts) = @_;
-
- $log->verbose_message("Setting CLM configuration script directory to $cfgdir");
-
- # Create a configuration object from the default config_definition file
- my $configfile;
- if ( -f $opts->{'config'} ) {
- $configfile = $opts->{'config'};
- } else {
- $configfile = "$cfgdir/config_files/config_definition.xml";
- }
-
- # Check that configuration cache file exists.
- $log->verbose_message("Using CLM configuration cache file $opts->{'config'}");
- if ( $configfile ne $opts->{'config'} ) {
- $log->fatal_error("Cannot find configuration cache file: \"$opts->{'config'}\"");
- }
-
- my $cfg = Build::Config->new("$configfile");
-
- return $cfg;
-}
-
-#-----------------------------------------------------------------------------------------------
-
-sub read_namelist_definition {
- my ($cfgdir, $opts, $nl_flags, $physv) = @_;
-
- # The namelist definition file contains entries for all namelist
- # variables that can be output by build-namelist.
- my $phys = $physv->as_filename( );
- my @nl_definition_files = ( "$cfgdir/namelist_files/namelist_definition_drv.xml",
- "$cfgdir/namelist_files/namelist_definition_$phys.xml" );
- foreach my $nl_defin_file ( @nl_definition_files ) {
- (-f "$nl_defin_file") or $log->fatal_error("Cannot find namelist definition file \"$nl_defin_file\"");
-
- $log->verbose_message("Using namelist definition file $nl_defin_file");
- }
-
- # Create a namelist definition object. This object provides a
- # method for verifying that the output namelist variables are in the
- # definition file, and are output in the correct namelist groups.
- my $definition = Build::NamelistDefinition->new( shift(@nl_definition_files) );
- foreach my $nl_defin_file ( @nl_definition_files ) {
- $definition->add( "$nl_defin_file" );
- }
-
- return $definition;
-}
-
-#-----------------------------------------------------------------------------------------------
-
-sub read_envxml_case_files {
- # read the contents of the env*.xml files in the case directory
- my ($opts) = @_;
-
- my %envxml = ();
- if ( defined($opts->{'envxml_dir'}) ) {
- (-d $opts->{'envxml_dir'}) or $log->fatal_error( "envxml_dir is not a directory" );
- my @files = glob( $opts->{'envxml_dir'}."/env_*xml" );
- ($#files >= 0) or $log->fatal_error( "there are no env_*xml files in the envxml_dir" );
- foreach my $file (@files) {
- $log->verbose_message( "Open env.xml file: $file" );
- my $xml = XML::Lite->new( "$file" );
- my @e = $xml->elements_by_name('entry');
- while ( my $e = shift @e ) {
- my %a = $e->get_attributes();
- $envxml{$a{'id'}} = $a{'value'};
- }
- }
- foreach my $attr (keys %envxml) {
- if ( $envxml{$attr} =~ m/\$/ ) {
- $envxml{$attr} = SetupTools::expand_xml_var( $envxml{$attr}, \%envxml );
- }
- }
- } else {
- $log->fatal_error( "The -envxml_dir option was NOT given and it is a REQUIRED option" );
- }
- return( %envxml );
-}
-
-#-----------------------------------------------------------------------------------------------
-
-sub read_namelist_defaults {
- my ($cfgdir, $opts, $nl_flags, $cfg, $physv) = @_;
-
- my $phys = $physv->as_filename( );
- # The namelist defaults file contains default values for all required namelist variables.
- my @nl_defaults_files = ( "$cfgdir/namelist_files/namelist_defaults_overall.xml",
- "$cfgdir/namelist_files/namelist_defaults_$phys.xml" );
-
- # Add the location of the use case defaults files to the options hash
- $opts->{'use_case_dir'} = "$cfgdir/namelist_files/use_cases";
-
- if (defined $opts->{'use_case'}) {
- if ( $opts->{'use_case'} ne "list" ) {
- unshift( @nl_defaults_files, "$opts->{'use_case_dir'}/$opts->{'use_case'}.xml" );
- }
- }
-
- foreach my $nl_defaults_file ( @nl_defaults_files ) {
- (-f "$nl_defaults_file") or $log->fatal_error("Cannot find namelist defaults file \"$nl_defaults_file\"");
-
- $log->verbose_message("Using namelist defaults file $nl_defaults_file");
- }
-
- # Create a namelist defaults object. This object provides default
- # values for variables contained in the input defaults file. The
- # configuration object provides attribute values that are relevent
- # for the CLM executable for which the namelist is being produced.
- my $defaults = Build::NamelistDefaults->new( shift( @nl_defaults_files ), $cfg);
- foreach my $nl_defaults_file ( @nl_defaults_files ) {
- $defaults->add( "$nl_defaults_file" );
- }
- return $defaults;
-}
-
-#-------------------------------------------------------------------------------
-
-sub check_cesm_inputdata {
- # Check that the CESM inputdata root directory has been specified. This must be
- # a local or nfs mounted directory.
-
- my ($opts, $nl_flags) = @_;
-
- $nl_flags->{'inputdata_rootdir'} = undef;
- if (defined($opts->{'csmdata'})) {
- $nl_flags->{'inputdata_rootdir'} = $opts->{'csmdata'};
- }
- elsif (defined $ENV{'CSMDATA'}) {
- $nl_flags->{'inputdata_rootdir'} = $ENV{'CSMDATA'};
- }
- else {
- $log->fatal_error("CESM inputdata root directory must be specified by either -csmdata\n" .
- "argument or by the CSMDATA environment variable.");
- }
- if ( ! defined($ENV{'DIN_LOC_ROOT'}) ) {
- $ENV{'DIN_LOC_ROOT'} = $nl_flags->{'inputdata_rootdir'};
- }
-
- if ($opts->{'test'}) {
- (-d $nl_flags->{'inputdata_rootdir'}) or $log->fatal_error("CESM inputdata root is not a directory: \"$nl_flags->{'inputdata_rootdir'}\"");
- }
-
- $log->verbose_message("CESM inputdata root directory: $nl_flags->{'inputdata_rootdir'}");
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_user_input {
- # Process the user input in general by order of precedence. At each point
- # we'll only add new values to the namelist and not overwrite
- # previously specified specified values which have higher
- # precedence. The one exception to this rule are the specifc command-line
- # options which are done last as if the user contradicts these settings
- # CLM build-namelist will abort with an error.
- #
- # 1. values set on the command-line using the -namelist option,
- # (i.e. CLM_NAMELIST_OPTS env_run variable)
- # 2. values read from the file(s) specified by -infile,
- # (i.e. user_nl_clm files)
- # After the above are done the command line options are processed and they
- # are made sure the user hasn't contradicted any of their settings with
- # anything above. Because of this they are condsidered to have the highest
- # precedence.
- # 0. namelist values set by specific command-line options, like, -d, -sim_year
- # (i.e. CLM_BLDNML_OPTS env_run variable)
- # The results of these are needed for the final two user input
- # 4. values set from a use-case scenario, e.g., -use_case
- # (i.e. CLM_NML_USE_CASE env_run variable)
- #
- # Finally after all the above is done, the defaults are found from the
- # namelist defaults file (outside of this routine).
- #
-
-
- my ($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $envxml_ref, $physv) = @_;
-
- # Get the inputs that will be coming from the user...
- process_namelist_commandline_namelist($opts, $definition, $nl, $envxml_ref);
- process_namelist_commandline_infile($opts, $definition, $nl, $envxml_ref);
-
- # Apply the commandline options and make sure the user didn't change it above
- process_namelist_commandline_options($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $physv);
-
- # The last two process command line arguments for use_case
- # They require that process_namelist_commandline_options was called before this
- process_namelist_commandline_use_case($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $envxml_ref, $physv);
-
- # Set the start_type by the command line setting for clm_start_type
- process_namelist_commandline_clm_start_type($opts, $nl_flags, $definition, $defaults, $nl);
-
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_commandline_options {
- # First process the commandline args that provide specific namelist values.
- #
- # First get the command-line specified overall values or their defaults
- # Obtain default values for the following build-namelist input arguments
- # : res, mask, rcp, sim_year, sim_year_range.
- #
- my ($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $physv) = @_;
-
- setup_cmdl_chk_res($opts, $defaults);
- setup_cmdl_resolution($opts, $nl_flags, $definition, $defaults);
- setup_cmdl_mask($opts, $nl_flags, $definition, $defaults, $nl);
- setup_cmdl_maxpft($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $physv);
- setup_cmdl_rcp($opts, $nl_flags, $definition, $defaults, $nl);
- setup_cmdl_simulation_year($opts, $nl_flags, $definition, $defaults, $nl);
- setup_cmdl_run_type($opts, $nl_flags, $definition, $defaults, $nl);
- setup_cmdl_output_reals($opts, $nl_flags, $definition, $defaults, $nl, $physv);
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_chk_res {
- my ($opts, $defaults) = @_;
-
- my $var = "chk_res";
- if ( ! defined($opts->{$var}) ) {
- $opts->{$var} = $defaults->get_value($var);
- }
-}
-
-sub setup_cmdl_resolution {
- my ($opts, $nl_flags, $definition, $defaults) = @_;
-
- my $var = "res";
- my $val;
-
- if ( $opts->{$var} ne "default" ) {
- $val = $opts->{$var};
- } else {
- $val= $defaults->get_value($var);
- }
-
- $nl_flags->{'res'} = $val;
- $log->verbose_message("CLM atm resolution is $nl_flags->{'res'}");
- $opts->{$var} = $val;
- if ( $opts->{'chk_res'} ) {
- $val = "e_string( $nl_flags->{'res'} );
- if ( ! $definition->is_valid_value( $var, $val ) ) {
- my @valid_values = $definition->get_valid_values( $var );
- $log->fatal_error("$var has a value ($val) that is NOT valid. Valid values are: @valid_values");
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_mask {
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
-
- my $var = "mask";
- my $val;
-
- if ( $opts->{$var} ne "default" ) {
- $val = $opts->{$var};
- } else {
- my %tmp = ( 'hgrid'=>$nl_flags->{'res'} );
- $val = $defaults->get_value($var, \%tmp );
- }
-
- $nl_flags->{'mask'} = $val;
- $opts->{'mask'} = $nl_flags->{'mask'};
- if ( $opts->{'chk_res'} ) {
- $val = "e_string( $val );
- my $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, $val);
- if ( ! $definition->is_valid_value( $var, $val ) ) {
- my @valid_values = $definition->get_valid_values( $var );
- $log->fatal_error("$var has a value ($val) that is NOT valid. Valid values are: @valid_values");
- }
- }
- $log->verbose_message("CLM land mask is $nl_flags->{'mask'}");
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_maxpft {
- my ($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $physv) = @_;
-
- my $val;
- my $var = "maxpft";
- my $maxpatchpft = 17;
- if ( $opts->{$var} ne "default") {
- $val = $opts->{$var};
- } else {
- $val = $maxpatchpft;
- }
- $nl_flags->{'maxpft'} = $val;
-
- if ( $nl_flags->{'maxpft'} > $maxpatchpft ) {
- $log->fatal_error("** Max patch PFT's can NOT exceed $maxpatchpft\n" .
- "**\n" .
- "** Set maxpft by the following means from highest to lowest precedence:\n" .
- "** * by the command-line options -maxpft\n" .
- "** * by a default configuration file, specified by -defaults\n" .
- "**");
- }
- if ( $nl_flags->{'maxpft'} != $maxpatchpft ) {
- $log->warning("running with maxpft NOT equal to $maxpatchpft is " .
- "NOT validated / scientifically supported." );
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_rcp {
- # representative concentration pathway
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
-
- my $val;
- my $var = "rcp";
- if ( $opts->{$var} ne "default" ) {
- $val = $opts->{$var};
- } else {
- $val = $defaults->get_value($var);
- }
- $nl_flags->{'rcp'} = $val;
- $opts->{'rcp'} = $nl_flags->{'rcp'};
- my $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, $val);
- if ( ! $definition->is_valid_value( $var, $val ) ) {
- my @valid_values = $definition->get_valid_values( $var );
- $log->fatal_error("$var has a value ($val) that is NOT valid. Valid values are: @valid_values");
- }
- $log->verbose_message("CLM future scenario representative concentration is $nl_flags->{'rcp'}");
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_simulation_year {
- my ($opts, $nl_flags, $definition, $defaults, $nl, $cfg) = @_;
-
- my $val;
- my $var = "sim_year";
- if ( $opts->{$var} ne "default" ) {
- $val = $opts->{$var};
- } else {
- $val = $defaults->get_value($var);
- }
-
- $nl_flags->{'sim_year_range'} = $defaults->get_value("sim_year_range");
- $nl_flags->{'sim_year'} = $val;
- if ( $val =~ /([0-9]+)-([0-9]+)/ ) {
- $nl_flags->{'sim_year'} = $1;
- $nl_flags->{'sim_year_range'} = $val;
- }
- $val = $nl_flags->{'sim_year'};
- my $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, $val );
- if ( ! $definition->is_valid_value( $var, $val, 'noquotes'=>1 ) ) {
- my @valid_values = $definition->get_valid_values( $var );
- $log->fatal_error("$var of $val is NOT valid. Valid values are: @valid_values");
- }
- $nl->set_variable_value($group, $var, $val );
- $log->verbose_message("CLM sim_year is $nl_flags->{'sim_year'}");
-
- $var = "sim_year_range";
- $val = $nl_flags->{'sim_year_range'};
- if ( $val ne "constant" ) {
- $opts->{$var} = $val;
- $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, $val );
- if ( ! $definition->is_valid_value( $var, $val, 'noquotes'=>1 ) ) {
- my @valid_values = $definition->get_valid_values( $var );
- $log->fatal_error("$var of $val is NOT valid. Valid values are: @valid_values");
- }
- $val = "'".$defaults->get_value($var)."'";
- $nl->set_variable_value($group, $var, $val );
- $log->verbose_message("CLM sim_year_range is $nl_flags->{'sim_year_range'}");
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_run_type {
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
-
- my $val;
- my $var = "clm_start_type";
- if (defined $opts->{$var}) {
- if ($opts->{$var} eq "default" ) {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var);
- } else {
- my $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, quote_string( $opts->{$var} ) );
- }
- } else {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var);
- }
- $nl_flags->{'clm_start_type'} = $nl->get_value($var);
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_cmdl_output_reals {
- my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_;
-
- my $var = "output_reals_filename";
- my $file = $opts->{$var};
- if ( defined($file) ) {
- # Make sure can open file and if not die with an error
- my $fh = IO::File->new($file, '>') or $log->fatal_error("can't create real parameter filename: $file");
- $fh->close();
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_commandline_namelist {
- # Process the commandline '-namelist' arg.
- my ($opts, $definition, $nl, $envxml_ref) = @_;
-
- if (defined $opts->{'namelist'}) {
- # Parse commandline namelist
- my $nl_arg = Build::Namelist->new($opts->{'namelist'});
-
- # Validate input namelist -- trap exceptions
- my $nl_arg_valid;
- eval { $nl_arg_valid = $definition->validate($nl_arg); };
- if ($@) {
- $log->fatal_error("Invalid namelist variable in commandline arg '-namelist'.\n $@");
- }
- # Go through all variables and expand any XML env settings in them
- expand_xml_variables_in_namelist( $nl_arg_valid, $envxml_ref );
-
- # Merge input values into namelist. Previously specified values have higher precedence
- # and are not overwritten.
- $nl->merge_nl($nl_arg_valid);
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_commandline_infile {
- # Process the commandline '-infile' arg.
- my ($opts, $definition, $nl, $envxml_ref) = @_;
-
- if (defined $opts->{'infile'}) {
- my @infiles = split( /,/, $opts->{'infile'} );
- foreach my $infile ( @infiles ) {
- # Make sure a valid file was found
- if ( -f "$infile" ) {
- # Otherwise abort as a valid file doesn't exist
- } else {
- $log->fatal_error("input namelist file does NOT exist $infile.\n $@");
- }
- # Parse namelist input from the next file
- my $nl_infile = Build::Namelist->new($infile);
-
- # Validate input namelist -- trap exceptions
- my $nl_infile_valid;
- eval { $nl_infile_valid = $definition->validate($nl_infile); };
- if ($@) {
- $log->fatal_error("Invalid namelist variable in '-infile' $infile.\n $@");
- }
- # Go through all variables and expand any XML env settings in them
- expand_xml_variables_in_namelist( $nl_infile_valid, $envxml_ref );
-
- # Merge input values into namelist. Previously specified values have higher precedence
- # and are not overwritten.
- $nl->merge_nl($nl_infile_valid);
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_commandline_use_case {
- # Now process the -use_case arg.
- my ($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $envxml_ref, $physv) = @_;
-
- if (defined $opts->{'use_case'}) {
-
- # The use case definition is contained in an xml file with the same format as the defaults file.
- # Create a new NamelistDefaults object.
- my $uc_defaults = Build::NamelistDefaults->new("$opts->{'use_case_dir'}/$opts->{'use_case'}.xml", $cfg);
-
- my %settings;
- $settings{'res'} = $nl_flags->{'res'};
- $settings{'rcp'} = $nl_flags->{'rcp'};
- $settings{'mask'} = $nl_flags->{'mask'};
- $settings{'sim_year'} = $nl_flags->{'sim_year'};
- $settings{'sim_year_range'} = $nl_flags->{'sim_year_range'};
- $settings{'phys'} = $nl_flags->{'phys'};
- # Loop over the variables specified in the use case.
- # Add each one to the namelist.
- my @vars = $uc_defaults->get_variable_names();
- my $nl_usecase = Build::Namelist->new();
- foreach my $var (@vars) {
- my $val = $uc_defaults->get_value($var, \%settings );
-
- if ( defined($val) ) {
- $log->message("CLM adding use_case $opts->{'use_case'} defaults for var '$var' with val '$val'");
-
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl_usecase, $var, 'val'=>$val);
- }
- }
- # Go through all variables and expand any XML env settings in them
- expand_xml_variables_in_namelist( $nl_usecase, $envxml_ref );
-
- # Merge input values into namelist. Previously specified values have higher precedence
- # and are not overwritten.
- $nl->merge_nl($nl_usecase);
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_commandline_clm_start_type {
- # Set the start_type according to the command line clm_start_type option
-
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
-
- # Run type for driver namelist - note that arb_ic implies that the run is startup
- my $var = "start_type";
- if ($nl_flags->{'clm_start_type'} eq "'cold'" || $nl_flags->{'clm_start_type'} eq "'arb_ic'") {
- # Add default is used here, but the value is explicitly set
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'val'=>'startup' );
- } else {
- # Add default is used here, but the value is explicitly set
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'val'=>$nl_flags->{'clm_start_type'} );
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub process_namelist_inline_logic {
- # Use the namelist default object to add default values for required
- # namelist variables that have not been previously set.
- my ($opts, $nl_flags, $definition, $defaults, $nl, $cfg, $envxml_ref, $physv) = @_;
-
-
- ##############################
- # namelist group: clm_inparm #
- ##############################
- setup_logic_lnd_frac($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref);
- setup_logic_start_type($opts, $nl_flags, $nl);
- setup_logic_delta_time($opts, $nl_flags, $definition, $defaults, $nl);
- setup_logic_decomp_performance($opts, $nl_flags, $definition, $defaults, $nl);
- setup_logic_demand($opts, $nl_flags, $definition, $defaults, $nl, $physv);
- setup_logic_surface_dataset($opts, $nl_flags, $definition, $defaults, $nl, $physv);
- setup_logic_initial_conditions($opts, $nl_flags, $definition, $defaults, $nl, $physv);
-
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_lnd_frac {
-
- my ($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref) = @_;
-
- my $var = "lnd_frac";
- if ( defined($opts->{$var}) ) {
- if ( defined($nl->get_value('fatmlndfrc')) ) {
- $log->fatal_error("Can NOT set both -lnd_frac option (set via LND_DOMAIN_PATH/LND_DOMAIN_FILE " .
- "env variables) AND fatmlndfrac on namelist");
- }
- my $lnd_frac = SetupTools::expand_xml_var( $opts->{$var}, $envxml_ref);
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fatmlndfrc','val'=>$lnd_frac );
- }
-
- # Get the fraction file
- if (defined $nl->get_value('fatmlndfrc')) {
- # do nothing - use value provided by config_grid.xml and clm.cpl7.template
- } else {
- $log->fatal_error("fatmlndfrc was NOT sent into CLM build-namelist.");
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_start_type {
- my ($opts, $nl_flags, $nl) = @_;
-
- my $var = "start_type";
- my $drv_start_type = $nl->get_value($var);
- my $my_start_type = $nl_flags->{'clm_start_type'};
- my $nsrest = $nl->get_value('override_nsrest');
-
- if ( defined($nsrest) ) {
- if ( $nsrest == 0 ) { $my_start_type = "startup"; }
- if ( $nsrest == 1 ) { $my_start_type = "continue"; }
- if ( $nsrest == 3 ) { $my_start_type = "branch"; }
- if ( "$my_start_type" eq "$drv_start_type" ) {
- $log->fatal_error("no need to set override_nsrest to same as start_type.");
- }
- if ( "$drv_start_type" !~ /startup/ ) {
- $log->fatal_error("can NOT set override_nsrest if driver is NOT a startup type.");
- }
- }
-
- if ( $my_start_type =~ /branch/ ) {
- if (not defined $nl->get_value('nrevsn')) {
- $log->fatal_error("nrevsn is required for a branch type.");
- }
- } else {
- if (defined $nl->get_value('nrevsn')) {
- $log->fatal_error("nrevsn should ONLY be set for a branch type.");
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_delta_time {
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
-
- if ( defined($opts->{'l_ncpl'}) ) {
- my $l_ncpl = $opts->{'l_ncpl'};
- if ( $l_ncpl <= 0 ) {
- $log->fatal_error("bad value for -l_ncpl option.");
- }
- my $val = ( 3600 * 24 ) / $l_ncpl;
- my $dtime = $nl->get_value('dtime');
- if ( ! defined($dtime) ) {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'dtime', 'val'=>$val);
- } elsif ( $dtime ne $val ) {
- $log->fatal_error("can NOT set both -l_ncpl option (via LND_NCPL env variable) AND dtime namelist variable.");
- }
- } else {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'dtime', 'hgrid'=>$nl_flags->{'res'});
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_decomp_performance {
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
-
- # Set the number of segments per clump
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'nsegspc', 'hgrid'=>$nl_flags->{'res'});
-}
-
-#-------------------------------------------------------------------------------
-
-sub error_if_set {
- # do a fatal_error and exit if any of the input variable names are set
- my ($nl, $error, @list) = @_;
- foreach my $var ( @list ) {
- if ( defined($nl->get_value($var)) ) {
- $log->fatal_error( "$var $error" );
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_demand {
- #
- # Deal with options that the user has said are required...
- #
- my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_;
-
- my %settings;
- $settings{'hgrid'} = $nl_flags->{'res'};
- $settings{'sim_year'} = $nl_flags->{'sim_year'};
- $settings{'sim_year_range'} = $nl_flags->{'sim_year_range'};
- $settings{'mask'} = $nl_flags->{'mask'};
- $settings{'rcp'} = $nl_flags->{'rcp'};
- # necessary for demand to be set correctly
-
- my $demand = $nl->get_value('clm_demand');
- if (defined($demand)) {
- $demand =~ s/\'//g; # Remove quotes
- if ( $demand =~ /.+/ ) {
- $opts->{'clm_demand'} .= ",$demand";
- }
- }
-
- $demand = $defaults->get_value('clm_demand', \%settings);
- if (defined($demand)) {
- $demand =~ s/\'//g; # Remove quotes
- if ( $demand =~ /.+/ ) {
- $opts->{'clm_demand'} .= ",$demand";
- }
- }
-
- my @demandlist = split( ",", $opts->{'clm_demand'} );
- foreach my $item ( @demandlist ) {
- if ( $item eq "null" ) {
- next;
- }
- if ( $item eq "finidat" ) {
- $log->fatal_error( "Do NOT put findat in the clm_demand list, set the clm_start_type=startup so initial conditions are required");
- }
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $item, %settings );
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_surface_dataset {
- #
- # Get surface dataset after flanduse_timeseries so that we can get surface data
- # consistent with it
- # MUST BE AFTER: setup_logic_demand which is where flanduse_timeseries is set
- #
- my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_;
-
- $nl_flags->{'flanduse_timeseries'} = "null";
- my $flanduse_timeseries = $nl->get_value('flanduse_timeseries');
- if (defined($flanduse_timeseries)) {
- $flanduse_timeseries =~ s!(.*)/!!;
- $flanduse_timeseries =~ s/\'//;
- $flanduse_timeseries =~ s/\"//;
- if ( $flanduse_timeseries ne "" ) {
- $nl_flags->{'flanduse_timeseries'} = $flanduse_timeseries;
- }
- }
- $flanduse_timeseries = $nl_flags->{'flanduse_timeseries'};
-
- # MML: try and add my own namelist variable for mml_surdat forcing file
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'mml_surdat', 'hgrid'=>$nl_flags->{'res'});
-
-
-}
-
-#-------------------------------------------------------------------------------
-
-sub setup_logic_initial_conditions {
- # Initial conditions
- # The initial date is an attribute in the defaults file which should be matched unless
- # the user explicitly requests to ignore the initial date via the -ignore_ic_date option,
- # or just ignore the year of the initial date via the -ignore_ic_year option.
- #
- # MUST BE AFTER: setup_logic_demand which is where flanduse_timeseries is set
- my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_;
-
- my $var = "finidat";
- my $finidat = $nl->get_value($var);
- if ( $nl_flags->{'clm_start_type'} =~ /cold/ ) {
- if (defined $finidat ) {
- $log->warning("setting $var (either explicitly in your user_nl_clm or by doing a hybrid or branch RUN_TYPE)\n is incomptable with using a cold start" .
- " (by setting CLM_FORCE_COLDSTART=on)." );
- $log->warning("Overridding input $var file with one specifying that this is a cold start from arbitrary initial conditions." );
- my $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, "' '" );
- }
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl,
- $var, 'val'=>"' '", 'no_abspath'=>1);
- $finidat = $nl->get_value($var);
- } elsif ( defined $finidat ) {
- if ( string_is_undef_or_empty($finidat) ) {
- print "You are setting $var to blank which signals arbitrary initial conditions.\n";
- print "But, CLM_FORCE_COLDSTART is off which is a contradiction. For arbitrary initial conditions just use the CLM_FORCE_COLDSTART option\n";
- $log->fatal_error("To do a cold-start set ./xmlchange CLM_FORCE_COLDSTART=on, and remove the setting of $var in the user_nl_clm file");
- }
- }
- my $useinitvar = "use_init_interp";
-
- if (not defined $finidat ) {
- my $ic_date = $nl->get_value('start_ymd');
- my $st_year = int( $ic_date / 10000);
- my $nofail = 1;
- my %settings;
- $settings{'hgrid'} = $nl_flags->{'res'};
- $settings{'phys'} = $physv->as_string();
- $settings{'nofail'} = $nofail;
- #
- # If not transient use sim_year, otherwise use date
- #
- if (string_is_undef_or_empty($nl->get_value('flanduse_timeseries'))) {
- $settings{'sim_year'} = $nl_flags->{'sim_year'};
- $opts->{'ignore_ic_year'} = 1;
- } else {
- delete( $settings{'sim_year'} );
- }
- foreach my $item ( "mask", "maxpft" ) {
- $settings{$item} = $nl_flags->{$item};
- }
- if ($opts->{'ignore_ic_year'}) {
- $settings{'ic_md'} = $ic_date;
- } else {
- $settings{'ic_ymd'} = $ic_date;
- }
- my $try = 0;
- my $done = 2;
- my $use_init_interp_default = $nl->get_value($useinitvar);
- if ( string_is_undef_or_empty( $use_init_interp_default ) ) {
- $use_init_interp_default = ".false.";
- }
- $settings{$useinitvar} = $use_init_interp_default;
- do {
- $try++;
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, %settings );
- # If couldn't find a matching finidat file, check if can turn on interpolation and try to find one again
- $finidat = $nl->get_value($var);
- if ( not defined $finidat ) {
- # Delete any date settings
- delete( $settings{'ic_ymd'} );
- delete( $settings{'ic_md'} );
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "init_interp_sim_years" );
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "init_interp_how_close" );
- foreach my $sim_yr ( split( /,/, $nl->get_value("init_interp_sim_years") )) {
- if ( abs($st_year - $sim_yr) < $nl->get_value("init_interp_how_close") ) {
- $settings{'sim_year'} = $sim_yr;
- }
- }
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $useinitvar,
- 'phys'=>$physv->as_string(),
- 'sim_year'=>$settings{'sim_year'}, 'nofail'=>1 );
- $settings{$useinitvar} = $nl->get_value($useinitvar);
- if ( $try > 1 ) {
- my $group = $definition->get_group_name($useinitvar);
- $nl->set_variable_value($group, $useinitvar, $use_init_interp_default );
- }
- if ( &value_is_true($nl->get_value($useinitvar) ) ) {
-
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "init_interp_attributes",
- 'sim_year'=>$settings{'sim_year'},
- 'nofail'=>1 );
- my $attributes_string = remove_leading_and_trailing_quotes($nl->get_value("init_interp_attributes"));
- foreach my $pair ( split( /\s/, $attributes_string) ) {
- if ( $pair =~ /^([a-z_]+)=([a-z._0-9]+)$/ ) {
- $settings{$1} = $2;
- } else {
- $log->fatal_error("Problem interpreting init_interp_attributes");
- }
- }
- } else {
- if ( $nl_flags->{'clm_start_type'} =~ /startup/ ) {
- $log->fatal_error("clm_start_type is startup so an initial conditions ($var) file is required, but can't find one without $useinitvar being set to true");
- }
- $try = $done;
- }
- } else {
- $try = $done
- }
- } while( ($try < $done) && (not defined $finidat ) );
- if ( not defined $finidat ) {
- my $group = $definition->get_group_name($var);
- $nl->set_variable_value($group, $var, "' '" );
- }
- }
- $finidat = $nl->get_value($var);
- if ( &value_is_true($nl->get_value($useinitvar) ) && string_is_undef_or_empty($finidat) ) {
- $log->fatal_error("$useinitvar is set BUT $var is NOT, need to set both" );
- }
-} # end initial conditions
-
-#-------------------------------------------------------------------------------
-
-sub write_output_files {
- my ($opts, $nl_flags, $defaults, $nl, $physv) = @_;
-
- my $note = "";
- my $var = "note";
- if ( ! defined($opts->{$var}) ) {
- $opts->{$var} = $defaults->get_value($var);
- }
- if ( $opts->{$var} ) {
- $note = "Comment:\n" .
- "This namelist was created using the following command-line:\n" .
- " $nl_flags->{'cfgdir'}/$ProgName $nl_flags->{'cmdline'}\n" .
- "For help on options use: $nl_flags->{'cfgdir'}/$ProgName -help";
- }
-
- # CLM component
- my @groups = qw(clm_inparm
- finidat_consistency_checks);
-# clm_initinterp_inparm);
-
- my $outfile;
- $outfile = "$opts->{'dir'}/lnd_in";
- $nl->write($outfile, 'groups'=>\@groups, 'note'=>"$note" );
- $log->verbose_message("Writing clm namelist to $outfile");
-}
-
-sub write_output_real_parameter_file {
- my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_;
-
- # Output real parameters
- if ( defined($opts->{'output_reals_filename'}) ) {
- my $file = $opts->{'output_reals_filename'};
- my $fh = IO::File->new($file, '>>') or $log->fatal_error("can't create real parameter filename: $file");
- foreach my $var ( $definition->get_var_names() ) {
- my $type = $definition->get_var_type($var);
- my $doc = $definition->get_var_doc($var);
- $doc =~ s/\n//g;
- if ( $type =~ /real/ ) {
- my $val = $nl->get_value($var);
- if ( ! defined($val) ) { $val = "?.??"; }
- print $fh "\! $doc\n$var = $val\n";
- }
- }
- $fh->close();
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub add_default {
-
-# Add a value for the specified variable to the specified namelist object. The variables
-# already in the object have the higher precedence, so if the specified variable is already
-# defined in the object then don't overwrite it, just return.
-#
-# This method checks the definition file and adds the variable to the correct
-# namelist group.
-#
-# The value can be provided by using the optional argument key 'val' in the
-# calling list. Otherwise a default value is obtained from the namelist
-# defaults object. If no default value is found this method throws an exception
-# unless the 'nofail' option is set true.
-#
-# Example 1: Specify the default value $val for the namelist variable $var in namelist
-# object $nl:
-#
-# add_default($inputdata_rootdir, $definition, $defaults, $nl, $var, 'val'=>$val)
-#
-# Example 2: Add a default for variable $var if an appropriate value is found. Otherwise
-# don't add the variable
-#
-# add_default($inputdata_rootdir, $definition, $defaults, $nl, $var, 'nofail'=>1)
-#
-#
-# ***** N.B. ***** This routine assumes the following variables are in package main::
-# $definition -- the namelist definition object
-# $defaults -- the namelist defaults object
-# $inputdata_rootdir -- CESM inputdata root directory
-
- my $opts = shift;
- my $inputdata_rootdir = shift;
- my $definition = shift;
- my $defaults = shift;
- my $nl = shift;
- my $var = shift;
- my %settings = @_;
-
- my $test_files = $opts->{'test'};
- #my $nl = shift; # namelist object
- #my $var = shift; # name of namelist variable
- #my %settings = @_; # options
-
- # If variable has quotes around it
- if ( $var =~ /'(.+)'/ ) {
- $var = $1;
- }
- # Query the definition to find which group the variable belongs to. Exit if not found.
-
- my $group = $definition->get_group_name($var);
- unless ($group) {
- my $fname = $definition->get_file_name();
- $log->fatal_error("variable \"$var\" not found in namelist definition file $fname.");
- }
-
- # check whether the variable has a value in the namelist object -- if so then skip to end
- my $val = $nl->get_variable_value($group, $var);
- if (! defined $val) {
-
- # Look for a specified value in the options hash
-
- if (defined $settings{'val'}) {
- $val = $settings{'val'};
- }
- # or else get a value from namelist defaults object.
- # Note that if the 'val' key isn't in the hash, then just pass anything else
- # in %settings to the get_value method to be used as attributes that are matched
- # when looking for default values.
- else {
-
- $val = $defaults->get_value($var, \%settings);
-
- # Truncate model_version appropriately
-
- if ( $var eq "model_version" ) {
- $val =~ /(URL: https:\/\/[a-zA-Z0-9._-]+\/)([a-zA-Z0-9\/._-]+)(\/bld\/.+)/;
- $val = $2;
- }
- }
-
- # if no value is found then exit w/ error (unless 'nofail' option set)
- unless ( defined($val) ) {
- unless ($settings{'nofail'}) {
- if ($var eq 'finidat') {
- $log->message("No default value found for $var.\n" .
- " Are defaults provided for this resolution and land mask?" );
- } else {
- $log->fatal_error("No default value found for $var.\n" .
- " Are defaults provided for this resolution and land mask?");
- }
- }
- else {
- return;
- }
- }
-
- # query the definition to find out if the variable is an input pathname
- my $is_input_pathname = $definition->is_input_pathname($var);
-
- # The default values for input pathnames are relative. If the namelist
- # variable is defined to be an absolute pathname, then prepend
- # the CESM inputdata root directory.
- if (not defined $settings{'no_abspath'}) {
- if (defined $settings{'set_abspath'}) {
- $val = set_abs_filepath($val, $settings{'set_abspath'});
- } else {
- if ($is_input_pathname eq 'abs') {
- $val = set_abs_filepath($val, $inputdata_rootdir);
- if ( $test_files and ($val !~ /null/) and (! -f "$val") ) {
- $log->fatal_error("file not found: $var = $val");
- }
- }
- }
- }
-
- # query the definition to find out if the variable takes a string value.
- # The returned string length will be >0 if $var is a string, and 0 if not.
- my $str_len = $definition->get_str_len($var);
-
- # If the variable is a string, then add quotes if they're missing
- if ($str_len > 0) {
- $val = quote_string($val);
- }
-
- # set the value in the namelist
- $nl->set_variable_value($group, $var, $val);
- }
-
-}
-
-#-------------------------------------------------------------------------------
-
-sub expand_xml_variables_in_namelist {
- # Go through all variables in the namelist and expand any XML env settings in them
- my ($nl, $xmlvar_ref) = @_;
-
- foreach my $group ( $nl->get_group_names() ) {
- foreach my $var ( $nl->get_variable_names($group) ) {
- my $val = $nl->get_variable_value($group, $var);
- my $newval = SetupTools::expand_xml_var( $val, $xmlvar_ref );
- if ( $newval ne $val ) {
- $nl->set_variable_value($group, $var, $newval);
- }
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub check_input_files {
-
-# For each variable in the namelist which is an input dataset, check to see if it
-# exists locally.
-#
-# ***** N.B. ***** This routine assumes the following variables are in package main::
-# $definition -- the namelist definition object
-# $nl -- namelist object
-# $inputdata_rootdir -- if false prints test, else creates inputdata file
-
- my ($nl, $inputdata_rootdir, $outfile, $definition) = @_;
-
- open(OUTFILE, ">>$outfile") if defined $inputdata_rootdir;
-
- # Look through all namelist groups
- my @groups = $nl->get_group_names();
- foreach my $group (@groups) {
-
- # Look through all variables in each group
- my @vars = $nl->get_variable_names($group);
- foreach my $var (@vars) {
-
- # Is the variable an input dataset?
- my $input_pathname_type = $definition->is_input_pathname($var);
-
- # If it is, check whether it exists locally and print status
- if ($input_pathname_type) {
-
- # Get pathname of input dataset
- my $pathname = $nl->get_variable_value($group, $var);
- # Need to strip the quotes
- $pathname =~ s/['"]//g;
-
- if ($input_pathname_type eq 'abs') {
- if ($inputdata_rootdir) {
- #MV $pathname =~ s:$inputdata_rootdir::;
- print OUTFILE "$var = $pathname\n";
- }
- else {
- if (-e $pathname) { # use -e rather than -f since the absolute pathname
- # might be a directory
- print "OK -- found $var = $pathname\n";
- }
- else {
- print "NOT FOUND: $var = $pathname\n";
- }
- }
- }
- elsif ($input_pathname_type =~ m/rel:(.+)/o) {
- # The match provides the namelist variable that contains the
- # root directory for a relative filename
- my $rootdir_var = $1;
- my $rootdir = $nl->get_variable_value($group, $rootdir_var);
- $rootdir =~ s/['"]//g;
- if ($inputdata_rootdir) {
- $pathname = "$rootdir/$pathname";
- #MV $pathname =~ s:$inputdata_rootdir::;
- print OUTFILE "$var = $pathname\n";
- }
- else {
- if (-f "$rootdir/$pathname") {
- print "OK -- found $var = $rootdir/$pathname\n";
- }
- else {
- print "NOT FOUND: $var = $rootdir/$pathname\n";
- }
- }
- }
- }
- }
- }
- close OUTFILE if defined $inputdata_rootdir;
- return 0 if defined $inputdata_rootdir;
-}
-
-#-------------------------------------------------------------------------------
-
-sub set_abs_filepath {
-
-# check whether the input filepath is an absolute path, and if it isn't then
-# prepend a root directory
-
- my ($filepath, $rootdir) = @_;
-
- # strip any leading/trailing whitespace and quotes
- $filepath = trim($filepath);
- $filepath = remove_leading_and_trailing_quotes($filepath);
- $rootdir = trim($rootdir);
- $rootdir = remove_leading_and_trailing_quotes($rootdir);
-
- my $out = $filepath;
- unless ( $filepath =~ /^\// ) { # unless $filepath starts with a /
- $out = "$rootdir/$filepath"; # prepend the root directory
- }
- return $out;
-}
-
-#-------------------------------------------------------------------------------
-
-sub valid_option {
-
- my ($val, @expect) = @_;
-
- my $expect;
-
- $val = trim($val);
-
- foreach $expect (@expect) {
- if ($val =~ /^$expect$/i) { return $expect; }
- }
- return undef;
-}
-
-#-------------------------------------------------------------------------------
-
-sub check_use_case_name {
-#
-# Check the use-case name and ensure it follows the naming convention.
-#
- my ($use_case) = @_;
-
- my $diestring = "bad use_case name $use_case, follow the conventions " .
- "in namelist_files/use_cases/README\n";
- my $desc = "[a-zA-Z0-9]*";
- my $rcp = "rcp[0-9\.]+";
- if ( $use_case =~ /^[0-9]+-[0-9]+([a-zA-Z0-9_\.]*)_transient$/ ) {
- my $string = $1;
- if ( $string =~ /^_($rcp)_*($desc)$/ ) {
- # valid name
- } elsif ( $string =~ /^_*($desc)$/ ) {
- # valid name
- } else {
- $log->fatal_error($diestring);
- }
- } elsif ( $use_case =~ /^20thC([a-zA-Z0-9_\.]*)_transient$/ ) {
- my $string = $1;
- if ( $string =~ /^_($rcp)_*($desc)$/ ) {
- # valid name
- } elsif ( $string =~ /^_*($desc)$/ ) {
- # valid name
- } else {
- $log->fatal_error($diestring);
- }
- } elsif ( $use_case =~ /^([0-9]+)_*($desc)_control$/ ) {
- # valid name
- } elsif ( $use_case =~ /^($desc)_pd$/ ) {
- # valid name
- } else {
- $log->fatal_error($diestring);
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub validate_options {
-
-# $source -- text string declaring the source of the options being validated
-# $cfg -- configure object
-# $opts -- reference to hash that contains the options
-
- my ($source, $cfg, $opts) = @_;
-
- my ($opt, $old, @expect);
-
- # use_case
- $opt = 'use_case';
- if (defined $opts->{$opt}) {
-
- if ( $opts->{$opt} ne "list" ) {
- # create the @expect array by listing the files in $use_case_dir
- # and strip off the ".xml" part of the filename
- @expect = ();
- my @files = glob("$opts->{'use_case_dir'}/*.xml");
- foreach my $file (@files) {
- $file =~ m{.*/(.*)\.xml};
- &check_use_case_name( $1 );
- push @expect, $1;
- }
-
- $old = $opts->{$opt};
- $opts->{$opt} = valid_option($old, @expect)
- or $log->fatal_error("invalid value of $opt ($old) specified in $source\n" .
- "expected one of: @expect");
- } else {
- print "Use cases are:...\n\n";
- my @ucases;
- foreach my $file( sort( glob($opts->{'use_case_dir'}."/*.xml") ) ) {
- my $use_case;
- if ( $file =~ /\/([^\/]+)\.xml$/ ) {
- &check_use_case_name( $1 );
- $use_case = $1;
- } else {
- $log->fatal_error("Bad name for use case file = $file");
- }
- my $uc_defaults = Build::NamelistDefaults->new("$file", $cfg);
- printf "%15s = %s\n", $use_case, $uc_defaults->get_value("use_case_desc");
- push @ucases, $use_case;
- }
- $log->exit_message("use cases : @ucases");
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub list_options {
-#
-# List the options for different command line values if asked for
-#
- my ($opts_cmdl, $definition, $defaults) = @_;
-
- # options to list values that are in the defaults files
- my @opts_list = ( "res", "mask", "sim_year", "rcp" );
- my %opts_local;
- foreach my $var ( "res", "mask", "sim_year", "rcp" ) {
- my $val;
- if ( $opts_cmdl->{$var} eq "list" ) {
- $val = "default";
- } elsif ( $opts_cmdl->{$var} eq "default" ) {
- $val = $defaults->get_value($var, \%opts_local );
- } else {
- $val = $opts_cmdl->{$var};
- }
- my $vname = $var;
- if ( $vname eq "res" ) { $vname = "hgrid"; }
- $opts_local{$vname} = $val;
- }
- foreach my $var ( @opts_list ) {
- if (defined $opts_cmdl->{$var}) {
-
- if ( $opts_cmdl->{$var} eq "list" ) {
- my @valid_values = $definition->get_valid_values( $var );
- if ( $var eq "sim_year" ) {
- unshift( @valid_values,
- $definition->get_valid_values( "sim_year_range" ) );
- }
- unshift( @valid_values, "default" );
- # Strip out quotes and the constant value
- for( my $i = 0; $i <= $#valid_values; $i++ ) {
- $valid_values[$i] =~ s/('|')//g;
- if ( $valid_values[$i] eq "constant" ) { $valid_values[$i] = undef; }
- }
- my $val= $defaults->get_value($var, \%opts_local);
- my $doc = $definition->get_var_doc( $var );
- $doc =~ s/\n//;
- chomp( $doc );
- $log->exit_message("valid values for $var ($doc) :\n" .
- " Values: @valid_values\n" .
- " Default = $val\n" .
- " (NOTE: resolution and mask and other settings may influence what the default is)");
- }
- }
- }
- # clm_demand
- my $var = 'clm_demand';
- if (defined $opts_cmdl->{$var}) {
-
- if ( $opts_cmdl->{$var} eq "list" ) {
- my @vars = $definition->get_var_names( );
- my @demands = ( "null" );
- foreach my $var ( @vars ) {
- if ( $definition->get_group_name( $var ) ne "clm_inparm" ) { next; }
- if ( defined($defaults->get_value($var, $opts_cmdl ) ) ) {
- push( @demands, $var );
- }
- }
- my $doc = $definition->get_var_doc( 'clm_demand' );
- $doc =~ s/\n//;
- chomp( $doc );
- $log->exit_message("valid values for $var ($doc) :\n" .
- "Namelist options to require: @demands\n" .
- "any valid namelist item for clm_inparm can be set. However, not all are\n" .
- "available in the clm defaults file. The defaults are also dependent on\n" .
- "resolution and landmask, as well as other settings. Hence, the list above\n" .
- "will vary depending on what you set for resolution and landmask.");
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub trim {
- # remove leading and trailing whitespace from a string.
- my ($str) = @_;
- $str =~ s/^\s+//;
- $str =~ s/\s+$//;
- return $str;
-}
-
-#-------------------------------------------------------------------------------
-
-sub quote_string {
- # Add quotes around a string, unless they are already there
- my ($str) = @_;
- $str = trim($str);
- unless ($str =~ /^['"]/) { #"'
- $str = "\'$str\'";
- }
- return $str;
- }
-
-#-------------------------------------------------------------------------------
-
-sub remove_leading_and_trailing_quotes {
- # Remove leading and trailing single and double quotes from a string. Also
- # removes leading spaces before the leading quotes, and trailing spaces after
- # the trailing quotes.
-
- my ($str) = @_;
-
- $str = trim($str);
-
- # strip any leading/trailing quotes
- $str =~ s/^['"]+//;
- $str =~ s/["']+$//;
-
- return $str;
-}
-
-#-------------------------------------------------------------------------------
-
-sub logical_to_fortran {
- # Given a logical variable ('true' / 'false'), convert it to a fortran-style logical ('.true.' / '.false.')
- # The result will be lowercase, regardless of the case of the input.
- my ($var) = @_;
- my $result;
-
- if (lc($var) eq 'true') {
- $result = ".true.";
- }
- elsif (lc($var) eq 'false') {
- $result = ".false.";
- }
- else {
- $log->fatal_error("Unexpected value in logical_to_fortran: $var");
- }
-
- return $result;
-}
-
-#-------------------------------------------------------------------------------
-
-sub string_is_undef_or_empty {
- # Return true if the given string is undefined or only spaces, false otherwise.
- # A quoted empty string (' ' or " ") is treated as being empty.
- my ($str) = @_;
- if (!defined($str)) {
- return 1;
- }
- else {
- $str = remove_leading_and_trailing_quotes($str);
- if ($str =~ /^\s*$/) {
- return 1;
- }
- else {
- return 0;
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub value_is_true {
- # Return true if the given namelist value is .true.
- # An undefined value is treated as false (with the assumption that false is the default in the code)
- my ($val) = @_;
-
- # Some regular expressions...
- ###my $TRUE = qr/\.true\./i;
- ###my $FALSE = qr/\.false\./i;
- # **N.B.** the use of qr// for precompiling regexps isn't supported until perl 5.005.
- my $TRUE = '\.?true\.?|[t]';
- my $FALSE = '\.?false\.?|[f]';
- my $is_true = 0;
- if (defined($val)) {
- if ($val =~ /$TRUE/i) {
- $is_true = 1;
- }
- }
-
- return $is_true;
-}
-
-#-------------------------------------------------------------------------------
-
-sub version {
-# The version is found in CLM ChangeLog file.
-# $cfgdir is set by the configure script to the name of its directory.
-
- my ($cfgdir) = @_;
-
- my $logfile = "$cfgdir/../doc/ChangeLog";
-
- my $fh = IO::File->new($logfile, '<') or $log->fatal_error("can't open ChangeLog file: $logfile");
-
- while (my $line = <$fh>) {
-
- if ($line =~ /^Tag name:\s*([a-zA-Z0-9_. -]*[clmcesm0-9_.-]+)$/ ) {
- $log->exit_message("$1");
- }
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub main {
- my %nl_flags;
- $nl_flags{'cfgdir'} = dirname(abs_path($0));
-
- my %opts = process_commandline(\%nl_flags);
- my $cfgdir = $nl_flags{'cfgdir'};
- check_for_perl_utils($cfgdir, \%opts);
-
- $log = namelist_files::LogMessages->new( $ProgName, \%opts ); # global
- version($cfgdir) if $opts{'version'};
- my $cfg = read_configure_definition($cfgdir, \%opts);
-
- my $physv = config_files::clm_phys_vers->new( $cfg->get('phys') );
- my $definition = read_namelist_definition($cfgdir, \%opts, \%nl_flags, $physv);
- my $defaults = read_namelist_defaults($cfgdir, \%opts, \%nl_flags, $cfg, $physv);
-
- # List valid values if asked for
- list_options(\%opts, $definition, $defaults);
-
- # Validate some of the commandline option values.
- validate_options("commandline", $cfg, \%opts);
-
- # Create an empty namelist object.
- my $nl = Build::Namelist->new();
-
- check_cesm_inputdata(\%opts, \%nl_flags);
-
- # Read in the env_*.xml files
- my %env_xml = read_envxml_case_files( \%opts );
-
- # Process the user inputs
- process_namelist_user_input(\%opts, \%nl_flags, $definition, $defaults, $nl, $cfg, \%env_xml, $physv );
- # Get any other defaults needed from the namelist defaults file
- process_namelist_inline_logic(\%opts, \%nl_flags, $definition, $defaults, $nl, $cfg, \%env_xml, $physv);
-
- # Validate that the entire resultant namelist is valid
- $definition->validate($nl);
- write_output_files(\%opts, \%nl_flags, $defaults, $nl, $physv);
- write_output_real_parameter_file(\%opts, \%nl_flags, $definition, $defaults, $nl, $physv);
-
- if ($opts{'inputdata'}) {
- check_input_files($nl, $nl_flags{'inputdata_rootdir'}, $opts{'inputdata'}, $definition);
- }
- $log->final_exit("Successfully made CLM namelist file");
-}
-
-#-------------------------------------------------------------------------------
-
-1;
diff --git a/bld/Filepath b/bld/Filepath
deleted file mode 100644
index b8ec46d2..00000000
--- a/bld/Filepath
+++ /dev/null
@@ -1,8 +0,0 @@
-../SourceMods/src.clm
-/glade/p/work/erik/SimpleLand/src/main
-/glade/p/work/erik/SimpleLand/src/biogeophys
-/glade/p/work/erik/SimpleLand/src/biogeochem
-/glade/p/work/erik/SimpleLand/src/soilbiogeochem
-/glade/p/work/erik/SimpleLand/src/init_interp
-/glade/p/work/erik/SimpleLand/src/utils
-/glade/p/work/erik/SimpleLand/src/cpl
diff --git a/bld/build-namelist b/bld/build-namelist
deleted file mode 100755
index 46e485d1..00000000
--- a/bld/build-namelist
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env perl
-#-----------------------------------------------------------------------------------------------
-#
-# clm build-namelist driver
-#
-# Placing all of build-namelist into CLMBuildNamelist.pm means we can unit test the module.
-#
-require 5;
-
-use strict;
-
-BEGIN {
- # ensure that the cesm create_X scripts can find CLMBuildNamelist.pm
- use File::Basename qw(dirname);
- use Cwd qw(abs_path);
- my $dirname = dirname(abs_path($0));
- my @dirs = ($dirname, );
- unshift @INC, @dirs;
-}
-
-use CLMBuildNamelist qw(main);
-
-CLMBuildNamelist::main();
diff --git a/bld/config_cache.xml b/bld/config_cache.xml
deleted file mode 100644
index 2875f0b1..00000000
--- a/bld/config_cache.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-/glade/p/work/erik/SimpleLand/bld/configure
-
-
-Root directory of CLM source distribution (directory above CLM configure).
-
-
-Component framework interface to use
-(Model Coupling Toolkit, or Earth System Modeling Framework)
-
-
-User specified CPP defines to append to Makefile defaults.
-Note: It's recommended to use configure options to set standard CPP values rather
-than defining them here.
-
-
-Specifies either clm4_5, or clm5_0 physics
-
-
-User source directories to prepend to the filepath. Multiple directories
-are specified as a comma separated list with no embedded white space.
-Normally this is SourceMods/src.clm in your case.
-
-
-
diff --git a/bld/config_files/clm_phys_vers.pm b/bld/config_files/clm_phys_vers.pm
deleted file mode 100755
index efd83609..00000000
--- a/bld/config_files/clm_phys_vers.pm
+++ /dev/null
@@ -1,196 +0,0 @@
-package config_files::clm_phys_vers;
-my $pkg_nm = 'config_files::clm_phys_vers';
-#-----------------------------------------------------------------------------------------------
-#
-# SYNOPSIS
-#
-# require config_files::clm_phys_vers;
-#
-# my $phys = config_files::clm_phys_vers->new("clm4_5");
-# print $phys->as_float();
-# print $phys->as_long();
-# print $phys->as_string();
-# print $phys->as_filename();
-#
-# DESCRIPTION
-#
-# Enter the physics version as a string, with a list of valid versions, and have the ability to convert it to
-# different formats.
-#
-# COLLABORATORS: None
-#
-#-----------------------------------------------------------------------------------------------
-#
-# Date Author Modification
-# 03/06/2014 Erik Kluzek creation
-#
-#--------------------------------------------------------------------------------------------
-
-use strict;
-use bigint;
-#use warnings;
-#use diagnostics;
-
-my $major_mask = 1000000;
-my $minor_mask = 1000;
-my @version_strings = ( "clm4_5", "clm5_0" );
-my @version_long = ( 4*$major_mask+5*$minor_mask, 5*$major_mask );
-
-#-------------------------------------------------------------------------------
-
-sub new {
- # Constructor, enter version string as argument
- my $class = shift;
- my $vers_string = shift;
-
- my $nm = "$class\:\:new";
- my $self = {};
- bless($self, $class);
- $self->__validate_vers__( $vers_string );
- $self->{'vers_string'} = $vers_string;
- return( $self );
-}
-
-#-------------------------------------------------------------------------------
-
-sub __validate_vers__ {
- # Make sure the version string is a valid one
- my $class = shift;
- my $vers_string = shift;
-
- my $found = undef;
- foreach my $i (0..$#version_strings) {
- if ( $vers_string eq $version_strings[$i] ) {
- $found = 1;
- last;
- }
- }
- if ( ! defined($found) ) {
- die "NOT a valid CLM version: $vers_string\n";
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub as_long {
-# Return the physics version as a long
- my $self = shift;
- my $vers = shift;
-
- if ( ! defined($vers) ) {
- $vers = $self->{'vers_string'};
- } else {
- $self->__validate_vers__( $vers );
- }
- my $phys = undef;
- for( my $i = 0; $i <= $#version_strings; $i++ ) {
- if ( $vers eq $version_strings[$i] ) {
- $phys = $version_long[$i];
- last;
- }
- }
- return( $phys );
-}
-
-#-------------------------------------------------------------------------------
-
-sub as_float {
-# Return the physics version as a float
- my $self = shift;
-
- my $long = $self->as_long();
- my $major = int($long / $major_mask);
- my $minor = int(($long - $major*$major_mask)/ $minor_mask);
- my $rev = $long - $major*$major_mask - $minor*$minor_mask;
- {
- no bigint;
- use bignum;
-
- my $phys = $major*1.0 + $minor/10.0 + $rev / 10000.0;
- return( $phys );
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub as_string {
-# Return the physics version as a string
- my $self = shift;
-
- my $phys = $self->{'vers_string'};
- return( $phys );
-}
-
-#-------------------------------------------------------------------------------
-
-sub as_filename {
-# Return the physics version string with clm4_5 and clm5_0 pointing to the same name
- my $self = shift;
-
- my $phys = undef;
- if ( $self->as_long() < 5*$major_mask ) {
- $phys = $self->as_string();
- } else {
- $phys = "clm4_5";
- }
- return( $phys );
-}
-
-#-----------------------------------------------------------------------------------------------
-# Unit testing of above
-#-----------------------------------------------------------------------------------------------
-if ( ! defined(caller) && $#ARGV == -1 ) {
- package phys_vers_unit_tester;
-
- require Test::More;
- Test::More->import( );
-
- plan( tests=>8);
-
- sub testit {
- print "unit tester\n";
- my %lastv;
- my @vers_list = ( "clm4_5", "clm5_0" );
- foreach my $vers ( @vers_list ) {
- my $phys = config_files::clm_phys_vers->new($vers);
- isa_ok($phys, "config_files::clm_phys_vers", "created clm_phys_vers object");
- print "$vers: long: ".$phys->as_long()." float: ".$phys->as_float()." string: ".$phys->as_string()." file: ".$phys->as_filename()."\n";
- if ( exists($lastv{"long"}) ) {
- is( $phys->as_long() > $lastv{'long'}, 1, "Definition of long is not increasing\n" );
- }
- if ( exists($lastv{"float"}) ) {
- is( $phys->as_float() > $lastv{'float'}, 1, "Definition of float is not increasing\n" );
- }
- # Check that also can get results of any valid value for long
- foreach my $chvers ( @vers_list ) {
- my $lvalue = $phys->as_long($chvers);
- print "Long value of $chvers = $lvalue\n";
- }
- # Check that a bad value gives an error
- eval { $phys->as_long('xxx'); };
- like( $@, qr/NOT a valid CLM version:/, "check that a bad version fails" );
- # Save last values to make sure increasing
- $lastv{'long'} = $phys->as_long();
- $lastv{'float'} = $phys->as_float();
- }
- my $phys = config_files::clm_phys_vers->new("clm4_5");
- no bigint;
- use bignum;
- is( 4.5, $phys->as_float(), "Make sure clm4_5 correct float value" );
- no bignum;
- use bigint;
- $phys = config_files::clm_phys_vers->new("clm5_0");
- is( 5.0, $phys->as_float(), "Make sure clm5_0 correct float value" );
- print "\nSuccessfully ran all tests\n";
- }
-}
-
-#-----------------------------------------------------------------------------------------------
-# Determine if you should run the unit test or if this is being called from a require statement
-#-----------------------------------------------------------------------------------------------
-
-if ( defined(caller) ) {
- 1 # to make use or require happy
-} elsif ( $#ARGV == -1 ) {
- &phys_vers_unit_tester::testit();
-}
diff --git a/bld/config_files/config_defaults.xml b/bld/config_files/config_defaults.xml
deleted file mode 100644
index 09d5634b..00000000
--- a/bld/config_files/config_defaults.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/bld/config_files/config_definition.xsl b/bld/config_files/config_definition.xsl
deleted file mode 100644
index f2f88609..00000000
--- a/bld/config_files/config_definition.xsl
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- CLM Configuration Definition
-
-
-
CLM Configuration Definition
-
-
-
CLM Physics Configurations
-
-
Name
-
Value
-
Description
-
-
-
Valid Values
-
-
-
-
-
-
CLM Biogeochemistry Configurations
-
-
Name
-
Value
-
Description
-
-
-
Valid Value
-
-
-
-
-
-
Configuration Directories
-
-
Name
-
Value
-
Description
-
-
-
Valid Value
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Valid values:
-
-
-
-
-
diff --git a/bld/config_files/config_definition_clm4_5.xml b/bld/config_files/config_definition_clm4_5.xml
deleted file mode 100644
index eb38cbe2..00000000
--- a/bld/config_files/config_definition_clm4_5.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-Specifies either clm4_5, or clm5_0 physics
-
-
-
-Root directory of CLM source distribution (directory above CLM configure).
-
-
-
-Component framework interface to use
-(Model Coupling Toolkit, or Earth System Modeling Framework)
-
-
-
-User source directories to prepend to the filepath. Multiple directories
-are specified as a comma separated list with no embedded white space.
-Normally this is SourceMods/src.clm in your case.
-
-
-
-User specified CPP defines to append to Makefile defaults.
-Note: It's recommended to use configure options to set standard CPP values rather
-than defining them here.
-
-
-
diff --git a/bld/configure b/bld/configure
deleted file mode 100755
index b9b58f1b..00000000
--- a/bld/configure
+++ /dev/null
@@ -1,545 +0,0 @@
-#!/usr/bin/env perl
-#-----------------------------------------------------------------------------------------------
-#
-# configure
-#
-#
-# This utility allows the CLM user to specify compile-time configuration
-# options via a commandline interface. The output from configure is a
-# Makefile and a cache file that contains all configuration parameters
-# required to produce the Makefile. A subsequent invocation of configure
-# can use the cache file as input (via the -defaults argument) to reproduce
-# the CLM configuration contained in it. Note that when a cache file is
-# used to set default values only the model parameters are used. The
-# parameters that are platform dependent (e.g., compiler options, library
-# locations, etc) are ignored.
-#
-# As the build time configurable options of CLM are changed, this script
-# must also be changed. Thus configure is maintained under revision
-# control in the CLM source tree and it is assumed that only the version of
-# configure in the source tree will be used to build CLM. Thus we assume
-# that the root of the source tree can be derived from the location of this
-# script.
-#
-#-----------------------------------------------------------------------------------------------
-
-use strict;
-#use warnings;
-#use diagnostics;
-use Cwd qw(getcwd abs_path);
-use English;
-use Getopt::Long;
-use IO::File;
-use IO::Handle;
-use File::Copy;
-
-#-----------------------------------------------------------------------------------------------
-
-sub usage {
- die <). Any value that contains
- white-space must be quoted. Long option names may be supplied with either single
- or double leading dashes. A consequence of this is that single letter options may
- NOT be bundled.
-
- -bgc Build CLM with BGC package [ none | cn ]
- (default is none).
- -cache Name of output cache file (default: config_cache.xml).
- -cachedir Name of directory where output cache file is written
- (default: CLM build directory).
- -cimeroot REQUIRED: Path to cime directory
- -clm_root Root directory of clm source code
- (default: directory above location of this script)
- -cppdefs A string of user specified CPP defines. Appended to
- Makefile defaults. e.g. -cppdefs '-DVAR1 -DVAR2'
- -crop Toggle for prognostic crop model. [on | off] (default is off)
- (can ONLY be turned on when BGC type is CN)
- -comp_intf Component interface to use (ESMF or MCT) (default MCT)
- -defaults Specify full path to a configuration file which will be used
- to supply defaults instead of the defaults in bld/config_files.
- This file is used to specify model configuration parameters only.
- Parameters relating to the build which are system dependent will
- be ignored.
- -help [or -h] Print usage to STDOUT.
- -noio Turn history output completely off (typically for testing).
- -phys Value of clm4_5, or clm5_0 (default is clm4_5)
- -silent [or -s] Turns on silent mode - only fatal messages issued.
- -sitespf_pt Setup for the given site specific single-point resolution.
- -snicar_frc Turn on SNICAR radiative forcing calculation. [on | off]
- (default is off)
- -usr_src [,[,[...]]]
- Directories containing user source code.
- -verbose [or -v] Turn on verbose echoing of settings made by configure.
- -version Echo the SVN tag name used to check out this CLM distribution.
-EOF
-}
-
-#-----------------------------------------------------------------------------------------------
-# Setting autoflush (an IO::Handle method) on STDOUT helps in debugging. It forces the test
-# descriptions to be printed to STDOUT before the error messages start.
-
-*STDOUT->autoflush();
-
-#-----------------------------------------------------------------------------------------------
-# Set the directory that contains the CLM configuration scripts. If the configure command was
-# issued using a relative or absolute path, that path is in $ProgDir. Otherwise assume the
-# command was issued from the current working directory.
-
-(my $ProgName = $0) =~ s!(.*)/!!; # name of this script
-my $ProgDir = $1; # name of directory containing this script -- may be a
- # relative or absolute path, or null if the script is in
- # the user's PATH
-my $cwd = getcwd(); # current working directory
-my $cfgdir; # absolute pathname of directory that contains this script
-if ($ProgDir) {
- $cfgdir = abs_path($ProgDir);
-} else {
- $cfgdir = $cwd;
-}
-
-#-----------------------------------------------------------------------------------------------
-# Save commandline
-my $commandline = "$cfgdir/configure @ARGV";
-
-#-----------------------------------------------------------------------------------------------
-# Parse command-line options.
-my %opts = (
- cache => "config_cache.xml",
- phys => "clm4_5",
- noio => undef,
- cimeroot => undef,
- clm_root => undef,
- );
-GetOptions(
- "bgc=s" => \$opts{'bgc'},
- "cache=s" => \$opts{'cache'},
- "cachedir=s" => \$opts{'cachedir'},
- "snicar_frc=s" => \$opts{'snicar_frc'},
- "cimeroot=s" => \$opts{'cimeroot'},
- "clm_root=s" => \$opts{'clm_root'},
- "cppdefs=s" => \$opts{'cppdefs'},
- "comp_intf=s" => \$opts{'comp_intf'},
- "defaults=s" => \$opts{'defaults'},
- "clm4me=s" => \$opts{'clm4me'},
- "h|help" => \$opts{'help'},
- "noio" => \$opts{'noio'},
- "phys=s" => \$opts{'phys'},
- "snicar_frc=s" => \$opts{'snicar_frc'},
- "s|silent" => \$opts{'silent'},
- "sitespf_pt=s" => \$opts{'sitespf_pt'},
- "usr_src=s" => \$opts{'usr_src'},
- "v|verbose" => \$opts{'verbose'},
- "version" => \$opts{'version'},
- "crop=s" => \$opts{'crop'},
-) or usage();
-
-# Give usage message.
-usage() if $opts{'help'};
-
-# Echo version info.
-version($cfgdir) if $opts{'version'};
-
-# Check for unparsed arguments
-if (@ARGV) {
- print "ERROR: unrecognized arguments: @ARGV\n";
- usage();
-}
-
-# Define 3 print levels:
-# 0 - only issue fatal error messages
-# 1 - only informs what files are created (default)
-# 2 - verbose
-my $print = 1;
-if ($opts{'silent'}) { $print = 0; }
-if ($opts{'verbose'}) { $print = 2; }
-my $eol = "\n";
-
-my %cfg = (); # build configuration
-
-#-----------------------------------------------------------------------------------------------
-# Make sure we can find required perl modules and configuration files.
-# Look for them in the directory that contains the configure script.
-
-my $cimeroot = $opts{'cimeroot'};
-if ( ! defined($cimeroot) ) {
- $cimeroot = "$cfgdir/../cime";
- if ( -d $cimeroot ) {
- } elsif ( -d "$cfgdir/../../../cime" ) {
- $cimeroot = "$cfgdir/../../../cime";
- } else {
- die <<"EOF";
-** Cannot find the root of the cime directory enter it using the -cimeroot option
- Did you run the checkout_externals scripts?
-EOF
- }
-}
-my $casecfgdir = "$cimeroot/scripts/Tools";
-my $perl5lib = "$cimeroot/utils/perl5lib/";
-
-# The Build::Config module provides utilities to store and manipulate the configuration.
-my $file = "$perl5lib/Build/Config.pm";
-(-f "$file") or die <<"EOF";
-** Cannot find perl module \"Build/Config.pm\" in path
- \"$file\" **
-EOF
-#-----------------------------------------------------------------------------------------------
-# Add $cfgdir/perl5lib to the list of paths that Perl searches for modules
-my @dirs = ( $cfgdir, "$perl5lib", $casecfgdir);
-unshift @INC, @dirs;
-require Build::Config;
-require config_files::clm_phys_vers;
-
-# Get the physics version
-my $phys = config_files::clm_phys_vers->new($opts{'phys'});
-
-# Check for the physics specific configuration definition file.
-my $phys_string = $phys->as_filename();
-
-my $config_def_file = "config_definition_$phys_string.xml";
-(-f "$cfgdir/config_files/$config_def_file") or die <<"EOF";
-** Cannot find configuration definition file \"$config_def_file\" in directory
- \"$cfgdir/config_files\" **
-EOF
-
-# The configuration defaults file modifies the generic defaults in the configuration
-# definition file. Note that the -defaults option has precedence over all other options.
-my $config_defaults_file;
-my $std_config_defaults_file = "$cfgdir/config_files/config_defaults.xml";
-if ($opts{'defaults'}) {
- $config_defaults_file = $opts{'defaults'};
-} else {
- $config_defaults_file = "$std_config_defaults_file";
-}
-(-f "$config_defaults_file") or die <<"EOF";
-** Cannot find configuration defaults file \"$config_defaults_file\" **
-EOF
-
-if ($print>=2) { print "Setting CLM configuration script directory to $cfgdir$eol"; }
-if ($print>=2) { print "Using configuration defaults file $config_defaults_file$eol"; }
-
-# Initialize the configuration. The $config_def_file provides the definition of a CLM
-# configuration, and the $config_defaults_file provides default values for a specific CLM
-# configuration. $cfg_ref is a reference to the new configuration object.
-my $cfg_ref = Build::Config->new("$cfgdir/config_files/$config_def_file",
- "$config_defaults_file");
-
-#-----------------------------------------------------------------------------------------------
-# CLM root directory.
-my $clm_root;
-
-if ( ! defined($opts{'clm_root'} ) ) {
- $clm_root = abs_path("$cfgdir/..");
-} else {
- $clm_root = $opts{'clm_root'};
-}
-
-if ( &is_valid_directory( "$clm_root/src", allowEnv=>0 ) ) {
- $cfg_ref->set('clm_root', $clm_root);
-} else {
- die <<"EOF";
-** Invalid CLM root directory: $clm_root
-**
-** The CLM root directory must contain the subdirectory /src/.
-** clm_root can be entered on the command line or it will be derived
-** from the location of this script.
-EOF
-}
-
-if ($print>=2) { print "Setting CLM root directory to $clm_root$eol"; }
-
-#-----------------------------------------------------------------------------------------------
-# CLM build directory is current directory
-my $clm_bld = `pwd`;
-chomp( $clm_bld );
-
-# Make sure directory is valid
-if ( ! &is_valid_directory( $clm_bld ) and ! mkdirp($clm_bld)) {
- die <<"EOF";
-** Could not create the specified CLM build directory: $clm_bld
-EOF
-}
-
-if ($print>=2) { print "Setting CLM build directory to $clm_bld$eol"; }
-
-#-----------------------------------------------------------------------------------------------
-# User source directories.
-my $usr_src = '';
-if (defined $opts{'usr_src'}) {
- my @dirs = split ',', $opts{'usr_src'};
- my @adirs;
- while ( my $dir = shift @dirs ) {
- if (&is_valid_directory( "$dir", allowEnv=>0 ) ) {
- push @adirs, $dir;
- } else {
- die "** User source directory does not exist: $dir\n";
- }
- }
- $usr_src = join ',', @adirs;
- $cfg_ref->set('usr_src', $usr_src);
-}
-
-if ($print>=2) { print "Setting user source directories to $usr_src$eol"; }
-
-#-----------------------------------------------------------------------------------------------
-# configuration cache directory and file.
-my $config_cache_dir;
-my $config_cache_file;
-if (defined $opts{'cachedir'}) {
- $config_cache_dir = abs_path($opts{'cachedir'});
-}
-else {
- $config_cache_dir = $clm_bld;
-}
-
-if (&is_valid_directory( $config_cache_dir, allowEnv=>0 ) or mkdirp($config_cache_dir)) {
- $config_cache_file = "$config_cache_dir/$opts{'cache'}";
-} else {
- die <<"EOF";
-** Could not create the specified directory for configuration cache file: $config_cache_dir
-EOF
-}
-
-if ($print>=2) { print "The configuration cache file will be created in $config_cache_file$eol"; }
-
-
-#-----------------------------------------------------------------------------------------------
-# physics
-
-$cfg_ref->set('phys', $opts{'phys'});
-my $phys_string = $phys->as_string();
-if ($print>=2) {
- if( defined($opts{'phys'}) ) {
- print "Using version $phys_string physics.$eol";
- }
-}
-
-#-----------------------------------------------------------------------------------------------
-# comp_intf option
-if (defined $opts{'comp_intf'}) {
- $cfg_ref->set('comp_intf', $opts{'comp_intf'});
-}
-my $comp_intf = $cfg_ref->get('comp_intf');
-if ($print>=2) { print "Using $comp_intf for comp_intf.$eol"; }
-
-
-#-----------------------------------------------------------------------------------------------
-# Makefile configuration #######################################################################
-#-----------------------------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------------------------
-# Name of CLM executable.
-my $clm_exe = "clm";
-
-if ($print>=2) { print "Name of CLM executable: $clm_exe.$eol"; }
-
-#-----------------------------------------------------------------------------------------------
-# For the CPP tokens, start with the defaults (from defaults file) and append the specifications
-# from the commandline. That way the user can override defaults since the commandline versions
-# occur last.
-my $usr_cppdefs = $cfg_ref->get('cppdefs');
-if (defined $opts{'cppdefs'}) {
- $usr_cppdefs .= " $opts{'cppdefs'}";
- print "Warning:: running with user defined cppdefs is NOT validated / " .
- "scientifically supported.$eol";
-}
-$cfg_ref->set('cppdefs', $usr_cppdefs);
-
-if ($usr_cppdefs and $print>=2) { print "Default and user CPP definitions: \'$usr_cppdefs\'$eol";}
-
-# The following CPP macro definitions are used to implement the compile-time options. They are
-# determined by the configuration parameters that have been set above. They will be appended to
-# the CPP definitions that were explicitly set in the defaults file or by the user on the commandline.
-my $cfg_cppdefs = '';
-if ($phys->as_long() >= $phys->as_long("clm4_5") ) {
- # clm4_5 cppdefs -- SHOULD NOT BE ANY!
- if ( $cfg_cppdefs ne '' ) {
- die <<"EOF";
-** CPP definitions should be empty for clm5_0 and is NOT **
-EOF
- }
-} elsif ($phys->as_long() == $phys->as_long("clm5_0") ) {
- # clm5_0 cppdefs -- SHOULD NOT BE ANY!
- if ( $cfg_cppdefs ne '' ) {
- die <<"EOF";
-** CPP definitions should be empty for clm5_0 and is NOT **
-EOF
- }
-} else {
- # this should NOT happen
- die <<"EOF";
-** Bad CLM physics version **
-EOF
-}
-# CPP defines to put on Makefile
-my $make_cppdefs = "$usr_cppdefs $cfg_cppdefs";
-
-if ($print>=2) { print "CPP definitions set by configure: \'$cfg_cppdefs\'$eol"; }
-
-#-----------------------------------------------------------------------------------------------
-# Write configuration files ####################################################################
-#-----------------------------------------------------------------------------------------------
-
-my $fp_filename = 'Filepath'; # name of output filepath file
-my $cpp_filename = 'CESM_cppdefs'; # name of output file for clm's cppdefs in cesm
-
-# Write the filepath file for cesm.
-write_filepath_cesmbld("$clm_bld/$fp_filename", $cfg_ref, $phys, allowEnv=>0 );
-if ($print>=2) { print "creating $clm_bld/$fp_filename\n"; }
-
-# Write the file for clm's cppdefs needed in cesm.
-write_cppdefs("$clm_bld/$cpp_filename", $make_cppdefs);
-if ($print>=2) { print "creating $clm_bld/$cpp_filename\n"; }
-
-# Write the configuration file.
-$cfg_ref->write_file($config_cache_file, $commandline);
-if ($print>=2) { print "creating $config_cache_file\n"; }
-
-#-----------------------------------------------------------------------------------------------
-# Done
-chdir( $cwd ) || die <<"EOF";
-** Trouble changing directory back to $cwd
-**
-EOF
-if ($print) { print "CLM configure done.\n"; }
-exit;
-
-#-----------------------------------------------------------------------------------------------
-# FINISHED ####################################################################################
-#-----------------------------------------------------------------------------------------------
-
-#-------------------------------------------------------------------------------
-
-sub write_filepath_cesmbld
-{
- my ($file, $cfg_ref, $phys, %opts) = @_;
- my $fh = new IO::File;
-
- $fh->open(">$file") or die "** can't open filepath file: $file\n";
-
- # configuration parameters used to determine paths
- my $usr_src = $cfg_ref->get('usr_src');
- my $clm_root = $cfg_ref->get('clm_root');
-
- # User specified source directories.
- if ($usr_src =~ /\S+/) {
- my @dirs = split ',', $usr_src;
- while ( my $dir = shift @dirs ) {
- print $fh "$dir\n";
- }
- } else {
- print $fh "../SourceMods/src.clm\n";
- }
-
- if ($phys->as_long() == $phys->as_long("clm4_0") ) {
- # source root
- my $srcdir = "$clm_root/src_clm40";
- if ( ! &is_valid_directory( "$srcdir", %opts ) ) { die "** source directory does not exist: $srcdir\n"; }
-
- # source directories under root
- my @dirs = ( "main", "biogeophys", "biogeochem" );
- foreach my $dir ( @dirs ) {
- if ( &is_valid_directory( "$srcdir/$dir", %opts ) ) {
- print $fh "$srcdir/$dir\n";
- } else {
- die "** source directory does not exist: $srcdir/$dir\n";
- }
- }
- } else {
- # source root
- my $srcdir = "$clm_root/src";
- if ( ! &is_valid_directory( "$srcdir", %opts ) ) { die "** source directory does not exist: $srcdir\n"; }
-
- # source directories under root
- my @dirs = ( "main",
- "biogeophys",
- "biogeochem",
- "soilbiogeochem",
- "init_interp",
- "utils",
- "cpl" );
-
- foreach my $dir ( @dirs ) {
- if ( &is_valid_directory( "$srcdir/$dir", %opts ) ) {
- print $fh "$srcdir/$dir\n";
- } else {
- die "** source directory does not exist: $srcdir/$dir\n";
- }
- }
- }
-
-
- $fh->close;
-}
-#-------------------------------------------------------------------------------
-
-sub write_cppdefs
-{
- my ($file, $make_cppdefs) = @_;
- my $fh = new IO::File;
-
- $fh->open(">$file") or die "** can't open cpp defs file: $file\n";
-
- print $fh "$make_cppdefs\n";
- $fh->close;
-}
-
-#-------------------------------------------------------------------------------
-
-sub mkdirp {
- my ($dir) = @_;
- my (@dirs) = split /\//, $dir;
- my (@subdirs, $path);
-
- # if $dir is absolute pathname then @dirs will start with ""
- if ($dirs[0] eq "") { push @subdirs, shift @dirs; }
-
- while ( @dirs ) { # check that each subdir exists and mkdir if it doesn't
- push @subdirs, shift @dirs;
- $path = join '/', @subdirs;
- unless (-d $path or mkdir($path, 0777)) { return 0; }
- }
- return 1;
-}
-
-#-------------------------------------------------------------------------------
-
-sub version {
-# The version is found in CLM's ChangeLog file.
-# $cfgdir is set by the configure script to the name of its directory.
-
- my ($cfgdir) = @_;
-
- my $logfile = "$cfgdir/../doc/ChangeLog";
-
- my $fh = IO::File->new($logfile, '<') or die "** can't open ChangeLog file: $logfile\n";
-
- while (my $line = <$fh>) {
-
- if ($line =~ /^Tag name:\s*[clm0-9_.-]*\s*[toin]*\s*([cesmclm0-9_.-]+)$/ ) {
- print "$1\n";
- exit;
- }
- }
-
-}
-
-#-------------------------------------------------------------------------------
-
-sub is_valid_directory {
-#
-# Validate that the input is a valid existing directory.
-#
- my ($dir, %opts) = @_;
- my $nm = "is_valid_directory";
-
- my $valid = 0;
- if ( -d $dir ) { $valid = 1; }
- return( $valid );
-
-}
-
diff --git a/bld/env_run.xml b/bld/env_run.xml
deleted file mode 100644
index 8bf59d09..00000000
--- a/bld/env_run.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/bld/namelist_files/LogMessages.pm b/bld/namelist_files/LogMessages.pm
deleted file mode 100755
index 77f0569b..00000000
--- a/bld/namelist_files/LogMessages.pm
+++ /dev/null
@@ -1,244 +0,0 @@
-package namelist_files::LogMessages;
-my $pkg_nm = 'namelist_files::LogMessages';
-#-----------------------------------------------------------------------------------------------
-#
-# SYNOPSIS
-#
-# require namelist_files::LogMessages;
-#
-# my %opts;
-# my $log = namelist_files::LogMessages->new("ProgName", \%opts);
-# $log->message("message to print");
-# $log->verbose_message("message to print only if verbose mode is on");
-# $log->warning("Warning message");
-# $log->exit_message("clean exit");
-# $log->fatal_error("die with fatal error");
-# $log->final_exit("Final message to send (and exit");
-#
-#
-# DESCRIPTION
-#
-# Handles log messages for perl. Sets up log messages according to verbose
-# or silent setting. It also handles warnings printing them, but on finalization
-# aborting unless ignore_warnings was set.
-#
-# COLLABORATORS: None
-#
-#-----------------------------------------------------------------------------------------------
-#
-# Date Author Modification
-# 10/06/2017 Erik Kluzek creation
-#
-#--------------------------------------------------------------------------------------------
-
-use strict;
-#use warnings;
-#use diagnostics;
-
-#-------------------------------------------------------------------------------
-
-sub new {
- my $class = shift;
- my $ProgName = shift;
- my %opts = %{shift()};
-
- my $nm = "$class\:\:new";
- my $self = {};
- bless($self, $class);
- $self->{'nwarns'} = 0;
- $self->{'verbosity'} = 1;
- $self->{'NO_EXIT'} = $opts{'NO_EXIT'};
- $self->{'ProgName'} = $ProgName;
- $self->{'ignore_warnings'} = $opts{'ignore_warnings'};
- $self->__set_print_level( \%opts );
- return( $self );
-}
-
-
-#-------------------------------------------------------------------------------
-
-sub __set_print_level {
- my $self = shift;
- # Define print levels:
- # 0 - only issue fatal error messages
- # 1 - only informs what files are created (default)
- # 2 - verbose
- my %opts = %{shift()};
-
- if ( $opts{'silent'} && $opts{'verbose'} ) {
- $self->fatal_error( "Can not set both the -silent and the -verbose options -- set one or the other" );
- }
- my $verbosity = 1;
- if ($opts{'silent'}) { $verbosity = 0; }
- if ($opts{'verbose'}) { $verbosity = 2; }
- $self->{'verbosity'} = $verbosity;
- $self->{'print_verbose'} = 2;
-}
-
-#-------------------------------------------------------------------------------
-
-sub message {
- my $self = shift;
- my ($message) = @_;
- if ($self->{'verbosity'} > 0) {
- print "$message\n";
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub verbose_message {
- my $self = shift;
-
- my ($message) = @_;
- if ($self->{'verbosity'} >= $self->{'print_verbose'}) {
- print "$message\n";
- }
-}
-#-------------------------------------------------------------------------------
-
-sub nwarns {
- my $self = shift;
-
- return( $self->{'nwarns'} );
-}
-
-#-------------------------------------------------------------------------------
-
-sub final_exit {
- my $self = shift;
- my ($message) = @_;
- if ( $self->{'nwarns'} > 0 ) {
- $self->message( "\n\nYou ran with the -ignore_warnings options and allowed $self->{'nwarns'} to go past\n" );
- }
- $self->verbose_message( $message );
- if ( $self->{'NO_EXIT'} ) {
- die
- } else {
- exit;
- }
-}
-
-#-------------------------------------------------------------------------------
-# Some simple subroutines to do a clean exit, print warning, or a fatal error
-
-sub exit_message {
- my $self = shift;
- my ($message) = @_;
- print "$self->{ProgName} : $message\n";
- if ( $self->{'NO_EXIT'} ) {
- die
- } else {
- exit;
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub warning {
- my $self = shift;
- my $message = shift;
-
- $self->{'nwarns'} = $self->{'nwarns'} + 1;
- my $func_name = (caller(1))[3];
- if ( $self->{'ignore_warnings'} ) {
- print "Warning : $self->{ProgName}::${func_name}() : $message\n\n";
- } else {
- die "Warning : $self->{ProgName}::${func_name}() : $message\n" .
- " -- Add -ignore_warnings option to CLM_BLDNML_OPTS to ignore this warning\n\n";
- }
-}
-
-#-------------------------------------------------------------------------------
-
-sub fatal_error {
- my $self = shift;
- my ($message) = @_;
- my $func_name = (caller(1))[3];
- die "ERROR : $self->{ProgName}::${func_name}() : $message\n";
-}
-
-#-------------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------------------------
-# Unit testing of above
-#-----------------------------------------------------------------------------------------------
-if ( ! defined(caller) && $#ARGV == -1 ) {
- package LogMessage_unit_tester;
-
- require Test::More;
- Test::More->import( );
-
- plan( tests=>11 );
-
- sub testit {
- print "unit tester\n";
- my %opts;
- my $message;
-
- # Standard verbose level, test all methods
- $opts{'NO_EXIT'} = 1;
- my $log = namelist_files::LogMessages->new("ProgName", \%opts);
- isa_ok($log, "namelist_files::LogMessages", "Created LogMessages object");
- $log->message("message to print");
- $log->verbose_message("YOU SHOULD NOT SEE THIS MESSAGE BECAUSE IT IS VERBOSE AND VERBOSE NOT ON");
- $message = "Warning message";
- is ( $log->nwarns(), 0, "Make sure have zero warnings" );
- eval{ $log->warning($message); };
- like( $@, qr/$message/, "check that a warning dies without ignore_warnings option" );
- is ( $log->nwarns(), 1, "Make sure have one warning" );
- $message = "die with fatal error";
- eval{ $log->fatal_error($message); };
- like( $@, qr/$message/, "check that a fatal_error dies" );
- $message = "exit with exit message";
- eval{ $log->exit_message($message); };
- like( $@, qr/Died/, "check that a exit_message exits" );
- $message = "Final message to send";
- eval{ $log->final_exit($message); };
- like( $@, qr/Died/, "check that a final exits" );
-
- # Test ignore_warnings option and verbose mode
- $opts{'ignore_warnings'} = 1;
- $opts{'verbose'} = 1;
- $opts{'NO_EXIT'} = 1;
- $log = namelist_files::LogMessages->new("ProgName", \%opts);
- isa_ok($log, "namelist_files::LogMessages", "Created LogMessages object");
- $log->verbose_message("message to print only if verbose mode is on");
- $log->warning("Warning message");
- $log->warning("Warning message2");
- $log->warning("Warning message3");
- $log->warning("Warning message4");
- $log->warning("Warning message5");
- is ( $log->nwarns(), 5, "Make sure have five warnings" );
- eval{ $log->final_exit($message); };
- print "content: $@\n";
- like( $@, qr/Died/, "check that a final_exit with warning exits" );
- # silent mode
- $opts{'ignore_warnings'} = 0;
- $opts{'verbose'} = 0;
- $opts{'silent'} = 1;
- $opts{'NO_EXIT'} = 1;
- $log = namelist_files::LogMessages->new("ProgName", \%opts);
- $log->message("YOU SHOULD NOT SEE THIS MESSAGE BECAUSE SILENT MODE IS ON");
- $log->verbose_message("YOU SHOULD NOT SEE THIS VERBOSE MESSAGE BECAUSE SILENT MODE IS ON");
- # Should die with error if both silent and verbose mode is on
- $opts{'ignore_warnings'} = 0;
- $opts{'verbose'} = 1;
- $opts{'silent'} = 1;
- $opts{'NO_EXIT'} = 1;
- eval{ $log = namelist_files::LogMessages->new("ProgName", \%opts); };
- print "content: $@\n";
- like( $@, qr/ERROR : /, "check that died if both verbose and silent mode is on" );
- print "\nSuccessfully ran all tests\n";
- }
-}
-
-#-----------------------------------------------------------------------------------------------
-# Determine if you should run the unit test or if this is being called from a require statement
-#-----------------------------------------------------------------------------------------------
-
-if ( defined(caller) ) {
- 1 # to make use or require happy
-} elsif ( $#ARGV == -1 ) {
- &LogMessage_unit_tester::testit();
-}
diff --git a/bld/namelist_files/namelist_defaults.xsl b/bld/namelist_files/namelist_defaults.xsl
deleted file mode 100644
index 3085d98f..00000000
--- a/bld/namelist_files/namelist_defaults.xsl
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
-
-
-
- CLM Namelist Defaults
-
-
-
Default Values for Namelist Variables
-
Included in the table are the following pieces of information:
-
Table headers include:
-
-
Name of variable
-
Horizontal grid resolution
-
Land ocean mask type
-
Simulation year
-
Simulation year range (for transient datasets)
-
-
Miscellaneous items include:
-
-
Biogeochemistry (BGC) type (none, CN)
-
Initial condition date (ymd - year month day)
-
Initial condition time of day (tod) (sec)
-
Maximum number of Plant Function Types (maxpft)
-
Site specific point name (sitespf_pt)
-
Crop model (crop)
-
Data model forcing source (forcing)
-
Representative concentration pathway for future scenarios (rcp)
We list all of the relevant namelist variables for CLM I cases. This includes
- CLM Namelist items as well as CLM build-namelist settings and namelist settings
- for CLM offline tools.
-
-
Definition of CLM namelist variables
-
Note, these all would go into the user_nl_clm file
- before configure):
-
Included in the table are the following pieces of information:
-
-
Variable name.
-
Variable type (char, integer,
- real, or logical). The type
- char has the length appended
- following an asterisk, e.g., char*256. Variables that are
- arrays have their dimension specifier appended inside parentheses. For
- example char*1(6) denotes a array of six
- char*1 values.
-
-
Variable description (includes information on defaults).
-
Valid values (if restricted).
-
-
-
-
CLM Namelist Physics Options
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
-
CLM Namelist Datasets
-
-
Name
-
Type
-
Description
-
-
-
-
Valid values
-
-
-
-
-
-
CLM Namelist History output settings
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
-
CLM Namelist Restart settings
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
-
CLM Namelist Performance Tuning
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
-
-
-
-
-
Command Line Options to CLM Build-namelist
-
Variables that are entered as options to build-namelist (but NOT used by
- namelists in code). Most of these are options that could be added to
- CLM_BLDNML_OPTS. Included in the table are the following pieces
- of information:
-
-
Variable name.
-
Type.
-
Valid values.
-
Variable description.
-
-
-
-
CLM Namelist Default Settings
-
-
Name
-
Type
-
Description
-
-
-
Valid values, if restricted at all
-
-
-
-
-
-
-
-
-
Command Line Options to CLM Build-namelist
-
Variables that are entered as options to build-namelist (but NOT used by
- namelists in code). Most of these are options that could be added to
- CLM_BLDNML_OPTS. Included in the table are the following pieces
- of information:
-
-
Variable name.
-
Type.
-
Valid values.
-
Variable description.
-
-
-
-
CLM Namelist Default Settings
-
-
Name
-
Type
-
Description
-
-
-
Valid values, if restricted at all
-
-
-
-
-
-
-
-
-
Namelist items for CLM Tools
-
These are namelist items that appear in the CLM Tools under components/clm/tools.
-
-
-
CLM mksurfdata
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
CLM mkgriddata
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
CLM mkmapdata
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
CLM mkgriddata
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
Miscellaneous CLM tools
-
-
Name
-
Type
-
Description
-
-
-
Valid values
-
-
-
-
-
-
-
Namelist items for Driver Dry Deposition
-
-
Driver Dry-Deposition Namelist Options
-
-
Name
-
Type
-
Description
-
-
-
Valid values, if restricted at all
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Valid Values:
-
-
-
-
-
diff --git a/bld/namelist_files/namelist_definition_clm4_5.xml b/bld/namelist_files/namelist_definition_clm4_5.xml
deleted file mode 100644
index e4c9ada8..00000000
--- a/bld/namelist_files/namelist_definition_clm4_5.xml
+++ /dev/null
@@ -1,388 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-If use_init_interp is set to .true., interpinic will be called to interpolate
-the file given by finidat, creating the output file specified by finidat_interp_dest.
-
-
-
-Full pathname of initial conditions file. If blank CLM will startup from
-arbitrary initial conditions.
-
-
-
-If set to .true., interpinic will be called to interpolate the file given by finidat,
-creating the output file specified by finidat_interp_dest.
-
-This requires that finidat be non-blank.
-
-
-
-Full pathname of master restart file for a branch run. (only used if RUN_TYPE=branch)
-(Set with RUN_REFCASE and RUN_REFDATE)
-
-
-
-Full pathname of land fraction data file.
-
-
-
-Clumps per processor.
-
-
-
-Time step (seconds)
-
-
-
-Override the start type from the driver: it can only be
-set to 3 meaning branch.
-
-
-
-Full pathname of surface data file.
-
-
-
-Full pathname of MML surface data forcing file.
-
-
-
-Per file averaging flag.
- 'A' (average over history period)
- 'I' (instantaneous)
- 'X' (maximum over history period)
- 'M' (minimum over history period)
-
-
-
-Averaging type of output for 1D vector output (when hist_dov2xy is false).
- GRID means average all land-units up to the grid-point level
- LAND means average all columns up to the land-unit level
- COLS means average all PFT's up to the column level
- PFTS means report everything on native PFT level
-
-
-
-If TRUE, implies output data on a 2D latitude/longitude grid. False means
-output in 1D vector format. One setting per history tape series.
-
-
-
-If TRUE, indicates do NOT output any default history fields (requires you to use
-hist_fincl* to set the exact output fields to use)..
-
-
-
-Fields to exclude from history tape series 1.
-
-
-
-Fields to exclude from history tape series 2.
-
-
-
-Fields to exclude from history tape series 3.
-
-
-
-Fields to exclude from history tape series 4.
-
-
-
-Fields to exclude from history tape series 5.
-
-
-
-Fields to exclude from history tape series 6.
-
-
-
-Fields to add to history tape series 1.
-
-
-
-Fields to add to history tape series 2.
-
-
-
-Fields to add to history tape series 3.
-
-
-
-Fields to add to history tape series 4.
-
-
-
-Fields to add to history tape series 5.
-
-
-
-Fields to add to history tape series 6.
-
-
-
-Per tape series maximum number of time samples.
-
-
-
-Per tape series history file density (i.e. output precision)
- 1=double precision
- 2=single precision
-Default: 2,2,2,2,2,2
-
-
-
-Per tape series history write frequency.
- positive means in time steps
- 0=monthly
- negative means hours
-(i.e. 5 means every 24 time-steps and -24 means every day
-Default: 0,-24,-24,-24,-24,-24
-
-
-
-number of segments per clump for decomposition
-Default: 20
-
-
-
-Perturbation limit when doing error growth test
-
-
-
-If FALSE, don't write any restart files.
-
-
-
-If TRUE, write diagnostic of global radiative temperature written to CLM log file.
-
-
-
-
-
-
-
-Toggle to turn all history output completely OFF (possibly used for testing)
-
-
-
-
-
-
-
-datm input directory
-
-
-datm output directory
-
-
-Datm logfile name
-
-
-
-
-
-
-
-Mapping file to go from one resolution/land-mask to another resolution/land-mask
-
-
-
-Land mask description for mksurfdata input files
-
-
-
-Horizontal grid resolutions for mksurfdata input files
-
-
-
-
-
-
-
-
-Check that the resolution and land-mask is valid before continuing.
-
-
-
-Add a note to the output namelist about the options given to build-namelist
-
-
-
-CLM run type.
- 'default' use the default type of clm_start type for this configuration
- 'cold' is a run from arbitrary initial conditions
- 'arb_ic' is a run using initial conditions if provided, OR arbitrary initial conditions if no files can be found
- 'startup' is an initial run with initial conditions provided.
- 'continue' is a restart run.
- 'branch' is a restart run in which properties of the output history files may be changed.
-
-
-
-Horizontal resolutions
-Note: 0.1x0.1, 0.25x0.25, 0.5x0.5, 5x5min, 10x10min, 3x3min and 0.33x0.33 are only used for CLM tools
-
-
-
-Representative concentration pathway for future scenarios [radiative forcing at peak or 2100 in W/m^2]
--999.9 means do NOT use a future scenario, just use historical data.
-
-
-
-Land mask description
-
-
-
-General configuration of model version and atmospheric forcing to tune the model to run under.
-This sets the model to run with constants and initial conditions that were set to run well under
-the configuration of model version and atmospheric forcing. To run well constants would need to be changed
-to run with a different type of atmospheric forcing.
-
-
-
-Year to simulate and to provide datasets for (such as surface datasets, initial conditions, aerosol-deposition, Nitrogen deposition rates etc.)
-A sim_year of 1000 corresponds to data used for testing only, NOT corresponding to any real datasets.
-A sim_year greater than 2005 corresponds to rcp scenario data
-Most years are only used for clm_tools and there aren't CLM datasets that correspond to them.
-CLM datasets exist for years: 1000 (for testing), 1850, and 2000
-
-
-
-Range of years to simulate transitory datasets for (such as dynamic: land-use datasets, aerosol-deposition, Nitrogen deposition rates etc.)
-Constant means simulation will be held at a constant year given in sim_year.
-A sim_year_range of 1000-1002 or 1000-1004 corresponds to data used for testing only, NOT corresponding to any real datasets.
-A sim_year_range that goes beyond 2005 corresponds to historical data until 2005 and then scenario data beyond that point.
-
-
-
-Namelist entries to demand be provided on the namelist.
-
-
-
-Description of the use case selected.
-
-
-
-Attributes to use when looking for an initial condition file (finidat) if interpolation is turned on (use_init_interp is .true.)
-
-
-
-How close in years to use when looking for an initial condition file (finidat) if interpolation is turned on (use_init_interp is .true.)
-
-
-
-Simulation years you can look for in initial condition files (finidat) if interpolation is turned on (use_init_interp is .true.)
-
-
-
-
-
-
-
-If TRUE (which is the default), check consistency between year on the finidat file
-and the current model year. This check is only done for a transient run.
-
-
-
-If TRUE (which is the default), check consistency between pct_pft on the finidat file
-and pct_pft read from the surface dataset. This check is only done for a NON-transient run.
-
-
-
-
-
-
-
diff --git a/bld/namelist_files/namelist_definition_drv.xml b/bld/namelist_files/namelist_definition_drv.xml
deleted file mode 100644
index 4c3c4004..00000000
--- a/bld/namelist_files/namelist_definition_drv.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- 1.0
-
-
-
-
-
-
-
-
diff --git a/bld/namelist_files/use_cases/1850_control.xml b/bld/namelist_files/use_cases/1850_control.xml
deleted file mode 100644
index 786b9ae9..00000000
--- a/bld/namelist_files/use_cases/1850_control.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-Conditions to simulate 1850 land-use
-
-1850
-
-constant
-
-
diff --git a/bld/namelist_files/use_cases/2000_control.xml b/bld/namelist_files/use_cases/2000_control.xml
deleted file mode 100644
index c339f2d0..00000000
--- a/bld/namelist_files/use_cases/2000_control.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-Conditions to simulate 2000 land-use
-
-2000
-
-constant
-
-
diff --git a/cime_config/buildlib b/cime_config/buildlib
index 43016826..598f5dc8 100755
--- a/cime_config/buildlib
+++ b/cime_config/buildlib
@@ -1,7 +1,7 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""
-build clm library
+build slim ibrary
"""
import sys, os, time, filecmp, shutil, imp
@@ -21,7 +21,7 @@ logger = logging.getLogger(__name__)
###############################################################################
def _main_func():
-###############################################################################
+ ###############################################################################
caseroot, libroot, bldroot = parse_input(sys.argv)
@@ -34,54 +34,56 @@ def _main_func():
mach = case.get_value("MACH")
nthrds = case.get_value("LND_NTHRDS")
- clm_config_opts = case.get_value("CLM_CONFIG_OPTS")
- if "clm4_5" in clm_config_opts:
- clm_phys = "clm4_5"
- elif "clm5_0" in clm_config_opts:
- clm_phys = "clm5_0"
- else:
- expect(False, "CLM_CONFIG_OPTS must support either clm4_5 or clm5_0 physics")
-
- if ( nthrds > 1 ):
- expect(False, "LND_NTHRDS must be 1 as threading isn't implemented (see issue #14)" )
-
- #-------------------------------------------------------
- # create Filepath file for clm4_5 or clm5_0
- #-------------------------------------------------------
- filepath_file = os.path.join(bldroot,"Filepath")
+ if nthrds > 1:
+ expect(
+ False,
+ "LND_NTHRDS must be 1 as threading isn't implemented (see issue #14)",
+ )
+
+ # -------------------------------------------------------
+ # create Filepath file
+ # -------------------------------------------------------
+ filepath_file = os.path.join(bldroot, "Filepath")
if not os.path.isfile(filepath_file):
caseroot = case.get_value("CASEROOT")
- paths = [os.path.join(caseroot,"SourceMods","src.clm"),
- os.path.join(lnd_root,"src","main"),
- os.path.join(lnd_root,"src","biogeophys"),
- os.path.join(lnd_root,"src","biogeochem"),
- os.path.join(lnd_root,"src","soilbiogeochem"),
- os.path.join(lnd_root,"src","init_interp"),
- os.path.join(lnd_root,"src","utils"),
- os.path.join(lnd_root,"src","cpl")]
+ paths = [
+ os.path.join(caseroot, "SourceMods", "src.slim"),
+ os.path.join(lnd_root, "src", "main"),
+ os.path.join(lnd_root, "src", "init_interp"),
+ os.path.join(lnd_root, "src", "utils"),
+ os.path.join(lnd_root, "src", "cpl"),
+ ]
+ # Paths needed to build the current system, but won't be long term
+ paths.append(os.path.join(lnd_root, "src", "biogeophys"))
+ paths.append(os.path.join(lnd_root, "src", "biogeochem"))
+ paths.append(os.path.join(lnd_root, "src", "soilbiogeochem"))
with open(filepath_file, "w") as filepath:
filepath.write("\n".join(paths))
filepath.write("\n")
-
- #-------------------------------------------------------
+
+ # -------------------------------------------------------
# create the library in libroot
- #-------------------------------------------------------
+ # -------------------------------------------------------
- clm_config_opts = case.get_value("CLM_CONFIG_OPTS")
- complib = os.path.join(libroot,"libclm.a")
+ complib = os.path.join(libroot, "liblnd.a")
makefile = os.path.join(casetools, "Makefile")
- macfile = os.path.join(caseroot, "Macros.%s" % mach)
+ macfile = os.path.join(caseroot, "Macros.%s" % mach)
- cmd = "%s complib -j %d MODEL=clm COMPLIB=%s -f %s MACFILE=%s " \
- % (gmake, gmake_j, complib, makefile, macfile )
+ cmd = "%s complib -j %d MODEL=slim COMPLIB=%s -f %s MACFILE=%s " % (
+ gmake,
+ gmake_j,
+ complib,
+ makefile,
+ macfile,
+ )
rc, out, err = run_cmd(cmd)
- logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n"%(cmd,out,err))
+ logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n" % (cmd, out, err))
expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))
+
###############################################################################
if __name__ == "__main__":
_main_func()
-
diff --git a/cime_config/buildnml b/cime_config/buildnml
index 1548aa35..9c2a0c3f 100755
--- a/cime_config/buildnml
+++ b/cime_config/buildnml
@@ -1,231 +1,33 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""
-CLM namelist creator
+SLIM namelist creator executable
"""
-import sys, os, time, shutil, re, imp, filecmp
+import sys, os
-_CIMEROOT = os.environ.get("CIMEROOT")
-if _CIMEROOT is None:
- raise SystemExit("ERROR: must set CIMEROOT environment variable")
+_SLIM_PYTHON = os.path.normpath(
+ os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, "python")
+)
+sys.path.insert(1, _SLIM_PYTHON)
-_LIBDIR = os.path.join(_CIMEROOT, "scripts", "Tools")
-sys.path.append(_LIBDIR)
+from slim import add_cime_to_path
+from slim import add_slim_cime_py_to_path
+from slim.slim_logging import setup_logging
-from standard_script_setup import *
-from CIME.buildnml import create_namelist_infile, parse_input
-from CIME.case import Case
-from CIME.utils import expect, run_cmd
-
-logger = logging.getLogger(__name__)
-
-_config_cache_template = """
-
-
-
-Specifies clm physics
-
-"""
-
-###############################################################################
-def buildnml(case, caseroot, compname):
-###############################################################################
- """Build the clm namelist """
-
- # Build the component namelist
- if compname != "clm":
- raise AttributeError
-
- lnd_root = case.get_value("COMP_ROOT_DIR_LND")
- din_loc_root = case.get_value("DIN_LOC_ROOT")
- clm_namelist_opts = case.get_value("CLM_NAMELIST_OPTS")
- clm_bldnml_opts = case.get_value("CLM_BLDNML_OPTS")
- clm_nml_use_case = case.get_value("CLM_NML_USE_CASE")
- clm_force_coldstart = case.get_value("CLM_FORCE_COLDSTART")
- comp_glc = case.get_value("COMP_GLC")
- comp_atm = case.get_value("COMP_ATM")
- lnd_grid = case.get_value("LND_GRID")
- lnd_ncpl = case.get_value("LND_NCPL")
- lnd_domain_path = case.get_value("LND_DOMAIN_PATH")
- lnd_domain_file = case.get_value("LND_DOMAIN_FILE")
- ninst_lnd = case.get_value("NINST_LND")
- rundir = case.get_value("RUNDIR")
- run_type = case.get_value("RUN_TYPE")
- run_startdate = case.get_value("RUN_STARTDATE")
- run_refcase = case.get_value("RUN_REFCASE")
- run_refdate = case.get_value("RUN_REFDATE")
- run_reftod = case.get_value("RUN_REFTOD")
- mask = case.get_value("MASK_GRID")
-
- # -----------------------------------------------------
- # Clear out old data
- # -----------------------------------------------------
-
- input_data_list = os.path.join(caseroot,"Buildconf","clm.input_data_list")
- if os.path.exists(input_data_list):
- os.remove(input_data_list)
-
- # -----------------------------------------------------
- # Set clmconf
- # -----------------------------------------------------
-
- clmconf = os.path.join(caseroot, "Buildconf", "clmconf")
- if not os.path.isdir(clmconf):
- os.makedirs(clmconf)
-
- # -----------------------------------------------------
- # Create config_cache.xml file
- # -----------------------------------------------------
-
- # Note that build-namelist utilizes the contents of the config_cache.xml file in
- # the namelist_defaults.xml file to obtain namelist variables
-
- clm_config_opts = case.get_value("CLM_CONFIG_OPTS")
- if "clm4_5" in clm_config_opts:
- clm_phys = "clm4_5"
- elif "clm5_0" in clm_config_opts:
- clm_phys = "clm5_0"
- else:
- expect(False, "CLM_CONFIG_OPTS must support either clm4_5 or clm5_0 physics")
-
- config_cache_text = _config_cache_template.format(clm_phys=clm_phys)
- config_cache_path = os.path.join(caseroot, "Buildconf", "clmconf", "config_cache.xml")
- with open(config_cache_path, 'w') as config_cache_file:
- config_cache_file.write(config_cache_text)
-
- # -----------------------------------------------------
- # Determine input arguments into build-namelist
- # -----------------------------------------------------
-
- startfile_type = "finidat"
- start_type = "default"
- if run_type == "hybrid":
- start_type = "startup"
- elif run_type != "startup":
- start_type = run_type
-
- if run_type == "branch":
- startfile_type = "nrevsn"
- if clm_force_coldstart == "on":
- clm_force_coldstart = "off"
- logger.warning( "WARNING: You've turned on CLM_FORCE_COLDSTART for a branch run_type, which is a contradiction, the coldstart will be ignored\n" +
- " turn off CLM_FORCE_COLDSTART, or set RUN_TYPE=hybrid to get rid of this warning"
- )
-
- if (clm_force_coldstart == "on"):
- logger.warning( "WARNING: CLM is starting up from a cold state" )
- start_type = "cold"
-
- if lnd_grid == 'T31':
- lnd_grid = '48x96'
- if lnd_grid == 'T42':
- lnd_grid = '64x128'
- if lnd_grid == 'T85':
- lnd_grid = '128x256'
- if lnd_grid == 'T341':
- lnd_grid = '512x1024'
-
- if clm_nml_use_case != "UNSET":
- usecase = "-use_case %s" %clm_nml_use_case
- else:
- usecase = ""
-
- if ( (mask != "null") and (mask != "UNSET") ):
- gridmask = "-mask %s" %mask
- else:
- gridmask = ""
-
- start_ymd = run_startdate.replace('-','')
-
- if ('-01-01' in run_startdate) or ('-09-01' in run_startdate):
- ignore = "-ignore_ic_year"
- else:
- ignore = "-ignore_ic_date"
-
- infile = os.path.join(clmconf, "namelist")
-
- inputdata_file = os.path.join(caseroot,"Buildconf","clm.input_data_list")
-
- lndfrac_file = os.path.join(lnd_domain_path,lnd_domain_file)
-
- config_cache_file = os.path.join(caseroot,"Buildconf","clmconf","config_cache.xml")
-
- # -----------------------------------------------------
- # loop over instances
- # -----------------------------------------------------
-
- ninst = int(ninst_lnd)
- for inst_counter in range(1, ninst+1):
-
- # determine instance string
- inst_string = ""
- if ninst > 1:
- inst_string = '_' + '%04d' % inst_counter
-
- # If multi-instance case does not have restart file, use
- # single-case restart for each instance
- rpointer = "rpointer.lnd"
- if (os.path.isfile(os.path.join(rundir,rpointer)) and
- (not os.path.isfile(os.path.join(rundir,rpointer + inst_string)))):
- shutil.copy(os.path.join(rundir, rpointer),
- os.path.join(rundir, rpointer + inst_string))
-
- # -----------------------------------------------------
- # call build-namelist
- # -----------------------------------------------------
-
- if run_type == "hybrid" or run_type == "branch":
- clm_startfile = "%s.clm2%s.r.%s-%s.nc"%(run_refcase,inst_string,run_refdate,run_reftod)
- if not os.path.exists(os.path.join(rundir, clm_startfile)):
- clm_startfile = "%s.clm2.r.%s-%s.nc"%(run_refcase,run_refdate,run_reftod)
- clm_icfile = "%s = \'%s\'"%(startfile_type, clm_startfile)
- else:
- clm_icfile = ""
-
- infile_lines = []
- infile_lines.append(clm_icfile)
-
- user_nl_file = os.path.join(caseroot, "user_nl_clm" + inst_string)
- namelist_infile = os.path.join(clmconf, "namelist")
-
- create_namelist_infile(case, user_nl_file, namelist_infile, "\n".join(infile_lines))
-
- cmd = os.path.join(lnd_root,"bld","build-namelist")
-
- command = ("%s -cimeroot %s -infile %s -csmdata %s -inputdata %s %s -namelist \"&clm_inparm start_ymd=%s/ \" "
- "%s %s -res %s -clm_start_type %s -envxml_dir %s -l_ncpl %s "
- "-lnd_frac %s -config %s "
- "%s %s"
- %(cmd, _CIMEROOT, infile, din_loc_root, inputdata_file, ignore, start_ymd, clm_namelist_opts,
- usecase, lnd_grid, start_type, caseroot, lnd_ncpl,
- lndfrac_file, config_cache_file,
- clm_bldnml_opts, gridmask))
-
- rc, out, err = run_cmd(command, from_dir=clmconf)
- expect(rc==0,"Command %s failed rc=%d\nout=%s\nerr=%s"%(cmd,rc,out,err))
- if out is not None:
- logger.debug(" %s"%out)
- if err is not None:
- logger.debug(" %s"%err)
-
- # -----------------------------------------------------
- # copy resolved namelist to rundir
- # -----------------------------------------------------
-
- if os.path.isdir(rundir):
- file1 = os.path.join(clmconf, "lnd_in")
- file2 = os.path.join(rundir, "lnd_in")
- if ninst > 1:
- file2 += inst_string
- logger.debug("CLM namelist copy: file1 %s file2 %s " %(file1, file2))
- shutil.copy(file1,file2)
+from standard_script_setup import *
+from CIME.buildnml import parse_input
+from CIME.case import Case
+from slim_cime_py import buildnml
###############################################################################
def _main_func():
caseroot = parse_input(sys.argv)
+ level = logging.WARNING
+ setup_logging(level)
with Case(caseroot) as case:
- buildnml(case, caseroot, "clm")
+ buildnml(case, caseroot, "slim")
+
if __name__ == "__main__":
_main_func()
diff --git a/cime_config/buildnml_test/env_archive.xml b/cime_config/buildnml_test/env_archive.xml
new file mode 100644
index 00000000..21e8595f
--- /dev/null
+++ b/cime_config/buildnml_test/env_archive.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/env_batch.xml b/cime_config/buildnml_test/env_batch.xml
new file mode 100644
index 00000000..d9bc277d
--- /dev/null
+++ b/cime_config/buildnml_test/env_batch.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+ char
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/env_build.xml b/cime_config/buildnml_test/env_build.xml
new file mode 100644
index 00000000..3464158b
--- /dev/null
+++ b/cime_config/buildnml_test/env_build.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+ char
+ Land (lnd) grid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/env_case.xml b/cime_config/buildnml_test/env_case.xml
new file mode 100644
index 00000000..f6f4ef9d
--- /dev/null
+++ b/cime_config/buildnml_test/env_case.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+ char
+ file containing specification of component specific definitions and values(for documentation only - DO NOT EDIT)
+ $CIMEROOT/config/xml_schemas/entry_id.xsd
+ $CIMEROOT/config/xml_schemas/entry_id_version3.xsd
+
+
+
+ char
+ Component set long name (for documentation only - DO NOT EDIT)
+
+
+
+ char
+ Root directory of the case land model component
+ $CIMEROOT/config/xml_schemas/config_compsets.xsd
+
+
+
+ char
+ slim
+ Name of land component
+
+
+
+ char
+ full pathname of source root directory
+
+
+
+ char
+ case name
+
+
+
+ char
+ model system name
+
+
+
+ char
+ full pathname of case
+
+
+
+ char
+ Land grid
+
+
+
+
diff --git a/cime_config/buildnml_test/env_mach_pes.xml b/cime_config/buildnml_test/env_mach_pes.xml
new file mode 100644
index 00000000..5697d09f
--- /dev/null
+++ b/cime_config/buildnml_test/env_mach_pes.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+ integer
+
+
+
+ integer
+
+
+
+ integer
+
+
+
+ integer
+
+
+
+ integer
+ Force this exact number of spare nodes to be allocated
+
+
+
+ integer
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+ integer
+
+ -2
+ -2
+ -2
+ -2
+
+
+
+
+
+ integer
+
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+ integer
+
+ 1
+ 1
+ 1
+
+
+
+
+
+ integer
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/env_mach_specific.xml b/cime_config/buildnml_test/env_mach_specific.xml
new file mode 100644
index 00000000..c38d868a
--- /dev/null
+++ b/cime_config/buildnml_test/env_mach_specific.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+ char
+ executable name
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/env_run.xml b/cime_config/buildnml_test/env_run.xml
new file mode 100644
index 00000000..858cfc74
--- /dev/null
+++ b/cime_config/buildnml_test/env_run.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/env_workflow.xml b/cime_config/buildnml_test/env_workflow.xml
new file mode 100644
index 00000000..69c9aa80
--- /dev/null
+++ b/cime_config/buildnml_test/env_workflow.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/buildnml_test/run_buildnml b/cime_config/buildnml_test/run_buildnml
new file mode 100755
index 00000000..2ad7a4a0
--- /dev/null
+++ b/cime_config/buildnml_test/run_buildnml
@@ -0,0 +1,4 @@
+#!/bin/bash
+rm Buildconf/slimconf/lnd_in
+env CIMEROOT=`pwd`/../../cime ../buildnml `pwd` --verbose --debug
+cat Buildconf/slimconf/lnd_in
diff --git a/cime_config/user_nl_clm b/cime_config/buildnml_test/user_nl_slim
similarity index 90%
rename from cime_config/user_nl_clm
rename to cime_config/buildnml_test/user_nl_slim
index 1df94b9d..43893a6e 100644
--- a/cime_config/user_nl_clm
+++ b/cime_config/buildnml_test/user_nl_slim
@@ -7,7 +7,7 @@
! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options
! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases
! (includes $inst_string for multi-ensemble cases)
-! or with CLM_FORCE_COLDSTART to do a cold start
+! or with SLIM_START_TYPE=cold to do a cold start
! or set it with an explicit filename here.
!----------------------------------------------------------------------------------
diff --git a/cime_config/config_archive.xml b/cime_config/config_archive.xml
index 4c2412a0..9b3e93b7 100644
--- a/cime_config/config_archive.xml
+++ b/cime_config/config_archive.xml
@@ -1,5 +1,5 @@
-
+ rrh\d?h\d*.*\.nc$
@@ -7,18 +7,18 @@
locfnhrpointer.lnd$NINST_STRING
- ./$CASE.clm2$NINST_STRING.r.$DATENAME.nc
+ ./$CASE.slim$NINST_STRING.r.$DATENAME.ncrpointer.lndrpointer.lnd_9999
- casename.clm2.r.1976-01-01-00000.nc
- casename.clm2.rh4.1976-01-01-00000.nc
- casename.clm2.h0.1976-01-01-00000.nc
- casename.clm2.h0.1976-01-01-00000.nc.base
- casename.clm2_0002.e.postassim.1976-01-01-00000.nc
- casename.clm2_0002.e.preassim.1976-01-01-00000.nc
- anothercasename.clm2.i.1976-01-01-00000.nc
+ casename.slim.r.1976-01-01-00000.nc
+ casename.slim.rh4.1976-01-01-00000.nc
+ casename.slim.h0.1976-01-01-00000.nc
+ casename.slim.h0.1976-01-01-00000.nc.base
+ casename.slim_0002.e.postassim.1976-01-01-00000.nc
+ casename.slim_0002.e.preassim.1976-01-01-00000.nc
+ anothercasename.slim.i.1976-01-01-00000.nc
diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml
index b858907d..e90e3dcc 100644
--- a/cime_config/config_component.xml
+++ b/cime_config/config_component.xml
@@ -13,119 +13,62 @@
-->
-
- clm4.5:
- clm5.0:
- Satellite phenology:
+
+ Simple Land Model:char
- clm
- clm
+ slim
+ slimcase_compenv_case.xmlName of land component
-
+ char
-
-
- -phys clm4_5
- -phys clm5_0
-
- build_component_clm
- env_build.xml
- Provides option(s) for the CLM configure utility.
- CLM_CONFIG_OPTS are normally set as compset variables (e.g., -bgc cn)
- and in general should not be modified for supported compsets.
- It is recommended that if you want to modify this value for your experiment,
- you should use your own user-defined component sets via using create_newcase
- with a compset_file argument.
- This is an advanced flag and should only be used by expert users.
-
-
-
- char
- UNSET
-
-
- 2000_control
- 1850_control
-
- run_component_clm
- env_run.xml
- CLM namelist use_case.
- Determines the use-case that will be sent to the CLM build-namelist utility.
- This is normally set by the component set. This is an advanced flag and should only be
- used by expert users.
-
-
-
-
-
- char
-
+ global_uniform
+ global_uniform,realistic_from_1850,realistic_from_2000,user_defined
- -bgc sp
- -bgc sp
+ realistic_from_2000
+ realistic_from_1850
+ realistic_from_1850
- run_component_clm
+ run_component_slimenv_run.xml
- CLM build-namelist options
+ SLIM namelist use_case scenario.
+ Determines the use-case scenario that will be used in the SLIM buildnml utility.
+ This is normally set by the component set.
+ 'global_uniform' is for surface conditions are globally constant
+ 'realistic_from_1850' are surface conditions taken from a 1850 control simulation with CTSM
+ 'realistic_from_2000' are surface conditions taken from a 2000 control simulation with CTSM
+ 'user_defined' means the user will provide their own surface condition file (mml_surdat)
+
-
+ char
- constant,diagnostic,prognostic
- constant
+ cold,any,required
+ any
- diagnostic
- diagnostic
+ required
+ required
+ any
- run_component_clm
- env_run.xml
- Determines how CLM will determine where CO2 is set.
- If value is constant, it will be set to CCSM_CO2_PPMV,
- if value is either diagnostic or prognostic, the atmosphere model
- MUST send it to CLM. CLM_CO2_TYPE is normally set by the specific
- compset, since it HAS to be coordinated with settings for the
- atmospheric model. Do not modify this variable. If you want to modify for
- your experiment, use your own user-defined component set
- This is an advanced flag and should only be used by expert users.
-
-
-
- char
-
- run_component_clm
- env_run.xml
- CLM-specific namelist settings for -namelist option in the CLM
- build-namelist. CLM_NAMELIST_OPTS is normally set as a compset variable
- and in general should not be modified for supported compsets.
- It is recommended that if you want to modify this value for your experiment,
- you should use your own user-defined component sets via using create_newcase
- with a compset_file argument.
- This is an advanced flag and should only be used by expert users.
-
-
-
- char
- on,off
- off
- run_component_clm
+ run_component_slimenv_run.xml
- Flag to the CLM build-namelist command to force CLM to do a
- cold start (finidat will be set to blanks).
- A value of on forces the model to spin up from a cold-start
- (arbitrary initial conditions). Setting this value in the xml file will take
- precedence over any settings for finidat in the $CASEROOT/user_clm_clm file.
+
+ SLIM run type.
+ 'cold' is a cold start from arbitrary initial conditions, it will fail if you do provide initial conditions
+ 'any' is a run using initial conditions if provided, OR arbitrary initial conditions if no files can be found
+ 'required' is a run where starting from provided initial conditions is required, it will fail if they aren't
+
=========================================
- CLM naming conventions
+ SLIM naming conventions
=========================================
note: [^_]* means match zero or more of any character BUT an underbar.
(in other words make sure there is NOT a underbar before the string afterwards)
diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml
index cd5da592..81d47dc9 100644
--- a/cime_config/config_compsets.xml
+++ b/cime_config/config_compsets.xml
@@ -14,7 +14,7 @@
Where for the CAM specific compsets below the following is supported
TIME = Time period (e.g. 2000, HIST, RCP8...)
ATM = [CAM40, CAM50, CAM55]
- LND = [CLM45, CLM50, SLND]
+ LND = [SLIM, SLND]
ICE = [CICE, DICE, SICE]
OCN = [DOCN, ,AQUAP, SOCN]
ROF = [RTM, SROF]
@@ -41,30 +41,30 @@
ELT2000ClimoTESTC6I5Slim
- 2000_CAM60_CLM50%SP_CICE_DOCN%SOM_SROF_SGLC_SWAV
+ 2000_CAM60_SLIM_CICE_DOCN%SOM_SROF_SGLC_SWAVELT1850TESTC6I5Slim
- 1850_CAM60_CLM50%SP_CICE_DOCN%SOM_SROF_SGLC_SWAV
+ 1850_CAM60_SLIM_CICE_DOCN%SOM_SROF_SGLC_SWAVFLT2000ClimoC6I5Slim
- 2000_CAM60_CLM50%SP_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV
+ 2000_CAM60_SLIM_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAVELT2000ClimoTESTC5I5Slim
- 2000_CAM50_CLM50%SP_CICE_DOCN%SOM_SROF_SGLC_SWAV
+ 2000_CAM50_SLIM_CICE_DOCN%SOM_SROF_SGLC_SWAVFLTHISTC5I5Slim
- HIST_CAM50_CLM50%SP_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV
+ HIST_CAM50_SLIM_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAVIHistSlimRsGs
- HIST_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+ HIST_DATM%GSWP3v1_SLIM_SICE_SOCN_SROF_SGLC_SWAVIHistSlimQianRsGs
- HIST_DATM%QIA_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+ HIST_DATM%QIA_SLIM_SICE_SOCN_SROF_SGLC_SWAVI2000SlimRsGs
- 2000_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+ 2000_DATM%GSWP3v1_SLIM_SICE_SOCN_SROF_SGLC_SWAVI1850SlimRsGs
- 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+ 1850_DATM%GSWP3v1_SLIM_SICE_SOCN_SROF_SGLC_SWAVI1850SlimCruRsGs
- 1850_DATM%CRUv7_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+ 1850_DATM%CRUv7_SLIM_SICE_SOCN_SROF_SGLC_SWAVI1850SlimCplhistRsGs
- 1850_DATM%CPLHIST_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV
+ 1850_DATM%CPLHIST_SLIM_SICE_SOCN_SROF_SGLC_SWAV
diff --git a/cime_config/config_pes.xml b/cime_config/config_pes.xml
index 0797bb4d..9e6fa44b 100644
--- a/cime_config/config_pes.xml
+++ b/cime_config/config_pes.xml
@@ -79,7 +79,7 @@
-
+ Coupled to CAM for 2 degree on cheyenne-10
diff --git a/cime_config/namelist_definition.xsl b/cime_config/namelist_definition.xsl
new file mode 100644
index 00000000..62e02bf0
--- /dev/null
+++ b/cime_config/namelist_definition.xsl
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ SLIM Namelist Definition
+
+
+
+
+
+
+
+
Definition of SLIM namelist variables
+
We list all of the relevant namelist variables for SLIM cases. This includes
+ SLIM Namelist items.
+
+
Definition of SLIM namelist variables
+
Note, these all would go into the user_nl_slim file
+
Included in the table are the following pieces of information:
+
+
Variable name.
+
Variable type (char, integer,
+ real, or logical). The type
+ char has the length appended
+ following an asterisk, e.g., char*256. Variables that are
+ arrays have their dimension specifier appended inside parentheses. For
+ example char*1(6) denotes a array of six
+ char*1 values.
+
+
Variable description (includes information on defaults).
+
Valid values (if restricted).
+
+
+
+
SLIM Namelist Physics Options
+
+
Name
+
Type
+
Description
+
+
+
Valid values
+
+
+
+
+
+
SLIM Namelist Datasets
+
+
Name
+
Type
+
Description
+
+
+
+
Valid values
+
+
+
+
+
+
SLIM Namelist History output settings
+
+
Name
+
Type
+
Description
+
+
+
Valid values
+
+
+
+
+
+
SLIM Namelist Performance Tuning
+
+
Name
+
Type
+
Description
+
+
+
Valid values
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Valid Values:
+
+
+
+
+
diff --git a/cime_config/namelist_definition_slim.xml b/cime_config/namelist_definition_slim.xml
new file mode 100644
index 00000000..99ed1089
--- /dev/null
+++ b/cime_config/namelist_definition_slim.xml
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ char
+ datasets
+ abs
+ slim_data_and_initial
+
+ UNSET
+ UNSET
+ $DIN_LOC_ROOT/lnd/slim/surdat/globalconst_alpha0.2_soilcv2e6_hc0.1_rs100.0_glc_hc0.01_f19_cdf5_20211105.nc
+ $DIN_LOC_ROOT/lnd/slim/surdat/slim_realistic_fromCLM5_alb1850_hc1850_rs1850_f19_20190110.nc
+ $DIN_LOC_ROOT/lnd/slim/surdat/slim2deg_fromCMIP6-AMIP-1deg_ensemble001-010_1991to2010clim_max-ctrl-bucket_rs150_c20210401.nc
+ $DIN_LOC_ROOT/lnd/slim/surdat/slim_realistic_f19_20190110_reverse_cutout_to_f09_c20230224.nc
+ $DIN_LOC_ROOT/lnd/slim/surdat/slim_realistic_f19_20190110_cutout_to_f45_c20230131.nc
+ $DIN_LOC_ROOT/lnd/slim/surdat/slim_realistic_f19_20190110_cutout_to_f10_c20230131.nc
+
+
+ Surface dataset describing surface properties at each gridcell
+
+
+
+
+ char
+ datasets
+ abs
+ slim_data_and_initial
+
+
+ UNSET
+
+
+ If use_init_interp is set to .true., interpinic will be called to interpolate
+ the file given by finidat, creating the output file specified by finidat_interp_dest.
+
+
+
+
+ char
+ datasets
+ slim_data_and_initial
+
+
+ UNSET
+ UNSET
+
+
+ Full pathname of initial conditions file. If blank SLIM will startup from
+ arbitrary initial conditions.
+
+
+
+
+ logical
+ datasets
+ slim_data_and_initial
+
+
+ If set to .true., interpinic will be called to interpolate the file given by finidat,
+ creating the output file specified by finidat_interp_dest.
+
+ This requires that finidat be non-blank.
+
+
+
+
+ char
+ datasets
+ abs
+ slim_data_and_initial
+
+
+ Full pathname of master restart file for a branch run. (only used if RUN_TYPE=branch)
+ (Set with RUN_REFCASE and RUN_REFDATE)
+
+
+
+
+ char
+ datasets
+ abs
+ slim_data_and_initial
+
+
+ $LND_DOMAIN_PATH/$LND_DOMAIN_FILE
+
+ Full pathname of land fraction data file.
+
+
+
+
+
+
+
+ integer
+ slim_performance
+ slim_perf
+ number of segments per clump for decomposition
+ 35
+
+ 35
+
+
+
+
+
+
+
+
+ real
+ slim_physics
+ slim_inparm
+ Time step (seconds)
+
+
+
+
+
+
+
+
+ char(6)
+ history
+ slim_history
+ A,I,X,M
+
+ Per file averaging flag.
+ 'A' (average over history period)
+ 'I' (instantaneous)
+ 'X' (maximum over history period)
+ 'M' (minimum over history period)
+
+
+
+
+ logical
+ history
+ slim_history
+
+ If TRUE, indicates do NOT output any default history fields (requires you to use
+ hist_fincl* to set the exact output fields to use)..
+
+
+
+
+ logical
+ history
+ slim_history
+
+ Toggle to turn all history output completely OFF (possibly used for testing)
+
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to exclude from default history tape series 1.
+
+ ''
+
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to add to history tape series 1.
+
+ ''
+
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to add to history tape series 2.
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to add to history tape series 3.
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to add to history tape series 4.
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to add to history tape series 5.
+
+
+
+ char(1000)
+ history
+ slim_history
+ Fields to add to history tape series 6.
+
+
+
+ integer(6)
+ history
+ slim_history
+ Per tape series maximum number of time samples.
+
+ 1
+
+
+
+
+ integer(6)
+ history
+ slim_history
+ 1,2
+
+ Per tape series history file density (i.e. output precision)
+ 1=double precision
+ 2=single precision
+
+ 2,2,2,2,2,2
+
+ 2
+
+
+
+
+
+ integer(6)
+ history
+ slim_history
+
+ Per tape series history write frequency.
+ positive means in time steps
+ 0=monthly
+ negative means hours
+ (i.e. 5 means every 5 time-steps and -24 means every day
+
+ 0,-24,-24,-24,-24,-24
+
+ 0
+
+
+
+
+
+
+
+
+ char
+ default_settings
+ default_settings
+ cold,any,required
+
+ $SLIM_START_TYPE
+
+
+ SLIM run type.
+ 'cold' is a run from arbitrary initial conditions
+ 'any' is a run using initial conditions if provided, OR arbitrary initial conditions if no files can be found
+ 'required' is a startup run which requires setting initial conditions
+
+
+
+
+ char
+ default_settings
+ default_settings
+
+ $LND_GRID
+
+ Horizontal resolutions
+
+
+
+
+
+
+
+ logical
+ datasets
+ finidat_consistency_checks
+ .false.
+
+ .false.
+
+
+ If TRUE, check consistency between year on the finidat file
+ and the current model year. This check is only done for a transient run.
+
+ This requires that finidat be non-blank.
+
+
+
+
+
+
+
+
+
+ integer
+ performance
+ clm_inparm
+
+ Number of processors to use per clump (when threading is implemented)
+ Currently has no effect
+ See this issue:
+ https://github.com/ESCOMP/SimpleLand/issues/29
+
+
+
+
+ logical
+ datasets
+ clm_inparm
+
+ Write diagnostics out to the log file about global statistics
+ Currently is implemented, but should be removed.
+
+
+
+
+
+ logical
+ datasets
+ clm_inparm
+ .false.
+ .false.
+
+ Run as a single column (NOT currently implemented)
+ See this issue:
+ https://github.com/ESCOMP/SimpleLand/issues/29
+
+
+
+
+
diff --git a/cime_config/slim_cime_py/__init__.py b/cime_config/slim_cime_py/__init__.py
new file mode 100644
index 00000000..f63ce26b
--- /dev/null
+++ b/cime_config/slim_cime_py/__init__.py
@@ -0,0 +1,2 @@
+# pylint: disable=missing-module-docstring
+from .buildnml import buildnml
diff --git a/cime_config/slim_cime_py/buildnml.py b/cime_config/slim_cime_py/buildnml.py
new file mode 100644
index 00000000..d3bf36af
--- /dev/null
+++ b/cime_config/slim_cime_py/buildnml.py
@@ -0,0 +1,523 @@
+"""
+SLIM namelist creator
+"""
+import os
+import shutil
+import logging
+import re
+
+from CIME.buildnml import create_namelist_infile
+from CIME.nmlgen import NamelistGenerator
+from CIME.namelist import literal_to_python_value
+from CIME.utils import expect
+
+logger = logging.getLogger(__name__)
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+####################################################################################
+def check_nml_dtime(nmlgen, case):
+ ####################################################################################
+ """Set the namelist settings for time-step"""
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ logger.debug(" check_nml_dtime")
+ ncpl_base_period = case.get_value("NCPL_BASE_PERIOD")
+ calendar = case.get_value("CALENDAR")
+ if ncpl_base_period == "hour":
+ basedt = 3600
+ elif ncpl_base_period == "day":
+ basedt = 3600 * 24
+ elif ncpl_base_period == "year":
+ if calendar == "NO_LEAP":
+ basedt = 3600 * 24 * 365
+ else:
+ logger.error("CALENDAR = %s", calendar)
+ expect(False, "Invalid CALENDAR for NCPL_BASE_PERIOD %s " % ncpl_base_period)
+ elif ncpl_base_period == "decade":
+ if calendar == "NO_LEAP":
+ basedt = 3600 * 24 * 365 * 10
+ else:
+ logger.error("CALENDAR = %s", calendar)
+ expect(
+ False,
+ "Invalid CALENDAR for NCPL_BASE_PERIOD %s " % ncpl_base_period,
+ )
+ else:
+ expect(False, "Invalid NCPL_BASE_PERIOD %s " % ncpl_base_period)
+
+ if basedt < 0:
+ expect(False, "basedt invalid overflow for NCPL_BASE_PERIOD %s " % ncpl_base_period)
+
+ lnd_ncpl = int(case.get_value("LND_NCPL"))
+ if basedt % lnd_ncpl != 0:
+ logger.error("CALENDAR = %s", calendar)
+ expect(
+ False,
+ "LND_NCPL=%s doesn't divide evenly into NCPL_BASE_PERIOD %s\n"
+ % (lnd_ncpl, ncpl_base_period),
+ )
+ else:
+ dtime = basedt // lnd_ncpl
+
+ expect(
+ dtime > 1,
+ "LND_NCPL=%s is too frequent which gives a time step that is too short\n" % lnd_ncpl,
+ )
+ expect(
+ dtime <= 86400,
+ "LND_NCPL=%s is too infrequent which gives a time step that is too long\n" % lnd_ncpl,
+ )
+ nmlgen.set_value("dtime", value=dtime)
+
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+####################################################################################
+def check_nml_general(nmlgen):
+ ####################################################################################
+ """Set the namelist settings for general settings"""
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ logger.debug(" check_nml_general")
+ for var in ("slim_start_type", "res"):
+ expect(nmlgen.get_value(var) is not None, var + " must be set")
+
+
+####################################################################################
+def check_file(filename, case):
+ ####################################################################################
+ """Check that the file exists"""
+ if os.path.isabs(filename):
+ expect(os.path.isfile(filename), "filename must exist:" + filename)
+ else:
+ rundir = case.get_value("RUNDIR")
+ fname = os.path.normpath(os.path.join(rundir, filename))
+ expect(os.path.isfile(fname), "filename must exist:" + fname)
+
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+####################################################################################
+def check_nml_performance(nmlgen):
+ ####################################################################################
+ """Set the namelist settings for performance"""
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ logger.debug(" check_nml_performance")
+ expect(int(nmlgen.get_value("nsegspc")) > 0, "nsegspc must be positive")
+
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+####################################################################################
+def check_nml_history(nmlgen):
+ ####################################################################################
+ """Set the namelist settings for history"""
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ logger.debug(" check_nml_history")
+
+ avg_opts = ("A", "I", "X", "M")
+ hist_mfilt = nmlgen.get_value("hist_mfilt")
+ for mfilt in hist_mfilt:
+ if mfilt is None:
+ break
+ if int(mfilt) <= 0:
+ raise SystemExit("hist_mfilt must be 1 or larger")
+
+ #
+ # Check the list of fincl for validity and get number of tapes
+ #
+ hist_empty_htapes = nmlgen.get_value("hist_empty_htapes")
+ if hist_empty_htapes is not None:
+ hist_empty = literal_to_python_value(hist_empty_htapes, type_="logical")
+ else:
+ hist_empty = False
+
+ if hist_empty:
+ num_tapes = 0
+ else:
+ num_tapes = 1
+
+ ftype = "fincl"
+ for tape in (1, 2, 3, 4, 5, 6):
+ var = "hist_" + ftype + str(tape)
+ val = nmlgen.get_value(var)
+ for field in val:
+ if field is None:
+ break
+ match = re.fullmatch(r"([A-Za-z0-9_.]+):*([A-Z0-9]*)\s*", field)
+ if match is None:
+ raise SystemExit(
+ "History field name "
+ + var
+ + " has invalid characters or whitespace in it="
+ + field
+ )
+ if match.group(2):
+ if match.group(2) not in avg_opts:
+ raise SystemExit(
+ "History averaging option "
+ + match.group(2)
+ + " is not valid in "
+ + var
+ + " = "
+ + field
+ )
+ if val != [None]:
+ num_tapes = tape
+ #
+ # hist_fexcl1 can only be set if hist_empty is NOT true
+ #
+ var = "hist_fexcl1"
+ val = nmlgen.get_value(var)
+ if hist_empty:
+ if val != [None]:
+ raise SystemExit("hist_fexcl1 can not be set if hist_empty_htapes is set to true")
+ else:
+ for field in val:
+ if field is None:
+ break
+ match = re.search(r"^[A-Za-z0-9_.]+\s*$", field)
+ if match is None:
+ raise SystemExit(
+ "History field name "
+ + var
+ + " has invalid characters or whitespace in it="
+ + field
+ )
+ #
+ # Loop through history array types and make sure array sizes
+ # are consistent and match the expected number
+ #
+ for var in (
+ "hist_mfilt",
+ "hist_ndens",
+ "hist_nhtfrq",
+ "hist_avgflag_pertape",
+ ):
+ val = nmlgen.get_value(var)
+ if val != [None]:
+ if len(val) != num_tapes:
+ raise SystemExit(
+ var
+ + " array size does not agree with the expected size of "
+ + str(num_tapes)
+ + " "
+ + str(val)
+ )
+ #
+ # History options should not be used when use_noio is on, because it turns off all history...
+ #
+ use_noio = nmlgen.get_value("use_noio")
+ if use_noio is not None:
+ noio = literal_to_python_value(use_noio, type_="logical")
+ else:
+ noio = False
+
+ if noio:
+ # NOTE: hist_nhtfrq is excluded from this list since it is set by default
+ # Loop over the history array options
+ for var in (
+ "hist_fexcl1",
+ "hist_fincl1",
+ "hist_fincl2",
+ "hist_fincl3",
+ "hist_fincl4",
+ "hist_fincl5",
+ "hist_fincl6",
+ "hist_mfilt",
+ "hist_ndens",
+ "hist_avgflag_pertape",
+ ):
+ val = nmlgen.get_value(var)
+ if val != [None]:
+ raise SystemExit(
+ "use_noio turns off all history output"
+ + ", so no hist_ namelist option should also be set"
+ + ", the %s array is also being set here" % var
+ )
+ # Loop over any history scalar options
+ for var in ("hist_empty_htapes",):
+ val = nmlgen.get_value(var)
+ if val is not None:
+ raise SystemExit(
+ "use_noio turns off all history output"
+ + ", so no hist_ namelist option should also be set"
+ + ", %s is also being set here" % var
+ )
+
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+####################################################################################
+def check_nml_initial_conditions(nmlgen, case, inst_string=""):
+ ####################################################################################
+ """Set the namelist settings for initial conditions"""
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ logger.debug(" check_nml_initial_conditions")
+ start_type = case.get_value("SLIM_START_TYPE")
+ run_type = case.get_value("RUN_TYPE")
+ run_refcase = case.get_value("RUN_REFCASE")
+ run_refdate = case.get_value("RUN_REFDATE")
+ run_reftod = case.get_value("RUN_REFTOD")
+ rundir = case.get_value("RUNDIR")
+ if run_type in ("hybrid", "branch"):
+ slim_startfile = "%s.slim%s.r.%s-%s.nc" % (
+ run_refcase,
+ inst_string,
+ run_refdate,
+ run_reftod,
+ )
+ if not os.path.exists(os.path.join(rundir, slim_startfile)):
+ slim_startfile = "%s.slim.r.%s-%s.nc" % (
+ run_refcase,
+ run_refdate,
+ run_reftod,
+ )
+
+ nrevsn = nmlgen.get_value("nrevsn")
+ finidat = nmlgen.get_value("finidat")
+ #
+ # Non branch types
+ #
+ if run_type != "branch":
+ # Handle a cold start
+ if start_type == "cold":
+ if finidat != " " and finidat != "UNSET" and finidat is not None:
+ raise SystemExit(
+ "finidat is set but SLIM_START_TYPE is cold which is a contradiction"
+ )
+ nmlgen.set_value("finidat", value=" ")
+
+ # Set to blank meaning a cold start if still UNSET
+ if finidat == " " or finidat == "UNSET" or finidat is None:
+ if run_type == "hybrid" and start_type != "cold":
+ finidat = slim_startfile
+ check_file(finidat, case)
+ nmlgen.set_value("finidat", value=finidat)
+ else:
+ nmlgen.set_value("finidat", value=" ")
+ logger.warning("WARNING: SLIM is starting up from a cold state")
+
+ else:
+ check_file(finidat, case)
+
+ if nrevsn is not None:
+ raise SystemExit("nrevsn can NOT be set except when RUN_TYPE is a branch")
+ #
+ # branch types
+ #
+ else:
+ if nrevsn is None:
+ nrevsn = slim_startfile
+ nmlgen.set_value("nrevsn", value=nrevsn)
+
+ check_file(nrevsn, case)
+ if finidat is not None:
+ raise SystemExit("finidat can NOT be set when RUN_TYPE is a branch")
+
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+####################################################################################
+def check_nml_data(nmlgen, case):
+ ####################################################################################
+ """Set the namelist settings for data must be after check_nml_initial_conditions"""
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ logger.debug(" check_nml_data")
+
+ mml_surdat = nmlgen.get_value("mml_surdat")
+ if mml_surdat == "UNSET":
+ slim_scenario = case.get_value("SLIM_SCENARIO")
+ if slim_scenario == "user_defined":
+ raise SystemExit(
+ "When SLIM_SCENARIO is set to user_defined, you must provide the mml_surdat "
+ + "file by adding it to the user_nl_slim file to add it to the namelist"
+ )
+ raise SystemExit("mml_surdat file is NOT set and is required")
+
+ #
+ # use_init_interp requires that finidat be set
+ #
+ finidat = nmlgen.get_value("finidat")
+ use_init_interp = nmlgen.get_value("use_init_interp")
+ if use_init_interp is not None:
+ interp = literal_to_python_value(use_init_interp, type_="logical")
+ else:
+ interp = False
+
+ if finidat == " " and interp:
+ raise SystemExit("use_init_interp can not be set to TRUE for a cold start")
+ #
+ # use_init_interp can not be set for a branch case
+ #
+ run_type = case.get_value("RUN_TYPE")
+ if run_type == "branch" and interp:
+ raise SystemExit("use_init_interp can NOT be set to TRUE for a branch run type")
+
+ #
+ # finidat destination file can only be set if interp is on
+ #
+ finidat_dest = nmlgen.get_value("finidat_interp_dest")
+ if finidat_dest is not None and not interp:
+ raise SystemExit("finidat_interp_dest can NOT be set if use_init_interp is not on")
+
+
+# pylint: disable=too-many-arguments,too-many-locals,too-many-branches,too-many-statements
+# Turn off unused-argument for inst_string, since isn't in place right now
+# pylint: disable=unused-argument
+####################################################################################
+def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path):
+ ####################################################################################
+ """Write out the namelist for this component.
+
+ Most arguments are the same as those for `NamelistGenerator`. The
+ `inst_string` argument is used as a suffix to distinguish files for
+ different instances. The `confdir` argument is used to specify the directory
+ in which output files will be placed.
+ """
+ # pylint: disable=global-statement
+ global logger
+ # ------------------------------------------------------
+ # Create config dictionary
+ # ------------------------------------------------------
+ config = {}
+ config["lnd_grid"] = case.get_value("LND_GRID")
+ config["compset"] = case.get_value("COMPSET")
+ config["slim_scenario"] = case.get_value("SLIM_SCENARIO")
+ config["slim_start_type"] = case.get_value("SLIM_START_TYPE")
+
+ logger.info(" SLIM lnd grid is %s", config["lnd_grid"])
+
+ # ------------------------------------------------------
+ # Initialize namelist defaults
+ # ------------------------------------------------------
+ nmlgen.init_defaults(infile, config)
+
+ # ------------------------------------------------------
+ # Process different namelists and parts of the namelist
+ # ------------------------------------------------------
+ check_nml_dtime(nmlgen, case)
+ check_nml_general(nmlgen)
+ check_nml_performance(nmlgen)
+ check_nml_history(nmlgen)
+ check_nml_initial_conditions(nmlgen, case, inst_string)
+ check_nml_data(nmlgen, case)
+
+ # ----------------------------------------------------
+ # Write output namelist
+ # ----------------------------------------------------
+ logger.info("Write namelists")
+ namelist_file = os.path.join(confdir, "lnd_in")
+ nmlgen.write_output_file(
+ namelist_file,
+ data_list_path,
+ groups=[
+ "slim_inparm",
+ "slim_data_and_initial",
+ "slim_history",
+ "slim_perf",
+ "finidat_consistency_checks",
+ ],
+ )
+
+
+###############################################################################
+def buildnml(case, caseroot, compname):
+ ###############################################################################
+ """Build the slim namelist"""
+ # pylint: disable=global-statement
+ global logger
+
+ # Build the component namelist
+ if compname != "slim":
+ logger.error("compname = %s", compname)
+ raise AttributeError
+
+ lnd_root = case.get_value("COMP_ROOT_DIR_LND")
+
+ # -----------------------------------------------------
+ # Clear out old data
+ # -----------------------------------------------------
+
+ input_data_list = os.path.join(caseroot, "Buildconf", "slim.input_data_list")
+ if os.path.exists(input_data_list):
+ os.remove(input_data_list)
+
+ # -----------------------------------------------------
+ # Set confdir
+ # -----------------------------------------------------
+
+ confdir = os.path.join(caseroot, "Buildconf", "slimconf")
+ if not os.path.isdir(confdir):
+ os.makedirs(confdir)
+
+ # namelist definition file
+ namelist_xml_dir = os.path.join(lnd_root, "cime_config")
+ definition_file = [os.path.join(namelist_xml_dir, "namelist_definition_slim.xml")]
+ for file_ in definition_file:
+ expect(os.path.isfile(file_), "Namelist XML file %s not found!" % file_)
+
+ # Create the namelist generator object - independent of instance
+ nmlgen = NamelistGenerator(case, definition_file)
+
+ # ----------------------------------------------------
+ # Clear out old data list
+ # ----------------------------------------------------
+ data_list_path = os.path.join(case.get_case_root(), "Buildconf", "slim.input_data_list")
+ if os.path.exists(data_list_path):
+ os.remove(data_list_path)
+
+ ### Independent of instance...
+ rundir = case.get_value("RUNDIR")
+
+ # -----------------------------------------------------
+ # loop over instances
+ # -----------------------------------------------------
+
+ ninst_lnd = case.get_value("NINST_LND")
+ ninst = int(ninst_lnd)
+ for inst_counter in range(1, ninst + 1):
+
+ # determine instance string
+ inst_string = ""
+ if ninst > 1:
+ inst_string = "_" + "%04d" % inst_counter
+
+ # If multi-instance case does not have restart file, use
+ # single-case restart for each instance
+ rpointer = "rpointer.lnd"
+ if os.path.isfile(os.path.join(rundir, rpointer)) and (
+ not os.path.isfile(os.path.join(rundir, rpointer + inst_string))
+ ):
+ shutil.copy(
+ os.path.join(rundir, rpointer),
+ os.path.join(rundir, rpointer + inst_string),
+ )
+ ###
+ ### Namelist infile
+ ###
+ infile_lines = []
+
+ user_nl_file = os.path.join(caseroot, "user_nl_slim" + inst_string)
+ infile = os.path.join(confdir, "namelist_infile")
+
+ create_namelist_infile(case, user_nl_file, infile, "\n".join(infile_lines))
+ namelist_infile = [infile]
+
+ # create namelist
+ _create_namelists(case, confdir, inst_string, namelist_infile, nmlgen, data_list_path)
+ # -----------------------------------------------------
+ # copy resolved namelist to rundir
+ # -----------------------------------------------------
+ if os.path.isdir(rundir):
+ file1 = os.path.join(confdir, "lnd_in")
+ file2 = os.path.join(rundir, "lnd_in")
+ if ninst > 1:
+ file2 += inst_string
+ logger.debug("SLIM namelist copy: file1 %s file2 %s ", file1, file2)
+ shutil.copy(file1, file2)
diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml
index 23804416..2d940c46 100644
--- a/cime_config/testdefs/ExpectedTestFails.xml
+++ b/cime_config/testdefs/ExpectedTestFails.xml
@@ -29,6 +29,16 @@
+
+
+ FAIL
+
+
+
+
+ FAIL
+
+ FAIL
diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_slim.xml
similarity index 100%
rename from cime_config/testdefs/testlist_clm.xml
rename to cime_config/testdefs/testlist_slim.xml
diff --git a/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_1deg_ensemble_FHistMonthly/include_user_mods b/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_1deg_ensemble_FHistMonthly/include_user_mods
new file mode 100644
index 00000000..7aeecdf4
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_1deg_ensemble_FHistMonthly/include_user_mods
@@ -0,0 +1,2 @@
+../Monthly
+../2000_CMIP6_AMIP_1deg_ensemble
diff --git a/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/shell_commands b/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/shell_commands
index 5d354486..f3a1a014 100755
--- a/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/shell_commands
+++ b/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/shell_commands
@@ -1,2 +1,2 @@
#!/bin/bash
-./xmlchange CLM_FORCE_COLDSTART="on"
+./xmlchange SLIM_START_TYPE="cold"
diff --git a/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/user_nl_clm b/cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/user_nl_slim
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/user_nl_clm
rename to cime_config/testdefs/testmods_dirs/slim/2000_CMIP6_AMIP_ensemble/user_nl_slim
diff --git a/cime_config/testdefs/testmods_dirs/slim/Monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/slim/Monthly/user_nl_slim
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/slim/Monthly/user_nl_clm
rename to cime_config/testdefs/testmods_dirs/slim/Monthly/user_nl_slim
diff --git a/cime_config/testdefs/testmods_dirs/slim/default/shell_commands b/cime_config/testdefs/testmods_dirs/slim/default/shell_commands
index b212e325..f3a1a014 100755
--- a/cime_config/testdefs/testmods_dirs/slim/default/shell_commands
+++ b/cime_config/testdefs/testmods_dirs/slim/default/shell_commands
@@ -1,4 +1,2 @@
#!/bin/bash
-./xmlchange CLM_FORCE_COLDSTART="on"
-./xmlchange CLM_CO2_TYPE="constant"
-./xmlchange CCSM_CO2_PPMV="999.99"
+./xmlchange SLIM_START_TYPE="cold"
diff --git a/cime_config/testdefs/testmods_dirs/slim/default/user_nl_clm b/cime_config/testdefs/testmods_dirs/slim/default/user_nl_slim
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/slim/default/user_nl_clm
rename to cime_config/testdefs/testmods_dirs/slim/default/user_nl_slim
diff --git a/cime_config/testdefs/testmods_dirs/slim/g16_SOM/shell_commands b/cime_config/testdefs/testmods_dirs/slim/g16_SOM/shell_commands
index b7909fce..1638132d 100755
--- a/cime_config/testdefs/testmods_dirs/slim/g16_SOM/shell_commands
+++ b/cime_config/testdefs/testmods_dirs/slim/g16_SOM/shell_commands
@@ -1,4 +1,3 @@
#!/bin/bash
CIMEROOT=`./xmlquery --value -s CIMEROOT`
cp $CIMEROOT/../cime_config/testdefs/testmods_dirs/slim/g16_SOM/user_docn* .
-./xmlchange CLM_CO2_TYPE="diagnostic"
diff --git a/cime_config/testdefs/testmods_dirs/slim/global_uniform/include_user_mods b/cime_config/testdefs/testmods_dirs/slim/global_uniform/include_user_mods
index d243c2a4..fe0e18cf 100644
--- a/cime_config/testdefs/testmods_dirs/slim/global_uniform/include_user_mods
+++ b/cime_config/testdefs/testmods_dirs/slim/global_uniform/include_user_mods
@@ -1,2 +1 @@
../default
-../../../../usermods_dirs/global_uniform
diff --git a/cime_config/testdefs/testmods_dirs/slim/global_uniform/shell_commands b/cime_config/testdefs/testmods_dirs/slim/global_uniform/shell_commands
new file mode 100755
index 00000000..9c10e11c
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/slim/global_uniform/shell_commands
@@ -0,0 +1,2 @@
+#!/bin/bash
+./xmlchange SLIM_SCENARIO="global_uniform"
diff --git a/cime_config/testdefs/testmods_dirs/slim/global_uniform_g16_SOM/shell_commands b/cime_config/testdefs/testmods_dirs/slim/global_uniform_g16_SOM/shell_commands
deleted file mode 100755
index 626ff59f..00000000
--- a/cime_config/testdefs/testmods_dirs/slim/global_uniform_g16_SOM/shell_commands
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-./xmlchange CLM_CO2_TYPE="diagnostic"
diff --git a/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850/include_user_mods b/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850/include_user_mods
index ad975dc0..fe0e18cf 100644
--- a/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850/include_user_mods
+++ b/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850/include_user_mods
@@ -1,2 +1 @@
../default
-../../../../usermods_dirs/realistic_fromCLM5_1850
diff --git a/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850_g16_SOM_save_cplhist/shell_commands b/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850_g16_SOM_save_cplhist/shell_commands
deleted file mode 100755
index 626ff59f..00000000
--- a/cime_config/testdefs/testmods_dirs/slim/realistic_fromCLM5_1850_g16_SOM_save_cplhist/shell_commands
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-./xmlchange CLM_CO2_TYPE="diagnostic"
diff --git a/cime_config/testdefs/testmods_dirs/slim/save_cplhist/shell_commands b/cime_config/testdefs/testmods_dirs/slim/save_cplhist/shell_commands
deleted file mode 100755
index 626ff59f..00000000
--- a/cime_config/testdefs/testmods_dirs/slim/save_cplhist/shell_commands
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-./xmlchange CLM_CO2_TYPE="diagnostic"
diff --git a/cime_config/user_nl_slim b/cime_config/user_nl_slim
new file mode 100644
index 00000000..43893a6e
--- /dev/null
+++ b/cime_config/user_nl_slim
@@ -0,0 +1,13 @@
+!----------------------------------------------------------------------------------
+! Users should add all user specific namelist changes below in the form of
+! namelist_var = new_namelist_value
+!
+! EXCEPTIONS:
+! Set dtime with L_NCPL option
+! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options
+! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases
+! (includes $inst_string for multi-ensemble cases)
+! or with SLIM_START_TYPE=cold to do a cold start
+! or set it with an explicit filename here.
+!----------------------------------------------------------------------------------
+
diff --git a/cime_config/usermods_dirs/global_uniform/user_nl_clm b/cime_config/usermods_dirs/global_uniform/user_nl_clm
deleted file mode 100644
index f84c9987..00000000
--- a/cime_config/usermods_dirs/global_uniform/user_nl_clm
+++ /dev/null
@@ -1 +0,0 @@
-mml_surdat = '$DIN_LOC_ROOT/lnd/slim/surdat/globalconst_alpha0.2_soilcv2e6_hc0.1_rs100.0_glc_hc0.01_f19_cdf5_20211105.nc'
diff --git a/cime_config/usermods_dirs/realistic_fromCLM5_1850/user_nl_clm b/cime_config/usermods_dirs/realistic_fromCLM5_1850/user_nl_clm
deleted file mode 100644
index f7953f1f..00000000
--- a/cime_config/usermods_dirs/realistic_fromCLM5_1850/user_nl_clm
+++ /dev/null
@@ -1 +0,0 @@
-mml_surdat = '$DIN_LOC_ROOT/lnd/slim/surdat/slim_realistic_fromCLM5_alb1850_hc1850_rs1850_f19_20190110.nc'
diff --git a/cime_config/usermods_dirs/realistic_fromCLM5_2000/user_nl_clm b/cime_config/usermods_dirs/realistic_fromCLM5_2000/user_nl_clm
deleted file mode 100644
index 171aa345..00000000
--- a/cime_config/usermods_dirs/realistic_fromCLM5_2000/user_nl_clm
+++ /dev/null
@@ -1 +0,0 @@
-mml_surdat = '$DIN_LOC_ROOT/lnd/slim/surdat/slim2deg_fromCMIP6-AMIP-1deg_ensemble001-010_1991to2010clim_max-ctrl-bucket_rs150_c20210401.nc'
diff --git a/py_env_create b/py_env_create
new file mode 100755
index 00000000..648f1e70
--- /dev/null
+++ b/py_env_create
@@ -0,0 +1,136 @@
+#!/bin/bash
+#
+# py_env_create -- setup the python environment in order to use SLIM python tools
+#
+# Simple bash script to setup the python environment for the user so they can run the SLIM
+# python tools using "conda".
+#
+dir=${0%/*}
+if [ "$dir" = "$0" ];then
+ dir="."
+fi
+
+# Check if conda is in your path
+conda --help >& condahelp.txt
+error=$?
+if [ $error != 0 ]; then
+ echo "conda is NOT in your path for the bash shell add it with modules or whatever is required on your system to get it in your path"
+ echo "on cheyenne/capser/etc use -- module load conda"
+ echo "on izumi/CGD systems use -- module load lang/python"
+ echo "For notes on installing on a user system see: https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html"
+ echo "Error code was $error"
+ cat condahelp.txt
+ exit -1
+fi
+rm condahelp.txt
+python_env=slim_pylib
+
+
+condadir="$dir/python"
+
+domain=`domainname`
+if [[ $domain =~ cgd.* ]]; then
+ condafile="conda_env_slim_py_cgd.txt"
+else
+ condafile="conda_env_slim_py.txt"
+fi
+#----------------------------------------------------------------------
+# Usage subroutine
+usage() {
+ echo ""
+ echo "***********************************************************************"
+ echo "usage:"
+ echo "./py_env_create"
+ echo ""
+ echo "valid arguments: "
+ echo "[-h|--help] "
+ echo " Displays this help message"
+ echo "[-v|--verbose] "
+ echo " Run with verbose mode for the install so you see the progress bar"
+ echo "[-f|--file ] "
+ echo " Conda environment file to use (can be a text format or YAML format)"
+ echo " Assumed to be under the directory: $condadir"
+ echo " Default is: $condafile"
+ echo "[--option