vp.power.cpf
The continuation power flow: the PV curve of a transfer into one bus, through the nose.
Part of the distribution vipyr; it runs from a checkout of the
repository. Planned on PyPI as pip install vipyr.
vp.power.cpf traces the bus voltages as the power injected at poi_bus
(and taken out at the sink) grows, past the point where the plain power
flow stops converging. It is the pseudo-arclength continuation of
MATPOWER's runcpf: the transfer is an unknown, a tangent predictor steps
along the curve and Newton's method corrects on the power flow augmented
with the step equation, which stays solvable at the nose. The nose is the
voltage-stability limit of that transfer.
Signature
vp.power.cpf(case, poi_bus, *, sink='slack', step=0.5, max_step=2.0, stop_frac=0.7, max_steps=300, tol=1e-10, nose_tol=0.0001, singular_values=False) Parameters
- case : str | dict, required
- A case as vp.power.runpf takes it, or a .raw path.
- poi_bus : int, required
- The bus receiving the transfer, a bus number.
- sink : str, default
'slack' - 'slack' or 'gens', as for vp.power.interconnect.
- step : float, default
0.5 - The first step along the curve (arc length, per unit).
- max_step : float, default
2.0 - The largest step.
- stop_frac : float, default
0.7 - Stop once the transfer falls below this fraction of the nose's.
- max_steps : int, default
300 - The most steps.
- tol : float, default
1e-10 - The corrector's tolerance, per unit.
- nose_tol : float, default
0.0001 - Past the nose the trace steps back and shrinks its step until the step is below this; the nose is then located to about its square.
- singular_values : bool, default
False - Also compute the smallest singular value of the power-flow Jacobian at each point (dense SVD).
Returns
A frozen PVCurve. Iterating it gives the fields below in order; it also has
params, tests, log and check().
- mw : ndarray[float64]
- The transfer at each point, MW.
- v_poi : ndarray[float64]
- Vm at the POI, per unit.
- v_min : ndarray[float64]
- The lowest Vm in the network.
- vm : ndarray[float64]
- Points x buses: Vm.
- va : ndarray[float64]
- Points x buses: Va, radians.
- nose_mw : float
- The largest transfer on the curve, MW.
- nose : int
- The point of the nose.
- smin : ndarray[float64]
- The smallest singular value of the Jacobian per point (0 if not asked).
- success : bool
- Whether the trace passed a nose.
Raises
- ValueError
- An unknown method, a case name that is not shipped, or a case dict without baseMVA, bus, gen and branch.
- module.VivStop
- The case has no bus that can be the reference, or every generator is at a reactive limit.
- TypeError
- An argument of the wrong type, or an unknown keyword.
- vipyr.VivBuildError
- An ImportError: no C compiler, or the program's C does not build.
References
- V. Ajjarapu, C. Christy, The continuation power flow: a tool for steady state voltage stability analysis, IEEE Trans. Power Systems 7 (1992) 416-423 doi:10.1109/59.141737
Examples
import vipyr as vp
r = vp.power.cpf("case118", 38, step=0.2, max_step=1.0)
print(round(r.nose_mw, 1), r.v_poi[r.nose])
assert r.check() 1990.7 0.6914210369321251Each example ran as written when these pages were generated, and the output shown is what it printed.
Checked against
- Reference
- PYPOWER 5.1.21's runcpf (pseudo-arclength, full trace) and the largest transfer at which PYPOWER's Newton power flow converges, on case9, case30 and case118; every curve point re-solved by PYPOWER at its transfer agrees in Vm; the Jacobian's smallest singular value at the nose is a small fraction of its base-case value (lib/power/compare_study.py).
Credits
- The methods follow MATPOWER's (BSD-3-Clause). The test cases are MATPOWER's case files, each with its source named in its header.
Source
- Viv: lib/power/cpf.viv
- Viv: lib/power/api.viv
- Viv: lib/power/pf.viv