Ejemplo n.º 1
0
Real
SlaveConstraint::computeQpResidual()
{
  PenetrationInfo * pinfo = _point_to_info[_current_point];
  const Node * node = pinfo->_node;

  Real resid = pinfo->_contact_force(_component);

  const Real area = nodalArea(*pinfo);

  if (_formulation == CF_DEFAULT)
  {
    RealVectorValue distance_vec(_mesh.node(node->id()) - pinfo->_closest_point);
    RealVectorValue pen_force(_penalty * distance_vec);
    if (_normalize_penalty)
      pen_force *= area;

    if (_model == CM_FRICTIONLESS)
      resid += pinfo->_normal(_component) * pinfo->_normal * pen_force;

    else if (_model == CM_GLUED || _model == CM_COULOMB)
      resid += pen_force(_component);

  }

  return _test[_i][_qp] * resid;
}
Ejemplo n.º 2
0
Real
MechanicalContactConstraint::computeQpResidual(Moose::ConstraintType type)
{
  PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];
  computeContactForce(pinfo);
  Real resid = pinfo->_contact_force(_component);

  switch(type)
  {
    case Moose::Slave:
      if (_formulation == CF_DEFAULT)
      {
        //Real distance = (*_current_node)(_component) - pinfo->_closest_point(_component);
        //Real pen_force = _penalty * distance;
        RealVectorValue distance_vec(*_current_node - pinfo->_closest_point);
        RealVectorValue pen_force(_penalty * distance_vec);

        if (_model == CM_FRICTIONLESS || _model == CM_EXPERIMENTAL)
          resid += pinfo->_normal(_component) * pinfo->_normal * pen_force;

        else if (_model == CM_GLUED || _model == CM_TIED || _model == CM_COULOMB)
          resid += pen_force(_component);

      }
      return _test_slave[_i][_qp] * resid;
    case Moose::Master:
      return _test_master[_i][_qp] * -resid;
  }

  return 0;
}
Ejemplo n.º 3
0
void
ContactMaster::computeContactForce(PenetrationInfo * pinfo)
{
  std::map<unsigned int, Real> & lagrange_multiplier = _penetration_locator._lagrange_multiplier;
  const Node * node = pinfo->_node;

  RealVectorValue res_vec;
  // Build up residual vector
  for (unsigned int i=0; i<_mesh_dimension; ++i)
  {
    long int dof_number = node->dof_number(0, _vars(i), 0);
    res_vec(i) = _residual_copy(dof_number);
  }

  const Real area = nodalArea(*pinfo);

  RealVectorValue distance_vec(_mesh.node(node->id()) - pinfo->_closest_point);
  RealVectorValue pen_force(_penalty * distance_vec);
  if (_normalize_penalty)
    pen_force *= area;

  RealVectorValue tan_residual(0,0,0);

  if (_model == CM_FRICTIONLESS)
  {
    switch (_formulation)
    {
    case CF_DEFAULT:
      pinfo->_contact_force = -pinfo->_normal * (pinfo->_normal * res_vec);
      break;
    case CF_PENALTY:
      pinfo->_contact_force = pinfo->_normal * (pinfo->_normal * pen_force);
      break;
    case CF_AUGMENTED_LAGRANGE:
      pinfo->_contact_force = (pinfo->_normal * (pinfo->_normal *
          //( pen_force + (lagrange_multiplier[node->id()]/distance_vec.size())*distance_vec)));
          ( pen_force + lagrange_multiplier[node->id()] * pinfo->_normal)));
      break;
    default:
      mooseError("Invalid contact formulation");
      break;
    }
    pinfo->_mech_status=PenetrationInfo::MS_SLIPPING;
  }
  else if (_model == CM_COULOMB && _formulation == CF_PENALTY)
  {
    distance_vec = pinfo->_incremental_slip + (pinfo->_normal * (_mesh.node(node->id()) - pinfo->_closest_point)) * pinfo->_normal;
    pen_force = _penalty * distance_vec;
    if (_normalize_penalty)
      pen_force *= area;


    // Frictional capacity
    // const Real capacity( _friction_coefficient * (pen_force * pinfo->_normal < 0 ? -pen_force * pinfo->_normal : 0) );
    const Real capacity( _friction_coefficient * (res_vec * pinfo->_normal > 0 ? res_vec * pinfo->_normal : 0) );

    // Elastic predictor
    pinfo->_contact_force = pen_force + (pinfo->_contact_force_old - pinfo->_normal*(pinfo->_normal*pinfo->_contact_force_old));
    RealVectorValue contact_force_normal( (pinfo->_contact_force*pinfo->_normal) * pinfo->_normal );
    RealVectorValue contact_force_tangential( pinfo->_contact_force - contact_force_normal );

    // Tangential magnitude of elastic predictor
    const Real tan_mag( contact_force_tangential.size() );

    if ( tan_mag > capacity )
    {
      pinfo->_contact_force = contact_force_normal + capacity * contact_force_tangential / tan_mag;
      pinfo->_mech_status=PenetrationInfo::MS_SLIPPING;
    }
    else
    {
      pinfo->_mech_status=PenetrationInfo::MS_STICKING;
    }
  }
  else if (_model == CM_GLUED ||
           (_model == CM_COULOMB && _formulation == CF_DEFAULT))
  {
    switch (_formulation)
    {
    case CF_DEFAULT:
      pinfo->_contact_force =  -res_vec;
      break;
    case CF_PENALTY:
      pinfo->_contact_force = pen_force;
      break;
    case CF_AUGMENTED_LAGRANGE:
      pinfo->_contact_force = pen_force +
                              lagrange_multiplier[node->id()]*distance_vec/distance_vec.size();
      break;
    default:
      mooseError("Invalid contact formulation");
      break;
    }
    pinfo->_mech_status=PenetrationInfo::MS_STICKING;
  }
  else
  {
    mooseError("Invalid or unavailable contact model");
  }
}
Ejemplo n.º 4
0
void
MechanicalContactConstraint::computeContactForce(PenetrationInfo * pinfo)
{
  const Node * node = pinfo->_node;

  RealVectorValue res_vec;
  // Build up residual vector
  for (unsigned int i=0; i<_mesh_dimension; ++i)
  {
    dof_id_type dof_number = node->dof_number(0, _vars(i), 0);
    res_vec(i) = _residual_copy(dof_number);
  }
  RealVectorValue distance_vec(_mesh.node(node->id()) - pinfo->_closest_point);
  const Real penalty = getPenalty(*pinfo);
  RealVectorValue pen_force(penalty * distance_vec);

  switch (_model)
  {
    case CM_FRICTIONLESS:
      switch (_formulation)
      {
        case CF_KINEMATIC:
          pinfo->_contact_force = -pinfo->_normal * (pinfo->_normal * res_vec);
          break;
        case CF_PENALTY:
          pinfo->_contact_force = pinfo->_normal * (pinfo->_normal * pen_force);
          break;
        case CF_AUGMENTED_LAGRANGE:
          pinfo->_contact_force = (pinfo->_normal * (pinfo->_normal *
                                  ( pen_force + pinfo->_lagrange_multiplier * pinfo->_normal)));
          break;
        default:
          mooseError("Invalid contact formulation");
          break;
      }
      pinfo->_mech_status=PenetrationInfo::MS_SLIPPING;
      break;
    case CM_COULOMB:
      switch (_formulation)
      {
        case CF_KINEMATIC:
          pinfo->_contact_force =  -res_vec;
          break;
        case CF_PENALTY:
        {
          distance_vec = pinfo->_incremental_slip + (pinfo->_normal * (_mesh.node(node->id()) - pinfo->_closest_point)) * pinfo->_normal;
          pen_force = penalty * distance_vec;

          // Frictional capacity
          // const Real capacity( _friction_coefficient * (pen_force * pinfo->_normal < 0 ? -pen_force * pinfo->_normal : 0) );
          const Real capacity( _friction_coefficient * (res_vec * pinfo->_normal > 0 ? res_vec * pinfo->_normal : 0) );

          // Elastic predictor
          pinfo->_contact_force = pen_force + (pinfo->_contact_force_old - pinfo->_normal*(pinfo->_normal*pinfo->_contact_force_old));
          RealVectorValue contact_force_normal( (pinfo->_contact_force*pinfo->_normal) * pinfo->_normal );
          RealVectorValue contact_force_tangential( pinfo->_contact_force - contact_force_normal );

          // Tangential magnitude of elastic predictor
          const Real tan_mag( contact_force_tangential.size() );

          if ( tan_mag > capacity )
          {
            pinfo->_contact_force = contact_force_normal + capacity * contact_force_tangential / tan_mag;
            pinfo->_mech_status=PenetrationInfo::MS_SLIPPING;
          }
          else
            pinfo->_mech_status=PenetrationInfo::MS_STICKING;
          break;
        }
        case CF_AUGMENTED_LAGRANGE:
          pinfo->_contact_force = pen_force +
                                  pinfo->_lagrange_multiplier*distance_vec/distance_vec.size();
          break;
        default:
          mooseError("Invalid contact formulation");
          break;
      }
      break;
    case CM_GLUED:
      switch (_formulation)
      {
        case CF_KINEMATIC:
          pinfo->_contact_force =  -res_vec;
          break;
        case CF_PENALTY:
          pinfo->_contact_force = pen_force;
          break;
        case CF_AUGMENTED_LAGRANGE:
          pinfo->_contact_force = pen_force +
                                  pinfo->_lagrange_multiplier*distance_vec/distance_vec.size();
          break;
        default:
          mooseError("Invalid contact formulation");
          break;
      }
      pinfo->_mech_status=PenetrationInfo::MS_STICKING;
      break;
    default:
      mooseError("Invalid or unavailable contact model");
      break;
  }
}