Wall eigenmodes

Wall eigenmodes

The reduced vessel-wall contract is owned by VFIT (VEST-Tokamak/vfit#8); this page describes the VAFT implementation (#473). The principle in one line: local eigenbasis, global electromagnetic dynamics.

Every function of vaft.process.wall_modes is documented under the processing contract, with its units, its coupling and normalization conventions and what it refuses: the generated wall_modes reference page is that text, and this page is the workflow.

What it is

The passive wall is ~950 filament loops. They are grouped into physical segments — by loop name, split where a structure has a genuine gap in Z — and each segment gets its own L/R eigenbasis. The bases are block-assembled into V_seg, and every reduced operator is then a projection of the full matrices, so the mutual inductance between segments survives in the off-diagonal blocks of the reduced inductance.

import vaft
from vaft.omas.process_wrapper import compute_impedance_matrices_ods, compute_wall_mode_basis_ods
from vaft.process.wall_modes import reduced_operators, reduce_response, select_slowest, check_wall_mode_basis

ods = vaft.omas.sample.sample_ods()          # the packaged 39915 machine
basis = compute_wall_mode_basis_ods(ods)     # 19 segments, 950 modes, ~0.15 s

basis.n_modes()                               # (240, 10, 10, 8, 8, 23, 23, 230, ...)
basis.labels()[:3]                            # (('W1', 0), ('W1', 1), ('W1', 2))
basis.segment("W1").tau[:3]                   # slowest local decay times [s]

R_mat, L_mat, M_mat = compute_impedance_matrices_ods(ods, [])   # code naming: M_mat is the inductance
keep = select_slowest(basis, 40)              # forty slowest modes, wherever they live
ops = reduced_operators(basis, R_mat, M_mat, L_mat, keep)
ops.L_r.shape, ops.R_r                        # (40, 40), identity
G_red = reduce_response(G_full, basis, keep)  # any (n_obs, 950) response -> (n_obs, 40)
check_wall_mode_basis(basis, R_mat, M_mat)["coupling"]["W9_L-W8_L"]   # 0.91: strongly coupled halves

Conventions

item rule
segmentation by pf_passive.loop.*.name, split at Z gaps > 1.5 × median loop height (vest-name-zgap-1.5-v1); ordered by first element index; W11 included
eigenproblem per segment, S_g = R^{-1/2} L R^{-1/2}, eigh; eigenvalues are the decay times, descending
normalization R-orthonormal: vᵀ R v = 1, vᵀ L v = τ; amplitudes in √W (aᵀa is the ohmic dissipation)
sign largest-magnitude component positive
projection a = V_segᵀ R I_w — exact in the retained subspace; not V_segᵀ I_w
reduced operators R_r = I (computed and checked), L_r = V_segᵀ L V_seg, M_r = V_segᵀ M_src, G_red = G V_seg
indexing (segment_id, k), segment-major; per-segment orders M_repr = (M_1, …, M_G)

The basis chooses no reduced order; select_slowest and select_tau_range exist for the study that will (vfit #10).

What it refuses

A non-diagonal or non-positive resistance, an inductance block that is not positive definite, a condition number above 1e12, an inductance asymmetric by more than 1e-6 (relative), and a near-degenerate pair of decay times inside a segment (relative gap below 1e-6; pass on_cluster="warn" to record instead). The packaged coupling asset has been exactly reciprocal since #373 (its provenance record names the repair); an artifact materialized before that carries a 1.27e-3 asymmetry and must be re-mapped: compute_wall_mode_basis_ods(ods, remap_em_coupling=True).

Provenance

basis.provenance records the segmentation version and digest, the resistance calibration in force (#308), the input asymmetry, the normalization, sign rule and mode order; basis.digest() fingerprints the modes. With record=True the identity is appended to em_coupling.code.parameters as wall_mode_* lines — never under pf_passive, whose loops are compared bitwise against the reference geometry. The basis is computed on demand, not shipped; to_npz / from_npz exist for export.

wall_time_constants in the plasma-free benchmark now reads the same pencil at full rank, so the QA and the basis cannot report two different walls. TokaMaker’s eig_wall (#232) remains an independent global reference on its own mesh (6.88 ms vs 7.19 ms here; meshing W11 since #965 moves it by 1 µs).

results matching ""

    No results matching ""