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#
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 (aPlasmaPhasewithe-).phase (
str) – Mechanism (YAML) file path and phase name (aPlasmaPhasewithe-).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 (
listofMomentumTransferCollisionFrequencyModel) – Per-species momentum-transfer collision-frequency models (as built byget_momentum_transfer_collision_frequencies_list); drives the C++Reactor0Dcollision model (seerizer.plasma.constant_mass_reactor_cpp.build_reactor0d()).species_names (
listofstr) – 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 evaluatecv). Defaultcantera.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
scipyvode/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:
- 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 matchessolve_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) -> floatfield [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:
- 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
circuitclosed on the channel’s plasma resistanceR_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 byConstantMassPlasmaReactorOdeCpp.gap (
float) – Inter-electrode gap [m], used forR_p = gap / integral(sigma ...)andE = 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 diagnosticsRp[Ohm],Vp[V],I[A],E[V/m].- Return type: