CartesianGraphFactory.hpp 9.67 KB
 incardon committed Dec 03, 2014 1 2 3 4 5 6 7 8 9 10 ``````/* * CartesianGraphFactory.hpp * * Created on: Nov 28, 2014 * Author: i-bird */ #ifndef CARTESIANGRAPHFACTORY_HPP_ #define CARTESIANGRAPHFACTORY_HPP_ `````` incardon committed Mar 05, 2015 11 12 ``````#include "Vector/map_vector.hpp" #include "Graph/map_graph.hpp" `````` incardon committed Apr 01, 2015 13 ``````#include "Grid/grid_sm.hpp" `````` incardon committed Dec 03, 2014 14 ``````#include "Space/Shape/Box.hpp" `````` incardon committed Jan 28, 2015 15 ``````#include "Space/Shape/HyperCube.hpp" `````` incardon committed Dec 03, 2014 16 `````` `````` incardon committed Jan 04, 2015 17 ``````/*! \brief This class work as a functor `````` incardon committed Dec 03, 2014 18 `````` * `````` incardon committed Jan 04, 2015 19 20 21 22 23 24 25 26 `````` * For each number in the boost::mpl::vector (for example 3 6) set the properties of the vertex at the * specified id (3 6) with pos[d] * spacing[d] with d running from 0 to 1, pos[d] the position id of the vertex * spacing the grid spacing * * Example * * if we give a grid_key of dimension 2 4x4 the expression "pos[d] * spacing[d]" * will assume the value `````` incardon committed Dec 03, 2014 27 `````` * `````` incardon committed Jan 04, 2015 28 29 30 31 32 33 34 35 36 37 38 39 40 41 `````` * (0.0 0.0) (0.25 0.0) ...... (1.0 0.0) * (0.0 0.25)................. (1.0 0.25) * .................................... * (0.0 1.0).................. (1.0 1.0) * * and the properties 3 6 will be filled with the numbers 0.0 0.0 ....... 1.0 1.0 * progressively * * \tparam dim Dimensionality of the cartesian grid * \tparam dT type of the domain * \tparam G_v vertex type object * \tparam v boost::mpl::vector containing all the index to fill * \tparam is_stub when is true, produce a trivial operator(), * to use when v is an empty vector to avoid compilation error `````` incardon committed Dec 03, 2014 42 43 44 `````` * */ `````` incardon committed Jan 04, 2015 45 46 ``````template class fill_prop `````` incardon committed Dec 03, 2014 47 ``````{ `````` incardon committed Jan 04, 2015 48 49 50 51 52 53 54 55 `````` //! Reference to an array containing the spacing const dT (& szd)[dim]; //! grid_key_dx Reference containing the actual position grid_key_dx & gk; //! Vertex object to fill G_v & g_v; `````` incardon committed Dec 03, 2014 56 57 58 `````` public: `````` incardon committed Jan 04, 2015 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 `````` //! Fill the object from where to take the properties fill_prop(G_v & g_v , const dT (& szd)[dim], grid_key_dx & gk) :szd(szd),gk(gk),g_v(g_v) {} //! It call the function for each property we want to copy template void operator()(T& t) const { typedef typename boost::fusion::result_of::at>::type t_val; g_v.template get() = gk.get(T::value) * szd[T::value]; } }; /*! \brief Graph constructor function specialization * * On C++ partial function specialization is not allowed, so we need a class to do it * * \see CartesianGraphFactory method construct * */ template class Graph_constructor_impl { public: //! Construct cartesian graph `````` incardon committed Feb 02, 2015 87 `````` static Graph construct(size_t (& sz)[dim], Box dom) `````` incardon committed Dec 03, 2014 88 89 90 91 92 93 94 95 96 97 98 99 100 101 `````` { // Calculate the size of the hyper-cubes on each dimension T szd[dim]; for (int i = 0 ; i < dim ; i++) {szd[i] = (dom.getHigh(i) - dom.getLow(i)) / sz[i];} //! Construct an hyper-cube of dimension dim HyperCube hc; // Construct a grid info `````` incardon committed Apr 01, 2015 102 `````` grid_sm g(sz); `````` incardon committed Dec 03, 2014 103 104 105 106 107 108 109 110 111 112 `````` // Create a graph with the number of vertices equal to the number of // grid point //! Graph to construct Graph gp(g.size()); /****************** * `````` incardon committed Jan 04, 2015 113 114 `````` * Create the edges and fill spatial * information properties `````` incardon committed Dec 03, 2014 115 116 117 118 119 120 121 122 123 `````` * ******************/ //! Construct a key iterator grid_key_dx_iterator k_it(g); //! Iterate through all the elements `````` incardon committed Dec 09, 2014 124 `````` while (k_it.isNext()) `````` incardon committed Dec 03, 2014 125 126 127 `````` { grid_key_dx key = k_it.get(); `````` incardon committed Jan 04, 2015 128 129 130 131 132 133 134 135 136 137 `````` // Vertex object auto obj = gp.vertex(g.LinId(key)); // vertex spatial properties functor fill_prop::type, sizeof...(pos) == 0 > flp(obj,szd,key); // fill properties boost::mpl::for_each< boost::mpl::range_c >(flp); `````` incardon committed Dec 03, 2014 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 `````` // Get the combinations of dimension d for (int d = dim-1 ; d >= dim_c ; d--) { // create the edges for that dimension std::vector> c = hc.getCombinations_R(d); // for each combination calculate a safe linearization and create an edge for (int j = 0 ; j < c.size() ; j++) { // Calculate the element size T ele_sz = 0; // for each dimension multiply and reduce for (int s = 0 ; s < dim ; s++) { `````` incardon committed Dec 09, 2014 158 `````` ele_sz += szd[s] * abs(c[j][s]); `````` incardon committed Dec 03, 2014 159 160 161 162 163 164 `````` } // Calculate the end point vertex id // Calculate the start point id size_t start_v = g.LinId(key); `````` incardon committed Dec 09, 2014 165 `````` size_t end_v = g.template LinId(key,c[j].getComb()); `````` incardon committed Dec 03, 2014 166 `````` `````` incardon committed Jan 04, 2015 167 `````` // Add an edge and set the the edge property to the size of the face (communication weight) `````` incardon committed Dec 09, 2014 168 `````` gp.template addEdge(start_v,end_v).template get() = ele_sz; `````` incardon committed Dec 03, 2014 169 170 171 `````` } } `````` incardon committed Jan 04, 2015 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 `````` // Fill vertex properties ++k_it; } return gp; } }; /*! \brief Graph constructor function specialization * * On C++ partial function specialization is not allowed, so we need a class to do it * This specialization handle the case when we have NO_EDGE option active * * \see CartesianGraphFactory method construct * */ template class Graph_constructor_impl { public: //! Construct cartesian graph `````` incardon committed Feb 02, 2015 197 `````` static Graph construct(size_t ( & sz)[dim], Box dom) `````` incardon committed Jan 04, 2015 198 199 200 201 202 203 204 205 206 207 208 209 210 211 `````` { // Calculate the size of the hyper-cubes on each dimension T szd[dim]; for (int i = 0 ; i < dim ; i++) {szd[i] = (dom.getHigh(i) - dom.getLow(i)) / sz[i];} //! Construct an hyper-cube of dimension dim HyperCube hc; // Construct a grid info `````` incardon committed Apr 01, 2015 212 `````` grid_sm g(sz); `````` incardon committed Jan 04, 2015 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 `````` // Create a graph with the number of vertices equal to the number of // grid point //! Graph to construct Graph gp(g.size()); /****************** * * Create the edges and fill spatial * information properties * ******************/ //! Construct a key iterator grid_key_dx_iterator k_it(g); //! Iterate through all the elements while (k_it.isNext()) { grid_key_dx key = k_it.get(); // Vertex object auto obj = gp.vertex(g.LinId(key)); // vertex spatial properties functor fill_prop::type, sizeof...(pos) == 0 > flp(obj,szd,key); // fill properties boost::mpl::for_each< boost::mpl::range_c >(flp); // Get the combinations of dimension d for (int d = dim-1 ; d >= dim_c ; d--) { // create the edges for that dimension std::vector> c = hc.getCombinations_R(d); // for each combination calculate a safe linearization and create an edge for (int j = 0 ; j < c.size() ; j++) { // Calculate the element size T ele_sz = 0; // for each dimension multiply and reduce for (int s = 0 ; s < dim ; s++) { ele_sz += szd[s] * abs(c[j][s]); } // Calculate the end point vertex id // Calculate the start point id size_t start_v = g.LinId(key); size_t end_v = g.template LinId(key,c[j].getComb()); // Add an edge and set the the edge property to the size of the face (communication weight) gp.template addEdge(start_v,end_v); } } // Fill vertex properties `````` incardon committed Dec 03, 2014 284 285 286 `````` ++k_it; } `````` incardon committed Dec 09, 2014 287 `````` return gp; `````` incardon committed Jan 04, 2015 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 `````` } }; /*! \brief This class work as a functor * * For each number in the boost::mpl::vector (for example 3 6) set the properties of the vertex at the * specified id (3 6) with pos[d] * spacing[d] with d running from 0 to 1, pos[d] the position id of the vertex * spacing the grid spacing * * Example * * if we give a grid_key of dimension 2 4x4 the expression "pos[d] * spacing[d]" * will assume the value * * (0.0 0.0) (0.25 0.0) ...... (1.0 0.0) * (0.0 0.25)................. (1.0 0.25) * .................................... * (0.0 1.0).................. (1.0 1.0) * * and the properties 3 6 will be filled with the numbers 0.0 0.0 ....... 1.0 1.0 * progressively * * \tparam dim Dimensionality of the cartesian grid * \tparam dT type of the domain * \tparam G_v vertex type object * \tparam v boost::mpl::vector containing all the index to fill * */ template class fill_prop { public: //! Fill the object from where to take the properties fill_prop(G_v & g_v , const dT (& szd)[dim], grid_key_dx & gk) {} //! It call the function for each property we want to copy template void operator()(T& t) const {} }; /*! \brief This class construct a cartesian graph * * This class construct a cartesian graph * * \param dim dimensionality of the cartesian grid * */ template class CartesianGraphFactory { public: `````` incardon committed Dec 03, 2014 347 `````` `````` incardon committed Jan 04, 2015 348 349 350 351 352 353 354 355 `````` /*! * * \brief Construct a cartesian graph, with V and E edge properties * * Construct a cartesian graph, with V and E edge properties * * Each vertex is a subspace (Hyper-cube) of dimension dim, each vertex is * connected with an edge if two vertex (Hyper-cube) share a element of dimension grater than `````` incardon committed May 29, 2015 356 357 `````` * dim_c. One property can be used to store the contact size or the d-dimensional * surface in common between two connected hyper-cube. `````` incardon committed Jan 04, 2015 358 359 360 361 `````` * * \param sz Vector that store the size of the grid on each dimension * \param dom Box enclosing the physical domain * `````` incardon committed May 29, 2015 362 363 364 `````` * \tparam se Indicate which properties fill with the contact size. The * contact size is the point, line , surface, d-dimensional object size * in contact (in common) between two hyper-cube. NO_EDGE indicate `````` incardon committed Jan 04, 2015 365 366 367 `````` * no property will store this information * \tparam T type of the domain like (int real complex ... ) * \tparam dim_c Connectivity dimension `````` incardon committed Feb 26, 2015 368 `````` * \tparam pos... (optional)one or more integer indicating the spatial properties `````` incardon committed Jan 04, 2015 369 370 371 `````` * */ template `````` incardon committed Feb 02, 2015 372 `````` static Graph construct(size_t (& sz)[dim], Box dom) `````` incardon committed Jan 04, 2015 373 374 `````` { return Graph_constructor_impl::construct(sz,dom); `````` incardon committed Dec 03, 2014 375 376 377 378 `````` } }; #endif /* CARTESIANGRAPHFACTORY_HPP_ */``````