Path: blob/main/src/equations/linear_elasticity_1d.jl
5586 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@doc raw"""8LinearElasticityEquations1D(;rho::Real, lambda::Real, mu::Real)910Linear elasticity equations in one space dimension. The equations are given by11```math12\partial_t13\begin{pmatrix}14v_1 \\ \sigma_{11}15\end{pmatrix}16+17\partial_x18\begin{pmatrix}19-\frac{1}{\rho} \sigma_{11} \\ -\frac{\rho}{c_1^2} v_120\end{pmatrix}21=22\begin{pmatrix}230 \\ 024\end{pmatrix}.25```26The variables are the deformation velocity `v_1` and the stress `\sigma_{11}`.2728The parameters are the constant density of the material `\rho`29and the Lamé parameters `\lambda` and `\mu`.30From these, one can compute the dilatational wave speed as31```math32c_1^2= \frac{\lambda + 2 * \mu}{\rho}33```34In one dimension the linear elasticity equations reduce to a wave equation.3536For reference, see37- Aleksey Sikstel (2020)38Analysis and numerical methods for coupled hyperbolic conservation laws39[DOI: 10.18154/RWTH-2020-07821](https://doi.org/10.18154/RWTH-2020-07821)40"""41struct LinearElasticityEquations1D{RealT <: Real} <:42AbstractLinearElasticityEquations{1, 2}43rho::RealT # Constant density of the material44c1::RealT # Dilatational wave speed45E::RealT # Young's modulus46end4748function LinearElasticityEquations1D(; rho::Real, mu::Real, lambda::Real)49if !(rho > 0)50throw(ArgumentError("Density rho must be positive."))51end52if !(mu > 0)53throw(ArgumentError("Shear modulus mu (second Lamé parameter) must be positive."))54end5556c1_squared = (lambda + 2 * mu) / rho5758# Young's modulus59# See for reference equation (11-11) in60# https://cns.gatech.edu/~predrag/courses/PHYS-4421-04/lautrup/book/elastic.pdf61E = mu * (3 * lambda + 2 * mu) / (lambda + mu)62return LinearElasticityEquations1D(rho, sqrt(c1_squared), E)63end6465function varnames(::typeof(cons2cons), ::LinearElasticityEquations1D)66return ("v1", "sigma11")67end68function varnames(::typeof(cons2prim), ::LinearElasticityEquations1D)69return ("v1", "sigma11")70end7172"""73initial_condition_convergence_test(x, t, equations::LinearElasticityEquations1D)7475A smooth initial condition used for convergence tests.76This requires that the material parameters `rho` is a positive integer77and `c1` is equal to one.78"""79function initial_condition_convergence_test(x, t,80equations::LinearElasticityEquations1D)81@unpack rho = equations8283v1 = sinpi(2 * t) * cospi(2 * x[1] / rho)84sigma11 = -cospi(2 * t) * sinpi(2 * x[1] * rho)8586return SVector(v1, sigma11)87end8889# Calculate 1D flux for a single point90@inline function flux(u, orientation::Integer, equations::LinearElasticityEquations1D)91@unpack rho, c1 = equations92v1, sigma11 = u93f1 = -sigma11 / rho94f2 = -rho * c1^2 * v19596return SVector(f1, f2)97end9899"""100have_constant_speed(::LinearElasticityEquations1D)101102Indicates whether the characteristic speeds are constant, i.e., independent of the solution.103Queried in the timestep computation [`StepsizeCallback`](@ref) and [`linear_structure`](@ref).104105# Returns106- `True()`107"""108@inline have_constant_speed(::LinearElasticityEquations1D) = True()109110@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,111equations::LinearElasticityEquations1D)112return equations.c1113end114115# Required for `StepsizeCallback`116@inline function max_abs_speeds(equations::LinearElasticityEquations1D)117return equations.c1118end119120# More refined estimates for minimum and maximum wave speeds for HLL-type fluxes121@inline function min_max_speed_davis(u_ll, u_rr, orientation::Integer,122equations::LinearElasticityEquations1D)123@unpack c1 = equations124125λ_min = -c1126λ_max = c1127128return λ_min, λ_max129end130131# Convert conservative variables to primitive132@inline cons2prim(u, equations::LinearElasticityEquations1D) = u133@inline cons2entropy(u, ::LinearElasticityEquations1D) = u134135# Useful for e.g. limiting indicator variable selection136@inline function velocity(u, equations::LinearElasticityEquations1D)137return u[1]138end139140@doc raw"""141energy_kinetic(u, equations::LinearElasticityEquations1D)142143Calculate kinetic energy for a conservative state `u` as144```math145E_{kin} = \frac{1}{2} \rho v_1^2146```147"""148@inline function energy_kinetic(u, equations::LinearElasticityEquations1D)149return 0.5f0 * equations.rho * u[1]^2150end151152@doc raw"""153energy_internal(u, equations::LinearElasticityEquations1D)154155Calculate internal energy for a conservative state `u` as156```math157E_{int} = \frac{1}{2} \frac{\sigma_{11}^2}{E}158```159"""160@inline function energy_internal(u, equations::LinearElasticityEquations1D)161return 0.5f0 * u[2]^2 / equations.E162end163164"""165energy_total(u, equations::LinearElasticityEquations1D)166167Calculate total energy for a conservative state `u` as the sum of168[`energy_kinetic`](@ref) and [`energy_internal`](@ref).169"""170@inline function energy_total(u, equations::LinearElasticityEquations1D)171return energy_kinetic(u, equations) + energy_internal(u, equations)172end173174"""175entropy(u, equations::LinearElasticityEquations1D)176177Calculate entropy for a conservative state `u`,178here same as [`energy_total(u, equations::AbstractLinearElasticityEquations)`](@ref).179"""180@inline entropy(u, equations::LinearElasticityEquations1D) = energy_total(u, equations)181end # muladd182183184