38 #include <Xyce_config.h>
47 #include <N_IO_ActiveOutput.h>
48 #include <N_IO_CmdParse.h>
49 #include <N_IO_PkgOptionsMgr.h>
50 #include <N_LAS_BlockSystemHelpers.h>
51 #include <N_LAS_BlockVector.h>
52 #include <N_LAS_HBBuilder.h>
53 #include <N_LAS_HBPrecondFactory.h>
54 #include <N_LAS_PrecondFactory.h>
55 #include <N_LAS_System.h>
59 #include <N_PDS_ParMap.h>
64 #include <N_UTL_APFT.h>
65 #include <N_UTL_Diagnostic.h>
66 #include <N_UTL_ExtendedString.h>
67 #include <N_UTL_FFTInterface.hpp>
68 #include <N_UTL_FeatureTest.h>
69 #include <N_UTL_MachDepParams.h>
70 #include <N_UTL_Math.h>
71 #include <N_UTL_Timer.h>
73 #include <Teuchos_BLAS.hpp>
74 #include <Teuchos_Utils.hpp>
75 #include <Teuchos_ScalarTraits.hpp>
76 #include <Teuchos_SerialDenseMatrix.hpp>
77 #include <Teuchos_SerialDenseVector.hpp>
78 #include <Teuchos_SerialDenseHelpers.hpp>
79 #include <Teuchos_SerialDenseSolver.hpp>
81 #include <N_PDS_Comm.h>
85 using Teuchos::rcp_dynamic_cast;
100 Linear::System & linear_system,
103 Linear::Builder & builder,
104 Topo::Topology & topology)
108 loader_(analysis_manager.getLoader()),
127 startUpPeriodsGiven_(false),
134 intmodMaxGiven_(false),
135 fastTimeDisc_(N_MPDE_Discretization::Backward),
136 fastTimeDiscOrder_(1),
137 resetForStepCalledBefore_(false)
185 std::vector<std::string> srcVec;
275 Xyce::lout() <<
" ***** Running HB initial conditions....\n" << std::endl;
278 Xyce::dout() << std::endl
279 << section_divider << std::endl
280 <<
" HB::init()" << std::endl;
289 Xyce::dout() <<
"HB period =" <<
period_ << std::endl;
300 for(
int i = 0; i <
size_; ++i )
321 Xyce::dout() <<
"HB::init(): Generate Maps\n";
324 rcp(
pdsMgrPtr_->getParallelMap( Parallel::SOLUTION_OVERLAP_GND ),
false) );
338 std::vector<std::string> srcVec;
362 ftInterface_ = Teuchos::rcp(
new N_UTL_FFTInterface<std::vector<double> >(
size_ ) );
367 ftInterface_ = Teuchos::rcp(
new N_UTL_FFTInterface<std::vector<double> >(
size_ ) );
384 for (
int i=0 ; i<
size_ ; ++i)
386 if (DEBUG_HB && isActive(Diag::HB_FAST_TIMES))
387 Xyce::dout() <<
"HB::init(): Loading initial condition data from time: fastTimes_["
400 if (DEBUG_HB && isActive(Diag::HB_PRINT_VECTORS))
402 Xyce::dout() <<
"HB Initial Condition Solution!\n";
404 Xyce::dout() <<
"HB Initial Condition State Vector!\n";
406 Xyce::dout() <<
"HB Initial Condition Store Vector!\n";
484 Xyce::dout() << section_divider << std::endl;
501 bool returnValue =
true;
503 Xyce::lout() <<
" ***** Beginning full HB simulation....\n" << std::endl;
507 Xyce::dout() << std::endl
508 << section_divider << std::endl
509 <<
" HB::loopProcess" << std::endl;
522 returnValue = dc_sweep.
doRun();
528 Xyce::lout() <<
" ***** Harmonic Balance Computation Summary *****" << std::endl;
538 dout() << section_divider << std::endl;
639 const Util::OptionBlock & option_block)
641 for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
643 if ((*it).uTag() ==
"FREQ")
645 freqs_ = (*it).getValue<std::vector<double> >();
652 Report::UserError() <<
"Frequency of oscillation " <<
freqs_[0] <<
" is less than or equal to zero, invalid .HB specification";
655 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
657 dout() << section_divider << std::endl
658 <<
"HB transient simulation parameters"
661 <<
"HB frequency = " <<
freqs_[0] << std::endl
680 for(Util::ParamList::const_iterator iterPL = OB.begin(), endPL = OB.end(); iterPL != endPL; ++iterPL )
682 ExtendedString tag = iterPL->tag();
685 if (std::string(tag,0,7) ==
"NUMFREQ" )
688 size_ = iterPL->getImmutableValue<
int>() *2 + 1;
692 else if ( tag ==
"STARTUPPERIODS" )
699 else if( tag ==
"SAVEICDATA" )
703 else if( tag ==
"TEST" )
705 test_ =
static_cast<bool> (iterPL->getImmutableValue<
int>());
707 else if (tag ==
"DEBUGLEVEL" )
709 setHBDebugLevel(iterPL->getImmutableValue<
int>());
711 else if ( tag ==
"TAHB" )
713 taHB_ = iterPL->getImmutableValue<
int>();
715 else if ( tag ==
"VOLTLIM" )
717 voltLimFlag_ =
static_cast<bool> (iterPL->getImmutableValue<
int>());
719 else if ( tag ==
"INTMODMAX" )
721 intmodMax_ = iterPL->getImmutableValue<
int>();
726 else if ( tag ==
"METHOD" )
728 ExtendedString stringVal ( iterPL->stringValue() );
734 UserWarning(*
this) <<
"Unrecognized HBINT option " << tag;
740 Report::UserError() <<
"The size of numFreq does not match the number of tones in .hb!";
748 for (
int i=0; i <
freqs_.size(); i++ )
788 precFactory_ =
new Linear::HBPrecondFactory(OB, builder);
817 Linear::Vector & solnVecPtr,
818 std::vector<double> & timePoints,
819 std::vector<double> & freqPoints,
820 RCP<Linear::BlockVector> & timeDomainSolnVec,
821 RCP<Linear::BlockVector> & freqDomainSolnVecReal,
822 RCP<Linear::BlockVector> & freqDomainSolnVecImag,
823 RCP<Linear::BlockVector> & timeDomainStoreVec,
824 RCP<Linear::BlockVector> & freqDomainStoreVecReal,
825 RCP<Linear::BlockVector> & freqDomainStoreVecImag,
826 RCP<Linear::BlockVector> & timeDomainLeadCurrentVec,
827 RCP<Linear::BlockVector> & freqDomainLeadCurrentVecReal,
828 RCP<Linear::BlockVector> & freqDomainLeadCurrentVecImaginary,
829 RCP<Linear::BlockVector> & timeDomainJunctionVoltageVec,
830 RCP<Linear::BlockVector> & freqDomainJunctionVoltageVecReal,
831 RCP<Linear::BlockVector> & freqDomainJunctionVoltageVecImaginary
834 Linear::BlockVector & blockSolVecPtr =
dynamic_cast<Linear::BlockVector &
>(solnVecPtr);
838 timeDomainStoreVec =
hbBuilderPtr_->createTimeDomainStoreBlockVector();
839 timeDomainLeadCurrentVec =
hbBuilderPtr_->createTimeDomainLeadCurrentBlockVector();
840 timeDomainJunctionVoltageVec =
hbBuilderPtr_->createTimeDomainLeadCurrentBlockVector();
841 if (bStoreVecFreqPtr_->blockCount() > 0 )
846 if (bLeadCurrentVecFreqPtr_->blockCount() > 0 )
852 timeDomainSolnVec =
hbBuilderPtr_->createTimeDomainBlockVector();
853 int blockCount = timeDomainSolnVec->blockCount();
854 int N = timeDomainSolnVec->block(0).globalLength();
855 timePoints.resize(
size_);
861 Teuchos::RCP<N_PDS_ParMap> baseMap = Teuchos::rcp_const_cast<N_PDS_ParMap>(
hbBuilderPtr_->getBaseSolutionMap() );
862 Teuchos::RCP<N_PDS_ParMap> globalMap = Linear::createBlockParMap( blockCount, *baseMap );
863 freqDomainSolnVecReal = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalMap, baseMap ) );
864 freqDomainSolnVecImag = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalMap, baseMap ) );
869 for (
int j=0; j<N; j++)
875 int lid = baseMap->globalToLocalIndex( j );
876 Linear::Vector& solBlock = blockSolVecPtr.block( j );
878 Linear::Vector& realVecRef = freqDomainSolnVecReal->block((blockCount-1)/2);
879 Linear::Vector& imagVecRef = freqDomainSolnVecImag->block((blockCount-1)/2);
883 realVecRef[lid] = solBlock[0];
884 imagVecRef[lid] = solBlock[1];
887 for (
int i=1; i <= (blockCount-1)/2; ++i)
889 Linear::Vector& realVecRef_neg = freqDomainSolnVecReal->block((blockCount-1)/2 - i);
890 Linear::Vector& imagVecRef_neg = freqDomainSolnVecImag->block((blockCount-1)/2 - i);
891 Linear::Vector& realVecRef_pos = freqDomainSolnVecReal->block((blockCount-1)/2 + i);
892 Linear::Vector& imagVecRef_pos = freqDomainSolnVecImag->block((blockCount-1)/2 + i);
896 realVecRef_neg[lid] = solBlock[ 2*(blockCount-i) ];
897 imagVecRef_neg[lid] = solBlock[ 2*(blockCount-i) + 1 ];
898 realVecRef_pos[lid] = solBlock[ 2*i ];
899 imagVecRef_pos[lid] = solBlock[ 2*i+1 ];
905 Teuchos::RCP<N_PDS_ParMap> baseStoreMap = Teuchos::rcp_const_cast<N_PDS_ParMap>(
hbBuilderPtr_->getBaseStoreMap() );
906 Teuchos::RCP<N_PDS_ParMap> globalStoreMap = Linear::createBlockParMap( blockCount, *baseStoreMap );
907 freqDomainStoreVecReal = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
908 freqDomainStoreVecImag = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
910 N = timeDomainStoreVec->block(0).globalLength();
912 for (
int j=0; j<N; j++)
917 int lid = baseStoreMap->globalToLocalIndex( j );
918 Linear::Vector& storeBlock = bStoreVecFreqPtr_->block( j );
920 Linear::Vector& realVecRef = freqDomainStoreVecReal->block((blockCount-1)/2);
921 Linear::Vector& imagVecRef = freqDomainStoreVecImag->block((blockCount-1)/2);
925 realVecRef[lid] = storeBlock[0];
926 imagVecRef[lid] = storeBlock[1];
929 for (
int i=1; i <= (blockCount-1)/2; ++i)
931 Linear::Vector& realVecRef_neg = freqDomainStoreVecReal->block((blockCount-1)/2 - i);
932 Linear::Vector& imagVecRef_neg = freqDomainStoreVecImag->block((blockCount-1)/2 - i);
933 Linear::Vector& realVecRef_pos = freqDomainStoreVecReal->block((blockCount-1)/2 + i);
934 Linear::Vector& imagVecRef_pos = freqDomainStoreVecImag->block((blockCount-1)/2 + i);
938 realVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) ];
939 imagVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) + 1 ];
940 realVecRef_pos[lid] = storeBlock[ 2*i ];
941 imagVecRef_pos[lid] = storeBlock[ 2*i+1 ];
947 Teuchos::RCP<N_PDS_ParMap> baseLeadCurrentMap = Teuchos::rcp_const_cast<N_PDS_ParMap>(
hbBuilderPtr_->getBaseLeadCurrentMap() );
948 Teuchos::RCP<N_PDS_ParMap> globalLeadCurrentMap = Linear::createBlockParMap( blockCount, *baseLeadCurrentMap );
949 freqDomainLeadCurrentVecReal = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
950 freqDomainLeadCurrentVecImaginary = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
951 freqDomainJunctionVoltageVecReal = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
952 freqDomainJunctionVoltageVecImaginary = Teuchos::rcp(
new Linear::BlockVector( blockCount, globalLeadCurrentMap, baseLeadCurrentMap ) );
954 N = timeDomainLeadCurrentVec->block(0).globalLength();
955 for (
int j=0; j<N; j++)
960 int lid = baseLeadCurrentMap->globalToLocalIndex( j );
961 Linear::Vector& leadCurrentBlock = bLeadCurrentVecFreqPtr_->block( j );
963 Linear::Vector& realVecRef1 = freqDomainLeadCurrentVecReal->block((blockCount-1)/2);
964 Linear::Vector& imagVecRef1 = freqDomainLeadCurrentVecImaginary->block((blockCount-1)/2);
965 Linear::Vector& realVecRef2 = freqDomainJunctionVoltageVecReal->block((blockCount-1)/2);
966 Linear::Vector& imagVecRef2 = freqDomainJunctionVoltageVecImaginary->block((blockCount-1)/2);
970 realVecRef1[lid] = leadCurrentBlock[0];
971 imagVecRef1[lid] = leadCurrentBlock[1];
972 realVecRef2[lid] = leadCurrentBlock[0];
973 imagVecRef2[lid] = leadCurrentBlock[1];
976 for (
int i=1; i <= (blockCount-1)/2; ++i)
978 Linear::Vector& realVecRef_neg1 = freqDomainLeadCurrentVecReal->block((blockCount-1)/2 - i);
979 Linear::Vector& imagVecRef_neg1 = freqDomainLeadCurrentVecImaginary->block((blockCount-1)/2 - i);
980 Linear::Vector& realVecRef_pos2 = freqDomainLeadCurrentVecReal->block((blockCount-1)/2 + i);
981 Linear::Vector& imagVecRef_pos2 = freqDomainLeadCurrentVecImaginary->block((blockCount-1)/2 + i);
983 Linear::Vector& realVecRef_neg3 = freqDomainJunctionVoltageVecReal->block((blockCount-1)/2 - i);
984 Linear::Vector& imagVecRef_neg3 = freqDomainJunctionVoltageVecImaginary->block((blockCount-1)/2 - i);
985 Linear::Vector& realVecRef_pos4 = freqDomainJunctionVoltageVecReal->block((blockCount-1)/2 + i);
986 Linear::Vector& imagVecRef_pos4 = freqDomainJunctionVoltageVecImaginary->block((blockCount-1)/2 + i);
990 realVecRef_neg1[lid] = leadCurrentBlock[ 2*(blockCount-i) ];
991 imagVecRef_neg1[lid] = leadCurrentBlock[ 2*(blockCount-i) + 1 ];
992 realVecRef_pos2[lid] = leadCurrentBlock[ 2*i ];
993 imagVecRef_pos2[lid] = leadCurrentBlock[ 2*i+1 ];
994 realVecRef_neg3[lid] = leadCurrentBlock[ 2*(blockCount-i) ];
995 imagVecRef_neg3[lid] = leadCurrentBlock[ 2*(blockCount-i) + 1 ];
996 realVecRef_pos4[lid] = leadCurrentBlock[ 2*i ];
997 imagVecRef_pos4[lid] = leadCurrentBlock[ 2*i+1 ];
1004 freqDomainSolnVecReal->printPetraObject(std::cout);
1005 freqDomainSolnVecImag->printPetraObject(std::cout);
1007 Xyce::dout() <<
"HB Store Vector FD" << std::endl;
1009 freqDomainStoreVecReal->printPetraObject(std::cout);
1010 freqDomainStoreVecImag->printPetraObject(std::cout);
1053 maxValue = (
size_ - 1)/2;
1060 int numAnalysisFreqs =
freqs_.size();
1064 k.resize(numAnalysisFreqs);
1073 int numTotalFrequencies;
1075 int numExtraFreqs = 0;
1085 for (
int i=1; i < numAnalysisFreqs; i++)
1097 numTotalFrequencies *= numFreqs_[i];
1102 for (
int i=0; i< numAnalysisFreqs; i++)
1104 Xyce::dout() <<
"HB index " << i << std::endl;
1105 Xyce::dout() <<
"HB numPosFreqs =" <<
numPosFreqs[i] << std::endl;
1106 Xyce::dout() <<
"HB k =" << k[i] << std::endl;
1108 Xyce::dout() <<
"HB numTotalFrequencies =" << numTotalFrequencies<< std::endl;
1109 Xyce::dout() <<
"HB numextrafreqs =" << numExtraFreqs << std::endl;
1112 int numIndex = numTotalFrequencies;
1114 Teuchos::SerialDenseMatrix<int,double> indexMatrix(numAnalysisFreqs, numTotalFrequencies);
1118 Xyce::dout() <<
"HB intmodMax =" <<
intmodMax_ << std::endl;
1123 int idxMod, idxValues;
1126 std::vector<int> goodIndex;
1127 for (
int i=0; i < numIndex; i++)
1132 for (
int j= (numAnalysisFreqs - 1); j >= 0; j-- )
1134 idxMod = nextIndex%k[j];
1135 idxValues = (nextIndex - idxMod)/k[j];
1137 indexMatrix (j, i) =
static_cast<double>(idxValues - (
numFreqs_[j] - 1)/2 );
1139 sumIndex += abs(idxValues - (
numFreqs_[j] - 1)/2 );
1144 goodIndex.push_back(i);
1147 int diaindexSize = goodIndex.size();
1149 Teuchos::SerialDenseMatrix<int,double> diaindexMatrix( numAnalysisFreqs, (diaindexSize + numExtraFreqs) );
1150 diaindexMatrix.putScalar(0.0);
1152 for (
int i=0; i < diaindexSize; i++)
1154 for (
int j= (numAnalysisFreqs - 1); j >= 0; j-- )
1155 diaindexMatrix (j, i) = indexMatrix (j, goodIndex[i]);
1160 for (
int i=0; i< diaindexSize; i++)
1162 dout() <<
"good index i = " << i << goodIndex[i] << std::endl;
1164 dout() <<
" checking diamond indexMatrix" << std::endl;
1165 diaindexMatrix.print(dout());
1167 dout() <<
" checking indexMatrix" << std::endl;
1168 indexMatrix.print(dout());
1172 int extraIndexPos = diaindexSize;
1173 for (
int i=0; i < numAnalysisFreqs ; i++)
1180 diaindexMatrix (i, extraIndexPos + j ) =
static_cast<double>(
intmodMax_ + j + 1 );
1189 dout() <<
" checking diamond indexMatrix after axis" << std::endl;
1190 diaindexMatrix.print(dout());
1195 std::vector<double> posfreqPoints_;
1197 int posindexSize = (diaindexSize - 1)/2;
1198 posfreqPoints_.resize(posindexSize + numExtraFreqs);
1200 Teuchos::SerialDenseMatrix<int,double> currindexMatrix( Teuchos::View, diaindexMatrix, numAnalysisFreqs, (posindexSize + numExtraFreqs), 0, posindexSize+1 );
1201 Teuchos::SerialDenseVector<int,double> currfreqPoints( Teuchos::View, &posfreqPoints_[0], (posindexSize + numExtraFreqs ) );
1203 Teuchos::SerialDenseVector<int,double> hbFreqs( Teuchos::View, &
freqs_[0], numAnalysisFreqs);
1205 currfreqPoints.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, currindexMatrix, hbFreqs, 0.0 );
1210 dout() <<
"checking positive frequencies" << std::endl;
1211 currindexMatrix.print(dout());
1212 hbFreqs.print(dout());
1213 currfreqPoints.print(dout());
1216 for (
int i=0; i < posindexSize; i++)
1218 if (posfreqPoints_[i] < 0.0)
1219 posfreqPoints_[i] = fabs( posfreqPoints_[i]);
1222 std::sort(posfreqPoints_.begin(), posfreqPoints_.end() );
1227 for (
int i=0; i< posfreqPoints_.size(); i++)
1228 dout() <<
"pos frequency point " << posfreqPoints_[i] << std::endl;
1231 posfreqPoints_.erase(std::unique(posfreqPoints_.begin(), posfreqPoints_.end() ), posfreqPoints_.end() );
1234 if (abs( posfreqPoints_[0]) < 2.0*Util::MachineDependentParams::MachinePrecision() )
1235 posfreqPoints_.erase( posfreqPoints_.begin());
1237 size_ = ( posfreqPoints_.size() ) *2 + 1;
1241 for (
int i=0; i<posfreqPoints_.size(); i++)
1243 dout() <<
"pos frequency point after " << posfreqPoints_[i] << std::endl;
1246 Xyce::dout() <<
"HB size =" <<
size_ << std::endl;
1252 for( i = 0; i <
size_; ++i )
1254 if (i < (size_-1)/2)
1255 freqPoints_[i] = - posfreqPoints_[ (size_-1)/2 - i - 1 ];
1256 else if (i > (size_-1)/2)
1257 freqPoints_[i] = posfreqPoints_[ i - (size_-1)/2 - 1 ];
1266 dout() <<
" frequency point " <<
freqPoints_[i] << std::endl;
1288 int posFreq = (
size_-1)/2;
1289 int oversampleRate = 5;
1291 int periodSampleMultiplier = 1;
1293 Teuchos::BLAS<int,double> blas;
1294 std::vector<double> testPoints(oversampleRate*
size_);
1296 int myPID =
pdsMgrPtr_->getPDSComm()->procID();
1301 for (
int i=0; i<oversampleRate*
size_; ++i)
1303 testPoints[i] = periodSampleMultiplier*
period_*((Teuchos::ScalarTraits<double>::random()+1)/2);
1306 Teuchos::SerialDenseMatrix<int,double> testMatrix(size_,oversampleRate*size_);
1309 for (
int j=0; j<oversampleRate*
size_; ++j)
1311 testMatrix(0,j) = 1.0;
1314 for (
int i=1; i<=posFreq; i++)
1317 for (
int j=0; j<oversampleRate*
size_; j++)
1319 testMatrix(2*i-1,j) = cos(2*
M_PI*
freqPoints_[posFreq+i]*testPoints[j]);
1325 std::vector<double> weightVector(oversampleRate*size_);
1326 for (
int i=0; i<
size_; ++i)
1330 double maxValue = 0.0;
1331 for (
int j=i; j<oversampleRate*
size_; ++j)
1333 Teuchos::SerialDenseMatrix<int,double> tempVector( Teuchos::View, testMatrix, size_, 1, 0, j );
1334 weightVector[j] = tempVector.normFrobenius();
1336 if (weightVector[j] > maxValue)
1339 maxValue = weightVector[j];
1345 std::swap( testPoints[i], testPoints[maxIndex] );
1346 Teuchos::SerialDenseVector<int,double> newSwapVector2 = Teuchos::getCol<int,double>( Teuchos::Copy, testMatrix, maxIndex );
1347 Teuchos::SerialDenseVector<int,double> newSwapVector = Teuchos::getCol<int,double>( Teuchos::View, testMatrix, i );
1348 Teuchos::setCol<int,double>( newSwapVector, maxIndex, testMatrix );
1349 Teuchos::setCol<int,double>( newSwapVector2, i, testMatrix );
1355 Teuchos::SerialDenseMatrix<int,double> currTestMatrix( Teuchos::View, testMatrix, size_, oversampleRate*size_-(i+1), 0, i+1 );
1356 Teuchos::SerialDenseVector<int,double> currWeightVector( Teuchos::View, &weightVector[i+1], oversampleRate*size_-(i+1) );
1358 currWeightVector.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, currTestMatrix, newSwapVector, 0.0 );
1365 for (
int j=i+1; j<oversampleRate*
size_; ++j)
1367 Teuchos::SerialDenseMatrix<int,double> currVector( Teuchos::View, testMatrix, size_, 1, 0, j );
1368 blas.AXPY( size_, -(currWeightVector[j-(i+1)]/(maxValue*maxValue) ), newSwapVector.values(), 1, currVector.values(), 1 );
1377 std::sort( testPoints.begin(), testPoints.begin()+
size_ );
1379 for (
int i=0; i<
size_; ++i)
1402 int posFreq = (
size_-1)/2;
1407 for (
int i=0; i<
size_; ++i)
1413 for (
int i=0; i<
size_; i++)
1415 for (
int j=1; j<=posFreq; j++)
1425 Teuchos::SerialDenseSolver<int,double> ftSolver;
1426 ftSolver.setMatrix( Teuchos::rcp( &
dftMatrix_,
false ) );
1442 bool success =
true;
1453 bool retTol1 =
runTol(tia_params);
1454 success = success && retTol1;
1467 if (!startupPeriodsSuccess)
1469 Report::UserError() <<
"Failed to calculate the startup periods";
1473 success = success && startupPeriodsSuccess;
1483 Report::UserError() <<
"Initial HB Transient failed";
1486 success = success && icSuccess;
1510 Xyce::lout() <<
" ***** Computing tolerance parameters for HB IC calculation....\n" << std::endl;
1518 analysisManager_.pushActiveAnalysis(&
transient);
1520 transient.setAnalysisParams(Util::OptionBlock());
1522 transient.resetForHB();
1524 analysisManager_.getStepErrorControl().
resetAll(tia_params);
1526 analysisManager_.setNextOutputTime(0.0);
1529 if (!
transient.
run())
1531 Report::UserError() <<
"Calculation of tolerance parameters failed for relErrorTol = " << tia_params.
relErrorTol;
1536 numPoints =
transient.getStepNumber();
1541 analysisManager_.popActiveAnalysis();
1542 currentAnalysisObject_ = 0;
1549 Report::UserWarning() <<
"Tolerance parameters refined, re-running with relErrorTol = " << tia_params.
relErrorTol/10;
1565 analysisManager_.pushActiveAnalysis(&
transient);
1567 transient.setTIAParams(tia_params);
1568 transient.setAnalysisParams(Util::OptionBlock());
1569 transient.resetForHB();
1571 analysisManager_.getStepErrorControl().
resetAll(tia_params);
1573 analysisManager_.setNextOutputTime(0.0);
1576 if (!
transient.
run())
1578 Report::UserError() <<
"Calculation of tolerance parameters failed for relErrorTol = " << tia_params.
relErrorTol;
1583 numPoints =
transient.getStepNumber();
1588 analysisManager_.popActiveAnalysis();
1589 currentAnalysisObject_ = 0;
1610 bool returnValue =
true;
1612 Xyce::lout() <<
" ***** Computing " <<
startUpPeriods_ <<
" start up periods for HB IC calculation...." << std::endl;
1615 Xyce::dout() <<
"HB::runStartupPeriods_(): Advancing time through "
1618 <<
" finalTime = " << tia_params.
finalTime << std::endl;
1633 x.add(Xyce::IO::PrintType::HB_STARTUP,
ANP_MODE_HB);
1639 analysisManager_.pushActiveAnalysis(&
transient);
1641 transient.setTIAParams(tia_params);
1642 transient.setAnalysisParams(Util::OptionBlock());
1643 transient.resetForHB();
1645 analysisManager_.getStepErrorControl().
resetAll(tia_params);
1647 analysisManager_.setNextOutputTime(0.0);
1650 returnValue =
transient.
run();
1658 analysisManager_.getOutputManagerAdapter().finishOutput();
1660 analysisManager_.popActiveAnalysis();
1691 bool returnValue =
true;
1693 Xyce::lout() <<
" ***** Running transient to compute HB initial condition....\n" << std::endl;
1705 Xyce::dout() <<
"HB::runTransientIC_(): Advancing time from"
1707 <<
" finalTime = " << tia_params.
finalTime << std::endl;
1724 transient.setSaveTimeSteps(
true);
1726 analysisManager_.pushActiveAnalysis(&
transient);
1728 transient.setAnalysisParams(Util::OptionBlock());
1729 transient.resetForHB();
1731 analysisManager_.getStepErrorControl().
resetAll(tia_params);
1733 analysisManager_.setNextOutputTime(0.0);
1736 returnValue =
transient.
run();
1744 analysisManager_.popActiveAnalysis();
1767 double initial_time)
1769 Xyce::lout() <<
" ***** Interpolating transient solution for IC calculation....\n" << std::endl;
1772 int numPoints = dsPtr->
timeSteps.size();
1775 Xyce::dout() <<
"HB::interpolateIC_(): Initial transient run produced " << numPoints <<
" points." << std::endl;
1777 std::vector<int> goodIndicies;
1778 for(
int i = 0; i <
size_; ++i )
1783 bool sortedTimesFlag =
true;
1786 sortedTimesFlag =
false;
1788 int breakpoints = 0;
1791 if (sortedTimesFlag)
1793 goodIndicies.push_back(startIndex);
1794 int GoodTimePointIndex = startIndex + 1;
1796 for(
int i=startIndex; i < numPoints - 1 ; i++ )
1805 if (DEBUG_HB && isActive(Diag::HB_TIMESTEP))
1807 Xyce::dout() <<
"\t\t timeStep[ " << i <<
" ] = " << dsPtr->
timeSteps[i];
1810 Xyce::dout() <<
" Breakpoint";
1812 Xyce::dout() << std::endl;
1818 goodIndicies.push_back( i );
1819 GoodTimePointIndex = GoodTimePointIndex+1;
1825 double tmpTimePoints;
1827 for(
int i=0; i<
size_; i++ )
1834 for(
int j=0; (j< (numPoints - 1) && !found ); j++)
1836 if((dsPtr->
timeSteps[j] <= tmpTimePoints ) && ( tmpTimePoints < dsPtr->
timeSteps[j+1]))
1839 goodIndicies.push_back( j );
1846 for(
int i=0; i<
size_; i++ )
1848 int currentIndex = goodIndicies[i];
1853 Linear::Vector * secondStateVecPtr = dsPtr->
fastTimeStateVec[currentIndex+1];
1855 Linear::Vector * firstQVecPtr = dsPtr->
fastTimeQVec[currentIndex];
1856 Linear::Vector * secondQVecPtr = dsPtr->
fastTimeQVec[currentIndex+1];
1859 Linear::Vector * secondStoreVecPtr = dsPtr->
fastTimeStoreVec[currentIndex+1];
1863 RCP<Linear::Vector> InterpICSolVecPtr = rcp(
new Linear::Vector( *secondSolVecPtr ) );
1864 RCP<Linear::Vector> InterpICStateVecPtr = rcp(
new Linear::Vector( *secondStateVecPtr ) );
1865 RCP<Linear::Vector> InterpICQVecPtr = rcp(
new Linear::Vector( *secondQVecPtr ) );
1866 RCP<Linear::Vector> InterpICStoreVecPtr = rcp(
new Linear::Vector( *secondStoreVecPtr ) );
1868 InterpICSolVecPtr->putScalar(0.0);
1869 InterpICStateVecPtr->putScalar(0.0);
1870 InterpICQVecPtr->putScalar(0.0);
1871 InterpICStoreVecPtr->putScalar(0.0);
1873 InterpICSolVecPtr->linearCombo(-1.0, *firstSolVecPtr, 1.0, *secondSolVecPtr );
1874 InterpICSolVecPtr->linearCombo(1.0, *firstSolVecPtr, fraction , *InterpICSolVecPtr);
1876 InterpICStateVecPtr->linearCombo(-1.0, *firstStateVecPtr, 1.0, *secondStateVecPtr );
1877 InterpICStateVecPtr->linearCombo(1.0, *firstStateVecPtr, fraction , *InterpICStateVecPtr);
1879 InterpICQVecPtr->linearCombo(-1.0, *firstQVecPtr, 1.0, *secondQVecPtr );
1880 InterpICQVecPtr->linearCombo(1.0, *firstQVecPtr, fraction , *InterpICQVecPtr);
1882 InterpICStoreVecPtr->linearCombo(-1.0, *firstStoreVecPtr, 1.0, *secondStoreVecPtr );
1883 InterpICStoreVecPtr->linearCombo(1.0, *firstStoreVecPtr, fraction , *InterpICStoreVecPtr);
1911 class HBFactory :
public Factory<HB>
1941 Linear::System & linear_system,
1944 Linear::Builder & builder,
1945 Topo::Topology & topology)
1955 virtual ~HBFactory()
1999 void setHBAnalysisOptionBlock(
const Util::OptionBlock &option_block)
2019 void setHBIntOptionBlock(
const Util::OptionBlock &option_block)
2039 void setHBLinSolOptionBlock(
const Util::OptionBlock &option_block)
2059 void setLinSolOptionBlock(
const Util::OptionBlock &option_block)
2081 struct HBIntOptionsReg :
public IO::PkgOptionsReg
2084 HBFactory & factory )
2088 bool operator()(
const Util::OptionBlock &option_block)
2090 factory_.setHBIntOptionBlock(option_block);
2099 struct HBLinSolOptionsReg :
public IO::PkgOptionsReg
2102 HBFactory & factory )
2106 bool operator()(
const Util::OptionBlock &option_block)
2108 factory_.setHBLinSolOptionBlock(option_block);
2117 struct LinSolOptionsReg :
public IO::PkgOptionsReg
2120 HBFactory & factory )
2124 bool operator()(
const Util::OptionBlock &option_block)
2126 factory_.setLinSolOptionBlock(option_block);
2135 struct HBAnalysisReg :
public IO::PkgOptionsReg
2138 HBFactory & factory )
2142 bool operator()(
const Util::OptionBlock &option_block)
2144 factory_.setHBAnalysisOptionBlock(option_block);
2145 factory_.deviceManager_.setBlockAnalysisFlag(
true);
2160 const std::string & netlist_filename,
2161 IO::PkgOptionsMgr & options_manager,
2163 Linear::System & linear_system,
2166 Linear::Builder & builder,
2167 Topo::Topology & topology)
2169 HBFactory *factory =
new HBFactory(analysis_manager, linear_system, nonlinear_manager, device_manager, builder, topology);
2173 options_manager.submitRegistration(
"HB", netlist_filename,
new HBAnalysisReg(*factory));
2174 options_manager.submitRegistration(
"HBINT", netlist_filename,
new HBIntOptionsReg(*factory));
2175 options_manager.submitRegistration(
"LINSOL-HB", netlist_filename,
new HBLinSolOptionsReg(*factory));
2176 options_manager.submitRegistration(
"LINSOL", netlist_filename,
new LinSolOptionsReg(*factory));
IO::OutputMgr & getOutputManager()
void accumulateStatistics_(AnalysisBase &analysis)
std::vector< Linear::Vector * > fastTimeQVec
Util::OptionBlock saved_lsHBOB_
Linear::HBPrecondFactory * precFactory_
std::vector< double > timeSteps
Util::OptionBlock linSolOptionBlock_
AnalysisBase * currentAnalysisObject_
Teuchos::RCP< Linear::BlockVector > HBICQVectorPtr_
HB initial Q condition.
Teuchos::RCP< N_MPDE_Discretization > mpdeDiscPtr_
Linear::Builder & builder_
Teuchos::SerialDenseMatrix< int, double > dftMatrix_
std::vector< double > freqs_
Problem Size.
std::vector< bool > timeStepsBreakpointFlag
Teuchos::RCP< Linear::Vector > dcOpStateVecPtr_
std::vector< int > numFreqs_
void setNextOutputTime(double next_output_time)
HB(AnalysisManager &analysis_manager, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Device::DeviceMgr &device_manager, Linear::Builder &builder, Topo::Topology &topology)
bool printLoopInfo(int start, int finish)
bool startUpPeriodsGiven_
Pure virtual class to augment a linear system.
void registerDFTInterface(const Teuchos::RCP< N_UTL_DFTInterfaceDecl< std::vector< double > > > &dftInterface)
std::vector< double > freqPoints_
void setFastTimes(const std::vector< double > ×)
void setTIAParams(const TimeIntg::TIAParams &tia_params)
bool resetForStepAnalysis()
void pushActiveAnalysis(AnalysisBase *analysis)
bool isTransient_
Current analysis state flags.
bool setAnalysisParams(const Util::OptionBlock &option_block)
Linear::System & linearSystem_
Linear::Vector * currStorePtr
std::vector< double > iftOutData_
Teuchos::RCP< Linear::Vector > dcOpSolVecPtr_
bool isAnalysis(int analysis_type) const
Topo::Topology & topology_
double finalTime
End time for simulation.
std::vector< double > timeSteps_
AnalysisManager & analysisManager_
Util::OptionBlock hbIntOptionBlock_
virtual int getDoubleDCOPStep() const
std::vector< double > ftInData_
std::vector< Linear::Vector * > fastTimeStateVec
Teuchos::SerialDenseMatrix< int, double > idftMatrix_
N_PDS_Manager * pdsMgrPtr_
Util::ListenerAutoSubscribe< StepEvent > StepEventListener
std::vector< double > ftOutData_
Util::Timer & getXyceTranTimer()
void setAnalysisMode(AnalysisMode mode)
Linear::Vector * currStatePtr
Teuchos::RCP< Linear::HBBuilder > hbBuilderPtr_
HB loader, builder, system, and DFT.
Parallel::Manager * getPDSManager() const
TimeIntg::StepErrorControl & getStepErrorControl()
Device::DeviceMgr & deviceManager_
bool registerHBFactory(const std::string &netlist_filename, IO::PkgOptionsMgr &options_manager, AnalysisManager &analysis_manager, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Device::DeviceMgr &device_manager, Linear::Builder &builder, Topo::Topology &topology)
std::vector< Linear::Vector * > fastTimeSolutionVec
std::vector< Teuchos::RCP< Linear::Vector > > goodStateVec_
void permutedFFT(const Linear::BlockVector &xt, Linear::BlockVector *xf)
Linear::System * hbLinearSystem_
bool interpolateIC(double initial_time)
bool runStartupPeriods(const TimeIntg::TIAParams &tia_params)
bool setLinSol(const Util::OptionBlock &option_block)
void prepareHBOutput(Linear::Vector &solnVecPtr, std::vector< double > &timePoints, std::vector< double > &freqPoints, Teuchos::RCP< Linear::BlockVector > &timeDomainSolnVec, Teuchos::RCP< Linear::BlockVector > &freqDomainSolnVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainSolnVecImaginary, Teuchos::RCP< Linear::BlockVector > &timeDomainStoreVec, Teuchos::RCP< Linear::BlockVector > &freqDomainStoreVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainStoreVecImaginary, Teuchos::RCP< Linear::BlockVector > &timeDomainLeadCurrentVec, Teuchos::RCP< Linear::BlockVector > &freqDomainLeadCurrentVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainLeadCurrentVecImaginary, Teuchos::RCP< Linear::BlockVector > &timeDomainJunctionVoltageVec, Teuchos::RCP< Linear::BlockVector > &freqDomainJunctionVoltageVecReal, Teuchos::RCP< Linear::BlockVector > &freqDomainJunctionVoltageVecImaginary) const
void setMatrixFreeFlag(bool matrixFreeFlag)
std::vector< Teuchos::RCP< Linear::Vector > > goodStoreVec_
Linear::Vector * daeQVectorPtr
Teuchos::RCP< Linear::Vector > dcOpStoreVecPtr_
Device::DeviceMgr & deviceManager_
Teuchos::RCP< Linear::BlockVector > HBICVectorPtr_
bool setLinSolOptions(const Util::OptionBlock &option_block)
void resetAll(AnalysisMode mode)
Linear::Vector * deviceErrorWeightMask_
void setSaveTimeSteps(bool save_time_steps)
Teuchos::RCP< Linear::BlockVector > & getLeadCurrentVecFreqPtr()
bool initializeSolverSystem(const TimeIntg::TIAParams &tia_params, Loader::Loader &loader, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Device::DeviceMgr &device_manager)
Initializes the solver system.
bool doProcessFailedStep()
int getDoubleDCOPStep() const
bool resetForStepCalledBefore_
Teuchos::RCP< Linear::BlockVector > HBICStoreVectorPtr_
HB initial store condition.
std::vector< int > numPosFreqs
void setMPDEFlag(bool flagVal)
bool setLoader(Loader::Loader &loader_)
Nonlinear::AnalysisMode nonlinearAnalysisMode(Mode mode)
Returns the nonlinear analysis mode given the analysis mode.
void setHBFreqs(const std::vector< double > &freqs)
Teuchos::RCP< N_UTL_DFTInterfaceDecl< std::vector< double > > > dftInterface_
int startUpPeriods_
Periodicity Information.
void registerHBBuilder(Teuchos::RCP< Linear::HBBuilder > hbBuilderPtr)
bool runTol(TimeIntg::TIAParams &tia_params)
N_MPDE_Discretization::Type fastTimeDisc_
Teuchos::RCP< Linear::Vector > dcOpQVecPtr_
Teuchos::RCP< Linear::BlockVector > HBICVectorFreqPtr_
OutputMgrAdapter & getOutputManagerAdapter() const
Linear::Vector * nextStatePtr
std::vector< Linear::Vector * > fastTimeStoreVec
bool initializeAll(Linear::System &linear_system)
Loader::NonlinearEquationLoader & getNonlinearEquationLoader()
Util::OptionBlock saved_lsOB_
bool initializeAll(Analysis::AnalysisManager &analysis_manager, Loader::NonlinearEquationLoader &nonlinear_equation_loader, Linear::System &linear_system, TimeIntg::DataStore &data_store, Parallel::Manager ¶llel_manager, IO::InitialConditionsManager &initial_conditions_manager, IO::OutputMgr &output_manager, Topo::Topology &topology)
double pauseTime
Time step value at which to "pause" the simulation.
Teuchos::RCP< Linear::BlockVector > & getStoreVecFreqPtr()
std::vector< double > iftInData_
void addAnalysisFactory(Factory< void > *factory)
Nonlinear::Manager & nonlinearManager_
Loader::HBLoader * hbLoaderPtr_
Linear::Vector * nextSolutionPtr
void deRegisterFastSources(const std::vector< std::string > &sourceNames)
Linear::Builder & builder_
Topo::Topology & topology_
virtual bool getDoubleDCOPFlag() const
Linear::Vector * nextStorePtr
The analysis factory template defines an interface for analysis type testing and analysis creation...
double initialTime
Beginning time for the time integrator (StepErrorControl, integrators access from StepErrorControl) ...
Teuchos::RCP< Linear::BlockVector > HBICStateVectorPtr_
HB initial state condition.
IO::InitialConditionsManager & getInitialConditionsManager()
std::vector< double > goodTimePoints_
bool processSuccessfulDCOP()
void setVoltageLimiterFlag(bool flagVal)
Linear::System & linearSystem_
std::vector< Teuchos::RCP< Linear::Vector > > goodQVec_
bool doProcessSuccessfulStep()
bool setHBIntParams(const Util::OptionBlock &option_block)
bool runTransientIC(const TimeIntg::TIAParams &tia_params)
Teuchos::RCP< N_UTL_FFTInterface< std::vector< double > > > ftInterface_
Linear::Vector * currSolutionPtr
TimeIntg::DataStore * getDataStore()
bool doubleDCOPFlag_
true if doing a double-DCOP is possible.
std::vector< Teuchos::RCP< Linear::Vector > > goodSolutionVec_
bool setHBLinSol(const Util::OptionBlock &option_block, Linear::Builder &builder)
AnalysisManager & analysisManager_
Nonlinear::Manager & nonlinearManager_
void permutedIFT(const Linear::BlockVector &xf, Linear::BlockVector *xt)
std::vector< double > registerFastSources(Parallel::Machine comm, const std::vector< std::string > &sourceNames)
void setMatrixFreeFlag(bool matrixFreeFlag)
virtual bool getDCOPFlag() const =0
Util::OptionBlock timeIntegratorOptionBlock_
bool finalVerboseOutput()
bool registerPrecondFactory(const Linear::PrecondFactory *preconditioner_factory)
Util::OptionBlock hbLinSolOptionBlock_
void registerAppLoader(Teuchos::RCP< Loader > appLoaderPtr)
Util::OptionBlock hbAnalysisOptionBlock_
std::vector< double > fastTimes_
void notify(const StepEvent &event)
bool loadDeviceErrorWeightMask(Linear::Vector *deviceMask) const