Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/callbacks_step/analysis_surface_integral.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
# This file contains analysis computations that are performed on the surface,
9
# such as aerodynamic coefficients.
10
11
"""
12
AnalysisSurfaceIntegral{Variable, NBoundaries}(boundary_symbols::NTuple{NBoundaries, Symbol},
13
variable)
14
15
This struct is used to compute the surface integral of a quantity of interest `variable` alongside
16
the boundary/boundaries associated with particular names given in `boundary_symbols`.
17
For instance, this can be used to compute the lift [`LiftCoefficientPressure2D`](@ref) or
18
drag coefficient [`DragCoefficientPressure2D`](@ref) of e.g. an 2D airfoil with the boundary
19
names `:AirfoilTop`, `:AirfoilBottom` which would be supplied as
20
`boundary_symbols = (:AirfoilTop, :AirfoilBottom)`.
21
A single boundary name can also be supplied, e.g. `boundary_symbols = (:AirfoilTop,)`.
22
23
- `boundary_symbols::NTuple{NBoundaries, Symbol}`: Name(s) of the boundary/boundaries
24
where the quantity of interest is computed
25
- `variable::Variable`: Quantity of interest, like lift or drag
26
"""
27
struct AnalysisSurfaceIntegral{Variable, NBoundaries}
28
variable::Variable # Quantity of interest, like lift or drag
29
boundary_symbols::NTuple{NBoundaries, Symbol} # Name(s) of the boundary/boundaries
30
31
function AnalysisSurfaceIntegral(boundary_symbols::NTuple{NBoundaries, Symbol},
32
variable) where {NBoundaries}
33
return new{typeof(variable), NBoundaries}(variable, boundary_symbols)
34
end
35
end
36
37
# This returns the boundary indices of a given iterable datastructure of boundary symbols.
38
function get_boundary_indices(boundary_symbols, boundary_symbol_indices)
39
indices = Int[]
40
for name in boundary_symbols
41
append!(indices, boundary_symbol_indices[name])
42
end
43
sort!(indices) # Try to achieve some data locality by sorting
44
45
return indices
46
end
47
48
struct ForceState{RealT <: Real, NDIMS}
49
psi::NTuple{NDIMS, RealT} # Unit vector normal or parallel to freestream
50
rho_inf::RealT
51
u_inf::RealT
52
l_inf::RealT
53
end
54
55
# Abstract base type used for dispatch of `analyze` for quantities
56
# requiring gradients of the velocity field.
57
abstract type VariableViscous end
58
59
struct LiftCoefficientPressure{RealT <: Real, NDIMS}
60
force_state::ForceState{RealT, NDIMS}
61
end
62
63
struct DragCoefficientPressure{RealT <: Real, NDIMS}
64
force_state::ForceState{RealT, NDIMS}
65
end
66
67
struct LiftCoefficientShearStress{RealT <: Real, NDIMS} <: VariableViscous
68
force_state::ForceState{RealT, NDIMS}
69
end
70
71
struct DragCoefficientShearStress{RealT <: Real, NDIMS} <: VariableViscous
72
force_state::ForceState{RealT, NDIMS}
73
end
74
75
function (lift_coefficient::LiftCoefficientPressure)(u, normal_direction, x, t,
76
equations)
77
p = pressure(u, equations)
78
@unpack psi, rho_inf, u_inf, l_inf = lift_coefficient.force_state
79
# Normalize as `normal_direction` is not necessarily a unit vector
80
n = dot(normal_direction, psi) / norm(normal_direction)
81
return p * n / (0.5f0 * rho_inf * u_inf^2 * l_inf)
82
end
83
84
function (drag_coefficient::DragCoefficientPressure)(u, normal_direction, x, t,
85
equations)
86
p = pressure(u, equations)
87
@unpack psi, rho_inf, u_inf, l_inf = drag_coefficient.force_state
88
# Normalize as `normal_direction` is not necessarily a unit vector
89
n = dot(normal_direction, psi) / norm(normal_direction)
90
return p * n / (0.5f0 * rho_inf * u_inf^2 * l_inf)
91
end
92
93
function pretty_form_ascii(::AnalysisSurfaceIntegral{<:LiftCoefficientPressure{<:Any,
94
<:Any}})
95
"CL_p"
96
end
97
function pretty_form_utf(::AnalysisSurfaceIntegral{<:LiftCoefficientPressure{<:Any,
98
<:Any}})
99
"CL_p"
100
end
101
102
function pretty_form_ascii(::AnalysisSurfaceIntegral{<:DragCoefficientPressure{<:Any,
103
<:Any}})
104
"CD_p"
105
end
106
function pretty_form_utf(::AnalysisSurfaceIntegral{<:DragCoefficientPressure{<:Any,
107
<:Any}})
108
"CD_p"
109
end
110
111
function pretty_form_ascii(::AnalysisSurfaceIntegral{<:LiftCoefficientShearStress{<:Any,
112
<:Any}})
113
"CL_f"
114
end
115
function pretty_form_utf(::AnalysisSurfaceIntegral{<:LiftCoefficientShearStress{<:Any,
116
<:Any}})
117
"CL_f"
118
end
119
120
function pretty_form_ascii(::AnalysisSurfaceIntegral{<:DragCoefficientShearStress{<:Any,
121
<:Any}})
122
"CD_f"
123
end
124
function pretty_form_utf(::AnalysisSurfaceIntegral{<:DragCoefficientShearStress{<:Any,
125
<:Any}})
126
"CD_f"
127
end
128
129
include("analysis_surface_integral_2d.jl")
130
include("analysis_surface_integral_3d.jl")
131
end # muladd
132
133