FDM multilayer demagnetizing-field convolution¶
Last changes: Documentation changelog
This page describes the physics, discretization, and public configuration contract for
multilayer_convolution. The method computes the demagnetizing field of disconnected
magnetic layers or objects on separate FDM grids. It is not a FEM Poisson or BEM model;
choosing this strategy changes the numerical realization but does not change the physical
definition of the demagnetizing field.
Each magnetic object owns a native FDM grid. The common convolution grid is an FFT supercell used
for pair kernels and transfers; it is neither a material mesh nor a FEM universe mesh. Geometry
translations determine layer offsets, including the signed \(z\) offsets used by the kernels. A
public FDM multilayer script uses named geometry and per-object mesh(cell_size=...) calls;
study.universe.mesh(cell_size=...) defines the common computational-grid resolution when it
cannot be inferred, and study.demag() enables the physical interaction.
The partial status is intentional. FDM CPU FP64 has local field, energy, reciprocity,
and transfer evidence for the stated case classes. CUDA sources and the ABI contract are
implemented, but without a fresh, complete device comparison the GPU lane must not be
called production-qualified.
1. Physical problem¶
Consider \(L\) disconnected ferromagnetic objects. Index \(s\) denotes a source layer and
\(d\) a destination layer. Each layer has its own regular native_grid, cell size
\(\mathbf h_s\), origin \(\mathbf o_s\), active mask, and magnetization field \(\mathbf M_s\).
The only permitted pair-offset convention is
\(\boldsymbol\delta_{d,s}=\mathbf o_d-\mathbf o_s\).
The field in a destination layer is the sum of its self contribution and all inter-layer
contributions. FFT convolution accelerates this sum; it does not replace the magnetostatic
tensor with a local approximation. The scratch_grid is a computational tool. Physical
position, source-cell size, and destination-cell size remain part of the kernel.
2. Governing equations¶
2.1. Continuous model and discrete pair sum¶
The magnetostatic field is defined by
The implemented FDM contract is a directed source-to-destination pair sum corresponding to equation (3) of Lepadatu (2019):
The tensor \(\mathsf N\) has six independent components: \(N_{xx}\), \(N_{yy}\), \(N_{zz}\), \(N_{xy}\), \(N_{xz}\), and \(N_{yz}\). The minus sign belongs to the field definition. Tensor-vector multiplication in the FFT domain accumulates the product without that sign, and the field stage applies the negation exactly once.
2.2. Reciprocity and energy¶
For different cell volumes, reciprocity is volume-weighted:
Simple equality of the two directions is valid only when \(V_d=V_s\). The demagnetization energy over active cells in all layers is
The factor \(1/2\) removes double counting of pair energy. The field, active mask, volumes, and precision used by the energy reduction must match the field path.
2.3. FFT convolution¶
Each source layer is transformed once, each ordered pair accumulates a six-component tensor product, and each destination receives one inverse transform:
One complete operator refresh for \(L\) layers therefore has \(L\) forward transforms, \(L\) inverse transforms, and \(L^2\) pair accumulations. These counters describe the demagnetization operator, not automatically the residency of the complete time integrator.
2.4. Transfer between native_grid and scratch_grid¶
When native and scratch grids differ, magnetization is transferred by operator \(P\):
The weights from equations (4)-(5) of Lepadatu are
Returning the field to a native grid must use the volume-adjoint \(P^*\):
This identity is the work and energy conservation condition. Pointwise field interpolation alone is not sufficient evidence of a correct transfer.
2.5. Irregular Newell tensor for unequal Z thickness¶
For common \(h_x,h_y\) and different \(h_{s,z},h_{d,z}\), Appendix A of the publication defines
The remaining components follow by axis permutations consistent with Newell-tensor symmetry. Appendix A covers unequal Z thickness with a common XY cell size; it does not justify arbitrary XY offsets or arbitrary, different XY grids.
3. Symbols and SI units¶
Symbol |
Meaning |
SI unit |
|---|---|---|
\(L\) |
number of magnetic layers |
\(1\) |
\(d,s\) |
destination and source layer indices |
\(1\) |
\(l,j,c,i\) |
cell, component, or transfer-point indices |
\(1\) |
\(\Omega_m\) |
magnetic part of the domain |
\(\mathrm{m^3}\) |
\(V_s\) |
source domain or source-cell volume, according to the sum context |
\(\mathrm{m^3}\) |
\(V_d\) |
destination-cell volume |
\(\mathrm{m^3}\) |
\(V_{d,c}\) |
volume of active cell \(c\) in destination layer \(d\) |
\(\mathrm{m^3}\) |
\(V_c\) |
convolution-cell volume |
\(\mathrm{m^3}\) |
\(V_n\) |
native-cell volume |
\(\mathrm{m^3}\) |
\(\mathbf r,\mathbf r'\) |
observation and source positions in the continuous model |
\(\mathrm m\) |
\(\mathbf r_{d,l}\) |
destination-cell center |
\(\mathrm m\) |
\(\mathbf r_{s,j}\) |
source-cell center |
\(\mathrm m\) |
\(\mathbf r_i\) |
input-cell center for transfer |
\(\mathrm m\) |
\(\mathbf o_d,\mathbf o_s\) |
destination and source grid origins |
\(\mathrm m\) |
\(\boldsymbol\delta_{d,s}\) |
offset \(\mathbf o_d-\mathbf o_s\) |
\(\mathrm m\) |
\(\mathbf q\) |
spatial kernel lag |
\(\mathrm m\) |
\(\mathbf s=(x,y,z)\) |
spatial argument of the Appendix A operator |
\(\mathrm m\) |
\(x,y,z\) |
coordinates of the kernel argument |
\(\mathrm m\) |
\(R\) |
distance \(\sqrt{x^2+y^2+z^2}\) |
\(\mathrm m\) |
\(\mathbf h_s,\mathbf h_d\) |
source and destination cell sizes |
\(\mathrm m\) |
\(\mathbf h,\mathbf h'\) |
input and scratch transfer-cell sizes |
\(\mathrm m\) |
\(h_x,h_y\) |
common cell sizes along X and Y |
\(\mathrm m\) |
\(h_{s,z},h_{d,z}\) |
source and destination cell thicknesses |
\(\mathrm m\) |
\(\Delta\) |
difference \(h_{s,z}-h_{d,z}\) |
\(\mathrm m\) |
\(\tau\) |
normalization \(\pi h_xh_yh_{d,z}\) |
\(\mathrm{m^3}\) |
\(\mathbf M,\mathbf M_s,\mathbf M_{d,c}\) |
magnetization |
\(\mathrm{A\,m^{-1}}\) |
\(\mathbf H,\mathbf H_d,\mathbf H_{d,c},\mathbf H_c\) |
magnetostatic or demagnetizing field |
\(\mathrm{A\,m^{-1}}\) |
\(\widehat{\mathbf M}_s\) |
discrete transform of source magnetization |
\(\mathrm{A\,m^{-1}}\) |
\(\widehat{\mathbf H}_d\) |
discrete transform of the destination field |
\(\mathrm{A\,m^{-1}}\) |
\(\mathcal N\) |
continuous magnetostatic kernel |
\(\mathrm{m^{-3}}\) |
\(\mathsf N,\mathsf N_{d\leftarrow s}\) |
discrete cell-pair demagnetizing tensor |
\(1\) |
\(\widehat{\mathsf N}_{d\leftarrow s}\) |
discrete transform of the pair tensor |
\(1\) |
\(N_{xx},N_{yy},N_{zz},N_{xy},N_{xz},N_{yz}\) |
six independent tensor components |
\(1\) |
\(\mathcal F,\mathcal F^{-1}\) |
discrete Fourier transform and inverse |
\(1\) |
\(\mathbf k\) |
discrete-transform index or wave vector |
\(\mathrm{m^{-1}}\) |
\(P,P^*\) |
native-to-scratch transfer and volume adjoint |
\(1\) |
\(\mathcal P\) |
set of cells participating in transfer |
\(1\) |
\(w_i\) |
normalized transfer weight |
\(1\) |
\(\delta_i\) |
cell-overlap indicator |
\(1\) |
\(\widetilde d_i,\widetilde d_T\) |
weighted distance and its sum |
\(\mathrm m\) |
\(\mathcal A_d\) |
active-cell set of layer \(d\) |
\(1\) |
\(E_{\mathrm d}\) |
demagnetization energy |
\(\mathrm J\) |
\(\mu_0\) |
vacuum permeability |
\(\mathrm{N\,A^{-2}}\) |
\(\mathcal L\) |
irregular Newell corner operator |
\(1\) |
\(f,g,w\) |
Appendix A basis functions |
\(\mathrm{m^3}\) |
\(\epsilon_1,\epsilon_2\) |
corner-sum indices |
\(1\) |
4. Assumptions, kernel classes, and validity limits¶
The current public planner accepts disconnected objects with different XY extents and/or
centers by forming the union of their native XY bounds as a computational common-scratch
envelope. Native origins, cell sizes, masks, and material objects remain independent; layers
that do not coincide with that envelope use explicit push_pull transfer. An explicitly
requested common_cells or common_cells_xy must contain the union and have a compatible
resolved pitch; a lane that cannot consume the resulting insertion/crop or transfer descriptor
fails closed. This is not the same as evaluating the irregular Newell formula on arbitrary
different XY cells: that formula is only the unequal-Z/common-XY kernel, while lateral
differences are handled by the transfer path. Layers may be separated by arbitrary non-overlapping
Z gaps, but overlapping bodies and periodic axes fail closed until the corresponding pair,
transfer, and exchange-seam classes are qualified.
two_d_stack is intended for thin layers with one native Z cell. A layer with multiple Z
cells is rejected: there is no public moment-preserving Z average today, and the planner
does not copy an arbitrary slice. Select three_d instead. common_cells_xy=(N_x,N_y)
resolves a scratch grid \((N_x,N_y,1)\); common_cells=(N_x,N_y,N_z) selects a full 3-D grid.
two_d_stack is a Fullmag mode, not a spelling for BORIS 2dmulticonvolution=1 or =2:
those BORIS modes remain distinct, unsupported semantics. If both common_cells fields are
absent, Fullmag applies planner-auto common-scratch selection and records the resolved layout in
the plan/provenance; the authored ProblemIR contains no common_cells* fields. This absence is
not an alias for BORIS ncommonstatus=false, whose largest-mesh default is a different policy.
The symmetry classes in Lepadatu Table I determine the legal spectral representation:
Class |
Geometry |
Spectral representation and storage |
Fullmag status |
|---|---|---|---|
2D-self |
one Z cell, no shift |
real diagonal and XY components, reduced |
locally verified CPU FP64; no production qualification |
3D-self |
common cell size |
real, reduced |
small L=3 local oracle; no independent managed receipt |
2D-zShift |
common XY, pure Z shift |
real diagonal/XY, imaginary XZ/YZ, reduced |
locally verified CPU FP64 for both Z signs |
3D-zShift |
common cell, pure Z shift |
complex, reduced |
small local oracle; no complete production matrix |
2D-full |
geometry without shift-only parity |
complex, full |
not an executable qualified lane |
3D-full |
general 3-D geometry |
complex, full |
not an executable qualified lane |
Zero padding must provide at least \(n_{\mathrm{src}}+n_{\mathrm{dst}}-1\) samples on each
axis for a linear convolution. The transform descriptor separates physical grids from
fft_shape, insertion offsets, lag-zero position, and destination crop. The inverse
transform applies \(1/(F_xF_yF_z)\) exactly once.
5. Python API¶
5.1. Complete parameter table¶
The canonical interface separates the physical interaction from its numerical realization. Mesh
calls carry geometric resolution, study.demag() enables the interaction, and the planner selects
the qualified numerical realization. The FDM* rows document migration adapters only.
Python parameter |
Type |
Default |
SI unit |
Validation |
Meaning |
Backend support |
ProblemIR |
|---|---|---|---|---|---|---|---|
|
|
required unless a default exists |
\(\mathrm m\) |
Exactly three finite positive values; object extents must divide exactly. |
Native Cartesian cell size of one magnetic object. |
FDM CPU/GPU authoring; runtime lane gated. |
|
|
|
|
\(\mathrm m\) |
Exactly three finite positive values. |
Default native cell size for objects without overrides. |
FDM CPU/GPU authoring. |
|
|
|
required for unequal native grids |
\(\mathrm m\) |
Exactly three finite positive values; common extents must divide exactly. |
Requested non-physical common convolution-grid resolution. |
FDM multilayer CPU/GPU authoring; runtime lane gated. |
|
|
|
|
\(\mathrm m\) |
Exactly three finite, positive values. |
Native cell size of one named magnet. |
FDM CPU/GPU authoring; execution remains lane-gated. |
|
|
|
|
\(\mathrm m\) |
Exactly three positive values; cannot be supplied with |
Backward-compatible alias for the default cell size. |
FDM CPU/GPU authoring. |
|
|
|
|
\(\mathrm m\) |
Exactly three positive values; required when the per-magnet map is incomplete. |
Default native cell size. |
FDM CPU/GPU authoring. |
|
|
|
|
\(1\) |
Keys are non-empty names; values must be |
Native-grid overrides for named magnets. |
FDM multilayer CPU/GPU authoring. |
|
|
|
|
\(1\) |
|
Demagnetizing-field realization policy. |
FDM CPU/GPU authoring. |
|
|
|
|
\(1\) |
|
Requested strategy; an explicit multilayer request cannot silently fall back to single grid. |
FDM CPU/GPU authoring; runtime qualified per lane. |
|
|
|
|
\(1\) |
|
Requested mode; |
FDM CPU/GPU authoring. |
|
|
|
|
\(1\) |
Three positive integers; mutually exclusive with |
Explicit full 3-D scratch-grid size. |
FDM CPU/GPU authoring. |
|
|
|
|
\(1\) |
Two positive integers; mutually exclusive with |
Explicit in-plane scratch-grid size for a 2-D stack. |
FDM CPU/GPU authoring. |
|
|
|
|
\(1\) |
The raw script builder requires a Boolean; the constructor itself does not type-check it. |
Requests a readable plan explanation; it is not physical data and is not serialized by |
FDM authoring helper. |
|
|
|
|
\(1\) |
Any value other than |
Removed compatibility switch; forbids silent fallback. |
Unsupported combinations are rejected. |
|
boundary_correction, boundary_phi_floor, and boundary_delta_min belong to the
general FDM partial-cell policy. They are not multilayer-convolution parameters and are not
presented as FFT, padding, or transfer-accuracy controls. The current multilayer plan does not
carry or reject non-neutral values and therefore does not fail closed, which is an open round-trip
defect. Until their per-layer meaning is defined and validated, these inputs must not be used with
multilayer convolution.
The current qualification boundary is stricter than source availability: CPU FP64 has scoped,
local evidence. The declared push_pull operator is locally validated for different extents and
\(V_{native}\ne V_{scratch}\); the missing proof is a direct continuum/native-cell oracle for
\(h_{source,z}\ne h_{destination,z}\).
CUDA-assisted execution for heterogeneous two_d_stack cases does not yet use the same
descriptor pair operator as CPU, and no CUDA lane is runtime-verified or production-qualified.
5.2. Common XY versus full 3-D mode¶
two_d_stack is a thin-layer optimization. It is legal only when every magnetic object has one
native cell through its thickness. The solver retains each layer’s world-space Z origin, but the
common transform has one Z plane. It is therefore unsuitable when magnetization may vary through
the thickness.
three_d retains multiple common cells along Z. The planner selects it whenever any native layer
has more than one Z cell or when the author supplies all three components of
study.universe.mesh(cell_size=...). This does not merge the magnets: native magnetization and
field samples remain on each object’s mesh, while the common 3-D supercell is temporary FFT
storage.
study.mode("strict") is an execution policy, not an accuracy preset. It forbids rounding a cell
count, resizing geometry, silently changing the requested cell sizes, or falling back to an
unqualified transfer/backend. A planned and qualified push_pull transfer is part of the selected
method, so using it does not violate strict mode.
5.3. Heterogeneous native grids with a 3-D supercell¶
This example is the regression case exercised by the Python, planner, round-trip, and CPU
reference tests. The lower magnet uses 2 nm x 2 nm x 10 nm cells, the upper magnet uses
5 nm x 5 nm x 10 nm cells, and the common convolution domain uses
2 nm x 2 nm x 2.5 nm cells.
import fullmag as fm
nm = 1.0e-9
study = fm.study("heterogeneous_fdm_multilayer")
study.engine("fdm")
study.device("cpu", precision="double")
study.mode("strict")
bottom = study.geometry(
fm.Box(size=(100 * nm, 50 * nm, 10 * nm)),
name="layer_bottom",
)
top = study.geometry(
fm.Box(size=(100 * nm, 50 * nm, 10 * nm)).translate((0, 0, 20 * nm)),
name="layer_top",
)
bottom.mesh(cell_size=(2 * nm, 2 * nm, 10 * nm))
top.mesh(cell_size=(5 * nm, 5 * nm, 10 * nm))
study.universe.mesh(cell_size=(2 * nm, 2 * nm, 2.5 * nm))
for layer in (bottom, top):
layer.Ms = 800e3
layer.Aex = 13e-12
layer.alpha = 0.02
layer.m = fm.init.UniformMagnetization((1.0, 0.0, 0.0))
study.exchange(enabled=True)
study.demag(enabled=True)
study.stages.add_run(until=1e-13, stage_id="heterogeneous_run")
The common XY extent is 100 nm x 50 nm, so exact division gives 50 x 25 common cells.
The common scratch thickness is the maximum native layer thickness, 10 nm, not the complete
30 nm world-space span between the bottom of the first layer and the top of the second. Layer
separation is encoded in pair-kernel offsets. Therefore 10 nm / 2.5 nm = 4 and the resolved
common transform shape is 50 x 25 x 4.
The lower native shape is 50 x 25 x 1; the upper native shape is 20 x 10 x 1. Because a
5 nm cell is not an integer multiple of a 2 nm common cell in XY, direct copying would be
wrong. The planner selects push_pull: volume-overlap weights push magnetization to the common
grid and the volume-adjoint pull maps the computed field back to each native grid. The CPU test
checks that this real transfer executes, produces finite demagnetization energy, and preserves 29
native cells across the two reduced test layers.
5.5. When to use three_d¶
Set mode="three_d" and common_cells=(N_x,N_y,N_z) when at least one layer has multiple
native Z cells or when through-thickness texture matters. Do not set common_cells_xy at
the same time. For the simplest identity transfer, choose a common grid equal to every
native grid. Different grids activate push_pull and require a separate transfer-error
assessment.
5.6. Real test scenarios and interpretation¶
The cases below are copyable counterparts of the fixtures in
tests/standard_problems/mumag/sp4/fdm/multilayer_convolution/. They are
SP4-derived scenarios, not the canonical µMAG Standard Problem 4.
L=3, three_d, transfer identity¶
This case has three layers of size 31.25 nm × 15.625 nm × 6 nm, native cell
(3.90625 nm, 3.90625 nm, 3 nm), and common grid (8, 4, 2). Every layer has
the same grid, so the planner can use identity; Z translations remain part of
the physical pair offset.
# %% L=3 identity fixture (corresponds to scenario_l3_identity_3d_small.py)
import fullmag as fm
CELL = (3.90625e-9, 3.90625e-9, 3e-9)
SIZE = (31.25e-9, 15.625e-9, 6e-9)
study = fm.study("fdm_multilayer_l3_identity_3d_small")
study.engine("fdm")
study.device("cpu", precision="double")
study.mode("strict")
study.universe(mode="manual", size=(40e-9, 20e-9, 36e-9),
center=(0.0, 0.0, 12e-9), padding=(0.0, 0.0, 0.0))
for name, z in (("layer_bottom", 0.0), ("layer_middle", 12e-9),
("layer_top", 24e-9)):
shape = fm.Box(size=SIZE).translate((0.0, 0.0, z))
layer = study.geometry(shape, name=name)
layer.mesh(cell_size=CELL)
layer.Ms = 8e5
layer.Aex = 1.3e-11
layer.alpha = 0.02
layer.m = fm.init.UniformMagnetization((0.9950371902099893,
0.09950371902099893, 0.0))
study.universe.mesh(cell_size=CELL)
study.exchange(enabled=True)
study.demag(enabled=True)
study.stages.add_run(until=1e-14, stage_id="l3_identity_three_d_small")
The test test_l3_identity_three_d_scenario_preserves_common_identity_grid
checks the exact lowered strategy, mode, common_cells, and three
per_magnet entries. It does not measure fields; it is authoring and ProblemIR
evidence.
L=2, unequal thickness through three_d¶
scenario_unequal_small.py uses a lower layer of height 3 nm, an upper layer
of 6 nm, the same native cell, and common_cells=(16, 8, 2). The native Z
counts are 1 and 2, respectively. This is the correct public way to encode
through-thickness texture: do not force two_d_stack or pretend that a Z
average was performed.
# %% Unequal-Z fixture (corresponds to scenario_unequal_small.py)
import fullmag as fm
cell = (3.90625e-9, 3.90625e-9, 3e-9)
study = fm.study("fdm_multilayer_unequal_z_small")
study.engine("fdm")
study.device("cpu", precision="double")
study.mode("strict")
study.universe(mode="manual", size=(64e-9, 32e-9, 24e-9),
center=(0.0, 0.0, 7.5e-9), padding=(0.0, 0.0, 0.0))
bottom = study.geometry(
fm.Box(size=(31.25e-9, 15.625e-9, 3e-9)), name="layer_bottom"
)
top_shape = fm.Box(size=(31.25e-9, 15.625e-9, 6e-9)).translate(
(0.0, 0.0, 12e-9)
)
top = study.geometry(top_shape, name="layer_top")
bottom.mesh(cell_size=cell)
top.mesh(cell_size=cell)
study.universe.mesh(cell_size=cell)
for layer in (bottom, top):
layer.Ms = 8e5
layer.Aex = 1.3e-11
layer.alpha = 0.02
layer.m = fm.init.UniformMagnetization((0.9950371902099893,
0.09950371902099893, 0.0))
study.exchange(enabled=True)
study.demag(enabled=True)
study.stages.add_run(until=1e-14, stage_id="l2_unequal_small")
Supercell and push_pull¶
In scenario_l3_heterogeneous_small.py, the layers have native Z counts
1/2/1 but share a working grid (16, 8, 2). This requires explicit
native → scratch → native transfer; it does not create one ferromagnetic mesh
covering all layers. The multilayer_engine tests also check that a regular
stack of nine ordered pairs materializes five unique kernels and that an
irregular stack does not perform forbidden reuse.
The small descriptor test uses simpler numbers: source [3,2,1], target
[5,4,1], hence linear extent [7,5,1]; crop and insertion offset are stored
separately. CommonTransformLayout has physical_mesh=false. A field in this
scratch grid is not an observable material field and must not be rendered as a
layer.
Test |
Result on current |
Interpretation |
|---|---|---|
|
19/19 |
supercell, mask, crop, padding, and reuse contract; no field proof |
|
7/7 |
GL8 for unequal \(h_z\), separate parity for \(+z/-z\) offsets, inverse FFT, reciprocity, and unequal-XY fail-closed behavior |
|
7/7 |
independent cubature, parity, and bounded far-field |
|
16/16 (one benchmark |
CPU catalog/workspace and transfer contracts |
|
25/25 |
planner mode, identity/push-pull, PBC, and unsupported interactions |
|
4/4 (filter |
Z moment, masked adjointness, reused buffers, and fail-closed PBC |
Python fixture tests |
21/21 |
stage-first authoring, lowering, and fail-closed API; no field parity |
These results are contract tests and local oracles. They do not promote CUDA to
runtime-verified: the current CUDA-assisted heterogeneous path does not use
the same descriptor pair operator as CPU, and the complete step remains
host-authoritative. For unequal native-cell thicknesses, an independent
continuum/native-cell oracle for composed transfer is still missing.
6. ProblemIR, planner, and provenance¶
FDMGrid.to_ir() normalizes a cell tuple to an SI list. FDMDemag.to_ir() writes only
the requested strategy, requested mode, and optional common layout. explain does not
change physics and does not enter ProblemIR.
The following fragment is the actual serialized shape for an \(L=3\) scenario with
mode="three_d":
{
"backend_policy": {
"discretization_hints": {
"fdm": {
"cell": [3.90625e-09, 3.90625e-09, 3e-09],
"default_cell": [3.90625e-09, 3.90625e-09, 3e-09],
"per_magnet": {
"layer_bottom": {"cell": [3.90625e-09, 3.90625e-09, 3e-09]},
"layer_middle": {"cell": [3.90625e-09, 3.90625e-09, 3e-09]},
"layer_top": {"cell": [3.90625e-09, 3.90625e-09, 3e-09]}
},
"demag": {
"strategy": "multilayer_convolution",
"mode": "three_d",
"common_cells": [16, 8, 2]
}
}
}
}
}
The planner creates one FdmLayerPlanIR per object and one FdmMultilayerPlanIR for the
realization. Each layer contains stable layer_id, object_id, native grid, origin, mask,
scratch grid, and transfer_kind. planner_summary preserves requested_strategy,
selected_strategy, requested_mode, resolved_mode, eligibility, and estimates of kernel
count and memory.
7. Round-trip and failure semantics¶
requested intent is the authored contract: strategy, mode, per-magnet cells, common
layout, device, and precision. resolved execution is the planner/runtime decision:
actual mode, grids, transfers, padding, FFT backend, device, and operator counters. UI
export preserves requested intent through public mesh-authoring calls plus study.demag(); it does not
export multilayer as a FEM realization.
validation errors are returned for invalid enums, non-positive sizes, simultaneous
common_cells and common_cells_xy, mode/layout mismatches, missing per-magnet cells,
overlapping layers, an explicit common grid that cannot contain the union of native XY
rectangles, unsupported transfer/boundary combinations, and periodicity.
unsupported combinations must be rejected; the planner cannot silently change strategy,
device, precision, boundary conditions, or remove an interaction.
Runtime artifacts must separate requested/resolved demag realization, transfer telemetry,
and CUDA stage telemetry. CUDA L/L/L² counters prove the shape of one device demag refresh,
not that the complete integrator was device-resident.
8. Backend realizations¶
Solver |
Device |
Status |
What is implemented |
What the status does not prove |
|---|---|---|---|---|
FDM |
CPU |
|
FP64, FFT, six-component pairs, identity and push/pull, field and energy; local 2-D/3-D oracles and scoped Airbox convergence. |
Does not automatically qualify full-complex, PBC, or every size and offset. |
FDM |
GPU |
|
ABI v2, D-07 plan, cuFFT workspace, and stage telemetry counters exist in source. |
Build and ABI contract do not replace fresh executed-device field/energy parity; FP32 has separate thresholds. |
FEM |
CPU |
|
None: this method is Newell/FFT Cartesian convolution on FDM grids. |
It does not describe Poisson on an Airbox or FEM-BEM. |
FEM |
GPU |
|
None for the same physical/numerical reason; FEM GPU has separate magnetostatic realizations. |
|
8.1. FDM CPU¶
CPU FP64 is the reference execution lane. MultilayerDemagRuntime clears each destination
spectrum, sums all sources, performs the inverse FFT, and pulls the field back to the native
grid. The 2-D lane uses the exact Newell corner sum. General 3-D has an explicitly bounded
asymptotic branch for distant pairs; the oracle scope must therefore be reported with every
result.
8.2. FDM CUDA¶
The native v2 plan stores layer and pair descriptors, creates a compute stream, and prepares cuFFT workspace. An identity common grid may use device-side D-07; a heterogeneous path may retain host-authoritative orchestration. Provenance must report that distinction instead of calling the whole run device-resident.
9. Enable and control the method in the UI¶
Open the Study module in the unified workspace and select the study’s global Explorer node to open its Inspector.
Set Engine to
FDM, Requested device toCPU,CUDA, orAuto, Requested precision toDoubleorSingle, and keep Mode=Strictwhen fallback is forbidden.Enable Demag enabled. In FDM demag, select FDM multilayer convolution.
Enter
dx, dy, dzin metres under FDM default cell. Under FDM per-magnet grids, enter JSON keyed by exact magnet names, for example{"layer_bottom":{"cell":[4e-9,4e-9,3e-9]}}.For thin, one-cell layers select FDM demag mode = 2-D stack and enter
Nx, Nyunder Common convolution cells XY. Leave Common convolution cells empty.For full 3-D select 3-D and enter
Nx, Ny, Nzunder Common convolution cells. Leave the XY field empty. Positive integers are required.Enable Explain FDM demag plan to retain a readable planner explanation, then apply the draft; the UI validator rejects contradictory parameter pairs.
After materialization, Explorer shows each native layer target as
fdm-native-layer:<layer-id>. If a target-only Airbox is published, it appears as a separate
target. Select a layer or Airbox and request quantity H_demag; Airbox H_eff is explicitly
unavailable and must not be synthesized by the UI.
The viewport supports layer solids, bounds, wireframe, points, and field vectors. A full Airbox
wireframe also includes an interior bounds/volume overlay. A visible image is not by itself
correctness evidence: qualification requires a fresh compute_fields, runtime-origin data,
working WebGL, and a non-zero drawing buffer.
9.1. Stable implementation mapping¶
Responsibility |
Path |
Symbol |
Lane |
|---|---|---|---|
Python grid |
|
|
Public authoring |
Python demag policy |
|
|
Public authoring |
Python FDM wrapper |
|
|
Public authoring |
ProblemIR validation |
|
|
Authored and resolved FDM IR |
Planner |
|
|
FDM planner |
CPU runtime |
|
|
FDM CPU FP64 |
CPU observation and energy |
|
|
FDM CPU FP64 |
Push transfer |
|
|
FDM CPU transfer |
Pull transfer |
|
|
FDM CPU transfer |
Newell diagonal primitive |
|
|
Kernel preparation |
Newell cross primitive |
|
|
Kernel preparation |
Shifted Newell builder |
|
|
Shifted pair kernel |
CUDA v2 plan creation |
|
|
FDM CUDA |
CUDA FFT workspace |
|
|
FDM CUDA |
UI round-trip model |
|
|
Control Room authoring |
UI native-layer adapter |
|
|
Explorer/viewport |
UI Airbox adapter |
|
|
Explorer/viewport |
10. Validation and current evidence status¶
Statuses are disjoint: implemented means code is present, executable means the contract
can run, runtime-verified means a fresh execution, physically-validated means an
independent oracle, and production-qualified means a complete evidence matrix. A lower
status does not inherit a higher one.
Scope |
Evidence |
Status |
|---|---|---|
CPU 2D-self FP64 |
Complete L=1 field, energy, reciprocity, cubature, and self-trace |
locally physically-validated; not production-qualified |
CPU 2D-zShift FP64 |
Complete L=2 field for both Z signs, energy, and weighted reciprocity |
locally physically-validated; not production-qualified |
CPU 3D identity FP64 |
Small L=3 field, energy, reciprocity, self-trace, and cubature |
locally physically-validated; no independent managed receipt |
CPU push/pull FP64 |
Transfer moment/adjoint unit contracts plus local equal-thickness field/energy cases |
locally physically-validated in the stated scope; no unequal-native-cell continuum oracle |
CPU target-only Airbox |
|
locally runtime-verified and physically-validated for this mesh pair |
CUDA FP64 |
ABI v2 contract, plan creation, and static tests |
implemented/executable contract; no fresh device parity |
CUDA FP32 |
Source and runtime path |
not runtime-verified and not physically-validated |
UI/viewport |
Round-trip, adapter, Explorer/Inspector, and render-model tests |
contract-verified; no fresh post-integration browser/WebGL proof |
The remaining independent qualification gate is full field coverage across all six tensor components and lag signs, energy, weighted reciprocity, and the composed unequal-native-cell transfer. The transfer unit tests cover moment and adjoint contracts, but comparing two paths that share the same kernel builder is not independent physical evidence.
11. Limitations¶
PBC, general XY offsets, and full-complex 2-D/3-D classes are not production-qualified.
The CPU descriptor path now has a kernel catalog and reusable FFT workspace; this closes an implementation gap, not the qualification gap for every BORIS kernel family or for CUDA.
two_d_stackcannot represent through-thickness texture without an explicit moment-preserving transfer; multi-cell Z fails closed.Different XY cells require a transfer grid or rejection; Appendix A does not legalize an arbitrary XY difference.
CPU FP64 is the execution reference but does not replace independent analysis or cubature.
A CUDA build, cuFFT presence, and a valid ABI are not field/energy parity evidence on a concrete GPU.
Target-only Airbox publishes
H_demag.H_effoutside magnetic support has a versioned unavailable reason and is not synthesized.SP4-derived scenarios provide traceability and do not change the canonical µMAG Standard Problem 4 definition.
11.1. BORIS comparison and gap matrix¶
BORIS is a traceability reference, not a Fullmag oracle. The comparison below records the
observable contract differences against the clean-room manifest
docs/physics/multilayer_convolution/boris-reference-manifest.v1.json and its behavior-only
transcription in docs/physics/multilayer_convolution/boris-behavioral-spec.v1.md. The original
external snapshot is intentionally ignored by Git; the manifest hashes identify it without making
unavailable source files part of the published source index.
Contract axis |
BORIS snapshot (path and symbol, line anchor) |
Fullmag public contract |
Qualification or gap |
|---|---|---|---|
Multilayer versus supermesh choice |
|
|
Fullmag preserves requested intent and fails closed when the requested path is not eligible; BORIS’s supermesh option is not a semantic alias. |
Per-layer |
|
|
|
|
BORIS |
|
A matching integer tuple does not imply matching semantics: Fullmag native grids and physical origins remain per magnet. |
Common-cell pitch and normalization |
BORIS derives |
Fullmag keeps common-cell size, native-cell size, and transform layout as separate resolved descriptor fields; a mismatch becomes explicit transfer or rejection. |
Equal counts do not prove equal cell volumes or transfer accuracy; each cell-size class needs its own field/energy evidence. |
|
|
Fullmag |
No Fullmag claim maps either BORIS option to |
Arbitrary XY extents, centers, and XYZ offsets |
BORIS |
Planner materializes the union of native XY bounds as one computational scratch envelope and marks layers that need |
Authoring/planner support is present, but the complete transfer, insertion/crop, energy, and CUDA matrix is not production-qualified. Do not draw the union scratch envelope as a material mesh. |
Arbitrary Z gaps |
BORIS pair kernels carry signed shifts through |
Non-overlapping layers may have arbitrary Z gaps. The planner quantizes the signed origin difference by resolved convolution-cell thickness for a reuse key; overlapping Z intervals are rejected. |
Gap support is planner/runtime scoped and still requires pair-kernel and energy evidence for each claimed geometry class. |
Unequal source/destination thickness |
BORIS |
Fullmag’s irregular Newell contract is documented for common XY cells and unequal \(h_{s,z},h_{d,z}\); the checked pair builder preserves both cell sizes in the oriented kernel. |
Pair/oracle tests and a focused CPU unequal-thickness test pass; this does not qualify arbitrary XY transfer, reduced-storage families, or CUDA. |
Weighted transfer |
BORIS |
Fullmag exposes |
Transfer correctness requires moment, energy, and adjointness evidence; point interpolation is not enough. |
Full pair-oriented kernels |
BORIS |
Fullmag plans all \(L^2\) ordered source→destination pairs and six tensor components. Pair orientation includes source/destination cell sizes, signed Z shift, common shape, masks, and transfer. |
A scalar separation-only kernel is not the Fullmag contract; each orientation must have field/energy and reciprocity evidence. |
Spectral storage and representation |
BORIS |
Fullmag |
Real/reduced versus complex/full storage is a kernel-class decision; source presence does not qualify every representation or precision. |
Kernel catalog and reuse |
BORIS catalog declarations in |
Fullmag |
CPU descriptor-path reuse is implemented and fail-closed, but it does not qualify all BORIS kernel families, reduced/full representations, CUDA, or device residency. |
FFT work decomposition |
BORIS |
Fullmag’s documented operator shape is \(L\) forward transforms, \(L^2\) pair accumulation, and \(L\) inverse transforms; CUDA telemetry is scoped to one demag refresh. |
Counters do not prove full time-integrator device residency or production parity. |
Zero padding and crop |
BORIS |
Fullmag records |
Static shape descriptions do not qualify numerical padding for every geometry or precision. |
CPU/CUDA realization |
BORIS has |
Fullmag has a CPU FP64 reference and a CUDA v2 plan/workspace contract. GPU status remains partial until fresh managed executed-device field/energy parity and residency telemetry are recorded. |
BORIS CUDA source presence is not a Fullmag qualification receipt, and Fullmag source/build/ABI presence is not device proof. |
PBC images |
BORIS |
Fullmag’s multilayer boundary mode is |
PBC remains an explicit gap requiring Python/ProblemIR fields, image kernels, energy/provenance rules, and separate CPU/CUDA qualification. |
Empty cells, masks, and energy |
BORIS tracks |
Fullmag keeps native active masks, uses volume-weighted demag energy, and publishes target-only Airbox |
Mask, volume, energy, and Airbox claims require separate runtime artifacts; source tests do not close the full matrix. |
Antiferromagnetic and atomistic meshes |
BORIS tracks antiferromagnetic participation and forces transfer for atomistic meshes. |
Fullmag’s public multilayer contract is for named ferromagnetic FDM objects; AFM and atomistic mesh semantics are not silently mapped into it. |
This is an explicit scope gap requiring a separate material, mask, transfer, energy, and qualification contract. |
Reconfiguration and invalidation |
BORIS rebuilds per-mesh demag modules when mesh geometry, |
Fullmag resolves a new plan from topology fingerprints and invalidates the CPU catalog/workspace when descriptor geometry changes. |
An end-to-end session replan and post-replan parity receipt is still missing; a fingerprint alone is not a runtime qualification. |
Airbox target-only observation |
BORIS multilayer/supermesh descriptions do not define Fullmag’s target-only Airbox resource. |
Fullmag |
Airbox extent and wireframe are UI geometry evidence only; field qualification needs fresh runtime data and WebGL checks. |
UI, Explorer, and viewport semantics |
BORIS source has no Fullmag resource-first browser contract. |
|
UI tests and source mappings are contract evidence, not fresh interactive qualification. |
Production qualification boundary |
BORIS source and the clean-room manifest provide traceability only. |
Fullmag must report implemented, executable, runtime-verified, physically-validated, and production-qualified separately for CPU, CUDA, UI, and each requested display mode. |
Neither static source comparison nor a visual screenshot alone closes the production gate. |
12. Scientific bibliography¶
S. Lepadatu, “Efficient computation of demagnetizing fields for magnetic multilayers using multilayered convolution,” Journal of Applied Physics 126, 103903 (2019), doi:10.1063/1.5116754.
A. J. Newell, W. Williams, and D. J. Dunlop, “A generalization of the demagnetizing tensor for nonuniform magnetization,” Journal of Geophysical Research: Solid Earth 98, 9551–9555 (1993), doi:10.1029/93JE01171.
A. Aharoni, “Demagnetizing factors for rectangular ferromagnetic prisms,” Journal of Applied Physics 83, 3432–3434 (1998), doi:10.1063/1.367113.
BORIS clean-room boundary¶
BORIS is used only as external traceability material for kernel categories and convolution
organization. The canonical boundary is recorded in
docs/physics/multilayer_convolution/boris-reference-manifest.v1.json. BORIS code is not
copied into Fullmag, is not a numerical oracle, and is not qualification evidence. The
equations on this page come from Lepadatu and Newell and map to independently maintained
Fullmag code.
13. Source-code index¶
Claim |
Path |
Symbol |
Responsibility |
Lane |
Tests/evidence |
Evidence status |
Immutable link |
|---|---|---|---|---|---|---|---|
Python grid |
|
|
Validates and lowers one magnet’s cell. |
Public API |
|
executable authoring |
|
Python demag policy |
|
|
Validates requested strategy, mode, and common layout. |
Public API |
|
executable authoring |
|
Python FDM wrapper |
|
|
Lowers complete FDM hints. |
Public API |
|
round-trip contract |
|
ProblemIR topology identity |
|
|
Binds resolved mode and layer geometry to topology certificate. |
IR |
|
executable contract |
|
ProblemIR validation |
|
|
Rejects illegal authored configuration. |
IR |
|
executable contract |
|
Planner |
|
|
Resolves mode, layers, grid certificate, and transfer. |
Planner |
|
executable contract |
|
CPU runtime |
|
|
Runs CPU reference; runtime performs FFT, pairs, and field pull. |
FDM CPU FP64 |
multilayer engine tests and independent oracles |
local/source-unbound runtime evidence |
|
CPU observation and energy |
|
|
Publishes CPU field, energy, and provenance. |
FDM CPU FP64 |
SP4-derived runtime artifacts |
local/source-unbound runtime evidence |
|
Push transfer |
|
|
Transfers magnetization to the scratch grid. |
FDM CPU transfer |
|
locally physically-validated for the stated moment contract; no unequal-native-cell-thickness continuum oracle |
|
Pull transfer |
|
|
Returns field to the native grid. |
FDM CPU transfer |
|
locally physically-validated for the stated volume-adjoint and mask contract; no unequal-native-cell-thickness continuum oracle |
|
Newell diagonal primitive |
|
|
Evaluates Newell tensor function \(f\). |
Kernel preparation |
Newell reference tests |
code/test evidence |
|
Newell cross primitive |
|
|
Evaluates Newell tensor function \(g\). |
Kernel preparation |
Newell reference tests |
code/test evidence |
|
Shifted Newell builder |
|
|
Builds an oriented shifted tensor. |
FDM CPU kernel |
shifted/cubature tests |
locally physically-validated |
|
CUDA v2 plan creation |
|
|
Validates, uploads, and prepares D-07 plan. |
FDM CUDA |
managed ABI/contract tests |
executable contract, no device parity |
|
CUDA FFT workspace |
|
|
Prepares batched cuFFT workspace. |
FDM CUDA |
managed contract tests |
executable contract, no device parity |
|
UI round-trip model |
|
|
Reads scene FDM values into the Inspector draft. |
Control Room |
|
contract-verified |
|
UI native-layer adapter |
|
|
Adapts independent physical native-layer carriers and rejects malformed mask declarations. |
Explorer/viewport |
viewport adapter tests |
contract-verified |
|
UI Airbox adapter |
|
|
Adapts the validated target-only Airbox without treating the common FFT grid as geometry. |
Explorer/viewport |
viewport adapter tests |
contract-verified, no fresh browser proof |
|
BORIS common-grid policy |
|
|
Reference behavior for explicit shared convolution counts. |
BORIS reference |
clean-room behavioral reference; SHA-256 manifest |
traceability only |
External reference snapshot |
BORIS ordered kernel reuse |
|
|
Observed reference key lookup over oriented shift and source/destination cell size. |
BORIS reference |
clean-room behavioral reference; SHA-256 manifest |
traceability only |
External reference snapshot |
BORIS pair accumulation |
|
|
Observed reference ordered pair multiplication. |
BORIS reference |
clean-room behavioral reference; SHA-256 manifest |
traceability only |
External reference snapshot |
BORIS irregular-thickness tensor |
|
|
Observed unequal-thickness tensor construction. |
BORIS reference |
clean-room behavioral reference; SHA-256 manifest |
traceability only |
External reference snapshot |
BORIS multilayer phases |
|
|
Observed forward, pair, and inverse staging. |
BORIS reference |
clean-room behavioral reference; SHA-256 manifest |
traceability only |
External reference snapshot |
Fullmag kernel reuse |
|
|
Builds the independent reuse key from the full transform and layer descriptors. |
FDM CPU/GPU |
descriptor unit tests |
executable contract |
|
Fullmag common-transform schema |
|
|
Builds the resource containing the computational common-transform schema, not a physical mesh. |
Control Room API |
API schema tests |
contract-verified |
|
Fullmag layer correlation |
|
|
Binds artifact and execution-plan layers one-to-one and rejects identity disagreement. |
Control Room API |
v2 route tests |
contract-verified |
|
Fullmag layout route |
|
|
Publishes layout availability and an explicit unavailable reason. |
Control Room API |
v2 route tests |
contract-verified |
|
Fullmag FMBM mask route |
|
|
Publishes a revisioned FMBM v1 active-mask payload with bound layout and grid identities. |
Control Room API |
v2 route tests |
contract-verified |
|
Fullmag FMBM payload builder |
|
|
Packs the native active mask carried by the FMBM payload. |
Control Room API |
v2 route tests |
contract-verified |
|
Fullmag FMBM codec |
|
|
Validates FMBM magic, version, shape, cell count, and payload length. |
Control Room API |
codec tests |
contract-verified |
|
Fullmag FMBM identity contract |
|
|
Rejects mismatched layout revision, grid identity, hash, and active-cell counts. |
Control Room API |
codec tests |
contract-verified |
|
Fullmag FMBM resource hook |
|
|
Fetches only declared masks and marks incompatible payloads unusable. |
Control Room API |
resource-hook tests |
contract-verified |
|
Fullmag Explorer omission |
|
|
Omits unavailable layout nodes and keeps native-layer targets separate. |
Explorer |
Explorer tests |
contract-verified |
|
Fullmag native-layer domains |
|
|
Adapts physical native-layer carriers only. |
Viewport |
viewport adapter tests |
contract-verified |
|
Fullmag target-only Airbox domain |
|
|
Adapts target-only Airbox and validates field availability. |
Viewport |
viewport adapter tests |
contract-verified, no fresh browser proof |
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.