Add MaximumMask forcing mask#5576
Open
ewquon wants to merge 13 commits into
Open
Conversation
Composes any number of callable masks via pointwise `max`, so overlapping nudging zones saturate at 1 rather than summing. Useful for Davies-style lateral boundary nudging where corner zones overlap and additive combination would double the effective relaxation rate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a host-side `@testset` covering single-mask passthrough, pointwise `max` correctness across a 3D sweep, composition with mixed mask types (`GaussianMask` + `PiecewiseLinearMask`), saturation at 1 for overlapping unit-peaked masks, the no-arg `ArgumentError`, and the `summary` string. Adds an architecture-parameterized smoke test that runs a `Relaxation` with a Davies-style `MaximumMask` of two `GaussianMask`s for one time step on a `NonhydrostaticModel`, exercising the mask through the kernel path on both CPU and GPU. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds `MaximumMask` to the mask-type bullet list in the `Relaxation` section and a jldoctest snippet showing a Davies-style lateral mask built from two `GaussianMask`s near opposite x-boundaries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
glwagner
reviewed
May 12, 2026
glwagner
reviewed
May 12, 2026
glwagner
reviewed
May 12, 2026
glwagner
approved these changes
May 12, 2026
glwagner
reviewed
May 13, 2026
glwagner
reviewed
May 13, 2026
glwagner
reviewed
May 13, 2026
glwagner
reviewed
May 13, 2026
glwagner
reviewed
May 13, 2026
glwagner
reviewed
May 13, 2026
glwagner
reviewed
May 13, 2026
# Conflicts: # src/Forcings/relaxation.jl # test/test_forcings.jl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MaximumMask(masks...)callable: composes any number of mask objects bytheir pointwise maximum,
mask(x, y, z) = max(mask₁(x, y, z), mask₂(x, y, z), …).GaussianMask,PiecewiseLinearMask, or any othercallable mask (no hard dependency on
CosineRampMaskfrom AddCosineRampMaskforcing mask #5574).GaussianMask/PiecewiseLinearMaskinsrc/Forcings/relaxation.jl,exported from
Forcings.jland re-exported fromOceananigans.(x, y, z)callable matching the existing mask precedent; defaultAdaptcovers the struct.
Why
Composing multiple sponge or boundary-nudging zones via
MultipleForcingsisadditive, which double-strengths the relaxation rate wherever zones overlap —
typically at corners in Davies-style lateral nudging or where an upper sponge
meets a lateral one.
MaximumMasksaturates at 1 in the overlap region instead,preserving the user-specified timescale
1/ratethroughout the nudging volume.This is independently useful for users assembling boundary forcing today (no
CosineRampMaskrequired), and pairs cleanly withCosineRampMask(#5574) oncethat lands for the canonical Davies recipe.
Tests
@testset "MaximumMask construction and pointwise max"intest/test_forcings.jlcovers:maxcorrectness across a 3D(x, y, z)sweepGaussianMask+PiecewiseLinearMask)ArgumentErroron the no-arg constructorsummarystring formatrelaxed_time_stepping_max_mask(arch)smoke test runs a Davies-styleMaximumMaskof twoGaussianMasks inside aRelaxationon aNonhydrostaticModelfor one time step, exercising the mask through thekernel path; wired into the existing relaxation-forcing testset (CPU + GPU).
docs/src/models/forcing_functions.mdshowing aDavies-style construction; output verified locally.
Test plan