Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/equations/hyperbolic_diffusion_1d.jl
2055 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
@doc raw"""
9
HyperbolicDiffusionEquations1D
10
11
The linear hyperbolic diffusion equations in one space dimension.
12
A description of this system can be found in Sec. 2.5 of the book
13
- Masatsuka (2013)
14
I Do Like CFD, Too: Vol 1.
15
Freely available at [http://www.cfdbooks.com/](http://www.cfdbooks.com/)
16
Further analysis can be found in the paper
17
- Nishikawa (2007)
18
A first-order system approach for diffusion equation. I: Second-order residual-distribution
19
schemes
20
[DOI: 10.1016/j.jcp.2007.07.029](https://doi.org/10.1016/j.jcp.2007.07.029)
21
"""
22
struct HyperbolicDiffusionEquations1D{RealT <: Real} <:
23
AbstractHyperbolicDiffusionEquations{1, 2}
24
Lr::RealT # reference length scale
25
inv_Tr::RealT # inverse of the reference time scale
26
nu::RealT # diffusion constant
27
end
28
29
function HyperbolicDiffusionEquations1D(; nu = 1.0, Lr = inv(2pi))
30
Tr = Lr^2 / nu
31
HyperbolicDiffusionEquations1D(promote(Lr, inv(Tr), nu)...)
32
end
33
34
varnames(::typeof(cons2cons), ::HyperbolicDiffusionEquations1D) = ("phi", "q1")
35
varnames(::typeof(cons2prim), ::HyperbolicDiffusionEquations1D) = ("phi", "q1")
36
function default_analysis_errors(::HyperbolicDiffusionEquations1D)
37
(:l2_error, :linf_error, :residual)
38
end
39
40
@inline function residual_steady_state(du, ::HyperbolicDiffusionEquations1D)
41
abs(du[1])
42
end
43
44
"""
45
initial_condition_poisson_nonperiodic(x, t, equations::HyperbolicDiffusionEquations1D)
46
47
A non-priodic smooth initial condition. Can be used for convergence tests in combination with
48
[`source_terms_poisson_nonperiodic`](@ref) and [`boundary_condition_poisson_nonperiodic`](@ref).
49
!!! note
50
The solution is periodic but the initial guess is not.
51
"""
52
function initial_condition_poisson_nonperiodic(x, t,
53
equations::HyperbolicDiffusionEquations1D)
54
# elliptic equation: -νΔϕ = f
55
# Taken from Section 6.1 of Nishikawa https://doi.org/10.1016/j.jcp.2007.07.029
56
RealT = eltype(x)
57
if t == 0
58
# initial "guess" of the solution and its derivative
59
phi = x[1]^2 - x[1]
60
q1 = 2 * x[1] - 1
61
else
62
phi = sinpi(x[1]) # ϕ
63
q1 = convert(RealT, pi) * cospi(x[1]) # ϕ_x
64
end
65
return SVector(phi, q1)
66
end
67
68
"""
69
source_terms_poisson_nonperiodic(u, x, t,
70
equations::HyperbolicDiffusionEquations1D)
71
72
Source terms that include the forcing function `f(x)` and right hand side for the hyperbolic
73
diffusion system that is used with [`initial_condition_poisson_nonperiodic`](@ref) and
74
[`boundary_condition_poisson_nonperiodic`](@ref).
75
"""
76
@inline function source_terms_poisson_nonperiodic(u, x, t,
77
equations::HyperbolicDiffusionEquations1D)
78
# elliptic equation: -νΔϕ = f
79
# analytical solution: ϕ = sin(πx) and f = π^2sin(πx)
80
RealT = eltype(u)
81
@unpack inv_Tr = equations
82
83
dphi = convert(RealT, pi)^2 * sinpi(x[1])
84
dq1 = -inv_Tr * u[2]
85
86
return SVector(dphi, dq1)
87
end
88
89
"""
90
boundary_condition_poisson_nonperiodic(u_inner, orientation, direction, x, t,
91
surface_flux_function,
92
equations::HyperbolicDiffusionEquations1D)
93
94
Boundary conditions used for convergence tests in combination with
95
[`initial_condition_poisson_nonperiodic`](@ref) and [`source_terms_poisson_nonperiodic`](@ref).
96
"""
97
function boundary_condition_poisson_nonperiodic(u_inner, orientation, direction, x, t,
98
surface_flux_function,
99
equations::HyperbolicDiffusionEquations1D)
100
# elliptic equation: -νΔϕ = f
101
RealT = eltype(u_inner)
102
phi = sinpi(x[1]) # ϕ
103
q1 = convert(RealT, pi) * cospi(x[1]) # ϕ_x
104
u_boundary = SVector(phi, q1)
105
106
# Calculate boundary flux
107
if direction == 2 # u_inner is "left" of boundary, u_boundary is "right" of boundary
108
flux = surface_flux_function(u_inner, u_boundary, orientation, equations)
109
else # u_boundary is "left" of boundary, u_inner is "right" of boundary
110
flux = surface_flux_function(u_boundary, u_inner, orientation, equations)
111
end
112
113
return flux
114
end
115
116
"""
117
source_terms_harmonic(u, x, t, equations::HyperbolicDiffusionEquations1D)
118
119
Source term that only includes the forcing from the hyperbolic diffusion system.
120
"""
121
@inline function source_terms_harmonic(u, x, t,
122
equations::HyperbolicDiffusionEquations1D)
123
# harmonic solution of the form ϕ = A + B * x, so f = 0
124
@unpack inv_Tr = equations
125
126
dq1 = -inv_Tr * u[2]
127
128
return SVector(0, dq1)
129
end
130
131
"""
132
initial_condition_eoc_test_coupled_euler_gravity(x, t, equations::HyperbolicDiffusionEquations1D)
133
134
Setup used for convergence tests of the Euler equations with self-gravity used in
135
- Michael Schlottke-Lakemper, Andrew R. Winters, Hendrik Ranocha, Gregor J. Gassner (2020)
136
A purely hyperbolic discontinuous Galerkin approach for self-gravitating gas dynamics
137
[arXiv: 2008.10593](https://arxiv.org/abs/2008.10593)
138
in combination with [`source_terms_harmonic`](@ref).
139
"""
140
function initial_condition_eoc_test_coupled_euler_gravity(x, t,
141
equations::HyperbolicDiffusionEquations1D)
142
143
# Determine phi_x
144
RealT = eltype(x)
145
G = 1 # gravitational constant
146
C = -4 * G / convert(RealT, pi) # -4 * G / ndims * pi
147
A = convert(RealT, 0.1) # perturbation coefficient must match Euler setup
148
rho1 = A * sinpi(x[1] - t)
149
# initialize with ansatz of gravity potential
150
phi = C * rho1
151
q1 = C * A * convert(RealT, pi) * cospi(x[1] - t) # = gravity acceleration in x-direction
152
153
return SVector(phi, q1)
154
end
155
156
# Calculate 1D flux for a single point
157
@inline function flux(u, orientation::Integer,
158
equations::HyperbolicDiffusionEquations1D)
159
phi, q1 = u
160
@unpack inv_Tr = equations
161
162
# Ignore orientation since it is always "1" in 1D
163
f1 = -equations.nu * q1
164
f2 = -phi * inv_Tr
165
166
return SVector(f1, f2)
167
end
168
169
# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation
170
@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,
171
equations::HyperbolicDiffusionEquations1D)
172
return sqrt(equations.nu * equations.inv_Tr)
173
end
174
175
@inline have_constant_speed(::HyperbolicDiffusionEquations1D) = True()
176
177
@inline function max_abs_speeds(eq::HyperbolicDiffusionEquations1D)
178
return sqrt(eq.nu * eq.inv_Tr)
179
end
180
181
# Convert conservative variables to primitive
182
@inline cons2prim(u, equations::HyperbolicDiffusionEquations1D) = u
183
184
# Convert conservative variables to entropy found in I Do Like CFD, Too, Vol. 1
185
@inline function cons2entropy(u, equations::HyperbolicDiffusionEquations1D)
186
phi, q1 = u
187
188
w1 = phi
189
w2 = equations.Lr^2 * q1
190
191
return SVector(w1, w2)
192
end
193
194
# Calculate entropy for a conservative state `u` (here: same as total energy)
195
@inline function entropy(u, equations::HyperbolicDiffusionEquations1D)
196
energy_total(u, equations)
197
end
198
199
# Calculate total energy for a conservative state `u`
200
@inline function energy_total(u, equations::HyperbolicDiffusionEquations1D)
201
# energy function as found in equations (2.5.12) in the book "I Do Like CFD, Vol. 1"
202
phi, q1 = u
203
return 0.5f0 * (phi^2 + equations.Lr^2 * q1^2)
204
end
205
end # @muladd
206
207