RxLineDP.cpp 6.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** RX Line
 *
 * @author Markus Mirz <mmirz@eonerc.rwth-aachen.de>
 * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
 * @license GNU General Public License (version 3)
 *
 * DPsim
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *********************************************************************************/

Markus Mirz's avatar
Markus Mirz committed
23
#include "RxLineDP.h"
Viviane's avatar
Viviane committed
24
25
26

using namespace DPsim;

27
RxLineDP::RxLineDP(String name, Int node1, Int node2, Real resistance, Real inductance, LineTypes type) : BaseComponent(name, node1, node2) {
28
29
	mNumVirtualNodes = 1;
	mVirtualNodes = { 0 };
Markus Mirz's avatar
Markus Mirz committed
30
31
32
	mResistance = resistance;
	mConductance = 1.0 / resistance;
	mInductance = inductance;
33
34
35
	mType = type;
	attrMap["resistance"] = { AttrReal, &mResistance };
	attrMap["inductance"] = { AttrReal, &mInductance };
Viviane's avatar
Viviane committed
36
}
Viviane's avatar
Viviane committed
37

38
void RxLineDP::applySystemMatrixStamp(SystemModel& system) {
39
	if (mType == LineTypes::RxLine2Node) {
Viviane's avatar
Viviane committed
40
41
42
		Real a = system.getTimeStep() / (2 * mInductance);
		Real b = system.getTimeStep()*system.getOmega() / 2;
		Real R = mResistance;
Viviane's avatar
Viviane committed
43

Viviane's avatar
Viviane committed
44
45
46
47
48
49
		mGlr = a*(1 + b*b + R*a + R*a*b*b) / ((1 + b*b + R*a)*(1 + b*b + R*a) + R*R*a*a*b*b);
		mGli = -a*b*(1 + b*b) / ((1 + b*b + R*a)*(1 + b*b + R*a) + R*R*a*a*b*b);

		glr_ind = a / (1 + b*b);
		gli_ind = -a*b / (1 + b*b);
		mPrevCurFacRe = (1 - b*b) / (1 + b*b);
50
		mPrevCurFacIm = -2. * b / (1 + b*b);
Viviane's avatar
Viviane committed
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

		correctr = (1 + 2 * b*b + R*a + b*b*b*b + R*a*b*b) / ((1 + b*b + R*a)*(1 + b*b + R*a) + R*R*a*a*b*b);
		correcti = R*a*b*(1 + b*b) / ((1 + b*b + R*a)*(1 + b*b + R*a) + R*R*a*a*b*b);


		if (mNode1 >= 0) {
			system.addCompToSystemMatrix(mNode1, mNode1, mGlr, mGli);
		}

		if (mNode2 >= 0) {
			system.addCompToSystemMatrix(mNode2, mNode2, mGlr, mGli);
		}

		if (mNode1 >= 0 && mNode2 >= 0) {
			system.addCompToSystemMatrix(mNode1, mNode2, -mGlr, -mGli);
			system.addCompToSystemMatrix(mNode2, mNode1, -mGlr, -mGli);
		}
Viviane's avatar
Viviane committed
68
	}
Viviane's avatar
Viviane committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
	else {

		Real a = system.getTimeStep() / (2. * mInductance);
		Real b = system.getTimeStep() * system.getOmega() / 2.;
		mGlr = a / (1 + b*b);
		mGli = -a*b / (1 + b*b);
		mPrevCurFacRe = (1 - b*b) / (1 + b*b);
		mPrevCurFacIm = -2. * b / (1 + b*b);

		// Resistive part
		// Set diagonal entries
		if (mNode1 >= 0) {
			system.addCompToSystemMatrix(mNode1, mNode1, mConductance, 0);
		}
83
84
		if (mVirtualNodes[0] >= 0) {
			system.addCompToSystemMatrix(mVirtualNodes[0], mVirtualNodes[0], mConductance, 0);
Viviane's avatar
Viviane committed
85
86
		}
		// Set off diagonal entries
87
88
89
		if (mNode1 >= 0 && mVirtualNodes[0] >= 0) {
			system.addCompToSystemMatrix(mNode1, mVirtualNodes[0], -mConductance, 0);
			system.addCompToSystemMatrix(mVirtualNodes[0], mNode1, -mConductance, 0);
Viviane's avatar
Viviane committed
90
91
92
93
		}

		// Inductance part
		// Set diagonal entries
94
95
		if (mVirtualNodes[0] >= 0) {
			system.addCompToSystemMatrix(mVirtualNodes[0], mVirtualNodes[0], mGlr, mGli);
Viviane's avatar
Viviane committed
96
97
98
99
100
		}
		if (mNode2 >= 0) {
			system.addCompToSystemMatrix(mNode2, mNode2, mGlr, mGli);
		}

101
102
103
		if (mVirtualNodes[0] >= 0 && mNode2 >= 0) {
			system.addCompToSystemMatrix(mVirtualNodes[0], mNode2, -mGlr, -mGli);
			system.addCompToSystemMatrix(mNode2, mVirtualNodes[0], -mGlr, -mGli);
Viviane's avatar
Viviane committed
104
		}
Viviane's avatar
Viviane committed
105
106
107
	}
}

108
void RxLineDP::init(Real om, Real dt) {
Viviane's avatar
Viviane committed
109
	// Initialize internal state
110
111
112
113
114
115
	mCurrRe = 0;
	mCurrIm = 0;
	mCurEqRe = 0;
	mCurEqIm = 0;
	mDeltaVre = 0;
	mDeltaVim = 0;
Viviane's avatar
Viviane committed
116
117
118

	deltavr_ind = 0;
	deltavi_ind = 0;
119
120
	curri_ind = 0;
	currr_ind = 0;
Viviane's avatar
Viviane committed
121
122
	cureqr_ind = 0;
	cureqi_ind = 0;
Viviane's avatar
Viviane committed
123
124
}

125
void RxLineDP::step(SystemModel& system, Real time) {
Viviane's avatar
Viviane committed
126

127
	if (mType == LineTypes::RxLine2Node) {
Viviane's avatar
Viviane committed
128
129

		// Initialize internal state
130
131
		cureqr_ind = mPrevCurFacRe*currr_ind - mPrevCurFacIm*mCurrIm + mGlr*deltavr_ind - mGli*deltavi_ind;
		cureqi_ind = mPrevCurFacIm*currr_ind + mPrevCurFacRe*mCurrIm + mGli*deltavr_ind + mGlr*deltavi_ind;
Viviane's avatar
Viviane committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145

		mCurEqRe = cureqr_ind*correctr - cureqi_ind*correcti;
		mCurEqIm = cureqi_ind*correctr + correcti*cureqr_ind;

		//cout << "cureq = " << cureq << endl;

		if (mNode1 >= 0) {
			system.addCompToRightSideVector(mNode1, -mCurEqRe, -mCurEqIm);
		}

		if (mNode2 >= 0) {
			system.addCompToRightSideVector(mNode2, mCurEqRe, mCurEqIm);
		}

Viviane's avatar
Viviane committed
146
	}
Viviane's avatar
Viviane committed
147
148
149
150
151
152
153

	else {

		// Initialize internal state
		mCurEqRe = mGlr * mDeltaVre - mGli * mDeltaVim + mPrevCurFacRe * mCurrRe - mPrevCurFacIm * mCurrIm;
		mCurEqIm = mGli * mDeltaVre + mGlr * mDeltaVim + mPrevCurFacIm * mCurrRe + mPrevCurFacRe * mCurrIm;

154
155
		if (mVirtualNodes[0] >= 0) {
			system.addCompToRightSideVector(mVirtualNodes[0], -mCurEqRe, -mCurEqIm);
Viviane's avatar
Viviane committed
156
157
158
159
		}
		if (mNode2 >= 0) {
			system.addCompToRightSideVector(mNode2, mCurEqRe, mCurEqIm);
		}
Viviane's avatar
Viviane committed
160
161
162
	}
}

163
void RxLineDP::postStep(SystemModel& system) {
Steffen Vogel's avatar
Steffen Vogel committed
164

165
	if (mType == LineTypes::RxLine2Node) {
Viviane's avatar
Viviane committed
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

		Real vposr, vnegr;
		Real vposi, vnegi;

		// extract solution
		if (mNode1 >= 0) {
			vposr = system.getRealFromLeftSideVector(mNode1);
			vposi = system.getImagFromLeftSideVector(mNode1);
		}
		else {
			vposr = 0;
			vposi = 0;
		}

		if (mNode2 >= 0) {
			vnegr = system.getRealFromLeftSideVector(mNode2);
			vnegi = system.getImagFromLeftSideVector(mNode2);
		}
		else {
			vnegr = 0;
			vnegi = 0;
		}

		mDeltaVre = vposr - vnegr;
		mDeltaVim = vposi - vnegi;

		mCurrRe = mGlr * mDeltaVre - mGli * mDeltaVim + mCurEqRe;
		mCurrIm = mGli * mDeltaVre + mGlr * mDeltaVim + mCurEqIm;

		deltavr_ind = vposr - mResistance*mCurrRe - vnegr;
		deltavi_ind = vposi - mResistance*mCurrIm - vnegi;

198
199
		currr_ind = mCurrRe;
		curri_ind = mCurrIm;
Viviane's avatar
Viviane committed
200
201
202
	}

	else{
203
	Real vposr, vnegr, vposi, vnegi;
Viviane's avatar
Viviane committed
204
205

	// extract solution
206
207
208
209
	if (mVirtualNodes[0] >= 0) {
		system.getRealFromLeftSideVector(mVirtualNodes[0]);
		vposr = system.getRealFromLeftSideVector(mVirtualNodes[0]);
		vposi = system.getImagFromLeftSideVector(mVirtualNodes[0]);
Viviane's avatar
Viviane committed
210
211
212
213
214
	}
	else {
		vposr = 0;
		vposi = 0;
	}
Viviane's avatar
Viviane committed
215

Viviane's avatar
Viviane committed
216
	if (mNode2 >= 0) {
Viviane's avatar
Viviane committed
217
		system.getRealFromLeftSideVector(mNode2);
218
219
		vnegr = system.getRealFromLeftSideVector(mNode2);
		vnegi = system.getImagFromLeftSideVector(mNode2);
Viviane's avatar
Viviane committed
220
221
222
223
224
	}
	else {
		vnegr = 0;
		vnegi = 0;
	}
225
226
227
228
	mDeltaVre = vposr - vnegr;
	mDeltaVim = vposi - vnegi;
	mCurrRe = mGlr * mDeltaVre - mGli * mDeltaVim + mCurEqRe;
	mCurrIm = mGli * mDeltaVre + mGlr * mDeltaVim + mCurEqIm;
Viviane's avatar
Viviane committed
229
	}
Viviane's avatar
Viviane committed
230
}
Viviane's avatar
Viviane committed
231

232
Complex RxLineDP::getCurrent(SystemModel& system) {
233
234
	return Complex(mCurrRe, mCurrIm);
}