GridCal.Engine.Simulations.PowerFlow package

Submodules

GridCal.Engine.Simulations.PowerFlow.fast_decoupled_power_flow module

GridCal.Engine.Simulations.PowerFlow.fast_decoupled_power_flow.FDPF(Vbus, Sbus, Ibus, Ybus, B1, B2, pq, pv, pqpv, tol=1e-09, max_it=100)

Fast decoupled power flow Args:

Vbus: Sbus: Ibus: Ybus: B1: B2: pq: pv: pqpv: tol:

Returns:

GridCal.Engine.Simulations.PowerFlow.helm_power_flow module

Method implemented from the article: Online voltage stability assessment for load areas based on the holomorphic embedding method by Chengxi Liu, Bin Wang, Fengkai Hu, Kai Sun and Claus Leth Bak

Implemented by Santiago Peñate Vera 2018 This implementation computes W[n] for all the buses outside the system matrix leading to better results

GridCal.Engine.Simulations.PowerFlow.helm_power_flow.assign_solution(x, bus_idx, pvpos, pv, nbus)

Assign the solution vector to the appropriate coefficients :param x: solution vector :param bus_idx: array from 0..nbus-1 :param nbus2: two times the number of buses (integer) :param pvpos: array from 0..npv :return: Array of:

  • voltage coefficients
  • reactive power

of order n

GridCal.Engine.Simulations.PowerFlow.helm_power_flow.calc_W(n, V, W)

Calculation of the inverse coefficients W. @param n: Order of the coefficients @param V: Structure of voltage coefficients (Ncoeff x nbus elements) @param W: Structure of inverse voltage coefficients (Ncoeff x nbus elements) @return: Array of inverse voltage coefficients for the order n

GridCal.Engine.Simulations.PowerFlow.helm_power_flow.get_rhs(n, V, W, Q, Vbus, Vst, Sbus, Pbus, nsys, nbus2, pv, pq, pvpos)

Right hand side :param n: order of the coefficients :param V: Voltage coefficients (order, all buses) :param W: Inverse voltage coefficients (order, pv buses) :param Q: Reactive power coefficients (order, pv buses) :param Vbus: Initial bus estimate (only used to pick the PV buses set voltage) :param Vst: Start voltage due to slack injections :param Pbus: Active power injections (all the buses) :param nsys: number of rows or cols in the system matrix A :param nbus2: two times the number of buses :param pv: list of pv indices in the grid :param pvpos: array from 0..npv :return: right hand side vector to solve the coefficients of order n

GridCal.Engine.Simulations.PowerFlow.helm_power_flow.helm(Vbus, Sbus, Ybus, pq, pv, ref, pqpv, tol=1e-09, max_coefficient_count=30)

Helm Method :param Vbus: voltages array :param Sbus: Power injections array :param Ibus: Currents injection array :param Ybus: System admittance matrix :param pq: list of pq node indices :param pv: list of pv node indices :param ref: list of slack node indices :param pqpv: list of pq and pv node indices sorted :param tol: tolerance :return: Voltage array and the power mismatch

GridCal.Engine.Simulations.PowerFlow.helm_power_flow.pade_approximation(n, an, s=1)

Computes the n/2 pade approximant of the series an at the approximation point s

Arguments:
an: coefficient matrix, (number of coefficients, number of series) n: order of the series s: point of approximation
Returns:
pade approximation at s
GridCal.Engine.Simulations.PowerFlow.helm_power_flow.prepare_system_matrices(Ybus, Vbus, bus_idx, pqpv, pq, pv, ref)

Prepare the system matrices :param Ybus: :param Vbus: :param pqpv: :param ref: :return:

GridCal.Engine.Simulations.PowerFlow.helm_power_flow.res_2_df(V, Sbus, tpe)

Create dataframe to display the results nicely :param V: Voltage complex vector :param Sbus: Power complex vector :param tpe: Types :return: Pandas DataFrame

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow module

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.ContinuousNR(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=15)

Solves the power flow using a full Newton’s method with the backtrack improvement algorithm Args:

Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations robust: Boolean variable for the use of the Iwamoto optimal step factor.
Returns:
Voltage solution, converged?, error, calculated power injections

@author: Ray Zimmerman (PSERC Cornell) @Author: Santiago Penate Vera

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.F(V, Ybus, S, I, pq, pv)
Parameters:
  • V
  • Ybus
  • S
  • I
  • pq
  • pv
  • pvpq
Returns:

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.IwamotoNR(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=15, robust=False)

Solves the power flow using a full Newton’s method with the Iwamoto optimal step factor. Args:

Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations robust: Boolean variable for the use of the Iwamoto optimal step factor.
Returns:
Voltage solution, converged?, error, calculated power injections

@author: Ray Zimmerman (PSERC Cornell) @Author: Santiago Penate Vera

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.Jacobian(Ybus, V, Ibus, pq, pvpq)

Computes the system Jacobian matrix Args:

Ybus: Admittance matrix V: Array of nodal voltages Ibus: Array of nodal current injections pq: Array with the indices of the PQ buses pvpq: Array with the indices of the PV and PQ buses
Returns:
The system Jacobian matrix
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.Jacobian_I(Ybus, V, pq, pvpq)

Computes the system Jacobian matrix Args:

Ybus: Admittance matrix V: Array of nodal voltages pq: Array with the indices of the PQ buses pvpq: Array with the indices of the PV and PQ buses
Returns:
The system Jacobian matrix in current equations
GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.LevenbergMarquardtPF(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=50)

Solves the power flow problem by the Levenberg-Marquardt power flow algorithm. It is usually better than Newton-Raphson, but it takes an order of magnitude more time to converge. Args:

Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations
Returns:
Voltage solution, converged?, error, calculated power injections

@Author: Santiago Peñate Vera

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.NR_I_LS(Ybus, Sbus_sp, V0, Ibus_sp, pv, pq, tol, max_it=15)

Solves the power flow using a full Newton’s method in current equations with current mismatch with line search Args:

Ybus: Admittance matrix Sbus_sp: Array of nodal specified power injections V0: Array of nodal voltages (initial solution) Ibus_sp: Array of nodal specified current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations
Returns:
Voltage solution, converged?, error, calculated power injections

@Author: Santiago Penate Vera

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.NR_LS(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=15)

Solves the power flow using a full Newton’s method with the backtrack improvement algorithm Args:

Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations robust: Boolean variable for the use of the Iwamoto optimal step factor.
Returns:
Voltage solution, converged?, error, calculated power injections

@author: Ray Zimmerman (PSERC Cornell) @Author: Santiago Penate Vera

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.dSbus_dV(Ybus, V, I)

Computes partial derivatives of power injection w.r.t. voltage. :param Ybus: Admittance matrix :param V: Bus voltages array :param I: Bus current injections array :return:

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.fx(x, Ybus, S, I, pq, pv, pvpq, j1, j2, j3, j4, j5, j6, Va, Vm)
Parameters:
  • x
  • Ybus
  • S
  • I
  • pq
  • pv
  • pvpq
Returns:

GridCal.Engine.Simulations.PowerFlow.jacobian_based_power_flow.mu(Ybus, Ibus, J, incS, dV, dx, pvpq, pq)

Calculate the Iwamoto acceleration parameter as described in: “A Load Flow Calculation Method for Ill-Conditioned Power Systems” by Iwamoto, S. and Tamura, Y.” Args:

Ybus: Admittance matrix J: Jacobian matrix incS: mismatch vector dV: voltage increment (in complex form) dx: solution vector as calculated dx = solve(J, incS) pvpq: array of the pq and pv indices pq: array of the pq indices
Returns:
the Iwamoto’s optimal multiplier for ill conditioned systems

GridCal.Engine.Simulations.PowerFlow.linearized_power_flow module

GridCal.Engine.Simulations.PowerFlow.linearized_power_flow.dcpf(Ybus, Sbus, Ibus, V0, ref, pvpq, pq, pv)

Solves a DC power flow. :param Ybus: Normal circuit admittance matrix :param Sbus: Complex power injections at all the nodes :param Ibus: Complex current injections at all the nodes :param V0: Array of complex seed voltage (it contains the ref voltages) :param ref: array of the indices of the slack nodes :param pvpq: array of the indices of the non-slack nodes :param pq: array of the indices of the pq nodes :param pv: array of the indices of the pv nodes :return:

Complex voltage solution Converged: Always true Solution error Computed power injections given the found solution
GridCal.Engine.Simulations.PowerFlow.linearized_power_flow.lacpf(Y, Ys, S, I, Vset, pq, pv)

Linearized AC Load Flow

form the article:

Linearized AC Load Flow Applied to Analysis in Electric Power Systems
by: P. Rossoni, W. M da Rosa and E. A. Belati
Args:
Y: Admittance matrix Ys: Admittance matrix of the series elements S: Power injections vector of all the nodes Vset: Set voltages of all the nodes (used for the slack and PV nodes) pq: list of indices of the pq nodes pv: list of indices of the pv nodes

Returns: Voltage vector, converged?, error, calculated power and elapsed time

GridCal.Engine.Simulations.PowerFlow.power_flow_driver module

class GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlow(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions)

Bases: PySide2.QtCore.QRunnable

Power flow wrapper to use with Qt

cancel()
get_steps()
run()

Pack run_pf for the QThread :return:

run_pf(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vbus, Sbus, Ibus)

Run a power flow for every circuit @return:

class GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowMP(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions)

Bases: object

Power flow without QT to use with multi processing.

Arguments:

grid (MultiCircuit): Electrical grid to run the power flow in

options (PowerFlowOptions): Power flow options to use

cancel()
static compile_types(Sbus, types=None, logger=[])

Compile the types.

static control_q_direct(V, Vset, Q, Qmax, Qmin, types, original_types, verbose)

Change the buses type in order to control the generators reactive power.

Arguments:

pq (list): array of pq indices

pv (list): array of pq indices

ref (list): array of pq indices

V (list): array of voltages (all buses)

Vset (list): Array of set points (all buses)

Q (list): Array of reactive power (all buses)

types (list): Array of types (all buses)

original_types (list): Types as originally intended (all buses)

verbose (bool): output messages via the console

Returns:

Vnew (list): New voltage values

Qnew (list): New reactive power values

types_new (list): Modified types array

any_control_issue (bool): Was there any control issue?

ON PV-PQ BUS TYPE SWITCHING LOGIC IN POWER FLOW COMPUTATION Jinquan Zhao

  1. Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its lower limit:

    If its voltage magnitude Vi ≥ Viset, then

    it is still a PQ bus at current iteration and set Qi = Qimin .

    If Vi < Viset , then

    compare Qi with the upper and lower limits.

    If Qi ≥ Qimax , then

    it is still a PQ bus but set Qi = Qimax .

    If Qi ≤ Qimin , then

    it is still a PQ bus and set Qi = Qimin .

    If Qimin < Qi < Qi max , then

    it is switched to PV bus, set Vinew = Viset.

  2. Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its upper limit:

    If its voltage magnitude Vi ≤ Viset , then:

    bus i still a PQ bus and set Q i = Q i max.

    If Vi > Viset , then

    Compare between Qi and its upper/lower limits

    If Qi ≥ Qimax , then

    it is still a PQ bus and set Q i = Qimax .

    If Qi ≤ Qimin , then

    it is still a PQ bus but let Qi = Qimin in current iteration.

    If Qimin < Qi < Qimax , then

    it is switched to PV bus and set Vinew = Viset

  3. Bus i is a PV bus in the previous iteration.

    Compare Q i with its upper and lower limits.

    If Qi ≥ Qimax , then

    it is switched to PQ and set Qi = Qimax .

    If Qi ≤ Qimin , then

    it is switched to PQ and set Qi = Qimin .

    If Qi min < Qi < Qimax , then

    it is still a PV bus.

control_q_iterative(V, Vset, Q, Qmax, Qmin, types, original_types, verbose, k)

Change the buses type in order to control the generators reactive power using iterative changes in Q to reach Vset.

Arguments:

V (list): array of voltages (all buses)

Vset (list): Array of set points (all buses)

Q (list): Array of reactive power (all buses)

Qmin (list): Array of minimal reactive power (all buses)

Qmax (list): Array of maximal reactive power (all buses)

types (list): Array of types (all buses)

original_types (list): Types as originally intended (all buses)

verbose (list): output messages via the console

k (float, 30): Steepness factor

Return:

Qnew (list): New reactive power values

types_new (list): Modified types array

any_control_issue (bool): Was there any control issue?

static control_taps_direct(voltage, T, bus_to_regulated_idx, tap_position, tap_module, min_tap, max_tap, tap_inc_reg_up, tap_inc_reg_down, vset, verbose=False)

Change the taps and compute the continuous tap magnitude.

Arguments:

voltage (list): array of bus voltages solution

T (list): array of indices of the “to” buses of each branch

bus_to_regulated_idx (list): array with the indices of the branches that regulate the bus “to”

tap_position (list): array of branch tap positions

tap_module (list): array of branch tap modules

min_tap (list): array of minimum tap positions

max_tap (list): array of maximum tap positions

tap_inc_reg_up (list): array of tap increment when regulating up

tap_inc_reg_down (list): array of tap increment when regulating down

vset (list): array of set voltages to control

Returns:

stable (bool): Is the system stable (i.e.: are controllers stable)?

tap_magnitude (list): Tap module at each bus in per unit

tap_position (list): Tap position at each bus

control_taps_iterative(voltage, T, bus_to_regulated_idx, tap_position, tap_module, min_tap, max_tap, tap_inc_reg_up, tap_inc_reg_down, vset, verbose=False)

Change the taps and compute the continuous tap magnitude.

Arguments:

voltage (list): array of bus voltages solution

T (list): array of indices of the “to” buses of each branch

bus_to_regulated_idx (list): array with the indices of the branches that regulate the bus “to”

tap_position (list): array of branch tap positions

tap_module (list): array of branch tap modules

min_tap (list): array of minimum tap positions

max_tap (list): array of maximum tap positions

tap_inc_reg_up (list): array of tap increment when regulating up

tap_inc_reg_down (list): array of tap increment when regulating down

vset (list): array of set voltages to control

Returns:

stable (bool): Is the system stable (i.e.: are controllers stable)?

tap_magnitude (list): Tap module at each bus in per unit

tap_position (list): Tap position at each bus

static get_q_increment(V1, V2, k)

Logistic function to get the Q increment gain using the difference between the current voltage (V1) and the target voltage (V2).

The gain varies between 0 (at V1 = V2) and inf (at V2 - V1 = inf).

The default steepness factor k was set through trial an error. Other values may be specified as a PowerFlowOptions.

Arguments:

V1 (float): Current voltage

V2 (float): Target voltage

k (float, 30): Steepness factor

Returns:

Q increment gain
static power_flow_post_process(calculation_inputs: GridCal.Engine.Core.calculation_inputs.CalculationInputs, V, only_power=False)

Compute the power flows trough the branches.

Arguments:

calculation_inputs: instance of Circuit

V: Voltage solution array for the circuit buses

only_power: compute only the power injection

Returns:

Sbranch (MVA), Ibranch (p.u.), loading (p.u.), losses (MVA), Sbus(MVA)
run()

Run a power flow for a circuit (wrapper for run_pf).

Returns:

PowerFlowResults instance (self.results)
run_multi_island(numerical_circuit, calculation_inputs, Vbus, Sbus, Ibus)

Power flow execution for optimization purposes.

Arguments:

numerical_circuit:

calculation_inputs:

Vbus:

Sbus:

Ibus:

Returns:

PowerFlowResults instance
run_pf(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vbus, Sbus, Ibus)

Run a power flow for a circuit. In most cases, the run method should be used instead.

Arguments:

circuit (CalculationInputs): CalculationInputs instance

Vbus (list): Initial voltage at each bus in complex per unit

Sbus (list): Power injection at each bus in complex MVA

Ibus (list): Current injection at each bus in complex amperes

Returns:

single_power_flow(circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, solver_type: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.SolverType, voltage_solution, Sbus, Ibus)

Run a power flow simulation for a single circuit using the selected outer loop controls. This method shouldn’t be called directly.

Arguments:

circuit: CalculationInputs instance

solver_type: type of power flow to use first

voltage_solution: vector of initial voltages

Sbus: vector of power injections

Ibus: vector of current injections

Return:

PowerFlowResults instance
static solve(solver_type, V0, Sbus, Ibus, Ybus, Yseries, B1, B2, pq, pv, ref, pqpv, tolerance, max_iter)

Run a power flow simulation using the selected method (no outer loop controls).

solver_type:

V0: Voltage solution vector

Sbus: Power injections vector

Ibus: Current injections vector

Ybus: Admittance matrix

Yseries: Series elements’ Admittance matrix

B1: B’ for the fast decoupled method

B2: B’’ for the fast decoupled method

pq: list of pq nodes

pv: list of pv nodes

ref: list of slack nodes

pqpv: list of pq and pv nodes

tolerance: power error tolerance

max_iter: maximum iterations

Returns:

V0 (Voltage solution), converged (converged?), normF (error in power), Scalc (Computed bus power), iterations, elapsed
static tap_down(tap, min_tap)

Go to the next upper tap position

static tap_up(tap, max_tap)

Go to the next upper tap position

class GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions(solver_type: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.SolverType = <SolverType.NR: 1>, retry_with_other_methods=True, verbose=False, initialize_with_existing_solution=True, tolerance=1e-06, max_iter=25, max_outer_loop_iter=100, control_q=<ReactivePowerControlMode.NoControl: 'NoControl'>, control_taps=<TapsControlMode.NoControl: 'NoControl'>, multi_core=False, dispatch_storage=False, control_p=False, apply_temperature_correction=False, branch_impedance_tolerance_mode=<BranchImpedanceMode.Specified: 0>, q_steepness_factor=30)

Bases: object

Power flow options class; its object is used as an argument for the PowerFlowMP constructor.

Arguments:

solver_type (SolverType, SolverType.NR): Solver type

retry_with_other_methods (bool, True): Use a battery of methods to tackle the problem if the main solver fails

verbose (bool, False): Print additional details in the logger

initialize_with_existing_solution (bool, True): To be detailed

tolerance (float, 1e-6): Solution tolerance for the power flow numerical methods

max_iter (int, 25): Maximum number of iterations for the power flow numerical method

max_outer_loop_iter (int, 100): Maximum number of iterations for the controls outer loop

control_q (ReactivePowerControlMode, ReactivePowerControlMode.NoControl): Control mode for the PV nodes reactive power limits

control_taps (TapsControlMode, TapsControlMode.NoControl): Control mode for the transformer taps equipped with a voltage regulator (as part of the outer loop)

multi_core (bool, False): Use multi-core processing? applicable for time series

dispatch_storage (bool, False): Dispatch storage?

control_p (bool, False): Control active power (optimization dispatch)

apply_temperature_correction (bool, False): Apply the temperature correction to the resistance of the branches?

branch_impedance_tolerance_mode (BranchImpedanceMode, BranchImpedanceMode.Specified): Type of modification of the branches impedance

q_steepness_factor (float, 30): Steepness factor k for the ReactivePowerControlMode iterative control

class GridCal.Engine.Simulations.PowerFlow.power_flow_driver.ReactivePowerControlMode

Bases: enum.Enum

The ReactivePowerControlMode offers 3 modes to control how Generator objects supply reactive power:

NoControl: In this mode, the generators don’t try to regulate the voltage at their bus.

Direct: In this mode, the generators try to regulate the voltage at their bus. GridCal does so by applying the following algorithm in an outer control loop. For grids with numerous generators tied to the same system, for example wind farms, this control method sometimes fails with some generators not trying hard enough*. In this case, the simulation converges but the voltage controlled buses do not reach their target voltage, while their generator(s) haven’t reached their reactive power limit. In this case, the slower Iterative control mode may be used (see below).

ON PV-PQ BUS TYPE SWITCHING LOGIC IN POWER FLOW COMPUTATION Jinquan Zhao

  1. Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its lower limit:

    If its voltage magnitude Vi >= Viset, then

    it is still a PQ bus at current iteration and set Qi = Qimin .

    If Vi < Viset , then

    compare Qi with the upper and lower limits.

    If Qi >= Qimax , then

    it is still a PQ bus but set Qi = Qimax .

    If Qi <= Qimin , then

    it is still a PQ bus and set Qi = Qimin .

    If Qimin < Qi < Qi max , then

    it is switched to PV bus, set Vinew = Viset.

  2. Bus i is a PQ bus in the previous iteration and its reactive power was fixed at its upper limit:

    If its voltage magnitude Vi <= Viset , then:

    bus i still a PQ bus and set Q i = Q i max.

    If Vi > Viset , then

    Compare between Qi and its upper/lower limits

    If Qi >= Qimax , then

    it is still a PQ bus and set Q i = Qimax .

    If Qi <= Qimin , then

    it is still a PQ bus but let Qi = Qimin in current iteration.

    If Qimin < Qi < Qimax , then

    it is switched to PV bus and set Vinew = Viset

  3. Bus i is a PV bus in the previous iteration.

    Compare Q i with its upper and lower limits.

    If Qi >= Qimax , then

    it is switched to PQ and set Qi = Qimax .

    If Qi <= Qimin , then

    it is switched to PQ and set Qi = Qimin .

    If Qi min < Qi < Qimax , then

    it is still a PV bus.

Iterative: As mentioned above, the Direct control mode may not yield satisfying results in some isolated cases. The Direct control mode tries to jump to the final solution in a single or few iterations, but in grids where a significant change in reactive power at one generator has a significant impact on other generators, additional iterations may be required to reach a satisfying solution.

Instead of trying to jump to the final solution, the Iterative mode raises or lowers each generator’s reactive power incrementally. The increment is determined using a logistic function based on the difference between the current bus voltage its target voltage. The steepness factor k of the logistic function was determined through trial and error, with the intent of reducing the number of iterations while avoiding instability. Other values may be specified in PowerFlowOptions.

The Q_{Increment} in per unit is determined by:

Q_{Increment} = 2 * \left[\frac{1}{1 + e^{-k|V_2 - V_1|}}-0.5\right]

Where:

k = 30 (by default)
Direct = 'Direct'
Iterative = 'Iterative'
NoControl = 'NoControl'
class GridCal.Engine.Simulations.PowerFlow.power_flow_driver.SolverType

Bases: enum.Enum

Refer to the Power Flow section for details about the different algorithms supported by GridCal.

AC_OPF = (15,)
CONTINUATION_NR = (9,)
DC = (5,)
DC_OPF = (14,)
DYCORS_OPF = (17,)
FASTDECOUPLED = (12,)
GAUSS = 4
GA_OPF = (18,)
HELM = (6,)
HELMZ = (10,)
IWAMOTO = (8,)
LACPF = (13,)
LM = 11
NELDER_MEAD_OPF = 19
NR = 1
NRFD_BX = 3
NRFD_XB = 2
NRI = (16,)
ZBUS = (7,)
class GridCal.Engine.Simulations.PowerFlow.power_flow_driver.TapsControlMode

Bases: enum.Enum

The TapsControlMode offers 3 modes to control how transformerstap changer regulate voltage on their regulated bus:

NoControl: In this mode, the transformers don’t try to regulate the voltage at their bus.

Direct: In this mode, the transformers try to regulate the voltage at their bus. GridCal does so by jumping straight to the tap that corresponds to the desired transformation ratio, or the highest or lowest tap if the desired ratio is outside of the tap range.

This behavior may fail in certain cases, especially if both the TapControlMode and ReactivePowerControlMode are set to Direct. In this case, the simulation converges but the voltage controlled buses do not reach their target voltage, while their generator(s) haven’t reached their reactive power limit. When this happens, the slower Iterative control mode may be used (see below).

Iterative: As mentioned above, the Direct control mode may not yield satisfying results in some isolated cases. The Direct control mode tries to jump to the final solution in a single or few iterations, but in grids where a significant change of tap at one transformer has a significant impact on other transformers, additional iterations may be required to reach a satisfying solution.

Instead of trying to jump to the final solution, the Iterative mode raises or lowers each transformer’s tap incrementally.

Direct = 'Direct'
Iterative = 'Iterative'
NoControl = 'NoControl'
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.power_flow_worker(t, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, circuit: GridCal.Engine.Core.calculation_inputs.CalculationInputs, Vbus, Sbus, Ibus, return_dict)
Power flow worker to schedule parallel power flows
**t: execution index **options: power flow options **circuit: circuit **Vbus: Voltages to initialize **Sbus: Power injections **Ibus: Current injections **return_dict: parallel module dictionary in wich to return the values
Returns:
GridCal.Engine.Simulations.PowerFlow.power_flow_driver.power_flow_worker_args(args)

Power flow worker to schedule parallel power flows

args -> t, options: PowerFlowOptions, circuit: Circuit, Vbus, Sbus, Ibus, return_dict

**t: execution index **options: power flow options **circuit: circuit **Vbus: Voltages to initialize **Sbus: Power injections **Ibus: Current injections **return_dict: parallel module dictionary in wich to return the values
Returns:

GridCal.Engine.Simulations.PowerFlow.power_flow_results module

class GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults(Sbus=None, voltage=None, Sbranch=None, Ibranch=None, loading=None, losses=None, tap_module=None, flow_direction=None, Vbranch=None, error=None, converged=None, Qpv=None, battery_power_inc=None, inner_it=None, outer_it=None, elapsed=None, methods=None, bus_types=None)

Bases: object

A PowerFlowResults object is create as an attribute of the PowerFlowMP (as PowerFlowMP.results) when the power flow is run. It provides access to the simulation results through its class attributes.

Attributes:

Sbus (list): Power at each bus in complex MVA

voltage (list): Voltage at each bus in complex per unit

Sbranch (list): Power through each branch in complex MVA

Ibranch (list): Current through each branch in complex per unit

loading (list): Loading of each branch in per unit

losses (list): Losses in each branch in complex MVA

tap_module (list): Computed tap module at each branch in per unit

flow_direction (list): Flow direction at each branch

Vbranch (list): Voltage increment at each branch

error (float): Power flow computed error

converged (bool): Did the power flow converge?

Qpv (list): Reactive power at each PV node in per unit

inner_it (int): Number of inner iterations

outer_it (int): Number of outer iterations

elapsed (float): Simulation duration in seconds

methods (list): Power flow methods used

apply_from_island(results, b_idx, br_idx)

Apply results from another island circuit to the circuit results represented here.

Arguments:

results: PowerFlowResults

b_idx: bus original indices

br_idx: branch original indices

check_limits(F, T, Vmax, Vmin, wo=1, wv1=1, wv2=1)

Check the grid violations on the whole circuit

Arguments:

F:

T:

Vmax:

Vmin:

wo:

wv1:

wv2:

Returns:

Summation of the deviations
copy()

Return a copy of this @return:

export_all()

Exports all the results to DataFrames.

Returns:

Bus results, Branch reuslts
get_convergence_report()
get_report_dataframe(island_idx=0)

Get a DataFrame containing the convergence report.

Arguments:

island_idx: (optional) island index

Returns:

DataFrame
initialize(n, m)

Initialize the arrays @param n: number of buses @param m: number of branches @return:

plot(result_type: GridCal.Engine.Simulations.result_types.ResultTypes, ax=None, indices=None, names=None)

Plot the results.

Arguments:

result_type: ResultTypes

ax: matplotlib axis

indices: Indices f the array to plot (indices of the elements)

names: Names of the elements

Returns:

DataFrame

GridCal.Engine.Simulations.PowerFlow.time_Series_input module

class GridCal.Engine.Simulations.PowerFlow.time_Series_input.TimeSeriesInput(s_profile: pandas.core.frame.DataFrame = None, i_profile: pandas.core.frame.DataFrame = None, y_profile: pandas.core.frame.DataFrame = None)

Bases: object

apply_from_island(res, bus_original_idx, branch_original_idx, nbus_full, nbranch_full)
Parameters:
  • res – TimeSeriesInput
  • bus_original_idx
  • branch_original_idx
  • nbus_full
  • nbranch_full
Returns:

compile()

Generate time-consistent arrays @return:

copy()
get_at(t)

Returns the necessary values @param t: time index @return:

get_from_buses(bus_idx)

@param bus_idx: @return:

GridCal.Engine.Simulations.PowerFlow.time_series_driver module

class GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeries(grid: GridCal.Engine.Core.multi_circuit.MultiCircuit, options: GridCal.Engine.Simulations.PowerFlow.power_flow_driver.PowerFlowOptions, use_opf_vals=False, opf_time_series_results=None, start_=0, end_=None)

Bases: PySide2.QtCore.QThread

cancel()

Cancel the simulation

done_signal = <PySide2.QtCore.Signal object>
get_steps()

Get time steps list of strings

progress_signal = <PySide2.QtCore.Signal object>
progress_text = <PySide2.QtCore.Signal object>
run()

Run the time series simulation @return:

run_multi_thread() → GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeriesResults

Run multi thread time series :return: TimeSeriesResults instance

run_single_thread() → GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeriesResults

Run single thread time series :return: TimeSeriesResults instance

staticMetaObject = <PySide2.QtCore.QMetaObject object>
class GridCal.Engine.Simulations.PowerFlow.time_series_driver.TimeSeriesResults(n, m, nt, start, end, time=None)

Bases: GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults

analyze()

Analyze the results @return:

apply_from_island(results, b_idx, br_idx, index, grid_idx)

Apply results from another island circuit to the circuit results represented here @param results: PowerFlowResults @param b_idx: bus original indices @param br_idx: branch original indices @return:

get_results_dict()

Returns a dictionary with the results sorted in a dictionary :return: dictionary of 2D numpy arrays (probably of complex numbers)

static merge_if(df, arr, ind, cols)

@param df: @param arr: @param ind: @param cols: @return:

plot(result_type: GridCal.Engine.Simulations.result_types.ResultTypes, ax=None, indices=None, names=None)

Plot the results :param result_type: :param ax: :param indices: :param names: :return:

save(fname)

Export as pickle

set_at(t, results: GridCal.Engine.Simulations.PowerFlow.power_flow_results.PowerFlowResults)

Set the results at the step t @param t: time index @param results: PowerFlowResults instance