void RotationMatrixTest::rotVtoU(RealVectorValue v, RealVectorValue u) { RealTensorValue ident(1,0,0, 0,1,0, 0,0,1); RealVectorValue vhat = v/v.size(); RealVectorValue uhat = u/u.size(); RealTensorValue r = RotationMatrix::rotVec1ToVec2(v, u); RealVectorValue rotated_v = r*vhat; for (unsigned i = 0 ; i < LIBMESH_DIM ; ++i) CPPUNIT_ASSERT_DOUBLES_EQUAL( rotated_v(i), uhat(i), 0.0001); CPPUNIT_ASSERT( r*r.transpose() == ident); CPPUNIT_ASSERT( r.transpose()*r == ident); }
ContactState FrictionalContactProblem::calculateInteractionSlip(RealVectorValue &slip, Real &slip_residual, const RealVectorValue &normal, const RealVectorValue &residual, const RealVectorValue &incremental_slip, const RealVectorValue &stiffness, const Real friction_coefficient, const Real slip_factor, const Real slip_too_far_factor, const int dim) { ContactState state = STICKING; RealVectorValue normal_residual = normal * (normal * residual); Real normal_force = normal_residual.size(); // _console<<"normal="<<info._normal<<std::endl; // _console<<"normal_force="<<normal_force<<std::endl; // _console<<"residual="<<residual<<std::endl; // _console<<"stiffness="<<stiff_vec<<std::endl; RealVectorValue tangential_force = normal_residual - residual ; // swap sign to make the code more manageable Real tangential_force_magnitude = tangential_force.size(); Real capacity = normal_force * friction_coefficient; if (capacity < 0.0) capacity = 0.0; Real slip_inc = incremental_slip.size(); slip(0)=0.0; slip(1)=0.0; slip(2)=0.0; if (slip_inc > 0) { state = SLIPPING; Real slip_dot_tang_force = incremental_slip*tangential_force / slip_inc; if (slip_dot_tang_force < capacity) { state = SLIPPED_TOO_FAR; // _console<<"STF slip_dot_force: "<<slip_dot_tang_force<<" capacity: "<<capacity<<std::endl; } } Real excess_force = tangential_force_magnitude - capacity; if (excess_force < 0.0) excess_force = 0; if (state == SLIPPED_TOO_FAR) { RealVectorValue slip_inc_direction = incremental_slip / slip_inc; Real tangential_force_in_slip_dir = slip_inc_direction*tangential_force; slip_residual = capacity - tangential_force_in_slip_dir; RealVectorValue force_from_unit_slip(0.0,0.0,0.0); for (int i=0; i<dim; ++i) { force_from_unit_slip(i) = stiffness(i) * slip_inc_direction(i); } Real stiffness_slipdir = force_from_unit_slip * slip_inc_direction; //k=f resolved to slip dir because f=kd and d is a unit vector Real slip_distance = slip_too_far_factor*(capacity - tangential_force_in_slip_dir) / stiffness_slipdir; // _console<<"STF dist: "<<slip_distance<<" inc: "<<slip_inc<<std::endl; // _console<<"STF cap: "<<capacity<<" tfs: "<<tangential_force_in_slip_dir<<std::endl; if (slip_distance < slip_inc) { // _console<<"STF"<<std::endl; slip = slip_inc_direction * -slip_distance; } else { // _console<<"STF max"<<std::endl; slip = -incremental_slip; } } else if (excess_force > 0) { state = SLIPPING; Real tangential_force_magnitude = tangential_force.size(); slip_residual = excess_force; RealVectorValue tangential_direction = tangential_force / tangential_force_magnitude; RealVectorValue excess_force_vector = tangential_direction * excess_force; for (int i=0; i<dim; ++i) { slip(i) = slip_factor * excess_force_vector(i) / stiffness(i); } //zero out component of slip in normal direction RealVectorValue slip_normal_dir = normal * (normal * slip); slip = slip - slip_normal_dir; } return state; }