Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_STEPPERS_MBD_2PASS_SHOCK_PROPAGATION_STEPPER_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_STEPPERS_MBD_2PASS_SHOCK_PROPAGATION_STEPPER_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/dynamics/mbd/interfaces/mbd_stepper_interface.h>
00013
00014 #include <OpenTissue/dynamics/mbd/steppers/mbd_dynamics_stepper.h>
00015 #include <OpenTissue/dynamics/mbd/steppers/mbd_first_order_stepper.h>
00016 #include <OpenTissue/dynamics/mbd/mbd_stack_propagation.h>
00017 #include <OpenTissue/dynamics/mbd/mbd_is_all_bodies_sleepy.h>
00018 #include <OpenTissue/dynamics/mbd/collision_laws/mbd_frictional_newton_collision_law_policy.h>
00019
00020 namespace OpenTissue
00021 {
00022 namespace mbd
00023 {
00035 template< typename mbd_types, typename solver_type >
00036 class TwoPassShockPropagationStepper
00037 : public StepperInterface<mbd_types>
00038 {
00039 protected:
00040
00041 typedef typename mbd_types::math_policy::real_type real_type;
00042 typedef typename mbd_types::math_policy::value_traits value_traits;
00043 typedef typename mbd_types::math_policy::vector3_type vector3_type;
00044 typedef typename mbd_types::math_policy::vector_type vector_type;
00045 typedef typename mbd_types::math_policy::idx_vector_type idx_vector_type;
00046 typedef typename mbd_types::group_type group_type;
00047
00048 typedef StackPropagation<mbd_types> propagation_algorithm;
00049 typedef DynamicsStepper<mbd_types,solver_type> dynamics_algorithm;
00050 typedef FirstOrderStepper<mbd_types,solver_type> error_correction_algorithm;
00051
00052 typedef typename collision_laws::FrictionalNewtonCollisionLawPolicy collision_law_policy;
00053 typedef IterateOnceCollisionResolver<mbd_types, collision_law_policy > collision_resolver_algorithm;
00054
00055 public:
00056
00057 class node_traits
00058 : public dynamics_algorithm::node_traits
00059 , public error_correction_algorithm::node_traits
00060 , public propagation_algorithm::node_traits
00061 {};
00062
00063 class edge_traits
00064 : public dynamics_algorithm::edge_traits
00065 , public error_correction_algorithm::edge_traits
00066 , public propagation_algorithm::edge_traits
00067 {};
00068
00069 class constraint_traits
00070 : public dynamics_algorithm::constraint_traits
00071 , public error_correction_algorithm::constraint_traits
00072 , public propagation_algorithm::constraint_traits
00073 {};
00074
00075 protected:
00076
00077 struct ErrorFunctor
00078 {
00079 error_correction_algorithm m_correction;
00080
00081 ErrorFunctor()
00082 {
00083 m_correction.warm_starting() = false;
00084 m_correction.use_external_forces() = false;
00085 m_correction.use_erp() = false;
00086 m_correction.get_solver()->set_max_iterations(5);
00087 }
00088
00089 void operator()(group_type & layer)
00090 {
00091 if(mbd::is_all_bodies_sleepy(layer))
00092 return;
00093 m_correction.error_correction(layer);
00094 }
00095 };
00096
00097 struct DynamicsFunctor
00098 {
00099 dynamics_algorithm m_dynamics;
00100 real_type m_h;
00101
00102 DynamicsFunctor()
00103 {
00104 m_dynamics.warm_starting() = false;
00105 m_dynamics.use_stabilization() = false;
00106 m_dynamics.use_friction() = true;
00107 m_dynamics.use_bounce() = true;
00108 m_dynamics.get_solver()->set_max_iterations(5);
00109 }
00110
00111 void operator()(group_type & layer)
00112 {
00113 if(mbd::is_all_bodies_sleepy(layer))
00114 return;
00115 m_dynamics.run(layer,m_h);
00116 }
00117 };
00118
00119 struct StepperFunctor
00120 {
00121 dynamics_algorithm m_dynamics;
00122 error_correction_algorithm m_correction;
00123 real_type m_h;
00124
00125 StepperFunctor()
00126 {
00127 m_correction.warm_starting() = false;
00128 m_correction.use_external_forces() = false;
00129 m_correction.use_erp() = false;
00130 m_correction.get_solver()->set_max_iterations(5);
00131
00132 m_dynamics.warm_starting() = false;
00133 m_dynamics.use_stabilization() = false;
00134 m_dynamics.use_friction() = true;
00135 m_dynamics.use_bounce() = true;
00136 m_dynamics.get_solver()->set_max_iterations(5);
00137 }
00138
00139 void operator()(group_type & layer)
00140 {
00141 if(mbd::is_all_bodies_sleepy(layer))
00142 return;
00143 m_correction.error_correction(layer);
00144 m_dynamics.run(layer,m_h);
00145 }
00146 };
00147
00148 protected:
00149
00150 propagation_algorithm m_propagation;
00151 StepperFunctor m_stepper_functor;
00152 collision_resolver_algorithm m_resolver;
00153 DynamicsFunctor m_dynamics_functor;
00154 ErrorFunctor m_error_functor;
00155
00156 public:
00157
00158 TwoPassShockPropagationStepper(){}
00159 virtual ~TwoPassShockPropagationStepper(){}
00160
00161 public:
00162
00163 void run(group_type & group,real_type const & time_step)
00164 {
00165 m_dynamics_functor.m_h = value_traits::zero();
00166 m_propagation.run(
00167 group
00168 , m_dynamics_functor
00169 , typename propagation_algorithm::downward_tag()
00170 );
00171
00172 m_dynamics_functor.m_h = time_step;
00173 m_propagation.rerun(
00174 group
00175 , m_dynamics_functor
00176 , typename propagation_algorithm::fixate_tag()
00177 , typename propagation_algorithm::upward_tag()
00178 );
00179 }
00180
00181 void error_correction(group_type & group)
00182 {
00183 m_propagation.rerun(
00184 group
00185 , m_error_functor
00186 , typename propagation_algorithm::fixate_tag()
00187 , typename propagation_algorithm::upward_tag()
00188 );
00189 }
00190
00191 void resolve_collisions(group_type & group)
00192 {
00193 m_dynamics_functor.m_dynamics.resolve_collisions(group);
00194 }
00195
00196 };
00197
00198 }
00199 }
00200
00201 #endif