Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and improve anomaly forcings for ISSP cases #292

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions cime_config/stream_cdeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,30 @@ def create_stream_xml(
),
)
if var_key in valid_values:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are expecting that the variable may or may not have surrounding quotes why not just strip the quotes if they exist and avoid asking the user for a correction?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samsrabin I think @jedwards4b is right here, it looks like there might be a simpler way to handle this. Could we get together and go over this together and see if there is a way to do that?

# # Handle, e.g., 'bilinear' in namelist instead of bilinear (no quotes)
mod_dict_var_key = mod_dict[var_key]

# Check that key is valid
is_valid = mod_dict_var_key in valid_values[var_key]
msg = "{} can only have values of {} for stream {} in file {}, not {}".format(
var_key,
valid_values[var_key],
stream_name,
user_mods_file,
mod_dict[var_key],
)
if not is_valid:
# Check for surrounding quote marks
has_surrounding_quotes = (
(mod_dict_var_key[0] == mod_dict_var_key[-1] == "'") or
(mod_dict_var_key[0] == mod_dict_var_key[-1] == '"')
)
if has_surrounding_quotes and mod_dict_var_key[1:-1] in valid_values[var_key]:
msg += " (try removing surrounding quotes)"
expect(
mod_dict[var_key] in valid_values[var_key],
"{} can only have values of {} for stream {} in file {}".format(
var_key,
valid_values[var_key],
stream_name,
user_mods_file,
),
is_valid,
msg,
)
stream_vars["stream_" + var_key] = mod_dict[var_key]
if var_key == "datafiles":
Expand Down
18 changes: 17 additions & 1 deletion datm/cime_config/buildnml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# pylint: disable=wildcard-import,unused-wildcard-import,wrong-import-position

import os, sys
import re

_CDEPS_CONFIG = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir,os.pardir,"cime_config")
_CIMEROOT = os.environ.get("CIMEROOT")
Expand Down Expand Up @@ -115,6 +116,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
atm_grid = case.get_value("ATM_GRID")
model_grid = case.get_value("GRID")
comp_lnd = case.get_value("COMP_LND")
compset = case.get_value("COMPSET")

# Check for incompatible options.
if "CLM" in datm_mode and comp_lnd == "clm":
Expand All @@ -135,6 +137,7 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
logger.debug("DATM preso3 mode is {}".format(datm_preso3))
logger.debug("DATM topo mode is {}".format(datm_topo))
logger.debug("CLM_USRDAT_NAME is {}".format(clm_usrdat_name))
logger.debug("COMPSET is {}".format(compset))

# Initialize namelist defaults
config = {}
Expand Down Expand Up @@ -177,6 +180,17 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path

nmlgen.init_defaults(infile, config)

# Get anomaly forcing
# First, look in namelist
anomaly_forcing = nmlgen.get_value("anomaly_forcing")
if not anomaly_forcing or anomaly_forcing[0] is None:
# If not in namelist, check whether it's an SSP compset
ssp = re.search(r"^SSP\d+_DATM", compset)
if ssp:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand this -- it will ensure anomaly_forcing is forced to be on for SSP compsets. But, I don't think that's what we want. I think that the default certainly should be for it to be on, but the user should be able to turn it off if they want. The AF forcing is also specific to the DATM_MODE so it should only do this depending on both the compset and DATM_MODE. And since the DATM_MODE the AF forcing matches will be changing, it would be better for this to be in the XML data rather than in the python code. Better to be data driven when possible.

As such I'm thinking this part should be reverted.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below for what I suggest to add to the namelist_definition file. We will also need to make sure compset is a valid field in the namelist defintion file.

ssp = ssp.group().replace("_DATM", "")
anomaly_forcing = ["Anomaly.Forcing.cmip6." + ssp.lower()]
nmlgen.set_value("anomaly_forcing", anomaly_forcing)

# Generate datm_in
namelist_file = os.path.join(confdir, "datm_in")
nmlgen.write_output_file(namelist_file, data_list_path, groups=['datm_nml','const_forcing_nml'])
Expand Down Expand Up @@ -205,8 +219,10 @@ def _create_namelists(case, confdir, inst_string, infile, nmlgen, data_list_path
bias_correct = nmlgen.get_value("bias_correct")
if bias_correct is not None:
streamlist.append(bias_correct)

# Set anomaly forcing in datm.streams.xml
anomaly_forcing = nmlgen.get_value("anomaly_forcing")
if anomaly_forcing[0] is not None:
if anomaly_forcing[0] is not None and anomaly_forcing[0] != "none":
streamlist += anomaly_forcing

# Generate datm.streams.xml
Expand Down
2 changes: 1 addition & 1 deletion datm/cime_config/namelist_definition_datm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
<type>char(10)</type>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Near the top of the file streamslist is being set with a setting for GSWP3 like this:

      <value datm_mode="CLMGSWP3v1">
        CLMGSWP3v1.Solar,CLMGSWP3v1.Precip,CLMGSWP3v1.TPQW
      </value>

This should be expanded to have an option for GSWP3 forcing and SSP compsets. So something like:

      <value datm_mode="CLMGSWP3v1" compset_period="SSP585">
        CLMGSWP3v1.Solar,CLMGSWP3v1.Precip,CLMGSWP3v1.TPQW,Anomaly.Forcing.cmip6.ssp585
      </value>

There might be a way to append just the AF file to the end, which would be preferred. But, we'd need to figure that out. The matching needs to be figured out to make sure it works right. And of course all the SSP options need to be added.

Note that compset_period needs to be added to the buildnml file which I'll sketch out below.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes to buildnml:

buildnml needs to:

  • Get the compset from the case
  • Extract out the period part of the compset
  • Send compset_period to the config object

So something like...

    caseroot = case.get_value("CASEROOT")
    datm_mode = case.get_value("DATM_MODE")
    datm_topo = case.get_value("DATM_TOPO")
    compset = case.get_value("COMPSET")
.
.
.
    # Do some reg-ex or other magic to get the compset_period from it
    compset_period = something(compset)

    config['datm_mode'] = datm_mode
    config['datm_co2_tseries'] = datm_co2_tseries
    config['compset_period'] compset_period
.
.
.

<category>datm</category>
<group>datm_nml</group>
<valid_values>Anomaly.Forcing.Precip,Anomaly.Forcing.Temperature,Anomaly.Forcing.Pressure,Anomaly.Forcing.Humidity,Anomaly.Forcing.Uwind,Anomaly.Forcing.Vwind,Anomaly.Forcing.Shortwave,Anomaly.Forcing.Longwave</valid_values>
<valid_values>none,Anomaly.Forcing.cmip5.rcp45,Anomaly.Forcing.cmip6.ssp126,Anomaly.Forcing.cmip6.ssp245,Anomaly.Forcing.cmip6.ssp370,Anomaly.Forcing.cmip6.ssp585</valid_values>
<desc>
If set, include anomaly forcing streams in namelist.
</desc>
Expand Down
Loading
Loading