Skip to main content

Python package for working with ADCIRC input and output files.

Project description

ADCIRCPy

Python library for automating ADCIRC model runs.

tests build codecov version license style documentation

Documentation can be found at https://adcircpy.readthedocs.io

Installation notes:

Please use a virtual environment with Python>=3.6. You may use conda or the OS's Python to provide a virtual environment for the application.

You may install the application though pip. This will install the latest tagged version.

pip install adcircpy

Alternatively, you many manually install the repo by cloning it and then running

pip install .

Command Line:

This program exposes a few commands available from the command line interface. You may pass the -h flag to any of this commands to explore their functionality.

  • tide_gen
  • plot_mesh
  • tidal_run
  • best_track_run
  • best_track_file
  • plot_maxele
  • plot_fort61
  • fort63

Command line examples:

Generate tidal constituent template from command line

You can quickly create a tidal component table for your your mesh by executing the tide_gen command and by passing a mesh, a start date and number of run days as arguments. This functions sources data from the HAMTIDE database by default.

tide_gen \
    /path/to/your/fort.14 \
    2021-02-26T00:00:00 \
    15 \
    --mesh-crs='epsg:4326'
Hurricane Sandy (AL182012)

To create the ADCIRC input files includes both tides and storm data for Hurricane Sandy:

best_track_run \
    /path/to/your/fort.14 \
    Sandy2012 \
    --fort13=/path/to/your/fort.13 \
    --crs=EPSG:4326 \
    --output-directory=/path/where/you/want/the/files \
    --constituents=all \
    --spinup-days=15.0 \
    --elev=30. \
    --mete=30. \
    --velo=30. \
    --skip-run

Note that the --crs flag is required due to the fort.14 not containing Coordinate Reference System information which is required for correct operation. EPSG:4326 means that the mesh is in WGS84 ( lat/lon). Note that the backlash represents "continue on next line" for the shell. You may write the command above on a single line after excluding the backslashes.

Quick plots

These are two examples for doing quick plots with the package. These are given here as illustrative examples only. There is support for more file types than this examples, but the program does not yet support every output input/output file type. As a user, you are encouraged to explore what's available and suggest and contribute your improvements.

plot_fort61 /path/to/fort.61.nc MSL --show --coops-only
plot_mesh /path/to/fort.14 --show-elements

Python API:

See the examples directory for usage examples.

example_1.py

The following code builds a simple ADCIRC run configuration by doing the following:

  1. reads a fort.14 mesh file (specifically a test mesh for Shinnecock Inlet)
  2. adds tidal forcing to the mesh
  3. creates an AdcircRun driver object with the mesh, including start and end dates
  4. overrides default model options in the resulting fort.15
  5. runs ADCIRC if present, otherwise writes configuration to disk
from datetime import datetime, timedelta
import logging
from pathlib import Path
import shutil

from adcircpy import AdcircMesh, AdcircRun, Tides
from adcircpy.utilities import download_mesh

DATA_DIRECTORY = Path(__file__).parent.absolute() / 'data'
INPUT_DIRECTORY = DATA_DIRECTORY / 'input' / 'shinnecock'
OUTPUT_DIRECTORY = DATA_DIRECTORY / 'output' / 'example_1'

MESH_URL = 'https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1'
MESH_DIRECTORY = INPUT_DIRECTORY / 'shinnecock'

download_mesh(
    url=MESH_URL, directory=MESH_DIRECTORY,
)

# open mesh file
mesh = AdcircMesh.open(MESH_DIRECTORY / 'fort.14', crs=4326)

# initialize tidal forcing and constituents
tidal_forcing = Tides()
tidal_forcing.use_constituent('M2')
tidal_forcing.use_constituent('N2')
tidal_forcing.use_constituent('S2')
tidal_forcing.use_constituent('K1')
tidal_forcing.use_constituent('O1')
mesh.add_forcing(tidal_forcing)

# set simulation dates
duration = timedelta(days=5)
start_date = datetime(2015, 12, 14)
end_date = start_date + duration

# instantiate driver object
driver = AdcircRun(mesh, start_date, end_date)

# request outputs
driver.set_elevation_surface_output(sampling_rate=timedelta(minutes=30))
driver.set_velocity_surface_output(sampling_rate=timedelta(minutes=30))

# override default options so the resulting `fort.15` matches the original Shinnecock test case options
driver.timestep = 6.0
driver.DRAMP = 2.0
driver.TOUTGE = 3.8
driver.TOUTGV = 3.8
driver.smagorinsky = False
driver.horizontal_mixing_coefficient = 5.0
driver.gwce_solution_scheme = 'semi-implicit-legacy'

if shutil.which('padcirc') is not None:
    driver.run(OUTPUT_DIRECTORY, overwrite=True)
elif shutil.which('adcirc') is not None:
    driver.run(OUTPUT_DIRECTORY, overwrite=True, nproc=1)
else:
    logging.warning(
        'ADCIRC binaries were not found in PATH. '
        'ADCIRC will not run. Writing files to disk...'
    )
    driver.write(OUTPUT_DIRECTORY, overwrite=True)

example_2.py

The following code is similar to example_1.py, above, except it adds a static Manning's N coefficient to the mesh.

from datetime import datetime, timedelta
import logging
from pathlib import Path
import shutil

import numpy

from adcircpy import AdcircMesh, AdcircRun, Tides
from adcircpy.utilities import download_mesh

DATA_DIRECTORY = Path(__file__).parent.absolute() / 'data'
INPUT_DIRECTORY = DATA_DIRECTORY / 'input'
OUTPUT_DIRECTORY = DATA_DIRECTORY / 'output' / 'example_2'

MESH_URL = 'https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1'
MESH_DIRECTORY = INPUT_DIRECTORY / 'shinnecock'

download_mesh(
    url=MESH_URL, directory=MESH_DIRECTORY,
)

# open mesh file
mesh = AdcircMesh.open(MESH_DIRECTORY / 'fort.14', crs=4326)

# generate tau0 factor
mesh.generate_tau0()

# also add Manning's N to the domain (constant for this example)
mesh.mannings_n_at_sea_floor = numpy.full(mesh.values.shape, 0.025)

# initialize tidal forcing and constituents
tidal_forcing = Tides()
tidal_forcing.use_constituent('M2')
tidal_forcing.use_constituent('N2')
tidal_forcing.use_constituent('S2')
tidal_forcing.use_constituent('K1')
tidal_forcing.use_constituent('O1')
mesh.add_forcing(tidal_forcing)

# set simulation dates
spinup_time = timedelta(days=2)
duration = timedelta(days=3)
start_date = datetime(2015, 12, 14) + spinup_time
end_date = start_date + duration

# instantiate driver object
driver = AdcircRun(mesh, start_date, end_date, spinup_time)

# request outputs
driver.set_elevation_surface_output(sampling_rate=timedelta(minutes=30))
driver.set_velocity_surface_output(sampling_rate=timedelta(minutes=30))

# override default options
driver.timestep = 4.0

if shutil.which('padcirc') is not None:
    driver.run(OUTPUT_DIRECTORY, overwrite=True)
elif shutil.which('adcirc') is not None:
    driver.run(OUTPUT_DIRECTORY, overwrite=True, nproc=1)
else:
    logging.warning(
        'ADCIRC binaries were not found in PATH. '
        'ADCIRC will not run. Writing files to disk...'
    )
    driver.write(OUTPUT_DIRECTORY, overwrite=True)

example_3.py

The following code is similar to example_1.py, above, except it adds HURDAT BestTrack wind forcing and also builds a Slurm job script for submission to a job manager.

from datetime import datetime, timedelta
from pathlib import Path

from adcircpy import AdcircMesh, AdcircRun, Tides
from adcircpy.forcing.winds import BestTrackForcing
from adcircpy.server import SlurmConfig
from adcircpy.utilities import download_mesh

DATA_DIRECTORY = Path(__file__).parent.absolute() / 'data'
INPUT_DIRECTORY = DATA_DIRECTORY / 'input'
OUTPUT_DIRECTORY = DATA_DIRECTORY / 'output' / 'test_example_3'

MESH_URL = 'https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1'
MESH_DIRECTORY = INPUT_DIRECTORY / 'shinnecock'

download_mesh(
    url=MESH_URL, directory=MESH_DIRECTORY,
)

# open mesh file
mesh = AdcircMesh.open(MESH_DIRECTORY / 'fort.14', crs=4326)

# initialize tidal forcing and constituents
tidal_forcing = Tides()
tidal_forcing.use_all()
mesh.add_forcing(tidal_forcing)

# initialize wind forcing
wind_forcing = BestTrackForcing('Sandy2012')
mesh.add_forcing(wind_forcing)

# initialize Slurm configuration
slurm = SlurmConfig(
    account='account',
    ntasks=1000,
    run_name='adcircpy/examples/test_example_3.py',
    partition='partition',
    walltime=timedelta(hours=8),
    mail_type='all',
    mail_user='example@email.gov',
    log_filename='test_example_3.log',
    modules=['intel/2020', 'impi/2020', 'netcdf/4.7.2-parallel'],
    path_prefix='$HOME/adcirc/build',
)

# set simulation dates
spinup_time = timedelta(days=15)
duration = timedelta(days=3)
start_date = datetime(2012, 10, 21, 18)
end_date = start_date + duration

# instantiate driver object
driver = AdcircRun(mesh, start_date, end_date, spinup_time, server_config=slurm)

# write driver state to disk
driver.write(OUTPUT_DIRECTORY, overwrite=True)

example_4.py

The following code is similar to example_3.py, above, except it uses ATMESH wind forcing and WW3DATA wave forcing.

from datetime import datetime, timedelta
from pathlib import Path

from adcircpy import AdcircMesh, AdcircRun, Tides
from adcircpy.forcing.waves.ww3 import WaveWatch3DataForcing
from adcircpy.forcing.winds.atmesh import AtmosphericMeshForcing
from adcircpy.server import SlurmConfig
from adcircpy.utilities import download_mesh

DATA_DIRECTORY = Path(__file__).parent.absolute() / 'data'
INPUT_DIRECTORY = DATA_DIRECTORY / 'input'
OUTPUT_DIRECTORY = DATA_DIRECTORY / 'output' / 'example_4'

MESH_URL = 'https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1'
MESH_DIRECTORY = INPUT_DIRECTORY / 'shinnecock'

download_mesh(
    url=MESH_URL, directory=MESH_DIRECTORY,
)

# open mesh file
mesh = AdcircMesh.open(MESH_DIRECTORY / 'fort.14', crs=4326)

# initialize tidal forcing and constituents
tidal_forcing = Tides()
tidal_forcing.use_all()
mesh.add_forcing(tidal_forcing)

# initialize atmospheric mesh forcings (for NUOPC coupling)
wind_forcing = AtmosphericMeshForcing(
    filename='Wind_HWRF_SANDY_Nov2018_ExtendedSmoothT.nc', nws=17, interval_seconds=3600,
)
mesh.add_forcing(wind_forcing)

# initialize wave mesh forcings (for NUOPC coupling)
wave_forcing = WaveWatch3DataForcing(
    filename='ww3.HWRF.NOV2018.2012_sxy.nc', nrs=5, interval_seconds=3600,
)
mesh.add_forcing(wave_forcing)

# initialize Slurm configuration
slurm = SlurmConfig(
    account='account',
    ntasks=1000,
    run_name='adcircpy/examples/example_4.py',
    partition='partition',
    walltime=timedelta(hours=8),
    mail_type='all',
    mail_user='example@email.gov',
    log_filename='example_4.log',
    modules=['intel/2020', 'impi/2020', 'netcdf/4.7.2-parallel'],
    path_prefix='$HOME/adcirc/build',
)

# instantiate driver object
driver = AdcircRun(
    mesh=mesh,
    start_date=datetime.now(),
    end_date=timedelta(days=7),
    spinup_time=timedelta(days=5),
    server_config=slurm,
)

# write driver state to disk
driver.write(OUTPUT_DIRECTORY, overwrite=True)

Acknowledgements

The majority of ADCIRCpy was written by @jreniel.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

adcircpy-1.1.2.tar.gz (100.5 kB view details)

Uploaded Source

Built Distribution

adcircpy-1.1.2-py3-none-any.whl (118.6 kB view details)

Uploaded Python 3

File details

Details for the file adcircpy-1.1.2.tar.gz.

File metadata

  • Download URL: adcircpy-1.1.2.tar.gz
  • Upload date:
  • Size: 100.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.10

File hashes

Hashes for adcircpy-1.1.2.tar.gz
Algorithm Hash digest
SHA256 6ed7c2e4ab7573273efaf271b88aa1e318a27c539be5ad04ac09fd3abfea4379
MD5 8b0c0cf91d606169a797ae6ffde17b2d
BLAKE2b-256 fe931651ac98ab73701e1073620634f97c4fa706fca5beaca94a406611296e02

See more details on using hashes here.

File details

Details for the file adcircpy-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: adcircpy-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 118.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.10

File hashes

Hashes for adcircpy-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a4bf2dd5cbec40f0ff450cf4b2b661dfd6feb3a14bb37c02b6c785c5819231d2
MD5 2cf8b4ac841c0e24ede79770b79b5603
BLAKE2b-256 78d4bafe6cf481a45da89c3eeca01fd64869a27f4163be98a3c5a1e4ded0df7c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page