Skip to content

Commit 3fe5e9e

Browse files
Clean up immersed boundary interface (#4140)
* test it out * add testing * correct active map computation * better naming * bugfix * bugfix * bugfix * bugfix * bugfix * comment * materialize immersed bonudary * this should work * THIS SHOULD WORK
1 parent 703bb69 commit 3fe5e9e

9 files changed

+97
-109
lines changed

ext/OceananigansReactantExt/Grids.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ module Grids
33
using Reactant
44
using Oceananigans
55
using Oceananigans.Architectures: ReactantState, CPU
6-
using Oceananigans.Grids: AbstractGrid, StaticVerticalDiscretization, MutableVerticalDiscretization
6+
using Oceananigans.Grids: AbstractGrid, AbstractUnderlyingGrid, StaticVerticalDiscretization, MutableVerticalDiscretization
77
using Oceananigans.Fields: Field
8-
using Oceananigans.ImmersedBoundaries: GridFittedBottom
8+
using Oceananigans.ImmersedBoundaries: GridFittedBottom, AbstractImmersedBoundary
99

1010
import ..OceananigansReactantExt: deconcretize
1111
import Oceananigans.Grids: LatitudeLongitudeGrid, RectilinearGrid, OrthogonalSphericalShellGrid
1212
import Oceananigans.OrthogonalSphericalShellGrids: RotatedLatitudeLongitudeGrid
1313
import Oceananigans.ImmersedBoundaries: ImmersedBoundaryGrid
1414

1515
const ReactantGrid{FT, TX, TY, TZ} = AbstractGrid{FT, TX, TY, TZ, <:ReactantState}
16+
const ReactantUnderlyingGrid{FT, TX, TY, TZ, CZ} = AbstractUnderlyingGrid{FT, TX, TY, TZ, CZ, <:ReactantState}
1617

1718
deconcretize(z::StaticVerticalDiscretization) =
1819
StaticVerticalDiscretization(
@@ -61,13 +62,13 @@ end
6162
# This low-level constructor supports the external package OrthogonalSphericalShellGrids.jl.
6263
function OrthogonalSphericalShellGrid{TX, TY, TZ}(arch::ReactantState,
6364
Nx, Ny, Nz, Hx, Hy, Hz,
64-
Lz :: FT,
65+
Lz :: FT,
6566
λᶜᶜᵃ :: CC, λᶠᶜᵃ :: FC, λᶜᶠᵃ :: CF, λᶠᶠᵃ :: FF,
6667
φᶜᶜᵃ :: CC, φᶠᶜᵃ :: FC, φᶜᶠᵃ :: CF, φᶠᶠᵃ :: FF, z :: Z,
6768
Δxᶜᶜᵃ :: CC, Δxᶠᶜᵃ :: FC, Δxᶜᶠᵃ :: CF, Δxᶠᶠᵃ :: FF,
6869
Δyᶜᶜᵃ :: CC, Δyᶠᶜᵃ :: FC, Δyᶜᶠᵃ :: CF, Δyᶠᶠᵃ :: FF,
6970
Azᶜᶜᵃ :: CC, Azᶠᶜᵃ :: FC, Azᶜᶠᵃ :: CF, Azᶠᶠᵃ :: FF,
70-
radius :: FT,
71+
radius :: FT,
7172
conformal_mapping :: Map) where {TX, TY, TZ, FT, Z, Map,
7273
CC, FC, CF, FF, C}
7374

@@ -113,10 +114,7 @@ function reactant_immersed_boundary_grid(grid, ib; active_cells_map)
113114
ibg.interior_active_cells, ibg.active_z_columns)
114115
end
115116

116-
ImmersedBoundaryGrid(grid::ReactantGrid, ib::GridFittedBottom; active_cells_map::Bool=true) =
117-
reactant_immersed_boundary_grid(grid, ib; active_cells_map)
118-
119-
ImmersedBoundaryGrid(grid::ReactantGrid, ib; active_cells_map::Bool=true) =
117+
ImmersedBoundaryGrid(grid::ReactantUnderlyingGrid, ib::AbstractImmersedBoundary; active_cells_map::Bool=true) =
120118
reactant_immersed_boundary_grid(grid, ib; active_cells_map)
121119

122120
end # module

src/DistributedComputations/distributed_immersed_boundaries.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,35 +106,35 @@ const DistributedActiveCellsIBG = ImmersedBoundaryGrid{<:Any, <:Any, <:Any, <:An
106106
# For the same reason we need to construct `south` and `north` maps if we partition the domain in the y-direction.
107107
# Therefore, the `interior_active_cells` in this case is a `NamedTuple` containing 5 elements.
108108
# Note that boundary-adjacent maps corresponding to non-partitioned directions are set to `nothing`
109-
function map_interior_active_cells(ibg::ImmersedBoundaryGrid{<:Any, <:Any, <:Any, <:Any, <:DistributedGrid})
109+
function map_interior_active_cells(grid::DistributedGrid, ib)
110110

111-
arch = architecture(ibg)
111+
arch = architecture(grid)
112112

113113
# If we using a synchronized architecture, nothing
114114
# changes with serial execution.
115115
if arch isa SynchronizedDistributed
116-
return interior_active_indices(ibg; parameters = :xyz)
116+
return interior_active_indices(grid, ib; parameters = :xyz)
117117
end
118118

119119
Rx, Ry, _ = arch.ranks
120-
Tx, Ty, _ = topology(ibg)
121-
Nx, Ny, Nz = size(ibg)
122-
Hx, Hy, _ = halo_size(ibg)
120+
Tx, Ty, _ = topology(grid)
121+
Nx, Ny, Nz = size(grid)
122+
Hx, Hy, _ = halo_size(grid)
123123

124124
west_boundary = (1:Hx, 1:Ny, 1:Nz)
125125
east_boundary = (Nx-Hx+1:Nx, 1:Ny, 1:Nz)
126126
south_boundary = (1:Nx, 1:Hy, 1:Nz)
127127
north_boundary = (1:Nx, Ny-Hy+1:Ny, 1:Nz)
128128

129-
include_west = !isa(ibg, XFlatGrid) && (Rx != 1) && !(Tx == RightConnected)
130-
include_east = !isa(ibg, XFlatGrid) && (Rx != 1) && !(Tx == LeftConnected)
131-
include_south = !isa(ibg, YFlatGrid) && (Ry != 1) && !(Ty == RightConnected)
132-
include_north = !isa(ibg, YFlatGrid) && (Ry != 1) && !(Ty == LeftConnected)
129+
include_west = !isa(grid, XFlatGrid) && (Rx != 1) && !(Tx == RightConnected)
130+
include_east = !isa(grid, XFlatGrid) && (Rx != 1) && !(Tx == LeftConnected)
131+
include_south = !isa(grid, YFlatGrid) && (Ry != 1) && !(Ty == RightConnected)
132+
include_north = !isa(grid, YFlatGrid) && (Ry != 1) && !(Ty == LeftConnected)
133133

134-
west_halo_dependent_cells = interior_active_indices(ibg; parameters = KernelParameters(west_boundary...))
135-
east_halo_dependent_cells = interior_active_indices(ibg; parameters = KernelParameters(east_boundary...))
136-
south_halo_dependent_cells = interior_active_indices(ibg; parameters = KernelParameters(south_boundary...))
137-
north_halo_dependent_cells = interior_active_indices(ibg; parameters = KernelParameters(north_boundary...))
134+
west_halo_dependent_cells = interior_active_indices(grid, ib; parameters = KernelParameters(west_boundary...))
135+
east_halo_dependent_cells = interior_active_indices(grid, ib; parameters = KernelParameters(east_boundary...))
136+
south_halo_dependent_cells = interior_active_indices(grid, ib; parameters = KernelParameters(south_boundary...))
137+
north_halo_dependent_cells = interior_active_indices(grid, ib; parameters = KernelParameters(north_boundary...))
138138

139139
west_halo_dependent_cells = ifelse(include_west, west_halo_dependent_cells, nothing)
140140
east_halo_dependent_cells = ifelse(include_east, east_halo_dependent_cells, nothing)
@@ -147,7 +147,7 @@ function map_interior_active_cells(ibg::ImmersedBoundaryGrid{<:Any, <:Any, <:Any
147147
ox = Rx == 1 || Tx == RightConnected ? 0 : Hx
148148
oy = Ry == 1 || Ty == RightConnected ? 0 : Hy
149149

150-
halo_independent_cells = interior_active_indices(ibg; parameters = KernelParameters((nx, ny, Nz), (ox, oy, 0)))
150+
halo_independent_cells = interior_active_indices(grid, ib; parameters = KernelParameters((nx, ny, Nz), (ox, oy, 0)))
151151

152152
return (; halo_independent_cells,
153153
west_halo_dependent_cells,

src/ImmersedBoundaries/active_cells_map.jl

Lines changed: 34 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -52,56 +52,38 @@ A tuple of indices corresponding to the linear index.
5252
"""
5353
@inline active_linear_index_to_tuple(idx, active_cells_map) = @inbounds Base.map(Int, active_cells_map[idx])
5454

55-
function ImmersedBoundaryGrid(grid, ib; active_cells_map::Bool=true)
56-
ibg = ImmersedBoundaryGrid(grid, ib)
57-
TX, TY, TZ = topology(ibg)
58-
59-
# Create the cells map on the CPU, then switch it to the GPU
60-
if active_cells_map
61-
interior_active_cells = map_interior_active_cells(ibg)
62-
active_z_columns = map_active_z_columns(ibg)
63-
else
64-
interior_active_cells = nothing
65-
active_z_columns = nothing
66-
end
67-
68-
return ImmersedBoundaryGrid{TX, TY, TZ}(ibg.underlying_grid,
69-
ibg.immersed_boundary,
70-
interior_active_cells,
71-
active_z_columns)
72-
end
73-
7455
with_halo(halo, ibg::ActiveCellsIBG) =
7556
ImmersedBoundaryGrid(with_halo(halo, ibg.underlying_grid), ibg.immersed_boundary; active_cells_map = true)
7657

77-
@inline active_cell(i, j, k, ibg) = !immersed_cell(i, j, k, ibg)
78-
@inline active_column(i, j, k, grid, column) = column[i, j, k] != 0
58+
@inline active_cell(i, j, k, grid, ib) = !immersed_cell(i, j, k, grid, ib)
7959

80-
@kernel function _set_active_indices!(active_cells_field, grid)
60+
@kernel function _set_active_indices!(active_cells_field, grid, ib)
8161
i, j, k = @index(Global, NTuple)
82-
@inbounds active_cells_field[i, j, k] = active_cell(i, j, k, grid)
62+
@inbounds active_cells_field[i, j, k] = active_cell(i, j, k, grid, ib)
8363
end
8464

85-
function compute_interior_active_cells(ibg; parameters = :xyz)
86-
active_cells_field = Field{Center, Center, Center}(ibg, Bool)
65+
function compute_interior_active_cells(grid, ib; parameters = :xyz)
66+
active_cells_field = Field{Center, Center, Center}(grid, Bool)
8767
fill!(active_cells_field, false)
88-
launch!(architecture(ibg), ibg, parameters, _set_active_indices!, active_cells_field, ibg)
68+
launch!(architecture(grid), grid, parameters, _set_active_indices!, active_cells_field, grid, ib)
8969
return active_cells_field
9070
end
9171

92-
function compute_active_z_columns(ibg)
93-
one_field = OneField(Int)
94-
condition = NotImmersed(truefunc)
95-
mask = 0
72+
@kernel function _set_active_columns!(active_z_columns, grid, ib)
73+
i, j = @index(Global, NTuple)
74+
active_column = false
75+
for k in 1:size(grid, 3)
76+
active_column = active_column | active_cell(i, j, k, grid, ib)
77+
end
78+
@inbounds active_z_columns[i, j, 1] = active_column
79+
end
9680

97-
# Compute all the active cells in a z-column using a ConditionalOperation
98-
conditional_active_cells = ConditionalOperation{Center, Center, Center}(one_field, identity, ibg, condition, mask)
99-
active_cells_in_column = sum(conditional_active_cells, dims = 3)
81+
function compute_active_z_columns(grid, ib)
82+
active_z_columns = Field{Center, Center, Nothing}(grid, Bool)
83+
fill!(active_z_columns, false)
10084

101-
# Check whether the column ``i, j`` is immersed, which would correspond to `active_cells_in_column[i, j, 1] == 0`
102-
is_immersed_column = KernelFunctionOperation{Center, Center, Nothing}(active_column, ibg, active_cells_in_column)
103-
active_z_columns = Field{Center, Center, Nothing}(ibg, Bool)
104-
set!(active_z_columns, is_immersed_column)
85+
# Compute the active cells in the column
86+
launch!(architecture(grid), grid, :xy, _set_active_columns!, active_z_columns, grid, ib)
10587

10688
return active_z_columns
10789
end
@@ -113,22 +95,23 @@ const MAXUInt16 = 2^16 - 1
11395
const MAXUInt32 = 2^32 - 1
11496

11597
"""
116-
interior_active_indices(ibg; parameters = :xyz)
98+
interior_active_indices(grid, ib; parameters = :xyz)
11799
118100
Compute the indices of the active interior cells in the given immersed boundary grid within the indices
119101
specified by the `parameters` keyword argument
120102
121103
# Arguments
122-
- `ibg`: The immersed boundary grid.
104+
- `grid`: The underlying grid.
105+
- `ib`: The immersed boundary.
123106
- `parameters`: (optional) The parameters to be used for computing the active cells. Default is `:xyz`.
124107
125108
# Returns
126109
An array of tuples representing the indices of the active interior cells.
127110
"""
128-
function interior_active_indices(ibg; parameters = :xyz)
129-
active_cells_field = compute_interior_active_cells(ibg; parameters)
111+
function interior_active_indices(grid, ib; parameters = :xyz)
112+
active_cells_field = compute_interior_active_cells(grid, ib; parameters)
130113

131-
N = maximum(size(ibg))
114+
N = maximum(size(grid))
132115
IntType = N > MAXUInt8 ? (N > MAXUInt16 ? (N > MAXUInt32 ? UInt64 : UInt32) : UInt16) : UInt8
133116

134117
IndicesType = Tuple{IntType, IntType, IntType}
@@ -137,18 +120,18 @@ function interior_active_indices(ibg; parameters = :xyz)
137120
# For this reason, we split the computation in vertical levels and `findall` the active indices in
138121
# subsequent xy planes, then stitch them back together
139122
active_indices = IndicesType[]
140-
active_indices = findall_active_indices!(active_indices, active_cells_field, ibg, IndicesType)
141-
active_indices = on_architecture(architecture(ibg), active_indices)
123+
active_indices = findall_active_indices!(active_indices, active_cells_field, grid, IndicesType)
124+
active_indices = on_architecture(architecture(grid), active_indices)
142125

143126
return active_indices
144127
end
145128

146129
# Cannot `findall` on very large grids, so we split the computation in levels.
147130
# This makes the computation a little heavier but avoids OOM errors (this computation
148131
# is performed only once on setup)
149-
function findall_active_indices!(active_indices, active_cells_field, ibg, IndicesType)
132+
function findall_active_indices!(active_indices, active_cells_field, grid, IndicesType)
150133

151-
for k in 1:size(ibg, 3)
134+
for k in 1:size(grid, 3)
152135
interior_indices = findall(on_architecture(CPU(), interior(active_cells_field, :, :, k:k)))
153136
interior_indices = convert_interior_indices(interior_indices, k, IndicesType)
154137
active_indices = vcat(active_indices, interior_indices)
@@ -169,22 +152,22 @@ end
169152
# In case of a serial grid, the interior computations are performed over the whole three-dimensional
170153
# domain. Therefore, the `interior_active_cells` field contains the indices of all the active cells in
171154
# the range 1:Nx, 1:Ny and 1:Nz (i.e., we construct the map with parameters :xyz)
172-
map_interior_active_cells(ibg) = interior_active_indices(ibg; parameters = :xyz)
155+
map_interior_active_cells(grid, ib) = interior_active_indices(grid, ib; parameters = :xyz)
173156

174157
# If we eventually want to perform also barotropic step, `w` computation and `p`
175158
# computation only on active `columns`
176-
function map_active_z_columns(ibg)
177-
active_cells_field = compute_active_z_columns(ibg)
159+
function map_active_z_columns(grid, ib)
160+
active_cells_field = compute_active_z_columns(grid, ib)
178161
interior_cells = on_architecture(CPU(), interior(active_cells_field, :, :, 1))
179162

180163
full_indices = findall(interior_cells)
181164

182-
Nx, Ny, _ = size(ibg)
165+
Nx, Ny, _ = size(grid)
183166
# Reduce the size of the active_cells_map (originally a tuple of Int64)
184167
N = max(Nx, Ny)
185168
IntType = N > MAXUInt8 ? (N > MAXUInt16 ? (N > MAXUInt32 ? UInt64 : UInt32) : UInt16) : UInt8
186169
surface_map = getproperty.(full_indices, Ref(:I)) .|> Tuple{IntType, IntType}
187-
surface_map = on_architecture(architecture(ibg), surface_map)
170+
surface_map = on_architecture(architecture(grid), surface_map)
188171

189172
return surface_map
190173
end

src/ImmersedBoundaries/grid_fitted_bottom.jl

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,20 @@ end
8989
Adapt.adapt_structure(to, ib::GridFittedBottom) = GridFittedBottom(adapt(to, ib.bottom_height), adapt(to, ib.immersed_condition))
9090

9191
"""
92-
ImmersedBoundaryGrid(grid, ib::GridFittedBottom)
92+
materialize_immersed_boundary(grid, ib)
9393
94-
Return a grid with `GridFittedBottom` immersed boundary (`ib`).
95-
96-
Computes `ib.bottom_height` and wraps it in a Field. `ib.bottom_height` is the z-coordinate of top-most interface
97-
of the last ``immersed`` cell in the column.
94+
Returns a new `ib` wrapped around a Field that holds the numerical `immersed_boundary`.
95+
If `ib` is an `AbstractGridFittedBottom`, `ib.bottom_height` is the z-coordinate of
96+
top-most interface of the last ``immersed`` cell in the column. If `ib` is a `GridFittedBoundary`,
97+
`ib.mask` is a field of booleans that indicates whether a cell is immersed or not.
9898
"""
99-
function ImmersedBoundaryGrid(grid, ib::GridFittedBottom)
99+
function materialize_immersed_boundary(grid, ib::GridFittedBottom)
100100
bottom_field = Field{Center, Center, Nothing}(grid)
101101
set!(bottom_field, ib.bottom_height)
102102
@apply_regionally compute_numerical_bottom_height!(bottom_field, grid, ib)
103103
fill_halo_regions!(bottom_field)
104104
new_ib = GridFittedBottom(bottom_field)
105-
TX, TY, TZ = topology(grid)
106-
return ImmersedBoundaryGrid{TX, TY, TZ}(grid, new_ib)
105+
return new_ib
107106
end
108107

109108
compute_numerical_bottom_height!(bottom_field, grid, ib) =

src/ImmersedBoundaries/grid_fitted_boundary.jl

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,9 @@ function compute_mask(grid, ib)
2424
return mask_field
2525
end
2626

27-
function ImmersedBoundaryGrid(grid, ib::GridFittedBoundary; precompute_mask=true)
28-
TX, TY, TZ = topology(grid)
29-
30-
# TODO: validate ib
31-
32-
if precompute_mask
33-
mask_field = compute_mask(grid, ib)
34-
new_ib = GridFittedBoundary(mask_field)
35-
return ImmersedBoundaryGrid{TX, TY, TZ}(grid, new_ib)
36-
else
37-
return ImmersedBoundaryGrid{TX, TY, TZ}(grid, ib)
38-
end
27+
function materialize_immersed_boundary(grid, ib::GridFittedBoundary)
28+
mask_field = compute_mask(grid, ib)
29+
return GridFittedBoundary(mask_field)
3930
end
4031

4132
on_architecture(arch, ib::GridFittedBoundary{<:Field}) = GridFittedBoundary(compute_mask(on_architecture(arch, ib.mask.grid), ib))

src/ImmersedBoundaries/immersed_boundary_grid.jl

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,41 @@ struct ImmersedBoundaryGrid{FT, TX, TY, TZ, G, I, M, S, Arch} <: AbstractGrid{FT
1414
end
1515

1616
# Internal interface
17-
function ImmersedBoundaryGrid{TX, TY, TZ}(grid::G, ib::I, mi::M,
18-
ms::S) where {TX, TY, TZ, G <: AbstractUnderlyingGrid, I, M, S}
17+
function ImmersedBoundaryGrid{TX, TY, TZ}(grid::G, ib::I, mi::M, ms::S) where {TX, TY, TZ, G <: AbstractUnderlyingGrid, I, M, S}
1918
FT = eltype(grid)
2019
arch = architecture(grid)
2120
Arch = typeof(arch)
2221
return ImmersedBoundaryGrid{FT, TX, TY, TZ, G, I, M, S, Arch}(arch, grid, ib, mi, ms)
2322
end
2423

25-
# Constructor with no active map
26-
function ImmersedBoundaryGrid{TX, TY, TZ}(grid::G, ib::I) where {TX, TY, TZ, G <: AbstractUnderlyingGrid, I}
27-
FT = eltype(grid)
28-
arch = architecture(grid)
29-
Arch = typeof(arch)
30-
return ImmersedBoundaryGrid{FT, TX, TY, TZ, G, I, Nothing, Nothing, Arch}(arch, grid, ib, nothing, nothing)
24+
"""
25+
ImmersedBoundaryGrid(grid, ib::AbstractImmersedBoundary; active_cells_map::Bool=true)
26+
27+
Return a grid with an `AbstractImmersedBoundary` immersed boundary (`ib`). If `active_cells_map` is `true`,
28+
the grid will also populate an `interior_active_cells` and `active_z_columns` fields that are a list of active indices in the
29+
interior and on a reduced x-y plane, respectively.
30+
"""
31+
function ImmersedBoundaryGrid(grid::AbstractUnderlyingGrid, ib::AbstractImmersedBoundary; active_cells_map::Bool=false)
32+
new_ib = materialize_immersed_boundary(grid, ib)
33+
34+
# Create the cells map on the CPU, then switch it to the GPU
35+
if active_cells_map
36+
interior_active_cells = map_interior_active_cells(grid, new_ib)
37+
active_z_columns = map_active_z_columns(grid, new_ib)
38+
else
39+
interior_active_cells = nothing
40+
active_z_columns = nothing
41+
end
42+
43+
TX, TY, TZ = topology(grid)
44+
45+
return ImmersedBoundaryGrid{TX, TY, TZ}(grid,
46+
new_ib,
47+
interior_active_cells,
48+
active_z_columns)
3149
end
3250

51+
3352
const IBG = ImmersedBoundaryGrid
3453

3554
@inline Base.getproperty(ibg::IBG, property::Symbol) = get_ibg_property(ibg, Val(property))

src/ImmersedBoundaries/partial_cell_bottom.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,12 @@ function PartialCellBottom(bottom_height; minimum_fractional_cell_height=0.2)
6262
return PartialCellBottom(bottom_height, minimum_fractional_cell_height)
6363
end
6464

65-
function ImmersedBoundaryGrid(grid, ib::PartialCellBottom)
65+
function materialize_immersed_boundary(grid, ib::PartialCellBottom)
6666
bottom_field = Field{Center, Center, Nothing}(grid)
6767
set!(bottom_field, ib.bottom_height)
6868
@apply_regionally compute_numerical_bottom_height!(bottom_field, grid, ib)
6969
fill_halo_regions!(bottom_field)
70-
new_ib = PartialCellBottom(bottom_field, ib.minimum_fractional_cell_height)
71-
TX, TY, TZ = topology(grid)
72-
return ImmersedBoundaryGrid{TX, TY, TZ}(grid, new_ib)
70+
return PartialCellBottom(bottom_field, ib.minimum_fractional_cell_height)
7371
end
7472

7573
@kernel function _compute_numerical_bottom_height!(bottom_field, grid, ib::PartialCellBottom)

test/test_active_cells_map.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Nz = 10
7070
end
7171

7272
bottom_height = on_architecture(arch, bottom_height)
73-
immersed_grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height))
73+
immersed_grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); active_cells_map = false)
7474
immersed_active_grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); active_cells_map = true)
7575

7676
@testset "Active cells map construction" begin

0 commit comments

Comments
 (0)