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_PkgOptionsMgr.h>
62 #include <N_IO_CmdParse.h>
69 #include <N_PDS_Comm.h>
70 #include <N_PDS_ParMap.h>
71 #include <N_PDS_Serial.h>
72 #include <N_PDS_MPI.h>
79 #include <N_TOP_Topology.h>
81 #include <N_UTL_Diagnostic.h>
82 #include <N_UTL_ExtendedString.h>
83 #include <N_UTL_FeatureTest.h>
84 #include <N_UTL_Math.h>
85 #include <N_UTL_Timer.h>
87 #ifdef Xyce_PARALLEL_MPI
88 #include <N_PDS_ParComm.h>
91 #include <N_PDS_SerialComm.h>
96 #include <Epetra_CrsMatrix.h>
97 #include <Epetra_Operator.h>
98 #include <Epetra_CrsGraph.h>
99 #include <Epetra_MultiVector.h>
100 #include <Epetra_LinearProblem.h>
104 #include <BelosLinearProblem.hpp>
105 #include <BelosBlockGmresIter.hpp>
106 #include <BelosDGKSOrthoManager.hpp>
107 #include <BelosStatusTestMaxIters.hpp>
108 #include <BelosOutputManager.hpp>
109 #include <BelosEpetraAdapter.hpp>
112 #include <Teuchos_SerialDenseMatrix.hpp>
113 #include <Teuchos_ScalarTraits.hpp>
114 #include <Teuchos_LAPACK.hpp>
115 #include <Teuchos_BLAS.hpp>
131 Topo::Topology & topology)
133 comm_(analysis_manager.getPDSManager()->getPDSComm()->comm()),
135 loader_(analysis_manager.getLoader()),
138 outputManagerAdapter_(analysis_manager.getOutputManagerAdapter()),
141 morSaveRedSys_(false),
142 morCompOrigTF_(false),
143 morCompRedTF_(false),
152 morScaleFactor_(1.0),
154 morScaleFactor1_(1.0),
155 morSparsificationType_(0),
159 isSingleFreq_(false),
187 for (Util::ParamList::const_iterator it = paramsBlock.begin(), end = paramsBlock.end(); it != end; ++it)
189 if ((*it).uTag() ==
"PORTLIST")
191 portList_ = (*it).getValue<std::vector<std::string> >();
195 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
198 << section_divider << std::endl
199 <<
" MOR simulation parameters" << std::endl
200 <<
" size = " <<
ROMsize_ << std::endl;
216 Util::ParamList::const_iterator it_tpL;
217 Util::ParamList::const_iterator first = OB.begin();
218 Util::ParamList::const_iterator last = OB.end();
220 for (it_tpL = first; it_tpL != last; ++it_tpL)
222 if (it_tpL->uTag()==
"METHOD")
224 ExtendedString stringVal ( it_tpL->stringValue() );
228 else if (it_tpL->uTag()==
"SAVEREDSYS")
230 morSaveRedSys_ =
static_cast<bool>(it_tpL->getImmutableValue<
int>());
232 else if (it_tpL->uTag()==
"COMPORIGTF")
234 morCompOrigTF_ =
static_cast<bool>(it_tpL->getImmutableValue<
int>());
236 else if (it_tpL->uTag()==
"COMPREDTF")
238 morCompRedTF_ =
static_cast<bool>(it_tpL->getImmutableValue<
int>());
240 else if (it_tpL->uTag()==
"COMPTYPE")
242 ExtendedString stringVal ( it_tpL->stringValue() );
246 else if (it_tpL->uTag()==
"COMPNP")
248 morCompNP_ = it_tpL->getImmutableValue<
int>();
250 else if (it_tpL->uTag()==
"COMPFSTART")
254 else if (it_tpL->uTag()==
"AUTOSIZE")
256 morAutoSize_ =
static_cast<bool>(it_tpL->getImmutableValue<
int>());
258 else if (it_tpL->uTag()==
"MAXSIZE")
262 else if (it_tpL->uTag()==
"MAXFREQ")
264 morMaxFreq_ = it_tpL->getImmutableValue<
double>();
266 else if (it_tpL->uTag()==
"SIZE")
268 ROMsize_ = it_tpL->getImmutableValue<
int>();
270 else if (it_tpL->uTag()==
"COMPFSTOP")
274 else if (it_tpL->uTag()==
"EXPPOINT")
278 else if (it_tpL->uTag()==
"SCALETYPE")
282 else if (it_tpL->uTag()==
"SCALEFACTOR")
286 else if (it_tpL->uTag()==
"SCALEFACTOR1")
290 else if (it_tpL->uTag()==
"SPARSIFICATIONTYPE")
294 else if (std::string(it_tpL->uTag(),0,7) ==
"SUBCKTS" )
296 ExtendedString stringVal ( it_tpL->stringValue() );
302 Report::UserError0() << it_tpL->uTag() <<
" is not a recognized model-order reduction option.";
361 bool bsuccess =
true;
407 Report::UserError() <<
"Solving for DC operating point failed, cannot continue MOR analysis";
412 std::vector<int> tempVec;
416 int hsize = tempVec.size();
422 Report::UserError() <<
"Number of specified ports in .MOR line is inconsistent with number of voltage sources";
428 std::vector<int> gidPosEntries( hsize );
429 for (
int i=0; i<hsize; ++i)
431 std::vector<int> svGIDList1, dummyList;
436 gidPosEntries[i] = svGIDList1.front();
442 RCP<N_PDS_ParMap> BaseMap = rcp(pdsManager.getParallelMap( Parallel::SOLUTION ),
false);
446 for (
int i=0; i<hsize; ++i)
448 int gid = gidPosEntries[i];
450 for (
int j=0; j<hsize; ++j)
461 Report::UserError() <<
"Did not find voltage source corresponding to port";
546 int length=1, numEntries=0;
547 std::vector<int> colIndices(length);
548 std::vector<double> coeffs(length);
554 if ( numEntries != 1 )
556 Report::UserError0() <<
"Supposed voltage source row has too many entries, cannot continue MOR analysis";
561 GPtr_->getLocalRowCopy(
bMatEntriesVec_[i], length, numEntries, &coeffs[0], &colIndices[0]);
564 if ( coeffs[0] > 0.0 )
567 GPtr_->putLocalRow(
bMatEntriesVec_[i], length, &coeffs[0], &colIndices[0]);
592 bool bsuccess =
true;
597 N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap( Parallel::SOLUTION );
613 RPtr_->putScalar( 0.0 );
630 Amesos amesosFactory;
635 int linearStatus =
origSolver_->SymbolicFactorization();
636 if (linearStatus != 0)
638 Xyce::dout() <<
"Amesos symbolic factorization exited with error: " << linearStatus << std::endl;
643 linearStatus =
origSolver_->NumericFactorization();
644 if (linearStatus != 0)
646 Xyce::dout() <<
"Amesos numeric factorization exited with error: " << linearStatus << std::endl;
652 if (linearStatus != 0)
654 Xyce::dout() <<
"Amesos solve exited with error: " << linearStatus << std::endl;
662 RCP<Epetra_Operator> COpPtr_ = rcp( &
CPtr_->epetraObj(), false );
663 RCP<Linear::AmesosGenOp> AOp = rcp(
new Linear::AmesosGenOp(
origSolver_, COpPtr_ ) );
683 Report::UserError() <<
"Automatic Sizing is OFF. Please specify the ROM dimension";
691 UserWarning(*
this) <<
"Requested reduced-order model dimension is larger than original system dimension, resizing to original system dimension";
702 redB_.shape(k, numPorts_);
703 redL_.shape(k, numPorts_);
712 typedef Epetra_MultiVector MV;
713 typedef Epetra_Operator OP;
714 typedef Belos::MultiVecTraits<ST,MV> MVT;
717 Belos::OutputManager<ST> printer;
720 Belos::StatusTestMaxIters<ST, MV, OP> maxIterTest( kblock );
723 Belos::DGKSOrthoManager<ST, MV, OP> orthoMgr;
727 Linear::MultiVector temp( BaseMap, numPorts_ );
728 Belos::LinearProblem<ST, MV, OP > problem( AOp,
729 rcp( &temp.epetraObj(), false ),
730 rcp( &
RPtr_->epetraObj(), false ));
731 problem.setProblem();
734 Teuchos::ParameterList params;
735 params.set(
"Num Blocks", kblock);
736 params.set(
"Block Size", numPorts_ );
739 Belos::BlockGmresIter<ST, MV, OP> krylovIter( rcp( &problem,
false ),
740 rcp( &printer,
false ),
741 rcp( &maxIterTest,
false ),
742 rcp( &orthoMgr,
false ),
746 RCP<Teuchos::SerialDenseMatrix<int,ST> > z
747 = rcp(
new Teuchos::SerialDenseMatrix<int,ST>( numPorts_, numPorts_ ) );
750 RCP<MV> V = rcp(
new Epetra_MultiVector(
RPtr_->epetraObj() ) );
751 orthoMgr.normalize( *V, z );
754 Belos::GmresIterationState<ST,MV> initState;
757 initState.curDim = 0;
758 krylovIter.initializeGmres(initState);
762 krylovIter.iterate();
764 catch (
const Belos::GmresIterationOrthoFailure &e) {
767 catch (
const std::exception &e) {
772 Belos::GmresIterationState<ST,MV> newState = krylovIter.getState();
779 RCP<MV>
W = rcp(
new Epetra_MultiVector( V->Map(), k ) );
781 int low = 1, high = k;
785 double abstol = 1e-6;
786 double reltol = 1e-3;
790 while ((high - low) > 0 )
792 mid = (low + high)/2;
794 std::vector<int> indices(mid);
797 redG_.shape(mid, mid);
798 redC_.shape(mid, mid);
799 redB_.shape(mid, numPorts_);
800 redL_.shape(mid, numPorts_);
802 for (
int i=0; i<mid; ++i) { indices[i] = i; }
804 V = rcp(
new Epetra_MultiVector( View, *newState.V, &indices[0], mid) );
809 Linear::MultiVector xyceV( &*V,
false );
810 Linear::MultiVector temp2( BaseMap, mid);
812 Linear::MultiVector xyceW( &*W,
false );
814 GPtr_->matvec(
false, xyceV, temp2 );
817 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redG_ );
820 CPtr_->matvec(
false, xyceV, temp2 );
822 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redC_ );
826 MVT::MvTransMv( 1.0, xyceW.epetraObj(),
BPtr_->epetraObj(),
redB_ );
828 MVT::MvTransMv( 1.0, xyceV.epetraObj(),
BPtr_->epetraObj(),
redL_ );
836 origH_.shape(numPorts_, numPorts_);
837 redH_.shape(numPorts_, numPorts_);
843 Teuchos::SerialDenseMatrix<int, double> H_diff, totaltol, errOverTol;
845 totaltol.shape(numPorts_, numPorts_);
846 H_diff.shape(numPorts_, numPorts_);
849 errOverTol.shape(numPorts_, numPorts_);
854 totaltol(i,j) = reltol*abs(
origH_(i,j)) + abstol;
858 errOverTol(i, j) = H_diff(i,j)/totaltol(i,j);
862 double totalErrOverTol = errOverTol.normFrobenius()/
numPorts_;
865 if( totalErrOverTol < 1)
879 UserWarning(*
this) <<
"Requested reduced-order model dimension is larger than original system dimension, resizing to original system dimension";
883 kblock = (int)(
ROMsize_ / numPorts_);
891 redB_.shape(k, numPorts_);
892 redL_.shape(k, numPorts_);
895 std::vector<int> indices(k);
896 for (
int i=0; i<k; ++i) { indices[i] = i; }
898 V = rcp(
new Epetra_MultiVector( View, *newState.V, &indices[0], k) );
907 Linear::MultiVector xyceV( &*V,
false );
908 Linear::MultiVector temp2( BaseMap, k );
911 GPtr_->matvec(
false, xyceV, temp2 );
913 MVT::MvTransMv( 1.0, xyceV.epetraObj(), temp2.epetraObj(),
redG_ );
917 CPtr_->matvec(
false, xyceV, temp2 );
919 MVT::MvTransMv( 1.0, xyceV.epetraObj(), temp2.epetraObj(),
redC_ );
923 MVT::MvTransMv( 1.0, xyceV.epetraObj(),
BPtr_->epetraObj(),
redB_ );
934 Teuchos::SerialDenseMatrix<int,ST> Xhatscale( k, 1 );
938 if ( scaleType == 1 )
940 for (
int i=0; i<k; ++i)
951 if ( scaleType == 2 || scaleType == 3 || scaleType ==4)
953 Epetra_MultiVector Xmag( V->Map(), 1 );
955 if ( scaleType == 2 )
961 MVT::MvTransMv( 1.0, *V, Xmag, Xhatscale );
964 for (
int i=0; i<k; ++i)
967 if ( scaleType == 2 )
979 if ( scaleType == 3 )
982 if ( scaleType == 4 )
984 if ( fabs(Xhatscale( i, 0 )) > 1.0 )
1001 Teuchos::SerialDenseMatrix<int,ST> D(k,k);
1002 if ( scaleType != 0 )
1004 RCP<MV> Vtemp = rcp(
new Epetra_MultiVector( V->Map(), k ) );
1006 for (
int i=0; i<k; ++i)
1008 if (Xhatscale( i, 0 ) != 0.0)
1009 D(i,i) = 1.0/Xhatscale( i, 0 );
1013 Xyce::dout() <<
" the scaling matrix " << std::endl;
1017 MVT::MvTimesMatAddMv( 1.0, *V, D, 0.0, *Vtemp );
1030 Linear::MultiVector xyceV( &*V,
false );
1031 Linear::MultiVector xyceW( &*W,
false );
1032 Linear::MultiVector temp2( BaseMap, k );
1037 GPtr_->matvec(
false, xyceV, temp2 );
1039 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redG_ );
1043 CPtr_->matvec(
false, xyceV, temp2 );
1045 MVT::MvTransMv( 1.0, xyceW.epetraObj(), temp2.epetraObj(),
redC_ );
1048 MVT::MvTransMv( 1.0, xyceW.epetraObj(),
BPtr_->epetraObj(),
redB_ );
1050 MVT::MvTransMv( 1.0, xyceV.epetraObj(),
BPtr_->epetraObj(),
redL_ );
1054 if ( scaleType <= 1 )
1063 Report::UserError0() <<
"MOR options sparsificationType=1 can only be used with scaletype=1, other scale types have not been supported for sparsification";
1082 Report::UserError0() <<
"Belos is necessary to compute a reduced-order model, please recompile Xyce with Belos enabled";
1085 #endif // Xyce_BELOS
1100 bool bsuccess =
true;
1104 int currentStep = 0;
1110 bool stepAttemptStatus;
1112 while (currentStep < finalStep)
1124 if (stepAttemptStatus)
1148 bool bsuccess =
true;
1152 int currentStep = 0;
1159 bool stepAttemptStatus;
1161 while (currentStep < finalStep)
1172 if (stepAttemptStatus)
1195 bool bsuccess =
true;
1199 N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION);
1200 N_PDS_ParMap &oBaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION_OVERLAP_GND);
1201 Epetra_CrsGraph &BaseFullGraph = *pdsManager.getMatrixGraph(Parallel::JACOBIAN);
1205 std::vector<RCP<N_PDS_ParMap> > blockMaps = Linear::createBlockParMaps(numBlocks, BaseMap, oBaseMap);
1207 std::vector<std::vector<int> > blockPattern(2);
1208 blockPattern[0].resize(2);
1209 blockPattern[0][0] = 0; blockPattern[0][1] = 1;
1210 blockPattern[1].resize(2);
1211 blockPattern[1][0] = 0; blockPattern[1][1] = 1;
1213 int offset = Linear::generateOffset( BaseMap );
1214 RCP<Epetra_CrsGraph> blockGraph = Linear::createBlockGraph( offset, blockPattern, *blockMaps[0], BaseFullGraph);
1216 sCpG_REFMatrixPtr_ = rcp (
new Linear::BlockMatrix( numBlocks, offset, blockPattern, *blockGraph, BaseFullGraph) );
1234 Amesos amesosFactory;
1237 REFBPtr_ = rcp (
new Linear::BlockVector ( numBlocks, blockMaps[0], rcp(&BaseMap,
false) ) );
1238 REFXPtr_ = rcp (
new Linear::BlockVector ( numBlocks, blockMaps[0], rcp(&BaseMap,
false) ) );
1245 int linearStatus =
blockSolver_->SymbolicFactorization();
1247 if (linearStatus != 0)
1249 Xyce::dout() <<
"Amesos symbolic factorization exited with error: " << linearStatus;
1273 int k =
redG_.numRows();
1282 Teuchos::SerialDenseMatrix<int, double> subMtx( Teuchos::View,
sCpG_tmpMatrix_, k, k, 0, 0 );
1283 subMtx.assign(
redC_ );
1284 subMtx.scale( -
s0_ );
1288 Teuchos::SerialDenseMatrix<int, double> subMtx2( Teuchos::View,
sCpG_tmpMatrix_, k, k, k, k );
1289 subMtx2.assign(
redC_ );
1290 subMtx2.scale( -
s0_ );
1300 N_PDS_ParMap redPDSMap(
redMapPtr_.get(), *pdsManager.getPDSComm() );
1302 RCP<N_PDS_ParMap> redBlockMapPtr = Linear::createBlockParMap(numBlocks, redPDSMap);
1304 std::vector<std::vector<int> > blockPattern(2);
1305 blockPattern[0].resize(2);
1306 blockPattern[0][0] = 0; blockPattern[0][1] = 1;
1307 blockPattern[1].resize(2);
1308 blockPattern[1][0] = 0; blockPattern[1][1] = 1;
1310 int offset= Linear::generateOffset( redPDSMap );
1311 RCP<Epetra_CrsGraph> blockGraph = Linear::createBlockGraph( offset, blockPattern, *redBlockMapPtr, (
redCPtr_->epetraObj()).Graph() );
1316 sCpG_ref_redMatrixPtr_->put( 0.0 );
1321 sCpG_ref_redMatrixPtr_->block( 0, 0 ).add(*
redCPtr_);
1322 sCpG_ref_redMatrixPtr_->block( 0, 0 ).scale(-
s0_);
1323 sCpG_ref_redMatrixPtr_->block( 1, 1 ).add(*
redCPtr_);
1324 sCpG_ref_redMatrixPtr_->block( 1, 1 ).scale(-
s0_);
1327 sCpG_ref_redMatrixPtr_->block( 0, 0 ).add(*
redGPtr_);
1328 sCpG_ref_redMatrixPtr_->block( 1, 1 ).add(*
redGPtr_);
1331 Amesos amesosFactory;
1334 ref_redBPtr_ = rcp (
new Linear::BlockVector ( numBlocks, redBlockMapPtr, rcp(&redPDSMap,
false) ) );
1335 ref_redXPtr_ = rcp (
new Linear::BlockVector ( numBlocks, redBlockMapPtr, rcp(&redPDSMap,
false) ) );
1338 blockRedProblem_ = rcp(
new Epetra_LinearProblem(&sCpG_ref_redMatrixPtr_->epetraObj(),
1345 if (linearStatus != 0)
1347 Xyce::dout() <<
"Amesos symbolic factorization exited with error: " << linearStatus;
1404 int k =
redG_.numRows();
1410 Teuchos::SerialDenseMatrix<int, double> subMtx( Teuchos::View,
sCpG_redMatrix_, k, k, 0, k );
1411 subMtx.assign(
redC_ );
1412 subMtx.scale( -omega );
1414 Teuchos::SerialDenseMatrix<int, double> subMtx2( Teuchos::View,
sCpG_redMatrix_, k, k, k, 0 );
1415 subMtx2.assign(
redC_ );
1416 subMtx2.scale( omega );
1434 bool bsuccess =
true;
1437 int linearStatus =
blockSolver_->NumericFactorization();
1439 if (linearStatus != 0)
1441 Xyce::dout() <<
"Amesos numeric factorization exited with error: " << linearStatus;
1452 if (linearStatus != 0)
1454 Xyce::dout() <<
"Amesos solve exited with error: " << linearStatus;
1482 bool bsuccess =
true;
1489 if (linearStatus != 0)
1491 Xyce::dout() <<
"Amesos numeric factorization exited with error: " << linearStatus;
1498 Linear::MultiVector redBmv( &tmp_redB,
false ), redLmv( &tmp_redL,
false );
1505 (
ref_redBPtr_->block( 0 )) = *(redBmv.getVectorView( j ));
1508 if (linearStatus != 0)
1510 Xyce::dout() <<
"Amesos solve exited with error: " << linearStatus;
1518 double realPart = ( redLmv.getVectorView( i ) )->dotProduct(
ref_redXPtr_->block( 0 ) );
1519 double imagPart = ( redLmv.getVectorView( i ) )->dotProduct(
ref_redXPtr_->block( 1 ) );
1521 redH_(i,j) = std::complex<double>(realPart, imagPart);
1527 int k =
redG_.numRows();
1528 Teuchos::LAPACK<int, double> lapack;
1531 Teuchos::SerialDenseMatrix<int, double> tmpRedB( Teuchos::View,
ref_redB_,
redB_.numRows(),
redB_.numCols(), 0, 0 );
1532 tmpRedB.assign(
redB_ );
1541 Xyce::dout() <<
"LAPACK::GETRF: LU factorization failed with error: " << info << std::endl;
1546 const char trans =
'N';
1551 Xyce::dout() <<
"LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1558 tmpRedReal.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0,
redB_, tmpRedB, 0.0 );
1561 Teuchos::SerialDenseMatrix<int, double> tmpRedB2( Teuchos::View,
ref_redB_,
redB_.numRows(),
redB_.numCols(), k, 0 );
1562 tmpRedImag.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0,
redB_, tmpRedB2, 0.0 );
1569 redH_(i,j) = std::complex<double>(tmpRedReal(i,j), tmpRedImag(i,j));
1587 bool bsuccess =
true;
1589 int k =
redB_.numRows();
1592 Teuchos::SerialDenseMatrix<int, double> R(
redB_);
1593 Teuchos::SerialDenseMatrix<int, double> A(
redC_);
1596 Teuchos::LAPACK<int, double> lapack;
1597 Teuchos::SerialDenseMatrix<int, double> tmp_Ghat(
redG_ );
1600 std::vector<int> ipiv( tmp_Ghat.numRows() );
1601 lapack.GETRF( tmp_Ghat.numRows(), tmp_Ghat.numCols(), tmp_Ghat.values(),
1602 tmp_Ghat.stride(), &ipiv[0], &
info );
1605 Xyce::dout() <<
"LAPACK::GETRF: LU factorization of Ghat failed with error: " << info << std::endl;
1610 const char norm =
'1';
1611 double condGhat = 0.0;
1612 std::vector<double> condWork( 4*k );
1613 std::vector<int> condIWork( k );
1614 lapack.GECON( norm, tmp_Ghat.numRows(), tmp_Ghat.values(), tmp_Ghat.stride(), tmp_Ghat.normOne(), &condGhat, &condWork[0], &condIWork[0], &
info );
1618 Xyce::dout() <<
"LAPACK::GECON: Computing condition estimate of Ghat failed with error: " << info << std::endl;
1623 const char trans =
'N';
1624 lapack.GETRS( trans, tmp_Ghat.numRows(), A.numCols(), tmp_Ghat.values(),
1625 tmp_Ghat.stride(), &ipiv[0], A.values(), A.stride(), &
info );
1628 Xyce::dout() <<
"LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1635 lapack.GETRS( trans, tmp_Ghat.numRows(), R.numCols(), tmp_Ghat.values(),
1636 tmp_Ghat.stride(), &ipiv[0], R.values(), R.stride(), &
info );
1639 Xyce::dout() <<
"LAPACK::GETRS: LU solve failed with error: " << info << std::endl;
1652 std::vector<double> work( lwork );
1653 std::vector<double> revals( k );
1654 std::vector<double> ievals( k );
1655 Teuchos::SerialDenseMatrix<int, double> Q(k, k);
1660 std::vector<double> beta( k );
1661 Teuchos::SerialDenseMatrix<int, double> tmpB( k, k );
1662 for (
int i=0; i<k; i++)
1664 lapack.GGEV(
'N',
'V', k, A.values(), A.stride(), tmpB.values(), tmpB.stride(),
1665 &revals[0], &ievals[0], &beta[0], &vl[0], ldvl, Q.values(), Q.stride(),
1666 &work[0], lwork, &
info );
1669 Xyce::dout() <<
"LAPACK::GGEV: Computing eigenvectors and values of A = inv(Ghat)*Chat failed with error: " << info << std::endl;
1675 Teuchos::BLAS<int, double> blas;
1676 std::vector<int> rowIndex( k );
1680 if ( ievals[i] != 0.0 )
1686 double norm_r = blas.NRM2( k, Q[i], 1 );
1687 double norm_i = blas.NRM2( k, Q[i+1], 1 );
1688 double norm = lapack.LAPY2( norm_r, norm_i );
1691 for (
int j=0; j<k; j++)
1703 double norm = blas.NRM2( k, Q[i], 1 );
1706 for (
int j=0; j<k; j++)
1722 Teuchos::SerialDenseMatrix<int, std::complex<double> > V(k, k);
1723 for (
int i=0; i<k; i++)
1725 if (rowIndex[i] == 1)
1727 for (
int j=0; j<k; j++)
1730 V(j,i) = std::complex<double>( Q(j,i), Q(j,i+1) );
1731 V(j,i+1) = std::complex<double>( Q(j,i), -Q(j,i+1) );
1737 for (
int j=0; j<k; j++)
1739 V(j,i) = std::complex<double>( Q(j,i), 0.0 );
1745 Teuchos::LAPACK<int, std::complex<double> > lapack_complex;
1746 lapack_complex.GETRF( V.numRows(), V.numCols(), V.values(), V.stride(), &ipiv[0], &
info );
1749 Xyce::dout() <<
"LAPACK::GETRF: LU factorization of eigenvectors failed with error: " << info << std::endl;
1755 std::vector<std::complex<double> > condCWork( 2*k );
1756 lapack_complex.GECON( norm, V.numRows(), V.values(), V.stride(), V.normOne(), &condV, &condCWork[0], &condWork[0], &
info );
1760 Xyce::dout() <<
"LAPACK::GECON: Computing condition estimate of V failed with error: " << info << std::endl;
1765 std::vector<std::complex<double> > cwork( lwork );
1766 lapack_complex.GETRI( V.numRows(), V.values(), V.stride(), &ipiv[0], &cwork[0], lwork, &
info );
1769 Xyce::dout() <<
"LAPACK::GETRI: Computing inverse of V failed with error: " << info << std::endl;
1774 Teuchos::SerialDenseMatrix<int, std::complex<double> > tmpR( k,
numPorts_ );
1776 for (
int i=0; i<k; i++)
1777 tmpR(i,j) = std::complex<double>( R(i,j), 0.0 );
1780 Teuchos::SerialDenseMatrix<int, std::complex<double> > tmp_redB(k ,numPorts_);
1781 tmp_redB.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, tmpR, 0.0);
1785 Teuchos::SerialDenseMatrix<int, double> invV(k, k);
1786 for (
int i=0; i<k; i++)
1788 if (rowIndex[i] == 1)
1790 for (
int j=0; j<k; j++)
1792 invV(i, j) = V(i,j).real();
1793 invV(i+1, j) = V(i,j).imag();
1797 redB_(i, j) = tmp_redB(i, j).real();
1798 redB_(i+1, j) = tmp_redB(i, j).imag();
1804 for (
int j=0; j<k; j++)
1805 invV(i, j) = V(i,j).real();
1807 redB_(i, j) = tmp_redB(i, j).real();
1812 lapack.GETRF( invV.numRows(), invV.numCols(), invV.values(), invV.stride(), &ipiv[0], &
info );
1815 Xyce::dout() <<
"LAPACK::GETRF: LU factorization of inv(V) failed with error: " << info << std::endl;
1820 const char trans2 =
'T';
1821 lapack.GETRS( trans2, invV.numRows(),
redL_.numCols(), invV.values(),
1822 invV.stride(), &ipiv[0],
redL_.values(),
redL_.stride(), &
info );
1825 Xyce::dout() <<
"LAPACK::GETRS: LU solve for Lhat failed with error: " << info << std::endl;
1837 N_PDS_ParMap &BaseMap = *pdsManager.getParallelMap(Parallel::SOLUTION);
1838 if (BaseMap.petraMap()->Comm().MyPID() == 0)
1839 redMapPtr_ = Teuchos::rcp(
new Epetra_Map( k, k, 0, BaseMap.petraMap()->Comm() ) );
1841 redMapPtr_ = Teuchos::rcp(
new Epetra_Map( k, 0, 0, BaseMap.petraMap()->Comm() ) );
1843 Epetra_CrsMatrix* tmpRedG =
new Epetra_CrsMatrix( Copy, *
redMapPtr_, 1 );
1844 Epetra_CrsMatrix* tmpRedC =
new Epetra_CrsMatrix( Copy, *
redMapPtr_, 2 );
1847 if (BaseMap.petraMap()->Comm().MyPID() == 0)
1849 std::vector<int> index(2);
1850 std::vector<double> val(2);
1851 for (
int i=0; i<k; i++)
1854 index[0] = i; val[0] = 1.0;
1855 tmpRedG->InsertGlobalValues( i, 1, &val[0], &index[0] );
1858 if (rowIndex[i] == 1)
1860 index[0] = i; index[1] = i+1;
1861 val[0] = revals[i]; val[1] = -ievals[i];
1862 tmpRedC->InsertGlobalValues( i, 2, &val[0], &index[0] );
1864 else if (rowIndex[i] == -1)
1866 index[0] = i-1; index[1] = i;
1867 val[0] = ievals[i-1]; val[1] = revals[i-1];
1868 tmpRedC->InsertGlobalValues( i, 2, &val[0], &index[0] );
1872 index[0] = i; val[0] = revals[i];
1873 tmpRedC->InsertGlobalValues( i, 1, &val[0], &index[0] );
1878 tmpRedC->FillComplete();
1879 tmpRedG->FillComplete();
1882 redGPtr_ = rcp(
new Linear::Matrix( tmpRedG ) );
1883 redCPtr_ = rcp(
new Linear::Matrix( tmpRedC ) );
1902 bool bsuccess =
true;
1938 bool bsuccess =
true;
1958 bool bsuccess =
true;
1961 Xyce::dout() <<
"Calling MOR::doFinish() outputs!" << std::endl;
2015 Report::DevelFatal().in(
"MOR::updateCurrentFreq_") <<
"Unsupported STEP type";
2035 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2037 Xyce::dout() << std::endl << std::endl;
2038 Xyce::dout() << section_divider << std::endl;
2039 Xyce::dout() <<
"MOR::setupSweepParam_" << std::endl;
2051 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2053 Xyce::dout() <<
"fStep = " <<
fStep_ << std::endl;
2059 fCount = (int)(floor(fabs(log10(fStart) - log10(fStop)) * morCompNP_ + 1));
2060 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2062 Xyce::dout() <<
"stepMult_ = " <<
stepMult_ << std::endl;
2072 double ln2=log(2.0);
2073 fCount = floor(fabs(log(fStart) - log(fStop))/ln2 *
morCompNP_ + 1);
2074 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
2076 Xyce::dout() <<
"stepMult_ = " <<
stepMult_ << std::endl;
2081 Report::DevelFatal().in(
"MOR::setupSweepParam_") <<
"Unsupported type";
2102 class MORFactory :
public Factory<MOR>
2130 Linear::System & linear_system,
2132 Topo::Topology & topology)
2140 virtual ~MORFactory()
2182 void setMORAnalysisOptionBlock(
const Util::OptionBlock &option_block)
2202 void setMOROptsOptionBlock(
const Util::OptionBlock &option_block)
2219 struct MOROptsOptionsReg :
public IO::PkgOptionsReg
2222 MORFactory & factory )
2226 bool operator()(
const Util::OptionBlock &option_block)
2228 factory_.setMOROptsOptionBlock(option_block);
2237 struct MORAnalysisReg :
public IO::PkgOptionsReg
2240 MORFactory & factory )
2244 bool operator()(
const Util::OptionBlock &option_block)
2246 factory_.setMORAnalysisOptionBlock(option_block);
2261 const std::string & netlist_filename,
2262 IO::PkgOptionsMgr & options_manager,
2264 Linear::System & linear_system,
2266 Topo::Topology & topology)
2268 MORFactory *factory =
new MORFactory(analysis_manager, linear_system, nonlinear_manager, topology);
2272 options_manager.submitRegistration(
"MOR", netlist_filename,
new MORAnalysisReg(*factory));
2273 options_manager.submitRegistration(
"MOR_OPTS", netlist_filename,
new MOROptsOptionsReg(*factory));
RCP< Linear::MultiVector > RPtr_
Linear::Vector * lastSolutionPtr
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()
Pure virtual class to augment a linear system.
int doubleDCOPStep_
current step in the DCOP loop.
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)
unsigned int stepNumber
Time-integration step number counter.
Nonlinear::Manager & nonlinearManager_
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)
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
bool setupInitialConditions(Linear::Vector &solnVec, Linear::Vector &flagVec)
RCP< Epetra_LinearProblem > blockProblem_
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()
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
virtual bool startTimeStep()
Teuchos::SerialDenseMatrix< int, double > redG_
void setErrorWtVector(const TIAParams &tia_params)
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_
MOR(AnalysisManager &analysis_manager, Nonlinear::Manager &nonlinear_manager, Topo::Topology &topology)
bool processSuccessfulStep()
Linear::Matrix * dFdxMatrixPtr
bool sparsifyRedSystem_()
bool solveRedLinearSystem_()
virtual bool updateSources()
Linear::Vector * nextStatePtr
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_
int numberSuccessiveFailures
int morSparsificationType_
void outputMORTF(bool origSys, double freq, const Teuchos::SerialDenseMatrix< int, std::complex< double > > &H)
RCP< Linear::BlockVector > REFBPtr_
RCP< Linear::BlockVector > ref_redXPtr_
void addAnalysisFactory(Factory< void > *factory)
bool createRedLinearSystem_()
Linear::Vector * nextSolutionPtr
virtual bool getDoubleDCOPFlag() const
Linear::Vector * nextStorePtr
std::vector< int > bMatPosEntriesVec_
The analysis factory template defines an interface for analysis type testing and analysis creation...
Linear::Vector * dQdxdVpVectorPtr
bool setMOROptions(const Util::OptionBlock &OB)
virtual bool doProcessFailedStep()
Linear::Vector * currLeadCurrentPtr
Linear::Vector * lastStorePtr
void setInputOPFlag(bool initial_conditions_loaded)
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
bool firstDoubleDCOPStep()
void obtainPredictorDeriv()
RCP< Linear::Matrix > redGPtr_
std::list< int > morEvalFailures_
RCP< Linear::Matrix > GPtr_
Linear::Vector * currSolutionPtr
std::vector< std::string > subcircuitNames_
bool registerMORFactory(const std::string &netlist_filename, IO::PkgOptionsMgr &options_manager, AnalysisManager &analysis_manager, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Topo::Topology &topology)
TimeIntg::DataStore * getDataStore()
void evaluateStepError(const TIAParams &tia_params)
bool doubleDCOPFlag_
true if doing a double-DCOP is possible.
unsigned int baseIntegrationMethod_
Current time-integration method flag.
bool evalRedTransferFunction()
Linear::Vector * nextStoreLeadCurrQPtr
void outputROM(const Teuchos::SerialDenseMatrix< int, double > &Ghat, const Teuchos::SerialDenseMatrix< int, double > &Chat, const Teuchos::SerialDenseMatrix< int, double > &Bhat, const Teuchos::SerialDenseMatrix< int, double > &Lhat)
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
OutputMgrAdapter & outputManagerAdapter_
Linear::Vector * daeBVectorPtr
bool solveOrigLinearSystem_()
virtual bool doHandlePredictor()
bool updateRedLinearSystemFreq_()
Linear::Vector * nextLeadCurrentPtr