Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}