Process reference: electromagnetics

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

Overview

Two halves. The first builds free-space Green’s-function response matrices – the poloidal flux and field per unit current – for active coils, passive vessel loops and plasma filaments. The second integrates the passive circuit those matrices describe, giving the eddy currents a coil programme drives in the vessel.

Physics only. Nothing here reads a machine description: every geometry, resistance and mutual-inductance matrix arrives as an argument, so the same code serves any axisymmetric machine. The VEST geometry and the packaged coupling matrices live in vaft.machine_mapping.

SymbolMeaningUnit
psipoloidal flux per unit source currentWb/A
Br, Bzfield components per unit source currentT/A
Rloop resistance matrix, diagonalohm
Mpassive-passive mutual inductance matrixH
Lpassive-active mutual inductance matrixH
dt_subsubstep of the circuit integrations

Response matrices are per unit current, so a field is recovered by contracting one with a current history; nothing here carries a current of its own. Sources are ideal filaments unless a turn count says otherwise, and a turn count multiplies the response rather than changing the geometry.

The passive circuit is driven by the rate of change of the active current, not by the current itself, which is why a coil programme flat in time drives no eddy current however large it is.

The singularity where an observation point coincides with its source is handled by evaluating either side of it and averaging, rather than by excluding the point; see compute_br_bz_phi.

Functions

calc_gridAssemble the response of every coil and passive loop on a rectangular grid. Convention
compute_br_bz_phiField and flux of one unit-current ring at a set of observation points. Convention
compute_impedance_matricesAssemble the resistance and inductance matrices of the passive circuit. Convention
compute_mutual_passive_activeMutual inductance between passive loops and active coils, derived from geometry. Convention
compute_point_response_matricesBroadcast response of point sources at observation points, with exact kernels. Convention
compute_response_matrixFlux and field response at arbitrary observation points, per source. Convention
compute_response_vectorThe same response as the matrix form, with the arguments in the legacy order. Convention
compute_vacuum_fields_1dContract current histories with response matrices into field histories. Convention
solve_eddy_currentsIntegrate the vessel eddy currents driven by a coil and plasma programme. Convention
wall_propagatorThe one-substep propagator of the passive circuit. Convention

calc_grid

Machine-independentConvention-sensitive source
calc_grid(xvar, zvar, coil_turns, coil_r, coil_z, loop_geometry_type, loop_outline_r, loop_outline_z, loop_rectangle_r, loop_rectangle_z)

Assemble the response of every coil and passive loop on a rectangular grid.

NameTypeUnitDescription
xvararray_likem

Major-radius grid axis.

zvararray_likem

Height grid axis.

coil_turnsarray_like-

Turns of each active coil.

coil_rarray_likem

Major radius of each coil.

coil_zarray_likem

Height of each coil.

loop_geometry_typesequence-

Which shape each passive loop is described by.

loop_outline_rsequencem

Major radius of each outline-described loop’s vertices.

loop_outline_zsequencem

Height of those vertices.

loop_rectangle_rsequencem

Major radius of each rectangle-described loop.

loop_rectangle_zsequencem

Height of those rectangles.

Returns
—np.ndarray-

Response per unit current with one row per grid point and one column per source, coils first and passive loops after.

Convention

Rows run over the flattened grid and columns over the sources, coils before loops, which is the ordering every consumer of this matrix assumes. A loop described by an outline is reduced to its centroid before its response is taken, so an extended loop is treated as a filament at that point.

Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

The centroid reduction means a loop large compared with its distance to the grid is poorly represented. Builds the whole grid at once, so memory grows as the product of grid points and sources.

Provenance

  1. compute_br_bz_phi, evaluated per source and stacked.

compute_br_bz_phi

Machine-independentConvention-sensitive source
compute_br_bz_phi(r_obs, z_obs, r_src, z_src, shift=0.01)
Show source vaft/process/electromagnetics.py, lines 74–146
def compute_br_bz_phi(
    r_obs: np.ndarray,
    z_obs: np.ndarray,
    r_src: float,
    z_src: float,
    shift: float = 0.01
    ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Field and flux of one unit-current ring at a set of observation points.

    Parameters
    ----------
    r_obs : array_like
        Major radius of the observation points [m].
    z_obs : array_like
        Height of the observation points [m].
    r_src : float
        Major radius of the source ring [m].
    z_src : float
        Height of the source ring [m].
    shift : float, optional
        Offset used to step around the source singularity [m].

    Returns
    -------
    tuple of np.ndarray
        The radial and vertical field per unit current in tesla per ampere, and
        the poloidal flux per unit current in weber per ampere [-].

    Convention
    ----------
    Per unit current, so the caller multiplies by an actual current. An
    observation point sitting on the source has no finite response; rather than
    excluding it, the response is evaluated at two points either side and
    averaged, which keeps the returned array the same shape as the input and gives
    a finite value whose error is second order in the offset.

    Defaults
    --------
    ``shift = 0.01`` is a numerical convenience. The averaging is applied only
    within a third of it from the source, so a point comfortably away from the
    ring is untouched.

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

    Limitations
    -----------
    Free space: no iron, no shielding, no image currents. The source is an ideal
    filament, so the response very close to a real conductor of finite section is
    not physical, which is what the offset is papering over rather than solving.

    Provenance
    ----------
    .. [1] The axisymmetric Green's functions in :mod:`vaft.formula.green`.
    """
    distances = calculate_distance(r_obs, r_src, z_obs, z_src)

    condition = distances < (shift / 3.0)

    br1_shifted, bz1_shifted = green_br_bz(r_obs + shift, z_obs, r_src, z_src)
    br2_shifted, bz2_shifted = green_br_bz(r_obs - shift, z_obs, r_src, z_src)
    phi1_shifted = green_r(r_obs + shift, z_obs, r_src, z_src)
    phi2_shifted = green_r(r_obs - shift, z_obs, r_src, z_src)

    br_direct, bz_direct = green_br_bz(r_obs, z_obs, r_src, z_src)
    phi_direct = green_r(r_obs, z_obs, r_src, z_src)

    br_final = np.where(condition, (br1_shifted + br2_shifted) / 2.0, br_direct)
    bz_final = np.where(condition, (bz1_shifted + bz2_shifted) / 2.0, bz_direct)
    phi_final = np.where(condition, (phi1_shifted + phi2_shifted) / 2.0, phi_direct)

    return br_final, bz_final, phi_final

Field and flux of one unit-current ring at a set of observation points.

NameTypeUnitDescription
r_obsarray_likem

Major radius of the observation points.

z_obsarray_likem

Height of the observation points.

r_srcfloatm

Major radius of the source ring.

z_srcfloatm

Height of the source ring.

shiftfloat, optionalm

Offset used to step around the source singularity.

Returns
—tuple of np.ndarray-

The radial and vertical field per unit current in tesla per ampere, and the poloidal flux per unit current in weber per ampere.

Convention

Per unit current, so the caller multiplies by an actual current. An observation point sitting on the source has no finite response; rather than excluding it, the response is evaluated at two points either side and averaged, which keeps the returned array the same shape as the input and gives a finite value whose error is second order in the offset.

Defaults · Applicability · Limitations · Provenance

Defaults

shift = 0.01 is a numerical convenience. The averaging is applied only within a third of it from the source, so a point comfortably away from the ring is untouched.

Applicability

Machine-independent.

Limitations

Free space: no iron, no shielding, no image currents. The source is an ideal filament, so the response very close to a real conductor of finite section is not physical, which is what the offset is papering over rather than solving.

Provenance

  1. The axisymmetric Green’s functions in vaft.formula.green.

compute_impedance_matrices

Machine-independentConvention-sensitive source
compute_impedance_matrices(loop_resistances, passive_loop_geometry, coil_geometry, mutual_pp, mutual_pa, plasma_rz)

Assemble the resistance and inductance matrices of the passive circuit.

NameTypeUnitDescription
loop_resistancesarray_likeohm

Resistance of each passive loop.

passive_loop_geometrysequence-

Geometry of each passive loop.

coil_geometrysequence-

Geometry of the active coils; superseded by the mutual matrix below.

mutual_pparray_likeH

Passive-to-passive mutual inductance.

mutual_paarray_likeH

Passive-to-active mutual inductance.

plasma_rzarray_likem

Plasma filament positions, coupled in when given.

Returns
—tuple of np.ndarray-

The diagonal resistance matrix in ohms, and the two inductance matrices in henries, the second widened by the plasma coupling when supplied.

Convention

Resistance is diagonal: loops are resistively independent and coupled only inductively. The passive-to-active matrix is widened to the right by the plasma coupling when filaments are given, so the plasma enters the circuit as another driving current rather than as a separate term.

The coil geometry argument is kept for compatibility and is superseded by the supplied mutual matrix; passing geometry alone no longer determines the coupling.

Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

Takes the mutual matrices as given and cannot check they were computed for this geometry, which is exactly the mismatch compute_mutual_passive_active exists to resolve.

Provenance

  1. The circuit form the eddy-current solve integrates; see solve_eddy_currents.

compute_mutual_passive_active

Machine-independentConvention-sensitive source
compute_mutual_passive_active(passive_loop_geometry, coil_geometry)
Show source vaft/process/electromagnetics.py, lines 543–599
def compute_mutual_passive_active(
    passive_loop_geometry: List[Tuple[str, float, float, float]],
    coil_geometry: List[List[Tuple[float, float, int]]],
) -> np.ndarray:
    """Mutual inductance between passive loops and active coils, derived from geometry.

    Parameters
    ----------
    passive_loop_geometry : sequence
        Geometry of each passive loop [-].
    coil_geometry : sequence
        Geometry and turns of each active coil [-].

    Returns
    -------
    np.ndarray
        Mutual inductance with one row per loop and one column per coil [H].

    Convention
    ----------
    Derived from the geometry given, which is what makes it a usable fallback when
    a packaged coupling matrix does not apply. The packaged matrix represents a
    historical coil geometry; a machine whose coils have since moved needs this
    instead, and the two must not be mixed within one calculation.

    Applicability
    -------------
    Machine-independent.  The geometry is the argument; the packaged matrix it
    substitutes for is VEST's.

    Limitations
    -----------
    Filament idealization, so it is less accurate than a matrix computed from the
    real conductor sections. Use it when the packaged matrix does not match the
    geometry, not in preference to one that does.

    Provenance
    ----------
    .. [1] The Green's functions in :mod:`vaft.formula.green`; the packaged
       alternative is the machine layer's ``em_coupling`` asset.
    """
    coupling = np.zeros((len(passive_loop_geometry), len(coil_geometry)))

    for i_loop, (_, r_loop, z_loop, coefficient) in enumerate(
        passive_loop_geometry
    ):
        for i_coil, elements in enumerate(coil_geometry):
            if not elements:
                raise ValueError(f"active coil {i_coil} has no geometry elements")
            total_turns = sum(element[2] for element in elements)
            mean_response = sum(
                green_r(r_loop, z_loop, r_coil, z_coil)
                for r_coil, z_coil, _ in elements
            ) / len(elements)
            coupling[i_loop, i_coil] = coefficient * total_turns * mean_response

    return coupling

Mutual inductance between passive loops and active coils, derived from geometry.

NameTypeUnitDescription
passive_loop_geometrysequence-

Geometry of each passive loop.

coil_geometrysequence-

Geometry and turns of each active coil.

Returns
—np.ndarrayH

Mutual inductance with one row per loop and one column per coil.

Convention

Derived from the geometry given, which is what makes it a usable fallback when a packaged coupling matrix does not apply. The packaged matrix represents a historical coil geometry; a machine whose coils have since moved needs this instead, and the two must not be mixed within one calculation.

Applicability · Limitations · Provenance

Applicability

Machine-independent. The geometry is the argument; the packaged matrix it substitutes for is VEST’s.

Limitations

Filament idealization, so it is less accurate than a matrix computed from the real conductor sections. Use it when the packaged matrix does not match the geometry, not in preference to one that does.

Provenance

  1. The Green’s functions in vaft.formula.green; the packaged alternative is the machine layer’s em_coupling asset.

compute_point_response_matrices

Machine-independentConvention-sensitive source
compute_point_response_matrices(obs_r, obs_z, src_r, src_z, turns=None, groups=None, n_groups=None, components=('psi', 'bz', 'br'))

Broadcast response of point sources at observation points, with exact kernels.

NameTypeUnitDescription
obs_rarray_likem

Major radius of the observation points.

obs_zarray_likem

Height of the observation points.

src_rarray_likem

Major radius of the sources.

src_zarray_likem

Height of the sources.

turnsarray_like, optional-

Turn count weighting each source.

groupsarray_like, optional-

Which output column each source contributes to.

n_groupsint, optional-

How many columns the grouping produces.

componentssequence of str, optional-

Which of the flux and the two field components to return.

Returns
—dict of str to np.ndarray-

One matrix per requested component, per unit current.

Convention

Exact elliptic-integral kernels rather than the approximations elsewhere in this module, and fully broadcast rather than looped, which is what makes it the right choice for many sources at many points.

Grouping sums columns as it goes, so a set of filaments belonging to one circuit becomes a single column instead of being summed afterwards; on a real machine that turns several hundred filament columns into a handful of circuit ones. Turns weight each source before that sum.

Defaults · Applicability · Limitations · Provenance

Defaults

Returning all three components is a numerical convenience, not a physical choice, and narrowing it is worth doing: each field component costs roughly twice the flux pass.

Applicability

Machine-independent.

Limitations

A source coincident with an observation point has no finite response here; unlike compute_br_bz_phi, nothing steps around the singularity. On axis the kernels take their analytic limits.

Provenance

  1. The exact elliptic-integral Green’s functions in vaft.formula.green.

compute_response_matrix

Machine-independentConvention-sensitive source
compute_response_matrix(observation_points, coil_data, passive_loop_data, plasma_points=None)

Flux and field response at arbitrary observation points, per source.

NameTypeUnitDescription
observation_pointsarray_likem

Points at which to evaluate, as major radius and height pairs.

coil_datasequence-

Active coil geometry and turns.

passive_loop_datasequence-

Passive loop geometry.

plasma_pointsarray_like, optionalm

Plasma filament positions.

Returns
—tuple of np.ndarray-

The flux, vertical field and radial field response, each with one row per observation point and one column per source.

Convention

Unlike calc_grid, the observation points are arbitrary rather than a rectangular mesh, which is what a diagnostic set of sensor positions needs. Column order is coils, then passive loops, then plasma filaments when given.

Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

Same filament idealization as the rest of the module. Plasma filaments are positions only: this returns their response, not their currents.

Provenance

  1. compute_br_bz_phi, evaluated per source.

compute_response_vector

Machine-independentConvention-sensitive source
compute_response_vector(coil_data, passive_loop_data, plasma_points, observation_points)
Show source vaft/process/electromagnetics.py, lines 386–429
def compute_response_vector(
    coil_data: List[Dict[str, Any]],
    passive_loop_data: List[Dict[str, Any]],
    plasma_points: List[List[float]],
    observation_points: List[List[float]]
    ) -> Tuple[ndarray, ndarray, ndarray]:
    """The same response as the matrix form, with the arguments in the legacy order.

    Parameters
    ----------
    coil_data : sequence
        Active coil geometry and turns [-].
    passive_loop_data : sequence
        Passive loop geometry [-].
    plasma_points : array_like
        Plasma filament positions [m].
    observation_points : array_like
        Points at which to evaluate [m].

    Returns
    -------
    tuple of np.ndarray
        Exactly what :func:`compute_response_matrix` returns [-].

    Convention
    ----------
    A thin wrapper that reorders its arguments and delegates. It exists because
    the legacy call order put the observation points last; new code should call
    the matrix form directly.

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

    Provenance
    ----------
    .. [1] :func:`compute_response_matrix`, which does the work.
    """
    return compute_response_matrix(
        observation_points=observation_points,
        coil_data=coil_data,
        passive_loop_data=passive_loop_data,
        plasma_points=plasma_points
    )

The same response as the matrix form, with the arguments in the legacy order.

NameTypeUnitDescription
coil_datasequence-

Active coil geometry and turns.

passive_loop_datasequence-

Passive loop geometry.

plasma_pointsarray_likem

Plasma filament positions.

observation_pointsarray_likem

Points at which to evaluate.

Returns
—tuple of np.ndarray-

Exactly what compute_response_matrix returns.

Convention

A thin wrapper that reorders its arguments and delegates. It exists because the legacy call order put the observation points last; new code should call the matrix form directly.

Applicability · Provenance

Applicability

Machine-independent.

Provenance

  1. compute_response_matrix, which does the work.

compute_vacuum_fields_1d

Machine-independentConvention-sensitive source
compute_vacuum_fields_1d(coil_plus_loop_currents, coil_plus_loop_psi_resp, coil_plus_loop_br_resp, coil_plus_loop_bz_resp)
Show source vaft/process/electromagnetics.py, lines 997–1057
def compute_vacuum_fields_1d(
    coil_plus_loop_currents: np.ndarray,  # shape (n_times, nb_coil+nb_loop)
    coil_plus_loop_psi_resp: np.ndarray,  # shape (n_points, nb_coil+nb_loop)
    coil_plus_loop_br_resp: np.ndarray,   # shape (n_points, nb_coil+nb_loop)
    coil_plus_loop_bz_resp: np.ndarray,   # shape (n_points, nb_coil+nb_loop)
    ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Contract current histories with response matrices into field histories.

    Parameters
    ----------
    coil_plus_loop_currents : array_like
        Current history, one row per time and one column per source [A].
    coil_plus_loop_psi_resp : array_like
        Flux response per unit current [Wb/A].
    coil_plus_loop_br_resp : array_like
        Radial field response per unit current [T/A].
    coil_plus_loop_bz_resp : array_like
        Vertical field response per unit current [T/A].

    Returns
    -------
    tuple of np.ndarray
        Flux in weber and the two field components in tesla, each with one row per
        time and one column per observation point [-].

    Convention
    ----------
    The linear step the response matrices exist for: each output is the current
    history contracted against its own response. **Vacuum fields only** -- the
    plasma's own contribution is not here unless it entered as a filament current
    in the input.

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

    Limitations
    -----------
    Column order in the currents must match the response matrices' own, and
    nothing checks it; a mismatched ordering gives plausible numbers that are
    wrong.

    Provenance
    ----------
    .. [1] The response matrices built by :func:`compute_response_matrix` or
       :func:`calc_grid`.
    """
    n_times = coil_plus_loop_currents.shape[0]
    n_points = coil_plus_loop_psi_resp.shape[0]

    psi_out = np.zeros((n_times, n_points))
    br_out = np.zeros((n_times, n_points))
    bz_out = np.zeros((n_times, n_points))

    for i_time in range(n_times):
        ix = coil_plus_loop_currents[i_time]  # shape (nb_coil+nb_loop,)
        psi_out[i_time] = coil_plus_loop_psi_resp @ ix
        br_out[i_time]  = coil_plus_loop_br_resp  @ ix
        bz_out[i_time]  = coil_plus_loop_bz_resp  @ ix

    return psi_out, br_out, bz_out

Contract current histories with response matrices into field histories.

NameTypeUnitDescription
coil_plus_loop_currentsarray_likeA

Current history, one row per time and one column per source.

coil_plus_loop_psi_resparray_likeWb/A

Flux response per unit current.

coil_plus_loop_br_resparray_likeT/A

Radial field response per unit current.

coil_plus_loop_bz_resparray_likeT/A

Vertical field response per unit current.

Returns
—tuple of np.ndarray-

Flux in weber and the two field components in tesla, each with one row per time and one column per observation point.

Convention

The linear step the response matrices exist for: each output is the current history contracted against its own response. Vacuum fields only – the plasma’s own contribution is not here unless it entered as a filament current in the input.

Applicability · Limitations · Provenance

Applicability

Machine-independent.

Limitations

Column order in the currents must match the response matrices’ own, and nothing checks it; a mismatched ordering gives plausible numbers that are wrong.

Provenance

  1. The response matrices built by compute_response_matrix or calc_grid.

solve_eddy_currents

Machine-independentConvention-sensitive source
solve_eddy_currents(R_mat, L_mat, M_mat, coil_plasma_currents, time, dt_sub=5e-05, *, method='auto')

Integrate the vessel eddy currents driven by a coil and plasma programme.

NameTypeUnitDescription
R_matarray_likeohm

Loop resistance matrix.

L_matarray_likeH

Passive-to-active mutual inductance.

M_matarray_likeH

Passive-to-passive mutual inductance.

coil_plasma_currentsarray_likeA

Driving current history, one row per time and one column per source.

timearray_likes

Time base of that history.

dt_subfloat, optionals

Substep of the integration.

methodstr, optional-

Decomposition passed to the propagator.

Returns
—np.ndarrayA

Eddy current in each passive loop over time.

Convention

Driven by the rate of change of the driving current, not by its value, so a flat coil programme drives nothing however large. The integration is substepped and advanced by a single reused propagator, which is what makes it cheap over a long shot.

Defaults · Applicability · Limitations · Provenance

Defaults

The substep is a hard-coded value. It is meant to be finer than the input grid, and the shipped value is coarser than the 40 microsecond diagnostics grid, making this a mild rate reduction rather than the refinement intended; tracked in #425.

Applicability

Machine-independent.

Limitations

The driving derivative is taken from the supplied history, so a coarsely sampled programme understates a fast ramp. Assumes the circuit is constant in time, so no geometry or resistance change during the shot is represented.

Provenance

  1. The legacy vfit_eddy workflow, whose matrix setup this retains structural similarity to.
  2. Issue #425, tracking the substep default.

wall_propagator

Machine-independentConvention-sensitive source
wall_propagator(R_mat, M_mat, dt_sub, *, method='auto')

The one-substep propagator of the passive circuit.

NameTypeUnitDescription
R_matarray_likeohm

Loop resistance matrix, diagonal and positive.

M_matarray_likeH

Passive-to-passive mutual inductance matrix.

dt_subfloats

Length of the substep.

methodstr, optional-

Which decomposition to use: automatic, general, or symmetric.

Returns
—np.ndarray-

The propagator advancing the loop currents by one substep.

Convention

The matrix exponential of the negative circuit operator times the substep. solve_eddy_currents consumes nothing from the decomposition except this, so it is the whole seam for a faster one.

The symmetric path uses the symmetric-definite pencil: with resistance diagonal and positive and inductance symmetric, a change of variable makes the operator symmetric, so the symmetric eigensolver applies and the eigenvector inverse is a transpose. On the real 950-loop machine that is about eleven times faster than the general solver and agrees to about one part in 1e14 (#308). It is valid only when the inductance is symmetric, which the loader guarantees for the packaged asset (#347) but nothing guarantees for a caller-built matrix, so the automatic mode checks and otherwise leaves the general path unchanged.

Raises

  • ValueError The method is not one of the three accepted names.
Defaults · Applicability · Limitations · Provenance

Defaults

Automatic selection is a numerical convenience: it takes the fast path when the check passes and is otherwise identical to the general one.

Applicability

Machine-independent.

Limitations

Assumes the circuit is constant over the substep, which is what makes a single propagator reusable across every step.

Provenance

  1. Issue #308 for the measured speedup and agreement; issue #347 for the loader guarantee that makes the symmetric path safe on the packaged asset.

results matching ""

    No results matching ""