Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/solvers/dgsem_structured/containers.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
struct StructuredElementContainer{NDIMS, RealT <: Real, uEltype <: Real,
9
NDIMSP1, NDIMSP2, NDIMSP3} <: AbstractElementContainer
10
# Physical coordinates at each node
11
node_coordinates::Array{RealT, NDIMSP2} # [orientation, node_i, node_j, node_k, element]
12
13
# Physical coordinates at boundary nodes
14
boundary_node_coordinates::Array{RealT, NDIMSP1} # [orientation, node_i, node_j, direction/face]
15
16
# ID of neighbor element in negative direction in orientation
17
left_neighbors::Array{Int, 2} # [orientation, elements]
18
19
# Jacobian matrix of the transformation
20
# [jacobian_i, jacobian_j, node_i, node_j, node_k, element] where jacobian_i is the first index of the Jacobian matrix
21
jacobian_matrix::Array{RealT, NDIMSP3}
22
23
# Contravariant vectors, scaled by J, in Kopriva's blue book called Ja^i_n (i index, n dimension)
24
contravariant_vectors::Array{RealT, NDIMSP3} # [dimension, index, node_i, node_j, node_k, element]
25
26
# 1/J where J is the Jacobian determinant (determinant of Jacobian matrix)
27
inverse_jacobian::Array{RealT, NDIMSP1} # [node_i, node_j, node_k, element]
28
29
# Buffer for solution values at interfaces (filled by `prolong2interfaces!`)
30
interfaces_u::Array{uEltype, NDIMSP2} # [variable, i, j, direction, element]
31
32
# Buffer for calculated surface flux
33
surface_flux_values::Array{uEltype, NDIMSP2} # [variable, i, j, direction, element]
34
end
35
36
# Create element container and initialize element data
37
function init_elements(mesh::Union{StructuredMesh{NDIMS, RealT},
38
StructuredMeshView{NDIMS, RealT}},
39
equations::AbstractEquations,
40
basis,
41
::Type{uEltype}) where {NDIMS, RealT <: Real, uEltype <: Real}
42
nelements = prod(size(mesh))
43
node_coordinates = Array{RealT, NDIMS + 2}(undef, NDIMS,
44
ntuple(_ -> nnodes(basis), NDIMS)...,
45
nelements)
46
boundary_node_coordinates = Array{RealT, NDIMS + 1}(undef, NDIMS,
47
ntuple(_ -> nnodes(basis),
48
NDIMS - 1)...,
49
NDIMS * 2)
50
left_neighbors = Array{Int, 2}(undef, NDIMS, nelements)
51
jacobian_matrix = Array{RealT, NDIMS + 3}(undef, NDIMS, NDIMS,
52
ntuple(_ -> nnodes(basis), NDIMS)...,
53
nelements)
54
contravariant_vectors = similar(jacobian_matrix)
55
inverse_jacobian = Array{RealT, NDIMS + 1}(undef,
56
ntuple(_ -> nnodes(basis), NDIMS)...,
57
nelements)
58
interfaces_u = Array{uEltype, NDIMS + 2}(undef, nvariables(equations),
59
ntuple(_ -> nnodes(basis),
60
NDIMS - 1)..., NDIMS * 2,
61
nelements)
62
surface_flux_values = Array{uEltype, NDIMS + 2}(undef, nvariables(equations),
63
ntuple(_ -> nnodes(basis),
64
NDIMS - 1)..., NDIMS * 2,
65
nelements)
66
67
elements = StructuredElementContainer{NDIMS, RealT, uEltype,
68
NDIMS + 1, NDIMS + 2, NDIMS + 3}(node_coordinates,
69
boundary_node_coordinates,
70
left_neighbors,
71
jacobian_matrix,
72
contravariant_vectors,
73
inverse_jacobian,
74
interfaces_u,
75
surface_flux_values)
76
77
init_elements!(elements, mesh, basis)
78
return elements
79
end
80
81
@inline nelements(elements::StructuredElementContainer) = size(elements.left_neighbors,
82
2)
83
84
function Base.eltype(::StructuredElementContainer{NDIMS, RealT, uEltype}) where {NDIMS,
85
RealT,
86
uEltype
87
}
88
return uEltype
89
end
90
91
# Essentially equivalent to `get_contravariant_vector` and `get_node_coords`
92
@inline function get_normal_vector(normal_vectors, indices...)
93
# Returns SVector{NDIMS} where NDIMS is 2 or 3.
94
# Can be deduced at compile time from (number of dims - 2) from `normal_vectors` since
95
# for 2d we have 4 dims (2 two dims for nodes) - 2 => 2
96
# and for 3d we have 5 dims (3 three dims for nodes) - 2 = > 3
97
return SVector(ntuple(@inline(dim->normal_vectors[dim, indices...]),
98
Val(ndims(normal_vectors) - 2)))
99
end
100
101
@inline storage_type(::AbstractNormalVectorContainer) = Array
102
103
include("containers_1d.jl")
104
include("containers_2d.jl")
105
include("containers_3d.jl")
106
end # @muladd
107
108