From fcdecfb32e2841cc5cd4c5a362d5d98de5bfa324 Mon Sep 17 00:00:00 2001 From: Brian Groenke Date: Fri, 26 Sep 2025 16:09:50 +0200 Subject: [PATCH 1/4] Fix getbc not passing args for discrete BC functions --- src/BoundaryConditions/discrete_boundary_function.jl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/BoundaryConditions/discrete_boundary_function.jl b/src/BoundaryConditions/discrete_boundary_function.jl index a65b4f4654..ad41627b71 100644 --- a/src/BoundaryConditions/discrete_boundary_function.jl +++ b/src/BoundaryConditions/discrete_boundary_function.jl @@ -19,8 +19,9 @@ When `parameters` is not `nothing`, the boundary condition `func` is called with the signature ``` -func(i, j, grid, clock, model_fields, parameters) +func(i, j, grid, clock, model_fields, parameters, args...) ``` +where `args` are any additional arguments passed to `getbc`. *Note* that the index `end` does *not* access the final physical grid point of a model field in any direction. The final grid point must be explictly specified, as @@ -34,17 +35,17 @@ end const UnparameterizedDBF = DiscreteBoundaryFunction{<:Nothing} @inline getbc(condition::UnparameterizedDBF, i::Integer, j::Integer, grid::AbstractGrid, clock, model_fields, args...) = - condition.func(i, j, grid, clock, model_fields) + condition.func(i, j, grid, clock, model_fields, args...) @inline getbc(condition::DiscreteBoundaryFunction, i::Integer, j::Integer, grid::AbstractGrid, clock, model_fields, args...) = - condition.func(i, j, grid, clock, model_fields, condition.parameters) + condition.func(i, j, grid, clock, model_fields, condition.parameters, args...) # 3D function for immersed boundary conditions @inline getbc(condition::UnparameterizedDBF, i::Integer, j::Integer, k::Integer, grid::AbstractGrid, clock, model_fields, args...) = - condition.func(i, j, k, grid, clock, model_fields) + condition.func(i, j, k, grid, clock, model_fields, args...) @inline getbc(condition::DiscreteBoundaryFunction, i::Integer, j::Integer, k::Integer, grid::AbstractGrid, clock, model_fields, args...) = - condition.func(i, j, k, grid, clock, model_fields, condition.parameters) + condition.func(i, j, k, grid, clock, model_fields, condition.parameters, args...) # Don't re-convert DiscreteBoundaryFunctions passed to BoundaryCondition constructor BoundaryCondition(Classification::DataType, condition::DiscreteBoundaryFunction) = BoundaryCondition(Classification(), condition) From 9bbebb887c446d5d656ad2441615854cb363fff7 Mon Sep 17 00:00:00 2001 From: Brian Groenke Date: Fri, 26 Sep 2025 16:12:55 +0200 Subject: [PATCH 2/4] Improve docstring for DiscreteBoundaryFunction --- .../discrete_boundary_function.jl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/BoundaryConditions/discrete_boundary_function.jl b/src/BoundaryConditions/discrete_boundary_function.jl index ad41627b71..ec76d2e1cf 100644 --- a/src/BoundaryConditions/discrete_boundary_function.jl +++ b/src/BoundaryConditions/discrete_boundary_function.jl @@ -5,15 +5,17 @@ A wrapper for boundary condition functions with optional parameters. When `parameters=nothing`, the boundary condition `func` is called with the signature ``` -func(i, j, grid, clock, model_fields) +func(i, j, grid, clock, model_fields, args...) ``` where `i, j` are the indices along the boundary, -where `grid` is `model.grid`, `clock.time` is the current simulation time and -`clock.iteration` is the current model iteration, and -`model_fields` is a `NamedTuple` with `u, v, w`, the fields in `model.tracers`, -and the fields in `model.diffusivity_fields`, each of which is an `OffsetArray`s (or `NamedTuple`s -of `OffsetArray`s depending on the turbulence closure) of field data. +`grid` is `model.grid`, +`model_fields` is a `NamedTuple` with `u, v, w`, the fields in `model.tracers` or +the fields in `model.diffusivity_fields`, each of which is an `OffsetArray`s (or `NamedTuple`s +of `OffsetArray`s depending on the turbulence closure) of field data, +and `args` are any additional arguments passed to `getbc`. +Note also that `clock.time` is the current simulation time and `clock.iteration` is the current model +iteration. When `parameters` is not `nothing`, the boundary condition `func` is called with the signature @@ -21,7 +23,6 @@ the signature ``` func(i, j, grid, clock, model_fields, parameters, args...) ``` -where `args` are any additional arguments passed to `getbc`. *Note* that the index `end` does *not* access the final physical grid point of a model field in any direction. The final grid point must be explictly specified, as From 899aba597e2d413d3f3fbe291921b499f3a239d1 Mon Sep 17 00:00:00 2001 From: Brian Groenke Date: Fri, 26 Sep 2025 16:44:25 +0200 Subject: [PATCH 3/4] Remove redundant varargs in getbc for ContinuousBoundaryFunction --- .../continuous_boundary_function.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/BoundaryConditions/continuous_boundary_function.jl b/src/BoundaryConditions/continuous_boundary_function.jl index 0f3e070a6d..96b98f43b8 100644 --- a/src/BoundaryConditions/continuous_boundary_function.jl +++ b/src/BoundaryConditions/continuous_boundary_function.jl @@ -124,7 +124,7 @@ const ZBoundaryFunction{LX, LY, S} = ContinuousBoundaryFunction{LX, LY, Nothing, # Return ContinuousBoundaryFunction on east or west boundaries. @inline function getbc(cbf::XBoundaryFunction{LY, LZ, S}, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields, args...) where {LY, LZ, S} + grid::AbstractGrid, clock, model_fields) where {LY, LZ, S} i, i′ = domain_boundary_indices(S(), grid.Nx) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -135,7 +135,7 @@ end # Return ContinuousBoundaryFunction on south or north boundaries. @inline function getbc(cbf::YBoundaryFunction{LX, LZ, S}, i::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields, args...) where {LX, LZ, S} + grid::AbstractGrid, clock, model_fields) where {LX, LZ, S} j, j′ = domain_boundary_indices(S(), grid.Ny) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -146,7 +146,7 @@ end # Return ContinuousBoundaryFunction on bottom or top boundaries. @inline function getbc(cbf::ZBoundaryFunction{LX, LY, S}, i::Integer, j::Integer, - grid::AbstractGrid, clock, model_fields, args...) where {LX, LY, S} + grid::AbstractGrid, clock, model_fields) where {LX, LY, S} k, k′ = domain_boundary_indices(S(), grid.Nz) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -161,7 +161,7 @@ end # Return ContinuousBoundaryFunction on the east or west interface of a cell adjacent to an immersed boundary @inline function getbc(cbf::XBoundaryFunction{LY, LZ, S}, i::Integer, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields, args...) where {LY, LZ, S} + grid::AbstractGrid, clock, model_fields) where {LY, LZ, S} i′ = cell_boundary_index(S(), i) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -172,7 +172,7 @@ end # Return ContinuousBoundaryFunction on the south or north interface of a cell adjacent to an immersed boundary @inline function getbc(cbf::YBoundaryFunction{LX, LZ, S}, i::Integer, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields, args...) where {LX, LZ, S} + grid::AbstractGrid, clock, model_fields) where {LX, LZ, S} j′ = cell_boundary_index(S(), j) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -183,7 +183,7 @@ end # Return ContinuousBoundaryFunction on the bottom or top interface of a cell adjacent to an immersed boundary @inline function getbc(cbf::ZBoundaryFunction{LX, LY, S}, i::Integer, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields, args...) where {LX, LY, S} + grid::AbstractGrid, clock, model_fields) where {LX, LY, S} k′ = cell_boundary_index(S(), k) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) From 027aa8f35c9d929f9e4659f234da47d50a9805bd Mon Sep 17 00:00:00 2001 From: Brian Groenke Date: Thu, 2 Oct 2025 14:48:40 +0200 Subject: [PATCH 4/4] Revert "Merge branch 'bg/fix-discrete-bc' of github.com:CliMA/Oceananigans.jl into bg/fix-discrete-bc" This reverts commit f100b7e7a3fff90d60303297df6a81ffb13b5a8e, reversing changes made to 9bbebb887c446d5d656ad2441615854cb363fff7. --- .../continuous_boundary_function.jl | 12 ++++++------ .../compute_hydrostatic_flux_bcs.jl | 7 +++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/BoundaryConditions/continuous_boundary_function.jl b/src/BoundaryConditions/continuous_boundary_function.jl index 96b98f43b8..0f3e070a6d 100644 --- a/src/BoundaryConditions/continuous_boundary_function.jl +++ b/src/BoundaryConditions/continuous_boundary_function.jl @@ -124,7 +124,7 @@ const ZBoundaryFunction{LX, LY, S} = ContinuousBoundaryFunction{LX, LY, Nothing, # Return ContinuousBoundaryFunction on east or west boundaries. @inline function getbc(cbf::XBoundaryFunction{LY, LZ, S}, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields) where {LY, LZ, S} + grid::AbstractGrid, clock, model_fields, args...) where {LY, LZ, S} i, i′ = domain_boundary_indices(S(), grid.Nx) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -135,7 +135,7 @@ end # Return ContinuousBoundaryFunction on south or north boundaries. @inline function getbc(cbf::YBoundaryFunction{LX, LZ, S}, i::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields) where {LX, LZ, S} + grid::AbstractGrid, clock, model_fields, args...) where {LX, LZ, S} j, j′ = domain_boundary_indices(S(), grid.Ny) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -146,7 +146,7 @@ end # Return ContinuousBoundaryFunction on bottom or top boundaries. @inline function getbc(cbf::ZBoundaryFunction{LX, LY, S}, i::Integer, j::Integer, - grid::AbstractGrid, clock, model_fields) where {LX, LY, S} + grid::AbstractGrid, clock, model_fields, args...) where {LX, LY, S} k, k′ = domain_boundary_indices(S(), grid.Nz) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -161,7 +161,7 @@ end # Return ContinuousBoundaryFunction on the east or west interface of a cell adjacent to an immersed boundary @inline function getbc(cbf::XBoundaryFunction{LY, LZ, S}, i::Integer, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields) where {LY, LZ, S} + grid::AbstractGrid, clock, model_fields, args...) where {LY, LZ, S} i′ = cell_boundary_index(S(), i) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -172,7 +172,7 @@ end # Return ContinuousBoundaryFunction on the south or north interface of a cell adjacent to an immersed boundary @inline function getbc(cbf::YBoundaryFunction{LX, LZ, S}, i::Integer, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields) where {LX, LZ, S} + grid::AbstractGrid, clock, model_fields, args...) where {LX, LZ, S} j′ = cell_boundary_index(S(), j) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) @@ -183,7 +183,7 @@ end # Return ContinuousBoundaryFunction on the bottom or top interface of a cell adjacent to an immersed boundary @inline function getbc(cbf::ZBoundaryFunction{LX, LY, S}, i::Integer, j::Integer, k::Integer, - grid::AbstractGrid, clock, model_fields) where {LX, LY, S} + grid::AbstractGrid, clock, model_fields, args...) where {LX, LY, S} k′ = cell_boundary_index(S(), k) args = user_function_arguments(i, j, k, grid, model_fields, cbf.parameters, cbf) diff --git a/src/Models/HydrostaticFreeSurfaceModels/compute_hydrostatic_flux_bcs.jl b/src/Models/HydrostaticFreeSurfaceModels/compute_hydrostatic_flux_bcs.jl index 2e8f3d5a71..d64741642a 100644 --- a/src/Models/HydrostaticFreeSurfaceModels/compute_hydrostatic_flux_bcs.jl +++ b/src/Models/HydrostaticFreeSurfaceModels/compute_hydrostatic_flux_bcs.jl @@ -20,14 +20,17 @@ function compute_flux_bc_tendencies!(model::HydrostaticFreeSurfaceModel) velocities = model.velocities tracers = model.tracers + args = (model.clock, fields(model), model.closure, model.buoyancy) + + # Velocity fields for i in (:u, :v) - @apply_regionally compute_flux_bcs!(Gⁿ[i], velocities[i], arch, model.clock, fields(model)) + @apply_regionally compute_flux_bcs!(Gⁿ[i], velocities[i], arch, args) end # Tracer fields for i in propertynames(tracers) - @apply_regionally compute_flux_bcs!(Gⁿ[i], tracers[i], arch, model.clock, fields(model)) + @apply_regionally compute_flux_bcs!(Gⁿ[i], tracers[i], arch, args) end return nothing