deltaFlow
Qlim Class Referencefinal

Checks reactive power limits on PV buses after solver convergence. More...

#include <Qlim.H>

Static Public Member Functions

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.
 

Detailed Description

Checks reactive power limits on PV buses after solver convergence.

Definition at line 47 of file Qlim.H.

Member Function Documentation

◆ check()

bool Qlim::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 
)
static

Checks reactive power limits on PV buses after solver convergence.

Computes the reactive power at each bus using converged voltages and angles, then checks if PV buses violate their $$ Q_{gmax} $$ or $$ Q_{gmin} $$ limits. Violating PV buses are converted to PQ type (type 3 in C++ convention).

Parameters
VConverged voltage magnitudes [p.u.].
deltaConverged voltage angles [rad].
type_bus(in/out) Bus type vector; PV buses that violate limits are set to PQ.
GConductance matrix.
BSusceptance matrix.
busDataBus data (for Ql, Qgmax, Qgmin).
pv_bus_id0-based indices of PV buses (before any conversion).
n_busTotal number of buses.
observerOptional injected log observer (DIP); nullptr means silent.
Returns
true if any Q-limit was hit (solver must be re-run), false otherwise.

Definition at line 36 of file Qlim.C.

46 {
47 // Q-limits: zero means no limit, using +/-inf
48 Eigen::VectorXd Qmax = busData.Qgmax;
49 Eigen::VectorXd Qmin = busData.Qgmin;
50
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();
54 }
55
56 // Compute reactive power Q at each bus with converged V and delta
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));
62 }
63 }
64
65 // Qg = Q_calc + Ql (all in p.u.)
66 Eigen::VectorXd Qg = Q + busData.Ql;
67
68 // Check Q-limits only for PV buses
69 bool qlim_hit = false;
70
71 for (int idx : pv_bus_id) {
72 if (Qg(idx) > Qmax(idx)) {
73 type_bus(idx) = 3; // PV to PQ
74 busData.Qg(idx) = Qmax(idx); // Fix Q at limit for next solver run
75 qlim_hit = true;
76 if (observer) {
77 std::string msg = fmt::format("Q-limit (max) hit at bus {} : Qg = {:.4f} > Qmax = {:.4f}", idx + 1, Qg(idx), Qmax(idx));
78 observer->onMessage("Qlim", msg.c_str());
79 }
80 } else if (Qg(idx) < Qmin(idx)) {
81 type_bus(idx) = 3; // PV to PQ
82 busData.Qg(idx) = Qmin(idx); // Fix Q at limit for next solver run
83 qlim_hit = true;
84 if (observer) {
85 std::string msg = fmt::format("Q-limit (min) hit at bus {} : Qg = {:.4f} < Qmin = {:.4f}", idx + 1, Qg(idx), Qmin(idx));
86 observer->onMessage("Qlim", msg.c_str());
87 }
88 }
89 }
90
91 if (!qlim_hit && observer) {
92 observer->onMessage("Qlim", "Power flow converged without hitting Q-limits.");
93 }
94
95 return qlim_hit;
96}
virtual void onMessage(const char *solverName, const char *message)=0
Called for solver-specific diagnostic/warning messages (e.g.
Eigen::VectorXd Ql
Reactive power load [MVAr or p.u.].
Definition Data.H:65
Eigen::VectorXd Qgmax
Max reactive power generation [MVAr or p.u.].
Definition Data.H:66
Eigen::VectorXd Qgmin
Min reactive power generation [MVAr or p.u.].
Definition Data.H:67
Eigen::VectorXd Qg
Reactive power generation [MVAr or p.u.].
Definition Data.H:63

References ISolverObserver::onMessage(), BusData::Qg, BusData::Qgmax, BusData::Qgmin, and BusData::Ql.

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: