51 const Eigen::MatrixXcd& Y,
52 Eigen::VectorXd& Vmag,
53 Eigen::VectorXd& delta,
54 const Eigen::VectorXi& type_bus,
55 const Eigen::VectorXd& P,
56 const Eigen::VectorXd& Q,
61 std::vector<std::pair<int, double>>* iterHistory,
65 Eigen::VectorXd Vmag_sched = Vmag;
68 Eigen::VectorXcd V(N);
69 for (
int i = 0; i < N; ++i)
70 V(i) = std::polar(Vmag(i), delta(i));
73 double error = std::numeric_limits<double>::infinity();
75 if (omega <= 0.0 || omega >= 2.0) {
76 if (observer) observer->
onMessage(
"Gauss-Seidel",
"Invalid input: Relaxation coefficient must be between 0 and 2. Setting Relaxation coefficient to 1.");
82 observer->
onMessage(
"Gauss-Seidel",
"Under-relaxation enabled (omega < 1), this will slow down convergence.");
83 }
else if (omega == 1.0) {
84 observer->
onMessage(
"Gauss-Seidel",
"Standard Gauss-Seidel enabled (omega = 1).");
86 observer->
onMessage(
"Gauss-Seidel",
"Over-relaxation enabled (omega > 1), this will accelerate convergence.");
90 while (error >= tolerance && iteration < maxIter) {
91 Eigen::VectorXcd dV = Eigen::VectorXcd::Zero(N);
93 for (
int n = 0; n < N; ++n) {
94 if (type_bus(n) == 1)
continue;
96 std::complex<double> In = Y.row(n) * V;
98 if (type_bus(n) == 2) {
100 double Qn = -std::imag(std::conj(V(n)) * In);
103 std::complex<double> I_excl = In - Y(n, n) * V(n);
104 std::complex<double> V_updated = ((P(n) - std::complex<double>(0, 1) * Qn) / std::conj(V(n)) - I_excl) / Y(n, n);
105 std::complex<double> V_corrected = Vmag_sched(n) * V_updated / std::abs(V_updated);
106 dV(n) = V_corrected - V(n);
109 }
else if (type_bus(n) == 3) {
110 std::complex<double> I_excl = In - Y(n, n) * V(n);
111 std::complex<double> V_updated = ((P(n) - std::complex<double>(0, 1) * Q(n)) / std::conj(V(n)) - I_excl) / Y(n, n);
112 std::complex<double> V_relaxed = V(n) + omega * (V_updated - V(n));
113 dV(n) = V_relaxed - V(n);
120 if (iterHistory) iterHistory->emplace_back(iteration, error);
121 if (observer) observer->
onIteration(
"Gauss-Seidel", iteration, maxIter, error, tolerance);
124 if (iteration >= maxIter) {
125 if (observer) observer->
onFinished(
"Gauss-Seidel",
false, iteration, maxIter, error, tolerance);
130 for (
int i = 0; i < N; ++i) {
131 Vmag(i) = std::abs(V(i));
132 delta(i) = std::arg(V(i));
135 if (observer) observer->
onFinished(
"Gauss-Seidel",
true, iteration, maxIter, error, tolerance);
Declaration of the Gauss-Seidel load flow solver for power system analysis.
static bool run(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, ISolverObserver *observer=nullptr)
Solves the power flow equations using the Gauss-Seidel iterative method.
bool solve(SolverContext &ctx) override
Run the Gauss-Seidel solver using the given context.
Sink for solver progress/diagnostics (Dependency Inversion / SRP).
virtual void onIteration(const char *solverName, int iter, int maxIter, double error, double tolerance)=0
Called after every iteration with the current error/tolerance.
virtual void onFinished(const char *solverName, bool converged, int iter, int maxIter, double error, double tolerance)=0
Called once after the iteration loop ends (converged or not).
virtual void onMessage(const char *solverName, const char *message)=0
Called for solver-specific diagnostic/warning messages (e.g.
Shared input/output parameters for power-flow solvers.
const Eigen::VectorXd * Q
Scheduled reactive power injections (Qg - Ql).
double tolerance
Convergence tolerance.
Eigen::VectorXd * V
Voltage magnitudes [p.u.].
const Eigen::MatrixXcd * Y
Bus admittance matrix (used by Gauss-Seidel).
const Eigen::VectorXd * P
Scheduled active power injections (Pg - Pl).
int maxIter
Maximum number of iterations.
int N
Total number of buses.
Eigen::VectorXd * delta
Voltage angles [rad].
Eigen::VectorXi * type_bus
Bus type vector (1=Slack, 2=PV, 3=PQ).
class ISolverObserver * observer
Optional injected progress/log observer (DIP); nullptr = silent.
std::vector< std::pair< int, double > > * iterHistory
Optional iteration history sink.
double omega
Relaxation coefficient (Gauss-Seidel only).