36 const Eigen::MatrixXcd& Y,
37 Eigen::VectorXd& Vmag,
38 Eigen::VectorXd& delta,
39 const Eigen::VectorXi& type_bus,
40 const Eigen::VectorXd& P,
41 const Eigen::VectorXd& Q,
46 std::vector<std::pair<int, double>>* iterHistory
49 Eigen::VectorXd Vmag_sched = Vmag;
52 Eigen::VectorXcd V(N);
53 for (
int i = 0; i < N; ++i)
54 V(i) = std::polar(Vmag(i), delta(i));
57 double error = std::numeric_limits<double>::infinity();
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.");
66 LOG_CRITICAL(
"Under-relaxation enabled (omega < 1), this will slow down convergence.");
68 else if (omega == 1.0) {
69 LOG_DEBUG(
"Standard Gauss-Seidel enabled (omega = 1).");
71 else if (omega > 1.0) {
72 LOG_DEBUG(
"Over-relaxation enabled (omega > 1), this will accelerate convergence.");
75 LOG_DEBUG(
"Relaxation Coefficient :: {}", omega);
77 while (error >= tolerance && iteration < maxIter) {
78 Eigen::VectorXcd dV = Eigen::VectorXcd::Zero(N);
80 for (
int n = 0; n < N; ++n) {
81 if (type_bus(n) == 1)
continue;
83 std::complex<double> In = Y.row(n) * V;
85 if (type_bus(n) == 2) {
87 double Qn = -std::imag(std::conj(V(n)) * In);
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);
96 }
else if (type_bus(n) == 3) {
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);
107 if (iterHistory) iterHistory->emplace_back(iteration, error);
111 if (iteration >= maxIter) {
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);
119 for (
int i = 0; i < N; ++i) {
120 Vmag(i) = std::abs(V(i));
121 delta(i) = std::arg(V(i));
125 LOG_DEBUG(
"Gauss-Seidel converged in {} iterations with error norm {:.6e}.", iteration, error);
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.
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.