rizer.models.nrp.nrp_driver#

Reusable driver for the constant-mass 0D2T NRP discharge simulation.

Library form of scripts/2T0D_constant_mass_NRP/run_2T0D_constant_mass_simulation.py: build_nrp_case() assembles everything a run needs from the script’s parameter dictionary (sections plasma, electric_circuit, simulation, optional radius_changes; see scripts/2T0D_constant_mass_NRP/input_parameters_2T0D_constant_mass_simulation.yaml), and run_nrp_case() integrates it through run_constant_mass_nrp_simulation(), so other frontends (tests, the adaptive stages, the Boulder GUI plugin) drive the exact same simulation as the script.

The reactor is the one build_isomass_2T_volume_reactor() builds (solver_backend "cpp" – requires the built _plasma1d extension – or the pure-Python "python" reference), driven by cantera.ReactorNet.

Attributes#

Classes#

NRPCase

A constant-mass NRP 0D2T case.

Functions#

check_circuit_solver_compatibility(→ None)

Raise if simulation.solver.max_step would violate a windowed circuit's causality window.

build_circuit_from_input(...)

Build an NRP electric circuit from its electric_circuit YAML block.

set_initial_state(→ tuple[float, float])

Set plasma to the initial state described by initial_conditions.

build_nrp_case(→ NRPCase)

Construct an NRPCase from a parsed parameter dictionary.

run_nrp_case(→ cantera.SolutionArray)

Integrate an NRPCase from t = 0, returning the full state history.

Module Contents#

rizer.models.nrp.nrp_driver.logger#
rizer.models.nrp.nrp_driver.SOLVER_BACKENDS = ('cpp', 'python')#
rizer.models.nrp.nrp_driver.check_circuit_solver_compatibility(circuit_input: dict[str, Any], max_step: float) → None#

Raise if simulation.solver.max_step would violate a windowed circuit’s causality window.

TransmissionLineRCLoadCircuit/DirectRCLoadCircuit (load.type == “c_parallel”) and TransmissionLineCapacitiveSourceResistiveLoadCircuit/TransmissionLineParallelCapacitiveSourceResistiveLoadCircuit (source.type in (“c_shunt”, “c_parallel”)) all need the reactor to never advance past their own re-solved window (method-of-steps DDE) – checked once here, at case-build time, rather than letting a misconfigured max_step surface as a RuntimeError mid-integration.

Parameters:
  • circuit_input (dict) – The electric_circuit section (same shape build_circuit_from_input takes).

  • max_step (float) – simulation.solver.max_step [s].

Raises:

ValueError – If load.type == “c_parallel” or source.type in (“c_shunt”, “c_parallel”) and max_step exceeds half that block’s own window_span.

rizer.models.nrp.nrp_driver.build_circuit_from_input(circuit_input: dict[str, Any]) → rizer.electrical_model.circuit.base_circuit.PlasmaVoltageCircuit#

Build an NRP electric circuit from its electric_circuit YAML block.

Always requires a source (a generator waveform, see get_generator_from_input() for the supported waveform types, including "from_measurement" for an experimentally-measured one). Dispatches on source.is_plasma_voltage:

  • True: the generator’s own voltage is imposed directly at the plasma, bypassing source resistance, cable, and reflection physics entirely (GeneratorVoltageCircuit). source.R_g, source.type (and its own kwargs), cable, and load have no effect in this mode – if present, a warning is logged (not an error) naming which keys are ignored, so toggling the flag on an otherwise-unchanged config (e.g. to A/B a direct-voltage run against the same circuit) needs no editing.

  • False (default): source.R_g and load are required (cable optional). source.type picks the source-side network:

    "c_shunt"/"c_parallel" additionally require source.C_s and source.window_span (optionally source.r_p_rtol and an initial capacitor voltage, source.u_s_0/source.u_c_0 respectively), and only support load.type == "resistive" (no circuit class combines a capacitive source with a capacitive load). "c_parallel" further requires a cable (no no-cable circuit exists for that topology); "c_shunt" with no cable instead builds a DirectRCLoadCircuit with R_para=0 (a capacitive source and a capacitive load are the same single node with no cable to separate them – see the package README’s “Sources” section).

    load.type (for a "resistive" source) picks "resistive" (just R_p) or "c_parallel" (R_p in parallel with a capacitor C, an optional parasitic R_para in series before it) – four combinations with/without a cable, each a different circuit class (see the package README’s “Which one do I need?” list).

Parameters:

circuit_input (dict) – The electric_circuit section of the nrp_driver-layout parameters.

Return type:

PlasmaVoltageCircuit

Raises:
  • TypeError – If source.is_plasma_voltage or include_reflections is present and not a bool.

  • ValueError – If source.type or load.type is unknown, if a “c_shunt”/ “c_parallel” source is combined with a non-“resistive” load, or if source.type=”c_parallel” has no cable.

class rizer.models.nrp.nrp_driver.NRPCase#

A constant-mass NRP 0D2T case.

Fully-constructed (ready to integrate) when built from parameters that include the electric_circuit section; otherwise circuit/reactor are None until attach_circuit() is called (used by the Boulder plugin, where the circuit is wired from separate Generator/CoaxialCable YAML blocks).

plasma: cantera.Solution#
collision_freq: rizer.transport.mixture_law.MixtureCollisionFrequencies#
circuit: rizer.electrical_model.circuit.base_circuit.PlasmaVoltageCircuit | None#
reactor: Any | None#
solver_backend: str#
mechanism: str#

On-disk mechanism the native reactor loads from (a temporary file when the mechanism was assembled in memory).

mechanism_path: pathlib.Path | None#

Mechanism the plasma was loaded from; None when assembled in memory (see resolve_plasma_mechanism()).

plasma_phase_name: str#
mtcf: list#
mass: float#
gap: float#
pulse_duration: float | None#
initial_radius: float#
polytropic_index: float | str#
p_ext: float | str#
solver_input: dict[str, Any]#
t_end: float#
output_interval: float#
radius_changes: list[tuple[float, float]]#
n_e_0: float#
y0: numpy.ndarray#
attach_circuit(circuit: rizer.electrical_model.circuit.base_circuit.PlasmaVoltageCircuit) → None#

Attach the electric circuit and build the reactor.

Completes a case constructed without an electric_circuit section (Boulder wires the circuit from separate Generator/CoaxialCable blocks).

make_reactor(mass: float, initial_radius: float, circuit: rizer.electrical_model.circuit.base_circuit.PlasmaVoltageCircuit, compute_chemistry: bool = True) → Any#

Build a reactor for this case, seeded from plasma’s current state.

The returned reactor carries this case as reactor.case (read by RizerNRP2TNetwork).

rizer.models.nrp.nrp_driver.set_initial_state(plasma: cantera.Solution, initial_conditions: dict[str, Any]) → tuple[float, float]#

Set plasma to the initial state described by initial_conditions.

mole_fractions is a Cantera composition (string or mapping). Charged species may be given there directly, or as absolute number densities in additional_number_density [m^-3] – the form a measured seed electron density comes in:

mole_fractions: "CH4: 1.0"
additional_number_density: "e-: 1.0e19, CH4+: 1.0e19"   # m^-3

The driver only applies the composition (apply_initial_composition()) and checks it (electrons present, charge-neutral).

Parameters:
  • plasma (cantera.Solution) – Plasma phase, set in place.

  • initial_conditions (dict of str to Any) – plasma.initial_conditions section: total_pressure [Pa], gas_temperature [K], electron_temperature [K], mole_fractions, radius [m], gap [m], and optionally pulse_duration [s] and additional_number_density [m^-3].

Returns:

  • T_e_0 (float) – Initial electron temperature [K].

  • n_e_0 (float) – Initial electron density [m^-3], read back from the composition.

rizer.models.nrp.nrp_driver.build_nrp_case(params: dict[str, Any], solver_backend: str | None = None) → NRPCase#

Construct an NRPCase from a parsed parameter dictionary.

Parameters:
  • params – Parsed input parameters with sections plasma, electric_circuit (optional, see NRPCase.attach_circuit()), simulation and optional radius_changes (same layout as the run script’s YAML, e.g. from rizer.misc.yaml_utils.parse_convert_yaml()).

  • solver_backend – Reactor backend override, "cpp" or "python". When None, params["simulation"]["solver_backend"] is used.

rizer.models.nrp.nrp_driver.run_nrp_case(case: NRPCase) → cantera.SolutionArray#

Integrate an NRPCase from t = 0, returning the full state history.

Restores the case’s initial state (the shared plasma object is mutated by any earlier run) and delegates to run_constant_mass_nrp_simulation() (output every output_interval, radius changes applied as configured).