Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/solvers/fdsbp_unstructured/containers_2d.jl
5591 views
1
# !!! warning "Experimental implementation (curvilinear FDSBP)"
2
# This is an experimental feature and may change in future releases.
3
4
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).
5
# Since these FMAs can increase the performance of many numerical algorithms,
6
# we need to opt-in explicitly.
7
# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.
8
@muladd begin
9
#! format: noindent
10
11
# initialize all the values in the container of a general FD block (either straight sided or curved)
12
# OBS! Requires the SBP derivative matrix in order to compute metric terms.
13
function init_element!(elements, element, basis::AbstractDerivativeOperator,
14
corners_or_surface_curves)
15
calc_node_coordinates!(elements.node_coordinates, element, get_nodes(basis),
16
corners_or_surface_curves)
17
18
calc_metric_terms!(elements.jacobian_matrix, element, basis,
19
elements.node_coordinates)
20
21
calc_inverse_jacobian!(elements.inverse_jacobian, element, elements.jacobian_matrix)
22
23
calc_contravariant_vectors!(elements.contravariant_vectors, element,
24
elements.jacobian_matrix)
25
26
calc_normal_directions!(elements.normal_directions, element,
27
elements.jacobian_matrix)
28
29
return elements
30
end
31
32
# Specialization to pass the central differencing matrix from an upwind SBP operator
33
function calc_metric_terms!(jacobian_matrix, element,
34
D_SBP::SummationByPartsOperators.UpwindOperators,
35
node_coordinates)
36
return calc_metric_terms!(jacobian_matrix, element, D_SBP.central, node_coordinates)
37
end
38
39
# construct the metric terms for a FDSBP element "block". Directly use the derivative matrix
40
# applied to the node coordinates.
41
function calc_metric_terms!(jacobian_matrix, element, D_SBP::AbstractDerivativeOperator,
42
node_coordinates)
43
44
# storage format:
45
# jacobian_matrix[1,1,:,:,:] <- X_xi
46
# jacobian_matrix[1,2,:,:,:] <- X_eta
47
# jacobian_matrix[2,1,:,:,:] <- Y_xi
48
# jacobian_matrix[2,2,:,:,:] <- Y_eta
49
50
# Compute the xi derivatives by applying D on the left
51
# This is basically the same as
52
# jacobian_matrix[1, 1, :, :, element] = Matrix(D_SBP) * node_coordinates[1, :, :, element]
53
# but uses only matrix-vector products instead of a matrix-matrix product.
54
for j in eachnode(D_SBP)
55
mul!(view(jacobian_matrix, 1, 1, :, j, element), D_SBP,
56
view(node_coordinates, 1, :, j, element))
57
end
58
# jacobian_matrix[2, 1, :, :, element] = Matrix(D_SBP) * node_coordinates[2, :, :, element]
59
for j in eachnode(D_SBP)
60
mul!(view(jacobian_matrix, 2, 1, :, j, element), D_SBP,
61
view(node_coordinates, 2, :, j, element))
62
end
63
64
# Compute the eta derivatives by applying transpose of D on the right
65
# jacobian_matrix[1, 2, :, :, element] = node_coordinates[1, :, :, element] * Matrix(D_SBP)'
66
for i in eachnode(D_SBP)
67
mul!(view(jacobian_matrix, 1, 2, i, :, element), D_SBP,
68
view(node_coordinates, 1, i, :, element))
69
end
70
# jacobian_matrix[2, 2, :, :, element] = node_coordinates[2, :, :, element] * Matrix(D_SBP)'
71
for i in eachnode(D_SBP)
72
mul!(view(jacobian_matrix, 2, 2, i, :, element), D_SBP,
73
view(node_coordinates, 2, i, :, element))
74
end
75
76
return jacobian_matrix
77
end
78
79
# construct the normal direction vectors (but not actually normalized) for a curved sided FDSBP element "block"
80
# normalization occurs on the fly during the surface flux computation
81
# OBS! This assumes that the boundary points are included.
82
function calc_normal_directions!(normal_directions, element, jacobian_matrix)
83
84
# normal directions on the boundary for the left (local side 4) and right (local side 2)
85
N = size(jacobian_matrix, 4)
86
for j in 1:N
87
# +x side or side 2 in the local indexing
88
X_xi = jacobian_matrix[1, 1, N, j, element]
89
X_eta = jacobian_matrix[1, 2, N, j, element]
90
Y_xi = jacobian_matrix[2, 1, N, j, element]
91
Y_eta = jacobian_matrix[2, 2, N, j, element]
92
Jtemp = X_xi * Y_eta - X_eta * Y_xi
93
normal_directions[1, j, 2, element] = sign(Jtemp) * (Y_eta)
94
normal_directions[2, j, 2, element] = sign(Jtemp) * (-X_eta)
95
96
# -x side or side 4 in the local indexing
97
X_xi = jacobian_matrix[1, 1, 1, j, element]
98
X_eta = jacobian_matrix[1, 2, 1, j, element]
99
Y_xi = jacobian_matrix[2, 1, 1, j, element]
100
Y_eta = jacobian_matrix[2, 2, 1, j, element]
101
Jtemp = X_xi * Y_eta - X_eta * Y_xi
102
normal_directions[1, j, 4, element] = -sign(Jtemp) * (Y_eta)
103
normal_directions[2, j, 4, element] = -sign(Jtemp) * (-X_eta)
104
end
105
106
# normal directions on the boundary for the top (local side 3) and bottom (local side 1)
107
N = size(jacobian_matrix, 3)
108
for i in 1:N
109
# -y side or side 1 in the local indexing
110
X_xi = jacobian_matrix[1, 1, i, 1, element]
111
X_eta = jacobian_matrix[1, 2, i, 1, element]
112
Y_xi = jacobian_matrix[2, 1, i, 1, element]
113
Y_eta = jacobian_matrix[2, 2, i, 1, element]
114
Jtemp = X_xi * Y_eta - X_eta * Y_xi
115
normal_directions[1, i, 1, element] = -sign(Jtemp) * (-Y_xi)
116
normal_directions[2, i, 1, element] = -sign(Jtemp) * (X_xi)
117
118
# +y side or side 3 in the local indexing
119
X_xi = jacobian_matrix[1, 1, i, N, element]
120
X_eta = jacobian_matrix[1, 2, i, N, element]
121
Y_xi = jacobian_matrix[2, 1, i, N, element]
122
Y_eta = jacobian_matrix[2, 2, i, N, element]
123
Jtemp = X_xi * Y_eta - X_eta * Y_xi
124
normal_directions[1, i, 3, element] = sign(Jtemp) * (-Y_xi)
125
normal_directions[2, i, 3, element] = sign(Jtemp) * (X_xi)
126
end
127
128
return normal_directions
129
end
130
end # @muladd
131
132