Process reference: zeff_projection

Generated from the docstrings of vaft.process.zeff_projection: 6 public functions. Each entry is what vaft.process.describe("zeff_projection.<name>") prints. All process categories

Overview

The composition model (#1565) gives a local profile Z_eff(rho); the Romero transformer balance (#1214, Lane Z) gives one scalar Z_eff^res, the constant a conductivity model needs to reproduce the observed plasma resistance. They are different quantities and are compared only through an explicit forward projection (issue #1566): the scalar that makes the same conductivity model, on the same flux-surface states, produce the same resistance – or, over a window, the same resistive voltage under the same objective – as the profile does.

The chain::

Z_eff(psi_N) on a FluxSurfaceState      [composition, #1565]
-> sigma_par(psi_N; Z_eff(psi_N))       [Lane Z's model, surface by surface]
-> R_p^profile = P_Ohm / I_p^2          [vaft.process.resistive_zeff.model_resistance]
-> Z* with R_p^model(Z*) = R_p^profile  [one slice: a bounded root]
-> or argmin_Z sum w (V_R^profile - V_R^model(Z))^2 over a window
                                        [vaft.process.resistive_zeff.infer_resistive_zeff]

Nothing here writes core_profiles.zeff: the projection is a model-space scalar, never a profile. A flat profile built from a resistive scalar needs the explicit assumption of flat_profile_from_resistive.

SymbolMeaningUnit
Z_eff(psi_N)effective-charge profile on the state's surfaces-
R_pplasma resistance, P_Ohm / I_p^2Ohm
Z_eff^res,equivconstant Z_eff giving the profile's R_p (or V_R(t))-
Z_eff^res,obsLane Z's scalar inferred from the observed V_R-

Same model, same states, same objective. The profile’s conductivity is Lane Z’s vaft.process.resistive_zeff.parallel_conductivity evaluated surface by surface at that surface’s Z_eff, so the profile and the scalar differ only in Z_eff; the window scalar is Lane Z’s own vaft.process.resistive_zeff.infer_resistive_zeff fed the profile’s predicted voltage, so the projection is defined in the observable space the experimental scalar lives in.

Functions

flat_profile_from_resistiveA flat Z_eff profile from a resistive scalar – only under the stated flat assumption. Convention
profile_conductivity_modelA conductivity-model callable that evaluates Lane Z’s model at a radially varying Z_eff. Convention
project_window_to_resistive_scalarThe window scalar Lane Z’s estimator would infer if the profile were the truth. Convention
project_zeff_profile_to_resistive_scalarThe constant Z_eff whose model resistance equals that of a Z_eff profile, on one slice. Convention
spitzer_resistive_equivalent_zeffAnalytic resistive equivalent of a Z_eff profile under Spitzer (NRL) resistivity. Convention
zeff_profile_for_stateThe atomic-data Z_eff profile on a flux-surface state’s own surfaces. Convention

flat_profile_from_resistive

Machine-independentConvention-sensitive source
flat_profile_from_resistive(zeff_resistive, state, *, assumption)
Show source vaft/process/zeff_projection.py, lines 427–467
def flat_profile_from_resistive(zeff_resistive: float, state: Any, *, assumption: str) -> np.ndarray:
    """A flat Z_eff profile from a resistive scalar -- only under the stated flat assumption.

    Parameters
    ----------
    zeff_resistive : float
        A resistive scalar (Lane Z), at least 1 [-].
    state : FluxSurfaceState
        The surfaces to put it on [any].
    assumption : str
        Must be ``"flat"``: the caller states the modelling assumption [-].

    Returns
    -------
    np.ndarray
        ``Z_eff(psi_N) = zeff_resistive`` on every surface [-].

    Raises
    ------
    ValueError
        Any assumption other than ``"flat"``, or a scalar below 1.

    Convention
    ----------
    #1566 Sec. 6: a modelling assumption, never a measurement or an
    inference of the profile; nothing here writes it to ``core_profiles``.

    Applicability
    -------------
    Machine-independent.

    Provenance
    ----------
    .. [issue] #1566 Sec. 6.
    """
    if assumption != "flat":
        raise ValueError("a profile from a resistive scalar needs assumption='flat', stated explicitly")
    value = float(zeff_resistive)
    if not value >= 1.0:
        raise ValueError(f"zeff_resistive must be at least 1, got {zeff_resistive!r}")
    return np.full(np.shape(state.psi_norm), value)

A flat Z_eff profile from a resistive scalar – only under the stated flat assumption.

NameTypeUnitDescription
zeff_resistivefloat-

A resistive scalar (Lane Z), at least 1.

stateFluxSurfaceStateany

The surfaces to put it on.

assumptionstr-

Must be "flat": the caller states the modelling assumption.

Returns
—np.ndarray-

Z_eff(psi_N) = zeff_resistive on every surface.

Convention

#1566 Sec. 6: a modelling assumption, never a measurement or an inference of the profile; nothing here writes it to core_profiles.

Raises

  • ValueError Any assumption other than "flat", or a scalar below 1.
Applicability · Provenance

Applicability

Machine-independent.

Provenance

  1. #1566 Sec. 6.

profile_conductivity_model

Machine-independentConvention-sensitive source
profile_conductivity_model(zeff_profile, *, base_model='redl', ln_lambda='sauter')
Show source vaft/process/zeff_projection.py, lines 105–175
def profile_conductivity_model(
    zeff_profile: Any,
    *,
    base_model: str = "redl",
    ln_lambda: Union[float, str] = "sauter",
) -> Callable:
    """A conductivity-model callable that evaluates Lane Z's model at a radially varying Z_eff.

    Parameters
    ----------
    zeff_profile : array-like
        Z_eff on the state's ``psi_norm`` surfaces, at least 1 [-].
    base_model : str, optional
        One of :data:`vaft.process.resistive_zeff.CONDUCTIVITY_MODELS` [-].
    ln_lambda : float or str, optional
        Coulomb logarithm as :func:`~vaft.process.resistive_zeff.parallel_conductivity`
        takes it [-].

    Returns
    -------
    callable
        ``model(state, z, lnl) -> sigma(psi_N)`` for
        :func:`~vaft.process.resistive_zeff.model_resistance`; the scalar
        ``z`` it is handed is ignored [any].

    Raises
    ------
    ValueError
        At call time: a profile that does not match the state's surfaces, or
        that is non-finite or below 1.

    Convention
    ----------
    Surface ``i`` gets ``parallel_conductivity(state, Z_eff[i])[i]``: the
    unmodified scalar model, so a flat profile reproduces it exactly and no
    kernel is copied.  ``model_resistance`` records ``z_eff = 1`` for this
    route; the profile is the record of what was used.  The ``ln_lambda`` it
    is built with must be the one ``model_resistance`` is called with; a
    mismatch is refused, not silently overridden.

    Applicability
    -------------
    Machine-independent.

    Provenance
    ----------
    .. [issue] #1566 Sec. 3 (the Redl/Sauter projection through Lane Z's
               conductivity models), #1214 (the models), #1486 (Lane Z).
    """
    from vaft.process.resistive_zeff import _ln_lambda_profile, parallel_conductivity

    profile = np.asarray(zeff_profile, dtype=float)

    def model(state, _z, lnl):
        z = _profile(state, profile)
        own, _ = _ln_lambda_profile(state, ln_lambda)
        if not np.allclose(np.asarray(lnl, dtype=float), own, rtol=1e-12, atol=0.0):
            raise ValueError(
                "model_resistance was given a different ln_lambda from the one this profile model was "
                f"built with ({ln_lambda!r}); build it with the same ln_lambda"
            )
        sigma = np.empty(z.shape)
        for value in np.unique(z):
            at = z == value
            sigma[at] = parallel_conductivity(state, float(value), model=base_model, ln_lambda=ln_lambda)[at]
        return sigma

    model.zeff_profile = profile
    model.base_model = base_model
    model.__name__ = f"profile_{base_model}"
    return model

A conductivity-model callable that evaluates Lane Z’s model at a radially varying Z_eff.

NameTypeUnitDescription
zeff_profilearray-like-

Z_eff on the state’s psi_norm surfaces, at least 1.

base_modelstr, optional-

One of vaft.process.resistive_zeff.CONDUCTIVITY_MODELS.

ln_lambdafloat or str, optional-

Coulomb logarithm as vaft.process.resistive_zeff.parallel_conductivity takes it.

Returns
—callableany

model(state, z, lnl) -> sigma(psi_N) for vaft.process.resistive_zeff.model_resistance; the scalar z it is handed is ignored.

Convention

Surface i gets parallel_conductivity(state, Z_eff[i])[i]: the unmodified scalar model, so a flat profile reproduces it exactly and no kernel is copied. model_resistance records z_eff = 1 for this route; the profile is the record of what was used. The ln_lambda it is built with must be the one model_resistance is called with; a mismatch is refused, not silently overridden.

Raises

  • ValueError At call time: a profile that does not match the state’s surfaces, or that is non-finite or below 1.
Applicability · Provenance

Applicability

Machine-independent.

Provenance

  1. #1566 Sec. 3 (the Redl/Sauter projection through Lane Z’s conductivity models), #1214 (the models), #1486 (Lane Z).

project_window_to_resistive_scalar

Machine-independentConvention-sensitive source
project_window_to_resistive_scalar(states, zeff_profiles, *, model='redl', ln_lambda='sauter', bounds=(1.0, 10.0), weights='uniform', profile_source='caller')

The window scalar Lane Z’s estimator would infer if the profile were the truth.

NameTypeUnitDescription
statessequence of FluxSurfaceStateany

The window’s slices.

zeff_profilessequence of array-like-

One Z_eff profile per state, on its surfaces.

modelstr, optional-

Conductivity model.

ln_lambdafloat or str, optional-

Coulomb logarithm.

boundstuple of float, optional-

Search interval.

weightsstr or sequence of float, optional-

As vaft.process.resistive_zeff.infer_resistive_zeff.

profile_sourcestr, optional-

Where the profiles came from.

Returns
—ResistiveZeffProjectionany

The scalar, the per-slice resistances of the profile and of the scalar, the window and Lane Z’s status.

Convention

#1566 Sec. 7: a spatio-temporal model-equivalent scalar, comparable with Z_eff^res,obs because the objective is literally the same function. The drive is |I_p|: R_p is a dissipation and does not depend on the current’s sign convention. Near Z_eff = 1 the estimator reports bound_hit (a ~0.3 % bias at the lower bound), exactly as it does for the observed scalar.

Raises

  • ValueError Unequal numbers of states and profiles, two states at one time, or a profile off its state’s surfaces.
Processing steps · Applicability · Provenance

Processing steps

  1. Per slice, R_p^profile(t) as in project_zeff_profile_to_resistive_scalar.
  2. An ObservedResistance whose V_R = R_p^profile (I_p - I_ni) with I_ni = 0 – the profile’s voltage, as if observed.
  3. Lane Z’s infer_resistive_zeff on it: the same objective sum w (V_R - R_p^model(Z) I_p)^2 and bounds as the experimental scalar.

Applicability

Machine-independent.

Provenance

  1. #1566 Sec. 7, #1214 Sec. 10.

project_zeff_profile_to_resistive_scalar

Machine-independentConvention-sensitive source
project_zeff_profile_to_resistive_scalar(state, zeff_profile, *, model='redl', ln_lambda='sauter', bounds=(1.0, 10.0), profile_source='caller')

The constant Z_eff whose model resistance equals that of a Z_eff profile, on one slice.

NameTypeUnitDescription
stateFluxSurfaceStateany

One slice.

zeff_profilearray-like-

Z_eff on the state’s psi_norm surfaces.

modelstr, optional-

Conductivity model, as Lane Z names them.

ln_lambdafloat or str, optional-

Coulomb logarithm.

boundstuple of float, optional-

Search interval for the scalar.

profile_sourcestr, optional-

Where the profile came from, for provenance.

Returns
—ResistiveZeffProjectionany

The scalar, both resistances, the bracket and status.

Convention

The projection is defined in resistance space with the same states and model on both sides (#1566 Sec. 1); a flat profile returns its own value.

Raises

  • ValueError A profile off the state’s surfaces, or no root inside bounds (the profile’s resistance is outside what a constant Z_eff in bounds can give).
Processing steps · Applicability · Provenance

Processing steps

  1. R_p^profile from model_resistance with profile_conductivity_model.
  2. A bounded root of R_p^model(Z) - R_p^profile (brentq).

Applicability

Machine-independent.

Provenance

  1. #1566 Sec. 1 and 3.

spitzer_resistive_equivalent_zeff

Machine-independentConvention-sensitive source
spitzer_resistive_equivalent_zeff(state, zeff_profile, *, ln_lambda='sauter')
Show source vaft/process/zeff_projection.py, lines 178–232
def spitzer_resistive_equivalent_zeff(state: Any, zeff_profile: Any, *, ln_lambda: Union[float, str] = "sauter") -> float:
    """Analytic resistive equivalent of a Z_eff profile under Spitzer (NRL) resistivity.

    Parameters
    ----------
    state : FluxSurfaceState
        One slice (``bootstrap = none``) [any].
    zeff_profile : array-like
        Z_eff on the state's ``psi_norm`` surfaces [-].
    ln_lambda : float or str, optional
        Coulomb logarithm [-].

    Returns
    -------
    float
        ``int Z w dV / int w dV`` with ``w = eta(Z=1) <J.B>^2/<B^2>``, the
        Ohmic-dissipation weight [-].

    Raises
    ------
    ValueError
        A profile off the state's surfaces, a state carrying a bootstrap
        current (the weight is then not linear in Z), or a zero weight.

    Convention
    ----------
    NRL Spitzer resistivity is linear in Z_eff, so ``P_Ohm`` is a weighted
    integral of Z_eff and the equivalent scalar is that weighted mean -- the
    weight is the dissipation ``eta_1 j^2``, not the volume or the density.
    Integrated with the same trapezoid rule on the enclosed volume as
    :func:`~vaft.process.resistive_zeff.model_resistance`.

    Applicability
    -------------
    Machine-independent.

    Provenance
    ----------
    .. [issue] #1566 Sec. 2 (the Spitzer reference projection).
    """
    from scipy.integrate import trapezoid

    from vaft.process.resistive_zeff import parallel_conductivity

    if getattr(state, "j_bootstrap_dot_b", None) is not None:
        raise ValueError("the analytic Spitzer projection needs a state without bootstrap current")
    z = _profile(state, zeff_profile)
    sigma_1 = parallel_conductivity(state, 1.0, model="spitzer_nrl", ln_lambda=ln_lambda)
    jb = np.asarray(state.j_dot_b, dtype=float)
    weight = jb**2 / np.asarray(state.b2_average, dtype=float) / sigma_1
    volume = np.asarray(state.volume, dtype=float)
    denominator = trapezoid(weight, volume)
    if not denominator > 0.0:
        raise ValueError("the dissipation weight integrates to zero")
    return float(trapezoid(weight * z, volume) / denominator)

Analytic resistive equivalent of a Z_eff profile under Spitzer (NRL) resistivity.

NameTypeUnitDescription
stateFluxSurfaceStateany

One slice (bootstrap = none).

zeff_profilearray-like-

Z_eff on the state’s psi_norm surfaces.

ln_lambdafloat or str, optional-

Coulomb logarithm.

Returns
—float-

int Z w dV / int w dV with w = eta(Z=1) <J.B>^2/<B^2>, the Ohmic-dissipation weight.

Convention

NRL Spitzer resistivity is linear in Z_eff, so P_Ohm is a weighted integral of Z_eff and the equivalent scalar is that weighted mean – the weight is the dissipation eta_1 j^2, not the volume or the density. Integrated with the same trapezoid rule on the enclosed volume as vaft.process.resistive_zeff.model_resistance.

Raises

  • ValueError A profile off the state’s surfaces, a state carrying a bootstrap current (the weight is then not linear in Z), or a zero weight.
Applicability · Provenance

Applicability

Machine-independent.

Provenance

  1. #1566 Sec. 2 (the Spitzer reference projection).

zeff_profile_for_state

Machine-independentConvention-sensitive source
zeff_profile_for_state(state, elemental_weights, **options)
Show source vaft/process/zeff_projection.py, lines 470–512
def zeff_profile_for_state(state: Any, elemental_weights: Mapping[str, float], **options: Any):
    """The atomic-data Z_eff profile on a flux-surface state's own surfaces.

    Parameters
    ----------
    state : FluxSurfaceState
        One slice; its ``T_e``, ``n_e`` and enclosed volume are used [any].
    elemental_weights : mapping
        Relative elemental densities, e.g. ``{"C": 1, "O": 1}``; further
        keyword arguments go to
        :func:`vaft.process.impurity.resolve_radial_composition`
        (``normalization``, ``target_zeff``, ``ionization``, ``plasma_age_s``,
        ``projection``/``resistive_target``, ``tables``...) [-].

    Returns
    -------
    RadialImpurityComposition
        On ``psi_norm``, with ``dV`` from the state's volume [any].

    Raises
    ------
    ValueError
        As ``resolve_radial_composition``.

    Convention
    ----------
    The profile is built from the very T_e and n_e the conductivity model
    uses, so composition and resistance share one state.

    Applicability
    -------------
    Machine-independent.

    Provenance
    ----------
    .. [issue] #1566 Sec. 5 (connect #1565 profiles to #1214).
    """
    from vaft.process.impurity import resolve_radial_composition

    volume = np.asarray(state.volume, dtype=float)
    edges = np.concatenate(([volume[0]], 0.5 * (volume[1:] + volume[:-1]), [volume[-1]]))
    return resolve_radial_composition(state.T_e, state.n_e, state.psi_norm, elemental_weights,
                                      volume_weights=np.diff(edges), time=float(state.time), **options)

The atomic-data Z_eff profile on a flux-surface state’s own surfaces.

NameTypeUnitDescription
stateFluxSurfaceStateany

One slice; its T_e, n_e and enclosed volume are used.

elemental_weightsmapping-

Relative elemental densities, e.g. {"C": 1, "O": 1}; further keyword arguments go to vaft.process.impurity.resolve_radial_composition (normalization, target_zeff, ionization, plasma_age_s, projection/resistive_target, tables…).

Returns
—RadialImpurityCompositionany

On psi_norm, with dV from the state’s volume.

Convention

The profile is built from the very T_e and n_e the conductivity model uses, so composition and resistance share one state.

Raises

  • ValueError As resolve_radial_composition.
Applicability · Provenance

Applicability

Machine-independent.

Provenance

  1. #1566 Sec. 5 (connect #1565 profiles to #1214).

results matching ""

    No results matching ""