Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_VERSATILE_VERSATILE_DISTANCE_CONSTRAINT_H
00002 #define OPENTISSUE_DYNAMICS_VERSATILE_VERSATILE_DISTANCE_CONSTRAINT_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace versatile
00015 {
00016 namespace detail
00017 {
00018
00019 template <typename versatile_types>
00020 class DistanceConstraint
00021 {
00022 public:
00023
00024 typedef typename versatile_types::value_traits value_traits;
00025 typedef typename versatile_types::real_type real_type;
00026 typedef typename versatile_types::vector3_type vector3_type;
00027 typedef typename versatile_types::node_type node_type;
00028
00029 public:
00030
00031 real_type m_k;
00032 real_type m_b;
00033 real_type m_D0;
00034 node_type * m_ni;
00035 node_type * m_nj;
00036
00037 real_type m_c_yield;
00038 real_type m_c_creep;
00039 real_type m_c_max;
00040 real_type m_l_plastic;
00041
00042 public:
00043
00044 DistanceConstraint()
00045 : m_k( value_traits::zero() )
00046 , m_b( value_traits::zero() )
00047 , m_D0( value_traits::zero() )
00048 , m_ni(0)
00049 , m_nj(0)
00050 , m_c_yield( value_traits::infinity() )
00051 , m_c_creep( value_traits::zero() )
00052 , m_c_max( value_traits::zero() )
00053 , m_l_plastic( value_traits::zero() )
00054 {}
00055
00056 public:
00057
00058 void initialize(node_type & ni, node_type & nj)
00059 {
00060 using std::sqrt;
00061
00062 m_ni = & ni;
00063 m_nj = & nj;
00064 vector3_type d = m_nj->m_coord - m_ni->m_coord;
00065 m_D0 = sqrt(d*d);
00066 }
00067
00068 void apply()
00069 {
00070 using std::min;
00071 using std::sqrt;
00072
00073 vector3_type e = m_nj->m_coord - m_ni->m_coord;
00074 real_type e_norm = sqrt(e*e);
00075 real_type C = ( (e_norm-m_D0) / m_D0);
00076 vector3_type dCdj = ( e/ (m_D0 * e_norm));
00077 vector3_type dCdi = - dCdj;
00078 real_type factor = value_traits::zero();
00079 if(m_k>value_traits::zero())
00080 factor -= m_k *C;
00081 if(m_b>value_traits::zero())
00082 factor -= m_b * (dCdi*m_ni->m_v + dCdj*m_nj->m_v);
00083 if(factor)
00084 {
00085 m_ni->m_f_con += factor*dCdi;
00086 m_nj->m_f_con += factor*dCdj;
00087 }
00088
00089
00090 real_type l = e_norm-m_D0;
00091 if(l>m_c_yield)
00092 {
00093 m_l_plastic += m_c_creep*(l-m_l_plastic);
00094 m_l_plastic = min(m_l_plastic,m_c_max);
00095 }
00096 vector3_type f_plastic = vector3_type(-m_k*m_l_plastic );
00097 m_ni->m_f_con -= f_plastic;
00098 m_nj->m_f_con += f_plastic;
00099 }
00100
00101 real_type compute_internal_energy()
00102 {
00103 using std::sqrt;
00104
00105 vector3_type e = m_nj->m_coord - m_ni->m_coord;
00106 real_type e_norm = sqrt(e*e);
00107 real_type C = ( (e_norm-m_D0) / m_D0);
00108 return value_traits::half()*m_k*C*C;
00109 }
00110 };
00111
00112 }
00113 }
00114 }
00115
00116
00117 #endif