Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/solvers/dgsem_p4est/subcell_limiters_3d.jl
5616 views
1
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).
2
# Since these FMAs can increase the performance of many numerical algorithms,
3
# we need to opt-in explicitly.
4
# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.
5
@muladd begin
6
#! format: noindent
7
8
function calc_bounds_twosided_interface!(var_min, var_max, variable, u,
9
semi, mesh::P4estMesh{3}, equations)
10
_, _, dg, cache = mesh_equations_solver_cache(semi)
11
12
(; neighbor_ids, node_indices) = cache.interfaces
13
index_range = eachnode(dg)
14
15
for interface in eachinterface(dg, cache)
16
# Get element and side index information on the primary element
17
primary_element = neighbor_ids[1, interface]
18
primary_indices = node_indices[1, interface]
19
20
# Get element and side index information on the secondary element
21
secondary_element = neighbor_ids[2, interface]
22
secondary_indices = node_indices[2, interface]
23
24
# Create the local i,j,k indexing
25
i_primary_start, i_primary_step_i, i_primary_step_j = index_to_start_step_3d(primary_indices[1],
26
index_range)
27
j_primary_start, j_primary_step_i, j_primary_step_j = index_to_start_step_3d(primary_indices[2],
28
index_range)
29
k_primary_start, k_primary_step_i, k_primary_step_j = index_to_start_step_3d(primary_indices[3],
30
index_range)
31
32
i_primary = i_primary_start
33
j_primary = j_primary_start
34
k_primary = k_primary_start
35
36
i_secondary_start, i_secondary_step_i, i_secondary_step_j = index_to_start_step_3d(secondary_indices[1],
37
index_range)
38
j_secondary_start, j_secondary_step_i, j_secondary_step_j = index_to_start_step_3d(secondary_indices[2],
39
index_range)
40
k_secondary_start, k_secondary_step_i, k_secondary_step_j = index_to_start_step_3d(secondary_indices[3],
41
index_range)
42
43
i_secondary = i_secondary_start
44
j_secondary = j_secondary_start
45
k_secondary = k_secondary_start
46
47
for j in eachnode(dg)
48
for i in eachnode(dg)
49
var_primary = u[variable, i_primary, j_primary, k_primary,
50
primary_element]
51
var_secondary = u[variable, i_secondary, j_secondary, k_secondary,
52
secondary_element]
53
54
var_min[i_primary, j_primary, k_primary, primary_element] = min(var_min[i_primary,
55
j_primary,
56
k_primary,
57
primary_element],
58
var_secondary)
59
var_max[i_primary, j_primary, k_primary, primary_element] = max(var_max[i_primary,
60
j_primary,
61
k_primary,
62
primary_element],
63
var_secondary)
64
65
var_min[i_secondary, j_secondary, k_secondary, secondary_element] = min(var_min[i_secondary,
66
j_secondary,
67
k_secondary,
68
secondary_element],
69
var_primary)
70
var_max[i_secondary, j_secondary, k_secondary, secondary_element] = max(var_max[i_secondary,
71
j_secondary,
72
k_secondary,
73
secondary_element],
74
var_primary)
75
76
# Increment the primary element indices
77
i_primary += i_primary_step_i
78
j_primary += j_primary_step_i
79
k_primary += k_primary_step_i
80
# Increment the secondary element surface indices
81
i_secondary += i_secondary_step_i
82
j_secondary += j_secondary_step_i
83
k_secondary += k_secondary_step_i
84
end
85
# Increment the primary element indices
86
i_primary += i_primary_step_j
87
j_primary += j_primary_step_j
88
k_primary += k_primary_step_j
89
# Increment the secondary element surface indices
90
i_secondary += i_secondary_step_j
91
j_secondary += j_secondary_step_j
92
k_secondary += k_secondary_step_j
93
end
94
end
95
96
return nothing
97
end
98
99
@inline function calc_bounds_twosided_boundary!(var_min, var_max, variable, u, t,
100
boundary_conditions::BoundaryConditionPeriodic,
101
mesh::P4estMesh{3},
102
equations, dg, cache)
103
return nothing
104
end
105
106
@inline function calc_bounds_twosided_boundary!(var_min, var_max, variable, u, t,
107
boundary_conditions,
108
mesh::P4estMesh{3},
109
equations, dg, cache)
110
(; boundary_condition_types, boundary_indices) = boundary_conditions
111
(; contravariant_vectors) = cache.elements
112
113
(; boundaries) = cache
114
index_range = eachnode(dg)
115
116
foreach_enumerate(boundary_condition_types) do (i, boundary_condition)
117
for boundary in boundary_indices[i]
118
element = boundaries.neighbor_ids[boundary]
119
node_indices = boundaries.node_indices[boundary]
120
direction = indices2direction(node_indices)
121
122
i_node_start, i_node_step_i, i_node_step_j = index_to_start_step_3d(node_indices[1],
123
index_range)
124
j_node_start, j_node_step_i, j_node_step_j = index_to_start_step_3d(node_indices[2],
125
index_range)
126
k_node_start, k_node_step_i, k_node_step_j = index_to_start_step_3d(node_indices[3],
127
index_range)
128
129
i_node = i_node_start
130
j_node = j_node_start
131
k_node = k_node_start
132
for j in eachnode(dg)
133
for i in eachnode(dg)
134
normal_direction = get_normal_direction(direction,
135
contravariant_vectors,
136
i_node, j_node, k_node,
137
element)
138
139
u_inner = get_node_vars(u, equations, dg, i_node, j_node, k_node,
140
element)
141
142
u_outer = get_boundary_outer_state(u_inner, t, boundary_condition,
143
normal_direction,
144
mesh, equations, dg, cache,
145
i_node, j_node, k_node, element)
146
var_outer = u_outer[variable]
147
148
var_min[i_node, j_node, k_node, element] = min(var_min[i_node,
149
j_node,
150
k_node,
151
element],
152
var_outer)
153
var_max[i_node, j_node, k_node, element] = max(var_max[i_node,
154
j_node,
155
k_node,
156
element],
157
var_outer)
158
159
i_node += i_node_step_i
160
j_node += j_node_step_i
161
k_node += k_node_step_i
162
end
163
i_node += i_node_step_j
164
j_node += j_node_step_j
165
k_node += k_node_step_j
166
end
167
end
168
end
169
170
return nothing
171
end
172
173
function calc_bounds_onesided_interface!(var_minmax, minmax, variable, u,
174
semi, mesh::P4estMesh{3})
175
_, equations, dg, cache = mesh_equations_solver_cache(semi)
176
177
(; neighbor_ids, node_indices) = cache.interfaces
178
index_range = eachnode(dg)
179
180
for interface in eachinterface(dg, cache)
181
# Get element and side index information on the primary element
182
primary_element = neighbor_ids[1, interface]
183
primary_indices = node_indices[1, interface]
184
185
# Get element and side index information on the secondary element
186
secondary_element = neighbor_ids[2, interface]
187
secondary_indices = node_indices[2, interface]
188
189
# Create the local i,j,k indexing
190
i_primary_start, i_primary_step_i, i_primary_step_j = index_to_start_step_3d(primary_indices[1],
191
index_range)
192
j_primary_start, j_primary_step_i, j_primary_step_j = index_to_start_step_3d(primary_indices[2],
193
index_range)
194
k_primary_start, k_primary_step_i, k_primary_step_j = index_to_start_step_3d(primary_indices[3],
195
index_range)
196
197
i_primary = i_primary_start
198
j_primary = j_primary_start
199
k_primary = k_primary_start
200
201
i_secondary_start, i_secondary_step_i, i_secondary_step_j = index_to_start_step_3d(secondary_indices[1],
202
index_range)
203
j_secondary_start, j_secondary_step_i, j_secondary_step_j = index_to_start_step_3d(secondary_indices[2],
204
index_range)
205
k_secondary_start, k_secondary_step_i, k_secondary_step_j = index_to_start_step_3d(secondary_indices[3],
206
index_range)
207
208
i_secondary = i_secondary_start
209
j_secondary = j_secondary_start
210
k_secondary = k_secondary_start
211
212
for j in eachnode(dg)
213
for i in eachnode(dg)
214
var_primary = variable(get_node_vars(u, equations, dg, i_primary,
215
j_primary, k_primary,
216
primary_element), equations)
217
var_secondary = variable(get_node_vars(u, equations, dg, i_secondary,
218
j_secondary, k_secondary,
219
secondary_element),
220
equations)
221
222
var_minmax[i_primary, j_primary, k_primary, primary_element] = minmax(var_minmax[i_primary,
223
j_primary,
224
k_primary,
225
primary_element],
226
var_secondary)
227
var_minmax[i_secondary, j_secondary, k_secondary, secondary_element] = minmax(var_minmax[i_secondary,
228
j_secondary,
229
k_secondary,
230
secondary_element],
231
var_primary)
232
233
# Increment the primary element indices
234
i_primary += i_primary_step_i
235
j_primary += j_primary_step_i
236
k_primary += k_primary_step_i
237
# Increment the secondary element surface indices
238
i_secondary += i_secondary_step_i
239
j_secondary += j_secondary_step_i
240
k_secondary += k_secondary_step_i
241
end
242
# Increment the primary element indices
243
i_primary += i_primary_step_j
244
j_primary += j_primary_step_j
245
k_primary += k_primary_step_j
246
# Increment the secondary element surface indices
247
i_secondary += i_secondary_step_j
248
j_secondary += j_secondary_step_j
249
k_secondary += k_secondary_step_j
250
end
251
end
252
253
return nothing
254
end
255
256
@inline function calc_bounds_onesided_boundary!(var_minmax, minmax, variable, u, t,
257
boundary_conditions::BoundaryConditionPeriodic,
258
mesh::P4estMesh{3},
259
equations, dg, cache)
260
return nothing
261
end
262
263
@inline function calc_bounds_onesided_boundary!(var_minmax, minmax, variable, u, t,
264
boundary_conditions,
265
mesh::P4estMesh{3},
266
equations, dg, cache)
267
(; boundary_condition_types, boundary_indices) = boundary_conditions
268
(; contravariant_vectors) = cache.elements
269
270
(; boundaries) = cache
271
index_range = eachnode(dg)
272
273
foreach_enumerate(boundary_condition_types) do (i, boundary_condition)
274
for boundary in boundary_indices[i]
275
element = boundaries.neighbor_ids[boundary]
276
node_indices = boundaries.node_indices[boundary]
277
direction = indices2direction(node_indices)
278
279
i_node_start, i_node_step_i, i_node_step_j = index_to_start_step_3d(node_indices[1],
280
index_range)
281
j_node_start, j_node_step_i, j_node_step_j = index_to_start_step_3d(node_indices[2],
282
index_range)
283
k_node_start, k_node_step_i, k_node_step_j = index_to_start_step_3d(node_indices[3],
284
index_range)
285
286
i_node = i_node_start
287
j_node = j_node_start
288
k_node = k_node_start
289
for j in eachnode(dg)
290
for i in eachnode(dg)
291
normal_direction = get_normal_direction(direction,
292
contravariant_vectors,
293
i_node, j_node, k_node,
294
element)
295
296
u_inner = get_node_vars(u, equations, dg, i_node, j_node, k_node,
297
element)
298
299
u_outer = get_boundary_outer_state(u_inner, t, boundary_condition,
300
normal_direction,
301
mesh, equations, dg, cache,
302
i_node, j_node, k_node, element)
303
var_outer = variable(u_outer, equations)
304
305
var_minmax[i_node, j_node, k_node, element] = minmax(var_minmax[i_node,
306
j_node,
307
k_node,
308
element],
309
var_outer)
310
311
i_node += i_node_step_i
312
j_node += j_node_step_i
313
k_node += k_node_step_i
314
end
315
i_node += i_node_step_j
316
j_node += j_node_step_j
317
k_node += k_node_step_j
318
end
319
end
320
end
321
322
return nothing
323
end
324
end # @muladd
325
326