Path: blob/main/examples/p4est_3d_dgsem/elixir_navierstokes_viscous_shock.jl
2067 views
using OrdinaryDiffEqLowStorageRK1using Trixi23# This is the classic 1D viscous shock wave problem with analytical solution4# for a special value of the Prandtl number.5# The original references are:6#7# - R. Becker (1922)8# Stoßwelle und Detonation.9# [DOI: 10.1007/BF01329605](https://doi.org/10.1007/BF01329605)10#11# English translations:12# Impact waves and detonation. Part I.13# https://ntrs.nasa.gov/api/citations/19930090862/downloads/19930090862.pdf14# Impact waves and detonation. Part II.15# https://ntrs.nasa.gov/api/citations/19930090863/downloads/19930090863.pdf16#17# - M. Morduchow, P. A. Libby (1949)18# On a Complete Solution of the One-Dimensional Flow Equations19# of a Viscous, Head-Conducting, Compressible Gas20# [DOI: 10.2514/8.11882](https://doi.org/10.2514/8.11882)21#22#23# The particular problem considered here is described in24# - L. G. Margolin, J. M. Reisner, P. M. Jordan (2017)25# Entropy in self-similar shock profiles26# [DOI: 10.1016/j.ijnonlinmec.2017.07.003](https://doi.org/10.1016/j.ijnonlinmec.2017.07.003)2728### Fixed parameters ###2930# Special value for which nonlinear solver can be omitted31# Corresponds essentially to fixing the Mach number32alpha = 0.533# We want kappa = cp * mu = mu_bar to ensure constant enthalpy34prandtl_number() = 3 / 43536### Free choices: ###37gamma() = 5 / 33839# In Margolin et al., the Navier-Stokes equations are given for an40# isotropic stress tensor τ, i.e., ∇ ⋅ τ = μ Δu41mu_isotropic() = 0.1542mu_bar() = mu_isotropic() / (gamma() - 1) # Re-scaled viscosity4344rho_0() = 145v() = 1 # Shock speed4647domain_length = 4.04849### Derived quantities ###5051Ma() = 2 / sqrt(3 - gamma()) # Mach number for alpha = 0.552c_0() = v() / Ma() # Speed of sound ahead of the shock5354# From constant enthalpy condition55p_0() = c_0()^2 * rho_0() / gamma()5657l() = mu_bar() / (rho_0() * v()) * 2 * gamma() / (gamma() + 1) # Appropriate length scale5859"""60initial_condition_viscous_shock(x, t, equations)6162Classic 1D viscous shock wave problem with analytical solution63for a special value of the Prandtl number.64The version implemented here is described in65- L. G. Margolin, J. M. Reisner, P. M. Jordan (2017)66Entropy in self-similar shock profiles67[DOI: 10.1016/j.ijnonlinmec.2017.07.003](https://doi.org/10.1016/j.ijnonlinmec.2017.07.003)68"""69function initial_condition_viscous_shock(x, t, equations)70y = x[1] - v() * t # Translated coordinate7172# Coordinate transformation. See eq. (33) in Margolin et al. (2017)73chi = 2 * exp(y / (2 * l()))7475w = 1 + 1 / (2 * chi^2) * (1 - sqrt(1 + 2 * chi^2))7677rho = rho_0() / w78u = v() * (1 - w)79p = p_0() * 1 / w * (1 + (gamma() - 1) / 2 * Ma()^2 * (1 - w^2))8081return prim2cons(SVector(rho, u, 0, 0, p), equations)82end83initial_condition = initial_condition_viscous_shock8485###############################################################################86# semidiscretization of the ideal compressible Navier-Stokes equations8788equations = CompressibleEulerEquations3D(gamma())8990# Trixi implements the stress tensor in deviatoric form, thus we need to91# convert the "isotropic viscosity" to the "deviatoric viscosity"92mu_deviatoric() = mu_bar() * 3 / 493equations_parabolic = CompressibleNavierStokesDiffusion3D(equations, mu = mu_deviatoric(),94Prandtl = prandtl_number(),95gradient_variables = GradientVariablesPrimitive())9697solver = DGSEM(polydeg = 3, surface_flux = flux_hlle)9899coordinates_min = (-domain_length / 2, -domain_length / 2, -domain_length / 2)100coordinates_max = (domain_length / 2, domain_length / 2, domain_length / 2)101102trees_per_dimension = (8, 2, 2)103mesh = P4estMesh(trees_per_dimension, polydeg = 3,104coordinates_min = coordinates_min, coordinates_max = coordinates_max,105periodicity = (false, true, true))106107### Inviscid boundary conditions ###108109# Prescribe pure influx based on initial conditions110function boundary_condition_inflow(u_inner, normal_direction::AbstractVector, x, t,111surface_flux_function,112equations::CompressibleEulerEquations3D)113u_cons = initial_condition_viscous_shock(x, t, equations)114return flux(u_cons, normal_direction, equations)115end116117# Completely free outflow118function boundary_condition_outflow(u_inner, normal_direction::AbstractVector, x, t,119surface_flux_function,120equations::CompressibleEulerEquations3D)121# Calculate the boundary flux entirely from the internal solution state122return flux(u_inner, normal_direction, equations)123end124125boundary_conditions = Dict(:x_neg => boundary_condition_inflow,126:x_pos => boundary_condition_outflow)127128### Viscous boundary conditions ###129# For the viscous BCs, we use the known analytical solution130velocity_bc = NoSlip() do x, t, equations_parabolic131Trixi.velocity(initial_condition_viscous_shock(x,132t,133equations_parabolic),134equations_parabolic)135end136137heat_bc = Isothermal() do x, t, equations_parabolic138Trixi.temperature(initial_condition_viscous_shock(x,139t,140equations_parabolic),141equations_parabolic)142end143144boundary_condition_parabolic = BoundaryConditionNavierStokesWall(velocity_bc, heat_bc)145146boundary_conditions_parabolic = Dict(:x_neg => boundary_condition_parabolic,147:x_pos => boundary_condition_parabolic)148149semi = SemidiscretizationHyperbolicParabolic(mesh, (equations, equations_parabolic),150initial_condition, solver;151boundary_conditions = (boundary_conditions,152boundary_conditions_parabolic))153154###############################################################################155# ODE solvers, callbacks etc.156157# Create ODE problem with time span `tspan`158tspan = (0.0, 0.5)159ode = semidiscretize(semi, tspan)160161summary_callback = SummaryCallback()162163alive_callback = AliveCallback(alive_interval = 10)164165analysis_interval = 100166analysis_callback = AnalysisCallback(semi, interval = analysis_interval)167168callbacks = CallbackSet(summary_callback, alive_callback, analysis_callback)169170###############################################################################171# run the simulation172173time_int_tol = 1e-8174sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol,175dt = 1e-3, ode_default_options()..., callback = callbacks)176177178