47 #include <Xyce_config.h>
54 #include <N_ERH_ErrorMgr.h>
55 #include <N_IO_CmdParse.h>
56 #include <N_LAS_Builder.h>
57 #include <N_LAS_Matrix.h>
58 #include <N_LAS_Problem.h>
59 #include <N_LAS_Solver.h>
60 #include <N_LAS_System.h>
61 #include <N_LAS_Vector.h>
68 #include <N_PDS_Comm.h>
69 #include <N_UTL_FeatureTest.h>
70 #include <N_UTL_OptionBlock.h>
71 #include <N_UTL_Param.h>
87 const IO::CmdParse & cp)
91 loadJacobianFlag_(true),
93 searchDirectionPtr_(0),
95 delta_(pow(Util::MachineDependentParams::MachineEpsilon(), 0.67)),
105 constraintFactor_(1.0),
112 initialDeltaXTol(0.0),
251 <<
" Iter Step Wt DX Inf-Norm 2-Norm (rel)\n"
252 <<
" -------------------------------------------------------------------\n";
265 os << Xyce::section_divider << std::endl;
278 os <<
"Niter: " << std::fixed << step
279 <<
" " << std::setprecision(4) << std::scientific <<
stepLength_
280 <<
" " << std::setprecision(4) << std::scientific <<
wtNormDX_
281 <<
" " << std::setprecision(4) << std::scientific <<
maxNormRHS_
282 <<
" " << std::setprecision(4) << std::scientific <<
normRHS_rel_
303 (*nextSolVectorPtrPtr_)->maxValue(&tmp);
304 double solnNorm = fabs(tmp);
306 if ((
iNumCalls_ == 0) && (solnNorm <= Util::MachineDependentParams::DoubleMin()))
312 double newSoln, oldSoln;
314 int length = (*nextSolVectorPtrPtr_)->localLength();
315 for (
int i = 0; i < length; ++i)
317 newSoln = (*(*nextSolVectorPtrPtr_))[i];
318 oldSoln = (*(*currSolVectorPtrPtr_))[i];
352 static const char *trace =
"DampedNewton::solve: ";
377 #ifndef Xyce_SPICE_NORMS
389 if (VERBOSE_NONLINEAR)
394 Xyce::Report::UserWarning0() <<
"Use of the gradient strategy (1) is discouraged";
405 if (VERBOSE_NONLINEAR)
418 std::vector<int> index(1, -1);
429 if (
normRHS_ < Util::MachineDependentParams::MachineEpsilon())
457 int convergedStatus = 0;
458 while (convergedStatus == 0)
503 #ifdef Xyce_SPICE_NORMS
526 if (VERBOSE_NONLINEAR)
558 #ifndef Xyce_SPICE_NORMS
569 if (VERBOSE_NONLINEAR)
574 return convergedStatus;
594 static const char *trace =
"DampedNewton::takeFirstSolveStep: ";
611 if (VERBOSE_NONLINEAR)
616 Xyce::Report::UserWarning0() <<
"Use of the gradient strategy (1) is discouraged";
627 if (VERBOSE_NONLINEAR)
647 if (
normRHS_ < Util::MachineDependentParams::MachineEpsilon())
return 1;
668 int convergedStatus = 0;
710 #ifdef Xyce_SPICE_NORMS
733 if (VERBOSE_NONLINEAR)
754 #ifndef Xyce_SPICE_NORMS
769 return convergedStatus;
808 static const char *trace =
"DampedNewton::takeOneSolveStep";
833 int convergedStatus = 0;
876 #ifdef Xyce_SPICE_NORMS
899 if (VERBOSE_NONLINEAR)
920 if (DEBUG_NONLINEAR && convergedStatus > 0)
936 return convergedStatus;
1032 static const char *trace =
"DampedNewton::direction_: ";
1047 const double minRedFac = 0.999;
1057 const double minRedFac = 0.999;
1115 if (DEBUG_NONLINEAR)
1116 Xyce::Report::DevelFatal0().in(
"DampedNewton::direction_") <<
"Invalid search direction: " <<
static_cast<int>(
nlParams.
getDirection());
1141 static const char *trace =
"DampedNewton::computeStepLength_";
1198 static const char *trace =
"DampedNewton::divide__";
1202 const double oldNormRHS =
normRHS_;
1216 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1219 <<
"\toldNormRHS: " << oldNormRHS <<
", normRHS: " <<
normRHS_ << std::endl;
1223 bool searchDone = (
normRHS_ < oldNormRHS);
1230 if (
stepLength_ < Util::MachineDependentParams::MachineEpsilon())
1232 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1234 Xyce::Report::UserWarning0() <<
"\tStep size too small: " <<
stepLength_ <<
"\n\tTaking a full step.\n";
1249 searchDone = ((
normRHS_ < oldNormRHS) || (searchDone) ||
1252 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1255 <<
"\toldNormRHS: " << oldNormRHS <<
", normRHS: " <<
normRHS_ << std::endl;
1285 double sdotg = s.dotProduct(g);
1288 const double f = 0.5 * normrhs * normrhs;
1299 if (((sdotg >= 0) || (!issuffdec)) &&
1302 Xyce::lout() <<
"Switching to Cauchy!" << std::endl;
1304 s.scale(-1.0 / normrhs);
1305 sdotg = s.dotProduct(g);
1318 Xyce::lout() <<
"Linesearch failed!" << std::endl;
1342 double f = 0.5 * normrhs * normrhs;
1343 const double alpha = 1.0e-6;
1345 Xyce::dout().setf(std::ios::scientific);
1346 Xyce::dout().precision(10);
1348 Xyce::dout() <<
"\nIteration: " << 0
1350 <<
" F(X): " << finit
1351 <<
" gsinit: " << gsinit
1352 <<
" alpha * gsinit: " << alpha * gsinit
1356 const int nstepmax = 20;
1357 const double minstep = Util::MachineDependentParams::MachineEpsilon();
1361 bool issuffdec =
false;
1365 if (nstep >= nstepmax)
1386 f = 0.5 * normrhs * normrhs;
1389 issuffdec = (f <= (finit + (alpha * step * gsinit)));
1394 Xyce::dout() <<
"Iteration: " << nstep
1395 <<
" Step: " << step
1397 <<
" Test: " << (finit + (alpha * step * gsinit))
1401 Xyce::dout().unsetf(std::ios::scientific);
1416 static const char *trace =
"DampedNewton::computeStepLength_";
1420 const double oldNormRHS =
normRHS_;
1436 double rho, delta, theta, lambda;
1437 const double t = 1.0e-04, thetaMin = 0.1, thetaMax = 0.5;
1438 const double minStep = pow(Util::MachineDependentParams::MachineEpsilon(), 0.33);
1449 while ((rho > 1.0 - t * lambda) &&
1452 delta = rho * rho - 1.0 + 2.0 * lambda;
1457 theta = lambda / delta;
1459 if (theta > thetaMax)
1461 else if (theta < thetaMin)
1482 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1485 <<
"\toldNormRHS: " << oldNormRHS <<
", normRHS: " <<
normRHS_ << std::endl;
1489 return (rho <= 1.0 - t * lambda);
1545 (*nextSolVectorPtrPtr_)->putScalar(0.0);
1574 static const char * trace =
"DampedNewton::evalModNewton_";
1576 const double minConvFactor = 0.01;
1578 const double etaMax = 1.0;
1579 const double etaMin = 1.0e-12;
1580 const double etaInit = 1.0e-01;
1594 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1596 Util::Param linRes(
"RESIDUAL", 0.0 );
1598 Xyce::dout() <<
"\tnlResNorm: " << nlResNorm <<
" linRes: " << linRes.getImmutableValue<
double>()
1599 <<
"nlResNormOld: " <<
nlResNormOld <<
"calculated eta: " << eta << std::endl;
1605 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1606 Xyce::dout() <<
"\t\teta:\t" << eta <<
"\n" << std::endl;
1610 if (eta < minConvFactor)
1615 if (VERBOSE_NONLINEAR) {
1617 Xyce::lout() <<
" ***** Calculating new Jacobian and preconditioner\n" << std::endl;
1619 Xyce::lout() <<
" ***** Using old Jacobian and preconditioner\n" << std::endl;
1657 static const char *trace =
"DampedNewton::converged_";
1659 const double rhsTol = Util::MachineDependentParams::MachineEpsilon();
1660 const double convRateMax = 0.5 * Util::MachineDependentParams::DoubleMax();
1661 const double minResReduct = 9.0e-1;
1662 const double stagnationTol = 1.0e-3;
1673 if (!allDevicesConverged_ &&
1682 if (!innerDevicesConverged_ )
1726 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1727 Xyce::dout() <<
"\tcount:\t" <<
count << std::endl
1728 <<
"\tresConvRate_:\t" <<
resConvRate_ <<
"\n" << std::endl;
1738 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1739 Xyce::dout() <<
"\ttmpConvRate: " <<
tmpConvRate << std::endl
1741 <<
"\tReturning 3\n" << std::endl;
1747 if (DEBUG_NONLINEAR &&
debugTimeFlag_ && isActive(Diag::NONLINEAR_PARAMETERS) )
1748 Xyce::dout() <<
"\ttmpConvRate: " <<
tmpConvRate << std::endl
1750 <<
"\tReturning -3\n" << std::endl;
1795 if (DEBUG_NONLINEAR)
1796 Xyce::dout() <<
"DampedNewton::constrain_: minValue: " << minValue << std::endl;
1798 if (VERBOSE_NONLINEAR && minValue < 1.0)
1799 Xyce::lout() <<
" ***** Constraining:\t" << minValue << std::endl;
1816 const double etaExp = 0.5 * (1.0 + sqrt(5.0));
1817 const double etaMax = 0.1;
1818 const double etaMin = 1.0e-12;
1819 const double etaInit = 1.0e-01;
1829 else if (
nlResNormOld > Util::MachineDependentParams::DoubleMin())
1831 Util::Param linRes(
"RESIDUAL", 0.0 );
1833 eta = fabs(nlResNorm - linRes.getImmutableValue<
double>()) /
nlResNormOld;
1837 etaSafe = pow(
etaOld, etaExp);
1839 eta = std::max(eta, etaSafe);
1842 eta = std::min(etaMax, eta);
1845 eta = std::max(etaMin, eta);
1847 if (DEBUG_NONLINEAR)
1848 Xyce::dout() <<
"\tnlResNorm: " << nlResNorm
1849 <<
" linRes: " << linRes.getImmutableValue<
double>()
1851 <<
" calculated eta: " << fabs(nlResNorm - linRes.getImmutableValue<
double>())/
nlResNormOld << std::endl;
1860 if (VERBOSE_NONLINEAR)
1861 Xyce::lout() <<
"\t\teta:\t" << eta <<
"\n" << std::endl;
1889 Xyce::lout() <<
"THIS IS BROKEN. DO NOT USE THIS METHOD" << std::endl;
1904 Xyce::lout() <<
"THIS IS BROKEN. DO NOT USE THIS METHOD" << std::endl;
void debugOutput3(Linear::Vector &dxVector, Linear::Vector &xVector)
double getThetaChange() const
bool simpleBt_(double gsinit, double finit)
Pure virtual class to augment a linear system.
double getSmallUpdateTol() const
void setForcingTerm(double value)
bool getCurrentParams(NLParams &nlp)
unsigned getMaxNewtonStep() const
Linear::Matrix * dFdxTestMatrixPtr_
void printStepInfo_(std::ostream &os, int step)
Linear::Vector ** tmpSolVectorPtrPtr_
Linear::Vector * rhsVectorPtr_
AnalysisMode getAnalysisMode() const
int getDebugLevel() const
bool innerDevicesConverged(Parallel::Machine comm)
double resConvRate_
Convergence Rate.
Linear::Vector * gradVectorPtr_
int getParameterNumber() const
virtual bool initializeAll()
bool allDevicesConverged(Parallel::Machine comm)
Linear::Matrix * jacobianMatrixPtr_
void setForcing_(const double)
bool addParameterSet(AnalysisMode mode, NLParams &nlp)
N_PDS_Manager * pdsMgrPtr_
bool setHBOptions(const Util::OptionBlock &OB)
Direction getDirection() const
void updateThetaBoundNeg(const Linear::Vector *oldSoln, const Linear::Vector *solnUpdate)
const Analysis::AnalysisManager & getAnalysisManager() const
LineSearchMethod getSearchMethod() const
Linear::System * lasSysPtr_
void setDebugFlags(int output_step_number, double time)
Linear::Vector ** nextSolVectorPtrPtr_
double getForcingTerm() const
void setDeltaXTol(double Tolerance)
void debugOutput1(Linear::Matrix &jacobian, Linear::Vector &rhs)
double getThetaBoundNeg() const
Linear::Solver * lasSolverPtr_
bool getConstraintBT() const
void resetCountersAndTimers_()
const IO::CmdParse & commandLine_
void updateThetaChange(const Linear::Vector *oldSoln, const Linear::Vector *solnUpdate)
Linear::Vector * fdxVLVectorPtr_
Linear::Vector * jdxVLVectorPtr_
void setDirection(Direction value)
void printHeader_(std::ostream &os)
Linear::Vector * searchDirectionPtr_
Pointer to direction vector.
bool getLinearOpt() const
Linear::Matrix * jacTestMatrixPtr_
int takeFirstSolveStep(NonLinearSolver *nlsTmpPtr=NULL)
Linear::Vector * solWtVectorPtr_
Linear::Vector * dxVoltlimVectorPtr_
bool setTranOptions(const Util::OptionBlock &OB)
DampedNewton(const IO::CmdParse &cp)
Linear::Vector * NewtonVectorPtr_
Linear::Vector * tmpVectorPtr_
double getDeltaXTol() const
Linear::Vector * qdxVLVectorPtr_
double getThetaBoundPos() const
int solve(NonLinearSolver *nlsTmpPtr=NULL)
NLStrategy getNLStrategy() const
Linear::Matrix * dQdxTestMatrixPtr_
bool isFirstContinuationParam() const
bool setOptions(const Util::OptionBlock &OB)
ConstraintBT * nlConstraintPtr_
Constraint object pointer.
ParamMgr * nonlinearParameterManager_
bool setOptions(const Util::OptionBlock &OB)
bool getEnforceDeviceConvFlag() const
bool getForcingFlag() const
Loader::NonlinearEquationLoader * loaderPtr_
bool getLinearSystemFlag() const
void updateThetaBoundPos(const Linear::Vector *oldSoln, const Linear::Vector *solnUpdate)
bool initializeAll(Linear::System *lasSysPtr, const NLParams &nlParams)
unsigned getMaxSearchStep() const
void printFooter_(std::ostream &os)
bool computeStepLength_()
int getContinuationStep() const