FDM tensor convolution and FFT demagnetization¶
Last changes: Documentation changelog
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 Periodic Demagnetization.
For multiple separated magnetic layers with native grids, use the dedicated FDM multilayer demagnetizing-field convolution physics page and the complete FDM multilayer convolution: Python, ProblemIR, and UI Python/ProblemIR/UI guide.
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.
2. Governing equations¶
The continuous energy convention is
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
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
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
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:
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.
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\) |
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.
5. Python API and complete parameter reference¶
Python parameter |
Type |
Default |
SI unit |
Validation |
Meaning |
Backend support |
ProblemIR |
|---|---|---|---|---|---|---|---|
|
|
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. |
|
|
|
|
\(\mathrm{m}\) |
Three finite positive values. |
Default native cell size. |
FDM CPU/GPU. |
|
|
|
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. |
|
|
|
|
\(1\) |
|
Selects one common-grid or explicit multilayer convolution topology. |
FDM CPU/GPU. |
|
|
|
|
\(1\) |
|
Selects thin-film stack or full 3-D multilayer mode. |
FDM CPU/GPU. |
|
|
|
|
\(1\) |
Exactly three positive integers. |
Explicit 3-D common convolution grid size. |
FDM CPU/GPU. |
|
|
|
|
\(1\) |
Exactly two positive integers. |
Explicit in-plane common grid for |
FDM CPU/GPU. |
|
|
|
|
\(1\) |
Any non- |
Removed compatibility switch. |
Unsupported; choose strategy explicitly. |
Not serialized |
|
|
|
\(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 |
|
|
required |
\(\mathrm{m}\) |
Exactly three finite positive values. |
Native Cartesian cell size for one named magnet. |
FDM multilayer authoring. |
|
|
|
|
\(\mathrm{m}\) |
Backward-compatible alias; cannot be supplied together with |
Legacy spelling of the default Cartesian cell size. |
FDM CPU/GPU. |
Both |
|
|
|
\(\mathrm{m}\) |
Exactly three finite positive values; cannot be supplied together with |
Default Cartesian cell size. |
FDM CPU/GPU. |
Both |
|
|
|
\(1\) |
Each grid has three positive cell sizes. |
Native grid overrides for individual magnets. |
FDM multilayer paths. |
|
|
|
|
\(1\) |
|
FDM demagnetization topology and common-grid controls. |
FDM CPU/GPU. |
|
|
|
|
\(1\) |
|
Partial-cell correction family: none, T0 volume fraction, or T1 full boundary stencil. |
Lane/precision dependent; no universal qualification is implied. |
|
|
|
|
\(1\) |
Strictly between \(0\) and \(1\) when supplied. |
Lower bound for partial-cell volume fraction in stability logic. |
Boundary-correction lanes. |
|
|
|
|
\(\mathrm{m}\) |
Greater than or equal to \(0\) when supplied. |
Lower bound for T1 boundary distance. |
Boundary-correction lanes. |
|
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
FDM multilayer demagnetizing-field convolution or the
FDM multilayer convolution: Python, ProblemIR, and UI guide.
# %% 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")
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.
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.
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:
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:
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.
9. Implementation mapping¶
Responsibility |
Stable source owner |
Lane |
|---|---|---|
Python policy |
|
Public authoring |
Newell base functions and 27-point tensor |
|
CPU/reference preparation |
FFT tensor product |
|
CPU/reference |
CPU field path |
|
FDM CPU |
CUDA FP64 field |
|
FDM GPU FP64 |
CUDA FP32 field |
|
FDM GPU FP32 |
CUDA FP64 energy |
|
FDM GPU FP64 |
GPU resource/FFT setup |
|
FDM GPU |
Active and airbox effective-field reconstruction |
|
FDM CPU, source-level owner; terminal contract not runtime-qualified |
Atomic terminal field materialization |
|
FDM CPU, publishes one terminal update with the final field set |
CPU terminal outcome |
|
FDM CPU source-level current path; not proof of an atomic terminal generation/batch |
Session field promotion |
|
CLI promotes fields individually; not proof of an atomic terminal generation/batch |
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. |
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.
12. Scientific bibliography¶
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).
W. F. Brown, Micromagnetics, Wiley, 1963.
FullMag internal reference:
docs/physics/0420-fdm-dipolar-demag-foundations.md.
13. Source-code index¶
Repository path |
Stable symbol |
Responsibility |
Lane |
|---|---|---|---|
|
|
Strategy, mode, common-grid and explanation policy. |
Public authoring |
|
|
Cell, multilayer and boundary-correction policy. |
Public authoring |
|
|
Newell base functions, 27-point tensor and stable summation. |
CPU/reference |
|
|
Symmetric tensor-vector FFT product before negation. |
CPU/reference |
|
|
CPU kernel-spectrum construction. |
FDM CPU |
|
|
CPU field realization. |
FDM CPU |
|
|
CUDA double-precision field dispatch. |
FDM GPU FP64 |
|
|
CUDA single-precision field dispatch. |
FDM GPU FP32 |
|
|
CUDA FP64 energy reduction. |
FDM GPU FP64 |
|
|
Device tensor-spectrum upload and validation. |
FDM GPU |
|
|
Device demag observable refresh. |
FDM GPU |
|
|
Reconstructs the defined airbox aggregate from demag, external, Oersted and antenna fields. |
FDM CPU, source-level only |
|
|
Builds one atomic terminal update and materializes the final FDM field set from the terminal backend state. |
FDM CPU, source-level only |
|
|
Returns the CPU terminal run outcome and scheduled outputs; it is not proof of an atomic terminal generation/batch. |
FDM CPU, source-level only |
|
|
Promotes incoming fields individually into session state; it is not proof of an atomic terminal generation/batch. |
CLI control plane |
|
|
Reads preview-disable benchmark/display configuration. |
CLI control plane |
Control Room crosswalk¶
Use Model Explorer -> Objects -> <object> -> 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/fdmorbackends/femlane; frontend ownership isapps/control-room/src/modules/inspector/panels/PhysicsInteractionPanel.tsxwhere a live control exists.