9#include <dpsim-models/SP/SP_Ph1_Transformer.h>
15 Logger::Level logLevel,
16 Bool withResistiveLosses)
25 if (withResistiveLosses)
26 setVirtualNodeNumber(3);
28 setVirtualNodeNumber(2);
30 SPDLOG_LOGGER_INFO(
mSLog,
"Create {} {}", this->
type(), name);
41 Real nomVoltageEnd2, Real ratioAbs,
42 Real ratioPhase, Real resistance,
46 Base::Ph1::Transformer::setParameters(nomVoltageEnd1, nomVoltageEnd2,
47 ratioAbs, ratioPhase, resistance,
51 mSLog,
"Nominal Voltage End 1={} [V] Nominal Voltage End 2={} [V]",
54 mSLog,
"Resistance={} [Ohm] Inductance={} [H] (referred to primary side)",
56 SPDLOG_LOGGER_INFO(
mSLog,
"Tap Ratio={} [/] Phase Shift={} [deg]",
60 mRatioAbs = std::abs(**
mRatio);
61 mRatioPhase = std::arg(**
mRatio);
67 Real nomVoltageEnd2, Real ratedPower,
68 Real ratioAbs, Real ratioPhase,
69 Real resistance, Real inductance) {
75 ratioPhase, resistance, inductance);
80 auto copy = Transformer::make(name,
mLogLevel);
88 mNominalOmega = 2. * PI * frequency;
90 SPDLOG_LOGGER_INFO(
mSLog,
"Reactance={} [Ohm] (referred to primary side)",
96 if (Math::abs(**
mRatio) < 1.) {
98 mRatioAbs = std::abs(**
mRatio);
99 mRatioPhase = std::arg(**
mRatio);
100 std::shared_ptr<SimTerminal<Complex>> tmp =
mTerminals[0];
106 SPDLOG_LOGGER_INFO(
mSLog,
"Switching terminals to have first terminal at "
107 "higher voltage side. Updated parameters: ");
109 mSLog,
"Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
111 SPDLOG_LOGGER_INFO(
mSLog,
"Tap Ratio = {} [ ] Phase Shift = {} [deg]",
112 mRatioAbs, mRatioPhase);
120 (**mIntfVoltage)(0, 0) =
121 mVirtualNodes[0]->initialSingleVoltage() - initialSingleVoltage(0);
122 (**mIntfCurrent)(0, 0) = (**
mIntfVoltage)(0, 0) / impedance;
125 mSubInductor = std::make_shared<SP::Ph1::Inductor>(
126 **
mUID +
"_ind", **
mName +
"_ind", Logger::Level::off);
129 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
132 mVirtualNodes[2]->setInitialVoltage(initialSingleVoltage(0));
133 mSubResistor = std::make_shared<SP::Ph1::Resistor>(
134 **
mUID +
"_res", **
mName +
"_res", Logger::Level::off);
139 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
145 if (
mBehaviour == TopologicalPowerComp::Behaviour::Initialization ||
146 mBehaviour == TopologicalPowerComp::Behaviour::MNASimulation) {
154 std::make_shared<SP::Ph1::Resistor>(**
mName +
"_snub_res1",
mLogLevel);
155 mSubSnubResistor1->setParameters(mSnubberResistance1);
156 mSubSnubResistor1->connect({
node(0), SP::SimNode::GND});
159 "Snubber Resistance 1 (connected to higher voltage side {}) = {} [Ohm]",
160 node(0)->name(), Logger::realToString(mSnubberResistance1));
163 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
164 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
169 std::make_shared<SP::Ph1::Resistor>(**
mName +
"_snub_res2",
mLogLevel);
170 mSubSnubResistor2->setParameters(mSnubberResistance2);
171 mSubSnubResistor2->connect({
node(1), SP::SimNode::GND});
174 "Snubber Resistance 2 (connected to lower voltage side {}) = {} [Ohm]",
175 node(1)->name(), Logger::realToString(mSnubberResistance2));
178 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
179 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
191 mSnubberCapacitance2 =
194 std::make_shared<SP::Ph1::Capacitor>(**
mName +
"_snub_cap2",
mLogLevel);
195 mSubSnubCapacitor2->setParameters(mSnubberCapacitance2);
196 mSubSnubCapacitor2->connect({
node(1), SP::SimNode::GND});
199 "Snubber Capacitance 2 (connected to lower voltage side {}) = {} [F]",
200 node(1)->name(), Logger::realToString(mSnubberCapacitance2));
203 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
204 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
208 SPDLOG_LOGGER_INFO(
mSLog,
"Electrical subcomponents: ");
210 SPDLOG_LOGGER_INFO(
mSLog,
"- {}", subcomp->name());
212 subcomp->initializeFromNodesAndTerminals(frequency);
217 "\n--- Initialization from powerflow ---"
218 "\nVoltage across: {:s}"
220 "\nTerminal 0 voltage: {:s}"
221 "\nTerminal 1 voltage: {:s}"
222 "\nVirtual Node 1 voltage: {:s}"
223 "\n--- Initialization from powerflow finished ---",
226 Logger::phasorToString(initialSingleVoltage(0)),
227 Logger::phasorToString(initialSingleVoltage(1)),
228 Logger::phasorToString(
mVirtualNodes[0]->initialSingleVoltage()));
241void SP::Ph1::Transformer::setBaseVoltage(Real baseVoltage) {
244 **mBaseVoltage = baseVoltage;
249 SPDLOG_LOGGER_INFO(
mSLog,
"#### Calculate Per Unit Parameters for {}",
251 mBaseApparentPower = baseApparentPower;
252 mBaseOmega = baseOmega;
253 SPDLOG_LOGGER_INFO(
mSLog,
"Base Power={} [VA] Base Omega={} [1/s]",
254 baseApparentPower, baseOmega);
257 mBaseAdmittance = 1.0 / mBaseImpedance;
258 mBaseCurrent = baseApparentPower /
261 SPDLOG_LOGGER_INFO(
mSLog,
"Base Voltage={} [V] Base Impedance={} [Ohm]",
264 mResistancePerUnit = **
mResistance / mBaseImpedance;
265 mReactancePerUnit = mReactance / mBaseImpedance;
266 SPDLOG_LOGGER_INFO(
mSLog,
"Resistance={} [pu] Reactance={} [pu]",
267 mResistancePerUnit, mReactancePerUnit);
269 mBaseInductance = mBaseImpedance / mBaseOmega;
270 mInductancePerUnit = **
mInductance / mBaseInductance;
272 mLeakagePerUnit = Complex(mResistancePerUnit, 1. * mInductancePerUnit);
273 SPDLOG_LOGGER_INFO(
mSLog,
"Leakage Impedance={} [pu] ", mLeakagePerUnit);
276 SPDLOG_LOGGER_INFO(
mSLog,
"Tap Ratio={} [pu]", mRatioAbsPerUnit);
279 if (mSubSnubResistor1)
280 mSubSnubResistor1->calculatePerUnitParameters(mBaseApparentPower);
281 if (mSubSnubResistor2)
282 mSubSnubResistor2->calculatePerUnitParameters(mBaseApparentPower);
283 if (mSubSnubCapacitor1)
284 mSubSnubCapacitor1->calculatePerUnitParameters(mBaseApparentPower);
285 if (mSubSnubCapacitor2)
286 mSubSnubCapacitor2->calculatePerUnitParameters(mBaseApparentPower);
290 SparseMatrixCompRow &Y) {
292 mY_element = MatrixComp(2, 2);
293 Complex y = Complex(1, 0) / mLeakagePerUnit;
295 mY_element(0, 0) = y;
296 mY_element(0, 1) = -y * mRatioAbsPerUnit;
297 mY_element(1, 0) = -y * mRatioAbsPerUnit;
298 mY_element(1, 1) = y * std::pow(mRatioAbsPerUnit, 2);
301 for (
int i = 0; i < 2; i++)
302 for (
int j = 0; j < 2; j++)
303 if (std::isinf(mY_element.coeff(i, j).real()) ||
304 std::isinf(mY_element.coeff(i, j).imag())) {
305 std::cout << mY_element << std::endl;
306 std::cout <<
"Zl:" << mLeakage << std::endl;
307 std::cout <<
"tap:" << mRatioAbsPerUnit << std::endl;
308 std::stringstream ss;
309 ss <<
"Transformer>>" << this->name()
310 <<
": infinite or nan values in the element Y at: " << i <<
"," << j;
311 throw std::invalid_argument(ss.str());
315 Y.coeffRef(this->matrixNodeIndex(0), this->matrixNodeIndex(0)) +=
316 mY_element.coeff(0, 0);
317 Y.coeffRef(this->matrixNodeIndex(0), this->matrixNodeIndex(1)) +=
318 mY_element.coeff(0, 1);
319 Y.coeffRef(this->matrixNodeIndex(1), this->matrixNodeIndex(1)) +=
320 mY_element.coeff(1, 1);
321 Y.coeffRef(this->matrixNodeIndex(1), this->matrixNodeIndex(0)) +=
322 mY_element.coeff(1, 0);
324 SPDLOG_LOGGER_INFO(
mSLog,
"#### Y matrix stamping: {}", mY_element);
326 if (mSubSnubResistor1)
327 mSubSnubResistor1->pfApplyAdmittanceMatrixStamp(Y);
328 if (mSubSnubResistor2)
329 mSubSnubResistor2->pfApplyAdmittanceMatrixStamp(Y);
330 if (mSubSnubCapacitor1)
331 mSubSnubCapacitor1->pfApplyAdmittanceMatrixStamp(Y);
332 if (mSubSnubCapacitor2)
333 mSubSnubCapacitor2->pfApplyAdmittanceMatrixStamp(Y);
337 VectorComp &powerflow) {
338 **
mCurrent = current * mBaseCurrent;
353 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
356 "\nTerminal 0 connected to {:s} = sim node {:d}"
357 "\nTerminal 1 connected to {:s} = sim node {:d}",
363 SparseMatrixRow &systemMatrix) {
365 if (terminalNotGrounded(0)) {
366 Math::setMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(),
369 Math::setMatrixElement(systemMatrix,
mVirtualNodes[1]->matrixNodeIndex(),
373 if (terminalNotGrounded(1)) {
374 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1),
376 Math::setMatrixElement(systemMatrix,
mVirtualNodes[1]->matrixNodeIndex(),
377 matrixNodeIndex(1), -**
mRatio);
382 if (
auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
383 mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
385 if (terminalNotGrounded(0)) {
386 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
387 Logger::complexToString(Complex(-1.0, 0)),
390 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
391 Logger::complexToString(Complex(1.0, 0)),
395 if (terminalNotGrounded(1)) {
396 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
397 Logger::complexToString(**
mRatio), matrixNodeIndex(1),
399 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
400 Logger::complexToString(-**
mRatio),
406 AttributeBase::List &prevStepDependencies,
407 AttributeBase::List &attributeDependencies,
408 AttributeBase::List &modifiedAttributes) {
419 AttributeBase::List &prevStepDependencies,
420 AttributeBase::List &attributeDependencies,
421 AttributeBase::List &modifiedAttributes,
422 Attribute<Matrix>::Ptr &leftVector) {
423 attributeDependencies.push_back(leftVector);
429 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
435 (**mIntfCurrent)(0, 0) = mSubInductor->intfCurrent()(0, 0);
436 SPDLOG_LOGGER_DEBUG(
mSLog,
"Current {:s}",
442 (**mIntfVoltage)(0, 0) = 0;
443 (**mIntfVoltage)(0, 0) =
444 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
446 Math::complexFromVectorElement(
448 SPDLOG_LOGGER_DEBUG(
mSLog,
"Voltage {:s}",
void addMNASubComponent(typename SimPowerComp< Complex >::Ptr subc, MNA_SUBCOMP_TASK_ORDER preStepOrder, MNA_SUBCOMP_TASK_ORDER postStepOrder, Bool contributeToRightVector)
void mnaCompApplyRightSideVectorStamp(Matrix &rightVector) override
CompositePowerComp(String uid, String name, Bool hasPreStep, Bool hasPostStep, Logger::Level logLevel)
const Attribute< String >::Ptr mName
Human readable name.
String uid()
Returns unique id.
String type()
Get component type (cross-platform)
const Attribute< String >::Ptr mUID
Unique identifier.
AttributeList::Ptr mAttributes
Attribute List.
void mnaUpdateCurrent(const Matrix &leftVector) final
void mnaUpdateVoltage(const Matrix &leftVector) final
Attribute< Matrix >::Ptr mRightVector
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
SimTerminal< Complex >::List mTerminals
SimNode< Complex >::Ptr node(UInt index)
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
SimNode< Complex >::List mVirtualNodes
std::vector< std::shared_ptr< SimPowerComp< Complex > > > mSubComponents
Logger::Level mLogLevel
Component logger control for internal variables.
UInt mNumVirtualNodes
Determines the number of virtual or internal Nodes.
bool mParametersSet
Flag indicating that parameters are set via setParameters() function.
Logger::Log mSLog
Component logger.