Source code for struphy.models.vlasov
import copy
from feectools.ddm.mpi import mpi as MPI
from struphy import BaseUnits
from struphy.io.options import LiteralOptions
from struphy.models.base import StruphyModel
from struphy.models.scalars import KineticEnergyPIC, Scalars
from struphy.models.species import (
ParticleSpecies,
)
from struphy.models.variables import PICVariable
from struphy.propagators.push_eta import PushEta
from struphy.propagators.push_vxb import PushVxB
rank = MPI.COMM_WORLD.Get_rank()
[docs]
class Vlasov(StruphyModel):
"""Vlasov equation for a single species in a static background magnetic field.
Parameters
----------
base_units: BaseUnits
Base units for normalization (default: BaseUnits())
charge_number: int
Charge number (in units of the positive elementary charge) of the species (default: 1)
mass_number: float
Mass number (in units of Proton mass) of the species (default: 1.0)
"""
@classmethod
def model_type(cls) -> LiteralOptions.ModelTypes:
return "Kinetic"
## species
class KineticIons(ParticleSpecies):
def __init__(
self,
charge_number: int = 1,
mass_number: float = 1.0,
):
self.var = PICVariable(space="Particles6D")
self.init_variables(
charge_number=charge_number,
mass_number=mass_number,
)
## propagators
class Propagators:
def __init__(self):
self.push_vxb = PushVxB()
self.push_eta = PushEta()
## abstract methods
def __init__(
self,
base_units: BaseUnits = BaseUnits(),
charge_number: int = 1,
mass_number: float = 1.0,
):
# 0. store input parameters
self.params = copy.deepcopy(locals())
# 1. instantiate all species
self.kinetic_ions = self.KineticIons(
charge_number,
mass_number,
)
# 2. derive units (must be done after instantiating species to access charge and mass numbers)
self.setup_equation_params(base_units=base_units)
# 3. instantiate all propagators
self.propagators = self.Propagators()
# 4. assign variables to propagators
self.propagators.push_vxb.variables.ions = self.kinetic_ions.var
self.propagators.push_eta.variables.var = self.kinetic_ions.var
# 5. define scalars to be tracked during simulation
kinetic_energy = KineticEnergyPIC(self.kinetic_ions.var)
self.scalars = Scalars(kinetic_energy=kinetic_energy)
@property
def bulk_species(self):
return self.kinetic_ions
@property
def velocity_scale(self):
return "cyclotron"
def allocate_helpers(self):
pass
[docs]
@classmethod
def doc_pde(cls):
r"""**PDEs solved by model:**
Vlasov equation:
.. math::
\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
"""
[docs]
@classmethod
def doc_normalization(cls):
r"""The characteristic speed is the cyclotron scale
.. math::
\hat v = \hat\Omega_c \hat x.
"""
[docs]
@classmethod
def doc_scalar_quantities(cls):
r"""**The following scalars are tracked during simulation:**
- Particle kinetic energy: ``kinetic_energy``"""
[docs]
@classmethod
def doc_discretization(cls):
"""Time integration is performed by the following propagators (in sequence):
1. :class:`~struphy.propagators.push_vxb.PushVxB`
2. :class:`~struphy.propagators.push_eta.PushEta`
"""
doc = rf"""**1. push_vxb.PushVxB:**
{PushVxB.__doc__}
**2. push_eta.PushEta:**
{PushEta.__doc__}
"""
return doc
[docs]
@classmethod
def doc_long_description(cls):
r"""Vlasov is the simplest kinetic test-particle model in the 6D hierarchy.
It evolves particles in a static magnetic background without electric or
magnetic self-consistency."""
[docs]
@classmethod
def doc_examples(cls):
r"""Create and initialize a Vlasov test-particle model:
.. code-block:: python
from struphy.models import Vlasov
model = Vlasov()
model.kinetic_ions.var
"""
[docs]
@classmethod
def doc_use_cases(cls):
r"""This model is appropriate for:
- test-particle motion in prescribed magnetic fields
- verification of the Boris-like VxB and PushEta splitting
- reduced kinetic transport studies without field feedback"""
[docs]
@classmethod
def doc_cannot_be_used_for(cls):
r"""This model is not suitable for:
- self-consistent electrostatic or electromagnetic coupling
- collisional kinetic dynamics
- guiding-center reduction studies
- fluid or MHD-scale closures"""