Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coastal #1

Merged
merged 22 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__
18 changes: 18 additions & 0 deletions coastal/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
TARGETS = format lint test typecheck

.PHONY: $(TARGETS)

all:
$(error Valid targets are: $(TARGETS))

format:
black *.py
isort *.py

lint:
pylint *.py

test: lint typecheck

typecheck:
mypy *.py
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved
46 changes: 46 additions & 0 deletions coastal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Coastal

To execute this driver, in a conda environment where [`uwtools`](https://github.com/ufs-community/uwtools) is [installed](https://uwtools.readthedocs.io/en/stable/sections/user_guide/installation.html):

```
uw execute --module coastal.py --classname Coastal --task provisioned_rundir --config-file coastal.yaml --cycle 2024-08-05T12 --batch
```

Afterwards:

```
$ tree run
run
├── albedo.gr3 -> /path/to/data/albedo.gr3
├── bctides.in -> /path/to/data/bctides.in
├── datm_in
├── datm.streams
├── fd_ufs.yaml -> /path/to/model/tests/parm/fd_ufs.yaml
├── hgrid.gr3 -> /path/to/data/hgrid.gr3
├── hgrid.ll -> /path/to/data/hgrid.ll
├── INPUT
│   ├── data.nc -> /path/to/data/INPUT/wind_atm_fin_ch_time_vec_STR_fixed.nc
│   └── esmf_mesh.nc -> /path/to/data/INPUT/wind_atm_fin_ch_time_vec_ESMFmesh.nc
├── manning.gr3 -> /path/to/data/manning.gr3
├── model_configure -> /path/to/data/model_configure
├── noahmptable.tbl -> /path/to/data/noahmptable.tbl
├── param.nml
├── RESTART
├── runscript.coastal
├── station.in -> /path/to/data/station.in
├── ufs.configure -> /path/to/data/ufs.configure
├── vgrid.in -> /path/to/data/vgrid.in
├── watertype.gr3 -> /path/to/data/watertype.gr3
└── windrot_geo2proj.gr3 -> /path/to/data/windrot_geo2proj.gr3

2 directories, 19 files
```

To be run in a conda environment with [`uwtools`](https://github.com/ufs-community/uwtools) installed.

For development/testing, with conda active in your shell:

```
$ conda env create -f environment.yml
$ conda activate coastal
```
3 changes: 3 additions & 0 deletions coastal/coastal.jsonschema
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "object"
}
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved
62 changes: 62 additions & 0 deletions coastal/coastal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""
A driver for the Coastal App coupled executable.
"""

from iotaa import asset, task, tasks
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved
from uwtools.api.cdeps import CDEPS
from uwtools.api.driver import DriverCycleBased
from uwtools.api.file import link
from uwtools.api.logging import use_uwtools_logger
from uwtools.api.schism import SCHISM

use_uwtools_logger()


class Coastal(DriverCycleBased):
"""
A driver for the Coastal App coupled executable.
"""

@task
def linked_files(self):
"""
Data files linked into the run directory.
"""
links = self.config["links"]
path = lambda fn: self.rundir / fn
yield self.taskname("Linked files")
yield [asset(path(fn), path(fn).is_file) for fn in links.keys()]
yield None
link(config=links, target_dir=self.rundir)

@tasks
def provisioned_rundir(self):
"""
The run directory provisioned with all required content.
"""
cdeps = CDEPS(config=self.config_full, cycle=self.cycle, controller=self.driver_name)
schism = SCHISM(config=self.config_full, cycle=self.cycle, controller=self.driver_name)
yield self.taskname("Provisioned run directory")
yield [
cdeps.atm_nml(),
cdeps.atm_stream(),
schism.namelist_file(),
self.linked_files(),
self.restart_dir(),
self.runscript(),
]

@task
def restart_dir(self):
"""
RESTART directory in run directory.
"""
path = self.rundir / "RESTART"
yield self.taskname("RESTART directory")
yield asset(path, path.is_dir)
yield None
path.mkdir(parents=True)

@property
def driver_name(self):
return "coastal"
82 changes: 82 additions & 0 deletions coastal/coastal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
cdeps:
atm_in:
update_values:
datm_nml:
datamode: ATMMESH
export_all: true
factorfn_data: 'null'
factorfn_mesh: 'null'
flds_co2: false
flds_presaero: false
flds_wiso: false
iradsw: 1
model_maskfile: INPUT/esmf_mesh.nc
model_meshfile: INPUT/esmf_mesh.nc
nx_global: 101
ny_global: 101
restfilm: 'null'
atm_streams:
streams:
stream01:
dtlimit: 1.5
mapalgo: redist
readmode: single
stream_data_files:
- INPUT/data.nc
stream_data_variables:
- uwnd Sa_u10m
- vwnd Sa_v10m
- P Sa_pslv
stream_lev_dimname: 'null'
stream_mesh_file: INPUT/esmf_mesh.nc
stream_offset: 0
stream_vectors: 'null'
taxmode: limit
tinterpalgo: linear
yearAlign: 2008
yearFirst: 2008
yearLast: 2008
template_file: stream.jinja2
coastal:
execution:
batchargs:
cores: 6
export: NONE
jobname: coastal
partition: hercules
queue: batch
walltime: '00:30:00'
envcmds:
- module use {{ dir.model }}/modulefiles
- module load ufs_hercules.intel
executable: /path/to/ufs_model
mpiargs:
- '--export=ALL'
mpicmd: srun
links:
INPUT/data.nc: '{{ dir.data }}/INPUT/wind_atm_fin_ch_time_vec_STR_fixed.nc'
INPUT/esmf_mesh.nc: '{{ dir.data }}/INPUT/wind_atm_fin_ch_time_vec_ESMFmesh.nc'
albedo.gr3: '{{ dir.data }}/albedo.gr3'
bctides.in: '{{ dir.data }}/bctides.in'
fd_ufs.yaml: '{{ dir.model }}/tests/parm/fd_ufs.yaml'
hgrid.gr3: '{{ dir.data }}/hgrid.gr3'
hgrid.ll: '{{ dir.data }}/hgrid.ll'
manning.gr3: '{{ dir.data }}/manning.gr3'
model_configure: '{{ dir.data }}/model_configure'
noahmptable.tbl: '{{ dir.data }}/noahmptable.tbl'
station.in: '{{ dir.data }}/station.in'
ufs.configure: '{{ dir.data }}/ufs.configure'
vgrid.in: '{{ dir.data }}/vgrid.in'
watertype.gr3: '{{ dir.data }}/watertype.gr3'
windrot_geo2proj.gr3: '{{ dir.data }}/windrot_geo2proj.gr3'
rundir: run
dir:
test: /path/to/coastal/test/input
data: '{{ dir.test }}//data'
model: '{{ dir.test }}//model'
platform:
account: me
scheduler: slurm
schism:
namelist:
template_file: '{{ dir.test }}/param.nml'
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 9 additions & 0 deletions coastal/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: coastal
channels:
- ufs-community
- conda-forge
dependencies:
- black
- mypy
- pylint
- uwtools >=2.4.0
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved
14 changes: 14 additions & 0 deletions coastal/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[tool.black]
line-length = 100

[tool.isort]
line_length = 100
profile = "black"

[tool.mypy]
check_untyped_defs = true
pretty = true
warn_return_any = true

[tool.pylint."messages control"]
disable = ["unnecessary-lambda-assignment"]
33 changes: 33 additions & 0 deletions coastal/stream.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{% set stream_info = [] -%}
{% for key, val in streams.items() -%}
{% set _ = stream_info.append( key ) -%}
{% endfor -%}
stream_info: {{ stream_info | join(' ') }}
{% for key, val in streams.items() %}
taxmode{{'%02d' % loop.index}}: {{ val['taxmode'] }}
mapalgo{{'%02d' % loop.index}}: {{ val['mapalgo'] }}
tInterpAlgo{{'%02d' % loop.index}}: {{ val['tinterpalgo'] }}
readMode{{'%02d' % loop.index}}: {{ val['readmode'] }}
dtlimit{{'%02d' % loop.index}}: {{ val['dtlimit'] }}
stream_offset{{'%02d' % loop.index}}: {{ val['stream_offset'] }}
yearFirst{{'%02d' % loop.index}}: {{ val['yearFirst'] }}
yearLast{{'%02d' % loop.index}}: {{ val['yearLast'] }}
yearAlign{{'%02d' % loop.index}}: {{ val['yearAlign'] }}
{% if val['stream_vectors'] is string -%}
stream_vectors{{'%02d' % loop.index}}: {{ val['stream_vectors'] }}
{% else -%}
stream_vectors{{'%02d' % loop.index}}: "{{ val['stream_vectors'] | join(':') }}"
{% endif -%}
stream_mesh_file{{'%02d' % loop.index}}: {{ val['stream_mesh_file'] }}
stream_lev_dimname{{'%02d' % loop.index}}: {{ val['stream_lev_dimname'] }}
{% if val['stream_data_files'] | length > 1 -%}
stream_data_files{{'%02d' % loop.index}}: ""{{ val['stream_data_files'] | join('" "') }}""
{% else -%}
stream_data_files{{'%02d' % loop.index}}: "{{ val['stream_data_files'] | first }}"
{% endif -%}
{% if val['stream_data_variables'] is string -%}
stream_data_variables{{'%02d' % loop.index}}: "{{ val['stream_data_variables'] }}"
{% else -%}
stream_data_variables{{'%02d' % loop.index}}: "{{ val['stream_data_variables'] | join('" "') }}"
{% endif -%}
{% endfor %}