Source code for pycif.plugins.models.wrfchem.ini_periods
import numpy as np
import pandas as pd
[docs]
def ini_periods(self, **kwargs):
"""Compute temporal discretisation for the WRF-Chem model.
Splits the full simulation window into sub-simulation periods (using
``self.periods`` if set, otherwise a single window) and derives the
output and input date arrays from the WRF namelist output interval.
Sets on *self*:
* ``subsimu_dates`` — period boundary dates.
* ``tstep_dates`` — per-period time-step arrays (at WRF output frequency).
* ``meteo_dates`` — per-period meteorological input date arrays.
* ``input_dates`` — per-period initial/end-concentration date arrays.
* ``tstep_all`` — sorted unique merge of all time steps.
* ``iniobs``, ``reset_obs`` — per-period observation bookkeeping flags.
* ``chain`` — per-period flag indicating chained restarts.
Args:
self: WRF-Chem model plugin instance with ``datei``, ``datef``,
and ``domain`` (WRF namelist) set.
**kwargs: unused.
"""
datei = self.datei
datef = self.datef
# List of sub-simulation windows
# self.subsimu_dates = date_range(datei, datef, period=self.periods)
# freum:
# - Not using subsimulations for now
# - Explanation in online documentation: "List of the starting dates
# of all the model sub-simulations chained to form the simulation
# window; it should include the end date of the chain simulation
# as well; for instance, LMDZ simulations are split into monthly
# simulations; subsimu_dates would then include the list of the
# first day of every months in the simulation window; if your
# model is not split into sub-simulations, subsimu_dates is a list
# with a single element, the starting date of the overall
# simulation window."
if hasattr(self, "periods"):
self.subsimu_dates = pd.date_range(datei, datef, freq=self.periods)
else:
self.subsimu_dates = np.array([datei, datef])
# Time steps of output are defined by namelist
# For now, this can only handle time steps
# identical in each domain.
# Actually it can only handle one domain at
# this point, but prepare.
wrfout_freqs_min = \
self.namelist["time_control"]["history_interval"]
if len(np.unique(wrfout_freqs_min)) > 1:
msg = \
"Can only handle identical " + \
"history_interval across all domains"
raise NotImplementedError(msg)
else:
wrfout_freq_min = wrfout_freqs_min[0]
# Time interval of flux input is defined
# in namelist (change this?)
wrfchemi_freqs_min = \
self.namelist["time_control"]["auxinput5_interval_m"]
if len(np.unique(wrfchemi_freqs_min)) > 1:
msg = \
"Can only handle identical " + \
"auxinput5_interval_m across all " + \
"domains"
raise NotImplementedError(msg)
else:
wrfchemi_freq_min = wrfout_freqs_min[0]
# Input frequency of meteo data (=that of lbc) is
# defined by namelist
meteo_freq_sec = \
self.namelist["time_control"]["interval_seconds"]
self.tstep_dates = {}
self.meteo_dates = {}
self.flux_dates = {}
for dd0, dd1 in zip(self.subsimu_dates[:-1], self.subsimu_dates[1:]):
self.tstep_dates[dd0] = pd.date_range(
dd0, dd1,
freq=str(wrfout_freq_min) + "min"
).to_pydatetime()
self.meteo_dates[dd0] = pd.date_range(
dd0, dd1,
freq=str(meteo_freq_sec) + "S"
).to_pydatetime()
self.flux_dates[dd0] = pd.date_range(
dd0, dd1,
freq=str(wrfchemi_freq_min) + "min"
).to_pydatetime()
# All time steps unpacked
# This is a nested list comprehension:
# list(self.tstep_dates.values()) is a list with one list of values
# per key. The nested list comprehension picks all elements from
# the sublists one-by-one, so it un-nests this 2-level list.
self.tstep_all = \
np.sort(np.unique(
np.array([x
for l in list(self.tstep_dates.values())
for x in l])))
# Initializes dictionary to keep in memory whether observations were
# already dumped for a given period
#self.iniobs = {ddi: False for ddi in self.subsimu_dates}
self.reset_obs = {ddi: True for ddi in self.subsimu_dates}