Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(0.91.7) Open boundary conditions for NonhydrostaticModel #3482

Merged
merged 125 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from 123 commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
2cd21fe
Generalised `Open` boundary condition
jagoosw Mar 13, 2024
2d36090
`adapt` seems to be defined twice for boundary conditions
jagoosw Mar 18, 2024
581159f
added internal wave example
jagoosw Mar 18, 2024
dea4e2b
corrected spelling in adapt
jagoosw Mar 19, 2024
d7ec522
mistake
jagoosw Mar 19, 2024
ed83fed
Merge remote-tracking branch 'origin' into jsw/open-boundaries
jagoosw Mar 21, 2024
98cc3b4
corrected syntax
jagoosw Mar 21, 2024
a60b476
Merge branch 'main' into jsw/open-boundaries
glwagner Mar 26, 2024
14f7958
changed validation name
jagoosw Mar 26, 2024
ec5b515
clarified sponge
jagoosw Mar 26, 2024
3aa6b6b
fixed docs
jagoosw Mar 28, 2024
8892a7f
a slightly less ugly way of passing around boundary condition classif…
jagoosw Mar 28, 2024
2555886
added `update_boundary_condition!` and `update_boundary_conditions!`
jagoosw Mar 28, 2024
42da017
more update boundary condition changes
jagoosw Mar 29, 2024
4bf0252
add mean outflow open boundary condition
jagoosw Apr 23, 2024
5b7fb6b
Merge remote-tracking branch 'origin' into jsw/open-boundaries
jagoosw May 7, 2024
5dae25f
Merge branch 'main' into jsw/open-boundaries
jagoosw May 22, 2024
6dfa874
Merge remote-tracking branch 'origin/jsw/open-boundaries' into jsw/op…
jagoosw May 22, 2024
c06aded
change boundary conditions setup to allow classifcations to have prop…
jagoosw May 22, 2024
e6e33f4
forgot to add Adapt import
jagoosw May 22, 2024
c9aa318
forgot another local change
jagoosw May 22, 2024
f00eea3
fixed immersed boundary conditions
jagoosw May 22, 2024
9d106cd
fixed tests
jagoosw May 22, 2024
7294f47
fixed for etc.
jagoosw May 24, 2024
1369d64
added kwarg to to know if the pressure is corrected
jagoosw May 28, 2024
26e7f4a
addded no wall normal velocity gradcient
jagoosw May 28, 2024
15a527a
moved clock tick to before pressure correction
jagoosw May 29, 2024
b38400b
Revert "added kwarg to to know if the pressure is corrected"
jagoosw May 30, 2024
c8f6cd6
refuse to fill bounded-wall normal velocity points after the pressure…
jagoosw May 30, 2024
a8e5c24
Revert "refuse to fill bounded-wall normal velocity points after the …
jagoosw May 31, 2024
dc6fa32
different implementation to only fill bounde wall normal velocity hal…
jagoosw May 31, 2024
d951d2f
corrections
jagoosw May 31, 2024
9f72248
correction
jagoosw May 31, 2024
ee83c91
refactor open halo filling to multiple dispatch rather than if else
jagoosw Jun 1, 2024
d200123
formatting
jagoosw Jun 1, 2024
087288e
formatting
jagoosw Jun 3, 2024
319615e
fixed new way to fill open halos
jagoosw Jun 3, 2024
6a7c91e
backwars compatible, do we want this or to update the tests?
jagoosw Jun 3, 2024
cc177ab
renamed functions
jagoosw Jun 4, 2024
980e253
change no graidnet bc to return nothing
jagoosw Jun 4, 2024
56e6837
Fixed set model for new boundary filling
jagoosw Jun 4, 2024
924c48c
fixed poisson solver test
jagoosw Jun 4, 2024
0f982a4
fixed stretched poisson solver test
jagoosw Jun 4, 2024
6af937c
simplified test updates
jagoosw Jun 5, 2024
ee478d4
fixed naming for boundary condition updates
jagoosw Jun 5, 2024
dbf175a
fixed bc tests again
jagoosw Jun 5, 2024
14c32ec
fixed bc integration test
jagoosw Jun 5, 2024
4c3623c
fixed import
jagoosw Jun 5, 2024
aed409d
added \`fill_open_boundary_region\` method for manual call on \`Field\`
jagoosw Jun 5, 2024
3dd71ad
moved `fill_open_boundary_region\!`
jagoosw Jun 5, 2024
4e2b75f
Merge branch 'main' into jsw/open-boundaries
jagoosw Jun 5, 2024
7b4ee13
corrected order of boundary filling
jagoosw Jun 6, 2024
730a50c
solved multi region bug for update boundary conditions
jagoosw Jun 6, 2024
44687b0
renamed `ZeroGradient` matching scheme
jagoosw Jun 6, 2024
361d6d8
renamed flat extrapolation file
jagoosw Jun 6, 2024
9524775
fixed open halo filling for tracers
jagoosw Jun 6, 2024
f88b5c6
correction
jagoosw Jun 6, 2024
dbbe26b
fixed set nonhydrostatic model
jagoosw Jun 6, 2024
da50c49
corrected doc string
jagoosw Jun 7, 2024
92c16f3
fix (?) multi region grid fills
jagoosw Jun 7, 2024
bf312b8
maybe made windowed fields work
jagoosw Jun 20, 2024
19aad6c
fixed multiregion open fills (more tests now pass locally ...)
jagoosw Jun 20, 2024
f439402
Revert previous test change
jagoosw Jun 20, 2024
2c5e6b5
fixed more tests
jagoosw Jun 20, 2024
f3a7ff8
reverted an accidental (?) change
jagoosw Jun 20, 2024
bfb3f08
MRG tests pass locally
jagoosw Jun 20, 2024
8d8b049
Removed redundant code
jagoosw Jun 20, 2024
d468538
added back Impenetrable BC summary
jagoosw Jun 20, 2024
727a3af
change some @test_skip to @test
jagoosw Jun 20, 2024
43d6ac1
Update src/BoundaryConditions/show_boundary_conditions.jl
jagoosw Jun 20, 2024
42f9216
renamed `left/right_boundary_condition`
jagoosw Jun 21, 2024
399799b
maybe made distributed work
jagoosw Jun 25, 2024
38fe629
oops
jagoosw Jun 25, 2024
2332b00
corrected multi region change
jagoosw Jun 25, 2024
d7b6af4
Merge branch 'main' into jsw/open-boundaries
jagoosw Jun 25, 2024
f3e382f
I can't use githubs merge conflict thing
jagoosw Jun 25, 2024
8df0534
renamed distributed halo fill
jagoosw Jun 26, 2024
d6515bc
revert computed field test change
jagoosw Jun 26, 2024
a443e8c
finally understand distributed bc filling
jagoosw Jun 26, 2024
7afba99
mistake
jagoosw Jun 26, 2024
231658d
added oscillating example and added relaxation to flat extrapolation
jagoosw Jun 28, 2024
0cdefc7
fixed
jagoosw Jun 28, 2024
102bee6
added documentation for open boundary conditions
jagoosw Jun 29, 2024
d5cd0da
Apply suggestions from code review
jagoosw Jul 1, 2024
16f9a0b
spelling
jagoosw Jul 1, 2024
312b786
Update src/BoundaryConditions/flat_extrapolation_open_boundary_matchi…
jagoosw Jul 1, 2024
ab961c4
made FEOBC work for stretched grids
jagoosw Jul 2, 2024
23d8ac6
Merge branch 'main' into jsw/open-boundaries
jagoosw Jul 4, 2024
68003d4
Apply suggestions from code review
jagoosw Jul 8, 2024
99e2c80
Update src/BoundaryConditions/BoundaryConditions.jl
jagoosw Jul 8, 2024
3b3aca3
bump version
jagoosw Jul 8, 2024
4a176d7
review comments
jagoosw Jul 10, 2024
762197d
rename \`update_boundary_conditions!\` to \`update_boundary_condition!\`
jagoosw Jul 10, 2024
abb06b7
made `spacing_factor` stuff grid agnostic
jagoosw Jul 10, 2024
589fb60
fix
jagoosw Jul 10, 2024
1787e1d
renamed \`unrelaxed\` to \`gradient_free_c\`
jagoosw Jul 10, 2024
a8b563a
fix formatting in validation scripts
jagoosw Jul 10, 2024
ca7ad37
removed redundant adapts
jagoosw Jul 10, 2024
ff0a93f
formatting in update model
jagoosw Jul 10, 2024
c3c136f
removed commenting out of \`update_model_field_time_series!\`
jagoosw Jul 10, 2024
7e587a1
replaced redundant \`get_boundary_conditions\`
jagoosw Jul 10, 2024
35e31b7
Apply suggestions from code review
jagoosw Jul 15, 2024
ecdc372
fix boundary conditions doctest
jagoosw Jul 23, 2024
c3c76bf
clarified fallbacks for open boundary conditions
jagoosw Jul 23, 2024
db7ab11
Apply suggestions from code review
jagoosw Jul 23, 2024
6fab8df
turns out we did need this fallback
jagoosw Jul 24, 2024
fa50db4
changed `C` to `c` and `c` to `a`
jagoosw Jul 25, 2024
137b2de
changed `a` to `ϕ`
jagoosw Jul 25, 2024
d9bb081
changed argument order for `update_boundary_condition!`
jagoosw Jul 25, 2024
0720bd8
failure to find and replace
jagoosw Jul 25, 2024
cd218e1
failure to find and replace more
jagoosw Jul 25, 2024
310440d
Update lagrangian_particle_advection.jl
jagoosw Jul 26, 2024
22a0dc9
Merge branch 'main' into jsw/open-boundaries
jagoosw Jul 26, 2024
775d154
changed argument order in `relax`
jagoosw Jul 26, 2024
cc3667b
Attempts to fix enzyme tests
jagoosw Jul 30, 2024
99e09f0
Apply suggestions from code review
jagoosw Aug 1, 2024
c1d051c
Update update_boundary_conditions.jl
jagoosw Aug 1, 2024
35ea06b
merge
jagoosw Aug 1, 2024
cdd0a22
modify `boundary_conditions`
jagoosw Aug 1, 2024
91bdd79
Rearranged regular fills for OBCs
jagoosw Aug 3, 2024
5e9c99c
Update fill_halo_regions_open.jl
jagoosw Aug 4, 2024
87ac61d
Apply suggestions from code review
jagoosw Aug 6, 2024
e0edca7
hopeflly merged main
jagoosw Aug 7, 2024
ef4d2fc
correct version number
jagoosw Aug 7, 2024
a1bbddd
Merge branch 'main' into jsw/open-boundaries
jagoosw Aug 7, 2024
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Oceananigans"
uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09"
authors = ["Climate Modeling Alliance and contributors"]
version = "0.91.6"
version = "0.92.0"
glwagner marked this conversation as resolved.
Show resolved Hide resolved

[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
Expand Down
4 changes: 2 additions & 2 deletions docs/src/model_setup/boundary_conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ julia> model.velocities.v.boundary_conditions
Oceananigans.FieldBoundaryConditions, with boundary conditions
├── west: PeriodicBoundaryCondition
├── east: PeriodicBoundaryCondition
├── south: OpenBoundaryCondition: Nothing
├── north: OpenBoundaryCondition: Nothing
├── south: OpenBoundaryCondition{Nothing}: Nothing
├── north: OpenBoundaryCondition{Nothing}: Nothing
├── bottom: ValueBoundaryCondition: 0.0
├── top: FluxBoundaryCondition: Nothing
└── immersed: FluxBoundaryCondition: Nothing
Expand Down
101 changes: 101 additions & 0 deletions docs/src/numerical_implementation/boundary_conditions.md
tomchor marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,104 @@ boundaries ``\partial \Omega_b``:
values of ``c``.

Flux boundary conditions are represented by the [`Flux`](@ref) type.

## Open boundary conditions

Open boundary conditions directly specify the value of the halo points. Typically this is used
to impose no penetration boundary conditions, i.e. setting wall normal velocity components on
to zero on the boundary.

The nuance here is that open boundaries behave differently for fields on face points in the
boundary direction due to the [staggered grid](@ref finite_volume). For example, the u-component
of velocity lies on `(Face, Center, Center)` points so for open `west` or `east` boundaries the
point specified by the boundary condition is the point lying on the boundary, where as for a
tracer on `(Center, Center, Center)` points the open boundary condition specifies a point outside
of the domain (hence the difference with `Value` boundary conditions).

The other important detail is that open (including no-penetration) boundary conditions are the
only conditions used on wall normal velocities when the domain is not periodic. This means that
their value affects the pressure calculation for nonhydrostatic models as it is involved in
calculating the divergence in the boundary adjacent center point (as described in the
[fractional step method](@ref time_stepping) documentation). Usually boundary points are filled
for the predictor velocity (i.e. before the pressure is calculated), and on the corrected field
(i.e. after the pressure correction is applied), but for open boundaries this would result in
the boundary adjacent center point becoming divergent so open boundaries are only filled for the
predictor velocity and stay the same after the pressure correction (so the boundary point is filled
with the final corrected velocity at the predictor step).

The restriction arrises as the boundary condition is specifying the wall normal velocity,
``\hat{\boldsymbol{n}}\cdot\boldsymbol{u}``, which leads to the pressure boundary condition
```math
\begin{equation}
\label{eq:pressure_boundary_condition}
\Delta t \, \hat{\boldsymbol{n}}\cdot\boldsymbol{\nabla}p^{n+1}\big |_{\partial\Omega} = \left[\Delta t \, \hat{\boldsymbol{n}}\cdot\boldsymbol{u}^\star - \hat{\boldsymbol{n}}\cdot\boldsymbol{u}^{n+1}\right],
\end{equation}
```
implying that there is a pressure gradient across the boundary. Since we solve the pressure poisson
equation (``\nabla^2p^{n+1}=\frac{\boldsymbol{\nabla}\cdot\boldsymbol{u}^\star}{\Delta t}``)
using the method described by [Schumann88](@citet) we have to move inhomogeneus boundary conditions
on the pressure to the right hand side. In order to do this we define a new field ``\phi`` where
```math
\begin{equation}
\label{eq:modified_pressure_field}
\phi = p^{n+1} \quad \text{inside} \quad \Omega \quad \text{but} \quad \boldsymbol{\nabla} \cdot \boldsymbol{\nabla} \phi \, \big |_{\partial\Omega} = 0.
\end{equation}
```
This moves the boundary condition to the right hand side as ``\phi`` becomes
```math
\begin{equation}
\label{eq:modified_pressure_poisson}
\boldsymbol{\nabla}^2\phi^{n+1} = \boldsymbol{\nabla}\cdot\left[\frac{\boldsymbol{u}^\star}{\Delta t} - \delta\left(\boldsymbol{x} - \boldsymbol{x}_\Omega\right)\boldsymbol{\nabla}p\right].
\end{equation}
```
Given the boundary condition on pressure given above, we can define a new modified predictor velocity
which is equal to the predictor velocity within the domain but shares boundary conditions with the
corrected field,
```math
\begin{equation}
\label{eq:quasi_predictor_velocity}
\tilde{\boldsymbol{u}}^\star:=\boldsymbol{u}^\star + \delta\left(\boldsymbol{x} - \boldsymbol{x}_\Omega\right)(\boldsymbol{u}^{n+1} - \boldsymbol{u}^\star).
\end{equation}
```
The modified pressure poisson equation becomes ``\nabla^2p^{n+1}=\frac{\boldsymbol{\nabla}\cdot\tilde{\boldsymbol{u}}^\star}{\Delta t}``
which can easily be solved.

Perhaps a more intuitive way to consider this is to recall that the corrector step projects ``\boldsymbol{u}^\star``
to the space of divergenece free velocity by applying
```math
\begin{equation}
\label{eq:pressure_correction_step}
\boldsymbol{u}^{n+1} = \boldsymbol{u}^\star - \Delta t\boldsymbol{\nabla}p^{n+1},
\end{equation}
```
but we have changed ``p^{n+1}`` to ``\phi`` and ``\boldsymbol{u}^\star`` to ``\tilde{\boldsymbol{u}}^\star``
so for ``\boldsymbol{\nabla}\phi \big |_{\partial\Omega} = 0`` the modified predictor velocity must
equal the corrected velocity on the boundary.

For simple open boundary conditions such as no penetration or a straight forward prescription of
a known velocity at ``t^{n+1}`` this is simple to implement as we just set the boundary condition
on the predictor velocity and don't change it after the correction. But some open boundary methods
calculate the boundary value based on the interior solution. As a simple example, if we wanted to
set the wall normal veloicty gradient to zero at the west boundary then we would set the boundary
point to
```math
\begin{equation}
\label{eq:zero_wall_normal_velocity_gradient}
u^\star_{1jk} \approx u^\star_{3jk} + (u^\star_{2jk} - u^\star_{jk4}) / 2 + \mathcal{O}(\Delta x^2),
\end{equation}
```
but we then pressure correct the interior so a new ``\mathcal{O}(\Delta t)`` error is introduced as
```math
\begin{equation}
\begin{align}
u^{n+1}_{1jk} &\approx u^{n+1}_{3jk} + (u^{n+1}_{2jk} - u^{n+1}_{jk4}) / 2 + \mathcal{O}(\Delta x^2),\\
&= u^\star_{1jk} - \Delta t \left(\boldsymbol{\nabla}p^{n+1}_{3jk} + (\boldsymbol{\nabla}p^{n+1}_{2jk} - \boldsymbol{\nabla}p^{n+1}_{4jk}) / 2\right) + \mathcal{O}(\Delta x^2),\\
&\approx u^\star_{1jk} + \mathcal{O}(\Delta x^2) + \mathcal{O}(\Delta t).
\end{align}
\end{equation}
```
This is prefered to a divergent interior solution as open boundary conditions (except no penetration)
are typlically already unphysical and only used in an attempt to allow information to enter or exit
the domain.

Open boundary conditions are represented by the [`Open`](@ref) type.
2 changes: 1 addition & 1 deletion docs/src/numerical_implementation/finite_volume.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Finite volume method on a staggered grid
# [Finite volume method on a staggered grid](@id finite_volume)

The `Oceananigans.jl` staggered grid is defined by a rectilinear array of cuboids of horizontal dimensions
``\Delta x_{i, j, k}, \Delta y_{i, j, k}`` and vertical dimension
Expand Down
7 changes: 6 additions & 1 deletion src/BoundaryConditions/BoundaryConditions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ export
apply_x_bcs!, apply_y_bcs!, apply_z_bcs!,
fill_halo_regions!

using CUDA
using CUDA, Adapt
using KernelAbstractions: @index, @kernel

using Oceananigans.Architectures: CPU, GPU, device
using Oceananigans.Utils: work_layout, launch!
using Oceananigans.Operators: Ax, Ay, Az, volume
using Oceananigans.Grids

import Adapt: adapt_structure
tomchor marked this conversation as resolved.
Show resolved Hide resolved

include("boundary_condition_classifications.jl")
include("boundary_condition.jl")
include("discrete_boundary_function.jl")
Expand All @@ -34,4 +36,7 @@ include("fill_halo_regions_nothing.jl")

include("apply_flux_bcs.jl")

include("update_boundary_conditions.jl")

include("flat_extrapolation_open_boundary_matching_scheme.jl")
end # module
54 changes: 20 additions & 34 deletions src/BoundaryConditions/boundary_condition.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Adapt
import Oceananigans.Architectures: on_architecture

"""
Expand All @@ -12,21 +11,12 @@ struct BoundaryCondition{C<:AbstractBoundaryConditionClassification, T}
end

"""
BoundaryCondition(Classification::DataType, condition)

Construct a boundary condition of type `BC` with a number or array as a `condition`.

Boundary condition types include `Periodic`, `Flux`, `Value`, `Gradient`, and `Open`.
"""
BoundaryCondition(Classification::DataType, condition) = BoundaryCondition(Classification(), condition)

"""
BoundaryCondition(Classification::DataType, condition::Function;
BoundaryCondition(classification::AbstractBoundaryConditionClassification, condition::Function;
parameters = nothing,
discrete_form = false,
field_dependencies=())

Construct a boundary condition of type `Classification` with a function boundary `condition`.
Construct a boundary condition of type `classification` with a function boundary `condition`.

By default, the function boudnary `condition` is assumed to have the 'continuous form'
`condition(ξ, η, t)`, where `t` is time and `ξ` and `η` vary along the boundary.
Expand All @@ -50,7 +40,7 @@ where `i`, and `j` are indices that vary along the boundary. If `discrete_form =
condition(i, j, grid, clock, model_fields, parameters)
```
"""
function BoundaryCondition(Classification::DataType, condition::Function;
function BoundaryCondition(classification::AbstractBoundaryConditionClassification, condition::Function;
parameters = nothing,
discrete_form = false,
field_dependencies=())
Expand All @@ -63,17 +53,16 @@ function BoundaryCondition(Classification::DataType, condition::Function;
condition = ContinuousBoundaryFunction(condition, parameters, field_dependencies)
end

return BoundaryCondition(Classification(), condition)
return BoundaryCondition(classification, condition)
end
jagoosw marked this conversation as resolved.
Show resolved Hide resolved

# Adapt boundary condition struct to be GPU friendly and passable to GPU kernels.
Adapt.adapt_structure(to, b::BoundaryCondition{Classification}) where Classification =
BoundaryCondition(Classification(), Adapt.adapt(to, b.condition))

Adapt.adapt_structure(to, b::BoundaryCondition) =
BoundaryCondition(Adapt.adapt(to, b.classification), Adapt.adapt(to, b.condition))

# Adapt boundary condition struct to be GPU friendly and passable to GPU kernels.
on_architecture(to, b::BoundaryCondition{Classification}) where Classification =
BoundaryCondition(Classification(), on_architecture(to, b.condition))
on_architecture(to, b::BoundaryCondition) =
BoundaryCondition(on_architecture(to, b.classification), on_architecture(to, b.condition))

#####
##### Some abbreviations to make life easier.
Expand All @@ -91,18 +80,18 @@ const MCBC = BoundaryCondition{<:MultiRegionCommunication}
const DCBC = BoundaryCondition{<:DistributedCommunication}

# More readable BC constructors for the public API.
PeriodicBoundaryCondition() = BoundaryCondition(Periodic, nothing)
NoFluxBoundaryCondition() = BoundaryCondition(Flux, nothing)
ImpenetrableBoundaryCondition() = BoundaryCondition(Open, nothing)
MultiRegionCommunicationBoundaryCondition() = BoundaryCondition(MultiRegionCommunication, nothing)
DistributedCommunicationBoundaryCondition() = BoundaryCondition(DistributedCommunication, nothing)

FluxBoundaryCondition(val; kwargs...) = BoundaryCondition(Flux, val; kwargs...)
ValueBoundaryCondition(val; kwargs...) = BoundaryCondition(Value, val; kwargs...)
GradientBoundaryCondition(val; kwargs...) = BoundaryCondition(Gradient, val; kwargs...)
OpenBoundaryCondition(val; kwargs...) = BoundaryCondition(Open, val; kwargs...)
MultiRegionCommunicationBoundaryCondition(val; kwargs...) = BoundaryCondition(MultiRegionCommunication, val; kwargs...)
DistributedCommunicationBoundaryCondition(val; kwargs...) = BoundaryCondition(DistributedCommunication, val; kwargs...)
PeriodicBoundaryCondition() = BoundaryCondition(Periodic(), nothing)
NoFluxBoundaryCondition() = BoundaryCondition(Flux(), nothing)
ImpenetrableBoundaryCondition() = BoundaryCondition(Open(), nothing)
MultiRegionCommunicationBoundaryCondition() = BoundaryCondition(MultiRegionCommunication(), nothing)
DistributedCommunicationBoundaryCondition() = BoundaryCondition(DistributedCommunication(), nothing)

FluxBoundaryCondition(val; kwargs...) = BoundaryCondition(Flux(), val; kwargs...)
ValueBoundaryCondition(val; kwargs...) = BoundaryCondition(Value(), val; kwargs...)
GradientBoundaryCondition(val; kwargs...) = BoundaryCondition(Gradient(), val; kwargs...)
OpenBoundaryCondition(val; kwargs...) = BoundaryCondition(Open(nothing), val; kwargs...)
MultiRegionCommunicationBoundaryCondition(val; kwargs...) = BoundaryCondition(MultiRegionCommunication(), val; kwargs...)
DistributedCommunicationBoundaryCondition(val; kwargs...) = BoundaryCondition(DistributedCommunication(), val; kwargs...)
tomchor marked this conversation as resolved.
Show resolved Hide resolved

# Support for various types of boundary conditions.
#
Expand All @@ -125,9 +114,6 @@ DistributedCommunicationBoundaryCondition(val; kwargs...) = BoundaryCondition(Di
const NumberRef = Base.RefValue{<:Number}
@inline getbc(bc::BC{<:Any, <:NumberRef}, args...) = bc.condition[]

Adapt.adapt_structure(to, bc::BoundaryCondition) = BoundaryCondition(Adapt.adapt(to, bc.classification),
Adapt.adapt(to, bc.condition))

#####
##### Validation with topology
#####
Expand Down
10 changes: 9 additions & 1 deletion src/BoundaryConditions/boundary_condition_classifications.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,15 @@ For fields located at `Faces`, `Open` also specifies field value _on_ the bounda
Open boundary conditions are used to specify the component of a velocity field normal to a boundary
and can also be used to describe nested or linked simulation domains.
"""
struct Open <: AbstractBoundaryConditionClassification end
struct Open{MS} <: AbstractBoundaryConditionClassification
matching_scheme::MS
end

Open() = Open(nothing)

(open::Open)() = open

Adapt.adapt_structure(to, open::Open) = Open(adapt(to, open.matching_scheme))

"""
struct MultiRegionCommunication <: AbstractBoundaryConditionClassification
Expand Down
2 changes: 1 addition & 1 deletion src/BoundaryConditions/continuous_boundary_function.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function regularize_boundary_condition(bc::BoundaryCondition{C, <:ContinuousBoun
boundary_func.field_dependencies,
indices, interps)

return BoundaryCondition(C, regularized_boundary_func)
return BoundaryCondition(bc.classification, regularized_boundary_func)
end

@inline domain_boundary_indices(::LeftBoundary, N) = 1, 1
Expand Down
3 changes: 2 additions & 1 deletion src/BoundaryConditions/field_boundary_conditions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ function FieldBoundaryConditions(indices::Tuple, west, east, south, north, botto
end

FieldBoundaryConditions(indices::Tuple, bcs::FieldBoundaryConditions) =
FieldBoundaryConditions(indices, (getproperty(bcs, side) for side in fieldnames(FieldBoundaryConditions))...)
FieldBoundaryConditions(indices, (getproperty(bcs, side) for side in propertynames(bcs))...)


window_boundary_conditions(::Colon, left, right) = left, right
window_boundary_conditions(::UnitRange, left, right) = nothing, nothing
Expand Down
9 changes: 6 additions & 3 deletions src/BoundaryConditions/fill_halo_regions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ end
const MaybeTupledData = Union{OffsetArray, NTuple{<:Any, OffsetArray}}

"Fill halo regions in ``x``, ``y``, and ``z`` for a given field's data."
function fill_halo_regions!(c::MaybeTupledData, boundary_conditions, indices, loc, grid, args...; kwargs...)

function fill_halo_regions!(c::MaybeTupledData, boundary_conditions, indices, loc, grid, args...;
fill_boundary_normal_velocities = true, kwargs...)
arch = architecture(grid)

if fill_boundary_normal_velocities
fill_open_boundary_regions!(c, boundary_conditions, indices, loc, grid, args...; kwargs...)
end

fill_halos!, bcs = permute_boundary_conditions(boundary_conditions)
number_of_tasks = length(fill_halos!)

Expand Down Expand Up @@ -208,7 +212,6 @@ end
_fill_bottom_halo!(i, j, grid, c, bottom_bc, loc, args...)
_fill_top_halo!(i, j, grid, c, top_bc, loc, args...)
end

#####
##### Single-sided fill_halo! kernels
#####
Expand Down
Loading