46 #include <Xyce_config.h>
64 #include <N_LOA_Loader.h>
66 #include <N_LAS_System.h>
67 #include <N_LAS_Vector.h>
68 #include <N_LAS_Matrix.h>
69 #include <N_LAS_Builder.h>
71 #include <N_ERH_ErrorMgr.h>
72 #include <N_UTL_Xyce.h>
73 #include <N_UTL_Param.h>
74 #include <N_UTL_OptionBlock.h>
76 #include <N_IO_OutputMgr.h>
89 (
bool noxFlag,
bool noxFlagInner, N_IO_CmdParse & cp)
92 twoLevelAlgorithm_(3),
93 twoLevelAlgorithmTran_(0),
97 setupOuterLoopParamsFlag_(
false),
98 setupTranParamsFlag_(
false),
99 externalAnalysisMode(
DC_OP),
100 outerLoopActiveFlag_(
true),
102 noxFlagInner_(noxFlagInner),
103 numInterfaceNodesSetup_(
false),
109 continuationType_(1),
110 innerLoopFailFatal_(
true),
111 totalSolveFailFatal_(
false),
112 doFullNewtonFinalEnforcement_(
true),
114 firstDCOPFlag_(
false),
115 increaseContScalar_(1.5),
116 decreaseContScalar_(0.2),
117 continuationCalledBefore_(
false),
139 nlsOuterPtr_->registerTwoLevelSolver(
this);
140 nlsInnerPtr_->registerTwoLevelSolver(
this);
173 bool bsuccess =
true;
176 tiaPtr_ = tiaPtr_tmp;
177 tmpBool = nlsOuterPtr_->registerAnalysisInterface(tiaPtr_);
178 bsuccess = bsuccess && tmpBool;
180 tmpBool = nlsInnerPtr_->registerAnalysisInterface(tiaPtr_);
181 bsuccess = bsuccess && tmpBool;
197 bool bsuccess =
true;
201 tmpBool = nlsOuterPtr_->registerLinearSystem (ptr);
202 bsuccess = bsuccess && tmpBool;
204 tmpBool = nlsInnerPtr_->registerLinearSystem (ptr);
205 bsuccess = bsuccess && tmpBool;
219 (N_LOA_Loader * loaderPtr_tmp)
221 bool bsuccess =
true;
224 loaderPtr_ = loaderPtr_tmp;
225 tmpBool = nlsOuterPtr_->registerLoader (loaderPtr_tmp);
226 bsuccess = bsuccess && tmpBool;
228 tmpBool = nlsInnerPtr_->registerLoader (loaderPtr_tmp);
229 bsuccess = bsuccess && tmpBool;
244 bool bsuccess =
true;
249 bsuccess = bsuccess && tmpBool;
252 bsuccess = bsuccess && tmpBool;
313 int numLinSolves = 0;
329 int numFLinSolves = 0;
332 return numFLinSolves;
377 double totalLinSolveTime = 0.0;
380 return totalLinSolveTime;
393 double totalResLoadTime = 0.0;
396 return totalResLoadTime;
409 double totalJacLoadTime = 0.0;
412 return totalJacLoadTime;
498 bool bsuccess =
true;
502 bsuccess = bsuccess && tmpBool;
505 bsuccess = bsuccess && tmpBool;
508 bsuccess = bsuccess && tmpBool;
542 std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
543 std::list<N_UTL_Param>::const_iterator end_tpL = OB.getParams().end();
544 for ( ; it_tpL != end_tpL; ++it_tpL)
546 if (it_tpL->uTag() ==
"MAXSTEP")
548 maxOuterSteps_ =
static_cast<int>(it_tpL->getImmutableValue<
int>());
613 N_UTL_OptionBlock OBtmp;
615 std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
616 std::list<N_UTL_Param>::const_iterator end_tpL = OB.getParams().end();
617 for ( ; it_tpL != end_tpL; ++it_tpL)
619 if (it_tpL->uTag() ==
"ALGORITHM")
623 else if (it_tpL->uTag() ==
"NOX")
627 else if (it_tpL->uTag() ==
"MAXCONTSTEPS")
629 maxContSteps_ =
static_cast<int>(it_tpL->getImmutableValue<
int>());
631 else if (it_tpL->uTag() ==
"CONTINUATIONFLAG")
633 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
636 else if (it_tpL->uTag() ==
"INNERFAIL")
638 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
641 else if (it_tpL->uTag() ==
"EXITWITHFAILURE")
643 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
646 else if (it_tpL->uTag() ==
"FULLNEWTONENFORCE")
648 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
651 else if (it_tpL->uTag() ==
"CONPARAM")
655 else if (it_tpL->uTag() ==
"VOLTLIMTOL")
657 voltLimTol_ =
static_cast<double>(it_tpL->getImmutableValue<
double>());
662 OBtmp.getParams().push_back(*it_tpL);
670 if (twoLevelAlgorithm_ < 0 || twoLevelAlgorithm_ > 5)
672 Xyce::lout() <<
"***** WARNING: Right now the only two-level algorithms are algorithm=0-5. Resetting to 0.\n\n" << std::endl;
677 #ifdef Xyce_VERBOSE_NONLINEAR
678 Xyce::dout() <<
"\n" << std::endl
679 << Xyce::section_divider << std::endl
680 <<
"\n***** 2-level Inner Loop Nonlinear solver options:\n" << std::endl
686 innerLoopParams.printParams(Xyce::dout());
689 Xyce::dout() <<
"\n***** Done printing Inner Loop Params:\n" << std::endl
690 << Xyce::section_divider << std::endl
691 <<
"\n" << std::endl;
712 #ifdef Xyce_VERBOSE_NONLINEAR
713 Xyce::dout() <<
"In N_NLS_TwoLevelNewton::setTwoLevelTranOptions" << std::endl;
716 N_UTL_OptionBlock OBtmp;
718 std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
719 std::list<N_UTL_Param>::const_iterator end_tpL = OB.getParams().end();
720 for ( ; it_tpL != end_tpL; ++it_tpL)
722 if (it_tpL->uTag() ==
"ALGORITHM")
726 else if ( it_tpL->uTag() ==
"MAXCONTSTEPS" )
733 OBtmp.getParams().push_back(*it_tpL);
739 if (twoLevelAlgorithmTran_ < 0 || twoLevelAlgorithmTran_ > 3)
741 Xyce::lout() <<
"***** WARNING: Right now the only two-level algorithms are algorithm=0-3. Resetting to 0.\n\n" << std::endl;
746 #ifdef Xyce_VERBOSE_NONLINEAR
748 Xyce::lout() <<
"\n" << std::endl
749 << Xyce::section_divider << std::endl
750 <<
"\n***** 2-level Transient Inner Loop Nonlinear solver options:\n" << std::endl;
751 innerLoopTranParams.printParams(Xuce::lout());
753 Xyce::lout() <<
"\n***** Done printing Inner Loop Transient Params:\n" << std::endl
754 << Xyce::section_divider << std::endl
755 <<
"\n" << std::endl;
776 #ifdef Xyce_VERBOSE_NONLINEAR
777 Xyce::dout() << std::endl;
778 Xyce::dout() <<
"Setting the externalAnalysisMode = " << mode << std::endl;
797 bool bsuccess =
true;
800 bsuccess = bsuccess && tmpBool;
803 bsuccess = bsuccess && tmpBool;
806 bsuccess = bsuccess && tmpBool;
826 Xyce::lout() <<
"---------- 2LNiter: " << step <<
"\t" << success <<
"\tFULL PROBLEM --------------------------------" << std::endl;
830 Xyce::lout() <<
"---------- 2LNiter: " << step <<
"\t" << success <<
"\tINNER PROBLEM ----------------------------" << std::endl;
834 Xyce::lout() <<
"---------- 2LNiter: " << step <<
"\t" << success <<
"\tOUTER PROBLEM ----------------------------" << std::endl;
919 #ifdef Xyce_VERBOSE_NONLINEAR
920 Xyce::dout() << std::endl <<
"Running algorithm 0:" << std::endl;
982 #ifdef Xyce_VERBOSE_NONLINEAR
983 Xyce::dout() << std::endl <<
"Running algorithm 1:" << std::endl;
986 bool firstOuterStepTaken =
false;
1001 #ifdef Xyce_VERBOSE_NONLINEAR
1016 if (firstOuterStepTaken)
1022 firstOuterStepTaken =
true;
1028 #ifdef Xyce_VERBOSE_NONLINEAR
1042 #ifdef Xyce_VERBOSE_NONLINEAR
1045 Xyce::dout() <<
"TWO LEVEL Newton succeeded!" << std::endl;
1072 bool statusFull =
false;
1073 bool firstOuterStepTaken =
false;
1075 #ifdef Xyce_VERBOSE_NONLINEAR
1076 Xyce::dout() << std::endl <<
"Running algorithm 2:" << std::endl;
1082 firstOuterStepTaken =
true;
1086 #ifdef Xyce_VERBOSE_NONLINEAR
1116 #ifdef Xyce_VERBOSE_NONLINEAR
1135 if (firstOuterStepTaken)
1141 firstOuterStepTaken =
true;
1146 #ifdef Xyce_VERBOSE_NONLINEAR
1157 if (status > 0 && statInner>0) statusFull =
true;
1159 if (statusFull)
break;
1164 #ifdef Xyce_VERBOSE_NONLINEAR
1165 if (status >0 && statInner > 0)
1167 Xyce::dout() <<
"TWO LEVEL Newton succeeded!" << std::endl;
1195 bool statusFull =
false;
1196 bool firstOuterStepTaken =
false;
1198 #ifdef Xyce_VERBOSE_NONLINEAR
1199 Xyce::dout() << std::endl <<
"Running algorithm 3:" << std::endl;
1230 #ifdef Xyce_VERBOSE_NONLINEAR
1251 if (firstOuterStepTaken)
1257 firstOuterStepTaken =
true;
1266 #ifdef Xyce_VERBOSE_NONLINEAR
1273 double twoNormJDXP_ = 0.0;
1278 #ifdef Xyce_VERBOSE_NONLINEAR
1279 Xyce::dout() << std::endl;
1280 Xyce::dout() <<
" 2-norm of voltage limiting vector: " << twoNormJDXP_ << std::endl;
1285 if (status > 0 && statInner>0 && voltLimStat) statusFull =
true;
1287 if (statusFull)
break;
1300 #ifdef Xyce_VERBOSE_NONLINEAR
1310 #ifdef Xyce_VERBOSE_NONLINEAR
1311 if (status >0 && statInner > 0 && statFinal > 0)
1313 Xyce::dout() <<
"TWO LEVEL Newton succeeded!" << std::endl;
1343 bool continuationLoop =
false;
1345 int contMaxTmp = 100;
1346 int stepsLeft = contMaxTmp;
1348 #ifdef Xyce_VERBOSE_NONLINEAR
1349 Xyce::dout() << std::endl <<
"Running algorithm 4:" << std::endl;
1350 Xyce::dout() << std::endl <<
"Initial continuation steps: ";
1351 Xyce::dout() << contMaxTmp << std::endl;
1367 double initVal = 0.0;
1368 double currVal = initVal;
1369 double prevVal = initVal;
1372 std::vector<std::string>::iterator iter;
1373 std::vector<std::string>::iterator begin =
paramNameList.begin ();
1374 std::vector<std::string>::iterator end =
paramNameList.end ();
1376 std::vector<double>::iterator iterFinalVal;
1377 std::vector<double>::iterator beginFinalVal =
paramFinalVal.begin ();
1378 std::vector<double>::iterator endFinalVal =
paramFinalVal.end ();
1380 std::vector<double>::iterator iterCurrentVal;
1381 std::vector<double>::iterator beginCurrentVal =
paramCurrentVal.begin ();
1385 for (iter=begin, iterFinalVal=beginFinalVal, iterCurrentVal=beginCurrentVal;
1387 ++iter, ++iterFinalVal, ++iterCurrentVal)
1390 *iterFinalVal = 1.0;
1398 for (iter=begin, iterFinalVal=beginFinalVal;
1400 ++iter, ++iterFinalVal)
1403 stepSizeEst = (*iterFinalVal-0.0)/(
static_cast<double>(contMaxTmp));
1408 #ifdef Xyce_VERBOSE_NONLINEAR
1409 Xyce::dout() <<
"Parameter = " << *iter;
1410 Xyce::dout() <<
" finalVal = " << *iterFinalVal << std::endl;
1414 bool continuationLoopFinished =
false;
1415 int numTotalFailures = 0;
1416 while (!continuationLoopFinished)
1418 bool stepFinished =
false;
1419 int numFailures = 0;
1421 while(!stepFinished)
1423 if (stepSizeEst != 0.0)
1425 stepsLeft =
static_cast<int>((*iterFinalVal-currVal)/stepSizeEst) + 1;
1432 #ifdef Xyce_VERBOSE_NONLINEAR
1433 Xyce::dout() << std::endl <<
"Continuation Step: " <<
contStep_;
1434 Xyce::dout() <<
" Estimated Remaining Steps: " << stepsLeft;
1435 Xyce::dout() <<
" " << *iter;
1436 Xyce::dout() << std::endl;
1437 Xyce::dout() <<
"currVal= " << currVal;
1438 Xyce::dout() <<
" prevVal= " << prevVal;
1439 Xyce::dout() <<
" step= " << stepSizeEst;
1440 Xyce::dout() << std::endl;
1445 std::string tmp =
"Continuation step estimate broken. Exiting\n";
1446 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1450 (*savedNextSolPtr_) = (**nextSolVectorPtrPtr_);
1454 *iterCurrentVal = currVal;
1469 successBool = (statNL > 0);
1473 stepFinished =
true;
1476 if (numFailures <= 0)
1482 if (numFailures < 0) numFailures = 0;
1485 currVal += stepSizeEst;
1487 if ( (*iterFinalVal >= 0 && currVal > *iterFinalVal) ||
1488 (*iterFinalVal < 0 && currVal < *iterFinalVal) )
1490 currVal = *iterFinalVal;
1491 stepSizeEst = currVal - prevVal;
1494 #ifdef Xyce_DEBUG_NONLINEAR
1495 Xyce::dout() <<
"\nRight before outputHOMOTOPY:" << std::endl;
1512 (**nextSolVectorPtrPtr_) = (*savedNextSolPtr_);
1517 currVal = prevVal + stepSizeEst;
1528 continuationLoopFinished =
1529 ( (*iterFinalVal >= 0 && prevVal >= *iterFinalVal) ||
1530 (*iterFinalVal < 0 && prevVal <= *iterFinalVal) );
1534 #ifdef Xyce_VERBOSE_NONLINEAR
1535 Xyce::dout() <<
"currVal= " << currVal;
1536 Xyce::dout() <<
" prevVal= " << prevVal;
1537 Xyce::dout() << std::endl;
1538 Xyce::dout() << std::endl;
1539 Xyce::dout() <<
"Total number of failures = " << numTotalFailures << std::endl;
1540 Xyce::dout() <<
"Number of actual steps = " <<
contStep_-1;
1541 Xyce::dout() << std::endl;
1569 #ifdef Xyce_VERBOSE_NONLINEAR
1570 Xyce::dout() << std::endl <<
"Running algorithm 5:" << std::endl;
1610 Xyce::dout() << std::endl;
1611 Xyce::dout() <<
"tiaPtr is null. exiting" << std::endl; exit(0);
1620 if (doubleDCOPEnable && (tiaMode == 0) && (ddcopStep==0) )
1636 #ifdef Xyce_VERBOSE_NONLINEAR
1637 Xyce::dout() << std::endl;
1650 else if (algorithm == 1)
1655 else if (algorithm == 2)
1661 else if (algorithm == 3)
1665 else if (algorithm == 4)
1669 else if (algorithm == 5)
1676 "Two-Level Newton Algorithm set to invalid number.\n";
1677 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1686 #ifndef Xyce_PARALLEL_MPI
1691 "Two-Level Newton Algorithm failed to converge. Exiting.\n";
1692 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1725 bool bsuccess =
true;
1726 bool tmpBool =
true;
1728 char filename1[256];
1730 for (
int ich = 0; ich < 256; ++ich)
1731 { filename1[ich] = 0; }
1744 sprintf(filename1,
"%s",
"tmpJac.txt");
1745 N_LAS_Matrix *A =
lasSysPtr_->getJacobianMatrix();
1746 A->writeToFile(filename1);
1749 N_LAS_Vector *rhsVecPtr =
lasSysPtr_->getRHSVector();
1760 #ifdef Xyce_VERBOSE_NONLINEAR
1761 Xyce::dout() <<
"\n numCoupleTerms = " << numCoupleTerms << std::endl;
1764 for (iCouple=0;iCouple<numCoupleTerms;++iCouple)
1767 rhsVecPtr->putScalar(0.0);
1770 tmpBool =
loaderPtr_->loadCouplingRHS (iSubProblem, iCouple, rhsVecPtr );
1771 bsuccess = bsuccess && tmpBool;
1773 sprintf(filename1,
"dfdv%02d.txt", iCouple);
1774 rhsVecPtr->writeToFile(filename1);
1778 bsuccess = bsuccess && tmpBool;
1781 sprintf(filename1,
"dvdx%02d.txt", iCouple);
1782 newtVecPtr->writeToFile(filename1);
1787 *rhsVecPtr = *newtVecPtr;
1790 tmpBool =
loaderPtr_->calcCouplingTerms (iSubProblem, iCouple, rhsVecPtr);
1791 bsuccess = bsuccess && tmpBool;
1821 int suggestedSteps = 10;
1822 suggestedSteps =
loaderPtr_->enablePDEContinuation ();
1824 if (suggestedSteps < 1) suggestedSteps = 1;
1825 contMaxTmp = suggestedSteps;
1827 double stepSizeEst = 1.0/(
static_cast<double>(contMaxTmp));
1828 double currentAlpha = 0.0;
1829 double previousAlpha = 0.0;
1830 int stepsLeft = contMaxTmp;
1839 currentAlpha = stepSizeEst;
1844 bool continuationLoopFinished =
false;
1846 int numTotalFailures = 0;
1848 while (!continuationLoopFinished)
1850 bool stepFinished =
false;
1851 int numFailures = 0;
1853 while(!stepFinished)
1856 stepsLeft =
static_cast<int>((1.0-currentAlpha)/stepSizeEst) + 1;
1858 #ifdef Xyce_VERBOSE_NONLINEAR
1859 Xyce::dout() << std::endl <<
"Continuation Step: " <<
contStep_;
1860 Xyce::dout() <<
" Estimated Remaining Steps: " << stepsLeft;
1861 Xyce::dout() << std::endl;
1862 Xyce::dout() <<
"current alpha = " << currentAlpha;
1863 Xyce::dout() <<
" prev. alpha = " << previousAlpha;
1864 Xyce::dout() <<
" step = " << stepSizeEst;
1865 Xyce::dout() << std::endl;
1869 std::string tmp =
"Continuation step estimate broken. Exiting\n";
1870 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1874 (*savedNextSolPtr_) = (**nextSolVectorPtrPtr_);
1876 std::string paramName =
"pdealpha";
1877 loaderPtr_->setParam (paramName, currentAlpha);
1889 #ifdef Xyce_DEBUG_NONLINEAR
1890 Xyce::dout() <<
"Status of inner loop solve: " << statInner << std::endl;
1892 successBool = (statInner > 0);
1896 stepFinished =
true;
1898 if (numFailures <= 0)
1904 if (numFailures < 0) numFailures = 0;
1906 previousAlpha = currentAlpha;
1907 currentAlpha += stepSizeEst;
1909 if (currentAlpha > 1.0)
1912 stepSizeEst = currentAlpha - previousAlpha;
1920 (**nextSolVectorPtrPtr_) = (*savedNextSolPtr_);
1925 currentAlpha = previousAlpha + stepSizeEst;
1935 continuationLoopFinished = (previousAlpha >= 1.0);
1939 #ifdef Xyce_VERBOSE_NONLINEAR
1940 Xyce::dout() <<
"current alpha = " << currentAlpha;
1941 Xyce::dout() <<
" previous alpha = " << previousAlpha;
1942 Xyce::dout() << std::endl;
1943 Xyce::dout() << std::endl;
1944 Xyce::dout() <<
"Total number of failures = " << numTotalFailures << std::endl;
1945 Xyce::dout() <<
"Number of actual steps = " <<
contStep_-1;
1946 Xyce::dout() << std::endl;
1970 int suggestedSteps =
loaderPtr_->enablePDEContinuation ();
1980 Xyce::dout() <<
"suggested steps are: " << suggestedSteps << std::endl;
1982 std::list<N_UTL_Param>::iterator it_tpL;
1987 ExtendedString tmpTag = it_tpL->tag ();
1990 Xyce::dout() <<
"tmpTag = " << tmpTag << std::endl;
1992 if (tmpTag ==
"CONTINUATION")
1994 if (suggestedSteps <= 1)
1996 Xyce::dout() <<
"Setting the solver type to 0" << std::endl;
2039 #ifdef Xyce_VERBOSE_NONLINEAR
2040 Xyce::dout() << std::endl;
2041 Xyce::dout() << Xyce::section_divider << std::endl;
2042 Xyce::dout() <<
"N_NLS_TwoLevelNewton::enableSensitivity " << std::endl;
2044 bool bsuccess =
true;
2045 bool tmpBool =
true;
2055 #ifdef Xyce_VERBOSE_NONLINEAR
2057 double maxNormRHS_=0, twoNormRHS_ = 0.0;
2060 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2061 Xyce::dout() << std::endl;
2062 Xyce::dout() <<
"Max. norm of full Newton RHS: " << maxNormRHS_ << std::endl;
2063 Xyce::dout() <<
" 2-norm of full Newton RHS: " << twoNormRHS_ << std::endl;
2064 Xyce::dout() << Xyce::section_divider << std::endl;
2068 #ifdef Xyce_DEBUG_NONLINEAR
2069 static int callsSens = 0;
2070 char filename1[256];
for (
int ich = 0; ich < 256; ++ich) filename1[ich] = 0;
2071 char filename2[256];
for (
int ich = 0; ich < 256; ++ich) filename2[ich] = 0;
2073 sprintf(filename1,
"matrixTmp%d.txt",callsSens);
2074 N_LAS_Matrix *A =
lasSysPtr_->getJacobianMatrix();
2075 A->writeToFile(filename1);
2078 N_LAS_Vector *b =
lasSysPtr_->getRHSVector();
2079 sprintf(filename2,
"rhsTmp%d.txt", callsSens);
2083 #ifndef Xyce_PARALLEL_MPI
2084 fp1 = fopen(filename2,
"w");
2086 for (i=0;i<size;++i)
2088 double output = b->getElementByGlobalIndex(i);
2089 fprintf(fp1,
"%25.18e\n",output);
2094 N_LAS_Vector *x = (*nextSolVectorPtrPtr_);
2095 sprintf(filename2,
"solTmp%d.txt", callsSens);
2097 #ifndef Xyce_PARALLEL_MPI
2098 fp1 = fopen(filename2,
"w");
2100 for (i=0;i<size;++i)
2102 double output = x->getElementByGlobalIndex(i);
2103 fprintf(fp1,
"%25.18e\n",output);