# mhd_sandbox.solver

*module*

Finite-volume solvers for the two-dimensional ideal MHD equations.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L1-L1)

## mhd_sandbox.solver.IdealMHD2DSolver

*class*

```python
class IdealMHD2DSolver
```

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.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L34-L566)

### mhd_sandbox.solver.IdealMHD2DSolver.B_X

*attribute* · *class attribute* · *instance attribute*

```python
B_X = 5
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L53-L53)

### mhd_sandbox.solver.IdealMHD2DSolver.B_Y

*attribute* · *class attribute* · *instance attribute*

```python
B_Y = 6
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L54-L54)

### mhd_sandbox.solver.IdealMHD2DSolver.B_Z

*attribute* · *class attribute* · *instance attribute*

```python
B_Z = 7
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L55-L55)

### mhd_sandbox.solver.IdealMHD2DSolver.ENERGY

*attribute* · *class attribute* · *instance attribute*

```python
ENERGY = 4
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L52-L52)

### mhd_sandbox.solver.IdealMHD2DSolver.MOM_X

*attribute* · *class attribute* · *instance attribute*

```python
MOM_X = 1
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L49-L49)

### mhd_sandbox.solver.IdealMHD2DSolver.MOM_Y

*attribute* · *class attribute* · *instance attribute*

```python
MOM_Y = 2
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L50-L50)

### mhd_sandbox.solver.IdealMHD2DSolver.MOM_Z

*attribute* · *class attribute* · *instance attribute*

```python
MOM_Z = 3
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L51-L51)

### mhd_sandbox.solver.IdealMHD2DSolver.NUM_COMPONENTS

*attribute* · *class attribute* · *instance attribute*

```python
NUM_COMPONENTS = 8
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L47-L47)

### mhd_sandbox.solver.IdealMHD2DSolver.RHO

*attribute* · *class attribute* · *instance attribute*

```python
RHO = 0
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L48-L48)

### mhd_sandbox.solver.IdealMHD2DSolver.cfl

*property*

```python
cfl: float
```

Return the CFL number.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L519-L521)

### mhd_sandbox.solver.IdealMHD2DSolver.density_floor

*property*

```python
density_floor: float
```

Return the density floor.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L524-L526)

### mhd_sandbox.solver.IdealMHD2DSolver.dt_history

*property*

```python
dt_history: list[float]
```

Return the timestep history.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L559-L561)

### mhd_sandbox.solver.IdealMHD2DSolver.dx

*property*

```python
dx: float
```

Return the cell width along x.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L539-L541)

### mhd_sandbox.solver.IdealMHD2DSolver.dy

*property*

```python
dy: float
```

Return the cell width along y.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L544-L546)

### mhd_sandbox.solver.IdealMHD2DSolver.gamma

*property*

```python
gamma: float
```

Return the adiabatic index.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L514-L516)

### mhd_sandbox.solver.IdealMHD2DSolver.grid

*property*

```python
grid: Grid
```

Return the grid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L509-L511)

### mhd_sandbox.solver.IdealMHD2DSolver.pressure_floor

*property*

```python
pressure_floor: float
```

Return the pressure floor.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L529-L531)

### mhd_sandbox.solver.IdealMHD2DSolver.project_divergence

*property*

```python
project_divergence: bool
```

Return whether periodic magnetic divergence projection is enabled.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L534-L536)

### mhd_sandbox.solver.IdealMHD2DSolver.state

*property*

```python
state: np.ndarray
```

Return the conservative state array.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L564-L566)

### mhd_sandbox.solver.IdealMHD2DSolver.steps

*property*

```python
steps: int
```

Return the number of completed timesteps.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L554-L556)

### mhd_sandbox.solver.IdealMHD2DSolver.time

*property*

```python
time: float
```

Return the current simulation time.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L549-L551)

### mhd_sandbox.solver.IdealMHD2DSolver.compute_dt

*method*

```python
def compute_dt() -> float
```

Return a CFL-limited timestep for the current state.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L375-L382)

### mhd_sandbox.solver.IdealMHD2DSolver.divergence_b

*method*

```python
def divergence_b() -> np.ndarray
```

Return a centered finite-difference estimate of div(B).

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L494-L502)

### mhd_sandbox.solver.IdealMHD2DSolver.max_abs_divergence_b

*method*

```python
def max_abs_divergence_b() -> float
```

Return the maximum absolute centered div(B) diagnostic.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L504-L506)

### mhd_sandbox.solver.IdealMHD2DSolver.orszag_tang_initial_state

*method* · *classmethod*

```python
def orszag_tang_initial_state(grid: Grid, gamma: float = 5.0 / 3.0) -> np.ndarray
```

Build 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.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L138-L179)

### mhd_sandbox.solver.IdealMHD2DSolver.primitive_to_conservative

*method* · *classmethod*

```python
def primitive_to_conservative(density: np.ndarray, velocity: np.ndarray, magnetic_field: np.ndarray, pressure: np.ndarray, gamma: float = 5.0 / 3.0) -> np.ndarray
```

Convert primitive variables to conservative MHD state variables.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L103-L136)

### mhd_sandbox.solver.IdealMHD2DSolver.primitive_variables

*method*

```python
def primitive_variables(state: np.ndarray | None = None) -> dict[str, np.ndarray]
```

Return primitive variables for a conservative state.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L247-L258)

### mhd_sandbox.solver.IdealMHD2DSolver.primitive_variables_from_state

*method* · *classmethod*

```python
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.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L260-L286)

### mhd_sandbox.solver.IdealMHD2DSolver.project_magnetic_field

*method*

```python
def project_magnetic_field() -> None
```

Project 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.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L456-L492)

### mhd_sandbox.solver.IdealMHD2DSolver.set_primitive

*method*

```python
def set_primitive(density: np.ndarray, velocity: np.ndarray, magnetic_field: np.ndarray, pressure: np.ndarray) -> None
```

Set the state from primitive MHD variables.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L229-L245)

### mhd_sandbox.solver.IdealMHD2DSolver.set_state

*method*

```python
def set_state(state: np.ndarray) -> None
```

Set the conservative MHD state.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L217-L227)

### mhd_sandbox.solver.IdealMHD2DSolver.solve

*method*

```python
def solve(t_end: float, max_steps: int = 100000, dt: float | None = None, verbose: bool = False) -> MHDResult
```

Advance 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``.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L412-L454)

### mhd_sandbox.solver.IdealMHD2DSolver.step

*method*

```python
def step(dt: float | None = None) -> float
```

Advance the MHD state by one timestep and return the timestep used.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L384-L410)

## mhd_sandbox.solver.MHDResult

*class* · *dataclass*

```python
class MHDResult
```

Result returned by an MHD time integration.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L12-L20)

### mhd_sandbox.solver.MHDResult.dt_history

*attribute* · *instance attribute*

```python
dt_history: list[float]
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L19-L19)

### mhd_sandbox.solver.MHDResult.max_divergence_b

*attribute* · *instance attribute*

```python
max_divergence_b: float
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L20-L20)

### mhd_sandbox.solver.MHDResult.state

*attribute* · *instance attribute*

```python
state: np.ndarray
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L16-L16)

### mhd_sandbox.solver.MHDResult.steps

*attribute* · *instance attribute*

```python
steps: int
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L18-L18)

### mhd_sandbox.solver.MHDResult.time

*attribute* · *instance attribute*

```python
time: float
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L17-L17)

## mhd_sandbox.solver.MultiFluidIdealMHD2DSolver

*class*

```python
class MultiFluidIdealMHD2DSolver
```

Coordinate multiple ideal-MHD fluid solvers on one grid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L569-L768)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.dt_history

*property*

```python
dt_history: list[float]
```

Return timestep history.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L761-L763)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.fluid_names

*property*

```python
fluid_names: list[str]
```

Return all registered fluid names.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L746-L748)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.grid

*property*

```python
grid: Grid
```

Return the shared simulation grid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L741-L743)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.state

*property*

```python
state: dict[str, np.ndarray]
```

Return conservative state by fluid name.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L766-L768)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.steps

*property*

```python
steps: int
```

Return the number of completed timesteps.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L756-L758)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.time

*property*

```python
time: float
```

Return the current simulation time.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L751-L753)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.compute_dt

*method*

```python
def compute_dt() -> float
```

Return the most restrictive CFL timestep across all fluids.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L663-L665)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.fluid_solver

*method*

```python
def fluid_solver(fluid_name: str) -> IdealMHD2DSolver
```

Return the underlying one-fluid solver by name.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L659-L661)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.max_abs_divergence_b

*method*

```python
def max_abs_divergence_b() -> dict[str, float]
```

Return max |div(B)| by fluid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L733-L738)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.primitive_variables

*method*

```python
def primitive_variables(fluid_name: str, state: np.ndarray | None = None) -> dict[str, np.ndarray]
```

Return primitive variables for one fluid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L651-L657)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.set_primitive

*method*

```python
def set_primitive(fluid_name: str, density: np.ndarray, velocity: np.ndarray, magnetic_field: np.ndarray, pressure: np.ndarray) -> None
```

Set primitive state for one fluid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L635-L649)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.set_state

*method*

```python
def set_state(fluid_name: str, state: np.ndarray) -> None
```

Set conservative state for one fluid.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L631-L633)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.solve

*method*

```python
def solve(t_end: float, max_steps: int = 100000, dt: float | None = None, verbose: bool = False) -> MultiFluidMHDResult
```

Advance all fluid states until ``t_end``.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L690-L731)

### mhd_sandbox.solver.MultiFluidIdealMHD2DSolver.step

*method*

```python
def step(dt: float | None = None) -> float
```

Advance all fluids by one synchronized timestep.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L667-L688)

## mhd_sandbox.solver.MultiFluidMHDResult

*class* · *dataclass*

```python
class MultiFluidMHDResult
```

Result returned by a multi-fluid MHD integration.

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L23-L31)

### mhd_sandbox.solver.MultiFluidMHDResult.dt_history

*attribute* · *instance attribute*

```python
dt_history: list[float]
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L30-L30)

### mhd_sandbox.solver.MultiFluidMHDResult.max_divergence_b

*attribute* · *instance attribute*

```python
max_divergence_b: dict[str, float]
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L31-L31)

### mhd_sandbox.solver.MultiFluidMHDResult.states

*attribute* · *instance attribute*

```python
states: dict[str, np.ndarray]
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L27-L27)

### mhd_sandbox.solver.MultiFluidMHDResult.steps

*attribute* · *instance attribute*

```python
steps: int
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L29-L29)

### mhd_sandbox.solver.MultiFluidMHDResult.time

*attribute* · *instance attribute*

```python
time: float
```

[View source](https://github.com/max-models/mhd-sandbox/blob/devel/src/mhd_sandbox/solver.py#L28-L28)
