--- title: FDM Convolution status: implemented doc_kind: reference audience: user owner: fullmag-public-docs source_of_truth: docs/physics/0420-fdm-dipolar-demag-foundations.md --- (public-docs-physics-interactions-demagnetization-fdm-convolution)= # FDM tensor convolution and FFT demagnetization The FDM realization represents the non-local demagnetizing operator by a cell-averaged demagnetization tensor and evaluates its convolution with FFTs. It does not solve a scalar potential on an airbox and it does not use FEM boundary matrices. Open-boundary behavior comes from the finite convolution embedding and the precomputed Newell tensor; periodic behavior uses a separate truncated-image policy documented in {doc}`periodic-demag`. For multiple separated magnetic layers with native grids, use the dedicated {doc}`multilayer-convolution` physics page and the complete {doc}`../../../python-api/discretization/fdm-multilayer-convolution` Python/ProblemIR/UI guide. (demag-fdm-problem-statement)= ## 1. Physical problem and grid Let $i$ and $p$ index destination and source cells on a uniform Cartesian FDM grid. Each cell has volume $V$ and magnetization $\mathbf M_{q,j}=M_s\mathbf m_{q,j}$, where $q$ is the source-cell index and $j$ is a Cartesian component. The field in destination cell $p$ is the discrete cell-volume average of the continuum demagnetizing field generated by all source cells. The method is naturally non-local: every source cell contributes to every destination cell. FFT embedding changes the computational complexity, not the physical tensor definition. In a multilayer problem, the planner either maps objects to one common grid or preserves per-magnet native grids and performs explicit cross-layer convolutions. (demag-fdm-governing-equations)= ## 2. Governing equations The continuous energy convention is ```{math} :label: eq-fdm-demag-continuum-energy E_{\mathrm d}=-\frac{\mu_0}{2}\int_{\Omega_m} \mathbf M\cdot\mathbf H_{\mathrm d}\,\mathrm dV. ``` The cell-averaged tensor $N^{\mathrm{cell}}_{pq,ij}$ is obtained by integrating the continuum demagnetization kernel over both the source and destination cells. The real-space discrete field is ```{math} :label: eq-fdm-demag-field H_{\mathrm d,p,i} =-\sum_q\sum_{j\in\{x,y,z\}} N^{\mathrm{cell}}_{pq,ij}M_{q,j}. ``` The tensor is symmetric in its Cartesian cross-components and is stored as six components: $N_{xx}$, $N_{yy}$, $N_{zz}$, $N_{xy}$, $N_{xz}$, and $N_{yz}$. The convolution kernel computes the raw tensor product without the overall minus sign; the caller applies the sign before inverse FFT and field publication. The cell energy is ```{math} :label: eq-fdm-demag-energy E_{\mathrm d} =-\frac{\mu_0}{2}\sum_p V_p \sum_{i\in\{x,y,z\}}M_{p,i}H_{\mathrm d,p,i}. ``` For a uniform grid $V_p=V$. The factor $1/2$ removes double counting of the self-interaction. The energy reduction must use the same field, magnetization mask, volume fraction, and precision policy as the field path. The Newell construction evaluates base functions $f$ and $g$ and applies a 27-point stencil. A representative diagonal stencil is ```{math} :label: eq-fdm-demag-newell-stencil N_{xx}(i,j,k)=\frac{1}{4\pi h_xh_yh_z} \left(8f_0-4\sum_{\mathrm{faces}}f+2\sum_{\mathrm{edges}}f-\sum_{\mathrm{corners}}f\right). ``` The implementation uses compensated Kahan–Neumaier summation for the stencil cancellation and stable `log1p` forms in the base functions. These are numerical-stability measures of the exact cell-averaged tensor construction, not a replacement equation. The FFT realization embeds the finite grid in a padded grid and uses the convolution theorem: ```{math} :label: eq-fdm-demag-fft \widehat{\mathbf H}_{\mathrm d}(\mathbf k) =-\widehat{\mathbf N}^{\mathrm{cell}}(\mathbf k)\, \widehat{\mathbf M}(\mathbf k), \qquad \mathbf H_{\mathrm d}=\mathcal F^{-1} \left[\widehat{\mathbf H}_{\mathrm d}\right]. ``` Zero padding separates the source and destination copies and prevents circular wraparound from being mistaken for an open-boundary solution. Periodic truncated images intentionally change this embedding and are not the same policy. (demag-fdm-symbols-and-si-units)= ## 3. Symbols and SI units | Symbol | Definition | SI unit | |---|---|---:| | $\mathbf M$ | magnetization field | $\mathrm{A\,m^{-1}}$ | | $M_s$ | saturation magnetization | $\mathrm{A\,m^{-1}}$ | | $\mathbf m$ | reduced magnetization | $1$ | | $\mathbf H_{\mathrm d}$ | demagnetizing field | $\mathrm{A\,m^{-1}}$ | | $\mathbf H_{\mathrm{eff},m}$ | full active effective-field sum on magnetic support | $\mathrm{A\,m^{-1}}$ | | $\mathbf H_{\mathrm{eff},\mathrm{air}}$ | airbox effective-field observable | $\mathrm{A\,m^{-1}}$ | | $\mathbf H_{\mathrm{ext}}$ | external (Zeeman) field | $\mathrm{A\,m^{-1}}$ | | $\mathbf H_{\mathrm{oe}}$ | Oersted field | $\mathrm{A\,m^{-1}}$ | | $\mathbf H_{\mathrm{ant}}$ | antenna field | $\mathrm{A\,m^{-1}}$ | | $\Omega_m$ | active magnetic support | $\mathrm{m^3}$ | | $\Omega_{\mathrm{air}}$ | inactive cells of the same FDM structured grid | $\mathrm{m^3}$ | | $N^{\mathrm{cell}}_{pq,ij}$ | cell-averaged demagnetization tensor | $1$ | | $N_{xx}$ | diagonal tensor component in the Newell stencil | $1$ | | $H_{\mathrm d,p,i}$ | component $i$ of the field in destination cell $p$ | $\mathrm{A\,m^{-1}}$ | | $M_{q,j}$ | component $j$ of source-cell magnetization $q$ | $\mathrm{A\,m^{-1}}$ | | $V_p$ | destination-cell volume | $\mathrm{m^3}$ | | $h_x,h_y,h_z$ | FDM cell sizes | $\mathrm{m}$ | | $\mathbf k$ | FFT wave vector | $\mathrm{m^{-1}}$ | | $\mathcal F$ | discrete Fourier transform | $1$ | | $f$ | Newell diagonal base function | $\mathrm{m^4}$ | | $g$ | Newell off-diagonal base function | $\mathrm{m^4}$ | | $E_{\mathrm d}$ | demagnetization energy | $\mathrm{J}$ | | $\mu_0$ | vacuum permeability | $\mathrm{N\,A^{-2}}$ | | $p,q$ | destination and source cell indices | $1$ | | $i,j$ | Cartesian component indices | $1$ | | $\widehat{\mathbf M}$ | FFT of the packed magnetization | $\mathrm{A\,m^{-1}}$ | | $\widehat{\mathbf N}^{\mathrm{cell}}$ | FFT of the tensor kernel | $1$ | | $\widehat{\mathbf H}_{\mathrm d}$ | FFT-domain demagnetizing field | $\mathrm{A\,m^{-1}}$ | | $\varphi_p$ | magnetic volume fraction of cell $p$ | $1$ | (demag-fdm-assumptions-and-validity)= ## 4. Assumptions and validity The standard path assumes Cartesian uniform cells and a magnetization sampled at cell locations. The grid must resolve geometry and the relevant magnetization variation. A cell that is partially magnetic may use a volume-fraction correction, but that correction is a separate configured realization and must be reported. The following errors are independent: * cell discretization and geometry staircasing; * finite FFT padding or truncated periodic-image count; * Newell tensor construction and self term; * FP32/FP64 arithmetic and reduction order; * multilayer grid interpolation or cross-layer placement; * boundary-correction policy for partial cells. A matching result between two FFT implementations does not prove continuum accuracy. Validation must compare against an independent analytical or high-resolution reference and must state the grid, padding, precision, mask, and energy reduction policy. (demag-fdm-python-api)= ## 5. Python API and complete parameter reference | Python parameter | Type | Default | SI unit | Validation | Meaning | Backend support | ProblemIR | |---|---|---|---|---|---|---|---| | `body.mesh(cell_size=...)` | `Sequence[float]` | required unless a default exists | $\mathrm{m}$ | Three finite positive values; geometry extents must be exactly divisible. | Native Cartesian cell size of one magnetic object. | FDM CPU/GPU subject to lane qualification. | `backend_policy.discretization_hints.fdm.per_magnet..cell` | | `study.objects.mesh.defaults(cell_size=...)` | `Sequence[float]` | `None` | $\mathrm{m}$ | Three finite positive values. | Default native cell size. | FDM CPU/GPU. | `backend_policy.discretization_hints.fdm.default_cell` | | `study.universe.mesh(cell_size=...)` | `Sequence[float]` | inferred for compatible grids | $\mathrm{m}$ | Three finite positive values; common extents must divide exactly. | Requested common convolution-grid resolution for multiple native grids. | FDM multilayer CPU/GPU subject to lane qualification. | `backend_policy.discretization_hints.fdm.demag.common_cell_size` | | `FDMDemag.strategy` | `str` | `auto` | $1$ | `auto`, `single_grid`, or `multilayer_convolution`. | Selects one common-grid or explicit multilayer convolution topology. | FDM CPU/GPU. | `backend_policy.discretization_hints.fdm.demag.strategy` | | `FDMDemag.mode` | `str` | `auto` | $1$ | `auto`, `two_d_stack`, or `three_d`. | Selects thin-film stack or full 3-D multilayer mode. | FDM CPU/GPU. | `backend_policy.discretization_hints.fdm.demag.mode` | | `FDMDemag.common_cells` | `tuple[int,int,int] \| None` | `None` | $1$ | Exactly three positive integers. | Explicit 3-D common convolution grid size. | FDM CPU/GPU. | `backend_policy.discretization_hints.fdm.demag.common_cells` | | `FDMDemag.common_cells_xy` | `tuple[int,int] \| None` | `None` | $1$ | Exactly two positive integers. | Explicit in-plane common grid for `two_d_stack`. | FDM CPU/GPU. | `backend_policy.discretization_hints.fdm.demag.common_cells_xy` | | `FDMDemag.allow_single_grid_fallback` | `bool \| None` | `None` | $1$ | Any non-`None` value raises `ValueError`; it is never silently lowered. | Removed compatibility switch. | Unsupported; choose strategy explicitly. | Not serialized | | `FDMDemag.explain` | `bool` | `True` | $1$ | The raw script builder requires a Boolean; the constructor itself does not type-check it. | Enables a human-readable plan summary; it is not serialized physics. | FDM authoring helper. | Not serialized | | `FDMGrid.cell` | `tuple[float,float,float]` | required | $\mathrm{m}$ | Exactly three finite positive values. | Native Cartesian cell size for one named magnet. | FDM multilayer authoring. | `backend_policy.discretization_hints.fdm.per_magnet..cell` | | `FDM.cell` | `tuple[float,float,float] \| None` | `None` | $\mathrm{m}$ | Backward-compatible alias; cannot be supplied together with `default_cell`. | Legacy spelling of the default Cartesian cell size. | FDM CPU/GPU. | Both `backend_policy.discretization_hints.fdm.cell` and `.default_cell` | | `FDM.default_cell` | `tuple[float,float,float] \| None` | `None` | $\mathrm{m}$ | Exactly three finite positive values; cannot be supplied together with `cell`. | Default Cartesian cell size. | FDM CPU/GPU. | Both `backend_policy.discretization_hints.fdm.cell` and `.default_cell` | | `FDM.per_magnet` | `dict[str,FDMGrid] \| None` | `None` | $1$ | Each grid has three positive cell sizes. | Native grid overrides for individual magnets. | FDM multilayer paths. | `backend_policy.discretization_hints.fdm.per_magnet` | | `FDM.demag` | `FDMDemag \| None` | `None` | $1$ | `FDM.__init__` has no explicit type check; a valid `FDMDemag` is required during lowering. | FDM demagnetization topology and common-grid controls. | FDM CPU/GPU. | `backend_policy.discretization_hints.fdm.demag` | | `FDM.boundary_correction` | `str \| None` | `None` | $1$ | `none`, `volume`, or `full`. | Partial-cell correction family: none, T0 volume fraction, or T1 full boundary stencil. | Lane/precision dependent; no universal qualification is implied. | `backend_policy.discretization_hints.fdm.boundary_correction` | | `FDM.boundary_phi_floor` | `float \| None` | `None` | $1$ | Strictly between $0$ and $1$ when supplied. | Lower bound for partial-cell volume fraction in stability logic. | Boundary-correction lanes. | `backend_policy.discretization_hints.fdm.boundary_phi_floor` | | `FDM.boundary_delta_min` | `float \| None` | `None` | $\mathrm{m}$ | Greater than or equal to $0$ when supplied. | Lower bound for T1 boundary distance. | Boundary-correction lanes. | `backend_policy.discretization_hints.fdm.boundary_delta_min` | ### Minimal stage-first script The example below runs one magnet on an FDM CPU FP64 grid and saves `H_demag`. For multiple disjoint layers, use the complete example on {doc}`multilayer-convolution` or the {doc}`../../../python-api/discretization/fdm-multilayer-convolution` guide. ```python # %% Imports and execution intent import fullmag as fm nm = 1.0e-9 study = fm.study("fdm_convolution_python") study.engine("fdm") study.device("cpu", precision="double") study.mode("strict") study.interactive(False) # %% One magnetic body and physical terms study.universe( mode="manual", size=(32.0 * nm, 16.0 * nm, 8.0 * nm), center=(0.0, 0.0, 0.0), padding=(0.0, 0.0, 0.0), ) magnet = study.geometry(fm.Box(size=(24.0 * nm, 12.0 * nm, 4.0 * nm)), name="magnet") magnet.mesh(cell_size=(4.0 * nm, 4.0 * nm, 4.0 * nm)) magnet.Ms = 800.0e3 magnet.Aex = 13.0e-12 magnet.alpha = 0.02 magnet.m = fm.init.UniformMagnetization((1.0, 0.0, 0.0)) study.exchange(enabled=True) study.demag(enabled=True) # %% Observable and fixed-step stage study.save("H_demag", every=1.0e-13) study.solver(integrator="rk4", fix_dt=1.0e-14, gamma=2.211e5) study.stages.add_run(until=1.0e-13, stage_id="fdm_demag_run") ``` (demag-fdm-problem-ir)= ## 6. ProblemIR and normalization `FDMDemag.to_ir()` stores the requested strategy and mode, plus explicit common-grid sizes. The outer `FDM.to_ir()` stores cell sizes, per-magnet overrides, boundary controls, and the nested demag policy. The planner then resolves actual grid dimensions, FFT padding, precision, masks, periodicity, and memory estimates. None of these resolved values may be inferred from `auto` after execution; they belong in provenance. The interaction term `Demag()` enables demagnetization. `FDMDemag` does not replace the physical term; it controls the FDM numerical realization. This separation means a requested physical model can remain identical while the resolved single-grid and multilayer paths differ. (demag-fdm-round-trip-and-failure-semantics)= ## 7. Round-trip and failure semantics **Requested intent** contains the authored cell, strategy, mode, boundary correction, and precision request. **Resolved execution** contains the common or native grids, padded FFT shape, tensor spectrum identity, active masks, periodic boundary policy, FP32/FP64 lane, memory reservation, and runtime identity. Constructor validation errors cover invalid strategies, modes, cell shapes, non-positive cell sizes, malformed common-grid dimensions, invalid volume-fraction floors, and the removed fallback switch. Planner validation reports incompatible periodic policies, grid-cost overflow, missing validated tensor spectra, and illegal output requests. Unsupported combinations are reported explicitly; the planner must not silently change multilayer convolution to one common grid or replace CUDA with CPU. (demag-fdm-discrete-realization)= ## 8. Discrete realization by lane ### FDM CPU reference The CPU reference path computes or consumes Newell tensor spectra, packs the magnetization into the FFT domain, accumulates the symmetric six-component tensor product, applies the overall negative sign, inverse-transforms the field, and performs the energy reduction. It is a trusted numerical reference lane, not evidence that a CUDA device executed. ### FDM GPU FP64 The persistent CUDA FP64 path uploads prevalidated tensor spectra, uses cuFFT for the vector components, applies device-side mask and volume-fraction semantics, and reduces energy in a CUDA reduction path. FP64 is a separate arithmetic lane: host double precision and device execution identity must both be recorded. ### FDM GPU FP32 The FP32 path uses float magnetization/field and complex spectra. It has distinct rounding and reduction behavior from FP64. A source-level or compile-only check cannot establish FP32/FP64 parity; the same grid, tensor, magnetization, padding, and executed device must be used in a comparison. ### Terminal single-grid fields and airbox — planned / in implementation This section specifies a terminal runtime contract; it does not add a Python DSL parameter, `ProblemIR` property, or a new demagnetization API. The contract is **planned / in implementation** until fresh completed-runtime evidence exists. In particular, source-level code, unit contracts, or CPU execution do not qualify a CUDA device path. On active magnetic support, `H_eff` is the full sum of every resolved active contribution: ```{math} :label: eq-fdm-final-active-effective-field \mathbf H_{\mathrm{eff},m} = \sum_{\ell\in\mathcal A_m}\mathbf H_\ell, \qquad \mathbf x\in\Omega_m. ``` The airbox is an observable domain, not magnetic solver support. When all source fields below are defined and materialized from the same state, it exposes only: ```{math} :label: eq-fdm-final-airbox-effective-field \mathbf H_{\mathrm{eff},\mathrm{air}} = \mathbf H_{\mathrm d} + \mathbf H_{\mathrm{ext}} + \mathbf H_{\mathrm{oe}} + \mathbf H_{\mathrm{ant}}, \qquad \mathbf x\in\Omega_{\mathrm{air}}. ``` For each of `H_demag`, `H_ext`, `H_oe`, and `H_ant`, the terminal legality check must record `full_domain` coverage for this exact structured grid, state generation, step, and time. Matching vector length does not prove this: a field can be `magnetic_only`. If a source is absent in the resolved plan its contribution is zero. If a required source is not `full_domain` or is not materialized from the same state, the airbox aggregate is unavailable; it must not combine values from different steps. `H_demag` is `full_domain` by the FDM observable contract. `H_ext` is `full_domain` only when its own observable metadata says so. `H_oe` is `full_domain` only when its own observable metadata says so. `H_ant` is `full_domain` only when its own observable metadata says so; its support cannot be inferred from its name. Material-only fields (exchange, anisotropy, DMI, magnetoelastic, thermal and torque) are zero or unavailable in the airbox with explicit metadata. For `Completed`, the target publication is one atomic replacement batch: final `m` and every requested field carry exactly the same terminal step and time. A newer complete batch replaces the previous terminal batch as a whole; consumers must not merge old and new quantities. This is session-memory retention only, not disk persistence or a restart guarantee. Durable field output still requires an explicit output/artifact schedule. `Failed` and `Cancelled` runs do not publish a completed terminal batch; any retained earlier batch keeps its own status, step, and time. `disable_preview_3d` controls intermediate 3-D preview work for benchmark/display use. It neither requests omission of terminal scientific-field finalization nor proves that a field has been persisted. The CPU single-grid target is host materialization and atomic replacement. The CUDA single-grid target must publish the same complete batch with executed-device evidence, or reject an unsupported requested terminal quantity explicitly; it may not silently substitute CPU data. ### Multilayer convolution `single_grid` makes the planner construct one common grid. `multilayer_convolution` preserves per-magnet native grids and evaluates self- and cross-layer tensor products explicitly. In `two_d_stack`, common in-plane cells are mandatory when explicitly provided; thickness and layer placement remain part of the resolved plan. The path must not silently fall back when the requested layout cannot be represented. (demag-fdm-implementation-mapping)= ## 9. Implementation mapping | Responsibility | Stable source owner | Lane | |---|---|---| | Python policy | `class FDMDemag` | Public authoring | | Newell base functions and 27-point tensor | `compute_newell_kernels` | CPU/reference preparation | | FFT tensor product | `accumulate_tensor_convolution` | CPU/reference | | CPU field path | `compute_newell_kernel_spectra` and `demag_field_from_vectors` | FDM CPU | | CUDA FP64 field | `launch_demag_field_fp64` | FDM GPU FP64 | | CUDA FP32 field | `launch_demag_field_fp32` | FDM GPU FP32 | | CUDA FP64 energy | `reduce_demag_energy_fp64` | FDM GPU FP64 | | GPU resource/FFT setup | `context_upload_demag_kernel_spectra` and `context_refresh_demag_observable` | FDM GPU | | Active and airbox effective-field reconstruction | `reconstruct_inactive_fdm_visual_effective_field` | FDM CPU, source-level owner; terminal contract not runtime-qualified | | Atomic terminal field materialization | `build_atomic_terminal_update` | FDM CPU, publishes one terminal update with the final field set | | CPU terminal outcome | `execute_reference_fdm` | FDM CPU source-level current path; not proof of an atomic terminal generation/batch | | Session field promotion | `ingest_preview_fields_from_update` | CLI promotes fields individually; not proof of an atomic terminal generation/batch | (demag-fdm-validation)= ## 10. Validation and qualification | Validation | Required evidence | |---|---| | Newell self term | Symmetry, diagonal trace convention, and independently computed self interaction. | | Open boundary | Padding and far-field comparison against an analytical or high-resolution reference. | | Uniform body | Demagnetization factors and energy for a rectangular prism, sphere, or ellipsoid. | | CPU/GPU parity | Same tensor spectrum, grid, mask, precision, reduction policy, and executed device. | | FP64/FP32 comparison | Absolute and relative field/energy error with a stated scale; near-zero values need absolute tolerances. | | Multilayer | Self and cross-layer terms, layer offsets, common-grid policy, and no-fallback behavior. | | Boundary correction | T0/T1 geometry, volume fractions, distance floor, precision and lane-specific evidence. | (demag-fdm-limitations)= ## 11. Limitations FFT padding is a finite computational embedding, not a proof of exact continuum infinity. FP32 reductions can differ from FP64 even when both use the same tensor spectrum. A larger FFT grid may reduce wraparound error but increases memory and does not fix geometric staircasing. `rtol` and linear-solver parameters belong to FEM Poisson/BEM; FDM convolution has no Krylov solve and must not expose those parameters as if they controlled FFT accuracy. (demag-fdm-scientific-bibliography)= ## 12. Scientific bibliography 1. A. J. Newell, W. Williams and D. J. Dunlop, “A calculation of the demagnetizing factors for cylinders,” *Journal of Geophysical Research*, 98, 9551–9555 (1993). 2. W. F. Brown, *Micromagnetics*, Wiley, 1963. 3. FullMag internal reference: `docs/physics/0420-fdm-dipolar-demag-foundations.md`. (demag-fdm-source-code-index)= ## 13. Source-code index | Repository path | Stable symbol | Responsibility | Lane | |---|---|---|---| | `packages/fullmag-py/src/fullmag/model/discretization.py` | `class FDMDemag` | Strategy, mode, common-grid and explanation policy. | Public authoring | | `packages/fullmag-py/src/fullmag/model/discretization.py` | `class FDM` | Cell, multilayer and boundary-correction policy. | Public authoring | | `crates/fullmag-fdm-demag/src/newell.rs` | `compute_newell_kernels` | Newell base functions, 27-point tensor and stable summation. | CPU/reference | | `crates/fullmag-fdm-demag/src/multiply.rs` | `accumulate_tensor_convolution` | Symmetric tensor-vector FFT product before negation. | CPU/reference | | `crates/fullmag-engine/src/fdm/cpu/fft.rs` | `compute_newell_kernel_spectra` | CPU kernel-spectrum construction. | FDM CPU | | `crates/fullmag-engine/src/fdm/cpu/fields.rs` | `demag_field_from_vectors` | CPU field realization. | FDM CPU | | `backends/fdm/gpu/cuda/interactions/demag_fp64.cu` | `launch_demag_field_fp64` | CUDA double-precision field dispatch. | FDM GPU FP64 | | `backends/fdm/gpu/cuda/interactions/demag_fp32.cu` | `launch_demag_field_fp32` | CUDA single-precision field dispatch. | FDM GPU FP32 | | `backends/fdm/gpu/cuda/runtime/reductions_fp64.cu` | `reduce_demag_energy_fp64` | CUDA FP64 energy reduction. | FDM GPU FP64 | | `backends/fdm/gpu/cuda/runtime/context.cu` | `context_upload_demag_kernel_spectra` | Device tensor-spectrum upload and validation. | FDM GPU | | `backends/fdm/gpu/cuda/runtime/context.cu` | `context_refresh_demag_observable` | Device demag observable refresh. | FDM GPU | | `crates/fullmag-runner/src/fdm/cpu/reference.rs` | `reconstruct_inactive_fdm_visual_effective_field` | Reconstructs the defined airbox aggregate from demag, external, Oersted and antenna fields. | FDM CPU, source-level only | | `crates/fullmag-runner/src/interactive/runtime.rs` | `build_atomic_terminal_update` | Builds one atomic terminal update and materializes the final FDM field set from the terminal backend state. | FDM CPU, source-level only | | `crates/fullmag-runner/src/fdm/cpu/reference.rs` | `execute_reference_fdm` | Returns the CPU terminal run outcome and scheduled outputs; it is not proof of an atomic terminal generation/batch. | FDM CPU, source-level only | | `crates/fullmag-cli/src/live_workspace.rs` | `ingest_preview_fields_from_update` | Promotes incoming fields individually into session state; it is not proof of an atomic terminal generation/batch. | CLI control plane | | `crates/fullmag-cli/src/live_workspace.rs` | `feature_flags` | Reads preview-disable benchmark/display configuration. | CLI control plane | ## Control Room crosswalk Use `Model Explorer -> Objects -> -> Physics` when `PhysicsInteractionPanel` exposes the interaction. Status: `partial`. frontend support is not implemented applies to physical parameters without a matching control. See {doc}/frontend/capability-register; do not infer UI support from backend or Python availability. ## Python/API crosswalk The linked Python API page is authoritative for exact functions, arguments, units, and failure semantics. If this page is a foundation or category overview, runnable Python is ot applicable here and must be taken from the terminal API page. ## Bibliography and source scope Use the scientific bibliography and source-code index on the linked terminal page. This block adds no new equation or unverified implementation claim. ## Source-code index - Public Python and lowering sources are linked by the applicable terminal API page. Runtime realization is in the relevant `backends/fdm` or `backends/fem` lane; frontend ownership is `apps/control-room/src/modules/inspector/panels/PhysicsInteractionPanel.tsx` where a live control exists.