Skip to content

Commit 4619055

Browse files
Mask ReducedFields accounting the immersed column (#3900)
* this works * better comment * better approach * bugfix * chnage function names
1 parent 7316917 commit 4619055

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

src/ImmersedBoundaries/mask_immersed_field.jl

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using KernelAbstractions: @kernel, @index
22
using Statistics
33
using Oceananigans.AbstractOperations: BinaryOperation
4-
using Oceananigans.Fields: location, ZReducedField, Field
4+
using Oceananigans.Fields: location, XReducedField, YReducedField, ZReducedField, Field, ReducedField
55

66
instantiate(T::Type) = T()
77
instantiate(t) = t
@@ -89,6 +89,55 @@ end
8989
@inbounds field[i, j, k] = scalar_mask(i, j, k, grid, grid.immersed_boundary, loc..., value, field, mask)
9090
end
9191

92+
#####
93+
##### Masking a `ReducedField`
94+
#####
95+
96+
# We mask a `ReducedField` if the entire reduced direction is immersed.
97+
# This requires a sweep over the reduced direction
98+
99+
function mask_immersed_field!(field::ReducedField, grid::ImmersedBoundaryGrid, loc, value)
100+
loc = instantiate.(loc)
101+
dims = reduced_dimensions(field)
102+
launch!(architecture(field), grid, size(field), _mask_immersed_reduced_field!, field, dims, loc, grid, value)
103+
return nothing
104+
end
105+
106+
@kernel function _mask_immersed_reduced_field!(field, dims, loc, grid, value)
107+
i, j, k = @index(Global, NTuple)
108+
mask = inactive_dimensions(i, j, k, grid, dims, loc)
109+
@inbounds field[i, j, k] = ifelse(mask, value, field[i, j, k])
110+
end
111+
112+
@inline inactive_search_range(i, grid, dim, dims) = ifelse(dim dims, 1:size(grid, dim), i:i)
113+
114+
@inline function inactive_dimensions(i₀, j₀, k₀, grid, dims, loc)
115+
mask = true
116+
irange = inactive_search_range(i₀, grid, 1, dims)
117+
jrange = inactive_search_range(j₀, grid, 2, dims)
118+
krange = inactive_search_range(k₀, grid, 3, dims)
119+
120+
# The loop activates over the whole direction only if reduced directions
121+
for i in irange, j in jrange, k in krange
122+
mask = mask & peripheral_node(i, j, k, grid, loc...)
123+
end
124+
125+
return mask
126+
end
127+
128+
###
129+
### Efficient masking for `OnlyZReducedField` and an `AbstractGridFittedBoundary`
130+
###
131+
132+
const AGFBIBG = ImmersedBoundaryGrid{<:Any, <:Any, <:Any, <:Any, <:Any, <:AbstractGridFittedBottom}
133+
134+
const CenterOrFace = Union{Center, Face}
135+
const OnlyZReducedField = Field{<:CenterOrFace, <:CenterOrFace, Nothing}
136+
137+
# Does not require a sweep
138+
mask_immersed_field!(field::OnlyZReducedField, grid::AGFBIBG, loc, value) =
139+
mask_immersed_field_xy!(field, grid, loc, value; k=size(grid, 3), mask=peripheral_node)
140+
92141
#####
93142
##### Masking for GridFittedBoundary
94143
#####

0 commit comments

Comments
 (0)