============= Configuration ============= Cocoa uses YAML configuration files for simulation setup. Configuration File Structure ---------------------------- A complete configuration file contains the following sections: .. code-block:: yaml mesh: # Mesh file and projection settings simulation: # Simulation time control initial_conditions: # Initial state physics: # Physical parameters numeric: # Numerical solver parameters forcing: # Forcing configuration (tides, meteorological, ramp) output: # Output file configuration diagnostics: # Logging and screen output checkpoint: # Checkpoint/restart (optional) Validation ---------- Configuration files are validated against a schema at startup, before any other input is read. Unknown keys (with "did you mean" suggestions for near-misses), missing required fields, wrong value types, and out-of-range values are reported together in a single pass. Boolean values must be written as ``true`` or ``false``; the YAML 1.1 spellings ``yes``/``no``/``on``/``off`` are rejected. A key present with no value behaves as if the key were omitted, and the default applies. The complete schema is reproduced in the :ref:`config-schema-reference` at the end of this page. Mesh Section ------------ Specifies the mesh file, coordinate projection, and optional coordinate rotation for global meshes. .. code-block:: yaml mesh: filename: "mesh.nc" # Path to mesh file (required) projection: type: "EquidistantCylindrical" # Projection type (optional) center: [-76.5, 23.2] # Projection center [lon, lat] (optional) rotation: # Coordinate rotation (optional) enabled: false pole_location: [0.0, 0.0] # [longitude, latitude] of new North Pole **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``filename`` - string - (required) - Path to mesh file (NetCDF UGRID format) * - ``projection.type`` - string - ``EquidistantCylindrical`` - Coordinate projection type * - ``projection.center`` - [lon, lat] - [0.0, 0.0] - Projection center coordinates .. _rotation-configuration: Coordinate Rotation (Global Meshes) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For global ocean models, coordinate rotation moves the computational poles away from the geographic poles to avoid singularities. .. code-block:: yaml mesh: rotation: enabled: true pole_location: [0.0, 0.0] # [longitude, latitude] of new North Pole **Rotation Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``rotation.enabled`` - bool - false - Enable coordinate rotation * - ``rotation.pole_location`` - [lon, lat] - (required) - Geographic coordinates where the new North Pole is located [degrees] When ``enabled: true``, the ``pole_location`` parameter must be specified. Common choices for ``pole_location``: - ``[0.0, 0.0]``: North Pole moves to the equator at the prime meridian - ``[180.0, 0.0]``: North Pole moves to the equator at the date line - ``[-90.0, 0.0]``: North Pole moves to the equator in the Atlantic **Effects of rotation:** - Node coordinates are transformed to the rotated frame - Metric terms (spherical ``tan(phi)`` correction, projection scale factors) use the rotated latitude -- they belong to the frame the equations are discretized in - Coriolis parameter continues to use geographic latitude; the planetary rotation term is frame-independent - Tidal potential continues to use geographic latitude - Output velocities are transformed back to geographic (east, north) frame See :ref:`coordinate-rotation` in the Theory documentation for details and :doc:`../user_guide/global_simulations` for a complete guide. Simulation Section ------------------ Controls simulation timing. .. code-block:: yaml simulation: start_time: 2025-01-01 # Simulation start time (required) end_time: 2025-01-15 # Simulation end time (required) time_step: 10s # Time step (default 1s), e.g. 10s, 1m, 0.5s **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``start_time`` - datetime - (required) - Simulation start time * - ``end_time`` - datetime - (required) - Simulation end time * - ``time_step`` - duration - ``1s`` - Computational time step. Accepts a :ref:`duration string ` (e.g. ``4s``, ``1m``) or a bare number of seconds (e.g. ``10.0``). DateTime formats supported: - ``2025-01-01`` (date only, midnight assumed) - ``2025-01-01T12:00:00`` (ISO 8601 format) Initial Conditions Section -------------------------- Sets initial state for the simulation. .. code-block:: yaml initial_conditions: water_level: 0.0 # Initial water surface elevation [m] **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``water_level`` - float - 0.0 - Initial water surface elevation [m] Physics Section --------------- Physical model parameters. .. code-block:: yaml physics: manning_n: 0.025 # Manning's roughness coefficient (or "mesh") tau0: 0.005 # GWCE weighting parameter (or "mesh") cf_lower_limit: 0.001 # Minimum friction coefficient internal_tide_friction: 0 # Internal tide friction (0, constant, or "mesh") smagorinsky_coefficient: 0.2 # Smagorinsky turbulence coefficient min_viscosity: 1.0e-6 # Minimum eddy viscosity [m^2/s] h0: 0.1 # Minimum depth threshold [m] velmin: 0.01 # Minimum wetting velocity [m/s] wet_dry_slope_limiter: 1.0e9 # Slope limiter coefficient **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``manning_n`` - float or "mesh" - 0.025 - Manning's roughness coefficient for bottom friction * - ``tau0`` - float or "mesh" - 0.05 - GWCE weighting parameter * - ``cf_lower_limit`` - float - 0.001 - Lower limit for the computed quadratic friction coefficient * - ``min_depth_friction`` - float - 0.1 - Minimum total water depth (HBREAK) used in the bottom friction computation [m] * - ``min_velocity_friction`` - float - 0.0 - Minimum velocity used in the bottom friction computation [m/s] * - ``internal_tide_friction`` - float, "mesh", or 0 - 0 - Internal tide friction coefficient [1/s]. Set to ``0`` to disable, a constant value to apply uniformly, or ``mesh`` to read from the mesh file (see :ref:`spatially-varying-parameters`). * - ``h0`` - float - 0.1 - Minimum depth threshold for wet elements [m] * - ``velmin`` - float - 0.01 - Minimum velocity for node wetting [m/s] * - ``smagorinsky_coefficient`` - float - 0.2 - Smagorinsky subgrid turbulence coefficient * - ``min_viscosity`` - float - 1.0e-6 - Minimum eddy viscosity [m^2/s] * - ``wind_drag_limit`` - float - 0.0025 - Maximum drag coefficient for wind stress * - ``surface_directional_roughness`` - 0 or "mesh" - 0 - Directional effective roughness lengths for wind reduction. Set to ``mesh`` to read the 12-directional roughness field from the mesh file, or ``0`` to disable (see :ref:`wind-reduction-config`). * - ``surface_canopy_coefficient`` - float or "mesh" - 1.0 - Binary canopy mask for wind reduction (0 or 1). Set to ``mesh`` to read per-node values from the mesh file, or ``1`` to disable (identity). A fractional value fails loud. See :ref:`wind-reduction-config`. * - ``wet_dry_slope_limiter`` - float - 1.0e9 - Wet/dry shallow-water slope limiter coefficient (ADCIRC ``SLIM``). Distinct from ``elemental_slope_limiter`` below. * - ``elemental_slope_limiter`` - float or "mesh" - (disabled) - Optional selective post-continuity elevation-gradient limiter [m/m]. Absent/``null`` disables it; a constant applies one threshold everywhere; ``mesh`` reads per-node thresholds from the mesh file. See :doc:`../user_guide/elemental_slope_limiter`. * - ``advection`` - bool, "off_at_open_boundaries" or "mesh" - ``off_at_open_boundaries`` - Where the advective terms are evaluated. ``off_at_open_boundaries`` (the default) disables advection along the open, flow and radiation boundary strings, ``true`` applies it everywhere, ``false`` disables it everywhere, and ``mesh`` reads a per-node binary mask (1 = on, 0 = off) from the mesh file's ``advection_state`` nodal attribute. A fractional mesh value fails loud; ``yes``/``on``/``1`` are not accepted spellings. See :ref:`advection-state-config`. .. _advection-state-config: Advection ^^^^^^^^^ Every mode resolves to the same per-node binary mask; they differ only in where it comes from. The mask is reduced to one flag per element once at startup, and **an element evaluates advection only when every one of its corner nodes does** (ADCIRC's ``ADVECTLOCAL``). A node with advection off therefore switches it off in every element touching that node. .. code-block:: yaml physics: advection: off_at_open_boundaries # default: off where the domain ends # advection: true # everywhere # advection: false # nowhere # advection: mesh # per-node mask from the mesh file ``off_at_open_boundaries`` clears the mask at every node of the boundary strings where the domain is truncated -- elevation-specified (open), specified-flow and radiation -- so the disabled region is a band **one element thick** just inside those strings. That is where the advective terms are least well behaved: they reach for an upstream state the mesh does not hold. Land walls and weirs keep advection, because the flow they bound is inside the mesh; clearing them as well cost a channel bend its cross-bend balance one element in from each bank. For anything finer, write the mask you want into the mesh file and use ``mesh``: for example, to disable advection only on the open boundary and not on the inflow, set ``advection_state`` to 0 at those nodes and 1 everywhere else. See :doc:`../user_guide/mesh_preparation`. .. note:: ``off_at_open_boundaries`` became the default in place of "advection everywhere". A run that needs the previous behavior must set ``advection: true`` explicitly. .. _spatially-varying-parameters: Spatially-Varying Parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``manning_n``, ``tau0``, ``internal_tide_friction``, ``surface_directional_roughness``, and ``surface_canopy_coefficient`` parameters support spatially-varying values from the mesh file. To enable this, set the parameter value to ``mesh``: .. code-block:: yaml physics: manning_n: mesh # Read from "mannings_n_at_sea_floor" tau0: mesh # Read from "primitive_weighting_in_continuity_equation" internal_tide_friction: mesh # Read from "internal_tide_friction" surface_directional_roughness: mesh # Read from "surface_directional_effective_roughness_length" surface_canopy_coefficient: mesh # Read from "surface_canopy_coefficient" When set to ``mesh``, Cocoa will read the corresponding nodal attribute from the NetCDF mesh file: .. list-table:: :header-rows: 1 :widths: 20 40 40 * - Parameter - Mesh Variable Name - Description * - ``manning_n`` - ``mannings_n_at_sea_floor`` - Manning's n at each node [s/m^(1/3)] * - ``tau0`` - ``primitive_weighting_in_continuity_equation`` - GWCE tau0 at each node [1/s] * - ``internal_tide_friction`` - ``internal_tide_friction`` - Internal tide friction coefficient at each node [1/s]. Supports both scalar (1 value per node, isotropic) and tensor (3 values per node: xx, yy, xy components) storage in the mesh file. * - ``surface_directional_roughness`` - ``surface_directional_effective_roughness_length`` - Directional land roughness lengths at each node [m]. Stored as a 12-component vector (one per 30-degree directional bin). * - ``surface_canopy_coefficient`` - ``surface_canopy_coefficient`` - Canopy coefficient at each node [dimensionless, 0--1]. Multiplicative reduction applied to wind velocity under forest canopy. If the mesh file does not contain the required variable when ``mesh`` is specified, Cocoa will report an error and exit. See :doc:`../user_guide/mesh_preparation` for details on creating mesh files with nodal attributes. .. _wind-reduction-config: Wind Reduction """""""""""""" When meteorological forcing is enabled, Cocoa can apply two types of overland wind reduction before computing wind stress: 1. **Directional roughness reduction** (``surface_directional_roughness: mesh``): Reduces wind speed based on the ratio of upwind land surface roughness to marine roughness. Uses 12 directional bins (30-degree spacing) with linear interpolation between bins. 2. **Canopy coefficient** (``surface_canopy_coefficient: mesh``): Applies a simple multiplicative reduction to wind components to represent sheltering by forest canopy. A value of 1.0 means no reduction; 0.0 means complete sheltering. The processing order within the meteorological forcing kernel is: 1. Apply directional roughness reduction (if enabled) 2. Apply canopy coefficient (if enabled) 3. Apply meteorological ramp 4. Compute kinematic wind stress from the reduced, ramped wind **Bottom Friction:** The friction coefficient is computed from Manning's n: .. math:: C_f = \max\left(\frac{g n^2}{H^{1/3}}, C_{f,min}\right) where :math:`C_{f,min}` is ``cf_lower_limit``. Wetting and Drying Algorithm ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Minimum Depth Threshold (H0):** The ``h0`` parameter sets the minimum total water depth for a node to be considered wet. When the total depth falls below this threshold, the node transitions to dry. Typical values range from 0.01 to 0.5 meters. **Minimum Wetting Velocity (VELMIN):** The ``velmin`` parameter controls the minimum velocity required for water to advance onto a dry node during the wetting process. Lower values allow easier wetting but may cause numerical oscillations. Default is 0.01 m/s. **Slope Limiter (SLIM):** The ``wet_dry_slope_limiter`` parameter limits water surface gradients in shallow water to prevent spurious oscillations. The limiter computes a scaling factor :math:`\alpha` for the elevation gradient: .. math:: \alpha = \frac{\text{SLIM} \cdot |\nabla h|}{|\nabla \zeta|} where :math:`h` is bathymetric depth and :math:`\zeta` is water surface elevation. The gradient is scaled by :math:`\min(\alpha, 1)`. - **Default (1.0e9):** Effectively disables limiting - **Typical active value (0.0004):** Applies gradient limiting in shallow areas Example enabling slope limiting: .. code-block:: yaml physics: h0: 0.1 velmin: 0.01 wet_dry_slope_limiter: 0.0004 Numeric Section --------------- Numerical solver parameters. .. code-block:: yaml numeric: solver: explicit # Solver type (default: explicit) gwce_coefficients: [0.0, 1.0, 0.0] # Temporal weights [a00, b00, c00] linear_solver: # CG solver settings (consistent only) type: belos_cg tolerance: 1.0e-5 max_iterations: 50 convergence_scaling: norm_of_initial_residual **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``solver`` - string - ``explicit`` - GWCE solver type (see below) * - ``gwce_coefficients`` - [a00, b00, c00] - [0.0, 1.0, 0.0] - GWCE temporal integration weights **Solver Types:** The ``solver`` parameter accepts the following values: .. list-table:: :header-rows: 1 :widths: 30 70 * - Value - Description * - ``explicit`` or ``lumped`` - Diagonal mass matrix with direct solve (faster, coefficients set to [0, 1, 0]) * - ``implicit``, ``iterative``, or ``consistent`` - Sparse matrix with iterative CG solver (more accurate, semi-implicit) When using the explicit/lumped solver, the ``gwce_coefficients`` are automatically set to ``[0, 1, 0]`` regardless of user specification. For the implicit/consistent solver, typical values are ``[0.35, 0.30, 0.35]``. **GWCE Coefficients:** The coefficients control temporal weighting in the GWCE: - ``a00``: Weight for time level n+1 - ``b00``: Weight for time level n - ``c00``: Weight for time level n-1 Linear Solver Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``linear_solver`` subsection controls the iterative Conjugate Gradient solver used by the consistent (implicit) GWCE solver. These settings are ignored when using the explicit/lumped solver. .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``type`` - string - ``belos_cg`` - CG solver implementation (see below) * - ``tolerance`` - float - 1.0e-5 - Convergence tolerance for the iterative solver. The solver terminates when the (scaled) residual norm drops below this value. * - ``max_iterations`` - int - 50 - Maximum number of CG iterations per solve. If the solver does not converge within this limit, it reports unconverged. * - ``verbosity`` - int - 0 - Solver output verbosity: ``0`` = silent, ``1`` = summary, ``2`` = per-iteration. * - ``convergence_scaling`` - string - ``norm_of_initial_residual`` - How the residual is scaled when testing convergence (see below) **Solver Implementation Types:** The ``type`` parameter selects the CG algorithm variant. All variants solve the same linear system with Jacobi preconditioning; they differ in communication pattern and internal implementation. .. list-table:: :header-rows: 1 :widths: 30 70 * - Value - Description * - ``belos_cg`` - Standard Belos CG. The most portable and well-tested implementation. Uses classical Belos convergence testing with configurable verbosity output. * - ``tpetra_cg_pipeline`` - Tpetra-native pipelined CG. Overlaps communication with computation by pipelining inner products, which can reduce latency on distributed systems with many MPI ranks. * - ``tpetra_single_reduce`` - Tpetra-native single-reduce CG. Combines two inner products per iteration into a single MPI allreduce, reducing synchronization points. Useful on high-latency interconnects. Use the default ``belos_cg``. The Tpetra-native variants may scale better on large distributed runs; all three produce identical mathematical results. **Convergence Scaling:** The ``convergence_scaling`` parameter determines how the residual norm is normalized when checking the convergence criterion. .. list-table:: :header-rows: 1 :widths: 30 70 * - Value - Description * - ``norm_of_initial_residual`` - Relative convergence: the solver converges when :math:`\|r_k\| / \|r_0\| < \text{tolerance}`. This is the most common choice and makes the tolerance independent of problem scaling. * - ``norm_of_prec_init_res`` - Like ``norm_of_initial_residual`` but scales by the preconditioned initial residual :math:`\|M^{-1} r_0\|` instead. This can be useful when the preconditioner significantly changes the residual norm. * - ``none`` - Absolute convergence: the solver converges when :math:`\|r_k\| < \text{tolerance}`. The tolerance must be chosen relative to the expected magnitude of the right-hand side. **Example: Consistent solver with custom linear solver settings:** .. code-block:: yaml numeric: solver: consistent gwce_coefficients: [0.35, 0.30, 0.35] linear_solver: type: belos_cg tolerance: 1.0e-6 max_iterations: 100 convergence_scaling: norm_of_initial_residual Forcing Section --------------- Configures tidal and meteorological forcing, along with the spinup ramp. Ramp Configuration ^^^^^^^^^^^^^^^^^^ .. code-block:: yaml forcing: ramp: enabled: true # Enable spinup ramp duration: 1d # Ramp duration (e.g. 1d, 12h, 2d) **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``ramp.enabled`` - bool - true - Enable hyperbolic tangent spinup ramp * - ``ramp.duration`` - duration - ``1d`` - Duration of spinup ramp. Accepts a :ref:`duration string ` (e.g. ``1d``, ``12h``) or a bare number of seconds. To use a different ramp for meteorological forcing, add an optional ``ramp`` subsection under ``forcing.meteorological``: .. code-block:: yaml forcing: ramp: enabled: true duration: 5d # Tidal ramp duration meteorological: enabled: true format: cf_netcdf filename: "met.nc" ramp: # Optional: overrides forcing.ramp for met enabled: true duration: 1d # Shorter met ramp **Meteorological Ramp Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``meteorological.ramp.enabled`` - bool - (from ``ramp.enabled``) - Enable met-specific spinup ramp * - ``meteorological.ramp.duration`` - duration - (from ``ramp.duration``) - Met ramp duration. Accepts a :ref:`duration string ` or a bare number of seconds. See :ref:`meteorological-ramp` for details on the ramp function. .. _meteo-forcing-config: Meteorological Forcing ^^^^^^^^^^^^^^^^^^^^^^ Configures atmospheric wind and pressure forcing. See :doc:`../user_guide/meteorological_forcing` for full details on file formats and usage. .. code-block:: yaml forcing: meteorological: enabled: true format: cf_netcdf # cf_netcdf, owi_ascii, owi_netcdf, or grib filename: "path/to/meteo_data.nc" # Single file (cf_netcdf, owi_netcdf) This is the flat, single-source form. Two or more sources (mixed formats, nested grids, a reduced vs. unreduced field) are configured as a ``forcing.meteorological.domains`` list instead; see :doc:`../user_guide/meteorological_forcing` for the composition rules. **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``meteorological.enabled`` - bool - false - Enable meteorological forcing * - ``meteorological.format`` - string - ``cf_netcdf`` - File format: ``cf_netcdf`` (aliases: ``cf``, ``netcdf``), ``owi_ascii`` (alias: ``owi``), ``owi_netcdf``, or ``grib`` (alias: ``grib2``, requires ``cocoa_ENABLE_GRIB``) * - ``meteorological.filename`` - string - (one of ``filename``/``filenames``) - Path to meteorological data file (CF NetCDF, OWI NetCDF, or a single GRIB file) * - ``meteorological.filenames`` - list - (one of ``filename``/``filenames``) - List of pressure/wind file pairs (OWI ASCII), or a list of GRIB files (GRIB) * - ``meteorological.product`` - string - (required for GRIB) - Preset weather product name (e.g. ``gfs``, ``hrrr``) selecting the numeric GRIB2 field identities, or omit and supply a ``variables`` override * - ``meteorological.drag_law`` - string - ``garratt`` - Wind drag coefficient formulation * - ``meteorological.pressure_scale`` - float - 100.0 - Scale factor for pressure, OWI formats only (default converts hPa to Pa). Rejected for ``cf_netcdf`` (units come from the file's ``units`` attribute) and ``grib`` (GRIB2 fields are SI by definition). * - ``meteorological.wind_scale`` - float - 1.0 - Scale factor for wind velocity * - ``meteorological.wind_reduction`` - bool - true - Opt out of overland wind reduction for this source by setting ``false``; the reduction applies only when the mesh carries the roughness/canopy attributes (see :ref:`wind-reduction-config`) **CF NetCDF Variable Names:** When using the ``cf_netcdf`` format, you can override the default variable names used to read the meteorological data: .. code-block:: yaml forcing: meteorological: enabled: true format: cf_netcdf filename: "met_data.nc" variables: pressure: "mslp" # Default: "mslp" wind_u: "wind_u" # Default: "wind_u" wind_v: "wind_v" # Default: "wind_v" time: "time" # Default: "time" lon: "lon" # Default: "lon" lat: "lat" # Default: "lat" For OWI ASCII format, use ``filenames`` with paired pressure/wind files: .. code-block:: yaml forcing: meteorological: enabled: true format: owi_ascii filenames: - pressure: "basin.pre" wind: "basin.wnd" For GRIB2 (requires a build with ``cocoa_ENABLE_GRIB``), name a weather product preset and the file list; see :doc:`../user_guide/meteorological_forcing` for the available products, numeric ``variables`` overrides, and multi-source composition: .. code-block:: yaml forcing: meteorological: enabled: true format: grib product: gfs filenames: ["gfs_f000.grib2", "gfs_f003.grib2"] External File Inclusion ^^^^^^^^^^^^^^^^^^^^^^^ Two configuration blocks routinely grow long enough to be worth maintaining as separate, reusable files: meteorological file lists (a multi-day forecast run's GRIB list can span hundreds of files) and the open-ocean tide boundary block (per-node constituent data). At exactly these locations, a node's content may be replaced with an ``include`` mapping naming a YAML file whose root content is spliced in place of the node before validation runs -- the result is indistinguishable from writing the same content inline: .. code-block:: yaml forcing: meteorological: enabled: true format: grib product: gfs filenames: include: hafs_ida_files.yaml # a YAML list of file paths tide: boundary: include: wnat_tide_boundary.yaml # the whole boundary block Rules: * ``include`` is accepted only at ``forcing.meteorological.filenames``, a ``domains`` entry's ``filenames``, ``forcing.tide.boundary``, and ``forcing.tide.boundary.constituents``. Anywhere else it is a configuration error naming the allowed locations. * The ``include`` mapping must contain only the ``include`` key. * Relative paths resolve against the directory of the file containing the ``include``, so a configuration and its included files move together as a portable bundle. * Included files may not themselves contain ``include`` nodes (one level only). Flow Boundary Forcing ^^^^^^^^^^^^^^^^^^^^^^ Configures normal-flow (discharge) boundary conditions driven by per-segment time series. .. code-block:: yaml forcing: flow_boundary: enabled: true ramp: # Optional spinup ramp for flow boundaries enabled: true duration: 1d segments: - segment_index: 0 time_series_file: "inflow_0.txt" - segment_index: 1 time_series_file: "inflow_1.txt" **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``flow_boundary.enabled`` - bool - false - Enable flow boundary forcing * - ``flow_boundary.ramp`` - ramp - (from ``forcing.ramp``) - Optional spinup ramp applied to flow boundaries. Accepts ``enabled`` and ``duration`` (see :ref:`duration-syntax`). * - ``flow_boundary.segments`` - list - (none) - List of flow boundary segments. Each entry maps a flow boundary to a time series file. Each ``segments`` entry contains: - ``segment_index``: Index of the flow boundary segment in the mesh - ``time_series_file``: Path to the discharge time series file for that segment Tidal Potential Forcing ^^^^^^^^^^^^^^^^^^^^^^^ The tide potential can be computed using either harmonic constituents or the astronomical method. The ``type`` parameter selects the method: - ``constituent`` (or ``harmonic``): Uses pre-defined tidal constituents - ``astronomical`` (or ``ephemeris``, ``direct``): Computes directly from Moon and Sun positions - ``auto`` (default): Selects automatically based on what is configured **Harmonic Constituent Method:** .. code-block:: yaml forcing: tide: potential: enabled: true type: constituent constituents: - name: M2 frequency: 0.000140518902509 # rad/s amplitude: 0.242334 # m etrf: 0.693 # Earth tide reduction factor nodal_factor: 0.96461 # Nodal modulation equilibrium_arg: 315.69 # degrees **Constituent Parameters:** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Parameter - Units - Description * - ``name`` - string - Constituent name (Q1, O1, P1, K1, N2, M2, S2, K2, etc.) * - ``frequency`` - rad/s - Angular frequency * - ``amplitude`` - m - Tidal potential constant K * - ``etrf`` - - - Earth tide reduction factor * - ``nodal_factor`` - - - Nodal modulation factor f * - ``equilibrium_arg`` - degrees - Equilibrium argument V+u **Astronomical Method:** .. code-block:: yaml forcing: tide: potential: enabled: true type: astronomical astronomical: order: 3 # Expansion order: 2=P2, 3=P2+P3, 4+=untruncated include_nutation: true # Include nutation corrections k2: 0.302 # Love number (optional) h2: 0.609 # Love number (optional) **Astronomical Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 60 * - Parameter - Default - Description * - ``order`` - 3 - Legendre polynomial expansion order (ADCIRC's ``TIPOrder`` semantics). 2 is the degree-2 equilibrium tide; 3, the default, adds degree-3 corrections; 4 or higher carries every degree that matters rather than truncating. See :doc:`../user_guide/tidal_forcing` for how cocoa evaluates the untruncated form and why it deviates from ADCIRC there. * - ``include_nutation`` - true - Include nutation corrections in celestial position calculations. * - ``k2`` - 0.302 - Second-degree Love number for body tide. * - ``h2`` - 0.609 - Second-degree Love number for vertical displacement. The astronomical method needs no constituent list. See :doc:`../user_guide/tidal_forcing` for details. Tidal Boundary Forcing ^^^^^^^^^^^^^^^^^^^^^^ Elevation-specified tidal boundary conditions. .. code-block:: yaml 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 } # ... one entry per open boundary node **Constituent Parameters:** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Parameter - Units - Description * - ``name`` - string - Constituent name * - ``frequency`` - rad/s - Angular frequency * - ``nodal_factor`` - - - Nodal modulation factor * - ``equilibrium_arg`` - degrees - Equilibrium argument * - ``boundary_values`` - list - Per-node amplitude [m] and phase [degrees] Self-Attraction and Loading (SAL) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SAL corrections account for the ocean's gravitational self-attraction and Earth deformation under tidal loads. SAL data must be pre-computed and embedded in the mesh file (see :doc:`../user_guide/tidal_forcing`). .. code-block:: yaml forcing: tide: sal: enabled: true parameter_source: "auto" # or "manual" **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 60 * - Parameter - Default - Description * - ``enabled`` - false - Enable SAL forcing * - ``parameter_source`` - "auto" - How to determine constituent parameters. ``"auto"`` looks up frequencies and nodal factors from the built-in tidal database. ``"manual"`` uses values provided in the ``constituents`` list. In manual mode, provide constituent parameters explicitly: .. code-block:: yaml forcing: tide: sal: enabled: true parameter_source: "manual" constituents: - name: M2 frequency: 1.405189028e-04 # rad/s nodal_factor: 1.026777 equilibrium_arg: 26.668130 # degrees Output Section -------------- Controls simulation output. By default the output file is named ``cocoa_output.nc`` in the working directory. .. code-block:: yaml output: filename: "cocoa_output.nc" # Output file name (optional, default: cocoa_output.nc) step_interval: 1h # Output every hour (duration or integer step count) mode: split # "split" (default) or "combined" variables: # Selectively disable time-series variables pressure: false wind: false **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``filename`` - string - ``cocoa_output.nc`` - Output file name (NetCDF format) * - ``step_interval`` - int or duration - 100 - Interval between output writes. Accepts a plain integer (number of time steps) or a duration string with suffix: ``s`` (seconds), ``m`` (minutes), ``h`` (hours), ``d`` (days). Fractional values are allowed (e.g., ``0.5h``). The duration must be evenly divisible by the simulation time step. * - ``mode`` - string - ``split`` - Controls where peak variables are written. In ``split`` mode (default), peak variables are written to a separate file named ``_peak.nc`` (e.g., ``cocoa_output_peak.nc``). In ``combined`` mode, peak variables are included in the main output file. See :doc:`../user_guide/output_files` for details. * - ``variables`` - map - *(all enabled except* ``tide_potential`` *and* ``bpg_effective`` *)* - Selectively disable time-series output variables. List variable names with ``false`` to disable them. Omitted variables remain enabled, except the forcing diagnostics ``tide_potential`` and ``bpg_effective``, which are off unless set to ``true``. Peak variables are always written and cannot be disabled. Available names: ``zeta``, ``velocity``, ``pressure``, ``wind``, ``tide_potential``, ``ice_concentration``, ``bpg_effective``. See :doc:`../user_guide/output_files` for the full variable reference. * - ``compression`` - map - ``level: 1``, ``shuffle: false`` - NetCDF deflate settings: ``level`` 0-9 (0 disables compression) and the ``shuffle`` byte-shuffle filter. Lower the level (or use 0) when frequent output stalls the run on the background writer. See :doc:`../user_guide/output_files`. Diagnostics Section ------------------- Controls logging and screen output. .. code-block:: yaml diagnostics: screen_interval: 2h # Screen output every 2 hours (duration or integer step count) log_file: "simulation.log" # Structured log file path (optional) **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 15 45 * - Parameter - Type - Default - Description * - ``screen_interval`` - int or duration - 100 - Interval between screen output. Accepts a plain integer (number of time steps) or a duration string (e.g., ``30m``, ``1h``). See :ref:`duration-intervals` for the full syntax. * - ``log_file`` - string - (none) - Path to log file (JSON structured log format) .. _checkpoint-configuration: Checkpoint Section ------------------ Configures checkpoint/restart for long-running simulations. See :doc:`../user_guide/checkpoint` for a complete guide. .. code-block:: yaml checkpoint: enabled: true write_interval: 12h # Write checkpoint every 12 hours file_prefix: "cocoa_checkpoint" # Prefix for checkpoint files restart_file: "" # Path to checkpoint file to restart from **Parameters:** .. list-table:: :header-rows: 1 :widths: 25 15 20 40 * - Parameter - Type - Default - Description * - ``enabled`` - bool - false - Enable the checkpoint/restart system * - ``write_interval`` - int or duration - 0 - How often to write checkpoints. ``0`` (the default) writes a single checkpoint at the end of the run; a positive value writes every ``N`` time steps plus one at the final step. Accepts a plain integer (number of time steps) or a duration string (e.g., ``6h``, ``1d``). See :ref:`duration-intervals` for the full syntax. * - ``file_prefix`` - string - ``cocoa_checkpoint`` - Filename prefix. Each write produces a timestamped file ``{prefix}.{simulation_time}.nc`` (e.g. ``cocoa_checkpoint.20250101T120000.nc``). * - ``restart_file`` - string - (none) - Path to a checkpoint file to restart from. When set, the simulation resumes from the saved state. **Restarting from a checkpoint:** .. code-block:: yaml checkpoint: enabled: true restart_file: "cocoa_checkpoint.20250101T120000.nc" Complete Example ---------------- A complete configuration file for a tidal simulation: .. code-block:: yaml mesh: filename: "gulf_mesh.nc" projection: type: "EquidistantCylindrical" center: [-90.0, 25.0] simulation: start_time: 2025-01-01 end_time: 2025-01-15 time_step: 10s initial_conditions: water_level: 0.0 physics: manning_n: 0.025 tau0: 0.005 cf_lower_limit: 0.001 numeric: solver: implicit gwce_coefficients: [0.35, 0.30, 0.35] linear_solver: type: belos_cg tolerance: 1.0e-5 max_iterations: 50 forcing: ramp: enabled: true duration: 1d tide: potential: enabled: false boundary: enabled: true constituents: - name: M2 frequency: 1.405189028e-04 nodal_factor: 0.964 equilibrium_arg: 23.06 boundary_values: - { amplitude: 0.50, phase: 340.0 } - { amplitude: 0.48, phase: 342.0 } # ... additional boundary nodes output: filename: "gulf_output.nc" step_interval: 10m diagnostics: screen_interval: 1h .. _duration-syntax: .. _duration-intervals: Duration Syntax --------------- Time-based fields share a common duration grammar. A duration string consists of a numeric value followed by a unit suffix: .. list-table:: :header-rows: 1 :widths: 15 25 30 * - Suffix - Unit - Example * - ``s`` - seconds - ``30s`` = 30 seconds * - ``m`` - minutes - ``20m`` = 20 minutes * - ``h`` - hours - ``1h`` = 1 hour * - ``d`` - days - ``1d`` = 1 day The grammar is used by two groups of fields with slightly different handling of a *bare* number (one with no suffix): - **Pure durations** -- ``simulation.time_step`` and the ramp ``duration`` fields (``forcing.ramp.duration``, ``forcing.meteorological.ramp.duration``, ``forcing.flow_boundary.ramp.duration``). A bare number is interpreted as **seconds** (``time_step: 2.0`` is identical to ``time_step: 2s``). - **Step intervals** -- ``output.step_interval``, ``diagnostics.screen_interval`` and ``checkpoint.write_interval``. A bare integer is interpreted as a **count of time steps** (``step_interval: 3600`` means every 3600 steps). A suffixed duration must be evenly divisible by ``time_step``; for example ``20m`` with ``time_step: 7s`` errors because 1200 s is not a multiple of 7 s. **Rules:** - Fractional values are allowed: ``0.5h`` = 30 minutes, ``0.25d`` = 6 hours. - ``0`` is legal only for ``checkpoint.write_interval``, where it means "write a single checkpoint at the end of the run" (see :ref:`checkpoint-configuration`); the other intervals must be positive. **Examples:** .. code-block:: yaml simulation: time_step: 2s # 2-second time step (or: 2.0) forcing: ramp: duration: 12h # 12-hour spinup ramp (or: 43200) output: step_interval: 15m # Every 15 minutes (= 450 steps) diagnostics: screen_interval: 2h # Every 2 hours (= 3600 steps) checkpoint: enabled: true write_interval: 12h # Every 12 hours (= 21600 steps) Unit Conventions ---------------- Input units follow these conventions: .. list-table:: :header-rows: 1 :widths: 30 35 35 * - Quantity - Input Units - Internal Units * - Tidal frequency - rad/s - rad/hr * - Angles (phase, equilibrium_arg) - degrees - radians * - Amplitude - meters - meters * - Time step - seconds - seconds * - Ramp duration - duration string or seconds - seconds Environment Variables --------------------- Cocoa uses standard environment variables for runtime configuration: .. list-table:: :header-rows: 1 :widths: 30 45 25 * - Variable - Description - Default * - ``OMP_NUM_THREADS`` - Number of OpenMP threads (CPU backend) - All available * - ``CUDA_VISIBLE_DEVICES`` - GPU device selection (CUDA backend) - (unset; all devices visible) .. _config-schema-reference: Schema Reference ---------------- The schema below is the exact document the model validates against: it is included here directly from the source tree (``src/cocoa_kernel/core/config/cocoa_config.schema.yaml``), the same file embedded into the binary at build time, so this reference cannot drift from the running code. It is a `JSON Schema (draft-07) `_ document authored as YAML; the conventions (null handling, weak scalar typing, closed key sets) are documented in its header comment. .. literalinclude:: ../../../src/cocoa_kernel/core/config/cocoa_config.schema.yaml :language: yaml