00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_SIMULATORS_MBD_SEPARATED_COLLISION_CONTACT_FIXED_STEP_SIMULATOR_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_SIMULATORS_MBD_SEPARATED_COLLISION_CONTACT_FIXED_STEP_SIMULATOR_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/dynamics/mbd/interfaces/mbd_simulator_interface.h>
00013 #include <OpenTissue/dynamics/mbd/mbd_stack_propagation.h>
00014
00015 namespace OpenTissue
00016 {
00017 namespace mbd
00018 {
00056 template< typename mbd_types >
00057 class SeparatedCollisionContactFixedStepSimulator
00058 : public SimulatorInterface<mbd_types>
00059 {
00060 protected:
00061
00062 typedef typename mbd_types::math_policy math_policy;
00063 typedef typename math_policy::index_type size_type;
00064 typedef typename math_policy::real_type real_type;
00065 typedef typename math_policy::vector3_type vector3_type;
00066 typedef typename math_policy::idx_vector_type idx_vector_type;
00067 typedef typename math_policy::matrix_type matrix_type;
00068 typedef typename math_policy::vector_type vector_type;
00069 typedef typename math_policy::value_traits value_traits;
00070
00071 typedef typename mbd_types::group_type group_type;
00072 typedef typename mbd_types::group_ptr_container group_ptr_container;
00073 typedef typename mbd_types::stepper_policy stepper_policy;
00074 typedef StackPropagation<mbd_types> propagation_algorithm;
00075 typedef typename mbd_types::material_library_type material_library_type;
00076 typedef typename material_library_type::material_iterator material_iterator;
00077
00078 public:
00079
00080 class node_traits
00081 : public propagation_algorithm::node_traits
00082 {};
00083
00084 class edge_traits
00085 : public propagation_algorithm::edge_traits
00086 {};
00087
00088 class constraint_traits
00089 : public propagation_algorithm::constraint_traits
00090 {};
00091
00092 protected:
00093
00099 struct StepperFunctor
00100 {
00101 stepper_policy * m_stepper;
00102 real_type m_h;
00103
00104 void operator()(group_type & layer)
00105 {
00106 assert(m_stepper || !"StepperFunc::operator(): missing stepper");
00107 m_stepper->run(layer,m_h);
00108 }
00109 };
00110
00111 protected:
00112
00113 propagation_algorithm m_propagation;
00114 StepperFunctor m_stepper_functor;
00115 vector_type m_s_cur;
00116 vector_type m_s_predicted;
00117 vector_type m_u;
00118 vector_type m_F;
00119 matrix_type m_invM;
00120 vector_type m_restitution;
00121 group_type * m_all;
00122 group_ptr_container m_groups;
00123
00124 public:
00125
00126 SeparatedCollisionContactFixedStepSimulator(){}
00127
00128 virtual ~SeparatedCollisionContactFixedStepSimulator(){}
00129
00130 public:
00131
00132 void run(real_type const & time_step)
00133 {
00134 assert(time_step>0 || !"SeparatedCollisionContactFixedStepSimulator::run(): time step must be positive");
00135
00136 m_all = this->get_configuration()->get_all_body_group();
00137
00138 size_type n = m_all->size_bodies();
00139
00140 math_policy::resize( m_s_cur, 7*n);
00141 math_policy::resize( m_s_predicted, 7*n);
00142 math_policy::resize( m_u, 6*n);
00143 math_policy::resize( m_F, 6*n);
00144
00145 mbd::get_position_vector(*m_all, m_s_cur);
00146 mbd::get_inverse_mass_matrix(*m_all,m_invM);
00147
00148 mbd::compute_scripted_motions(*m_all, this->time() + time_step);
00149
00150 m_stepper_functor.m_stepper = this->get_stepper();
00151 m_stepper_functor.m_h = time_step;
00152
00153 int collision_iterations = 5;
00154 for(int i=0;i<collision_iterations;++i)
00155 resolve_collisions(time_step);
00156 velocity_update(time_step);
00157
00158 extract_restitution();
00159 int contact_iterations = 10;
00160 real_type amount = 1./contact_iterations;
00161 for(int i=0;i<contact_iterations;++i)
00162 {
00163 increase_restitution(amount);
00164 contact_handling(time_step);
00165 }
00166 int shock_iterations = 1;
00167 for(int i=0;i<shock_iterations;++i)
00168 shock_propagation(time_step);
00169 restore_restitution();
00170
00171 position_update(time_step);
00172 update_time(time_step);
00173 }
00174
00175 protected:
00176
00177 void velocity_update(real_type const & h)
00178 {
00179 assert(m_all || !"SeparatedCollisionContactFixedStepSimulator::velocity_update(): missing all group");
00180 mbd::get_external_force_vector(*m_all,m_F,true);
00181 mbd::get_velocity_vector(*m_all, m_u);
00182
00183
00184 math_policy::prod_add(m_invM, m_F,m_u,h);
00185
00186 mbd::set_velocity_vector(*m_all,m_u);
00187 }
00188
00189 void position_update(real_type const & h)
00190 {
00191 assert(m_all || !"SeparatedCollisionContactFixedStepSimulator::position_update(): missing all group");
00192 mbd::get_velocity_vector(*m_all, m_u);
00193 mbd::compute_position_update(*m_all,m_s_cur,m_u,h,m_s_cur);
00194 mbd::set_position_vector(*m_all,m_s_cur);
00195 }
00196
00197 void resolve_collisions(real_type const & h)
00198 {
00199 assert(m_all || !"SeparatedCollisionContactFixedStepSimulator::resolve_collisions(): missing all group");
00200
00201
00202 mbd::get_external_force_vector(*m_all,m_F, true);
00203 mbd::get_velocity_vector(*m_all, m_u);
00204
00205 m_u += prod(m_invM, m_F)*h;
00206
00207 mbd::compute_position_update(*m_all,m_s_cur,m_u,h,m_s_predicted);
00208 mbd::set_position_vector(*m_all,m_s_predicted);
00209
00210 this->get_collision_detection()->run( m_groups );
00211 for(typename group_ptr_container::iterator tmp=m_groups.begin();tmp!=m_groups.end();++tmp)
00212 {
00213 group_type * group = (*tmp);
00214 this->get_stepper()->resolve_collisions(*group);
00215 }
00216 }
00217
00218 void contact_handling(real_type const & h)
00219 {
00220 assert(m_all || !"SeparatedCollisionContactFixedStepSimulator::contact_handling(): missing all group");
00221
00222 mbd::get_velocity_vector(*m_all, m_u);
00223 mbd::compute_position_update(*m_all,m_s_cur,m_u,h,m_s_predicted);
00224 mbd::set_position_vector(*m_all,m_s_predicted);
00225
00226 this->get_collision_detection()->run( m_groups );
00227 for(typename group_ptr_container::iterator tmp=m_groups.begin();tmp!=m_groups.end();++tmp)
00228 {
00229 group_type * group = (*tmp);
00230 this->get_stepper()->resolve_collisions(*group);
00231 }
00232 }
00233
00234 void shock_propagation(real_type const & h)
00235 {
00236 assert(m_all || !"SeparatedCollisionContactFixedStepSimulator::shock_propagation(): missing all group");
00237
00238
00239 mbd::get_velocity_vector(*m_all, m_u);
00240 mbd::compute_position_update(*m_all,m_s_cur,m_u,h,m_s_predicted);
00241 mbd::set_position_vector(*m_all,m_s_predicted);
00242
00243 this->get_collision_detection()->run( m_groups );
00244 for(typename group_ptr_container::iterator tmp=m_groups.begin();tmp!=m_groups.end();++tmp)
00245 {
00246 group_type * group = (*tmp);
00247 m_propagation.run(
00248 *group
00249 , m_stepper_functor
00250 , typename propagation_algorithm::fixate_tag()
00251 , typename propagation_algorithm::upward_tag()
00252 );
00253 }
00254 }
00255
00256 void extract_restitution()
00257 {
00258 size_type N = this->get_configuration()->get_material_library()->size_materials();
00259
00260 math_policy::resize( m_restitution, N);
00261
00262 typename vector_type::iterator e_n = m_restitution.begin();
00263
00264 material_iterator material = this->get_configuration()->get_material_library()->material_begin();
00265 material_iterator end = this->get_configuration()->get_material_library()->material_end();
00266
00267 for(;material!=end;++material)
00268 {
00269 *e_n++ = material->normal_restitution();
00270 material->normal_restitution() = -1.;
00271 }
00272 }
00273
00274 void increase_restitution(real_type const & amount)
00275 {
00276 using std::min;
00277
00278 material_iterator material = this->get_configuration()->get_material_library()->material_begin();
00279 material_iterator end = this->get_configuration()->get_material_library()->material_end();
00280
00281 for(;material!=end;++material)
00282 {
00283 real_type e_n = material->normal_restitution() + amount;
00284 e_n = min(value_traits::zero(),e_n);
00285 material->normal_restitution() = e_n;
00286 }
00287 }
00288
00289 void restore_restitution()
00290 {
00291 typename vector_type::iterator e_n = m_restitution.begin();
00292
00293 material_iterator material = this->get_configuration()->get_material_library()->material_begin();
00294 material_iterator end = this->get_configuration()->get_material_library()->material_end();
00295
00296 for(;material!=end;++material)
00297 {
00298 material->normal_restitution() = (*e_n++);
00299 }
00300 }
00301
00302 };
00303
00304 }
00305 }
00306
00307 #endif