Tidal Forcing
Tidal forcing enters Cocoa in two places, and a run may use either or both:
The tide potential (
forcing.tide.potential) is the tide-generating body force applied over the whole domain. With noconstituentslist it is computed astronomically: Moon and Sun positions from Jean Meeus’s algorithms give the complete potential with no harmonic decomposition. A constituent-based potential (type: constituentwith an explicitconstituentslist) is also accepted but is not documented here.Harmonic boundary constituents (
forcing.tide.boundary) prescribe the elevation at open boundary nodes from pre-defined tidal amplitudes, frequencies, and phases.
A regional mesh with an open ocean boundary typically uses both (the Western North Atlantic (WNAT) case does); a global mesh has no open boundaries and is driven by the potential alone (see Global Ocean).
Astronomical Tide Potential
The astronomical method computes the equilibrium tide directly from the positions of the Moon and Sun, so it includes every tidal constituent, the 18.6-year nodal modulation, and the long-period tides (fortnightly, monthly, semi-annual, annual) without a harmonic decomposition. Use it for long simulations, where fixed nodal factors go stale, and for applications that lack a constituent database or need the complete tidal spectrum.
Configuration
Enable astronomical tide potential in your configuration file:
forcing:
ramp:
enabled: true
duration: 1d
tide:
potential:
enabled: true
type: "astronomical"
astronomical:
order: 3 # Expansion order: 2=P2, 3=P2+P3, 4+=untruncated
include_nutation: true
k2: 0.302 # Optional Love number override
h2: 0.609 # Optional Love number override
Parameters:
Parameter |
Default |
Description |
|---|---|---|
|
3 |
Legendre polynomial expansion order, matching ADCIRC’s |
|
true |
Include nutation corrections in position calculations for higher accuracy at the cost of slightly more computation. |
|
0.302 |
Second-degree Love number for body tide. Represents elastic deformation of Earth due to tidal forces. |
|
0.609 |
Second-degree Love number for vertical displacement. Represents radial displacement of Earth’s surface. |
The Earth elasticity factor \((1 + k_2 - h_2) \approx 0.69\) reduces the equilibrium tide amplitude to account for the solid Earth’s elastic response.
The applied potential is not written to the output file by default, since it
is a diagnostic of the forcing rather than a model result. Set
output.global.variables.tide_potential: true to write it.
Self-Attraction and Loading (SAL)
Self-attraction and loading (SAL) accounts for two effects that modify the ocean tide:
The gravitational attraction of the ocean on itself (self-attraction)
The deformation of the Earth’s crust under the weight of the ocean tide (loading)
SAL corrections are applied as spatially-varying amplitude and phase adjustments per tidal constituent at each mesh node. The SAL data must be pre-computed externally (e.g., from a global tide model) and embedded in the mesh file during conversion.
Preparing SAL Data
SAL data is included during mesh conversion using the --sal flag:
cocoa-mesh-tools from_adcirc \
--mesh fort.14 \
--attributes fort.13 \
--sal fort.24 \
--output mesh.nc
The SAL file can be in ADCIRC ASCII format (fort.24) or NetCDF format (fort.24.nc). It contains per-node amplitude (meters) and phase (degrees) for each SAL constituent.
Configuration
Enable SAL in the configuration file:
forcing:
tide:
sal:
enabled: true
parameter_source: "auto" # or "manual"
Parameters:
Parameter |
Default |
Description |
|---|---|---|
|
false |
Enable SAL forcing |
|
“auto” |
How to determine constituent frequencies and nodal factors.
|
Auto Mode
In auto mode (the default), Cocoa matches SAL constituent names from the mesh file against its built-in tidal constituent database to determine frequencies, nodal factors, and equilibrium arguments at the simulation coldstart time. No additional configuration is needed:
forcing:
tide:
sal:
enabled: true
Manual Mode
Manual mode is used for exact validation against ADCIRC, where you need to specify the precise frequency, nodal factor, and equilibrium argument for each constituent:
forcing:
tide:
sal:
enabled: true
parameter_source: "manual"
constituents:
- name: M2
frequency: 1.405189028e-04 # rad/s (converted to rad/hr internally)
nodal_factor: 1.026777
equilibrium_arg: 26.668130 # degrees (converted to radians internally)
- name: K1
frequency: 7.292117e-05 # rad/s
nodal_factor: 1.0064
equilibrium_arg: 12.45 # degrees
Each constituent in the list must have a name matching one of the
constituent names stored in the mesh SAL data.
Note
If SAL is enabled but the mesh file has no SAL data, Cocoa logs a warning
and continues without SAL corrections. Re-run the mesh
converter with the --sal flag to include the data.
Harmonic Constituents
Harmonic constituents prescribe the tidal elevation at open boundary nodes from pre-computed amplitudes, frequencies, and phases. They need a tidal database for the boundary, and because each constituent’s nodal factor is fixed for the run, they suit simulations short enough for it to remain valid.
Common Tidal Constituents
Name |
Description |
Period (hours) |
Frequency (rad/s) |
|---|---|---|---|
M2 |
Principal lunar semidiurnal |
12.42 |
1.405189e-4 |
S2 |
Principal solar semidiurnal |
12.00 |
1.454441e-4 |
N2 |
Larger lunar elliptic semidiurnal |
12.66 |
1.378797e-4 |
K1 |
Lunisolar diurnal |
23.93 |
7.292117e-5 |
O1 |
Principal lunar diurnal |
25.82 |
6.759774e-5 |
K2 |
Lunisolar semidiurnal |
11.97 |
1.458423e-4 |
Q1 |
Larger lunar elliptic diurnal |
26.87 |
6.495854e-5 |
Boundary Configuration
Tidal boundary constituents are specified in the forcing section of the configuration file:
forcing:
tide:
boundary:
enabled: true
constituents:
- name: M2
frequency: 0.000140518902509 # rad/s
nodal_factor: 0.96461 #
equilibrium_arg: 315.69 # degrees
boundary_values: # Per-node amplitude/phase
- { amplitude: 0.52, phase: 344.17 }
- { amplitude: 0.51, phase: 345.15 }
- name: K1
frequency: 0.000072921158358
nodal_factor: 1.0064
equilibrium_arg: 12.45
boundary_values:
- { amplitude: 0.15, phase: 45.0 }
- { amplitude: 0.14, phase: 46.2 }
Each constituent requires:
name: Constituent identifier (M2, S2, K1, O1, etc.)frequency: Angular frequency in rad/snodal_factor: Nodal modulation factorequilibrium_arg: Equilibrium argument in degreesboundary_values: List of amplitude (meters) / phase (degrees) pairs, one per open boundary node, in the order the open boundary strings appear in the mesh file. A constituent whose list is longer or shorter than the mesh’s open boundary node count stops the run at startup.
With per-node values for every constituent, this block grows with the mesh’s
open boundary and is the same for every run on that mesh. It can therefore
live in its own reusable file and be pulled in with an include node,
either the whole boundary block or just the constituents list (see
Configuration for the inclusion rules):
forcing:
tide:
boundary:
include: wnat_tide_boundary.yaml
Ramp-up Period
To avoid initial transients, use a ramp-up period:
forcing:
ramp:
enabled: true
duration: 1d # 1 day ramp-up
During the ramp-up period the tidal forcing is scaled by a normalized hyperbolic tangent:
The normalization by \(\tanh(2)\) makes the ramp reach exactly 1.0 at \(t = T_{ramp}\). The value is clamped to 1.0 for \(t \ge T_{ramp}\).