Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions components/omega/configs/Default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Omega:
VelocityVertAdvTendencyEnable: true
TracerVertAdvTendencyEnable: true
PressureGradTendencyEnable: true
FrazilTendencyEnable: true

@alicebarthel alicebarthel Jul 14, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FrazilTendencyEnable: true
FrazilTendencyEnable: false

This needs to be off by default else the omega_pr tests will fail against baseline, and any test using constant/linear eos and frazil will fail. FYI @katsmith133 @cbegeman

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @alicebarthel !

VelVertMixTendencyEnable: true
TracerVertMixTendencyEnable: true
ManufacturedSolution:
Expand All @@ -81,6 +82,12 @@ Omega:
DRhoDT: -0.2
DRhoDS: 0.8
RhoT0S0: 1000.0
Frazil:
FrazilType: basic
MassLimit: 0.1
Phi: 0.75
DepthLimit: -1.0
ConservationCheck: false
VertMix:
Background:
Diffusivity: 1.0e-5
Expand Down
101 changes: 101 additions & 0 deletions components/omega/doc/devGuide/Frazil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
(omega-dev-frazil)=

# Frazil

This page describes frazil design and implementation details in Omega,
including both the `basic` and `teos` pathways.

## Purpose and coupling points

Frazil computes phase-change-related tendencies that modify:

- pseudo-thickness tendency
- temperature tracer tendency
- salinity tracer tendency

The tendency hook-up is implemented through `FrazilOnCell` in the tracer
tendency phase, where frazil contributions are added to the accumulated
`PseudoThicknessTend` and `TracerTend` arrays.

## Data flow and call sequence

1. `Tendencies::computeTracerTendenciesOnly` checks
`Tendencies.FrazilTendencyEnable`.
2. If enabled, `FrazilOnCell::operator()` retrieves the default `Frazil`
object and zeros frazil tendency/accumulator arrays.
3. `FrazilOnCell` extracts `Temperature` and `Salinity` tracer subviews,
then calls `Frazil::computeFrazil(CT, SA, PressureMid, PseudoThickness)`.
4. `Frazil::computeFrazil` dispatches to `computeFrazilBasicImpl` or
`computeFrazilTeosImpl` based on `FrazilType`.
5. Returned frazil tendencies are added into `PseudoThicknessTend` and
`TracerTend` for all active cell layers.

## Configuration coupling

Frazil behavior is configured with:

- `Omega.Tendencies.FrazilTendencyEnable`
- global switch for applying frazil tendency terms
- `Omega.Frazil.FrazilType`
- implementation choice (`basic` or `teos`)
- `Omega.Frazil.MassLimit`
- per-layer mass/thickness limiter used by frazil formation/melt pathways
- `Omega.Frazil.Phi`
- teos pathway liquid-fraction parameter for new frazil partitioning
- `Omega.Frazil.DepthLimit`
- optional depth cutoff for frazil activity; negative means no cutoff
- `Omega.Frazil.ConservationCheck`
- optional post-compute column conservation diagnostic/logging

## Physics/algorithm summary

### Common behavior

- Freezing-point checks are based on conservative temperature and absolute
salinity with pressure-dependent freezing temperature.
- Vertical accumulation order is bottom-to-top within each active column.
- Frazil tendencies are not time-step scaled inside `Frazil`; they are
accumulated as tendency contributions.

### Basic pathway (`FrazilType: basic`)

- Uses simplified energetics: the energy of the super-cooled water sets the
amount of solid ice formed (used constant latent heat of fusion of fresh ice).
Salt is added based on a constant bulk salinity `IceRefSal` (default) or a
manual toggle (for now) using the local salinity and the frazil porosity.
Melting of existing frazil is set by the amount of pure ice that can be melted
by the warm layer, and the enthalpy of melt water at the local freezing point
is added to the temperature tendency.
temperature comparisons and fractional thickness limits.
- Computes local layer tendencies (`HTend`, `TTend`, `STend`) and updates
accumulated frazil stores.
- Applies surface salt redistribution adjustment and converts accumulators to
coupler units at the end of the column loop.
-Warnings: 1) basic frazil formation/melt is does not conserve energy.
2) Using porosity to set the salt content includes a redistribution of excess
salt in the surface layer, which can be very significant.

### Teos pathway (`FrazilType: teos`)

- Uses teos-10 Gibbs SeaWater routines for frazil formation and melt state
transitions.
- Formation uses `Phi` and `MassLimit` to partition and limit newly formed
frazil contributions.
- Melt computes fraction melted subject to available thermodynamic energy and
mass-limit constraints.

## Existing ctest coverage

The existing frazil test driver is in
`components/omega/test/ocn/FrazilTest.cpp` and covers:

- teos frazil formation in cold and warm single-layer states
- basic frazil formation in cold and warm single-layer states
- mixed warm/cold column behavior with sign checks for branch switching
- depth-limit behavior ensuring excluded deep layers have zero frazil tendency


## Related pages

- User-facing options: [User Frazil Guide](../userGuide/Frazil.md)
- Tendency container/hook-up: [Tendencies](Tendencies.md)
17 changes: 17 additions & 0 deletions components/omega/doc/devGuide/Tendencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ Tendencies.computeVelocityTendencies(State, AuxState, ThickTimeLevel, VelTimeLev
To call only the tracer tendency terms:
Tendencies.computeTracerTendencies(State, AuxState, TracerArray, ThickTimeLevel, VelTimeLevel);

## Frazil tendencies

Frazil tendencies are calculated by the Frazil class, not the TendencyTerms.
The tendencies are integrated in the tracer tendency compute path and read in from
the frazil computation. When
`Omega.Tendencies.FrazilTendencyEnable` is true, `computeTracerTendenciesOnly`
invokes `FrazilOnCell`, which calls the default `Frazil` object and adds frazil
contributions to:

- `PseudoThicknessTend`
- `TracerTend` for `Temperature`
- `TracerTend` for `Salinity`

The frazil implementation choice and parameters are read from the
`Omega.Frazil` block. Detailed algorithm/physics notes are in
[Frazil](Frazil.md).

## Removal of tendencies
To erase a specific named tendencies instance use `erase`
```c++
Expand Down
2 changes: 2 additions & 0 deletions components/omega/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ userGuide/Timing
userGuide/VerticalMixingCoeff
userGuide/VertAdv
userGuide/Forcing
userGuide/Frazil
userGuide/SfcCoupling
```

Expand Down Expand Up @@ -101,6 +102,7 @@ devGuide/Timing
devGuide/VerticalMixingCoeff
devGuide/VertAdv
devGuide/Forcing
devGuide/Frazil
devGuide/SfcCoupling
```

Expand Down
67 changes: 67 additions & 0 deletions components/omega/doc/userGuide/Frazil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
(omega-user-frazil)=

# Frazil

This page describes user-facing configuration for frazil tendencies in Omega.
Frazil physics is used to represent the formation and melt of frazil ice within
the ocean water column. It impacts the local layer pseudo-thickness (i.e. mass),
temperature, and salinity tendencies. The vertical sum of the frazil energy,
mass of water and mass of salt are passed to the coupler (if coupled) or
discarded (in ocean standalone mode).

## Configuration overview

Frazil behavior is controlled by one enable switch in `Tendencies` and one
`Frazil` configuration block:

```yaml
Omega:
Tendencies:
FrazilTendencyEnable: true

Frazil:
FrazilType: basic
MassLimit: 0.1
Phi: 0.75
DepthLimit: -1.0
ConservationCheck: false
```

- `Tendencies.FrazilTendencyEnable`
- enables/disables application of frazil tendency contributions
- `Frazil.FrazilType`
- selects frazil option
- supported options in current code: `basic` and `teos`
- `simple` exists as a placeholder name but is not supported
- `Frazil.MassLimit`
- limits per-layer frazil mass/thickness tendency magnitude (applied to formation and melt)
- `Frazil.Phi`
- liquid-mass fraction of frazil (used by the teos frazil formation, or by the basic frazil when using porosity rather than constant salinity).
- `Frazil.DepthLimit`
- limits the depth range over which frazil is computed
- negative values mean no depth limit
- `Frazil.ConservationCheck`
- enables a column-level diagnostic conservation check with logging

## Available frazil options

Omega currently includes two active frazil pathways:

- `basic`
- freezing is based on the formation of fresh solid ice, to which salt is added (similar the mpas-ocean implementation).
- `teos`
- teos-10-based option using Gibbs SeaWater thermodynamic routines.

Both pathways contribute to:

- pseudo-thickness tendency
- temperature tracer tendency
- salinity tracer tendency

## Notes

- Frazil tendencies are applied through the `Tendencies` tracer-step workflow.
- The frazil tendency hook assumes tracer names include `Temperature` and
`Salinity`.
- For implementation and algorithm details, see
[Developer Frazil Guide](../devGuide/Frazil.md).
6 changes: 6 additions & 0 deletions components/omega/doc/userGuide/Tendencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ The `Tendencies` class provides a container for the [tendency terms](#omega-user
Upon creation of an `Tendencies` instance, these functors are initialized and arrays for the
accumulated tendencies are allocated.
There are no user-configurable options beyond those for the tendency term functors.

Frazil is one of the configurable tendency contributions. It is controlled by
`Omega.Tendencies.FrazilTendencyEnable` together with the `Omega.Frazil`
configuration block (`FrazilType`, `MassLimit`, `Phi`, `DepthLimit`, and
`ConservationCheck`). For operational guidance and options, see
[Frazil](Frazil.md).
18 changes: 16 additions & 2 deletions components/omega/src/ocn/Eos.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,8 @@ class Teos10Eos {

/// Calculates freezing Conservative Temperature using TEOS-10 polynomial
/// (polynomial error in [-5e-4, 6e-4] K, from GSW package)
KOKKOS_FUNCTION Real calcCtFreezing(const Real Sa, const Real P,
const Real SaturationFract) const {
KOKKOS_FUNCTION static Real calcCtFreezing(const Real Sa, const Real P,
const Real SaturationFract) {
constexpr Real Sso = 35.16504;
constexpr Real C0 = 0.017947064327968736;
constexpr Real C1 = -6.076099099929818;
Expand Down Expand Up @@ -756,6 +756,20 @@ class Eos {
/// Convert potential temperature to Conservative Temperature
Real calcCtFromPt(const Real &Sa, const Real &Pt) const;

/// Calculate Conservative Temperature at freezing point.
/// P is expected in dbar to match TEOS polynomial convention.
KOKKOS_FUNCTION static Real calcCtFreezing(const Real Sa, const Real P,
const Real SaturationFract,
const EosType Choice) {
if (Choice == EosType::Teos10Eos) {
return Teos10Eos::calcCtFreezing(Sa, P, SaturationFract);
}

Kokkos::abort("Eos::calcCtFreezing: CtFreezing not implemented for "
"non-TEOS-10 EOS");
return 0.0_Real;
}

/// Initialize EOS from config and mesh
static void init();

Expand Down
Loading
Loading