Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_LAWS_MBD_FRICTIONAL_NEWTON_COLLISION_LAW_POLICY_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_LAWS_MBD_FRICTIONAL_NEWTON_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 {
00018
00033 template<typename contact_type>
00034 typename contact_type::vector3_type
00035 compute_frictional_newton_impulse(contact_type const * contact)
00036 {
00037 typedef typename contact_type::body_type body_type;
00038 typedef typename contact_type::material_type material_type;
00039 typedef typename contact_type::real_type real_type;
00040 typedef typename contact_type::vector3_type vector3_type;
00041 typedef typename body_type::matrix3x3_type matrix3x3_type;
00042 typedef typename body_type::value_traits value_traits;
00043
00044 material_type * material = contact->m_material;
00045 body_type * A = contact->get_body_A();
00046 body_type * B = contact->get_body_B();
00047 real_type e_n = material->normal_restitution();
00048 real_type mu = material->get_isotropic_friction_coefficient();
00049 vector3_type v_a,v_b,w_a,w_b,r_a,r_b;
00050 A->get_velocity(v_a);
00051 A->get_spin(w_a);
00052 r_a = contact->m_rA;
00053 B->get_velocity(v_b);
00054 B->get_spin(w_b);
00055 r_b = contact->m_rB;
00056 real_type inv_m_a = A->get_inverse_mass();
00057 real_type inv_m_b = B->get_inverse_mass();
00058 matrix3x3_type invI_a,invI_b;
00059 A->get_inverse_inertia_wcs(invI_a);
00060 B->get_inverse_inertia_wcs(invI_b);
00061 matrix3x3_type K = mbd::compute_collision_matrix(inv_m_a,invI_a,r_a,inv_m_b,invI_b,r_b);
00062 matrix3x3_type invK = inverse(K);
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 vector3_type u_before = compute_relative_contact_velocity(v_a,w_a,r_a,v_b,w_b,r_b);
00078 real_type u_n_before = contact->m_n * u_before;
00079 if(u_n_before>=0)
00080 return vector3_type(value_traits::zero(),value_traits::zero(),value_traits::zero());
00081 vector3_type u_after = contact->m_n*(-e_n*u_n_before);
00082 vector3_type J = invK *(u_after-u_before);
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 real_type j_n = contact->m_n*J;
00095 vector3_type J_N = contact->m_n*j_n;
00096 vector3_type J_T = J - J_N;
00097
00098 real_type norm_j_t = sqrt(J_T*J_T);
00099 real_type friction_limit = std::fabs(mu*j_n);
00100 if(mu==0 || norm_j_t < friction_limit)
00101 {
00102 return J;
00103 }
00104
00105
00106
00107
00108
00109 vector3_type u_t_before = u_before - u_n_before*contact->m_n;
00110 real_type norm_u_t_before = sqrt(u_t_before*u_t_before);
00111 if(!norm_u_t_before)
00112 {
00113
00114
00115 if(norm_j_t)
00116 {
00117 J = J_N + J_T *(friction_limit/norm_j_t);
00118 return J;
00119 }
00120 return vector3_type(value_traits::zero(),value_traits::zero(),value_traits::zero());
00121 }
00122 vector3_type T = u_t_before / norm_u_t_before;
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 j_n = (-(1.+e_n)*u_n_before)/ (contact->m_n * (K*(contact->m_n- T*mu)));
00147 J = contact->m_n*j_n - T*mu* j_n;
00148 return J;
00149 }
00150
00151 class FrictionalNewtonCollisionLawPolicy
00152 {
00153 public:
00154 template<typename contact_type>
00155 typename contact_type::vector3_type compute_impulse(contact_type const * contact) const
00156 {
00157 return compute_frictional_newton_impulse(contact);
00158 }
00159 };
00160
00161 }
00162 }
00163 }
00164
00165 #endif