Distribution power flow#
GPF solves an OpenDSS circuit in the phase domain when unbalanced voltages, single-phase laterals, delta connections, or explicit neutrals must be retained. The input remains an OpenDSS command file, and the result uses the same GPF report formats as a transmission power flow.
Use a transmission power flow when a balanced positive-sequence representation is sufficient.
GPF implements a strict snapshot subset of OpenDSS. Supported electrical behavior is matched against OpenDSS reference results, and unsupported active behavior is rejected before the solve starts. GPF does not reproduce the OpenDSS interactive environment, API, report commands, dynamics, harmonics, or protection workflows. The exact input boundary is listed in the OpenDSS compatibility reference.
Solve a feeder#
The main command accepts a root .dss file directly:
gpf feeder/Master.dss
gpf solve feeder/Master.dss --full
gpf feeder/Master.dss --json
The first two commands render the phase-domain result with the same terminal
renderer that is used for transmission results. The --json option writes the
versioned result document instead.
The following Python example is executed by the documentation test suite:
import gpf
circuit = gpf.parse_dss("feeder/Master.dss")
solved = gpf.solve_power_flow(circuit)
assert solved.converged
loadbus = [
voltage
for bus, voltage in zip(
solved.bus_names, solved.node_voltage, strict=True
)
if bus.casefold() == "loadbus"
]
print([abs(voltage) for voltage in loadbus])
parse_dss() interprets the complete include tree and returns a DssCircuit.
solve_power_flow() solves the electrical and static-control equations and
returns a PhaseSolvedCase.
Understand the snapshot boundary#
The command interpreter applies New, Edit, More, include, and supported
Set commands in source order. Zero or one Solve command may follow the last
electrical edit. The resulting object state defines one electrical operating
point.
Interactive output commands are recorded and ignored because they do not alter the electrical state. Commands that can alter unsupported electrical behavior are rejected. This rule prevents a successful solve from silently omitting a model that was active in the source circuit.
Source paths in Redirect and Compile commands are resolved relative to the
file that contains the command. File lookup follows OpenDSS case-insensitive
path behavior, and include cycles are rejected.
Understand nodes, terminals, and units#
A physical bus and an electrical node are distinct objects. The source identity
loadbus.2 denotes OpenDSS node 2 at physical bus loadbus. Only nodes that
participate in the electrical model receive solved state. Ground node 0 never
receives a solved voltage.
Each element retains its declared conductor order. A wye element maps conductor voltages to phase-to-neutral voltage, while a delta element maps them to phase-to-phase voltage. Open-delta and missing-phase elements retain only their active conductors.
The phase-domain data plane uses SI units:
Node voltages use volts.
Terminal currents use amperes.
Terminal powers and element losses use volt-amperes.
Impedances use ohms, and admittances use siemens.
GPF converts OpenDSS engineering units to these units. Per-unit quantities are used only where a model or convergence criterion defines an explicit base.
Read a phase result#
PhaseSolvedCase stores one entry in node_voltage for each pair in
bus_names and node_numbers. The following expression selects all active
nodes at one physical bus:
loadbus_voltage = [
voltage
for bus, voltage in zip(
solved.bus_names, solved.node_voltage, strict=True
)
if bus.casefold() == "loadbus"
]
Element results use one flattened conductor array. For element index k, the
half-open slice below selects its ordered conductor results:
start = solved.terminal_offsets[k]
stop = solved.terminal_offsets[k + 1]
current = solved.terminal_currents[start:stop]
power = solved.terminal_powers[start:stop]
loss = solved.element_losses[k]
element_classes[k] and element_names[k] identify the source object.
tap_positions, capacitor_states, and control_actions describe the final
static-control state and the ordered actions that produced it.
Interpret convergence and controls#
Every electrical pass uses a rectangular Newton method with analytic device
derivatives. electrical_iterations reports the iteration count for each
completed pass. maximum_voltage_change reports the final normalized Newton
step measure.
Static controls are reviewed after an electrical solution. A selected action
changes the controlled device, and the electrical equations are solved again.
Therefore, converged and controls_settled report different conditions. A
result can satisfy the electrical equations while a control pass stops at its
iteration limit or detects an oscillation.
The controls option in PhaseSolveOptions holds all supported static controls
at their input state when it is false. max_control_iterations bounds the
control episode independently from max_iterations, which bounds each
electrical solve.
Diagnose rejected circuits#
Compilation rejects a circuit when any of the following conditions is found:
An active command or electrical class has unsupported semantics.
A required object reference or conductor identity is missing.
An impedance or connection matrix has an invalid dimension or is singular.
An electrical island has no voltage source.
An ungrounded common mode has no physical neutral or anti-float behavior.
The rejection identifies the source object and condition. The model should be corrected or reduced explicitly; an undocumented global shunt or model fallback is not added by the solver.
The phase-domain conventions define the common equations. The distribution load models and distribution device models define the supported device behavior.