39 #include <Xyce_config.h>
53 #include <N_LAS_BlockMatrix.h>
54 #include <N_LAS_BlockSystemHelpers.h>
55 #include <N_LAS_BlockVector.h>
56 #include <N_LAS_MOROperators.h>
57 #include <N_LAS_Matrix.h>
58 #include <N_LAS_MultiVector.h>
59 #include <N_LAS_System.h>
61 #include <N_IO_CircuitBlock.h>
62 #include <N_IO_CmdParse.h>
63 #include <N_IO_InitialConditions.h>
64 #include <N_IO_OptionBlock.h>
65 #include <N_IO_OutputROM.h>
66 #include <N_IO_PkgOptionsMgr.h>
67 #include <N_IO_SpiceSeparatedFieldTool.h>
74 #include <N_PDS_Comm.h>
75 #include <N_PDS_ParMap.h>
76 #include <N_PDS_Serial.h>
77 #include <N_PDS_MPI.h>
84 #include <N_TOP_Topology.h>
86 #include <N_UTL_Diagnostic.h>
87 #include <N_UTL_ExtendedString.h>
88 #include <N_UTL_Factory.h>
89 #include <N_UTL_FeatureTest.h>
90 #include <N_UTL_Math.h>
91 #include <N_UTL_Timer.h>
93 #ifdef Xyce_PARALLEL_MPI
94 #include <N_PDS_ParComm.h>
97 #include <N_PDS_SerialComm.h>
102 #include <Epetra_CrsMatrix.h>
103 #include <Epetra_Operator.h>
104 #include <Epetra_CrsGraph.h>
105 #include <Epetra_MultiVector.h>
106 #include <Epetra_LinearProblem.h>
110 #include <BelosLinearProblem.hpp>
111 #include <BelosBlockGmresIter.hpp>
112 #include <BelosDGKSOrthoManager.hpp>
113 #include <BelosStatusTestMaxIters.hpp>
114 #include <BelosOutputManager.hpp>
115 #include <BelosEpetraAdapter.hpp>
118 #include <Teuchos_SerialDenseMatrix.hpp>
119 #include <Teuchos_ScalarTraits.hpp>
120 #include <Teuchos_LAPACK.hpp>
121 #include <Teuchos_BLAS.hpp>
138 Topo::Topology & topology,
139 IO::InitialConditionsManager & initial_conditions_manager)
141 comm_(analysis_manager.getPDSManager()->getPDSComm()->comm()),
147 outputManagerAdapter_(analysis_manager.getOutputManagerAdapter()),
151 morSaveRedSys_(false),
152 morCompOrigTF_(false),
153 morCompRedTF_(false),
162 morScaleFactor_(1.0),
164 morScaleFactor1_(1.0),
165 morSparsificationType_(0),
169 isSingleFreq_(false),
197 for (Util::ParamList::const_iterator it = paramsBlock.begin(), end = paramsBlock.end(); it != end; ++it)
199 if ((*it).uTag() ==
"PORTLIST")
201 portList_ = (*it).getValue<std::vector<std::string> >();
205 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
208 << section_divider << std::endl
209 <<
" MOR simulation parameters" << std::endl
210 <<
" size = " <<
ROMsize_ << std::endl;
226 const Util::OptionBlock & option_block)
228 for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
254 Report::UserError0() << (*it).uTag() <<
" is not a recognized model-order reduction option.";
314 bool bsuccess =
true;
365 Report::UserError() <<
"Solving for DC operating point failed, cannot continue MOR analysis";
370 std::vector<int> tempVec;
374 int hsize = tempVec.size();
380 Report::UserError() <<
"Number of specified ports in .MOR line is inconsistent with number of voltage sources";
386 std::vector<int> gidPosEntries( hsize );
387 for (
int i=0; i<hsize; ++i)
389 std::vector<int> svGIDList1, dummyList;
394 gidPosEntries[i] = svGIDList1.front();
400 RCP<N_PDS_ParMap> BaseMap = rcp(pdsManager.getParallelMap( Parallel::SOLUTION ),
false);
404 for (
int i=0; i<hsize; ++i)
406 int gid = gidPosEntries[i];
408 for (
int j=0; j<hsize; ++j)
419 Report::UserError() <<
"Did not find voltage source corresponding to port";
504 int length=1, numEntries=0;
505 std::vector<int> colIndices(length);
506 std::vector<double> coeffs(length);
512 if ( numEntries != 1 )
514 Report::UserError0() <<
"Supposed voltage source row has too many entries, cannot continue MOR analysis";
519 GPtr_->getLocalRowCopy(
bMatEntriesVec_[i], length, numEntries, &coeffs[0], &colIndices[0]);
522 if ( coeffs[0] > 0.0 )
525 GPtr_->putLocalRow(
bMatEntriesVec_[i], length, &coeffs[0], &colIndices[0]);
550 bool bsuccess =
true;
555 N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap( Parallel::SOLUTION );
571 RPtr_->putScalar( 0.0 );
588 Amesos amesosFactory;
593 int linearStatus =
origSolver_->SymbolicFactorization();
594 if (linearStatus != 0)
596 Xyce::dout() <<
"Amesos symbolic factorization exited with error: " << linearStatus << std::endl;
601 linearStatus =
origSolver_->NumericFactorization();
602 if (linearStatus != 0)
604 Xyce::dout() <<
"Amesos numeric factorization exited with error: " << linearStatus << std::endl;
610 if (linearStatus != 0)
612 Xyce::dout() <<
"Amesos solve exited with error: " << linearStatus << std::endl;
620 RCP<Epetra_Operator> COpPtr_ = rcp( &
CPtr_->epetraObj(), false );
621 RCP<Linear::AmesosGenOp> AOp = rcp(
new Linear::AmesosGenOp(
origSolver_, COpPtr_ ) );
641 Report::UserError() <<
"Automatic Sizing is OFF. Please specify the ROM dimension";
649 UserWarning(*
this) <<
"Requested reduced-order model dimension is larger than original system dimension, resizing to original system dimension";
660 redB_.shape(k, numPorts_);
661 redL_.shape(k, numPorts_);
670 typedef Epetra_MultiVector MV;
671 typedef Epetra_Operator OP;
672 typedef Belos::MultiVecTraits<ST,MV> MVT;
675 Belos::OutputManager<ST> printer;
678 Belos::StatusTestMaxIters<ST, MV, OP> maxIterTest( kblock );
681 Belos::DGKSOrthoManager<ST, MV, OP> orthoMgr;
685 Linear::MultiVector temp( BaseMap, numPorts_ );
686 Belos::LinearProblem<ST, MV, OP > problem( AOp,
687 rcp( &temp.epetraObj(), false ),
688 rcp( &
RPtr_->epetraObj(), false ));
689 problem.setProblem();
692 Teuchos::ParameterList params;
693 params.set(
"Num Blocks", kblock);
694 params.set(
"Block Size", numPorts_ );
697 Belos::BlockGmresIter<ST, MV, OP> krylovIter( rcp( &problem,
false ),
698 rcp( &printer,
false ),
699 rcp( &maxIterTest,
false ),
700 rcp( &orthoMgr,
false ),
704 RCP<Teuchos::SerialDenseMatrix<int,ST> > z
705 = rcp(
new Teuchos::SerialDenseMatrix<int,ST>( numPorts_, numPorts_ ) );
708 RCP<MV> V = rcp(
new Epetra_MultiVector(
RPtr_->epetraObj() ) );
709 orthoMgr.normalize( *V, z );
712 Belos::GmresIterationState<ST,MV> initState;
715 initState.curDim = 0;
716 krylovIter.initializeGmres(initState);
720 krylovIter.iterate();
722 catch (
const Belos::GmresIterationOrthoFailure &e) {
725 catch (
const std::exception &e) {
730 Belos::GmresIterationState<ST,MV> newState = krylovIter.getState();
737 RCP<MV>
W = rcp(
new Epetra_MultiVector( V->Map(), k ) );
739 int low = 1, high = k;
743 double abstol = 1e-6;
744 double reltol = 1e-3;
748 while ((high - low) > 0 )
750 mid = (low + high)/2;
752 std::vector<int> indices(mid);
755 redG_.shape(mid, mid);
756 redC_.shape(mid, mid);
757 redB_.shape(mid, numPorts_);
758 redL_.shape(mid, numPorts_);
760 for (
int i=0; i<mid; ++i) { indices[i] = i; }
762 V = rcp(
new Epetra_MultiVector( View, *newState.V, &indices[0], mid) );
767 Linear::MultiVector xyceV( &*V,
false );
768 Linear::MultiVector temp2( BaseMap, mid);
770 Linear::MultiVector xyceW( &*W,
false );
772 GPtr_->matvec(
false, xyceV, temp2 );
775 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redG_ );
778 CPtr_->matvec(
false, xyceV, temp2 );
780 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redC_ );
784 MVT::MvTransMv( 1.0, xyceW.epetraObj(),
BPtr_->epetraObj(),
redB_ );
786 MVT::MvTransMv( 1.0, xyceV.epetraObj(),
BPtr_->epetraObj(),
redL_ );
794 origH_.shape(numPorts_, numPorts_);
795 redH_.shape(numPorts_, numPorts_);
801 Teuchos::SerialDenseMatrix<int, double> H_diff, totaltol, errOverTol;
803 totaltol.shape(numPorts_, numPorts_);
804 H_diff.shape(numPorts_, numPorts_);
807 errOverTol.shape(numPorts_, numPorts_);
812 totaltol(i,j) = reltol*abs(
origH_(i,j)) + abstol;
816 errOverTol(i, j) = H_diff(i,j)/totaltol(i,j);
820 double totalErrOverTol = errOverTol.normFrobenius()/
numPorts_;
823 if( totalErrOverTol < 1)
837 UserWarning(*
this) <<
"Requested reduced-order model dimension is larger than original system dimension, resizing to original system dimension";
841 kblock = (int)(
ROMsize_ / numPorts_);
849 redB_.shape(k, numPorts_);
850 redL_.shape(k, numPorts_);
853 std::vector<int> indices(k);
854 for (
int i=0; i<k; ++i) { indices[i] = i; }
856 V = rcp(
new Epetra_MultiVector( View, *newState.V, &indices[0], k) );
865 Linear::MultiVector xyceV( &*V,
false );
866 Linear::MultiVector temp2( BaseMap, k );
869 GPtr_->matvec(
false, xyceV, temp2 );
871 MVT::MvTransMv( 1.0, xyceV.epetraObj(), temp2.epetraObj(),
redG_ );
875 CPtr_->matvec(
false, xyceV, temp2 );
877 MVT::MvTransMv( 1.0, xyceV.epetraObj(), temp2.epetraObj(),
redC_ );
881 MVT::MvTransMv( 1.0, xyceV.epetraObj(),
BPtr_->epetraObj(),
redB_ );
892 Teuchos::SerialDenseMatrix<int,ST> Xhatscale( k, 1 );
896 if ( scaleType == 1 )
898 for (
int i=0; i<k; ++i)
909 if ( scaleType == 2 || scaleType == 3 || scaleType ==4)
911 Epetra_MultiVector Xmag( V->Map(), 1 );
913 if ( scaleType == 2 )
919 MVT::MvTransMv( 1.0, *V, Xmag, Xhatscale );
922 for (
int i=0; i<k; ++i)
925 if ( scaleType == 2 )
937 if ( scaleType == 3 )
940 if ( scaleType == 4 )
942 if ( fabs(Xhatscale( i, 0 )) > 1.0 )
959 Teuchos::SerialDenseMatrix<int,ST> D(k,k);
960 if ( scaleType != 0 )
962 RCP<MV> Vtemp = rcp(
new Epetra_MultiVector( V->Map(), k ) );
964 for (
int i=0; i<k; ++i)
966 if (Xhatscale( i, 0 ) != 0.0)
967 D(i,i) = 1.0/Xhatscale( i, 0 );
971 Xyce::dout() <<
" the scaling matrix " << std::endl;
975 MVT::MvTimesMatAddMv( 1.0, *V, D, 0.0, *Vtemp );
988 Linear::MultiVector xyceV( &*V,
false );
989 Linear::MultiVector xyceW( &*W,
false );
990 Linear::MultiVector temp2( BaseMap, k );
995 GPtr_->matvec(
false, xyceV, temp2 );
997 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redG_ );
1001 CPtr_->matvec(
false, xyceV, temp2 );
1003 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redC_ );
1006 MVT::MvTransMv( 1.0, xyceW.epetraObj(),
BPtr_->epetraObj(),
redB_ );
1008 MVT::MvTransMv( 1.0, xyceV.epetraObj(),
BPtr_->epetraObj(),
redL_ );
1012 if ( scaleType <= 1 )
1021 Report::UserError0() <<
"MOR options sparsificationType=1 can only be used with scaletype=1, other scale types have not been supported for sparsification";
1042 Report::UserError0() <<
"Belos is necessary to compute a reduced-order model, please recompile Xyce with Belos enabled";
1045 #endif // Xyce_BELOS
1060 bool bsuccess =
true;
1064 int currentStep = 0;
1070 bool stepAttemptStatus;
1072 while (currentStep < finalStep)
1084 if (stepAttemptStatus)
1108 bool bsuccess =
true;
1112 int currentStep = 0;
1119 bool stepAttemptStatus;
1121 while (currentStep < finalStep)
1132 if (stepAttemptStatus)
1155 bool bsuccess =
true;
1159 N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION);
1160 N_PDS_ParMap &oBaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION_OVERLAP_GND);
1161 Epetra_CrsGraph &BaseFullGraph = *pdsManager.getMatrixGraph(Parallel::JACOBIAN);
1165 std::vector<RCP<N_PDS_ParMap> > blockMaps = Linear::createBlockParMaps(numBlocks, BaseMap, oBaseMap);
1167 std::vector<std::vector<int> > blockPattern(2);
1168 blockPattern[0].resize(2);
1169 blockPattern[0][0] = 0; blockPattern[0][1] = 1;
1170 blockPattern[1].resize(2);
1171 blockPattern[1][0] = 0; blockPattern[1][1] = 1;
1173 int offset = Linear::generateOffset( BaseMap );
1174 RCP<Epetra_CrsGraph> blockGraph = Linear::createBlockGraph( offset, blockPattern, *blockMaps[0], BaseFullGraph);
1176 sCpG_REFMatrixPtr_ = rcp (
new Linear::BlockMatrix( numBlocks, offset, blockPattern, *blockGraph, BaseFullGraph) );
1194 Amesos amesosFactory;
1197 REFBPtr_ = rcp (
new Linear::BlockVector ( numBlocks, blockMaps[0], rcp(&BaseMap,
false) ) );
1198 REFXPtr_ = rcp (
new Linear::BlockVector ( numBlocks, blockMaps[0], rcp(&BaseMap,
false) ) );
1205 int linearStatus =
blockSolver_->SymbolicFactorization();
1207 if (linearStatus != 0)
1209 Xyce::dout() <<
"Amesos symbolic factorization exited with error: " << linearStatus;
1233 int k =
redG_.numRows();
1242 Teuchos::SerialDenseMatrix<int, double> subMtx( Teuchos::View,
sCpG_tmpMatrix_, k, k, 0, 0 );
1243 subMtx.assign(
redC_ );
1244 subMtx.scale( -
s0_ );
1248 Teuchos::SerialDenseMatrix<int, double> subMtx2( Teuchos::View,
sCpG_tmpMatrix_, k, k, k, k );
1249 subMtx2.assign(
redC_ );
1250 subMtx2.scale( -
s0_ );
1260 N_PDS_ParMap redPDSMap(
redMapPtr_.get(), *pdsManager.getPDSComm() );
1262 RCP<N_PDS_ParMap> redBlockMapPtr = Linear::createBlockParMap(numBlocks, redPDSMap);
1264 std::vector<std::vector<int> > blockPattern(2);
1265 blockPattern[0].resize(2);
1266 blockPattern[0][0] = 0; blockPattern[0][1] = 1;
1267 blockPattern[1].resize(2);
1268 blockPattern[1][0] = 0; blockPattern[1][1] = 1;
1270 int offset= Linear::generateOffset( redPDSMap );
1271 RCP<Epetra_CrsGraph> blockGraph = Linear::createBlockGraph( offset, blockPattern, *redBlockMapPtr, (
redCPtr_->epetraObj()).Graph() );
1276 sCpG_ref_redMatrixPtr_->put( 0.0 );
1281 sCpG_ref_redMatrixPtr_->block( 0, 0 ).add(*
redCPtr_);
1282 sCpG_ref_redMatrixPtr_->block( 0, 0 ).scale(-
s0_);
1283 sCpG_ref_redMatrixPtr_->block( 1, 1 ).add(*
redCPtr_);
1284 sCpG_ref_redMatrixPtr_->block( 1, 1 ).scale(-
s0_);
1287 sCpG_ref_redMatrixPtr_->block( 0, 0 ).add(*
redGPtr_);
1288 sCpG_ref_redMatrixPtr_->block( 1, 1 ).add(*
redGPtr_);
1291 Amesos amesosFactory;
1294 ref_redBPtr_ = rcp (
new Linear::BlockVector ( numBlocks, redBlockMapPtr, rcp(&redPDSMap,
false) ) );
1295 ref_redXPtr_ = rcp (
new Linear::BlockVector ( numBlocks, redBlockMapPtr, rcp(&redPDSMap,
false) ) );
1298 blockRedProblem_ = rcp(
new Epetra_LinearProblem(&sCpG_ref_redMatrixPtr_->epetraObj(),
1305 if (linearStatus != 0)
1307 Xyce::dout() <<
"Amesos symbolic factorization exited with error: " << linearStatus;
1364 int k =
redG_.numRows();
1370 Teuchos::SerialDenseMatrix<int, double> subMtx( Teuchos::View,
sCpG_redMatrix_, k, k, 0, k );
1371 subMtx.assign(
redC_ );
1372 subMtx.scale( -omega );
1374 Teuchos::SerialDenseMatrix<int, double> subMtx2( Teuchos::View,
sCpG_redMatrix_, k, k, k, 0 );
1375 subMtx2.assign(
redC_ );
1376 subMtx2.scale( omega );
1394 bool bsuccess =
true;
1397 int linearStatus =
blockSolver_->NumericFactorization();
1399 if (linearStatus != 0)
1401 Xyce::dout() <<
"Amesos numeric factorization exited with error: " << linearStatus;
1412 if (linearStatus != 0)
1414 Xyce::dout() <<
"Amesos solve exited with error: " << linearStatus;
1442 bool bsuccess =
true;
1449 if (linearStatus != 0)
1451 Xyce::dout() <<
"Amesos numeric factorization exited with error: " << linearStatus;
1458 Linear::MultiVector redBmv( &tmp_redB,
false ), redLmv( &tmp_redL,
false );
1465 (
ref_redBPtr_->block( 0 )) = *(redBmv.getVectorView( j ));
1468 if (linearStatus != 0)
1470 Xyce::dout() <<
"Amesos solve exited with error: " << linearStatus;
1478 double realPart = ( redLmv.getVectorView( i ) )->dotProduct(
ref_redXPtr_->block( 0 ) );
1479 double imagPart = ( redLmv.getVectorView( i ) )->dotProduct(
ref_redXPtr_->block( 1 ) );
1481 redH_(i,j) = std::complex<double>(realPart, imagPart);
1487 int k =
redG_.numRows();
1488 Teuchos::LAPACK<int, double> lapack;
1491 Teuchos::SerialDenseMatrix<int, double> tmpRedB( Teuchos::View,
ref_redB_,
redB_.numRows(),
redB_.numCols(), 0, 0 );
1492 tmpRedB.assign(
redB_ );
1501 Xyce::dout() <<
"LAPACK::GETRF: LU factorization failed with error: " << info << std::endl;
1506 const char trans =
'N';
1511 Xyce::dout() <<
"LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1518 tmpRedReal.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0,
redB_, tmpRedB, 0.0 );
1521 Teuchos::SerialDenseMatrix<int, double> tmpRedB2( Teuchos::View,
ref_redB_,
redB_.numRows(),
redB_.numCols(), k, 0 );
1522 tmpRedImag.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0,
redB_, tmpRedB2, 0.0 );
1529 redH_(i,j) = std::complex<double>(tmpRedReal(i,j), tmpRedImag(i,j));
1547 bool bsuccess =
true;
1549 int k =
redB_.numRows();
1552 Teuchos::SerialDenseMatrix<int, double> R(
redB_);
1553 Teuchos::SerialDenseMatrix<int, double> A(
redC_);
1556 Teuchos::LAPACK<int, double> lapack;
1557 Teuchos::SerialDenseMatrix<int, double> tmp_Ghat(
redG_ );
1560 std::vector<int> ipiv( tmp_Ghat.numRows() );
1561 lapack.GETRF( tmp_Ghat.numRows(), tmp_Ghat.numCols(), tmp_Ghat.values(),
1562 tmp_Ghat.stride(), &ipiv[0], &
info );
1565 Xyce::dout() <<
"LAPACK::GETRF: LU factorization of Ghat failed with error: " << info << std::endl;
1570 const char norm =
'1';
1571 double condGhat = 0.0;
1572 std::vector<double> condWork( 4*k );
1573 std::vector<int> condIWork( k );
1574 lapack.GECON( norm, tmp_Ghat.numRows(), tmp_Ghat.values(), tmp_Ghat.stride(), tmp_Ghat.normOne(), &condGhat, &condWork[0], &condIWork[0], &
info );
1578 Xyce::dout() <<
"LAPACK::GECON: Computing condition estimate of Ghat failed with error: " << info << std::endl;
1583 const char trans =
'N';
1584 lapack.GETRS( trans, tmp_Ghat.numRows(), A.numCols(), tmp_Ghat.values(),
1585 tmp_Ghat.stride(), &ipiv[0], A.values(), A.stride(), &
info );
1588 Xyce::dout() <<
"LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1595 lapack.GETRS( trans, tmp_Ghat.numRows(), R.numCols(), tmp_Ghat.values(),
1596 tmp_Ghat.stride(), &ipiv[0], R.values(), R.stride(), &
info );
1599 Xyce::dout() <<
"LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1612 std::vector<double> work( lwork );
1613 std::vector<double> revals( k );
1614 std::vector<double> ievals( k );
1615 Teuchos::SerialDenseMatrix<int, double> Q(k, k);
1620 std::vector<double> beta( k );
1621 Teuchos::SerialDenseMatrix<int, double> tmpB( k, k );
1622 for (
int i=0; i<k; i++)
1624 lapack.GGEV(
'N',
'V', k, A.values(), A.stride(), tmpB.values(), tmpB.stride(),
1625 &revals[0], &ievals[0], &beta[0], &vl[0], ldvl, Q.values(), Q.stride(),
1626 &work[0], lwork, &
info );
1629 Xyce::dout() <<
"LAPACK::GGEV: Computing eigenvectors and values of A = inv(Ghat)*Chat failed with error: " << info << std::endl;
1635 Teuchos::BLAS<int, double> blas;
1636 std::vector<int> rowIndex( k );
1640 if ( ievals[i] != 0.0 )
1646 double norm_r = blas.NRM2( k, Q[i], 1 );
1647 double norm_i = blas.NRM2( k, Q[i+1], 1 );
1648 double norm = lapack.LAPY2( norm_r, norm_i );
1651 for (
int j=0; j<k; j++)
1663 double norm = blas.NRM2( k, Q[i], 1 );
1666 for (
int j=0; j<k; j++)
1682 Teuchos::SerialDenseMatrix<int, std::complex<double> > V(k, k);
1683 for (
int i=0; i<k; i++)
1685 if (rowIndex[i] == 1)
1687 for (
int j=0; j<k; j++)
1690 V(j,i) = std::complex<double>( Q(j,i), Q(j,i+1) );
1691 V(j,i+1) = std::complex<double>( Q(j,i), -Q(j,i+1) );
1697 for (
int j=0; j<k; j++)
1699 V(j,i) = std::complex<double>( Q(j,i), 0.0 );
1705 Teuchos::LAPACK<int, std::complex<double> > lapack_complex;
1706 lapack_complex.GETRF( V.numRows(), V.numCols(), V.values(), V.stride(), &ipiv[0], &
info );
1709 Xyce::dout() <<
"LAPACK::GETRF: LU factorization of eigenvectors failed with error: " << info << std::endl;
1715 std::vector<std::complex<double> > condCWork( 2*k );
1716 lapack_complex.GECON( norm, V.numRows(), V.values(), V.stride(), V.normOne(), &condV, &condCWork[0], &condWork[0], &
info );
1720 Xyce::dout() <<
"LAPACK::GECON: Computing condition estimate of V failed with error: " << info << std::endl;
1725 std::vector<std::complex<double> > cwork( lwork );
1726 lapack_complex.GETRI( V.numRows(), V.values(), V.stride(), &ipiv[0], &cwork[0], lwork, &
info );
1729 Xyce::dout() <<
"LAPACK::GETRI: Computing inverse of V failed with error: " << info << std::endl;
1734 Teuchos::SerialDenseMatrix<int, std::complex<double> > tmpR( k,
numPorts_ );
1736 for (
int i=0; i<k; i++)
1737 tmpR(i,j) = std::complex<double>( R(i,j), 0.0 );
1740 Teuchos::SerialDenseMatrix<int, std::complex<double> > tmp_redB(k ,numPorts_);
1741 tmp_redB.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, tmpR, 0.0);
1745 Teuchos::SerialDenseMatrix<int, double> invV(k, k);
1746 for (
int i=0; i<k; i++)
1748 if (rowIndex[i] == 1)
1750 for (
int j=0; j<k; j++)
1752 invV(i, j) = V(i,j).real();
1753 invV(i+1, j) = V(i,j).imag();
1757 redB_(i, j) = tmp_redB(i, j).real();
1758 redB_(i+1, j) = tmp_redB(i, j).imag();
1764 for (
int j=0; j<k; j++)
1765 invV(i, j) = V(i,j).real();
1767 redB_(i, j) = tmp_redB(i, j).real();
1772 lapack.GETRF( invV.numRows(), invV.numCols(), invV.values(), invV.stride(), &ipiv[0], &
info );
1775 Xyce::dout() <<
"LAPACK::GETRF: LU factorization of inv(V) failed with error: " << info << std::endl;
1780 const char trans2 =
'T';
1781 lapack.GETRS( trans2, invV.numRows(),
redL_.numCols(), invV.values(),
1782 invV.stride(), &ipiv[0],
redL_.values(),
redL_.stride(), &
info );
1785 Xyce::dout() <<
"LAPACK::GETRS: LU solve for Lhat failed with error: " << info << std::endl;
1797 N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION);
1798 if (BaseMap.petraMap()->Comm().MyPID() == 0)
1799 redMapPtr_ = Teuchos::rcp(
new Epetra_Map( k, k, 0, BaseMap.petraMap()->Comm() ) );
1801 redMapPtr_ = Teuchos::rcp(
new Epetra_Map( k, 0, 0, BaseMap.petraMap()->Comm() ) );
1803 Epetra_CrsMatrix* tmpRedG =
new Epetra_CrsMatrix( Copy, *
redMapPtr_, 1 );
1804 Epetra_CrsMatrix* tmpRedC =
new Epetra_CrsMatrix( Copy, *
redMapPtr_, 2 );
1807 if (BaseMap.petraMap()->Comm().MyPID() == 0)
1809 std::vector<int> index(2);
1810 std::vector<double> val(2);
1811 for (
int i=0; i<k; i++)
1814 index[0] = i; val[0] = 1.0;
1815 tmpRedG->InsertGlobalValues( i, 1, &val[0], &index[0] );
1818 if (rowIndex[i] == 1)
1820 index[0] = i; index[1] = i+1;
1821 val[0] = revals[i]; val[1] = -ievals[i];
1822 tmpRedC->InsertGlobalValues( i, 2, &val[0], &index[0] );
1824 else if (rowIndex[i] == -1)
1826 index[0] = i-1; index[1] = i;
1827 val[0] = ievals[i-1]; val[1] = revals[i-1];
1828 tmpRedC->InsertGlobalValues( i, 2, &val[0], &index[0] );
1832 index[0] = i; val[0] = revals[i];
1833 tmpRedC->InsertGlobalValues( i, 1, &val[0], &index[0] );
1838 tmpRedC->FillComplete();
1839 tmpRedG->FillComplete();
1842 redGPtr_ = rcp(
new Linear::Matrix( tmpRedG ) );
1843 redCPtr_ = rcp(
new Linear::Matrix( tmpRedC ) );
1862 bool bsuccess =
true;
1899 bool bsuccess =
true;
1919 bool bsuccess =
true;
1922 Xyce::dout() <<
"Calling MOR::doFinish() outputs!" << std::endl;
1981 Report::DevelFatal().in(
"MOR::updateCurrentFreq_") <<
"Unsupported STEP type";
2001 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2003 Xyce::dout() << std::endl << std::endl;
2004 Xyce::dout() << section_divider << std::endl;
2005 Xyce::dout() <<
"MOR::setupSweepParam_" << std::endl;
2017 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2019 Xyce::dout() <<
"fStep = " <<
fStep_ << std::endl;
2025 fCount = (int)(floor(fabs(log10(fStart) - log10(fStop)) * morCompNP_ + 1));
2026 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2028 Xyce::dout() <<
"stepMult_ = " <<
stepMult_ << std::endl;
2038 double ln2=log(2.0);
2039 fCount = floor(fabs(log(fStart) - log(fStop))/ln2 *
morCompNP_ + 1);
2040 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2042 Xyce::dout() <<
"stepMult_ = " <<
stepMult_ << std::endl;
2047 Report::DevelFatal().in(
"MOR::setupSweepParam_") <<
"Unsupported type";
2057 typedef Util::Factory<AnalysisBase, MOR> MORFactoryBase;
2070 class MORFactory :
public MORFactoryBase
2098 Linear::System & linear_system,
2101 Topo::Topology & topology,
2102 IO::InitialConditionsManager & initial_conditions_manager)
2112 virtual ~MORFactory()
2154 void setMORAnalysisOptionBlock(
const Util::OptionBlock &option_block)
2174 bool setMOROptsOptionBlock(
const Util::OptionBlock &option_block)
2195 struct MORAnalysisReg :
public IO::PkgOptionsReg
2198 MORFactory & factory )
2202 bool operator()(
const Util::OptionBlock &option_block)
2204 factory_.setMORAnalysisOptionBlock(option_block);
2225 IO::PkgOptionsMgr & options_manager,
2226 IO::CircuitBlock & circuit_block,
2227 const std::string & netlist_filename,
2228 const IO::TokenVector & parsed_line)
2230 Util::OptionBlock option_block(
"MOR", Util::OptionBlock::NO_EXPRESSIONS, netlist_filename, parsed_line[0].lineNumber_);
2232 int numFields = parsed_line.size();
2234 int linePosition = 0;
2236 Util::Param parameter(
"",
"");
2240 std::vector<std::string> portNames(numFields - 1);
2241 for (
int i=0; i<(numFields-1); ++i)
2246 ExtendedString stringVal ( parsed_line[linePosition].string_ );
2247 stringVal.toUpper();
2248 portNames[i] = stringVal;
2251 parameter.setTag(
"PORTLIST" );
2252 parameter.setVal( portNames );
2253 option_block.addParam( parameter );
2256 circuit_block.addOptions(option_block);
2263 IO::PkgOptionsMgr & options_manager)
2265 Util::ParamMap ¶meters = options_manager.addOptionsMetadataMap(
"MOR_OPTS");
2267 parameters.insert(Util::ParamMap::value_type(
"SIZE", Util::Param(
"SIZE", -1)));
2268 parameters.insert(Util::ParamMap::value_type(
"METHOD", Util::Param(
"METHOD",
"PRIMA")));
2269 parameters.insert(Util::ParamMap::value_type(
"AUTOSIZE", Util::Param(
"AUTOSIZE",
false)));
2270 parameters.insert(Util::ParamMap::value_type(
"ANALYSISONLY", Util::Param(
"ANALYSISONLY",
false)));
2271 parameters.insert(Util::ParamMap::value_type(
"MAXSIZE", Util::Param(
"MAXSIZE", -1)));
2272 parameters.insert(Util::ParamMap::value_type(
"MAXFREQ", Util::Param(
"MAXFREQ", 1.0e9)));
2273 parameters.insert(Util::ParamMap::value_type(
"SAVEREDSYS", Util::Param(
"SAVEREDSYS",
false)));
2274 parameters.insert(Util::ParamMap::value_type(
"COMPORIGTF", Util::Param(
"COMPORIGTF",
false)));
2275 parameters.insert(Util::ParamMap::value_type(
"COMPREDTF", Util::Param(
"COMPREDTF",
false)));
2276 parameters.insert(Util::ParamMap::value_type(
"COMPTYPE", Util::Param(
"COMPTYPE",
"DEC")));
2277 parameters.insert(Util::ParamMap::value_type(
"COMPNP", Util::Param(
"COMPNP", 10)));
2278 parameters.insert(Util::ParamMap::value_type(
"COMPFSTART", Util::Param(
"COMPFSTART", 1.0)));
2279 parameters.insert(Util::ParamMap::value_type(
"COMPFSTOP", Util::Param(
"COMPFSTOP", 1.0)));
2280 parameters.insert(Util::ParamMap::value_type(
"EXPPOINT", Util::Param(
"EXPPOINT", 0.0)));
2281 parameters.insert(Util::ParamMap::value_type(
"SCALETYPE", Util::Param(
"SCALETYPE", 0)));
2282 parameters.insert(Util::ParamMap::value_type(
"SCALEFACTOR", Util::Param(
"SCALEFACTOR", 1)));
2283 parameters.insert(Util::ParamMap::value_type(
"SCALEFACTOR1", Util::Param(
"SCALEFACTOR1", 0.01)));
2284 parameters.insert(Util::ParamMap::value_type(
"SPARSIFICATIONTYPE", Util::Param(
"SPARSIFICATIONTYPE", 0)));
2285 parameters.insert(Util::ParamMap::value_type(
"SUBCKTS", Util::Param(
"SUBCKTS",
"VECTOR")));
2301 factory_block.
optionsManager_.addCommandParser(
".MOR", extractMORData);
2303 factory_block.
optionsManager_.addCommandProcessor(
"MOR",
new MORAnalysisReg(*factory));
2305 factory_block.
optionsManager_.addOptionsProcessor(
"MOR_OPTS", IO::createRegistrationOptions(*factory, &MORFactory::setMOROptsOptionBlock));
RCP< Linear::MultiVector > RPtr_
Linear::Vector * lastSolutionPtr
IO::PkgOptionsMgr & optionsManager_
unsigned int successStepsThisParameter_
unsigned int successfulStepsTaken_
Number of consecutive successful time-integration steps.
Topo::Topology & topology_
int newtonConvergenceStatus
virtual bool setInitialGuess(Linear::Vector *solVectorPtr)
Linear::Vector * lastLeadDeltaVPtr
Teuchos::SerialDenseMatrix< int, double > redB_
RCP< Epetra_LinearProblem > origProblem_
RCP< Epetra_LinearProblem > blockRedProblem_
RCP< Linear::BlockVector > ref_redBPtr_
virtual bool getBMatrixEntriesforMOR(std::vector< int > &bMatEntriesVec, std::vector< int > &bMatPosEntriesVec)
bool evalOrigTransferFunction()
void evaluateStepError(const Loader::Loader &loader, const TIAParams &tia_params)
Pure virtual class to augment a linear system.
RCP< Linear::MultiVector > BPtr_
Linear::System & linearSystem_
RCP< Linear::BlockMatrix > sCpG_REFMatrixPtr_
virtual bool loadDAEVectors(Linear::Vector *nextSolVectorPtr, Linear::Vector *currSolVectorPtr, Linear::Vector *lastSolVectorPtr, Linear::Vector *nextStaVectorPtr, Linear::Vector *currStaVectorPtr, Linear::Vector *lastStaVectorPtr, Linear::Vector *StaDerivVectorPtr, Linear::Vector *nextStoVectorPtr, Linear::Vector *currStoVectorPtr, Linear::Vector *lastStoVectorPtr, Linear::Vector *stoLeadCurrQVectorPtr, Linear::Vector *nextLeadFVectorPtr, Linear::Vector *currLeadFVectorPtr, Linear::Vector *lastLeadFVectorPtr, Linear::Vector *nextLeadQVectorPtr, Linear::Vector *nextJunctionVVectorPtr, Linear::Vector *currJunctionVVectorPtr, Linear::Vector *lastJunctionVVectorPtr, Linear::Vector *QVectorPtr, Linear::Vector *FVectorPtr, Linear::Vector *BVectorPtr, Linear::Vector *dFdxdVpVectorPtr, Linear::Vector *dQdxdVpVectorPtr)
MOR(AnalysisManager &analysis_manager, Nonlinear::Manager &nonlinear_manager, Loader::Loader &loader, Topo::Topology &topology, IO::InitialConditionsManager &initial_conditions_manager)
unsigned int stepNumber
Time-integration step number counter.
Nonlinear::Manager & nonlinearManager_
bool registerMORFactory(FactoryBlock &factory_block)
std::vector< std::string > portList_
Linear::Vector * currStorePtr
Linear::Vector * lastStatePtr
bool createOrigLinearSystem_()
Teuchos::SerialDenseMatrix< int, std::complex< double > > origH_
RCP< Linear::BlockMatrix > sCpG_ref_redMatrixPtr_
void gatherStepStatistics(StatCounts &stats, Nonlinear::NonLinearSolver &nonlinear_solver, int newton_convergence_status)
Topo::Topology & topology_
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
RCP< Epetra_LinearProblem > blockProblem_
void setValue(ParameterBase &entity, const Descriptor &descriptor, const T &value)
Sets the value of the parameter.
RCP< Amesos_BaseSolver > blockSolver_
Teuchos::SerialDenseMatrix< int, double > sCpG_redMatrix_
bool updateOrigLinearSystemFreq_()
Linear::Vector * nextLeadDeltaVPtr
Linear::Vector * currStatePtr
bool setAnalysisParams(const Util::OptionBlock ¶msBlock)
unsigned int failedStepsAttempted_
Total number of failed time-integration steps.
void obtainCorrectorDeriv()
Parallel::Manager * getPDSManager() const
Topo::Topology & topology_
TimeIntg::StepErrorControl & getStepErrorControl()
bool getBeginningIntegrationFlag() const
const std::string & getNetlistFilename() const
void computeDividedDifferences()
NonLinearSolver & getNonlinearSolver()
RCP< Linear::BlockVector > REFXPtr_
AnalysisManager & analysisManager_
Util::OptionBlock morAnalysisOptionBlock_
Linear::Vector * daeQVectorPtr
void setConstantHistory()
Teuchos::SerialDenseMatrix< int, double > sCpG_tmpMatrix_
RCP< Amesos_BaseSolver > origSolver_
Linear::Vector * lastLeadCurrentPtr
Teuchos::SerialDenseMatrix< int, double > redG_
virtual bool startTimeStep(bool beginIntegrationFlag, double nextTimeStep, double nextTime, int currentOrder)
void setErrorWtVector(const TIAParams &tia_params)
virtual bool isPDESystem() const
std::vector< int > bMatEntriesVec_
RCP< Amesos_BaseSolver > blockRedSolver_
Linear::Vector * daeFVectorPtr
Linear::Vector * currLeadCurrentQPtr
Nonlinear::Manager & nonlinearManager_
void info(const std::string &msg)
Teuchos::SerialDenseMatrix< int, std::complex< double > > redH_
Teuchos::SerialDenseMatrix< int, double > redL_
The FactoryBlock contains parameters needed by the analysis creation functions.
Linear::System & linearSystem_
IO::InitialConditionsManager & initialConditionsManager_
bool processSuccessfulStep()
IO::InitialConditionsManager & initialConditionsManager_
Linear::Matrix * dFdxMatrixPtr
bool sparsifyRedSystem_()
bool solveRedLinearSystem_()
virtual bool updateSources()
Linear::Vector * nextStatePtr
AnalysisManager & analysisManager_
Linear::Vector * dFdxdVpVectorPtr
RCP< Linear::Matrix > redCPtr_
virtual bool loadDAEMatrices(Linear::Vector *tmpSolVectorPtr, Linear::Vector *tmpStaVectorPtr, Linear::Vector *tmpStaDerivVectorPtr, Linear::Vector *tmpStoVectorPtr, Linear::Matrix *tmpdQdxMatrixPtr, Linear::Matrix *tmpdFdxMatrixPtr)
virtual bool updateState(Linear::Vector *nextSolVectorPtr, Linear::Vector *currSolVectorPtr, Linear::Vector *lastSolVectorPtr, Linear::Vector *nextStaVectorPtr, Linear::Vector *currStaVectorPtr, Linear::Vector *lastStaVectorPtr, Linear::Vector *nextStoVectorPtr, Linear::Vector *currStoVectorPtr, Linear::Vector *lastStoVectorPtr)
Teuchos::SerialDenseMatrix< int, double > redC_
Linear::Vector * currLeadDeltaVPtr
RCP< Epetra_Map > redMapPtr_
AnalysisManager & analysisManager_
void setDoubleDCOPEnabled(bool enable)
int numberSuccessiveFailures
int morSparsificationType_
RCP< Linear::BlockVector > REFBPtr_
RCP< Linear::BlockVector > ref_redXPtr_
Nonlinear::Manager & nonlinearManager_
bool createRedLinearSystem_()
Linear::Vector * nextSolutionPtr
Linear::Vector * nextStorePtr
std::vector< int > bMatPosEntriesVec_
void addAnalysisFactory(FactoryBlock &factory_block, Util::Factory< AnalysisBase, void > *factory)
Linear::Vector * dQdxdVpVectorPtr
virtual bool doProcessFailedStep()
bool setMOROptions(const Util::OptionBlock &option_block)
Linear::Vector * currLeadCurrentPtr
Linear::Vector * lastStorePtr
void setInputOPFlag(bool initial_conditions_loaded)
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
void obtainPredictorDeriv()
RCP< Linear::Matrix > redGPtr_
std::list< int > morEvalFailures_
RCP< Linear::Matrix > GPtr_
Linear::Vector * currSolutionPtr
std::vector< std::string > subcircuitNames_
bool firstDoubleDCOPStep() const
TimeIntg::DataStore * getDataStore()
unsigned int baseIntegrationMethod_
Current time-integration method flag.
bool evalRedTransferFunction()
Parallel::Machine getComm()
Linear::Vector * nextStoreLeadCurrQPtr
Util::OptionBlock morOptsOptionBlock_
RCP< Linear::Matrix > sCpG_MatrixPtr_
Linear::Vector * nextStateDerivPtr
bool updateCurrentFreq_(int stepNumber)
Teuchos::SerialDenseMatrix< int, double > ref_redB_
RCP< Linear::Matrix > CPtr_
Linear::Matrix * dQdxMatrixPtr
TimeIntg::TIAParams tiaParams_
Linear::Vector * flagSolutionPtr
IO::InitialConditionsManager & initialConditionsManager_
OutputMgrAdapter & outputManagerAdapter_
Linear::Vector * daeBVectorPtr
bool solveOrigLinearSystem_()
virtual bool doHandlePredictor()
bool updateRedLinearSystemFreq_()
Linear::Vector * nextLeadCurrentPtr