1 #ifndef LIBGEODECOMP_STORAGE_DISPLACEDGRID_H 2 #define LIBGEODECOMP_STORAGE_DISPLACEDGRID_H 3 4 #include <libgeodecomp/geometry/coordbox.h> 5 #include <libgeodecomp/geometry/region.h> 6 #include <libgeodecomp/storage/grid.h> 7 8 namespace LibGeoDecomp { 9 10 /** 11 * A grid whose origin has been shiftet by a certain offset. If 12 * TOPOLOGICALLY_CORRECT is set to true, the coordinates will be 13 * normalized according to the given topology and some superordinate 14 * dimension (see topologicalDimensions()) before using them for 15 * access. Useful for writing topology agnostic code that should work 16 * an a torus, too. 17 */ 18 template<typename CELL_TYPE, 19 typename TOPOLOGY=Topologies::Cube<2>::Topology, 20 bool TOPOLOGICALLY_CORRECT=false> 21 class DisplacedGrid : public GridBase<CELL_TYPE, TOPOLOGY::DIM> 22 { 23 public: 24 const static int DIM = TOPOLOGY::DIM; 25 26 typedef CELL_TYPE Cell; 27 typedef TOPOLOGY Topology; 28 typedef typename boost::multi_array<CELL_TYPE, DIM>::index Index; 29 typedef Grid<CELL_TYPE, TOPOLOGY> Delegate; 30 typedef CoordMap<CELL_TYPE, Delegate> CoordMapType; 31 32 explicit DisplacedGrid( 33 const CoordBox<DIM>& box = CoordBox<DIM>(), 34 const CELL_TYPE& defaultCell = CELL_TYPE(), 35 const CELL_TYPE& edgeCell = CELL_TYPE(), 36 const Coord<DIM>& topologicalDimensions = Coord<DIM>()) : 37 delegate(box.dimensions, defaultCell, edgeCell), 38 origin(box.origin), 39 topoDimensions(topologicalDimensions) 40 {} 41 42 explicit DisplacedGrid( 43 const Delegate& grid, 44 const Coord<DIM>& origin=Coord<DIM>()) : delegate(grid)45 delegate(grid), 46 origin(origin) 47 {} 48 topologicalDimensions()49 inline const Coord<DIM>& topologicalDimensions() const 50 { 51 return topoDimensions; 52 } 53 topologicalDimensions()54 inline Coord<DIM>& topologicalDimensions() 55 { 56 return topoDimensions; 57 } 58 baseAddress()59 inline CELL_TYPE *baseAddress() 60 { 61 return delegate.baseAddress(); 62 } 63 baseAddress()64 inline const CELL_TYPE *baseAddress() const 65 { 66 return delegate.baseAddress(); 67 } 68 getOrigin()69 inline const Coord<DIM>& getOrigin() const 70 { 71 return origin; 72 } 73 getEdgeCell()74 inline const CELL_TYPE& getEdgeCell() const 75 { 76 return delegate.getEdgeCell(); 77 } 78 getEdgeCell()79 inline CELL_TYPE& getEdgeCell() 80 { 81 return delegate.getEdgeCell(); 82 } 83 setOrigin(const Coord<DIM> & newOrigin)84 inline void setOrigin(const Coord<DIM>& newOrigin) 85 { 86 origin = newOrigin; 87 } 88 resize(const CoordBox<DIM> & box)89 inline void resize(const CoordBox<DIM>& box) 90 { 91 delegate.resize(box.dimensions); 92 origin = box.origin; 93 } 94 95 inline CELL_TYPE& operator[](const Coord<DIM>& absoluteCoord) 96 { 97 Coord<DIM> relativeCoord = absoluteCoord - origin; 98 if (TOPOLOGICALLY_CORRECT) { 99 relativeCoord = Topology::normalize(relativeCoord, topoDimensions); 100 } 101 return delegate[relativeCoord]; 102 } 103 104 inline const CELL_TYPE& operator[](const Coord<DIM>& absoluteCoord) const 105 { 106 return (const_cast<DisplacedGrid&>(*this))[absoluteCoord]; 107 } 108 set(const Coord<DIM> & coord,const CELL_TYPE & cell)109 virtual void set(const Coord<DIM>& coord, const CELL_TYPE& cell) 110 { 111 (*this)[coord] = cell; 112 } 113 set(const Streak<DIM> & streak,const CELL_TYPE * cells)114 virtual void set(const Streak<DIM>& streak, const CELL_TYPE *cells) 115 { 116 delegate.set(Streak<DIM>(streak.origin - origin, 117 streak.endX - origin.x()), 118 cells); 119 } 120 get(const Coord<DIM> & coord)121 virtual CELL_TYPE get(const Coord<DIM>& coord) const 122 { 123 return (*this)[coord]; 124 } 125 get(const Streak<DIM> & streak,CELL_TYPE * cells)126 virtual void get(const Streak<DIM>& streak, CELL_TYPE *cells) const 127 { 128 delegate.get(Streak<DIM>(streak.origin - origin, 129 streak.endX - origin.x()), 130 cells); 131 } 132 setEdge(const CELL_TYPE & cell)133 virtual void setEdge(const CELL_TYPE& cell) 134 { 135 getEdgeCell() = cell; 136 } 137 getEdge()138 virtual const CELL_TYPE& getEdge() const 139 { 140 return getEdgeCell(); 141 } 142 fill(const CoordBox<DIM> & box,const CELL_TYPE & cell)143 void fill(const CoordBox<DIM>& box, const CELL_TYPE& cell) 144 { 145 delegate.fill(CoordBox<DIM>(box.origin - origin, box.dimensions), cell); 146 } 147 paste(const GridBase<CELL_TYPE,DIM> & grid,const Region<DIM> & region)148 inline void paste(const GridBase<CELL_TYPE, DIM>& grid, const Region<DIM>& region) 149 { 150 for (typename Region<DIM>::StreakIterator i = region.beginStreak(); i != region.endStreak(); ++i) { 151 for (Coord<DIM> c = i->origin; c.x() < i->endX; ++c.x()) { 152 (*this)[c] = grid.get(c); 153 } 154 } 155 } 156 getDimensions()157 inline const Coord<DIM>& getDimensions() const 158 { 159 return delegate.getDimensions(); 160 } 161 boundingBox()162 virtual CoordBox<DIM> boundingBox() const 163 { 164 return CoordBox<DIM>(origin, delegate.getDimensions()); 165 } 166 getNeighborhood(const Coord<DIM> & center)167 inline CoordMapType getNeighborhood(const Coord<DIM>& center) const 168 { 169 Coord<DIM> relativeCoord = center - origin; 170 if (TOPOLOGICALLY_CORRECT) { 171 relativeCoord = Topology::normalize(relativeCoord, topoDimensions); 172 } 173 return CoordMapType(relativeCoord, &delegate); 174 } 175 vanillaGrid()176 inline const Delegate *vanillaGrid() const 177 { 178 return &delegate; 179 } 180 vanillaGrid()181 inline Delegate *vanillaGrid() 182 { 183 return &delegate; 184 } 185 toString()186 inline std::string toString() const 187 { 188 std::ostringstream message; 189 message << "DisplacedGrid<" << DIM << ">(\n" 190 << " origin: " << origin << "\n" 191 << " delegate:\n" 192 << delegate 193 << ")"; 194 return message.str(); 195 } 196 197 protected: saveMemberImplementation(char * target,const Selector<CELL_TYPE> & selector,const Region<DIM> & region)198 void saveMemberImplementation( 199 char *target, const Selector<CELL_TYPE>& selector, const Region<DIM>& region) const 200 { 201 for (typename Region<DIM>::StreakIterator i = region.beginStreak(); i != region.endStreak(); ++i) { 202 selector.copyMemberOut(&(*this)[i->origin], target, i->length()); 203 target += selector.sizeOfExternal() * i->length(); 204 } 205 } 206 loadMemberImplementation(const char * source,const Selector<CELL_TYPE> & selector,const Region<DIM> & region)207 void loadMemberImplementation( 208 const char *source, const Selector<CELL_TYPE>& selector, const Region<DIM>& region) 209 { 210 for (typename Region<DIM>::StreakIterator i = region.beginStreak(); i != region.endStreak(); ++i) { 211 selector.copyMemberIn(source, &(*this)[i->origin], i->length()); 212 source += selector.sizeOfExternal() * i->length(); 213 } 214 } 215 216 217 private: 218 Delegate delegate; 219 Coord<DIM> origin; 220 Coord<DIM> topoDimensions; 221 }; 222 223 } 224 225 template<typename _CharT, typename _Traits, typename _CellT, typename _Topology, bool _Correctness> 226 std::basic_ostream<_CharT, _Traits>& 227 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 228 const LibGeoDecomp::DisplacedGrid<_CellT, _Topology, _Correctness>& grid) 229 { 230 __os << grid.toString(); 231 return __os; 232 } 233 234 #endif 235