Wave Forcing
Breaking waves push water shoreward. The wave field’s momentum flux, the radiation stress [LonguetHiggins1964], varies in space, and its divergence is a force on the water column that sets up the water level where waves break and draws it down just seaward of the breaking zone. In a hurricane this wave setup is a large share of the surge in the surf zone [Dietrich2011].
Cocoa takes that force from one of two sources, chosen by
forcing.wave.source:
A file (External Wave Forcing) carrying the force itself, from any wave model (an ADCIRC+SWAN
rads.64converts directly), or the radiation stress, whose divergence Cocoa takes.Cocoa’s own spectral wave model (Internal Wave Model), run on the circulation mesh and coupled to it every few minutes.
Either way the force enters the equations exactly as the wind stress does. Every key is listed in the configuration reference (Wave Forcing).
Theory
For a spectrum of action density \(N(\sigma, \theta)\) with group and phase speeds \(c_g\) and \(c\), and \(n = c_g / c\), the radiation stress divided by the water density (units m3 s-2) is
The force per unit density, in m2 s-2, the units of the kinematic wind stress \(\boldsymbol{\tau}/\rho_0\), is
The two are one surface stress: they enter the GWCE at time level \(n\) (averaged over an element under the wind limiter) and the momentum equations as the Crank-Nicolson pair
ADCIRC does the same by adding the force into its wind stress array.
Applying the Force
These conventions hold for both sources.
One surface stress. The wave force is summed with the wind stress where the equations read it, so it inherits the wind stress’s wet/dry treatment: the wind limiter near drying nodes and the depth floor in the momentum division. A run without meteorological forcing still applies the wave force.
Divergence of a stress. Where Cocoa differentiates a radiation stress (a stress file, or the internal model’s), the element-mean gradient
uses the same Green coefficients \(b_i\), \(a_i\) ((40)) and momentum scale factors as every other element term, which is exact for the linear stress on a triangle and the bilinear stress on a quadrilateral. A node then takes the area-weighted mean of its elements’ values. The force is zero at a node on the mesh boundary and at a node touching any element that is not wet (not active, or with a dry vertex), as in SWAN: a wave model sets \(S = 0\) at dry nodes, so a gradient there is an artifact of the waterline, not wave forcing.
Ramp. forcing.wave.ramp is the wave force’s own ramp (ADCIRC’s
RampWRad), the same hyperbolic-tangent form as the other ramps. It is on
by default over one day and does not inherit forcing.ramp.
Cap. forcing.wave.cap bounds the magnitude of the ramped force the
equations see, keeping its direction (ADCIRC’s WaveStressGrad_Cap). The
output keeps the uncapped value.
Precision. The force is stored in single precision at two time levels, the precision in which wave models hand over their stresses; all arithmetic is double.
Checkpoints. The force’s current level is checkpointed (the next step stages it as time level \(n\)), so a restart reproduces the uninterrupted run. A restart from a checkpoint written without wave forcing evaluates the force at the resume time.
External Wave Forcing
forcing:
wave:
enabled: true
source: file
filename: "wave_force.nc"
quantity: force # force (default) or stress
ramp:
enabled: false # a converted rads.64 is already ramped
cap: 0.05 # optional, m2 s-2
A file needs source: file, since the internal model is the default.
quantity says what the file carries:
the force, or the radiation stress, whose divergence Cocoa takes each step.
File Format
A NetCDF file with dimensions time and node (the mesh’s node count,
in mesh order):
Variable |
Units |
Content |
|---|---|---|
|
CF, e.g. |
Strictly ascending snapshot times covering the run. |
|
|
Force per unit density, geographic east/north ( |
|
|
Radiation stress per unit density, mesh frame ( |
Values must be finite; dry nodes carry zero. A mesh_id global attribute,
when present, is checked against the run’s mesh. The file is validated at
startup, and every failure names the file and what to fix.
Time. Snapshots are interpolated linearly in time, ADCIRC’s
NRS = 1 reading, and the file must cover the whole run. A stress is
interpolated before its divergence is taken, so every step uses its own wet
mask.
Frames. A force file is geographic east/north and is rotated into the solver frame on a rotated-pole mesh. A stress file is in the mesh frame and is refused on a rotated-pole mesh, where the tensor would need rotating before it is differentiated.
Converting ADCIRC Output
utils/adcirc_rads_to_cocoa.py converts an ADCIRC+SWAN rads.64
(ASCII or NetCDF) into a force file: dry-node values become zero and the
units attribute is corrected.
python utils/adcirc_rads_to_cocoa.py rads.64.nc wave_force.nc --prepend-zero
python utils/adcirc_rads_to_cocoa.py rads.64 wave_force.nc \
--start "2011-08-25 12:00:00" --prepend-zero
rads.64 holds ADCIRC’s ramped force, so run Cocoa with
forcing.wave.ramp.enabled: false. Its first record is one output interval
after the cold start; --prepend-zero adds a zero record at the cold
start, where a ramped ADCIRC run’s force is zero, so the file covers a Cocoa
run beginning at the same time. Write rads.64 at the coupling interval
(NSPOOLGW) for the interpolation to follow the forcing.
Deviations from ADCIRC
Waterline and boundary nodes. Cocoa follows SWAN’s
SwanComputeForceand ADCIRC’sMARCELSWANbuild option: the force is zero at boundary nodes and at nodes touching a dry element. ADCIRC’s default build averages each node’s force over every element around it, dry ones included, which puts an artificial shoreward gradient into waterline nodes. Interior nodes agree with ADCIRC exactly.Nodal gradient. Cocoa keeps ADCIRC’s area-weighted mean of element gradients rather than SWAN’s Green’s-theorem gradient over the polygon joining the centroids of the surrounding cells.
Dryness. An element is dry when Cocoa’s wet/dry scheme marks it inactive or any of its vertices dry, not when a depth falls below SWAN’s
DEPMIN.MARCELSWAN partial sum. At a node touching a dry element, ADCIRC’s
MARCELSWANbranch zeroes the output array instead of its accumulator (couple2swan.F), so the node keeps the undivided sum of the elements visited before the dry one. Cocoa implements the intended zero.Units attribute. ADCIRC’s NetCDF
rads.64labels the forcem-2 s-2; the values are m2 s-2, which is what the converter writes.
Internal Wave Model
With source: model Cocoa runs its own spectral wave model on the same
mesh. Its equations, numerics and source terms, and where each came from,
are in Spectral Wave Model; this section covers running it.
forcing:
wave:
enabled: true
source: model # the default
Every key has a default, and the defaults are the SWAN+ADCIRC hurricane
configuration, so this is a complete setup. The waves take their wind from
forcing.meteorological; without it they have no wind to grow from. The
configuration reference shows every key at its default
(Wave Forcing).
Coupling
At every coupling time \(t_k\) the model takes the circulation as it
stands (water depth, depth-averaged current, the wet mask), advances the
spectrum by one coupling interval (model.coupling_interval, 10 minutes
by default), and forms the radiation stress (1) as
SWAN’s sum over the bins,
Its divergence (Applying the Force) is the force \(\mathbf F_k\). The next force is not known until \(t_{k+1}\), so between couplings the circulation sees ADCIRC+SWAN’s schedule, a linear ramp from \(\mathbf F_k\) toward the extrapolated \(2\mathbf F_k - \mathbf F_{k-1}\):
(\(\mathbf F_0\) is held over the first interval).
The couplings run every interval from the start, or, on a restart whose checkpoint carries no wave state, from the restart time. A checkpoint carries the spectrum, the force bracket, the depth of the last coupling and the relaxed sink rate, so a restart continues the schedule exactly. The spectrum lives in the solver frame, so the force needs no rotation on a rotated-pole mesh; its output copy is rotated back to geographic like every other vector.
The progress table shows the largest Hs and each coupling’s iterations
(Quick Start). A step that reaches
stop.max_iterations is logged and the run continues; an Hs that is not
finite, or that reaches stop.max_height (30 m by default), stops the run
as a diverged circulation does.
Choosing the Spectral Grid
directions sets the direction bins, \(360^\circ/n\) wide.
frequencies sets how many frequencies are spaced geometrically from
lowest_frequency to highest_frequency, both included. This is SWAN’s
CGRID ... CIRCLE mdc flow fhigh msc, whose msc counts the intervals
between frequencies, one fewer than frequencies: the default grid is
SWAN’s CIRCLE 36 0.031384 1.420416 40 (The Spectral Grid).
Frequency spacing. Keep the ratio between neighbors near 1.1,
(7)\[r = \left(\frac{f_{max}}{f_{min}}\right)^{1/(N_f - 1)},\]with \(N_f\) the
frequenciescount. The quadruplet approximation interpolates across bins and is tuned for that spacing, as SWAN recommends. To widen the range, add frequencies rather than stretching the spacing.Lowest frequency. Below the longest swell the domain can generate: 0.031 Hz is a 32 s period.
Highest frequency. At least an octave above the peak of the lightest wind sea that matters: a young sea under 4 m/s peaks near 0.6-0.7 Hz. The spectrum is extended above the grid as \(f^{-4}\), but only the bins on the grid grow, and a peak close to the top grows too slowly.
Directions. 36 (10 degrees) is the SWAN+ADCIRC standard. Operational unstructured hurricane runs use 24 to 36; fewer directions spread swell into rays (the garden-sprinkler effect) and resolve refraction more coarsely. Use an even count: an odd one makes the sweep’s snapshot hold every node instead of the block-boundary rows (Precision and Memory), and the minimum is 3.
Cost and memory scale with the number of bins, directions times
frequencies. The model holds two single-precision spectra (the iterate and
the step’s start, 4 bytes per node per bin each) and a snapshot of the
sweep blocks’ boundary rows. The full CPRA Louisiana mesh (1.57M nodes,
36 x 41 bins) needs 9.3 GB per spectrum: the iterate stays on a 16 GB V100
and sweep.host_spectra: auto puts the starting spectrum in pinned host
memory, costing about a quarter more time per iteration and leaving the
results unchanged. The log reports where each spectrum was placed and how
much device memory remained.
Choosing the Source Terms
sources.physics picks the wind input and whitecapping
(Source Terms); breaking, friction and the quadruplets are
the same under both.
default: SWAN’sGEN3 KOMEN AGROWwithWCAP KOMEN, the configuration of the SWAN+ADCIRC hurricane studies. Its whitecapping coefficients are exposed (sources.whitecapping).st6: SWAN’s ST6 package as Day and Dietrich recommend it for ADCIRC+SWAN storm runs (ST6). Its coefficients are fixed, and settingsources.whitecappingwith it is refused.
The wind the waves feel is relative to the current,
\(\mathbf U_{10} - s\,\mathbf U_c\) (64), with
\(s\) set by sources.wind.current_coupling; the circulation’s own
wind stress uses the absolute wind (Wind). The
default, 1, is SWAN’s form; the atmosphere partly adjusts to a moving
surface, so a smaller value may be more realistic. \(u_*\) comes from
the wave model’s own drag law at that relative speed:
sources.wind.drag_law, chosen from the laws the circulation offers and
capped by sources.wind.drag_limit. swell
reads the spread of the spectrum at the start of each step, where SWAN
re-forms it every iteration.
The defaults, Garratt capped at 0.0025 with SWAN’s constant
\(1.2875\times10^{-3}\) at and below 7.5 m/s
(sources.wind.low_wind_drag), are how ADCIRC+SWAN couples when the
circulation keeps its own defaults. The two caps are independent here,
whereas ADCIRC+SWAN hands SWAN the circulation’s cap: a run that changes
physics.wind_drag_limit and wants the coupled behavior must set
sources.wind.drag_limit to the same value. To run as standalone SWAN
does, set a drag_limit no law reaches and either wu for the default
package, whose law already holds \(1.2875\times10^{-3}\) at and below
7.5 m/s so low_wind_drag changes nothing, or hwang with
low_wind_drag: false for ST6.
The waves take the meteorological wind with its wind_scale divided back
out, as ADCIRC hands SWAN an NWS = 12 wind without fort.22’s
multiplier, times sources.wind.multiplier (ADCIRC’s
waveWindMultiplier). That needs every gridded source to share one
wind_scale, and a vortex to be composed only with unscaled sources; the
run refuses to start otherwise. Without meteorological forcing there is no
wind input.
sources.friction.roughness: manning derives the friction roughness from
the mesh’s Manning’s \(n\) at every coupling, as ADCIRC does for SWAN’s
READINP ADCFRIC. The value ADCIRC passes is a roughness length
(59), which SWAN uses as \(k_N\) unchanged
(Shared Terms). A roughness needs
sources.friction.enabled: true; one given with friction off is refused.
Limitations
No incoming boundary spectra. Mesh boundaries let waves out and none in, so the model sees only waves generated inside the domain; swell arriving from outside it is absent.
Triads and wave-induced currents beyond the radiation-stress force are not modeled; the Stokes drift is omitted from continuity, as in SWAN+ADCIRC.
Waves start from rest at the first coupling (or at a restart whose checkpoint has no wave state), so allow a spin-up before the waves matter.
Output
output.variables.wave_force: true writes wave_force_x and
wave_force_y (m2 s-2): the ramped force, uncapped and
geographic, as ADCIRC writes rads.64. Off by default, like the other
forcing diagnostics. The internal model also writes its integral parameters
at the last coupling: wave_hs, wave_dir and wave_tm01 by
default, wave_tmm10 and wave_tps when set to true
(Output Files). They follow SWAN’s definitions with CF metadata
(Output Parameters). The peak file carries wave_hs_max and,
for each period and the direction written, its value at the coupling of
that maximum (wave_tm01_max, …), so the periods describe the
sea state of the largest waves rather than maxima of their own
(Peak Variables).
Two conventions matter when comparing with ADCIRC+SWAN: the periods are
absolute, as SWAN’s TM01 and TMM10 (the frequency a fixed point sees
on a current), and wave_dir is where the waves come from, clockwise from
north, where SWAN’s default DIR is where they travel, counterclockwise
from east.
References
Longuet-Higgins, M. S., and R. W. Stewart (1964). Radiation stresses in water waves; a physical discussion, with applications. Deep Sea Research, 11(4), 529-562.
Dietrich, J. C., et al. (2011). Modeling hurricane waves and storm surge using integrally-coupled, scalable computations. Coastal Engineering, 58(1), 45-65.