• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

geometry/topologies.h

Go to the documentation of this file.
00001 #ifndef LIBGEODECOMP_GEOMETRY_TOPOLOGIES_H
00002 #define LIBGEODECOMP_GEOMETRY_TOPOLOGIES_H
00003 
00004 #include <stdexcept>
00005 #include <iostream>
00006 #include <libgeodecomp/geometry/coord.h>
00007 
00008 namespace LibGeoDecomp {
00009 
00010 namespace TopologiesHelpers {
00011 
00012 template<int DIM, class TOPOLOGY>
00013 class WrapsAxis;
00014 
00015 template<class TOPOLOGY>
00016 class WrapsAxis<0, TOPOLOGY>
00017 {
00018 public:
00019     static const bool VALUE = TOPOLOGY::WRAP_AXIS0;
00020 };
00021 
00022 template<class TOPOLOGY>
00023 class WrapsAxis<1, TOPOLOGY>
00024 {
00025 public:
00026     static const bool VALUE = TOPOLOGY::WRAP_AXIS1;
00027 };
00028 
00029 template<class TOPOLOGY>
00030 class WrapsAxis<2, TOPOLOGY>
00031 {
00032 public:
00033     static const bool VALUE = TOPOLOGY::WRAP_AXIS2;
00034 };
00035 
00036 template<class TOPOLOGY>
00037 class NormalizeEdges
00038 {
00039 public:
00040     Coord<1> operator()(const Coord<1>& coord, const Coord<1>& dim)
00041     {
00042         return Coord<1>(
00043             wrap(coord[0], dim[0]));
00044     }
00045 
00046     Coord<2> operator()(const Coord<2>& coord, const Coord<2>& dim)
00047     {
00048         return Coord<2>(
00049             wrap(coord[0], dim[0]),
00050             wrap(coord[1], dim[1]));
00051     }
00052 
00053     Coord<3> operator()(const Coord<3>& coord, const Coord<3>& dim)
00054     {
00055         return Coord<3>(
00056             wrap(coord[0], dim[0]),
00057             wrap(coord[1], dim[1]),
00058             wrap(coord[2], dim[2]));
00059     }
00060 
00061 private:
00062     inline int wrap(int x, int dim)
00063     {
00064         if (x < 0) {
00065             return (x + dim) % dim;
00066         }
00067         if (x >= dim) {
00068             return x % dim;
00069         }
00070 
00071         return x;
00072     }
00073 };
00074 
00075 template<class TOPOLOGY>
00076 class OutOfBounds
00077 {
00078 public:
00079     bool operator()(const Coord<1> coord, const Coord<1> dim)
00080     {
00081         return
00082             ((!WrapsAxis<0, TOPOLOGY>::VALUE) && ((coord[0] < 0) || (coord[0] >= dim[0])));
00083     }
00084 
00085     bool operator()(const Coord<2> coord, const Coord<2> dim)
00086     {
00087         return
00088             ((!WrapsAxis<0, TOPOLOGY>::VALUE) && ((coord[0] < 0) || (coord[0] >= dim[0]))) ||
00089             ((!WrapsAxis<1, TOPOLOGY>::VALUE) && ((coord[1] < 0) || (coord[1] >= dim[1])));
00090     }
00091 
00092     bool operator()(const Coord<3> coord, const Coord<3> dim)
00093     {
00094         return
00095             ((!WrapsAxis<0, TOPOLOGY>::VALUE) && ((coord[0] < 0) || (coord[0] >= dim[0]))) ||
00096             ((!WrapsAxis<1, TOPOLOGY>::VALUE) && ((coord[1] < 0) || (coord[1] >= dim[1]))) ||
00097             ((!WrapsAxis<2, TOPOLOGY>::VALUE) && ((coord[2] < 0) || (coord[2] >= dim[2])));
00098     }
00099 };
00100 
00101 template<class TOPOLOGY>
00102 class NormalizeCoord
00103 {
00104 public:
00105     template<int DIM>
00106     Coord<DIM> operator()(const Coord<DIM>& coord, const Coord<DIM>& dim)
00107     {
00108         if (OutOfBounds<TOPOLOGY>()(coord, dim)) {
00109             return Coord<DIM>::diagonal(-1);
00110         }
00111 
00112         return NormalizeEdges<TOPOLOGY>()(coord, dim);
00113     }
00114 };
00115 
00116 template<int DIM>
00117 class Accessor;
00118 
00119 template<>
00120 class Accessor<1>
00121 {
00122 public:
00123     template<typename STORAGE, typename VALUE>
00124     void operator()(STORAGE& storage, VALUE **value, const Coord<1>& coord) const
00125     {
00126         *value = &storage[coord.x()];
00127     }
00128 
00129     template<typename STORAGE, typename VALUE>
00130     void operator()(const STORAGE& storage, const VALUE **value, const Coord<1>& coord) const
00131     {
00132         *value = &storage[coord.x()];
00133     }
00134 };
00135 
00136 template<>
00137 class Accessor<2>
00138 {
00139 public:
00140     template<typename STORAGE, typename VALUE>
00141     void operator()(STORAGE& storage, VALUE **value, const Coord<2>& coord) const
00142     {
00143         *value = &storage[coord.y()][coord.x()];
00144     }
00145 
00146     template<typename STORAGE, typename VALUE>
00147     void operator()(const STORAGE& storage, const VALUE **value, const Coord<2>& coord) const
00148     {
00149         *value = &storage[coord.y()][coord.x()];
00150     }
00151 };
00152 
00153 template<>
00154 class Accessor<3>
00155 {
00156 public:
00157     template<typename STORAGE, typename VALUE>
00158     void operator()(STORAGE& storage, VALUE **value, const Coord<3>& coord) const
00159     {
00160         *value = &storage[coord.z()][coord.y()][coord.x()];
00161     }
00162 
00163     template<typename STORAGE, typename VALUE>
00164     void operator()(const STORAGE& storage, const VALUE **value, const Coord<3>& coord) const
00165     {
00166         *value = &storage[coord.z()][coord.y()][coord.x()];
00167     }
00168 };
00169 
00170 template<int DIMENSIONS, bool WRAP_DIM0, bool WRAP_DIM1, bool WRAP_DIM2>
00171 class RawTopology
00172 {
00173 public:
00174     const static int DIM = DIMENSIONS;
00175     const static bool WRAP_AXIS0 = WRAP_DIM0;
00176     const static bool WRAP_AXIS1 = WRAP_DIM1;
00177     const static bool WRAP_AXIS2 = WRAP_DIM2;
00178 };
00179 
00180 template<int DIMENSIONS, bool WRAP_DIM0=false, bool WRAP_DIM1=false, bool WRAP_DIM2=false>
00181 class Topology
00182 {
00183 public:
00184     typedef RawTopology<DIMENSIONS, WRAP_DIM0, WRAP_DIM1, WRAP_DIM2> RawTopologyType;
00185     static const int DIM = DIMENSIONS;
00186 
00187     template<typename GRID, int DIM>
00188     static inline const typename GRID::CellType& locate(
00189         const GRID& grid,
00190         const Coord<DIM>& coord)
00191     {
00192         const Coord<DIM>& dim = grid.getDimensions();
00193         if (OutOfBounds<RawTopologyType>()(coord, dim)) {
00194             return grid.getEdgeCell();
00195         }
00196 
00197         typename GRID::CellType *ret;
00198         Accessor<DIM>()(grid, &ret, NormalizeEdges<RawTopologyType>()(coord, dim));
00199         return *ret;
00200     }
00201 
00202     template<typename GRID>
00203     static inline typename GRID::CellType& locate(
00204         GRID& grid,
00205         const Coord<DIMENSIONS>& coord)
00206     {
00207         const Coord<DIMENSIONS>& dim = grid.getDimensions();
00208         if (OutOfBounds<RawTopologyType>()(coord, dim)) {
00209             return grid.getEdgeCell();
00210         }
00211 
00212         typename GRID::CellType *ret;
00213         Accessor<DIMENSIONS>()(grid, &ret, NormalizeEdges<RawTopologyType>()(coord, dim));
00214         return *ret;
00215     }
00216 
00217     template<int D>
00218     class WrapsAxis
00219     {
00220     public:
00221         static const bool VALUE = TopologiesHelpers::WrapsAxis<D, RawTopologyType>::VALUE;
00222     };
00223 
00224     static Coord<DIM> normalize(const Coord<DIMENSIONS>& coord, const Coord<DIMENSIONS>& dimensions)
00225     {
00226         return NormalizeCoord<RawTopologyType>()(coord, dimensions);
00227     }
00228 
00229     static bool isOutOfBounds(const Coord<DIM>& coord, const Coord<DIM>& dim)
00230     {
00231         return TopologiesHelpers::OutOfBounds<RawTopologyType>()(coord, dim);
00232     }
00233 
00240     static bool wrapsAxis(const int& dim)
00241     {
00242         if (dim == 0) {
00243             return WrapsAxis<0>::VALUE;
00244         }
00245         if (dim == 1) {
00246             return WrapsAxis<1>::VALUE;
00247         }
00248 
00249         return WrapsAxis<2>::VALUE;
00250     }
00251 };
00252 
00253 }
00254 
00255 class Topologies
00256 {
00257 public:
00258     template<int DIM>
00259     class Cube
00260     {
00261     public:
00262         typedef TopologiesHelpers::Topology<DIM, false, false, false> Topology;
00263     };
00264 
00265     template<int DIM>
00266     class Torus
00267     {
00268     public:
00269         typedef TopologiesHelpers::Topology<DIM, true, true, true> Topology;
00270     };
00271 };
00272 
00273 }
00274 
00275 #endif

Generated on Thu Jan 8 2015 01:34:43 for LibGeoDecomp by  doxygen 1.7.1