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 @@ char unset - $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
NameValueDescription
Valid Values
- - - - - - - - - - - - -
CLM Biogeochemistry Configurations
NameValueDescription
Valid Value
- - - - - - - - - - - - -
Configuration Directories
NameValueDescription
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:

-
    -
  1. Biogeochemistry (BGC) type (none, CN)
  2. -
  3. Initial condition date (ymd - year month day)
  4. -
  5. Initial condition time of day (tod) (sec)
  6. -
  7. Maximum number of Plant Function Types (maxpft)
  8. -
  9. Site specific point name (sitespf_pt)
  10. -
  11. Crop model (crop)
  12. -
  13. Data model forcing source (forcing)
  14. -
  15. Representative concentration pathway for future scenarios (rcp)
  16. -
  17. New good wood harvest (newwoodharv)
  18. -
  19. Type of file (type)
  20. -
  21. Grid mapping to (to_hgrid)
  22. -
  23. Land-mask mapping to (to_lmask)
  24. -
  25. High resolution file? (hires)
  26. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Namelist Defaults
NameHorz. GridMaskSim yearSim year rangeMiscellaneous
Default Value for this Configuration
- - - - - - - - - - - All res - - - - - - - - - - - - - - - MODIS - - - All masks - - - - - - - - - All yrs - - - - - - - - - All sim-yr-rng - - - - - bgc= - - - ymd= - - - tod= - - - maxpft= - - - sitespf_pt= - - - datm_presaero= - - - crop= - - - forcing= - - - rcp= - - - newwoodharv= - - - type= - - - to_hgrid= - - - to_lmask= - - - hires= - -
Value:
- - - - -
- -
diff --git a/bld/namelist_files/namelist_defaults_clm4_5.xml b/bld/namelist_files/namelist_defaults_clm4_5.xml deleted file mode 100644 index 1c0cf2d0..00000000 --- a/bld/namelist_files/namelist_defaults_clm4_5.xml +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - - - - - -0.9x1.25 - -2000 - - -1800 - - - - - - - - -75 - - -1850,2000 - - -.true. -.true. -.false. - - -hgrid=0.9x1.25 maxpft=17 mask=gx1v6 - - -hgrid=0.9x1.25 maxpft=17 mask=gx1v6 - - -hgrid=0.9x1.25 maxpft=79 mask=gx1v7 - - - -hgrid=0.9x1.25 maxpft=79 mask=gx1v6 - - -hgrid=0.9x1.25 maxpft=79 mask=gx1v6 - - -hgrid=0.9x1.25 maxpft=17 mask=gx1v6 - - -hgrid=0.9x1.25 maxpft=79 mask=gx1v7 - - -hgrid=1.9x2.5 maxpft=79 mask=gx1v6 - - - - - -lnd/slim/surdat/slim_realistic_f19_20190110_reverse_cutout_to_f09_c20230224.nc - -lnd/slim/surdat/mml_1.9x2.5_default_cdf5_c20211105.nc - -lnd/slim/surdat/slim_realistic_f19_20190110_cutout_to_f45_c20230131.nc - -lnd/slim/surdat/slim_realistic_f19_20190110_cutout_to_f10_c20230131.nc - - - - -lnd/clm2/initdata_map/clmi.I1850Clm45BgcGs.0901-01-01.0.9x1.25_gx1v6_simyr1850_c180204.nc - - -lnd/clm2/initdata_map/clmi.I1850Clm45BgcCruGs.1101-01-01.0.9x1.25_gx1v6_simyr1850_c180204.nc - - -lnd/clm2/initdata_map/clmi.B1850.0161-01-01.0.9x1.25_gx1v7_simyr1850_c180130.nc - - - -lnd/clm2/initdata_map/clmi.I1850Clm50Sp.0181-01-01.0.9x1.25_gx1v6_simyr1850_c171214.nc - - - -lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop.1366-01-01.0.9x1.25_gx1v6_simyr1850_c171213.nc - - - -lnd/clm2/initdata_map/clmi.I1850Clm50BgcCropCru.1526-01-01.0.9x1.25_gx1v6_simyr1850_c180109.nc - - - -lnd/clm2/initdata_map/clmi.B1850.0161-01-01.0.9x1.25_gx1v7_simyr1850_c180130.nc - - -lnd/clm2/initdata_map/clmi.I1850Clm50SpCru.1706-01-01.0.9x1.25_gx1v6_simyr1850_c180110.nc - - - - - - -lnd/clm2/initdata_map/clmi.IGM2000GSWP3CLM50BGCCROPIRR.2011-01-01.1.9x2.5_gx1v6_gl5_simyr2000_c170419.nc - - - - -lnd/clm2/surfdata_map/surfdata_360x720cru_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_48x96_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_0.47x0.63_16pfts_Irrig_CMIP6_simyr2000_c170919.nc - -lnd/clm2/surfdata_map/surfdata_0.9x1.25_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_1.9x2.5_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_4x5_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_10x15_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_ne120np4_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_ne30np4_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_ne16np4_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc - -lnd/clm2/surfdata_map/surfdata_1x1_brazil_16pfts_Irrig_CMIP6_simyr2000_c171214.nc - - -lnd/clm2/surfdata_map/surfdata_64x128_16pfts_Irrig_CMIP6_simyr2000_c170824.nc - - - -lnd/clm2/surfdata_map/surfdata_0.47x0.63_78pfts_CMIP6_simyr2000_c170919.nc - -lnd/clm2/surfdata_map/surfdata_0.9x1.25_78pfts_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_1.9x2.5_78pfts_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_0.125x0.125_mp24_simyr2000_c150114.nc - -lnd/clm2/surfdata_map/surfdata_10x15_78pfts_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_4x5_78pfts_CMIP6_simyr2000_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_ne120np4_78pfts_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_ne30np4_78pfts_CMIP6_simyr2000_c170824.nc - -lnd/clm2/surfdata_map/surfdata_ne16np4_78pfts_CMIP6_simyr2000_c170824.nc - - - -lnd/clm2/surfdata_map/surfdata_360x720cru_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_48x96_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_0.47x0.63_16pfts_Irrig_CMIP6_simyr1850_c170919.nc - -lnd/clm2/surfdata_map/surfdata_0.9x1.25_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_1.9x2.5_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_10x15_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_4x5_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_1x1_brazil_16pfts_Irrig_CMIP6_simyr1850_c171214.nc - - - -lnd/clm2/surfdata_map/surfdata_ne120np4_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_ne30np4_16pfts_Irrig_CMIP6_simyr1850_c170824.nc - - - -lnd/clm2/surfdata_map/surfdata_360x720cru_78pfts_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_48x96_78pfts_CMIP6_simyr1850_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_0.47x0.63_78pfts_CMIP6_simyr1850_c170919.nc - -lnd/clm2/surfdata_map/surfdata_0.9x1.25_78pfts_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_1.9x2.5_78pfts_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_10x15_78pfts_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_4x5_78pfts_CMIP6_simyr1850_c170824.nc - - -lnd/clm2/surfdata_map/surfdata_1x1_brazil_78pfts_CMIP6_simyr1850_c171214.nc - - -lnd/clm2/surfdata_map/surfdata_ne30np4_78pfts_CMIP6_simyr1850_c170824.nc - -lnd/clm2/surfdata_map/surfdata_ne120np4_78pfts_CMIP6_simyr1850_c170824.nc - - - - - -lnd/clm2/surfdata_map/landuse.timeseries_0.47x0.63_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c171025.nc -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_1x1_brazil_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - - - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_1x1_brazil_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - - - - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_1x1_brazil_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc - - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_1x1_brazil_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc - -bilinear - -nn -nn -nn -nn - - - - - -35 - - - - - -. -. - - diff --git a/bld/namelist_files/namelist_defaults_overall.xml b/bld/namelist_files/namelist_defaults_overall.xml deleted file mode 100644 index a3e7e368..00000000 --- a/bld/namelist_files/namelist_defaults_overall.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - -startup -startup - - -/fs/cgd/csm/inputdata - - -1.9x2.5 -1x1_brazil -5x5_amazon - - -2000 - - -constant - - -1 -0 - - -1 -0 - - --999.9 - - -gx1v6 -gx1v6 -gx1v6 -gx1v6 -gx3v7 -gx3v7 -USGS - -cruncep -USGS -USGS -gx3v7 -USGS -USGS - -T62 - -gx1v6 -gx1v6 -gx1v6 - -navy -navy -gx1v6 - - diff --git a/bld/namelist_files/namelist_definition.xsl b/bld/namelist_files/namelist_definition.xsl deleted file mode 100644 index a83d4d7d..00000000 --- a/bld/namelist_files/namelist_definition.xsl +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - - - - - - - - CLM Namelist Definition - - -

-

-
-

-

-

Definition of CLM namelist variables

-

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
NameTypeDescription
Valid values
- - - - - - - - - - - - -
CLM Namelist Datasets
NameTypeDescription -
Valid values
- - - - - - - - - - - - -
CLM Namelist History output settings
NameTypeDescription
Valid values
- - - - - - - - - - - - -
CLM Namelist Restart settings
NameTypeDescription
Valid values
- - - - - - - - - - - - -
CLM Namelist Performance Tuning
NameTypeDescription
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
NameTypeDescription
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
NameTypeDescription
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
NameTypeDescription
Valid values
- - - - - - - - - - - -
CLM mkgriddata
NameTypeDescription
Valid values
- - - - - - - - - - - -
CLM mkmapdata
NameTypeDescription
Valid values
- - - - - - - - - - - -
CLM mkgriddata
NameTypeDescription
Valid values
- - - - - - - - - - - -
Miscellaneous CLM tools
NameTypeDescription
Valid values
- -
- -

Namelist items for Driver Dry Deposition

- - - - - - - - - - - -
Driver Dry-Deposition Namelist Options
NameTypeDescription
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 @@ - + r rh\d? h\d*.*\.nc$ @@ -7,18 +7,18 @@ locfnh rpointer.lnd$NINST_STRING - ./$CASE.clm2$NINST_STRING.r.$DATENAME.nc + ./$CASE.slim$NINST_STRING.r.$DATENAME.nc rpointer.lnd rpointer.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 + slim case_comp env_case.xml Name 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_slim env_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_slim env_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_SWAV ELT1850TESTC6I5Slim - 1850_CAM60_CLM50%SP_CICE_DOCN%SOM_SROF_SGLC_SWAV + 1850_CAM60_SLIM_CICE_DOCN%SOM_SROF_SGLC_SWAV FLT2000ClimoC6I5Slim - 2000_CAM60_CLM50%SP_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV + 2000_CAM60_SLIM_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV ELT2000ClimoTESTC5I5Slim - 2000_CAM50_CLM50%SP_CICE_DOCN%SOM_SROF_SGLC_SWAV + 2000_CAM50_SLIM_CICE_DOCN%SOM_SROF_SGLC_SWAV FLTHISTC5I5Slim - HIST_CAM50_CLM50%SP_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV + HIST_CAM50_SLIM_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV IHistSlimRsGs - HIST_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV + HIST_DATM%GSWP3v1_SLIM_SICE_SOCN_SROF_SGLC_SWAV IHistSlimQianRsGs - HIST_DATM%QIA_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV + HIST_DATM%QIA_SLIM_SICE_SOCN_SROF_SGLC_SWAV I2000SlimRsGs - 2000_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV + 2000_DATM%GSWP3v1_SLIM_SICE_SOCN_SROF_SGLC_SWAV I1850SlimRsGs - 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV + 1850_DATM%GSWP3v1_SLIM_SICE_SOCN_SROF_SGLC_SWAV I1850SlimCruRsGs - 1850_DATM%CRUv7_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV + 1850_DATM%CRUv7_SLIM_SICE_SOCN_SROF_SGLC_SWAV I1850SlimCplhistRsGs - 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
NameTypeDescription
Valid values
+ + + + + + + + + + + + +
SLIM Namelist Datasets
NameTypeDescription +
Valid values
+ + + + + + + + + + + + +
SLIM Namelist History output settings
NameTypeDescription
Valid values
+ + + + + + + + + + + + +
SLIM Namelist Performance Tuning
NameTypeDescription
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