Derivations
Each section below is generated from a script in python/pe_core/derive/.
The same script runs under pytest, which fails unless the symbolic
difference between the derived result and the expression stored in
equations.yaml simplifies to zero. The prose and headings are written by
hand; every formula on this page is printed by sympy from those scripts.
Refreshers: element laws, impedance, Fourier series, magnetics, the ideal transformer
Section titled “Refreshers: element laws, impedance, Fourier series, magnetics, the ideal transformer”The element laws are integrated for constant excitation, impedances follow from the phasor form of the same laws, the Fourier coefficients and the rms value of a pulse train are computed over one period, and the ideal transformer follows from Faraday's and Ampère's laws with a lossless core of zero reluctance.
Inductor law: . With a constant voltage the slope of the current is constant; integrate it over the interval .
Evaluate the integral.
✓ reproduces
ind.di(equality checked symbolically by pytest)Capacitor law, the dual: , integrated for a constant current .
Evaluate the integral.
✓ reproduces
cap.dv(equality checked symbolically by pytest)Energy delivered to an inductor: , from zero current to .
Evaluate the integral.
✓ reproduces
ind.E(equality checked symbolically by pytest)Energy delivered to a capacitor: , from zero voltage to .
Evaluate the integral.
✓ reproduces
cap.E(equality checked symbolically by pytest)In sinusoidal steady state becomes multiplication by , with . The inductor law gives the inductor's impedance.
Its magnitude.
✓ reproduces
imp.ZL(equality checked symbolically by pytest)The capacitor law gives the capacitor's impedance.
Its magnitude.
✓ reproduces
imp.ZC(equality checked symbolically by pytest)Unloaded R-C low-pass filter: the output is the capacitor's share of the divider formed by and the capacitor's impedance.
Squared magnitude.
The corner (-3 dB) frequency is where the squared magnitude falls to one half.
✓ reproduces
rc.fc(equality checked symbolically by pytest)Write the magnitude with in place of .
✓ reproduces
rc.gain(equality checked symbolically by pytest)An inductance with a parasitic capacitance in parallel: the admittances add.
At resonance the admittance is zero (the impedance is infinite for the lossless model).
✓ reproduces
passive.f_srf(equality checked symbolically by pytest)A pulse train of height and width in every period . Its cosine coefficient for the harmonic :
and its sine coefficient:
The squared amplitude of the harmonic is the sum of their squares; with it is a perfect square.
Take the non-negative root.
✓ reproduces
fourier.pulse.harm(equality checked symbolically by pytest)The mean square over one period: the pulse contributes during .
The rms value is its square root.
✓ reproduces
fourier.pulse.rms(equality checked symbolically by pytest)The ripple current flows through the capacitor's series resistance, whose voltage follows the current at every instant. The difference between its extremes:
The current's peak-to-peak value is its maximum minus its minimum.
✓ reproduces
cap.esr.ripple(equality checked symbolically by pytest)Ampère's law around the core: the line integral of equals the enclosed current, turns each carrying . In an ungapped core with a uniform field it is times the path length.
Solve for .
✓ reproduces
mag.H_ampere(equality checked symbolically by pytest)Faraday's law for two windings on one core: each winding voltage is its number of turns times the rate of change of the common flux. For the primary:
and for the secondary:
Divide the two: the flux term cancels, and the ratio of the turns is (1:n convention).
✓ reproduces
xfmr.V2(equality checked symbolically by pytest)Ampère's law with a core of zero reluctance (ideal): the net magnetomotive force is zero.
Solve for the secondary current, with .
✓ reproduces
xfmr.I2(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/foundations.py
Averaging, balance, and losses in the averaged model
Section titled “Averaging, balance, and losses in the averaged model”A switching converter chops a dc input into a pulse train; a low-pass filter keeps its average. Averaging each circuit equation over one period turns the switched circuit into a dc model in which losses such as the inductor winding resistance appear as ordinary resistors.
The buck switch node is at for and at for ; average it over one period.
Evaluate the two pieces.
✓ reproduces
sw.v_avg(equality checked symbolically by pytest)The inductor obeys . Integrated over one period, the current's change is the integral of the voltage over .
For a voltage during and for the rest, the integral is times the average over the period.
So the change over one period is the average voltage times over ; it is zero only when the average is (volt-second balance).
✓ reproduces
vsb.drift(equality checked symbolically by pytest)With the small-ripple approximation the inductor voltage (or capacitor current) takes one value for and another value for ; its average must be zero.
For the inductor voltage (): volt-second balance.
✓ reproduces
vsb.v_off(equality checked symbolically by pytest)For the capacitor current (): charge balance.
✓ reproduces
csb.i_off(equality checked symbolically by pytest)Boost with inductor winding resistance , volt-second balance: the inductor sees while the switch is on and while the diode conducts ( = dc inductor current).
Charge balance on the output capacitor: while the switch is on, while the diode conducts.
Solve the two linear equations for .
and for .
✓ reproduces
boost.ccm.M_RL(equality checked symbolically by pytest)Efficiency is the output power over the input power .
✓ reproduces
boost.ccm.eta_RL(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/averaging.py
CCM conversion ratios and ripple
Section titled “CCM conversion ratios and ripple”In periodic steady state every inductor current ends a switching period where it started, so the average inductor voltage over the period is zero. With the small-ripple approximation each interval applies a constant voltage, and the balance becomes a linear equation in the output voltage .
Volt-second balance: the inductor voltage averaged over one switching period is zero.
Buck: the inductor sees while the switch is on (fraction ) and while the diode conducts ().
Solve for and divide by .
✓ reproduces
buck.ccm.M(equality checked symbolically by pytest)Boost: while the switch is on, while the diode conducts.
Solve for .
✓ reproduces
boost.ccm.M(equality checked symbolically by pytest)Buck-boost: while the switch is on, the (negative) output voltage while the diode conducts.
Solve for ; the output is inverted.
✓ reproduces
buckboost.ccm.M(equality checked symbolically by pytest)Flyback (1:, magnetizing inductance on the primary): while the switch is on; while the diode conducts the secondary is clamped at , which reflects to on the primary.
Solve for .
✓ reproduces
flyback.ccm.M(equality checked symbolically by pytest)Forward: the secondary applies to the output filter while the switch is on, so the output inductor sees , then while the freewheeling diode conducts.
Solve for .
✓ reproduces
forward.ccm.M(equality checked symbolically by pytest)Forward reset: the magnetizing inductance sees for , then the reset winding ( turns) clamps it to for until the magnetizing current is back to zero.
Solve for the reset interval.
The reset must finish within the period, ; the equality gives the largest duty ratio.
✓ reproduces
forward.reset.Dmax(equality checked symbolically by pytest)Buck ripple: during the on-interval the inductor current rises with slope for , which is the full peak-to-peak ripple, i.e. .
Half of it is Erickson's .
✓ reproduces
buck.ripple.iL(equality checked symbolically by pytest)The peak-to-peak value, with .
✓ reproduces
buck.ripple.iL_pp(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/ccm_ratios.py
CCM/DCM boundary and DCM conversion ratios
Section titled “CCM/DCM boundary and DCM conversion ratios”The converter leaves CCM when the inductor current ripple is large enough for the current to reach zero: at the boundary the half-ripple equals the dc inductor current. In DCM a third interval appears in which both switch and diode are off; its length is unknown, so volt-second balance is combined with capacitor charge balance (the average diode or inductor current must equal what the load draws).
Definition used throughout: , i.e. .
Buck: the dc inductor current equals the load current , with in CCM.
The half-ripple over the on-interval, with the CCM operating point substituted.
Boundary , with , solved for .
✓ reproduces
Kcrit.buck(equality checked symbolically by pytest)Boost: the inductor carries the input current, , with .
The half-ripple over the on-interval, with the CCM operating point substituted.
Boundary , with , solved for .
✓ reproduces
Kcrit.boost(equality checked symbolically by pytest)Buck-boost: the inductor current is , with .
The half-ripple over the on-interval, with the CCM operating point substituted.
Boundary , with , solved for .
✓ reproduces
Kcrit.buckboost(equality checked symbolically by pytest)At the boundary equals ; solve the definition of for .
✓ reproduces
L.crit(equality checked symbolically by pytest)Buck DCM, volt-second balance with : for , for , for .
Solve for .
✓ reproduces
buck.dcm.D2(equality checked symbolically by pytest)Peak inductor current at the end of the on-interval.
Charge balance: the average inductor current (a triangle of height and base ) equals the load current .
Substitute and take the positive root of the quadratic in .
✓ reproduces
buck.dcm.M(equality checked symbolically by pytest)Boost DCM, volt-second balance: for , for .
Solve for .
Charge balance at the output: the average diode current (a triangle of height over ) equals the load current.
Substitute and keep the root with .
✓ reproduces
boost.dcm.M(equality checked symbolically by pytest)Buck-boost DCM, volt-second balance with the negative output : for , for .
Solve for .
Charge balance: the average diode current equals the load current .
Substitute and solve ().
✓ reproduces
buckboost.dcm.M(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/dcm.py
Flyback: DCM ratio, boundaries, stresses, loss-free resistor
Section titled “Flyback: DCM ratio, boundaries, stresses, loss-free resistor”The flyback stores energy in the magnetizing inductance while the switch is on and releases it to the output through the diode while the switch is off. With a 1: transformer () the secondary voltage reflects to the primary divided by , and the secondary current is the primary-referred magnetizing current divided by .
On-interval: across , so the magnetizing current rises from zero (DCM) to .
Volt-second balance on : for , then the reflected output for .
Solve for .
Charge balance: the secondary current starts at and falls to zero over ; its average equals the load current .
Substitute and solve for ; cancels.
✓ reproduces
flyback.dcm.M(equality checked symbolically by pytest)The DCM demagnetizing interval, with the DCM output voltage substituted.
The boundary is reached when the demagnetizing interval fills the rest of the period, .
✓ reproduces
Kcrit.flyback(equality checked symbolically by pytest)Output held at (battery or regulated bus) and the diode dropping : the reflected voltage is during demagnetization.
Setting gives the input voltage at which the converter enters CCM; above it CCM volt-second balance holds at this value.
✓ reproduces
flyback.V_crit(equality checked symbolically by pytest)While the diode conducts, the primary winding carries the reflected on top of , so the off-state switch voltage is their sum (the leakage spike comes on top of this).
✓ reproduces
flyback.Vds_off(equality checked symbolically by pytest)With the input pinned at the off-state switch voltage simplifies.
✓ reproduces
flyback.Vds_clamped(equality checked symbolically by pytest)While the switch is on the secondary winding voltage adds to the output voltage across the reverse-biased diode.
✓ reproduces
flyback.diode.VR(equality checked symbolically by pytest)CCM charge balance: while the diode conducts, for , the secondary carries (small ripple); its average equals the load current .
Solve for .
✓ reproduces
flyback.IM(equality checked symbolically by pytest)On-interval: across for , so the magnetizing current rises by twice the half-ripple .
Solve for .
✓ reproduces
flyback.ripple.iM(equality checked symbolically by pytest)While the switch is on the diode is off, so the capacitor alone supplies the load current for and its voltage falls by twice the half-ripple .
Solve for .
✓ reproduces
flyback.ripple.v(equality checked symbolically by pytest)The DCM peak magnetizing current, with .
✓ reproduces
flyback.Ipk.dcm(equality checked symbolically by pytest)Energy stored in at the end of each on-interval (all of it is delivered every cycle in DCM).
Power = energy per cycle × switching frequency; it depends on , , , but not on the load.
✓ reproduces
dcm.P_in(equality checked symbolically by pytest)Since the input behaves as a resistance that dissipates nothing (a loss-free resistor).
✓ reproduces
lfr.R_in(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/flyback.py
Flyback clamp: reflected voltage, clamp dissipation, output ceiling
Section titled “Flyback clamp: reflected voltage, clamp dissipation, output ceiling”When the flyback's switch turns off, the magnetizing current passes to the secondary, but the current in the leakage inductance has nowhere to go except a clamp across the primary. The clamp holds the primary at until that current has fallen to zero.
While the output diode conducts, the secondary winding carries the output voltage plus the diode drop.
An ideal 1: transformer divides a secondary voltage by on the primary.
✓ reproduces
flyback.V_OR(equality checked symbolically by pytest)The switch lies between the input and the primary winding, which the clamp holds at while it conducts.
✓ reproduces
clamp.Vds(equality checked symbolically by pytest)The magnetizing inductance holds while the output diode conducts, so the leakage inductance sees and its current falls linearly from .
It reaches zero after this time, which must fit in the off-time.
✓ reproduces
clamp.t_reset(equality checked symbolically by pytest)The clamp absorbs its voltage times this falling current: more than the leakage energy , because the reflected voltage keeps driving the current meanwhile.
Once per switching period.
✓ reproduces
clamp.P(equality checked symbolically by pytest)In an RCD clamp the capacitor holds and the resistor dissipates the clamp power.
The root above .
✓ reproduces
clamp.rcd.V(equality checked symbolically by pytest)With the load removed and no regulation, the output keeps charging and its reflected voltage rises until it reaches the clamp voltage; from then on the clamp takes all of the input power. This holds for a clamp whose voltage does not depend on that power (a TVS); an RCD clamp's voltage rises with it.
Solve for the output voltage.
✓ reproduces
flyback.V_ceiling(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/clamp.py
Snubbers: parasitics from the ringing, damping resistance and loss
Section titled “Snubbers: parasitics from the ringing, damping resistance and loss”A switching edge makes a node's parasitic inductance and capacitance ring. Their values, which cannot be read from the layout, follow from the ringing frequency measured twice: as built, and with a known capacitor added.
As built, the node rings at the resonance of its inductance and capacitance:
A known capacitor across the node adds to the capacitance but leaves the inductance as it is:
The inductance cancels from the ratio of the two frequencies, :
Solved for the node's capacitance:
✓ reproduces
snub.C_par(equality checked symbolically by pytest)and the first resonance then gives the inductance:
✓ reproduces
snub.L_par(equality checked symbolically by pytest)AN11160 takes the damping factor of the parasitic inductance, the snubber resistor and the snubber capacitor in series, leaving the node's own capacitance out. That loop's natural frequencies solve
Divided by and written as , with , its damping factor is
Solved for the resistance:
✓ reproduces
snub.R(equality checked symbolically by pytest)At an edge the node steps by and the snubber capacitor charges through the resistor, ; the energy the resistor takes does not depend on :
The next edge discharges the capacitor, through the resistor and the switch that turns on, and loses its stored energy, as much again, so each period loses
At periods per second:
✓ reproduces
snub.P(equality checked symbolically by pytest)AN11160 rates the resistor from the edge that charges the capacitor while the parasitic inductance carries a current . The source delivers the capacitor's charge at :
The capacitor keeps half of that energy and the inductance gives up all of its own, ; the resistor takes the rest, whatever its value:
Once per period:
✓ reproduces
snub.P_R(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/snubbers.py
Topology details: dc currents, ripple, switch stress, utilization
Section titled “Topology details: dc currents, ripple, switch stress, utilization”Charge balance on the output capacitor gives each converter's dc inductor current. During the on-interval the inductor sees a constant voltage, so its current changes linearly by twice the half-ripple ; the capacitor's charge per period gives the voltage ripple in the same way. The transistor utilization compares the load power with the product of the transistor's peak voltage and rms current.
Buck, charge balance: the capacitor current is in both intervals (small ripple).
Set the average to zero.
✓ reproduces
buck.IL(equality checked symbolically by pytest)Buck output ripple: the capacitor takes the triangular ac part of the inductor current. Its positive half lasts and peaks at , so it delivers the charge .
That charge raises the capacitor voltage from its minimum to its maximum, .
Solve for .
✓ reproduces
buck.ripple.v(equality checked symbolically by pytest)Boost, charge balance: while the switch is on, while the diode conducts.
Solve for .
✓ reproduces
boost.IL(equality checked symbolically by pytest)Boost current ripple: the inductor sees for , so its current rises by , which is .
Solve for .
✓ reproduces
boost.ripple.iL(equality checked symbolically by pytest)Boost voltage ripple: while the switch is on, the capacitor alone feeds the load current for , so its voltage falls by .
Solve for .
✓ reproduces
boost.ripple.v(equality checked symbolically by pytest)Buck-boost with the output magnitude : the inductor sees while the switch is on and while the diode conducts.
Solve for .
✓ reproduces
buckboost.V(equality checked symbolically by pytest)Charge balance is the boost's: the capacitor feeds the load while the switch is on and receives while the diode conducts.
✓ reproduces
buckboost.IL(equality checked symbolically by pytest)The inductor sees during , as in the boost.
✓ reproduces
buckboost.ripple.iL(equality checked symbolically by pytest)The capacitor alone feeds the load during , as in the boost.
✓ reproduces
buckboost.ripple.v(equality checked symbolically by pytest)Buck: while the diode conducts, the switch node sits at ground (ideal diode); the switch between the input and that node blocks .
✓ reproduces
buck.Vds(equality checked symbolically by pytest)Boost: while the diode conducts, the switch node is connected to the output; the switch from that node to ground blocks .
✓ reproduces
boost.Vds(equality checked symbolically by pytest)While the diode conducts, the switch's far end sits at the output, ; the switch blocks .
✓ reproduces
buckboost.Vds(equality checked symbolically by pytest)Forward, reset interval: the reset winding ( turns) connects to with reversed polarity, so the primary ( turns) sees .
The switch blocks the input voltage minus the primary voltage.
✓ reproduces
forward.Vds(equality checked symbolically by pytest)Forward output inductor: while the switch is on, the secondary applies , so the inductor sees for .
Solve for .
✓ reproduces
forward.ripple.iL(equality checked symbolically by pytest)Transistor utilization: the load power over the transistor's peak voltage times its rms current. With small ripple the transistor current is a flat pulse of height for , whose rms value is .
Buck: , the transistor blocks and carries the inductor current .
Simplify.
✓ reproduces
util.buck(equality checked symbolically by pytest)Boost: the transistor blocks and carries the inductor current .
Simplify.
✓ reproduces
util.boost(equality checked symbolically by pytest)Buck-boost: , the transistor blocks and carries .
Simplify.
✓ reproduces
util.buckboost(equality checked symbolically by pytest)Flyback: , the transistor blocks and carries the primary-referred magnetizing current ; the turns ratio cancels and the result equals the buck-boost's.
Forward: , the transistor blocks and carries the reflected inductor current (magnetizing current neglected).
Simplify.
✓ reproduces
util.forward(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/topologies.py
Small-signal transfer functions, CCM
Section titled “Small-signal transfer functions, CCM”Averaging removes the switching ripple; perturbing the averaged equations around the operating point (, , ) and dropping second-order products gives linear equations whose Laplace transform yields . Each converter below ends in the standard second-order form with gain , poles at with quality factor , and, for the boost and buck-boost, a zero in the right half-plane.
Buck, linearised averaged equations (): the inductor sees , the capacitor carries .
Solve for .
DC gain: the value at .
✓ reproduces
buck.ss.Gd0(equality checked symbolically by pytest)Poles: from the coefficient .
✓ reproduces
buck.ss.w0(equality checked symbolically by pytest)from the coefficient .
✓ reproduces
buck.ss.Q(equality checked symbolically by pytest)Boost: the averaged inductor voltage is and the capacitor current (). Perturbing and linearising:
Operating point from the steady state, writing : , .
Solve for .
DC gain (results are written back with ).
✓ reproduces
boost.ss.Gd0(equality checked symbolically by pytest)Pole frequency.
✓ reproduces
boost.ss.w0(equality checked symbolically by pytest)Quality factor.
✓ reproduces
boost.ss.Q(equality checked symbolically by pytest)The numerator vanishes at a positive real : a right-half-plane zero.
✓ reproduces
boost.ss.wz(equality checked symbolically by pytest)Buck-boost: averaged inductor voltage and capacitor current , with the output negative. Linearised:
Operating point, with : , .
Solve for .
The dc gain is negative (inverting output); its magnitude is:
✓ reproduces
buckboost.ss.Gd0(equality checked symbolically by pytest)Pole frequency.
✓ reproduces
buckboost.ss.w0(equality checked symbolically by pytest)Quality factor.
✓ reproduces
buckboost.ss.Q(equality checked symbolically by pytest)Right-half-plane zero.
✓ reproduces
buckboost.ss.wz(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/small_signal.py
PWM modulator and loop gain
Section titled “PWM modulator and loop gain”A voltage-mode controller compares a control voltage with a periodic ramp to set the duty ratio. Going once around the loop multiplies the gains of the compensator, the modulator, the power stage and the sensor; that product, the loop gain , decides how strongly the loop rejects disturbances.
The ramp rises from to in ; the switch turns off when it crosses .
The on-time fraction is .
✓ reproduces
pwm.d(equality checked symbolically by pytest)Around the loop: the compensator output drives the modulator (gain ), the power stage turns into (gain ), and the sensor feeds back .
The loop gain is the product around the loop.
✓ reproduces
loop.T(equality checked symbolically by pytest)An output disturbance adds to the controlled output; the controller acts on the error .
The disturbance reaching the output is divided by .
✓ reproduces
loop.suppression(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/control.py
Stored energy, losses and ringing
Section titled “Stored energy, losses and ringing”Energy stored in an inductor or capacitor is the integral of the power delivered to it. A loss that repeats every switching period is the energy lost per cycle times ; a conduction loss is the period average of the instantaneous power.
Energy delivered to an inductance: with , so . Integrate from zero to the turn-off current.
Evaluate the integral.
✓ reproduces
flyback.leak.E(equality checked symbolically by pytest)If this energy is removed (clamped or dissipated) every cycle, the average power is .
✓ reproduces
flyback.leak.P(equality checked symbolically by pytest)Energy stored in the switch-node capacitance charged to : .
A hard turn-on discharges it through the switch channel every cycle: .
✓ reproduces
loss.sw.cap(equality checked symbolically by pytest)Conduction loss is the period average of the instantaneous power .
By definition the rms current is the square root of the period average of .
is constant, so it moves out of the average.
✓ reproduces
loss.cond(equality checked symbolically by pytest)A conducting diode is modelled as a forward-voltage intercept plus a dynamic resistance, , so .
The average of is and the average of is .
✓ reproduces
loss.diode(equality checked symbolically by pytest)Each cycle the driver draws the gate charge from its supply; the energy taken from the supply is the integral of .
All of it ends up as heat in the driver and gate resistances; multiply by .
✓ reproduces
loss.gate(equality checked symbolically by pytest)An undamped L-C loop obeys ; its characteristic equation is .
The roots are .
.
✓ reproduces
dcm.ring.f(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/energy.py
Magnetic circuits: the inductance factor, flux density and the core geometrical constant
Section titled “Magnetic circuits: the inductance factor, flux density and the core geometrical constant”A magnetic path behaves like a resistive circuit: the magnetomotive force drives flux through reluctances . With a uniform flux density over the effective area , .
Core reluctance (relative permeability ).
Gap reluctance (no fringing: the gap area equals ).
They are in series.
Flux linkage , so .
The inductance factor is the inductance per turn squared, .
Substitute the two reluctances.
✓ reproduces
mag.AL_gap(equality checked symbolically by pytest)Hence .
✓ reproduces
mag.L_from_AL(equality checked symbolically by pytest)Flux linkage and inductance: , so .
At the peak current, .
✓ reproduces
mag.B_pk(equality checked symbolically by pytest)The flux density follows the current, . A ripple of about the dc current moves it by about its dc value: that amplitude is .
✓ reproduces
mag.B_ac(equality checked symbolically by pytest)Holding at the limit and solving for the turns gives the fewest turns that stay within it.
✓ reproduces
mag.N_Bmax(equality checked symbolically by pytest)With fixed, the inductance sets the gap reluctance, and with it the gap length.
✓ reproduces
mag.gap_length(equality checked symbolically by pytest)Choosing a core. The winding's turns of copper area may fill only of the window :
At the limit, its resistance, turns of mean length MLT, equals the copper-loss budget :
The window fixes the wire, , so the resistance grows as the square of the turns:
The flux limit fixes the turns, :
Collecting the core's dimensions on one side defines the core geometrical constant; the other side depends on the specification alone.
A core meets the flux limit, the window and the resistance budget together when its is at least:
✓ reproduces
mag.Kg_req(equality checked symbolically by pytest)Faraday's law: , so the change of over the on-time is the integral of .
With a constant winding voltage the swing is proportional to the volt-seconds .
✓ reproduces
mag.dB_faraday(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/magnetics.py
Windings: resistance, skin depth, thin layers, leakage and the short circuit
Section titled “Windings: resistance, skin depth, thin layers, leakage and the short circuit”A winding is a long conductor wound in layers. Its resistance follows from its length and cross-section; at high frequency the current crowds into a skin; and the field between the windings stores the energy that appears as leakage inductance.
The winding is one conductor, turns of mean length MLT:
Its dc resistance is the resistivity times the length over the conductor's area.
✓ reproduces
wind.dcr(equality checked symbolically by pytest)In a good conductor (conductivity ) a sinusoidal current density obeys , so it varies as with
The root with a positive real part:
The magnitude falls by over one skin depth, the inverse of the real part of .
✓ reproduces
wind.skin_depth(equality checked symbolically by pytest)Dowell's ac resistance factor of layers, each skin depths thick (`wind.dowell`):
For thin layers, expand the hyperbolic and circular functions in powers of : the terms up to cancel and the first excess is of fourth order.
✓ reproduces
wind.dowell_low(equality checked symbolically by pytest)At a given frequency the skin depth is fixed, so a layer skin depths thick has the dc resistance , being that of a layer one skin depth thick. Carrying a current , it loses
Relative to the loss of a layer one skin depth thick carrying the same current as dc, :
✓ reproduces
wind.loss_rel(equality checked symbolically by pytest)With the series for thin layers:
It is least where its derivative vanishes:
✓ reproduces
wind.phi_opt(equality checked symbolically by pytest)There the ac resistance factor is the same for every number of layers:
The field in the window runs along the breadth , so where is the MMF enclosed at that height; the energy it stores over the turn length MLT is
Primary, then secondary: the MMF rises linearly through the primary to , stays there across the spacing, and falls back to zero through the secondary.
With , each winding counts with a third of its height, the spacing in full.
✓ reproduces
xfmr.leakage.ps(equality checked symbolically by pytest)Primary split around the secondary: the MMF rises to through the first half, crosses the secondary from to , and returns to zero through the second half.
The peak MMF is halved, so the energy, and the leakage, fall to about a quarter; the two spacings both count.
✓ reproduces
xfmr.leakage.psp(equality checked symbolically by pytest)Two coupled windings, each with its own inductance and the mutual inductance between them:
and at winding 2:
Shorting winding 2 sets , so its current changes against winding 1's:
Winding 1 then sees the inductance :
With the coupling coefficient (`xfmr.k`):
✓ reproduces
xfmr.L_sc(equality checked symbolically by pytest)In the transformer model (1:, magnetizing inductance and the leakage inductances, all referred to the primary) the winding inductances are
the mutual inductance,
and winding 2's inductance (its leakage ):
Substituting them, the turns ratio cancels: the primary's leakage in series with the secondary's in parallel with .
✓ reproduces
xfmr.L_sc_T(equality checked symbolically by pytest)With winding 2 open, no current flows in it (), and the two voltages stand in the ratio
In the transformer model: slightly below the turns ratio, the primary's leakage taking its share of the voltage.
✓ reproduces
xfmr.V_oc(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/windings.py
Measurement: inductance read near self-resonance
Section titled “Measurement: inductance read near self-resonance”A winding is an inductance with its turns' capacitance in parallel. An impedance meter divides the reactance it measures by and reports that as the inductance.
The inductance and the capacitance in parallel:
which is a pure reactance,
so the meter reads the inductance :
The self-resonant frequency (`passive.f_srf`) gives :
Substituting :
✓ reproduces
meas.L_app(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/measurement.py
Linear sources: maximum power, constant-voltage extraction and the loss-free resistor
Section titled “Linear sources: maximum power, constant-voltage extraction and the loss-free resistor”A linear energy source is modelled by its Thevenin equivalent: open-circuit voltage behind a source resistance . How much of its available power reaches the converter depends on what the converter's input looks like.
Power into a load resistance .
gives the matched load.
Substitute .
✓ reproduces
src.Pmax(equality checked symbolically by pytest)A constant-voltage sink at (e.g. a converter pinned at a fixed input voltage) draws .
The power it absorbs: negative when , when the sink returns energy to the source.
✓ reproduces
src.cv_power(equality checked symbolically by pytest)Normalise by .
✓ reproduces
src.cv_extraction(equality checked symbolically by pytest)A converter in DCM draws an average input current proportional to its input voltage: its input is a resistance , the loss-free resistor, which takes the place of .
The source resistance and divide the source voltage.
✓ reproduces
lfr.Vg(equality checked symbolically by pytest)with , normalised by : the source voltage cancels.
✓ reproduces
lfr.eta(equality checked symbolically by pytest)The loss-free resistor draws the power of a resistance at its input voltage.
Solve for : a larger power needs a higher input voltage.
✓ reproduces
lfr.Vg_power(equality checked symbolically by pytest)A DCM flyback's input resistance is (derived with the flyback).
Solve for : the inductance that presents a wanted , such as to match the source.
✓ reproduces
lfr.L_M(equality checked symbolically by pytest)Under an envelope slow against the bus, the loss-free resistor takes at every instant; take , one half-wave of the envelope (a rectified sine repeats it).
Average over the half-wave: the square of a sine averages to half its peak's.
✓ reproduces
lfr.P_env(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/harvesting.py
Piezoelectric source: loads and interfaces
Section titled “Piezoelectric source: loads and interfaces”Under a steady sinusoidal vibration of constant amplitude, a piezoelectric element is a current source in parallel with its clamped capacitance . What a load or an interface takes follows from where that current's charge goes in each half period.
With nothing connected, the whole current charges : .
Its amplitude.
✓ reproduces
piezo.Vp(equality checked symbolically by pytest)A resistor across the element shares the current with : its voltage amplitude is , and it takes half the square of that over .
.
✓ reproduces
piezo.R_opt(equality checked symbolically by pytest)Substitute it.
✓ reproduces
piezo.P_R(equality checked symbolically by pytest)The source drives of charge each half period, between two extrema of the displacement.
Through a full-wave bridge onto , the element's voltage swings from to before the bridge conducts, which takes ; the rest of the charge enters .
Per unit time: one such half period every .
✓ reproduces
piezo.P_std(equality checked symbolically by pytest): half the open-circuit amplitude.
Substitute it.
✓ reproduces
piezo.P_std_max(equality checked symbolically by pytest)SECE leaves the element open between extrema, so its voltage climbs from zero to ; at the extremum all of is taken, whatever the load.
Per unit time.
✓ reproduces
piezo.P_sece(equality checked symbolically by pytest)Parallel SSHI inverts the element's voltage at each extremum, from to , so the swing to the other rail takes only .
Per unit time.
✓ reproduces
piezo.P_sshi(equality checked symbolically by pytest).
Substitute it.
✓ reproduces
piezo.P_sshi_max(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/piezo.py
Current-output shunt monitor
Section titled “Current-output shunt monitor”A current-output high-side monitor converts the small voltage across a shunt into a current, which an output resistor turns back into a ground-referenced voltage.
Ohm's law across the shunt: the signal, and the voltage the shunt takes from the measured circuit.
✓ reproduces
sense.burden(equality checked symbolically by pytest)The ideal amplifier forces the same voltage across , so the current through is .
That current flows out through : .
✓ reproduces
sense.current_out_monitor(equality checked symbolically by pytest)A voltage-output amplifier multiplies the sense voltage by its fixed gain and adds the voltage on its REF pin, which sets the output at zero current.
✓ reproduces
sense.voltage_out_monitor(equality checked symbolically by pytest)An input offset voltage adds directly to the sense voltage, so the output of either amplifier reads the current
The reading exceeds the current by the offset over the sense resistor, whatever the current.
✓ reproduces
sense.offset_current(equality checked symbolically by pytest)Without a Kelvin connection the sense connections sit beyond the pads and solder joints, whose resistance carries the same current; the reading, scaled by , is
Its relative error: independent of the current, and larger the smaller the shunt.
✓ reproduces
sense.pad_error(equality checked symbolically by pytest)With both, the amplifier sees and reads it as a current through . The output is the output equation at this current; the offset's sign that raises it bounds the output from above, the other sign from below.
✓ reproduces
sense.reading(equality checked symbolically by pytest)Its relative error is the sum of the two, with no cross term: the offset's share falls as , the pad's share stays.
✓ reproduces
sense.rel_error(equality checked symbolically by pytest)A current-output amplifier drives its current into at node A. An R-C filter follows: from node A to node B, and from node B to ground, with nothing else loading node B. The current balance at node A (Laplace domain):
and at node B:
Solving for the capacitor's voltage gives a single pole; at dc the output is still :
The pole's time constant is : the capacitor sees in series with . is the Thevenin resistance of the current source it loads.
✓ reproduces
sense.filter_R(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/sensing.py
Bench: edges, gate drive, rise time, inrush, heat and a battery’s terminals
Section titled “Bench: edges, gate drive, rise time, inrush, heat and a battery’s terminals”Results of the inductor's and the capacitor's laws, the first-order step response, Ohm's law across a gate resistor, a series thermal path and the Rint battery model, in the form they take on the bench.
The voltage across an inductance is proportional to the rate of change of its current:
A current that changes by linearly over the edge changes at a constant rate:
so throughout the edge the loop's inductance develops
✓ reproduces
layout.v_spike(equality checked symbolically by pytest)After the turn-off edge the loop's inductance rings with the switch node's capacitance, a series L-C, at
so the ring's frequency gives the loop's inductance:
✓ reproduces
layout.L_ring(equality checked symbolically by pytest)While the drain voltage makes its transition the gate stays at the plateau voltage . The driver switches its output to (turn-on) or to 0 (turn-off) behind the gate loop's resistance , so by Ohm's law the gate current is constant meanwhile:
at turn-on
✓ reproduces
gate.I_on(equality checked symbolically by pytest)and at turn-off
✓ reproduces
gate.I_off(equality checked symbolically by pytest)A constant current delivers charge at a constant rate:
so the plateau, along which the gate takes the gate-drain charge , lasts
✓ reproduces
gate.t_pl(equality checked symbolically by pytest)A capacitor's charge is its capacitance times its voltage, so supplying the charge lowers its voltage by
For a droop of at most the capacitance must be at least
✓ reproduces
boot.C(equality checked symbolically by pytest)A single-pole system answers a unit step with
It reaches 10 % and 90 % of its final value at
so its 10-90 % rise time is
Its -3 dB bandwidth is the corner frequency of the same pole:
Eliminating :
✓ reproduces
probe.t_rise(equality checked symbolically by pytest)The tip-and-ground loop's inductance and the probe's input capacitance form a series L-C; without loss its current obeys
whose solutions ring at the angular frequency
that is, the frequency
✓ reproduces
probe.f_ring(equality checked symbolically by pytest)An empty capacitor switched onto a step through a series resistance charges with the current
which is largest at the step, when the capacitor has no voltage across it:
✓ reproduces
inrush.I_pk(equality checked symbolically by pytest)The integral of its square over the whole pulse is
✓ reproduces
inrush.I2t(equality checked symbolically by pytest)A capacitor's current is its capacitance times the rate of change of its voltage:
so a voltage ramped linearly from zero to over draws a constant current:
✓ reproduces
inrush.I_ramp(equality checked symbolically by pytest)A thermal resistance is the temperature difference across a part of the heat's path per watt flowing through it. With all of the device's power flowing from the junction to the case, the case to the heat sink and the heat sink to the ambient in turn,
and the rises add up from the ambient:
✓ reproduces
therm.Tj(equality checked symbolically by pytest)The Rint model is the open-circuit voltage behind the internal resistance; the charging current flows into the positive terminal through the resistance (`bat.rint`):
so the terminals sit at
✓ reproduces
bat.v_term(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/bench.py
Simulation: stepping a circuit in time, and how long it takes to settle
Section titled “Simulation: stepping a circuit in time, and how long it takes to settle”A simulator advances a circuit's state in time steps. Within a step a switching converter is a linear circuit with constant sources, which a first-order example shows can be stepped exactly. The usual integration rules are compared on one decaying mode, the test equation, where each multiplies the deviation by a fixed factor per step. The envelope of the output filter's ring then says how many switching periods a simulation from rest needs before its last periods show the steady state.
Within a step the circuit is linear and its sources are constant. A capacitor charged through a resistance then approaches the voltage at a rate proportional to the distance left, over the time constant :
Solve it from the voltage at the start of the step:
At the end of the step, . Nothing was approximated, so the step may be as long as the interval:
✓ reproduces
sim.exact_step(equality checked symbolically by pytest)Compare the usual rules on one decaying mode on its own, the deviation from where the circuit is going, which changes at the rate (the test equation). A rule that steps it from to over multiplies it by a factor in every step:
Forward Euler takes the slope at the start of the step:
Its factor per step:
✓ reproduces
num.gain_fe(equality checked symbolically by pytest)The trapezoidal rule averages the slopes at both ends of the step, so appears on both sides:
Solve for and divide by :
✓ reproduces
num.gain_tr(equality checked symbolically by pytest)Backward Euler takes the slope at the end of the step:
Its factor per step:
✓ reproduces
num.gain_be(equality checked symbolically by pytest)For a step far longer than , a stiff mode, the exact factor is nearly zero. Forward Euler's factor grows without bound, the trapezoidal rule's tends to , so the mode keeps its size and flips its sign every step, and backward Euler's tends to zero, as the exact one does:
Backward Euler steps an inductor's current with the slope at the end of the step, the voltage across it over its inductance:
A diode's current has gone past zero, to , before the diode turns off. If nothing else takes the current, the next step must end with it at zero:
Solve for the voltage across the inductor in that step:
✓ reproduces
sim.step_jump(equality checked symbolically by pytest)Take a buck with ideal parts. With its source at rest (a voltage source is a short), the filter's inductance, its capacitance and the load resistance are in parallel. The natural response of this parallel RLC circuit goes as , with a root of its characteristic equation:
When the filter rings, the roots are a complex-conjugate pair. Their common real part, half their sum, is , and is the decay rate of the ring's envelope (the neper frequency):
The envelope decays as , with the time constant , whatever the inductance (with ideal parts):
✓ reproduces
filter.tau_env(equality checked symbolically by pytest)A simulation from rest starts with an error as large as the steady state itself. After switching periods it has fallen to the fraction :
Solve for :
✓ reproduces
sim.periods_settle(equality checked symbolically by pytest)
Derivation script: python/pe_core/derive/numerics.py
The numbers in the examples, presets and exercises on this site are synthetic: round teaching values, not data from any real design.