@@ -52,56 +52,38 @@ A tuple of indices corresponding to the linear index.
52
52
"""
53
53
@inline active_linear_index_to_tuple (idx, active_cells_map) = @inbounds Base. map (Int, active_cells_map[idx])
54
54
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
-
74
55
with_halo (halo, ibg:: ActiveCellsIBG ) =
75
56
ImmersedBoundaryGrid (with_halo (halo, ibg. underlying_grid), ibg. immersed_boundary; active_cells_map = true )
76
57
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)
79
59
80
- @kernel function _set_active_indices! (active_cells_field, grid)
60
+ @kernel function _set_active_indices! (active_cells_field, grid, ib )
81
61
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 )
83
63
end
84
64
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)
87
67
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 )
89
69
return active_cells_field
90
70
end
91
71
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
96
80
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 )
100
84
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)
105
87
106
88
return active_z_columns
107
89
end
@@ -113,22 +95,23 @@ const MAXUInt16 = 2^16 - 1
113
95
const MAXUInt32 = 2 ^ 32 - 1
114
96
115
97
"""
116
- interior_active_indices(ibg ; parameters = :xyz)
98
+ interior_active_indices(grid, ib ; parameters = :xyz)
117
99
118
100
Compute the indices of the active interior cells in the given immersed boundary grid within the indices
119
101
specified by the `parameters` keyword argument
120
102
121
103
# Arguments
122
- - `ibg`: The immersed boundary grid.
104
+ - `grid`: The underlying grid.
105
+ - `ib`: The immersed boundary.
123
106
- `parameters`: (optional) The parameters to be used for computing the active cells. Default is `:xyz`.
124
107
125
108
# Returns
126
109
An array of tuples representing the indices of the active interior cells.
127
110
"""
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)
130
113
131
- N = maximum (size (ibg ))
114
+ N = maximum (size (grid ))
132
115
IntType = N > MAXUInt8 ? (N > MAXUInt16 ? (N > MAXUInt32 ? UInt64 : UInt32) : UInt16) : UInt8
133
116
134
117
IndicesType = Tuple{IntType, IntType, IntType}
@@ -137,18 +120,18 @@ function interior_active_indices(ibg; parameters = :xyz)
137
120
# For this reason, we split the computation in vertical levels and `findall` the active indices in
138
121
# subsequent xy planes, then stitch them back together
139
122
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)
142
125
143
126
return active_indices
144
127
end
145
128
146
129
# Cannot `findall` on very large grids, so we split the computation in levels.
147
130
# This makes the computation a little heavier but avoids OOM errors (this computation
148
131
# 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)
150
133
151
- for k in 1 : size (ibg , 3 )
134
+ for k in 1 : size (grid , 3 )
152
135
interior_indices = findall (on_architecture (CPU (), interior (active_cells_field, :, :, k: k)))
153
136
interior_indices = convert_interior_indices (interior_indices, k, IndicesType)
154
137
active_indices = vcat (active_indices, interior_indices)
@@ -169,22 +152,22 @@ end
169
152
# In case of a serial grid, the interior computations are performed over the whole three-dimensional
170
153
# domain. Therefore, the `interior_active_cells` field contains the indices of all the active cells in
171
154
# 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 )
173
156
174
157
# If we eventually want to perform also barotropic step, `w` computation and `p`
175
158
# 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 )
178
161
interior_cells = on_architecture (CPU (), interior (active_cells_field, :, :, 1 ))
179
162
180
163
full_indices = findall (interior_cells)
181
164
182
- Nx, Ny, _ = size (ibg )
165
+ Nx, Ny, _ = size (grid )
183
166
# Reduce the size of the active_cells_map (originally a tuple of Int64)
184
167
N = max (Nx, Ny)
185
168
IntType = N > MAXUInt8 ? (N > MAXUInt16 ? (N > MAXUInt32 ? UInt64 : UInt32) : UInt16) : UInt8
186
169
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)
188
171
189
172
return surface_map
190
173
end
0 commit comments