Process reference: impurity

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

Overview

One resolved impurity composition for every consumer of Z_eff (issue #1565, Stage B): a species list – element, charge state, mass and relative density, kept apart – with the target effective charge it is closed at, the absolute fractions n_s / n_e that closure gives, the reduced pseudo-impurity and the main-ion dilution, and a kind saying how the composition is known. The algebra is vaft.formula.impurity; this module decides which composition applies and records why.

The chain::

core_profiles ion[] labelled measured        -> kind "measured"
explicit composition argument                -> kind "explicit"
derived composition (an atomic-data model)   -> kind "derived"
core_profiles ion[] labelled assumed/unlabelled -> kind "assumed"
machine preset (``"vest"``: vest.yaml impurity_model) -> kind "assumed"
-> target Z_eff: core_profiles.zeff labelled measured, else the composition's own
-> n_s/n_e, n_main/n_e, S1, S2, Z_I,eff, f_dil   [ResolvedImpurityComposition]
SymbolMeaningUnit
w_srelative impurity particle density, sum_s w_s = 1-
Z_scharge state of impurity species s-
S_1, S_2sum_s w_s Z_s and sum_s w_s Z_s^2-
Z_I,effcharge of the reduced pseudo-impurity, S_2 / S_1-
f_dilmain-ion dilution 1 - n_main / n_e-

Kinds are not interchangeable. measured is a composition a diagnostic determined; explicit is what the caller passed; derived is computed from other data by a stated model; assumed is a preset or a stored composition that says it was assumed (or says nothing). A resistive Z_eff inferred from the transformer balance (#1214) is none of these: it is accepted only as resistive_zeff= and carried beside the composition under its own provenance, never used as a target and never turned into a composition (#1566).

Provenance records on core_profiles use one grammar, written by composition_record_text and read by composition_record_origin: origin=<measured|assumed|derived|inferred>; method=<m>[; key=value...].

Functions

charge_state_momentsCharge-state distribution of one element and its first two charge moments.
composition_from_fractionsAn impurity composition from parallel lists of elements, relative fractions and charge states.
composition_from_modelAn impurity composition from a parsed machine impurity_model record.
composition_record_originThe origin a composition record states, or None when it states none.
composition_record_textThe record a writer stores beside a composition or Z_eff it put into core_profiles.
populate_impurity_profilesA copy of ods whose core_profiles slice carries the resolved ion composition. Convention
populate_radial_impurity_profilesA copy of ods whose core_profiles slice carries a charge-state-resolved composition. Convention
populate_zeff_profileA copy of ods whose core_profiles slice carries the resolved Z_eff(rho). Convention
resolve_impurity_compositionResolve the impurity composition that applies, close it at its Z_eff and reduce it. Convention
resolve_radial_compositionRadial Z_eff and reduced impurity from an elemental composition and atomic-data charge states. Convention
surface_composition_profileA copy of a GACODE profile whose ions are the main ion plus an explicit impurity composition. Convention

charge_state_moments

Machine-independent source
charge_state_moments(element, te_eV, ne_m3, *, ionization='coronal', age_s=None, tables=None, cache_dir=None)

Charge-state distribution of one element and its first two charge moments.

NameTypeUnitDescription
elementstr-

Element symbol.

te_eVarray-likeeV

Electron temperature, positive.

ne_m3array-likem^-3

Electron density, positive.

ionizationstr, optional-

"coronal" (steady ionisation balance) or "transient" (a parcel age_s after entering as neutrals).

age_sfloat, optionals

Ionisation age for "transient".

tablesmapping, optionalany

{element: (acd, scd)} ADF11 tables or paths overriding the OPEN-ADAS defaults.

cache_dirstr, optional-

ADF11 cache directory.

Returns
—dictany

fractions (charge on the last axis, neutral first), mean_charge and mean_square_charge [-], coronal_mean_charge [-], relaxation_time_s [s] and the tables used.

Raises

  • ValueError An unknown ionization model, "transient" without an age, or non-positive profiles.
Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

No transport and no charge exchange: the transient model is an age, not an impurity-transport solution (Aurora, #897).

Provenance

  1. H. P. Summers, The ADAS User Manual, version 2.6 (2004), ADF11.
  2. #1565 Sec. 8.

composition_from_fractions

Machine-independent source
composition_from_fractions(elements, fractions, charge_states, *, target_zeff, masses=None, main_ion='H', status='explicit', source='caller')
Show source vaft/process/impurity.py, lines 302–369
def composition_from_fractions(
    elements: Sequence[str],
    fractions: Sequence[float],
    charge_states: Sequence[float],
    *,
    target_zeff: Optional[float],
    masses: Optional[Sequence[float]] = None,
    main_ion: str = "H",
    status: str = "explicit",
    source: str = "caller",
) -> ImpurityComposition:
    """An impurity composition from parallel lists of elements, relative fractions and charge states.

    The form issue #1565 Sec. 2 names (``species=["C", "O", "N"]``,
    ``fractions=[0.3, 0.4, 0.3]``) with the one addition it requires: the
    charge state of each species is stated, never read off the atomic number.

    Parameters
    ----------
    elements : sequence of str
        Element symbols [-].
    fractions : sequence of float
        Relative particle densities, non-negative; normalised internally, the
        given values kept in ``input_record`` [-].
    charge_states : sequence of float
        Ionic charge of each species, in ``(0, Z_n]`` [-].
    target_zeff : float or None
        Plasma effective charge to close the composition at [-].
    masses : sequence of float, optional
        Species masses; default the standard atomic weights [u].
    main_ion : str, optional
        Main-ion element, default ``"H"`` [-].
    status : str, optional
        One of :data:`COMPOSITION_KINDS`, default ``"explicit"`` [-].
    source : str, optional
        Where the composition came from, for provenance [-].

    Returns
    -------
    ImpurityComposition
        The validated composition [any].

    Raises
    ------
    ValueError
        Lists of unequal length, an unknown element, a charge state outside
        ``(0, Z_n]``, negative fractions or a bad status.

    Applicability
    -------------
    Machine-independent.
    """
    n = len(elements)
    if len(fractions) != n or len(charge_states) != n or (masses is not None and len(masses) != n):
        raise ValueError("elements, fractions, charge_states (and masses) must have equal lengths")
    species = tuple(
        ImpuritySpecies(
            element=str(elements[k]),
            charge_state=float(charge_states[k]),
            relative_density=float(fractions[k]),
            mass=None if masses is None else float(masses[k]),
        )
        for k in range(n)
    )
    record = {"elements": list(elements), "fractions": [float(v) for v in fractions],
              "charge_states": [float(v) for v in charge_states]}
    return ImpurityComposition(species=species, target_zeff=target_zeff, main_ion=main_ion,
                               status=status, source=source, input_record=record)

An impurity composition from parallel lists of elements, relative fractions and charge states.

The form issue #1565 Sec. 2 names (species=["C", "O", "N"], fractions=[0.3, 0.4, 0.3]) with the one addition it requires: the charge state of each species is stated, never read off the atomic number.

NameTypeUnitDescription
elementssequence of str-

Element symbols.

fractionssequence of float-

Relative particle densities, non-negative; normalised internally, the given values kept in input_record.

charge_statessequence of float-

Ionic charge of each species, in (0, Z_n].

target_zefffloat or None-

Plasma effective charge to close the composition at.

massessequence of float, optionalu

Species masses; default the standard atomic weights.

main_ionstr, optional-

Main-ion element, default "H".

statusstr, optional-

One of COMPOSITION_KINDS, default "explicit".

sourcestr, optional-

Where the composition came from, for provenance.

Returns
—ImpurityCompositionany

The validated composition.

Raises

  • ValueError Lists of unequal length, an unknown element, a charge state outside (0, Z_n], negative fractions or a bad status.
Applicability

Applicability

Machine-independent.

composition_from_model

Machine-independent source
composition_from_model(model, *, source=None)
Show source vaft/process/impurity.py, lines 372–422
def composition_from_model(model: Mapping[str, Any], *, source: Optional[str] = None) -> ImpurityComposition:
    """An impurity composition from a parsed machine ``impurity_model`` record.

    Parameters
    ----------
    model : mapping
        A record as :func:`vaft.machine_mapping.core_profiles.vest_impurity_model`
        returns it: ``status``, ``species`` (element, charge_state, mass,
        relative_density), ``target_zeff``, ``reduction``, ``main_ion`` and
        ``provenance`` [any].
    source : str, optional
        Provenance label; default the record's own ``provenance.source`` [-].

    Returns
    -------
    ImpurityComposition
        The composition, with ``status`` ``"assumed"``, ``"measured"`` or
        ``"derived"`` as the preset's own ``status`` (``inferred`` and any
        other value map to ``derived``) [any].

    Raises
    ------
    ValueError
        A malformed record (as :class:`ImpuritySpecies` validates it).

    Applicability
    -------------
    Machine-independent.
    """
    species = tuple(
        ImpuritySpecies(
            element=str(item["element"]),
            charge_state=float(item["charge_state"]),
            relative_density=float(item["relative_density"]),
            mass=float(item["mass"]) if item.get("mass") is not None else None,
        )
        for item in model["species"]
    )
    provenance = dict(model.get("provenance") or {})
    # measured stays measured, inferred is a derived kind (COMPOSITION_KINDS has no
    # "inferred"), assumed stays assumed; anything else is derived
    status = {"assumed": "assumed", "measured": "measured", "inferred": "derived"}.get(model.get("status"), "derived")
    return ImpurityComposition(
        species=species,
        target_zeff=model.get("target_zeff"),
        main_ion=str(model.get("main_ion", "H")),
        reduction=str(model.get("reduction", "preserve_charge_z2_mass")),
        status=status,
        source=source or str(provenance.get("source", "machine preset")),
        input_record={"model_status": model.get("status"), **provenance},
    )

An impurity composition from a parsed machine impurity_model record.

NameTypeUnitDescription
modelmappingany

A record as vaft.machine_mapping.core_profiles.vest_impurity_model returns it: status, species (element, charge_state, mass, relative_density), target_zeff, reduction, main_ion and provenance.

sourcestr, optional-

Provenance label; default the record’s own provenance.source.

Returns
—ImpurityCompositionany

The composition, with status "assumed", "measured" or "derived" as the preset’s own status (inferred and any other value map to derived).

Raises

  • ValueError A malformed record (as ImpuritySpecies validates it).
Applicability

Applicability

Machine-independent.

composition_record_origin

Machine-independent source
composition_record_origin(record)
Show source vaft/process/impurity.py, lines 464–490
def composition_record_origin(record: Any) -> Optional[str]:
    """The ``origin`` a composition record states, or ``None`` when it states none.

    Parameters
    ----------
    record : str or None
        A ``*_fit.parameters`` record [-].

    Returns
    -------
    str or None
        One of :data:`COMPOSITION_ORIGINS`, ``"unknown"`` for an ``origin``
        outside them, or ``None`` for an absent record or one without an
        ``origin`` field (an unlabelled value) [-].

    Applicability
    -------------
    Machine-independent.
    """
    if record is None:
        return None
    for part in str(record).replace("\n", ";").split(";"):
        match = _RECORD_FIELD.fullmatch(part)
        if match and match.group(1).lower() == "origin":
            origin = match.group(2).strip().lower()
            return origin if origin in COMPOSITION_ORIGINS else "unknown"
    return None

The origin a composition record states, or None when it states none.

NameTypeUnitDescription
recordstr or None-

A *_fit.parameters record.

Returns
—str or None-

One of COMPOSITION_ORIGINS, "unknown" for an origin outside them, or None for an absent record or one without an origin field (an unlabelled value).

Applicability

Applicability

Machine-independent.

composition_record_text

Machine-independent source
composition_record_text(origin, method, **fields)
Show source vaft/process/impurity.py, lines 428–461
def composition_record_text(origin: str, method: str, **fields: Any) -> str:
    """The record a writer stores beside a composition or Z_eff it put into ``core_profiles``.

    Parameters
    ----------
    origin : str
        One of :data:`COMPOSITION_ORIGINS` [-].
    method : str
        How the value was obtained, e.g. ``impurity_model_preset``; further
        keyword arguments are appended as ``key=value`` fields, in order [-].

    Returns
    -------
    str
        ``origin=<origin>; method=<method>[; key=value...]`` [-].

    Raises
    ------
    ValueError
        An unknown origin, or a ``;`` or ``=`` inside a value.

    Applicability
    -------------
    Machine-independent.
    """
    if origin not in COMPOSITION_ORIGINS:
        raise ValueError(f"origin must be one of {COMPOSITION_ORIGINS}, got {origin!r}")
    parts = [f"origin={origin}", f"method={method}"]
    for key, value in fields.items():
        text = f"{value:g}" if isinstance(value, float) else str(value)
        if ";" in text or "=" in text:
            raise ValueError(f"field {key} carries a separator: {text!r}")
        parts.append(f"{key}={text}")
    return "; ".join(parts)

The record a writer stores beside a composition or Z_eff it put into core_profiles.

NameTypeUnitDescription
originstr-

One of COMPOSITION_ORIGINS.

methodstr-

How the value was obtained, e.g. impurity_model_preset; further keyword arguments are appended as key=value fields, in order.

Returns
—str-

origin=<origin>; method=<method>[; key=value...].

Raises

  • ValueError An unknown origin, or a ; or = inside a value.
Applicability

Applicability

Machine-independent.

populate_impurity_profiles

Machine-independentConvention-sensitive source
populate_impurity_profiles(ods, resolved, *, time=None, tolerance=0.0005, method=None, write_zeff=True)

A copy of ods whose core_profiles slice carries the resolved ion composition.

NameTypeUnitDescription
odsODSany

Source; never modified.

resolvedResolvedImpurityCompositionany

From resolve_impurity_composition; not of kind measured.

timefloat, optionals

Slice time; default the resolved composition’s own.

tolerancefloat, optionals

Largest |t_slice - time| accepted.

methodstr, optional-

method= field of the records; default <kind>_composition.

write_zeffbool, optional-

Also write zeff through populate_zeff_profile.

Returns
—ODSany

A deep copy whose slice ion[] is the hydrogenic main ion (density diluted to n_e (1 - sum Z_s n_s/n_e) / Z_m) followed by one entry per impurity species (label, z_ion, element.0.z_n/a, density, density_thermal, density_fit.parameters).

Convention

origin=assumed for an explicit or preset composition, derived for one computed from other data (atomic data, a measured Z_eff), in the grammar composition_record_origin reads. Impurities share the main ion’s temperature: an assumption, recorded in the density record as temperature=main_ion.

Raises

  • ValueError A measured composition (resolved or stored in the target slice), a time that is not the resolved composition’s, no slice at the time, no electron density, a stored main ion that is not hydrogenic, or two stored hydrogenic ions.
Processing steps · Input semantics · Output semantics · Applicability · Limitations · Provenance

Processing steps

  1. Match the slice by time and read n_e and its rho grid.
  2. Keep the existing hydrogenic main ion entry whole (temperature, velocity and their records) or create H+; drop every stored impurity entry.
  3. Write the main ion’s diluted density and each impurity’s n_e * n_s/n_e (a profile composition is interpolated in rho).
  4. Give each impurity the main ion’s temperature, its temperature_fit.parameters record unchanged (so a Ti reader classifies every ion alike) and its toroidal rotation; label each density origin=.... A point where the composition is undefined is filled from its neighbours in rho and counted (filled_points).
  5. Write zeff (populate_zeff_profile), or, with write_zeff=False, drop a non-measured zeff that the new species list would contradict.

Input semantics

A core_profiles slice with an electron density, and a composition resolved independently of it (preset, explicit, derived).

Output semantics

The same slice with an explicit species list: assumed or derived, never measured, as each record says.

Applicability

Machine-independent.

Limitations

A non-hydrogenic main ion is refused. Only this slice is written. The impurities’ copied temperature record reads as whatever the main ion’s says (measured, assumed or inferred): equal temperatures are an assumption noted only in the density record.

Provenance

  1. #1565 Sec. 5 (core_profiles ion[] and zeff from the resolved composition), Lane K #1454 (origin records on core_profiles).

populate_radial_impurity_profiles

Machine-independentConvention-sensitive source
populate_radial_impurity_profiles(ods, radial, *, time=None, tolerance=0.0005, method=None, record_fields=None)

A copy of ods whose core_profiles slice carries a charge-state-resolved composition.

NameTypeUnitDescription
odsODSany

Source; never modified.

radialRadialImpurityCompositionany

From resolve_radial_composition.

timefloat, optionals

Slice time; default the composition’s own.

tolerancefloat, optionals

Largest |t_slice - time| accepted.

methodstr, optional-

method= field; default openadas_<ionization>.

record_fieldsmapping, optional-

The caller’s provenance of the normalization target, appended to the same record as key=value fields – e.g. resistive_method, resistive_sigma, resistive_window for a Romero-closed amplitude.

Returns
—ODSany

A deep copy whose slice ion[] is the diluted hydrogenic main ion and one bundled entry per element: z_ion (the mean charge weighted by the element’s density at the grid points, no volume element), z_ion_1d = (rho), ``z_ion_square_1d`` = <Z^2>(rho), the elemental ``density`` -- all charge states *including the neutral atoms*, the density and <Z^2> are averaged over -- and ``state[q]`` (``z_min = z_max = q``, charge-state density) for every ionised state, so ``sum(state.density) = density (1 - f_0)``; plus ``zeff``.

Convention

IMAS bundled ions: z_ion is one number, the radial charge lives in z_ion_1d / z_ion_square_1d. A reader of z_ion alone loses the radial variation and the charge variance – GACODE does, so the transport path lumps per surface instead (Lane L PR 5).

Raises

  • ValueError As populate_impurity_profiles; or a record_fields key that would restate a field the writer owns (origin, method, normalization, temperature, rotation or one of the normalization’s own fields), a key outside [A-Za-z_][A-Za-z0-9_]*, or a value that is not a string or a number or holds ; or =.
Processing steps · Input semantics · Output semantics · Applicability · Limitations · Provenance

Processing steps

  1. Match the slice by time and read n_e; refuse a measured target.
  2. Keep the hydrogenic main ion (diluted), drop stored impurity entries.
  3. Write each element bundled, with its charge-state densities, from the composition interpolated onto the slice rho grid.
  4. Write zeff (origin=derived, or inferred for a resistive closure). Every record names the normalization and its target as the resolver stated them (target_zeff, target_zeff_fully_stripped, resistive_target, at_rho, scale, weighting), then record_fields.

Input semantics

A core_profiles slice with an electron density.

Output semantics

The same slice with bundled impurity ions whose charge varies with rho.

Applicability

Machine-independent.

Limitations

Neutral atoms are not written (core_profiles.neutral is out of scope).

Provenance

  1. #1565 Sec. 5 and 8.

populate_zeff_profile

Machine-independentConvention-sensitive source
populate_zeff_profile(ods, resolved, *, time=None, tolerance=0.0005, method=None)
Show source vaft/process/impurity.py, lines 1209–1272
def populate_zeff_profile(
    ods: Any,
    resolved: ResolvedImpurityComposition,
    *,
    time: Optional[float] = None,
    tolerance: float = 5e-4,
    method: Optional[str] = None,
) -> Any:
    """A copy of ``ods`` whose ``core_profiles`` slice carries the resolved Z_eff(rho).

    Parameters
    ----------
    ods : ODS
        Source; never modified [any].
    resolved : ResolvedImpurityComposition
        From :func:`resolve_impurity_composition`; not of kind ``measured`` [any].
    time : float, optional
        Slice time; default the resolved composition's own [s].
    tolerance : float, optional
        Largest ``|t_slice - time|`` accepted [s].
    method : str, optional
        ``method=`` field of the record; default ``<kind>_composition`` [-].

    Returns
    -------
    ODS
        A deep copy with ``profiles_1d.zeff`` and ``profiles_1d.zeff_fit.parameters``
        (``origin=assumed|derived; method=...``) written [any].

    Raises
    ------
    ValueError
        A measured composition (already in ``core_profiles``), no slice at the
        time, or no electron density.

    Convention
    ----------
    The record's ``origin`` is ``assumed`` for an explicit or preset
    composition (Z_eff is then the assumed target) and ``derived`` for one
    computed from other data; :func:`resolve_impurity_composition` never reads
    either back as a measured target.  A measured ``zeff`` is never
    overwritten: a composition closed at it is left with the slice's own
    measured profile and record.

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

    Provenance
    ----------
    .. [issue] #1565 Sec. 5 (core_profiles.zeff from the resolved composition).
    """
    work = copy.deepcopy(ods)
    index, ne, rho = _write_slice(work, resolved, time, tolerance)
    base = f"core_profiles.profiles_1d.{index}"
    if "measured" in resolved.zeff_source:
        return work  # the slice already carries the measured profile it was closed at
    if composition_record_origin(_get(work, f"{base}.zeff_fit.parameters")) == "measured":
        raise ValueError(f"{base}.zeff is labelled measured; it is never overwritten")
    zeff, filled = _fill_undefined(_on_grid(resolved.zeff, resolved, rho, ne.size), rho)
    work[f"{base}.zeff"] = zeff
    record = _record(resolved, "zeff", method)
    work[f"{base}.zeff_fit.parameters"] = record + (f"; filled_points={filled}" if filled else "")
    return work

A copy of ods whose core_profiles slice carries the resolved Z_eff(rho).

NameTypeUnitDescription
odsODSany

Source; never modified.

resolvedResolvedImpurityCompositionany

From resolve_impurity_composition; not of kind measured.

timefloat, optionals

Slice time; default the resolved composition’s own.

tolerancefloat, optionals

Largest |t_slice - time| accepted.

methodstr, optional-

method= field of the record; default <kind>_composition.

Returns
—ODSany

A deep copy with profiles_1d.zeff and profiles_1d.zeff_fit.parameters (origin=assumed|derived; method=...) written.

Convention

The record’s origin is assumed for an explicit or preset composition (Z_eff is then the assumed target) and derived for one computed from other data; resolve_impurity_composition never reads either back as a measured target. A measured zeff is never overwritten: a composition closed at it is left with the slice’s own measured profile and record.

Raises

  • ValueError A measured composition (already in core_profiles), no slice at the time, or no electron density.
Applicability · Provenance

Applicability

Machine-independent.

Provenance

  1. #1565 Sec. 5 (core_profiles.zeff from the resolved composition).

resolve_impurity_composition

Machine-independentConvention-sensitive source
resolve_impurity_composition(ods=None, *, time=None, tolerance=0.0005, composition=None, derived=None, machine_preset=None, shot=None, use_measured_zeff=True, resistive_zeff=None, info_file=None)

Resolve the impurity composition that applies, close it at its Z_eff and reduce it.

NameTypeUnitDescription
odsODS, optionalany

Source of a stored core_profiles composition and Z_eff; read without creating any path.

timefloat, optionals

Time of the core_profiles slice to read; required when it holds more than one slice.

tolerancefloat, optionals

Largest |t_slice - time| accepted.

compositionImpurityComposition, optionalany

An explicit composition from the caller.

derivedImpurityComposition, optionalany

A composition derived by a stated model (atomic data, a resistive closure).

machine_presetstr or mapping, optionalany

"vest" (the vest.yaml impurity_model for shot), or a parsed impurity_model record; used only when nothing above applies.

shotint, optional-

Shot whose machine preset era applies.

use_measured_zeffbool, optional-

Close a non-measured composition at a core_profiles.zeff labelled measured instead of the composition’s own target.

resistive_zefffloat or mapping, optional-

A resistively inferred Z_eff (a Lane Z row) to carry beside the result under its own provenance; never used as a target.

info_filestr, optional-

Alternative vest.yaml for the "vest" preset.

Returns
—ResolvedImpurityCompositionany

Species, n_s/n_e, n_main/n_e, Z_eff and where it came from, the moments S1/S2/A_bar, the reduced pseudo-impurity, the dilution, the kind and the candidates considered.

Convention

The precedence measured > explicit > derived > assumed is #1565 Sec. 4. A stored composition that does not say how it is known ranks with the assumed ones, below an explicit argument: the Lane K products carry an H+/C6+ list assumed at Z_eff = 2 with no density label, and reading that as a measurement would let an assumption outrank the caller.

Raises

  • ValueError No source applies, a composition without a target Z_eff and no measured one, a target the composition cannot reach, or a core_profiles slice that cannot be matched in time.
Processing steps · Applicability · Limitations · Provenance

Processing steps

  1. Match the core_profiles slice by time (never by index); read its impurity ions (element.0.z_n > 1) and their density_fit origin, and its zeff if labelled origin=measured. A bundled ion is read with its radial charge (z_ion_1d, z_ion_square_1d, else state[]); z_ion alone is read as a fixed charge state. provenance["charge_fields"] records which fields each ion gave.
  2. Choose the composition: stored ions labelled measured; else the explicit argument; else the derived argument, or stored ions labelled derived/inferred; else stored ions labelled assumed or unlabelled; else the machine preset.
  3. A stored composition labelled measured is used as stored. Any other is closed by quasi-neutrality at the measured Z_eff profile when there is one and use_measured_zeff (a stored one keeps its relative weights per rho), else at its own target (a stored one: as stored). A measured-Z_eff point outside [Z_m, S2/S1] or not finite is left undefined and counted in provenance["undefined_points"].
  4. Reduce to the pseudo-impurity and form the dilution.

Applicability

Machine-independent. The "vest" preset reads vest.yaml diagnostics.core_profiles.impurity_model when, and only when, it is asked for.

Limitations

An argument composition has fixed charge states per species; a radially varying charge-state distribution enters as a derived composition (#1565 Sec. 8) or is read back from the bundled ions populate_radial_impurity_profiles wrote (mean_charge / mean_square_charge of the result). A stored composition is read only with a hydrogenic main ion; a slice whose ions are not hydrogen isotopes plus impurities is skipped with its reason.

Provenance

  1. #1565 Sec. 3-4 (presets, precedence) and its main-ion dilution comment; #1566 (resistive Z_eff kept apart).

resolve_radial_composition

Machine-independentConvention-sensitive source
resolve_radial_composition(te_eV, ne_m3, rho, elemental_weights, *, normalization='ne_weighted_mean', target_zeff=2.0, ionization='coronal', plasma_age_s=None, volume_weights=None, resistive_target=None, projection=None, coronal_tolerance=0.1, tables=None, cache_dir=None, time=None)

Radial Z_eff and reduced impurity from an elemental composition and atomic-data charge states.

NameTypeUnitDescription
te_eVarray-likeeV

Electron temperature on rho.

ne_m3array-likem^-3

Electron density on rho.

rhoarray-like-

Radial coordinate, increasing.

elemental_weightsmapping-

Relative elemental (all charge states) densities by element, e.g. {"C": 1, "O": 1}; normalised internally.

normalizationstr, optional-

One of NORMALIZATIONS: ne_weighted_mean (the n_e-weighted volume mean of Z_eff equals target_zeff), axis (Z_eff at the innermost point), fixed (the fully stripped closure at target_zeff, i.e. 1/86 each for the VEST preset, then let Z_eff fall where the charge states do) or resistive_closure (projection(Z_eff) == resistive_target).

target_zefffloat, optional-

Target of the ne_weighted_mean, axis and fixed rules.

ionizationstr, optional-

"coronal" or "transient" (needs plasma_age_s).

plasma_age_sfloat, optionals

Time since breakdown; also the age of the coronal-validity check.

volume_weightsarray-like, optionalm^3

dV per rho point for the volume mean; default rho drho, a cylindrical stand-in in rho units.

resistive_targetfloat, optional-

Resistive Z_eff the resistive_closure rule matches.

projectioncallable, optionalany

Z_eff(rho) -> scalar resistive projection (#1566) for resistive_closure; it receives the full rho grid with NaN at undefined points and must ignore them.

coronal_tolerancefloat, optional-

Largest |<Z>_transient(age) - <Z>_coronal| still called coronal.

tablesmapping, optionalany

{element: (acd, scd)} overriding the OPEN-ADAS defaults.

cache_dirstr, optional-

ADF11 cache directory.

timefloat, optionals

Slice time, carried for the writer.

Returns
—RadialImpurityCompositionany

zeff(rho), <Z>, <Z^2>, S1, S2, Z_I,eff, dilution, elemental and charge-state fractions, the coronal check and the normalization record.

Convention

The elemental ratio and a flat n_s/n_e shape are fixed; only their common amplitude is normalised, so the radial structure of Z_eff is the charge states’ alone. ne_weighted_mean is the default the VEST atlas uses (#1569); fixed shows how far Z_eff falls from the stripped value.

Raises

  • ValueError An unknown rule or model, a target the composition cannot reach (a negative main-ion density), resistive_closure without its projection and target, or no valid profile point.
Processing steps · Assumptions · Applicability · Limitations · Provenance

Processing steps

  1. ADF11 charge-state fractions of each element at each point (coronal, or transient at plasma_age_s); <Z>_s, <Z^2>_s.
  2. S1 = sum w_s <Z>_s, S2 = sum w_s <Z^2>_s.
  3. With n_s/n_e = c w_s, Z_eff = Z_m + c (S2 - Z_m S1) is linear in the one scale c; the normalization rule fixes c.
  4. n_main/n_e = (1 - c S1)/Z_m, Z_I,eff = S2/S1, dilution.
  5. Coronal check: transient <Z> at plasma_age_s against coronal.

Assumptions

No impurity transport: flat n_s/n_e; equal ages everywhere.

Applicability

Machine-independent.

Limitations

VEST discharges last tens of ms while carbon relaxes on ~10-80 ms at 20-200 eV and 1e19 m^-3: the coronal model overstates the charge; coronal_valid says where. Charge exchange with neutrals is ignored.

Provenance

  1. H. P. Summers, The ADAS User Manual, version 2.6 (2004), ADF11.
  2. #1565 Sec. 8, Lane L log #1569 (normalization decision).

surface_composition_profile

Machine-independentConvention-sensitive source
surface_composition_profile(profile, composition, r_over_a)

A copy of a GACODE profile whose ions are the main ion plus an explicit impurity composition.

NameTypeUnitDescription
profileGACODEProfileany

The resolved transport profile (its main ion, temperatures, rotation and geometry are kept).

compositionRadialImpurityComposition or ResolvedImpurityCompositionany

A radial composition must be resolved on profile.rho; a resolved one may be scalar, or a profile on its own rho (rho_tor_norm), which is interpolated onto profile.rho.

r_over_afloat-

The surface, rmin / rmin[-1], whose charge states the lumped impurities take.

Returns
—GACODEProfileany

z, name, type, mass, ni, ti, vtor/vpol and z_eff replaced; provenance records the composition and the surface.

Convention

GACODE carries one charge per species for the whole profile, so a charge that varies with rho is lumped per surface (one profile per TGLF or CGYRO surface); with fixed charge states the profile is the same at every surface. Z_eff at the surface equals the composition’s. A profile-valued composition is paired with profile.rho by coordinate (both are rho_tor_norm): a radial composition must be resolved on profile.rho; a resolved one is interpolated from its own rho, which it must carry (provenance["ni"]["composition_grid"] says so).

Raises

  • ValueError A profile without a hydrogenic main ion or rmin, a radial composition on another grid, or a surface outside the profile.
Processing steps · Input semantics · Output semantics · Applicability · Limitations · Provenance

Processing steps

  1. Main ion: the profile’s first z = 1 species, its density replaced by n_e n_main/n_e of the composition.
  2. At the surface, each element’s lumped charge Z_s = <Z^2>_s/<Z>_s.
  3. Its density n_s'(rho) = n_e (n_s/n_e) <Z>_s(rho) / Z_s: the element’s charge density is kept at every rho (so the gradients stay quasi-neutral) and its Z^2 moment exactly at the surface.
  4. Temperatures and rotation of the impurities are the main ion’s.

Input semantics

A converted GACODE profile (GACODE units: 1e19 m^-3, keV).

Output semantics

The same profile with a species list valid at one surface only.

Applicability

Machine-independent.

Limitations

The charge-state variance enters only through <Z^2>; the charge’s own radial gradient away from the surface is not represented. Equal ion temperatures are assumed.

Provenance

  1. #1565 Sec. 6, Lane L log #1569 (lumped species per surface).

results matching ""

    No results matching ""