Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/solvers/dgsem_unstructured/mappings_geometry_straight_2d.jl
5591 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
# mapping formula from a point (xi, eta) in reference space [-1,1]^2 to a point (x,y)
9
# in physical coordinate space for a quadrilateral element with straight sides
10
# Alg. 95 from the blue book of Kopriva
11
function straight_side_quad_map(xi, eta, corner_points)
12
x = 0.25f0 * (corner_points[1, 1] * (1 - xi) * (1 - eta)
13
+ corner_points[2, 1] * (1 + xi) * (1 - eta)
14
+ corner_points[3, 1] * (1 + xi) * (1 + eta)
15
+ corner_points[4, 1] * (1 - xi) * (1 + eta))
16
17
y = 0.25f0 * (corner_points[1, 2] * (1 - xi) * (1 - eta)
18
+ corner_points[2, 2] * (1 + xi) * (1 - eta)
19
+ corner_points[3, 2] * (1 + xi) * (1 + eta)
20
+ corner_points[4, 2] * (1 - xi) * (1 + eta))
21
22
return x, y
23
end
24
25
# Compute the metric terms for the straight sided quadrilateral mapping
26
# Alg. 100 from the blue book of Kopriva
27
function straight_side_quad_map_metrics(xi, eta, corner_points)
28
X_xi = 0.25f0 * ((1 - eta) * (corner_points[2, 1] - corner_points[1, 1]) +
29
(1 + eta) * (corner_points[3, 1] - corner_points[4, 1]))
30
31
X_eta = 0.25f0 * ((1 - xi) * (corner_points[4, 1] - corner_points[1, 1]) +
32
(1 + xi) * (corner_points[3, 1] - corner_points[2, 1]))
33
34
Y_xi = 0.25f0 * ((1 - eta) * (corner_points[2, 2] - corner_points[1, 2]) +
35
(1 + eta) * (corner_points[3, 2] - corner_points[4, 2]))
36
37
Y_eta = 0.25f0 * ((1 - xi) * (corner_points[4, 2] - corner_points[1, 2]) +
38
(1 + xi) * (corner_points[3, 2] - corner_points[2, 2]))
39
40
return X_xi, X_eta, Y_xi, Y_eta
41
end
42
43
# construct the (x,y) node coordinates in the volume of a straight sided element
44
function calc_node_coordinates!(node_coordinates::AbstractArray{<:Any, 4}, element,
45
nodes, corners)
46
for j in eachindex(nodes), i in eachindex(nodes)
47
node_coordinates[:, i, j, element] .= straight_side_quad_map(nodes[i], nodes[j],
48
corners)
49
end
50
51
return node_coordinates
52
end
53
54
# construct the metric terms for a straight sided element
55
function calc_metric_terms!(jacobian_matrix, element, nodes, corners)
56
57
# storage format:
58
# jacobian_matrix[1,1,:,:,:] <- X_xi
59
# jacobian_matrix[1,2,:,:,:] <- X_eta
60
# jacobian_matrix[2,1,:,:,:] <- Y_xi
61
# jacobian_matrix[2,2,:,:,:] <- Y_eta
62
for j in eachindex(nodes), i in eachindex(nodes)
63
(jacobian_matrix[1, 1, i, j, element],
64
jacobian_matrix[1, 2, i, j, element],
65
jacobian_matrix[2, 1, i, j, element],
66
jacobian_matrix[2, 2, i, j, element]) = straight_side_quad_map_metrics(nodes[i],
67
nodes[j],
68
corners)
69
end
70
71
return jacobian_matrix
72
end
73
74
# construct the normal direction vectors (but not actually normalized) for a straight sided element
75
# normalization occurs on the fly during the surface flux computation
76
function calc_normal_directions!(normal_directions, element, nodes, corners)
77
78
# normal directions on the boundary for the left (local side 4) and right (local side 2)
79
for j in eachindex(nodes)
80
# side 2
81
X_xi, X_eta, Y_xi, Y_eta = straight_side_quad_map_metrics(1, nodes[j],
82
corners)
83
Jtemp = X_xi * Y_eta - X_eta * Y_xi
84
normal_directions[1, j, 2, element] = sign(Jtemp) * (Y_eta)
85
normal_directions[2, j, 2, element] = sign(Jtemp) * (-X_eta)
86
87
# side 4
88
X_xi, X_eta, Y_xi, Y_eta = straight_side_quad_map_metrics(-1, nodes[j],
89
corners)
90
Jtemp = X_xi * Y_eta - X_eta * Y_xi
91
normal_directions[1, j, 4, element] = -sign(Jtemp) * (Y_eta)
92
normal_directions[2, j, 4, element] = -sign(Jtemp) * (-X_eta)
93
end
94
95
# normal directions on the boundary for the top (local side 3) and bottom (local side 1)
96
for i in eachindex(nodes)
97
# side 1
98
X_xi, X_eta, Y_xi, Y_eta = straight_side_quad_map_metrics(nodes[i], -1,
99
corners)
100
Jtemp = X_xi * Y_eta - X_eta * Y_xi
101
normal_directions[1, i, 1, element] = -sign(Jtemp) * (-Y_xi)
102
normal_directions[2, i, 1, element] = -sign(Jtemp) * (X_xi)
103
104
# side 3
105
X_xi, X_eta, Y_xi, Y_eta = straight_side_quad_map_metrics(nodes[i], 1,
106
corners)
107
Jtemp = X_xi * Y_eta - X_eta * Y_xi
108
normal_directions[1, i, 3, element] = sign(Jtemp) * (-Y_xi)
109
normal_directions[2, i, 3, element] = sign(Jtemp) * (X_xi)
110
end
111
112
return normal_directions
113
end
114
end # @muladd
115
116