74 #define ASSERT(expr) assert(expr)
75 #define TRACE(expr) silent_cerr(__FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << ":" << expr)
77 #define TRACE(expr) static_cast<void>(0)
80 #define TRACE_VAR(varname) TRACE(#varname "=" << (varname) << std::endl)
81 #define TRACE_FLAG(varname, flag) TRACE(#varname "&" #flag "=" << ((varname) & (flag)) << std::endl)
93 uFlags(DIVERGENCE_CHECK
97 | ABORT_AT_LAMBDA_MIN)
167 const integer iMaxIterRebuild = 10;
176 silent_cout(
"NewtonRaphsonSolver: "
177 "rebuilding matrix..."
185 }
while (++iIter < iMaxIterRebuild);
187 if (iIter >= iMaxIterRebuild) {
188 silent_cerr(
"Maximum number of iterations exceeded when rebuilding the Jacobian matrix" << std::endl);
195 if (!bParallel || MBDynComm.Get_rank() == 0)
199 silent_cout(
"Jacobian:" << std::endl
218 if (dNormSol > stpmax) {
221 silent_cerr(
"line search warning: "
222 "Newton increment is reduced by factor " << dScale
224 <<
" at iteration " << iIterCnt
225 <<
" The time step is probably too large" << std::endl);
244 silent_cerr(
"line search warning: slope=" << slope <<
" >= 0"
246 <<
" at iteration " << iIterCnt << std::endl
247 <<
"This could be a roundoff problem" << std::endl);
261 if (dLambdaMinEff < 0) {
297 TRACE(
"Start new step from Xold, XPold with lambda = " << lambda <<
" ..." << std::endl);
305 dXneg(i) = -(*pSol)(i);
307 TRACE(
"Update the nonlinear problem ... pSol->Norm()=" <<
pSol->
Norm() << std::endl);
314 TRACE(
"New value for f:" << f << std::endl);
321 if (!bParallel || MBDynComm.Get_rank() == 0)
324 silent_cout(
"\t\tf(" << iIterCnt <<
":" << iIter <<
")=" << std::setw(12) << f
325 <<
"\tErr=" << std::setw(12) << dErr
326 <<
"\tlambda=" << std::setw(12) << lambda
327 <<
"\tslope=" << slope << std::endl);
333 if (f <= fold +
dAlpha * lambda * slope) {
334 TRACE(
"Sufficient decrease in f: backtrack" << std::endl);
336 }
else if (lambda <= dLambdaMinEff) {
337 TRACE(
"Checking for convergence: lambda=" << lambda <<
" < lambdaMin=" << dLambdaMinEff << std::endl);
342 TRACE(
"Calculate new value for alam ..." << std::endl);
344 tmplam = -slope / (2 * (f - fold - slope));
347 const doublereal rhs1 = f - fold - lambda * slope;
348 const doublereal rhs2 = f2 - fold - lambda2 * slope;
349 const doublereal a = (rhs1 / (lambda * lambda) - rhs2 / (lambda2 * lambda2)) / (lambda - lambda2);
350 const doublereal b = (-lambda2 * rhs1 / (lambda * lambda) + lambda * rhs2 / (lambda2 * lambda2)) / (lambda - lambda2);
353 tmplam = -slope / (2. * b);
356 const doublereal disc = b * b - 3. * a * slope;
359 tmplam = 0.5 * lambda;
361 }
else if (b <= 0.) {
362 tmplam = (-b +
sqrt(disc)) / (3. * a);
365 tmplam = -slope / (b +
sqrt(disc));
369 if (tmplam > 0.5 * lambda) {
370 tmplam = 0.5 * lambda;
390 silent_cerr(
"line search warning: Maximum number of line search iterations="
392 <<
" exceeded in line search at time step " <<
pDM->
dGetTime()
393 <<
" at iteration " << iIterCnt << std::endl);
412 pNLP = pNonLinProblem;
418 TRACE(
"Resize temporary vectors ..." << std::endl);
432 TRACE(
"\t\tf(0) = " << f << std::endl);
435 doublereal dPrevErr = std::numeric_limits<doublereal>::max();
440 if (!bParallel || MBDynComm.Get_rank() == 0)
443 silent_cout(
"\tIteration(" << iIterCnt <<
") " << std::setw(12) << dErr);
446 silent_cout(
" f=" << std::setw(12) << f);
449 silent_cout(std::endl);
461 : std::numeric_limits<doublereal>::max();
465 doublereal dStartTimeCPU, dEndTimeCPU, dJacobianCPU, dResidualCPU, dLinSolveCPU;
483 dJacobianCPU = dEndTimeCPU - dStartTimeCPU;
485 dStartTimeCPU = dEndTimeCPU;
494 dLinSolveCPU = dEndTimeCPU - dStartTimeCPU;
512 dResidualCPU = dEndTimeCPU - dStartTimeCPU;
517 dErrFactor *= dErr / dPrevErr;
523 if (!bParallel || MBDynComm.Get_rank() == 0)
528 silent_cout(
"\tIteration(" << iIterCnt <<
") " << std::setw(12) << dErr <<
" J");
532 silent_cout(
" cond=");
552 silent_cout(
" f=" << std::setw(12) << f);
555 silent_cout(
" Err(n-1)=" << std::setw(12) << dPrevErr
556 <<
" Err(n)/Err(n-1)=" << std::setw(12) << dErr / dPrevErr
557 <<
" Err(n)/Err(1)=" << std::setw(12) << dErrFactor);
563 || (
uFlags & PRINT_CONVERGENCE_INFO)) {
564 silent_cout(std::endl);
577 if (!bParallel || MBDynComm.Get_rank() == 0)
580 silent_cout(
"\t\tSolErr "
581 << dSolErr << std::endl);
587 silent_cerr(
"line search warning: Convergence on solution "
589 <<
"at iteration " << iIterCnt
590 <<
"\tErr(n)=" << dErr);
593 silent_cerr(
"\tErr(n-1)=" << dPrevErr
594 <<
"\tErr(n)/Err(n-1)=" << dErr/dPrevErr
595 <<
"\tErr(n)/Err(1) " << dErrFactor);
598 silent_cerr(std::endl);
610 const doublereal temp = std::abs(
g(i)) * std::max(absX, 1.) / den;
618 silent_cerr(
"line search warning: Zero gradient detected at time step "
620 << iIterCnt <<
" (spurious convergence) test=" << test
622 <<
"\tErr(n)=" << dErr
623 <<
" > Tol = " << Tol << std::endl);
633 silent_cerr(
"line search warning: lambda min"
634 " has been reached at time step " <<
pDM->
dGetTime()
635 <<
" at iteration " << iIterCnt
636 <<
" but the gradient is not zero" << std::endl);
643 }
else if (dErr > dPrevErr) {
647 silent_cerr(
"line search warning: f has been reduced during line search but the residual could not be reduced at time step "
649 <<
" at iteration " << iIterCnt << std::endl);
663 silent_cerr(
"line search warning: The residual could not be decreased"
665 <<
" at iteration " << iIterCnt << std::endl);
668 silent_cerr(
"Err(n-1)=" << dPrevErr
669 <<
"\tErr(n)=" << dErr
670 <<
"\tErr(n)/Err(n-1)=" << dErr/dPrevErr
671 <<
"\tErr(n)/Err(1)=" << dErrFactor << std::endl);
678 if (iIterCnt >= std::abs(iMaxIter)) {
679 if (iMaxIter < 0 && dErrFactor < 1.) {
virtual void Reset(void)=0
virtual VectorHandler * pResHdl(void) const =0
void Solve(const NonlinearProblem *pNLP, Solver *pS, const integer iMaxIter, const doublereal &Tol, integer &iIterCnt, doublereal &dErr, const doublereal &SolTol, doublereal &dSolErr)
bool outputMatrixConditionNumber(void) const
virtual SolutionManager * pGetSolutionManager(void) const
void AddCond(doublereal dCond)
virtual void Jacobian(MatrixHandler *pJac) const =0
doublereal dGetCondMax() const
virtual integer iGetNumCols(void) const =0
bool outputIters(void) const
#define MBDYN_EXCEPT_ARGS
bool outputBailout(void) const
MatrixHandler::Norm_t GetCondMatNorm(void) const
virtual bool MakeSolTest(Solver *pS, const VectorHandler &Vec, const doublereal &dTol, doublereal &dTest)
virtual void PrintResidual(const VectorHandler &Res, integer iIterCnt) const
virtual bool MakeResTest(Solver *pS, const NonlinearProblem *pNLP, const VectorHandler &Vec, const doublereal &dTol, doublereal &dTest, doublereal &dTestDiff)
doublereal dGetTime(void) const
double mbdyn_clock_time()
virtual VectorHandler & MatTVecDecMul(VectorHandler &out, const VectorHandler &in) const
virtual void CheckTimeStepLimit(doublereal dErr, doublereal dErrDiff) const
virtual doublereal InnerProd(const VectorHandler &VH) const
doublereal dGetCondAvg() const
void LineSearch(doublereal stpmax, doublereal fold, doublereal &f, bool &check, const integer &iIterCnt)
bool outputRes(void) const
virtual void Residual(VectorHandler *pRes) const =0
bool outputJac(void) const
doublereal dGetCondMin() const
virtual doublereal Dot(void) const
virtual integer iGetSize(void) const =0
virtual doublereal Norm(void) const
doublereal dGetTimeCPU(CPUTimeType eType) const
bool outputSolverConditionNumber(void) const
const NonlinearProblem * pNLP
virtual doublereal ConditionNumber(enum Norm_t eNorm=NORM_1) const
virtual void Resize(integer iSize)
const DataManager *const pDM
int mbdyn_stop_at_end_of_iteration(void)
virtual integer iGetSize(void) const
bool outputSol(void) const
doublereal dDivergenceCheck
void Residual(doublereal &f, integer iIterCnt)
virtual MatrixHandler * pMatHdl(void) const =0
#define TRACE_FLAG(varname, flag)
const VectorHandler * GetpXPCurr(void) const
virtual VectorHandler & ScalarMul(const VectorHandler &VH, const doublereal &d)
virtual void MatrReset(void)=0
void AddTimeCPU(doublereal dTime, CPUTimeType eType)
virtual void Solve(void)=0
#define ASSERT(expression)
const VectorHandler * GetpXCurr(void) const
GradientExpression< UnaryExpr< FuncSqrt, Expr > > sqrt(const GradientExpression< Expr > &u)
virtual void MatrInitialize(void)
#define TRACE_VAR(varname)
LineSearchSolver(DataManager *pDM, const NonlinearSolverOptions &options, const struct LineSearchParameters ¶m)
bool bGetConditionNumber(doublereal &dCond) const
virtual void PrintSolution(const VectorHandler &Sol, integer iIterCnt) const
bool outputCPUTime(void) const
static const doublereal a
doublereal dLambdaFactMin
virtual VectorHandler * pSolHdl(void) const =0
virtual void Update(const VectorHandler *pSol) const =0
bool outputSolverConditionStat(void) const
virtual integer iGetNumRows(void) const =0