FDM multi-magnet grids¶
Last changes: Documentation changelog
Physical problem¶
FDMGrid provides body-local Cartesian cells; FDMDemag requests a common demagnetization strategy. A request is not an implicit resampling permission.
Governing equations¶
Symbols and SI units¶
Symbol |
Meaning |
SI unit |
|---|---|---|
\(\mathbf H_a\) |
field on layer \(a\) |
A m^-1 |
\(\mathcal N_{ab}\) |
cross-kernel |
1 |
\(\mathbf M_b\) |
magnetization on layer \(b\) |
A m^-1 |
Assumptions and validity¶
Names are non-empty and values are FDMGrid. With multiple magnets,
strategy="single_grid" is rejected; the executable strategy is
multilayer_convolution. Explicit fftw and mkl requests are unavailable in this build,
rustfft is the CPU realization, and cufft is the CUDA realization. Any explicit FFT
backend requires an active demag interaction.
common_cell_size is incompatible with explicit mode="two_d_stack". For a 3-D plan, every
component must divide the corresponding common convolution extent into an integer cell count
within the planner tolerance; strict mode rejects a nonintegral ratio and does not round it.
Runner preflight additionally requires a compatible certificate, common grid, transfers, masks,
and memory accounting. This is not a convergence proof.
Python API¶
# %%
import fullmag as fm
nm = 1e-9
study = fm.study("two-magnet-grid")
study.engine("fdm")
study.fdm(
default_cell=(2 * nm, 2 * nm, nm),
per_magnet={
"free": fm.FDMGrid(cell=(2 * nm, 2 * nm, nm)),
"reference": fm.FDMGrid(cell=(4 * nm, 4 * nm, nm)),
},
demag=fm.FDMDemag(
strategy="multilayer_convolution",
mode="two_d_stack",
common_cells_xy=(256, 128),
fft_backend="rustfft",
),
)
free = study.geometry(
fm.Box(60 * nm, 40 * nm, nm).translate((-40 * nm, 0.0, 0.0)),
name="free",
)
free.Ms = 800.0e3
free.Aex = 13.0e-12
free.m = fm.texture.uniform(1.0, 0.0, 0.0)
reference = study.geometry(
fm.Box(60 * nm, 40 * nm, nm).translate((40 * nm, 0.0, 0.0)),
name="reference",
)
reference.Ms = 800.0e3
reference.Aex = 13.0e-12
reference.m = fm.texture.uniform(1.0, 0.0, 0.0)
study.demag()
study.stages.add_relax(stage_id="equilibrium", dt=5.0e-13, max_steps=1)
Python |
Type |
Default |
SI unit |
Validation |
Meaning |
Backend support |
ProblemIR |
|---|---|---|---|---|---|---|---|
|
|
required |
m |
exactly three positive finite values |
native cell dimensions |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
m |
exclusive with |
compatibility alias for default grid |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
m |
three positive finite values |
default grid |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
m |
non-empty names and |
named grid overrides |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
1 |
|
nested demag policy |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
1 |
|
demag strategy |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
1 |
|
grid topology mode |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
cells |
three positive integers; exclusive with |
common 3-D cell counts |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
cells |
positive values; only |
common in-plane cells |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
m |
positive finite; exclusive with count fields; forbidden with explicit |
common convolution cell size |
FDM CPU source-backed; GPU capability-gated; FEM not applicable |
|
|
|
|
1 |
explicit choice requires active demag; |
requested FFT backend |
|
|
|
|
|
1 |
no runtime type guard |
authoring-only explanation flag |
authoring only; not a backend capability |
not lowered |
|
|
|
1 |
any non- |
removed compatibility input |
unsupported on all lanes |
no field; construction fails |
ProblemIR¶
StudyBuilder.fdm(...) applies the complete FDM policy to the current study. FDM(cell=...) is
the compatibility form: it emits both cell and default_cell, and cannot be combined with
default_cell. FDM.demag nests FDMDemag.to_ir() as demag. That payload always contains
strategy, mode, and fft_backend, and conditionally contains common_cells,
common_cells_xy, or common_cell_size. explain is accepted by the Python object but
deliberately not lowered.
Round-trip and failure semantics¶
Requested intent preserves native grids and the nested demag policy, including requested FFT
realization. Resolved execution requires a certified common grid and a lane-compatible FFT
backend. Validation errors cover malformed grids, conflicting common-grid controls, nondivisible
common extents, unknown enum values, unavailable/lane-incompatible FFT requests, explicit FFT
without active demag, multi-body single_grid, and every non-None request for the removed
fallback input. Unsupported combinations, transfers, certificates, or budgets reject before
allocation without fallback.
Discrete realization¶
validate_multilayer_grid_budget checks topology-bound certificates, layer grid equality, masks,
and kernel accounting. The CPU operator owner is
MultilayerDemagRuntime::compute_demag_fields_checked: it pushes each source to the convolution
grid, performs FFTs, accumulates every destination/source tensor pair, then inverse-transforms and
pulls fields to native grids. CUDA owns the analogous FP64/FP32 paths in
launch_multilayer_demag_field_fp64 and launch_multilayer_demag_field_fp32.
Implementation mapping¶
Python owns schema/lowering and StudyBuilder.fdm(...) applies it to the active study.
FdmDemagHintsIR::validate owns the explicit two_d_stack/common_cell_size rejection;
plan_fdm_multilayer owns multi-body strategy and exact common-grid resolution;
plan_fdm_fft owns FFT lane selection. Runner owns preflight. The engine and native CUDA
functions listed below own convolution execution.
Validation¶
Check IR names and grids, require a resolved certificate, then test invalid common-grid/certificate inputs. Sweep native and common cells for physical convergence.
Limitations¶
This contract does not prove two_d_stack equals three_d or GPU parity. explain has no
runtime type guard and is not represented in ProblemIR. FDM.demag likewise relies on its
annotation and calls .to_ir() when present. The example applies its per-magnet grids and FFT
policy directly through StudyBuilder.fdm(...).
Scientific bibliography¶
C. Abert, European Physical Journal B 92, 120 (2019), doi:10.1140/epjb/e2019-90599-6.
A. J. Newell, W. Williams and D. J. Dunlop, J. Geophys. Res. 98 (1993), 9551-9555, doi:10.1029/93JB00694.
Source-code index¶
Source |
Stable symbol |
Evidence |
|---|---|---|
|
|
public |
|
|
per-magnet grid |
|
|
policy validation |
|
|
FDM lowering |
|
|
IR validation, including |
|
|
executable FFT backend and active-demag checks |
|
|
multi-body strategy and common-grid resolution |
|
|
fail-closed preflight |
|
|
CPU construction |
|
|
CPU convolution operator |
|
|
CUDA FP64 convolution owner |
|
|
CUDA FP32 convolution owner |
Scope and purpose¶
This page defines the public contract for multiple magnets on one FDM grid. It is an authoring and implementation reference: the Python example, the serialized ProblemIR description, the implementation mapping, and the adjacent source map are the source-backed contract. A capability marked partial or not evaluated is not presented as a production guarantee.
Scientific and numerical model¶
The mesh or grid is a discrete approximation of the continuous domain. For a Cartesian partition, each spacing satisfies Delta_i = L_i / N_i; for a geometry-dependent FEM mesh, the requested local target is bounded by the active bulk, interface, boundary, and topology constraints. In compact form, h_target(x) = min(h_bulk(x), h_interface(x), h_boundary(x)). Length quantities use SI metres (m); counts, orders, and topology labels are dimensionless.
The equations and assumptions in the earlier physical-problem and governing-equations sections state the model-specific specialization. This section does not introduce a conversion from FEM to FDM, a hidden topology conversion, or a silent CPU fallback.
Parameters¶
The exact callable and argument names are the ones shown in the ## Python API section above. For this page the parameter family is cell_size, origin, object placement, and overlap policy. Use the documented defaults, validation rules, and ProblemIR lowering exactly as shown; do not replace a canonical argument with an unlisted alias. Numerical lengths must be supplied in metres, and invalid positive-length, count, order, periodicity, or topology constraints must fail closed rather than being silently repaired.
Control Room workflow¶
In Control Room, select the engine and mesh workflow, enter the same values as the Python authoring example, inspect the planned mesh or grid report, and only then submit the run. The UI is a projection of the public contract: a missing control is not evidence that the backend accepts the option, and a visible control is not evidence that a production lane is enabled. When the page or capability register marks a field partial or not evaluated, keep the workflow explicitly bounded to the implemented path.
Diagnostics and failure semantics¶
A valid request must preserve the declared geometry, units, element or cell topology, and backend lane. Reject non-finite or non-positive lengths, invalid counts and orders, incompatible periodic or shared-boundary data, and unsupported topology combinations at the owning validation layer. Reports should retain requested and resolved values, source identity, and any capability gate. No diagnostic may hide a failed mesh realization by substituting another discretization.
Where this is implemented¶
The existing implementation-mapping and source-code-index sections identify the exact public authoring, ProblemIR, planner, realization, and runtime owners for this topic. The adjacent .source-map.json file is the machine-readable source of truth for those paths, symbols, responsibilities, backend matrix, and reviewed revision. Claims in this page must be updated together with that map when an owner moves.