38 #include <Xyce_config.h>
45 #include <N_MPDE_Manager.h>
46 #include <N_MPDE_Discretization.h>
51 #include <N_LOA_HBLoader.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>
56 #include <N_LAS_BlockSystemHelpers.h>
60 #include <N_IO_OutputMgr.h>
62 #include <N_UTL_FFTInterface.hpp>
64 #include <Teuchos_Utils.hpp>
68 using Teuchos::rcp_dynamic_cast;
93 startUpPeriodsGiven_(false),
94 startUpPeriodsFinished_(false),
96 tiaParams_( anaManagerPtr->tiaParams ),
100 fastTimeDiscOrder_(1),
101 hbTotalNumberSuccessfulStepsTaken_(0),
102 hbTotalNumberFailedStepsAttempted_(0),
103 hbTotalNumberJacobiansEvaluated_(0),
104 hbTotalNumberIterationMatrixFactorizations_(0),
105 hbTotalNumberLinearSolves_(0),
106 hbTotalNumberFailedLinearSolves_(0),
107 hbTotalNumberLinearIters_(0),
108 hbTotalNumberResidualEvaluations_(0),
109 hbTotalNonlinearConvergenceFailures_(0),
110 hbTotalResidualLoadTime_(0.0),
111 hbTotalJacobianLoadTime_(0.0),
112 hbTotalLinearSolutionTime_(0.0),
113 resetForStepCalledBefore_(false)
255 bool bsuccess =
true;
257 bsuccess = bsuccess &
init();
264 bsuccess = bsuccess &
finish();
280 bool returnValue=
true;
282 Xyce::lout() <<
" ***** Running HB initial conditions....\n" << std::endl;
284 Xyce::dout() << std::endl
285 << section_divider << std::endl
286 <<
" HB::init()" << std::endl;
287 #endif // Xyce_DEBUG_HB
299 bool retTol1 =
runTol_(); returnValue = returnValue && retTol1;
306 if (!startupPeriodsSuccess)
308 std::string msg =
"HB::init(). Failed to calculate the startup periods.\n";
309 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
311 returnValue = returnValue && startupPeriodsSuccess;
316 std::string msg =
"HB::init(). Initial HB Transient failed \n";
317 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
319 returnValue = returnValue && icSuccess;
334 for(
int i = 0; i <=
size_; ++i )
345 for( i = 0; i <
size_; ++i )
361 Xyce::dout() <<
"HB::init(): Generate Maps\n";
362 #endif // Xyce_DEBUG_HB
364 rcp(
pdsMgrPtr_->getParallelMap(
"SOLUTION_OVERLAP_GND" ),
false) );
384 std::vector<std::string> srcVec;
398 for (
int i=0 ; i<
size_ ; ++i)
403 Xyce::dout() <<
"HB::init(): Loading initial condition data from time: fastTimes_["
406 #endif // Xyce_DEBUG_HB
420 Xyce::dout() <<
"HB Initial Condition Solution!\n";
422 Xyce::dout() <<
"HB Initial Condition State Vector!\n";
424 Xyce::dout() <<
"HB Initial Condition Store Vector!\n";
427 #endif // Xyce_DEBUG_HB
448 for(
int i = 0; i <
size_; ++i )
490 RCP<N_LAS_HBPrecondFactory> tmpPrecFactory
491 = rcp_dynamic_cast<N_LAS_HBPrecondFactory>(
precFactory_ );
513 Xyce::dout() << section_divider << std::endl;
514 #endif // Xyce_DEBUG_HB
529 bool returnValue =
true;
531 Xyce::lout() <<
" ***** Beginning full HB simulation....\n" << std::endl;
534 Xyce::dout() << std::endl
535 << section_divider << std::endl
536 <<
" HB::loopProcess" << std::endl;
537 #endif // Xyce_DEBUG_HB
552 Xyce::lout() <<
" ***** Harmonic Balance Computation Summary *****" << std::endl;
556 dout() << section_divider << std::endl;
557 #endif // Xyce_DEBUG_HB
682 std::vector<std::string> srcVec;
727 std::list<N_UTL_Param>::const_iterator iterPL = OB.getParams().begin();
728 std::list<N_UTL_Param>::const_iterator endPL = OB.getParams().end();
730 for( ; iterPL != endPL; ++iterPL )
732 ExtendedString tag = iterPL->tag();
735 if ( tag ==
"NUMFREQ" )
737 size_ = iterPL->getImmutableValue<
int>();
739 else if ( tag ==
"STARTUPPERIODS" )
746 else if( tag ==
"SAVEICDATA" )
750 else if( tag ==
"TEST" )
752 test_ =
static_cast<bool> (iterPL->getImmutableValue<
int>());
754 else if (tag ==
"DEBUGLEVEL" )
756 debugLevel = iterPL->getImmutableValue<
int>();
758 else if ( tag ==
"TAHB" )
760 taHB_ = iterPL->getImmutableValue<
int>();
762 else if ( tag ==
"VOLTLIM" )
764 voltLimFlag_ =
static_cast<bool> (iterPL->getImmutableValue<
int>());
768 UserWarning(*
this) <<
"Unrecognized HBINT option " << tag;
823 bool returnValue =
false;
845 N_LAS_Vector & solnVecPtr,
846 std::vector<double> & timePoints,
847 std::vector<double> & freqPoints,
848 RCP<N_LAS_BlockVector> & timeDomainSolnVec,
849 RCP<N_LAS_BlockVector> & freqDomainSolnVecReal,
850 RCP<N_LAS_BlockVector> & freqDomainSolnVecImag,
851 RCP<N_LAS_BlockVector> & timeDomainStoreVec,
852 RCP<N_LAS_BlockVector> & freqDomainStoreVecReal,
853 RCP<N_LAS_BlockVector> & freqDomainStoreVecImag
856 N_LAS_BlockVector & blockSolVecPtr =
dynamic_cast<N_LAS_BlockVector &
>(solnVecPtr);
858 Teuchos::RCP<N_LAS_BlockVector> bStoreVecFreqPtr_ =
hbLoaderPtr_->getStoreVecFreqPtr();
860 timeDomainStoreVec =
hbBuilderPtr_->createTimeDomainStoreBlockVector();
862 if (bStoreVecFreqPtr_->blockCount() > 0 )
864 hbLoaderPtr_->permutedIFT(*bStoreVecFreqPtr_, &*timeDomainStoreVec);
869 timeDomainSolnVec =
hbBuilderPtr_->createTimeDomainBlockVector();
870 int blockCount = timeDomainSolnVec->blockCount();
871 int N = timeDomainSolnVec->block(0).globalLength();
873 timePoints.resize(
size_);
875 for(
int i = 0; i <
size_; ++i )
883 Teuchos::RCP<N_PDS_ParMap> baseMap = Teuchos::rcp_const_cast<N_PDS_ParMap>(
hbBuilderPtr_->getBaseSolutionMap() );
884 Teuchos::RCP<N_PDS_ParMap> globalMap = createBlockParMap( blockCount, *baseMap );
885 freqDomainSolnVecReal = Teuchos::rcp(
new N_LAS_BlockVector( blockCount, globalMap, baseMap ) );
886 freqDomainSolnVecImag = Teuchos::rcp(
new N_LAS_BlockVector( blockCount, globalMap, baseMap ) );
888 hbLoaderPtr_->permutedIFT(blockSolVecPtr, &*timeDomainSolnVec);
897 for (
int j=0; j<N; j++)
902 int lid = baseMap->globalToLocalIndex( j );
903 N_LAS_Vector& solBlock = blockSolVecPtr.block( j );
905 N_LAS_Vector& realVecRef = freqDomainSolnVecReal->block((blockCount-1)/2);
906 N_LAS_Vector& imagVecRef = freqDomainSolnVecImag->block((blockCount-1)/2);
910 realVecRef[lid] = solBlock[0];
911 imagVecRef[lid] = solBlock[1];
914 for (
int i=1; i <= (blockCount-1)/2; ++i)
916 N_LAS_Vector& realVecRef_neg = freqDomainSolnVecReal->block((blockCount-1)/2 - i);
917 N_LAS_Vector& imagVecRef_neg = freqDomainSolnVecImag->block((blockCount-1)/2 - i);
918 N_LAS_Vector& realVecRef_pos = freqDomainSolnVecReal->block((blockCount-1)/2 + i);
919 N_LAS_Vector& imagVecRef_pos = freqDomainSolnVecImag->block((blockCount-1)/2 + i);
923 realVecRef_neg[lid] = solBlock[ 2*(blockCount-i) ];
924 imagVecRef_neg[lid] = solBlock[ 2*(blockCount-i) + 1 ];
925 realVecRef_pos[lid] = solBlock[ 2*i ];
926 imagVecRef_pos[lid] = solBlock[ 2*i+1 ];
932 Teuchos::RCP<N_PDS_ParMap> baseStoreMap = Teuchos::rcp_const_cast<N_PDS_ParMap>(
hbBuilderPtr_->getBaseStoreMap() );
933 Teuchos::RCP<N_PDS_ParMap> globalStoreMap = createBlockParMap( blockCount, *baseStoreMap );
934 freqDomainStoreVecReal = Teuchos::rcp(
new N_LAS_BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
935 freqDomainStoreVecImag = Teuchos::rcp(
new N_LAS_BlockVector( blockCount, globalStoreMap, baseStoreMap ) );
939 N = timeDomainStoreVec->block(0).globalLength();
941 for (
int j=0; j<N; j++)
946 int lid = baseStoreMap->globalToLocalIndex( j );
947 N_LAS_Vector& storeBlock = bStoreVecFreqPtr_->block( j );
949 N_LAS_Vector& realVecRef = freqDomainStoreVecReal->block((blockCount-1)/2);
950 N_LAS_Vector& imagVecRef = freqDomainStoreVecImag->block((blockCount-1)/2);
954 realVecRef[lid] = storeBlock[0];
955 imagVecRef[lid] = storeBlock[1];
958 for (
int i=1; i <= (blockCount-1)/2; ++i)
960 N_LAS_Vector& realVecRef_neg = freqDomainStoreVecReal->block((blockCount-1)/2 - i);
961 N_LAS_Vector& imagVecRef_neg = freqDomainStoreVecImag->block((blockCount-1)/2 - i);
962 N_LAS_Vector& realVecRef_pos = freqDomainStoreVecReal->block((blockCount-1)/2 + i);
963 N_LAS_Vector& imagVecRef_pos = freqDomainStoreVecImag->block((blockCount-1)/2 + i);
967 realVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) ];
968 imagVecRef_neg[lid] = storeBlock[ 2*(blockCount-i) + 1 ];
969 realVecRef_pos[lid] = storeBlock[ 2*i ];
970 imagVecRef_pos[lid] = storeBlock[ 2*i+1 ];
1023 bool returnValue =
true;
1025 Xyce::lout() <<
" ***** Computing tolerance parameters for HB IC calculation....\n" << std::endl;
1034 tiaParams.
resume =
false;
1056 std::string msg =
"Calculation of tolerance parameters failed for relErrorTol = "
1057 + Teuchos::Utils::toString(tiaParams.
relErrorTol) +
".\n";
1058 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0, msg );
1066 std::string msg =
"Tolerance parameters refined, re-running with relErrorTol = "
1067 + Teuchos::Utils::toString(tiaParams.
relErrorTol/10) +
".\n";
1068 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0, msg );
1074 dsPtr->resetFastTimeData();
1089 std::string msg =
"Calculation of tolerance parameters failed for relErrorTol = "
1090 + Teuchos::Utils::toString(tiaParams.
relErrorTol) +
".\n";
1091 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0, msg );
1093 returnValue = retV && returnValue;
1124 bool returnValue =
true;
1126 Xyce::lout() <<
" ***** Computing " <<
startUpPeriods_ <<
" start up periods for HB IC calculation...." << std::endl;
1137 #ifdef Xyce_DEBUG_HB
1138 Xyce::dout() <<
"HB::runStartupPeriods_(): Advancing time through "
1141 <<
" finalTime = " << tiaParams.
finalTime << std::endl;
1142 #endif // Xyce_DEBUG_HB
1149 x.add(Xyce::IO::PrintType::HB_STARTUP);
1174 dcOpSolVecPtr_ = rcp(
new N_LAS_Vector( *(dsPtr->currSolutionPtr) ));
1176 dcOpQVecPtr_ = rcp(
new N_LAS_Vector( *(dsPtr->daeQVectorPtr) ));
1198 bool returnValue =
true;
1200 Xyce::lout() <<
" ***** Running transient to compute HB initial condition....\n" << std::endl;
1223 #ifdef Xyce_DEBUG_HB
1224 Xyce::dout() <<
"HB::runTransientIC_(): Advancing time from"
1226 <<
" finalTime = " << tiaParams.
finalTime << std::endl;
1227 #endif // Xyce_DEBUG_HB
1232 tiaParams.
NOOP =
true;
1282 Xyce::lout() <<
" ***** Interpolating transient solution for IC calculation....\n" << std::endl;
1285 int numPoints = dsPtr->timeSteps.size();
1287 #ifdef Xyce_DEBUG_HB
1288 Xyce::dout() <<
"HB::interpolateIC_(): Initial transient run produced " << numPoints <<
" points." << std::endl;
1291 std::vector<int> goodIndicies;
1296 for(
int i = 0; i <
size_; ++i )
1304 int breakpoints = 0;
1308 goodIndicies.push_back(startIndex);
1309 int GoodTimePointIndex = startIndex + 1;
1311 for(
int i=startIndex; i < numPoints - 1 ; i++ )
1314 if( dsPtr->timeStepsBreakpointFlag[i] ==
true )
1319 #ifdef Xyce_DEBUG_HB
1322 Xyce::dout() <<
"\t\t timeStep[ " << i <<
" ] = " << dsPtr->timeSteps[i];
1323 if( dsPtr->timeStepsBreakpointFlag[i] ==
true )
1325 Xyce::dout() <<
" Breakpoint";
1327 Xyce::dout() << std::endl;
1330 while( ( GoodTimePointIndex < size_ ) && (dsPtr->timeSteps[i] <=
goodTimePoints_[GoodTimePointIndex]) && (
goodTimePoints_[GoodTimePointIndex] < dsPtr->timeSteps[i+1]))
1333 goodIndicies.push_back( i );
1334 GoodTimePointIndex = GoodTimePointIndex+1;
1338 for(
int i=0; i<
size_; i++ )
1340 int currentIndex = goodIndicies[i];
1341 N_LAS_Vector * firstSolVecPtr = dsPtr->fastTimeSolutionVec[currentIndex];
1342 N_LAS_Vector * secondSolVecPtr = dsPtr->fastTimeSolutionVec[currentIndex+1];
1344 N_LAS_Vector * firstStateVecPtr = dsPtr->fastTimeStateVec[currentIndex];
1345 N_LAS_Vector * secondStateVecPtr = dsPtr->fastTimeStateVec[currentIndex+1];
1347 N_LAS_Vector * firstQVecPtr = dsPtr->fastTimeQVec[currentIndex];
1348 N_LAS_Vector * secondQVecPtr = dsPtr->fastTimeQVec[currentIndex+1];
1350 N_LAS_Vector * firstStoreVecPtr = dsPtr->fastTimeStoreVec[currentIndex];
1351 N_LAS_Vector * secondStoreVecPtr = dsPtr->fastTimeStoreVec[currentIndex+1];
1353 double fraction = (
goodTimePoints_[i] - dsPtr->timeSteps[currentIndex])/(dsPtr->timeSteps[currentIndex+1] - dsPtr->timeSteps[currentIndex]);
1355 RCP<N_LAS_Vector> InterpICSolVecPtr = rcp(
new N_LAS_Vector( *secondSolVecPtr ) );
1356 RCP<N_LAS_Vector> InterpICStateVecPtr = rcp(
new N_LAS_Vector( *secondStateVecPtr ) );
1357 RCP<N_LAS_Vector> InterpICQVecPtr = rcp(
new N_LAS_Vector( *secondQVecPtr ) );
1358 RCP<N_LAS_Vector> InterpICStoreVecPtr = rcp(
new N_LAS_Vector( *secondStoreVecPtr ) );
1360 InterpICSolVecPtr->putScalar(0.0);
1361 InterpICStateVecPtr->putScalar(0.0);
1362 InterpICQVecPtr->putScalar(0.0);
1363 InterpICStoreVecPtr->putScalar(0.0);
1365 InterpICSolVecPtr->linearCombo(-1.0, *firstSolVecPtr, 1.0, *secondSolVecPtr );
1366 InterpICSolVecPtr->linearCombo(1.0, *firstSolVecPtr, fraction , *InterpICSolVecPtr);
1368 InterpICStateVecPtr->linearCombo(-1.0, *firstStateVecPtr, 1.0, *secondStateVecPtr );
1369 InterpICStateVecPtr->linearCombo(1.0, *firstStateVecPtr, fraction , *InterpICStateVecPtr);
1371 InterpICQVecPtr->linearCombo(-1.0, *firstQVecPtr, 1.0, *secondQVecPtr );
1372 InterpICQVecPtr->linearCombo(1.0, *firstQVecPtr, fraction , *InterpICQVecPtr);
1374 InterpICStoreVecPtr->linearCombo(-1.0, *firstStoreVecPtr, 1.0, *secondStoreVecPtr );
1375 InterpICStoreVecPtr->linearCombo(1.0, *firstStoreVecPtr, fraction , *InterpICStoreVecPtr);
1385 dsPtr->resetFastTimeData();