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