FullMag public documentation
FullMag public documentation Backend Numerical Methods Linearized-LLG eigensolvers Modal validation and qualification

Modal validation and qualification¶

Last changes: 06:12 31.08.2026·Documentation changelog

Scope and purpose¶

Modal validation compares computed eigenfrequencies and mode branches with an independent physical reference. It is not a plot-only step: the equilibrium, field units, \(\mathbf k\) sampling, branch identity, analytical model, tolerance and demagnetization policy define the validation case. Fullmag supports thin-film Damon–Eshbach/backward-volume dispersion checks and zero-wave-number Kittel field sweeps as explicit validation intent attached to the study.

Scientific and numerical model¶

For each matched mode sample \(j\), the relative frequency error is

(1)¶\[\varepsilon_j=\frac{|f_j^{\mathrm{num}}-f_j^{\mathrm{ref}}|}{|f_j^{\mathrm{ref}}|}, \qquad \max_j\varepsilon_j\leq\varepsilon_{\max}.\]

For a Kittel field sweep, each selected bias field \(\mathbf H_j\) is compared with the declared macrospin or thin-film analytical frequency \(f_{\mathrm{Kittel}}(\mathbf H_j)\):

(2)¶\[f_j^{\mathrm{num}}\approx f_{\mathrm{Kittel}}(\mathbf H_j), \qquad \Delta f_j=f_j^{\mathrm{num}}-f_{\mathrm{Kittel}}(\mathbf H_j).\]

The reference does not prescribe a branch-matching algorithm beyond the declared branch ID and sample indices. A validation result without a reproducible matching rule is not a qualification.

Symbols and SI units¶

Symbol

Meaning

SI unit

\(f_j^{\mathrm{num}}\)

computed frequency at sample \(j\)

\(\mathrm{Hz}\)

\(f_j^{\mathrm{ref}}\)

analytical/reference frequency

\(\mathrm{Hz}\)

\(\varepsilon_j\)

relative frequency error

\(1\)

\(\varepsilon_{\max}\)

permitted maximum relative error

\(1\)

\(f_{\mathrm{Kittel}}\)

Kittel reference frequency

\(\mathrm{Hz}\)

\(\mathbf H_j\)

bias field at sample \(j\)

\(\mathrm{A\,m^{-1}}\)

\(\Delta f_j\)

signed frequency difference

\(\mathrm{Hz}\)

\(j\)

validation sample index

\(1\)

Assumptions and validity¶

  • Thin-film dispersion validation requires both Damon–Eshbach and backward-volume scenarios, a nonzero equilibrium magnetization and a declared film normal.

  • Frequency windows and wave-vector bounds are validation-domain limits, not solver convergence tolerances. They must be reported separately.

  • Kittel validation requires at least three unique nonzero bias-field samples. The thin_film_in_plane model requires a positive effective magnetization.

  • relative_tolerance is a comparison threshold. It does not replace mesh, equilibrium, eigenvalue residual or branch-tracking evidence.

  • Synthetic demagnetization factors, periodic-airbox \(k=0\), and no-demag Kittel cases are separate physical assumptions and cannot be mixed without an explicit case ID.

Python API¶

# %% Attach reproducible modal validation intent to a stage-first study
import fullmag as fm

nm = 1.0e-9
study = fm.study("modal_validation")
study.engine("fem")
study.device("cpu", precision="double")
study.mode("strict")
study.universe(mode="manual", size=(700 * nm, 250 * nm, 250 * nm))
film = study.geometry(fm.Box(size=(500 * nm, 125 * nm, 3 * nm), name="film"), name="film")
film.Ms = 8.0e5
film.Aex = 1.3e-11
film.m = fm.init.UniformMagnetization((1.0, 0.0, 0.0))
study.dispersion_validation(
    fm.ThinFilmDEBVDispersionValidation(
        film_thickness_m=3 * nm,
        equilibrium_magnetization=(1.0, 0.0, 0.0),
        scenarios=[
            {"geometry": "damon_eshbach", "branch_id": "branch_0", "sample_indices": (0, 1, 2)},
            {"geometry": "backward_volume", "branch_id": "branch_0", "sample_indices": (3, 4, 5)},
        ],
    )
)
study.k0_kittel_validation(
    fm.K0KittelFieldSweepValidation(
        samples=[
            {"sample_index": 0, "bias_field": (8.0e3, 0.0, 0.0)},
            {"sample_index": 1, "bias_field": (1.0e4, 0.0, 0.0)},
            {"sample_index": 2, "bias_field": (1.2e4, 0.0, 0.0)},
        ],
        model="macrospin_larmor",
        relative_tolerance=0.05,
        case_id="k0-macrospin",
    )
)
study.stages.add_eigenmodes(count=8, target="lowest", equilibrium_source="provided")

Parameters¶

Python parameter

Type

Default

SI unit

Validation

Meaning

Backend support

ProblemIR

ThinFilmDEBVDispersionValidation.film_thickness_m

float

required

\(\mathrm{m}\)

positive

film thickness

FEM validation

runtime_metadata.dispersion_validation.film_thickness_m

ThinFilmDEBVDispersionValidation.equilibrium_magnetization

tuple[float,float,float]

required

\(1\)

nonzero three-vector

equilibrium direction/magnitude input

FEM validation

runtime_metadata.dispersion_validation.equilibrium_magnetization

ThinFilmDEBVDispersionValidation.scenarios

Sequence[DispersionValidationScenario]

required

\(1\)

must include both geometries

branch/sample cases

FEM validation

runtime_metadata.dispersion_validation.scenarios

ThinFilmDEBVDispersionValidation.film_normal

tuple[float,float,float]

(0,0,1)

\(1\)

nonzero three-vector

film normal

FEM validation

runtime_metadata.dispersion_validation.film_normal

ThinFilmDEBVDispersionValidation.frequency_window_hz

tuple[float,float]

(0,5e9)

\(\mathrm{Hz}\)

nonnegative lower, greater upper, upper at most \(5\) GHz

validation frequency domain

FEM validation

runtime_metadata.dispersion_validation.frequency_window_hz

ThinFilmDEBVDispersionValidation.max_k_rad_per_m

float

3e6

\(\mathrm{m^{-1}}\)

positive and at most \(3e6\)

wave-vector bound

FEM validation

runtime_metadata.dispersion_validation.max_k_rad_per_m

ThinFilmDEBVDispersionValidation.max_relative_error

float

0.10

\(1\)

positive and at most 0.25

permitted dispersion error

FEM validation

runtime_metadata.dispersion_validation.max_relative_error

ThinFilmDEBVDispersionValidation.analytic_model

str

kalinikos_slab_n0

\(1\)

currently kalinikos_slab_n0

analytical dispersion model

FEM validation

runtime_metadata.dispersion_validation.analytic_model

K0KittelFieldSweepValidation.samples

Sequence[K0KittelFieldSample]

required

\(1\)

at least three unique samples

bias-field sweep samples

FEM validation

runtime_metadata.k0_kittel_validation.samples

K0KittelFieldSweepValidation.model

str

macrospin_larmor

\(1\)

macrospin_larmor or thin_film_in_plane

Kittel model

FEM validation

runtime_metadata.k0_kittel_validation.model

K0KittelFieldSweepValidation.effective_magnetisation

`float

None`

None

\(\mathrm{A\,m^{-1}}\)

positive when required by model

effective magnetization

FEM validation

K0KittelFieldSweepValidation.relative_tolerance

float

0.05

\(1\)

positive and at most 0.25

permitted Kittel error

FEM validation

runtime_metadata.k0_kittel_validation.relative_tolerance

K0KittelFieldSweepValidation.case_id

`str

None`

None

\(1\)

nonempty when supplied

reproducible case identity

all validation

K0KittelFieldSweepValidation.demag_kind

`str

None`

None

\(1\)

none, periodic_airbox_k0, or synthetic_demag_factor

demag assumption

FEM validation

ProblemIR and provenance¶

Validation intent is serialized under runtime metadata and remains distinct from the modal study request. Provenance records the validation schema, canonicalized units, case ID, source mode branch, sample mapping, analytical model, tolerance, solver diagnostics and the exact resolved execution.

Diagnostics and failure semantics¶

Script export preserves validation objects and stage ordering. Requested intent and resolved execution are stored separately. Validation errors include missing geometries, too few samples, duplicate sample indices, invalid model names, invalid field/frequency windows and tolerance violations. Unsupported combinations combinations are rejected explicitly; validation metadata cannot make an unsupported solver lane qualified.

Discrete realization by lane¶

Solver

Device

Status

Realization

FEM

CPU

partial/source-backed

native modal output compared with analytical references

FEM

GPU

partial/qualification-dependent

validation can consume a result only after GPU execution identity is proven

FDM

CPU

unsupported for this modal validation contract

no native FDM modal lane is claimed

FDM

GPU

unsupported for this modal validation contract

no native CUDA modal lane is claimed

Where this is implemented¶

Claim

Repository path

Stable symbol

Responsibility

Lane

Dispersion validation schema

packages/fullmag-py/src/fullmag/model/eigen.py

class ThinFilmDEBVDispersionValidation

validates and serializes dispersion cases

Python

Kittel validation schema

packages/fullmag-py/src/fullmag/model/eigen.py

class K0KittelFieldSweepValidation

validates and serializes field sweeps

Python

Modal solver validation

backends/fem/src/frequency_domain/modal_eigen_solver.cpp

solve_modal_eigen_contract

native modal diagnostics

FEM CPU

Validation¶

The validation itself must report every sample, branch assignment, reference frequency, computed frequency, signed difference, relative error and acceptance threshold. In addition, report equilibrium torque, eigen residuals, mesh/cell resolution, precision, demag policy and runtime identity. A passing relative-error threshold without these provenance fields is incomplete.

Limitations¶

Analytical agreement is a qualification gate for the declared domain, not proof of correctness for all geometries, modes, wave vectors or devices. The current analytical model set is intentionally bounded by the Python validators and does not represent arbitrary multilayer dispersion.

Scientific bibliography¶

  • E. H. Lock, “The Kittel formula for ferromagnetic resonance,” standard macrospin reference.

  • I. A. Kalinikos and A. N. Slavin, “Theory of dipole-exchange spin wave spectrum for ferromagnetic films with mixed exchange boundary conditions,” Journal of Physics C 19 (1986).

  • Canonical modal owner: Linearized LLG eigensolver.

Control Room workflow¶

Use Model Explorer -> Stages -> Add stage -> <stage kind> for stage-level controls when the terminal page identifies a matching field. The current editor is partial: only fields surfaced by the stage draft are authorable. Numerical parameters without a matching control are not implemented in the frontend. Do not infer frontend support from Python or backend availability. See {doc}/frontend/capability-register for the current register and exact source owner.

Source-code index¶

Claim

Repository path

Stable symbol

Responsibility

Evidence

Dispersion schema

packages/fullmag-py/src/fullmag/model/eigen.py

class ThinFilmDEBVDispersionValidation

typed validation payload

Python source

Kittel schema

packages/fullmag-py/src/fullmag/model/eigen.py

class K0KittelFieldSweepValidation

typed validation payload

Python source

Native modal diagnostics

backends/fem/src/frequency_domain/modal_eigen_solver.cpp

solve_modal_eigen_contract

solver status and diagnostics

native source

  • Previous Linearized LLG eigensolver
  • Next Frequency-domain response
Show page source
  • Getting started
  • Frontend
  • Backend
    • FullMag architecture
    • Physics reference
    • Meshing and spatial discretization
    • Numerical Methods
      • Time integration
      • Relaxation
      • Demagnetization solver realizations
      • Linearized-LLG eigensolvers
        • Linearized LLG eigensolver
        • Modal validation and qualification
      • Frequency-domain response
      • Interpolation and cross-backend state transfer
  • Python API
  • Validation

On this page

  • Modal validation and qualification
    • Scope and purpose
    • Scientific and numerical model
    • Symbols and SI units
    • Assumptions and validity
    • Python API
    • Parameters
    • ProblemIR and provenance
    • Diagnostics and failure semantics
    • Discrete realization by lane
    • Where this is implemented
    • Validation
    • Limitations
    • Scientific bibliography
    • Control Room workflow
    • Source-code index
Copyright © FullMag contributors.
Made with Sphinx and Clarity Theme for Sphinx .
Back to top

Press Enter to search. Press Esc or click outside to close.

On this page

  • Modal validation and qualification
    • Scope and purpose
    • Scientific and numerical model
    • Symbols and SI units
    • Assumptions and validity
    • Python API
    • Parameters
    • ProblemIR and provenance
    • Diagnostics and failure semantics
    • Discrete realization by lane
    • Where this is implemented
    • Validation
    • Limitations
    • Scientific bibliography
    • Control Room workflow
    • Source-code index
  • Getting started
  • Frontend
  • Backend
    • FullMag architecture
    • Physics reference
    • Meshing and spatial discretization
    • Numerical Methods
      • Time integration
      • Relaxation
      • Demagnetization solver realizations
      • Linearized-LLG eigensolvers
        • Linearized LLG eigensolver
        • Modal validation and qualification
      • Frequency-domain response
      • Interpolation and cross-backend state transfer
  • Python API
  • Validation