EMT_Ph3_VoltageSource.cpp 7.66 KB
Newer Older
1
2
/* Copyright 2017-2020 Institute for Automation of Complex Power Systems,
 *                     EONERC, RWTH Aachen University
Markus Mirz's avatar
Markus Mirz committed
3
 *
4
5
6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
Markus Mirz's avatar
Markus Mirz committed
7
8
9
 *********************************************************************************/

#include <cps/EMT/EMT_Ph3_VoltageSource.h>
10
#include <cps/CIM/Reader.h>
Markus Mirz's avatar
Markus Mirz committed
11
12
13
14
15


using namespace CPS;

EMT::Ph3::VoltageSource::VoltageSource(String uid, String name, Logger::Level logLevel)
16
	: SimPowerComp<Real>(uid, name, logLevel) {
Markus Mirz's avatar
Markus Mirz committed
17
18
19
20
21
22
	mPhaseType = PhaseType::ABC;
	setVirtualNodeNumber(1);
	setTerminalNumber(2);
	mIntfVoltage = Matrix::Zero(3, 1);
	mIntfCurrent = Matrix::Zero(3, 1);

23
	addAttribute<MatrixComp>("V_ref", Flags::read | Flags::write);  // rms-value, phase-to-phase
Markus Mirz's avatar
Markus Mirz committed
24
25
26
	addAttribute<Real>("f_src", Flags::read | Flags::write);
}

Jan Dinkelbach's avatar
Jan Dinkelbach committed
27
28
void EMT::Ph3::VoltageSource::setParameters(MatrixComp voltageRef, Real srcFreq) {
	attribute<MatrixComp>("V_ref")->set(voltageRef);
Markus Mirz's avatar
Markus Mirz committed
29
	attribute<Real>("f_src")->set(srcFreq);
30

31
32
	mSLog->info("\nVoltage reference phasor [V]: {:s}"
				"\nFrequency [Hz]: {:s}", 
Jan Dinkelbach's avatar
Jan Dinkelbach committed
33
				Logger::matrixCompToString(voltageRef), 
34
				Logger::realToString(srcFreq));
35

36
	mParametersSet = true;
Markus Mirz's avatar
Markus Mirz committed
37
38
}

Jan Dinkelbach's avatar
Jan Dinkelbach committed
39
void EMT::Ph3::VoltageSource::initializeFromNodesAndTerminals(Real frequency) {
Jan Dinkelbach's avatar
Jan Dinkelbach committed
40

Jan Dinkelbach's avatar
Jan Dinkelbach committed
41
	mSLog->info("\n--- Initialization from node voltages ---");
42
	// TODO: this approach currently overwrites voltage reference set from outside, when not using setParameters
Jan Dinkelbach's avatar
Jan Dinkelbach committed
43
	if (!mParametersSet) {
44
45
		attribute<MatrixComp>("V_ref")->set(CIM::Reader::singlePhaseVariableToThreePhase(initialSingleVoltage(1) - initialSingleVoltage(0)));
		attribute<Real>("f_src")->set(frequency);
Jan Dinkelbach's avatar
Jan Dinkelbach committed
46
47

		mSLog->info("\nReference voltage: {:s}"
48
49
					"\nTerminal 0 voltage: {:s}"
					"\nTerminal 1 voltage: {:s}",
50
51
52
					Logger::matrixCompToString(attribute<MatrixComp>("V_ref")->get()),
					Logger::phasorToString(initialSingleVoltage(0)),
					Logger::phasorToString(initialSingleVoltage(1)));
Jan Dinkelbach's avatar
Jan Dinkelbach committed
53
54
55
	} else {
		mSLog->info("\nInitialization from node voltages omitted (parameter already set)."
					"\nReference voltage: {:s}",
56
					Logger::matrixCompToString(attribute<MatrixComp>("V_ref")->get()));
Jan Dinkelbach's avatar
Jan Dinkelbach committed
57
	}
Jan Dinkelbach's avatar
Jan Dinkelbach committed
58
	mSLog->info("\n--- Initialization from node voltages ---");
Jan Dinkelbach's avatar
Jan Dinkelbach committed
59
60
61
	mSLog->flush();
}

Markus Mirz's avatar
Markus Mirz committed
62
SimPowerComp<Real>::Ptr EMT::Ph3::VoltageSource::clone(String name) {
Markus Mirz's avatar
Markus Mirz committed
63
	auto copy = VoltageSource::make(name, mLogLevel);
Jan Dinkelbach's avatar
Jan Dinkelbach committed
64
	copy->setParameters(attribute<MatrixComp>("V_ref")->get(), attribute<Real>("f_src")->get());
Markus Mirz's avatar
Markus Mirz committed
65
66
67
68
69
70
71
	return copy;
}


void EMT::Ph3::VoltageSource::mnaInitialize(Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
	MNAInterface::mnaInitialize(omega, timeStep);

Markus Mirz's avatar
Markus Mirz committed
72
	updateMatrixNodeIndices();
Jan Dinkelbach's avatar
Jan Dinkelbach committed
73

Markus Mirz's avatar
Markus Mirz committed
74
75
	mMnaTasks.push_back(std::make_shared<MnaPreStep>(*this));
	mMnaTasks.push_back(std::make_shared<MnaPostStep>(*this, leftVector));
Jan Dinkelbach's avatar
Jan Dinkelbach committed
76

Markus Mirz's avatar
Markus Mirz committed
77
	mRightVector = Matrix::Zero(leftVector->get().rows(), 1);
Jan Dinkelbach's avatar
Jan Dinkelbach committed
78

Markus Mirz's avatar
Markus Mirz committed
79
80
81
82
}

void EMT::Ph3::VoltageSource::mnaApplySystemMatrixStamp(Matrix& systemMatrix) {
	if (terminalNotGrounded(0)) {
Markus Mirz's avatar
Markus Mirz committed
83
84
		Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 0), mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), -1);
		Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), matrixNodeIndex(0, 0), -1);
Markus Mirz's avatar
Markus Mirz committed
85

Markus Mirz's avatar
Markus Mirz committed
86
87
		Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 1), mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), -1);
		Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), matrixNodeIndex(0, 1), -1);
Markus Mirz's avatar
Markus Mirz committed
88

Markus Mirz's avatar
Markus Mirz committed
89
90
		Math::addToMatrixElement(systemMatrix, matrixNodeIndex(0, 2), mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), -1);
		Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), matrixNodeIndex(0, 2), -1);
Markus Mirz's avatar
Markus Mirz committed
91
92
	}
	if (terminalNotGrounded(1)) {
Markus Mirz's avatar
Markus Mirz committed
93
94
		Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 0), mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), 1);
		Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), matrixNodeIndex(1, 0), 1);
Markus Mirz's avatar
Markus Mirz committed
95

Markus Mirz's avatar
Markus Mirz committed
96
97
		Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 1), mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), 1);
		Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), matrixNodeIndex(1, 1), 1);
Markus Mirz's avatar
Markus Mirz committed
98

Markus Mirz's avatar
Markus Mirz committed
99
100
		Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), 1);
		Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), matrixNodeIndex(1, 2), 1);
Markus Mirz's avatar
Markus Mirz committed
101
102
103
104
	}


	// if (terminalNotGrounded(0)) {
Markus Mirz's avatar
Markus Mirz committed
105
106
	// 	mLog.debug() << "Add " << -1 << " to " << matrixNodeIndex(0) << "," << mVirtualNodes[0]->matrixNodeIndex() << std::endl;
	// 	mLog.debug() << "Add " << -1 << " to " << mVirtualNodes[0]->matrixNodeIndex() << "," << matrixNodeIndex(0) << std::endl;
Markus Mirz's avatar
Markus Mirz committed
107
108
	// }
	// if (terminalNotGrounded(1)) {
Markus Mirz's avatar
Markus Mirz committed
109
110
	// 	mLog.debug() << "Add " << 1 << " to " << matrixNodeIndex(1) << "," << mVirtualNodes[0]->matrixNodeIndex() << std::endl;
	// 	mLog.debug() << "Add " << 1 << " to " << mVirtualNodes[0]->matrixNodeIndex() << "," << matrixNodeIndex(1) << std::endl;
Markus Mirz's avatar
Markus Mirz committed
111
112
113
114
	// }
}

void EMT::Ph3::VoltageSource::mnaApplyRightSideVectorStamp(Matrix& rightVector) {
Markus Mirz's avatar
Markus Mirz committed
115
116
117
	Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A), mIntfVoltage(0, 0));
	Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B), mIntfVoltage(1, 0));
	Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C), mIntfVoltage(2, 0));
Markus Mirz's avatar
Markus Mirz committed
118
119
120
}

void EMT::Ph3::VoltageSource::updateVoltage(Real time) {
121
122
	if (attribute<Real>("f_src")->get() < 0) {
		mIntfVoltage = RMS3PH_TO_PEAK1PH * attribute<MatrixComp>("V_ref")->get().real();
Markus Mirz's avatar
Markus Mirz committed
123
124
	}
	else {
Jan Dinkelbach's avatar
Jan Dinkelbach committed
125
		mIntfVoltage(0, 0) =
126
			RMS3PH_TO_PEAK1PH * Math::abs(attribute<MatrixComp>("V_ref")->get()(0, 0)) * cos(time * 2. * PI * attribute<Real>("f_src")->get() + Math::phase(attribute<MatrixComp>("V_ref")->get())(0, 0));
Jan Dinkelbach's avatar
Jan Dinkelbach committed
127
		mIntfVoltage(1, 0) =
128
			RMS3PH_TO_PEAK1PH * Math::abs(attribute<MatrixComp>("V_ref")->get()(1, 0)) * cos(time * 2. * PI * attribute<Real>("f_src")->get() + Math::phase(attribute<MatrixComp>("V_ref")->get())(1, 0));
Jan Dinkelbach's avatar
Jan Dinkelbach committed
129
		mIntfVoltage(2, 0) =
130
			RMS3PH_TO_PEAK1PH * Math::abs(attribute<MatrixComp>("V_ref")->get()(2, 0)) * cos(time * 2. * PI * attribute<Real>("f_src")->get() + Math::phase(attribute<MatrixComp>("V_ref")->get())(2, 0));
Markus Mirz's avatar
Markus Mirz committed
131
	}
Jan Dinkelbach's avatar
Jan Dinkelbach committed
132
133
134
135
136

	mSLog->debug(
		"\nUpdate Voltage: {:s}",
		Logger::matrixToString(mIntfVoltage)
	);
Markus Mirz's avatar
Markus Mirz committed
137
138
}

139
140
141
142
143
144
145
146
147
void EMT::Ph3::VoltageSource::mnaAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) {
	attributeDependencies.push_back(attribute("V_ref"));
	modifiedAttributes.push_back(attribute("right_vector"));
	modifiedAttributes.push_back(attribute("v_intf"));
}

void EMT::Ph3::VoltageSource::mnaPreStep(Real time, Int timeStepCount) {
	updateVoltage(time);
	mnaApplyRightSideVectorStamp(mRightVector);
Markus Mirz's avatar
Markus Mirz committed
148
149
}

150
151
152
153
154
155
156
void EMT::Ph3::VoltageSource::mnaAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute<Matrix>::Ptr &leftVector) {
	attributeDependencies.push_back(leftVector);
	modifiedAttributes.push_back(attribute("i_intf"));
};

void EMT::Ph3::VoltageSource::mnaPostStep(Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
	mnaUpdateCurrent(*leftVector);
Markus Mirz's avatar
Markus Mirz committed
157
158
159
}

void EMT::Ph3::VoltageSource::mnaUpdateCurrent(const Matrix& leftVector) {
Markus Mirz's avatar
Markus Mirz committed
160
161
162
	mIntfCurrent(0, 0) = Math::realFromVectorElement(leftVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::A));
	mIntfCurrent(1, 0) = Math::realFromVectorElement(leftVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::B));
	mIntfCurrent(2, 0) = Math::realFromVectorElement(leftVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::C));
Markus Mirz's avatar
Markus Mirz committed
163
}