Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_MBD_STACK_PROPAGATION_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_MBD_STACK_PROPAGATION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/dynamics/mbd/mbd_stack_analysis.h>
00013
00014 namespace OpenTissue
00015 {
00016 namespace mbd
00017 {
00032 template<typename mbd_types >
00033 class StackPropagation : public StackAnalysis<mbd_types>
00034 {
00035 public:
00036
00037 typedef StackAnalysis<mbd_types> analysis_type;
00038
00039 typedef typename mbd_types::math_policy::index_type size_type;
00040 typedef typename mbd_types::math_policy::index_type index_type;
00041
00042 typedef typename mbd_types::math_policy::real_type real_type;
00043 typedef typename mbd_types::math_policy::vector3_type vector3_type;
00044 typedef typename mbd_types::group_type group_type;
00045 typedef typename mbd_types::body_type body_type;
00046 typedef typename mbd_types::edge_type edge_type;
00047
00048 typedef typename mbd_types::contact_type contact_type;
00049 typedef typename mbd_types::material_type material_type;
00050 typedef typename mbd_types::edge_ptr_container edge_ptr_container;
00051 typedef typename mbd_types::indirect_edge_iterator indirect_edge_iterator;
00052 typedef typename mbd_types::group_container group_container;
00053
00054 public:
00055
00056 class node_traits
00057 : public analysis_type::node_traits
00058 {
00059 public:
00060 bool m_sp_fixiated;
00061 };
00062
00063 class edge_traits
00064 : public analysis_type::edge_traits
00065 {};
00066
00067 class constraint_traits
00068 : public analysis_type::constraint_traits
00069 {};
00070
00071 protected:
00072
00073 group_container m_layers;
00074 size_type m_cnt;
00075
00076 public:
00077
00078 struct upward_tag {};
00079 struct downward_tag {};
00080 struct fixate_tag {};
00081
00082 public:
00083
00084
00092 size_type size() const { return m_cnt; }
00093
00105 template <typename algorithm_type>
00106 void run(group_type & group, algorithm_type & algorithm, fixate_tag, upward_tag )
00107 {
00108 m_cnt = analyze(group,m_layers);
00109 for(index_type height=0;height<m_cnt;++height)
00110 {
00111 fixiate(height,m_layers[height]);
00112 algorithm(m_layers[height]);
00113 unfixiate(m_layers[height]);
00114 }
00115 }
00116
00117
00118
00119
00120
00121 template <typename algorithm_type>
00122 void rerun(group_type & , algorithm_type & algorithm, fixate_tag, upward_tag)
00123 {
00124 for(index_type height=0;height<m_cnt;++height)
00125 {
00126 fixiate(height,m_layers[height]);
00127 algorithm(m_layers[height]);
00128 unfixiate(m_layers[height]);
00129 }
00130 }
00131
00132 public:
00133
00134 template <typename algorithm_type>
00135 void run(group_type & group, algorithm_type & algorithm, upward_tag)
00136 {
00137 m_cnt = analyze(group,m_layers);
00138 for(index_type height=0;height<m_cnt;++height)
00139 algorithm(m_layers[height]);
00140 }
00141
00142 template <typename algorithm_type>
00143 void rerun(group_type & group, algorithm_type & algorithm, upward_tag)
00144 {
00145 for(index_type height=0;height<m_cnt;++height)
00146 algorithm(m_layers[height]);
00147 }
00148
00149 template <typename algorithm_type>
00150 void run(group_type & group, algorithm_type & algorithm, downward_tag )
00151 {
00152 assert(m_cnt >= 1 || !"StackPropagation::run(...,downward): Need at least one layer");
00153
00154 m_cnt = analyze(group,m_layers);
00155 index_type height=m_cnt-1;
00156 for(index_type layer=0;layer<m_cnt;++layer,--height)
00157 {
00158 algorithm(m_layers[height]);
00159 }
00160 }
00161
00162 template <typename algorithm_type>
00163 void rerun(group_type & group, algorithm_type & algorithm, downward_tag)
00164 {
00165 assert(m_cnt >= 1 || !"StackPropagation::rerun(...,downward): Need at least one layer");
00166
00167 index_type height=m_cnt-1;
00168 for(index_type layer=0;layer<m_cnt;++layer,--height)
00169 algorithm(m_layers[height]);
00170 }
00171
00172 protected:
00173
00180 void fixiate(index_type height, group_type & layer)
00181 {
00182 typename group_type::indirect_body_iterator begin = layer.body_begin();
00183 typename group_type::indirect_body_iterator end = layer.body_end();
00184 for(typename group_type::indirect_body_iterator body = begin;body!=end;++body)
00185 {
00186 if(body->m_sa_stack_height==height && !body->is_fixed())
00187 {
00188 body->m_sp_fixiated = true;
00189 body->set_fixed(true);
00190 }
00191 else
00192 {
00193 body->m_sp_fixiated = false;
00194 }
00195 }
00196 }
00197
00205 void unfixiate(group_type & layer)
00206 {
00207 typename group_type::indirect_body_iterator begin = layer.body_begin();
00208 typename group_type::indirect_body_iterator end = layer.body_end();
00209 for(typename group_type::indirect_body_iterator body = begin;body!=end;++body)
00210 {
00211 if(body->m_sp_fixiated)
00212 body->set_fixed(false);
00213 }
00214 }
00215
00216 };
00217
00218
00219 }
00220 }
00221
00222 #endif