MooseNonlinearConvergenceReason ReferenceResidualProblem::checkNonlinearConvergence(std::string &msg, const int it, const Real xnorm, const Real snorm, const Real fnorm, const Real rtol, const Real stol, const Real abstol, const int nfuncs, const int max_funcs, const Real ref_resid, const Real /*div_threshold*/) { updateReferenceResidual(); if (_solnVars.size() > 0) { Moose::out<<"Solution, reference convergence variable norms:"<<std::endl; unsigned int maxwsv=0; unsigned int maxwrv=0; for (unsigned int i=0; i<_solnVars.size(); ++i) { if (_solnVarNames[i].size() > maxwsv) maxwsv = _solnVarNames[i].size(); if (_refResidVarNames[i].size() > maxwrv) maxwrv = _refResidVarNames[i].size(); } for (unsigned int i=0; i<_solnVars.size(); ++i) { Moose::out<<std::setw(maxwsv+2)<<std::left<<_solnVarNames[i]+":"<<_resid[i]<<" "<<std::setw(maxwrv+2)<<_refResidVarNames[i]+":"<<_refResid[i]<<std::endl; } } NonlinearSystem & system = getNonlinearSystem(); MooseNonlinearConvergenceReason reason = MOOSE_NONLINEAR_ITERATING; std::stringstream oss; if (fnorm != fnorm) { oss << "Failed to converge, function norm is NaN\n"; reason = MOOSE_DIVERGED_FNORM_NAN; } else if (fnorm < abstol) { oss << "Converged due to function norm " << fnorm << " < " << abstol << std::endl; reason = MOOSE_CONVERGED_FNORM_ABS; } else if (nfuncs >= max_funcs) { oss << "Exceeded maximum number of function evaluations: " << nfuncs << " > " << max_funcs << std::endl; reason = MOOSE_DIVERGED_FUNCTION_COUNT; } if (it && !reason) { if (checkConvergenceIndividVars(fnorm, abstol, rtol, ref_resid)) { if (_resid.size() > 0) oss << "Converged due to function norm " << " < " << " (relative tolerance) or (absolute tolerance) for all solution variables" << std::endl; else oss << "Converged due to function norm " << fnorm << " < " << " (relative tolerance)" << std::endl; reason = MOOSE_CONVERGED_FNORM_RELATIVE; } else if (it >= _accept_iters && checkConvergenceIndividVars(fnorm, abstol*_accept_mult, rtol*_accept_mult, ref_resid)) { if (_resid.size() > 0) oss << "Converged due to function norm " << " < " << " (acceptable relative tolerance) or (acceptable absolute tolerance) for all solution variables" << std::endl; else oss << "Converged due to function norm " << fnorm << " < " << " (acceptable relative tolerance)" << std::endl; Moose::out<<"ACCEPTABLE"<<std::endl; reason = MOOSE_CONVERGED_FNORM_RELATIVE; } else if (snorm < stol*xnorm) { oss << "Converged due to small update length: " << snorm << " < " << stol << " * " << xnorm << std::endl; reason = MOOSE_CONVERGED_SNORM_RELATIVE; } } system._last_nl_rnorm = fnorm; system._current_nl_its = it; msg = oss.str(); // Moose::out<<msg<<std::endl; //Print convergence diagnostic message return(reason); }
bool FrictionalContactProblem::updateSolution(NumericVector<Number>& vec_solution, NumericVector<Number>& ghosted_solution) { bool solution_modified(false); solution_modified |= enforceRateConstraint(vec_solution, ghosted_solution); unsigned int nfc = numLocalFrictionalConstraints(); std::vector<SlipData> iterative_slip; unsigned int dim = getNonlinearSystem().subproblem().mesh().dimension(); iterative_slip.reserve(nfc*dim); if (_do_slip_update) { updateReferenceResidual(); updateContactReferenceResidual(); _console<<"Slip Update: "<<_num_slip_iterations<<std::endl; _console<<"Iter #Cont #Slip #TooFar Slip resid Inc Slip It Slip"<<std::endl; for (int i=0; i<_slip_updates_per_iter; i++) { _console<<std::left<<std::setw(6)<<i+1; bool updated_this_iter = calculateSlip(ghosted_solution, &iterative_slip); _console<<std::setw(10)<<_num_contact_nodes <<std::setw(10)<<_num_slipping <<std::setw(10)<<_num_slipped_too_far <<std::setprecision(4)<<std::setw(12)<<_slip_residual <<std::setw(12)<<_inc_slip_norm <<std::setw(12)<<_it_slip_norm; if (updated_this_iter) { if (_slip_residual < _target_contact_residual || _slip_residual < _target_relative_contact_residual*_refResidContact) { _console<<" Converged: Slip resid < tolerance, not applying this slip update"<<std::endl; break; } else { _console<<std::endl; applySlip(vec_solution, ghosted_solution, iterative_slip); } } else { _console<<" Converged: No slipping nodes"<<std::endl; break; } solution_modified |= updated_this_iter; } _num_slip_iterations++; _do_slip_update = false; _num_nl_its_since_contact_update = 0; } return solution_modified; }