Process reference: kinetic_closure
Generated from the docstrings of vaft.process.kinetic_closure:
4 public functions. Each entry is what
vaft.process.describe("kinetic_closure.<name>") prints.
All process categories
Overview
Connects pieces VAFT already has – Thomson n_e and T_e, a T_i/T_e policy,
an impurity composition (#1565), the per-species pressure law – into one
pressure construction that does not assume n_i = n_e, and adds a
lightweight fast-ion baseline (vaft.formula.fast_ion) for when no
NUBEAM run exists. Thermal and fast pressure stay separate quantities.
The chain::
core_profiles slice (matched by time): n_e, T_e, T_i or T_i/T_e policy
+ impurity composition (vaft.process.impurity.resolve_impurity_composition)
-> species densities n_s = n_e (n_s/n_e), main ion diluted [dilution="species"]
or n_i = n_e, one hydrogenic ion [dilution="none", the old form]
-> p_e = e n_e T_e, p_i = e sum_s n_s T_s, p_thermal = p_e + p_i
+ optional fast-ion source (fast_ion_slowing_down_estimate)
-> p_fast = 2 W_f / 3
-> PressureAssembly: p_e, p_i_thermal, p_thermal, p_fast, p_total
| Symbol | Meaning | Unit |
|---|---|---|
| p_e, p_i | electron and summed ion thermal pressure | Pa |
| p_fast | scalar fast-ion pressure | Pa |
| p_total | p_thermal + p_fast | Pa |
| S | fast-ion birth rate per unit volume | m^-3 s^-1 |
Thermal and fast never share a field. p_thermal holds Maxwellian
species only; p_total adds p_fast. Writing fast pressure into a
thermal field is what #1606 Sec. 5 forbids.
Every assumed number is recorded. The T_i source (measured or a ratio
with its record), the composition’s kind and source, the dilution mode and
the fast-ion inputs are in provenance.
Functions
assemble_pressure | Electron, per-species ion, thermal, fast and total pressure, each kept separate. Convention |
fast_ion_slowing_down_estimate | Classical slowing-down density, energy and pressure of one fast-ion source on a grid. |
infer_kinetic_closure | Densities, temperatures and separated pressures of one core_profiles slice, dilution-aware. Convention |
infer_ti_pressure_partition | Ion temperature from the equilibrium pressure partition, T_i = p_eq / (e f n_e) - T_e / f.
Convention |
No function matches.
assemble_pressure
Machine-independentConvention-sensitive
source
assemble_pressure(n_e, T_e, ion_densities, ion_temperatures, *, p_fast=None, provenance=None)
Show source vaft/process/kinetic_closure.py, lines 140–213
def assemble_pressure(
n_e: Any,
T_e: Any,
ion_densities: Mapping[str, Any],
ion_temperatures: Mapping[str, Any],
*,
p_fast: Any = None,
provenance: Optional[Mapping[str, Any]] = None,
) -> PressureAssembly:
"""Electron, per-species ion, thermal, fast and total pressure, each kept separate.
Parameters
----------
n_e : array-like
Electron density [m^-3].
T_e : array-like
Electron temperature [eV].
ion_densities : mapping
Thermal density of each ion species by label [m^-3].
ion_temperatures : mapping
Temperature of each ion species, same labels [eV].
p_fast : array-like, optional
Scalar pressure of non-thermal populations; ``None`` when there is none
to add [Pa].
provenance : mapping, optional
Record carried into the result [any].
Returns
-------
PressureAssembly
``p_e = e n_e T_e``, ``p_i_species`` and their sum ``p_i_thermal``,
``p_thermal = p_e + p_i_thermal``, ``p_fast`` and
``p_total = p_thermal + p_fast`` [Pa].
Raises
------
ValueError
Labels that differ between densities and temperatures, or negative
densities, temperatures or fast pressure.
Convention
----------
Thermal and fast pressure are never merged into one field; ``p_total`` is
the only sum of the two. Uses :func:`vaft.formula.equilibrium.electron_pressure`
and :func:`~vaft.formula.equilibrium.ion_pressure` per species.
Applicability
-------------
Machine-independent.
Provenance
----------
.. [issue] #1606 Sec. 2 and 5.
"""
from vaft.formula.equilibrium import electron_pressure, ion_pressure
if set(ion_densities) != set(ion_temperatures):
raise ValueError("ion_densities and ion_temperatures must name the same species")
ne = _finite_non_negative(n_e, "n_e")
te = _finite_non_negative(T_e, "T_e", ne.shape)
p_e = np.asarray(electron_pressure(np.nan_to_num(ne), np.nan_to_num(te)), dtype=float)
p_e = np.where(np.isfinite(ne) & np.isfinite(te), p_e, np.nan)
p_species = {}
for label, density in ion_densities.items():
n = _finite_non_negative(density, f"density of {label}", ne.shape)
t = _finite_non_negative(ion_temperatures[label], f"temperature of {label}", ne.shape)
ok = np.isfinite(n) & np.isfinite(t)
p_species[label] = np.where(ok, np.asarray(ion_pressure(np.where(ok, n, 0.0), np.where(ok, t, 0.0))), np.nan)
p_i = np.sum(list(p_species.values()), axis=0) if p_species else np.zeros_like(p_e)
p_thermal = p_e + p_i
fast = None if p_fast is None else _finite_non_negative(p_fast, "p_fast", ne.shape)
return PressureAssembly(p_e=p_e, p_i_species=p_species, p_i_thermal=p_i, p_thermal=p_thermal,
p_fast=fast, p_total=p_thermal + (0.0 if fast is None else fast),
provenance=dict(provenance or {}))Electron, per-species ion, thermal, fast and total pressure, each kept separate.
| Name | Type | Unit | Description |
|---|---|---|---|
n_e | array-like | m^-3 | Electron density. |
T_e | array-like | eV | Electron temperature. |
ion_densities | mapping | m^-3 | Thermal density of each ion species by label. |
ion_temperatures | mapping | eV | Temperature of each ion species, same labels. |
p_fast | array-like, optional | Pa | Scalar pressure of non-thermal populations; |
provenance | mapping, optional | any | Record carried into the result. |
| Returns | |||
| — | PressureAssembly | Pa |
|
Convention
Thermal and fast pressure are never merged into one field; p_total is
the only sum of the two. Uses vaft.formula.equilibrium.electron_pressure
and vaft.formula.equilibrium.ion_pressure per species.
Raises
ValueErrorLabels that differ between densities and temperatures, or negative densities, temperatures or fast pressure.
Applicability · Provenance
Applicability
Machine-independent.
Provenance
- #1606 Sec. 2 and 5.
fast_ion_slowing_down_estimate
Machine-independent
source
fast_ion_slowing_down_estimate(n_e, T_e, field_ions, source_rate, beam_energy_eV, *, A_b, Z_b=1.0, ln_Lambda=None, time=None, rho=None)
Classical slowing-down density, energy and pressure of one fast-ion source on a grid.
| Name | Type | Unit | Description |
|---|---|---|---|
n_e | array-like | m^-3 | Electron density. |
T_e | array-like | eV | Electron temperature. |
field_ions | mapping | any |
|
source_rate | array-like | m^-3 s^-1 | Fast-ion birth rate per unit volume on the grid. |
beam_energy_eV | float | eV | Birth energy of the fast ions. |
A_b | float | - | Mass number of the fast ion. |
Z_b | float, optional | - | Charge of the fast ion. |
ln_Lambda | array-like, optional | - | Electron Coulomb logarithm; default the NRL form of n_e, T_e. |
time | float, optional | s | Time of the profiles; |
rho | array-like, optional | - | Radial grid of the profiles; checked against the slice grid. |
| Returns | |||
| — | FastIonEstimate | any |
|
Raises
ValueErrorNon-positive beam energy, mass or charge, or a negative source rate.
Processing steps · Assumptions · Applicability · Limitations · Provenance
Processing steps
v_cfrom the field ions (vaft.formula.fast_ion.critical_velocity_from_T_e_n_species).tau_son electrons with ln Lambda.- Steady slowing-down density and energy density from
source_rate. p_fast = 2 W_fast / 3.
Assumptions
Steady state, a single birth energy, classical drag, local deposition (no orbit width), an isotropic population, no charge-exchange loss. Points with a non-positive or non-finite n_e or T_e (the zero edge of a fitted profile) have no defined drag and are returned as NaN.
Applicability
Machine-independent.
Limitations
A baseline, not NUBEAM: orbit losses, anisotropy and charge exchange –
large in a small device like VEST – are absent, so it bounds the fast
pressure from above where those losses matter. On the packaged VEST
NUBEAM case (10 keV H, 200 kW), given NUBEAM’s own birth rate and
plasma, it gives 1.32x NUBEAM’s fast-ion number and 1.26x its energy;
NUBEAM loses 13 % of the deposited power to bad orbits and CX, and
with that removed the totals agree to 10-15 % (1.14x, 1.10x). Radial
profiles differ more, most at the edge, where orbit losses concentrate
(test/test_kinetic_closure_nubeam.py).
Provenance
- T. H. Stix, Plasma Phys. 14 (1972) 367.
- #1606 Sec. 3-4.
infer_kinetic_closure
Machine-independentConvention-sensitive
source
infer_kinetic_closure(ods, *, time=None, tolerance=0.0005, dilution='species', composition=None, machine_preset=None, shot=None, ti_te_ratio=None, ti_record=None, use_stored_inferred_ti=False, fast_ion=None)
Densities, temperatures and separated pressures of one core_profiles slice, dilution-aware.
| Name | Type | Unit | Description |
|---|---|---|---|
ods | ODS | any | Source of n_e, T_e and (when stored) the main-ion T_i; read without creating paths. |
time | float, optional | s | Slice time; required when the IDS holds several slices. |
tolerance | float, optional | s | Largest |
dilution | str, optional | - |
|
composition | ImpurityComposition, optional | any | Explicit composition for |
machine_preset | str or mapping, optional | any | Machine preset for the same resolver ( |
shot | int, optional | - | Shot whose preset era applies. |
ti_te_ratio | float, optional | - | T_i = ratio T_e for every ion when the slice stores no measured T_i: none at all, or one whose |
ti_record | str, optional | - | Provenance text for that ratio (e.g. the VEST policy record). |
use_stored_inferred_ti | bool, optional | - | Take a stored T_i whose record says |
fast_ion | FastIonEstimate, optional | any | A fast-ion estimate on the same grid, added as |
| Returns | |||
| — | KineticClosure | any | Composition, ion densities and temperatures, the |
Convention
dilution="none" reproduces pressure_thermal = e n_e (T_e + T_i) of
vaft.process.profile.core_profiles_from_eq_ratio exactly; the
species mode differs from it by e n_e T_i (sum_s n_s/n_e - 1).
Raises
ValueErrorAn unknown dilution mode, no slice at the time, no n_e or T_e, no measured T_i and no ratio (an inferred one needs the opt-in or a ratio), an ion-temperature record in no known grammar, several hydrogenic ions, a composition that cannot be resolved, a composition resolved on another grid than n_e, or a fast-ion estimate from another grid or time.
Processing steps · Input semantics · Output semantics · Applicability · Limitations · Provenance
Processing steps
- Match the slice by time; read n_e, T_e and the main-ion T_i if stored.
species: resolve the composition (stored ions, explicit, preset; #1565 precedence) and form n_s = n_e (n_s/n_e) with the diluted main ion;none: one hydrogenic ion with n_i = n_e.- Ion temperatures for every ion: the stored main-ion T_i when its
temperature_fit.parametersrecord classifies as measured (vaft.machine_mapping.core_profiles.classify_ti_record); a stored T_i the product itself assumed or inferred is not a measurement and is outranked by the caller’s ratio (recorded as assumed) – an inferred one is used only onuse_stored_inferred_ti(recorded as inferred);provenance["ti"]carriesstatusandlineage. - Assemble p_e, p_i, p_thermal; add
fast_ionas p_fast.
Input semantics
A fitted core_profiles slice (Thomson n_e, T_e; T_i measured or not).
Output semantics
Derived kinetic densities and separated pressures; nothing is written.
Applicability
Machine-independent. A machine preset reaches it only as machine_preset.
Limitations
Impurities share the main-ion temperature, read from the one hydrogenic
ion[] entry (by element.0.z_n, not position). A measured record
is taken at its word: whether the measurement itself is sound (CX
coverage, fit span) is the profile stage’s finding, not re-examined here.
The fast-ion
pressure is the caller’s estimate; it must share the slice’s grid (and
its time and rho when the estimate records them). No deposition model
is run here.
Provenance
- #1606 Sec. 1-2 and 5; #1565 (composition); #1526 (the T_i record grammar, cold review 0.8.0 delta-absorb-19 physics F1).
infer_ti_pressure_partition
Machine-independentConvention-sensitive
source
infer_ti_pressure_partition(p_eq, n_e, t_e, *, composition, sigma_p_eq, sigma_n_e, sigma_t_e, equilibrium_lineage)
Ion temperature from the equilibrium pressure partition, T_i = p_eq / (e f n_e) - T_e / f.
| Name | Type | Unit | Description |
|---|---|---|---|
p_eq | array-like | Pa | Equilibrium total pressure on the points. |
n_e | array-like | m^-3 | Electron density on the same points. |
t_e | array-like | eV | Electron temperature on the same points. |
composition | mapping | - |
|
sigma_p_eq | array-like | Pa | One-sigma uncertainty of |
sigma_n_e | array-like | m^-3 | One-sigma uncertainty of |
sigma_t_e | array-like | eV | One-sigma uncertainty of |
equilibrium_lineage | str | - | Where |
| Returns | |||
| — | dict | any | Refused ( |
Convention
The uncertainty is propagated through T_i = p_eq / (e f n_e) - T_e / f,
which keeps the n_e correlation between p_e and the ion density::
dT_i/dp_eq = 1/(e f n_e), dT_i/dn_e = -p_eq/(e f n_e^2), dT_i/dT_e = -1/f
Points are flagged, never filled. Scalars broadcast against arrays; every
input is brought to one shape. f is taken as exact, and p_eq is
the caller’s pressure with the caller’s uncertainty.
Raises
KeyErrorcompositionlacksion_density_per_electronorcomposition_source.
Processing steps · Assumptions · Applicability · Limitations · Provenance
Processing steps
- Refuse a lineage outside
INDEPENDENT_LINEAGES. p_e = e n_e T_eandp_i = p_eq - p_e.T_i = p_i / (e f n_e)for one common ion temperature ofn_i = f n_eions.- Propagate the one-sigma inputs linearly (below).
- Void
p_i <= 0(p_i_nonpositive),p_i < sigma(p_i)(p_i_not_significant) and non-finite or non-positive inputs (non_finite_input); a missing input uncertainty only adds the notesigma_unavailableand skips the significance test at that point.
Assumptions
A single ion temperature for every ion species; f from a composition
the caller names. The result is an inferred quantity, never a measurement.
Applicability
Machine-independent.
Limitations
The guard trusts the declared lineage. Equilibrium products carry no
machine-readable record of one, so a caller must derive
equilibrium_lineage from where the pressure came from (the FileDB stage
it loaded), never from intent. An electron_kinetic pressure was fitted
with an assumed T_i/T_e and is refused as circular.
Provenance
- #1426 (pressure-partition T_i); moved here from
vaft.validation.kinetic_stateby #1842.