Пример #1
0
Real
GluedContactConstraint::computeQpResidual(Moose::ConstraintType type)
{
  switch (type)
  {
    case Moose::Slave:
    {
      PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];
      Real distance = (*_current_node)(_component) - pinfo->_closest_point(_component);
      Real pen_force = _penalty * distance;

      Real resid = pen_force;
      pinfo->_contact_force(_component) = resid;
      pinfo->_mech_status=PenetrationInfo::MS_STICKING;

      return _test_slave[_i][_qp] * resid;
    }
    case Moose::Master:
    {
      PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];

      long int dof_number = _current_node->dof_number(0, _vars(_component), 0);
      Real resid = _residual_copy(dof_number);

      pinfo->_contact_force(_component) = -resid;
      pinfo->_mech_status=PenetrationInfo::MS_STICKING;

      return _test_master[_i][_qp] * resid;
    }
  }

  return 0;
}
Пример #2
0
void
GluedContactConstraint::updateContactSet(bool beginning_of_step)
{
    std::set<dof_id_type> & has_penetrated = _penetration_locator._has_penetrated;

    std::map<dof_id_type, PenetrationInfo *>::iterator
    it  = _penetration_locator._penetration_info.begin(),
    end = _penetration_locator._penetration_info.end();

    for (; it!=end; ++it)
    {
        PenetrationInfo * pinfo = it->second;

        // Skip this pinfo if there are no DOFs on this node.
        if ( ! pinfo || pinfo->_node->n_comp(_sys.number(), _vars(_component)) < 1 )
            continue;

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

        if (beginning_of_step)
        {
            pinfo->_starting_elem = it->second->_elem;
            pinfo->_starting_side_num = it->second->_side_num;
            pinfo->_starting_closest_point_ref = it->second->_closest_point_ref;
        }

        if (pinfo->_distance >= 0)
            if (hpit == has_penetrated.end())
                has_penetrated.insert(slave_node_num);
    }
}
Пример #3
0
void
ContactMaster::addPoints()
{
  _point_to_info.clear();

  std::map<dof_id_type, PenetrationInfo *>::iterator
    it  = _penetration_locator._penetration_info.begin(),
    end = _penetration_locator._penetration_info.end();

  for (; it!=end; ++it)
  {
    PenetrationInfo * pinfo = it->second;

    // Skip this pinfo if there are no DOFs on this node.
    if ( ! pinfo || pinfo->_node->n_comp(_sys.number(), _vars(_component)) < 1 )
      continue;

    if ( pinfo->isCaptured() )
    {
      addPoint(pinfo->_elem, pinfo->_closest_point);
      _point_to_info[pinfo->_closest_point] = pinfo;
      computeContactForce(pinfo);
    }
  }
}
Пример #4
0
inline expr MkAtMost(expr_vector vars, unsigned k) {
    array<Z3_ast> _vars(vars.size());
    for (unsigned i = 0; i < vars.size(); ++i) {
        _vars[i] = vars[i];
    }
	expr r{ vars.ctx(), Z3_mk_atmost(vars.ctx(), vars.size(), _vars.ptr(), k) };
	vars.check_error();
	return r;
}
Пример #5
0
void
ContactMaster::updateContactSet(bool beginning_of_step)
{
  std::map<dof_id_type, PenetrationInfo *>::iterator
    it  = _penetration_locator._penetration_info.begin(),
    end = _penetration_locator._penetration_info.end();
  for (; it!=end; ++it)
  {
    const dof_id_type slave_node_num = it->first;
    PenetrationInfo * pinfo = it->second;

    // Skip this pinfo if there are no DOFs on this node.
    if ( ! pinfo || pinfo->_node->n_comp(_sys.number(), _vars(_component)) < 1 )
      continue;

    if (beginning_of_step)
    {
      pinfo->_locked_this_step = 0;
      pinfo->_starting_elem = it->second->_elem;
      pinfo->_starting_side_num = it->second->_side_num;
      pinfo->_starting_closest_point_ref = it->second->_closest_point_ref;
      pinfo->_contact_force_old = pinfo->_contact_force;
      pinfo->_accumulated_slip_old = pinfo->_accumulated_slip;
      pinfo->_frictional_energy_old = pinfo->_frictional_energy;
    }

    const Real contact_pressure = -(pinfo->_normal * pinfo->_contact_force) / nodalArea(*pinfo);
    const Real distance = pinfo->_normal * (pinfo->_closest_point - _mesh.node(slave_node_num));

    // Capture
    if ( ! pinfo->isCaptured() && MooseUtils::absoluteFuzzyGreaterEqual(distance, 0, _capture_tolerance))
    {
      pinfo->capture();

      // Increment the lock count every time the node comes back into contact from not being in contact.
      if (_formulation == CF_KINEMATIC)
        ++pinfo->_locked_this_step;
    }
    // Release
    else if (_model != CM_GLUED &&
             pinfo->isCaptured() &&
             _tension_release >= 0 &&
             -contact_pressure >= _tension_release &&
             pinfo->_locked_this_step < 2)
    {
      pinfo->release();
      pinfo->_contact_force.zero();
    }

    if (_formulation == CF_AUGMENTED_LAGRANGE && pinfo->isCaptured())
      pinfo->_lagrange_multiplier -= getPenalty(*pinfo) * distance;
  }
}
Пример #6
0
bool
MechanicalContactConstraint::getCoupledVarComponent(unsigned int var_num,
                                                    unsigned int &component)
{
  component = std::numeric_limits<unsigned int>::max();
  bool coupled_var_is_disp_var = false;
  for (unsigned int i=0; i<_vars.size(); ++i)
  {
    if (var_num == _vars(i))
    {
      coupled_var_is_disp_var = true;
      component = i;
      break;
    }
  }
  return coupled_var_is_disp_var;
}
Пример #7
0
void
SlaveConstraint::addPoints()
{
  _point_to_info.clear();

  std::map<dof_id_type, PenetrationInfo *>::iterator
    it  = _penetration_locator._penetration_info.begin(),
    end = _penetration_locator._penetration_info.end();
  for (; it!=end; ++it)
  {
    PenetrationInfo * pinfo = it->second;

    // Skip this pinfo if there are no DOFs on this node.
    if ( ! pinfo || pinfo->_node->n_comp(_sys.number(), _vars(_component)) < 1 )
      continue;

    dof_id_type slave_node_num = it->first;
    const Node * node = pinfo->_node;

    if (pinfo->isCaptured() && node->processor_id() == processor_id())
    {
      // Find an element that is connected to this node that and that is also on this processor

      std::vector<dof_id_type> & connected_elems = _mesh.nodeToElemMap()[slave_node_num];

      Elem * elem = NULL;

      for (unsigned int i=0; i<connected_elems.size() && !elem; ++i)
      {
        Elem * cur_elem = _mesh.elem(connected_elems[i]);
        if (cur_elem->processor_id() == processor_id())
          elem = cur_elem;
      }

      mooseAssert(elem, "Couldn't find an element on this processor that is attached to the slave node!");

      addPoint(elem, *node);
      _point_to_info[*node] = pinfo;
    }
  }
}
Пример #8
0
Real
GluedContactConstraint::computeQpOffDiagJacobian(Moose::ConstraintJacobianType type, unsigned int /*jvar*/)
{
    Real retVal = 0;

    switch (type)
    {
    case Moose::SlaveSlave:
        break;
    case Moose::SlaveMaster:
        break;
    case Moose::MasterSlave:
    {
        double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
        retVal =  slave_jac*_test_master[_i][_qp];
        break;
    }
    case Moose::MasterMaster:
        break;
    }

    return retVal;
}
Пример #9
0
Real
GluedContactConstraint::computeQpJacobian(Moose::ConstraintJacobianType type)
{
  switch (type)
  {
    case Moose::SlaveSlave:
    {
      return _penalty*_phi_slave[_j][_qp]*_test_slave[_i][_qp];
    }
    case Moose::SlaveMaster:
    {
      return _penalty*-_phi_master[_j][_qp]*_test_slave[_i][_qp];
    }
    case Moose::MasterSlave:
    {
      double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
      return slave_jac*_test_master[_i][_qp];
    }
    case Moose::MasterMaster:
      return 0;
  }

  return 0;
}
Пример #10
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");
  }
}
Пример #11
0
Real
MechanicalContactConstraint::computeQpJacobian(Moose::ConstraintJacobianType type)
{
  PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];

  switch(type)
  {
    case Moose::SlaveSlave:
      switch(_model)
      {
        case CM_FRICTIONLESS:
        case CM_EXPERIMENTAL:
          switch (_formulation)
          {
            case CF_DEFAULT:
            {
              double curr_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
              //TODO:  Need off-diagonal term/s
              return (-curr_jac + _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp]) * pinfo->_normal(_component) * pinfo->_normal(_component);
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              //TODO:  Need off-diagonal terms
              return _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component);
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
        case CM_TIED:
          switch (_formulation)
          {
            case CF_DEFAULT:
            {
              double curr_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
              return -curr_jac + _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp];
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp];
            default:
              mooseError("Invalid contact formulation");
          }
        default:
          mooseError("Invalid or unavailable contact model");
      }

    case Moose::SlaveMaster:
      switch(_model)
      {
        case CM_FRICTIONLESS:
        case CM_EXPERIMENTAL:
          switch (_formulation)
          {
            case CF_DEFAULT:
            {
              Node * curr_master_node = _current_master->get_node(_j);
              double curr_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), curr_master_node->dof_number(0, _vars(_component), 0));
              //TODO:  Need off-diagonal terms
              return (-curr_jac - _phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp]) * pinfo->_normal(_component) * pinfo->_normal(_component);
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              //TODO:  Need off-diagonal terms
              return -_phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component);
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
        case CM_TIED:
          switch (_formulation)
          {
            case CF_DEFAULT:
            {
              Node * curr_master_node = _current_master->get_node(_j);
              double curr_jac = (*_jacobian)( _current_node->dof_number(0, _vars(_component), 0), curr_master_node->dof_number(0, _vars(_component), 0));
              return -curr_jac - _phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp];
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return -_phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp];
            default:
              mooseError("Invalid contact formulation");
          }
        default:
          mooseError("Invalid or unavailable contact model");
      }

    case Moose::MasterSlave:
      switch(_model)
      {
        case CM_FRICTIONLESS:
        case CM_EXPERIMENTAL:
          switch (_formulation)
          {
            case CF_DEFAULT:
            {
              //TODO:  Need off-diagonal terms
              double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
              //TODO: To get off-diagonal terms correct using an approach like this, we would need to assemble in the rows for
              //all displacement components times their components of the normal vector.
              return slave_jac * _test_master[_i][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component);
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              //TODO:  Need off-diagonal terms
              return -_test_master[_i][_qp] * _penalty * _phi_slave[_j][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component);
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
        case CM_TIED:
          switch (_formulation)
          {
            case CF_DEFAULT:
            {
              double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
              return slave_jac * _test_master[_i][_qp];
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return -_test_master[_i][_qp] * _penalty * _phi_slave[_j][_qp];
            default:
              mooseError("Invalid contact formulation");
          }
        default:
          mooseError("Invalid or unavailable contact model");
      }

    case Moose::MasterMaster:
      switch(_model)
      {
        case CM_FRICTIONLESS:
        case CM_EXPERIMENTAL:
          switch (_formulation)
          {
            case CF_DEFAULT:
              return 0;
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              //TODO: Need off-diagonal terms
              return _test_master[_i][_qp] * _penalty * _phi_master[_j][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component);
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
        case CM_TIED:
          switch (_formulation)
          {
            case CF_DEFAULT:
              return 0;
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return _test_master[_i][_qp] * _penalty * _phi_master[_j][_qp];
            default:
              mooseError("Invalid contact formulation");
          }
        default:
          mooseError("Invalid or unavailable contact model");
      }
  }

  return 0;
}
Пример #12
0
Real
MechanicalContactConstraint::computeQpOffDiagJacobian(Moose::ConstraintJacobianType type,
                                                      unsigned int jvar)
{
  PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];

  const Real penalty = getPenalty(*pinfo);

  unsigned int coupled_component;
  double normal_component_in_coupled_var_dir = 1.0;
  if (getCoupledVarComponent(jvar,coupled_component))
    normal_component_in_coupled_var_dir = pinfo->_normal(coupled_component);

  switch (type)
  {
    case Moose::SlaveSlave:
      switch (_model)
      {
        case CM_FRICTIONLESS:
          switch (_formulation)
          {
            case CF_KINEMATIC:
            {
              RealVectorValue jac_vec;
              for (unsigned int i=0; i<_mesh_dimension; ++i)
              {
                dof_id_type dof_number = _current_node->dof_number(0, _vars(i), 0);
                jac_vec(i) = (*_jacobian)(dof_number, _connected_dof_indices[_j]);
              }
              return -pinfo->_normal(_component) * (pinfo->_normal*jac_vec) + (_phi_slave[_j][_qp] * penalty * _test_slave[_i][_qp]) * pinfo->_normal(_component) * normal_component_in_coupled_var_dir;
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return _phi_slave[_j][_qp] * penalty * _test_slave[_i][_qp] * pinfo->_normal(_component) * normal_component_in_coupled_var_dir;
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
        {
          double curr_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
          return -curr_jac;
        }
        default:
          mooseError("Invalid or unavailable contact model");
      }

    case Moose::SlaveMaster:
      switch (_model)
      {
        case CM_FRICTIONLESS:
          switch (_formulation)
          {
            case CF_KINEMATIC:
            {
              Node * curr_master_node = _current_master->get_node(_j);

              RealVectorValue jac_vec;
              for (unsigned int i=0; i<_mesh_dimension; ++i)
              {
                dof_id_type dof_number = _current_node->dof_number(0, _vars(i), 0);
                jac_vec(i) = (*_jacobian)(dof_number, curr_master_node->dof_number(0, _vars(_component), 0));
              }
              return -pinfo->_normal(_component)*(pinfo->_normal*jac_vec) - (_phi_master[_j][_qp] * penalty * _test_slave[_i][_qp]) * pinfo->_normal(_component) * normal_component_in_coupled_var_dir;
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return -_phi_master[_j][_qp] * penalty * _test_slave[_i][_qp] * pinfo->_normal(_component) * normal_component_in_coupled_var_dir;
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
          return 0;
        default:
          mooseError("Invalid or unavailable contact model");
      }

    case Moose::MasterSlave:
      switch (_model)
      {
        case CM_FRICTIONLESS:
          switch (_formulation)
          {
            case CF_KINEMATIC:
            {
              RealVectorValue jac_vec;
              for (unsigned int i=0; i<_mesh_dimension; ++i)
              {
                dof_id_type dof_number = _current_node->dof_number(0, _vars(i), 0);
                jac_vec(i) = (*_jacobian)(dof_number, _connected_dof_indices[_j]);
              }
              return pinfo->_normal(_component)*(pinfo->_normal*jac_vec) * _test_master[_i][_qp];
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return -_test_master[_i][_qp] * penalty * _phi_slave[_j][_qp] * pinfo->_normal(_component) * normal_component_in_coupled_var_dir;
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
          switch (_formulation)
          {
            case CF_KINEMATIC:
            {
              double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]);
              return slave_jac * _test_master[_i][_qp];
            }
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return 0;
            default:
              mooseError("Invalid contact formulation");
          }
        default:
          mooseError("Invalid or unavailable contact model");
      }

    case Moose::MasterMaster:
      switch (_model)
      {
        case CM_FRICTIONLESS:
          switch (_formulation)
          {
            case CF_KINEMATIC:
              return 0;
            case CF_PENALTY:
            case CF_AUGMENTED_LAGRANGE:
              return _test_master[_i][_qp] * penalty * _phi_master[_j][_qp] * pinfo->_normal(_component) * normal_component_in_coupled_var_dir;
            default:
              mooseError("Invalid contact formulation");
          }
        case CM_COULOMB:
        case CM_GLUED:
          return 0;
        default:
          mooseError("Invalid or unavailable contact model");
      }
  }

  return 0;
}
Пример #13
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;
  }
}
Пример #14
0
void
MultiDContactConstraint::updateContactSet()
{
  std::set<dof_id_type> & has_penetrated = _penetration_locator._has_penetrated;

  std::map<dof_id_type, PenetrationInfo *>::iterator
    it  = _penetration_locator._penetration_info.begin(),
    end = _penetration_locator._penetration_info.end();

  for (; it!=end; ++it)
  {
    PenetrationInfo * pinfo = it->second;

    // Skip this pinfo if there are no DOFs on this node.
    if ( ! pinfo || pinfo->_node->n_comp(_sys.number(), _vars(_component)) < 1 )
      continue;

    const Node * node = pinfo->_node;

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

    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);
    }

//    Real resid = 0;
    switch (_model)
    {
    case CM_FRICTIONLESS:

//      resid = pinfo->_normal * res_vec;
      break;

    case CM_GLUED:

//      resid = pinfo->_normal * res_vec;
      break;

    default:
      mooseError("Invalid or unavailable contact model");
      break;
    }

//    if (hpit != has_penetrated.end() && resid < 0)
//      Moose::err<<resid<<std::endl;
/*
    if (hpit != has_penetrated.end() && resid < -.15)
    {
      Moose::err<<std::endl<<"Unlocking node "<<node->id()<<" because resid: "<<resid<<std::endl<<std::endl;

      has_penetrated.erase(hpit);
      unlocked_this_step[slave_node_num] = true;
    }
    else*/
    if (pinfo->_distance > 0 && hpit == has_penetrated.end())// && !unlocked_this_step[slave_node_num])
    {
//      Moose::err<<std::endl<<"Locking node "<<node->id()<<" because distance: "<<pinfo->_distance<<std::endl<<std::endl;

      has_penetrated.insert(slave_node_num);
    }
  }
}
Пример #15
0
Real
MultiDContactConstraint::computeQpResidual(Moose::ConstraintType type)
{
  PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()];
  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);
  }

  const RealVectorValue distance_vec(_mesh.node(node->id()) - pinfo->_closest_point);
  const RealVectorValue pen_force(_penalty * distance_vec);
  Real resid = 0;

  switch (type)
  {
  case Moose::Slave:
    switch (_model)
    {
    case CM_FRICTIONLESS:

      resid = pinfo->_normal(_component) * (pinfo->_normal * ( pen_force - res_vec ));
      break;

    case CM_GLUED:

      resid = pen_force(_component)
        - res_vec(_component)
        ;

      break;

    default:
      mooseError("Invalid or unavailable contact model");
      break;
    }
    return _test_slave[_i][_qp] * resid;
  case Moose::Master:
    switch (_model)
    {
    case CM_FRICTIONLESS:

      resid = pinfo->_normal(_component) * (pinfo->_normal * res_vec);
      break;

    case CM_GLUED:
      resid = res_vec(_component);
      break;

    default:
      mooseError("Invalid or unavailable contact model");
      break;
    }
    return _test_master[_i][_qp] * resid;
  }
  return 0;
}