Example #1
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 = nullptr;

  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 (PLIterator 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();
}
void
ReferenceResidualProblem::initialSetup()
{
  NonlinearSystem & nonlinear_sys = getNonlinearSystem();
  AuxiliarySystem & aux_sys = getAuxiliarySystem();
  TransientNonlinearImplicitSystem &s = nonlinear_sys.sys();
  TransientExplicitSystem &as = aux_sys.sys();

  if (_solnVarNames.size() > 0 &&
      _solnVarNames.size() != s.n_vars())
  {
    std::ostringstream err;
    err << "In ReferenceResidualProblem, size of solution_variables ("<<_solnVarNames.size()
        <<") != number of variables in system ("<<s.n_vars()<<")";
    mooseError(err.str());
  }

  _solnVars.clear();
  for (unsigned int i=0; i<_solnVarNames.size(); ++i)
  {
    bool foundMatch = false;
    for (unsigned int var_num = 0; var_num < s.n_vars(); var_num++)
    {
      if (_solnVarNames[i] == s.variable_name(var_num))
      {
        _solnVars.push_back(var_num);
        _resid.push_back(0.0);
        foundMatch = true;
        break;
      }
    }
    if (!foundMatch)
    {
      std::ostringstream err;
      err << "Could not find solution variable '"<<_solnVarNames[i]<<"' in system";
      mooseError(err.str());
    }
  }

  _refResidVars.clear();
  for (unsigned int i=0; i<_refResidVarNames.size(); ++i)
  {
    bool foundMatch=false;
    for (unsigned int var_num = 0; var_num < as.n_vars(); var_num++)
    {
      if (_refResidVarNames[i] == as.variable_name(var_num))
      {
        _refResidVars.push_back(var_num);
        _refResid.push_back(0.0);
        foundMatch = true;
        break;
      }
    }
    if (!foundMatch)
      mooseError("Could not find variable '"<<_refResidVarNames[i]<<"' in auxiliary system");
  }

  FEProblem::initialSetup();
}
void
ReferenceResidualProblem::updateReferenceResidual()
{
  NonlinearSystem & nonlinear_sys = getNonlinearSystem();
  AuxiliarySystem & aux_sys = getAuxiliarySystem();
  TransientNonlinearImplicitSystem &s = nonlinear_sys.sys();
  TransientExplicitSystem &as = aux_sys.sys();

  for (unsigned int i=0; i<_solnVars.size(); ++i)
    _resid[i] = s.calculate_norm(*s.rhs,_solnVars[i],DISCRETE_L2);

  for (unsigned int i=0; i<_refResidVars.size(); ++i)
    _refResid[i] = as.calculate_norm(*as.current_local_solution,_refResidVars[i],DISCRETE_L2);
}
void
ReferenceResidualProblem::updateReferenceResidual()
{
  NonlinearSystemBase & nonlinear_sys = getNonlinearSystemBase();
  AuxiliarySystem & aux_sys = getAuxiliarySystem();
  System & s = nonlinear_sys.system();
  TransientExplicitSystem & as = aux_sys.sys();

  for (unsigned int i = 0; i < _solnVars.size(); ++i)
    _resid[i] = s.calculate_norm(nonlinear_sys.RHS(), _solnVars[i], DISCRETE_L2);

  for (unsigned int i = 0; i < _refResidVars.size(); ++i)
  {
    const Real refResidual =
        as.calculate_norm(*as.current_local_solution, _refResidVars[i], DISCRETE_L2);
    _refResid[i] = refResidual * _scaling_factors[i];
  }
}
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);
    }
}
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;
}
void
ReferenceResidualProblem::initialSetup()
{
  NonlinearSystemBase & nonlinear_sys = getNonlinearSystemBase();
  AuxiliarySystem & aux_sys = getAuxiliarySystem();
  System & s = nonlinear_sys.system();
  TransientExplicitSystem & as = aux_sys.sys();

  if (_solnVarNames.size() > 0 && _solnVarNames.size() != s.n_vars())
    mooseError("In ReferenceResidualProblem, size of solution_variables (",
               _solnVarNames.size(),
               ") != number of variables in system (",
               s.n_vars(),
               ")");

  _solnVars.clear();
  for (unsigned int i = 0; i < _solnVarNames.size(); ++i)
  {
    bool foundMatch = false;
    for (unsigned int var_num = 0; var_num < s.n_vars(); var_num++)
    {
      if (_solnVarNames[i] == s.variable_name(var_num))
      {
        _solnVars.push_back(var_num);
        _resid.push_back(0.0);
        foundMatch = true;
        break;
      }
    }
    if (!foundMatch)
      mooseError("Could not find solution variable '", _solnVarNames[i], "' in system");
  }

  _refResidVars.clear();
  for (unsigned int i = 0; i < _refResidVarNames.size(); ++i)
  {
    bool foundMatch = false;
    for (unsigned int var_num = 0; var_num < as.n_vars(); var_num++)
    {
      if (_refResidVarNames[i] == as.variable_name(var_num))
      {
        _refResidVars.push_back(var_num);
        _refResid.push_back(0.0);
        foundMatch = true;
        break;
      }
    }
    if (!foundMatch)
      mooseError("Could not find variable '", _refResidVarNames[i], "' in auxiliary system");
  }

  const unsigned int size_solnVars = _solnVars.size();
  _scaling_factors.resize(size_solnVars);
  for (unsigned int i = 0; i < size_solnVars; ++i)
    if (nonlinear_sys.isScalarVariable(_solnVars[i]))
      _scaling_factors[i] = nonlinear_sys.getScalarVariable(0, _solnVars[i]).scalingFactor();
    else
      _scaling_factors[i] = nonlinear_sys.getVariable(/*tid*/ 0, _solnVars[i]).scalingFactor();

  FEProblemBase::initialSetup();
}