// Private methods
// determine the slave/master pair in contact, and setup Vectors (N,T1,T2)
int ZeroLengthInterface2D::contactDetect(int s, int m1, int m2, int stage)
{
  //+--------------+-----------------+----------------+----------------+---------------+
  // NOTES: some methods to get displacements from nodes
  //+--------------+-----------------+----------------+----------------+---------------+
  // getDisp() :         get commit(k-1) disp, will be commit(k) after commit
  // getTrialDisp():     get Trial(k) disp
  // getIncrDisp():      get Trial(k)-Commit(k-1), will be 0 after commit
  // getIncrDeltaDisp(): get Trial(k)-Trial(k-1),  will be 0 after commit
  //+--------------+-----------------+----------------+----------------+--------------
  ////////////////////////////// for transient gap ///////////////////////////////////
  // DEFINE:
  // gap = (U_master-U_slave) / dot(ContactNormal),
  // defines overlapped normal distance, always keep positive (+) when contacted
  ///*
  // get current position and after trial displacement for (slave, master1, master2) nodes
  int i;
  const Vector &xs = nodePointers[s]->getCrds();
  const Vector &uxs = nodePointers[s]->getTrialDisp();
  const Vector &x1 = nodePointers[m1]->getCrds();
  const Vector &ux1= nodePointers[m1]->getTrialDisp();
  const Vector &x2 = nodePointers[m2]->getCrds();
  const Vector &ux2= nodePointers[m2]->getTrialDisp();
  
  Vector trial_slave(2), trial_master1(2), trial_master2(2);
  for (i = 0; i < 2; i++) {
    trial_slave(i) = xs(i) + uxs(i);
    trial_master1(i) = x1(i) + ux1(i);
    trial_master2(i) = x2(i) + ux2(i);
    //opserr << "trial_slave: " << trial_slave(i) << "\n";
    //opserr << "trial_master1: " << trial_master1(i) << "\n";
    //opserr << "trial_master2: " << trial_master2(i) << "\n";
  }
  
  // calculate normal gap for contact
  Vector diff(2);
  Vector ContactTangent(2);
  for (i = 0; i < 2; i++) {
    diff(i) = trial_master2(i) - trial_master1(i);
    //opserr << "diff: " << diff(i) << "\n";
  }
  double L  = diff.Norm();
  // tangent vector
  for (i = 0; i < 2; i++) ContactTangent(i) = (1/L) * (trial_master2(i) - trial_master1(i));
  // normal vector
  ContactNormal(0) = - ContactTangent(1);
  ContactNormal(1) = ContactTangent(0);
  
  normal_gap(s) = 0;
  double alpha = 0;
  double alpha_bar = 0;
  for (i = 0; i < 2; i++) {
    alpha += (1/L) * (trial_slave(i) - trial_master1(i)) * ContactTangent(i);
    normal_gap(s) += (trial_slave(i) - trial_master1(i)) * ContactNormal(i);
    diff(i) = x2(i) - x1(i);
  }
  
  double gapgap = normal_gap(s);
  
  double L_bar = diff.Norm();
  for (i = 0; i < 2; i++) alpha_bar += (1/L_bar) * (xs(i) - x1(i)) * ContactTangent(i);
  shear_gap(s) = (alpha - alpha_bar) * L_bar;
  /*
    /////////////////////////////// for transient gap ///////////////////////////////
    // we have another way to define the gap, can replace previous code block if want
    ////////////////////////////// for dynamic gap //////////////////////////////////
    const Vector   // get current trial incremental position
    &U_slave = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp();
    const Vector
    &U_master= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp();
    gap=0;
    int i;
    for (i=0; i<2; i++){
    gap += (U_master(i)-U_slave(i))* ContactNormal(i);
    }
    gap+=gap_n;
    ///////////////// for dynamic gap //////////////////////
    */
  // stage = 0 means searching slave nodes against master segments
  // stage = 1 means searching master nodes against slave segments
  if ((stage == 0  && normal_gap(s) >= 0 && alpha > 0 && alpha < 1) ||
      (stage == 1  && normal_gap(s) >= 0 && alpha >= 0 && alpha <= 1)) { // in contact
    N(0) = ContactNormal(0);
    N(1) = ContactNormal(1);
    N(2) = -(1 - alpha) * N(0);
    N(3) = -(1 - alpha) * N(1);
    N(4) = -(alpha) * N(0);
    N(5) = -(alpha) * N(1);
    
    T(0) = ContactTangent(0);
    T(1) = ContactTangent(1);
    T(2) = -(1-alpha) * T(0);
    T(3) = -(1-alpha) * T(1);
    T(4) = -(alpha) * T(0);
    T(5) = -(alpha) * T(1);
    
    return 1;
  } else {
    return 0; // Not in contact
  }
}
Example #2
0
template < > ElementMatrix < double > & ElementMatrix < double >::ux2uy2uz2(const Cell & cell, bool useCache){

    uint dim = cell.nodeCount();
    if (size() != dim) resize(dim);
    
    for (uint i = 0; i < dim; i ++) idx_[i] = cell.node(i).id();

    if (cell.uxCache().rows() > 0 && useCache){
        mat_ = cell.uxCache();
        return *this;
    }
    
//     double J = cell.jacobianDeterminant();
//     if (J <= 0) std::cerr << WHERE_AM_I << " JacobianDeterminant < 0 (" << J << ") " << cell << std::endl;
//      std::cout << J << std::endl;

    switch (cell.rtti()) {
    case MESH_EDGE_CELL_RTTI:
    case MESH_EDGE3_CELL_RTTI:
        ux2(cell, IntegrationRules::instance().edgWeights(2),
            IntegrationRules::instance().edgAbscissa(2), false); break;
    case MESH_TRIANGLE_RTTI: {
        double J = cell.size()*2.;
    ////////////////////////////////////////////////////////////////////
//         double dN1dx = cell.shape().deriveCoordinates(0, 0);
//         double dN2dx = cell.shape().deriveCoordinates(1, 0);
//         double dN3dx = cell.shape().deriveCoordinates(2, 0);
//         double dN1dy = cell.shape().deriveCoordinates(0, 1);
//         double dN2dy = cell.shape().deriveCoordinates(1, 1);
//         double dN3dy = cell.shape().deriveCoordinates(2, 1);
//         mat_[0][0] = J / 2.0 * (dN1dx * dN1dx + dN1dy * dN1dy);
//         mat_[1][0] = J / 2.0 * (dN2dx * dN1dx + dN2dy * dN1dy);
//         mat_[2][0] = J / 2.0 * (dN3dx * dN1dx + dN3dy * dN1dy);
//         mat_[1][1] = J / 2.0 * (dN2dx * dN2dx + dN2dy * dN2dy);
//         mat_[2][1] = J / 2.0 * (dN3dx * dN2dx + dN3dy * dN2dy);
//         mat_[2][2] = J / 2.0 * (dN3dx * dN3dx + dN3dy * dN3dy);
//         mat_[0][1] = mat_[1][0];
//         mat_[0][2] = mat_[2][0];
//         mat_[1][2] = mat_[2][1];
////////////////////////////////////////////////////////////////////
        // this is much faster than numerical integration
                
//         double x21 = cell.node(1).x()-cell.node(0).x();
//         double x31 = cell.node(2).x()-cell.node(0).x();
//         double y21 = cell.node(1).y()-cell.node(0).y();
//         double y31 = cell.node(2).y()-cell.node(0).y();
// 
//         double a =   ((x31) * (x31) + (y31) * (y31)) / J;
//         double b = - ((x31) * (x21) + (y31) * (y21)) / J;
//         double c =   ((x21) * (x21) + (y21) * (y21)) / J;

        double x1 = cell.node(0).x();
        double x2 = cell.node(1).x();
        double x3 = cell.node(2).x();
        double y1 = cell.node(0).y();
        double y2 = cell.node(1).y();
        double y3 = cell.node(2).y();

        double a =   ((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1)) / J;
        double b = - ((x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1)) / J;
        double c =   ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / J;

        mat_[0][0] = a *  0.5 + b        + c *  0.5 ;
        mat_[1][0] = a * -0.5 + b * -0.5            ;
        mat_[2][0] =            b * -0.5 + c * -0.5 ;
        mat_[1][1] = a *  0.5                       ;
        mat_[2][1] =            b *  0.5            ;
        mat_[2][2] =                       c *  0.5 ;

        mat_[0][1] = mat_[1][0];
        mat_[0][2] = mat_[2][0];
        mat_[1][2] = mat_[2][1];

        //std::cout << "2" << *this << std::endl;*/
        //ux2uy2(cell, IntegrationRules::instance().triWeights(1), IntegrationRules::instance().triAbscissa(1), false);
    } break;
    case MESH_TRIANGLE6_RTTI: {
///////////////////////////////////////////////////////////////////////////////////
//         double x1 = cell.node(0).x();
//         double x2 = cell.node(1).x();
//         double x3 = cell.node(2).x();
//         double y1 = cell.node(0).y();
//         double y2 = cell.node(1).y();
//         double y3 = cell.node(2).y();
//
//         double b1 = y2-y3;
//         double b2 = y3-y1;
//         double b3 = y1-y2;
//         double c1 = x3-x2;
//         double c2 = x1-x3;
//         double c3 = x2-x1;
//         double a = (c3*b2-c2*b3)/2.0;
//         double b1sqr=b1*b1;
//         double b2sqr=b2*b2;
//         double b3sqr=b3*b3;
//         double c1sqr=c1*c1;
//         double c2sqr=c2*c2;
//         double c3sqr=c3*c3;
//         double b1b2=b1*b2;
//         double b1b3=b1*b3;
//         double b2b3=b2*b3;
//         double c1c2=c1*c2;
//         double c1c3=c1*c3;
//         double c2c3=c2*c3;
//
//         mat_[0][0]=(b1sqr+c1sqr) / (4.0*a);
//         mat_[0][1]=(-b1b2-c1c2)/(12.0*a);
//         mat_[0][2]=(-b1b3-c1c3)/(12.0*a);
//         mat_[0][3]=(b1b2+c1c2)/(3.0*a);
//         mat_[0][4]=0.0;
//         mat_[0][5]=(b1b3+c1c3)/(3.0*a);
//         mat_[1][1]=(b2sqr+c2sqr)/(4.0*a);
//         mat_[1][2]=(-b2b3-c2c3)/(12.0*a);
//         mat_[1][3]=(b1b2+c1c2)/(3.0*a);
//         mat_[1][4]=(b2b3+c2c3)/(3.0*a);
//         mat_[1][5]=0.0;
//         mat_[2][2]=(b3sqr+c3sqr)/(4.0*a);
//         mat_[2][3]=0.0;
//         mat_[2][4]=(b2b3+c2c3)/(3.0*a);
//         mat_[2][5]=(b1b3+c1c3)/(3.0*a);
//         mat_[3][3]=2.0*((b1sqr+b1b2+b2sqr)+(c1sqr+c1c2+c2sqr))/(3.0*a);
//         mat_[3][4]=((b1b2+b2sqr+2.0*b1b3+b2b3)+(c1c2+c2sqr+2.0*c1c3+c2c3))/(3.0*a);
//         mat_[3][5]=((b1sqr+b1b3+b1b2+2.0*b2b3)+(c1sqr+c1c3+c1c2+2.0*c2c3))/(3.0*a);
//         mat_[4][4]=2.0*((b2sqr+b2b3+b3sqr)+(c2sqr+c2c3+c3sqr))/(3.0*a);
//         mat_[4][5]=((2.0*b1b2+b2b3+b1b3+b3sqr)+(2.0*c1c2+c2c3+c1c3+c3sqr))/(3.0*a);
//         mat_[5][5]=2.0*((b1sqr+b1b3+b3sqr)+(c1sqr+c1c3+c3sqr))/(3.0*a);
//
//         for (int i = 1, imax = 6; i < imax; i ++){
//              for (int j = 0, jmax = i; j < jmax; j ++){
//                 mat_[i][j]=mat_[j][i];
//              }
//         }

//working version
//         double x1 = cell.node(0).x();
//         double x2 = cell.node(1).x();
//         double x3 = cell.node(2).x();
//         double y1 = cell.node(0).y();
//         double y2 = cell.node(1).y();
//         double y3 = cell.node(2).y();
//
//         double a = ((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1)) / J / 6.0;
//         double b = - ((x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1)) / J / 6.0;
//         double c = ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / J / 6.0;
//         for (int i = 0, imax = 6; i < imax; i ++){
//             for (int j = 0, jmax = 6; j < jmax; j ++){
//                 mat_[i][j] = Triangle6_S1[i][j] * a +
//                                  Triangle6_S2[i][j] * b +
//                                  Triangle6_S3[i][j] * c;
//             }
//         }
//         std::cout << "2" << *this << std::endl;
        ux2uy2(cell,
               IntegrationRules::instance().triWeights(2),
               IntegrationRules::instance().triAbscissa(2), false); //ch
    } break;
    case MESH_QUADRANGLE_RTTI:
        ux2uy2(cell,
               IntegrationRules::instance().quaWeights(2), 
               IntegrationRules::instance().quaAbscissa(2), false); break;
    case MESH_QUADRANGLE8_RTTI:
        ux2uy2(cell, 
               IntegrationRules::instance().quaWeights(3),
               IntegrationRules::instance().quaAbscissa(3), false); break;
    case MESH_TETRAHEDRON_RTTI:
    //{
//         double x_xi = cell.shape().partDerivationRealToUnity(0, 1);
//         double x_eta = cell.shape().partDerivationRealToUnity(0, 2);
//         double x_zeta = cell.shape().partDerivationRealToUnity(0, 3);
//
//         double y_xi = cell.shape().partDerivationRealToUnity(1, 1);
//         double y_eta = cell.shape().partDerivationRealToUnity(1, 2);
//         double y_zeta = cell.shape().partDerivationRealToUnity(1, 3);
//
//         double z_xi = cell.shape().partDerivationRealToUnity(2, 1);
//         double z_eta = cell.shape().partDerivationRealToUnity(2, 2);
//         double z_zeta = cell.shape().partDerivationRealToUnity(2, 3);
//
//         double xi_x =  1.0 / J * det(y_eta, z_eta, y_zeta, z_zeta);
//         double xi_y = -1.0 / J * det(x_eta, z_eta, x_zeta, z_zeta);
//         double xi_z =  1.0 / J * det(x_eta, y_eta, x_zeta, y_zeta);
//
//         double eta_x = -1.0 / J * det(y_xi, z_xi, y_zeta, z_zeta);
//         double eta_y =  1.0 / J * det(x_xi, z_xi, x_zeta, z_zeta);
//         double eta_z = -1.0 / J * det(x_xi, y_xi, x_zeta, y_zeta);
//
//         double zeta_x =  1.0 / J * det(y_xi, z_xi, y_eta, z_eta);
//         double zeta_y = -1.0 / J * det(x_xi, z_xi, x_eta, z_eta);
//         double zeta_z =  1.0 / J * det(x_xi, y_xi, x_eta, y_eta);
//
//         double a = J / 6.0 * (xi_x * xi_x + xi_y * xi_y + xi_z * xi_z);
//         double b = J / 6.0 * (eta_x * eta_x + eta_y * eta_y + eta_z * eta_z);
//         double c = J / 6.0 * (zeta_x * zeta_x + zeta_y * zeta_y + zeta_z * zeta_z);
//
//         double d = J / 6.0 * (xi_x * eta_x + xi_y * eta_y + xi_z * eta_z);
//         double e = J / 6.0 * (xi_x * zeta_x + xi_y * zeta_y + xi_z * zeta_z);
//         double f = J / 6.0 * (eta_x * zeta_x + eta_y * zeta_y + eta_z * zeta_z);
//
//     double u_xi2[4][4] = {
//       {   a,  -a, 0.0, 0.0 },
//       {  -a,   a, 0.0, 0.0 },
//       { 0.0, 0.0, 0.0, 0.0 },
//       { 0.0, 0.0, 0.0, 0.0 }
//     };
//     double u_eta2[4][4] = {
//       {   b, 0.0,  -b, 0.0 },
//       { 0.0, 0.0, 0.0, 0.0 },
//       {  -b, 0.0,   b, 0.0 },
//       { 0.0, 0.0, 0.0, 0.0 }
//     };
//     double u_zeta2[4][4] = {
//       {   c, 0.0, 0.0,  -c },
//       { 0.0, 0.0, 0.0, 0.0 },
//       { 0.0, 0.0, 0.0, 0.0 },
//       {  -c, 0.0, 0.0,   c }
//     };
//     double u_xi__u_eta[4][4] = {
//       { 2.0 * d,  -d,  -d, 0.0 },
//       {      -d, 0.0,   d, 0.0 },
//       {      -d,   d, 0.0, 0.0 },
//       {     0.0, 0.0, 0.0, 0.0 }
//     };
//     double u_xi__u_zeta[4][4] = {
//       { 2.0 * e,  -e, 0.0,  -e },
//       {      -e, 0.0, 0.0,   e },
//       {     0.0, 0.0, 0.0, 0.0 },
//       {      -e,   e, 0.0, 0.0 }
//     };
//     double u_eta__u_zeta[4][4] = {
//       { 2.0 * f, 0.0,  -f,  -f },
//       {     0.0, 0.0, 0.0, 0.0 },
//       {      -f, 0.0, 0.0,   f },
//       {      -f, 0.0,   f, 0.0 }
//     };
//
//     for (uint i = 0; i < dim; i++){
//       for (uint j = 0; j < dim; j++){
//  mat_[i][j] = u_xi2[i][j] + u_eta2[i][j] +  u_zeta2[i][j] +
//    u_xi__u_eta[i][j] + u_xi__u_zeta[i][j] + u_eta__u_zeta[i][j];
//       }
//     }
//     std::cout << "0 " << *this << std::endl;
//} break;
        ux2uy2uz2(cell,
                  IntegrationRules::instance().tetWeights(1), 
                  IntegrationRules::instance().tetAbscissa(1), false); //ch
        break;
    case MESH_TETRAHEDRON10_RTTI:
//     {
// ////////////////////////////////////////////////////////////////////
//     double x_xi = cell.shape().partDerivationRealToUnity(0, 1);
//     double x_eta = cell.shape().partDerivationRealToUnity(0, 2);
//     double x_zeta = cell.shape().partDerivationRealToUnity(0, 3);
//
//     double y_xi = cell.shape().partDerivationRealToUnity(1, 1);
//     double y_eta = cell.shape().partDerivationRealToUnity(1, 2);
//     double y_zeta = cell.shape().partDerivationRealToUnity(1, 3);
//
//     double z_xi = cell.shape().partDerivationRealToUnity(2, 1);
//     double z_eta = cell.shape().partDerivationRealToUnity(2, 2);
//     double z_zeta = cell.shape().partDerivationRealToUnity(2, 3);
//
//     double xi_x =  1.0 / J * det(y_eta, z_eta, y_zeta, z_zeta);
//     double xi_y = -1.0 / J * det(x_eta, z_eta, x_zeta, z_zeta);
//     double xi_z =  1.0 / J * det(x_eta, y_eta, x_zeta, y_zeta);
//
//     double eta_x = -1.0 / J * det(y_xi, z_xi, y_zeta, z_zeta);
//     double eta_y =  1.0 / J * det(x_xi, z_xi, x_zeta, z_zeta);
//     double eta_z = -1.0 / J * det(x_xi, y_xi, x_zeta, y_zeta);
//
//     double zeta_x =  1.0 / J * det(y_xi, z_xi, y_eta, z_eta);
//     double zeta_y = -1.0 / J * det(x_xi, z_xi, x_eta, z_eta);
//     double zeta_z =  1.0 / J * det(x_xi, y_xi, x_eta, y_eta);
//
//     double a = J / 6.0 * (xi_x * xi_x + xi_y * xi_y + xi_z * xi_z);
//     double b = J / 6.0 * (eta_x * eta_x + eta_y * eta_y + eta_z * eta_z);
//     double c = J / 6.0 * (zeta_x * zeta_x + zeta_y * zeta_y + zeta_z * zeta_z);
//
//     double d = J / 6.0 * (xi_x * eta_x + xi_y * eta_y + xi_z * eta_z);
//     double e = J / 6.0 * (xi_x * zeta_x + xi_y * zeta_y + xi_z * zeta_z);
//     double f = J / 6.0 * (eta_x * zeta_x + eta_y * zeta_y + eta_z * zeta_z);
//
//     RSTLMatrix compound(10, 10);
//     compound = a * (*Tet10_u_xi2) + b * (*Tet10_u_eta2) + c * (*Tet10_u_zeta2)
//         + (2.0*d) * (*Tet10_u_xi_u_eta)
//         + (2.0*e) * (*Tet10_u_xi_u_zeta)
//         + (2.0*f) * (*Tet10_u_eta_u_zeta);
//     for (uint i = 0; i < dim; i++){
//       for (uint j = 0; j < dim; j++){
//         //** * 6.0 weil a b c d e f / 6
//         mat_[i][j] = compound[i][j] * 6.0;
//       }
//     }
// //    std::cout << " 2 " << *this << std::endl;
//
//     break;
//   }
        ux2uy2uz2(cell, 
                  IntegrationRules::instance().tetWeights(2),
                  IntegrationRules::instance().tetAbscissa(2), false);   break;
    case MESH_HEXAHEDRON_RTTI:
        ux2uy2uz2(cell,
                  IntegrationRules::instance().hexWeights(2),
                  IntegrationRules::instance().hexAbscissa(2), false);   break;
    case MESH_HEXAHEDRON20_RTTI:
        ux2uy2uz2(cell,
                  IntegrationRules::instance().hexWeights(4),
                  IntegrationRules::instance().hexAbscissa(4), false);   break;
    case MESH_TRIPRISM_RTTI:
        ux2uy2uz2(cell, 
                  IntegrationRules::instance().priWeights(2), 
                  IntegrationRules::instance().priAbscissa(2), false);   break;
    case MESH_TRIPRISM15_RTTI:
        ux2uy2uz2(cell,
                  IntegrationRules::instance().priWeights(4),
                  IntegrationRules::instance().priAbscissa(4), false);   break;
           
    default:
        std::cerr << cell.rtti() << std::endl;
        THROW_TO_IMPL
        break;
    }

    if (useCache) cell.setUxCache(mat_);
  
    return *this;
}