Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 2D multi-ion GLM-MHD equations for the TreeMesh solver #2196

Merged
merged 27 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fef17d2
Added 2D GLM-MHD equations, examples and tests
amrueda Dec 9, 2024
76eaaf8
Remove ES test
amrueda Dec 10, 2024
0b17871
Compatibility for single precision
amrueda Dec 10, 2024
42dbc96
Changed initial condition back to double precision
amrueda Dec 10, 2024
c6fd5f3
Merge branch 'main' into arr/multi-ion_mhd_2d
amrueda Dec 10, 2024
8919821
Update reference to Hennemann et al.
amrueda Dec 10, 2024
feac4b8
Replaced all occurrences of 2.0f0 and 4.0f0 with 2 and 4
amrueda Dec 10, 2024
2d8c833
Use a single elixir to test EC and EC+LLF
amrueda Dec 10, 2024
ffaf52f
Removed duplicated code in the outer constructor for @reset
amrueda Dec 10, 2024
7cc8dc9
Renamed AbstractIdealMhdMultiIonEquations to AbstractIdealGlmMhdMulti…
amrueda Dec 10, 2024
5f3d46c
GLM callback dispatches on AbstractIdealGlmMhdMultiIonEquations
amrueda Dec 10, 2024
5e7bed5
Moved routines that will be used by all AbstractIdealGlmMhdMultiIonEq…
amrueda Dec 10, 2024
be72d8d
Apply suggestions from code review
amrueda Dec 11, 2024
ad1509a
Apply suggestions from code review
amrueda Dec 11, 2024
6e68caf
Added appropriate formatting to admonitions in docstrings
amrueda Dec 11, 2024
f16b80f
Apply suggestions from code review
amrueda Dec 11, 2024
f3a3e7d
Make multi-ion GLM-MHD's initial condition initial_condition_weak_bla…
amrueda Dec 11, 2024
ee33ce1
Replaced divisions with multiplications
amrueda Dec 11, 2024
249ccf7
Merge branch 'main' into arr/multi-ion_mhd_2d
amrueda Dec 11, 2024
3411e3c
Changed code order...
amrueda Dec 11, 2024
2fbc1d7
Unexport get_component
amrueda Dec 11, 2024
373aab0
Replace division with multiplication
amrueda Dec 11, 2024
79b0e29
Added unit tests for type stability
amrueda Dec 11, 2024
b8e4a29
Added experimental admonitions
amrueda Dec 11, 2024
d31d5f9
Merge branch 'main' into arr/multi-ion_mhd_2d
ranocha Dec 11, 2024
5909d0f
Update src/equations/ideal_glm_mhd_multiion_2d.jl
ranocha Dec 11, 2024
d26713e
Apply suggestions from code review
sloede Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/tree_2d_dgsem/elixir_mhdmultiion_ec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the ideal MHD equations
# semidiscretization of the ideal multi-ion MHD equations
equations = IdealGlmMhdMultiIonEquations2D(gammas = (1.4, 1.667),
sloede marked this conversation as resolved.
Show resolved Hide resolved
charge_to_mass = (1.0, 2.0))

Expand Down
1 change: 0 additions & 1 deletion src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ export entropy, energy_total, energy_kinetic, energy_internal, energy_magnetic,
enstrophy, magnetic_field, divergence_cleaning_field
export lake_at_rest_error
export ncomponents, eachcomponent
export get_component

export TreeMesh, StructuredMesh, StructuredMeshView, UnstructuredMesh2D, P4estMesh,
T8codeMesh
Expand Down
45 changes: 28 additions & 17 deletions src/equations/ideal_glm_mhd_multiion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ function default_analysis_integrals(::AbstractIdealGlmMhdMultiIonEquations)
end

"""
source_terms_lorentz(u, x, t, equations::AbstractIdealGlmMhdMultiIonEquations)
source_terms_lorentz(u, x, t, equations::AbstractIdealGlmMhdMultiIonEquations)

Source terms due to the Lorentz' force for plasmas with more than one ion species. These source
terms are a fundamental, inseparable part of the multi-ion GLM-MHD equations, and vanish for
a single-species plasma.
a single-species plasma. In particular, they have to be used for every
simulation of [`IdealGlmMhdMultiIonEquations2D`](@ref).
"""
function source_terms_lorentz(u, x, t, equations::AbstractIdealGlmMhdMultiIonEquations)
@unpack charge_to_mass = equations
Expand All @@ -54,9 +55,10 @@ function source_terms_lorentz(u, x, t, equations::AbstractIdealGlmMhdMultiIonEqu

for k in eachcomponent(equations)
rho, rho_v1, rho_v2, rho_v3, rho_e = get_component(k, u, equations)
v1 = rho_v1 / rho
v2 = rho_v2 / rho
v3 = rho_v3 / rho
rho_inv = 1 / rho
v1 = rho_v1 * rho_inv
v2 = rho_v2 * rho_inv
v3 = rho_v3 * rho_inv
v1_diff = v1_plus - v1
v2_diff = v2_plus - v2
v3_diff = v3_plus - v3
Expand All @@ -73,7 +75,7 @@ function source_terms_lorentz(u, x, t, equations::AbstractIdealGlmMhdMultiIonEqu
end

"""
electron_pressure_zero(u, equations::AbstractIdealGlmMhdMultiIonEquations)
electron_pressure_zero(u, equations::AbstractIdealGlmMhdMultiIonEquations)

Returns the value of zero for the electron pressure. Needed for consistency with the
single-fluid MHD equations in the limit of one ion species.
Expand All @@ -83,13 +85,16 @@ function electron_pressure_zero(u, equations::AbstractIdealGlmMhdMultiIonEquatio
end

"""
v1, v2, v3, vk1, vk2, vk3 = charge_averaged_velocities(u,
v1, v2, v3, vk1, vk2, vk3 = charge_averaged_velocities(u,
equations::AbstractIdealGlmMhdMultiIonEquations)


Compute the charge-averaged velocities (v1, v2, and v3) and each ion species' contribution
to the charge-averaged velocities (vk1, vk2, and vk3). The output variables vk1, vk2, and vk3
are SVectors of size ncomponents(equations).
Compute the charge-averaged velocities (`v1`, `v2`, and `v3`) and each ion species' contribution
DanielDoehring marked this conversation as resolved.
Show resolved Hide resolved
to the charge-averaged velocities (`vk1`, `vk2`, and `vk3`). The output variables `vk1`, `vk2`, and `vk3`
are `SVectors` of size `ncomponents(equations)`.
DanielDoehring marked this conversation as resolved.
Show resolved Hide resolved

!!! warning "Experimental implementation"
This is an experimental feature and may change in future releases.
"""
@inline function charge_averaged_velocities(u,
equations::AbstractIdealGlmMhdMultiIonEquations)
Expand Down Expand Up @@ -121,7 +126,10 @@ end
"""
get_component(k, u, equations::AbstractIdealGlmMhdMultiIonEquations)

Get the hydrodynamic variables of component (ion species) k.
Get the hydrodynamic variables of component (ion species) `k`.

!!! warning "Experimental implementation"
This is an experimental feature and may change in future releases.
"""
@inline function get_component(k, u, equations::AbstractIdealGlmMhdMultiIonEquations)
return SVector(u[3 + (k - 1) * 5 + 1],
Expand All @@ -135,7 +143,10 @@ end
set_component!(u, k, u1, u2, u3, u4, u5,
equations::AbstractIdealGlmMhdMultiIonEquations)

Set the hydrodynamic variables of component (ion species) k.
Set the hydrodynamic variables (`u1` to `u5`) of component (ion species) `k`.

!!! warning "Experimental implementation"
This is an experimental feature and may change in future releases.
"""
@inline function set_component!(u, k, u1, u2, u3, u4, u5,
equations::AbstractIdealGlmMhdMultiIonEquations)
Expand Down Expand Up @@ -176,10 +187,10 @@ function cons2prim(u, equations::AbstractIdealGlmMhdMultiIonEquations)
prim[3] = B3
for k in eachcomponent(equations)
rho, rho_v1, rho_v2, rho_v3, rho_e = get_component(k, u, equations)
srho = 1 / rho
v1 = srho * rho_v1
v2 = srho * rho_v2
v3 = srho * rho_v3
rho_inv = 1 / rho
v1 = rho_inv * rho_v1
v2 = rho_inv * rho_v2
v3 = rho_inv * rho_v3

p = (gammas[k] - 1) * (rho_e -
0.5f0 * (rho_v1 * v1 + rho_v2 * v2 + rho_v3 * v3
Expand Down Expand Up @@ -241,7 +252,7 @@ end
rho_v2 = rho * v2
rho_v3 = rho * v3

rho_e = p / (gammas[k] - 1.0) +
rho_e = p / (gammas[k] - 1) +
0.5f0 * (rho_v1 * v1 + rho_v2 * v2 + rho_v3 * v3) +
0.5f0 * (B1^2 + B2^2 + B3^2) +
0.5f0 * psi^2
Expand Down
123 changes: 64 additions & 59 deletions src/equations/ideal_glm_mhd_multiion_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ References:
of the Ideal Multi-Ion Magnetohydrodynamics System (2024). Journal of Computational Physics.
[DOI: 10.1016/j.jcp.2024.113655](https://doi.org/10.1016/j.jcp.2024.113655).

!!! ATTENTION: In case of more than one ion species, these equations should ALWAYS be used
with `source_terms_lorentz`.
!!! info "The multi-ion GLM-MHD equations require source terms"
In case of more than one ion species, the multi-ion GLM-MHD equations should ALWAYS be used
with [`source_terms_lorentz`](@ref).
"""
mutable struct IdealGlmMhdMultiIonEquations2D{NVARS, NCOMP, RealT <: Real,
ElectronPressure} <:
Expand Down Expand Up @@ -66,13 +67,12 @@ function IdealGlmMhdMultiIonEquations2D(; gammas, charge_to_mass,
_gammas = promote(gammas...)
_charge_to_mass = promote(charge_to_mass...)
RealT = promote_type(eltype(_gammas), eltype(_charge_to_mass))
__gammas = SVector(map(RealT, _gammas))
__charge_to_mass = SVector(map(RealT, _charge_to_mass))

NVARS = length(_gammas) * 5 + 4
NCOMP = length(_gammas)

__gammas = SVector(map(RealT, _gammas))
__charge_to_mass = SVector(map(RealT, _charge_to_mass))

return IdealGlmMhdMultiIonEquations2D{NVARS, NCOMP, RealT,
typeof(electron_pressure)}(__gammas,
__charge_to_mass,
Expand Down Expand Up @@ -110,27 +110,23 @@ function initial_condition_weak_blast_wave(x, t,
# Adapted MHD version of the weak blast wave from Hennemann & Gassner JCP paper 2020 (Sec. 6.3)
# Same discontinuity in the velocities but with magnetic fields
# Set up polar coordinates
RealT = eltype(x)
amrueda marked this conversation as resolved.
Show resolved Hide resolved
inicenter = (0, 0)
x_norm = x[1] - inicenter[1]
y_norm = x[2] - inicenter[2]
r = sqrt(x_norm^2 + y_norm^2)
phi = atan(y_norm, x_norm)

# Calculate primitive variables
rho = zero(real(equations))
if r > 0.5
rho = 1.0
else
rho = 1.1691
end
v1 = r > 0.5 ? 0.0 : 0.1882 * cos(phi)
v2 = r > 0.5 ? 0.0 : 0.1882 * sin(phi)
p = r > 0.5 ? 1.0 : 1.245
rho = r > 0.5f0 ? one(RealT) : convert(RealT, 1.1691)
v1 = r > 0.5f0 ? zero(RealT) : convert(RealT, 0.1882) * cos(phi)
v2 = r > 0.5f0 ? zero(RealT) : convert(RealT, 0.1882) * sin(phi)
p = r > 0.5f0 ? one(RealT) : convert(RealT, 1.245)

prim = zero(MVector{nvariables(equations), real(equations)})
sloede marked this conversation as resolved.
Show resolved Hide resolved
prim[1] = 1.0
prim[2] = 1.0
prim[3] = 1.0
prim[1] = 1
prim[2] = 1
prim[3] = 1
for k in eachcomponent(equations)
set_component!(prim, k,
2^(k - 1) * (1 - 2) / (1 - 2^ncomponents(equations)) * rho, v1,
Expand Down Expand Up @@ -161,9 +157,10 @@ end

for k in eachcomponent(equations)
rho, rho_v1, rho_v2, rho_v3, rho_e = get_component(k, u, equations)
v1 = rho_v1 / rho
v2 = rho_v2 / rho
v3 = rho_v3 / rho
rho_inv = 1 / rho
v1 = rho_v1 * rho_inv
v2 = rho_v2 * rho_inv
v3 = rho_v3 * rho_inv
kin_en = 0.5f0 * rho * (v1^2 + v2^2 + v3^2)

gamma = equations.gammas[k]
Expand All @@ -187,9 +184,10 @@ end

for k in eachcomponent(equations)
rho, rho_v1, rho_v2, rho_v3, rho_e = get_component(k, u, equations)
v1 = rho_v1 / rho
v2 = rho_v2 / rho
v3 = rho_v3 / rho
rho_inv = 1 / rho
v1 = rho_v1 * rho_inv
v2 = rho_v2 * rho_inv
v3 = rho_v3 * rho_inv
kin_en = 0.5f0 * rho * (v1^2 + v2^2 + v3^2)

gamma = equations.gammas[k]
Expand All @@ -212,7 +210,7 @@ end
end

"""
flux_nonconservative_ruedaramirez_etal(u_ll, u_rr,
flux_nonconservative_ruedaramirez_etal(u_ll, u_rr,
orientation::Integer,
equations::IdealGlmMhdMultiIonEquations2D)
ranocha marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -221,11 +219,12 @@ Entropy-conserving non-conservative two-point "flux"" as described in
of the Ideal Multi-Ion Magnetohydrodynamics System (2024). Journal of Computational Physics.
[DOI: 10.1016/j.jcp.2024.113655](https://doi.org/10.1016/j.jcp.2024.113655).

ATTENTION: The non-conservative fluxes derived in the reference above are written as the product
of local and symmetric parts and are meant to be used in the same way as the conservative
fluxes (i.e., flux + flux_noncons in both volume and surface integrals). In this routine,
the fluxes are multiplied by 2 because the non-conservative fluxes are always multiplied
by 0.5 whenever they are used in the Trixi code
!!! info "Usage and Scaling of Non-Conservative Fluxes in Trixi.jl"
The non-conservative fluxes derived in the reference above are written as the product
of local and symmetric parts and are meant to be used in the same way as the conservative
fluxes (i.e., flux + flux_noncons in both volume and surface integrals). In this routine,
the fluxes are multiplied by 2 because the non-conservative fluxes are always multiplied
by 0.5 whenever they are used in the Trixi code.

The term is composed of four individual non-conservative terms:
1. The Godunov-Powell term, which arises for plasmas with non-vanishing magnetic field divergence, and
Expand Down Expand Up @@ -375,19 +374,21 @@ The term is composed of four individual non-conservative terms:
end

"""
flux_nonconservative_central(u_ll, u_rr, orientation::Integer,
equations::IdealGlmMhdMultiIonEquations2D)
flux_nonconservative_central(u_ll, u_rr, orientation::Integer,
equations::IdealGlmMhdMultiIonEquations2D)

Central non-conservative two-point "flux", where the symmetric parts are computed with standard averages.
The use of this term together with flux_central with VolumeIntegralFluxDifferencing yields a "standard"
The use of this term together with [`flux_central`](@ref)
with [`VolumeIntegralFluxDifferencing`](@ref) yields a "standard"
(weak-form) DGSEM discretization of the multi-ion GLM-MHD system. This flux can also be used to construct a
standard local Lax-Friedrichs flux using `surface_flux = (flux_lax_friedrichs, flux_nonconservative_central)`.

ATTENTION: The central non-conservative fluxes are written as the product
of local and symmetric parts and are meant to be used in the same way as the conservative
fluxes (i.e., flux + flux_noncons in both volume and surface integrals). In this routine,
we omit the 0.5 when computing averages because the non-conservative flux is multiplied by
0.5 whenever it's used in the Trixi code
!!! info "Usage and Scaling of Non-Conservative Fluxes in Trixi"
The central non-conservative fluxes implemented in this function are written as the product
of local and symmetric parts, where the symmetric part is a standard average. These fluxes
are meant to be used in the same way as the conservative fluxes (i.e., flux + flux_noncons
in both volume and surface integrals). In this routine, the fluxes are multiplied by 2 because
the non-conservative fluxes are always multiplied by 0.5 whenever they are used in the Trixi code.

The term is composed of four individual non-conservative terms:
1. The Godunov-Powell term, which arises for plasmas with non-vanishing magnetic field divergence, and
Expand Down Expand Up @@ -520,7 +521,7 @@ The term is composed of four individual non-conservative terms:
end

"""
flux_ruedaramirez_etal(u_ll, u_rr, orientation, equations::IdealGlmMhdMultiIonEquations2D)
flux_ruedaramirez_etal(u_ll, u_rr, orientation, equations::IdealGlmMhdMultiIonEquations2D)

Entropy conserving two-point flux for the multi-ion GLM-MHD equations from
- A. Rueda-Ramírez, A. Sikstel, G. Gassner, An Entropy-Stable Discontinuous Galerkin Discretization
Expand Down Expand Up @@ -582,13 +583,14 @@ function flux_ruedaramirez_etal(u_ll, u_rr, orientation::Integer,
equations)
rho_rr, rho_v1_rr, rho_v2_rr, rho_v3_rr, rho_e_rr = get_component(k, u_rr,
equations)

v1_ll = rho_v1_ll / rho_ll
v2_ll = rho_v2_ll / rho_ll
v3_ll = rho_v3_ll / rho_ll
v1_rr = rho_v1_rr / rho_rr
v2_rr = rho_v2_rr / rho_rr
v3_rr = rho_v3_rr / rho_rr
rho_inv_ll = 1 / rho_ll
v1_ll = rho_v1_ll * rho_inv_ll
v2_ll = rho_v2_ll * rho_inv_ll
v3_ll = rho_v3_ll * rho_inv_ll
rho_inv_rr = 1 / rho_rr
v1_rr = rho_v1_rr * rho_inv_rr
v2_rr = rho_v2_rr * rho_inv_rr
v3_rr = rho_v3_rr * rho_inv_rr
vel_norm_ll = v1_ll^2 + v2_ll^2 + v3_ll^2
vel_norm_rr = v1_rr^2 + v2_rr^2 + v3_rr^2

Expand Down Expand Up @@ -680,12 +682,14 @@ function flux_ruedaramirez_etal(u_ll, u_rr, orientation::Integer,
rho_rr, rho_v1_rr, rho_v2_rr, rho_v3_rr, rho_e_rr = get_component(k, u_rr,
equations)

v1_ll = rho_v1_ll / rho_ll
v2_ll = rho_v2_ll / rho_ll
v3_ll = rho_v3_ll / rho_ll
v1_rr = rho_v1_rr / rho_rr
v2_rr = rho_v2_rr / rho_rr
v3_rr = rho_v3_rr / rho_rr
rho_inv_ll = 1 / rho_ll
v1_ll = rho_v1_ll * rho_inv_ll
v2_ll = rho_v2_ll * rho_inv_ll
v3_ll = rho_v3_ll * rho_inv_ll
rho_inv_rr = 1 / rho_rr
v1_rr = rho_v1_rr * rho_inv_rr
v2_rr = rho_v2_rr * rho_inv_rr
v3_rr = rho_v3_rr * rho_inv_rr
vel_norm_ll = v1_ll^2 + v2_ll^2 + v3_ll^2
vel_norm_rr = v1_rr^2 + v2_rr^2 + v3_rr^2

Expand Down Expand Up @@ -820,20 +824,21 @@ end
for k in eachcomponent(equations)
rho, rho_v1, rho_v2, rho_v3, rho_e = get_component(k, cons, equations)

v1 = rho_v1 / rho
v2 = rho_v2 / rho
v3 = rho_v3 / rho
rho_inv = 1 / rho
v1 = rho_v1 * rho_inv
v2 = rho_v2 * rho_inv
v3 = rho_v3 * rho_inv
v_mag = sqrt(v1^2 + v2^2 + v3^2)
gamma = equations.gammas[k]
p = (gamma - 1) *
(rho_e - 0.5f0 * rho * v_mag^2 - 0.5f0 * (B1^2 + B2^2 + B3^2) -
0.5f0 * psi^2)
a_square = gamma * p / rho
sqrt_rho = sqrt(rho)
a_square = gamma * p * rho_inv
inv_sqrt_rho = 1 / sqrt(rho)

b1 = B1 / sqrt_rho
b2 = B2 / sqrt_rho
b3 = B3 / sqrt_rho
b1 = B1 * inv_sqrt_rho
b2 = B2 * inv_sqrt_rho
b3 = B3 * inv_sqrt_rho
b_square = b1^2 + b2^2 + b3^2

if orientation == 1
Expand Down
2 changes: 1 addition & 1 deletion test/test_tree_2d_mhdmultiion.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module TestExamples2DEulerMulticomponent
module TestExamples2DIdealGlmMhdMultiIon

using Test
using Trixi
Expand Down
Loading
Loading