Path: blob/main/src/callbacks_step/analysis_surface_integral.jl
2055 views
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).1# Since these FMAs can increase the performance of many numerical algorithms,2# we need to opt-in explicitly.3# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.4@muladd begin5#! format: noindent67# This file contains analysis computations that are performed on the surface,8# such as aerodynamic coefficients.910"""11AnalysisSurfaceIntegral{Variable, NBoundaries}(boundary_symbols::NTuple{NBoundaries, Symbol},12variable)1314This struct is used to compute the surface integral of a quantity of interest `variable` alongside15the boundary/boundaries associated with particular names given in `boundary_symbols`.16For instance, this can be used to compute the lift [`LiftCoefficientPressure2D`](@ref) or17drag coefficient [`DragCoefficientPressure2D`](@ref) of e.g. an 2D airfoil with the boundary18names `:AirfoilTop`, `:AirfoilBottom` which would be supplied as19`boundary_symbols = (:AirfoilTop, :AirfoilBottom)`.20A single boundary name can also be supplied, e.g. `boundary_symbols = (:AirfoilTop,)`.2122- `boundary_symbols::NTuple{NBoundaries, Symbol}`: Name(s) of the boundary/boundaries23where the quantity of interest is computed24- `variable::Variable`: Quantity of interest, like lift or drag25"""26struct AnalysisSurfaceIntegral{Variable, NBoundaries}27variable::Variable # Quantity of interest, like lift or drag28boundary_symbols::NTuple{NBoundaries, Symbol} # Name(s) of the boundary/boundaries2930function AnalysisSurfaceIntegral(boundary_symbols::NTuple{NBoundaries, Symbol},31variable) where {NBoundaries}32return new{typeof(variable), NBoundaries}(variable, boundary_symbols)33end34end3536# This returns the boundary indices of a given iterable datastructure of boundary symbols.37function get_boundary_indices(boundary_symbols, boundary_symbol_indices)38indices = Int[]39for name in boundary_symbols40append!(indices, boundary_symbol_indices[name])41end42sort!(indices) # Try to achieve some data locality by sorting4344return indices45end4647struct ForceState{RealT <: Real, NDIMS}48psi::NTuple{NDIMS, RealT} # Unit vector normal or parallel to freestream49rho_inf::RealT50u_inf::RealT51l_inf::RealT52end5354# Abstract base type used for dispatch of `analyze` for quantities55# requiring gradients of the velocity field.56abstract type VariableViscous end5758struct LiftCoefficientPressure{RealT <: Real, NDIMS}59force_state::ForceState{RealT, NDIMS}60end6162struct DragCoefficientPressure{RealT <: Real, NDIMS}63force_state::ForceState{RealT, NDIMS}64end6566struct LiftCoefficientShearStress{RealT <: Real, NDIMS} <: VariableViscous67force_state::ForceState{RealT, NDIMS}68end6970struct DragCoefficientShearStress{RealT <: Real, NDIMS} <: VariableViscous71force_state::ForceState{RealT, NDIMS}72end7374function (lift_coefficient::LiftCoefficientPressure)(u, normal_direction, x, t,75equations)76p = pressure(u, equations)77@unpack psi, rho_inf, u_inf, l_inf = lift_coefficient.force_state78# Normalize as `normal_direction` is not necessarily a unit vector79n = dot(normal_direction, psi) / norm(normal_direction)80return p * n / (0.5f0 * rho_inf * u_inf^2 * l_inf)81end8283function (drag_coefficient::DragCoefficientPressure)(u, normal_direction, x, t,84equations)85p = pressure(u, equations)86@unpack psi, rho_inf, u_inf, l_inf = drag_coefficient.force_state87# Normalize as `normal_direction` is not necessarily a unit vector88n = dot(normal_direction, psi) / norm(normal_direction)89return p * n / (0.5f0 * rho_inf * u_inf^2 * l_inf)90end9192function pretty_form_ascii(::AnalysisSurfaceIntegral{<:LiftCoefficientPressure{<:Any,93<:Any}})94"CL_p"95end96function pretty_form_utf(::AnalysisSurfaceIntegral{<:LiftCoefficientPressure{<:Any,97<:Any}})98"CL_p"99end100101function pretty_form_ascii(::AnalysisSurfaceIntegral{<:DragCoefficientPressure{<:Any,102<:Any}})103"CD_p"104end105function pretty_form_utf(::AnalysisSurfaceIntegral{<:DragCoefficientPressure{<:Any,106<:Any}})107"CD_p"108end109110function pretty_form_ascii(::AnalysisSurfaceIntegral{<:LiftCoefficientShearStress{<:Any,111<:Any}})112"CL_f"113end114function pretty_form_utf(::AnalysisSurfaceIntegral{<:LiftCoefficientShearStress{<:Any,115<:Any}})116"CL_f"117end118119function pretty_form_ascii(::AnalysisSurfaceIntegral{<:DragCoefficientShearStress{<:Any,120<:Any}})121"CD_f"122end123function pretty_form_utf(::AnalysisSurfaceIntegral{<:DragCoefficientShearStress{<:Any,124<:Any}})125"CD_f"126end127128include("analysis_surface_integral_2d.jl")129include("analysis_surface_integral_3d.jl")130end # muladd131132133