Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_MBD_MATERIAL_H
00002 #define OPENTISSUE_DYNAMICS_MBD_MBD_MATERIAL_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <boost/cast.hpp>
00013
00014 namespace OpenTissue
00015 {
00016
00017 namespace mbd
00018 {
00019
00039 template<typename mbd_types>
00040 class Material
00041 {
00042 public:
00043
00044 typedef typename mbd_types::math_policy math_policy;
00045 typedef typename math_policy::real_type real_type;
00046 typedef typename math_policy::value_traits value_traits;
00047 typedef typename math_policy::index_type index_type;
00048 typedef typename math_policy::index_type size_type;
00049 typedef typename math_policy::vector_type vector_type;
00050 typedef typename math_policy::vector_range vector_range;
00051 typedef typename math_policy::vector3_type vector3_type;
00052
00053 protected:
00054
00055 index_type m_material_idx_A;
00056 index_type m_material_idx_B;
00057
00058 vector_type m_mu;
00059 real_type m_e_n;
00060 real_type m_e_t;
00061 real_type m_erp;
00062 real_type m_gamma;
00063
00064 bool m_use_sliding_direction;
00065 bool m_use_prefixed_direction;
00066
00067 vector3_type m_prefixed_direction;
00068 index_type m_prefixed_material_idx;
00069 public:
00070
00071 Material(){ clear(); }
00072
00073
00074
00075 virtual ~Material(){ }
00076
00077 bool operator==(Material const & m) const
00078 {
00079 if(m_material_idx_A == m.m_material_idx_A && m_material_idx_B==m.m_material_idx_B)
00080 return true;
00081 return false;
00082 }
00083
00084 public:
00085
00090 void clear()
00091 {
00092 m_material_idx_A = 0;
00093 m_material_idx_B = 0;
00094 m_e_n = value_traits::half();
00095 m_e_t = value_traits::zero();
00096 m_erp = boost::numeric_cast<real_type>(0.8);
00097 m_gamma = value_traits::zero();
00098 m_use_sliding_direction = true;
00099 m_use_prefixed_direction = false;
00100 m_prefixed_direction = vector3_type( value_traits::zero(), value_traits::zero(), value_traits::zero() );
00101 m_prefixed_material_idx = 0;
00102 math_policy::resize(m_mu, 2);
00103 std::fill( m_mu.begin(), m_mu.end(), value_traits::half() );
00104 }
00105
00106 void set_material_indices(index_type A, index_type B)
00107 {
00108 if(A<B)
00109 {
00110 this->m_material_idx_A = A;
00111 this->m_material_idx_B = B;
00112 }
00113 else
00114 {
00115 this->m_material_idx_A = B;
00116 this->m_material_idx_B = A;
00117 }
00118 }
00119
00120 index_type hash_key() const { return Material::hash_key(m_material_idx_A,m_material_idx_B); }
00121
00131 static index_type hash_key(index_type A, index_type B){ return (A < B) ? ((A<<16)|(B&0x0000FFFF)) : ((B<<16)|(A&0x0000FFFF)) ; }
00132
00133 public:
00134
00144 void set_friction_coefficient(real_type const & mu)
00145 {
00146 assert(mu>value_traits::zero() || !"Material::set_friction_coefficient(): value must be positive");
00147 assert(m_mu.size()>0 || !"Material::set_friction_coefficient(): No friction directions exist");
00148 std::fill( m_mu.begin(), m_mu.end(), value_traits::half() );
00149 }
00150
00162 void set_friction_coefficient(size_t const & idx, real_type const & mu)
00163 {
00164 assert(mu>value_traits::zero() || !"Material::set_friction_coefficient(): value must be positive");
00165 assert(m_mu.size()>0 || !"Material::set_friction_coefficient(): No friction directions exist");
00166 assert(idx < m_mu.size() || !"Material::set_friction_coefficient(): No such friction direction exist");
00167 this->m_mu(idx) = mu;
00168 }
00169
00179 real_type const & get_friction_coefficient(size_t const & idx) const
00180 {
00181 assert(m_mu.size()>0 || !"Material::get_friction_coefficient(): No friction directions exist");
00182 assert(idx < m_mu.size() || !"Material::get_friction_coefficient(): No such friction direction exist");
00183 return this->m_mu(idx);
00184 }
00185
00198 real_type get_isotropic_friction_coefficient() const
00199 {
00200 if( m_mu.empty() )
00201 return value_traits::zero();
00202 return m_mu(0);
00203 }
00204
00214 void set_number_of_friction_directions(size_t const & eta)
00215 {
00216 using std::min;
00217
00218
00219 size_t old_eta = m_mu.size();
00220 vector_type tmp;
00221 math_policy::resize(tmp, old_eta );
00222 tmp = m_mu;
00223
00224
00225 math_policy::resize( m_mu, eta );
00226
00227 size_t N = min(old_eta,eta);
00228 if(N>0)
00229 {
00230 size_t i = 0;
00231
00232 for(;i<N;++i)
00233 m_mu(i) = tmp(i);
00234
00235 for(;i<eta;++i)
00236 m_mu(i) = tmp(N-1);
00237 }
00238 }
00239
00245 size_t get_number_of_friction_directions() const
00246 {
00247 return m_mu.size();
00248 }
00249
00250 real_type const & normal_restitution() const { return this->m_e_n; }
00251 real_type & normal_restitution() { return this->m_e_n; }
00252
00253 real_type const & tangential_restitution() const { return this->m_e_t; }
00254 real_type & tangential_restitution() { return this->m_e_t; }
00255
00256 real_type const & get_error_reduction_parameter() const { return m_erp; }
00257 void set_error_reduction_parameter(real_type const & erp)
00258 {
00259 assert(erp>=0 || !"Material::set_error_reduction_parameter(): value must be non-negative");
00260 assert(erp<=1 || !"Material::set_error_reduction_parameter(): value must be less than or equal 1");
00261 this->m_erp = erp;
00262 }
00263
00264 void set_normal_regularization(real_type const & gamma)
00265 {
00266 assert(is_number(gamma) || !"Material::set_regularization(): not a number was encountered");
00267 assert(gamma <= value_traits::one() || !"Material::set_regularization(): gamma must be less than or equal to one");
00268 assert(gamma >= value_traits::zero() || !"Material::set_regularization(): gamma must be non-negative");
00269 m_gamma = gamma;
00270 }
00271
00272 real_type const & get_normal_regularization() const { return m_gamma; }
00273
00279 bool get_use_sliding_direction() const { return m_use_sliding_direction; }
00280
00289 void set_use_sliding_direction(bool const & value) { m_use_sliding_direction = value; }
00290
00299 bool get_use_prefixed_direction() const { return m_use_prefixed_direction; }
00300
00308 void set_use_prefixed_direction(bool const & value) { m_use_prefixed_direction = value; }
00309
00321 vector3_type const & get_prefixed_direction() const { return m_prefixed_direction; }
00322
00331 void set_prefixed_direction(vector3_type const & dir) { m_prefixed_direction = unit( dir ); }
00332
00342 void set_prefixed_material_index(index_type const & idx)
00343 {
00344 m_prefixed_material_idx = idx;
00345 }
00346
00347
00361 index_type get_prefixed_material_index() const
00362 {
00363 return m_prefixed_material_idx;
00364 }
00365
00366 };
00367
00368 }
00369 }
00370
00371 #endif