コード例 #1
0
bool
FrictionalContactProblem::calculateSlip(const NumericVector<Number>& ghosted_solution,
                                        std::vector<SlipData> * iterative_slip)
{
    NonlinearSystem & nonlinear_sys = getNonlinearSystem();
    unsigned int dim = nonlinear_sys.subproblem().mesh().dimension();

    MooseVariable * residual_x_var = &getVariable(0,_residual_x);
    MooseVariable * residual_y_var = &getVariable(0,_residual_y);
    MooseVariable * residual_z_var = NULL;
    MooseVariable * diag_stiff_x_var = &getVariable(0,_diag_stiff_x);
    MooseVariable * diag_stiff_y_var = &getVariable(0,_diag_stiff_y);
    MooseVariable * diag_stiff_z_var = NULL;
    MooseVariable * inc_slip_x_var = &getVariable(0,_inc_slip_x);
    MooseVariable * inc_slip_y_var = &getVariable(0,_inc_slip_y);
    MooseVariable * inc_slip_z_var = NULL;
    if (dim == 3)
    {
        residual_z_var = &getVariable(0,_residual_z);
        diag_stiff_z_var = &getVariable(0,_diag_stiff_z);
        inc_slip_z_var = &getVariable(0,_inc_slip_z);
    }

    bool updatedSolution = false;
    _slip_residual = 0.0;
    _it_slip_norm = 0.0;
    _inc_slip_norm = 0.0;
    TransientNonlinearImplicitSystem & system = getNonlinearSystem().sys();

    if (iterative_slip)
        iterative_slip->clear();

    if (getDisplacedProblem() && _interaction_params.size() > 0)
    {
        computeResidual(system, ghosted_solution, *system.rhs);

        _num_contact_nodes = 0;
        _num_slipping = 0;
        _num_slipped_too_far = 0;

        GeometricSearchData & displaced_geom_search_data = getDisplacedProblem()->geomSearchData();
        std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *> * penetration_locators = &displaced_geom_search_data._penetration_locators;

        AuxiliarySystem & aux_sys = getAuxiliarySystem();
        const NumericVector<Number> & aux_solution = *aux_sys.currentSolution();

        for (std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *>::iterator plit = penetration_locators->begin();
                plit != penetration_locators->end();
                ++plit)
        {
            PenetrationLocator & pen_loc = *plit->second;
            std::set<dof_id_type> & has_penetrated = pen_loc._has_penetrated;

            bool frictional_contact_this_interaction = false;

            std::map<std::pair<int,int>,InteractionParams>::iterator ipit;
            std::pair<int,int> ms_pair(pen_loc._master_boundary,pen_loc._slave_boundary);
            ipit = _interaction_params.find(ms_pair);
            if (ipit != _interaction_params.end())
                frictional_contact_this_interaction = true;

            if (frictional_contact_this_interaction)
            {

                InteractionParams & interaction_params = ipit->second;
                Real slip_factor = interaction_params._slip_factor;
                Real slip_too_far_factor = interaction_params._slip_too_far_factor;
                Real friction_coefficient = interaction_params._friction_coefficient;


                std::vector<dof_id_type> & slave_nodes = pen_loc._nearest_node._slave_nodes;

                for (unsigned int i=0; i<slave_nodes.size(); i++)
                {
                    dof_id_type slave_node_num = slave_nodes[i];

                    if (pen_loc._penetration_info[slave_node_num])
                    {
                        PenetrationInfo & info = *pen_loc._penetration_info[slave_node_num];
                        const Node * node = info._node;

                        if (node->processor_id() == processor_id())
                        {

                            std::set<dof_id_type>::iterator hpit = has_penetrated.find(slave_node_num);

                            if (hpit != has_penetrated.end())
                            {
                                _num_contact_nodes++;

                                VectorValue<dof_id_type> residual_dofs(node->dof_number(aux_sys.number(), residual_x_var->number(), 0),
                                                                       node->dof_number(aux_sys.number(), residual_y_var->number(), 0),
                                                                       (residual_z_var ? node->dof_number(aux_sys.number(), residual_z_var->number(), 0) : 0));

                                VectorValue<dof_id_type> diag_stiff_dofs(node->dof_number(aux_sys.number(), diag_stiff_x_var->number(), 0),
                                        node->dof_number(aux_sys.number(), diag_stiff_y_var->number(), 0),
                                        (diag_stiff_z_var ? node->dof_number(aux_sys.number(), diag_stiff_z_var->number(), 0) : 0));

                                VectorValue<dof_id_type> inc_slip_dofs(node->dof_number(aux_sys.number(), inc_slip_x_var->number(), 0),
                                                                       node->dof_number(aux_sys.number(), inc_slip_y_var->number(), 0),
                                                                       (inc_slip_z_var ? node->dof_number(aux_sys.number(), inc_slip_z_var->number(), 0) : 0));

                                RealVectorValue res_vec;
                                RealVectorValue stiff_vec;
                                RealVectorValue slip_inc_vec;

                                for (unsigned int i=0; i<dim; ++i)
                                {
                                    res_vec(i) = aux_solution(residual_dofs(i));
                                    stiff_vec(i) = aux_solution(diag_stiff_dofs(i));
                                    slip_inc_vec(i) = aux_solution(inc_slip_dofs(i));
                                }

                                RealVectorValue slip_iterative(0.0,0.0,0.0);
                                Real interaction_slip_residual = 0.0;
//                _console<<"inc  slip: "<<slip_inc_vec<<std::endl;
//                _console<<"info slip: "<<info._incremental_slip<<std::endl;
//                ContactState state = calculateInteractionSlip(slip_iterative, interaction_slip_residual, info._normal, res_vec, info._incremental_slip, stiff_vec, friction_coefficient, slip_factor, slip_too_far_factor, dim);
                                ContactState state = calculateInteractionSlip(slip_iterative, interaction_slip_residual, info._normal, res_vec, slip_inc_vec, stiff_vec, friction_coefficient, slip_factor, slip_too_far_factor, dim);
//                _console<<"iter slip: "<<slip_iterative<<std::endl;
                                _slip_residual += interaction_slip_residual*interaction_slip_residual;

                                if (state == SLIPPING || state == SLIPPED_TOO_FAR)
                                {
                                    _num_slipping++;
                                    if (state == SLIPPED_TOO_FAR)
                                        _num_slipped_too_far++;
                                    for (unsigned int i=0; i<dim; ++i)
                                    {
                                        SlipData sd(node,i,slip_iterative(i));
                                        if (iterative_slip)
                                            iterative_slip->push_back(sd);
                                        _it_slip_norm += slip_iterative(i)*slip_iterative(i);
                                        _inc_slip_norm += (slip_inc_vec(i)+slip_iterative(i))*(slip_inc_vec(i)+slip_iterative(i));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        _communicator.sum(_num_contact_nodes);
        _communicator.sum(_num_slipping);
        _communicator.sum(_num_slipped_too_far);
        _communicator.sum(_slip_residual);
        _slip_residual = std::sqrt(_slip_residual);
        _communicator.sum(_it_slip_norm);
        _it_slip_norm = std::sqrt(_it_slip_norm);
        _communicator.sum(_inc_slip_norm);
        _inc_slip_norm = std::sqrt(_inc_slip_norm);
        if (_num_slipping > 0)
            updatedSolution = true;
    }

    return updatedSolution;
}
コード例 #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;
}
コード例 #3
0
bool
FrictionalContactProblem::enforceRateConstraint(NumericVector<Number>& vec_solution, NumericVector<Number>& ghosted_solution)
{
    NonlinearSystem & nonlinear_sys = getNonlinearSystem();
    unsigned int dim = nonlinear_sys.subproblem().mesh().dimension();

    _displaced_problem->updateMesh(ghosted_solution, *_aux.currentSolution());

    MooseVariable * disp_x_var = &getVariable(0,_disp_x);
    MooseVariable * disp_y_var = &getVariable(0,_disp_y);
    MooseVariable * disp_z_var = NULL;
    if (dim == 3)
        disp_z_var = &getVariable(0,_disp_z);

    bool updatedSolution = false;

    if (getDisplacedProblem() && _interaction_params.size() > 0)
    {
        GeometricSearchData & displaced_geom_search_data = getDisplacedProblem()->geomSearchData();
        std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *> * penetration_locators = &displaced_geom_search_data._penetration_locators;

        for (std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *>::iterator plit = penetration_locators->begin();
                plit != penetration_locators->end();
                ++plit)
        {
            PenetrationLocator & pen_loc = *plit->second;
            std::set<dof_id_type> & has_penetrated = pen_loc._has_penetrated;

            bool frictional_contact_this_interaction = false;

            std::map<std::pair<int,int>,InteractionParams>::iterator ipit;
            std::pair<int,int> ms_pair(pen_loc._master_boundary,pen_loc._slave_boundary);
            ipit = _interaction_params.find(ms_pair);

            if (ipit != _interaction_params.end())
                frictional_contact_this_interaction = true;

            if (frictional_contact_this_interaction)
            {
                std::vector<dof_id_type> & slave_nodes = pen_loc._nearest_node._slave_nodes;

                for (unsigned int i=0; i<slave_nodes.size(); i++)
                {
                    dof_id_type slave_node_num = slave_nodes[i];

                    if (pen_loc._penetration_info[slave_node_num])
                    {
                        PenetrationInfo & info = *pen_loc._penetration_info[slave_node_num];

                        std::set<dof_id_type>::iterator hpit = has_penetrated.find(slave_node_num);

                        if (hpit != has_penetrated.end())
                        {
//              _console<<"Slave node: "<<slave_node_num<<std::endl;
                            const Node * node = info._node;

                            VectorValue<dof_id_type> solution_dofs(node->dof_number(nonlinear_sys.number(), disp_x_var->number(), 0),
                                                                   node->dof_number(nonlinear_sys.number(), disp_y_var->number(), 0),
                                                                   (disp_z_var ? node->dof_number(nonlinear_sys.number(), disp_z_var->number(), 0) : 0));

                            //Get old parametric coords from info
                            //get old element from info
                            //Apply current configuration to that element and find xyz coords of that point
                            //find xyz coords of current point from original coords and displacement vector
                            //calculate difference between those two point coordinates to get correction

//              std::vector<Point>points(1);
//              points[0] = info._starting_closest_point_ref;
//              Elem *side = (info._starting_elem->build_side(info._starting_side_num,false)).release();
//              FEBase &fe = *(pen_loc._fe[0]);
//              fe.reinit(side, &points);
//              RealVectorValue correction = starting_point[0] - current_coords;

//              RealVectorValue current_coords = *node;
//              RealVectorValue correction = info._closest_point - current_coords;

                            const Node & undisp_node = _mesh.node(node->id());
                            RealVectorValue solution = info._closest_point - undisp_node;

                            for (unsigned int i=0; i<dim; ++i)
                            {
//                  vec_solution.add(solution_dofs(i), correction(i));
                                vec_solution.set(solution_dofs(i), solution(i));
                            }
                            info._distance = 0.0;
                        }

                    }
                }
            }

            updatedSolution = true;
        }

        vec_solution.close();

        _communicator.max(updatedSolution);

        if (updatedSolution)
        {
            ghosted_solution = vec_solution;
            ghosted_solution.close();
        }
    }

    return updatedSolution;
}
コード例 #4
0
void
FrictionalContactProblem::updateIncrementalSlip()
{
  AuxiliarySystem & aux_sys = getAuxiliarySystem();
  NumericVector<Number> & aux_solution = aux_sys.solution();

  MooseVariable * inc_slip_x_var = &getVariable(0,_inc_slip_x);
  MooseVariable * inc_slip_y_var = &getVariable(0,_inc_slip_y);
  MooseVariable * inc_slip_z_var = NULL;

  unsigned int dim = getNonlinearSystem().subproblem().mesh().dimension();
  if (dim == 3)
  {
    inc_slip_z_var = &getVariable(0,_inc_slip_z);
  }

  GeometricSearchData & displaced_geom_search_data = getDisplacedProblem()->geomSearchData();
  std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *> * penetration_locators = &displaced_geom_search_data._penetration_locators;

  for (std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *>::iterator plit = penetration_locators->begin();
      plit != penetration_locators->end();
      ++plit)
  {
    PenetrationLocator & pen_loc = *plit->second;

    bool frictional_contact_this_interaction = false;

    std::map<std::pair<int,int>,InteractionParams>::iterator ipit;
    std::pair<int,int> ms_pair(pen_loc._master_boundary,pen_loc._slave_boundary);
    ipit = _interaction_params.find(ms_pair);
    if (ipit != _interaction_params.end())
      frictional_contact_this_interaction = true;

    if (frictional_contact_this_interaction)
    {
      std::vector<dof_id_type> & slave_nodes = pen_loc._nearest_node._slave_nodes;

      for (unsigned int i=0; i<slave_nodes.size(); i++)
      {
        dof_id_type slave_node_num = slave_nodes[i];

        if (pen_loc._penetration_info[slave_node_num])
        {
          PenetrationInfo & info = *pen_loc._penetration_info[slave_node_num];

          if (info.isCaptured())
          {
            const Node * node = info._node;
            VectorValue<dof_id_type> inc_slip_dofs(node->dof_number(aux_sys.number(), inc_slip_x_var->number(), 0),
                                                   node->dof_number(aux_sys.number(), inc_slip_y_var->number(), 0),
                                                   (inc_slip_z_var ? node->dof_number(aux_sys.number(), inc_slip_z_var->number(), 0) : 0));

            RealVectorValue inc_slip = info._incremental_slip;

            for (unsigned int i=0; i<dim; ++i)
            {
              aux_solution.set(inc_slip_dofs(i), inc_slip(i));
            }
          }
        }
      }
    }
  }

  aux_solution.close();
}
コード例 #5
0
MooseNonlinearConvergenceReason
FrictionalContactProblem::checkNonlinearConvergence(std::string &msg,
                                                    const PetscInt it,
                                                    const Real xnorm,
                                                    const Real snorm,
                                                    const Real fnorm,
                                                    const Real rtol,
                                                    const Real stol,
                                                    const Real abstol,
                                                    const PetscInt nfuncs,
                                                    const PetscInt /*max_funcs*/,
                                                    const Real ref_resid,
                                                    const Real /*div_threshold*/)
{
  Real my_max_funcs = std::numeric_limits<int>::max();
  Real my_div_threshold = std::numeric_limits<Real>::max();

  MooseNonlinearConvergenceReason reason = ReferenceResidualProblem::checkNonlinearConvergence(msg,
                                                                                               it,
                                                                                               xnorm,
                                                                                               snorm,
                                                                                               fnorm,
                                                                                               rtol,
                                                                                               stol,
                                                                                               abstol,
                                                                                               nfuncs,
                                                                                               my_max_funcs,
                                                                                               ref_resid,
                                                                                               my_div_threshold);

  _refResidContact = ref_resid; //use initial residual if no reference variables are specified
  updateContactReferenceResidual();

  int min_nl_its_since_contact_update = 1;
  ++_num_nl_its_since_contact_update;

  if ((reason > 0) || //converged
      (reason == MOOSE_NONLINEAR_ITERATING && //iterating and converged within factor
       (fnorm < abstol*_contact_slip_tol_factor ||
        checkConvergenceIndividVars(fnorm, abstol*_contact_slip_tol_factor, rtol*_contact_slip_tol_factor, ref_resid))))
  {
    _console<<"Slip iteration "<<_num_slip_iterations<<" ";
    if (_num_slip_iterations < _min_slip_iters)
    { //force another iteration, and do a slip update
      reason = MOOSE_NONLINEAR_ITERATING;
      _do_slip_update = true;
      _console<<"Force slip update < min slip iterations"<<std::endl;
    }
    else if (_num_slip_iterations < _max_slip_iters)
    { //do a slip update if there is another iteration
      if (_num_nl_its_since_contact_update >= min_nl_its_since_contact_update)
      {
        _do_slip_update = true;

        NonlinearSystem & nonlinear_sys = getNonlinearSystem();
        nonlinear_sys.update();
        const NumericVector<Number>*& ghosted_solution = nonlinear_sys.currentSolution();

        calculateSlip(*ghosted_solution, NULL); //Just to calculate slip residual

        if (_slip_residual > _target_contact_residual &&
            _slip_residual > _target_relative_contact_residual*_refResidContact)
        { //force it to keep iterating
          reason = MOOSE_NONLINEAR_ITERATING;
          _console<<"Force slip update slip_resid > target: "<<_slip_residual<<std::endl;
        }
        else
        {
          //_do_slip_update = false; //maybe we want to do this
          _console<<"Not forcing slip update slip_resid <= target: "<<_slip_residual<<std::endl;
        }
      }
      else
      {
        if (_slip_residual > _target_contact_residual &&
            _slip_residual > _target_relative_contact_residual*_refResidContact)
        { //force it to keep iterating
          reason = MOOSE_NONLINEAR_ITERATING;
          _console<<"Forcing another nonlinear iteration before slip iteration: " <<_num_nl_its_since_contact_update <<std::endl;
        }
      }
    }
    else
    { //maxed out
      _console<<"Max slip iterations"<<std::endl;
      reason = MOOSE_DIVERGED_FUNCTION_COUNT;
    }
  }

  return(reason);
}
コード例 #6
0
void
FrictionalContactProblem::applySlip(NumericVector<Number>& vec_solution,
                                    NumericVector<Number>& ghosted_solution,
                                    std::vector<SlipData> & iterative_slip)
{
  NonlinearSystem & nonlinear_sys = getNonlinearSystem();
  unsigned int dim = nonlinear_sys.subproblem().mesh().dimension();
  AuxiliarySystem & aux_sys = getAuxiliarySystem();
  NumericVector<Number> & aux_solution = aux_sys.solution();

  MooseVariable * disp_x_var = &getVariable(0,_disp_x);
  MooseVariable * disp_y_var = &getVariable(0,_disp_y);
  MooseVariable * disp_z_var = NULL;
  MooseVariable * inc_slip_x_var = &getVariable(0,_inc_slip_x);
  MooseVariable * inc_slip_y_var = &getVariable(0,_inc_slip_y);
  MooseVariable * inc_slip_z_var = NULL;
  if (dim == 3)
  {
    disp_z_var = &getVariable(0,_disp_z);
    inc_slip_z_var = &getVariable(0,_inc_slip_z);
  }

  MooseVariable * disp_var;
  MooseVariable * inc_slip_var;

  for (unsigned int iislip=0; iislip<iterative_slip.size(); ++iislip)
  {
    const Node * node = iterative_slip[iislip]._node;
    const unsigned int dof = iterative_slip[iislip]._dof;
    const Real slip = iterative_slip[iislip]._slip;

    if (dof == 0)
    {
      disp_var = disp_x_var;
      inc_slip_var = inc_slip_x_var;
    }
    else if (dof == 1)
    {
      disp_var = disp_y_var;
      inc_slip_var = inc_slip_y_var;
    }
    else
    {
      disp_var = disp_z_var;
      inc_slip_var = inc_slip_z_var;
    }

    dof_id_type
      solution_dof = node->dof_number(nonlinear_sys.number(), disp_var->number(), 0),
      inc_slip_dof = node->dof_number(aux_sys.number(), inc_slip_var->number(), 0);

    vec_solution.add(solution_dof, slip);
    aux_solution.add(inc_slip_dof, slip);
  }

  aux_solution.close();
  vec_solution.close();
  unsigned int num_slipping_nodes = iterative_slip.size();
  _communicator.sum(num_slipping_nodes);
  if (num_slipping_nodes > 0)
  {
    ghosted_solution = vec_solution;
    ghosted_solution.close();

    updateContactPoints(ghosted_solution,false);

    enforceRateConstraint(vec_solution, ghosted_solution);
  }
}
コード例 #7
0
FrictionalContactProblem::FrictionalContactProblem(const InputParameters & params) :
    ReferenceResidualProblem(params),
    _refResidContact(0.0),
    _slip_residual(0.0),
    _do_slip_update(false),
    _num_slip_iterations(0),
    _target_contact_residual(0.0),
    _target_relative_contact_residual(0.0),
    _num_nl_its_since_contact_update(0),
    _num_contact_nodes(0),
    _num_slipping(0),
    _num_slipped_too_far(0),
    _inc_slip_norm(0.0),
    _it_slip_norm(0.0)
{
  std::vector<int> master = params.get<std::vector<int> >("master");
  std::vector<int> slave = params.get<std::vector<int> >("slave");
  std::vector<Real> friction_coefficient = params.get<std::vector<Real> >("friction_coefficient");
  std::vector<Real> slip_factor = params.get<std::vector<Real> >("slip_factor");
  std::vector<Real> slip_too_far_factor = params.get<std::vector<Real> >("slip_too_far_factor");

  unsigned int dim = getNonlinearSystem().subproblem().mesh().dimension();

  _disp_x = params.get<NonlinearVariableName>("disp_x");
  _residual_x = params.get<AuxVariableName>("residual_x");
  _diag_stiff_x = params.get<AuxVariableName>("diag_stiff_x");
  _inc_slip_x = params.get<AuxVariableName>("inc_slip_x");

  _disp_y = params.get<NonlinearVariableName>("disp_y");
  _residual_y = params.get<AuxVariableName>("residual_y");
  _diag_stiff_y = params.get<AuxVariableName>("diag_stiff_y");
  _inc_slip_y = params.get<AuxVariableName>("inc_slip_y");

  if (dim == 3)
  {
    if (!params.isParamValid("disp_z"))
      mooseError("Missing disp_z in FrictionalContactProblem");
    if (!params.isParamValid("residual_z"))
      mooseError("Missing residual_z in FrictionalContactProblem");
    if (!params.isParamValid("diag_stiff_z"))
      mooseError("Missing diag_stiff_z in FrictionalContactProblem");
    if (!params.isParamValid("inc_slip_z"))
      mooseError("Missing inc_slip_z in FrictionalContactProblem");
    _disp_z = params.get<NonlinearVariableName>("disp_z");
    _residual_z = params.get<AuxVariableName>("residual_z");
    _diag_stiff_z = params.get<AuxVariableName>("diag_stiff_z");
    _inc_slip_z = params.get<AuxVariableName>("inc_slip_z");
  }

  unsigned int num_interactions = master.size();
  if (num_interactions != slave.size())
    mooseError("Sizes of master surface and slave surface lists must match in FrictionalContactProblem");
  if (num_interactions != friction_coefficient.size())
    mooseError("Must have friction coefficient defined for every interaction in FrictionalContactProblem");
  if (num_interactions != slip_factor.size())
    mooseError("Must have slip factor defined for every interaction in FrictionalContactProblem");
  if (num_interactions != slip_too_far_factor.size())
    mooseError("Must have slip too far factor defined for every interaction in FrictionalContactProblem");

  for (unsigned int i=0; i<master.size(); ++i)
  {
    std::pair<int,int> ms_pair(master[i],slave[i]);
    InteractionParams ip;
    ip._friction_coefficient = friction_coefficient[i];
    ip._slip_factor = slip_factor[i];
    ip._slip_too_far_factor = slip_too_far_factor[i];

    _interaction_params[ms_pair] = ip;
  }

  _min_slip_iters = params.get<int>("minimum_slip_iterations");
  _max_slip_iters = params.get<int>("maximum_slip_iterations");
  _slip_updates_per_iter = params.get<int>("slip_updates_per_iteration");

  bool have_target = false;
  bool have_target_relative = false;
  if (params.isParamValid("target_contact_residual"))
  {
    _target_contact_residual = params.get<Real>("target_contact_residual");
    have_target = true;
  }
  if (params.isParamValid("target_relative_contact_residual"))
  {
    _target_relative_contact_residual = params.get<Real>("target_relative_contact_residual");
    have_target_relative = true;
  }
  if (!(have_target || have_target_relative))
    mooseError("Must specify either target_contact_residual or target_relative_contact_residual");

  _contact_slip_tol_factor = params.get<Real>("contact_slip_tolerance_factor");

  if (params.isParamValid("contact_reference_residual_variables"))
    _contactRefResidVarNames = params.get<std::vector<std::string> >("contact_reference_residual_variables");
}
コード例 #8
0
MooseNonlinearConvergenceReason
ReferenceResidualProblem::checkNonlinearConvergence(std::string &msg,
                                                    const PetscInt it,
                                                    const Real xnorm,
                                                    const Real snorm,
                                                    const Real fnorm,
                                                    const Real rtol,
                                                    const Real stol,
                                                    const Real abstol,
                                                    const PetscInt nfuncs,
                                                    const PetscInt max_funcs,
                                                    const Real ref_resid,
                                                    const Real /*div_threshold*/)
{
  updateReferenceResidual();

  if (_solnVars.size() > 0)
  {
    _console<<"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)
    {
      _console<<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;
      _console<<"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 = static_cast<unsigned int>(it);

  msg = oss.str();

//  _console<<msg<<std::endl; //Print convergence diagnostic message
  return(reason);
}