Skip to content

Commit 80a4f93

Browse files
authored
Merge branch 'main' into drop-python-3.10
2 parents 46ae9f5 + e3d9c4f commit 80a4f93

File tree

130 files changed

+1921
-133
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+1921
-133
lines changed

.clang-tidy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ readability-*,
5555
-readability-function-cognitive-complexity,
5656
-readability-identifier-length,
5757
-readability-magic-numbers,
58+
-bugprone-unchecked-optional-access,
5859
'
5960

6061
WarningsAsErrors: '*'

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
2929

3030
include(GNUInstallDirs)
3131

32-
cmake_policy(SET CMP0167 OLD) # libboost-headers packaged by conda does not come with BoostConfig.cmake
32+
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0")
33+
# libboost-headers packaged by conda does not come with BoostConfig.cmake
34+
cmake_policy(SET CMP0167 OLD)
35+
endif()
36+
3337
find_package(Boost REQUIRED)
3438
find_package(Eigen3 CONFIG REQUIRED)
3539
find_package(nlohmann_json CONFIG REQUIRED)

CMakePresets.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,10 @@
254254
},
255255
{
256256
"name": "ci-clang-release",
257-
"inherits": "clang-release"
257+
"inherits": "clang-release",
258+
"cacheVariables": {
259+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "TRUE"
260+
}
258261
},
259262
{
260263
"name": "ci-gcc-debug",
@@ -270,7 +273,13 @@
270273
"name": "ci-gcc-release",
271274
"inherits": [
272275
"gcc-release"
273-
]
276+
],
277+
"cacheVariables": {
278+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "TRUE"
279+
},
280+
"environment": {
281+
"ASAN_OPTIONS": "detect_odr_violation=0"
282+
}
274283
},
275284
{
276285
"name": "ci-sonar",

power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,10 @@ using IntSVector = std::vector<IntS>;
9191
template <class T, class... Ts>
9292
concept is_in_list_c = (std::same_as<std::remove_const_t<T>, Ts> || ...);
9393

94+
// functor to include all
95+
struct IncludeAll {
96+
template <class... T> constexpr bool operator()(T&&... /*ignored*/) const { return true; }
97+
};
98+
constexpr IncludeAll include_all{};
99+
94100
} // namespace power_grid_model

power_grid_model_c/power_grid_model/include/power_grid_model/common/exception.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class SparseMatrixError : public PowerGridError {
108108
std::string("If you get this error from state estimation, ") +
109109
"it might mean the system is not fully observable, i.e. not enough measurements.\n" +
110110
"It might also mean that you are running into a corner case where PGM cannot resolve yet." +
111-
"See https://github.com/PowerGridModel/power-grid-model/issues/853.");
111+
"See https://github.com/PowerGridModel/power-grid-model/issues/864.");
112112
}
113113
};
114114

power_grid_model_c/power_grid_model/include/power_grid_model/common/three_phase_tensor.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,18 @@ inline ComplexValue<asymmetric_t> piecewise_complex_value(ComplexValue<asymmetri
152152
inline double cabs(double x) { return std::abs(x); }
153153
inline double cabs(DoubleComplex const& x) { return std::sqrt(std::norm(x)); }
154154
inline double abs2(DoubleComplex const& x) { return std::norm(x); }
155-
template <column_vector_or_tensor DerivedA> inline auto cabs(Eigen::ArrayBase<DerivedA> const& m) {
155+
template <column_vector_or_tensor DerivedA>
156+
inline auto cabs(Eigen::ArrayBase<DerivedA> const& m)
157+
requires(std::same_as<typename DerivedA::Scalar, DoubleComplex>)
158+
{
156159
return sqrt(abs2(m));
157160
}
161+
template <column_vector_or_tensor DerivedA>
162+
inline auto cabs(Eigen::ArrayBase<DerivedA> const& m)
163+
requires(std::same_as<typename DerivedA::Scalar, double>)
164+
{
165+
return m.abs();
166+
}
158167

159168
// phase_shift(x) = e^{i arg(x)} = x / |x|
160169
inline DoubleComplex phase_shift(DoubleComplex const x) {

power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,8 +1014,6 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
10141014
return math_param_increment;
10151015
}
10161016

1017-
static constexpr auto include_all = [](Idx) { return true; };
1018-
10191017
/** This is a heavily templated member function because it operates on many different variables of many
10201018
*different types, but the essence is ever the same: filling one member (vector) of the calculation calc_input
10211019
*struct (soa) with the right calculation symmetric or asymmetric calculation parameters, in the same order as
@@ -1068,7 +1066,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
10681066
*/
10691067
template <calculation_input_type CalcStructOut, typename CalcParamOut,
10701068
std::vector<CalcParamOut>(CalcStructOut::*comp_vect), class ComponentIn,
1071-
std::invocable<Idx> PredicateIn = decltype(include_all)>
1069+
std::invocable<Idx> PredicateIn = IncludeAll>
10721070
requires std::convertible_to<std::invoke_result_t<PredicateIn, Idx>, bool>
10731071
static void prepare_input(MainModelState const& state, std::vector<Idx2D> const& components,
10741072
std::vector<CalcStructOut>& calc_input, PredicateIn include = include_all) {
@@ -1087,7 +1085,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
10871085

10881086
template <calculation_input_type CalcStructOut, typename CalcParamOut,
10891087
std::vector<CalcParamOut>(CalcStructOut::*comp_vect), class ComponentIn,
1090-
std::invocable<Idx> PredicateIn = decltype(include_all)>
1088+
std::invocable<Idx> PredicateIn = IncludeAll>
10911089
requires std::convertible_to<std::invoke_result_t<PredicateIn, Idx>, bool>
10921090
static void prepare_input(MainModelState const& state, std::vector<Idx2D> const& components,
10931091
std::vector<CalcStructOut>& calc_input,

power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/iterative_linear_se_solver.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,14 @@ template <symmetry_tag sym_type> class IterativeLinearSESolver {
9595
// preprocess measured value
9696
sub_timer = Timer(calculation_info, 2221, "Pre-process measured value");
9797
MeasuredValues<sym> const measured_values{y_bus.shared_topology(), input};
98-
necessary_observability_check(measured_values, y_bus.math_topology(), y_bus.y_bus_structure());
98+
auto const observability_result =
99+
necessary_observability_check(measured_values, y_bus.math_topology(), y_bus.y_bus_structure());
99100

100-
// prepare matrix, including pre-factorization
101+
// prepare matrix
101102
sub_timer = Timer(calculation_info, 2222, "Prepare matrix, including pre-factorization");
102103
prepare_matrix(y_bus, measured_values);
104+
// prefactorize
105+
sparse_solver_.prefactorize(data_gain_, perm_, observability_result.use_perturbation());
103106

104107
// initialize voltage with initial angle
105108
sub_timer = Timer(calculation_info, 2223, "Initialize voltages");
@@ -252,8 +255,6 @@ template <symmetry_tag sym_type> class IterativeLinearSESolver {
252255
Idx const data_idx_tranpose = y_bus.lu_transpose_entry()[data_idx_lu];
253256
data_gain_[data_idx_lu].qh() = hermitian_transpose(data_gain_[data_idx_tranpose].q());
254257
}
255-
// prefactorize
256-
sparse_solver_.prefactorize(data_gain_, perm_);
257258
}
258259

259260
void prepare_rhs(YBus<sym> const& y_bus, MeasuredValues<sym> const& measured_value,

power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/measured_values.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,13 @@ template <symmetry_tag sym> class MeasuredValues {
498498
}
499499

500500
// process one object
501-
static constexpr auto default_status_checker = [](auto x) -> bool { return x; };
501+
struct DefaultStatusChecker {
502+
template <class T> bool operator()(T x) const { return x; }
503+
};
504+
505+
static constexpr DefaultStatusChecker default_status_checker{};
502506

503-
template <class TS, class StatusChecker = decltype(default_status_checker)>
507+
template <class TS, class StatusChecker = DefaultStatusChecker>
504508
static Idx process_one_object(Idx const object, grouped_idx_vector_type auto const& sensors_per_object,
505509
std::vector<TS> const& object_status,
506510
std::vector<PowerSensorCalcParam<sym>> const& input_data,

power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/newton_raphson_se_solver.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ template <symmetry_tag sym_type> class NewtonRaphsonSESolver {
159159
// preprocess measured value
160160
sub_timer = Timer(calculation_info, 2221, "Pre-process measured value");
161161
MeasuredValues<sym> const measured_values{y_bus.shared_topology(), input};
162-
necessary_observability_check(measured_values, y_bus.math_topology(), y_bus.y_bus_structure());
162+
auto const observability_result =
163+
necessary_observability_check(measured_values, y_bus.math_topology(), y_bus.y_bus_structure());
163164

164165
// initialize voltage with initial angle
165166
sub_timer = Timer(calculation_info, 2223, "Initialize voltages");
@@ -175,7 +176,8 @@ template <symmetry_tag sym_type> class NewtonRaphsonSESolver {
175176
prepare_matrix_and_rhs(y_bus, measured_values, output.u);
176177
// solve with prefactorization
177178
sub_timer = Timer(calculation_info, 2225, "Solve sparse linear equation");
178-
sparse_solver_.prefactorize_and_solve(data_gain_, perm_, delta_x_rhs_, delta_x_rhs_);
179+
sparse_solver_.prefactorize_and_solve(data_gain_, perm_, delta_x_rhs_, delta_x_rhs_,
180+
observability_result.use_perturbation());
179181
sub_timer = Timer(calculation_info, 2226, "Iterate unknown");
180182
max_dev = iterate_unknown(output.u, measured_values);
181183
};
@@ -519,7 +521,8 @@ template <symmetry_tag sym_type> class NewtonRaphsonSESolver {
519521
/// eta(row) += w_k . (z_k - f_k(x))
520522
///
521523
/// In case there is no angle measurement, the slack bus or arbitray bus measurement is considered to have a virtual
522-
/// angle measurement of zero. w_theta = 1.0 by default for all measurements
524+
/// angle measurement of zero. w_theta = w_k by default for all measurements
525+
/// angle_error = u_error / u_rated (1.0) = w_k
523526
///
524527
/// @param block LHS(row, col), ie. LHS(row, row)
525528
/// @param rhs_block RHS(row)
@@ -545,10 +548,10 @@ template <symmetry_tag sym_type> class NewtonRaphsonSESolver {
545548
RealValue<sym> delta_theta{};
546549
if (measured_values.has_angle_measurement(bus)) {
547550
delta_theta = RealValue<sym>{arg(measured_values.voltage(bus))} - RealValue<sym>{x_[bus].theta()};
548-
w_theta = RealTensor<sym>{1.0};
551+
w_theta = RealTensor<sym>{w_v};
549552
} else if (bus == virtual_angle_measurement_bus && !measured_values.has_angle()) {
550553
delta_theta = arg(ComplexValue<sym>{1.0}) - RealValue<sym>{x_[bus].theta()};
551-
w_theta = RealTensor<sym>{1.0};
554+
w_theta = RealTensor<sym>{w_v};
552555
}
553556

554557
block.g_P_theta() += w_theta;

0 commit comments

Comments
 (0)