mhd_sandbox
Type part of a name or a dotted path
A sandbox for learning ideal MHD: finite-volume solvers on a periodic 2D grid.
Classes
| Name | Description |
|---|---|
Grid | A box lower_bound to upper_bound split into num_gridpoints cells. |
IdealMHD2DSolver | Explicit finite-volume solver for the two-dimensional ideal MHD equations. |
MHDResult | Result returned by an MHD time integration. |
MultiFluidIdealMHD2DSolver | Coordinate multiple ideal-MHD fluid solvers on one grid. |
MultiFluidMHDResult | Result returned by a multi-fluid MHD integration. |
Modules
Gridclassdataclass#
mhd_sandbox.gridView sourceclass Grid(lower_bound: tuple[float, ...], upper_bound: tuple[float, ...], num_gridpoints: tuple[int, ...])A box lower_bound to upper_bound split into num_gridpoints cells.
The values live at the cell centres; every axis is periodic.
lower_boundattributeinstance attribute#
lower_bound: tuple[float, ...]num_gridpointsattributeinstance attribute#
num_gridpoints: tuple[int, ...]upper_boundattributeinstance attribute#
upper_bound: tuple[float, ...]IdealMHD2DSolverclass#
mhd_sandbox.solverView sourceclass IdealMHD2DSolver(grid: Grid, gamma: float = 5.0 / 3.0, cfl: float = 0.35, density_floor: float = 1e-08, pressure_floor: float = 1e-08, project_divergence: bool = True)Explicit finite-volume solver for the two-dimensional ideal MHD equations.
The conservative state is stored as
[rho, rho*vx, rho*vy, rho*vz, E, Bx, By, Bz] on a periodic,
cell-centered grid. Fluxes are computed with the local Lax-Friedrichs
(Rusanov) numerical flux and the time step is forward Euler, both first
order, with an optional periodic magnetic-field projection for the
div(B)=0 constraint: the simplest scheme that works, as a starting point
for higher-order reconstructions, better Riemann solvers and other
div(B) treatments.
B_Xattributeclass attributeinstance attribute#
B_X = 5B_Yattributeclass attributeinstance attribute#
B_Y = 6B_Zattributeclass attributeinstance attribute#
B_Z = 7ENERGYattributeclass attributeinstance attribute#
ENERGY = 4MOM_Xattributeclass attributeinstance attribute#
MOM_X = 1MOM_Yattributeclass attributeinstance attribute#
MOM_Y = 2MOM_Zattributeclass attributeinstance attribute#
MOM_Z = 3NUM_COMPONENTSattributeclass attributeinstance attribute#
NUM_COMPONENTS = 8RHOattributeclass attributeinstance attribute#
RHO = 0cflproperty#
cfl: floatReturn the CFL number.
density_floorproperty#
density_floor: floatReturn the density floor.
dt_historyproperty#
dt_history: list[float]Return the timestep history.
dxproperty#
dx: floatReturn the cell width along x.
dyproperty#
dy: floatReturn the cell width along y.
gammaproperty#
gamma: floatReturn the adiabatic index.
gridproperty#
grid: GridReturn the grid.
pressure_floorproperty#
pressure_floor: floatReturn the pressure floor.
project_divergenceproperty#
project_divergence: boolReturn whether periodic magnetic divergence projection is enabled.
stateproperty#
state: np.ndarrayReturn the conservative state array.
stepsproperty#
steps: intReturn the number of completed timesteps.
timeproperty#
time: floatReturn the current simulation time.
compute_dtmethod#
def compute_dt() -> floatReturn a CFL-limited timestep for the current state.
divergence_bmethod#
def divergence_b() -> np.ndarrayReturn a centered finite-difference estimate of div(B).
max_abs_divergence_bmethod#
def max_abs_divergence_b() -> floatReturn the maximum absolute centered div(B) diagnostic.
orszag_tang_initial_statemethodclassmethod#
def orszag_tang_initial_state(grid: Grid, gamma: float = 5.0 / 3.0) -> np.ndarrayBuild the standard Orszag-Tang vortex initial condition.
The domain is interpreted as periodic and cell-centered. The returned state uses normalized MHD units with magnetic permeability set to one.
primitive_to_conservativemethodclassmethod#
def primitive_to_conservative(density: np.ndarray, velocity: np.ndarray, magnetic_field: np.ndarray, pressure: np.ndarray, gamma: float = 5.0 / 3.0) -> np.ndarrayConvert primitive variables to conservative MHD state variables.
primitive_variablesmethod#
def primitive_variables(state: np.ndarray | None = None) -> dict[str, np.ndarray]Return primitive variables for a conservative state.
primitive_variables_from_statemethodclassmethod#
def primitive_variables_from_state(state: np.ndarray, gamma: float = 5.0 / 3.0, density_floor: float = 1e-08, pressure_floor: float = 1e-08) -> dict[str, np.ndarray]Return primitive variables from a conservative MHD state.
project_magnetic_fieldmethod#
def project_magnetic_field() -> NoneProject the in-plane magnetic field onto a periodic div(B)=0 subspace.
The projection uses the Fourier symbol of the centered derivative used
by divergence_b. Total energy is then rebuilt so density, velocity,
and gas pressure remain unchanged by the projection.
set_primitivemethod#
def set_primitive(density: np.ndarray, velocity: np.ndarray, magnetic_field: np.ndarray, pressure: np.ndarray) -> NoneSet the state from primitive MHD variables.
set_statemethod#
def set_state(state: np.ndarray) -> NoneSet the conservative MHD state.
solvemethod#
def solve(t_end: float, max_steps: int = 100000, dt: float | None = None, verbose: bool = False) -> MHDResultAdvance the state until t_end and return the final state.
If dt is omitted, each step uses a CFL-limited timestep. When
dt is provided, it is clipped only on the last step so the solver
lands exactly on t_end.
stepmethod#
def step(dt: float | None = None) -> floatAdvance the MHD state by one timestep and return the timestep used.
MHDResultclassdataclass#
mhd_sandbox.solverView sourceclass MHDResult(state: np.ndarray, time: float, steps: int, dt_history: list[float], max_divergence_b: float)Result returned by an MHD time integration.
MultiFluidIdealMHD2DSolverclass#
mhd_sandbox.solverView sourceclass MultiFluidIdealMHD2DSolver(grid: Grid, fluid_names: list[str] | tuple[str, ...], gammas: dict[str, float] | float = 5.0 / 3.0, cfl: float = 0.35, density_floor: float = 1e-08, pressure_floor: float = 1e-08, project_divergence: bool = True)Coordinate multiple ideal-MHD fluid solvers on one grid.
dt_historyproperty#
dt_history: list[float]Return timestep history.
fluid_namesproperty#
fluid_names: list[str]Return all registered fluid names.
gridproperty#
grid: GridReturn the shared simulation grid.
stateproperty#
state: dict[str, np.ndarray]Return conservative state by fluid name.
stepsproperty#
steps: intReturn the number of completed timesteps.
timeproperty#
time: floatReturn the current simulation time.
compute_dtmethod#
def compute_dt() -> floatReturn the most restrictive CFL timestep across all fluids.
fluid_solvermethod#
def fluid_solver(fluid_name: str) -> IdealMHD2DSolverReturn the underlying one-fluid solver by name.
max_abs_divergence_bmethod#
def max_abs_divergence_b() -> dict[str, float]Return max |div(B)| by fluid.
primitive_variablesmethod#
def primitive_variables(fluid_name: str, state: np.ndarray | None = None) -> dict[str, np.ndarray]Return primitive variables for one fluid.
set_primitivemethod#
def set_primitive(fluid_name: str, density: np.ndarray, velocity: np.ndarray, magnetic_field: np.ndarray, pressure: np.ndarray) -> NoneSet primitive state for one fluid.
set_statemethod#
def set_state(fluid_name: str, state: np.ndarray) -> NoneSet conservative state for one fluid.
solvemethod#
def solve(t_end: float, max_steps: int = 100000, dt: float | None = None, verbose: bool = False) -> MultiFluidMHDResultAdvance all fluid states until t_end.
stepmethod#
def step(dt: float | None = None) -> floatAdvance all fluids by one synchronized timestep.
MultiFluidMHDResultclassdataclass#
mhd_sandbox.solverView sourceclass MultiFluidMHDResult(states: dict[str, np.ndarray], time: float, steps: int, dt_history: list[float], max_divergence_b: dict[str, float])Result returned by a multi-fluid MHD integration.