Skip to content

axfluxmdo.geometry

axfluxmdo.geometry.axial_flux

Parametric axial-flux permanent-magnet motor geometry.

Single-gap (one rotor disk, one stator disk) topology in Phase 1. All dimensions are SI (meters); the dataclass is frozen so design variants are produced with dataclasses.replace(motor, ...) — the mechanism used by sweeps and, later, optimization drivers.

AxialFluxMotor dataclass

AxialFluxMotor(outer_radius: float, inner_radius: float, air_gap: float, pole_pairs: int, phases: int = 3, turns_per_phase: int = 24, fill_factor: float = 0.45, magnet_thickness: float = 0.004, back_iron_thickness: float = 0.006, magnet_arc_ratio: float = 0.85, magnet_shape: str = 'wedge', slot_depth: float = 0.012, slot_width_fraction: float = 0.5, winding_factor: float = 0.933, end_turn_factor: float = 1.4, stator_core_thickness: float = 0.008, magnet: MagnetMaterial = N42, steel: ElectricalSteel = M19_29GA, conductor: Conductor = COPPER, thermal_resistance_k_per_w: float = 1.2, structure_mass_factor: float = 0.25, tolerances: GapImperfections = PERFECT_GAP)

Parametric axial-flux PM motor design.

The nine leading fields form the primary design vector (see SPEC.md); the remaining fields are Phase-1 modeling parameters with sensible defaults so the quickstart snippet runs unchanged.

active_length property

active_length: float

Radial length of the active annulus (the 'stack length' analogue).

airgap_area property

airgap_area: float

Annular air-gap area, pi * (r_o^2 - r_i^2).

pole_pitch property

pole_pitch: float

Circumferential pole pitch at the mean radius.

magnet_volume property

magnet_volume: float

Total magnet volume across all 2p poles.

back_iron_volume property

back_iron_volume: float

Rotor back-iron disk volume.

stator_core_volume property

stator_core_volume: float

Stator yoke volume (solid, before stacking factor).

copper_window_area property

copper_window_area: float

Circumferential copper window cross-section at the mean radius (m^2).

The winding window is slot_depth deep (axially) and occupies slot_width_fraction of the circumference at the mean radius; this is the total area available to all phase conductors crossing the annulus.

conductor_area property

conductor_area: float

Cross-section of one conductor (one turn of one phase), m^2.

Each phase places 2*N conductors through the window (go and return paths of N turns); copper fills fill_factor of the window.

mean_turn_length property

mean_turn_length: float

Mean length of one winding turn: two radial runs plus two end turns.

copper_volume property

copper_volume: float

Total copper volume across all phases.

axfluxmdo.geometry.tolerances

Air-gap imperfection models: assembly error, rotor coning, and runout.

These are manufacturing design variables (see SPEC.md): Layer 1 (:class:~axfluxmdo.models.analytical.AnalyticalModel) models the perfect axisymmetric machine and ignores them; only the annular 2.5D model consumes them. The local gap law is

g(r, theta) = g0 + gap_offset + coning * (r - r_m)/(r_o - r_i) + runout * cos(theta)

where the coning term is zero-mean at the mean radius and runout is a once-per-revolution axial oscillation.

GapImperfections dataclass

GapImperfections(gap_offset_m: float = 0.0, coning_m: float = 0.0, runout_m: float = 0.0)

Deviations of the running air gap from its nominal design value (SI meters).

axisymmetric_gap

axisymmetric_gap(nominal_gap: float, r: float, r_i: float, r_o: float) -> float

Mean-over-theta local gap at radius r (offset and coning, no runout).

Source code in src/axfluxmdo/geometry/tolerances.py
36
37
38
39
def axisymmetric_gap(self, nominal_gap: float, r: float, r_i: float, r_o: float) -> float:
    """Mean-over-theta local gap at radius r (offset and coning, no runout)."""
    r_m = 0.5 * (r_i + r_o)
    return nominal_gap + self.gap_offset_m + self.coning_m * (r - r_m) / (r_o - r_i)

local_gap

local_gap(nominal_gap: float, r: float, r_i: float, r_o: float, theta: float = 0.0) -> float

Local gap at radius r and circumferential angle theta.

Source code in src/axfluxmdo/geometry/tolerances.py
41
42
43
44
45
def local_gap(
    self, nominal_gap: float, r: float, r_i: float, r_o: float, theta: float = 0.0
) -> float:
    """Local gap at radius r and circumferential angle theta."""
    return self.axisymmetric_gap(nominal_gap, r, r_i, r_o) + self.runout_m * math.cos(theta)