Skip to content

Commit

Permalink
Add docstrings, and runtime checks to restart clone test, clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
blimlim committed Sep 11, 2024
1 parent 4bb6fc2 commit 10f5122
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 26 deletions.
45 changes: 32 additions & 13 deletions payu/models/cice.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,32 @@ def setup(self):
if setup_nml['restart']:
self.link_restart(setup_nml['pointer_file'])

self.calc_timestep_runtime(setup_nml)
self.calc_runtime(setup_nml)

# Write any changes to the work directory copy of the cice
# namelist
nml_path = os.path.join(self.work_path, self.ice_nml_fname)
self.ice_in.write(nml_path, force=True)

def calc_timestep_runtime(self, setup_nml):
def calc_runtime(self, setup_nml):
"""
Calculate 1: the previous number of timesteps simulated, and 2:
the number of timesteps to simulate in the next run.
Note 1: This method is overridden in the cice5 driver, as cice5
in ACCESS OM2 does not require the calculated runtime information.
Instead it performs the calculations within the model using the
restart files and OM2 namelist.
Note 2: For ESM1.5, the actual model start date and run time are
controlled via the separate input_ice.nml namelist, with relevant
calculations in the access driver.
Parameters
----------
setup_nml: Open 'setup_nml' section of the cice_in.nml namelist.
Modifies in place.
"""
init_date = datetime.date(year=setup_nml['year_init'], month=1, day=1)
if setup_nml['days_per_year'] == 365:
caltype = cal.NOLEAP
Expand All @@ -219,13 +237,18 @@ def calc_timestep_runtime(self, setup_nml):
if self.prior_restart_path:

prior_nml_path = os.path.join(self.prior_restart_path,
self.ice_nml_fname)
self.ice_nml_fname)

# TODO: Are there any models which leave cice_in.nml in
# the output rather than restart directory? If not we can remove
# this.

# With later versions this file exists in the prior restart path,
# but this was not always the case, so check, and if not there use
# prior output path
if not os.path.exists(prior_nml_path) and self.prior_output_path:
prior_nml_path = os.path.join(self.prior_output_path,
self.ice_nml_fname)
self.ice_nml_fname)

# If we cannot find a prior namelist, then we cannot determine
# the start time and must abort the run.
Expand All @@ -241,12 +264,13 @@ def calc_timestep_runtime(self, setup_nml):
prior_runtime_seconds = prior_runtime * prior_setup_nml['dt']

else:
# Initialise runtime
# If no prior restart directory exists, set the prior runtime to 0
prior_runtime_seconds = 0

# Set runtime for this run.
# Calculate runtime for this run.
if self.expt.runtime:
run_start_date = cal.date_plus_seconds(init_date, prior_runtime_seconds,
run_start_date = cal.date_plus_seconds(init_date,
prior_runtime_seconds,
caltype)
run_runtime = cal.runtime_from_date(
run_start_date,
Expand All @@ -258,18 +282,13 @@ def calc_timestep_runtime(self, setup_nml):
)
else:
run_runtime = setup_nml['npt']*setup_nml['dt']

# Add the prior runtime and new runtime to the working copy of the
# CICE namelist.
setup_nml['npt'] = run_runtime / setup_nml['dt']
assert (prior_runtime_seconds % setup_nml['dt'] == 0)
setup_nml['istep0'] = int(prior_runtime_seconds / setup_nml['dt'])






def set_local_timestep(self, t_step):
dt = self.ice_in['setup_nml']['dt']
npt = self.ice_in['setup_nml']['npt']
Expand Down
6 changes: 5 additions & 1 deletion payu/models/cice5.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def set_local_timestep(self, t_step):
self.ice_in.write(ice_in_path, force=True)

def setup(self):
# Force creation of a dump (restart) file at end of run
# Force creation of a dump (restart) file at end of run
self.ice_in['setup_nml']['dump_last'] = True

super(Cice5, self).setup()
Expand All @@ -73,4 +73,8 @@ def set_access_timestep(self, t_step):
self.set_local_timestep(t_step)

def calc_runtime(self, setup_nml):
"""
Overrides the cice driver method, as CICE5 in OM2 does not use
the timing information in the cice_in.nml namelist.
"""
pass
40 changes: 30 additions & 10 deletions test/models/test_cice.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@

verbose = True

DEFAULT_YEAR_INIT = 101 # arbitrary value for tests
DEFAULT_DT = 3600 # 1 hour
DEFAULT_CICE_NML = {
"setup_nml": {
"history_dir": "./HISTORY/",
"restart_dir": "./RESTART/",
"year_init": 9999,
"days_per_year": 360,
"year_init": DEFAULT_YEAR_INIT,
"days_per_year": 365,
"ice_ic": "default",
"restart": False,
"pointer_file": "./RESTART/ice.restart_file",
"runtype": "initial",
"npt": 99999,
"dt": 1,
"dt": DEFAULT_DT,
},
"grid_nml": {"grid_file": "./INPUT/grid.nc", "kmt_file": "./INPUT/kmt.nc"},
"icefields_nml": {"f_icy": "x"},
Expand Down Expand Up @@ -69,7 +71,7 @@ def setup_module(module):
"model": "cice",
"exe": "test.exe",
"experiment": ctrldir_basename,
"metadata": {"enable": False},
"metadata": {"enable": False}
}
write_config(config)

Expand All @@ -95,7 +97,6 @@ def empty_workdir():
a clean work directory
"""
expt_workdir.mkdir(parents=True)
print(f"SPENCER {os.path.abspath('.')}")

yield expt_workdir
shutil.rmtree(expt_workdir)
Expand Down Expand Up @@ -191,20 +192,24 @@ class TestClone:
"""
Test setting up the cice model in cloned control directories.
"""
PREVIOUS_ISTEP0 = 0
PREVIOUS_NPT = 8760 # 1 year of 1hr timesteps

@pytest.fixture
def prior_restart_dir_cice4(self, scope="class"):
"""
Create fake prior restart files required by CICE4's setup.
This differs from CICE5, which doesn't require a cice_in.nml
file in the restart directory.
"""
prior_restart_path = expt_archive_dir / "restartxyz"
os.mkdir(prior_restart_path)

# Previous cice_in namelist with time information
restart_cice_in = {"setup_nml": {
"istep0": 100,
"npt": 10,
"dt": 123
"istep0": self.PREVIOUS_ISTEP0,
"npt": self.PREVIOUS_NPT,
"dt": DEFAULT_DT
}}
f90nml.write(restart_cice_in, prior_restart_path/CICE_NML_NAME)

Expand Down Expand Up @@ -294,7 +299,7 @@ def test_restart_clone(self, cice_config_files, ctrldir_repo,
Test that seting up an experiment from a cloned control directory
works when a restart directory is specified.
Use a restart directory mimicking the CICE4 restarts required by setup.
Use a restart directory mimicking the CICE4 files required by setup.
"""
source_main = str(ctrldir_repo.active_branch)

Expand All @@ -313,9 +318,13 @@ def test_restart_clone(self, cice_config_files, ctrldir_repo,

# Setup experiment
with cd(cloned_repo_path):

lab = payu.laboratory.Laboratory(lab_path=str(labdir))
expt = payu.experiment.Experiment(lab, reproduce=False)

# Add a runtime to test calculated cice runtime values
expt.runtime = {"years": 0,
"months": 0,
"days": 2}
model = expt.models[0]

# Test that model setup runs without issue
Expand All @@ -324,6 +333,17 @@ def test_restart_clone(self, cice_config_files, ctrldir_repo,
work_path_files = os.listdir(model.work_path)
assert CICE_NML_NAME in work_path_files

# Check correct run time values written to work namelist
work_cice_nml = f90nml.read(
os.path.join(model.work_path, CICE_NML_NAME)
)
assert work_cice_nml["setup_nml"]["istep0"] == (
self.PREVIOUS_ISTEP0 + self.PREVIOUS_NPT
)
assert work_cice_nml["setup_nml"]["npt"] == (
48
)

# Check restart files were copied to cloned experiment's
# work directory.
cice_work_restart_files = os.listdir(model.work_restart_path)
Expand Down
3 changes: 1 addition & 2 deletions test/models/test_cice5.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ def empty_workdir():
a clean work directory
"""
expt_workdir.mkdir(parents=True)
print(f"SPENCER {expt_workdir}")

yield expt_workdir
shutil.rmtree(expt_workdir)
Expand Down Expand Up @@ -224,7 +223,7 @@ def prior_restart_dir_cice5(self, scope="class"):
"""
Create fake prior restart files required by CICE5's setup.
"""
prior_restart_path = expt_archive_dir / "restartxyz"
prior_restart_path = expt_archive_dir / "restartXYZ"
os.mkdir(prior_restart_path)

# Restart files required by CICE5 setup
Expand Down

0 comments on commit 10f5122

Please sign in to comment.