Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_SIMULATORS_MBD_BISECTION_STEP_SIMULATOR_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_SIMULATORS_MBD_BISECTION_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
00014 namespace OpenTissue
00015 {
00016 namespace mbd
00017 {
00033 template< typename mbd_types >
00034 class BisectionStepSimulator
00035 : public SimulatorInterface<mbd_types>
00036 {
00037 protected:
00038
00039 typedef typename mbd_types::math_policy::index_type size_type;
00040 typedef typename mbd_types::math_policy::real_type real_type;
00041 typedef typename mbd_types::math_policy::vector_type vector_type;
00042 typedef typename mbd_types::group_type group_type;
00043 typedef typename mbd_types::group_ptr_container group_ptr_container;
00044
00045 public:
00046
00047 class node_traits{};
00048 class edge_traits{};
00049 class constraint_traits{};
00050
00051 protected:
00052
00053 vector_type m_s;
00054 vector_type m_u;
00055 group_type * m_all;
00056
00057 group_ptr_container m_groups;
00058
00059 public:
00060
00061 BisectionStepSimulator()
00062 : m_all(0)
00063 {}
00064
00065 virtual ~BisectionStepSimulator() {}
00066
00067 public:
00068
00069 void run(real_type const & time_step)
00070 {
00071
00072 this->get_collision_detection()->set_short_circuiting(true);
00073
00074 size_type max_iteration = 100;
00075 size_type iteration = 0;
00076 real_type tst_underflow = 1e-3;
00077 real_type final = time_step;
00078 real_type cur = 0;
00079 real_type next = time_step;
00080
00081 mbd::compute_scripted_motions(*m_all,this->time());
00082
00083 this->get_collision_detection()->run(m_groups);
00084
00085 resolve_collisions(m_groups);
00086 do
00087 {
00088 record_state();
00089 run(m_groups,next-cur);
00090 bool penetration = this->get_collision_detection()->run(m_groups);
00091 if(penetration)
00092 {
00093 if(iteration>max_iteration)
00094 {
00095 next = final;
00096 resolve_collisions(m_groups);
00097 error_correction(m_groups);
00098 }
00099 else
00100 {
00101 rewind_state();
00102 real_type tmp = next;
00103 next = cur + ((next - cur)/2.0f);
00104 if(std::fabs(tmp-next)<tst_underflow)
00105 {
00106 cur = next;
00107 next = final;
00108 resolve_collisions(m_groups);
00109 }
00110 ++iteration;
00111 }
00112 }
00113 else
00114 {
00115 cur = next;
00116 next = final;
00117 resolve_collisions(m_groups);
00118 }
00119 }
00120 while(cur<final);
00121 update_time(time_step);
00122 }
00123
00124 protected:
00125
00126 void error_correction(group_ptr_container & groups)
00127 {
00128 for(typename group_ptr_container::iterator tmp=groups.begin();tmp!=groups.end();++tmp)
00129 {
00130 group_type * group = (*tmp);
00131 this->get_stepper()->error_correction(*group);
00132 }
00133 }
00134
00135 void resolve_collisions(group_ptr_container & groups)
00136 {
00137 for(typename group_ptr_container::iterator tmp=groups.begin();tmp!=groups.end();++tmp)
00138 {
00139 group_type * group = (*tmp);
00140 this->get_stepper()->resolve_collisions(*group);
00141 }
00142 }
00143
00144 void run(group_ptr_container & groups,real_type const & time_step)
00145 {
00146 m_all = this->get_configuration()->get_all_body_group();
00147 mbd::compute_scripted_motions(*m_all, this->time()+time_step);
00148
00149 for(typename group_ptr_container::iterator tmp=groups.begin();tmp!=groups.end();++tmp)
00150 {
00151 group_type * group = (*tmp);
00152 this->get_sleepy()->evaluate(group->body_begin(),group->body_end());
00153 if(!mbd::is_all_bodies_sleepy(*group))
00154 this->get_stepper()->run(*group,time_step);
00155 }
00156 }
00157
00158 void record_state()
00159 {
00160 m_all = this->get_configuration()->get_all_body_group();
00161 mbd::get_position_vector(*m_all, m_s);
00162 mbd::get_velocity_vector(*m_all, m_u);
00163 }
00164
00165 void rewind_state()
00166 {
00167 if(m_all)
00168 {
00169 mbd::set_position_vector(*m_all,m_s);
00170 mbd::set_velocity_vector(*m_all,m_u);
00171 }
00172 }
00173
00174 };
00175
00176 }
00177 }
00178
00179 #endif