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);
93 if (Math::abs(**
mRatio) < 1.) {
95 mRatioAbs = std::abs(**
mRatio);
96 mRatioPhase = std::arg(**
mRatio);
97 std::shared_ptr<SimTerminal<Complex>> tmp =
mTerminals[0];
103 SPDLOG_LOGGER_INFO(
mSLog,
"Switching terminals to have first terminal at "
104 "higher voltage side. Updated parameters: ");
106 mSLog,
"Nominal Voltage End 1 = {} [V] Nominal Voltage End 2 = {} [V]",
108 SPDLOG_LOGGER_INFO(
mSLog,
"Tap Ratio = {} [ ] Phase Shift = {} [deg]",
109 mRatioAbs, mRatioPhase);
113 mSubInductor = std::make_shared<SP::Ph1::Inductor>(
114 **
mUID +
"_ind", **
mName +
"_ind", Logger::Level::off);
117 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
120 mSubResistor = std::make_shared<SP::Ph1::Resistor>(
121 **
mUID +
"_res", **
mName +
"_res", Logger::Level::off);
126 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
133 if (
mBehaviour == TopologicalPowerComp::Behaviour::Initialization ||
134 mBehaviour == TopologicalPowerComp::Behaviour::MNASimulation) {
137 std::make_shared<SP::Ph1::Resistor>(**
mName +
"_snub_res1",
mLogLevel);
138 mSubSnubResistor1->connect({
node(0), SP::SimNode::GND});
140 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
141 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
144 std::make_shared<SP::Ph1::Resistor>(**
mName +
"_snub_res2",
mLogLevel);
145 mSubSnubResistor2->connect({
node(1), SP::SimNode::GND});
147 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
148 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
151 std::make_shared<SP::Ph1::Capacitor>(**
mName +
"_snub_cap2",
mLogLevel);
152 mSubSnubCapacitor2->connect({
node(1), SP::SimNode::GND});
154 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
155 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
161 mNominalOmega = 2. * PI * frequency;
163 SPDLOG_LOGGER_INFO(
mSLog,
"Reactance={} [Ohm] (referred to primary side)",
166 if (mSubSnubResistor1) {
172 mSubSnubResistor1->setParameters(mSnubberResistance1);
175 "Snubber Resistance 1 (connected to higher voltage side {}) = {} [Ohm]",
176 node(0)->name(), Logger::realToString(mSnubberResistance1));
181 mSubSnubResistor2->setParameters(mSnubberResistance2);
184 "Snubber Resistance 2 (connected to lower voltage side {}) = {} [Ohm]",
185 node(1)->name(), Logger::realToString(mSnubberResistance2));
198 mSnubberCapacitance2 =
200 mSubSnubCapacitor2->setParameters(mSnubberCapacitance2);
203 "Snubber Capacitance 2 (connected to lower voltage side {}) = {} [F]",
204 node(1)->name(), Logger::realToString(mSnubberCapacitance2));
213 (**mIntfVoltage)(0, 0) =
214 mVirtualNodes[0]->initialSingleVoltage() - initialSingleVoltage(0);
215 (**mIntfCurrent)(0, 0) = (**
mIntfVoltage)(0, 0) / impedance;
218 mVirtualNodes[2]->setInitialVoltage(initialSingleVoltage(0));
222 "\n--- Initialization from powerflow ---"
223 "\nVoltage across: {:s}"
225 "\nTerminal 0 voltage: {:s}"
226 "\nTerminal 1 voltage: {:s}"
227 "\nVirtual Node 1 voltage: {:s}"
228 "\n--- Initialization from powerflow finished ---",
231 Logger::phasorToString(initialSingleVoltage(0)),
232 Logger::phasorToString(initialSingleVoltage(1)),
233 Logger::phasorToString(
mVirtualNodes[0]->initialSingleVoltage()));
246void SP::Ph1::Transformer::setBaseVoltage(Real baseVoltage) {
249 **mBaseVoltage = baseVoltage;
254 SPDLOG_LOGGER_INFO(
mSLog,
"#### Calculate Per Unit Parameters for {}",
256 mBaseApparentPower = baseApparentPower;
257 mBaseOmega = baseOmega;
258 SPDLOG_LOGGER_INFO(
mSLog,
"Base Power={} [VA] Base Omega={} [1/s]",
259 baseApparentPower, baseOmega);
262 mBaseAdmittance = 1.0 / mBaseImpedance;
263 mBaseCurrent = baseApparentPower /
266 SPDLOG_LOGGER_INFO(
mSLog,
"Base Voltage={} [V] Base Impedance={} [Ohm]",
269 mResistancePerUnit = **
mResistance / mBaseImpedance;
270 mReactancePerUnit = mReactance / mBaseImpedance;
271 SPDLOG_LOGGER_INFO(
mSLog,
"Resistance={} [pu] Reactance={} [pu]",
272 mResistancePerUnit, mReactancePerUnit);
274 mBaseInductance = mBaseImpedance / mBaseOmega;
275 mInductancePerUnit = **
mInductance / mBaseInductance;
277 mLeakagePerUnit = Complex(mResistancePerUnit, 1. * mInductancePerUnit);
278 SPDLOG_LOGGER_INFO(
mSLog,
"Leakage Impedance={} [pu] ", mLeakagePerUnit);
281 SPDLOG_LOGGER_INFO(
mSLog,
"Tap Ratio={} [pu]", mRatioAbsPerUnit);
284 if (mSubSnubResistor1)
285 mSubSnubResistor1->calculatePerUnitParameters(mBaseApparentPower);
286 if (mSubSnubResistor2)
287 mSubSnubResistor2->calculatePerUnitParameters(mBaseApparentPower);
288 if (mSubSnubCapacitor1)
289 mSubSnubCapacitor1->calculatePerUnitParameters(mBaseApparentPower);
290 if (mSubSnubCapacitor2)
291 mSubSnubCapacitor2->calculatePerUnitParameters(mBaseApparentPower);
295 SparseMatrixCompRow &Y) {
297 mY_element = MatrixComp(2, 2);
298 Complex y = Complex(1, 0) / mLeakagePerUnit;
300 mY_element(0, 0) = y;
301 mY_element(0, 1) = -y * mRatioAbsPerUnit;
302 mY_element(1, 0) = -y * mRatioAbsPerUnit;
303 mY_element(1, 1) = y * std::pow(mRatioAbsPerUnit, 2);
306 for (
int i = 0; i < 2; i++)
307 for (
int j = 0; j < 2; j++)
308 if (std::isinf(mY_element.coeff(i, j).real()) ||
309 std::isinf(mY_element.coeff(i, j).imag())) {
310 std::cout << mY_element << std::endl;
311 std::cout <<
"Zl:" << mLeakage << std::endl;
312 std::cout <<
"tap:" << mRatioAbsPerUnit << std::endl;
313 std::stringstream ss;
314 ss <<
"Transformer>>" << this->name()
315 <<
": infinite or nan values in the element Y at: " << i <<
"," << j;
316 throw std::invalid_argument(ss.str());
320 Y.coeffRef(this->matrixNodeIndex(0), this->matrixNodeIndex(0)) +=
321 mY_element.coeff(0, 0);
322 Y.coeffRef(this->matrixNodeIndex(0), this->matrixNodeIndex(1)) +=
323 mY_element.coeff(0, 1);
324 Y.coeffRef(this->matrixNodeIndex(1), this->matrixNodeIndex(1)) +=
325 mY_element.coeff(1, 1);
326 Y.coeffRef(this->matrixNodeIndex(1), this->matrixNodeIndex(0)) +=
327 mY_element.coeff(1, 0);
329 SPDLOG_LOGGER_INFO(
mSLog,
"#### Y matrix stamping: {}", mY_element);
331 if (mSubSnubResistor1)
332 mSubSnubResistor1->pfApplyAdmittanceMatrixStamp(Y);
333 if (mSubSnubResistor2)
334 mSubSnubResistor2->pfApplyAdmittanceMatrixStamp(Y);
335 if (mSubSnubCapacitor1)
336 mSubSnubCapacitor1->pfApplyAdmittanceMatrixStamp(Y);
337 if (mSubSnubCapacitor2)
338 mSubSnubCapacitor2->pfApplyAdmittanceMatrixStamp(Y);
342 VectorComp &powerflow) {
343 **
mCurrent = current * mBaseCurrent;
358 Real omega, Real timeStep, Attribute<Matrix>::Ptr leftVector) {
361 "\nTerminal 0 connected to {:s} = sim node {:d}"
362 "\nTerminal 1 connected to {:s} = sim node {:d}",
368 SparseMatrixRow &systemMatrix) {
370 if (terminalNotGrounded(0)) {
371 Math::setMatrixElement(systemMatrix,
mVirtualNodes[0]->matrixNodeIndex(),
374 Math::setMatrixElement(systemMatrix,
mVirtualNodes[1]->matrixNodeIndex(),
378 if (terminalNotGrounded(1)) {
379 Math::setMatrixElement(systemMatrix, matrixNodeIndex(1),
381 Math::setMatrixElement(systemMatrix,
mVirtualNodes[1]->matrixNodeIndex(),
382 matrixNodeIndex(1), -**
mRatio);
387 if (
auto mnasubcomp = std::dynamic_pointer_cast<MNAInterface>(subcomp))
388 mnasubcomp->mnaApplySystemMatrixStamp(systemMatrix);
390 if (terminalNotGrounded(0)) {
391 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
392 Logger::complexToString(Complex(-1.0, 0)),
395 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
396 Logger::complexToString(Complex(1.0, 0)),
400 if (terminalNotGrounded(1)) {
401 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
402 Logger::complexToString(**
mRatio), matrixNodeIndex(1),
404 SPDLOG_LOGGER_INFO(
mSLog,
"Add {:s} to system at ({:d},{:d})",
405 Logger::complexToString(-**
mRatio),
411 AttributeBase::List &prevStepDependencies,
412 AttributeBase::List &attributeDependencies,
413 AttributeBase::List &modifiedAttributes) {
424 AttributeBase::List &prevStepDependencies,
425 AttributeBase::List &attributeDependencies,
426 AttributeBase::List &modifiedAttributes,
427 Attribute<Matrix>::Ptr &leftVector) {
428 attributeDependencies.push_back(leftVector);
434 Real time, Int timeStepCount, Attribute<Matrix>::Ptr &leftVector) {
440 (**mIntfCurrent)(0, 0) = mSubInductor->intfCurrent()(0, 0);
441 SPDLOG_LOGGER_DEBUG(
mSLog,
"Current {:s}",
447 (**mIntfVoltage)(0, 0) = 0;
448 (**mIntfVoltage)(0, 0) =
449 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
451 Math::complexFromVectorElement(
453 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.