Skip to content

Commit 5a58f5d

Browse files
Merge pull request #18 from alliander-opensource/feature/3-winding-transformer
Three winding transformer
2 parents dba4e93 + b14cc30 commit 5a58f5d

Some content is hidden

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

46 files changed

+4439
-233
lines changed

docs/graph-data-model.md

Lines changed: 207 additions & 126 deletions
Large diffs are not rendered by default.

include/power_grid_model/all_components.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
#include "component/sensor.hpp"
1919
#include "component/shunt.hpp"
2020
#include "component/source.hpp"
21+
#include "component/three_winding_transformer.hpp"
2122
#include "component/transformer.hpp"
2223
#include "component/voltage_sensor.hpp"
2324

2425
namespace power_grid_model {
2526

26-
using AllComponents = ComponentList<Node, Line, Link, Transformer, Shunt, Source, SymGenerator, AsymGenerator, SymLoad,
27-
AsymLoad, SymPowerSensor, AsymPowerSensor, SymVoltageSensor, AsymVoltageSensor>;
27+
using AllComponents =
28+
ComponentList<Node, Line, Link, Transformer, ThreeWindingTransformer, Shunt, Source, SymGenerator, AsymGenerator,
29+
SymLoad, AsymLoad, SymPowerSensor, AsymPowerSensor, SymVoltageSensor, AsymVoltageSensor>;
2830

2931
} // namespace power_grid_model
3032

include/power_grid_model/auxiliary/input.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ POWER_GRID_MODEL_DATA_STRUCT_DEF(NodeInput, 1, BaseInput,
2424
POWER_GRID_MODEL_DATA_STRUCT_DEF(BranchInput, 1, BaseInput,
2525
ID, from_node, ID, to_node, IntS, from_status, IntS, to_status);
2626

27+
POWER_GRID_MODEL_DATA_STRUCT_DEF(Branch3Input, 1, BaseInput,
28+
ID, node_1, ID, node_2, ID, node_3, IntS, status_1, IntS, status_2, IntS, status_3);
29+
2730
POWER_GRID_MODEL_DATA_STRUCT_DEF(ApplianceInput, 1, BaseInput,
2831
ID, node, IntS, status);
2932

@@ -42,6 +45,21 @@ POWER_GRID_MODEL_DATA_STRUCT_DEF(TransformerInput, 1, BranchInput,
4245
double, uk_min, double, uk_max, double, pk_min, double, pk_max,
4346
double, r_grounding_from, double, x_grounding_from, double, r_grounding_to, double, x_grounding_to);
4447

48+
// Due to the maximum entries in the POWER_GRID_MODEL_DATA_STRUCT_DEF macro, ThreeWindingTransformerInput is created in two steps
49+
// TODO: generate input data in a different way
50+
POWER_GRID_MODEL_DATA_STRUCT_DEF(ThreeWindingTransformerInputBasics, 1, Branch3Input,
51+
double, u1, double, u2, double, u3, double, sn_1, double, sn_2, double, sn_3,
52+
double, uk_12, double, uk_13, double, uk_23, double, pk_12, double, pk_13, double, pk_23, double, i0, double, p0,
53+
WindingType, winding_1, WindingType, winding_2, WindingType, winding_3,
54+
IntS, clock_12, IntS, clock_13,
55+
Branch3Side, tap_side, IntS, tap_pos, IntS, tap_min, IntS, tap_max, IntS, tap_nom, double, tap_size);
56+
57+
POWER_GRID_MODEL_DATA_STRUCT_DEF(ThreeWindingTransformerInput, 1, ThreeWindingTransformerInputBasics,
58+
double, uk_12_min, double, uk_12_max, double, uk_13_min, double, uk_13_max, double, uk_23_min, double, uk_23_max,
59+
double, pk_12_min, double, pk_12_max, double, pk_13_min, double, pk_13_max, double, pk_23_min, double, pk_23_max,
60+
double, r_grounding_1, double, x_grounding_1, double, r_grounding_2, double, x_grounding_2,
61+
double, r_grounding_3, double, x_grounding_3);
62+
4563
POWER_GRID_MODEL_DATA_STRUCT_DEF(GenericLoadGenInput, 1, ApplianceInput,
4664
LoadGenType, type);
4765

@@ -96,9 +114,15 @@ using BaseUpdate = BaseInput;
96114
POWER_GRID_MODEL_DATA_STRUCT_DEF(BranchUpdate, 1, BaseUpdate,
97115
IntS, from_status, IntS, to_status);
98116

117+
POWER_GRID_MODEL_DATA_STRUCT_DEF(Branch3Update, 1, BaseUpdate,
118+
IntS, status_1, IntS, status_2, IntS, status_3);
119+
99120
POWER_GRID_MODEL_DATA_STRUCT_DEF(TransformerUpdate, 1, BranchUpdate,
100121
IntS, tap_pos);
101122

123+
POWER_GRID_MODEL_DATA_STRUCT_DEF(ThreeWindingTransformerUpdate, 1, Branch3Update,
124+
IntS, tap_pos);
125+
102126
POWER_GRID_MODEL_DATA_STRUCT_DEF(ApplianceUpdate, 1, BaseUpdate,
103127
IntS, status);
104128

include/power_grid_model/auxiliary/output.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ POWER_GRID_MODEL_DATA_STRUCT_DEF(BranchOutput, 1, BaseOutput,
2929
RealValue<sym>, p_from, RealValue<sym>, q_from, RealValue<sym>, i_from, RealValue<sym>, s_from,
3030
RealValue<sym>, p_to, RealValue<sym>, q_to, RealValue<sym>, i_to, RealValue<sym>, s_to);
3131

32+
template <bool sym>
33+
POWER_GRID_MODEL_DATA_STRUCT_DEF(Branch3Output, 1, BaseOutput,
34+
double, loading,
35+
RealValue<sym>, p_1, RealValue<sym>, q_1, RealValue<sym>, i_1, RealValue<sym>, s_1,
36+
RealValue<sym>, p_2, RealValue<sym>, q_2, RealValue<sym>, i_2, RealValue<sym>, s_2,
37+
RealValue<sym>, p_3, RealValue<sym>, q_3, RealValue<sym>, i_3, RealValue<sym>, s_3);
38+
3239
template <bool sym>
3340
POWER_GRID_MODEL_DATA_STRUCT_DEF(ApplianceOutput, 1, BaseOutput,
3441
RealValue<sym>, p, RealValue<sym>, q, RealValue<sym>, i, RealValue<sym>, s, RealValue<sym>, pf);
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// SPDX-FileCopyrightText: 2022 Contributors to the Power Grid Model project <[email protected]>
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
#pragma once
6+
#ifndef POWER_GRID_MODEL_COMPONENT_BRANCH3_HPP
7+
#define POWER_GRID_MODEL_COMPONENT_BRANCH3_HPP
8+
9+
#include "../auxiliary/input.hpp"
10+
#include "../auxiliary/output.hpp"
11+
#include "../calculation_parameters.hpp"
12+
#include "base.hpp"
13+
14+
namespace power_grid_model {
15+
16+
class Branch3 : public Base {
17+
public:
18+
using InputType = Branch3Input;
19+
using UpdateType = Branch3Update;
20+
template <bool sym>
21+
using OutputType = Branch3Output<sym>;
22+
static constexpr char const* name = "branch3";
23+
ComponentType math_model_type() const final {
24+
return ComponentType::branch3;
25+
}
26+
27+
Branch3(Branch3Input const& branch3_input)
28+
: Base{branch3_input},
29+
node_1_{branch3_input.node_1},
30+
node_2_{branch3_input.node_2},
31+
node_3_{branch3_input.node_3},
32+
status_1_{(bool)branch3_input.status_1},
33+
status_2_{(bool)branch3_input.status_2},
34+
status_3_{(bool)branch3_input.status_3} {
35+
if (node_1_ == node_2_ || node_1_ == node_3_ || node_2_ == node_3_) {
36+
throw InvalidBranch3{id(), node_1_, node_2_, node_3_};
37+
}
38+
}
39+
40+
// getter
41+
ID node_1() const {
42+
return node_1_;
43+
}
44+
ID node_2() const {
45+
return node_2_;
46+
}
47+
ID node_3() const {
48+
return node_3_;
49+
}
50+
bool status_1() const {
51+
return status_1_;
52+
}
53+
bool status_2() const {
54+
return status_2_;
55+
}
56+
bool status_3() const {
57+
return status_3_;
58+
}
59+
bool branch3_status() const {
60+
return status_1_ && status_2_ && status_3_; // TODO: check if this makes sense for branch3
61+
}
62+
63+
// virtual getter
64+
bool energized(bool is_connected_to_source = true) const final {
65+
return is_connected_to_source && (status_1_ || status_2_ || status_3_);
66+
}
67+
virtual double base_i_1() const = 0;
68+
virtual double base_i_2() const = 0;
69+
virtual double base_i_3() const = 0;
70+
virtual double loading(double s_1, double s_2, double s_3) const = 0;
71+
virtual std::array<double, 3> phase_shift() const = 0;
72+
73+
template <bool sym>
74+
std::array<BranchCalcParam<sym>, 3> calc_param(bool is_connected_to_source = true) const {
75+
if (!energized(is_connected_to_source)) {
76+
return std::array<BranchCalcParam<sym>, 3>{};
77+
}
78+
if constexpr (sym) {
79+
return sym_calc_param();
80+
}
81+
else {
82+
return asym_calc_param();
83+
}
84+
}
85+
86+
template <bool sym>
87+
Branch3Output<sym> get_output(BranchMathOutput<sym> const& branch_math_output1,
88+
BranchMathOutput<sym> const& branch_math_output2,
89+
BranchMathOutput<sym> const& branch_math_output3) const {
90+
// result object
91+
Branch3Output<sym> output{};
92+
static_cast<BaseOutput&>(output) = base_output(true);
93+
// calculate result
94+
output.p_1 = base_power<sym> * real(branch_math_output1.s_f);
95+
output.q_1 = base_power<sym> * imag(branch_math_output1.s_f);
96+
output.i_1 = base_i_1() * cabs(branch_math_output1.i_f);
97+
output.s_1 = base_power<sym> * cabs(branch_math_output1.s_f);
98+
99+
output.p_2 = base_power<sym> * real(branch_math_output2.s_f);
100+
output.q_2 = base_power<sym> * imag(branch_math_output2.s_f);
101+
output.i_2 = base_i_2() * cabs(branch_math_output2.i_f);
102+
output.s_2 = base_power<sym> * cabs(branch_math_output2.s_f);
103+
104+
output.p_3 = base_power<sym> * real(branch_math_output3.s_f);
105+
output.q_3 = base_power<sym> * imag(branch_math_output3.s_f);
106+
output.i_3 = base_i_3() * cabs(branch_math_output3.i_f);
107+
output.s_3 = base_power<sym> * cabs(branch_math_output3.s_f);
108+
109+
output.loading = loading(sum_val(output.s_1), sum_val(output.s_2), sum_val(output.s_3));
110+
111+
return output;
112+
}
113+
114+
template <bool sym>
115+
Branch3Output<sym> get_null_output() const {
116+
Branch3Output<sym> output{};
117+
static_cast<BaseOutput&>(output) = base_output(false);
118+
return output;
119+
}
120+
121+
// setter
122+
bool set_status(IntS new_status_1, IntS new_status_2, IntS new_status_3) {
123+
bool const set_1 = new_status_1 != na_IntS;
124+
bool const set_2 = new_status_2 != na_IntS;
125+
bool const set_3 = new_status_3 != na_IntS;
126+
bool changed = false;
127+
if (set_1) {
128+
changed = changed || (status_1_ != (bool)new_status_1);
129+
status_1_ = (bool)new_status_1;
130+
}
131+
if (set_2) {
132+
changed = changed || (status_2_ != (bool)new_status_2);
133+
status_2_ = (bool)new_status_2;
134+
}
135+
if (set_3) {
136+
changed = changed || (status_3_ != (bool)new_status_3);
137+
status_3_ = (bool)new_status_3;
138+
}
139+
return changed;
140+
}
141+
142+
// default update for branch3, will be hidden for three winding transformer
143+
UpdateChange update(Branch3Update const& update) {
144+
assert(update.id == id());
145+
bool const changed = set_status(update.status_1, update.status_2, update.status_3);
146+
// change in branch3 connection will change both topo and param
147+
return {changed, changed};
148+
}
149+
150+
private:
151+
ID node_1_;
152+
ID node_2_;
153+
ID node_3_;
154+
bool status_1_;
155+
bool status_2_;
156+
bool status_3_;
157+
158+
virtual std::array<BranchCalcParam<true>, 3> sym_calc_param() const = 0;
159+
virtual std::array<BranchCalcParam<false>, 3> asym_calc_param() const = 0;
160+
};
161+
162+
} // namespace power_grid_model
163+
164+
#endif

0 commit comments

Comments
 (0)