23template <
typename VarType>
33 mLeftVectorLog = std::make_shared<DataLogger>(
34 name +
"_LeftVector", logLevel != CPS::Logger::Level::off);
35 mRightVectorLog = std::make_shared<DataLogger>(
36 name +
"_RightVector", logLevel != CPS::Logger::Level::off);
38 for (
auto comp : tearComponents) {
39 auto pcomp = std::dynamic_pointer_cast<SimPowerComp<VarType>>(comp);
41 mTearComponents.push_back(pcomp);
46template <
typename VarType>
48 std::vector<SystemTopology> subnets;
50 if (mSystem.mNodes.size() > 0)
51 mPhaseType = mSystem.
mNodes.at(0)->phaseType();
62template <
typename VarType>
63void DiakopticsSolver<VarType>::initSubnets(
64 const std::vector<SystemTopology> &subnets) {
65 mSubnets.resize(subnets.size());
66 for (
UInt i = 0; i < subnets.size(); ++i) {
68 for (
auto baseNode : subnets[i].mNodes) {
69 if (!baseNode->isGround()) {
70 auto node = std::dynamic_pointer_cast<CPS::SimNode<VarType>>(baseNode);
71 mSubnets[i].nodes.push_back(node);
75 for (
auto comp : subnets[i].mComponents) {
77 auto mnaComp = std::dynamic_pointer_cast<CPS::MNAInterface>(comp);
79 mSubnets[i].components.push_back(mnaComp);
81 auto sigComp = std::dynamic_pointer_cast<CPS::SimSignalComp>(comp);
83 mSimSignalComps.push_back(sigComp);
86 std::dynamic_pointer_cast<CPS::MNAVariableCompInterface>(comp);
88 mSubnets[i].mVariableComps.push_back(mnaVarComp);
93 for (
auto &net : mSubnets) {
94 for (
auto &node : net.nodes) {
95 mNodeSubnetMap[node] = &net;
99 for (
UInt idx = 0; idx < mTearComponents.size(); ++idx) {
100 auto comp = mTearComponents[idx];
101 auto tComp = std::dynamic_pointer_cast<MNATearInterface>(comp);
103 throw SystemError(
"Unsupported component type for diakoptics");
105 if (comp->hasVirtualNodes()) {
106 for (
UInt node = 0; node < comp->virtualNodesNumber(); ++node) {
109 comp->setVirtualNodeAt(std::make_shared<CPS::SimNode<VarType>>(node),
113 tComp->mnaTearSetIdx(idx);
114 comp->initializeFromNodesAndTerminals(mSystemFrequency);
115 tComp->mnaTearInitialize(2 *
PI * mSystemFrequency, mTimeStep);
117 for (
auto gndComp : tComp->mnaTearGroundComponents()) {
118 auto pComp = std::dynamic_pointer_cast<SimPowerComp<VarType>>(gndComp);
119 Subnet *net =
nullptr;
120 if (pComp->node(0)->isGround()) {
121 net = mNodeSubnetMap[pComp->node(1)];
122 }
else if (pComp->node(1)->isGround()) {
123 net = mNodeSubnetMap[pComp->node(0)];
126 "Invalid ground component passed from torn component");
128 net->components.push_back(gndComp);
132 for (
UInt i = 0; i < subnets.size(); ++i) {
133 collectVirtualNodes(i);
134 assignMatrixNodeIndices(i);
138template <
typename VarType>
139void DiakopticsSolver<VarType>::collectVirtualNodes(
int net) {
140 mSubnets[net].mVirtualNodeNum = 0;
141 mSubnets[net].mRealNetNodeNum =
static_cast<UInt>(mSubnets[net].nodes.size());
143 for (
auto comp : mSubnets[net].components) {
144 auto pComp = std::dynamic_pointer_cast<SimPowerComp<VarType>>(comp);
148 if (pComp->hasVirtualNodes()) {
149 for (
UInt node = 0; node < pComp->virtualNodesNumber(); ++node) {
150 ++(mSubnets[net].mVirtualNodeNum);
151 mSubnets[net].nodes.push_back(pComp->virtualNode(node));
155 if (pComp->hasSubComponents()) {
156 for (
auto pSubComp : pComp->subComponents()) {
157 for (
UInt node = 0; node < pSubComp->virtualNodesNumber(); ++node) {
158 auto vnode = pSubComp->virtualNode(node);
159 bool alreadyRegistered =
false;
160 for (
auto registeredNode : mSubnets[net].nodes) {
161 if (registeredNode == vnode) {
162 alreadyRegistered =
true;
166 if (alreadyRegistered)
168 ++(mSubnets[net].mVirtualNodeNum);
169 mSubnets[net].nodes.push_back(vnode);
174 SPDLOG_LOGGER_INFO(mSLog,
"Subnet {} has {} real network nodes.", net,
175 mSubnets[net].mRealNetNodeNum);
176 SPDLOG_LOGGER_INFO(mSLog,
"Subnet {} has {} virtual nodes.", net,
177 mSubnets[net].mVirtualNodeNum);
180template <
typename VarType>
181void DiakopticsSolver<VarType>::assignMatrixNodeIndices(
int net) {
182 UInt matrixNodeIndexIdx = 0;
183 for (
UInt idx = 0; idx < mSubnets[net].nodes.size(); ++idx) {
184 auto &node = mSubnets[net].nodes[idx];
186 node->setMatrixNodeIndex(0, matrixNodeIndexIdx);
187 SPDLOG_LOGGER_INFO(mSLog,
"Assigned index {} to node {}",
188 matrixNodeIndexIdx, node->name());
189 ++matrixNodeIndexIdx;
192 node->setMatrixNodeIndex(1, matrixNodeIndexIdx);
193 SPDLOG_LOGGER_INFO(mSLog,
"Assigned index {} to node {} phase B",
194 matrixNodeIndexIdx, node->name());
195 ++matrixNodeIndexIdx;
196 node->setMatrixNodeIndex(2, matrixNodeIndexIdx);
197 SPDLOG_LOGGER_INFO(mSLog,
"Assigned index {} to node {} phase C",
198 matrixNodeIndexIdx, node->name());
199 ++matrixNodeIndexIdx;
202 setSubnetSize(net, matrixNodeIndexIdx);
205 mSubnets[net].sysOff = 0;
207 mSubnets[net].sysOff = mSubnets[net - 1].sysOff + mSubnets[net - 1].sysSize;
210template <>
void DiakopticsSolver<Real>::setSubnetSize(
int net,
UInt nodes) {
211 mSubnets[net].sysSize = nodes;
212 mSubnets[net].mCmplOff = 0;
215template <>
void DiakopticsSolver<Complex>::setSubnetSize(
int net,
UInt nodes) {
216 mSubnets[net].sysSize = 2 * nodes;
217 mSubnets[net].mCmplOff = nodes;
220template <>
void DiakopticsSolver<Real>::setLogColumns() {
224template <>
void DiakopticsSolver<Complex>::setLogColumns() {
225 std::vector<String> names;
226 for (
auto &subnet : mSubnets) {
227 for (
UInt i = subnet.sysOff; i < subnet.sysOff + subnet.sysSize; ++i) {
228 std::stringstream name;
229 if (i < subnet.sysOff + subnet.mCmplOff)
230 name <<
"node" << std::setfill(
'0') << std::setw(5)
231 << i - subnet.sysOff / 2 <<
".real";
233 name <<
"node" << std::setfill(
'0') << std::setw(5)
234 << i - (subnet.sysOff + subnet.sysSize) / 2 <<
".imag";
235 names.push_back(name.str());
238 mLeftVectorLog->setColumnNames(names);
239 mRightVectorLog->setColumnNames(names);
242template <
typename VarType>
void DiakopticsSolver<VarType>::createMatrices() {
243 UInt totalSize = mSubnets.back().sysOff + mSubnets.back().sysSize;
244 mSystemMatrix = Matrix::Zero(totalSize, totalSize);
246 mRightSideVector = Matrix::Zero(totalSize, 1);
247 mLeftSideVector = Matrix::Zero(totalSize, 1);
248 **mOrigLeftSideVector = Matrix::Zero(totalSize, 1);
249 **mMappedTearCurrents = Matrix::Zero(totalSize, 1);
251 for (
auto &net : mSubnets) {
255 net.leftVector = AttributeStatic<Matrix>::make();
256 net.leftVector->set(Matrix::Zero(net.sysSize, 1));
259 createTearMatrices(totalSize);
262template <>
void DiakopticsSolver<Real>::createTearMatrices(
UInt totalSize) {
263 int phaseMultiplier = 1;
264 if (mPhaseType == PhaseType::ABC) {
268 Matrix::Zero(totalSize, mTearComponents.size() * phaseMultiplier);
271 mTearComponents.size() * phaseMultiplier);
272 mTearCurrents = Matrix::Zero(mTearComponents.size() * phaseMultiplier, 1);
273 mTearVoltages = Matrix::Zero(mTearComponents.size() * phaseMultiplier, 1);
276template <>
void DiakopticsSolver<Complex>::createTearMatrices(
UInt totalSize) {
277 int phaseMultiplier = 1;
278 if (mPhaseType == PhaseType::ABC) {
282 Matrix::Zero(totalSize, 2 * mTearComponents.size() * phaseMultiplier);
285 2 * mTearComponents.size() * phaseMultiplier);
286 mTearCurrents = Matrix::Zero(2 * mTearComponents.size() * phaseMultiplier, 1);
287 mTearVoltages = Matrix::Zero(2 * mTearComponents.size() * phaseMultiplier, 1);
290template <
typename VarType>
void DiakopticsSolver<VarType>::initComponents() {
291 for (
UInt net = 0; net < mSubnets.size(); ++net) {
292 for (
auto comp : mSubnets[net].components) {
293 auto pComp = std::dynamic_pointer_cast<SimPowerComp<VarType>>(comp);
296 pComp->initializeFromNodesAndTerminals(mSystem.mSystemFrequency);
300 for (
auto comp : mSubnets[net].components) {
301 comp->mnaInitialize(mSystem.mSystemOmega, mTimeStep,
302 mSubnets[net].leftVector);
303 const Matrix &stamp = comp->getRightVector()->get();
304 if (stamp.size() != 0) {
305 mSubnets[net].rightVectorStamps.push_back(&stamp);
310 for (
auto comp : mSimSignalComps)
311 comp->initialize(mSystem.mSystemOmega, mTimeStep);
314 for (
UInt net = 0; net < mSubnets.size(); ++net)
315 for (
auto node : mSubnets[net].nodes)
319template <
typename VarType>
void DiakopticsSolver<VarType>::initMatrices() {
320 for (
auto &net : mSubnets) {
323 net.systemMatrix =
SparseMatrix(net.sysSize, net.sysSize);
324 for (
auto comp : net.components) {
325 comp->mnaApplySystemMatrixStamp(net.systemMatrix);
328 mSystemMatrix.block(net.sysOff, net.sysOff, net.sysSize, net.sysSize);
329 block = net.systemMatrix;
330 SPDLOG_LOGGER_INFO(mSLog,
"Block: \n{}", block);
331 net.listVariableEntries.clear();
332 for (
auto varElem : net.mVariableComps)
333 for (
auto varEntry : varElem->mVariableSystemMatrixEntries)
334 net.listVariableEntries.push_back(varEntry);
335 net.directLinearSolver = std::make_shared<KLUAdapter>(mSLog);
336 net.directLinearSolver->preprocessing(net.systemMatrix,
337 net.listVariableEntries);
338 net.directLinearSolver->factorize(net.systemMatrix);
340 SPDLOG_LOGGER_INFO(mSLog,
"Complete system matrix: \n{}", mSystemMatrix);
343 for (
UInt compIdx = 0; compIdx < mTearComponents.size(); ++compIdx) {
344 applyTearComponentStamp(compIdx);
346 SPDLOG_LOGGER_INFO(mSLog,
"Topology matrix: \n{}", mTearTopology);
347 SPDLOG_LOGGER_INFO(mSLog,
"Removed impedance matrix: \n{}", mTearImpedance);
349 mSystemInverseTearTopology =
350 Matrix::Zero(mTearTopology.rows(), mTearTopology.cols());
351 for (
auto &net : mSubnets) {
353 mTearTopology.block(net.sysOff, 0, net.sysSize, mTearTopology.cols());
354 mSystemInverseTearTopology.block(net.sysOff, 0, net.sysSize,
355 mTearTopology.cols()) =
356 net.directLinearSolver->solve(tearTopoBlock);
359 net.tearColumns.clear();
360 for (
UInt col = 0; col < static_cast<UInt>(mTearTopology.cols()); ++col) {
361 if (!tearTopoBlock.col(col).isZero())
362 net.tearColumns.push_back(col);
366 mTearImpedance + mTearTopology.transpose() * mSystemInverseTearTopology;
367 mTotalTearImpedance = Eigen::PartialPivLU<Matrix>(mTearSchur);
368 SPDLOG_LOGGER_INFO(mSLog,
369 "Total removed impedance matrix LU decomposition: \n{}",
370 mTotalTearImpedance.matrixLU());
373 for (
auto &net : mSubnets) {
374 Matrix rInit = Matrix::Zero(net.sysSize, 1);
376 for (
auto comp : net.components) {
377 comp->mnaApplyRightSideVectorStamp(rInit);
379 SPDLOG_LOGGER_INFO(mSLog,
"Source block: \n{}", rInit);
383template <>
void DiakopticsSolver<Real>::applyTearComponentStamp(
UInt compIdx) {
384 auto comp = mTearComponents[compIdx];
387 std::vector<Eigen::Triplet<double>> triplets;
391 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
392 comp->node(0)->matrixNodeIndex(PhaseType::A),
394 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
395 comp->node(0)->matrixNodeIndex(PhaseType::B),
397 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
398 comp->node(0)->matrixNodeIndex(PhaseType::C),
401 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
402 comp->node(0)->matrixNodeIndex(),
408 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
409 comp->node(1)->matrixNodeIndex(PhaseType::A),
411 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
412 comp->node(1)->matrixNodeIndex(PhaseType::B),
413 compIdx * 3 + 1, -1);
414 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
415 comp->node(1)->matrixNodeIndex(PhaseType::C),
416 compIdx * 3 + 2, -1);
418 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
419 comp->node(1)->matrixNodeIndex(),
424 for (
const auto &triplet : triplets) {
425 mTearTopology.coeffRef(triplet.row(), triplet.col()) += triplet.value();
429 auto tearComp = std::dynamic_pointer_cast<MNATearInterface>(comp);
430 tearComp->mnaTearApplyMatrixStamp(mTearImpedance);
434void DiakopticsSolver<Complex>::applyTearComponentStamp(
UInt compIdx) {
435 auto comp = mTearComponents[compIdx];
438 std::vector<Eigen::Triplet<double>> triplets;
442 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
443 comp->node(0)->matrixNodeIndex(PhaseType::A),
445 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
446 mNodeSubnetMap[comp->node(0)]->mCmplOff +
447 comp->node(0)->matrixNodeIndex(PhaseType::A),
448 mTearComponents.size() * 3 + compIdx * 3,
450 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
451 comp->node(0)->matrixNodeIndex(PhaseType::B),
453 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
454 mNodeSubnetMap[comp->node(0)]->mCmplOff +
455 comp->node(0)->matrixNodeIndex(PhaseType::B),
456 mTearComponents.size() * 3 + compIdx * 3 + 1,
458 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
459 comp->node(0)->matrixNodeIndex(PhaseType::C),
461 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
462 mNodeSubnetMap[comp->node(0)]->mCmplOff +
463 comp->node(0)->matrixNodeIndex(PhaseType::C),
464 mTearComponents.size() * 3 + compIdx * 3 + 2,
467 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
468 comp->node(0)->matrixNodeIndex(),
470 triplets.emplace_back(mNodeSubnetMap[comp->node(0)]->sysOff +
471 mNodeSubnetMap[comp->node(0)]->mCmplOff +
472 comp->node(0)->matrixNodeIndex(),
473 mTearComponents.size() + compIdx,
double(1.0));
477 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
478 comp->node(1)->matrixNodeIndex(PhaseType::A),
480 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
481 mNodeSubnetMap[comp->node(1)]->mCmplOff +
482 comp->node(1)->matrixNodeIndex(PhaseType::A),
483 mTearComponents.size() * 3 + compIdx * 3,
485 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
486 comp->node(1)->matrixNodeIndex(PhaseType::B),
487 compIdx * 3 + 1, -1);
488 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
489 mNodeSubnetMap[comp->node(1)]->mCmplOff +
490 comp->node(1)->matrixNodeIndex(PhaseType::B),
491 mTearComponents.size() * 3 + compIdx * 3 + 1,
493 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
494 comp->node(1)->matrixNodeIndex(PhaseType::C),
495 compIdx * 3 + 2, -1);
496 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
497 mNodeSubnetMap[comp->node(1)]->mCmplOff +
498 comp->node(1)->matrixNodeIndex(PhaseType::C),
499 mTearComponents.size() * 3 + compIdx * 3 + 2,
502 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
503 comp->node(1)->matrixNodeIndex(),
505 triplets.emplace_back(mNodeSubnetMap[comp->node(1)]->sysOff +
506 mNodeSubnetMap[comp->node(1)]->mCmplOff +
507 comp->node(1)->matrixNodeIndex(),
508 mTearComponents.size() + compIdx,
double(-1.0));
511 for (
const auto &triplet : triplets) {
512 mTearTopology.coeffRef(triplet.row(), triplet.col()) += triplet.value();
516 auto tearComp = std::dynamic_pointer_cast<MNATearInterface>(comp);
517 tearComp->mnaTearApplyMatrixStamp(mTearImpedance);
523 for (
UInt net = 0; net < mSubnets.size(); ++net) {
524 for (
auto node : mSubnets[net].nodes) {
525 for (
auto task : node->mnaTasks())
529 for (
auto comp : mSubnets[net].components) {
530 for (
auto task : comp->mnaTasks()) {
534 l.push_back(std::make_shared<SubnetSolveTask>(*
this, net));
535 l.push_back(std::make_shared<SolveTask>(*
this, net));
538 for (
auto comp : mSimSignalComps) {
539 for (
auto task : comp->getTasks()) {
543 l.push_back(std::make_shared<PreSolveTask>(*
this));
544 l.push_back(std::make_shared<PostSolveTask>(*
this));
545 l.push_back(std::make_shared<LogTask>(*
this));
550template <
typename VarType>
554 mSubnet.systemMatrix.setZero();
555 for (
auto comp : mSubnet.components) {
556 comp->mnaApplySystemMatrixStamp(mSubnet.systemMatrix);
558 mSubnet.directLinearSolver->partialRefactorize(mSubnet.systemMatrix,
559 mSubnet.listVariableEntries);
565 const auto &cols = mSubnet.tearColumns;
566 const UInt nJ =
static_cast<UInt>(cols.size());
570 Matrix tearTopoBlock(mSubnet.sysSize, nJ);
571 for (
UInt c = 0; c < nJ; ++c)
572 tearTopoBlock.col(c) = mSolver.mTearTopology.block(mSubnet.sysOff, cols[c],
575 Matrix invTopoBlock = mSubnet.directLinearSolver->solve(tearTopoBlock);
577 for (
UInt c = 0; c < nJ; ++c)
578 mSolver.mSystemInverseTearTopology.block(
579 mSubnet.sysOff, cols[c], mSubnet.sysSize, 1) = invTopoBlock.col(c);
581 mSolver.mTearSchurNeedsRebuild =
true;
584template <
typename VarType>
586 bool changed =
false;
587 for (
auto varElem : mSubnet.mVariableComps) {
588 if (varElem->hasParameterChanged()) {
589 auto idObj = std::dynamic_pointer_cast<IdentifiedObject>(varElem);
598template <
typename VarType>
602 mSolver.mRightSideVector.block(mSubnet.sysOff, 0, mSubnet.sysSize, 1);
605 for (
auto stamp : mSubnet.rightVectorStamps)
608 auto lBlock = (**mSolver.mOrigLeftSideVector)
609 .block(mSubnet.sysOff, 0, mSubnet.sysSize, 1);
616 lBlock = mSubnet.directLinearSolver->solve(rhs);
619template <
typename VarType>
624 if (mSolver.mTearSchurNeedsRebuild.exchange(
false)) {
626 mSolver.mTearImpedance +
627 mSolver.mTearTopology.transpose() * mSolver.mSystemInverseTearTopology;
628 mSolver.mTotalTearImpedance =
629 Eigen::PartialPivLU<Matrix>(mSolver.mTearSchur);
632 mSolver.mTearVoltages.setZero();
633 for (
auto comp : mSolver.mTearComponents) {
634 auto tComp = std::dynamic_pointer_cast<MNATearInterface>(comp);
635 tComp->mnaTearApplyVoltageStamp(mSolver.mTearVoltages);
638 mSolver.mTearVoltages -=
639 mSolver.mTearTopology.transpose() * **mSolver.mOrigLeftSideVector;
641 mSolver.mTearCurrents =
642 mSolver.mTotalTearImpedance.solve(mSolver.mTearVoltages);
644 **mSolver.mMappedTearCurrents = mSolver.mTearTopology * mSolver.mTearCurrents;
645 mSolver.mLeftSideVector = **mSolver.mOrigLeftSideVector;
648template <
typename VarType>
652 mSolver.mLeftSideVector.block(mSubnet.sysOff, 0, mSubnet.sysSize, 1);
653 auto rBlock = (**mSolver.mMappedTearCurrents)
654 .block(mSubnet.sysOff, 0, mSubnet.sysSize, 1);
658 lBlock += mSubnet.directLinearSolver->solve(rhs);
659 **mSubnet.leftVector = lBlock;
666 mSolver.mTearVoltages =
667 -mSolver.mTearTopology.transpose() * mSolver.mLeftSideVector;
668 for (
UInt compIdx = 0; compIdx < mSolver.mTearComponents.size(); ++compIdx) {
669 auto comp = mSolver.mTearComponents[compIdx];
670 auto tComp = std::dynamic_pointer_cast<MNATearInterface>(comp);
672 Matrix voltage = Matrix::Zero(3, 1);
673 voltage << mSolver.mTearVoltages(compIdx * 3),
674 mSolver.mTearVoltages(compIdx * 3 + 1),
675 mSolver.mTearVoltages(compIdx * 3 + 2);
677 Matrix current = Matrix::Zero(3, 1);
678 current << mSolver.mTearCurrents(compIdx * 3),
679 mSolver.mTearCurrents(compIdx * 3 + 1),
680 mSolver.mTearCurrents(compIdx * 3 + 2);
681 tComp->mnaTearPostStep(voltage, current);
687 tComp->mnaTearPostStep(voltage, current);
692 for (
UInt net = 0; net < mSolver.mSubnets.size(); ++net) {
693 for (
UInt node = 0; node < mSolver.mSubnets[net].mRealNetNodeNum; ++node) {
694 mSolver.mSubnets[net].nodes[node]->mnaUpdateVoltage(
695 *(mSolver.mSubnets[net].leftVector));
704 mSolver.mTearVoltages =
705 -mSolver.mTearTopology.transpose() * mSolver.mLeftSideVector;
706 for (
UInt compIdx = 0; compIdx < mSolver.mTearComponents.size(); ++compIdx) {
707 auto comp = mSolver.mTearComponents[compIdx];
708 auto tComp = std::dynamic_pointer_cast<MNATearInterface>(comp);
724 tComp->mnaTearPostStep(voltage, current);
730 tComp->mnaTearPostStep(voltage, current);
735 for (
UInt net = 0; net < mSolver.mSubnets.size(); ++net) {
736 for (
UInt node = 0; node < mSolver.mSubnets[net].mRealNetNodeNum; ++node) {
737 mSolver.mSubnets[net].nodes[node]->mnaUpdateVoltage(
738 *(mSolver.mSubnets[net].leftVector));
743template <>
void DiakopticsSolver<Real>::log(
Real time,
Int timeStepCount) {
744 mLeftVectorLog->logEMTNodeValues(time, mLeftSideVector);
745 mRightVectorLog->logEMTNodeValues(time, mRightSideVector);
748template <>
void DiakopticsSolver<Complex>::log(
Real time,
Int timeStepCount) {
749 mLeftVectorLog->logPhasorNodeValues(time, mLeftSideVector);
750 mRightVectorLog->logPhasorNodeValues(time, mRightSideVector);
753template <
typename VarType>
755 mSolver.log(time, timeStepCount);
spdlog::level::level_enum Level
static Complex complexFromVectorElement(const Matrix &mat, Matrix::Index row, Int maxFreq=1, Int freqIdx=0)
Real mSystemFrequency
System frequency.
TopologicalNode::List mNodes
List of network nodes.
void splitSubnets(std::vector< CPS::SystemTopology > &splitSystems)
void execute(Real time, Int timeStepCount)
void execute(Real time, Int timeStepCount)
void execute(Real time, Int timeStepCount)
void execute(Real time, Int timeStepCount)
Bool hasVariableComponentChanged()
Check whether status of variable MNA elements has changed.
void execute(Real time, Int timeStepCount)
void recomputeSubnetMatrix(Real time)
CPS::Task::List getTasks() override
Get tasks for scheduler.
const CPS::Attribute< Matrix >::Ptr mOrigLeftSideVector
Solutions of the split systems.
DiakopticsSolver(String name, CPS::SystemTopology system, CPS::IdentifiedObject::List tearComponents, Real timeStep, CPS::Logger::Level logLevel)
const CPS::Attribute< Matrix >::Ptr mMappedTearCurrents
Currents through the removed network (as "seen" from the other subnets)
Real mTimeStep
Time step for fixed step solvers.
Solver(String name, CPS::Logger::Level logLevel)
static std::shared_ptr< AttributeList > make(Args &&...args)
Eigen::SparseMatrix< Real, Eigen::RowMajor > SparseMatrixRow
Sparse matrix for real numbers (row major).
CPS::SystemTopology SystemTopology
CPS::SparseMatrixRow SparseMatrix
CPS::MatrixComp MatrixComp