Reformat code. Add .gitignore

This commit is contained in:
CismonX 2018-12-13 20:33:02 +08:00
parent 55123fd783
commit e136c1b2c0
7 changed files with 127 additions and 62 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.vscode/
arma-flow
src/*.o
*.csv

View File

@ -32,8 +32,9 @@ namespace flow
bool args::input_file_path(std::string& nodes, std::string& edges) bool args::input_file_path(std::string& nodes, std::string& edges)
{ {
if (!arg_parser_.found("n") || !arg_parser_.found("e")) if (!arg_parser_.found("n") || !arg_parser_.found("e")) {
return false; return false;
}
nodes = arg_parser_.getString("n"); nodes = arg_parser_.getString("n");
edges = arg_parser_.getString("e"); edges = arg_parser_.getString("e");
return true; return true;
@ -69,8 +70,9 @@ namespace flow
bool args::short_circuit(unsigned& node) bool args::short_circuit(unsigned& node)
{ {
if (!arg_parser_.found("s")) if (!arg_parser_.found("s")) {
return false; return false;
}
node = arg_parser_.getInt("s"); node = arg_parser_.getInt("s");
return true; return true;
} }
@ -82,8 +84,9 @@ namespace flow
bool args::transition_impedance(std::complex<double>& z_f) bool args::transition_impedance(std::complex<double>& z_f)
{ {
if (!arg_parser_.found("tr") && !arg_parser_.found("ti")) if (!arg_parser_.found("tr") && !arg_parser_.found("ti")) {
return false; return false;
}
z_f = { arg_parser_.getDouble("tr"), arg_parser_.getDouble("ti") }; z_f = { arg_parser_.getDouble("tr"), arg_parser_.getDouble("ti") };
return true; return true;
} }

View File

@ -11,9 +11,11 @@ namespace flow
{ {
unsigned calc::node_offset(unsigned id) const unsigned calc::node_offset(unsigned id) const
{ {
for (auto offset = 0U; offset < num_nodes_; ++offset) for (auto offset = 0U; offset < num_nodes_; ++offset) {
if (nodes_[offset].id == id) if (nodes_[offset].id == id) {
return offset; return offset;
}
}
return 0; return 0;
} }
@ -30,18 +32,22 @@ namespace flow
double calc::j_elem_a(unsigned row) const double calc::j_elem_a(unsigned row) const
{ {
auto sum = 0.0; auto sum = 0.0;
for (auto col = 0U; col < num_nodes_; ++col) for (auto col = 0U; col < num_nodes_; ++col) {
if (row == col || adj_.at(row, col)) if (row == col || adj_.at(row, col)) {
sum += n_adm_b_.at(row, col) * f_[col] - n_adm_g_.at(row, col) * e_[col]; sum += n_adm_b_.at(row, col) * f_[col] - n_adm_g_.at(row, col) * e_[col];
}
}
return sum; return sum;
} }
double calc::j_elem_c(unsigned row) const double calc::j_elem_c(unsigned row) const
{ {
auto sum = 0.0; auto sum = 0.0;
for (auto col = 0U; col < num_nodes_; ++col) for (auto col = 0U; col < num_nodes_; ++col) {
if (row == col || adj_.at(row, col)) if (row == col || adj_.at(row, col)) {
sum += n_adm_g_.at(row, col) * f_[col] + n_adm_b_.at(row, col) * e_[col]; sum += n_adm_g_.at(row, col) * f_[col] + n_adm_b_.at(row, col) * e_[col];
}
}
return sum; return sum;
} }
@ -49,55 +55,68 @@ namespace flow
{ {
mat_elem_foreach(j_h_, [this](auto& elem, auto row, auto col) mat_elem_foreach(j_h_, [this](auto& elem, auto row, auto col)
{ {
if (row == col) if (row == col) {
elem = j_elem_c(row) - j_elem_d(row); elem = j_elem_c(row) - j_elem_d(row);
else } else {
elem = -j_elem_b_g(row, col); elem = -j_elem_b_g(row, col);
}
}); });
mat_elem_foreach(j_n_, [this](auto& elem, auto row, auto col) mat_elem_foreach(j_n_, [this](auto& elem, auto row, auto col)
{ {
if (row == col) if (row == col) {
elem = -j_elem_a(row) + j_elem_b(row); elem = -j_elem_a(row) + j_elem_b(row);
else } else {
elem = j_elem_g_b(row, col); elem = j_elem_g_b(row, col);
}
}); });
mat_elem_foreach(j_m_, [this](auto& elem, auto row, auto col) mat_elem_foreach(j_m_, [this](auto& elem, auto row, auto col)
{ {
if (row == col) if (row == col) {
elem = -j_elem_a(row) - j_elem_b(row); elem = -j_elem_a(row) - j_elem_b(row);
else } else {
elem = -j_elem_g_b(row, col); elem = -j_elem_g_b(row, col);
}
}); });
mat_elem_foreach(j_l_, [this](auto& elem, auto row, auto col) mat_elem_foreach(j_l_, [this](auto& elem, auto row, auto col)
{ {
if (row == col) if (row == col) {
elem = -j_elem_c(row) - j_elem_d(row); elem = -j_elem_c(row) - j_elem_d(row);
else } else {
elem = -j_elem_b_g(row, col); elem = -j_elem_b_g(row, col);
}
}); });
// We shouldn't start at 0. We should start at m. // We shouldn't start at 0. We should start at m.
mat_elem_foreach(j_r_, [this](auto& elem, auto row, auto col) mat_elem_foreach(j_r_, [this](auto& elem, auto row, auto col)
{ {
if (row + num_pq_ == col) if (row + num_pq_ == col) {
elem = f_[row + num_pq_] * 2; elem = f_[row + num_pq_] * 2;
else } else {
elem = 0; elem = 0;
}
}); });
mat_elem_foreach(j_s_, [this](auto& elem, auto row, auto col) mat_elem_foreach(j_s_, [this](auto& elem, auto row, auto col)
{ {
if (row + num_pq_ == col) if (row + num_pq_ == col) {
elem = e_[row + num_pq_] * 2; elem = e_[row + num_pq_] * 2;
else } else {
elem = 0; elem = 0;
}
}); });
} }
void calc::init(const arma::mat& nodes, const arma::mat& edges, void calc::init(
bool verbose, double epsilon, bool short_circuit, bool ignore_load, const arma::mat& nodes,
unsigned short_circuit_node, const std::complex<double>& z_f) const arma::mat& edges,
bool verbose,
double epsilon,
bool short_circuit,
bool ignore_load,
unsigned short_circuit_node,
const std::complex<double>& z_f)
{ {
if (nodes.n_cols != (short_circuit ? 6 : 5) || edges.n_cols != 6) if (nodes.n_cols != (short_circuit ? 6 : 5) || edges.n_cols != 6) {
writer::error("Bad input matrix format."); writer::error("Bad input matrix format.");
}
short_circuit_ = short_circuit; short_circuit_ = short_circuit;
nodes.each_row([this](const arma::rowvec& row) nodes.each_row([this](const arma::rowvec& row)
{ {
@ -109,8 +128,9 @@ namespace flow
} else if (type_val == 2) { } else if (type_val == 2) {
type = node_data::pv; type = node_data::pv;
++num_pv_; ++num_pv_;
} else if (type_val != 0) } else if (type_val != 0) {
writer::error("Bad node type."); writer::error("Bad node type.");
}
if (short_circuit_) { if (short_circuit_) {
nodes_.push_back({ nodes_.push_back({
num_nodes_++, row[0], row[1], row[2], row[3], row[4], type num_nodes_++, row[0], row[1], row[2], row[3], row[4], type
@ -128,14 +148,16 @@ namespace flow
return n1.type < n2.type; return n1.type < n2.type;
}); });
adj_.zeros(num_nodes_, num_nodes_); adj_.zeros(num_nodes_, num_nodes_);
if (num_nodes_ != num_pq_ + num_pv_ + 1) if (num_nodes_ != num_pq_ + num_pv_ + 1) {
writer::error("Only one swing node should exist."); writer::error("Only one swing node should exist.");
}
edges.each_row([this](const arma::rowvec& row) edges.each_row([this](const arma::rowvec& row)
{ {
const auto n1 = static_cast<unsigned>(row[0]) - 1; const auto n1 = static_cast<unsigned>(row[0]) - 1;
const auto n2 = static_cast<unsigned>(row[1]) - 1; const auto n2 = static_cast<unsigned>(row[1]) - 1;
if (n1 >= num_nodes_ || n2 >= num_nodes_) if (n1 >= num_nodes_ || n2 >= num_nodes_) {
writer::error("Bad node offset."); writer::error("Bad node offset.");
}
edges_.push_back({ edges_.push_back({
n1, n2, row[2], row[3], row[4], row[5] n1, n2, row[2], row[3], row[4], row[5]
}); });
@ -143,8 +165,9 @@ namespace flow
verbose_ = verbose; verbose_ = verbose;
epsilon_ = epsilon; epsilon_ = epsilon;
ignore_load_ = ignore_load; ignore_load_ = ignore_load;
if (short_circuit_node < 1 || short_circuit_node > num_nodes_) if (short_circuit_node < 1 || short_circuit_node > num_nodes_) {
writer::error("Bad node ID for short circuit calculation."); writer::error("Bad node ID for short circuit calculation.");
}
short_circuit_node_ = node_offset(short_circuit_node - 1); short_circuit_node_ = node_offset(short_circuit_node - 1);
z_f_ = z_f; z_f_ = z_f;
} }
@ -311,8 +334,9 @@ namespace flow
unsigned calc::solve() unsigned calc::solve()
{ {
if (verbose_) if (verbose_) {
writer::println("Number of iterations: ", n_iter_, " (begin)"); writer::println("Number of iterations: ", n_iter_, " (begin)");
}
jacobian(); jacobian();
prepare_solve(); prepare_solve();
const auto x_vec = spsolve(j_, f_x_, "superlu"); const auto x_vec = spsolve(j_, f_x_, "superlu");
@ -331,8 +355,9 @@ namespace flow
writer::print_mat(f_.t()); writer::print_mat(f_.t());
} }
update_f_x(); update_f_x();
if (verbose_) if (verbose_) {
writer::println("Number of iterations: ", n_iter_, " (end)"); writer::println("Number of iterations: ", n_iter_, " (end)");
}
return n_iter_++; return n_iter_++;
} }
@ -340,40 +365,48 @@ namespace flow
{ {
arma::mat mat = join_cols(join_cols(delta_p_, delta_q_), delta_v_); arma::mat mat = join_cols(join_cols(delta_p_, delta_q_), delta_v_);
auto max = 0.0; auto max = 0.0;
for (auto&& elem : mat) for (auto&& elem : mat) {
if (std::abs(elem) > max) if (std::abs(elem) > max) {
max = std::abs(elem); max = std::abs(elem);
}
}
return max; return max;
} }
arma::mat calc::result() arma::mat calc::result()
{ {
p_[num_nodes_ - 1] = calc_p(num_nodes_ - 1); p_[num_nodes_ - 1] = calc_p(num_nodes_ - 1);
for (auto&& elem : p_) for (auto&& elem : p_) {
if (approx_zero(elem)) if (approx_zero(elem)) {
elem = 0; elem = 0;
}
}
vec_elem_foreach(delta_v_, [this](auto& elem, auto row) vec_elem_foreach(delta_v_, [this](auto& elem, auto row)
{ {
auto i = row + num_pq_; auto i = row + num_pq_;
q_[i] = calc_q(i); q_[i] = calc_q(i);
}); });
q_[num_nodes_ - 1] = calc_q(num_nodes_ - 1); q_[num_nodes_ - 1] = calc_q(num_nodes_ - 1);
for (auto&& elem : q_) for (auto&& elem : q_) {
if (approx_zero(elem)) if (approx_zero(elem)) {
elem = 0; elem = 0;
}
}
v_.zeros(num_nodes_); v_.zeros(num_nodes_);
vec_elem_foreach(v_, [this](auto& elem, auto col) vec_elem_foreach(v_, [this](auto& elem, auto col)
{ {
elem = std::sqrt(std::pow(e_[col], 2) + std::pow(f_[col], 2)); elem = std::sqrt(std::pow(e_[col], 2) + std::pow(f_[col], 2));
if (approx_zero(elem)) if (approx_zero(elem)) {
elem = 0; elem = 0;
}
}); });
arma::colvec theta(num_nodes_); arma::colvec theta(num_nodes_);
vec_elem_foreach(theta, [this](auto& elem, auto row) vec_elem_foreach(theta, [this](auto& elem, auto row)
{ {
elem = std::atan(f_[row] / e_[row]); elem = std::atan(f_[row] / e_[row]);
if (approx_zero(elem)) if (approx_zero(elem)) {
elem = 0; elem = 0;
}
}); });
arma::colvec node_id(num_nodes_); arma::colvec node_id(num_nodes_);
vec_elem_foreach(node_id, [this](auto& elem, auto row) vec_elem_foreach(node_id, [this](auto& elem, auto row)
@ -393,10 +426,11 @@ namespace flow
std::complex<double> calc::short_circuit_current() std::complex<double> calc::short_circuit_current()
{ {
const auto n = short_circuit_node_; const auto n = short_circuit_node_;
if (ignore_load_) if (ignore_load_) {
i_f_ = 1; i_f_ = 1;
else } else {
i_f_ = { e_[n], f_[n] }; i_f_ = { e_[n], f_[n] };
}
i_f_ /= std::complex<double>(n_imp_g_.at(n, n), n_imp_b_.at(n, n)) + z_f_; i_f_ /= std::complex<double>(n_imp_g_.at(n, n), n_imp_b_.at(n, n)) + z_f_;
return i_f_; return i_f_;
} }
@ -415,10 +449,12 @@ namespace flow
} }
elem = u_f - cx(n_imp_g_.at(row, n), n_imp_b_.at(row, n)) * elem = u_f - cx(n_imp_g_.at(row, n), n_imp_b_.at(row, n)) *
(u_i / (cx(n_imp_g_.at(n, n), n_imp_b_.at(n, n)) + z_f_)); (u_i / (cx(n_imp_g_.at(n, n), n_imp_b_.at(n, n)) + z_f_));
if (approx_zero(elem.real())) if (approx_zero(elem.real())) {
elem.real(0); elem.real(0);
if (approx_zero(elem.imag())) }
if (approx_zero(elem.imag())) {
elem.imag(0); elem.imag(0);
}
}); });
arma::cx_colvec u_f_orig(num_nodes_); arma::cx_colvec u_f_orig(num_nodes_);
vec_elem_foreach(u_f_, [&u_f_orig, this](auto&& elem, auto row) vec_elem_foreach(u_f_, [&u_f_orig, this](auto&& elem, auto row)
@ -427,8 +463,9 @@ namespace flow
}); });
if (verbose_) { if (verbose_) {
writer::println("Short circuit node voltage:"); writer::println("Short circuit node voltage:");
for (auto&& elem : u_f_orig) for (auto&& elem : u_f_orig) {
writer::print_complex("", elem); writer::print_complex("", elem);
}
} }
return join_rows(arma::real(u_f_orig), arma::imag(u_f_orig)); return join_rows(arma::real(u_f_orig), arma::imag(u_f_orig));
} }
@ -444,9 +481,10 @@ namespace flow
const auto m = node_offset(edge.m); const auto m = node_offset(edge.m);
const auto n = node_offset(edge.n); const auto n = node_offset(edge.n);
edge_current[i] = (u_f_[m] - u_f_[n] / (edge.k ? edge.k : 1)) * admittance; edge_current[i] = (u_f_[m] - u_f_[n] / (edge.k ? edge.k : 1)) * admittance;
if (verbose_) if (verbose_) {
writer::print_complex(std::to_string(edge.m + 1) + ',' + writer::print_complex(std::to_string(edge.m + 1) + ',' +
std::to_string(edge.n + 1) + ": ", edge_current[i]); std::to_string(edge.n + 1) + ": ", edge_current[i]);
}
++i; ++i;
} }
return join_rows(arma::real(edge_current), arma::imag(edge_current)); return join_rows(arma::real(edge_current), arma::imag(edge_current));

View File

@ -273,9 +273,15 @@ namespace flow
/** /**
* Initialize. * Initialize.
*/ */
void init(const arma::mat& nodes, const arma::mat& edges, void init(
bool verbose, double epsilon, bool short_circuit, bool ignore_load, const arma::mat& nodes,
unsigned short_circuit_node, const std::complex<double>& z_f); const arma::mat& edges,
bool verbose,
double epsilon,
bool short_circuit,
bool ignore_load,
unsigned short_circuit_node,
const std::complex<double>& z_f);
/** /**
* Calculate node admittance. * Calculate node admittance.

View File

@ -25,35 +25,43 @@ namespace flow
// Read data from file. // Read data from file.
std::string path_to_nodes, path_to_edges; std::string path_to_nodes, path_to_edges;
if (!args->input_file_path(path_to_nodes, path_to_edges)) if (!args->input_file_path(path_to_nodes, path_to_edges)) {
args->help(); args->help();
}
const auto remove = args->remove_first_line(); const auto remove = args->remove_first_line();
if (!input->from_csv_file(path_to_nodes, remove)) if (!input->from_csv_file(path_to_nodes, remove)) {
writer::error("Failed to read node data from file."); writer::error("Failed to read node data from file.");
}
const auto nodes = input->get_mat(); const auto nodes = input->get_mat();
if (!input->from_csv_file(path_to_edges, remove)) if (!input->from_csv_file(path_to_edges, remove)) {
writer::error("Failed to read edge data from file."); writer::error("Failed to read edge data from file.");
}
const auto edges = input->get_mat(); const auto edges = input->get_mat();
// Get options. // Get options.
const auto verbose = args->verbose(); const auto verbose = args->verbose();
auto max = 0U; auto max = 0U;
if (!args->max_iterations(max) && verbose) if (!args->max_iterations(max) && verbose) {
writer::notice("Max number of iterations not specified. Defaulted to 100."); writer::notice("Max number of iterations not specified. Defaulted to 100.");
}
auto epsilon = 0.0; auto epsilon = 0.0;
if (!args->accuracy(epsilon) && verbose) if (!args->accuracy(epsilon) && verbose) {
writer::notice("Accuracy not specified. Defaulted to 0.00001."); writer::notice("Accuracy not specified. Defaulted to 0.00001.");
if (epsilon < 0 || epsilon > 1) }
if (epsilon < 0 || epsilon > 1) {
writer::error("Invalid accuracy."); writer::error("Invalid accuracy.");
}
std::string output_path; std::string output_path;
if (!args->output_file_path(output_path) && verbose) if (!args->output_file_path(output_path) && verbose) {
writer::notice("Output file path not specified. Defaulted to result-*.csv."); writer::notice("Output file path not specified. Defaulted to result-*.csv.");
}
writer->set_output_path_prefix(output_path); writer->set_output_path_prefix(output_path);
unsigned short_circuit_node; unsigned short_circuit_node;
const auto short_circuit = args->short_circuit(short_circuit_node); const auto short_circuit = args->short_circuit(short_circuit_node);
std::complex<double> transition_impedance; std::complex<double> transition_impedance;
if (short_circuit && !args->transition_impedance(transition_impedance) && verbose) if (short_circuit && !args->transition_impedance(transition_impedance) && verbose) {
writer::notice("Transition impedance not specified, Defaulted to 0."); writer::notice("Transition impedance not specified, Defaulted to 0.");
}
const auto ignore_load = args->ignore_load(); const auto ignore_load = args->ignore_load();
// Initialize calculation. // Initialize calculation.
@ -84,8 +92,9 @@ namespace flow
flow_done: flow_done:
// Calculate three-phase short circuit. // Calculate three-phase short circuit.
if (!short_circuit) if (!short_circuit) {
return; return;
}
const auto impedance = calc->node_impedance(); const auto impedance = calc->node_impedance();
writer->to_csv_file("node-impedance-real.csv", impedance.first); writer->to_csv_file("node-impedance-real.csv", impedance.first);
writer->to_csv_file("node-impedance-imag.csv", impedance.second); writer->to_csv_file("node-impedance-imag.csv", impedance.second);

View File

@ -23,8 +23,9 @@ namespace flow
path[0] == '/' path[0] == '/'
#endif // _WIN32 #endif // _WIN32
? path : fs::current_path().string() + '/' + path); ? path : fs::current_path().string() + '/' + path);
if (remove_first_line) if (remove_first_line) {
ifstream.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); ifstream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return do_read(ifstream); return do_read(ifstream);
} }
catch (const std::exception&) { catch (const std::exception&) {

View File

@ -20,13 +20,15 @@ namespace flow
{ {
#ifdef _WIN32 #ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi; CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
return 10; return 10;
}
const auto width = csbi.dwSize.X; const auto width = csbi.dwSize.X;
#else #else
winsize win; winsize win;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1) if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1) {
return 10; return 10;
}
const auto width = win.ws_col; const auto width = win.ws_col;
#endif // _WIN32 #endif // _WIN32
return std::floor((width - 7) / 11); return std::floor((width - 7) / 11);
@ -36,8 +38,9 @@ namespace flow
{ {
auto str = std::to_string(val ? val : std::abs(val)); auto str = std::to_string(val ? val : std::abs(val));
auto pos = str.find_last_not_of('0'); auto pos = str.find_last_not_of('0');
if (pos == 0 || str[pos] == '.') if (pos == 0 || str[pos] == '.') {
--pos; --pos;
}
return str.substr(0, pos + 1); return str.substr(0, pos + 1);
} }
@ -85,8 +88,9 @@ namespace flow
{ {
for (auto col = 0U; col < row.n_elem; ++col) { for (auto col = 0U; col < row.n_elem; ++col) {
ofstream << double_to_string(row[col]); ofstream << double_to_string(row[col]);
if (col != row.n_elem - 1) if (col != row.n_elem - 1) {
ofstream << ','; ofstream << ',';
}
} }
ofstream << std::endl; ofstream << std::endl;
}); });