Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/p4est_2d_dgsem/elixir_navierstokes_couette_flow.jl
2055 views
1
using OrdinaryDiffEqLowStorageRK
2
using Trixi
3
4
###############################################################################
5
# semidiscretization of the ideal compressible Navier-Stokes equations
6
7
# Fluid parameters
8
gamma() = 1.4
9
prandtl_number() = 0.71
10
11
# Parameters for compressible, yet viscous set up
12
Re() = 100
13
Ma() = 1.2
14
15
# Parameters that can be freely chosen
16
v_top() = 1
17
rho_in() = 1
18
height() = 1.0
19
20
# Parameters that follow from Reynolds and Mach number + adiabatic index gamma
21
nu() = v_top() * height() / Re()
22
23
c() = v_top() / Ma()
24
p_over_rho() = c()^2 / gamma()
25
p_in() = rho_in() * p_over_rho()
26
mu() = rho_in() * nu()
27
28
equations = CompressibleEulerEquations2D(gamma())
29
equations_parabolic = CompressibleNavierStokesDiffusion2D(equations, mu = mu(),
30
Prandtl = prandtl_number())
31
32
# Set inflow, impose known/expected velocity profile
33
@inline function initial_condition(x, t, equations)
34
v1 = x[2] / height() * v_top() # Linear profile from 0 to v_top
35
v2 = 0.0
36
37
prim = SVector(rho_in(), v1, v2, p_in())
38
return prim2cons(prim, equations)
39
end
40
41
len() = 5 * height() # Roughly constant at this len of the channel
42
coordinates_min = (0.0, 0.0) # minimum coordinates (min(x), min(y))
43
coordinates_max = (len(), height()) # maximum coordinates (max(x), max(y))
44
45
trees_per_dimension = (36, 12)
46
mesh = P4estMesh(trees_per_dimension, polydeg = 1,
47
coordinates_min = coordinates_min, coordinates_max = coordinates_max,
48
periodicity = (false, false))
49
50
# Free outflow
51
function boundary_condition_outflow(u_inner, normal_direction::AbstractVector, x, t,
52
surface_flux_function,
53
equations::CompressibleEulerEquations2D)
54
# Calculate the boundary flux entirely from the internal solution state
55
return flux(u_inner, normal_direction, equations)
56
end
57
58
### Hyperbolic boundary conditions ###
59
bs_hyperbolic = Dict(:x_neg => BoundaryConditionDirichlet(initial_condition), # Weakly enforced inflow BC
60
:x_pos => boundary_condition_outflow, # Free outflow/extended domain
61
# Top/Bottom of channel: Walls
62
:y_neg => boundary_condition_slip_wall,
63
:y_pos => boundary_condition_slip_wall)
64
65
### Parabolic boundary conditions ###
66
67
velocity_bc_top_left = NoSlip((x, t, equations) -> SVector(x[2] / height() * v_top(), 0))
68
# Use isothermal for inflow - adiabatic should also work
69
heat_bc_top_left = Isothermal() do x, t, equations_parabolic
70
Trixi.temperature(initial_condition(x, t,
71
equations_parabolic),
72
equations_parabolic)
73
end
74
bc_parabolic_top_left = BoundaryConditionNavierStokesWall(velocity_bc_top_left,
75
heat_bc_top_left)
76
77
velocity_bc_bottom = NoSlip((x, t, equations) -> SVector(0, 0))
78
heat_bc_bottom = Adiabatic((x, t, equations) -> 0)
79
boundary_condition_bottom = BoundaryConditionNavierStokesWall(velocity_bc_bottom,
80
heat_bc_bottom)
81
82
# On right end: Just copy the state/gradients
83
@inline function boundary_condition_copy(flux_inner,
84
u_inner,
85
normal::AbstractVector,
86
x, t,
87
operator_type::Trixi.Gradient,
88
equations::CompressibleNavierStokesDiffusion2D{GradientVariablesPrimitive})
89
return u_inner
90
end
91
@inline function boundary_condition_copy(flux_inner,
92
u_inner,
93
normal::AbstractVector,
94
x, t,
95
operator_type::Trixi.Divergence,
96
equations::CompressibleNavierStokesDiffusion2D{GradientVariablesPrimitive})
97
return flux_inner
98
end
99
100
bcs_parabolic = Dict(:x_neg => bc_parabolic_top_left,
101
:x_pos => boundary_condition_copy,
102
:y_neg => boundary_condition_bottom,
103
:y_pos => bc_parabolic_top_left)
104
105
solver = DGSEM(polydeg = 3, surface_flux = flux_hll)
106
107
semi = SemidiscretizationHyperbolicParabolic(mesh, (equations, equations_parabolic),
108
initial_condition, solver,
109
boundary_conditions = (bs_hyperbolic,
110
bcs_parabolic))
111
112
###############################################################################
113
114
tspan = (0, 5)
115
ode = semidiscretize(semi, tspan)
116
117
summary_callback = SummaryCallback()
118
119
analysis_interval = 1000
120
analysis_callback = AnalysisCallback(semi, interval = analysis_interval,
121
extra_analysis_errors = (:l2_error_primitive,
122
:linf_error_primitive))
123
124
alive_callback = AliveCallback(analysis_interval = analysis_interval)
125
126
save_solution = SaveSolutionCallback(dt = 1.0,
127
save_initial_solution = true,
128
save_final_solution = true,
129
solution_variables = cons2prim)
130
131
callbacks = CallbackSet(summary_callback,
132
analysis_callback,
133
alive_callback,
134
save_solution)
135
136
###############################################################################
137
138
time_int_tol = 1e-7
139
sol = solve(ode, RDPK3SpFSAL49();
140
abstol = time_int_tol, reltol = time_int_tol,
141
ode_default_options()..., callback = callbacks)
142
143