@@ -15,16 +15,6 @@ Collect all measured Values
15
15
#include < memory>
16
16
17
17
namespace power_grid_model ::math_solver {
18
-
19
- namespace detail {
20
- template <symmetry_tag sym> inline RealValue<sym> cabs_or_real (ComplexValue<sym> const & value) {
21
- if (is_nan (imag (value))) {
22
- return real (value); // only keep real part
23
- }
24
- return cabs (value); // get abs of the value
25
- }
26
- } // namespace detail
27
-
28
18
// processed measurement struct
29
19
// combined all measurement of the same quantity
30
20
// accumulate for bus injection measurement
@@ -71,6 +61,7 @@ template <symmetry_tag sym> class MeasuredValues {
71
61
72
62
constexpr bool has_angle () const { return n_voltage_angle_measurements_ > 0 ; }
73
63
constexpr bool has_voltage_measurements () const { return n_voltage_measurements_ > 0 ; }
64
+ constexpr bool has_global_angle_current () const { return n_global_angle_current_measurements_ > 0 ; }
74
65
75
66
constexpr bool has_voltage (Idx bus) const { return idx_voltage_[bus] >= 0 ; }
76
67
constexpr bool has_angle_measurement (Idx bus) const { return !is_nan (imag (voltage (bus))); }
@@ -215,6 +206,7 @@ template <symmetry_tag sym> class MeasuredValues {
215
206
216
207
Idx n_voltage_measurements_{};
217
208
Idx n_voltage_angle_measurements_{};
209
+ Idx n_global_angle_current_measurements_{};
218
210
219
211
// average angle shift of voltages with angle measurement
220
212
// default is zero is no voltage has angle measurement
@@ -406,15 +398,15 @@ template <symmetry_tag sym> class MeasuredValues {
406
398
connected at that side. For each branch the checker checks if the from and to side are connected by checking if
407
399
branch_bus_idx = disconnected.
408
400
409
- If the branch_bus_idx = disconnected, idx_branch_(to| from)_(power| current)_ is set to disconnected.
401
+ If the branch_bus_idx = disconnected, idx_branch_(to/ from)_(power/ current)_ is set to disconnected.
410
402
If the side is connected, but there are no measurements in this branch side
411
- idx_branch_(to| from)_(power| current)_ is set to disconnected.
412
- Else, idx_branch_(to| from)_(power| current)_ is set to the index of the aggregated data in
403
+ idx_branch_(to/ from)_(power/ current)_ is set to disconnected.
404
+ Else, idx_branch_(to/ from)_(power/ current)_ is set to the index of the aggregated data in
413
405
power/current_main_value_.
414
406
415
407
All measurement values for a single side of a branch are combined in a weighted average, which is appended to
416
408
power/current_main_value_. The values in power/current_main_value_ can be found using
417
- idx_branch_(to| from)_(power| current)_.
409
+ idx_branch_(to/ from)_(power/ current)_.
418
410
*/
419
411
MathModelTopology const & topo = math_topology ();
420
412
static constexpr auto branch_from_checker = [](BranchIdx x) { return x[0 ] != -1 ; };
@@ -437,12 +429,10 @@ template <symmetry_tag sym> class MeasuredValues {
437
429
process_one_object (branch, topo.current_sensors_per_branch_to , topo.branch_bus_idx ,
438
430
input.measured_branch_to_current , current_main_value_, branch_to_checker);
439
431
440
- if ((!has_angle ()) && std::ranges::any_of (current_main_value_, [](auto const & measurement) {
432
+ n_global_angle_current_measurements_ =
433
+ std::ranges::count_if (current_main_value_, [](auto const & measurement) {
441
434
return measurement.angle_measurement_type == AngleMeasurementType::global_angle;
442
- })) {
443
- throw ConflictingAngleMeasurementType{
444
- " Global angle current measurements require a voltage angle measurement in the connected subgrid." };
445
- }
435
+ });
446
436
}
447
437
}
448
438
@@ -455,28 +445,16 @@ template <symmetry_tag sym> class MeasuredValues {
455
445
IdxRange const & sensors) {
456
446
auto complex_measurements = sensors | std::views::transform ([&data](Idx pos) -> auto & { return data[pos]; });
457
447
if constexpr (only_magnitude) {
458
- auto const combined_magnitude_measurement = statistics::accumulate (
459
- complex_measurements | std::views::transform ([](auto const & measurement) {
460
- return UniformRealRandVar<sym>{.value = detail::cabs_or_real<sym>(measurement.value ),
461
- .variance = measurement.variance };
462
- }));
463
- return UniformComplexRandVar<sym>{.value =
464
- [&combined_magnitude_measurement]() {
465
- ComplexValue<sym> abs_value =
466
- piecewise_complex_value<sym>(DoubleComplex{0.0 , nan});
467
- abs_value += combined_magnitude_measurement.value ;
468
- return abs_value;
469
- }(),
470
- .variance = combined_magnitude_measurement.variance };
448
+ return statistics::combine_magnitude (complex_measurements);
471
449
} else {
472
- return statistics::accumulate (complex_measurements);
450
+ return statistics::combine (complex_measurements);
473
451
}
474
452
}
475
453
template <bool only_magnitude = false >
476
454
requires (!only_magnitude)
477
455
static PowerSensorCalcParam<sym> combine_measurements (std::vector<PowerSensorCalcParam<sym>> const & data,
478
456
IdxRange const & sensors) {
479
- return statistics::accumulate (sensors | std::views::transform ([&data](Idx pos) -> auto & { return data[pos]; }));
457
+ return statistics::combine (sensors | std::views::transform ([&data](Idx pos) -> auto & { return data[pos]; }));
480
458
}
481
459
template <bool only_magnitude = false >
482
460
requires (!only_magnitude)
@@ -485,15 +463,15 @@ template <symmetry_tag sym> class MeasuredValues {
485
463
auto const params = sensors | std::views::transform ([&data](Idx pos) -> auto & { return data[pos]; });
486
464
auto const angle_measurement_type = sensors.empty () ? AngleMeasurementType::local_angle // fallback
487
465
: params.front ().angle_measurement_type ;
488
- if (std::ranges::any_of (params, [angle_measurement_type](auto const & params ) {
489
- return params .angle_measurement_type != angle_measurement_type;
466
+ if (std::ranges::any_of (params, [angle_measurement_type](auto const & param ) {
467
+ return param .angle_measurement_type != angle_measurement_type;
490
468
})) {
491
469
throw ConflictingAngleMeasurementType{
492
470
" Cannot mix local and global angle current measurements on the same terminal." };
493
471
}
494
472
495
473
return {.angle_measurement_type = angle_measurement_type,
496
- .measurement = statistics::accumulate (
474
+ .measurement = statistics::combine (
497
475
params | std::views::transform ([](auto const & param) -> auto & { return param.measurement ; }))};
498
476
}
499
477
0 commit comments