Package: adcircpy
ADCIRCPyPython library for automating ADCIRC model runs.Documentation can be found athttps://adcircpy.readthedocs.ioOrganization / ResponsibilityADCIRCpy is currently maintained by theCoastal Marine Modeling Branch (CMMB)of the
Office of Coast Survey (OCS), a part of theNational Oceanic and Atmospheric Administration (NOAA), an
agency of the United States federal government. It was majorly developed by@jreniel.Zachary Burnett (lead) -zachary.burnett@noaa.govJaime Calzada -jrcalzada@vims.eduInstallationPlease 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.pipinstalladcircpyAlternatively, you many manually install the repo by cloning it and then runningpipinstall.UsageCommand Line Interface (CLI)This program exposes a few commands available from the command line interface. You may pass the-hflag to any of this
commands to explore their functionality.tide_genplot_meshtidal_runbest_track_runbest_track_fileplot_maxeleplot_fort61fort63examplesgenerate tidal constituent templateYou can quickly create a tidal component table for your your mesh by executing thetide_gencommand and by passing a mesh, a
start date and number of run days as arguments. This functions sources data from
theHAMTIDEdatabase by default.tide_gen\/path/to/your/fort.14\2021-02-26T00:00:00\15\--mesh-crs='epsg:4326'run best-track run for 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-runNote that the --crs flag is required due to the fort.14 not containing Coordinate Reference System information which is
required for correct operation.EPSG:4326means 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.plot resultsThese 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.ncMSL--show--coops-onlyplot_mesh/path/to/fort.14--show-elementsPython APISee theexamplesdirectory for usage examples.example_1.pyThe following code builds a simple ADCIRC run configuration by doing the following:reads afort.14mesh file (specifically a test mesh for Shinnecock Inlet)adds tidal forcing to the meshcreates anAdcircRundriver object with the mesh, including start and end datesoverrides default model options in the resultingfort.15runs ADCIRC if present, otherwise writes configuration to diskfromdatetimeimportdatetime,timedeltafrompathlibimportPathimportshutilfromadcircpyimportAdcircMesh,AdcircRun,Tidesfromadcircpy.utilitiesimportdownload_mesh,get_loggerLOGGER=get_logger(__name__)DATA_DIRECTORY=Path(__file__).parent.absolute()/'data'INPUT_DIRECTORY=DATA_DIRECTORY/'input'/'shinnecock'OUTPUT_DIRECTORY=DATA_DIRECTORY/'output'/'example_1'MESH_DIRECTORY=INPUT_DIRECTORY/'shinnecock'download_mesh(url='https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1',directory=MESH_DIRECTORY,known_hash='99d764541983bfee60d4176af48ed803d427dea61243fa22d3f4003ebcec98f4',)# open mesh filemesh=AdcircMesh.open(MESH_DIRECTORY/'fort.14',crs=4326)# initialize tidal forcing and constituentstidal_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 datesduration=timedelta(days=5)start_date=datetime(2015,12,14)end_date=start_date+duration# instantiate driver objectdriver=AdcircRun(mesh,start_date,end_date)# request outputsdriver.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 optionsdriver.timestep=6.0driver.DRAMP=2.0driver.TOUTGE=3.8driver.TOUTGV=3.8driver.smagorinsky=Falsedriver.horizontal_mixing_coefficient=5.0driver.gwce_solution_scheme='semi-implicit-legacy'ifshutil.which('padcirc')isnotNone:driver.run(OUTPUT_DIRECTORY,overwrite=True)elifshutil.which('adcirc')isnotNone:driver.run(OUTPUT_DIRECTORY,overwrite=True,nproc=1)else:LOGGER.warning('ADCIRC binaries were not found in PATH. ''ADCIRC will not run. Writing files to disk...')driver.write(OUTPUT_DIRECTORY,overwrite=True)example_2.pyThe following code is similar toexample_1.py, above, except it adds a static Manning's N coefficient to the mesh.fromdatetimeimportdatetime,timedeltafrompathlibimportPathimportshutilimportnumpyfromadcircpyimportAdcircMesh,AdcircRun,Tidesfromadcircpy.utilitiesimportdownload_mesh,get_loggerLOGGER=get_logger(__name__)DATA_DIRECTORY=Path(__file__).parent.absolute()/'data'INPUT_DIRECTORY=DATA_DIRECTORY/'input'OUTPUT_DIRECTORY=DATA_DIRECTORY/'output'/'example_2'MESH_DIRECTORY=INPUT_DIRECTORY/'shinnecock'download_mesh(url='https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1',directory=MESH_DIRECTORY,known_hash='99d764541983bfee60d4176af48ed803d427dea61243fa22d3f4003ebcec98f4',)# open mesh filemesh=AdcircMesh.open(MESH_DIRECTORY/'fort.14',crs=4326)# generate tau0 factormesh.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 constituentstidal_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 datesspinup_time=timedelta(days=2)duration=timedelta(days=3)start_date=datetime(2015,12,14)+spinup_timeend_date=start_date+duration# instantiate driver objectdriver=AdcircRun(mesh,start_date,end_date,spinup_time)# request outputsdriver.set_elevation_surface_output(sampling_rate=timedelta(minutes=30))driver.set_velocity_surface_output(sampling_rate=timedelta(minutes=30))# override default optionsdriver.timestep=4.0ifshutil.which('padcirc')isnotNone:driver.run(OUTPUT_DIRECTORY,overwrite=True)elifshutil.which('adcirc')isnotNone:driver.run(OUTPUT_DIRECTORY,overwrite=True,nproc=1)else:LOGGER.warning('ADCIRC binaries were not found in PATH. ''ADCIRC will not run. Writing files to disk...')driver.write(OUTPUT_DIRECTORY,overwrite=True)example_3.pyThe following code is similar toexample_1.py, above, except it adds HURDAT BestTrack wind forcing and also builds a Slurm
job script for submission to a job manager.fromdatetimeimportdatetime,timedeltafrompathlibimportPathfromadcircpyimportAdcircMesh,AdcircRun,Tidesfromadcircpy.forcing.windsimportBestTrackForcingfromadcircpy.serverimportSlurmConfigfromadcircpy.utilitiesimportdownload_meshDATA_DIRECTORY=Path(__file__).parent.absolute()/'data'INPUT_DIRECTORY=DATA_DIRECTORY/'input'OUTPUT_DIRECTORY=DATA_DIRECTORY/'output'/'example_3'MESH_DIRECTORY=INPUT_DIRECTORY/'shinnecock'download_mesh(url='https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1',directory=MESH_DIRECTORY,known_hash='99d764541983bfee60d4176af48ed803d427dea61243fa22d3f4003ebcec98f4',)# open mesh filemesh=AdcircMesh.open(MESH_DIRECTORY/'fort.14',crs=4326)# initialize tidal forcing and constituentstidal_forcing=Tides()tidal_forcing.use_all()mesh.add_forcing(tidal_forcing)# initialize wind forcingwind_forcing=BestTrackForcing('Sandy2012')mesh.add_forcing(wind_forcing)# initialize Slurm configurationslurm=SlurmConfig(account='account',ntasks=1000,run_name='adcircpy/examples/example_3.py',partition='partition',walltime=timedelta(hours=8),mail_type='all',mail_user='example@email.gov',log_filename='example_3.log',modules=['intel/2020','impi/2020','netcdf/4.7.2-parallel'],path_prefix='$HOME/adcirc/build',)# set simulation datesspinup_time=timedelta(days=15)duration=timedelta(days=3)start_date=datetime(2012,10,21,18)end_date=start_date+duration# instantiate driver objectdriver=AdcircRun(mesh,start_date,end_date,spinup_time,server_config=slurm)# write driver state to diskdriver.write(OUTPUT_DIRECTORY,overwrite=True)example_4.pyThe following code is similar toexample_3.py, above, except it uses ATMESH wind forcing and WW3DATA wave forcing.fromdatetimeimportdatetime,timedeltafrompathlibimportPathfromadcircpyimportAdcircMesh,AdcircRun,Tidesfromadcircpy.forcing.waves.ww3importWaveWatch3DataForcingfromadcircpy.forcing.winds.atmeshimportAtmosphericMeshForcingfromadcircpy.serverimportSlurmConfigfromadcircpy.utilitiesimportdownload_meshDATA_DIRECTORY=Path(__file__).parent.absolute()/'data'INPUT_DIRECTORY=DATA_DIRECTORY/'input'OUTPUT_DIRECTORY=DATA_DIRECTORY/'output'/'example_4'MESH_DIRECTORY=INPUT_DIRECTORY/'shinnecock'download_mesh(url='https://www.dropbox.com/s/1wk91r67cacf132/NetCDF_shinnecock_inlet.tar.bz2?dl=1',directory=MESH_DIRECTORY,known_hash='99d764541983bfee60d4176af48ed803d427dea61243fa22d3f4003ebcec98f4',)# open mesh filemesh=AdcircMesh.open(MESH_DIRECTORY/'fort.14',crs=4326)# initialize tidal forcing and constituentstidal_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 configurationslurm=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 objectdriver=AdcircRun(mesh=mesh,start_date=datetime.now(),end_date=timedelta(days=7),spinup_time=timedelta(days=5),server_config=slurm,)# write driver state to diskdriver.write(OUTPUT_DIRECTORY,overwrite=True)CitationCalzada, J., Burnett, Z., Moghimi, S., Myers, E., & Pe’eri, S. (2021). ADCIRCpy: A Python API to generate ADCIRC model input files (Technical Memorandum No. 41; NOAA NOS OCS). National Oceanic and Atmospheric Administation.@techreport{calzadaADCIRCpyPythonAPI2021,type={Technical {{Memorandum}}},title={{{ADCIRCpy}}: A {{Python API}} to Generate {{ADCIRC}} Model Input Files},author={Calzada, Jaime and Burnett, Zachary and Moghimi, Saeed and Myers, Edward and Pe'eri, Shachak},year={2021},month=dec,number={41},institution={{National Oceanic and Atmospheric Administation}},abstract={The Advanced Circulation Model (ADCIRC) is a Fortran program used for modeling ocean circulation due to tides, surface waves and atmospheric forcings. However, the input formats and configuration are inflexible and not straight forward for operational implementation, making rapid iteration of model testing, ensemble configuration, and model coupling complicated. Here, we introduce a flexible abstraction of model inputs and outputs written in Python, called ADCIRCpy, that provides a simpler user interface for automatically generating ADCIRC configuration to a variety of inputs and model scenarios. This documentation outlines 1. the needs for such an abstraction, 2. the peculiarities and challenges with the ADCIRC model that necessitate custom logic, and 3. methodologies for generalizing user input in such a way as to make generating model configurations consistent, fast, and efficient.}}AcknowledgementsThe majority of ADCIRCpy was written by Jaime Calzada@jreniel.