Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/structured_2d_dgsem/elixir_mhd_coupled.jl
2055 views
1
using OrdinaryDiffEqLowStorageRK
2
using Trixi
3
4
###############################################################################
5
# Two semidiscretizations of the ideal GLM-MHD systems using converter functions such that
6
# they are coupled across the domain boundaries to generate a periodic system.
7
#
8
# In this elixir, we have a square domain that is divided into a left and right half.
9
# On each half of the domain, an independent SemidiscretizationHyperbolic is created for
10
# each set of ideal GLM-MHD equations. The two systems are coupled in the x-direction
11
# and are periodic in the y-direction.
12
# For a high-level overview, see also the figure below:
13
#
14
# (-2, 2) ( 2, 2)
15
# ┌────────────────────┬────────────────────┐
16
# │ ↑ periodic ↑ │ ↑ periodic ↑ │
17
# │ │ │
18
# │ ========= │ ========= │
19
# │ system #1 │ system #2 │
20
# │ ========= │ ========= │
21
# │ │ │
22
# │<-- coupled │<-- coupled │
23
# │ coupled -->│ coupled -->│
24
# │ │ │
25
# │ ↓ periodic ↓ │ ↓ periodic ↓ │
26
# └────────────────────┴────────────────────┘
27
# (-2, -2) ( 2, -2)
28
29
gamma = 5 / 3
30
equations = IdealGlmMhdEquations2D(gamma)
31
32
cells_per_dimension = (32, 64)
33
34
# Up to version 0.13.0, `max_abs_speed_naive` was used as the default wave speed estimate of
35
# `const flux_lax_friedrichs = FluxLaxFriedrichs(), i.e., `FluxLaxFriedrichs(max_abs_speed = max_abs_speed_naive)`.
36
# In the `StepsizeCallback`, though, the less diffusive `max_abs_speeds` is employed which is consistent with `max_abs_speed`.
37
# Thus, we exchanged in PR#2458 the default wave speed used in the LLF flux to `max_abs_speed`.
38
# To ensure that every example still runs we specify explicitly `FluxLaxFriedrichs(max_abs_speed_naive)`.
39
# We remark, however, that the now default `max_abs_speed` is in general recommended due to compliance with the
40
# `StepsizeCallback` (CFL-Condition) and less diffusion.
41
surface_flux = (FluxLaxFriedrichs(max_abs_speed_naive), flux_nonconservative_powell)
42
volume_flux = (flux_hindenlang_gassner, flux_nonconservative_powell)
43
solver = DGSEM(polydeg = 3, surface_flux = surface_flux,
44
volume_integral = VolumeIntegralFluxDifferencing(volume_flux))
45
46
###########
47
# system #1
48
###########
49
50
initial_condition1 = initial_condition_convergence_test
51
coordinates_min1 = (-1 / sin(pi / 4), -1 / sin(pi / 4))
52
coordinates_max1 = (0.0, 1 / sin(pi / 4))
53
mesh1 = StructuredMesh(cells_per_dimension,
54
coordinates_min1,
55
coordinates_max1,
56
periodicity = (false, true))
57
58
coupling_function1 = (x, u, equations_other, equations_own) -> u
59
boundary_conditions1 = (x_neg = BoundaryConditionCoupled(2, (:end, :i_forward), Float64,
60
coupling_function1),
61
x_pos = BoundaryConditionCoupled(2, (:begin, :i_forward), Float64,
62
coupling_function1),
63
y_neg = boundary_condition_periodic,
64
y_pos = boundary_condition_periodic)
65
66
semi1 = SemidiscretizationHyperbolic(mesh1, equations, initial_condition1, solver,
67
boundary_conditions = boundary_conditions1)
68
69
###########
70
# system #2
71
###########
72
73
initial_condition2 = initial_condition_convergence_test
74
coordinates_min2 = (0.0, -1 / sin(pi / 4))
75
coordinates_max2 = (1 / sin(pi / 4), 1 / sin(pi / 4))
76
mesh2 = StructuredMesh(cells_per_dimension,
77
coordinates_min2,
78
coordinates_max2,
79
periodicity = (false, true))
80
81
coupling_function2 = (x, u, equations_other, equations_own) -> u
82
boundary_conditions2 = (x_neg = BoundaryConditionCoupled(1, (:end, :i_forward), Float64,
83
coupling_function2),
84
x_pos = BoundaryConditionCoupled(1, (:begin, :i_forward), Float64,
85
coupling_function2),
86
y_neg = boundary_condition_periodic,
87
y_pos = boundary_condition_periodic)
88
89
semi2 = SemidiscretizationHyperbolic(mesh2, equations, initial_condition2, solver,
90
boundary_conditions = boundary_conditions2)
91
92
# Create a semidiscretization that bundles all the semidiscretizations.
93
semi = SemidiscretizationCoupled(semi1, semi2)
94
95
###############################################################################
96
# ODE solvers, callbacks etc.
97
98
tspan = (0.0, 0.1)
99
ode = semidiscretize(semi, tspan)
100
101
summary_callback = SummaryCallback()
102
103
analysis_interval = 100
104
105
analysis_callback1 = AnalysisCallback(semi1, interval = 100)
106
analysis_callback2 = AnalysisCallback(semi2, interval = 100)
107
analysis_callback = AnalysisCallbackCoupled(semi, analysis_callback1, analysis_callback2)
108
109
alive_callback = AliveCallback(analysis_interval = analysis_interval)
110
111
save_solution = SaveSolutionCallback(interval = 50,
112
save_initial_solution = true,
113
save_final_solution = true,
114
solution_variables = cons2prim)
115
116
cfl = 1.0
117
118
stepsize_callback = StepsizeCallback(cfl = cfl)
119
120
glm_speed_callback = GlmSpeedCallback(glm_scale = 0.5, cfl = cfl,
121
semi_indices = [1, 2])
122
123
callbacks = CallbackSet(summary_callback,
124
analysis_callback, alive_callback,
125
save_solution,
126
stepsize_callback,
127
glm_speed_callback)
128
129
###############################################################################
130
# run the simulation
131
132
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);
133
dt = 0.01, # solve needs some value here but it will be overwritten by the stepsize_callback
134
ode_default_options()..., callback = callbacks);
135
136