IBR Dynamic Modeling and Simulation
Droop Grid-Forming Control
C1-05 · Lesson + simulation + practice · Allow 90 minutes
Build voltage-forming control with power filters and cascaded PI loops.
Learning objectives
- Explain the P–f and Q–V feedback paths.
- Identify the canonical 13-state model components.
From structure to model
Create an angle from a power–frequency law
A droop GFM creates an internal voltage angle by integrating its frequency command. It does not need a PLL for this synchronization law. A filtered active-power mismatch changes frequency; a filtered reactive-power mismatch changes voltage magnitude. The network then determines actual injected power.
Our three states are δ, P_f and Q_f. The voltage realization is E exp(jδ) behind Z_f = 0.00625 + j0.1 pu. The branch current is (E exp(jδ) − V)/Z_f. The physical LCL and PI loops are replaced by this algebraic relation. Z_f is a declared source impedance in the teaching model.
The loop closes through the network
For a small positive P* step, the frequency initially rises because P_f cannot jump. δ advances, electrical power increases, and P_f catches up. At the restored equilibrium against a nominal-frequency infinite bus, ω = 1 and P_f = P*. The reference is a control input, not a direct assignment to the measured power trajectory.
Increasing m_p changes both the steady frequency–power slope and the transient loop gain. The fixed measurement filters are τ_p = 0.1 s and τ_q = 0.05 s. Do not attribute every response change solely to “more droop” without also considering the network and filter time scales.
Match a terminal operating point
The experiment initializes all families at PoC P = 0.6 and Q = 0. Its internal source amplitude generally exceeds 1 because the source impedance carries current. With E₀ fixed at 1, Q* must be chosen so that E = E₀ − n_q(Q_f − Q*) equals that required amplitude. Therefore the droop Q* is not zero even when terminal Q is zero.
At SCR = 5, the baseline Q* is approximately 0.316795 pu. That is an equilibrium-matching control offset, not a claim that the PCC exports that reactive power. The lab exposes the actual commands so this distinction can be inspected.
A frequency step tests the slope
Apply +0.1 Hz to the grid. At a locked steady state, ω = ω_g and P ≈ P* − (ω_g − 1)/m_p. For m_p = 0.02, the predicted active-power change is −0.1/(50 × 0.02) = −0.1 pu. This is a within-model steady-state prediction; the algebraic impedances remain evaluated at nominal frequency.
Build the full cascaded-control realization
To retain inner loops, use x = [δ, P_f, Q_f, ξ_vd, ξ_vq, ξ_id, ξ_iq, i₁d, i₁q, v_cd, v_cq, i₂d, i₂q]. Set v* = [E, 0], voltage error e_v = v* − v_c and ξ̇_v = e_v. With output-current feedforward and capacitor decoupling enabled, the voltage PI produces i₁* using the first added equation below. Current error is e_i = i₁* − i₁ and ξ̇_i = e_i; the current PI produces converter voltage u using the second equation. Insert u into the LCL equations from Module 3 to close the model.
The canonical source droop realization feeds its power filters from v_c and i₂; its benchmark outputs are reconstructed at PoC. Those two ports must remain distinct. To initialize a no-limit equilibrium, first determine the electrical state, then set ξ_v = (i₁ − F i₂ + ω_b ω c Jv_c)/K_iv and ξ_i = (u − v_c + ω_b ω ℓ₁ Ji₁)/K_ii. Zero controller error does not imply zero PI integrals. The browser droop lab deliberately removes these four integrators and six electrical states.
Core equations
\tau_p\dot P_f=P_{PoC}-P_f,\qquad\tau_q\dot Q_f=Q_{PoC}-Q_f\omega=1-m_p(P_f-P^*),\quad E=E_0-n_q(Q_f-Q^*),\quad\dot\delta=\omega_b(\omega-\omega_g)I=\frac{Ee^{j\delta}-V}{Z_f},\qquad P+jQ=VI^*e_v=v^*-v_c,\quad\dot\xi_v=e_v,\quad i_1^*=F i_2-\omega_b\omega cJv_c+K_{pv}e_v+K_{iv}\xi_ve_i=i_1^*-i_1,\quad\dot\xi_i=e_i,\quad u=v_c-\omega_b\omega\ell_1Ji_1+K_{pi}e_i+K_{ii}\xi_iSimulation experiment
- Run +0.03 pu P*, then inspect frequency: explain why it changes before power settles.
- Inspect the matched Q* and compare it with measured Q at time zero.
- Apply +0.1 Hz and compare the final P change with −0.1/(50 m_p).
Laboratory · Python runs in your browser
Predict → run → inspect
Predict the response, then change a parameter and run. The initial plot is a baseline generated by the same solver. The first computation downloads Python; later runs reuse it.
Loading the baseline…
Numerical audit and samples
Low-frequency teaching realization: nominal-frequency algebraic network and ideal current/voltage realization. 50 Hz, 10 kVA, 400 V; initial PCC total P = 0.6, Q = 0; X/R = 10. τᵢ = 0.02 s, τₚ = 0.1 s, τq = 0.05 s, nq = 0.0325; GFM source impedance 0.00625 + j0.1 pu. LCL, inner PI, DC dynamics and current limits are omitted.
Edit the model and reproduce the experiment
The code reads the controls above and plots its own result. Edit the experiment or expand the solver source to test your prediction. Download experiment produces one .py file containing the parameters, full solver and experiment code; local execution needs only Python 3.
case is a snapshot of the controls when you press Run. Call solve(case) and assign the final solution to result to plot it.
The first run needs internet access to download Python. Computation stays in your browser; the solver uses only the standard library.
Ready to run.
Output appears here.
Python result
Inspect and edit the model source (advanced)
The source contains the transforms, LCL, PLL, droop, VSM, shared PCC and explicit reset. Source edits affect the next Python experiment; the laboratory above retains the original teaching equations.
Check your understanding
Explain which dynamics the simple model omits.
Continue in the source repository
Adapted from local PINN-IBR materials reviewed on 2026-10-03. The web code is a separately authored teaching realization. These repository paths contain the detailed models, configurations and research cases.
Coding/Modeling/src/ibrsim/models/droop_gfm.pyCoding/Modeling/Single-IBR-Infinite-Bus/00_Droop_GFM_Infinite_Bus_Model_Library.ipynb