Solver#
- solve_power_flow(case, *, backend=None, validate=True, expand_3w_transformers=True, options=None, member_costs=None, verbose=False, **solve_opts)#
Solve power flow for a case.
This is the canonical high-level API. It handles the full pipeline: 1. Expand 3W transformers (optional) 2. Validate case against solver capabilities 3. Normalize to solver arrays (respecting build options) 4. Call backend Newton-Raphson solver 5. Extract and return results
The input case is never mutated, so the same case object can be reused across solves.
Reactive-power limits are enforced automatically whenever the case has any voltage-regulating device: generator Q limits, STATCOM / UPFC shunt current limits, and VSC mode-1 Q limits. Enforcement timing is controlled by var_limit_start_outer_iter. Widen a device's qmin/qmax in the case data if you need unconstrained behavior for a specific unit.
- Parameters:
case -- Parsed case (from GpfCase.from_raw() or parse_raw()).
backend -- Backend to use: "cuda" or "cpu". Defaults to None, which auto-detects via resolve_backend (prefers "cpu", then "cuda") — the same selection the gpf CLI uses.
validate -- If True, validate case before solving.
expand_3w_transformers -- If True, expand 3W transformers via star-equivalent.
options -- Build options controlling which features are compiled into the network spec, used verbatim. If None, uses the case's format default (see registry.format_build_options); to customize, start from that object, edit fields, and pass it back. Use PfBuildOptions.minimal_nr() for debugging convergence issues.
member_costs -- Optional regulator cost override, keyed by (PF_REG_*, device_index). When given, a member's reactive sharing weight is 1/cost instead of rmpct/100, so group reactive power is split proportional to 1/cost. Members not keyed keep the rmpct/100 share.
verbose -- If True, print setup and solve progress to stderr: which stage is running during setup, plus a per-outer-pass trace (inner iteration count, max mismatch, and which discrete controls engaged each pass).
**solve_opts --
Numerical and control knobs forwarded to the backend; any field of
PfSolveOptions(max_iter, tol, q_tol, var_limit_start_outer_iter, the discrete-control gates, max_outer_iter, low_voltage_load_pu). Unknown keys raise TypeError.One extra key is consumed here, not forwarded:
area_interchange(0 = off, default; 1 = tie lines only; 2 = tie lines and loads). When set, each area's slack generator (isw) is redispatched until the area's net interchange reachespdeswithinptol.
- Returns:
SolvedCase with bus voltages, generator Q, branch flows, etc.
- Raises:
UnsupportedPowerFlowCaseError -- If case has features not supported by solver.
RuntimeError -- If backend fails.
Example
>>> from gpf import GpfCase, solve_power_flow >>> case = GpfCase.from_raw("ieee39.raw") >>> sol = solve_power_flow(case, backend="cpu") >>> print(sol.summary()) SolvedCase(CONVERGED in 4 iterations, ...)
# Debug mode with minimal features: >>> from gpf import PfBuildOptions >>> sol = solve_power_flow(case, options=PfBuildOptions.minimal_nr())
- solve_file(path, **overrides)#
Parse a case file and solve it in one call.
The case file's format is detected from its extension (
.raw,.rawx/.json,.m) and the matching modeling conventions are applied automatically, so this is just parse-then-solve. Any explicit keyword wins over those defaults.- Parameters:
path -- Filesystem path to the case file (str or Path). The extension selects the parser; unknown extensions raise
ValueError.**overrides -- Keyword arguments forwarded to
solve_power_flow()(e.g.backend,validate,options, or anyPfSolveOptionsfield). Each overrides the format default.
- Returns:
SolvedCase with bus voltages, generator Q, branch flows, etc.
- Raises:
ValueError -- If the file extension is not a supported case format.
UnsupportedPowerFlowCaseError -- If the case has features the solver does not support.
- class SolvePreset(var_limit_start_outer_iter=0, build=<factory>)#
Bases:
objectPer-format solver defaults: a plain data record, not a merge engine.
var_limit_start_outer_iter is the var-limit policy used when the caller passes no override. build is the set of PfBuildOptions field values the format implies; format_build_options materializes it into a concrete PfBuildOptions the caller can edit field-by-field and pass back.
- gpf.RAW_PRESET: SolvePreset#
- gpf.MATPOWER_PRESET: SolvePreset#
- format_build_options(case)#
Complete, format-correct
PfBuildOptionsforcase.The starting point for customization: edit fields on the returned object and pass it as
solve_power_flow(case, options=...). Equivalent to whatsolve_power_flowuses by default whenoptionsis omitted.
- parse_var_limit_mode(text)#
Translate a user-facing mode string into the backend integer.
- Accepts:
"off" -> PF_VAR_LIMIT_OFF (-1) "immediate" -> PF_VAR_LIMIT_IMMEDIATE (0) "auto" -> PF_VAR_LIMIT_AUTO (1) "at:<K>" -> K (any non-negative integer; advanced)
Any other string raises ValueError. Case-insensitive.
- class SolvedCase(sbase, basfrq, bus_ids, vm, va, p_inj, q_inj, bus_types_final, gen_bus_ids, gen_machids, gen_p, gen_q, branch_from_bus_ids, branch_to_bus_ids, branch_ckts, p_from, q_from, p_to, q_to, p_loss, q_loss, vsc_dc_names, vsc_dc_bus1_ids, vsc_dc_bus2_ids, vsc_dc_p_conv1, vsc_dc_q_conv1, vsc_dc_p_conv2, vsc_dc_q_conv2, vsc_dc_i_dc, vsc_dc_p_loss, vsc_dc_v_dc1, vsc_dc_v_dc2, converged, iterations, outer_iterations, max_mismatch, backend, solve_time_s=0.0, parse_time_s=0.0, warnings=(), iteration_history=(), exit_reason=PfExitReason.CONVERGED, gen_limit_binding=<factory>, statcom_limit_binding=<factory>, upfc_shunt_limit_binding=<factory>, vsc_limit_binding=<factory>, lcc_dc_names=<factory>, lcc_dc_rect_bus_ids=<factory>, lcc_dc_inv_bus_ids=<factory>, lcc_dc_p_rect=<factory>, lcc_dc_q_rect=<factory>, lcc_dc_p_inv=<factory>, lcc_dc_q_inv=<factory>, lcc_dc_i_d_pu=<factory>, lcc_dc_cos_alpha=<factory>, lcc_dc_cos_gamma=<factory>, lcc_dc_tap_r=<factory>, lcc_dc_tap_i=<factory>, lcc_dc_mode=<factory>, lcc_dc_limit_flags=<factory>, jacobian_dim=0, n_reg_groups=0, n_reg_groups_multi=0, n_reg_members=0, branch_rates=<factory>, rating_names=<factory>)#
Bases:
objectImmutable power flow solution.
All arrays are in per-unit on system base (sbase). Angles are in radians.
- property any_limit_binding#
True if at least one regulator of any kind hit its limit.
- property augmented_dim#
Voltage-regulation rows above the base system; equals n_reg_members + n_reg_groups_multi. Zero without regulation.
- property base_dim#
Base power-flow Newton dimension, always 2 * n_bus.
- get_bus_voltage(bus_id)#
Get voltage at a bus.
- Parameters:
bus_id -- bus number.
- Returns:
Voltage magnitude (pu) and angle (radians).
- Return type:
(vm_pu, va_rad)
- Raises:
KeyError -- If bus not found.
- get_generator_q(bus_id, machid='1')#
Get generator reactive power output.
- Parameters:
bus_id -- bus number.
machid -- Machine ID (default "1").
- Returns:
Q output in pu on system base.
- Raises:
KeyError -- If generator not found.
- property n_limit_binding#
Total regulator-kind devices whose VAR/Q/current limit bound during the last solve (generator + STATCOM + UPFC-shunt + VSC).
- property n_reg_groups_reduced#
a q_m column but no lambda.
- Type:
Single-member (reduced-form) groups
- property status#
Return convergence status as string.
- summary()#
Return a brief summary of the solution.
- to_dict()#
Convert to dictionary (arrays become lists).
- to_report(case_name='')#
Format as plain text report.
- For rich terminal output or HTML, use the public
renderhelper: from gpf import render print(render(solved_case)) # Auto-detects best format
- For rich terminal output or HTML, use the public
- PfIterationRecord#
alias of
IterationRecord
- PfArgmaxResults#
alias of
ArgmaxResults
- PfArgmaxBin#
alias of
ArgmaxBin
- class UnsupportedPowerFlowCaseError#
Bases:
ValueErrorRaised when a case contains features not supported by the solver.