Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace indptr with sparse and dense grouped index vector #402

Merged
merged 37 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
060ae65
apply indptr replace source bus (still segfaults)
mgovers Oct 10, 2023
f7d4772
fix source count
mgovers Oct 10, 2023
330d460
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 11, 2023
d222f58
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 11, 2023
a262749
Merge branch 'feature/refactor-indptr' into feature/refactor-replace-…
mgovers Oct 11, 2023
888c712
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 11, 2023
21e6a48
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 11, 2023
15f0dc0
use concept for grouped idx ptr
mgovers Oct 11, 2023
4e784b1
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 11, 2023
6dc2ca5
sneak in non-cached version badges (not perfect but it's something)
mgovers Oct 11, 2023
12e97e2
source buses are dense
mgovers Oct 11, 2023
23ca204
cleaner tests
mgovers Oct 11, 2023
f86d317
replace shunt indptr
mgovers Oct 11, 2023
a13e26b
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 11, 2023
c008a89
replace load gen indptrs by grouped
mgovers Oct 12, 2023
624822f
replace voltage sensor indptr
mgovers Oct 12, 2023
dbf3104
rename to components per bus
mgovers Oct 12, 2023
ff489ff
also replace source power sensors
mgovers Oct 12, 2023
e539494
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 12, 2023
865c7df
also replace power sensors per load gen
mgovers Oct 12, 2023
46098a9
also replace indptr on power sensor on branch to/from
mgovers Oct 12, 2023
b1d5aec
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 12, 2023
f515481
Merge remote-tracking branch 'origin/feature/refactor-indptr' into fe…
mgovers Oct 12, 2023
a4acffd
fix power sensor on branch to
mgovers Oct 12, 2023
7ccd987
finally also replace power sensor on bus indptr
mgovers Oct 12, 2023
6c80ebb
clang-tidy + sonar cloud
mgovers Oct 12, 2023
37c8f14
remove more TODOs
mgovers Oct 12, 2023
2202da1
attempt fix clang tidy
mgovers Oct 13, 2023
5ba071e
more clang-tidy
mgovers Oct 13, 2023
0708757
fix
mgovers Oct 13, 2023
12704ff
Merge branch 'main' into feature/refactor-replace-indptrs
mgovers Oct 13, 2023
813fcf6
fix movable object
mgovers Oct 13, 2023
df06d8f
sonar cloud
mgovers Oct 13, 2023
9255376
sonar cloud
mgovers Oct 13, 2023
cbc11d5
sonar cloud
mgovers Oct 13, 2023
7673b5f
fix
mgovers Oct 13, 2023
924eb49
fix performance issue
mgovers Oct 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"environment": {
"CC": "clang-cl.exe",
"CXX": "clang-cl.exe",
"CXXFLAGS": "$penv{CXXFLAGS} -Wno-uninitialized-const-reference"
"CXXFLAGS": "$penv{CXXFLAGS} -Wno-uninitialized-const-reference -Wno-unknown-attributes"
},
"inherits": "windows-base"
},
Expand All @@ -115,7 +115,7 @@
"CMAKE_C_CLANG_TIDY": "clang-tidy.exe;--extra-arg=/EHsc",
"CMAKE_CXX_CLANG_TIDY": "clang-tidy.exe;--extra-arg=/EHsc"
},
"inherits": "windows-base",
"inherits": "clang-cl-base",
"hidden": true
},
{
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ SPDX-FileCopyrightText: 2022 Contributors to the Power Grid Model project <dynam

SPDX-License-Identifier: MPL-2.0
-->
[![PyPI version](https://badge.fury.io/py/power-grid-model.svg)](https://badge.fury.io/py/power-grid-model)
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/power-grid-model/badges/version.svg)](https://anaconda.org/conda-forge/power-grid-model)
[![PyPI version](https://badge.fury.io/py/power-grid-model.svg?no-cache)](https://badge.fury.io/py/power-grid-model)
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/power-grid-model/badges/version.svg?no-cache)](https://anaconda.org/conda-forge/power-grid-model)
[![License: MIT](https://img.shields.io/badge/License-MPL2.0-informational.svg)](https://github.com/PowerGridModel/power-grid-model/blob/main/LICENSE)
[![Build and Test C++ and Python](https://github.com/PowerGridModel/power-grid-model/actions/workflows/main.yml/badge.svg)](https://github.com/PowerGridModel/power-grid-model/actions/workflows/main.yml)
[![Check Code Quality](https://github.com/PowerGridModel/power-grid-model/actions/workflows/check-code-quality.yml/badge.svg)](https://github.com/PowerGridModel/power-grid-model/actions/workflows/check-code-quality.yml)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define POWER_GRID_MODEL_CALCULATION_PARAMETERS_HPP

#include "enum.hpp"
#include "grouped_index_vector.hpp"
#include "power_grid_model.hpp"
#include "three_phase_tensor.hpp"

Expand Down Expand Up @@ -92,41 +93,41 @@ struct MathModelTopology {
std::vector<double> phase_shift;
std::vector<BranchIdx> branch_bus_idx;
std::vector<BranchIdx> fill_in;
IdxVector source_bus_indptr;
IdxVector shunt_bus_indptr;
IdxVector load_gen_bus_indptr;
DenseGroupedIdxVector sources_per_bus;
SparseGroupedIdxVector shunts_per_bus;
SparseGroupedIdxVector load_gens_per_bus;
std::vector<LoadGenType> load_gen_type;
IdxVector voltage_sensor_indptr;
IdxVector source_power_sensor_indptr; // indptr of the source
IdxVector load_gen_power_sensor_indptr; // indptr of the load_gen
IdxVector shunt_power_sensor_indptr; // indptr of the shunt
IdxVector branch_from_power_sensor_indptr; // indptr of the branch
IdxVector branch_to_power_sensor_indptr; // indptr of the branch
IdxVector bus_power_sensor_indptr; // indptr of the bus
SparseGroupedIdxVector voltage_sensors_per_bus;
SparseGroupedIdxVector power_sensors_per_source;
SparseGroupedIdxVector power_sensors_per_load_gen;
SparseGroupedIdxVector power_sensors_per_shunt;
SparseGroupedIdxVector power_sensors_per_branch_from;
SparseGroupedIdxVector power_sensors_per_branch_to;
SparseGroupedIdxVector power_sensors_per_bus;
mgovers marked this conversation as resolved.
Show resolved Hide resolved

Idx n_bus() const { return static_cast<Idx>(phase_shift.size()); }

Idx n_branch() const { return static_cast<Idx>(branch_bus_idx.size()); }

Idx n_source() const { return source_bus_indptr.back(); }
Idx n_source() const { return sources_per_bus.element_size(); }

Idx n_shunt() const { return shunt_bus_indptr.back(); }
Idx n_shunt() const { return shunts_per_bus.element_size(); }

Idx n_load_gen() const { return load_gen_bus_indptr.back(); }
Idx n_load_gen() const { return load_gens_per_bus.element_size(); }

Idx n_voltage_sensor() const { return voltage_sensor_indptr.back(); }
Idx n_voltage_sensor() const { return voltage_sensors_per_bus.element_size(); }

Idx n_source_power_sensor() const { return source_power_sensor_indptr.back(); }
Idx n_source_power_sensor() const { return power_sensors_per_source.element_size(); }

Idx n_load_gen_power_sensor() const { return load_gen_power_sensor_indptr.back(); }
Idx n_load_gen_power_sensor() const { return power_sensors_per_load_gen.element_size(); }

Idx n_shunt_power_power_sensor() const { return shunt_power_sensor_indptr.back(); }
Idx n_shunt_power_power_sensor() const { return power_sensors_per_shunt.element_size(); }

Idx n_branch_from_power_sensor() const { return branch_from_power_sensor_indptr.back(); }
Idx n_branch_from_power_sensor() const { return power_sensors_per_branch_from.element_size(); }

Idx n_branch_to_power_sensor() const { return branch_to_power_sensor_indptr.back(); }
Idx n_branch_to_power_sensor() const { return power_sensors_per_branch_to.element_size(); }

Idx n_bus_power_sensor() const { return bus_power_sensor_indptr.back(); }
Idx n_bus_power_sensor() const { return power_sensors_per_bus.element_size(); }
};

template <bool sym> struct MathModelParam {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define POWER_GRID_MODEL_SPARSE_IDX_VECTOR_HPP

#include "power_grid_model.hpp"
#include "typing.hpp"

#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/zip_iterator.hpp>
Expand Down Expand Up @@ -51,14 +52,6 @@ inline auto sparse_decode(IdxVector const& indptr) {
return result;
}

template <typename T, typename U> constexpr auto narrow_cast(U value) {
if constexpr (std::same_as<T, U>) {
return value;
}
assert(std::in_range<T>(value));
return static_cast<T>(value);
}

// TODO(mgovers): replace the below relevant subset here ourselves with the STD equivalent when we have std::ranges.
// boost::counting_iterator does not satisfy all requirements std::*_iterator concepts:
static_assert(!std::random_access_iterator<IdxCount>);
Expand Down Expand Up @@ -97,6 +90,8 @@ concept index_range_iterator =

template <typename T>
concept grouped_index_vector_type = std::default_initializable<T> && requires(T const t, Idx const idx) {
typename T::iterator;

{ t.size() } -> std::same_as<Idx>;

{ t.begin() } -> index_range_iterator;
Expand Down Expand Up @@ -152,6 +147,8 @@ class SparseGroupedIdxVector {
auto group_iterator(Idx group) const { return GroupIterator{indptr_, group}; }

public:
using iterator = GroupIterator;

auto size() const { return static_cast<Idx>(indptr_.size()) - 1; }
auto begin() const { return group_iterator(0); }
auto end() const { return group_iterator(size()); }
Expand Down Expand Up @@ -205,8 +202,8 @@ class DenseGroupedIdxVector {
auto dereference() const -> iterator {
assert(dense_vector_ != nullptr);
return boost::counting_range(
detail::narrow_cast<Idx>(std::distance(std::cbegin(*dense_vector_), group_range_.first)),
detail::narrow_cast<Idx>(std::distance(std::cbegin(*dense_vector_), group_range_.second)));
narrow_cast<Idx>(std::distance(std::cbegin(*dense_vector_), group_range_.first)),
narrow_cast<Idx>(std::distance(std::cbegin(*dense_vector_), group_range_.second)));
}
constexpr auto equal(GroupIterator const& other) const { return group_ == other.group_; }
constexpr auto distance_to(GroupIterator const& other) const { return other.group_ - group_; }
Expand All @@ -225,6 +222,8 @@ class DenseGroupedIdxVector {
auto group_iterator(Idx group) const { return GroupIterator{dense_vector_, group}; }

public:
using iterator = GroupIterator;

auto size() const { return num_groups_; }
auto begin() const { return group_iterator(Idx{}); }
auto end() const { return group_iterator(size()); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
namespace power_grid_model::common_solver_functions {

template <bool sym>
void add_sources(IdxVector const& source_bus_indptr, Idx const& bus_number, YBus<sym> const& y_bus,
void add_sources(grouped_idx_vector_type auto const& sources_per_bus, Idx const& bus_number, YBus<sym> const& y_bus,
ComplexVector const& u_source_vector, ComplexTensor<sym>& diagonal_element, ComplexValue<sym>& u_bus) {
for (Idx source_number = source_bus_indptr[bus_number]; source_number != source_bus_indptr[bus_number + 1];
++source_number) {
for (Idx const source_number : sources_per_bus.get_element_range(bus_number)) {
ComplexTensor<sym> const y_source = y_bus.math_model_param().source_param[source_number];
diagonal_element += y_source; // add y_source to the diagonal of Ybus
u_bus += dot(y_source, ComplexValue<sym>{u_source_vector[source_number]}); // rhs += Y_source * U_source
Expand All @@ -35,8 +34,8 @@ template <bool sym> void copy_y_bus(YBus<sym> const& y_bus, ComplexTensorVector<

template <bool sym>
void calculate_source_result(Idx const& bus_number, YBus<sym> const& y_bus, PowerFlowInput<sym> const& input,
MathOutput<sym>& output, IdxVector const& source_bus_indptr) {
for (Idx source = source_bus_indptr[bus_number]; source != source_bus_indptr[bus_number + 1]; ++source) {
MathOutput<sym>& output, grouped_idx_vector_type auto const& sources_per_bus) {
for (Idx const source : sources_per_bus.get_element_range(bus_number)) {
ComplexValue<sym> const u_ref{input.source[source]};
ComplexTensor<sym> const y_ref = y_bus.math_model_param().source_param[source];
output.source[source].i = dot(y_ref, u_ref - output.u[bus_number]);
Expand All @@ -46,8 +45,9 @@ void calculate_source_result(Idx const& bus_number, YBus<sym> const& y_bus, Powe

template <bool sym, class LoadGenFunc>
void calculate_load_gen_result(Idx const& bus_number, PowerFlowInput<sym> const& input, MathOutput<sym>& output,
IdxVector const& load_gen_bus_indptr, LoadGenFunc const& load_gen_func) {
for (Idx load_gen = load_gen_bus_indptr[bus_number]; load_gen != load_gen_bus_indptr[bus_number + 1]; ++load_gen) {
grouped_idx_vector_type auto const& load_gens_per_bus,
LoadGenFunc const& load_gen_func) {
for (auto load_gen : load_gens_per_bus.get_element_range(bus_number)) {
switch (LoadGenType const type = load_gen_func(load_gen); type) {
using enum LoadGenType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ template <bool sym> class IterativeCurrentPFSolver : public IterativePFSolver<sy

// Add source admittance to Y bus and set variable for prepared y bus to true
void initialize_derived_solver(YBus<sym> const& y_bus, MathOutput<sym> const& /* output */) {
IdxVector const& source_bus_indptr = *this->source_bus_indptr_;
auto const& sources_per_bus = *this->sources_per_bus_;
IdxVector const& bus_entry = y_bus.lu_diag();
// if Y bus is not up to date
// re-build matrix and prefactorize Build y bus data with source admittance
Expand All @@ -97,8 +97,7 @@ template <bool sym> class IterativeCurrentPFSolver : public IterativePFSolver<sy
for (Idx bus_number = 0; bus_number != this->n_bus_; ++bus_number) {
Idx const data_sequence = bus_entry[bus_number];
// loop sources
for (Idx source_number = source_bus_indptr[bus_number];
source_number != source_bus_indptr[bus_number + 1]; ++source_number) {
for (auto source_number : sources_per_bus.get_element_range(bus_number)) {
// YBus_diag += Y_source
mat_data[data_sequence] += y_bus.math_model_param().source_param[source_number];
}
Expand All @@ -117,17 +116,17 @@ template <bool sym> class IterativeCurrentPFSolver : public IterativePFSolver<sy
// Prepare matrix calculates injected current ie. RHS of solver for each iteration.
void prepare_matrix_and_rhs(YBus<sym> const& y_bus, PowerFlowInput<sym> const& input,
ComplexValueVector<sym> const& u) {
IdxVector const& load_gen_bus_indptr = *this->load_gen_bus_indptr_;
IdxVector const& source_bus_indptr = *this->source_bus_indptr_;
auto const& load_gens_per_bus = *this->load_gens_per_bus_;
auto const& sources_per_bus = *this->sources_per_bus_;
std::vector<LoadGenType> const& load_gen_type = *this->load_gen_type_;

// set rhs to zero for iteration start
std::fill(rhs_u_.begin(), rhs_u_.end(), ComplexValue<sym>{0.0});

// loop buses: i
for (Idx bus_number = 0; bus_number != this->n_bus_; ++bus_number) {
add_loads(bus_number, input, load_gen_bus_indptr, load_gen_type, u);
add_sources(bus_number, y_bus, input, source_bus_indptr);
add_loads(bus_number, input, load_gens_per_bus, load_gen_type, u);
add_sources(bus_number, y_bus, input, sources_per_bus);
}
}

Expand Down Expand Up @@ -158,10 +157,10 @@ template <bool sym> class IterativeCurrentPFSolver : public IterativePFSolver<sy
SparseLUSolver<ComplexTensor<sym>, ComplexValue<sym>, ComplexValue<sym>> sparse_solver_;
std::shared_ptr<BlockPermArray const> perm_;

void add_loads(Idx const& bus_number, PowerFlowInput<sym> const& input, IdxVector const& load_gen_bus_indptr,
std::vector<LoadGenType> const& load_gen_type, ComplexValueVector<sym> const& u) {
for (Idx load_number = load_gen_bus_indptr[bus_number]; load_number != load_gen_bus_indptr[bus_number + 1];
++load_number) {
void add_loads(Idx const& bus_number, PowerFlowInput<sym> const& input,
grouped_idx_vector_type auto const& load_gens_per_bus, std::vector<LoadGenType> const& load_gen_type,
ComplexValueVector<sym> const& u) {
for (auto load_number : load_gens_per_bus.get_element_range(bus_number)) {
// load type
LoadGenType const type = load_gen_type[load_number];
switch (type) {
Expand All @@ -186,9 +185,8 @@ template <bool sym> class IterativeCurrentPFSolver : public IterativePFSolver<sy
}

void add_sources(Idx const& bus_number, YBus<sym> const& y_bus, PowerFlowInput<sym> const& input,
IdxVector const& source_bus_indptr) {
for (Idx source_number = source_bus_indptr[bus_number]; source_number != source_bus_indptr[bus_number + 1];
++source_number) {
grouped_idx_vector_type auto const& sources_per_bus) {
for (Idx const source_number : sources_per_bus.get_element_range(bus_number)) {
// I_inj_i += Y_source_j * U_ref_j
rhs_u_[bus_number] += dot(y_bus.math_model_param().source_param[source_number],
ComplexValue<sym>{input.source[source_number]});
Expand Down