-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UW-585: Build driver for SCHISM (#506)
* Build Schism driver framework * Formatting fix * fix schema errors * Update src/uwtools/drivers/schism.py Co-authored-by: Paul Madden <[email protected]> * had to add logging to failing test * fix copy/paste name error * Apply suggestions from code review Co-authored-by: Paul Madden <[email protected]> * open template_values to all JSON types --------- Co-authored-by: Paul Madden <[email protected]>
- Loading branch information
1 parent
3509e23
commit dbe1224
Showing
10 changed files
with
281 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ UW YAML for Components | |
make_solo_mosaic | ||
mpas | ||
mpas_init | ||
schism | ||
sfc_climo_gen | ||
shave | ||
ungrib | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.. _schism_yaml: | ||
|
||
schism | ||
====== | ||
|
||
Structured YAML to configure SCHISM as part of a compiled coupled executable is validated by JSON Schema and requires the ``schism:`` block, described below. | ||
|
||
Here is a prototype UW YAML ``schism:`` block, explained in detail below: | ||
|
||
.. highlight:: yaml | ||
.. literalinclude:: /shared/schism.yaml | ||
|
||
UW YAML for the ``schism:`` Block | ||
--------------------------------- | ||
|
||
namelist: | ||
^^^^^^^^^ | ||
|
||
.. important:: The SCHISM namelist file is provisioned by rendering an input template file containing Jinja2 expressions. Unlike namelist files provisioned by ``uwtools`` for other components, the SCHISM namelist file will not be validated. | ||
|
||
**template_file:** | ||
|
||
The path to the input template file containing Jinja2 expressions (perhaps named ``param.nml.IN``), based on the ``param.nml`` file from the SCHISM build. | ||
|
||
**template_values:** | ||
|
||
Key-value pairs necessary to render all Jinja2 expressions in the input template file named by ``template_file:``. | ||
|
||
run_dir: | ||
^^^^^^^^ | ||
|
||
The path to the run directory. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
schism: | ||
namelist: | ||
template_file: /path/to/schism/param.nml.IN | ||
template_values: | ||
dt: 100 | ||
run_dir: /path/to/run/directory | ||
platform: | ||
account: me | ||
scheduler: slurm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
""" | ||
An assets driver for SCHISM. | ||
""" | ||
|
||
from datetime import datetime | ||
from pathlib import Path | ||
from typing import List, Optional | ||
|
||
from iotaa import asset, task, tasks | ||
|
||
from uwtools.api.template import render | ||
from uwtools.drivers.driver import Assets | ||
from uwtools.strings import STR | ||
from uwtools.utils.tasks import file | ||
|
||
|
||
class SCHISM(Assets): | ||
""" | ||
An assets driver for SCHISM. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
cycle: datetime, | ||
config: Optional[Path] = None, | ||
dry_run: bool = False, | ||
batch: bool = False, | ||
key_path: Optional[List[str]] = None, | ||
): | ||
""" | ||
The driver. | ||
:param cycle: The cycle. | ||
:param config: Path to config file (read stdin if missing or None). | ||
:param dry_run: Run in dry-run mode? | ||
:param batch: Run component via the batch system? | ||
:param key_path: Keys leading through the config to the driver's configuration block. | ||
""" | ||
super().__init__( | ||
config=config, dry_run=dry_run, batch=batch, cycle=cycle, key_path=key_path | ||
) | ||
self._cycle = cycle | ||
|
||
# Workflow tasks | ||
|
||
@task | ||
def namelist_file(self): | ||
""" | ||
Render the namelist from the template file. | ||
""" | ||
fn = "param.nml" | ||
yield self._taskname(fn) | ||
path = self._rundir / fn | ||
yield asset(path, path.is_file) | ||
template_file = Path(self._driver_config["namelist"]["template_file"]) | ||
yield file(path=template_file) | ||
render( | ||
input_file=template_file, | ||
output_file=path, | ||
overrides=self._driver_config["namelist"]["template_values"], | ||
) | ||
|
||
@tasks | ||
def provisioned_run_directory(self): | ||
""" | ||
Run directory provisioned with all required content. | ||
""" | ||
yield self._taskname("provisioned run directory") | ||
yield self.namelist_file() | ||
|
||
# Private helper methods | ||
|
||
@property | ||
def _driver_name(self) -> str: | ||
""" | ||
Returns the name of this driver. | ||
""" | ||
return STR.schism |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"properties": { | ||
"schism": { | ||
"additionalProperties": false, | ||
"properties": { | ||
"namelist": { | ||
"additionalProperties": false, | ||
"properties": { | ||
"template_file": { | ||
"type": "string" | ||
}, | ||
"template_values": { | ||
"minProperties": 1, | ||
"type": "object" | ||
} | ||
}, | ||
"required": [ | ||
"template_file" | ||
], | ||
"type": "object" | ||
}, | ||
"run_dir": { | ||
"type": "string" | ||
} | ||
}, | ||
"required": [ | ||
"namelist", | ||
"run_dir" | ||
], | ||
"type": "object" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# pylint: disable=missing-function-docstring,protected-access,redefined-outer-name | ||
""" | ||
SCHISM driver tests. | ||
""" | ||
import datetime as dt | ||
from unittest.mock import DEFAULT as D | ||
from unittest.mock import patch | ||
|
||
import yaml | ||
from pytest import fixture | ||
|
||
from uwtools.drivers import schism | ||
|
||
# Fixtures | ||
|
||
|
||
@fixture | ||
def config(tmp_path): | ||
return { | ||
"schism": { | ||
"namelist": { | ||
"template_file": str(tmp_path / "param.nml.IN"), | ||
"template_values": { | ||
"dt": 100, | ||
}, | ||
}, | ||
"run_dir": str(tmp_path), | ||
}, | ||
} | ||
|
||
|
||
@fixture | ||
def cycle(): | ||
return dt.datetime(2024, 2, 1, 18) | ||
|
||
|
||
@fixture | ||
def driverobj(config, cycle): | ||
return schism.SCHISM(config=config, cycle=cycle, batch=True) | ||
|
||
|
||
# Tests | ||
|
||
|
||
def test_SCHISM(driverobj): | ||
assert isinstance(driverobj, schism.SCHISM) | ||
|
||
|
||
def test_SCHISM_namelist_file(driverobj): | ||
src = driverobj._driver_config["namelist"]["template_file"] | ||
with open(src, "w", encoding="utf-8") as f: | ||
yaml.dump({}, f) | ||
dst = driverobj._rundir / "param.nml" | ||
assert not dst.is_file() | ||
driverobj.namelist_file() | ||
assert dst.is_file() | ||
|
||
|
||
def test_SCHISM_provisioned_run_directory(driverobj): | ||
with patch.multiple( | ||
driverobj, | ||
namelist_file=D, | ||
) as mocks: | ||
driverobj.provisioned_run_directory() | ||
for m in mocks: | ||
mocks[m].assert_called_once_with() | ||
|
||
|
||
def test_SCHISM__driver_config(driverobj): | ||
assert driverobj._driver_config == driverobj._config["schism"] | ||
|
||
|
||
def test_SCHISM__validate(driverobj): | ||
driverobj._validate() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters