Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/solvers/dgsem_p4est/containers_parallel_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
# Initialize node_indices of MPI interface container
9
@inline function init_mpi_interface_node_indices!(mpi_interfaces::P4estMPIInterfaceContainer{3},
10
faces, local_side, orientation,
11
mpi_interface_id)
12
# Align interface at the primary element (primary element has surface indices (:i_forward, :j_forward)).
13
# The secondary element needs to be indexed differently.
14
if local_side == 1
15
surface_index1 = :i_forward
16
surface_index2 = :j_forward
17
else # local_side == 2
18
surface_index1, surface_index2 = orientation_to_indices_p4est(faces[2],
19
faces[1],
20
orientation)
21
end
22
23
if faces[local_side] == 0
24
# Index face in negative x-direction
25
mpi_interfaces.node_indices[mpi_interface_id] = (:begin, surface_index1,
26
surface_index2)
27
elseif faces[local_side] == 1
28
# Index face in positive x-direction
29
mpi_interfaces.node_indices[mpi_interface_id] = (:end, surface_index1,
30
surface_index2)
31
elseif faces[local_side] == 2
32
# Index face in negative y-direction
33
mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, :begin,
34
surface_index2)
35
elseif faces[local_side] == 3
36
# Index face in positive y-direction
37
mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, :end,
38
surface_index2)
39
elseif faces[local_side] == 4
40
# Index face in negative z-direction
41
mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, surface_index2,
42
:begin)
43
else # faces[local_side] == 5
44
# Index face in positive z-direction
45
mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, surface_index2,
46
:end)
47
end
48
49
return mpi_interfaces
50
end
51
52
# Initialize node_indices of MPI mortar container. Works the same as for its serial counterpart.
53
# faces[1] is expected to be the face of the small side.
54
@inline function init_mortar_node_indices!(mortars::P4estMPIMortarContainer{3},
55
faces, orientation, mortar_id)
56
for side in 1:2
57
# Align mortar at small side.
58
# The large side needs to be indexed differently.
59
if side == 1
60
surface_index1 = :i_forward
61
surface_index2 = :j_forward
62
else
63
surface_index1, surface_index2 = orientation_to_indices_p4est(faces[2],
64
faces[1],
65
orientation)
66
end
67
68
if faces[side] == 0
69
# Index face in negative x-direction
70
mortars.node_indices[side, mortar_id] = (:begin, surface_index1,
71
surface_index2)
72
elseif faces[side] == 1
73
# Index face in positive x-direction
74
mortars.node_indices[side, mortar_id] = (:end, surface_index1,
75
surface_index2)
76
elseif faces[side] == 2
77
# Index face in negative y-direction
78
mortars.node_indices[side, mortar_id] = (surface_index1, :begin,
79
surface_index2)
80
elseif faces[side] == 3
81
# Index face in positive y-direction
82
mortars.node_indices[side, mortar_id] = (surface_index1, :end,
83
surface_index2)
84
elseif faces[side] == 4
85
# Index face in negative z-direction
86
mortars.node_indices[side, mortar_id] = (surface_index1, surface_index2,
87
:begin)
88
else # faces[side] == 5
89
# Index face in positive z-direction
90
mortars.node_indices[side, mortar_id] = (surface_index1, surface_index2,
91
:end)
92
end
93
end
94
95
return mortars
96
end
97
98
# Normal directions of small element surfaces are needed to calculate the mortar fluxes. Initialize
99
# them for locally available small elements.
100
function init_normal_directions!(mpi_mortars::P4estMPIMortarContainer{3},
101
basis, elements)
102
@unpack local_neighbor_ids, local_neighbor_positions, node_indices = mpi_mortars
103
@unpack contravariant_vectors = elements
104
index_range = eachnode(basis)
105
106
@threaded for mortar in 1:nmpimortars(mpi_mortars)
107
small_indices = node_indices[1, mortar]
108
small_direction = indices2direction(small_indices)
109
110
i_small_start, i_small_step_i, i_small_step_j = index_to_start_step_3d(small_indices[1],
111
index_range)
112
j_small_start, j_small_step_i, j_small_step_j = index_to_start_step_3d(small_indices[2],
113
index_range)
114
k_small_start, k_small_step_i, k_small_step_j = index_to_start_step_3d(small_indices[3],
115
index_range)
116
117
for (element, position) in zip(local_neighbor_ids[mortar],
118
local_neighbor_positions[mortar])
119
# ignore large elements
120
if position == 5
121
continue
122
end
123
124
i_small = i_small_start
125
j_small = j_small_start
126
k_small = k_small_start
127
for j in eachnode(basis)
128
for i in eachnode(basis)
129
# Get the normal direction on the small element.
130
# Note, contravariant vectors at interfaces in negative coordinate direction
131
# are pointing inwards. This is handled by `get_normal_direction`.
132
normal_direction = get_normal_direction(small_direction,
133
contravariant_vectors,
134
i_small, j_small, k_small,
135
element)
136
@views mpi_mortars.normal_directions[:, i, j, position, mortar] .= normal_direction
137
138
i_small += i_small_step_i
139
j_small += j_small_step_i
140
k_small += k_small_step_i
141
end
142
i_small += i_small_step_j
143
j_small += j_small_step_j
144
k_small += k_small_step_j
145
end
146
end
147
end
148
149
return nothing
150
end
151
end # muladd
152
153