Internal
Power Flow Types
PowerFlowData
Struct and Type Definitions
PowerFlows.ABAPowerFlowData — Type
A type alias for a PowerFlowData struct whose type parameters are configured for the DCPowerFlow method.
PowerFlows.ACPowerFlowData — Type
A type alias for a PowerFlowData struct whose type parameters are configured for the ACPowerFlow method.
PowerFlows.PTDFPowerFlowData — Type
A type alias for a PowerFlowData struct whose type parameters are configured for the PTDFDCPowerFlow method .
PowerFlows.PowerFlowData — Type
PowerFlowData{M <: PNM.PowerNetworkMatrix, N <: Union{PNM.PowerNetworkMatrix, Nothing}}Structure containing all the data required for the evaluation of the power flows and angles, as well as these ones.
All fields starting with bus_ are ordered according to bus_lookup, and all fields starting with arc_ are ordered according to arc_lookup: one row per bus/arc, one column per time period. Here, buses should be understood as "buses remaining, after the network reduction." Similarly, we use "arcs" instead of "branches" to distinguish between network elements (post-reduction) and system objects (pre-reduction).
Generally, do not construct this directly. Instead, use one of the later constructors to pass in a PowerFlowEvaluationModel and a PowerSystems.System. aux\_network\_matrix and power\_network\_matrix will then be set to the appropriate matrices that are needed for computing that type of powerflow. See also ACPowerFlowData, ABAPowerFlowData, PTDFPowerFlowData, and vPTDFPowerFlowData: these are all aliases for PowerFlowData{N, M} with specific N,M, that are used for the respective type of power flow evaluations.
Fields:
bus_activepower_injection::Matrix{Float64}: matrix containing the bus active power injection.bus_reactivepower_injection::Matrix{Float64}: matrix containing the bus reactive power injection.bus_activepower_withdrawals::Matrix{Float64}: matrix containing the bus reactive power withdrawals.bus_reactivepower_withdrawals::Matrix{Float64}: matrix containing the bus reactive power withdrawals.bus_activepower_constant_current_withdrawals::Matrix{Float64}: matrix containing the bus active power constant current withdrawals.bus_reactivepower_constant_current_withdrawals::Matrix{Float64}: matrix containing the bus reactive power constant current withdrawals.bus_activepower_constant_impedance_withdrawals::Matrix{Float64}: matrix containing the bus active power constant impedance withdrawals.bus_reactivepower_constant_impedance_withdrawals::Matrix{Float64}: matrix containing the bus reactive power constant impedance withdrawals.bus_reactivepower_bounds::Matrix{Float64}: matrix containing upper and lower bounds for the reactive supply at each bus at each time period.bus_type::Matrix{PSY.ACBusTypes}: matrix containing type of buses present in the system.bus_magnitude::Matrix{Float64}: matrix containing the bus voltage magnitudes.bus_angles::Matrix{Float64}: matrix containing the bus voltage angles.arc_activepower_flow_from_to::Matrix{Float64}: matrix containing the active power flows measured at thefrombus.arc_reactivepower_flow_from_to::Matrix{Float64}: matrix containing the reactive power flows measured at thefrombus.arc_activepower_flow_to_from::Matrix{Float64}: matrix containing the active power flows measured at thetobus.arc_reactivepower_flow_to_from::Matrix{Float64}: matrix containing the reactive power flows measured at thetobus.generic_hvdc_flows::Dict{Tuple{Int, Int}, Tuple{Float64, Float64}}: dictionary mapping each generic HVDC line (represented as a tuple of the from and to bus numbers) to a tuple of(P_from_to, P_to_from)active power flows.bus_hvdc_net_power::Matrix{Float64}: "(b, t)" matrix containing the net power injection from all HVDC lines at each bus. b: number of buses, t: number of time period. Only contains HVDCs handled as separate injection/withdrawal pairs: LCCs and generic for DC, or just generic for AC.timestep_map::Dict{Int, S}: dictionary mapping the number of the time periods (corresponding to the column number of the previously mentioned matrices) and their names.power_network_matrix::M: matrix used for the evaluation of either the power flows or bus angles, depending on the method considered.aux_network_matrix::N: matrix used for the evaluation of either the power flows or bus angles, depending on the method considered.neighbors::Vector{Set{Int}}: Vector with the sets of adjacent buses.
PowerFlows.PowerFlowData — Method
PowerFlowData(
pf::ACPowerFlow{<:ACPowerFlowSolverType},
sys::PSY.System;
time_steps::Int = 1,
timestep_names::Vector{String} = String[],
check_connectivity::Bool = true
) -> ACPowerFlowData{<:ACPowerFlowSolverType}Creates the structure for an AC power flow calculation, given the System sys, the number of time periods to consider, and their names.
Calling this function will not evaluate the power flows and angles. Note that first input is of type ACPowerFlow: this version is used to solve AC powerflows, and returns an ACPowerFlowData object.
Arguments:
pf::ACPowerFlow: the settings for the AC power flow solver.sys::PSY.System: ASystemobject that represents the power grid under consideration.time_steps::Int: number of time periods to consider in thePowerFlowDatastructure. It defines the number of columns of the matrices used to store data. Default value =1.timestep_names::Vector{String}: names of the time periods defined by the argumenttime_steps. Default value =String[].check_connectivity::Bool: Perform connectivity check on the network matrix. Default value =true.
WARNING: functions for the evaluation of the multi-period AC PF still to be implemented.
PowerFlows.PowerFlowData — Method
PowerFlowData(
::DCPowerFlow,
sys::PSY.System;
time_steps::Int = 1,
timestep_names::Vector{String} = String[],
check_connectivity::Bool = true
) -> ABAPowerFlowDataCreates a PowerFlowData structure configured for a stnadard DC power flow calculation, given the System sys, the number of time periods to consider, and their names.
Calling this function will not evaluate the power flows and angles. Note that first input is of type DCPowerFlow: this version is used to solve DC powerflows, and returns an ABAPowerFlowData object.
Arguments:
::DCPowerFlow: Run a DC powerflow: internally, store the ABA matrix aspower_network_matrixand the BA matrix asaux_network_matrix.sys::PSY.System: ASystemobject that represents the power grid under consideration.time_steps::Int: number of time periods to consider in thePowerFlowDatastructure. It defines the number of columns of the matrices used to store data. Default value =1.timestep_names::Vector{String}: names of the time periods defined by the argumenttime_steps. Default value =String[].check_connectivity::Bool: Perform connectivity check on the network matrix. Default value =true.
PowerFlows.PowerFlowData — Method
function PowerFlowData(
::PTDFDCPowerFlow,
sys::PSY.System;
time_steps::Int = 1,
timestep_names::Vector{String} = String[]
) -> PTDFPowerFlowDataCreates a PowerFlowData structure configured for a Partial Transfer Distribution Factor Matrix DC power flow calculation, given the System sys, the number of time periods to consider, and their names.
Calling this function will not evaluate the power flows and angles. Note that first input is of type PTDFDCPowerFlow: this version is used to solve DC powerflows via the Power Transfer Distribution Factor (PTDF) matrix. This function returns an PTDFPowerFlowData object.
Arguments:
::PTDFDCPowerFlow: Run a DC powerflow with PTDF matrix: internally, store the PTDF matrix aspower_network_matrixand the ABA matrix asaux_network_matrix.sys::PSY.System: ASystemobject that represents the power grid under consideration.time_steps::Int: number of time periods to consider in thePowerFlowDatastructure. It defines the number of columns of the matrices used to store data. Default value =1.timestep_names::Vector{String}: names of the time periods defined by the argumenttime_steps. Default value =String[].
PowerFlows.PowerFlowData — Method
function PowerFlowData(
::vPTDFDCPowerFlow,
sys::PSY.System;
time_steps::Int = 1,
timestep_names::Vector{String} = String[]
) -> vPTDFPowerFlowDataCreates a PowerFlowData structure configured for a virtual Partial Transfer Distribution Factor Matrix DC power flow calculation, given the System sys, the number of time periods to consider, and their names.
Calling this function will not evaluate the power flows and angles. Note that first input is of type vPTDFDCPowerFlow: this version is used to solve DC powerflows using a virtual Power Transfer Distribution Factor (PTDF) matrix. This function returns a vPTDFPowerFlowData object.
For internal usage: generally, do not construct this directly.
Arguments:
::PTDFDCPowerFlow: Run a virtual PTDF powerflow: internally, store the virtual PTDF matrixpower_network_matrixand the ABA matrix asaux_network_matrix.sys::PSY.System: ASystemobject that represents the power grid under consideration.time_steps::Int: number of time periods to consider in the PowerFlowData structure. It defines the number of columns of the matrices used to store data. Default value =1.timestep_names::Vector{String}: names of the time periods defined by the argument "time_steps". Default value =String[].
PowerFlows.PowerFlowData — Method
Sets the two PowerNetworkMatrix fields and a few others (timesteps, timestep_map), then creates arrays of default values (usually zeros) for the rest.
PowerFlows.SystemPowerFlowContainer — Type
A PowerFlowContainer that represents its data as a PSY.System.
PowerFlows.vPTDFPowerFlowData — Type
A type alias for a PowerFlowData struct whose type parameters are configured for the vPTDFDCPowerFlow method.
PowerFlows.make_power_flow_container — Function
Create an appropriate PowerFlowContainer for the given PowerFlowEvaluationModel and initialize it from the given PSY.System.
Arguments:
pfem::PowerFlowEvaluationModel: power flow model to construct a container for (e.g.,DCPowerFlow())sys::PSY.System: the System from which to initialize the power flow containertime_steps::Int: number of time periods to consider (default is1)timestep_names::Vector{String}: names of the time periods defines by the argument "time_steps". Default value isString[].
PowerFlows.supports_multi_period — Method
Trait signifying whether the PowerFlowContainer can represent multi-period data. Must be implemented for all concrete subtypes.
Solving a PowerFlowData instance
PowerFlows.solve_powerflow! — Method
solve_powerflow!(data::ACPowerFlowData; pf::ACPowerFlow{<:ACPowerFlowSolverType} = ACPowerFlow(), kwargs...)Solve the multiperiod AC power flow problem for the given power flow data.
The bus types can be changed from PV to PQ if the reactive power limits are violated.
Arguments
data::ACPowerFlowData: The power flow data containing the grid information and initial conditions.pf::ACPowerFlow{<:ACPowerFlowSolverType}: The power flow solver type. Defaults toNewtonRaphsonACPowerFlow.kwargs...: Additional keyword arguments.
Keyword Arguments
time_steps: Specifies the time steps to solve. Defaults to sorting and collecting the keys ofdata.timestep_map.
Description
This function solves the AC power flow problem for each time step specified in data. It preallocates memory for the results and iterates over the sorted time steps. For each time step, it calls the _ac_powerflow function to solve the power flow equations and updates the data object with the results. If the power flow converges, it updates the active and reactive power injections, as well as the voltage magnitudes and angles for different bus types (REF, PV, PQ). If the power flow does not converge, it sets the corresponding entries in data to NaN. Finally, it calculates the branch power flows and updates the data object.
Notes
- If the grid topology changes (e.g., tap positions of transformers or in-service status of branches), the admittance matrices
YftandYtfmust be updated. - If
YftandYtfchange between time steps, the branch flow calculations must be moved inside the loop.
Examples
solve_powerflow!(data)PowerFlows.adjust_power_injection_for_lccs! — Method
Adjust the power injection vector to account for the power flows through LCCs.
Relies on the fact that we calculate those flows during initialization and save them to the active_powerflow_from_to and active_powerflow_to_from fields of the LCCParameters struct.
PowerFlows.solve_powerflow! — Method
solve_powerflow!(data::vPTDFPowerFlowData)Evaluates the virtual PTDF power flow and writes the results to the fields of the vPTDFPowerFlowData structure.
This function modifies the following fields of data, setting them to the computed values:
data.bus_angles: the bus angles for each bus in the system.data.branch_activepower_flow_from_to: the active power flow from the "from" bus to the "to" bus of each branchdata.branch_activepower_flow_to_from: the active power flow from the "to" bus to the "from" bus of each branch
Additionally, it sets data.converged to true, indicating that the power flow calculation was successful.
PowerFlows.solve_powerflow! — Method
solve_powerflow!(data::PTDFPowerFlowData)Evaluates the PTDF power flow and writes the result to the fields of the PTDFPowerFlowData structure.
This function modifies the following fields of data, setting them to the computed values:
data.bus_angles: the bus angles for each bus in the system.data.branch_activepower_flow_from_to: the active power flow from the "from" bus to the "to" bus of each branchdata.branch_activepower_flow_to_from: the active power flow from the "to" bus to the "from" bus of each branch
Additionally, it sets data.converged to true, indicating that the power flow calculation was successful.
Manipulating a PowerFlowData instance
PowerFlows.partition_state — Method
Partitions the state vector's variables based on what physical quantity each represents. Returns a NamedTuple, with the 4 keys Va, Vm, P, and Q. The 4 values are vectors of length equal to the number of buses, with NaNs in the positions where that physical quantity is not part of the state vector for that bus. (Currently not intended for use in spots where performance is critical.)
PowerFlows.update_data! — Method
Update the fields of data based on the values of the state vector.
PowerFlows.update_net_power! — Method
Update P_net and Q_net based on the values of the state vector.
PowerFlows.update_state! — Method
Update state vector based on values of fields of data.
PowerFlows.initialize_powerflow_data! — Method
Sets the fields of a PowerFlowData struct to match the given System.
PowerFlows._dc_powerflow_fallback! — Method
When solving AC power flows, if the initial guess has large residual, we run a DC power flow as a fallback. This runs a DC powerflow on data::ACPowerFlowData for the given time_step, and writes the solution to data.bus_angles.
PowerFlows.calculate_x0 — Method
Calculate x0 from data.
PowerFlows.dc_powerflow_start! — Method
If initial residual is large, run a DC power flow and see if that gives a better starting point for angles. If so, then overwrite x0 with the result of the DC power flow. If not, keep the original x0.
LCC HVDC Parameters and Utilities
PowerFlows._calculate_dQ_dV_lcc — Method
_calculate_dQ_dV_lcc(t::Float64, I_dc::Float64, x_t::Float64, Vm::Float64, ϕ::Float64) -> Float64Compute the derivative of reactive power Q with respect to voltage magnitude Vm for LCC converter calculations.
PowerFlows._calculate_dQ_dt_lcc — Method
_calculate_dQ_dt_lcc(t::Float64, I_dc::Float64, x_t::Float64, Vm::Float64, ϕ::Float64) -> Float64Compute the derivative of reactive power Q with respect to transformer tap t for LCC converter calculations.
PowerFlows._calculate_dQ_dα_lcc — Method
_calculate_dQ_dα_lcc(t::Float64, I_dc::Float64, x_t::Float64, Vm::Float64, ϕ::Float64, α::Float64) -> Float64Compute the derivative of reactive power Q with respect to firing/extinction angle α for LCC converter calculations.
PowerFlows._calculate_y_lcc — Method
_calculate_y_lcc(t::Float64, I_dc::Float64, Vm::Float64, ϕ::Float64) -> ComplexF64Compute the admittance value Y for LCC converter calculations.
PowerFlows._calculate_ϕ_lcc — Method
_calculate_ϕ_lcc(α::Float64, I_dc::Float64, x_t::Float64, Vm::Float64) -> Float64Compute the phase angle ϕ for LCC converter calculations.
PowerFlows.hvdc_fixed_injections! — Method
Adjust the power injection/withdrawal vectors to account for all HVDC lines of a given type, modeling those HVDC lines as a simple fixed injection/withdrawal at each terminal.
PowerFlows.initialize_LCC_arcs_and_buses! — Method
Initialize the arcs and bus_indices fields of the LCCParameters structure in the PowerFlowData.
AC Power Flow
Residuals
PowerFlows.ACPowerFlowResidual — Type
struct ACPowerFlowResidualA struct to keep track of the residuals in the Newton-Raphson AC power flow calculation.
Fields
data::ACPowerFlowData: The grid model data.Rf!::Function: A function that updates the residuals based on the latest values stored in the grid at the given iteration.Rv::Vector{Float64}: A vector of the values of the residuals.P_net::Vector{Float64}: A vector of net active power injections.Q_net::Vector{Float64}: A vector of net reactive power injections.P_net_set::Vector{Float64}: A vector of the set-points for active power injections (their initial values before power flow calculation).bus_slack_participation_factors::SparseVector{Float64, Int}: A sparse vector of the slack participation factors aggregated at the bus level.subnetworks::Dict{Int64, Vector{Int64}}: The dictionary that identifies subnetworks (connected components), with the key defining the REF bus, values defining the corresponding buses in the subnetwork.
PowerFlows.ACPowerFlowResidual — Method
ACPowerFlowResidual(data::ACPowerFlowData, time_step::Int64)Create an instance of ACPowerFlowResidual for a given time step.
Arguments
data::ACPowerFlowData: The power flow data representing the power system model.time_step::Int64: The time step for which the power flow calculation is executed.
Returns
ACPowerFlowResidual: An instance containing the residual values, net bus active power injections, and net bus reactive power injections.
PowerFlows.ACPowerFlowResidual — Method
(Residual::ACPowerFlowResidual)(x::Vector{Float64}, time_step::Int64)Update the AC power flow residuals inplace and store the result in the attribute Rv of the struct. The inputs are the values of state vector x and the current time step time_step. This function implements the functor approach for the ACPowerFlowResidual struct. This makes the struct callable. Calling the ACPowerFlowResidual will also update the values of P, Q, V, Θ in the data struct.
Arguments
x::Vector{Float64}: The state vector values.time_step::Int64: The current time step.
PowerFlows.ACPowerFlowResidual — Method
(Residual::ACPowerFlowResidual)(Rv::Vector{Float64}, x::Vector{Float64}, time_step::Int64)Evaluate the AC power flow residuals and store the result in Rv using the provided state vector x and the current time step time_step. The residuals are updated inplace in the struct and additionally copied to the provided array. This function implements the functor approach for the ACPowerFlowResidual struct. This makes the struct callable. Calling the ACPowerFlowResidual will also update the values of P, Q, V, Θ in the data struct.
Arguments
Rv::Vector{Float64}: The vector to store the calculated residuals.x::Vector{Float64}: The state vector.time_step::Int64: The current time step.
PowerFlows._update_residual_values! — Method
_update_residual_values!(
F::Vector{Float64},
x::Vector{Float64},
P_net::Vector{Float64},
Q_net::Vector{Float64},
data::ACPowerFlowData,
time_step::Int64,
)Update the residual values for the Newton-Raphson AC power flow calculation. This function is used internally in the ACPowerFlowResidual struct. This function also updates the values of P, Q, V, Θ in the data struct.
Arguments
F::Vector{Float64}: Vector of the values of the residuals.x::Vector{Float64}: State vector values.P_net::Vector{Float64}: Vector of net active power injections at each bus.Q_net::Vector{Float64}: Vector of net reactive power injections at each bus.P_net_set::Vector{Float64}: Vector of the set-points for active power injections (their initial values before power flow calculation).bus_slack_participation_factors::SparseVector{Float64, Int}: Sparse vector of the slack participation factors aggregated at the bus level.ref_bus::Int: The index of the reference bus to be used for the total slack power.data::ACPowerFlowData: Data structure representing the grid model for the AC power flow calculation.time_step::Int64: The current time step for which the residual values are being updated.
Jacobian
PowerFlows.ACPowerFlowJacobian — Type
struct ACPowerFlowJacobianA struct that represents the Jacobian matrix for AC power flow calculations.
This struct uses the functor pattern, meaning instances of ACPowerFlowJacobian store the data (Jacobian matrix) internally and can be called as a function at the same time. Calling the instance as a function updates the stored Jacobian matrix.
Fields
data::ACPowerFlowData: The grid model data used for power flow calculations.Jf!::Function: A function that calculates the Jacobian matrix inplace.Jv::SparseArrays.SparseMatrixCSC{Float64, Int32}: The Jacobian matrix, which is updated by the functionJf!.
PowerFlows.ACPowerFlowJacobian — Method
(J::ACPowerFlowJacobian)(time_step::Int64)Update the Jacobian matrix Jv using the function Jf! and the provided data and time step.
Defining this method allows an instance of ACPowerFlowJacobian to be called as a function, following the functor pattern.
Arguments
time_step::Int64: The time step for the calculations.
Example
J = ACPowerFlowJacobian(data, time_step)
J(time_step) # Updates the Jacobian matrix JvPowerFlows.ACPowerFlowJacobian — Method
ACPowerFlowJacobian(data::ACPowerFlowData, time_step::Int64) -> ACPowerFlowJacobianThis is the constructor for ACPowerFlowJacobian. Create an ACPowerFlowJacobian instance. As soon as the instance is created, it already has the Jacobian matrix structure initialized and its values updated, stored internally as Jv. The data instance is stored internally and used to update the Jacobian matrix because the structure of the Jacobian matrix is tied to the data. Changing the data requires creating a new instance of ACPowerFlowJacobian.
Arguments
data::ACPowerFlowData: The data used for power flow calculations.time_step::Int64: The time step for the calculations.
Returns
ACPowerFlowJacobian: An instance ofACPowerFlowJacobian.
Example
J = ACPowerFlowJacobian(data, time_step) # Creates an instance J of ACPowerFlowJacobian, with the Jacobian matrix stored internally as J.Jv initialized and updated.
J(time_step) # Updates the Jacobian matrix stored internally in J (J.Jv) with the latest state of the `data` (`ACPowerFlowData` instance) and the provided time step.
J.Jv # Access the Jacobian matrix stored internally in J.PowerFlows.ACPowerFlowJacobian — Method
(J::ACPowerFlowJacobian)(J::SparseArrays.SparseMatrixCSC{Float64, Int32}, time_step::Int64)Use the ACPowerFlowJacobian to update the provided Jacobian matrix J inplace.
Update the internally stored Jacobian matrix Jv using the function Jf! and the provided data and time step, and write the updated Jacobian values to J.
This method allows an instance of ACPowerFlowJacobian to be called as a function, following the functor pattern.
Arguments
J::SparseArrays.SparseMatrixCSC{Float64, Int32}`: A sparse matrix to be updated with new values of the Jacobian matrix.time_step::Int64: The time step for the calculations.
Example
J = ACPowerFlowJacobian(data, time_step)
Jv = SparseArrays.sparse(Float64[], Int32[], Int32[])
J(Jv, time_step) # Updates the Jacobian matrix Jv and writes it to JPowerFlows._block_J_indices — Method
_block_J_indices(data::ACPowerFlowData, time_step::Int) -> (Vector{Int32}, Vector{Int32})Get the indices to reindex the Jacobian matrix from the interleaved form to the block form:
\[\begin{bmatrix} \frac{\partial P}{\partial \theta} & \frac{\partial P}{\partial V} \\ \frac{\partial Q}{\partial \theta} & \frac{\partial Q}{\partial V} \end{bmatrix}\]
Arguments
pvpq::Vector{Int32}: Indices of the buses that are PV or PQ buses.pq::Vector{Int32}: Indices of the buses that are PQ buses.
Returns
rows::Vector{Int32}: Row indices for the block Jacobian matrix.cols::Vector{Int32}: Column indices for the block Jacobian matrix.
PowerFlows._calculate_loss_factors — Method
calculate_loss_factors(data::ACPowerFlowData, Jv::SparseMatrixCSC{Float64, Int32}, time_step::Int)Calculate and store the active power loss factors in the loss_factors matrix of the ACPowerFlowData structure for a given time step.
The loss factors are computed using the Jacobian matrix Jv and the vector dSbus_dV_ref, which contains the partial derivatives of slack power with respect to bus voltages. The function interprets changes in slack active power injection as indicative of changes in grid active power losses. KLU is used to factorize the sparse Jacobian matrix to solve for the loss factors.
Arguments
data::ACPowerFlowData: The data structure containing power flow information, including theloss_factorsmatrix.Jv::SparseMatrixCSC{Float64, Int32}: The sparse Jacobian matrix of the power flow system.time_step::Int: The time step index for which the loss factors are calculated.
PowerFlows._calculate_voltage_stability_factors — Method
calculate_voltage_stability_factors(data::ACPowerFlowData, J::ACPowerFlowJacobian, time_step::Integer)Calculate and store the voltage stability factors in the voltage_stability_factors matrix of the ACPowerFlowData structure for a given time step. The voltage stability factors are computed using the Jacobian matrix J in block format after a converged power flow calculation. The results are stored in the voltage_stability_factors matrix in the data instance. The factor for the grid as a whole (σ) is stored in the position of the REF bus. The values of the singular vector v indicate the sensitivity of the buses and are stored in the positions of the PQ buses. The values of v for PV buses are set to zero. The function uses the method described in "Fast calculation of a voltage stability index" by PA Lof et. al.
Arguments
data::ACPowerFlowData: The instance containing the grid model data.J::ACPowerFlowJacobian: The Jacobian matrix cache.time_step::Integer: The calculated time step.
PowerFlows._create_jacobian_matrix_structure — Method
_create_jacobian_matrix_structure(data::ACPowerFlowData, time_step::Int64) -> SparseMatrixCSC{Float64, Int32}Create the structure of the Jacobian matrix for an AC power flow problem.
Arguments
data::ACPowerFlowData: The power flow model.time_step::Int64: The specific time step for which the Jacobian matrix structure is created.
Returns
SparseMatrixCSC{Float64, Int32}: A sparse matrix with structural zeros representing the structure of the Jacobian matrix.
Description
This function initializes the structure of the Jacobian matrix for an AC power flow problem. The Jacobian matrix is used in power flow analysis to represent the partial derivatives of bus active and reactive power injections with respect to bus voltage magnitudes and angles.
Unlike some commonly used approaches where the Jacobian matrix is constructed as four submatrices, each grouping values for the four types of partial derivatives, this function groups the partial derivatives by bus. The structure is organized as groups of 4 values per bus.
This approach is more memory-efficient. Furthermore, this structure results in a more efficient factorization because the values are more likely to be grouped close to the diagonal. Refer to Electric Energy Systems: Analysis and Operation by Antonio Gomez-Exposito and Fernando L. Alvarado for more details.
The function initializes three arrays (rows, columns, and values) to store the row indices, column indices, and values of the non-zero elements of the Jacobian matrix, respectively.
For each bus in the system, the function iterates over its neighboring buses and determines the type of each neighboring bus (REF, PV, or PQ). Depending on the bus type, the function adds the appropriate entries to the Jacobian matrix structure.
- For
REFbuses, entries are added for local active and reactive power. - For
PVbuses, entries are added for active and reactive power with respect to angle, and for local reactive power. - For
PQbuses, entries are added for active and reactive power with respect to voltage magnitude and angle.
Example Structure
For a system with 3 buses where bus 1 is REF, bus 2 is PV, and bus 3 is PQ:
Let $\Delta P_j$, $\Delta Q_j$ be the active, reactive power balance at the $j$th bus. Let $P_j$ and $Q_j$ be the active and reactive power generated at the $j$th bus (REF and PV only). The state vector is $x = [P_1, Q_1, Q_2, \theta_2, V_3, \theta_3]$, and the residual vector is $F(x) = [\Delta P_1, \Delta Q_1, \Delta P_2, \Delta Q_2, \Delta P_3, \Delta Q_3]$.
The Jacobian matrix $J = \nabla F(x)$ has the structure:
\[J = \begin{bmatrix} \frac{\partial \vec{F}}{\partial P_1} & \frac{\partial \vec{F}}{\partial Q_1} & \frac{\partial \vec{F}}{\partial Q_2} & \frac{\partial \vec{F}}{\partial \theta_2} & \frac{\partial \vec{F}}{\partial V_3} & \frac{\partial \vec{F}}{\partial \theta_3} \end{bmatrix}\]
In reality, for large networks, this matrix would be sparse, and each 2×2 block would only be nonzero when there's a line between the respective buses.
Finally, the function constructs a sparse matrix from the collected indices and values and returns it.
PowerFlows._create_jacobian_matrix_structure_bus! — Method
Create the Jacobian matrix structure for a PV bus. Currently unused: we fill all four values even for PV buses with structiural zeros using the same function as for PQ buses.
PowerFlows._create_jacobian_matrix_structure_bus! — Method
Create the Jacobian matrix structure for a reference bus (REF). Currently unused: we fill all four values even for PV buses with structiural zeros using the same function as for PQ buses.
PowerFlows._create_jacobian_matrix_structure_bus! — Method
Create the Jacobian matrix structure for a PQ bus. Using this for all buses because a) for REF buses it doesn't matter if there are 2 values or 4 values - there are not many of them in the grid b) for PV buses we fill all four values because we can have a PV -> PQ transition and then we need to fill all four values
PowerFlows._create_jacobian_matrix_structure_lcc — Method
_create_jacobian_matrix_structure_lcc(
data::ACPowerFlowData,
rows::Vector{Int32},
columns::Vector{Int32},
values::Vector{Float64},
num_buses::Int
)Create the Jacobian matrix structure for LCC HVDC systems.
Description
The function iterates over each LCC system and adds the non-zero entries to the Jacobian matrix structure. The state vector for every LCC contains 4 variables: tap position and thyristor angle for both the rectifier and inverter sides. The indices of non-zero entries correspond to the positions of these variables in the extended state vector.
For an LCC system connecting bus $i$ (rectifier side) and bus $j$ (inverter side), the state variables are:
- $t_i$: tap position at rectifier
- $t_j$: tap position at inverter
- $\alpha_i$: thyristor angle at rectifier
- $\alpha_j$: thyristor angle at inverter
The residuals include:
- $F_{t_i}$: Active power balance at rectifier (controls $P_i$ to match setpoint)
- $F_{t_j}$: Total active power balance across LCC system
- $F_{\alpha_i}$: Rectifier thyristor angle constraint (maintains $\alpha_i$ at minimum)
- $F_{\alpha_j}$: Inverter thyristor angle constraint (maintains $\alpha_j$ at minimum)
Example Structure
For a system with 2 buses connected by one LCC where bus 1 is the rectifier side and bus 2 is the inverter side, the Jacobian matrix would have non-zero entries at positions like:
\[\begin{array}{c|cccccccc} & V_1 & \delta_1 & V_2 & \delta_2 & t_1 & t_2 & \alpha_1 & \alpha_2 \\ \hline P_1 & \frac{\partial P_1}{\partial V_1} & & & & \frac{\partial P_1}{\partial t_1} & & \frac{\partial P_1}{\partial \alpha_1} & \\ Q_1 & \frac{\partial Q_1}{\partial V_1} & & & & \frac{\partial Q_1}{\partial t_1} & & \frac{\partial Q_1}{\partial \alpha_1} & \\ P_2 & & & & & & & & \\ Q_2 & & & & & & & & \\ F_{t_1} & \frac{\partial F_{t_1}}{\partial V_1} & & & & \frac{\partial F_{t_1}}{\partial t_1} & & \frac{\partial F_{t_1}}{\partial \alpha_1} & \\ F_{t_2} & \frac{\partial F_{t_2}}{\partial V_1} & & \frac{\partial F_{t_2}}{\partial V_2} & & \frac{\partial F_{t_2}}{\partial t_1} & \frac{\partial F_{t_2}}{\partial t_2} & \frac{\partial F_{t_2}}{\partial \alpha_1} & \frac{\partial F_{t_2}}{\partial \alpha_2} \\ F_{\alpha_1} & & & & & & & \frac{\partial F_{\alpha_1}}{\partial \alpha_1} & \\ F_{\alpha_2} & & & & & & & & \frac{\partial F_{\alpha_2}}{\partial \alpha_2} \end{array}\]
This function sets up the indices of these non-zero entries in the sparse Jacobian matrix structure.
Arguments
data::ACPowerFlowData: The power flow data containing LCC system information.rows::Vector{Int32}: Vector to store row indices of non-zero Jacobian entries.columns::Vector{Int32}: Vector to store column indices of non-zero Jacobian entries.values::Vector{Float64}: Vector to store initial values of non-zero Jacobian entries.num_buses::Int: Total number of buses in the system.
PowerFlows._singular_value_decomposition — Method
_singular_value_decomposition(J::SparseMatrixCSC{Float64, Int32}, npvpq::Integer; tol::Float64 = 1e-9, max_iter::Integer = 100,)Estimate the smallest singular value σ and corresponding left and right singular vectors u and v of a sparse matrix G_s (a sub-matrix of J). This function uses an iterative method involving LU factorization of the Jacobian matrix to estimate the smallest singular value of G_s. The algorithm alternates between updating u and v, normalizing, and checking for convergence based on the change in the estimated singular value σ. The function uses the method described in Algorithm 3 of "Fast calculation of a voltage stability index" by PA Lof et. al.
Arguments
J::SparseMatrixCSC{Float64, Int32}: The sparse block-form Jacobian matrix.npvpq::Integer: Number of PV and PQ buses in J.
Keyword Arguments
tol::Float64=1e-9: Convergence tolerance for the iterative algorithm.max_iter::Integer=100: Maximum number of iterations.
Returns
σ::Float64: The estimated smallest singular value.left::Vector{Float64}: The estimated left singular vector (referred to asuin the cited paper).right::Vector{Float64}: The estimated right singular vector (referred to asvin the cited paper).
PowerFlows._update_jacobian_matrix_values! — Method
Used to update Jv based on the bus voltages, angles, etc. in data.
Iterative Methods
PowerFlows.StateVectorCache — Type
Cache for non-linear methods.
Fields
x::Vector{Float64}: the current state vector.r::Vector{Float64}: the current residual.Δx_nr::Vector{Float64}: the step under the Newton-Raphson method.
The remainder of the fields are only used in the TrustRegionACPowerFlow:
r_predict::Vector{Float64}: the predicted residual atx+Δx_proposed, under a linear approximation: i.eJ_x⋅(x+Δx_proposed).Δx_proposed::Vector{Float64}: the suggested stepΔx, selected amongΔx_nr,Δx_cauchy, and the dogleg interpolation between the two. The first is chosen whenx+Δx_nris inside the trust region, the second when bothx+Δx_cauchyandx+Δx_nrare outside the trust region, and the third whenx+Δx_cauchyis inside andx+Δx_nroutside. The dogleg step selects the point where the line fromx+Δx_cauchytox+Δx_nrcrosses the boundary of the trust region.Δx_cauchy::Vector{Float64}: the step to the Cauchy point if the Cauchy point lies within the trust region, otherwise a step in that direction.
PowerFlows._do_refinement! — Method
Check error and do refinement.
PowerFlows._dogleg! — Method
Sets Δx_proposed equal to the Δx by which we should update x. Decides between the Cauchy step Δx_cauchy, Newton-Raphson step Δx_nr, and the dogleg interpolation between the two, based on which fall within the trust region.
PowerFlows._run_powerflow_method — Method
Runs the full NewtonRaphsonACPowerFlow.
Keyword arguments:
maxIterations::Int: maximum iterations. Default: 50.tol::Float64: tolerance. The iterative search ends whennorm(abs.(residual)) < tol. Default: 1.0e-9.refinement_threshold::Float64: If the solution toJ_x Δx = rsatisfiesnorm(J_x Δx - r, 1)/norm(r, 1) > refinement_threshold, do iterative refinement to improve the accuracy. Default: 0.05.refinement_eps::Float64: run iterative refinement onJ_x Δx = runtilnorm(Δx_{i}-Δx_{i+1}, 1)/norm(r,1) < refinement_eps. Default: 1.0e-6
PowerFlows._run_powerflow_method — Method
Runs the full TrustRegionNRMethod.
Keyword arguments:
maxIterations::Int: maximum iterations. Default: 50.tol::Float64: tolerance. The iterative search ends whenmaximum(abs.(residual)) < tol. Default: 1.0e-9.factor::Float64: the trust region starts out with radiusfactor*norm(x_0, 1), wherex_0is our initial guess, taken fromdata. Default: 1.0.eta::Float64: improvement threshold. If the observed improvement in our residual exceedsetatimes the predicted improvement, we accept the newx_i. Default: 0.0001.
PowerFlows._set_Δx_nr! — Method
Sets the Newton-Raphson step. Usually, this is just J.Jv \ stateVector.r, but J.Jv might be singular.
PowerFlows._simple_step — Function
Does a single iteration of NewtonRaphsonACPowerFlow. Updates the r and x fields of the stateVector, and computes the Jacobian at the new x.
PowerFlows._singular_J_fallback — Method
Returns a stand-in matrix for singular J's.
PowerFlows._solve_Δx_nr! — Method
Solve for the Newton-Raphson step, given the factorization object for J.Jv (if non-singular) or its stand-in (if singular).
PowerFlows._trust_region_step — Method
Does a single iteration of the TrustRegionNRMethod: updates the x and r fields of the stateVector and computes the value of the Jacobian at the new x, if needed. Unlike _simple_step, this has a return value, the updated value of delta`.
Robust Homotopy Method
PowerFlows.HomotopyHessian — Method
Compute value of gradient and Hessian at x.
PowerFlows.A_plus_eq_BT_B! — Method
Does A += B' * B, in a way that preserves the sparse structure of A, if possible. A workaround for the fact that Julia seems to run dropzeros!(A) automatically if I just do A .+= B' * B.
PowerFlows._update_hessian_matrix_values! — Method
_update_hessian_matrix_values!(
Hv::SparseMatrixCSC{Float64, Int32},
F_value::Vector{Float64},
data::ACPowerFlowData,
time_step::Int64
)Update the Hessian matrix values for the robust homotopy power flow solver.
Description
This function sets Hv equal to:
\[\sum_{k=1}^{2n} F_k(x) H_{F_k}(x)\]
where $F_k$ denotes the $k$th power balance equation and $H_{F_k}$ denotes its Hessian matrix.
This computes only the terms in the Hessian that come from the second derivatives of the power balance equations. The full Hessian of the objective function also includes a $J^T J$ term, which is computed separately.
Sparse Structure
The Hessian is organized into 2×2 blocks, each corresponding to a pair of buses. For a pair of buses $i$ and $k$ connected by a branch, the sparse structure of their block depends on the bus types:
\[\begin{array}{c|cc|cc|cc} & \text{REF} & & \text{PV} & & \text{PQ} & \\ & P_i & Q_i & Q_i & V_i & V_i & \theta_i \\ \hline \text{REF: } P_k & & & & & & \\ Q_k & & & & & & \\ \hline \text{PV: } Q_k & & & & & & \\ V_k & & & & \bullet & \bullet & \bullet \\ \hline \text{PQ: } V_k & & & & \bullet & \bullet & \bullet \\ \theta_k & & & & \bullet & \bullet & \bullet \end{array}\]
where $\bullet$ represents a potentially non-zero entry.
Diagonal blocks (where $i = k$) follow the same pattern as if each bus is its own neighbor. Off-diagonal blocks for pairs of buses not connected by a branch are structurally zero.
Arguments
Hv::SparseMatrixCSC{Float64, Int32}: The Hessian matrix to be updated (modified in-place).F_value::Vector{Float64}: Current values of the power balance residuals.data::ACPowerFlowData: The power flow data containing bus and network information.time_step::Int64: The time step for which to compute the Hessian.
Levenberg-Marquardt Method
PowerFlows._newton_powerflow — Method
Driver for the LevenbergMarquardtACPowerFlow method: sets up the data structures (e.g. residual), runs the powerflow method via calling _run_powerflow_method on them, then handles post-processing (e.g. loss factors).
Linear Algebra Backends
Robust Homotopy
PowerFlows.FixedStructureCHOLMOD — Type
In order to in-place modify the numeric values of a CHOLMOD matrix, we need to write our own wrapper around CHOLMOD.Sparse.
PowerFlows.set_values! — Method
set_values!(mat::FixedStructureCHOLMOD, new_vals::AbstractVector{Float64})In-place update of the numeric values in the CHOLMOD matrix.
Newton-Raphson
PowerFlows.KLULinSolveCache — Type
A cached linear solver using KLU. Carefully written so as to minimize allocations: solve! and numeric_refactor! are completely non-allocating.
Fields:
K: the underlying KLU object.reuse_symbolic::Bool: reuse the symbolic factorization. Defaults totrue.check_pattern::Bool: if true,numeric_refactor!verifies that the new matrix has the same sparsity structure. Defaults totrue.rf_common,rf_symbolic,rf_numeric: internal usage. Stored to avoid allocations.
PowerFlows.KLULinSolveCache — Method
Constructor.
PowerFlows.numeric_refactor! — Method
Frees numeric factorization stored by cache, if non-null. If cache.check_pattern is true and the sparse matrix structure of A doesn't match the cached one, throws an error. Finally, computes the numeric factorization of A and stores that to cache.
PowerFlows.symbolic_factor! — Method
symbolic_factor!(cache::KLULinSolveCache{T}, A::SparseMatrixCSC{Float64, T})Frees up the current symbolic and numeric factorizations stored by cache, if non-null. Then computes the symbolic factorization of A and stores that to cache.
PowerFlows.symbolic_refactor! — Method
Symbolic refactor. Behavior depends on the values of cache.reuse_symbol and cache.check_pattern. There are 3 cases:
!reuse_symbol: always refactor. Just callssymbolic_factor(cache, A).reuse_symbol && check_pattern: checks if the symbolic structure ofAmatches the cached one, and throws an error if it doesn't. This is to prevent bad input: we expected the structure to be the same, but it isn't.reuse_symbol && !check pattern: do nothing. Assume the structure ofAmatches the cached one.
PowerFlows.LinearSolverCache — Type
Abstract supertype for all cached linear solvers. Subtypes must implement: symbolic_factor!, symbolic_refactor!, numeric_refactor! (which doubles as numeric_factor!), and solve!.
Misc.
PSSE Export
PowerFlows._first_choice_gen_id — Method
Try to make an informative one or two character name for the load/generator/etc.
- generator-1234-AB -> AB
- 123_CT_7 -> 7
- load1234 -> 34
PowerFlows._fix_3w_transformer_rating — Method
Setting a value of zero 0.0 when having a value greater than or equal to INFINITE_BOUND reverses the operation done in the PSY parsing side, according to PSSE Manual.
PowerFlows._make_gens_from_hvdc — Method
Create a synthetic generator (PSY.ThermalStandard) representing one end of a TwoTerminalGenericHVDCLine for export purposes. The generator is initialized with parameters reflecting the HVDC line's state.
Notes
- The generator's name is constructed as "<hvdc_line_name>_<suffix>".
- The `ext` field includes `"HVDC_END"` to indicate the end ("FR"/"TO").PowerFlows._map_psse_container_names — Method
Validate that the Sienna area/zone names parse as PSS/E-compatible area/zone numbers, output a mapping
PowerFlows._psse_bus_names — Method
Given a vector of Sienna bus names, create a dictionary from Sienna bus name to PSS/E-compatible bus name. Guarantees determinism and minimal changes.
WRITTEN TO SPEC: PSS/E 33.3 POM 5.2.1 Bus Data
PowerFlows._psse_bus_numbers — Method
Given a vector of Sienna bus numbers, create a dictionary from Sienna bus number to PSS/E-compatible bus number. Assumes that the Sienna bus numbers are positive and unique. Guarantees determinism: if the input contains the same bus numbers in the same order, the output will. Guarantees minimal changes: that if an existing bus number is compliant, it will not be changed.
WRITTEN TO SPEC: PSS/E 33.3 POM 5.2.1 Bus Data
PowerFlows._psse_transformer_names — Method
Given a vector of Sienna transformer names, create a dictionary from Sienna transformer name to PSS/E-compatible transformer name. Guarantees determinism and minimal changes.
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Transformer Data
PowerFlows._update_gens_from_hvdc! — Method
Update the parameters of synthetic generators created from HVDC lines, so they reflect the current setpoints and limits of the HVDC devices in the system.
PowerFlows.better_float_to_buf — Method
Temporary, very specialized proof of concept patch for https://github.com/JuliaLang/julia/issues/55835
PowerFlows.check_supported_version — Method
Throw a NotImplementedError if the psse_version is not supported
PowerFlows.convert_empty — Method
If val is empty, returns T(); if not, asserts that val isa T and returns val. Has nice type checker semantics.
Examples
convert_empty(Vector{String}, []) # -> String[]
convert_empty(Vector{String}, ["a"]) # -> ["a"]
convert_empty(Vector{String}, [2]) # -> TypeError: in typeassert, expected Vector{String}, got a value of type Vector{Int64}
Base.return_types(Base.Fix1(convert_empty, Vector{String})) # -> [Vector{String}]PowerFlows.create_component_ids — Method
Given a vector of component names and a corresponding vector of container IDs (e.g., bus numbers), create unique-per-container PSS/E-compatible IDs, output a dictionary from (container ID, component name) to PSS/E-compatible component ID. The "singlesto1" flag detects components that are the only one on their bus and gives them the name "1".
PowerFlows.flatten_power_flow_evaluation_model — Method
Expand a single PowerFlowEvaluationModel into its possibly multiple parts for separate evaluation. Namely, if pfem contains a non-nothing exporter, return [pfem, exporter], else return [pfem].
PowerFlows.get_branches_with_numbers — Method
Collects all AC branches (Line, MonitoredLine, DiscreteControlledACBranch) from the system, sorts them by their bus numbers, and returns a vector of tuples (branch, bus_numbers).
Arguments
exporter::PSSEExporter: The exporter containing the system.
Returns
Vector{Tuple{<:PSY.Branch, Tuple}}: Each tuple contains a branch and its associated bus numbers.
PowerFlows.reset_caches — Method
Force all cached information (serialized metadata, component lists, etc.) to be regenerated
PowerFlows.serialize_component_ids — Method
Take the output of create_component_ids and make it more suitable for JSON serialization
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Bus Data. Sienna voltage limits treated as PSS/E normal voltage limits; PSSE emergency voltage limits left as default.
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Case Identification Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 FACTS Device Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Fixed Bus Shunt Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Generator Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Load Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Non-Transformer Branch Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3 POM 5.2.1 Q Record
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Switched Shunt Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 35.4 POM 5.2.1 System Switching Device Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Transformer Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Transformer Impedance Correction Tables
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Two-Terminal DC Transmission Line Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Voltage Source Converter (VSC) DC Transmission Line Data
PowerFlows.write_to_buffers! — Method
WRITTEN TO SPEC: PSS/E 33.3/35.4 POM 5.2.1 Zone Data
Post-Processing
PowerFlows._calculate_fixed_admittance_powers — Method
Returns a dictionary of bus index to power contribution at that bus from FixedAdmittance components, as a tuple of (active power, reactive power).
PowerFlows._set_series_voltages_and_flows! — Method
_set_series_voltages_and_flows!(
sys::PSY.System,
segment_sequence::PNM.BranchesSeries,
equivalent_arc::Tuple{Int, Int},
V_endpoints::Tuple{ComplexF64, ComplexF64},
temp_bus_map::Dict{Int, String},
)Calculate series voltages at buses removed in degree 2 reduction.
Method
Number the nodes in the series segment 0, 1, ..., n. Number the segments by their concluding node: 1, 2, ... n. The currents in the segments are given by:
\[\begin{bmatrix} y^i_{ff} & y^i_{ft} \\ y^i_{tf} & y^i_{tt} \end{bmatrix} \begin{bmatrix} V_{i-1} \\ V_i \end{bmatrix} = \begin{bmatrix} I_{i-1, i} \\ I_{i, i-1} \end{bmatrix}\]
where upper indices denote the segment number.
There are no loads or generators at the internal nodes, so $I_{i, i+1} + I_{i, i-1} = 0$. Substitute the above expressions for the currents and group by $V_i$:
\[y^i_{tf} V_{i-1} + (y_{tt}^i + y_{ff}^{i+1}) V_i + y_{ft}^{i+1} V_{i+1} = 0\]
For $i = 1$ and $i = n-1$, move the terms involving $V_0$ and $V_n$ (known) to the other side. This gives a tridiagonal system for $x = [V_1, \ldots, V_{n-1}]$:
\[A x = [-y^1_{tf} V_0, 0, \ldots, 0, -y^{n}_{ft} V_n]\]
where $A$ has diagonal entries $y_{tt}^i + y_{ff}^{i+1}$, subdiagonal entries $y_{tf}^{i+1}$, and superdiagonal entries $y_{ft}^i$.
In the implementation, $y_{11}$ is used instead of $y_{ff}$, $y_{12}$ instead of $y_{ft}$, etc.
PowerFlows.get_arc_names — Method
Return the names of the arcs in the power flow data: those that correspond to branches in the system will get the branch names, others will get a placeholder name of the form from-to.
PowerFlows.set_branch_flows_for_dict! — Method
Set the power flow in the arcs that remain after network reduction. Called on the direct_branch_map and transformer3W_map dictionaries.
PowerFlows.update_system! — Method
update_system!(sys::PSY.System, data::PowerFlowData; time_step = 1)Modify the values in the given System to correspond to the given PowerFlowData such that if a new PowerFlowData is constructed from the resulting system it is the same as data. See also write_powerflow_solution!. NOTE this assumes that data was initialized from sys and then solved with no further modifications.
PowerFlows.write_powerflow_solution! — Function
Updates system voltages and powers with power flow results
PowerFlows.write_results — Method
write_results(
::ACPowerFlow{<:ACPowerFlowSolverType},
sys::PSY.System,
data::ACPowerFlowData,
time_step::Int64,
) -> Dict{String, DataFrames.DataFrame}Returns a dictionary containing the AC power flow results.
Only single-period evaluation is supported at the moment for AC Power flows. The resulting dictionary will therefore feature just one key linked to one DataFrame.
Arguments:
::ACPowerFlow: use ACPowerFlow() storing AC power flow results.sys::PSY.System: container storing the system information.result::Vector{Float64}: vector containing the results for one single time-period.
PowerFlows.write_results — Method
write_results(
data::Union{PTDFPowerFlowData, vPTDFPowerFlowData, ABAPowerFlowData},
sys::PSY.System,
)Returns a dictionary containing the DC power flow results. Each key corresponds to the name of the considered time periods, storing a DataFrame with the powerflow results.
Arguments:
data::Union{PTDFPowerFlowData, vPTDFPowerFlowData, ABAPowerFlowData}: PowerFlowData structure containing power flows and bus angles.sys::PSY.System: APowerSystems.Systemobject storing the system information.
Power Systems Utilities
PowerFlows.can_be_PV — Method
Return set of all bus numbers that can be PV: i.e. have an available generator, or certain voltage regulation devices.
PowerFlows.get_active_and_reactive_power_from_generator — Method
Return the active and reactive power generation from a generator component. It's pg=0 as default for synchronous condensers since there's no field in the component for active power.
PowerFlows.get_active_power_limits_for_power_flow — Method
Return the active power limits that should be used in power flow calculations and PSS/E exports. Redirects to PSY.get_active_power_limits in all but special cases.
PowerFlows.get_reactive_power_limits_for_power_flow — Method
Return the reactive power limits that should be used in power flow calculations and PSS/E exports. Redirects to PSY.get_reactive_power_limits in all but special cases.
PowerFlows.must_be_PV — Method
Return set of all bus numbers that must be PV: i.e. have an available generator.
Common Utilities and Definitions
PowerFlows.my_mul_mt — Method
Similar to above: A*X where X is a matrix.
PowerFlows.my_mul_mt — Method
Matrix multiplication A*x. Written this way because a VirtualPTDF matrix does not store all of its entries: instead, it calculates them (or retrieves them from cache), one element or one row at a time.
PowerFlows.siground — Method
For pretty printing floats in debugging messages.
PowerFlows.wdot — Method
Weighted dot product of two vectors.
PowerFlows.wnorm — Method
Weighted norm of two vectors.
PowerFlows.contributes_active_power — Method
Check if a device has attribute 'active_power' for active power consumption or generation.