31 const std::string& jobName,
32 const std::string& inputFile,
33 const std::string& solverName,
34 const std::string& formatName,
37 const Eigen::MatrixXcd& Y,
44 std::string outFile = jobName +
".out";
45 std::ofstream out(outFile);
46 if (!out.is_open())
return false;
48 int nBus = busData.
V.size();
49 int nBranch = branchData.
From.size();
54 out << fmt::format(
"\n deltaFlow v{:<32s}Date {:>14s} Time {:>8s}\n",
60 out << fmt::format(
" CMake Version : {}\n", CMake_VERSION);
61 out << fmt::format(
" Compiler Version : GCC {}\n", gcc_VERSION);
62 out << fmt::format(
" deltaFlow Version : {}\n", deltaFlow_VERSION);
66 out << fmt::format(
" Job Name : {}\n", jobName);
67 out << fmt::format(
" Input File : {}\n", inputFile);
68 out << fmt::format(
" Input Format : {}\n", formatName);
69 out << fmt::format(
" Solver Method : {}\n", solverName);
70 out << fmt::format(
" Convergence Tol. : {:.6e}\n", tolerance);
77 out << fmt::format(
" Number of Buses : {:>6d}\n", nBus);
78 out << fmt::format(
" Slack Buses : {:>6d}\n", counts.nSlack);
79 out << fmt::format(
" PV Buses : {:>6d}\n", counts.nPV);
80 out << fmt::format(
" PQ Buses : {:>6d}\n", counts.nPQ);
81 out << fmt::format(
" Number of Branches : {:>6d}\n", nBranch);
82 out << fmt::format(
" Base MVA : {:>10.1f}\n", basemva);
86 out << fmt::format(
" Method : {}\n", solverName);
87 out << fmt::format(
" Iterations : {:>6d}\n", iterations);
88 out << fmt::format(
" Final Error : {:.6e}\n", finalError);
89 out << fmt::format(
" Tolerance : {:.6e}\n", tolerance);
90 out << fmt::format(
" Status : CONVERGED\n");
91 out << fmt::format(
" Elapsed Time (sec) : {:.3f}\n", elapsedSec);
95 out << fmt::format(
" {:>4s} {:>9s} {:>9s} {:>10s} {:>10s} {:>10s} {:>10s} {:>10s}\n",
96 "Bus",
"Voltage",
"Angle",
"Load",
"Load",
"Gen",
"Gen",
"Injected");
97 out << fmt::format(
" {:>4s} {:>9s} {:>9s} {:>10s} {:>10s} {:>10s} {:>10s} {:>10s}\n",
98 "No.",
"Mag.",
"Degree",
"MW",
"Mvar",
"MW",
"Mvar",
"Mvar");
99 out <<
" " << std::string(W - 4,
'=') <<
"\n";
101 for (
int i = 0; i < nBus; ++i) {
102 double injectedMvar = busData.
Qg(i) - busData.
Ql(i);
103 out << fmt::format(
" {:>4d} {:>9.4f} {:>9.4f} {:>10.4f} {:>10.4f} {:>10.4f} {:>10.4f} {:>10.4f}\n",
104 i + 1, busData.
V(i), busData.
delta(i),
105 busData.
Pl(i), busData.
Ql(i), busData.
Pg(i), busData.
Qg(i), injectedMvar);
110 out <<
" " << std::string(W - 4,
'=') <<
"\n";
111 out << fmt::format(
" Total{:>27.4f} {:>10.4f} {:>10.4f} {:>10.4f} {:>10.4f}\n",
112 totals.totalPl, totals.totalQl, totals.totalPg, totals.totalQg, totals.totalInjected);
116 out << fmt::format(
" {:>4s} {:>4s} {:>9s} {:>9s} {:>9s} {:>9s} {:>9s} {:>9s}\n",
117 "From",
"To",
"MW",
"Mvar",
"MVA",
"Loss MW",
"Loss Mvar",
"Tap");
118 out <<
" " << std::string(W - 4,
'=') <<
"\n";
120 auto Bc = branchData.
B;
123 Eigen::VectorXcd Vc(nBus);
124 Eigen::VectorXcd S(nBus);
125 for (
int i = 0; i < nBus; ++i) {
126 double mag = busData.
V(i);
127 double ang_rad = busData.
delta(i) * M_PI / 180.0;
128 Vc(i) = std::polar(mag, ang_rad);
129 double P = busData.
Pg(i) - busData.
Pl(i);
130 double Q = busData.
Qg(i) - busData.
Ql(i);
131 S(i) = std::complex<double>(P, Q);
134 std::complex<double> SLT = 0.0;
136 for (
int n = 1; n <= nBus; ++n) {
140 for (
int L = 0; L < nLine; ++L) {
142 double P_inj = busData.
Pg(n_idx) - busData.
Pl(n_idx);
143 double Q_inj = busData.
Qg(n_idx) - busData.
Ql(n_idx);
144 double S_mag = std::abs(S(n_idx)) * basemva;
145 out << fmt::format(
" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f}\n",
146 n, P_inj, Q_inj, S_mag);
150 auto writeLineFlow = [&](
int from,
int to,
int L) {
151 int f_idx = from - 1;
155 std::complex<double> In, Ik;
156 if (branchData.
From(L) == from) {
157 In = (Vc(f_idx) - aL * Vc(t_idx)) * Y(L) / (aL * aL) + Bc(L) / (aL * aL) * Vc(f_idx);
158 Ik = (Vc(t_idx) - Vc(f_idx) / aL) * Y(L) + Bc(L) * Vc(t_idx);
160 In = (Vc(f_idx) - Vc(t_idx) / aL) * Y(L) + Bc(L) * Vc(f_idx);
161 Ik = (Vc(t_idx) - aL * Vc(f_idx)) * Y(L) / (aL * aL) + Bc(L) / (aL * aL) * Vc(t_idx);
163 std::complex<double> Snk = Vc(f_idx) * std::conj(In) * basemva;
164 std::complex<double> Skn = Vc(t_idx) * std::conj(Ik) * basemva;
165 std::complex<double> SL = Snk + Skn;
169 out << fmt::format(
" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f}\n",
170 to, std::real(Snk), std::imag(Snk), std::abs(Snk),
171 std::real(SL), std::imag(SL), aL);
173 out << fmt::format(
" {:>4d} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f} {:>9.3f}\n",
174 to, std::real(Snk), std::imag(Snk), std::abs(Snk),
175 std::real(SL), std::imag(SL));
179 if (branchData.
From(L) == n) {
180 writeLineFlow(n, branchData.
To(L), L);
181 }
else if (branchData.
To(L) == n) {
182 writeLineFlow(n, branchData.
From(L), L);
189 out << fmt::format(
" Total loss {:>9.3f} {:>9.3f}\n",
190 std::real(SLT), std::imag(SLT));
195 out <<
" JOB TIME SUMMARY\n";
196 out << fmt::format(
" TOTAL CPU TIME (SEC) = {:>12.5f}\n", elapsedSec);
197 out << fmt::format(
" WALLCLOCK TIME (SEC) = {:>12d}\n",
static_cast<int>(std::round(elapsedSec)));
201 out <<
Display::center(
"THE ANALYSIS HAS BEEN COMPLETED SUCCESSFULLY") <<
"\n";
bool write(const std::string &jobName, const std::string &inputFile, const std::string &solverName, const std::string &formatName, const BusData &busData, const BranchData &branchData, const Eigen::MatrixXcd &Y, int iterations, double finalError, double tolerance, double elapsedSec, double basemva=100.0) const
Writes the main output file (.out) with full analysis results.