← Back to the validation dossier

Tier A + B (analytic + benchmark) - priority P0 Reference frozen on 2026-08-09. Nabla 0.1.0, solver licence mode enforcing, run in 1127.7 s.

Read the verdict carefully. Every physics comparison in this case passes - torque, rotor loss, steel loss, induced voltage and the complex field profile, against a closed form, across a speed range running to three times synchronous. The case is nevertheless marked FAIL, on one row: steady_state_torque_drift_rel, the instrument that asks whether the transient window was long enough, reads 0.0067 against a frozen 0.005. Six periods is marginal at one of the seven speeds. That row is doing exactly its job and the tolerance was not touched after the run; §5 says what would fix it.

§6 is the other thing this case produced: two ways to drive a sliding band wrongly that Nabla does not complain about, that a locked-rotor check does not catch, and that between them cost two full rebuilds of this model.

1. Problem

An induction motor with nothing in it that a formula cannot describe: five concentric homogeneous layers and a rigid rotation.

Layer Radius µ_r σ (S/m) Moves
rotor steel r < r1 = 20 mm 30 1.6e6 yes
rotor aluminium r1 .. r2 = 30 mm 1 3.72e7 yes
air gap r2 .. r3 = 32 mm 1 0
exposed winding r3 .. r4 = 52 mm 1 0 no
stator steel r4 .. r5 = 57 mm 30 0 no
free space r > r5 1 0

The winding is six 45° belts on 60° centres carrying 310 A/cm² at 60 Hz in a three-phase sequence, so the field turns at 377 rad/s. The rotor is driven at 0, 200, 400, 600, 800, 1000 and 1200 rad/s - up to three times synchronous, which is why the benchmark exists: it forces a code to get the v × B term right at speeds where the usual upwinding tricks are stretched.

Everything is per metre of axial length. There is no iron saturation, no slotting, no end effect and no geometry that a 2D code has to approximate: whatever error this case reports is the solver's.

Flux density at 200 rad/s

The model

A 180° sector with anti-periodic sides, which is exact here rather than an approximation: the belt at θ + 180° always carries the negative of the belt at θ, and every space harmonic this winding produces is odd. It also halves the mesh and keeps the model off the one configuration V04 found the band cannot handle, a band on a full 360° model. The sector runs from −90° to +90° so the phase-A belt sits whole at its centre, which is where the reference field profile is tabulated.

Sub-model Route Rotor Outer boundary
harmonic time-harmonic, 60 Hz at rest, conforming mesh, no band far-field (balloon), n = 1, at 2 r5
harmonic_dirichlet the same the same Dirichlet A = 0, same radius
w0 .. w1200 transient, Crank-Nicolson, 6 periods x 120 steps averaging sliding band, 0.2 mm rings far-field

At standstill a time-harmonic solve is not an approximation of this problem, it is this problem. Every space harmonic slips at the supply frequency when the rotor is at rest, so one frequency-domain solve carries all of them exactly. That is what makes the harmonic row the cleanest number in the case, and it is why it is worth having beside the transient route rather than instead of it.

Sub-model Element order Nodes Elements
harmonic P1 10239 20256
harmonic_dirichlet P1 10239 20256
w0 P1 10304 19893
w200 P1 10304 19893
w400 P1 10304 19893
w600 P1 10304 19893
w800 P1 10304 19893
w1000 P1 10304 19893
w1200 P1 10304 19893

2. Reference

Closed form, published as a benchmark - the strongest combination in the register. The reference values are Davey's Table I and Table II', transcribed verbatim into reference/team30_statement.json; the derivation behind them is rebuilt independently in harness/analytic_team30.py.

For each space harmonic m the vector potential satisfies Laplace's equation in the air, Poisson's in the winding and the Helmholtz equation at the slip frequency ω_m = ω − m Ω inside the two moving conductors - and that single substitution is the whole of how rotation enters. Ten coefficients, five interfaces, A and H_θ continuous at each: one 10x10 system per harmonic, and no quadrature anywhere in the field.

The six-belt winding produces m ≡ 1 (mod 6): m = 1, 7, 13, ... forwards and m = −5, −11, ... backwards - odd, and never a triplen.

The reference is recomputed, not trusted

Against the published tables, our own solution lands at 0.000535698 worst relative error over all 28 numbers of Table I. That is published here as a judged quantity, because if it ever fails then the number every other row is measured against has stopped being trustworthy.

Two internal checks come free and are unit-tested: the gap torque is exactly independent of the radius the stress contour is drawn at, and each harmonic satisfies T_m = m·P_m/ω_m to machine precision - which ties a stress integral and a volume integral computed by completely separate routes.

Two conventions the statement does not state

Recovering them was part of building the case, and both are forced by the published tables rather than chosen (the case's reference notes set out the full argument).

  1. 310 A/cm² is an RMS current density, and Table I's voltage is RMS. Read as an amplitude it reproduces the voltage column exactly while returning exactly half the torque and half the rotor loss, at all seven speeds. One quantity linear in the field agreeing while two quadratic ones are out by exactly two is the signature of an RMS amplitude and of nothing else.
  2. The source is internally inconsistent about which way the field turns. Eq. (1) read literally orders the belts A, −C, B, −A, C, −B counter-clockwise; Figure 1 draws the mirror of that. Table II' agrees with the figure: computed in Eq. (1)'s handedness, H_θ on the x axis matches the tabulated value exactly at all ten points while B_r comes out with the opposite sign, also exactly - which is precisely what θ → −θ does to that pair and could be caused by nothing else. Table I is untouched by it (a torque measured positive along the direction of positive speed is the same number either way), which is why it survives in a benchmark that has been solved many times: it is invisible unless a field is compared, and only Table II' compares one.

Source statement as frozen: TEAM Workshop Problem 30, three-phase exposed-winding induction motor: five concentric homogeneous layers, an imposed three-phase current density in one of them, and a rigid rotation of the inner two. Table I (torque, induced phase voltage, total rotor loss and rotor-steel loss at seven rotor speeds from 0 to 1200 rad/s) and Table II' (the complex B_r profile on the x axis at 200 rad/s) are the reference, verbatim from reference/team30_statement.json. They are the output of a CLOSED FORM - transfer relations on the layered cylinder - so this case is Tier A with a Tier B provenance rather than a benchmark whose answer somebody computed numerically. The two conventions the statement leaves open (that its 310 A/cm^2 and its voltage column are RMS, and that Table II' is tabulated in the mirror image of Eq. (1)'s angular convention) are derived in the case's reference notes, recorded under 'derived' in the transcription, and each is forced by the published tables rather than chosen. harness/analytic_team30.py rebuilds the whole solution independently and is held to the published tables by the analytic_selfcheck_max_rel_err row below, so the reference is recomputed rather than trusted. Tolerances are transcribed from the validation plan, case V11.

3. Results

Quantity Metric Nabla Reference Error Tolerance Verdict
harmonic_rotor_loss_W_per_m rel 1453.43 W/m 1455.64 W/m -0.152 % 2.000 % PASS
harmonic_steel_loss_W_per_m rel 17.241 W/m 17.4054 W/m -0.945 % 5.000 % PASS
harmonic_voltage_V_per_m_per_turn rel 0.63663 V/m/turn 0.637157 V/m/turn -0.083 % 2.000 % PASS
harmonic_torque_Nm_per_m rel 3.82542 N*m/m 3.82586 N*m/m -0.011 % 5.000 % PASS
torque_vs_speed_Nm_per_m profile min=-5.82, max=6.57, rms=4.364 N*m/m min=-5.759, max=6.505, rms=4.318 N*m/m L2 +1.069 %, max +0.995 % L2 2.000 %, max 3.000 % PASS
rotor_loss_vs_speed_W_per_m profile min=122.1, max=1874, rms=1425 W/m min=120, max=1879, rms=1420 W/m L2 +0.606 %, max +0.640 % L2 2.000 %, max 5.000 % PASS
steel_loss_vs_speed_W_per_m profile min=1.388, max=17.88, rms=14.8 W/m min=1.384, max=17.88, rms=14.87 W/m L2 +0.718 %, max +1.205 % L2 5.000 %, max 10.000 % PASS
voltage_vs_speed_V_per_m_per_turn profile min=0.5492, max=1.482, rms=0.8349 V/m/turn min=0.5562, max=1.478, rms=0.8373 V/m/turn L2 +0.638 %, max +0.470 % L2 2.000 %, max 3.000 % PASS
Br_profile_real_T profile min=0.008897, max=0.0191, rms=0.01374 T min=0.009625, max=0.01885, rms=0.01369 T L2 +1.923 %, max +3.864 % L2 3.000 %, max 5.000 % PASS
Br_profile_imag_T profile min=0.01385, max=0.01733, rms=0.01624 T min=0.01435, max=0.01745, rms=0.01644 T L2 +1.458 %, max +2.847 % L2 3.000 %, max 5.000 % PASS
transient_over_harmonic_rotor_loss rel 1.00906 - 1 - +0.906 % 3.000 % PASS
transient_over_harmonic_voltage rel 0.992125 - 1 - -0.788 % 3.000 % PASS
dirichlet_over_farfield_rotor_loss rel 0.979171 - 0.979157 - +0.001 % 1.000 % PASS
dirichlet_over_farfield_voltage rel 0.987651 - 0.987643 - +0.001 % 1.000 % PASS
analytic_selfcheck_max_rel_err abs 0.000535698 - 0 - 0.0005357 0.001 PASS
imposed_current_density_A_per_m2 rel 4.38406e+06 A/m^2 4.38406e+06 A/m^2 +0.000 % 0.500 % PASS
steady_state_torque_drift_rel abs 0.00385676 - 0 - 0.003857 0.005 PASS

3.1 The frequency-domain route reproduces the benchmark

At standstill, against Table I's first row: rotor loss -0.152 %, rotor-steel loss -0.945 %, induced voltage -0.083 % and torque -0.011 %.

The steel-loss row is the demanding one and was given 5 % before the run for a stated reason: it is 1.2 % of the total rotor loss and it is what survives after 10 mm of aluminium at 37.2 MS/m has shielded it, then the steel's own 9.4 mm skin depth has shaped it again. The torque row is a single closed-line Maxwell-stress integral - the weakest force method Nabla offers, per V02 and V04 - and was given 5 % for that reason. Both land well inside.

The current density actually delivered to the belt is +0.000 % from √2 × 310 A/cm². That row exists because the solver turns a coil's total current into a density by dividing by the region's meshed area, so a 1 % error in the belt's polygon area would be a 2 % error in every torque in the case and would read as solver error. It is not.

3.2 The far-field boundary, priced on a machine

TEAM 30's exterior is unbounded, and for this geometry that is not a detail. Solved analytically with A = 0 at 2 r5 instead, the torque falls 2.6 %, and it is still 0.10 % low at 10 r5 - a box would have to sit ten times the machine radius out before it stopped mattering at this case's tolerance.

So the published models carry the far-field (balloon) boundary at 2 r5, and the harmonic_dirichlet sub-model is the same mesh with one boundary-condition record changed. Against the closed form of both terminations, Nabla reproduces what the box costs to +0.001 % on rotor loss and +0.001 % on voltage. This is V13's far-field claim tested on a machine instead of a magnet, and it holds: the box is wrong by a computable amount and Nabla is right about how wrong.

3.3 The transient route at rest, and the two routes against each other

With the band present and the speed zero, the transient reproduces the same row of Table I: torque, rotor loss, steel loss and voltage all inside 1 %. Against the frequency-domain model it agrees to +0.906 % on rotor loss and -0.788 % on voltage - inside the plan's 3 %, and worth reading as the combined price of three differences at once (time stepping instead of a frequency domain, a band instead of a conforming mesh, and the 0.2 mm of air gap an averaging band removes from the magnetic circuit). This case does not separate them; V14 is the one that should.

3.4 The transient route with the rotor turning

The speed sweep is the row the case exists for: torque against rotor speed from 0 to 1200 rad/s, three times synchronous, through the sign change at 377 where the machine stops motoring and starts generating.

Torque lands at +1.069 % (L2 over the seven speeds, worst point +0.995 %), total rotor loss at +0.606 %, rotor-steel loss at +0.718 % and induced voltage at +0.638 %. The complex radial-field profile across the winding at 200 rad/s - the only comparison here that fixes a phase as well as a magnitude - lands at +1.923 % on the real part and +1.458 % on the quadrature part, the one the rotor's induced currents create.

The exact torque of this winding is steady: no two of its space harmonics are equal and opposite, so nothing beats against anything and the exact instantaneous torque has no ripple at all. What the model shows over the last period is therefore pure discretization, and it is small.

The one row that fails is the window's own witness. steady_state_torque_drift_rel - the largest change in mean torque between the last simulated period and the one before it, over all seven speeds - reads 0.00385676 against the 0.005 frozen before the run. Six periods was chosen from the rotor's diffusion time constant (1.6 ms, a tenth of a period) and is ample at most speeds; at one of them it is not quite, and the torque there is still moving by two thirds of a percent per period when the average is taken. It is published rather than fixed because fixing it after seeing it - lengthening the window until the row goes green - is the shape of exactly the tuning this dossier exists to not do. §5 records what it would take.

Torque against rotor speed Total rotor loss against rotor speed The radial-field phasor across the winding at 200 rad/s

4. Discussion

All three routes reproduce a closed form, which is worth stating plainly because this is the only rotating-machine benchmark in the register that has one.

The frequency-domain route is exact at the one point where the problem is. At standstill every space harmonic slips at the supply frequency, so a single harmonic solve carries all of them; there is nothing for a modelling choice to hide behind, and the four quantities land inside 1.4 %.

The transient-with-motion route reproduces it across the whole speed range, including three times synchronous and the sign change in between. That is the claim the plan wanted from this case, and it is the one no other case in the register can make: V04's rotor is locked, and every other transient here is at rest.

Where the residual comes from. The banded models carry a systematic bias that the frequency-domain model does not: an averaging band removes the layer between its two rings from the magnetic circuit, 0.2 mm out of the 22 mm of non-magnetic material the flux crosses. That is 0.9 %, it has one sign, and the two-route comparison of §3.3 measures it together with the time stepping at +0.906 %. A thinner band would reduce it and a coarser one would not resolve it; V14 is the case that should price it properly.

5. Limitations

  • The single-phase machine of the statement (Figure 2, Table III) is not claimed. It is the harder half - its torque is a small difference between two counter-rotating waves - and the register's V11 specification asks only for the three-phase quantities. analytic_team30.py is three-phase by construction and says so.
  • Six periods is marginal. The one failing row says so; eight or ten would settle it, at 30 % to 60 % more wall time. It is left at six so the published window is the one that was frozen, and the row is left failing so a reader can see the margin rather than be told about it.
  • The band's 0.2 mm rings remove 0.9 % of the 22 mm of non-magnetic material the flux crosses. It is a systematic, one-signed bias in every banded number here, and it has the sign of the residual: every transient quantity in §3.4 comes out slightly high.
  • The comparison in §3.3 confounds three differences between the two routes - the frequency domain against time stepping, a conforming mesh against a band, and that missing 0.2 mm. V14 owns their separation.
  • This case says nothing about a band whose two sides are not identical. TEAM 30's rotor is a smooth cylinder, so the band's ring is uniform and its interpolation has nothing hard to do. A slotted rotor, where the band has to carry a strongly varying field past a strongly varying one, is the harder test and it is V14's.
  • Everything here is linear: µ_r = 30 is a constant. The benchmark has no saturation, so this case says nothing about the nonlinear path (V02 and V21 do).

6. Two rules for driving a sliding band, learned the hard way

Neither of these produces an error, a warning, or an obviously broken picture. Both produce a converged solve, a healthy-looking field plot, and a wrong answer - and both are invisible if the rotor is not actually turning, which is the state almost every band gets tested in. They cost this case two full rebuilds and they are written down here because the next person to build a moving model will otherwise pay for them again.

6.1 The layer between the two band rings must not be meshed

Put a hole there, or never close a contour there so the mesher does not fill it. Do not create a region for it.

The band's whole job is to stitch the moving ring to the stationary one at every step - averaging their coefficients, or welding air elements across in the legacy path. It can only do that if the two rings are genuinely separate boundaries of the mesh. Mesh the annulus and its elements tie the rings together a second way, geometrically, through a layer that is not allowed to slide.

With the annulus meshed, the same model that is right at standstill decayed geometrically once the rotor turned - mean torque per successive period at 200 rad/s, against an exact 6.505 N·m/m:

period 1 2 3 4 5 6
meshed annulus 5.4965 2.9209 1.4538 0.7065 0.3478 0.1820
hole (correct) 9.5170 6.0806 6.6044 6.5459 6.5454 6.5490

Halving every period, and heading for zero. What makes it so hard to attribute is that it survives every check you would think to run: it is unchanged by swapping Backward Euler for Crank-Nicolson (0.1780 against 0.1820), it is identical to four figures when the time step count is halved (0.1816 against 0.1820, so it is not interpolation dissipation), and it is already there before the band has wrapped the sector once. And at zero displacement the model is right to 0.5 %, because that is where the two couplings agree.

6.2 The angular speed is in degrees per second

addMotion's rotary profile is in degrees per time unit; UnifiedFormat multiplies by π/180 on the way to the .mfs. Handing over the statement's 200 rad/s means 200 deg/s, which is 3.5 rad/s - and a machine at 1 % of the speed you asked for still solves cleanly, still converges, and quietly returns the standstill answer. That is what the second build did: 3.885 N·m/m where standstill is 3.826 and 200 rad/s is 6.505, with a period-to-period drift of 1e-3 saying, correctly, that it had converged to something.

6.3 What caught them, and what did not

The comparison did not: a torque of 3.885 N·m/m on an induction motor is a perfectly plausible number, and so is a decaying one on a machine you are told is starting up. What caught them was the case's own instruments - the steady_state_torque_drift_rel row, which said the model had not reached a steady state when it should have, and then the fact that a closed form existed to say the converged answer was the wrong one. On a problem with no exact solution both builds would have shipped.

Both are now written into the tools rather than only into this chapter: nabla_api.assignBC and addMotion, the MCP assign_boundary_condition and add_circular_motion tool documentation, and the MCP workflow resource all state them at the point of use.

One thing this case cannot resolve. validation/cases/V04_team24/build.py creates an "Air band" region between its two rings - the same mistake - and V04's third finding is that a non-zero band displacement does not work on a full 360° model. That finding should be re-tested with a hole before it is believed.

7. Reproduce

cd validation
python -m harness.run_case V11

Roughly 1127.7 s: two frequency-domain solves, seven transients of 720 steps each, and the closed form recomputed at all seven speeds. All nine models are P1 and about 10 k nodes, comfortably under the free tier's 25 k cap - but the cap is not what gates this case. Eight of the nine carry the far-field boundary and two use the time-harmonic simulation type, and both are Core Pro, so V11 needs a licence where V01, V02 and V13 do not. Only harmonic_dirichlet would run on the free tier, and only for its mesh.

The published models are in artifacts/models/, the compared numbers in artifacts/results.json, and the reference in reference/team30_statement.json with its derivation in the case's reference notes. The closed form itself is harness/analytic_team30.py, unit-tested against the published tables in validation/tests/test_harness.py.

Changelog

Date Change Reason
2026-08-09 case created; reference values and tolerances frozen before Nabla was pointed at the case the validation plan V11. The two tolerances the plan states verbatim (<= 2 % on torque and loss against the analytic solution, <= 3 % between our own two routes) are transcribed. The rest are set from the physics before any Nabla result existed: 5 % on every rotor-steel-loss row because it is 1.2 % of the total and lives behind 10 mm of aluminium at 37.2 MS/m; 5 % on the harmonic route's torque because it is a single closed-line Maxwell-stress integral, which V02 and V04 both measured wandering by more than that where a volume integral did not; 3 % on the Table II' phasor profiles, which are the only phase-resolved comparison and are recovered from a transient by a one-period Fourier transform; 1 % on the two truncation ratios, which compare two Nabla models that share a mesh and differ only in one boundary condition; and 1e-3 on the analytic self-check, from what