Skip to content

Add Jiles-Atherton B-H hysteresis to inductor#344

Open
esaruoho wants to merge 1 commit intopfalstad:v3-devfrom
esaruoho:bh-hysteresis-inductor
Open

Add Jiles-Atherton B-H hysteresis to inductor#344
esaruoho wants to merge 1 commit intopfalstad:v3-devfrom
esaruoho:bh-hysteresis-inductor

Conversation

@esaruoho
Copy link
Copy Markdown

Summary

Why

Critics have pointed to "linear-biased, can't do real B-H hysteresis cleanly" as a gap. #308 closed half the gap (single-valued saturation). This closes the other half — history-dependent magnetization, which is what you need to see real hysteresis loops, coercivity-driven demagnetization, and realistic flyback/Joule-Thief core loss.

How it works

Internal dimensionless Jiles-Atherton state:

  • h = I / Ic (normalized field)
  • Man(he) = coth(he/a) - a/he (Langevin, Ms = 1)
  • he = h + alpha*m
  • dMirr/dh = (Man - Mirr) / (delta - alpha*(Man - Mirr)) with delta = sign(dh) and k normalized to 1
  • m = Mirr + c*(Man - Mirr)

Fixed internal constants a = 1/3, alpha = 1e-3 are tuned so the virgin small-signal inductance equals the user-specified L0. The user only exposes:

  • Coercive Current (A)0 disables hysteresis (default)
  • Hysteresis Reversibility (0-1) — JA c, default 0.1

State is advanced once per timestep in startIteration() (not per Newton iteration), following the capacitor-charge pattern — Newton sees a linearized inductor per step. Companion resistance is derived from the incremental slope dm/dh, with a [0.01, 3.0] floor/cap and a |denom| >= 1e-3 clamp on the JA denominator to avoid singularities at loop tips.

Backwards compatibility

  • Text dump: new tokens appended at the end, read inside the existing try/catch block. Old circuit files load unchanged.
  • XML: ich and hrev attributes are only emitted when hysteresis is active. Old XML files round-trip unchanged.
  • All existing Inductor.setup() callers (RelayCoilElm, RelayElm, DCMotorElm) use the 3-arg overload which is preserved; the 6-arg overload is new.

Files changed

  • Inductor.java — JA state, advanceHysteresis(), extended startIteration() / stamp() / nonLinear() / resetTo(), new 6-arg setup()
  • InductorElm.java — two new EditInfo slots, dump/undump tail tokens, XML attrs, info-panel additions
  • war/circuits/hysteresis-loop.txt — minimal demo (AC source, inductor, 1-ohm sense)

Scope

In: InductorElm B-H hysteresis, 2 UI params, backwards-compat dump, demo circuit.

Deferred (future PRs):

  • TransformerElm hysteresis (coupled-state bookkeeping warrants its own review)
  • Core-loss energy as power output
  • Temperature dependence of Ms

Happy to simplify the model (fewer params, different formulation) if you prefer a lighter touch — JA is the SPICE-standard but the framework here can host a simpler Tellinen-style atan() model just as easily.

Test plan

  • Linear check: Ic = 0, Isat = 0 -> identical behavior to current inductor
  • Saturation check: Ic = 0, Isat > 0 -> identical to Add saturable core model for inductors and transformers #308
  • Hysteresis check: AC-driven inductor shows asymmetric I vs V on sine excitation; loop width ~ 2*Ic
  • Reset clears M to 0 (virgin curve on next excitation)
  • XML and text round-trip preserve the two new parameters
  • Joule Thief / flyback topologies still converge (degrades to saturation when Ic = 0)

Extends the saturable core model (PR pfalstad#308) with a full B-H hysteresis
loop using a normalized Jiles-Atherton formulation. Inductor tracks
irreversible magnetization Mirr and total M as internal state, advanced
once per timestep in startIteration(). Companion resistance is
recomputed from the incremental slope dm/dh, floored and capped for
convergence.

User-facing parameters on InductorElm:
- Coercive Current (A) -- 0 disables hysteresis (default)
- Hysteresis Reversibility (0-1) -- JA c parameter, default 0.1

Shape and interdomain coupling (JA a, alpha) use fixed internal
defaults tuned so initial small-signal inductance equals L0.

Degradation path:
- coerciveCurrent=0, saturationCurrent>0  -> PR pfalstad#308 saturation
- coerciveCurrent=0, saturationCurrent=0  -> linear inductor (unchanged)

Backwards-compatible dump: new tokens appended at end, wrapped in the
existing try/catch block. XML attrs ich/hrev only emitted when
hysteresis active. Transformer hysteresis is intentionally deferred to
a follow-up PR to keep this change focused.

Includes war/circuits/hysteresis-loop.txt as a minimal demo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant