diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/component/power_sensor.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/component/power_sensor.hpp index 76f33be8c..83aed9efb 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/component/power_sensor.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/component/power_sensor.hpp @@ -67,6 +67,8 @@ class GenericPowerSensor : public Sensor { }; template class PowerSensor : public GenericPowerSensor { + static constexpr double inv_base_power = 1.0 / base_power; + public: using power_sensor_symmetry = power_sensor_symmetry_; @@ -78,22 +80,20 @@ template class PowerSensor : public Generi explicit PowerSensor(PowerSensorInput const& power_sensor_input) : GenericPowerSensor{power_sensor_input}, - apparent_power_sigma_{power_sensor_input.power_sigma / base_power}, - p_sigma_{power_sensor_input.p_sigma / base_power}, - q_sigma_{power_sensor_input.q_sigma / base_power} { + apparent_power_sigma_{power_sensor_input.power_sigma * inv_base_power}, + p_sigma_{power_sensor_input.p_sigma * inv_base_power}, + q_sigma_{power_sensor_input.q_sigma * inv_base_power} { set_power(power_sensor_input.p_measured, power_sensor_input.q_measured); }; UpdateChange update(PowerSensorUpdate const& update_data) { - constexpr double scalar = 1.0 / base_power; - set_power(update_data.p_measured, update_data.q_measured); if (!is_nan(update_data.power_sigma)) { - apparent_power_sigma_ = update_data.power_sigma * scalar; + apparent_power_sigma_ = update_data.power_sigma * inv_base_power; } - update_real_value(update_data.p_sigma, p_sigma_, scalar); - update_real_value(update_data.q_sigma, q_sigma_, scalar); + update_real_value(update_data.p_sigma, p_sigma_, inv_base_power); + update_real_value(update_data.q_sigma, q_sigma_, inv_base_power); return {false, false}; } @@ -120,7 +120,7 @@ template class PowerSensor : public Generi void set_power(RealValue const& p_measured, RealValue const& q_measured) { - double const scalar = convert_direction() / base_power; + double const scalar = convert_direction() * inv_base_power; RealValue ps = real(s_measured_); RealValue qs = imag(s_measured_); update_real_value(p_measured, ps, scalar); diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/component/voltage_sensor.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/component/voltage_sensor.hpp index 2fde9e57b..753779042 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/component/voltage_sensor.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/component/voltage_sensor.hpp @@ -75,19 +75,18 @@ template class VoltageSensor : public GenericVoltageSensor { explicit VoltageSensor(VoltageSensorInput const& voltage_sensor_input, double u_rated) : GenericVoltageSensor{voltage_sensor_input}, u_rated_{u_rated}, - u_sigma_{voltage_sensor_input.u_sigma / (u_rated_ * u_scale)}, - u_measured_{voltage_sensor_input.u_measured / (u_rated_ * u_scale)}, + u_sigma_{voltage_sensor_input.u_sigma * inv_u_norm()}, + u_measured_{voltage_sensor_input.u_measured * inv_u_norm()}, u_angle_measured_{voltage_sensor_input.u_angle_measured} {}; UpdateChange update(VoltageSensorUpdate const& update_data) { assert(update_data.id == this->id() || is_nan(update_data.id)); - double const scalar = 1 / (u_rated_ * u_scale); - update_real_value(update_data.u_measured, u_measured_, scalar); + update_real_value(update_data.u_measured, u_measured_, inv_u_norm()); update_real_value(update_data.u_angle_measured, u_angle_measured_, 1.0); if (!is_nan(update_data.u_sigma)) { - u_sigma_ = update_data.u_sigma * scalar; + u_sigma_ = update_data.u_sigma * inv_u_norm(); } return {false, false}; @@ -110,6 +109,8 @@ template class VoltageSensor : public GenericVoltageSensor { RealValue u_measured_; RealValue u_angle_measured_; + constexpr auto inv_u_norm() const { return 1.0 / (u_rated_ * u_scale); } + bool has_angle() const { if constexpr (is_symmetric_v) { return !is_nan(u_angle_measured_); diff --git a/tests/cpp_unit_tests/test_power_sensor.cpp b/tests/cpp_unit_tests/test_power_sensor.cpp index 882ac5292..f051c6e7a 100644 --- a/tests/cpp_unit_tests/test_power_sensor.cpp +++ b/tests/cpp_unit_tests/test_power_sensor.cpp @@ -571,6 +571,34 @@ TEST_CASE("Test power sensor") { CHECK(result.q_residual[2] != r_nan[2]); } + SUBCASE("Construction and update") { + PowerSensorInput sym_power_sensor_input{.id = 7, + .measured_object = 3, + .measured_terminal_type = + MeasuredTerminalType::branch_from, + .power_sigma = 269258.24035672517, + .p_measured = -2e5, + .q_measured = -1e6, + .p_sigma = 2.5e5, + .q_sigma = 1e5}; + PowerSensorUpdate sym_power_sensor_update{.id = 7, + .power_sigma = sym_power_sensor_input.power_sigma, + .p_measured = sym_power_sensor_input.p_measured, + .q_measured = sym_power_sensor_input.q_measured, + .p_sigma = sym_power_sensor_input.p_sigma, + .q_sigma = sym_power_sensor_input.q_sigma}; + + SymPowerSensor sym_power_sensor{sym_power_sensor_input}; + auto const orig_calc_param = sym_power_sensor.calc_param(); + + sym_power_sensor.update(sym_power_sensor_update); + auto const updated_calc_param = sym_power_sensor.calc_param(); + + CHECK(orig_calc_param.value == updated_calc_param.value); + CHECK(orig_calc_param.p_variance == updated_calc_param.p_variance); + CHECK(orig_calc_param.q_variance == updated_calc_param.q_variance); + } + SUBCASE("Update inverse - sym") { constexpr auto power_sigma = 1.0; constexpr auto p_measured = 2.0; @@ -722,4 +750,4 @@ TEST_CASE("Test power sensor") { } } } -} // namespace power_grid_model \ No newline at end of file +} // namespace power_grid_model diff --git a/tests/cpp_unit_tests/test_voltage_sensor.cpp b/tests/cpp_unit_tests/test_voltage_sensor.cpp index 43ab0040f..432181d56 100644 --- a/tests/cpp_unit_tests/test_voltage_sensor.cpp +++ b/tests/cpp_unit_tests/test_voltage_sensor.cpp @@ -496,6 +496,25 @@ TEST_CASE("Test voltage sensor") { } } + SUBCASE("Construction and update") { + VoltageSensorInput sym_voltage_sensor_input{ + .id = 7, .measured_object = 3, .u_sigma = 1.0, .u_measured = 25000, .u_angle_measured = -0.2}; + VoltageSensorUpdate sym_voltage_sensor_update{.id = 7, + .u_sigma = sym_voltage_sensor_input.u_sigma, + .u_measured = sym_voltage_sensor_input.u_measured, + .u_angle_measured = + sym_voltage_sensor_input.u_angle_measured}; + + SymVoltageSensor sym_voltage_sensor{sym_voltage_sensor_input, 31250}; + auto const orig_calc_param = sym_voltage_sensor.calc_param(); + + sym_voltage_sensor.update(sym_voltage_sensor_update); + auto const updated_calc_param = sym_voltage_sensor.calc_param(); + + CHECK(orig_calc_param.value == updated_calc_param.value); + CHECK(orig_calc_param.variance == updated_calc_param.variance); + } + SUBCASE("Update inverse - sym") { constexpr auto u_sigma = 1.0; constexpr auto u_measured = 2.0;