Process reference: resistive_zeff
Generated from the docstrings of vaft.process.resistive_zeff:
7 public functions. Each entry is what
vaft.process.describe("resistive_zeff.<name>") prints.
All process categories
Overview
Infers one scalar Zeff_resistive over a time window: the effective charge
a stated parallel-conductivity model needs to reproduce the plasma resistance
observed through Romero’s transformer balance (issue #1214). It is a
model-inferred quantity, not the composition value sum n_i Z_i^2 / n_e;
it absorbs every error in T_e, the equilibrium, the boundary voltage, the
conductivity model and any non-inductive current, and is named and stored so
that nobody mistakes it for a measurement. Nothing here writes
core_profiles.zeff.
The chain, and where each step’s state changes::
boundary flux psi_B, I_p, li_3 per slice [RomeroBoundaryFlux]
-> smoothed in time, differentiated [Smoothing]
-> V_B, V_I, V_R = V_B - V_I, R_p = V_R/(I_p - I_ni) [ObservedResistance]
flux-surface state: T_e, n_e, <J.B>, <B^2>, V(psi) [FluxSurfaceState]
-> sigma_par(Z) -> P_Ohm(Z) -> R_p^model(Z) [ModelResistance]
-> bounded scalar fit of V_R^model(Z) to V_R^obs [ResistiveZeffInference]
| Symbol | Meaning | Unit |
|---|---|---|
| psi_B | boundary poloidal flux, full flux in Romero's sign | Wb |
| V_B | boundary loop voltage, -d psi_B / dt | V |
| V_I | inductive voltage, L_i dI_p/dt + I_p/2 dL_i/dt | V |
| V_R | resistive voltage, V_B - V_I = R_p (I_p - I_ni) | V |
| L_i | dimensional internal inductance, mu0 R0 li_3 / 2 | H |
| <J.B> | flux-surface average of J.B | A T m^-2 |
| <B^2> | flux-surface average of B^2 (IMAS gm5) | T^2 |
| sigma_par | parallel electrical conductivity | S m^-1 |
Romero’s voltage convention, full webers. Every voltage is
V = -d psi/dt on the full flux, so a positive V_B sustains a positive
I_p (issue #781). This is not the Ejima convention of
vaft.formula.equilibrium.loop_voltage_from_total_flux
(+2 pi d psi/dt on a per-radian flux, #354): the observed path accepts a
RomeroBoundaryFlux only, which carries its convention tag, and
refuses anything else rather than guess which one an array is in.
Ohmic power, not j_tor. The model resistance is the flux-surface
Ohmic dissipation over the current squared,
R_p = int <E.B><J.B>/<B^2> dV / I_p^2 with
<E.B> = (<J.B> - <J_bs.B>) / sigma_par. V_R I_p is the same
dissipation in Romero’s balance, so the two sides are one definition. The
parallel current is never replaced by j_tor – they differ at VEST
aspect ratio (#1214 Sec. 7.2).
One scalar, not a profile. A single global resistance constrains a
single amplitude; the inferred Z_eff is held constant across radius and
across the inference window (#1214 Sec. 10). The forward model accepts a
prescribed profile Z_eff(psi) – one from an impurity model, say (#1566)
– to project it onto the resistance; it is never fitted.
Plasma current from the reconstruction. I_p in R_p = V_R/I_p
and in the flux-surface state is the equilibrium’s global_quantities.ip,
not the Rogowski: the current that normalises <J.B> and the one that
divides V_R are then the same number (#1514). On Tier A they differ
from the Rogowski by 5-10 %.
Functions
infer_resistive_zeff | Bounded scalar Z_eff that makes the model resistive voltage match the observed one. |
model_resistance | Plasma resistance a conductivity model predicts from the flux-surface Ohmic power. Convention |
observed_resistance | Resistive voltage and plasma resistance from Romero’s transformer balance. Convention |
parallel_conductivity | Parallel electrical conductivity on every surface of a flux-surface state. Convention |
per_slice_resistive_zeff | Z_eff solved at each state on its own: a diagnostic of the window estimate. |
resistive_zeff_sensitivity | Nominal resistive Z_eff and how far each input moves it. |
smooth_local_polynomial | Local least-squares polynomial smoothing on a non-uniform time axis. |
No function matches.
infer_resistive_zeff
Machine-independent
source
infer_resistive_zeff(observed, states, *, model, ln_lambda, bounds, weights, time_tolerance_s=5e-05, scan_points=41)
Bounded scalar Z_eff that makes the model resistive voltage match the observed one.
| Name | Type | Unit | Description |
|---|---|---|---|
observed | ObservedResistance | any | Observed |
states | sequence of FluxSurfaceState | any | Flux-surface states at times inside |
model | str or callable | any | Conductivity model, as in |
ln_lambda | float or str | - | Coulomb logarithm, as in |
bounds | tuple of float | - |
|
weights | str or sequence of float | - |
|
time_tolerance_s | float, optional | s | Largest gap between a state and its observed sample. |
scan_points | int, optional | - | Log-spaced Z samples used to test monotonicity first. |
| Returns | |||
| — | ResistiveZeffInference | any | The #1214 Sec. 11 result: estimate ( |
Raises
ValueErrorNo state, bounds that are not1 <= Z_min < Z_max, weights of the wrong length, or a state with no observed sample at its time [-].
Processing steps · Defaults · Applicability · Limitations · Provenance
Processing steps
- Match each state to the observed sample at its time.
- Keep every matched sample, counting those flagged
R_p_nonpositive(dropping them would bias Z upward); a non-positive meanV_Rgivesnot_identifiable. - Scan
R_p^model(Z)over the bounds; a non-monotonic response givesnon_monotonicwithout a fit. - Minimise
J(Z) = sum w (V_R^obs - R_p^model(Z) (I_p - I_ni))^2with a bounded scalar search. - Uncertainty from the curvature of
Jand the residual scatter (Nonewith one sample); a minimum within 0.1 % of the range from a bound givesbound_hit. The scan only brackets the search: its smallestJsitting at an end point says nothing by itself, since a clean plasma (Z_eff ~ 1.0-1.03) minimises inside the first scan interval without touching the bound.
Defaults
time_tolerance_s 50 us is a numerical convenience below the 1e-4 s
rounding of the Lane K state key (#1454); scan_points 41 is a
numerical convenience.
Applicability
Machine-independent.
Limitations
One amplitude only: Z_eff is constant across radius and time
(#1214 Sec. 10). The uncertainty is statistical; the systematic part
comes from resistive_zeff_sensitivity.
Provenance
- #1214 Secs. 9-11.
model_resistance
Machine-independentConvention-sensitive
source
model_resistance(state, z_eff, *, model, ln_lambda)
Plasma resistance a conductivity model predicts from the flux-surface Ohmic power.
| Name | Type | Unit | Description |
|---|---|---|---|
state | FluxSurfaceState | any | One slice: profiles, |
z_eff | float or array_like | - | Effective charge, constant or a profile on |
model | str or callable | any | Conductivity model, as in |
ln_lambda | float or str | - | Coulomb logarithm, as in |
| Returns | |||
| — | ModelResistance | any |
|
Convention
V_R I_p = P_Ohm is the resistive term of Romero’s Poynting balance,
so this R_p is the same quantity observed_resistance closes
for. <E.J> ~ <E.B><J.B>/<B^2> treats J_par/B as a flux function;
the parallel current is used, never j_tor (#1214 Sec. 7.2).
Raises
ValueErrorPropagated fromparallel_conductivity[-].
Processing steps · Applicability · Limitations · Provenance
Processing steps
sigma_par(psi)fromparallel_conductivity.<E.B> = (<J.B> - <J_bs.B>) / sigma_par–<J_bs.B>is zero when the state carries none.P_Ohm = int <E.B><J.B>/<B^2> dVby the trapezoid rule on the enclosed volume.R_p = P_Ohm / I_p^2.
Applicability
Machine-independent.
Limitations
<E.J> ~ <E.B><J.B>/<B^2> is exact only when J_par/B is a flux
function; the poloidal variation of the Pfirsch-Schlueter current is
dropped, which at VEST aspect ratio is part of the model-form uncertainty
rather than a resolved term. Steady state is not assumed: the current
profile is the equilibrium’s own, and only its parallel resistivity is
modelled.
Provenance
- S. P. Hirshman and D. J. Sigmar, Nucl. Fusion 21 (1981) 1079 – the flux-surface parallel Ohm’s law.
- #1214 Sec. 7.
observed_resistance
Machine-independentConvention-sensitive
source
observed_resistance(flux, *, I_ni, smoothing)
Resistive voltage and plasma resistance from Romero’s transformer balance.
Smooths the plasma current, the boundary flux and the internal inductance,
evaluates vaft.process.equilibrium.romero_flux_balance on them, and
reports V_R = V_B - V_I and R_p = V_R / (I_p - I_ni) sample by
sample with the assumptions that produced them.
| Name | Type | Unit | Description |
|---|---|---|---|
flux | RomeroBoundaryFlux | any | Boundary flux, current and |
I_ni | float or array_like | A | Non-inductively driven current. Required: |
smoothing | Smoothing | any | How the series are smoothed before differentiation; required. |
| Returns | |||
| — | ObservedResistance | any |
|
Convention
Romero’s: full-weber flux, V = -dpsi/dt; a positive V_B drives a
positive I_p and an Ohmic R_p is positive. The Ejima loop voltage
of vaft.formula.equilibrium.loop_voltage_from_total_flux differs
by sign and, on a per-radian flux, by 2 pi (#354), which is why only a
tagged RomeroBoundaryFlux gets in.
Raises
TypeErrorfluxis not aRomeroBoundaryFlux: a bare loop-voltage array carries no convention and is refused [-].ValueErrorI_nidoes not broadcast to the time axis, orvaft.process.equilibrium.romero_flux_balancerejects the series [-].
Processing steps · Defaults · Applicability · Limitations · Provenance
Processing steps
- Smooth
I_p,psi_BandL_iwithsmoothing. psi_C = psi_B + L_i I_p(Romero eqs. 35-36) and run the balance withR_p = 0so that itsV_Ris unused.V_R = V_B - V_I;R_p = V_R / (I_p - I_ni).- Flag samples whose
V_BorR_pis not positive.
Defaults
None. I_ni and smoothing have no default: an assumed value for
either moves R_p and must be the caller’s stated choice.
Applicability
Machine-independent. Closed-flux phase only, as the balance it calls.
Limitations
R_p is a closure: it absorbs every error in V_B, L_i and
I_ni. dL_i/dt from reconstructed li_3 is the noisiest term;
where inductive_fraction is large the resistance is a small difference
of large numbers and should not be fitted.
Provenance
- J. A. Romero and JET-EFDA contributors, Nucl. Fusion 50 (2010) 115002, eqs. (23)-(27), (35)-(40).
- #1214 Sec. 5 (observed path) and Sec. 4 (convention).
parallel_conductivity
Machine-independentConvention-sensitive
source
parallel_conductivity(state, z_eff, *, model, ln_lambda)
Parallel electrical conductivity on every surface of a flux-surface state.
| Name | Type | Unit | Description |
|---|---|---|---|
state | FluxSurfaceState | any | Electron profiles and geometry on a flux grid. |
z_eff | float or array_like | - | Effective charge: one value for a constant charge, or a profile with one value per surface of |
model | str or callable | any |
|
ln_lambda | float or str | - | Coulomb logarithm: a number, or |
| Returns | |||
| — | np.ndarray | S/m |
|
Convention
Parallel, not perpendicular: spitzer_nrl is 1/eta_par with the
NRL coefficient 5.2e-5 Ohm m eV^1.5 (#1188). The neoclassical models use
the circular trapped fraction from epsilon = (R_out - R_in)/(R_out + R_in)
unless the state carries its own, and R = (R_out + R_in)/2 in
nu_e* – as vaft.omas.neoclassical.compute_conductivity does.
Raises
ValueErrorz_effbelow 1, a profile whose length is not the state’s, an unknown model name, or a non-positiveln_lambda[-].
Applicability · Limitations · Provenance
Applicability
Machine-independent.
Limitations
spitzer_nrl and sauter_spitzer differ by tens of percent at
Z > 1 (linear Z against Z N(Z)); the model name is part of the
result. The axis surface has epsilon = 0 and no trapped particles.
Provenance
- O. Sauter, C. Angioni and Y. R. Lin-Liu, Phys. Plasmas 6 (1999) 2834; 9 (2002) 5140 (erratum).
- A. Redl et al., Phys. Plasmas 28 (2021) 022502.
- NRL Plasma Formulary (2019), p. 29.
per_slice_resistive_zeff
Machine-independent
source
per_slice_resistive_zeff(observed, states, *, model, ln_lambda, bounds, time_tolerance_s=5e-05)
Show source vaft/process/resistive_zeff.py, lines 1120–1190
def per_slice_resistive_zeff(
observed: ObservedResistance,
states: Sequence[FluxSurfaceState],
*,
model: Union[str, Callable],
ln_lambda: Union[float, str],
bounds: tuple,
time_tolerance_s: float = 5e-5,
) -> dict:
"""Z_eff solved at each state on its own: a diagnostic of the window estimate.
Parameters
----------
observed : ObservedResistance
Observed ``V_R`` history from :func:`observed_resistance` [any].
states : sequence of FluxSurfaceState
Flux-surface states inside ``observed.time`` [any].
model : str or callable
Conductivity model, as in :func:`parallel_conductivity` [any].
ln_lambda : float or str
Coulomb logarithm, as in :func:`parallel_conductivity` [-].
bounds : tuple of float
``(Z_min, Z_max)`` [-].
time_tolerance_s : float, optional
Largest gap between a state and its observed sample [s].
Returns
-------
dict
``time`` [s], ``zeff`` (NaN where a slice has no estimate) [-] and
``status`` per state, ordered in time [any].
Raises
------
ValueError
Propagated from :func:`infer_resistive_zeff` [-].
Processing steps
----------------
1. Order the states in time.
2. Run :func:`infer_resistive_zeff` on each state alone.
3. Keep the value only for ``ok`` and ``bound_hit``; ``bound_hit`` keeps
its bound value so the reader sees where it stuck.
Applicability
-------------
Machine-independent.
Limitations
-----------
Not the estimate: #1214 Sec. 9 fits one scalar over a window, because one
sample carries the full noise of a differentiated ``V_R`` and no residual
to judge it by. These values show whether that scalar hides a trend, and
are labelled as a diagnostic wherever they are drawn.
Provenance
----------
.. [issue] #1214 Secs. 9-10.
"""
ordered = sorted(states, key=lambda s: s.time)
times, values, statuses = [], [], []
for state in ordered:
result = infer_resistive_zeff(
observed, [state], model=model, ln_lambda=ln_lambda, bounds=bounds,
weights="uniform", time_tolerance_s=time_tolerance_s,
)
times.append(float(state.time))
statuses.append(result.status)
values.append(result.zeff if result.zeff is not None else np.nan)
return {"time": np.asarray(times), "zeff": np.asarray(values, dtype=float),
"status": tuple(statuses)}Z_eff solved at each state on its own: a diagnostic of the window estimate.
| Name | Type | Unit | Description |
|---|---|---|---|
observed | ObservedResistance | any | Observed |
states | sequence of FluxSurfaceState | any | Flux-surface states inside |
model | str or callable | any | Conductivity model, as in |
ln_lambda | float or str | - | Coulomb logarithm, as in |
bounds | tuple of float | - |
|
time_tolerance_s | float, optional | s | Largest gap between a state and its observed sample. |
| Returns | |||
| — | dict | any |
|
Raises
ValueErrorPropagated frominfer_resistive_zeff[-].
Processing steps · Applicability · Limitations · Provenance
Processing steps
- Order the states in time.
- Run
infer_resistive_zeffon each state alone. - Keep the value only for
okandbound_hit;bound_hitkeeps its bound value so the reader sees where it stuck.
Applicability
Machine-independent.
Limitations
Not the estimate: #1214 Sec. 9 fits one scalar over a window, because one
sample carries the full noise of a differentiated V_R and no residual
to judge it by. These values show whether that scalar hides a trend, and
are labelled as a diagnostic wherever they are drawn.
Provenance
- #1214 Secs. 9-10.
resistive_zeff_sensitivity
Machine-independent
source
resistive_zeff_sensitivity(flux, states, *, I_ni, smoothing, model, ln_lambda, bounds, weights, relative_perturbation=0.1, smoothing_factors=(0.5, 2.0), models=('spitzer_nrl', 'sauter', 'redl'), time_tolerance_s=5e-05)
Nominal resistive Z_eff and how far each input moves it.
| Name | Type | Unit | Description |
|---|---|---|---|
flux | RomeroBoundaryFlux | any | Boundary flux history. |
states | sequence of FluxSurfaceState | any | Flux-surface states in the window. |
I_ni | float or array_like | A | Non-inductive current, as in |
smoothing | Smoothing | any | Nominal smoothing. |
model | str or callable | any | Nominal conductivity model. |
ln_lambda | float or str | - | Coulomb logarithm. |
bounds | tuple of float | - |
|
weights | str or sequence of float | - | As in |
relative_perturbation | float, optional | - | Fractional change applied to T_e, n_e and li_3, each way. |
smoothing_factors | tuple of float, optional | - | Multipliers of the smoothing window. |
models | tuple of str, optional | - | Alternative conductivity models compared with the nominal one. |
time_tolerance_s | float, optional | s | As in |
| Returns | |||
| — | tuple | any |
|
Raises
ValueErrorPropagated frominfer_resistive_zeff[-].
Processing steps · Defaults · Applicability · Limitations · Provenance
Processing steps
- Nominal inference.
- Re-infer with T_e, n_e and li_3 scaled by
1 +/- relative_perturbation. - Re-infer with the smoothing window scaled by each factor.
- Re-infer with each alternative conductivity model, and without the bootstrap current if the states carry one.
delta = Z - Z_nominal; the largest absolute delta per input goes intonominal.sensitivity.
Defaults
relative_perturbation 0.1 and smoothing_factors (0.5, 2) are
numerical-convenience probes of local sensitivity, not uncertainty
estimates of VEST diagnostics; models is the conventional
Spitzer/Sauter/Redl ladder of #1214 Sec. 3.
Applicability
Machine-independent.
Limitations
One-at-a-time perturbations; no correlation between inputs. NEO enters only as a callable model the caller supplies.
Provenance
- #1214 Sec. 12 and Phase F.
smooth_local_polynomial
Machine-independent
source
smooth_local_polynomial(time, values, *, window_s, order)
Show source vaft/process/resistive_zeff.py, lines 431–503
def smooth_local_polynomial(time, values, *, window_s: float, order: int) -> np.ndarray:
"""Local least-squares polynomial smoothing on a non-uniform time axis.
A Savitzky-Golay filter written for unevenly spaced samples: at each
sample a polynomial of ``order`` is fitted by least squares to every
sample within ``window_s / 2`` of it, and its value there is returned.
EFIT slices arrive at about 1 ms with gaps, which the uniform-grid filter
cannot take.
Parameters
----------
time : array_like
Sample times, strictly increasing [s].
values : array_like
The sampled quantity, same length as ``time`` [any].
window_s : float
Full width of the fitting window [s].
order : int
Polynomial order; at least ``order + 2`` samples must fall in every
window [-].
Returns
-------
np.ndarray
Smoothed values on ``time`` [any].
Raises
------
ValueError
Lengths differ, time does not strictly increase, or a window holds
fewer than ``order + 2`` samples -- a fit with no redundancy is an
interpolation, not a smoothing, and is refused [-].
Processing steps
----------------
1. For each sample, select the samples with ``|t - t_i| <= window_s/2``.
2. Fit a polynomial of ``order`` in ``t - t_i`` by least squares.
3. Return its constant term.
Applicability
-------------
Machine-independent.
Limitations
-----------
The window shrinks to one side at the ends of the record, where the fit
extrapolates and is least reliable; cut a margin of ``window_s / 2`` off
the inference window if the end samples matter.
Provenance
----------
.. [1] A. Savitzky and M. J. E. Golay, Anal. Chem. 36 (1964) 1627 --
the uniform-grid special case.
"""
t = np.asarray(time, dtype=float)
x = np.asarray(values, dtype=float)
if t.shape != x.shape or t.ndim != 1:
raise ValueError("time and values must be one-dimensional and the same length")
if np.any(np.diff(t) <= 0.0):
raise ValueError("time must strictly increase")
order = int(order)
half = 0.5 * float(window_s)
out = np.empty_like(x)
for i, centre in enumerate(t):
mask = np.abs(t - centre) <= half + 1e-12
if mask.sum() < order + 2:
raise ValueError(
f"{mask.sum()} samples within {window_s:g} s of t = {centre:.4f} s; "
f"order {order} needs at least {order + 2} -- widen the window"
)
coeffs = np.polynomial.polynomial.polyfit(t[mask] - centre, x[mask], order)
out[i] = coeffs[0]
return outLocal least-squares polynomial smoothing on a non-uniform time axis.
A Savitzky-Golay filter written for unevenly spaced samples: at each
sample a polynomial of order is fitted by least squares to every
sample within window_s / 2 of it, and its value there is returned.
EFIT slices arrive at about 1 ms with gaps, which the uniform-grid filter
cannot take.
| Name | Type | Unit | Description |
|---|---|---|---|
time | array_like | s | Sample times, strictly increasing. |
values | array_like | any | The sampled quantity, same length as |
window_s | float | s | Full width of the fitting window. |
order | int | - | Polynomial order; at least |
| Returns | |||
| — | np.ndarray | any | Smoothed values on |
Raises
ValueErrorLengths differ, time does not strictly increase, or a window holds fewer thanorder + 2samples – a fit with no redundancy is an interpolation, not a smoothing, and is refused [-].
Processing steps · Applicability · Limitations · Provenance
Processing steps
- For each sample, select the samples with
|t - t_i| <= window_s/2. - Fit a polynomial of
orderint - t_iby least squares. - Return its constant term.
Applicability
Machine-independent.
Limitations
The window shrinks to one side at the ends of the record, where the fit
extrapolates and is least reliable; cut a margin of window_s / 2 off
the inference window if the end samples matter.
Provenance
- A. Savitzky and M. J. E. Golay, Anal. Chem. 36 (1964) 1627 – the uniform-grid special case.