Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d3a4dcf
link-less implementation
figueroa1395 Aug 14, 2026
5ece020
link-less testing
figueroa1395 Aug 14, 2026
b204224
code quality
figueroa1395 Aug 19, 2026
8e5d0a3
Merge branch 'main' into pgm/feature/link-supernode-output
figueroa1395 Aug 19, 2026
47122b8
activate link solver
figueroa1395 Aug 19, 2026
7903df9
cleanup: ComplexVector
figueroa1395 Aug 19, 2026
c7159ec
tests for link solver output
mgovers Aug 20, 2026
3d0fab7
cleanup
mgovers Aug 20, 2026
877fcbd
address comments
figueroa1395 Aug 20, 2026
2e7989e
futher testing of link addition
figueroa1395 Aug 20, 2026
aedb8ac
clang-tidy + gcc
mgovers Aug 21, 2026
de6b24b
Merge branch 'main' into pgm/feature/link-supernode-output
figueroa1395 Aug 21, 2026
1dc682e
format
figueroa1395 Aug 21, 2026
11e1b67
remove reference_wrapper around lambda
mgovers Aug 24, 2026
4d72d0b
add link i_f and i_t to supernode output
mgovers Aug 24, 2026
8c06dff
nipick
mgovers Aug 24, 2026
6db6e33
fix
mgovers Aug 24, 2026
bde7b26
remove comment
mgovers Aug 24, 2026
13e7e4d
fix segfault
mgovers Aug 24, 2026
bab3fe3
test i_ft
mgovers Aug 24, 2026
6e3bdd5
format
mgovers Aug 24, 2026
b062aba
fix comment
mgovers Aug 24, 2026
1abfe22
resolve comments
mgovers Aug 24, 2026
40a8df0
minor
mgovers Aug 24, 2026
6bb6e79
minor
mgovers Aug 24, 2026
0807584
clang-tidy
mgovers Aug 24, 2026
db5adc7
remove redundant
mgovers Aug 24, 2026
ece4723
fix doctest almost equal
mgovers Aug 24, 2026
f2f3a38
work around gcc issue
mgovers Aug 25, 2026
c8304a7
Merge branch 'main' into pgm/feature/link-supernode-output
mgovers Aug 25, 2026
7b3e9b4
mock component container with edge
mgovers Aug 25, 2026
2a99d53
clang-tidy
mgovers Aug 26, 2026
0a16d2c
Merge branch 'main' into pgm/feature/link-supernode-output
mgovers Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
LimitViolation q_limit_violated{LimitViolation::none};
};

// TODO(mgovers): cleanup v2: branch solver output should always be in current domain; conversion to power domain should

Check warning on line 51 in power_grid_model_c/power_grid_model/include/power_grid_model/calculation_parameters.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=PowerGridModel_power-grid-model&issues=AaA0KUwus3ud2sinmb2j&open=AaA0KUwus3ud2sinmb2j&pullRequest=1536
// be done in main_core/output.hpp
template <symmetry_tag sym_type> struct BranchSolverOutput {
using sym = sym_type;

Expand Down Expand Up @@ -82,7 +84,8 @@
template <symmetry_tag sym_type> struct ApplianceSolverOutput {
using sym = sym_type;

ComplexValue<sym> s{};
ComplexValue<sym> s{}; // TODO(mgovers): cleanup v2: appliance solver output should always be in current domain;

Check warning on line 87 in power_grid_model_c/power_grid_model/include/power_grid_model/calculation_parameters.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=PowerGridModel_power-grid-model&issues=AaA0KUwus3ud2sinmb2k&open=AaA0KUwus3ud2sinmb2k&pullRequest=1536
// conversion to power domain should be done in main_core/output.hpp
ComplexValue<sym> i{};
};
template <symmetry_tag sym_type> struct ApplianceShortCircuitSolverOutput {
Expand Down Expand Up @@ -410,13 +413,13 @@
template <steady_state_solver_output_type SolverOutputType> struct SupernodeOutput<SolverOutputType> {
using sym = decode_symmetry_v<SolverOutputType>;

ComplexValueVector<sym> bus_injection; // user bus output
BranchSolverOutput<sym> branch; // user link
ComplexValueVector<sym> bus_injection; // user bus output
std::vector<BranchSolverOutput<sym>> link; // user link
};
template <short_circuit_solver_output_type SolverOutputType> struct SupernodeOutput<SolverOutputType> {
using sym = decode_symmetry_v<SolverOutputType>;

BranchShortCircuitSolverOutput<sym> branch; // user link
std::vector<BranchShortCircuitSolverOutput<sym>> link; // user link
};

template <typename T> struct MathOutput {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct EdgeHistory {

struct ReducedEchelonForm {
CooSparseMatrix matrix{};
std::vector<DoubleComplex> rhs{}; // RHS value at each pivot row
ComplexVector rhs{}; // RHS value at each pivot row
std::vector<Idx> free_edge_indices{}; // index of degrees of freedom (self loop edges)
std::vector<Idx> pivot_edge_indices{}; // index of pivot edges
std::vector<EdgeHistory> edges_history{}; // edges elimination history
Expand Down Expand Up @@ -134,8 +134,7 @@ inline void update_edge_info(Idx edge_idx, Idx matrix_row, std::vector<BranchIdx
// forward elimination is performed via a modified Gaussian elimination procedure
// we name this procedure elimination-game
// node_loads convention: caller passes negated external loads (as in RHS of power flow equations))
inline void forward_elimination(ReducedEchelonForm& result, std::vector<BranchIdx> edges,
std::vector<DoubleComplex> node_loads) {
inline void forward_elimination(ReducedEchelonForm& result, std::vector<BranchIdx> edges, ComplexVector node_loads) {
using enum EdgeEvent;
using enum EdgeDirection;

Expand Down Expand Up @@ -229,7 +228,7 @@ inline void backward_substitution(ReducedEchelonForm& elimination_result) {

// reduced echelon form based on custom forward elimination and backward substitution procedures
// in other words, this performs the Penrose inverse on the adjacency matrix
inline ReducedEchelonForm reduced_echelon_form(std::vector<BranchIdx> edges, std::vector<DoubleComplex> node_loads) {
inline ReducedEchelonForm reduced_echelon_form(std::vector<BranchIdx> edges, ComplexVector node_loads) {
auto const edge_number{narrow_cast<Idx>(edges.size())};

ReducedEchelonForm result{};
Expand All @@ -249,7 +248,7 @@ inline ReducedEchelonForm reduced_echelon_form(std::vector<BranchIdx> edges, std
// internal_loads = extended_rhs - dfs_matrix * lambda
struct SolutionSet {
CooSparseMatrix dfs_matrix{};
std::vector<DoubleComplex> extended_rhs{};
ComplexVector extended_rhs{};
};

// Constructs the dfs_matrix and the extended_rhs for the set of solutions.
Expand Down Expand Up @@ -289,10 +288,9 @@ inline SolutionSet set_solution_system(ReducedEchelonForm& result) {
return solution_set;
};

inline std::vector<std::vector<DoubleComplex>> set_projection_system(Idx free_indices_number, Idx total_indices_number,
SolutionSet& solution_set) {
std::vector<std::vector<DoubleComplex>> projection_system(free_indices_number,
std::vector<DoubleComplex>(free_indices_number + 1));
inline std::vector<ComplexVector> set_projection_system(Idx free_indices_number, Idx total_indices_number,
SolutionSet& solution_set) {
std::vector<ComplexVector> projection_system(free_indices_number, ComplexVector(free_indices_number + 1));

for (Idx dfs_matrix_col = 0; dfs_matrix_col < free_indices_number; dfs_matrix_col++) {
auto dot_product_rhs = DoubleComplex{};
Expand Down Expand Up @@ -324,7 +322,7 @@ inline std::vector<std::vector<DoubleComplex>> set_projection_system(Idx free_in
return projection_system;
};

inline void naive_gauss_elimination(std::vector<std::vector<DoubleComplex>>& system) {
inline void naive_gauss_elimination(std::vector<ComplexVector>& system) {
auto const system_size = narrow_cast<Idx>(std::ssize(system));

// we skip pivoting since the matrix system is mostly diagonally dominant
Expand Down Expand Up @@ -359,11 +357,10 @@ inline void naive_gauss_elimination(std::vector<std::vector<DoubleComplex>>& sys
}
};

inline std::vector<DoubleComplex> compute_internal_loads(SolutionSet const& solution_set,
std::span<std::vector<DoubleComplex> const> system) {
inline ComplexVector compute_internal_loads(SolutionSet const& solution_set, std::span<ComplexVector const> system) {
auto const number_of_rows = narrow_cast<Idx>(std::ranges::ssize(solution_set.extended_rhs));
auto const number_of_columns = narrow_cast<Idx>(std::ranges::ssize(system));
std::vector<DoubleComplex> internal_loads(number_of_rows);
ComplexVector internal_loads(number_of_rows);

for (auto const row : IdxRange{number_of_rows}) {
internal_loads[row] = solution_set.extended_rhs[row];
Expand All @@ -382,8 +379,7 @@ inline std::vector<DoubleComplex> compute_internal_loads(SolutionSet const& solu
};
} // namespace detail

inline std::vector<DoubleComplex> compute_loads_link_elements(std::vector<BranchIdx> edges,
std::vector<DoubleComplex> node_loads) {
inline ComplexVector compute_loads_link_elements(std::vector<BranchIdx> edges, ComplexVector node_loads) {
using namespace detail;

auto reduced_echelon_result = reduced_echelon_form(std::move(edges), std::move(node_loads));
Expand All @@ -396,7 +392,7 @@ inline std::vector<DoubleComplex> compute_loads_link_elements(std::vector<Branch
auto const free_indices_number = narrow_cast<Idx>(std::ranges::ssize(reduced_echelon_result.free_edge_indices));
auto const total_indices_number = narrow_cast<Idx>(std::ranges::ssize(reduced_echelon_result.free_edge_indices) +
std::ranges::ssize(reduced_echelon_result.pivot_edge_indices));
std::vector<std::vector<DoubleComplex>> projection_system =
std::vector<ComplexVector> projection_system =
set_projection_system(free_indices_number, total_indices_number, solution_set);

naive_gauss_elimination(projection_system);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
auto const& solver_output = math_output.solver_output[math_id.group];

auto const& component_type_output = [&solver_output]() -> auto const& {
if constexpr (std::derived_from<Component, Branch> || std::derived_from<Component, Branch3>) {
// TODO(mgovers): cleanup v2: change back to std::derived_from<Component, Branch>

Check warning on line 28 in power_grid_model_c/power_grid_model/include/power_grid_model/main_core/math_output_queries.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=PowerGridModel_power-grid-model&issues=AaA9HbDhlYqs4SuZF-M4&open=AaA9HbDhlYqs4SuZF-M4&pullRequest=1536
if constexpr (std::derived_from<Component, Edge> || std::derived_from<Component, Branch3>) {
return solver_output.branch;
} else if constexpr (std::same_as<Component, Source> && requires { solver_output.source; }) {
return solver_output.source;
Expand Down
Loading
Loading