Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_VERSATILE_VERSATILE_MESH_H
00002 #define OPENTISSUE_DYNAMICS_VERSATILE_VERSATILE_MESH_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/t4mesh/t4mesh.h>
00013 #include <OpenTissue/dynamics/versatile/versatile_node_traits.h>
00014 #include <OpenTissue/dynamics/versatile/versatile_tetrahedron_traits.h>
00015
00016 #include <OpenTissue/dynamics/versatile/versatile_distance_constraint.h>
00017 #include <OpenTissue/dynamics/versatile/versatile_area_constraint.h>
00018 #include <OpenTissue/dynamics/versatile/versatile_volume_constraint.h>
00019
00020
00021 namespace OpenTissue
00022 {
00023 namespace versatile
00024 {
00025
00026 template <typename versatile_types>
00027 class Mesh
00028 : public OpenTissue::t4mesh::T4Mesh<
00029 versatile_types
00030 , OpenTissue::versatile::detail::NodeTraits<versatile_types>
00031 , OpenTissue::versatile::detail::TetrahedronTraits<versatile_types>
00032 >
00033 {
00034 public:
00035
00036 typedef OpenTissue::t4mesh::T4Mesh<
00037 versatile_types
00038 , OpenTissue::versatile::detail::NodeTraits<versatile_types>
00039 , OpenTissue::versatile::detail::TetrahedronTraits<versatile_types>
00040 > base_class;
00041
00042 typedef typename versatile_types::value_traits value_traits;
00043 typedef typename versatile_types::real_type real_type;
00044 typedef typename versatile_types::vector3_type vector3_type;
00045 typedef typename versatile_types::matrix3x3_type matrix3x3_type;
00046 typedef typename base_class::node_type node_type;
00047 typedef typename base_class::node_iterator node_iterator;
00048 typedef typename base_class::tetrahedron_iterator tetrahedron_iterator;
00049
00050 typedef OpenTissue::versatile::detail::DistanceConstraint<versatile_types> distance_constraint;
00051 typedef OpenTissue::versatile::detail::AreaConstraint<versatile_types> area_constraint;
00052 typedef OpenTissue::versatile::detail::VolumeConstraint<versatile_types> volume_constraint;
00053
00054 typedef std::vector<distance_constraint> distance_container;
00055 typedef std::vector<area_constraint> area_container;
00056 typedef std::vector<volume_constraint> volume_container;
00057
00058 typedef typename distance_container::iterator distance_iterator;
00059 typedef typename area_container::iterator area_iterator;
00060 typedef typename volume_container::iterator volume_iterator;
00061
00062 protected:
00063
00064 distance_container m_distance_constraints;
00065 area_container m_area_constraints;
00066 volume_container m_volume_constraints;
00067
00068 public:
00069
00070 void clear()
00071 {
00072 base_class::clear();
00073 m_distance_constraints.clear();
00074 m_area_constraints.clear();
00075 m_volume_constraints.clear();
00076 }
00077
00078 void initialize()
00079 {
00080 typedef OpenTissue::t4mesh::T4Edges<
00081 Mesh<versatile_types>, OpenTissue::t4mesh::DefaultT4EdgeTraits > Edges;
00082
00083 Edges edges(*this);
00084
00085 for(typename Edges::edge_iterator edge=edges.begin();edge!=edges.end();++edge)
00086 {
00087 distance_constraint constraint;
00088 node_type & ni = *node(edge->idxA());
00089 node_type & nj = *node(edge->idxB());
00090 constraint.initialize(ni,nj);
00091 m_distance_constraints.push_back(constraint);
00092 }
00093
00094 typedef OpenTissue::t4mesh::T4BoundaryFaces<
00095 Mesh<versatile_types>
00096 , OpenTissue::t4mesh::DefaultT4FaceTraits
00097 > Boundary;
00098
00099 Boundary boundary(*this);
00100
00101 for(typename Boundary::face_iterator face=boundary.begin();face!=boundary.end();++face)
00102 {
00103 area_constraint constraint;
00104 node_type & ni = *node(face->idx0());
00105 node_type & nj = *node(face->idx1());
00106 node_type & nk = *node(face->idx2());
00107 constraint.initialize(ni,nj,nk);
00108 m_area_constraints.push_back(constraint);
00109 }
00110
00111 for(tetrahedron_iterator volume=this->tetrahedron_begin();volume!=this->tetrahedron_end();++volume)
00112 {
00113 volume_constraint constraint;
00114 node_type & ni = *volume->i();
00115 node_type & nj = *volume->j();
00116 node_type & nk = *volume->k();
00117 node_type & nm = *volume->m();
00118 constraint.initialize(ni,nj,nk,nm);
00119 m_volume_constraints.push_back(constraint);
00120 }
00121
00122 std::cout << "|D| = " << m_distance_constraints.size() << std::endl;
00123 std::cout << "|A| = " << m_area_constraints.size() << std::endl;
00124 std::cout << "|V| = " << m_volume_constraints.size() << std::endl;
00125 }
00126
00127 void set_distance_coefficients(real_type const & stiffness, real_type const & damping)
00128 {
00129 for(distance_iterator d=m_distance_constraints.begin();d!=m_distance_constraints.end();++d)
00130 {
00131 d->m_k = stiffness;
00132 d->m_b = damping;
00133 }
00134 }
00135
00136 void set_area_coefficients(real_type const & stiffness, real_type const & damping)
00137 {
00138 for(area_iterator a=m_area_constraints.begin();a!=m_area_constraints.end();++a)
00139 {
00140 a->m_k = stiffness;
00141 a->m_b = damping;
00142 }
00143 }
00144
00145 void set_volume_coefficients(real_type const & stiffness, real_type const & damping)
00146 {
00147 for(volume_iterator v=m_volume_constraints.begin();v!=m_volume_constraints.end();++v)
00148 {
00149 v->m_k = stiffness;
00150 v->m_b = damping;
00151 }
00152 }
00153
00154 void set_plasticity(real_type const & c_yield, real_type const & c_creep, real_type const & c_max)
00155 {
00156 for(distance_iterator d=m_distance_constraints.begin();d!=m_distance_constraints.end();++d)
00157 {
00158 d->m_c_yield = c_yield;
00159 d->m_c_creep = c_creep;
00160 d->m_c_max = c_max;
00161 }
00162 }
00163
00164 void clear_constraint_forces()
00165 {
00166 node_iterator begin = this->node_begin();
00167 node_iterator end = this->node_end();
00168 node_iterator node;
00169 for(node=begin;node!=end;++node)
00170 node->m_f_con.clear();
00171 }
00172
00173 void clear_penalty_forces()
00174 {
00175 node_iterator begin = this->node_begin();
00176 node_iterator end = this->node_end();
00177 node_iterator node;
00178 for(node=begin;node!=end;++node)
00179 node->m_f_pen.clear();
00180 }
00181
00182 void apply_constraint_forces()
00183 {
00184 for(distance_iterator d=m_distance_constraints.begin();d!=m_distance_constraints.end();++d)
00185 d->apply();
00186 for(area_iterator a=m_area_constraints.begin();a!=m_area_constraints.end();++a)
00187 a->apply();
00188 for(volume_iterator v=m_volume_constraints.begin();v!=m_volume_constraints.end();++v)
00189 v->apply();
00190 }
00191
00192 real_type compute_internal_energy()
00193 {
00194 real_type energy = value_traits::zero();
00195 for(distance_iterator d=m_distance_constraints.begin();d!=m_distance_constraints.end();++d)
00196 energy += d->compute_internal_energy();
00197 for(area_iterator a=m_area_constraints.begin();a!=m_area_constraints.end();++a)
00198 energy += a->compute_internal_energy();
00199 for(volume_iterator v=m_volume_constraints.begin();v!=m_volume_constraints.end();++v)
00200 energy += v->compute_internal_energy();
00201 return energy;
00202 }
00203
00204 void integrate(real_type const & dt)
00205 {
00206 real_type dt2 = dt*dt;
00207 node_iterator begin = this->node_begin();
00208 node_iterator end = this->node_end();
00209 node_iterator node;
00210 for(node=begin;node!=end;++node)
00211 {
00212 if(node->m_fixed)
00213 continue;
00214
00215 vector3_type tmp = node->m_coord;
00216 node->m_coord = value_traits::two()*node->m_coord - node->m_x0 + (dt2/node->m_mass)*( node->m_f_ext + node->m_f_con + node->m_f_pen);
00217 node->m_v = (node->m_coord - node->m_x0)/(value_traits::two()*dt);
00218 node->m_x0 = tmp;
00219 }
00220 }
00221 };
00222 }
00223 }
00224
00225
00226 #endif