FEM airbox meshing

Last changes: Documentation changelog

Problem statement

An airbox is the finite nonmagnetic exterior domain around magnetic geometry in an unstructured FEM shared-domain mesh. It is authored at study scope, not as an independent magnetic body. The outer geometry, region markers, conforming interfaces and outer-boundary marker are mesh data; a physical outer-boundary closure remains a separate solver decision.

Governing equations

For the scalar-potential demagnetization formulation on the shared magnetic-plus-air domain, the current-free exterior uses

(1)\[\nabla\!\cdot\!\left(-\nabla u+\mathbf{M}\right)=0, \qquad \mathbf{H}_d=-\nabla u.\]

Exterior sizing can use geometric grading from a near-interface target \(h_0\):

(2)\[h_j=\min(h_{\mathrm{far}},h_0 r^j),\qquad r>1.\]

Symbols and SI units

Token

Meaning

SI unit

\(u\)

scalar magnetic potential

\(\mathrm{A}\)

\(\mathbf{M}\)

magnetization in the magnetic region

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

\(\mathbf{H}_d\)

demagnetizing field

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

\(h_j\)

target airbox element size in grading layer \(j\)

\(\mathrm{m}\)

\(h_0\)

near-interface target element size

\(\mathrm{m}\)

\(h_{\mathrm{far}}\)

far-field element-size cap

\(\mathrm{m}\)

\(r\)

geometric grading ratio

\(1\)

Assumptions and validity

The finite airbox is a truncation of an exterior problem, not proof of an open-boundary solution. Converge outer distance separately from magnetic and air-region discretization. The OCC shared-domain route realizes an exact sphere only when AirboxOptions.shape == "sphere"; every other value takes its box branch. The mixed swept shared-domain route accepts only normalized bbox; a non-bbox request is rejected. In component_aware and concatenated_stl_fallback modes, a requested sphere is realized as a bbox and the mesh report records status="degraded", requested_method="sphere" and actual_method="bbox".

When that mixed route derives size automatically, padding_factor must be finite and strictly greater than 1. Explicit size and center are finite three-vectors and the airbox must strictly contain the magnetic body. The public study.universe(...) handle does not expose shape or padding_factor; they are realization-schema fields, documented here so that requested and realized shapes are not conflated.

Python API

Complete public signature and IR matrix

The following rows are the exhaustive public-signature contract for this page; each row mirrors one public_api.parameters entry in the source map.

Python

Type

Default

SI unit

Validation

Meaning

Backend support

ProblemIR

study.universe(mode=…)

str | None

None

1

forwarded to StudyUniverseConfig

domain mode

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.mode

study.universe(size=…)

Sequence[float] | None

None

m

as_vector3; explicit dimensions must be positive when realized

outer dimensions

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.size

study.universe(center=…)

Sequence[float] | None

None

m

as_vector3

outer center

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.center

study.universe(padding=…)

Sequence[float] | None

None

m

as_vector3; domain validation governs signs

directional padding

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.padding

study.universe.mesh(maximum_element_size=…)

float | None

None

m

positive

airbox coarse target

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.airbox_hmax

study.universe.mesh(minimum_element_size=…)

float | None

None

m

positive and no greater than numeric maximum

airbox lower clamp

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.airbox_hmin

study.universe.mesh(maximum_element_growth_rate=…)

float | None

None

1

finite positive at most 2.5

airbox growth target

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.airbox_growth_rate

study.universe.mesh(grading=…)

str | None

None

1

forwarded without vocabulary validation by this handle

airbox grading request

FEM CPU/GPU capability-gated

runtime_metadata.study_universe.airbox_grading

study.universe(mode=…)

str or None

None

\(1\)

normalized by _configure_study_universe

requested universe mode

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.mode

study.universe(size=…)

Sequence[float] or None

None

\(\mathrm{m}\)

explicit realized dimensions must be positive

requested outer-domain dimensions

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.size

study.universe(center=…)

Sequence[float] or None

None

\(\mathrm{m}\)

supplied center is a finite three-vector at realization

requested outer-domain center

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.center

study.universe(padding=…)

Sequence[float] or None

None

\(\mathrm{m}\)

universe configuration validation

requested directional clearance

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.padding

study.universe.mesh(maximum_element_size=…)

float or None

None

\(\mathrm{m}\)

positive when supplied

far-field airbox target

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_hmax

study.universe.mesh(minimum_element_size=…)

float or None

None

\(\mathrm{m}\)

positive and no greater than maximum size

near-interface airbox target

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_hmin

study.universe.mesh(maximum_element_growth_rate=…)

float or None

None

\(1\)

positive when supplied

requested neighbor growth limit

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_growth_rate

study.universe.mesh(grading=…)

str or None

None

\(1\)

stored as requested grading mode

requested exterior grading mode

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_grading

study.build_domain_mesh()

StudyBuilder

n/a

\(1\)

requires a realizable shared-domain configuration

public realization boundary

FEM build path; no device-runtime claim

current builder state to shared-domain mesh artifact

AirboxOptions.padding_factor

float

3.0

\(1\)

finite and greater than 1 for automatic mixed shared-domain sizing

automatic magnetic-bounding-box scale

FEM realization only

runtime_metadata.study_universe to AirboxOptions.padding_factor

AirboxOptions.shape

str

bbox

\(1\)

OCC: exact sphere only for that value; mixed swept route requires bbox

requested outer geometry

FEM realization only

runtime_metadata.study_universe to route-specific AirboxOptions.shape

The public authoring boundary is study.universe(...), followed by the separately scoped study.universe.mesh(...); StudyBuilder.build_domain_mesh() realizes the configured shared domain. AirboxOptions is the source-backed realization schema, not a replacement for the canonical study API.

Python

Type

Default

SI unit

Validation

Meaning

Backend support

ProblemIR

study.universe(mode=...)

str or None

None

\(1\)

normalized by _configure_study_universe

requested universe mode

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.mode

study.universe(size=...)

Sequence[float] or None

None

\(\mathrm{m}\)

explicit realized dimensions must be positive

requested outer-domain dimensions

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.size

study.universe(center=...)

Sequence[float] or None

None

\(\mathrm{m}\)

supplied center is a finite three-vector at realization

requested outer-domain center

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.center

study.universe(padding=...)

Sequence[float] or None

None

\(\mathrm{m}\)

universe configuration validation

requested directional clearance

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.padding

study.universe.mesh(maximum_element_size=...)

float or None

None

\(\mathrm{m}\)

positive when supplied

far-field airbox target

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_hmax

study.universe.mesh(minimum_element_size=...)

float or None

None

\(\mathrm{m}\)

positive and no greater than maximum size

near-interface airbox target

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_hmin

study.universe.mesh(maximum_element_growth_rate=...)

float or None

None

\(1\)

positive when supplied

requested neighbor growth limit

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_growth_rate

study.universe.mesh(grading=...)

str or None

None

\(1\)

stored as requested grading mode

requested exterior grading mode

FEM authoring/lowering; runtime not qualified here

runtime_metadata.study_universe.airbox_grading

study.build_domain_mesh()

StudyBuilder

n/a

\(1\)

requires a realizable shared-domain configuration

public realization boundary

FEM build path; no device-runtime claim

current builder state to shared-domain mesh artifact

AirboxOptions.padding_factor

float

3.0

\(1\)

finite and greater than 1 for automatic mixed shared-domain sizing

automatic magnetic-bounding-box scale

FEM realization only

runtime_metadata.study_universe to AirboxOptions.padding_factor

AirboxOptions.shape

str

bbox

\(1\)

OCC: exact sphere only for that value; mixed swept route requires bbox

requested outer geometry

FEM realization only

runtime_metadata.study_universe to route-specific AirboxOptions.shape

Complete Python example

# %%
import fullmag as fm

# %%
nm = 1.0e-9
study = fm.study("airbox_contract")
study.engine("fem")
study.device("cpu", precision="double")
study.mode("strict")
study.universe(
    mode="manual",
    size=(600 * nm, 400 * nm, 240 * nm),
    center=(0.0, 0.0, 0.0),
    padding=(0.0, 0.0, 0.0),
)
study.universe.mesh(
    maximum_element_size=80 * nm,
    minimum_element_size=10 * nm,
    maximum_element_growth_rate=1.3,
    grading="geometric",
)

# %%
film = study.geometry(fm.Box(size=(200 * nm, 100 * nm, 10 * nm), name="film"), name="film")
film.mesh(maximum_element_size=8 * nm, minimum_element_size=4 * nm)
film.Ms = 800.0e3
film.Aex = 13.0e-12
film.alpha = 0.02
film.m = fm.texture.uniform(1.0, 0.0, 0.0)
study.exchange()
study.demag(realization="poisson_robin")
study.build_domain_mesh()
study.stages.add_relax(stage_id="equilibrium", dt=5.0e-13, max_steps=20_000)

ProblemIR

The public calls lower requested universe mode, dimensions, center, padding and mesh controls through runtime_metadata.study_universe. build_domain_mesh() consumes that builder state to produce the shared-domain mesh artifact. OCC solids, physical tags, quality metrics and any fallback report are realized artifacts, not user-authored ProblemIR fields.

Round-trip and failure semantics

Requested intent is the universe and air-mesh policy preserved in builder metadata. Resolved execution is the selected build route, effective shape, mesh artifact and status report. Validation errors reject invalid dimensions, containment and mixed-route padding or shape violations. Unsupported combinations remain fail closed: ordinary open airbox authoring does not silently become a periodic domain, a different topology, or a CPU/GPU fallback.

Discrete realization

Solver

Device

Status

Limit

FEM

CPU

source-backed authoring and mesh lowering

no new native runtime or convergence receipt in this page

FEM

GPU

capability-gated after mesh realization

source inspection is not GPU execution or parity proof

FDM

CPU

not applicable

structured FDM domain sizing is outside this unstructured FEM airbox page

FDM

GPU

not applicable

structured FDM domain sizing is outside this unstructured FEM airbox page

Implementation mapping

StudyUniverseHandle.__call__ and StudyUniverseHandle.mesh own the public study policy; StudyBuilder.build_domain_mesh is the public build boundary. _build_problem preserves the builder metadata, and the asset pipeline selects the shared-domain realization. The OCC route constructs a sphere or box; the mixed swept route enforces its bbox-only policy; the report helper records route-specific sphere degradation.

Validation

After a build, inspect the realized outer marker, magnetic and air-region markers, interface conformity, counts, quality report, effective shape and any fallback status. Converge outer distance, exterior sizing and magnetic sizing independently against a physical observable. The page-specific executable probe exercises public builder/lowering semantics only; it is not a native FEM, GPU, or scientific-convergence qualification.

Limitations

A geometrically valid mesh does not establish a correct boundary closure or a converged solution. No runtime claim follows from the page, source map, or builder/lowering probe. Sphere support is route-specific, and mixed swept meshing deliberately rejects non-bbox requests.

Scientific bibliography

  • C. Geuzaine and J.-F. Remacle, “Gmsh: a three-dimensional finite element mesh generator with built-in pre- and post-processing facilities,” International Journal for Numerical Methods in Engineering 79 (2009), 1309-1331, doi:10.1002/nme.2579.

  • C. Abert, “Micromagnetics and spintronics: models and numerical methods,” European Physical Journal B 92, 120 (2019), doi:10.1140/epjb/e2019-90599-6.

Source-code index

ID

Path

Symbol

Responsibility

Evidence

airbox_options

packages/fullmag-py/src/fullmag/meshing/_gmsh_types.py

class AirboxOptions

realization schema and defaults

source-inspected

universe_authoring

packages/fullmag-py/src/fullmag/world.py

class StudyUniverseHandle

public universe and air-mesh authoring

source-inspected

domain_build

packages/fullmag-py/src/fullmag/world.py

class StudyBuilder

public shared-domain build boundary

source-inspected

problem_lowering

packages/fullmag-py/src/fullmag/world.py

_build_problem

builder-state lowering

source-inspected

domain_realization

packages/fullmag-py/src/fullmag/meshing/asset_pipeline.py

realize_fem_domain_mesh_asset_from_components_with_report

shared-domain asset realization

source-inspected

occ_airbox

packages/fullmag-py/src/fullmag/meshing/_gmsh_occ.py

generate_shared_domain_mesh_via_occ

OCC sphere and box realization

source-inspected

mixed_airbox

packages/fullmag-py/src/fullmag/meshing/_gmsh_airbox.py

_add_conforming_swept_box_airbox_geo

mixed-route bbox and padding checks

source-inspected

airbox_status

packages/fullmag-py/src/fullmag/meshing/mesh_build_report.py

_airbox_shape_status

requested/effective shape reporting

source-inspected

planner

crates/fullmag-plan/src/lib.rs

plan

capability rejection after lowering

source-inspected; runtime unverified

runtime

crates/fullmag-runner/src/lib.rs

run_planned_problem

resolved-plan execution boundary

source-inspected; device runtime unverified

Scope and purpose

This page defines the public contract for FEM airbox enclosure and boundary padding. 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 outer dimensions, padding, boundary closure, and mesh-size controls. 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.