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