deltaFlow
Writer.C
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Saud Zahir
3 *
4 * This file is part of deltaFlow.
5 *
6 * deltaFlow is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * deltaFlow is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with deltaFlow. If not, see
18 * <https://www.gnu.org/licenses/>.
19 */
20
26#include <complex>
27#include <fstream>
28#include <iomanip>
29
30#include "Display.H"
31#include "Data.H"
32#include "Logger.H"
33#include "Writer.H"
34
35
36void dispBusData(const BusData& busData) {
37 int nbus = busData.V.size();
38
39 Display::printSectionHeader("B U S D A T A R E S U L T S");
40
41 fmt::print(fg(Display::LOGO_COLOR), " {:>4s} {:>9s} {:>9s} {:>10s} {:>10s} {:>10s} {:>10s} {:>10s}\n",
42 "Bus", "Voltage", "Angle", "Load", "Load", "Gen", "Gen", "Injected");
43 fmt::print(fg(Display::LOGO_COLOR), " {:>4s} {:>9s} {:>9s} {:>10s} {:>10s} {:>10s} {:>10s} {:>10s}\n",
44 "No.", "Mag.", "Degree", "MW", "Mvar", "MW", "Mvar", "Mvar");
45 fmt::print(" {}\n", std::string(76, '='));
46
47 for (int i = 0; i < nbus; ++i) {
48 double injectedMvar = busData.Qg(i) - busData.Ql(i);
49
50 fmt::print(" {:>4d} {:>9.4f} {:>9.4f} {:>10.4f} {:>10.4f} {:>10.4f} {:>10.4f} {:>10.4f}\n",
51 i + 1,
52 busData.V(i),
53 busData.delta(i),
54 busData.Pl(i),
55 busData.Ql(i),
56 busData.Pg(i),
57 busData.Qg(i),
58 injectedMvar);
59 }
60
61 double totalPl = busData.Pl.sum();
62 double totalQl = busData.Ql.sum();
63 double totalPg = busData.Pg.sum();
64 double totalQg = busData.Qg.sum();
65 double totalInjected = totalQg - totalQl;
66
67 fmt::print(" {}\n", std::string(76, '='));
68 fmt::print(" Total{:>27.4f} {:>10.4f} {:>10.4f} {:>10.4f} {:>10.4f}\n",
69 totalPl, totalQl, totalPg, totalQg, totalInjected);
70 fmt::print("\n");
71
72 // Also log to file
73 LOG_INFO("Bus Data Summary: {} buses", nbus);
74}
75
77 const BusData& busData,
78 const BranchData& branchData,
79 const Eigen::MatrixXcd& Y,
80 double basemva
81) {
82 auto Bc = branchData.B;
83 int nBus = static_cast<int>(busData.V.size());
84 int nLine = static_cast<int>(branchData.From.size());
85
86 Eigen::VectorXcd V(nBus);
87 Eigen::VectorXcd S(nBus);
88
89 for (int i = 0; i < V.size(); ++i) {
90 double mag = busData.V(i);
91 double ang_rad = busData.delta(i) * M_PI / 180.0;
92 V(i) = std::polar(mag, ang_rad);
93
94 double P = busData.Pg(i) - busData.Pl(i);
95 double Q = busData.Qg(i) - busData.Ql(i);
96 S(i) = std::complex<double>(P, Q);
97 }
98
99 std::complex<double> SLT = 0.0;
100
101 Display::printSectionHeader("L I N E F L O W A N D L O S S E S");
102
103 fmt::print(fg(Display::LOGO_COLOR), " {:>4s} {:>4s} {:>9s} {:>9s} {:>9s} {:>9s} {:>9s} {:>9s}\n",
104 "From", "To", "MW", "Mvar", "MVA", "Loss MW", "Loss Mvar", "Tap");
105 fmt::print(" {}\n", std::string(76, '='));
106
107 for (int n = 1; n <= nBus; ++n) {
108 int n_idx = n - 1;
109 bool busprt = false;
110
111 for (int L = 0; L < nLine; ++L) {
112 if (!busprt) {
113 double P_inj = busData.Pg(n_idx) - busData.Pl(n_idx);
114 double Q_inj = busData.Qg(n_idx) - busData.Ql(n_idx);
115 double S_mag = std::abs(S(n_idx)) * basemva;
116
117 fmt::print(" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f}\n", n, P_inj, Q_inj, S_mag);
118 busprt = true;
119 }
120
121 if (branchData.From(L) == n) {
122 int k = branchData.To(L);
123 int k_idx = k - 1;
124 double aL = (branchData.tapRatio(L) == 0.0) ? 1.0 : branchData.tapRatio(L);
125
126 std::complex<double> In = (V(n_idx) - aL * V(k_idx)) * Y(L) / (aL * aL) + Bc(L) / (aL * aL) * V(n_idx);
127 std::complex<double> Ik = (V(k_idx) - V(n_idx) / aL) * Y(L) + Bc(L) * V(k_idx);
128
129 std::complex<double> Snk = V(n_idx) * std::conj(In) * basemva;
130 std::complex<double> Skn = V(k_idx) * std::conj(Ik) * basemva;
131 std::complex<double> SL = Snk + Skn;
132
133 SLT += SL;
134
135 if (aL != 1.0) {
136 fmt::print(" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f}\n",
137 k,
138 std::real(Snk),
139 std::imag(Snk),
140 std::abs(Snk),
141 std::real(SL),
142 std::imag(SL),
143 aL);
144 } else {
145 fmt::print(" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f}\n",
146 k,
147 std::real(Snk),
148 std::imag(Snk),
149 std::abs(Snk),
150 std::real(SL),
151 std::imag(SL));
152 }
153
154 } else if (branchData.To(L) == n) {
155 int k = branchData.From(L);
156 int k_idx = k - 1;
157 double aL = (branchData.tapRatio(L) == 0.0) ? 1.0 : branchData.tapRatio(L);
158
159 std::complex<double> In = (V(n_idx) - V(k_idx) / aL) * Y(L) + Bc(L) * V(n_idx);
160 std::complex<double> Ik = (V(k_idx) - aL * V(n_idx)) * Y(L) / (aL * aL) + Bc(L) / (aL * aL) * V(k_idx);
161
162 std::complex<double> Snk = V(n_idx) * std::conj(In) * basemva;
163 std::complex<double> Skn = V(k_idx) * std::conj(Ik) * basemva;
164 std::complex<double> SL = Snk + Skn;
165
166 SLT += SL;
167
168 fmt::print(" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f}\n",
169 k,
170 std::real(Snk),
171 std::imag(Snk),
172 std::abs(Snk),
173 std::real(SL),
174 std::imag(SL));
175 }
176 }
177 }
178
179 SLT /= 2.0;
180
181 fmt::print("\n");
182 fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold,
183 " Total loss {:>9.3f} {:>9.3f}\n",
184 std::real(SLT), std::imag(SLT));
185 fmt::print("\n");
186
187 // Log summary
188 LOG_INFO("Line Flow computed: Total loss P={:.3f} MW, Q={:.3f} Mvar",
189 std::real(SLT), std::imag(SLT));
190}
191
192bool writeOutputCSV(const BusData& busData) {
193 std::ofstream out("deltaFlow.csv");
194 if (!out.is_open()) return false;
195
196 out << "BusID,Name,Type,Voltage,Angle,Pg,Qg,Pl,Ql,Qgmax,Qgmin,Gs,Bs\n";
197 for (int i = 0; i < busData.ID.size(); ++i) {
198 out << busData.ID[i] << ","
199 << busData.Name[i] << ","
200 << busData.Type[i] << ","
201 << std::fixed << std::setprecision(64)
202 << busData.V[i] << ","
203 << busData.delta[i] << ","
204 << busData.Pg[i] << ","
205 << busData.Qg[i] << ","
206 << busData.Pl[i] << ","
207 << busData.Ql[i] << ","
208 << busData.Qgmax[i] << ","
209 << busData.Qgmin[i] << ","
210 << busData.Gs[i] << ","
211 << busData.Bs[i] << "\n";
212 }
213
214 out.close();
215
216 return true;
217}
Data structures and utility functions for reading and displaying bus and branch data in power system ...
Display and formatting utilities for terminal and file output.
Logger utilities for deltaFlow, providing logging macros and a singleton Logger class.
#define LOG_INFO(msg,...)
Macro for logging an info-level message.
Definition Logger.H:86
void dispBusData(const BusData &busData)
Displays bus data in a human-readable format.
Definition Writer.C:36
void dispLineFlow(const BusData &busData, const BranchData &branchData, const Eigen::MatrixXcd &Y, double basemva)
Displays the line flow results, including power flow and losses.
Definition Writer.C:76
bool writeOutputCSV(const BusData &busData)
Writes bus data results to a CSV file.
Definition Writer.C:192
Output utilities for writing power system analysis results to CSV files.
constexpr fmt::rgb LOGO_COLOR
deltaFlow logo color
Definition Display.H:50
void printSectionHeader(const std::string &title)
Prints a colored section header to terminal.
Definition Display.H:325
Contains all relevant data for each transmission line or transformer branch.
Definition Data.H:83
Eigen::VectorXd tapRatio
Transformer tap ratio ($$ a $$)
Definition Data.H:90
Eigen::VectorXd B
Line susceptance ($$ B $$) [p.u.].
Definition Data.H:89
Eigen::VectorXi From
From bus indices.
Definition Data.H:84
Eigen::VectorXi To
To bus indices.
Definition Data.H:85
Contains all relevant data for each bus in the power system.
Definition Data.H:55
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::VectorXi ID
Bus numbers.
Definition Data.H:56
Eigen::VectorXd V
Voltage magnitude [p.u.].
Definition Data.H:60
Eigen::VectorXd Pg
Active power generation [MW or p.u.].
Definition Data.H:62
std::vector< std::string > Name
Bus names.
Definition Data.H:57
Eigen::VectorXd Qgmin
Min reactive power generation [MVAr or p.u.].
Definition Data.H:67
Eigen::VectorXd Gs
Shunt conductance ($$ G_{sh} $$) [p.u.].
Definition Data.H:68
Eigen::VectorXd delta
Voltage angle [rad or deg].
Definition Data.H:61
Eigen::VectorXd Bs
Shunt susceptance ($$ B_{sh} $$) [p.u.].
Definition Data.H:69
Eigen::VectorXd Pl
Active power load [MW or p.u.].
Definition Data.H:64
Eigen::VectorXd Qg
Reactive power generation [MVAr or p.u.].
Definition Data.H:63
Eigen::VectorXi Type
Bus type (1=Slack, 2=PV, 3=PQ)
Definition Data.H:58