rizer.plasma.plasma_channel_split#

Two transient 1D radial plasma-channel solvers over one native C++ physics core.

Head-to-head comparison (the difference between them is numerics, not physics):

  • ChannelReactor1D.solve_monolithic() — method-of-lines: the whole coupled state [Tg, Te, Y] over all nodes is integrated by a single stiff CVODE/vode (the per-node reaction RHS comes from the C++ Reactor0D; radial conduction couples neighbours). No splitting error; one big stiff system.

  • ChannelReactor1D.solve_split() — operator splitting (Strang): each global step does ½ transport → an independent per-node stiff reaction solve → ½ transport. The OpenSMOKE++/reactPlasFoam pattern; each node is just a 0D reactor.

Both reuse constant_mass_reactor_cpp (the C++ Reactor0D with composition-resolved sigma = n_e e^2/(m_e nu_eH)), so a difference between the two is numerics, not physics. Constant volume per node (rho fixed), gas heat conduction only (electron conduction is intentionally omitted — a constant kappa_e over the vanishing electron heat capacity at the cold edge blows up; see cantera_ext/PORTING_PLASMA_RATES.md / the extending-cantera-cpp skill), species frozen. The field E(t) is prescribed.

Classes#

ChannelReactor1D

Radial 1D channel built from per-node C++ 0D reactors + gas conduction.

Module Contents#

class rizer.plasma.plasma_channel_split.ChannelReactor1D(mech: str, phase: str, grid: numpy.ndarray | list[float], rho: float, mtcf: list[rizer.plasma.collision_frequency.MomentumTransferCollisionFrequencyModel], species_names: list[str], reacting: bool = True, kappa: float = 0.0, T_amb: float = 300.0, p_ext: float = ct.one_atm, Te_n: int = 400)#

Radial 1D channel built from per-node C++ 0D reactors + gas conduction.

Parameters:
  • mech (str) – Mechanism (YAML) file path and phase name (a PlasmaPhase with e-).

  • phase (str) – Mechanism (YAML) file path and phase name (a PlasmaPhase with e-).

  • grid (array_like) – Radial node positions [m], increasing from 0 (axis) to the wall.

  • rho (float) – Fixed mass density [kg/m^3] (constant-volume model).

  • mtcf (list of MomentumTransferCollisionFrequencyModel) – Per-species momentum-transfer collision-frequency models (as built by get_momentum_transfer_collision_frequencies_list); drives the C++ Reactor0D collision model (see rizer.plasma.constant_mass_reactor_cpp.build_reactor0d()).

  • species_names (list of str) – Species names, in mechanism order.

  • reacting (bool, optional) – Include finite-rate chemistry in the per-node C++ RHS. Default True.

  • kappa (float, optional) – Gas thermal conductivity [W/m/K] for radial conduction (0 disables it). Default 0.0.

  • T_amb (float, optional) – Wall temperature [K] (Dirichlet boundary condition). Default 300.0.

  • p_ext (float, optional) – Ambient pressure [Pa] (only used by the reactor’s V-equation; constant-V here so it only sets the state used to evaluate cv). Default cantera.one_atm.

  • Te_n (int, optional) – Number of points in the C++ collision model’s electron-temperature table. Default 400.

reactor#
names#
nsp#
nv#
r#
npts#
rho#
T_amb#
p_ext#
conductivity_profile(Tg: numpy.ndarray, Te: numpy.ndarray, Y: numpy.ndarray) numpy.ndarray#

Radial electrical-conductivity profile \(\sigma(r)\) [S/m].

Evaluates the composition-resolved Mitchner conductivity \(\sigma = n_e e^2/(m_e \bar\nu_{eH})\) (C++ collision model) at every node. The total current and plasma resistance follow as

\[I = E \int_0^{R} \sigma(r)\,2\pi r\,dr, \qquad R_p = \frac{\text{gap}}{\int_0^{R} \sigma(r)\,2\pi r\,dr}.\]
Parameters:
  • Tg (numpy.ndarray, shape (npts,)) – Gas and electron temperature per node [K].

  • Te (numpy.ndarray, shape (npts,)) – Gas and electron temperature per node [K].

  • Y (numpy.ndarray, shape (npts, nsp)) – Mass fractions per node.

Returns:

Conductivity per node [S/m].

Return type:

numpy.ndarray, shape (npts,)

solve_monolithic(t_out: numpy.ndarray, E_func: Callable[[float], float], Tg0: numpy.ndarray, Te0: numpy.ndarray, Y0: numpy.ndarray, rtol: float = 1e-07, atol: float = 1e-13) dict[str, Any]#

Method-of-lines solve: one stiff integrator over the full coupled state.

Flattens the radial field into \(y = [T_g, T_e, Y]_j\) for \(j = 0\dots N-1\) and integrates

\[\frac{dy}{dt} = \underbrace{f_\text{react}(y_j, E(t))}_{\text{per node}} + \underbrace{\alpha\,(L\,T_g + w)}_{\text{radial conduction on }T_g}\]

with a single scipy vode/BDF over all nodes (radial conduction couples neighbours; electron conduction omitted). No splitting error; the reference against which the operator split is checked.

Parameters:
  • t_out (numpy.ndarray) – Output times [s] (t_out[0] is the initial time).

  • E_func (typing.Callable) – E_func(t) -> float, the prescribed field [V/m].

  • Tg0 (numpy.ndarray, shape (npts,)) – Initial gas / electron temperatures [K].

  • Te0 (numpy.ndarray, shape (npts,)) – Initial gas / electron temperatures [K].

  • Y0 (numpy.ndarray, shape (npts, nsp)) – Initial mass fractions.

  • rtol (float) – Integrator tolerances.

  • atol (float) – Integrator tolerances.

Returns:

History with keys t, Tg, Te, Y, ne (lists over frames).

Return type:

dict

solve_split(t_out: numpy.ndarray, E_func: Callable[[float], float], Tg0: numpy.ndarray, Te0: numpy.ndarray, Y0: numpy.ndarray, rtol: float = 1e-07, atol: float = 1e-13) dict[str, Any]#

Strang operator-split solve (prescribed field).

Each global step \([t_n, t_{n+1}]\) of size \(\Delta t\) applies the Strang sequence

\[T_g \xleftarrow{\;\text{cond}\;} \tfrac12\Delta t,\quad (T_g, T_e, Y)_j \xleftarrow{\;\text{react}\;} \Delta t\ \text{(per node)},\quad T_g \xleftarrow{\;\text{cond}\;} \tfrac12\Delta t ,\]

i.e. a half conduction step (_transport_step()), an independent per-node stiff reaction solve (each node a 0D reactor, _react_node()), then a second half conduction step. The external field \(E(t)\) is evaluated continuously inside the reaction substep (it is forcing, not a split operator), so the split carries no field-sampling error and matches solve_monolithic() to integrator tolerance. Second-order in \(\Delta t\) for the transport/reaction coupling.

Parameters:
  • t_out (numpy.ndarray) – Output / split times [s]; the step size is set by consecutive entries.

  • E_func (typing.Callable) – E_func(t) -> float field [V/m].

  • Tg0 (numpy.ndarray, shape (npts,)) – Initial temperatures [K].

  • Te0 (numpy.ndarray, shape (npts,)) – Initial temperatures [K].

  • Y0 (numpy.ndarray, shape (npts, nsp)) – Initial mass fractions.

  • rtol (float) – Per-node integrator tolerances.

  • atol (float) – Per-node integrator tolerances.

Returns:

History with keys t, Tg, Te, Y, ne.

Return type:

dict

solve_split_circuit(t_out: numpy.ndarray, circuit: rizer.electric_circuit.nrp_circuit.NRPCircuit, gap: float, nb_reflections: int, Tg0: numpy.ndarray, Te0: numpy.ndarray, Y0: numpy.ndarray, rtol: float = 1e-07, atol: float = 1e-13) dict[str, Any]#

Operator-split solve closing the NRP circuit on the channel’s own R_p.

The field is set by the NRP circuit closed on the channel’s plasma resistance R_p = gap / integral(sigma 2*pi*r dr), so as the channel broadens its falling R_p loads the line and pulls the field down (unlike a prescribed E(t)). R_p is frozen over each global step (explicit circuit coupling); the generator waveform V_g(t) still varies continuously within the step via a 2-point interpolation of V_p (which keeps the stateful circuit history monotonic). Records R_p, V_p, total current I = V_p/R_p, and E = V_p/gap.

Parameters:
  • t_out (numpy.ndarray) – Output / split times [s]; the step size is set by consecutive entries.

  • circuit (NRPCircuit) – Electric circuit object (generator + cable). Same single-source circuit used by ConstantMassPlasmaReactorOdeCpp.

  • gap (float) – Inter-electrode gap [m], used for R_p = gap / integral(sigma ...) and E = V_p / gap.

  • nb_reflections (int) – Number of reflections of the generator voltage wave to take into account in the computation of the plasma voltage.

  • Tg0 (numpy.ndarray, shape (npts,)) – Initial temperatures [K].

  • Te0 (numpy.ndarray, shape (npts,)) – Initial temperatures [K].

  • Y0 (numpy.ndarray, shape (npts, nsp)) – Initial mass fractions.

  • rtol (float, optional) – Per-node integrator tolerances.

  • atol (float, optional) – Per-node integrator tolerances.

Returns:

History with keys t, Tg, Te, Y, ne, plus the circuit diagnostics Rp [Ohm], Vp [V], I [A], E [V/m].

Return type:

dict