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>
92 (
bool noxFlag,
bool noxFlagInner, N_IO_CmdParse & cp)
95 twoLevelAlgorithm_(3),
96 twoLevelAlgorithmTran_(0),
100 setupOuterLoopParamsFlag_(
false),
101 setupTranParamsFlag_(
false),
102 externalAnalysisMode(
DC_OP),
103 outerLoopActiveFlag_(
true),
105 noxFlagInner_(noxFlagInner),
106 numInterfaceNodesSetup_(
false),
112 continuationType_(1),
113 innerLoopFailFatal_(
true),
114 totalSolveFailFatal_(
false),
115 doFullNewtonFinalEnforcement_(
true),
117 firstDCOPFlag_(
false),
118 increaseContScalar_(1.5),
119 decreaseContScalar_(0.2),
120 continuationCalledBefore_(
false),
142 nlsOuterPtr_->registerTwoLevelSolver(
this);
143 nlsInnerPtr_->registerTwoLevelSolver(
this);
176 bool bsuccess =
true;
179 tiaPtr_ = tiaPtr_tmp;
180 tmpBool = nlsOuterPtr_->registerAnalysisManager(tiaPtr_);
181 bsuccess = bsuccess && tmpBool;
183 tmpBool = nlsInnerPtr_->registerAnalysisManager(tiaPtr_);
184 bsuccess = bsuccess && tmpBool;
200 bool bsuccess =
true;
204 tmpBool = nlsOuterPtr_->registerLinearSystem (ptr);
205 bsuccess = bsuccess && tmpBool;
207 tmpBool = nlsInnerPtr_->registerLinearSystem (ptr);
208 bsuccess = bsuccess && tmpBool;
222 (N_LOA_Loader * loaderPtr_tmp)
224 bool bsuccess =
true;
227 loaderPtr_ = loaderPtr_tmp;
228 tmpBool = nlsOuterPtr_->registerLoader (loaderPtr_tmp);
229 bsuccess = bsuccess && tmpBool;
231 tmpBool = nlsInnerPtr_->registerLoader (loaderPtr_tmp);
232 bsuccess = bsuccess && tmpBool;
247 bool bsuccess =
true;
252 bsuccess = bsuccess && tmpBool;
255 bsuccess = bsuccess && tmpBool;
316 int numLinSolves = 0;
332 int numFLinSolves = 0;
335 return numFLinSolves;
380 double totalLinSolveTime = 0.0;
383 return totalLinSolveTime;
396 double totalResLoadTime = 0.0;
399 return totalResLoadTime;
412 double totalJacLoadTime = 0.0;
415 return totalJacLoadTime;
501 bool bsuccess =
true;
505 bsuccess = bsuccess && tmpBool;
508 bsuccess = bsuccess && tmpBool;
511 bsuccess = bsuccess && tmpBool;
545 std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
546 std::list<N_UTL_Param>::const_iterator end_tpL = OB.getParams().end();
547 for ( ; it_tpL != end_tpL; ++it_tpL)
549 if (it_tpL->uTag() ==
"MAXSTEP")
551 maxOuterSteps_ =
static_cast<int>(it_tpL->getImmutableValue<
int>());
616 N_UTL_OptionBlock OBtmp;
618 std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
619 std::list<N_UTL_Param>::const_iterator end_tpL = OB.getParams().end();
620 for ( ; it_tpL != end_tpL; ++it_tpL)
622 if (it_tpL->uTag() ==
"ALGORITHM")
626 else if (it_tpL->uTag() ==
"NOX")
630 else if (it_tpL->uTag() ==
"MAXCONTSTEPS")
632 maxContSteps_ =
static_cast<int>(it_tpL->getImmutableValue<
int>());
634 else if (it_tpL->uTag() ==
"CONTINUATIONFLAG")
636 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
639 else if (it_tpL->uTag() ==
"INNERFAIL")
641 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
644 else if (it_tpL->uTag() ==
"EXITWITHFAILURE")
646 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
649 else if (it_tpL->uTag() ==
"FULLNEWTONENFORCE")
651 int tmp =
static_cast<int>(it_tpL->getImmutableValue<
int>());
654 else if (it_tpL->uTag() ==
"CONPARAM")
658 else if (it_tpL->uTag() ==
"VOLTLIMTOL")
660 voltLimTol_ =
static_cast<double>(it_tpL->getImmutableValue<
double>());
665 OBtmp.getParams().push_back(*it_tpL);
673 if (twoLevelAlgorithm_ < 0 || twoLevelAlgorithm_ > 5)
675 Xyce::lout() <<
"***** WARNING: Right now the only two-level algorithms are algorithm=0-5. Resetting to 0.\n\n" << std::endl;
680 #ifdef Xyce_VERBOSE_NONLINEAR
681 Xyce::dout() <<
"\n" << std::endl
682 << Xyce::section_divider << std::endl
683 <<
"\n***** 2-level Inner Loop Nonlinear solver options:\n" << std::endl
689 innerLoopParams.printParams(Xyce::dout());
692 Xyce::dout() <<
"\n***** Done printing Inner Loop Params:\n" << std::endl
693 << Xyce::section_divider << std::endl
694 <<
"\n" << std::endl;
715 #ifdef Xyce_VERBOSE_NONLINEAR
716 Xyce::dout() <<
"In TwoLevelNewton::setTwoLevelTranOptions" << std::endl;
719 N_UTL_OptionBlock OBtmp;
721 std::list<N_UTL_Param>::const_iterator it_tpL = OB.getParams().begin();
722 std::list<N_UTL_Param>::const_iterator end_tpL = OB.getParams().end();
723 for ( ; it_tpL != end_tpL; ++it_tpL)
725 if (it_tpL->uTag() ==
"ALGORITHM")
729 else if ( it_tpL->uTag() ==
"MAXCONTSTEPS" )
736 OBtmp.getParams().push_back(*it_tpL);
742 if (twoLevelAlgorithmTran_ < 0 || twoLevelAlgorithmTran_ > 3)
744 Xyce::lout() <<
"***** WARNING: Right now the only two-level algorithms are algorithm=0-3. Resetting to 0.\n\n" << std::endl;
749 #ifdef Xyce_VERBOSE_NONLINEAR
751 Xyce::lout() <<
"\n" << std::endl
752 << Xyce::section_divider << std::endl
753 <<
"\n***** 2-level Transient Inner Loop Nonlinear solver options:\n" << std::endl;
754 innerLoopTranParams.printParams(Xuce::lout());
756 Xyce::lout() <<
"\n***** Done printing Inner Loop Transient Params:\n" << std::endl
757 << Xyce::section_divider << std::endl
758 <<
"\n" << std::endl;
779 #ifdef Xyce_VERBOSE_NONLINEAR
780 Xyce::dout() << std::endl;
781 Xyce::dout() <<
"Setting the externalAnalysisMode = " << mode << std::endl;
800 bool bsuccess =
true;
803 bsuccess = bsuccess && tmpBool;
806 bsuccess = bsuccess && tmpBool;
809 bsuccess = bsuccess && tmpBool;
829 Xyce::lout() <<
"---------- 2LNiter: " << step <<
"\t" << success <<
"\tFULL PROBLEM --------------------------------" << std::endl;
833 Xyce::lout() <<
"---------- 2LNiter: " << step <<
"\t" << success <<
"\tINNER PROBLEM ----------------------------" << std::endl;
837 Xyce::lout() <<
"---------- 2LNiter: " << step <<
"\t" << success <<
"\tOUTER PROBLEM ----------------------------" << std::endl;
922 #ifdef Xyce_VERBOSE_NONLINEAR
923 Xyce::dout() << std::endl <<
"Running algorithm 0:" << std::endl;
985 #ifdef Xyce_VERBOSE_NONLINEAR
986 Xyce::dout() << std::endl <<
"Running algorithm 1:" << std::endl;
989 bool firstOuterStepTaken =
false;
1004 #ifdef Xyce_VERBOSE_NONLINEAR
1019 if (firstOuterStepTaken)
1025 firstOuterStepTaken =
true;
1031 #ifdef Xyce_VERBOSE_NONLINEAR
1045 #ifdef Xyce_VERBOSE_NONLINEAR
1048 Xyce::dout() <<
"TWO LEVEL Newton succeeded!" << std::endl;
1075 bool statusFull =
false;
1076 bool firstOuterStepTaken =
false;
1078 #ifdef Xyce_VERBOSE_NONLINEAR
1079 Xyce::dout() << std::endl <<
"Running algorithm 2:" << std::endl;
1085 firstOuterStepTaken =
true;
1089 #ifdef Xyce_VERBOSE_NONLINEAR
1119 #ifdef Xyce_VERBOSE_NONLINEAR
1138 if (firstOuterStepTaken)
1144 firstOuterStepTaken =
true;
1149 #ifdef Xyce_VERBOSE_NONLINEAR
1160 if (status > 0 && statInner>0) statusFull =
true;
1162 if (statusFull)
break;
1167 #ifdef Xyce_VERBOSE_NONLINEAR
1168 if (status >0 && statInner > 0)
1170 Xyce::dout() <<
"TWO LEVEL Newton succeeded!" << std::endl;
1198 bool statusFull =
false;
1199 bool firstOuterStepTaken =
false;
1201 #ifdef Xyce_VERBOSE_NONLINEAR
1202 Xyce::dout() << std::endl <<
"Running algorithm 3:" << std::endl;
1233 #ifdef Xyce_VERBOSE_NONLINEAR
1254 if (firstOuterStepTaken)
1260 firstOuterStepTaken =
true;
1269 #ifdef Xyce_VERBOSE_NONLINEAR
1276 double twoNormJDXP_ = 0.0;
1281 #ifdef Xyce_VERBOSE_NONLINEAR
1282 Xyce::dout() << std::endl;
1283 Xyce::dout() <<
" 2-norm of voltage limiting vector: " << twoNormJDXP_ << std::endl;
1288 if (status > 0 && statInner>0 && voltLimStat) statusFull =
true;
1290 if (statusFull)
break;
1303 #ifdef Xyce_VERBOSE_NONLINEAR
1313 #ifdef Xyce_VERBOSE_NONLINEAR
1314 if (status >0 && statInner > 0 && statFinal > 0)
1316 Xyce::dout() <<
"TWO LEVEL Newton succeeded!" << std::endl;
1346 bool continuationLoop =
false;
1348 int contMaxTmp = 100;
1349 int stepsLeft = contMaxTmp;
1351 #ifdef Xyce_VERBOSE_NONLINEAR
1352 Xyce::dout() << std::endl <<
"Running algorithm 4:" << std::endl;
1353 Xyce::dout() << std::endl <<
"Initial continuation steps: ";
1354 Xyce::dout() << contMaxTmp << std::endl;
1370 double initVal = 0.0;
1371 double currVal = initVal;
1372 double prevVal = initVal;
1375 std::vector<std::string>::iterator iter;
1376 std::vector<std::string>::iterator begin =
paramNameList.begin ();
1377 std::vector<std::string>::iterator end =
paramNameList.end ();
1379 std::vector<double>::iterator iterFinalVal;
1380 std::vector<double>::iterator beginFinalVal =
paramFinalVal.begin ();
1381 std::vector<double>::iterator endFinalVal =
paramFinalVal.end ();
1383 std::vector<double>::iterator iterCurrentVal;
1384 std::vector<double>::iterator beginCurrentVal =
paramCurrentVal.begin ();
1388 for (iter=begin, iterFinalVal=beginFinalVal, iterCurrentVal=beginCurrentVal;
1390 ++iter, ++iterFinalVal, ++iterCurrentVal)
1393 *iterFinalVal = 1.0;
1401 for (iter=begin, iterFinalVal=beginFinalVal;
1403 ++iter, ++iterFinalVal)
1406 stepSizeEst = (*iterFinalVal-0.0)/(
static_cast<double>(contMaxTmp));
1411 #ifdef Xyce_VERBOSE_NONLINEAR
1412 Xyce::dout() <<
"Parameter = " << *iter;
1413 Xyce::dout() <<
" finalVal = " << *iterFinalVal << std::endl;
1417 bool continuationLoopFinished =
false;
1418 int numTotalFailures = 0;
1419 while (!continuationLoopFinished)
1421 bool stepFinished =
false;
1422 int numFailures = 0;
1424 while(!stepFinished)
1426 if (stepSizeEst != 0.0)
1428 stepsLeft =
static_cast<int>((*iterFinalVal-currVal)/stepSizeEst) + 1;
1435 #ifdef Xyce_VERBOSE_NONLINEAR
1436 Xyce::dout() << std::endl <<
"Continuation Step: " <<
contStep_;
1437 Xyce::dout() <<
" Estimated Remaining Steps: " << stepsLeft;
1438 Xyce::dout() <<
" " << *iter;
1439 Xyce::dout() << std::endl;
1440 Xyce::dout() <<
"currVal= " << currVal;
1441 Xyce::dout() <<
" prevVal= " << prevVal;
1442 Xyce::dout() <<
" step= " << stepSizeEst;
1443 Xyce::dout() << std::endl;
1448 std::string tmp =
"Continuation step estimate broken. Exiting\n";
1449 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1453 (*savedNextSolPtr_) = (**nextSolVectorPtrPtr_);
1457 *iterCurrentVal = currVal;
1472 successBool = (statNL > 0);
1476 stepFinished =
true;
1479 if (numFailures <= 0)
1485 if (numFailures < 0) numFailures = 0;
1488 currVal += stepSizeEst;
1490 if ( (*iterFinalVal >= 0 && currVal > *iterFinalVal) ||
1491 (*iterFinalVal < 0 && currVal < *iterFinalVal) )
1493 currVal = *iterFinalVal;
1494 stepSizeEst = currVal - prevVal;
1497 #ifdef Xyce_DEBUG_NONLINEAR
1498 Xyce::dout() <<
"\nRight before outputHOMOTOPY:" << std::endl;
1518 currVal = prevVal + stepSizeEst;
1529 continuationLoopFinished =
1530 ( (*iterFinalVal >= 0 && prevVal >= *iterFinalVal) ||
1531 (*iterFinalVal < 0 && prevVal <= *iterFinalVal) );
1535 #ifdef Xyce_VERBOSE_NONLINEAR
1536 Xyce::dout() <<
"currVal= " << currVal;
1537 Xyce::dout() <<
" prevVal= " << prevVal;
1538 Xyce::dout() << std::endl;
1539 Xyce::dout() << std::endl;
1540 Xyce::dout() <<
"Total number of failures = " << numTotalFailures << std::endl;
1541 Xyce::dout() <<
"Number of actual steps = " <<
contStep_-1;
1542 Xyce::dout() << std::endl;
1570 #ifdef Xyce_VERBOSE_NONLINEAR
1571 Xyce::dout() << std::endl <<
"Running algorithm 5:" << std::endl;
1611 Xyce::dout() << std::endl;
1612 Xyce::dout() <<
"tiaPtr is null. exiting" << std::endl; exit(0);
1621 if (doubleDCOPEnable && (tiaMode == 0) && (ddcopStep==0) )
1637 #ifdef Xyce_VERBOSE_NONLINEAR
1638 Xyce::dout() << std::endl;
1651 else if (algorithm == 1)
1656 else if (algorithm == 2)
1662 else if (algorithm == 3)
1666 else if (algorithm == 4)
1670 else if (algorithm == 5)
1677 "Two-Level Newton Algorithm set to invalid number.\n";
1678 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1687 #ifndef Xyce_PARALLEL_MPI
1692 "Two-Level Newton Algorithm failed to converge. Exiting.\n";
1693 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1726 bool bsuccess =
true;
1727 bool tmpBool =
true;
1729 char filename1[256];
1731 for (
int ich = 0; ich < 256; ++ich)
1732 { filename1[ich] = 0; }
1745 sprintf(filename1,
"%s",
"tmpJac.txt");
1746 N_LAS_Matrix *A =
lasSysPtr_->getJacobianMatrix();
1747 A->writeToFile(filename1);
1750 N_LAS_Vector *rhsVecPtr =
lasSysPtr_->getRHSVector();
1761 #ifdef Xyce_VERBOSE_NONLINEAR
1762 Xyce::dout() <<
"\n numCoupleTerms = " << numCoupleTerms << std::endl;
1765 for (iCouple=0;iCouple<numCoupleTerms;++iCouple)
1768 rhsVecPtr->putScalar(0.0);
1771 tmpBool =
loaderPtr_->loadCouplingRHS (iSubProblem, iCouple, rhsVecPtr );
1772 bsuccess = bsuccess && tmpBool;
1774 sprintf(filename1,
"dfdv%02d.txt", iCouple);
1775 rhsVecPtr->writeToFile(filename1);
1779 bsuccess = bsuccess && tmpBool;
1782 sprintf(filename1,
"dvdx%02d.txt", iCouple);
1783 newtVecPtr->writeToFile(filename1);
1788 *rhsVecPtr = *newtVecPtr;
1791 tmpBool =
loaderPtr_->calcCouplingTerms (iSubProblem, iCouple, rhsVecPtr);
1792 bsuccess = bsuccess && tmpBool;
1822 int suggestedSteps = 10;
1823 suggestedSteps =
loaderPtr_->enablePDEContinuation ();
1825 if (suggestedSteps < 1) suggestedSteps = 1;
1826 contMaxTmp = suggestedSteps;
1828 double stepSizeEst = 1.0/(
static_cast<double>(contMaxTmp));
1829 double currentAlpha = 0.0;
1830 double previousAlpha = 0.0;
1831 int stepsLeft = contMaxTmp;
1840 currentAlpha = stepSizeEst;
1845 bool continuationLoopFinished =
false;
1847 int numTotalFailures = 0;
1849 while (!continuationLoopFinished)
1851 bool stepFinished =
false;
1852 int numFailures = 0;
1854 while(!stepFinished)
1857 stepsLeft =
static_cast<int>((1.0-currentAlpha)/stepSizeEst) + 1;
1859 #ifdef Xyce_VERBOSE_NONLINEAR
1860 Xyce::dout() << std::endl <<
"Continuation Step: " <<
contStep_;
1861 Xyce::dout() <<
" Estimated Remaining Steps: " << stepsLeft;
1862 Xyce::dout() << std::endl;
1863 Xyce::dout() <<
"current alpha = " << currentAlpha;
1864 Xyce::dout() <<
" prev. alpha = " << previousAlpha;
1865 Xyce::dout() <<
" step = " << stepSizeEst;
1866 Xyce::dout() << std::endl;
1870 std::string tmp =
"Continuation step estimate broken. Exiting\n";
1871 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::USR_FATAL_0, tmp);
1875 (*savedNextSolPtr_) = (**nextSolVectorPtrPtr_);
1877 std::string paramName =
"pdealpha";
1878 loaderPtr_->setParam (paramName, currentAlpha);
1890 #ifdef Xyce_DEBUG_NONLINEAR
1891 Xyce::dout() <<
"Status of inner loop solve: " << statInner << std::endl;
1893 successBool = (statInner > 0);
1897 stepFinished =
true;
1899 if (numFailures <= 0)
1905 if (numFailures < 0) numFailures = 0;
1907 previousAlpha = currentAlpha;
1908 currentAlpha += stepSizeEst;
1910 if (currentAlpha > 1.0)
1913 stepSizeEst = currentAlpha - previousAlpha;
1921 (**nextSolVectorPtrPtr_) = (*savedNextSolPtr_);
1926 currentAlpha = previousAlpha + stepSizeEst;
1936 continuationLoopFinished = (previousAlpha >= 1.0);
1940 #ifdef Xyce_VERBOSE_NONLINEAR
1941 Xyce::dout() <<
"current alpha = " << currentAlpha;
1942 Xyce::dout() <<
" previous alpha = " << previousAlpha;
1943 Xyce::dout() << std::endl;
1944 Xyce::dout() << std::endl;
1945 Xyce::dout() <<
"Total number of failures = " << numTotalFailures << std::endl;
1946 Xyce::dout() <<
"Number of actual steps = " <<
contStep_-1;
1947 Xyce::dout() << std::endl;
1971 int suggestedSteps =
loaderPtr_->enablePDEContinuation ();
1981 Xyce::dout() <<
"suggested steps are: " << suggestedSteps << std::endl;
1983 std::list<N_UTL_Param>::iterator it_tpL;
1988 ExtendedString tmpTag = it_tpL->tag ();
1991 Xyce::dout() <<
"tmpTag = " << tmpTag << std::endl;
1993 if (tmpTag ==
"CONTINUATION")
1995 if (suggestedSteps <= 1)
1997 Xyce::dout() <<
"Setting the solver type to 0" << std::endl;
2040 #ifdef Xyce_VERBOSE_NONLINEAR
2041 Xyce::dout() << std::endl;
2042 Xyce::dout() << Xyce::section_divider << std::endl;
2043 Xyce::dout() <<
"TwoLevelNewton::enableSensitivity " << std::endl;
2045 bool bsuccess =
true;
2046 bool tmpBool =
true;
2056 #ifdef Xyce_VERBOSE_NONLINEAR
2058 double maxNormRHS_=0, twoNormRHS_ = 0.0;
2061 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2062 Xyce::dout() << std::endl;
2063 Xyce::dout() <<
"Max. norm of full Newton RHS: " << maxNormRHS_ << std::endl;
2064 Xyce::dout() <<
" 2-norm of full Newton RHS: " << twoNormRHS_ << std::endl;
2065 Xyce::dout() << Xyce::section_divider << std::endl;
2069 #ifdef Xyce_DEBUG_NONLINEAR
2070 static int callsSens = 0;
2071 char filename1[256];
for (
int ich = 0; ich < 256; ++ich) filename1[ich] = 0;
2072 char filename2[256];
for (
int ich = 0; ich < 256; ++ich) filename2[ich] = 0;
2074 sprintf(filename1,
"matrixTmp%d.txt",callsSens);
2075 N_LAS_Matrix *A =
lasSysPtr_->getJacobianMatrix();
2076 A->writeToFile(filename1);
2079 N_LAS_Vector *b =
lasSysPtr_->getRHSVector();
2080 sprintf(filename2,
"rhsTmp%d.txt", callsSens);
2084 #ifndef Xyce_PARALLEL_MPI
2085 fp1 = fopen(filename2,
"w");
2087 for (i=0;i<size;++i)
2089 double output = b->getElementByGlobalIndex(i);
2090 fprintf(fp1,
"%25.18e\n",output);
2095 N_LAS_Vector *x = (*nextSolVectorPtrPtr_);
2096 sprintf(filename2,
"solTmp%d.txt", callsSens);
2098 #ifndef Xyce_PARALLEL_MPI
2099 fp1 = fopen(filename2,
"w");
2101 for (i=0;i<size;++i)
2103 double output = x->getElementByGlobalIndex(i);
2104 fprintf(fp1,
"%25.18e\n",output);