Skip to content

Commit

Permalink
Merge pull request #507 from payu-org/iss499
Browse files Browse the repository at this point in the history
Don't require `cice_in.nml` namelist in CICE5 restarts
  • Loading branch information
blimlim authored Sep 23, 2024
2 parents 68d8482 + c39f45e commit 51e60c1
Show file tree
Hide file tree
Showing 4 changed files with 485 additions and 78 deletions.
83 changes: 55 additions & 28 deletions payu/models/cice.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,6 @@ def setup(self):
self.ice_in.patch(history_nml)

setup_nml = self.ice_in['setup_nml']
init_date = datetime.date(year=setup_nml['year_init'], month=1, day=1)

if setup_nml['days_per_year'] == 365:
caltype = cal.NOLEAP
else:
caltype = cal.GREGORIAN

if self.prior_restart_path:
# Generate ice.restart_file
Expand All @@ -185,8 +179,8 @@ def setup(self):
iced_restart_file = sorted(iced_restart_files)[-1]

if iced_restart_file is None:
print('payu: error: No restart file available.')
sys.exit(errno.ENOENT)
raise FileNotFoundError(
f'No iced restart file found in {self.prior_restart_path}')

res_ptr_path = os.path.join(self.work_init_path,
'ice.restart_file')
Expand All @@ -201,6 +195,43 @@ def setup(self):
setup_nml['runtype'] = 'continue'
setup_nml['restart'] = True

else:
# Locate and link any restart files (if required)
if not setup_nml['ice_ic'] in ('none', 'default'):
self.link_restart(setup_nml['ice_ic'])

if setup_nml['restart']:
self.link_restart(setup_nml['pointer_file'])

self._calc_runtime()

# 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_runtime(self):
"""
Calculate 1: the previous number of timesteps simulated, and 2:
the number of timesteps to simulate in the next run.
Modifies the working self.ice_in namelist in place
Note 1: This method is overridden in the cice5 driver.
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.
"""
setup_nml = self.ice_in['setup_nml']

init_date = datetime.date(year=setup_nml['year_init'], month=1, day=1)
if setup_nml['days_per_year'] == 365:
caltype = cal.NOLEAP
else:
caltype = cal.GREGORIAN

if self.prior_restart_path:

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

Expand All @@ -221,22 +252,17 @@ def setup(self):
prior_setup_nml = f90nml.read(prior_nml_path)['setup_nml']

# The total time in seconds since the beginning of the experiment
total_runtime = prior_setup_nml['istep0'] + prior_setup_nml['npt']
total_runtime = total_runtime * prior_setup_nml['dt']
else:
# Locate and link any restart files (if required)
if not setup_nml['ice_ic'] in ('none', 'default'):
self.link_restart(setup_nml['ice_ic'])

if setup_nml['restart']:
self.link_restart(setup_nml['pointer_file'])
prior_runtime = prior_setup_nml['istep0'] + prior_setup_nml['npt']
prior_runtime_seconds = prior_runtime * prior_setup_nml['dt']

# Initialise runtime
total_runtime = 0
else:
# 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, total_runtime,
run_start_date = cal.date_plus_seconds(init_date,
prior_runtime_seconds,
caltype)
run_runtime = cal.runtime_from_date(
run_start_date,
Expand All @@ -249,13 +275,11 @@ def setup(self):
else:
run_runtime = setup_nml['npt']*setup_nml['dt']

# Now write out new run start date and total runtime.
# Add the prior runtime and new runtime to the working copy of the
# CICE namelist.
setup_nml['npt'] = run_runtime / setup_nml['dt']
assert(total_runtime % setup_nml['dt'] == 0)
setup_nml['istep0'] = int(total_runtime / setup_nml['dt'])

nml_path = os.path.join(self.work_path, self.ice_nml_fname)
self.ice_in.write(nml_path, force=True)
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']
Expand Down Expand Up @@ -326,6 +350,9 @@ def link_restart(self, fpath):
if os.path.isfile(test_path):
input_path = test_path
break
assert input_path
if input_path is None:
raise RuntimeError(
f"Cannot find previous restart file, expected {fpath} to exist"
)

make_symlink(input_path, input_work_path)
9 changes: 8 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 @@ -71,3 +71,10 @@ def set_access_timestep(self, t_step):
# TODO: Figure out some way to move this to the ACCESS driver
# Re-read ice timestep and move this over there
self.set_local_timestep(t_step)

def _calc_runtime(self):
"""
Overrides the cice driver method, as CICE5 can store the timing information in restart files does not use
the timing information in the cice_in.nml namelist.
"""
pass
Loading

0 comments on commit 51e60c1

Please sign in to comment.