Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/solvers/dgsem_structured/dg_1d.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
function prolong2interfaces!(cache, u, mesh::StructuredMesh{1}, equations, dg::DG)
9
@unpack interfaces_u = cache.elements
10
11
@threaded for element in eachelement(dg, cache)
12
# Negative side (direction 1, left/negative x face)
13
for v in eachvariable(equations)
14
interfaces_u[v, 1, element] = u[v, 1, element]
15
end
16
# Positive side (direction 2, right/positive x face)
17
for v in eachvariable(equations)
18
interfaces_u[v, 2, element] = u[v, nnodes(dg), element]
19
end
20
end
21
22
return nothing
23
end
24
25
function prolong2interfaces!(cache, u, mesh::StructuredMesh{1}, equations,
26
dg::DGSEM{<:GaussLegendreBasis})
27
@unpack interfaces_u = cache.elements
28
@unpack boundary_interpolation = dg.basis
29
30
@threaded for element in eachelement(dg, cache)
31
for v in eachvariable(equations)
32
interface_u_1 = zero(eltype(interfaces_u))
33
interface_u_2 = zero(eltype(interfaces_u))
34
for i in eachnode(dg)
35
# Left/negative x face
36
interface_u_1 = interface_u_1 +
37
u[v, i, element] * boundary_interpolation[i, 1]
38
39
# Right/positive x face
40
interface_u_2 = interface_u_2 +
41
u[v, i, element] * boundary_interpolation[i, 2]
42
end
43
interfaces_u[v, 1, element] = interface_u_1
44
interfaces_u[v, 2, element] = interface_u_2
45
end
46
end
47
48
return nothing
49
end
50
51
function calc_interface_flux!(surface_flux_values, mesh::StructuredMesh{1},
52
nonconservative_terms, # can be True/False
53
equations, surface_integral, dg::DG, cache)
54
@unpack surface_flux = surface_integral
55
@unpack interfaces_u = cache.elements
56
57
@threaded for element in eachelement(dg, cache)
58
left_element = cache.elements.left_neighbors[1, element]
59
# => `element` is the right element of the interface
60
61
if left_element > 0 # left_element = 0 at boundaries
62
u_ll = get_node_vars(interfaces_u, equations, dg, 2, left_element)
63
u_rr = get_node_vars(interfaces_u, equations, dg, 1, element)
64
65
f1 = surface_flux(u_ll, u_rr, 1, equations)
66
67
for v in eachvariable(equations)
68
surface_flux_values[v, 2, left_element] = f1[v]
69
surface_flux_values[v, 1, element] = f1[v]
70
end
71
end
72
end
73
74
return nothing
75
end
76
77
function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple,
78
mesh::StructuredMesh{1}, equations, surface_integral,
79
dg::DG)
80
@unpack surface_flux = surface_integral
81
@unpack surface_flux_values, boundary_node_coordinates, interfaces_u = cache.elements
82
# Boundary values are for `StructuredMesh` stored in the interface datastructure
83
boundaries_u = interfaces_u
84
85
orientation = 1
86
87
# Negative x-direction
88
direction = 1
89
90
u_rr = get_node_vars(boundaries_u, equations, dg, direction, 1)
91
x = get_node_coords(boundary_node_coordinates, equations, dg, direction)
92
93
flux = boundary_conditions[direction](u_rr, orientation, direction, x, t,
94
surface_flux, equations)
95
96
# Only flux contribution for left element, left face is the boundary flux
97
for v in eachvariable(equations)
98
surface_flux_values[v, direction, 1] = flux[v]
99
end
100
101
# Positive x-direction
102
direction = 2
103
104
u_rr = get_node_vars(boundaries_u, equations, dg, direction, nelements(dg, cache))
105
x = get_node_coords(boundary_node_coordinates, equations, dg, direction)
106
107
flux = boundary_conditions[direction](u_rr, orientation, direction, x, t,
108
surface_flux, equations)
109
110
# Only flux contribution for right element, right face is the boundary flux
111
for v in eachvariable(equations)
112
surface_flux_values[v, direction, nelements(dg, cache)] = flux[v]
113
end
114
115
return nothing
116
end
117
118
function apply_jacobian!(backend::Nothing, du, mesh::StructuredMesh{1},
119
equations, dg::DG, cache)
120
@unpack inverse_jacobian = cache.elements
121
122
@threaded for element in eachelement(dg, cache)
123
for i in eachnode(dg)
124
# Negative sign included to account for the negated surface and volume terms,
125
# see e.g. the computation of `derivative_hat` in the basis setup and
126
# the comment in `calc_surface_integral!`.
127
factor = -inverse_jacobian[i, element]
128
129
for v in eachvariable(equations)
130
du[v, i, element] *= factor
131
end
132
end
133
end
134
135
return nothing
136
end
137
end # @muladd
138
139