49using SimPowerCompReal = CPS::SimPowerComp<CPS::Real>;
50using SimPowerCompComplex = CPS::SimPowerComp<CPS::Complex>;
52std::shared_ptr<CompositePowerComp<Real>>
54 if (
const auto composite =
55 std::dynamic_pointer_cast<EMT::Ph3::NetworkInjection>(component))
58 if (
const auto composite =
59 std::dynamic_pointer_cast<EMT::Ph3::PiLine>(component))
62 if (
const auto composite =
63 std::dynamic_pointer_cast<EMT::Ph3::RXLoad>(component))
66 if (
const auto composite =
67 std::dynamic_pointer_cast<EMT::Ph3::RxLine>(component))
70 if (
const auto composite =
71 std::dynamic_pointer_cast<EMT::Ph3::Shunt>(component))
74 if (
const auto composite =
75 std::dynamic_pointer_cast<EMT::Ph3::Transformer>(component))
81std::shared_ptr<CompositePowerComp<Complex>>
83 if (
const auto composite =
84 std::dynamic_pointer_cast<DP::Ph1::NetworkInjection>(component))
87 if (
const auto composite =
88 std::dynamic_pointer_cast<DP::Ph1::PiLine>(component))
91 if (
const auto composite =
92 std::dynamic_pointer_cast<DP::Ph1::RXLoad>(component))
95 if (
const auto composite =
96 std::dynamic_pointer_cast<DP::Ph1::RxLine>(component))
99 if (
const auto composite =
100 std::dynamic_pointer_cast<DP::Ph1::Shunt>(component))
103 if (
const auto composite =
104 std::dynamic_pointer_cast<DP::Ph1::Transformer>(component))
112Matrix buildTwoTerminalInterfaceVoltageMapping(SimPowerCompReal &component,
113 UInt mnaVectorSize) {
114 Matrix K = Matrix::Zero(3, mnaVectorSize);
116 if (component.terminalNotGrounded(1)) {
117 for (
UInt phase = 0; phase < 3; ++phase)
118 K(phase, component.matrixNodeIndex(1, phase)) = 1.0;
121 if (component.terminalNotGrounded(0)) {
122 for (
UInt phase = 0; phase < 3; ++phase)
123 K(phase, component.matrixNodeIndex(0, phase)) = -1.0;
132buildSinglePhaseComplexInterfaceVoltageMapping(SimPowerCompComplex &component,
133 UInt mnaVectorSize) {
134 if (mnaVectorSize % 2 != 0) {
135 throw std::logic_error(
136 "DP MNA state-space extraction requires a real-imaginary stacked "
137 "MNA vector with even size.");
140 const UInt complexOffset = mnaVectorSize / 2;
141 Matrix K = Matrix::Zero(2, mnaVectorSize);
143 if (component.terminalNotGrounded(1)) {
144 const UInt nodeIdx = component.matrixNodeIndex(1);
146 K(1, nodeIdx + complexOffset) = 1.0;
149 if (component.terminalNotGrounded(0)) {
150 const UInt nodeIdx = component.matrixNodeIndex(0);
151 K(0, nodeIdx) = -1.0;
152 K(1, nodeIdx + complexOffset) = -1.0;
161buildThreePhaseComplexInterfaceVoltageMapping(SimPowerCompComplex &component,
162 UInt mnaVectorSize) {
163 if (mnaVectorSize % 2 != 0) {
164 throw std::logic_error(
165 "DP MNA state-space extraction requires a real-imaginary stacked "
166 "MNA vector with even size.");
169 const UInt complexOffset = mnaVectorSize / 2;
170 Matrix K = Matrix::Zero(6, mnaVectorSize);
172 for (
UInt phase = 0; phase < 3; ++phase) {
173 if (component.terminalNotGrounded(1)) {
174 const UInt nodeIdx = component.matrixNodeIndex(1, phase);
175 K(2 * phase, nodeIdx) = 1.0;
176 K(2 * phase + 1, nodeIdx + complexOffset) = 1.0;
179 if (component.terminalNotGrounded(0)) {
180 const UInt nodeIdx = component.matrixNodeIndex(0, phase);
181 K(2 * phase, nodeIdx) = -1.0;
182 K(2 * phase + 1, nodeIdx + complexOffset) = -1.0;
193void stampTwoTerminalCurrentInjectionMapping(
const Matrix &K,
Matrix &CdMna,
195 const Matrix &outputMatrix) {
196 CdMna.block(0, stateOffset, CdMna.rows(), outputMatrix.cols()) +=
197 -K.transpose() * outputMatrix;
201 const Matrix::Index rows = matrix.rows();
202 const Matrix::Index cols = matrix.cols();
204 Matrix result = Matrix::Zero(2 * rows, 2 * cols);
205 result.topLeftCorner(rows, cols) = matrix.real();
206 result.topRightCorner(rows, cols) = -matrix.imag();
207 result.bottomLeftCorner(rows, cols) = matrix.imag();
208 result.bottomRightCorner(rows, cols) = matrix.real();
214 Matrix result = Matrix::Zero(2, 2);
215 result << value.real(), -value.imag(), value.imag(), value.real();
220 Matrix result = Matrix::Zero(2 * matrix.rows(), 2 * matrix.cols());
222 for (Matrix::Index row = 0; row < matrix.rows(); ++row) {
223 for (Matrix::Index col = 0; col < matrix.cols(); ++col)
224 result.block<2, 2>(2 * row, 2 * col) = realAugment(matrix(row, col));
230Complex calculateDPInductorPreviousCurrentFactor(
const Complex &conductance) {
231 const Real omegaDtHalf = -conductance.imag() / conductance.real();
237 if (stateIndex >= metadata.stateNames.size())
238 throw std::runtime_error(
239 "MNA state-space contributor tried to set a state name outside the "
240 "extracted state vector.");
242 metadata.stateNames[stateIndex] = name;
247 setStateName(metadata, stateOffset + 0, baseName +
"_a");
248 setStateName(metadata, stateOffset + 1, baseName +
"_b");
249 setStateName(metadata, stateOffset + 2, baseName +
"_c");
251 metadata.abcStateBlocks.push_back(
252 {{stateOffset + 0, stateOffset + 1, stateOffset + 2}, baseName});
258 setStateName(metadata, stateOffset + 0, baseName +
"_re");
259 setStateName(metadata, stateOffset + 1, baseName +
"_im");
263 UInt complexStateCount,
264 const String &componentName) {
265 for (
UInt idx = 0; idx < complexStateCount; ++idx) {
266 const String stateName = componentName +
".x" + std::to_string(idx);
267 setStateName(metadata, stateOffset + idx, stateName +
"_re");
268 setStateName(metadata, stateOffset + complexStateCount + idx,
274 UInt stateCount,
const String &componentName) {
275 for (
UInt idx = 0; idx < stateCount; ++idx)
276 setStateName(metadata, stateOffset + idx,
277 componentName +
".x" + std::to_string(idx));
280class EMTPh3InductorStateSpaceContributor final
283 explicit EMTPh3InductorStateSpaceContributor(
284 std::shared_ptr<EMT::Ph3::Inductor> component)
285 : mComponent(std::move(component)) {}
287 UInt getStateCount()
const override {
return 3; }
290 UInt mnaVectorSize)
const override {
291 const Matrix &conductance = mComponent->getMNAConductance();
294 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
300 AdLocal.block(stateOffset, stateOffset, 3, 3) += Matrix::Identity(3, 3);
302 BdMna.block(stateOffset, 0, 3, mnaVectorSize) += 2.0 * conductance * K;
304 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
305 Matrix::Identity(3, 3));
308 void contributeMetadata(StateSpaceMetadata &metadata,
309 UInt stateOffset)
const override {
310 addThreePhaseAbcStateMetadata(metadata, stateOffset, mComponent->name());
314 std::shared_ptr<EMT::Ph3::Inductor> mComponent;
317class EMTPh3CapacitorStateSpaceContributor final
320 explicit EMTPh3CapacitorStateSpaceContributor(
321 std::shared_ptr<EMT::Ph3::Capacitor> component)
322 : mComponent(std::move(component)) {}
324 UInt getStateCount()
const override {
return 3; }
327 UInt mnaVectorSize)
const override {
328 const Matrix &conductance = mComponent->getMNAConductance();
331 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
337 AdLocal.block(stateOffset, stateOffset, 3, 3) -= Matrix::Identity(3, 3);
339 BdMna.block(stateOffset, 0, 3, mnaVectorSize) -= 2.0 * conductance * K;
341 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
342 Matrix::Identity(3, 3));
345 void contributeMetadata(StateSpaceMetadata &metadata,
346 UInt stateOffset)
const override {
347 addThreePhaseAbcStateMetadata(metadata, stateOffset, mComponent->name());
351 std::shared_ptr<EMT::Ph3::Capacitor> mComponent;
354class EMTPh3TwoTerminalVTypeSSNStateSpaceContributor final
357 EMTPh3TwoTerminalVTypeSSNStateSpaceContributor(
358 std::shared_ptr<EMT::VTypeSSNComp> component,
Bool isVariable)
359 : mComponent(std::move(component)), mIsVariable(isVariable) {}
361 UInt getStateCount()
const override {
return mComponent->getStateCount(); }
363 Bool contributesToUpdatedMatrices()
const override {
return mIsVariable; }
366 UInt mnaVectorSize)
const override {
367 const UInt localStateCount = getStateCount();
369 const Matrix &discreteA = mComponent->getDiscreteA();
370 const Matrix &discreteB = mComponent->getDiscreteB();
371 const Matrix &outputC = mComponent->getC();
374 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
381 AdLocal.block(stateOffset, stateOffset, localStateCount, localStateCount) +=
384 const Matrix inputUpdate =
385 (discreteA + Matrix::Identity(localStateCount, localStateCount)) *
388 BdMna.block(stateOffset, 0, localStateCount, mnaVectorSize) +=
391 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset, outputC);
394 void contributeMetadata(StateSpaceMetadata &metadata,
395 UInt stateOffset)
const override {
396 const UInt localStateCount = getStateCount();
397 const String componentName = mComponent->name();
399 const auto localStateNames = mComponent->getLocalStateNames();
401 if (!localStateNames.empty() && localStateNames.size() != localStateCount) {
402 throw std::runtime_error(
403 "SSN component returned an invalid number of local state names.");
406 for (
UInt idx = 0; idx < localStateCount; ++idx) {
407 if (!localStateNames.empty()) {
408 setStateName(metadata, stateOffset + idx,
409 componentName +
"." + localStateNames[idx]);
413 for (
auto abcBlock : mComponent->getLocalAbcStateBlocks()) {
414 if (abcBlock.name.empty()) {
415 throw std::runtime_error(
416 "SSN component returned an abc state block with an empty name.");
419 for (
auto &idx : abcBlock.indices) {
420 if (idx >= localStateCount) {
421 throw std::runtime_error(
422 "SSN component returned an invalid abc state index.");
428 metadata.abcStateBlocks.push_back(
429 {abcBlock.indices, componentName +
"." + abcBlock.name});
434 std::shared_ptr<EMT::VTypeSSNComp> mComponent;
435 Bool mIsVariable =
false;
438class EMTPh3TwoTerminalVTypeSplitSSNStateSpaceContributor final
441 explicit EMTPh3TwoTerminalVTypeSplitSSNStateSpaceContributor(
442 std::shared_ptr<EMT::Ph3::TwoTerminalVTypeSplitSSNComp> component)
443 : mComponent(std::move(component)) {}
445 UInt getStateCount()
const override {
446 return mComponent->getSplitStateCount();
449 Bool contributesToUpdatedMatrices()
const override {
450 return mComponent->requiresStateSpaceMatrixUpdate();
453 Bool requiresUpdate()
const override {
454 return mComponent->requiresStateSpaceMatrixUpdate();
458 if (requiresUpdate())
459 return {mComponent->getSplitStateAttribute()};
465 UInt mnaVectorSize)
const override {
466 const UInt localStateCount = getStateCount();
467 const Matrix &discreteA = mComponent->getSplitDiscreteA();
468 const Matrix &discreteB = mComponent->getSplitDiscreteB();
469 const Matrix &historyC = mComponent->getSplitHistoryC();
471 buildTwoTerminalInterfaceVoltageMapping(*mComponent, mnaVectorSize);
473 AdLocal.block(stateOffset, stateOffset, localStateCount, localStateCount) +=
475 BdMna.block(stateOffset, 0, localStateCount, mnaVectorSize) +=
477 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset, historyC);
480 void contributeMetadata(StateSpaceMetadata &metadata,
481 UInt stateOffset)
const override {
482 const UInt localStateCount = getStateCount();
483 const String componentName = mComponent->name();
484 const auto localStateNames = mComponent->getSplitLocalStateNames();
486 if (!localStateNames.empty() && localStateNames.size() != localStateCount) {
487 throw std::runtime_error(
488 "Split SSN component returned an invalid number of local state "
492 for (
UInt idx = 0; idx < localStateCount; ++idx) {
493 if (!localStateNames.empty())
494 setStateName(metadata, stateOffset + idx,
495 componentName +
"." + localStateNames[idx]);
498 for (
auto abcBlock : mComponent->getSplitLocalAbcStateBlocks()) {
499 if (abcBlock.name.empty()) {
500 throw std::runtime_error(
501 "Split SSN component returned an abc state block with an empty "
505 for (
auto &idx : abcBlock.indices) {
506 if (idx >= localStateCount) {
507 throw std::runtime_error(
508 "Split SSN component returned an invalid abc state index.");
513 metadata.abcStateBlocks.push_back(
514 {abcBlock.indices, componentName +
"." + abcBlock.name});
519 std::shared_ptr<EMT::Ph3::TwoTerminalVTypeSplitSSNComp> mComponent;
522class DPPh1InductorStateSpaceContributor final
525 explicit DPPh1InductorStateSpaceContributor(
526 std::shared_ptr<DP::Ph1::Inductor> component)
527 : mComponent(std::move(component)) {}
529 UInt getStateCount()
const override {
return 2; }
532 UInt mnaVectorSize)
const override {
533 const Complex conductance = mComponent->getMNAConductance();
534 const Complex prevCurrentFactor =
535 calculateDPInductorPreviousCurrentFactor(conductance);
537 const Matrix K = buildSinglePhaseComplexInterfaceVoltageMapping(
538 *mComponent, mnaVectorSize);
545 AdLocal.block(stateOffset, stateOffset, 2, 2) +=
546 realAugment(prevCurrentFactor);
548 BdMna.block(stateOffset, 0, 2, mnaVectorSize) +=
549 realAugment((
Complex(1.0, 0.0) + prevCurrentFactor) * conductance) * K;
551 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
552 Matrix::Identity(2, 2));
555 void contributeMetadata(StateSpaceMetadata &metadata,
556 UInt stateOffset)
const override {
557 addSinglePhaseComplexStateMetadata(metadata, stateOffset,
562 std::shared_ptr<DP::Ph1::Inductor> mComponent;
565class DPPh1CapacitorStateSpaceContributor final
568 explicit DPPh1CapacitorStateSpaceContributor(
569 std::shared_ptr<DP::Ph1::Capacitor> component)
570 : mComponent(std::move(component)) {}
572 UInt getStateCount()
const override {
return 2; }
575 UInt mnaVectorSize)
const override {
576 const Complex conductance = mComponent->getMNAConductance();
578 const Matrix K = buildSinglePhaseComplexInterfaceVoltageMapping(
579 *mComponent, mnaVectorSize);
586 AdLocal.block(stateOffset, stateOffset, 2, 2) -= Matrix::Identity(2, 2);
588 BdMna.block(stateOffset, 0, 2, mnaVectorSize) -=
589 2.0 * conductance.real() * K;
591 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
592 Matrix::Identity(2, 2));
595 void contributeMetadata(StateSpaceMetadata &metadata,
596 UInt stateOffset)
const override {
597 addSinglePhaseComplexStateMetadata(metadata, stateOffset,
602 std::shared_ptr<DP::Ph1::Capacitor> mComponent;
605class DPPh1TwoTerminalVTypeSSNStateSpaceContributor final
608 explicit DPPh1TwoTerminalVTypeSSNStateSpaceContributor(
609 std::shared_ptr<DP::VTypeSSNComp> component)
610 : mComponent(std::move(component)) {}
612 UInt getStateCount()
const override {
613 return 2 * mComponent->getStateCount();
617 UInt mnaVectorSize)
const override {
618 const UInt complexStateCount = mComponent->getStateCount();
619 const UInt realStateCount = getStateCount();
621 const MatrixComp &discreteA = mComponent->getDiscreteA();
622 const MatrixComp &discreteB = mComponent->getDiscreteB();
625 const Matrix K = buildSinglePhaseComplexInterfaceVoltageMapping(
626 *mComponent, mnaVectorSize);
633 AdLocal.block(stateOffset, stateOffset, realStateCount, realStateCount) +=
634 realAugment(discreteA);
638 MatrixComp::Identity(complexStateCount, complexStateCount)) *
641 BdMna.block(stateOffset, 0, realStateCount, mnaVectorSize) +=
642 realAugment(inputUpdate) * K;
644 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
645 realAugment(outputC));
648 void contributeMetadata(StateSpaceMetadata &metadata,
649 UInt stateOffset)
const override {
650 addComplexStateMetadata(metadata, stateOffset, mComponent->getStateCount(),
655 std::shared_ptr<DP::VTypeSSNComp> mComponent;
658class DPPh1MixedVTypeVariableSSNStateSpaceContributor final
661 explicit DPPh1MixedVTypeVariableSSNStateSpaceContributor(
662 std::shared_ptr<DP::Ph1::MixedVTypeVariableSSNComp> component)
663 : mComponent(std::move(component)) {}
665 UInt getStateCount()
const override {
return mComponent->getStateCount(); }
667 Bool contributesToUpdatedMatrices()
const override {
return true; }
670 UInt mnaVectorSize)
const override {
671 const UInt localStateCount = getStateCount();
673 const Matrix &discreteA = mComponent->getDiscreteA();
674 const Matrix &discreteB = mComponent->getDiscreteB();
675 const Matrix &outputC = mComponent->getC();
677 const Matrix K = buildSinglePhaseComplexInterfaceVoltageMapping(
678 *mComponent, mnaVectorSize);
685 AdLocal.block(stateOffset, stateOffset, localStateCount, localStateCount) +=
688 const Matrix inputUpdate =
689 (discreteA + Matrix::Identity(localStateCount, localStateCount)) *
692 BdMna.block(stateOffset, 0, localStateCount, mnaVectorSize) +=
695 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset, outputC);
698 void contributeMetadata(StateSpaceMetadata &metadata,
699 UInt stateOffset)
const override {
700 addRealStateMetadata(metadata, stateOffset, getStateCount(),
705 std::shared_ptr<DP::Ph1::MixedVTypeVariableSSNComp> mComponent;
708class DPPh3InductorStateSpaceContributor final
711 explicit DPPh3InductorStateSpaceContributor(
712 std::shared_ptr<DP::Ph3::Inductor> component)
713 : mComponent(std::move(component)) {}
715 UInt getStateCount()
const override {
return 6; }
718 UInt mnaVectorSize)
const override {
719 const MatrixComp &conductance = mComponent->getMNAConductance();
720 const Complex previousCurrentFactor =
721 mComponent->getPreviousCurrentFactor();
722 const MatrixComp identity = MatrixComp::Identity(3, 3);
723 const MatrixComp previousState = previousCurrentFactor * identity;
725 (
Complex(1.0, 0.0) + previousCurrentFactor) * conductance;
726 const Matrix K = buildThreePhaseComplexInterfaceVoltageMapping(
727 *mComponent, mnaVectorSize);
729 AdLocal.block(stateOffset, stateOffset, 6, 6) +=
730 realAugmentInterleaved(previousState);
732 BdMna.block(stateOffset, 0, 6, mnaVectorSize) +=
733 realAugmentInterleaved(inputUpdate) * K;
735 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset,
736 Matrix::Identity(6, 6));
739 void contributeMetadata(StateSpaceMetadata &metadata,
740 UInt stateOffset)
const override {
741 static constexpr std::array<const char *, 3> phaseNames = {
"a",
"b",
"c"};
743 for (
UInt phase = 0; phase < 3; ++phase) {
744 const String baseName = mComponent->name() +
"_" + phaseNames[phase];
745 setStateName(metadata, stateOffset + 2 * phase, baseName +
"_re");
746 setStateName(metadata, stateOffset + 2 * phase + 1, baseName +
"_im");
751 std::shared_ptr<DP::Ph3::Inductor> mComponent;
754class DPPh3MixedVTypeVariableSSNStateSpaceContributor final
757 explicit DPPh3MixedVTypeVariableSSNStateSpaceContributor(
758 std::shared_ptr<DP::Ph3::MixedVTypeVariableSSNComp> component)
759 : mComponent(std::move(component)) {}
761 UInt getStateCount()
const override {
return mComponent->getStateCount(); }
763 Bool contributesToUpdatedMatrices()
const override {
return true; }
766 UInt mnaVectorSize)
const override {
767 const UInt localStateCount = getStateCount();
768 const Matrix &discreteA = mComponent->getDiscreteA();
769 const Matrix &discreteB = mComponent->getDiscreteB();
770 const Matrix &outputC = mComponent->getC();
771 const Matrix K = buildThreePhaseComplexInterfaceVoltageMapping(
772 *mComponent, mnaVectorSize);
774 AdLocal.block(stateOffset, stateOffset, localStateCount, localStateCount) +=
777 const Matrix inputUpdate =
778 (discreteA + Matrix::Identity(localStateCount, localStateCount)) *
781 BdMna.block(stateOffset, 0, localStateCount, mnaVectorSize) +=
784 stampTwoTerminalCurrentInjectionMapping(K, CdMna, stateOffset, outputC);
787 void contributeMetadata(StateSpaceMetadata &metadata,
788 UInt stateOffset)
const override {
789 addRealStateMetadata(metadata, stateOffset, getStateCount(),
794 std::shared_ptr<DP::Ph3::MixedVTypeVariableSSNComp> mComponent;
805 std::dynamic_pointer_cast<EMT::Ph3::Inductor>(component)) {
806 return std::make_shared<EMTPh3InductorStateSpaceContributor>(inductor);
810 std::dynamic_pointer_cast<EMT::Ph3::Capacitor>(component)) {
811 return std::make_shared<EMTPh3CapacitorStateSpaceContributor>(capacitor);
814 if (
auto variableSsn =
815 std::dynamic_pointer_cast<EMT::Ph3::TwoTerminalVTypeVariableSSNComp>(
817 return std::make_shared<EMTPh3TwoTerminalVTypeSSNStateSpaceContributor>(
822 std::dynamic_pointer_cast<EMT::Ph3::TwoTerminalVTypeSplitSSNComp>(
824 return std::make_shared<
825 EMTPh3TwoTerminalVTypeSplitSSNStateSpaceContributor>(splitSsn);
828 if (
auto ssn = std::dynamic_pointer_cast<EMT::Ph3::TwoTerminalVTypeSSNComp>(
830 return std::make_shared<EMTPh3TwoTerminalVTypeSSNStateSpaceContributor>(
834 if (std::dynamic_pointer_cast<EMT::Ph3::Resistor>(component))
837 if (std::dynamic_pointer_cast<EMT::Ph3::Switch>(component))
840 if (std::dynamic_pointer_cast<EMT::Ph3::VoltageSource>(component))
843 if (
auto inductor = std::dynamic_pointer_cast<DP::Ph1::Inductor>(component)) {
844 return std::make_shared<DPPh1InductorStateSpaceContributor>(inductor);
848 std::dynamic_pointer_cast<DP::Ph1::Capacitor>(component)) {
849 return std::make_shared<DPPh1CapacitorStateSpaceContributor>(capacitor);
852 if (
auto mixedVariableSsn =
853 std::dynamic_pointer_cast<DP::Ph1::MixedVTypeVariableSSNComp>(
855 return std::make_shared<DPPh1MixedVTypeVariableSSNStateSpaceContributor>(
859 if (
auto ssn = std::dynamic_pointer_cast<DP::Ph1::TwoTerminalVTypeSSNComp>(
861 return std::make_shared<DPPh1TwoTerminalVTypeSSNStateSpaceContributor>(ssn);
864 if (std::dynamic_pointer_cast<DP::Ph1::Resistor>(component))
867 if (std::dynamic_pointer_cast<DP::Ph1::Switch>(component))
870 if (std::dynamic_pointer_cast<DP::Ph1::VoltageSource>(component))
873 if (
auto inductor = std::dynamic_pointer_cast<DP::Ph3::Inductor>(component)) {
874 return std::make_shared<DPPh3InductorStateSpaceContributor>(inductor);
877 if (
auto mixedVariableSsn =
878 std::dynamic_pointer_cast<DP::Ph3::MixedVTypeVariableSSNComp>(
880 return std::make_shared<DPPh3MixedVTypeVariableSSNStateSpaceContributor>(
884 if (std::dynamic_pointer_cast<DP::Ph3::Resistor>(component))
887 if (std::dynamic_pointer_cast<DP::Ph3::VoltageSource>(component))
890 throw std::invalid_argument(
891 "Unsupported component in MNA state-space extraction.");
898 const auto appendContributor =
900 auto contributor = MNAStateSpaceContributorFactory::create(component);
903 contributors.push_back(std::move(contributor));
906 const auto appendCompositeContributors =
907 [&appendContributor](
const auto &composite) {
908 for (
const auto &subcomponent : composite->mnaSubComponents())
909 appendContributor(subcomponent);
912 for (
const auto &component : components) {
913 if (
const auto composite = getSupportedRealComposite(component)) {
914 appendCompositeContributors(composite);
918 if (
const auto composite = getSupportedComplexComposite(component)) {
919 appendCompositeContributors(composite);
923 appendContributor(component);
std::shared_ptr< MNAInterface > Ptr
static MNAStateSpaceContributor::List createList(const CPS::MNAInterface::List &components)
std::shared_ptr< MNAStateSpaceContributor > Ptr
CPS::MatrixComp MatrixComp