37 const Eigen::VectorXd& V,
38 const Eigen::VectorXd& delta,
39 Eigen::VectorXi& type_bus,
40 const Eigen::MatrixXd& G,
41 const Eigen::MatrixXd& B,
43 const std::vector<int>& pv_bus_id,
48 Eigen::VectorXd Qmax = busData.
Qgmax;
49 Eigen::VectorXd Qmin = busData.
Qgmin;
51 for (
int i = 0; i < n_bus; ++i) {
52 if (Qmax(i) == 0.0) Qmax(i) = std::numeric_limits<double>::infinity();
53 if (Qmin(i) == 0.0) Qmin(i) = -std::numeric_limits<double>::infinity();
57 Eigen::VectorXd Q = Eigen::VectorXd::Zero(n_bus);
58 for (
int i = 0; i < n_bus; ++i) {
59 for (
int j = 0; j < n_bus; ++j) {
60 double dij = delta(i) - delta(j);
61 Q(i) += V(i) * V(j) * (G(i, j) * std::sin(dij) - B(i, j) * std::cos(dij));
66 Eigen::VectorXd Qg = Q + busData.
Ql;
69 bool qlim_hit =
false;
71 for (
int idx : pv_bus_id) {
72 if (Qg(idx) > Qmax(idx)) {
74 busData.
Qg(idx) = Qmax(idx);
77 std::string msg = fmt::format(
"Q-limit (max) hit at bus {} : Qg = {:.4f} > Qmax = {:.4f}", idx + 1, Qg(idx), Qmax(idx));
80 }
else if (Qg(idx) < Qmin(idx)) {
82 busData.
Qg(idx) = Qmin(idx);
85 std::string msg = fmt::format(
"Q-limit (min) hit at bus {} : Qg = {:.4f} < Qmin = {:.4f}", idx + 1, Qg(idx), Qmin(idx));
91 if (!qlim_hit && observer) {
92 observer->
onMessage(
"Qlim",
"Power flow converged without hitting Q-limits.");
static bool check(const Eigen::VectorXd &V, const Eigen::VectorXd &delta, Eigen::VectorXi &type_bus, const Eigen::MatrixXd &G, const Eigen::MatrixXd &B, BusData &busData, const std::vector< int > &pv_bus_id, int n_bus, ISolverObserver *observer=nullptr)
Checks reactive power limits on PV buses after solver convergence.