deltaFlow
GaussSeidel.H File Reference

Declaration of the Gauss-Seidel load flow solver for power system analysis. More...

#include <Eigen/Dense>
#include <utility>
#include <vector>
Include dependency graph for GaussSeidel.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool GaussSeidel (const Eigen::MatrixXcd &Y, Eigen::VectorXd &V, Eigen::VectorXd &delta, const Eigen::VectorXi &type_bus, const Eigen::VectorXd &P, const Eigen::VectorXd &Q, int N, int maxIter=1024, double tolerance=1E-8, double omega=1.0, std::vector< std::pair< int, double > > *iterHistory=nullptr)
 Solves the power flow equations using the Gauss-Seidel iterative method.
 

Detailed Description

Declaration of the Gauss-Seidel load flow solver for power system analysis.

The Gauss-Seidel method is an iterative algorithm to solve the power flow equations for bus voltages in a power system. It uses the bus admittance matrix $$ Y_{bus} $$ and iteratively updates the bus voltages $$ V $$ to satisfy the power balance equations:

$$ S_i = V_i \sum_{j=1}^N Y_{ij}^* V_j^* $$

where:

  • $$ S_i $$ is the specified complex power at bus $$ i $$
  • $$ V_i $$ is the voltage at bus $$ i $$
  • $$ Y_{ij} $$ is the element of the admittance matrix

The Gauss-Seidel voltage update for the k-th iteration is:

$$ V_i^{(k+1)} = \frac{1}{Y_{ii}} \left( \frac{S_i^*}{V_i^{*(k)}} - \sum_{j=1, j \neq i}^N Y_{ij} V_j^{(k+1 \text{ or } k)} \right) $$

For voltage-controlled buses (PV buses), the reactive power injection $$ Q_k $$ is unknown initially but can be computed at iteration i by:

$$ Q_k^{(i)} = V_k^{(i)} \sum_{n=1}^N |Y_{kn}| V_n^{(i)} \sin \left( \delta_k^{(i)} - \delta_n^{(i)} - \theta_{kn} \right) $$

The total reactive power generation at bus k is:

$$ Q_{Gk} = Q_k + Q_{Lk} $$

where $$( Q_{Lk} )$$ is the reactive load demand at the bus.

If the calculated $$( Q_{Gk} )$$ remains within its specified limits (e.g., $$ Q_{Gk}^{min} \leq Q_{Gk} \leq Q_{Gk}^{max} $$), the voltage magnitude $$ V_k $$ is fixed at its specified value, and only the voltage angle $$ \delta_k $$ is updated using the Gauss-Seidel formula. This means:

  • The updated voltage magnitude $$ V_k^{(i+1)} $$ is set to the specified magnitude,
  • Only the angle $$ \delta_k^{(i+1)} $$ changes according to the iterative update.

If $$( Q_{Gk} )$$ exceeds its limits during any iteration, the bus type is switched from voltage-controlled (PV) to load bus (PQ), with $$ Q_{Gk} $$ fixed at the violated limit (either $$ Q_{Gk}^{max} $$ or $$ Q_{Gk}^{min} $$). Under this condition, the voltage magnitude $$ V_k $$ is no longer fixed and is recalculated by the load flow program.

To accelerate convergence, a relaxation (or acceleration) coefficient $$ \omega $$ (typically $$(0 < \omega \leq 1) $$) can be applied to the voltage update:

$$ V_i^{(k+1)} = \omega \times V_i^{(k+1)} + (1 - \omega) \times V_i^{(k)} $$

The iteration proceeds until the maximum change in bus voltages between iterations is below a specified tolerance, or the maximum number of iterations is reached.

Definition in file GaussSeidel.H.

Function Documentation

◆ GaussSeidel()

bool GaussSeidel ( const Eigen::MatrixXcd &  Y,
Eigen::VectorXd &  V,
Eigen::VectorXd &  delta,
const Eigen::VectorXi &  type_bus,
const Eigen::VectorXd &  P,
const Eigen::VectorXd &  Q,
int  N,
int  maxIter = 1024,
double  tolerance = 1E-8,
double  omega = 1.0,
std::vector< std::pair< int, double > > *  iterHistory = nullptr 
)

Solves the power flow equations using the Gauss-Seidel iterative method.

Pure solver: no Q-limit checking (handled by outer loop via checkQlimits). PV buses maintain their scheduled voltage magnitude; PQ buses are fully updated.

Parameters
YThe bus admittance matrix ($$ Y_{bus} $$).
V(in/out) Voltage magnitudes [p.u.]. PV buses maintain scheduled value.
delta(in/out) Voltage angles [rad].
type_busBus type vector (1=Slack, 2=PV, 3=PQ).
PScheduled net active power injections [p.u.] ($$ P_g - P_l $$).
QScheduled net reactive power injections [p.u.] ($$ Q_g - Q_l $$). Used only for PQ buses.
NTotal number of buses.
maxIterMaximum number of iterations (default: 1024).
toleranceConvergence tolerance for bus voltage updates (default: $$ 1 \times 10^{-8} $$).
omegaRelaxation parameter for the Successive Over-Relaxation (SOR) method (default: 1.0; SOR not applied).
iterHistoryOptional pointer to store iteration number and error at each step.
Returns
true if the algorithm converged within the specified number of iterations, false otherwise.

Definition at line 35 of file GaussSeidel.C.

47 {
48 // Store scheduled voltage magnitudes for PV buses
49 Eigen::VectorXd Vmag_sched = Vmag;
50
51 // Initialize complex voltage vector
52 Eigen::VectorXcd V(N);
53 for (int i = 0; i < N; ++i)
54 V(i) = std::polar(Vmag(i), delta(i));
55
56 int iteration = 0;
57 double error = std::numeric_limits<double>::infinity();
58
59 if (omega <= 0.0 || omega >= 2.0) {
60 LOG_WARN("Invalid input: Relaxation coefficient must be between 0 and 2.");
61 LOG_DEBUG("Setting Relaxation coefficient to 1.");
62 omega = 1.0;
63 }
64
65 if (omega < 1.0) {
66 LOG_CRITICAL("Under-relaxation enabled (omega < 1), this will slow down convergence.");
67 }
68 else if (omega == 1.0) {
69 LOG_DEBUG("Standard Gauss-Seidel enabled (omega = 1).");
70 }
71 else if (omega > 1.0) {
72 LOG_DEBUG("Over-relaxation enabled (omega > 1), this will accelerate convergence.");
73 }
74
75 LOG_DEBUG("Relaxation Coefficient :: {}", omega);
76
77 while (error >= tolerance && iteration < maxIter) {
78 Eigen::VectorXcd dV = Eigen::VectorXcd::Zero(N);
79
80 for (int n = 0; n < N; ++n) {
81 if (type_bus(n) == 1) continue; // Skip slack bus
82
83 std::complex<double> In = Y.row(n) * V;
84
85 if (type_bus(n) == 2) { // PV Bus
86 // Compute Q from current solution (no clamping)
87 double Qn = -std::imag(std::conj(V(n)) * In);
88
89 // GS update maintaining scheduled voltage magnitude
90 std::complex<double> I_excl = In - Y(n, n) * V(n);
91 std::complex<double> V_updated = ((P(n) - std::complex<double>(0, 1) * Qn) / std::conj(V(n)) - I_excl) / Y(n, n);
92 std::complex<double> V_corrected = Vmag_sched(n) * V_updated / std::abs(V_updated);
93 dV(n) = V_corrected - V(n);
94 V(n) = V_corrected;
95
96 } else if (type_bus(n) == 3) { // PQ Bus
97 std::complex<double> I_excl = In - Y(n, n) * V(n);
98 std::complex<double> V_updated = ((P(n) - std::complex<double>(0, 1) * Q(n)) / std::conj(V(n)) - I_excl) / Y(n, n);
99 std::complex<double> V_relaxed = V(n) + omega * (V_updated - V(n));
100 dV(n) = V_relaxed - V(n);
101 V(n) = V_relaxed;
102 }
103 }
104
105 error = dV.norm();
106 iteration++;
107 if (iterHistory) iterHistory->emplace_back(iteration, error);
108 printIterationProgress("Gauss-Seidel", iteration, maxIter, error, tolerance);
109 }
110
111 if (iteration >= maxIter) {
112 printConvergenceStatus("Gauss-Seidel", false, iteration, maxIter, error, tolerance);
113 LOG_WARN("Gauss-Seidel did not converge within max iterations ({}).", maxIter);
114 LOG_DEBUG("Final error norm was {:.6e}, tolerance is {:.6e}.", error, tolerance);
115 return false;
116 }
117
118 // Extract converged V magnitudes and angles
119 for (int i = 0; i < N; ++i) {
120 Vmag(i) = std::abs(V(i));
121 delta(i) = std::arg(V(i));
122 }
123
124 printConvergenceStatus("Gauss-Seidel", true, iteration, maxIter, error, tolerance);
125 LOG_DEBUG("Gauss-Seidel converged in {} iterations with error norm {:.6e}.", iteration, error);
126
127 return true;
128}
#define LOG_WARN(msg,...)
Macro for logging a warning-level message.
Definition Logger.H:87
#define LOG_DEBUG(msg,...)
Macro for logging a debug-level message.
Definition Logger.H:85
#define LOG_CRITICAL(msg,...)
Macro for logging a critical-level message.
Definition Logger.H:89
void printIterationProgress(const std::string &solver, int iter, int maxIter, double error, double tol, int barWidth=50)
Print an iteration progress line for a solver.
Definition Progress.H:50
void printConvergenceStatus(const std::string &solver, bool converged, int iter, int maxIter, double error, double tol, int barWidth=50)
Print the final convergence status line.
Definition Progress.H:100

References LOG_CRITICAL, LOG_DEBUG, LOG_WARN, printConvergenceStatus(), and printIterationProgress().

Here is the call graph for this function: