Skip to content

Commit

Permalink
add systemtest for potential vegetation spin up
Browse files Browse the repository at this point in the history
  • Loading branch information
loaner committed May 23, 2024
1 parent 5b30740 commit 2a7ca01
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 1 deletion.
120 changes: 120 additions & 0 deletions cime_config/SystemTests/pvt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""
FATES land use potential vegetation spin up + transient test
This is a FATES specific test:
1) conduct a spinup with use_fates_potentialveg on
- write restart file
- use CLM_ACCELERATED_SPINUP?
2) run a transient landuse case with use_fates_lupft
- start from the restart file generated in (1)
"""
from CIME.XML.standard_module_setup import *
from CIME.SystemTests.system_tests_common import SystemTestsCommon
from systemtest_utils import read_user_nl_clm
import shutil, glob, os

logger = logging.getLogger(__name__)

class PVT(SystemTestsCommon):
def __init_(self,case):
SystemTestsCommon.__init__(self,case)

# Do not allow PVT to be run with certain testmods
# Should this be targeted to a specific testmod for simplicity for now?
# Technically this could be run with the luh fates_harvest_modes
casebaseid = self._case.get_value("CASEBASEID")
casebasid = casebaseid.split("-")[-1]
if casebaseid[0:10] != "FatesLUPFT":
error_message = (
"Only call PVT with test FatesLUPFT"
)
logger.error(error_message)
raise RuntimeError(error_message)

# Only allow to run if resolution is 4x5 for now
# Eventually we could set this up to generate the necessary land use x pft mapping
# on the fly, although this would also require generating the land use timeseries
# regridding on the fly which is a more time consuming endevour currently
lnd_grid = self._case.get_value("LND_GRID")
if lnd_grid != "4x5":
error_message = (
"PVT can currently only be run with 4x5 resolution"
)
logger.error(error_message)
raise RuntimeError(error_message)

def run_phase(self):
# -------------------------------------------------------------------
# (1) Run FATES spin-up case in potential vegetation mode
# -------------------------------------------------------------------
orig_case = self._case
orig_casevar = self._case.get_value("CASE")
caseroot = self._case.get_value("CASEROOT")

# clone the main case to create spinup case
logger.info("PVT log: cloning setup")
clone_path = "{}.potveg".format(caseroot)
if os.path.exists(clone_path):
shutil.rmtree(clone_path)
logger.info("PVT log: cloning")
clone = self._case.create_clone(clone_path, keepexe=True)
logger.info("PVT log: cloning complete")

# setup the clone case
os.chdir(clone_path)
self._set_active_case(clone)
self._setup_all()

# Modify the spin up case to use the potential vegetation mode.
# Checks for incompatible cases and necessary mapping files are
# handled in the build case.
# use_fates_lupft should be set to true in the testmod
# save off the harvest mode for reinstating later
found, hmode = self.read_user_nl_clm('fates_harvest_mode')
logger.info("PVT log: modify user_nl_clm file for spin up run")
# TODO: remove fates_harvest_mode if found
self._append_to_user_nl_clm(
[
"use_fates_potentialveg = .true.",
]
)

stop_n_pveg = 1
with clone:
# clone.set_value("CLM_ACCELERATED_SPINUP", "on")
clone.set_value("STOP_N", stop_n_pveg)

# Run the spin up case
# As per SSP test:
# "No history files expected, set suffix=None to avoid compare error"
logger.info("PVT log: starting spin-up run")
dout_sr = clone.get_value("DOUT_S_ROOT")
self._skip_pnl = False
self.run_indv(suffix=None, st_archive=True)

# -------------------------------------------------------------------
# (2) Run FATES transient case using restart file from spin-up
# -------------------------------------------------------------------
os.chdir(caseroot)
self._set_active_case(orig_case)

# logger.info("PVT log: modify user_nl_clm file for transient run")
# self._append_to_user_nl_clm(
# [
# "use_fates_potentialveg = .true.",
# ]
# )


self._case.set_value("CLM_ACCELERATED_SPINUP", "off")
self._case.set_value("RUN_TYPE", "hybrid")
self._case.set_value("GET_REFCASE", False)
self._case.set_value("RUN_REFCASE", "{}.potveg".format(orig_casevar))
self._case.set_value("RUN_REFDATE", "1700-01-01")
self._case.set_value("DOUT_S", False)
self._case.flush()

# do the restart run (short term archiving is off)
self.run_indv()
20 changes: 19 additions & 1 deletion cime_config/SystemTests/systemtest_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Reduce code duplication by putting reused functions here.
"""

import os, subprocess
import os, subprocess, re


def cmds_to_setup_conda(caseroot):
Expand Down Expand Up @@ -84,3 +84,21 @@ def run_python_script(caseroot, this_conda_env, command_in, tool_path):
except:
print(f"ERROR trying to run {tool_name}.")
raise

def read_user_nl_clm(self,namelist_option):
user_nl_clm_path = os.path.join(self._get_caseroot(), "user_nl_clm")
with open(user_nl_clm_path) as f:
user_nl_clm_text = f.read()
reg = fr'{namelist_option}\s*=\s*([^\n]+)'
find_out = re.findall(reg, user_nl_clm_text)
# This could be more robust
if len(find_out) == 0:
return 0, False
elif len(find_out) > 1:
error_message = (
"ERROR: read_user_nl_clm: namelist option is set more than once"
)
# logger.error(error_message)
raise RuntimeError(error_message)
else:
return find_out[0], True

0 comments on commit 2a7ca01

Please sign in to comment.