Models#

This module contains all the models implemented in Struphy. Each model is defined in its own submodule, and this __init__.py file imports all the models and makes them available for use when the struphy.models package is imported.

class struphy.models.ColdPlasma[source]#

Bases: StruphyModel

Cold plasma model.

Normalization:

\[\hat v = c\,,\qquad \hat E = c \hat B \,.\]

Equations:

\[\begin{split}\frac{1}{n_0} &\frac{\partial \mathbf j}{\partial t} = \frac{1}{\varepsilon} \mathbf E + \frac{1}{\varepsilon n_0} \mathbf j \times \mathbf B_0\,, \\[2mm] &\frac{\partial \mathbf B}{\partial t} + \nabla\times\mathbf E = 0\,, \\[2mm] -&\frac{\partial \mathbf E}{\partial t} + \nabla\times\mathbf B = \frac{\alpha^2}{\varepsilon} \mathbf j \,,\end{split}\]

where \((n_0,\mathbf B_0)\) denotes a (inhomogeneous) background and

\[\alpha = \frac{\hat \Omega_\textnormal{p}}{\hat \Omega_\textnormal{c}}\,, \qquad \varepsilon = \frac{1}{\hat \Omega_\textnormal{c} \hat t}\,.\]

Propagators (called in sequence):

  1. Maxwell

  2. OhmCold

  3. JxBCold

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class Electrons[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.ColdPlasmaVlasov[source]#

Bases: StruphyModel

Cold plasma hybrid model.

Normalization:

\[\hat v = c\,,\qquad \hat E = c \hat B \,,\qquad \hat f = \frac{\hat n}{c^3} \,.\]

Equations:

\[\begin{split}&\frac{\partial f}{\partial t} + \mathbf{v} \cdot \, \nabla f + \frac{1}{\varepsilon_\textnormal{h}}\Big[ \mathbf{E} + \mathbf{v} \times \left( \mathbf{B} + \mathbf{B}_0 \right) \Big] \cdot \frac{\partial f}{\partial \mathbf{v}} = 0 \,, \\[2mm] \frac{1}{n_0} &\frac{\partial \mathbf j_\textnormal{c}}{\partial t} = \frac{1}{\varepsilon_\textnormal{c}} \mathbf E + \frac{1}{\varepsilon_\textnormal{c} n_0} \mathbf j_\textnormal{c} \times \mathbf B_0\,, \\[2mm] &\frac{\partial \mathbf B}{\partial t} + \nabla\times\mathbf E = 0\,, \\[2mm] -&\frac{\partial \mathbf E}{\partial t} + \nabla\times\mathbf B = \frac{\alpha^2}{\varepsilon_\textnormal{h}} \left( \mathbf j_\textnormal{c} + \int_{\mathbb{R}^3} \mathbf{v} f \, \text{d}^3 \mathbf{v} \right) \,,\end{split}\]

where \((n_0,\mathbf B_0)\) denotes a (inhomogeneous) background and

\[\alpha = \frac{\hat \Omega_\textnormal{p,cold}}{\hat \Omega_\textnormal{c,cold}}\,, \qquad \varepsilon_\textnormal{c} = \frac{1}{\hat \Omega_\textnormal{c,cold} \hat t}\,, \qquad \varepsilon_\textnormal{h} = \frac{1}{\hat \Omega_\textnormal{c,hot} \hat t} \,.\]

At initial time the Poisson equation is solved once to weakly satisfy the Gauss law:

\[\begin{align} \nabla \cdot \mathbf{E} & = \nu \frac{\alpha^2}{\varepsilon_\textnormal{h}} \int_{\mathbb{R}^3} f \, \text{d}^3 \mathbf{v}\,. \end{align}\]

Propagators (called in sequence):

  1. Maxwell

  2. OhmCold

  3. JxBCold

  4. PushVxB

  5. PushEta

  6. VlasovAmpere

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class ThermalElectrons[source]#

Bases: FluidSpecies

class HotElectrons[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.DeterministicParticleDiffusion[source]#

Bases: StruphyModel

Diffusion equation discretized with a deterministic particle method; the solution is \(L^2\)-projected onto \(V^0 \subset H^1\) to compute the flux.

Normalization:

\[\hat D := \frac{\hat x^2}{\hat t } \,.\]

Equations: Find \(u:\mathbb R\times \Omega\to \mathbb R^+\) such that

\[\frac{\partial u}{\partial t} + \nabla \cdot\left(\mathbf F(u) u\right) = 0\,, \qquad \mathbf F(u) = -\mathbb D\,\frac{\nabla u}{u}\,,\]

where \(\mathbb D: \Omega\to \mathbb R^{3\times 3 }\) is a positive diffusion matrix. At the moment only matrices of the form \(D*Id\) are implemented, where \(D > 0\) is a positive diffusion coefficient.

Propagators (called in sequence):

  1. PushDeterministicDiffusion

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class Hydrogen[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.DriftKineticElectrostaticAdiabatic[source]#

Bases: StruphyModel

Drift-kinetic equation for one ion species in static background magnetic field, coupled to quasi-neutrality equation with adiabatic electrons.

Normalization:

\[\hat v = \hat v_\textrm{i} = \sqrt{\frac{k_B \hat T_\textrm{i}}{m_\textrm{i}}}\,,\qquad \hat E = \hat v_\textrm{i}\hat B\,,\qquad \hat \phi = \hat E \hat x \,.\]

Equations:

\[\begin{split}&\frac{\partial f}{\partial t} + \left[ v_\parallel \frac{\mathbf{B}^*}{B^*_\parallel} + \frac{\mathbf{E}^* \times \mathbf{b}_0}{B^*_\parallel}\right] \cdot \frac{\partial f}{\partial \mathbf{X}} + \left[\frac{1}{\varepsilon} \frac{\mathbf{B}^*}{B^*_\parallel} \cdot \mathbf{E}^*\right] \cdot \frac{\partial f}{\partial v_\parallel} = 0\,. \\[2mm] - &\nabla_\perp \cdot \left( \frac{n_0}{|B_0|^2} \nabla_\perp \phi \right) + \frac{1}{\varepsilon} n_0 \left(1 + \frac{1}{Z \varepsilon} \frac{1}{T_{0}} \phi \right) = \frac 1 \varepsilon \int f B^*_\parallel \,\textnormal d v_\parallel \textnormal d \mu \,.\end{split}\]

where \(f(\mathbf{X}, v_\parallel, \mu, t)\) is the guiding center distribution and

\[\mathbf{E}^* = - \nabla \phi - \varepsilon \mu \nabla |B_0| \,, \qquad \mathbf{B}^* = \mathbf{B}_0 + \varepsilon v_\parallel \nabla \times \mathbf{b}_0 \,,\qquad B^*_\parallel = \mathbf B^* \cdot \mathbf b_0 \,,\]

and with the normalization parameters

\[\varepsilon := \frac{1}{\hat \Omega_\textrm{c} \hat t}\,,\qquad \hat \Omega_\textrm{c} = \frac{q_\textrm{i} \hat B}{m_\textrm{i}} \,.\]

Notes

  • The Control variate method in the Poisson equation is optional; in case it is enabled via the parameter file, the following Poisson equation is solved:

Find \(\phi \in H^1\) such that

\[\int \frac{n_0}{|B_0|^2} \nabla_\perp \psi \cdot \nabla_\perp \phi\,\textrm d \mathbf x + \frac{1}{Z\varepsilon^2} \int \frac{n_0}{T_{0}} \psi \phi \,\textrm d \mathbf x = \frac 1 \varepsilon \int \int \psi \, (f - f_0) B^*_\parallel \,\textrm d \mathbf x\,\textnormal d v_\parallel \textnormal d \mu \qquad \forall \ \psi \in H^1\,.\]

Propagators (called in sequence):

  1. ImplicitDiffusion

  2. PushGuidingCenterBxEstar

  3. PushGuidingCenterParallel

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.GuidingCenter[source]#

Bases: StruphyModel

Guiding-center equation in static background magnetic field.

Normalization:

\[\hat v = \hat v_\textnormal{A} \,.\]

Equations:

\[\frac{\partial f}{\partial t} + \left[ v_\parallel \frac{\mathbf{B}^*}{B^*_\parallel} + \frac{\mathbf{E}^* \times \mathbf{b}_0}{B^*_\parallel}\right] \cdot \frac{\partial f}{\partial \mathbf{X}} + \left[\frac{1}{\epsilon} \frac{\mathbf{B}^*}{B^*_\parallel} \cdot \mathbf{E}^*\right] \cdot \frac{\partial f}{\partial v_\parallel} = 0\,.\]

where \(f(\mathbf{X}, v_\parallel, \mu, t)\) is the guiding center distribution and

\[\mathbf{E}^* = -\epsilon \mu \nabla |B_0| \,, \qquad \mathbf{B}^* = \mathbf{B}_0 + \epsilon v_\parallel \nabla \times \mathbf{b}_0 \,,\qquad B^*_\parallel = \mathbf B^* \cdot \mathbf b_0 \,.\]

Moreover,

\[\epsilon = \frac{1 }{ \hat \Omega_{\textnormal{c}} \hat t}\,,\qquad \textnormal{with} \qquad\hat \Omega_{\textnormal{c}} = \frac{Ze \hat B}{A m_\textnormal{H}}\,.\]

Propagators (called in sequence):

  1. PushGuidingCenterBxEstar

  2. PushGuidingCenterParallel

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.HasegawaWakatani[source]#

Bases: StruphyModel

Hasegawa-Wakatani equations in 2D.

Normalization:

\[\hat u = \hat v_\textnormal{th}\,,\qquad \hat \phi = \hat u\, \hat x \,.\]

Equations:

\[\begin{split}&\frac{\partial n}{\partial t} = C (\phi - n) - [\phi, n] - \kappa\, \partial_y \phi + \nu\, \nabla^{2N} n\,, \\[2mm] &\frac{\partial \omega}{\partial t} = C (\phi - n) - [\phi, \omega] + \nu\, \nabla^{2N} \omega \,, \\[3mm] &\Delta \phi = \omega\,,\end{split}\]

where \([\phi, n] = \partial_x \phi \partial_y n - \partial_y \phi \partial_x n\), \(C = C(x, y)\) and \(\kappa\) and \(\nu\) are constants (at the moment only \(N=1\) is available).

Propagators (called in sequence):

  1. Poisson

  2. HasegawaWakatani

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class Plasma[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

update_rho()[source]#
generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearExtendedMHDuniform[source]#

Bases: StruphyModel

Linear extended MHD with zero-flow equilibrium (\(\mathbf U_0 = 0\)). For uniform background conditions only.

Normalization:

\[\hat U = \hat v_\textnormal{A} \,.\]

Equations:

\[\begin{split}&\frac{\partial \tilde \rho}{\partial t}+\nabla\cdot(\rho_0 \tilde{\mathbf{U}})=0\,, \\[2mm] \rho_0&\frac{\partial \tilde{\mathbf{U}}}{\partial t} + \nabla \tilde p =(\nabla\times \tilde{\mathbf{B}})\times\mathbf{B}_0 \,, \\[2mm] &\frac{\partial \tilde p}{\partial t} + \frac{5}{3}\,p_{0}\nabla\cdot \tilde{\mathbf{U}}=0\,, \\[2mm] &\frac{\partial \tilde{\mathbf{B}}}{\partial t} - \nabla\times \left( \tilde{\mathbf{U}} \times \mathbf{B}_0 - \frac{1}{\varepsilon} \frac{\nabla\times \tilde{\mathbf{B}}}{\rho_0}\times \mathbf{B}_0 \right) = 0\,.\end{split}\]

where

\[\varepsilon = \frac{1}{\hat \Omega_{\textnormal{c}} \hat t}\,,\qquad \textnormal{with} \qquad\hat \Omega_{\textnormal{c}} = \frac{Ze \hat B}{A m_\textnormal{H}}\,.\]

Propagators (called in sequence):

  1. ShearAlfvenB1

  2. Hall

  3. MagnetosonicUniform

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearMHD[source]#

Bases: StruphyModel

Linear ideal MHD with zero-flow equilibrium for magnetohydrodynamic wave propagation.

This model simulates small-amplitude perturbations in a magnetized plasma with a static equilibrium magnetic field \(\mathbf{B}_0\) and zero background flow. The model solves the linearized ideal magnetohydrodynamic (MHD) equations, which couple fluid dynamics (density, velocity, pressure) with magnetic field evolution. The system supports both Alfvén waves (incompressible shear) and magnetosonic waves (compressible fast and slow modes).

Governing Equations

Continuity (mass conservation):

\[\frac{\partial \tilde{\rho}}{\partial t} + \nabla \cdot (\rho_0 \tilde{\mathbf{U}}) = 0\]

Momentum (Lorentz force):

\[\rho_0 \frac{\partial \tilde{\mathbf{U}}}{\partial t} + \nabla \tilde{p} = (\nabla \times \tilde{\mathbf{B}}) \times \mathbf{B}_0 + (\nabla \times \mathbf{B}_0) \times \tilde{\mathbf{B}}\]

Energy (adiabatic process):

\[\frac{\partial \tilde{p}}{\partial t} + \nabla \cdot (p_0 \tilde{\mathbf{U}}) + \frac{2}{3} p_0 \nabla \cdot \tilde{\mathbf{U}} = 0\]

Induction (Faraday’s law):

\[\frac{\partial \tilde{\mathbf{B}}}{\partial t} - \nabla \times (\tilde{\mathbf{U}} \times \mathbf{B}_0) = 0\]

Normalization

All velocities are normalized by the Alfvén velocity:

\[\hat{U} = \hat{v}_\mathrm{A} = \frac{\hat{B}_0}{\sqrt{\mu_0 \rho_0}}\]

Perturbation Variables

All quantities in the equations represent perturbations around equilibrium:

  • \(\tilde{\rho}\) - Density perturbation

  • \(\tilde{\mathbf{U}}\) - Velocity perturbation

  • \(\tilde{p}\) - Pressure perturbation

  • \(\tilde{\mathbf{B}}\) - Magnetic field perturbation

Equilibrium quantities (with subscript 0) are stationary:

  • \(\rho_0\) - Static background density

  • \(p_0\) - Static background pressure

  • \(\mathbf{B}_0\) - Static background magnetic field

Species

  • em_fields.b_field - Magnetic field perturbation (H(div) space)

  • mhd.density - Density perturbation (L² space)

  • mhd.velocity - Velocity perturbation (H(div) space)

  • mhd.pressure - Pressure perturbation (L² space)

Wave Modes

The linear MHD system supports three wave types:

  • Alfvén waves: Incompressible shear waves propagating along \(\mathbf{B}_0\) with velocity \(v_A\)

  • Fast magnetosonic wave: Compressible wave with phase velocity \(v_\mathrm{fast} > v_A\)

  • Slow magnetosonic wave: Compressible wave with phase velocity \(v_\mathrm{slow} < v_A\)

Propagators

Time integration is performed by the following propagators (in sequence):

  1. ShearAlfven - Evolves Alfvén waves (velocity and magnetic field coupling)

  2. Magnetosonic - Evolves compressible modes (density, velocity, pressure)

Scalar Quantities

The following energies are tracked during simulation:

  • Kinetic energy (perturbation): \(E_U = \frac{1}{2} \int \rho_0 |\tilde{\mathbf{U}}|^2 \, \mathrm{d}V\)

  • Magnetic energy (perturbation): \(E_B = \frac{1}{2} \int \frac{|\tilde{\mathbf{B}}|^2}{\mu_0} \, \mathrm{d}V\)

  • Internal energy (perturbation): \(E_p = \int \frac{\tilde{p}}{\gamma - 1} \, \mathrm{d}V\) (\(\gamma = 5/3\))

  • Total perturbed energy: \(E_\mathrm{tot} = E_U + E_B + E_p\)

  • Equilibrium magnetic energy: \(E_{B0} = \frac{1}{2} \int \frac{|\mathbf{B}_0|^2}{\mu_0} \, \mathrm{d}V\)

  • Equilibrium internal energy: \(E_{p0} = \int \frac{p_0}{\gamma - 1} \, \mathrm{d}V\)

  • Total magnetic energy: \(E_{B,\mathrm{tot}} = \frac{1}{2} \int \frac{|\mathbf{B}_0 + \tilde{\mathbf{B}}|^2}{\mu_0} \, \mathrm{d}V\)

Model Properties

  • Model type: Fluid

  • Velocity scale: Alfvén velocity

  • Bulk species: mhd

  • Assumptions: Zero-flow equilibrium, linear perturbations, ideal MHD

Key Assumptions

  • Perturbations are small (linear theory valid)

  • Equilibrium is static: \(\mathbf{U}_0 = 0\)

  • Ideal MHD: infinite conductivity, no dissipation

  • Adiabatic process: polytropic index \(\gamma = 5/3\)

See Also

References

  • Boyd, T. J. M., & Sanderson, J. J. (2003). The physics of plasmas. Cambridge University Press.

  • Goedbloed, J. P., Keppens, R., & Poedts, S. (2019). Magnetohydrodynamics of laboratory and astrophysical plasmas. Cambridge University Press.

Examples

Create and initialize a linear MHD model:

from struphy.models.linear_mhd import LinearMHD

model = LinearMHD()

# Access fields
# model.em_fields.b_field     - Magnetic field perturbation
# model.mhd.density           - Density perturbation
# model.mhd.velocity          - Velocity perturbation
# model.mhd.pressure          - Pressure perturbation

# Track energies during simulation
# model.scalar_quantities["en_U"]  - Kinetic energy
# model.scalar_quantities["en_B"]  - Magnetic energy
# model.scalar_quantities["en_p"]  - Internal energy
classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearMHDDriftkineticCC(turn_off: tuple[str, ...] = (None,))[source]#

Bases: StruphyModel

Hybrid linear ideal MHD + energetic ions (5D Driftkinetic) with current coupling scheme.

Normalization:

\[\hat U = \hat v =: \hat v_\textnormal{A, bulk} \,, \qquad \hat f_\textnormal{h} = \frac{\hat n}{\hat v_\textnormal{h} \hat \mu \hat B} \,,\qquad \hat \mu = \frac{A_\textnormal{h} m_\textnormal{H} \hat v_\textnormal{h}^2}{\hat B} \,.\]

Equations:

\[\begin{split}\begin{align} \textnormal{MHD} &\left\{ \begin{aligned} &\frac{\partial \tilde{\rho}}{\partial t}+\nabla\cdot(\rho_{0} \tilde{\mathbf{U}})=0\,, \\ \rho_{0} &\frac{\partial \tilde{\mathbf{U}}}{\partial t} - \tilde p\, \nabla = (\nabla \times \tilde{\mathbf{B}}) \times \mathbf{B} + (\nabla \times \mathbf B_0) \times \tilde{\mathbf{B}} + \frac{A_\textnormal{h}}{A_\textnormal{b}} \left[ \frac{1}{\epsilon} n_\textnormal{gc} \tilde{\mathbf{U}} - \frac{1}{\epsilon} \mathbf{J}_\textnormal{gc} - \nabla \times \mathbf{M}_\textnormal{gc} \right] \times \mathbf{B} \,, \\ &\frac{\partial \tilde p}{\partial t} + \nabla\cdot(p_0 \tilde{\mathbf{U}}) + \frac{2}{3}\,p_0\nabla\cdot \tilde{\mathbf{U}}=0\,, \\ &\frac{\partial \tilde{\mathbf{B}}}{\partial t} - \nabla\times(\tilde{\mathbf{U}} \times \mathbf{B}) = 0\,, \end{aligned} \right. \\[2mm] \textnormal{EPs}\,\, &\left\{\,\, \begin{aligned} \quad &\frac{\partial f_\textnormal{h}}{\partial t} + \frac{1}{B_\parallel^*}(v_\parallel \mathbf{B}^* - \mathbf{b}_0 \times \mathbf{E}^*)\cdot\nabla f_\textnormal{h} + \frac{1}{\epsilon} \frac{1}{B_\parallel^*} (\mathbf{B}^* \cdot \mathbf{E}^*) \frac{\partial f_\textnormal{h}}{\partial v_\parallel} = 0\,, \\ & n_\textnormal{gc} = \int f_\textnormal{h} B_\parallel^* \,\textnormal dv_\parallel \textnormal d\mu \,, \\ & \mathbf{J}_\textnormal{gc} = \int \frac{f_\textnormal{h}}{B_\parallel^*}(v_\parallel \mathbf{B}^* - \mathbf{b}_0 \times \mathbf{E}^*) \,\textnormal dv_\parallel \textnormal d\mu \,, \\ & \mathbf{M}_\textnormal{gc} = - \int f_\textnormal{h} B_\parallel^* \mu \mathbf{b}_0 \,\textnormal dv_\parallel \textnormal d\mu \,, \end{aligned} \right. \end{align}\end{split}\]

where

\[\begin{split}\begin{align} B^*_\parallel = \mathbf{b}_0 \cdot \mathbf{B}^*\,, \\[2mm] \mathbf{B}^* &= \mathbf{B} + \epsilon v_\parallel \nabla \times \mathbf{b}_0 \,, \\[2mm] \mathbf{E}^* &= - \tilde{\mathbf{U}} \times \mathbf{B} - \epsilon \mu \nabla (\mathbf{b}_0 \cdot \mathbf{B}) \,, \end{align}\end{split}\]

with the normalization parameter

\[\epsilon = \frac{1}{\hat \Omega_\textnormal{c,hot} \hat t} \,, \qquad \hat \Omega_\textnormal{c,hot} = \frac{Z_\textnormal{h} e \hat B}{A_\textnormal{h} m_\textnormal{H}} \,.\]

Propagators (called in sequence):

  1. PushGuidingCenterBxEstar

  2. PushGuidingCenterParallel

  3. CurrentCoupling5DGradB

  4. CurrentCoupling5DCurlb

  5. CurrentCoupling5DDensity

  6. ShearAlfvenCurrentCoupling5D

  7. Magnetosonic

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EnergeticIons[source]#

Bases: ParticleSpecies

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Propagators(turn_off: tuple[str, ...] = (None,))[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearMHDVlasovCC[source]#

Bases: StruphyModel

Hybrid linear MHD + energetic ions (6D Vlasov) with current coupling scheme.

Normalization:

\[\hat U = \hat v = \hat v_\textnormal{A} \,, \qquad \hat f_\textnormal{h} = \frac{\hat n}{\hat v_\textnormal{A}^3} \,.\]

Equations:

\[\begin{split}\begin{align} \textnormal{MHD}\,\, &\left\{\,\, \begin{aligned} &\frac{\partial \tilde{\rho}}{\partial t}+\nabla\cdot(\rho_0 \tilde{\mathbf{U}})=0\,, \\[2mm] \rho_0 &\frac{\partial \tilde{\mathbf{U}}}{\partial t} + \nabla \tilde p =(\nabla\times \tilde{\mathbf{B}})\times\mathbf{B}_0 + \mathbf{J}_0\times \tilde{\mathbf{B}} \color{blue} + \frac{A_\textnormal{h}}{A_\textnormal{b}} \frac{1}{\varepsilon} \left(n_\textnormal{h}\tilde{\mathbf{U}}-n_\textnormal{h}\mathbf{u}_\textnormal{h}\right)\times(\mathbf{B}_0+\tilde{\mathbf{B}}) \color{black}\,, \\[2mm] &\frac{\partial \tilde p}{\partial t} + (\gamma-1)\nabla\cdot(p_0 \tilde{\mathbf{U}}) + p_0\nabla\cdot \tilde{\mathbf{U}}=0\,, \\[2mm] &\frac{\partial \tilde{\mathbf{B}}}{\partial t} = \nabla\times(\tilde{\mathbf{U}} \times \mathbf{B}_0)\,,\qquad \nabla\cdot\tilde{\mathbf{B}}=0\,, \end{aligned} \right. \\[2mm] \textnormal{EPs}\,\, &\left\{\,\, \begin{aligned} &\quad\,\,\frac{\partial f_\textnormal{h}}{\partial t}+\mathbf{v}\cdot\nabla f_\textnormal{h} + \frac{1}{\varepsilon} \left[\color{blue} (\mathbf{B}_0+\tilde{\mathbf{B}})\times\tilde{\mathbf{U}} \color{black} + \mathbf{v}\times(\mathbf{B}_0+\tilde{\mathbf{B}})\right]\cdot \frac{\partial f_\textnormal{h}}{\partial \mathbf{v}} =0\,, \\[2mm] &\quad\,\,n_\textnormal{h}=\int_{\mathbb{R}^3}f_\textnormal{h}\,\textnormal{d}^3 \mathbf v\,,\qquad n_\textnormal{h}\mathbf{u}_\textnormal{h}=\int_{\mathbb{R}^3}f_\textnormal{h}\mathbf{v}\,\textnormal{d}^3 \mathbf v\,, \end{aligned} \right. \end{align}\end{split}\]

where \(\mathbf{J}_0 = \nabla\times\mathbf{B}_0\) and

\[\varepsilon = \frac{1}{\hat \Omega_{\textnormal{c,hot}} \hat t}\,,\qquad \textnormal{with} \qquad\hat \Omega_{\textnormal{c,hot}} = \frac{Z_\textnormal{h}e \hat B}{A_\textnormal{h} m_\textnormal{H}}\,.\]

Propagators (called in sequence):

  1. CurrentCoupling6DDensity

  2. ShearAlfven

  3. CurrentCoupling6DCurrent

  4. PushEta

  5. PushVxB

  6. Magnetosonic

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class EnergeticIons[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearMHDVlasovPC(turn_off: tuple[str, ...] = (None,))[source]#

Bases: StruphyModel

Hybrid linear MHD + energetic ions (6D Vlasov) with pressure coupling scheme.

Normalization:

\[\hat U = \hat v =: \hat v_\textnormal{A, bulk} \,, \qquad \hat f_\textnormal{h} = \frac{\hat n}{\hat v_\textnormal{A}^3} \,,\qquad \hat{\mathbb{P}}_\textnormal{h} = A_\textnormal{h}m_\textnormal{H}\hat n \hat v_\textnormal{A}^2\,,\]

Implemented equations:

\[\begin{split}\begin{align} \textnormal{MHD} &\left\{ \begin{aligned} &\frac{\partial \tilde{\rho}}{\partial t}+\nabla\cdot(\rho_0 \tilde{\mathbf{U}})=0\,, \\ \rho_0 &\frac{\partial \tilde{\mathbf{U}}}{\partial t} + \nabla \tilde p + \frac{A_\textnormal{h}}{A_\textnormal{b}} \nabla\cdot \tilde{\mathbb{P}}_{\textnormal{h},\perp} =(\nabla\times \tilde{\mathbf{B}})\times\mathbf{B}_0 + \mathbf{J}_0\times \tilde{\mathbf{B}} \,, \qquad \mathbf{J}_0 = \nabla\times\mathbf{B}_0\,, \\ &\frac{\partial \tilde p}{\partial t} + \nabla\cdot(p_0 \tilde{\mathbf{U}}) + \frac{2}{3}\,p_0\nabla\cdot \tilde{\mathbf{U}}=0\,, \\ &\frac{\partial \tilde{\mathbf{B}}}{\partial t} - \nabla\times(\tilde{\mathbf{U}} \times \mathbf{B}_0) = 0\,, \end{aligned} \right. \\[2mm] \textnormal{EPs}\,\, &\left\{\,\, \begin{aligned} &\quad\,\,\frac{\partial f_\textnormal{h}}{\partial t} + (\mathbf{v} + \tilde{\mathbf{U}}_\perp)\cdot \nabla f_\textnormal{h} + \left[\frac{1}{\epsilon}\, \mathbf{v}\times(\mathbf{B}_0 + \tilde{\mathbf{B}}) - \nabla \tilde{\mathbf{U}}_\perp\cdot \mathbf{v} \right]\cdot \frac{\partial f_\textnormal{h}}{\partial \mathbf{v}} = 0\,, \\ &\quad\,\,\tilde{\mathbb{P}}_{\textnormal{h},\perp} = \int \mathbf{v}_\perp\mathbf{v}^\top_\perp f_\textnormal{h} d\mathbf{v} \,, \end{aligned} \right. \end{align}\end{split}\]

where

\[\epsilon = \frac{\hat \omega}{2 \pi \, \hat \Omega_{\textnormal{c,hot}}} \,,\qquad \textnormal{with} \qquad\hat \Omega_{\textnormal{c,hot}} = \frac{Z_\textnormal{h}e \hat B}{A_\textnormal{h} m_\textnormal{H}}\,.\]

Propagators (called in sequence):

  1. PushEtaPC

  2. PushVxB

  3. PressureCoupling6D

  4. ShearAlfven

  5. Magnetosonic

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EnergeticIons[source]#

Bases: ParticleSpecies

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Propagators(turn_off: tuple[str, ...] = (None,))[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearVlasovAmpereOneSpecies(with_B0: bool = True, with_E0: bool = True)[source]#

Bases: StruphyModel

Linearized Vlasov-Ampère equations for one species.

Normalization:

\[\begin{align} \hat v = c \,, \qquad \hat E = \hat B \hat v\,,\qquad \hat \phi = \hat E \hat x \,. \end{align}\]

Equations:

\[\begin{split}\begin{align} & \frac{\partial \tilde{\mathbf E}}{\partial t} = - \frac{\alpha^2}{\varepsilon} \int_{\mathbb R^3} \mathbf{v} \tilde f\, \textrm d^3 \mathbf v \,, \\[2mm] & \frac{\partial \tilde f}{\partial t} + \mathbf{v} \cdot \, \nabla \tilde f + \frac{1}{\varepsilon} \left( \mathbf{E}_0 + \mathbf{v} \times \mathbf{B}_0 \right) \cdot \frac{\partial \tilde f}{\partial \mathbf{v}} = \frac{1}{v_{\text{th}}^2 \varepsilon} \, \tilde{\mathbf E} \cdot \mathbf{v} f_0 \,, \end{align}\end{split}\]

with the normalization parameter

\[\alpha = \frac{\hat \Omega_\textnormal{p}}{\hat \Omega_\textnormal{c}}\,,\qquad \varepsilon = \frac{1}{\hat \Omega_\textnormal{c} \hat t} \,,\qquad \textnormal{with} \qquad \hat\Omega_\textnormal{p} = \sqrt{\frac{\hat n (Ze)^2}{\epsilon_0 (A m_\textnormal{H})}} \,,\qquad \hat \Omega_{\textnormal{c}} = \frac{(Ze) \hat B}{(A m_\textnormal{H})}\,,\]

where \(Z=-1\) and \(A=1/1836\) for electrons. The background distribution function \(f_0\) is a uniform Maxwellian

\[f_0 = \frac{n_0(\mathbf{x})}{\left( \sqrt{2 \pi} v_{\text{th}} \right)^3} \exp \left( - \frac{|\mathbf{v}|^2}{2 v_{\text{th}}^2} \right) \,,\]

and the background electric field has to verify the following compatibility condition between with background density

\[\nabla_{\mathbf{x}} \ln (n_0(\mathbf{x})) = \frac{1}{v_{\text{th}}^2 \varepsilon} \mathbf{E}_0 \,.\]

At initial time the weak Poisson equation is solved once to weakly satisfy Gauss’ law,

\[\begin{split}\begin{align} \int_\Omega \nabla \psi^\top \cdot \nabla \phi \,\textrm d \mathbf x &= \frac{\alpha^2}{\varepsilon} \int_\Omega \int_{\mathbb{R}^3} \psi\, \tilde f \, \text{d}^3 \mathbf{v}\,\textrm d \mathbf x \qquad \forall \ \psi \in H^1\,, \\[2mm] \tilde{\mathbf{E}}(t=0) &= -\nabla \phi(t=0) \,. \end{align}\end{split}\]

Moreover, it is assumed that

\[\int_{\mathbb{R}^3} \mathbf{v} f_0 \, \text{d}^3 \mathbf{v} = 0 \,.\]

Propagators (called in sequence):

  1. PushEta

  2. PushVinEfield

  3. EfieldWeights

  4. PushVxB

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators(with_B0: bool = True, with_E0: bool = True)[source]#

Bases: object

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.LinearVlasovMaxwellOneSpecies(with_B0: bool = True, with_E0: bool = True)[source]#

Bases: LinearVlasovAmpereOneSpecies

Linearized Vlasov-Ampère equations for one species.

Normalization:

\[\begin{align} \hat v = c \,, \qquad \hat E = \hat B \hat v\,,\qquad \hat \phi = \hat E \hat x \,. \end{align}\]

Equations:

\[\begin{split}\begin{align} & \frac{\partial \tilde{\mathbf E}}{\partial t} = \nabla \times \tilde{\mathbf B} - \frac{\alpha^2}{\varepsilon} \int_{\mathbb R^3}\mathbf{v} \tilde f\, \textrm d^3 \mathbf v \,, \\[2mm] & \frac{\partial \tilde{\mathbf B}}{\partial t} = - \nabla \times \tilde{\mathbf E} \,, \\[2mm] & \frac{\partial \tilde f}{\partial t} + \mathbf{v} \cdot \, \nabla \tilde f + \frac{1}{\varepsilon} \left( \mathbf{E}_0 + \mathbf{v} \times \mathbf{B}_0 \right) \cdot \frac{\partial \tilde f}{\partial \mathbf{v}} = \frac{1}{v_{\text{th}}^2 \varepsilon} \, \tilde{\mathbf E} \cdot \mathbf{v} f_0 \,, \end{align}\end{split}\]

with the normalization parameter

\[\alpha = \frac{\hat \Omega_\textnormal{p}}{\hat \Omega_\textnormal{c}}\,,\qquad \varepsilon = \frac{1}{\hat \Omega_\textnormal{c} \hat t} \,,\qquad \textnormal{with} \qquad \hat\Omega_\textnormal{p} = \sqrt{\frac{\hat n (Ze)^2}{\epsilon_0 (A m_\textnormal{H})}} \,,\qquad \hat \Omega_{\textnormal{c}} = \frac{(Ze) \hat B}{(A m_\textnormal{H})}\,,\]

where \(Z=-1\) and \(A=1/1836\) for electrons. The background distribution function \(f_0\) is a uniform Maxwellian

\[f_0 = \frac{n_0(\mathbf{x})}{\left( \sqrt{2 \pi} v_{\text{th}} \right)^3} \exp \left( - \frac{|\mathbf{v}|^2}{2 v_{\text{th}}^2} \right) \,,\]

and the background electric field has to verify the following compatibility condition between with background density

\[\nabla_{\mathbf{x}} \ln (n_0(\mathbf{x})) = \frac{1}{v_{\text{th}}^2 \varepsilon} \mathbf{E}_0 \,.\]

At initial time the weak Poisson equation is solved once to weakly satisfy Gauss’ law,

\[\begin{split}\begin{align} \int_\Omega \nabla \psi^\top \cdot \nabla \phi \,\textrm d \mathbf x &= \frac{\alpha^2}{\varepsilon} \int_\Omega \int_{\mathbb{R}^3} \psi\, \tilde f \, \text{d}^3 \mathbf{v}\,\textrm d \mathbf x \qquad \forall \ \psi \in H^1\,, \\[2mm] \tilde{\mathbf{E}(t=0)} &= -\nabla \phi(t=0) \,. \end{align}\end{split}\]

Moreover, it is assumed that

\[\int_{\mathbb{R}^3} \mathbf{v} f_0 \, \text{d}^3 \mathbf{v} = 0 \,.\]

Propagators (called in sequence):

  1. PushEta

  2. PushVinEfield

  3. EfieldWeights

  4. PushVxB

  5. Maxwell

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators(with_B0: bool = True, with_E0: bool = True)[source]#

Bases: object

class struphy.models.Maxwell[source]#

Bases: StruphyModel

Maxwell’s equations in vacuum for electromagnetic field evolution.

This model simulates the propagation of electromagnetic waves in vacuum using Maxwell’s equations without sources. It uses a finite element exterior calculus (FEEC) formulation with the electric field in H(curl) and the magnetic field in H(div) spaces.

Governing Equations

Ampère’s law (no current):

\[\frac{\partial \mathbf E}{\partial t} - \nabla\times\mathbf B = 0\]

Faraday’s law:

\[\frac{\partial \mathbf B}{\partial t} + \nabla\times\mathbf E = 0\]

Normalization

Fields are normalized such that:

\[\hat E = c \hat B\]

where \(c\) is the speed of light.

Species

  • em_fields.e_field - Electric field (H(curl) space)

  • em_fields.b_field - Magnetic field (H(div) space)

Propagators

  1. Maxwell - Time integration scheme

Scalar Quantities

The following quantities are tracked during simulation:

  • Electric energy: \(E_E = \frac{1}{2} \int |\mathbf E|^2 \, dV\)

  • Magnetic energy: \(E_B = \frac{1}{2} \int |\mathbf B|^2 \, dV\)

  • Total energy: \(E_{total} = E_E + E_B\)

Model Properties

  • Model type: Toy

  • Velocity scale: Speed of light

  • Bulk species: None

See Also

Examples

Create and initialize a Maxwell model:

from struphy.models.maxwell import Maxwell

model = Maxwell()
# Fields are accessible via:
# model.em_fields.e_field
# model.em_fields.b_field
classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.Poisson[source]#

Bases: StruphyModel

Weak discretization of Poisson’s equation with diffusion matrix, stabilization and time-depedent right-hand side.

Normalization:

\[\hat D = \frac{\hat n}{\hat x^2}\,,\qquad \hat \rho = \hat n \,.\]

Equations: Find \(\phi \in H^1\) such that

\[- \nabla \cdot D_0(\mathbf x) \nabla \phi + n_0(\mathbf x) \phi = \rho(t, \mathbf x)\,,\]

where \(n_0, \rho(t):\Omega \to \mathbb R\) are real-valued functions, \(\rho(t)\) parametrized with time \(t\), and \(D_0:\Omega \to \mathbb R^{3\times 3}\) is a positive matrix. Boundary terms from integration by parts are assumed to vanish.

Propagators (called in sequence):

  1. TimeDependentSource

  2. ImplicitDiffusion

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class Propagators[source]#

Bases: object

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.PressureLessSPH[source]#

Bases: StruphyModel

Pressureless fluid discretized with smoothed particle hydrodynamics

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) = - \nabla \phi_0 \,,\end{split}\]

where \(\phi_0\) is a static external potential.

Propagators (called in sequence):

  1. PushEta

This is discretized by particles going in straight lines.

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class ColdFluid[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.RandomParticleDiffusion[source]#

Bases: StruphyModel

Diffusion equation discretized with a (random) particle method; the diffusion is computed through a Wiener process.

Normalization:

\[\hat D := \frac{\hat x^2}{\hat t } \,.\]

Equations: Find \(u:\mathbb R\times \Omega\to \mathbb R^+\) such that

\[\frac{\partial u}{\partial t} - D \, \Delta u = 0\,,\]

where \(D > 0\) is a positive diffusion coefficient.

Propagators (called in sequence):

  1. PushRandomDiffusion

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class Hydrogen[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.ShearAlfven[source]#

Bases: StruphyModel

ShearAlfven propagator from LinearMHD with zero-flow equilibrium (\(\mathbf U_0 = 0\)).

Normalization:

\[\hat U = \hat v_\textnormal{A} \,.\]

Equations:

\[ \begin{align}\begin{aligned}\rho_0&\frac{\partial \tilde{\mathbf{U}}}{\partial t} =(\nabla\times \tilde{\mathbf{B}})\times\mathbf{B}_0\,,\\&\frac{\partial \tilde{\mathbf{B}}}{\partial t} - \nabla\times(\tilde{\mathbf{U}} \times \mathbf{B}_0) = 0\,.\end{aligned}\end{align} \]

Propagators (called in sequence):

  1. ShearAlfven

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.TwoFluidQuasiNeutralToy[source]#

Bases: StruphyModel

Linearized, quasi-neutral two-fluid model with zero electron inertia.

Normalization:

\[\hat u = \hat v_\textnormal{th}\,,\qquad e\hat \phi = m \hat v_\textnormal{th}^2\,.\]

Equations:

\[\begin{split}\frac{\partial \mathbf u}{\partial t} &= - \nabla \phi + \frac{\mathbf u \times \mathbf B_0}{\varepsilon} + \nu \Delta \mathbf u + \mathbf f\,, \\[2mm] 0 &= \nabla \phi - \frac{\mathbf u_e \times \mathbf B_0}{\varepsilon} + \nu_e \Delta \mathbf u_e + \mathbf f_e \,, \\[3mm] \nabla & \cdot (\mathbf u - \mathbf u_e) = 0\,,\end{split}\]

where \(\mathbf B_0\) is a static magnetic field and \(\mathbf f, \mathbf f_e\) are given forcing terms, and with the normalization parameter

\[\varepsilon = \frac{1}{\hat \Omega_\textnormal{c} \hat t} \,,\qquad \textnormal{with} \,,\qquad \hat \Omega_{\textnormal{c}} = \frac{(Ze) \hat B}{(A m_\textnormal{H})}\,,\]

Propagators (called in sequence):

  1. TwoFluidQuasiNeutralFull

Model info:

References

[1] Juan Vicente Gutiérrez-Santacreu, Omar Maj, Marco Restelli: Finite element discretization of a Stokes-like model arising in plasma physics, Journal of Computational Physics 2018.

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMfields[source]#

Bases: FieldSpecies

class Ions[source]#

Bases: FluidSpecies

class Electrons[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.VariationalBarotropicFluid[source]#

Bases: StruphyModel

Barotropic fluid equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A} \qquad \hat{\mathcal U} = \frac{\hat \rho}{2} \,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) + \rho \nabla \frac{(\rho \mathcal U (\rho))}{\partial \rho} = 0 \,.\end{split}\]

where the internal energy per unit mass is \(\mathcal U(\rho) = \rho/2\).

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class Fluid[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.VariationalCompressibleFluid[source]#

Bases: StruphyModel

Fully compressible fluid equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,, \qquad \hat{\mathcal U} = K\,,\qquad \hat s = \hat \rho C_v \,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) + \rho \nabla \frac{(\rho \mathcal U (\rho, s))}{\partial \rho} + s \nabla \frac{(\rho \mathcal U (\rho, s))}{\partial s} = 0 \,, \\[4mm] &\partial_t s + \nabla \cdot ( s \mathbf u ) = 0 \,,\end{split}\]

where the internal energy per unit mass is \(\mathcal U(\rho) = \rho^{\gamma-1} \exp(s / \rho)\).

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalEntropyEvolve

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class Fluid[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.VariationalPressurelessFluid[source]#

Bases: StruphyModel

Pressure-less fluid equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A} \,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) = 0 \,.\end{split}\]

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class Fluid[source]#

Bases: FluidSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveDeltafMHD(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

\(\delta f\) visco-resistive MHD equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,.\]

Equations:

\[\begin{split}&\partial_t \tilde{\rho} + \nabla \cdot ( (\tilde{\rho}+\rho_0) \tilde{\mathbf u} ) = 0 \,, \\[4mm] &\partial_t ((\tilde{\rho}+\rho_0) \tilde{\mathbf u}) + \nabla \cdot ((\tilde{\rho}+\rho_0) \tilde{\mathbf u} \otimes \tilde{\mathbf u}) + \frac{1}{\gamma -1} \nabla \tilde{p} + \mathbf B_0 \times \nabla \times \tilde{\mathbf B} + \tilde{\mathbf B} \times \nabla \times \mathbf B_0 + \tilde{\mathbf B} \times \nabla \times \tilde{\mathbf B} - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \tilde{\mathbf u} \right) = 0 \,, \\[4mm] &\partial_t \tilde{p} + \tilde{\mathbf u} \cdot \nabla (\tilde{p} + p_0) + \gamma (\tilde{p} + p_0) \nabla \cdot \tilde{\mathbf u} = \frac{1}{(\gamma -1)}\left((\mu+\mu_a(\mathbf x)) |\nabla \tilde{\mathbf u}|^2 + (\eta + \eta_a(\mathbf x)) |\nabla \times \tilde{\mathbf B}|^2\right) \,, \\[4mm] &\partial_t \tilde{\mathbf B} + \nabla \times ( (\tilde{\mathbf B} + \mathbf B_0) \times \tilde{\mathbf u} ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \tilde{\mathbf B} = 0 \,,\end{split}\]

and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalPBEvolve

  4. VariationalViscosity

  5. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Diagnostics[source]#

Bases: DiagnosticSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveDeltafMHD_with_q(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

Linear visco-resistive MHD equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,.\]

Equations:

\[\begin{split}&\partial_t \tilde{\rho} + \nabla \cdot ( \rho_0 \tilde{\mathbf u} ) = 0 \,, \\[4mm] &\partial_t (\rho_0 \tilde{\mathbf u}) + \frac{2 q_0}{\gamma -1} \nabla \tilde{q} + \frac{2 \tilde{q}}{\gamma -1} \nabla q_0 + \frac{2 \tilde{q}}{\gamma -1} \nabla \tilde{q} + \mathbf B_0 \times \nabla \times \tilde{\mathbf B} + \tilde{\mathbf B} \times \nabla \times \mathbf B_0 - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \tilde{\mathbf u} \right) = 0 \,, \\[4mm] &\partial_t \tilde{q} + \cdot(\nabla (q_0 + \tilde{q}) \mathbf u) + (\gamma/2 -1) (q_0 + \tilde{q}) \nabla \cdot u = 0 \,, \\[4mm] &\partial_t \tilde{\mathbf B} + \nabla \times ( \mathbf (B_0 + \tilde{\mathbf B}) \times \tilde{\mathbf u} ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \tilde{\mathbf B} = 0 \,,\end{split}\]

and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalQBEvolve

  4. VariationalViscosity

  5. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Diagnostics[source]#

Bases: DiagnosticSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveLinearMHD(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

Linear visco-resistive MHD equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,.\]

Equations:

\[\begin{split}&\partial_t \tilde{\rho} + \nabla \cdot ( \rho_0 \tilde{\mathbf u} ) = 0 \,, \\[4mm] &\partial_t (\rho_0 \tilde{\mathbf u}) + \frac{1}{\gamma -1} \nabla \tilde{p} + \mathbf B_0 \times \nabla \times \tilde{\mathbf B} + \tilde{\mathbf B} \times \nabla \times \mathbf B_0 - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \tilde{\mathbf u} \right) = 0 \,, \\[4mm] &\partial_t \tilde{p} + \tilde{\mathbf u} \cdot \nabla p_0 + \gamma p_0 \nabla \cdot \tilde{\mathbf u} = \frac{1}{(\gamma -1)}\left((\mu+\mu_a(\mathbf x)) |\nabla \tilde{\mathbf u}|^2 + (\eta + \eta_a(\mathbf x)) |\nabla \times \tilde{\mathbf B}|^2\right) \,, \\[4mm] &\partial_t \tilde{\mathbf B} + \nabla \times ( \mathbf B_0 \times \tilde{\mathbf u} ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \tilde{\mathbf B} = 0 \,,\end{split}\]

and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalPBEvolve

  3. VariationalViscosity

  4. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Diagnostics[source]#

Bases: DiagnosticSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveLinearMHD_with_q(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

Linear visco-resistive MHD equations, with the q variable (square root of the pressure), discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,.\]

Equations:

\[\begin{split}&\partial_t \tilde{\rho} + \nabla \cdot ( \rho_0 \tilde{\mathbf u} ) = 0 \,, \\[4mm] &\partial_t (\rho_0 \tilde{\mathbf u}) + \frac{2 q_0}{\gamma -1} \nabla \tilde{q} + \frac{2 \tilde{q}}{\gamma -1} \nabla q_0 + \mathbf B_0 \times \nabla \times \tilde{\mathbf B} + \tilde{\mathbf B} \times \nabla \times \mathbf B_0 - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \tilde{\mathbf u} \right) = 0 \,, \\[4mm] &\partial_t \tilde{q} + \cdot(\nabla q_0 \mathbf u) + (\gamma/2 -1) q_0 \nabla \cdot u = 0 \,, \\[4mm] &\partial_t \tilde{\mathbf B} + \nabla \times ( \mathbf B_0 \times \tilde{\mathbf u} ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \tilde{\mathbf B} = 0 \,,\end{split}\]

and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalQBEvolve

  3. VariationalViscosity

  4. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Diagnostics[source]#

Bases: DiagnosticSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveMHD(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

Full (non-linear) visco-resistive MHD equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,, \qquad \hat{\mathcal U} = \frac{\hat{\mathbf B}^2}{\hat \rho \mu_0 (\gamma-1)} \,,\qquad \hat s = \hat \rho\ \textrm{ln}\left(\frac{\hat{\mathbf B}^2}{\mu_0 (\gamma -1) \hat{\rho}}\right) \,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) + \rho \nabla \frac{(\rho \mathcal U (\rho, s))}{\partial \rho} + s \nabla \frac{(\rho \mathcal U (\rho, s))}{\partial s} + \mathbf B \times \nabla \times \mathbf B - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \mathbf u \right) = 0 \,, \\[4mm] &\partial_t s + \nabla \cdot ( s \mathbf u ) = \frac{1}{T}\left((\mu+\mu_a(\mathbf x)) |\nabla \mathbf u|^2 + (\eta + \eta_a(\mathbf x)) |\nabla \times \mathbf B|^2\right) \,, \\[4mm] &\partial_t \mathbf B + \nabla \times ( \mathbf B \times \mathbf u ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \mathbf B = 0 \,,\end{split}\]

where the internal energy per unit mass is \(\mathcal U(\rho) = \rho^{\gamma-1} \exp(s / \rho)\), and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalEntropyEvolve

  4. VariationalMagFieldEvolve

  5. VariationalViscosity

  6. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveMHD_with_p(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

Full (non-linear) visco-resistive MHD equations, with the pressure variable discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) + \frac{1}{\gamma -1} \nabla p + \mathbf B \times \nabla \times \mathbf B - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \mathbf u \right) = 0 \,, \\[4mm] &\partial_t p + u \cdot \nabla p + \gamma p \nabla \cdot u = \frac{1}{(\gamma -1)}\left((\mu+\mu_a(\mathbf x)) |\nabla \mathbf u|^2 + (\eta + \eta_a(\mathbf x)) |\nabla \times \mathbf B|^2\right) \,, \\[4mm] &\partial_t \mathbf B + \nabla \times ( \mathbf B \times \mathbf u ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \mathbf B = 0 \,,\end{split}\]

and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalPBEvolve

  4. VariationalViscosity

  5. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Diagnostics[source]#

Bases: DiagnosticSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscoResistiveMHD_with_q(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: StruphyModel

Full (non-linear) visco-resistive MHD equations, with the q variable (square root of the pressure) discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) + \frac{2q}{\gamma -1} \nabla q + \mathbf B \times \nabla \times \mathbf B - \nabla \cdot \left((\mu+\mu_a(\mathbf x)) \nabla \mathbf u \right) = 0 \,, \\[4mm] &\partial_t q + \cdot(\nabla q \mathbf u) + (\gamma/2 -1) q \nabla \cdot u = \frac{2 q}{(\gamma -1)}\left((\mu+\mu_a(\mathbf x)) |\nabla \mathbf u|^2 + (\eta + \eta_a(\mathbf x)) |\nabla \times \mathbf B|^2\right) \,, \\[4mm] &\partial_t \mathbf B + \nabla \times ( \mathbf B \times \mathbf u ) + \nabla \times (\eta + \eta_a(\mathbf x)) \nabla \times \mathbf B = 0 \,,\end{split}\]

and \(\mu_a(\mathbf x)\) and \(\eta_a(\mathbf x)\) are artificial viscosity and resistivity coefficients.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalQBEvolve

  4. VariationalViscosity

  5. VariationalResistivity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class MHD[source]#

Bases: FluidSpecies

class Diagnostics[source]#

Bases: DiagnosticSpecies

class Propagators(with_viscosity: bool = True, with_resistivity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscousEulerSPH(with_B0: bool = True, with_p: bool = True, with_viscosity: bool = True)[source]#

Bases: StruphyModel

Euler equations with viscosity discretized with smoothed particle hydrodynamics (SPH).

Normalization:

\[\hat u = \hat v_\textnormal{th} \,.\]

Equations:

\[\begin{split}\begin{align} \partial_t \rho + \nabla \cdot (\rho \mathbf u) &= 0\,, \\[2mm] \rho(\partial_t \mathbf u + \mathbf u \cdot \nabla \mathbf u) &= - \nabla \left(\rho^2 \frac{\partial \mathcal U(\rho, S)}{\partial \rho} \right) - \nabla \cdot \boldsymbol{\pi}\,, \\[2mm] \partial_t S + \mathbf u \cdot \nabla S &= 0\,, \end{align}\end{split}\]

where \(S\) denotes the entropy per unit mass and \(\boldsymbol{\pi}\) is the viscous stress tensor.

The viscous stress tensor for a Newtonian fluid is given by:

\[\boldsymbol{\sigma} = -\mu \left( \nabla \mathbf u + (\nabla \mathbf u)^T - \frac{2}{3}(\nabla \cdot \mathbf u)\mathbf{I} \right)\,,\]

where \(\mu\) is the dynamic (shear) viscosity and \(\mathbf{I}\) is the identity tensor.

The internal energy per unit mass can be defined in two ways:

\[ \begin{align}\begin{aligned}\mathrm{isothermal:}\qquad &\mathcal U(\rho, S) = \kappa(S) \log \rho\,.\\\mathrm{polytropic:}\qquad &\mathcal U(\rho, S) = \kappa(S) \frac{\rho^{\gamma - 1}}{\gamma - 1}\,.\end{aligned}\end{align} \]

Propagators (called in sequence):

  1. PushEta

  2. PushVxB

  3. PushVinSPHpressure

  4. PushVinViscousPotential

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EulerFluid[source]#

Bases: ParticleSpecies

class Propagators(with_B0: bool = True, with_p: bool = True, with_viscosity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.ViscousFluid(with_viscosity: bool = True)[source]#

Bases: StruphyModel

Full (non-linear) viscous Navier-Stokes equations discretized with a variational method.

Normalization:

\[\hat u = \hat v_\textnormal{A}\,, \qquad \hat{\mathcal U} = \frac{\hat{\mathbf B}^2}{\hat \rho \mu_0 (\gamma-1)} \,,\qquad \hat s = \hat \rho\ \textrm{ln}\left(\frac{\hat{\mathbf B}^2}{\mu_0 (\gamma -1) \hat{\rho}}\right) \,.\]

Equations:

\[\begin{split}&\partial_t \rho + \nabla \cdot ( \rho \mathbf u ) = 0 \,, \\[4mm] &\partial_t (\rho \mathbf u) + \nabla \cdot (\rho \mathbf u \otimes \mathbf u) + \rho \nabla \frac{(\rho \mathcal U (\rho, s))}{\partial \rho} + s \nabla \frac{(\rho \mathcal U (\rho, s))}{\partial s} - \nabla \cdot \left((\mu +\mu_a(\mathbf x)) \nabla \mathbf u\right) = 0 \,, \\[4mm] &\partial_t s + \nabla \cdot ( s \mathbf u ) = \frac{1}{T}\left((\mu+\mu_a(\mathbf x)) |\nabla \mathbf u|^2 \right) \,,\end{split}\]

where the internal energy per unit mass is \(\mathcal U(\rho) = \rho^{\gamma-1} \exp(s / \rho)\). and \(\mu_a(\mathbf x)\) is an artificial viscosity coefficient.

Propagators (called in sequence):

  1. VariationalDensityEvolve

  2. VariationalMomentumAdvection

  3. VariationalEntropyEvolve

  4. VariationalViscosity

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class Fluid[source]#

Bases: FluidSpecies

class Propagators(with_viscosity: bool = True)[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.Vlasov[source]#

Bases: StruphyModel

Vlasov equation in static background magnetic field.

Normalization:

\[\hat v = \hat \Omega_\textnormal{c} \hat x\,.\]

Equations:

\[\frac{\partial f}{\partial t} + \mathbf{v} \cdot \nabla f + \left(\mathbf{v}\times\mathbf{B}_0 \right) \cdot \frac{\partial f}{\partial \mathbf{v}} = 0\,.\]

Propagators (called in sequence):

  1. PushVxB

  2. PushEta

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

allocate_helpers(verbose: bool = False)[source]#

Allocate helper arrays and perform initial solves if needed.

class struphy.models.VlasovAmpereOneSpecies(with_B0: bool = True)[source]#

Bases: StruphyModel

Vlasov-Ampère system for a single kinetic species in an electric field.

This model couples the Vlasov equation for the particle distribution function with Ampère’s law for the electric field evolution. It includes the effect of a static background magnetic field \(\mathbf{B}_0\) and solves the initial Poisson equation to satisfy Gauss’s law at \(t=0\). The model uses a particle-in-cell (PIC) method with finite element exterior calculus (FEEC) for the electromagnetic fields.

Governing Equations

Vlasov equation:

\[\frac{\partial f}{\partial t} + \mathbf{v} \cdot \nabla f + \frac{1}{\varepsilon} \left( \mathbf{E} + \mathbf{v} \times \mathbf{B}_0 \right) \cdot \frac{\partial f}{\partial \mathbf{v}} = 0\]

Ampère’s law:

\[-\frac{\partial \mathbf{E}}{\partial t} = \frac{\alpha^2}{\varepsilon} \int_{\mathbb{R}^3} \mathbf{v} f \, \mathrm{d}^3 \mathbf{v}\]

Initial Poisson equation: At \(t=0\), solve weakly for the electric potential \(\phi\):

\[\begin{split}\int_{\Omega} \nabla \psi^\top \cdot \nabla \phi \,\mathrm{d} \mathbf{x} &= \frac{\alpha^2}{\varepsilon} \int_{\Omega} \int_{\mathbb{R}^3} \psi\, (f - f_0) \, \mathrm{d}^3 \mathbf{v}\,\mathrm{d} \mathbf{x} \qquad \forall \ \psi \in H^1 \\ \mathbf{E}(t=0) &= -\nabla \phi(t=0)\end{split}\]

Normalization

The model uses the following normalizations:

\[\hat{v} = c, \qquad \hat{E} = \hat{B} \hat{v}, \qquad \hat{\phi} = \hat{E} \hat{x}\]

Dimensionless parameters:

\[\alpha = \frac{\hat{\omega}_\mathrm{p}}{\hat{\omega}_\mathrm{c}}, \qquad \varepsilon = \frac{1}{\hat{\omega}_\mathrm{c} \hat{t}}\]

where

\[\hat{\omega}_\mathrm{p} = \sqrt{\frac{\hat{n} (Ze)^2}{\epsilon_0 (A m_\mathrm{H})}}, \qquad \hat{\omega}_\mathrm{c} = \frac{(Ze) \hat{B}}{(A m_\mathrm{H})}\]

For electrons: \(Z = -1\), \(A = 1/1836\).

Species

  • em_fields.e_field - Electric field (H(curl) space)

  • em_fields.phi - Electric potential (H¹ space)

  • kinetic_ions.var - Particle distribution function (6D phase space)

Propagators

Time integration is performed by the following propagators (in sequence):

  1. PushEta - Push particles in configuration space

  2. PushVxB - Push particles in velocity space (\(\mathbf{v} \times \mathbf{B}_0\) term)

  3. VlasovAmpere - Couple Vlasov and Ampère equations

Initial Condition

The initial electric field is computed by solving the weak Poisson equation to ensure the charge density from the particle distribution satisfies Gauss’s law. The background magnetic field \(\mathbf{B}_0\) must satisfy:

\[\nabla \times \mathbf{B}_0 = \frac{\alpha^2}{\varepsilon} \int_{\mathbb{R}^3} \mathbf{v} f_0 \, \mathrm{d}^3 \mathbf{v}\]

Control Variate Method

An optional control variate technique can be enabled to reduce numerical noise in Ampère’s law by subtracting the equilibrium distribution \(f_0\). When enabled, the weak form becomes:

Find \((\mathbf{E}, f) \in H(\mathrm{curl}) \times C^\infty\) such that

\[ \begin{align}\begin{aligned}&-\int_{\Omega} \mathbf{F} \cdot \frac{\partial \mathbf{E}}{\partial t}\,\mathrm{d} \mathbf{x} = \frac{\alpha^2}{\varepsilon} \int_{\Omega} \int_{\mathbb{R}^3} \mathbf{F} \cdot \mathbf{v} (f - f_0) \, \mathrm{d}^3 \mathbf{v}\,\mathrm{d} \mathbf{x} \qquad \forall \ \mathbf{F} \in H(\mathrm{curl})\\&\frac{\partial f}{\partial t} + \mathbf{v} \cdot \nabla f + \frac{1}{\varepsilon} \left( \mathbf{E} + \mathbf{v} \times \mathbf{B}_0 \right) \cdot \frac{\partial f}{\partial \mathbf{v}} = 0\end{aligned}\end{align} \]

Scalar Quantities

The following energies are tracked during simulation:

  • Electric field energy: \(E_E = \frac{1}{2} \int |\mathbf{E}|^2 \, \mathrm{d}V\)

  • Kinetic energy: \(E_f = \frac{\alpha^2}{2N} \sum_p w_p |\mathbf{v}_p|^2\)

  • Total energy: \(E_\mathrm{tot} = E_E + E_f\)

Model Properties

  • Model type: Kinetic

  • Velocity scale: Speed of light

  • Bulk species: kinetic_ions

Parameters

  • with_B0 (bool) - Include background magnetic field effects (default: True)

See Also

Examples

Create and initialize a Vlasov-Ampère model:

from struphy.models.vlasov_ampere_one_species import VlasovAmpereOneSpecies

# Create model with background magnetic field
model = VlasovAmpereOneSpecies(with_B0=True)

# Access fields and particles
# model.em_fields.e_field  - Electric field
# model.kinetic_ions.var   - Particle distribution

# After initialization, allocate_helpers() solves the initial Poisson equation
classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators(with_B0: bool = True)[source]#

Bases: object

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str

class struphy.models.VlasovMaxwellOneSpecies[source]#

Bases: StruphyModel

Vlasov-Maxwell equations for one species.

Normalization:

\[\begin{align} \hat v = c \,, \qquad \hat E = \hat B \hat v\,,\qquad \hat \phi = \hat E \hat x \,. \end{align}\]

Equations:

\[\begin{split}&\frac{\partial f}{\partial t} + \mathbf{v} \cdot \, \nabla f + \frac{1}{\varepsilon} \left( \mathbf{E} + \mathbf{v} \times \left( \mathbf{B} + \mathbf{B}_0 \right) \right) \cdot \frac{\partial f}{\partial \mathbf{v}} = 0 \,, \\[2mm] -&\frac{\partial \mathbf{E}}{\partial t} + \nabla \times \mathbf B = \frac{\alpha^2}{\varepsilon} \int_{\mathbb{R}^3} \mathbf{v} f \, \text{d}^3 \mathbf{v}\,, \\[2mm] &\frac{\partial \mathbf{B}}{\partial t} + \nabla \times \mathbf{E} = 0 \,,\end{split}\]

with the normalization parameters

\[\alpha = \frac{\hat \Omega_\textnormal{p}}{\hat \Omega_\textnormal{c}}\,,\qquad \varepsilon = \frac{1}{\hat \Omega_\textnormal{c} \hat t} \,,\qquad \textnormal{with} \qquad \hat\Omega_\textnormal{p} = \sqrt{\frac{\hat n (Ze)^2}{\epsilon_0 (A m_\textnormal{H})}} \,,\qquad \hat \Omega_{\textnormal{c}} = \frac{(Ze) \hat B}{(A m_\textnormal{H})}\,,\]

where \(Z=-1\) and \(A=1/1836\) for electrons. At initial time the weak Poisson equation is solved once to weakly satisfy Gauss’ law,

\[\begin{split}\begin{align} \int_\Omega \nabla \psi^\top \cdot \nabla \phi \,\textrm d \mathbf x &= \frac{\alpha^2}{\varepsilon} \int_\Omega \int_{\mathbb{R}^3} \psi\, (f - f_0) \, \text{d}^3 \mathbf{v}\,\textrm d \mathbf x \qquad \forall \ \psi \in H^1\,, \\[2mm] \mathbf{E}(t=0) &= -\nabla \phi(t=0)\,. \end{align}\end{split}\]

Moreover, it is assumed that

\[\nabla \times \mathbf B_0 = \frac{\alpha^2}{\varepsilon} \int_{\mathbb{R}^3} \mathbf{v} f_0 \, \text{d}^3 \mathbf{v}\,,\]

where \(\mathbf B_0\) is the static equilibirum magnetic field.

Notes

  • The Control variate method for Ampère’s law is optional; in case it is enabled via the parameter file, the following system is solved:

Find \((\mathbf E, \tilde{\mathbf B}, f) \in H(\textnormal{curl}) \times H(\textnormal{div}) \times C^\infty\) such that

\[\begin{split}\begin{align} -\int_\Omega \mathbf F\, \cdot \, &\frac{\partial \mathbf{E}}{\partial t}\,\textrm d \mathbf x + \int_\Omega \nabla \times \mathbf{F} \cdot \tilde{\mathbf B}\,\textrm d \mathbf x = \frac{\alpha^2}{\varepsilon} \int_\Omega \int_{\mathbb{R}^3} \mathbf F \cdot \mathbf{v} (f - f_0) \, \text{d}^3 \mathbf{v}\,\textrm d \mathbf x \qquad \forall \ \mathbf F \in H(\textnormal{curl}) \,, \\[2mm] &\frac{\partial \tilde{\mathbf B}}{\partial t} + \nabla \times \mathbf{E} = 0 \,, \\[2mm] &\frac{\partial f}{\partial t} + \mathbf{v} \cdot \, \nabla f + \frac{1}{\varepsilon}\Big[ \mathbf{E} + \mathbf{v} \times (\mathbf{B}_0 + \tilde{\mathbf B}) \Big] \cdot \frac{\partial f}{\partial \mathbf{v}} = 0 \,, \end{align}\end{split}\]

where \(\tilde{\mathbf B} = \mathbf B - \mathbf B_0\) denotes the magnetic perturbation.

Propagators (called in sequence):

  1. Maxwell

  2. PushEta

  3. PushVxB

  4. VlasovAmpere

Model info:

classmethod model_type() Literal['Toy', 'Kinetic', 'Fluid', 'Hybrid'][source]#

Model type (Fluid, Kinetic, Hybrid, or Toy)

class EMFields[source]#

Bases: FieldSpecies

class KineticIons[source]#

Bases: ParticleSpecies

class Propagators[source]#

Bases: object

generate_default_parameter_file(path=None, prompt=True)[source]#

Generate a parameter file with default options for each species, and save it to the current input path.

The default name is params_<model_name>.yml.

Parameters:
  • path (str) – Alternative path to getcwd()/params_MODEL.py.

  • prompt (bool) – Whether to prompt for overwriting the specified .yml file.

Returns:

params_path – The path of the parameter file.

Return type:

str