int BeamEndContact3D::update(void) // this function updates variables for an incremental step n to n+1 { Vector disp_L(3); Vector disp_a(6); Vector rot_a(BEC3_NUM_DIM); Vector omega(BEC3_NUM_DIM); Matrix eMap(BEC3_NUM_DIM,BEC3_NUM_DIM); // update beam node coordinates and rotations disp_a = theNodes[0]->getTrialDisp(); for (int i = 0; i < 3; i++) { mDcrd_a(i) = mIcrd_a(i) + disp_a(i); rot_a(i) = disp_a(i+3); } // update slave node coordinates mDcrd_s = mIcrd_s + theNodes[1]->getTrialDisp(); // update Lagrange multiplier value disp_L = theNodes[2]->getTrialDisp(); mLambda = disp_L(0); // update the normal vector omega = rot_a - ((mNormal^rot_a)*mNormal); // compute exponential map of skew(omega) eMap = ExpMap(omega); // compute the current normal vector mNormal = eMap*mIniNormal; // update gap mGap = (mDcrd_s - mDcrd_a)^mNormal; // update projection coordinate mx_p = mDcrd_s - (mGap*mNormal); // set the boolean release condition should_be_released = (mLambda <= -mForceTol); return 0; }
int BeamContact2Dp::update(void) // this function updates variables for an incremental step n to n+1 { double tensileStrength; Vector a1(BC2D_NUM_DIM); Vector b1(BC2D_NUM_DIM); Vector a1_n(BC2D_NUM_DIM); Vector b1_n(BC2D_NUM_DIM); Vector disp_a(3); Vector disp_b(3); Vector disp_L(BC2D_NUM_DIM); double rot_a; double rot_b; Vector x_c(BC2D_NUM_DIM); // update slave node coordinates mDcrd_s = mIcrd_s + theNodes[2]->getTrialDisp(); // update nodal coordinates disp_a = theNodes[0]->getTrialDisp(); disp_b = theNodes[1]->getTrialDisp(); for (int i = 0; i < 2; i++) { mDcrd_a(i) = mIcrd_a(i) + disp_a(i); mDcrd_b(i) = mIcrd_b(i) + disp_b(i); } // compute incremental rotation from step n to step n+1 rot_a = disp_a(2) - mDisp_a_n(2); rot_b = disp_b(2) - mDisp_b_n(2); // get tangent vectors from last converged step a1_n = Geta1(); b1_n = Getb1(); // linear update of tangent vectors a1 = a1_n + rot_a*mEyeS*a1_n; b1 = b1_n + rot_b*mEyeS*b1_n; // update centerline projection coordinate x_c = mDcrd_a*mShape(0) + a1*mLength*mShape(1) + mDcrd_b*mShape(2) + b1*mLength*mShape(3); // update penetration function mGap = (mNormal^(mDcrd_s - x_c)) - mRadius; if (mGap < 0.0 && in_bounds) { inContact = true; } else { mGap = 0.0; inContact = false; } // update normal contact force if (was_inContact) { mLambda = mPenalty*mGap; } else { mLambda = 0.0; } // get tensile strength from contact material tensileStrength = theMaterial->getTensileStrength(); // determine trial strain vector based on contact state if (inContact) { Vector strain(3); double slip; Vector c1n1(2); Vector c2n1(2); // tangent at the centerline projection in step n+1 c1n1 = mDshape(0)*mDcrd_a + mDshape(1)*mLength*ma_1 + mDshape(2)*mDcrd_b + mDshape(3)*mLength*mb_1; // update vector c2 for step n+1 c2n1 = (mDcrd_s - x_c)/((mDcrd_s - x_c).Norm()); // update vector c2 for step n+1 c2n1(0) = -c1n1(1); c2n1(1) = c1n1(0); // compute the slip slip = mg_xi^(mDcrd_s - x_c - mrho*c2n1); // set the strain vector strain(0) = mGap; strain(1) = slip; strain(2) = -mLambda; theMaterial->setTrialStrain(strain); } else { Vector strain(3); // set the strain vector strain(0) = mGap; strain(1) = 0.0; strain(2) = -mLambda; theMaterial->setTrialStrain(strain); } return 0; }