Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_LAWS_MBD_CHATTERJEE_RUINA_COLLISION_LAW_POLICY_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_LAWS_MBD_CHATTERJEE_RUINA_COLLISION_LAW_POLICY_H
00003
00004
00005
00006
00007 #include <OpenTissue/configuration.h>
00008
00009 #include <OpenTissue/dynamics/mbd/mbd_compute_collision_matrix.h>
00010 #include <OpenTissue/dynamics/mbd/mbd_compute_relative_contact_velocity.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace mbd
00015 {
00016 namespace collision_laws
00017 {
00034 template<typename contact_type>
00035 typename contact_type::vector3_type
00036 compute_chatterjee_ruina_impulse(contact_type const * contact)
00037 {
00038 typedef typename contact_type::body_type body_type;
00039 typedef typename contact_type::material_type material_type;
00040 typedef typename contact_type::real_type real_type;
00041 typedef typename contact_type::vector3_type vector3_type;
00042 typedef typename body_type::matrix3x3_type matrix3x3_type;
00043 typedef typename body_type::value_traits value_traits;
00044
00045 using std::sqrt;
00046
00047 material_type * material = contact->m_material;
00048 body_type const * A = contact->get_body_A();
00049 body_type const * B = contact->get_body_B();
00050 real_type e_n = material->normal_restitution();
00051 real_type e_t = material->tangential_restitution();
00052 real_type mu = material->get_isotropic_friction_coefficient();
00053 vector3_type v_a,v_b,w_a,w_b,r_a,r_b;
00054 A->get_velocity(v_a);
00055 A->get_spin(w_a);
00056 r_a = contact->m_rA;
00057 B->get_velocity(v_b);
00058 B->get_spin(w_b);
00059 r_b = contact->m_rB;
00060 vector3_type u = mbd::compute_relative_contact_velocity(v_a,w_a,r_a,v_b,w_b,r_b);
00061 real_type u_n = contact->m_n * u;
00062 if(u_n>=0)
00063 return vector3_type(value_traits::zero(),value_traits::zero(),value_traits::zero());
00064 real_type inv_m_a = A->get_inverse_mass();
00065 real_type inv_m_b = B->get_inverse_mass();
00066 matrix3x3_type invI_a,invI_b;
00067 A->get_inverse_inertia_wcs(invI_a);
00068 B->get_inverse_inertia_wcs(invI_b);
00069 matrix3x3_type K = mbd::compute_collision_matrix(inv_m_a,invI_a,r_a,inv_m_b,invI_b,r_b);
00070 matrix3x3_type invK = inverse(K);
00071
00072
00073 vector3_type JI = K * contact->m_n;
00074 real_type nKn = contact->m_n * JI;
00075 JI = contact->m_n*(-u_n/nKn);
00076
00077 vector3_type JII = -invK*u;
00078
00079
00080 vector3_type Jhat = JI*( value_traits::one() + e_n) + (JII - JI)*( value_traits::one() + e_t);
00081
00082 real_type Pn = Jhat * contact->m_n;
00083 vector3_type tmp = Jhat - contact->m_n*Pn;
00084 real_type norm = sqrt(tmp*tmp);
00085 if((mu>0) && (norm > mu*Pn))
00086 {
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 vector3_type tmp = JII - contact->m_n*(JII*contact->m_n);
00101 real_type w = sqrt(tmp*tmp);
00102 tmp = JII - JI;
00103 w -= mu*contact->m_n*tmp;
00104 real_type kappa = mu*(1. + e_n)*(contact->m_n*JI) / w;
00105
00106 vector3_type J = JI*(value_traits::one() + e_n) + (JII-JI)*kappa;
00107 return J;
00108 }
00109 else
00110 {
00111
00112
00113 return Jhat;
00114 }
00115 }
00116
00117 class ChatterjeeRuinaCollisionLawPolicy
00118 {
00119 public:
00120
00121 template<typename contact_type>
00122 typename contact_type::vector3_type compute_impulse(contact_type const * contact) const
00123 {
00124 return compute_chatterjee_ruina_impulse(contact);
00125 }
00126
00127 };
00128
00129 }
00130 }
00131 }
00132
00133 #endif