Source code for pycif.plugins.models.wrfchem.io.inputs.params
import os
import f90nml
import shutil
import logging
import numpy as np
import datetime as dtm
from ......utils.check.errclass import CifValueError
"""
STATUS: Adaptation from CTDAS in progress.
"""
[docs]
def update_namelist_file(namelist, datei, datef, is_restart, runsubdir):
"""Update namelist.input file for run
Updated values:
- start time, end time
- restart timestep
- restart flag
Note: format of namelist.input is slightly different after
running this:
- 19, 19, -> 19, 19
- 00 -> 0
- 2. -> 2.0
- "wrfchemi_d<domain>_<date>" -> "wrfchemi_d<domain>_<date>"
This could be adjusted in f90nml settings, but it doesn't
seem to matter to WRF.
VERSION HISTORY
2021-10-06 freum Replaced instances of 'self' with instances of
'namelist', fixed call to f90nml.patch
2021-09-26 freum Misc
- commented restart timestep and interval
- added runsubdir as argument
2021-08-18 freum Modified from CTDAS
- replaced dates
- commented fp_original
"""
# Set start and end time in namelist
_set_namelist_time(namelist, "start_", datei)
_set_namelist_time(namelist, "end_", datef)
# Set restart interval
intrvl_timedelta = datef - datei
intrvl_mins = intrvl_timedelta.total_seconds()/60
# Cast to integer
if np.abs(intrvl_mins-np.floor(intrvl_mins)) > np.finfo(float).eps:
msg = "Cannot safely cast restart_interval in WRF " + \
"namelist to integer. Without this casting, " + \
"restart-files might not be created. Stopping."
raise CifValueError(msg)
# Set restart interval, but only if the interval
# would not reach datef
intrvl_nml = namelist["time_control"]["restart_interval"]
if intrvl_mins // int(intrvl_nml) != 0:
logging.info("Resetting restart interval to " + str(int(intrvl_mins)))
namelist["time_control"]["restart_interval"] = int(intrvl_mins)
# the restart flag, so I guess this is the right value to use...)
if is_restart:
logging.info("Configuring WRF-Chem to perform restart.")
namelist["time_control"]["restart"] = True
else:
logging.info("Configuring WRF-Chem to perform cold start.")
namelist["time_control"]["restart"] = False
# Write namelist changes to file
# Patch cannot write to input file, so need to create a temporary
# file
fp = os.path.join(runsubdir, "namelist.input")
fp_tmp = fp + ".tmp"
shutil.copy2(fp, fp_tmp)
f90nml.patch(fp_tmp, namelist, fp)
os.remove(fp_tmp)
return namelist
def _set_namelist_time(namelist, prefix, date):
""" Inserts datetime object into namelist dictionary."""
if not isinstance(date, dtm.datetime):
logging.error("set_namelist_time: argument date must be a " +
"datetime.datetime- object")
# Incidentally, names of datetime components WRF namelists are
# identical to those in datetime objects. Therefore, we can set
# them by iterating over their names.
time_components = ["year", "month", "day", "hour", "minute", "second"]
for time_component in time_components:
namelist["time_control"][prefix + time_component] = \
_repeat_per_domain(namelist, getattr(date, time_component))
def _repeat_per_domain(namelist, value):
""" Output: list of 'value' repeated max_dom times."""
n_domains = namelist["domains"]["max_dom"]
return [value] * n_domains