From 4e514188f037bcb118d17bf8f2bdb1b152128ea1 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Fri, 23 Oct 2026 16:18:30 -0500 Subject: [PATCH] Skip inactive edges in the horizontal FCT provisional thickness FCTProvisionaLayerThicknesses summed the thickness flux through every edge of a cell at every layer of that cell, as MPAS-Ocean does. Omega computes FluxPseudoThickEdge and NormalTransportVelocity only on an edge's active layers, and the other entries keep the fill value (9.97e36) they get when their fields are attached. Wherever a cell has a layer that the cell across one of its edges lacks (every layer of a coastal cell, and the bottom layers of cells next to shallower ones), HProv picked up a fill-times-fill term of order 1e70 and HProvInv became of order 1e-71. The limiter's bounds test then reduced to the signs of the local extrema. A cell's own bound stopped limiting antidiffusive outflow once its stencil held a negative value, and never limited antidiffusive inflow of a positive tracer. Bottom cells next to water below 0 C were then cooled by the unlimited antidiffusive part of the centered flux, far below all of their neighbors (E3SM-Project/Omega#588). Skip edges outside [MinLayerEdgeBot, MaxLayerEdgeTop], as the pseudo-thickness flux divergence and ProvPseudoThickness already do. Co-Authored-By: Claude Opus 5.5 (1M context) --- components/omega/src/ocn/TendencyTerms.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/omega/src/ocn/TendencyTerms.h b/components/omega/src/ocn/TendencyTerms.h index 89aa545727f3..d0b655658fb9 100644 --- a/components/omega/src/ocn/TendencyTerms.h +++ b/components/omega/src/ocn/TendencyTerms.h @@ -751,6 +751,10 @@ class TracerHorzAdvOnCell { HProv(ICell, K) = LayerThickness(ICell, K); for (I4 I = 0; I < NEdgesOnCell(ICell); ++I) { const I4 IEdge = EdgesOnCell(ICell, I); + // Skip edges that are inactive at this layer, where the flux + // pseudo-thickness and transport velocity are never computed + if (K < MinLayerEdgeBot(IEdge) || K > MaxLayerEdgeTop(IEdge)) + continue; const Real SignedFactor = InvAreaCell * DvEdge(IEdge) * EdgeSignOnCell(ICell, I); // Provisional layer thickness is after horizontal