Source code for struphy.models.maxwell

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 BilinearEnergyFEEC, Scalars
from struphy.models.species import (
    FieldSpecies,
)
from struphy.models.variables import FEECVariable
from struphy.propagators.maxwell_weak_ampere import MaxwellWeakAmpere

rank = MPI.COMM_WORLD.Get_rank()


[docs] class Maxwell(StruphyModel): """Maxwell's equations in vacuum for electromagnetic field evolution. Parameters ---------- base_units: BaseUnits Base units for normalization (default: BaseUnits()) """ ## species class EMFields(FieldSpecies): def __init__(self): self.e_field = FEECVariable(space="Hcurl") self.b_field = FEECVariable(space="Hdiv") self.init_variables() ## propagators class Propagators: def __init__(self): self.maxwell = MaxwellWeakAmpere() ## abstract methods def __init__(self, base_units: BaseUnits = BaseUnits()): # 1. instantiate all species self.em_fields = self.EMFields() # 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.maxwell.variables.e = self.em_fields.e_field self.propagators.maxwell.variables.b = self.em_fields.b_field # 5. define scalars to be tracked during simulation electric_energy = BilinearEnergyFEEC(self.em_fields.e_field) magnetic_energy = BilinearEnergyFEEC(self.em_fields.b_field) total_energy = electric_energy + magnetic_energy self.scalars = Scalars( electric_energy=electric_energy, magnetic_energy=magnetic_energy, total_energy=total_energy, ) @property def bulk_species(self): return None @property def velocity_scale(self): return "light" def allocate_helpers(self, verbose: bool = False): pass ## abstract methods for documentation @classmethod def model_type(cls) -> LiteralOptions.ModelTypes: return "Toy"
[docs] @classmethod def doc_pde(cls): r"""**PDEs solved by model:** Ampère's law (no current): .. math:: \frac{\partial \mathbf{E}}{\partial t} - \nabla \times \mathbf{B} = 0 Faraday's law: .. math:: \frac{\partial \mathbf{B}}{\partial t} + \nabla \times \mathbf{E} = 0 """
[docs] @classmethod def doc_normalization(cls): r"""Velocity and fields are normalized as: .. math:: \hat v = c\,,\qquad \hat E = c \hat B where :math:`c` is the speed of light."""
[docs] @classmethod def doc_scalar_quantities(cls): r"""**The following scalars are tracked during simulation:** - Electric energy: :math:`E_E = \frac{1}{2} \int |\mathbf E|^2 \, dV` - Magnetic energy: :math:`E_B = \frac{1}{2} \int |\mathbf B|^2 \, dV` - Total energy: :math:`E_{total} = E_E + E_B`"""
[docs] @classmethod def doc_discretization(cls): """Propagators: 1. :class:`~struphy.propagators.maxwell.Maxwell` """ doc = rf"""**1. propagators.maxwell.Maxwell:** {MaxwellWeakAmpere.__doc__} """ return doc
[docs] @classmethod def doc_long_description(cls): r"""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."""
[docs] @classmethod def doc_examples(cls): r"""Create and initialize a Maxwell model: .. code-block:: python from struphy.models import Maxwell model = Maxwell() # Fields are accessible via: model.em_fields.e_field model.em_fields.b_field """
[docs] @classmethod def doc_use_cases(cls): """Propagation of electromagnetic waves in vacuum."""
[docs] @classmethod def doc_cannot_be_used_for(cls): """Plasma dynamics, plasma-field interactions, or any scenario involving charged particles. This model does not include any particle species or coupling to matter."""