DC motor with commutated armature¶
This scenario family complements the three-phase demos with a brushed DC
motor that exercises the new commutator primitives. The generator lives in
python/gen_dc_motor.py and emits both regression-sized fixtures and larger
profiles suitable for ParaView walkthroughs.
Generator overview¶
python3 python/gen_dc_motor.py --profile ci --mode spinup --out inputs/dc_motor_spinup_ci.json
python3 python/gen_dc_motor.py --profile hires --mode spinup --out inputs/dc_motor_spinup_hires.json
python3 python/gen_dc_motor.py --profile ci --mode commutator_test --out inputs/tests/dc_commutator_test.json
Profiles follow the established CI/hires split. The ci configuration keeps the
mesh at 65×65, limits circular tessellation to 24–48 vertices, and rounds all
floating-point coordinates to three decimals so JSON fixtures stay readable. The
hires preset scales those counts for offline studies.
mode selects the timeline wiring:
spinup– enables the RK4 mechanical simulator, runs a few dozen frames of torque-driven acceleration, and emits VTK, torque, and mechanical traces. The CI profile now stops after two electrical cycles (24 frames) so the regression rotor history remains strictly increasing; the hires preset keeps the longer six-cycle spin-up for offline inspection.locked– leaves the rotor at its initial angle. Handy for debugging static field maps or exporting outlines for documentation.commutator_test– generates a four-frame timeline with scripted rotor angles that the regression harness uses to validate the orientation switching logic. The armature inductor starts at 8 A so the deposited currents make the sign flips obvious.
Geometry and materials¶
- Stator yoke: steel ring (
μᵣ ≈ 1800) with bore radius 20 mm. - Rotor core: laminated steel disk (
μᵣ ≈ 1200) centred on the origin and attached to thedc_rotormechanical entry. - Field coils: two slot polygons at ±90° with 220 turns each, a 0.58 fill fraction, and default orientation of +1 (north pole) and −1 (south pole).
- Armature coil: two slots at 0° and 180° with 110 turns each, 0.52 fill, and base orientations +1 and −1 so the return path flows correctly.
The field and armature ampere-turns were tuned so the stator and rotor fields
live in the same 0.01–0.08 T envelope. The field circuit runs from 18 V through
1.6 Ω/80 mH; the armature is driven by 12 V through 0.75 Ω/32 mH. Both circuits
are defined in the same MNA network (dc_drive).
Commutator schema¶
Each coil_link may now carry a commutator block:
{
"type": "coil_link",
"inductor": "arm_L",
"region": "armature_a",
"turns": 110.0,
"commutator": {
"rotor": "dc_rotor",
"default_orientation": 1.0,
"segments": [
{"start_deg": -90.0, "end_deg": 90.0, "orientation": 1.0},
{"start_deg": 90.0, "end_deg": 270.0, "orientation": -1.0}
]
}
}
The solver normalises the rotor angle, picks the segment whose range contains
that angle (wrapping across ±180° as needed), and multiplies the region’s base
orientation by the selected orientation factor. The default_orientation
value applies if no segment matches (for example when the rotor is exactly on a
boundary). The orientation update happens before each frame solve so both the
current deposition and flux linkage integrals respect the commutator state.
Regression coverage¶
tests/dc_commutator_test.cpploads thecommutator_testfixture, advances through the scripted angles, and asserts that the armature region orientations switch signs at ±90° exactly as the JSON specifies. The harness now checks that both polarities occur and that at least one sign transition happens, so the commutator crossing is exercised explicitly.tests/dc_motor_spinup_test.cppreuses the spin-up scenario, performs full CG solves with torque probes, and requires ≥8° of electrical rotation and ≥5 rad/s of speed gain.
Both binaries are wired into CTest, scripts/run_ci_checks.sh, and the GitHub
Actions workflow.
CI demo¶
run_ci_checks.sh and .github/workflows/ci.yml regenerate a fresh
inputs/dc_motor_spinup_ci.json, solve it, validate the mechanical trace with
python/check_pm_spinup.py --rotor dc_rotor, and archive the VTK series,
mechanical CSV, the aggregated torque CSV, and outlines. The torque file now
lists time_s,frame_index,Fx,Fy,Tz[,CoEnergy] so the commutator waveforms can be
plotted directly against the timeline. The solver also emits dc_motor_currents.csv
(the circuit_trace output) so python/generate_rotor_animation.py can render a
rotor-only GIF/PNG alongside the field-mapped ParaView sequence. The brushed DC
demo therefore ships with the same artefact set as the synchronous and induction
motors.
Tuning notes¶
- Adjust the field/armature balance by changing the turn counts and resistances
in
DEFAULT_PROFILES. Because current regions record turn counts, the circuit parser enforces consistency across coil links. commutator_testkeeps only four frames so the regression JSON stays compact; you can expand theangleslist in the generator if you want additional validation positions.- The mechanical defaults (0.65×10⁻³ kg·m² inertia, 0.08 N·m load) produce a gentle spin-up in CI. Increase the load torque or damping to explore steady states, or drop them to showcase faster acceleration in the hires profile.