Skip to content

Commit

Permalink
Merge pull request #860 from PowerGridModel/bugfix/propagating-roundi…
Browse files Browse the repository at this point in the history
…ng-errors

Resolve difference between input and update
  • Loading branch information
mgovers authored Jan 7, 2025
2 parents 2998cde + 09d1dac commit c8865db
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class GenericPowerSensor : public Sensor {
};

template <symmetry_tag power_sensor_symmetry_> class PowerSensor : public GenericPowerSensor {
static constexpr double inv_base_power = 1.0 / base_power<power_sensor_symmetry_>;

public:
using power_sensor_symmetry = power_sensor_symmetry_;

Expand All @@ -78,22 +80,20 @@ template <symmetry_tag power_sensor_symmetry_> class PowerSensor : public Generi

explicit PowerSensor(PowerSensorInput<power_sensor_symmetry> const& power_sensor_input)
: GenericPowerSensor{power_sensor_input},
apparent_power_sigma_{power_sensor_input.power_sigma / base_power<power_sensor_symmetry>},
p_sigma_{power_sensor_input.p_sigma / base_power<power_sensor_symmetry>},
q_sigma_{power_sensor_input.q_sigma / base_power<power_sensor_symmetry>} {
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<power_sensor_symmetry> const& update_data) {
constexpr double scalar = 1.0 / base_power<power_sensor_symmetry>;

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<power_sensor_symmetry>(update_data.p_sigma, p_sigma_, scalar);
update_real_value<power_sensor_symmetry>(update_data.q_sigma, q_sigma_, scalar);
update_real_value<power_sensor_symmetry>(update_data.p_sigma, p_sigma_, inv_base_power);
update_real_value<power_sensor_symmetry>(update_data.q_sigma, q_sigma_, inv_base_power);

return {false, false};
}
Expand All @@ -120,7 +120,7 @@ template <symmetry_tag power_sensor_symmetry_> class PowerSensor : public Generi

void set_power(RealValue<power_sensor_symmetry> const& p_measured,
RealValue<power_sensor_symmetry> const& q_measured) {
double const scalar = convert_direction() / base_power<power_sensor_symmetry>;
double const scalar = convert_direction() * inv_base_power;
RealValue<power_sensor_symmetry> ps = real(s_measured_);
RealValue<power_sensor_symmetry> qs = imag(s_measured_);
update_real_value<power_sensor_symmetry>(p_measured, ps, scalar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,18 @@ template <symmetry_tag sym> class VoltageSensor : public GenericVoltageSensor {
explicit VoltageSensor(VoltageSensorInput<sym> 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<sym>)},
u_measured_{voltage_sensor_input.u_measured / (u_rated_ * u_scale<sym>)},
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<sym> const& update_data) {
assert(update_data.id == this->id() || is_nan(update_data.id));
double const scalar = 1 / (u_rated_ * u_scale<sym>);

update_real_value<sym>(update_data.u_measured, u_measured_, scalar);
update_real_value<sym>(update_data.u_measured, u_measured_, inv_u_norm());
update_real_value<sym>(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};
Expand All @@ -110,6 +109,8 @@ template <symmetry_tag sym> class VoltageSensor : public GenericVoltageSensor {
RealValue<sym> u_measured_;
RealValue<sym> u_angle_measured_;

constexpr auto inv_u_norm() const { return 1.0 / (u_rated_ * u_scale<sym>); }

bool has_angle() const {
if constexpr (is_symmetric_v<sym>) {
return !is_nan(u_angle_measured_);
Expand Down
30 changes: 29 additions & 1 deletion tests/cpp_unit_tests/test_power_sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,34 @@ TEST_CASE("Test power sensor") {
CHECK(result.q_residual[2] != r_nan[2]);
}

SUBCASE("Construction and update") {
PowerSensorInput<symmetric_t> 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<symmetric_t> 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<symmetric_t>();

sym_power_sensor.update(sym_power_sensor_update);
auto const updated_calc_param = sym_power_sensor.calc_param<symmetric_t>();

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;
Expand Down Expand Up @@ -722,4 +750,4 @@ TEST_CASE("Test power sensor") {
}
}
}
} // namespace power_grid_model
} // namespace power_grid_model
19 changes: 19 additions & 0 deletions tests/cpp_unit_tests/test_voltage_sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,25 @@ TEST_CASE("Test voltage sensor") {
}
}

SUBCASE("Construction and update") {
VoltageSensorInput<symmetric_t> sym_voltage_sensor_input{
.id = 7, .measured_object = 3, .u_sigma = 1.0, .u_measured = 25000, .u_angle_measured = -0.2};
VoltageSensorUpdate<symmetric_t> 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<symmetric_t>();

sym_voltage_sensor.update(sym_voltage_sensor_update);
auto const updated_calc_param = sym_voltage_sensor.calc_param<symmetric_t>();

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;
Expand Down

0 comments on commit c8865db

Please sign in to comment.