00001 #ifndef LIBGEODECOMP_STORAGE_UNSTRUCTUREDGRID_H
00002 #define LIBGEODECOMP_STORAGE_UNSTRUCTUREDGRID_H
00003
00004 #include <libgeodecomp/geometry/coord.h>
00005 #include <libgeodecomp/geometry/coordbox.h>
00006 #include <libgeodecomp/geometry/region.h>
00007 #include <libgeodecomp/geometry/streak.h>
00008 #include <libgeodecomp/misc/stdcontaineroverloads.h>
00009 #include <libgeodecomp/storage/gridbase.h>
00010 #include <libgeodecomp/storage/selector.h>
00011 #include <libgeodecomp/storage/sellcsigmasparsematrixcontainer.h>
00012
00013 #include <iostream>
00014 #include <vector>
00015 #include <list>
00016 #include <utility>
00017
00018
00019 namespace LibGeoDecomp {
00020
00024 template<typename ELEMENT_TYPE, size_t MATRICES=1,
00025 typename VALUE_TYPE=double, int C=64, int SIGMA=1>
00026 class UnstructuredGrid : public GridBase<ELEMENT_TYPE, 1>
00027 {
00028 public:
00029 typedef std::vector<std::pair<ELEMENT_TYPE, VALUE_TYPE> > NeighborList;
00030 typedef typename std::vector<std::pair<ELEMENT_TYPE, VALUE_TYPE> >::iterator NeighborListIterator;
00031 const static int DIM = 1;
00032
00033 explicit UnstructuredGrid(
00034 const Coord<DIM>& dim = Coord<DIM>(),
00035 const ELEMENT_TYPE& defaultElement = ELEMENT_TYPE(),
00036 const ELEMENT_TYPE& edgeElement = ELEMENT_TYPE()) :
00037 elements(dim.x(), defaultElement),
00038 edgeElement(edgeElement),
00039 dimension(dim)
00040 {
00041 for (size_t i=0; i < MATRICES; ++i) {
00042 matrices[i] =
00043 SellCSigmaSparseMatrixContainer<VALUE_TYPE,C,SIGMA> (dim.x());
00044 }
00045 }
00046
00047 template<typename O_ELEMENT_TYPE>
00048 UnstructuredGrid<ELEMENT_TYPE, MATRICES, VALUE_TYPE, C, SIGMA>&
00049 operator=(const UnstructuredGrid<O_ELEMENT_TYPE, MATRICES, VALUE_TYPE,
00050 C, SIGMA> & other)
00051 {
00052 elements = other.elements;
00053 edgeElement = other.edgeElement;
00054 dimension = other.dimension;
00055
00056 for (size_t i=0; i<MATRICES; ++i){
00057 matrices[i] = other.matrices[i];
00058 }
00059
00060 return *this;
00061 }
00062
00066 template<typename ITERATOR>
00067 void setAdjacency(size_t const matrixID, ITERATOR start,
00068 const ITERATOR end){
00069 if (matrixID >= MATRICES){
00070 throw std::invalid_argument("matrixID not available");
00071 }
00072 for (ITERATOR i = start; i != end; ++i) {
00073
00074 Coord<2> c = i->first;
00075 matrices[matrixID].addPoint(c.x(), c.y(), i->second);
00076 }
00077 }
00078
00079 const SellCSigmaSparseMatrixContainer<VALUE_TYPE,C,SIGMA> &
00080 getAdjacency(size_t const matrixID) const {
00081 if (matrixID >= MATRICES){
00082 throw std::invalid_argument("matrixID not available");
00083 }
00084
00085 return matrices[matrixID];
00086 }
00087
00088 SellCSigmaSparseMatrixContainer<VALUE_TYPE,C,SIGMA> &
00089 getAdjacency(size_t const matrixID){
00090 if (matrixID >= MATRICES){
00091 throw std::invalid_argument("matrixID not available");
00092 }
00093
00094 return matrices[matrixID];
00095 }
00104 inline NeighborList getNeighborhood(const Coord<DIM>& center) const
00105 {
00106 NeighborList neighborhood;
00107
00108 if (boundingBox().inBounds(center)) {
00109 neighborhood.push_back( std::make_pair( *this[center], -1 ) );
00110
00111 std::vector< std::pair<int, VALUE_TYPE> > neighbor =
00112 matrices[0].getRow(center.x());
00113
00114 for (NeighborListIterator it = neighbor.begin();
00115 it != neighbor.end();
00116 ++it) {
00117 neighborhood.push_back(std::make_pair((*this)[it->first], it->second));
00118 }
00119
00120 } else {
00121 neighborhood.push_back( std::make_pair( getEdgeElement(), -1) );
00122 }
00123
00124 return neighborhood;
00125 }
00126
00127 inline const Coord<DIM>& getDimensions() const
00128 {
00129 return dimension;
00130 }
00131
00132 inline const ELEMENT_TYPE& operator[](const int y) const
00133 {
00134 if ( y < 0 || y >= dimension.x()){
00135 return getEdgeElement();
00136 } else {
00137 return elements[y];
00138 }
00139 }
00140
00141 inline ELEMENT_TYPE& operator[](const int y)
00142 {
00143 if ( y < 0 || y >= dimension.x()){
00144 return getEdgeElement();
00145 } else {
00146 return elements[y];
00147 }
00148 }
00149
00150 inline ELEMENT_TYPE& operator[](const Coord<DIM>& coord)
00151 {
00152 return (*this)[coord.x()];
00153 }
00154
00155 inline const ELEMENT_TYPE& operator[](const Coord<DIM>& coord) const
00156 {
00157 return (*this)[coord.x()];
00158 }
00159
00160 inline bool operator==(const UnstructuredGrid& other) const
00161 {
00162 if (boundingBox() == CoordBox<DIM>() &&
00163 other.boundingBox() == CoordBox<DIM>()) {
00164 return true;
00165 }
00166
00167 if ((edgeElement != other.edgeElement) ||
00168 (elements != other.elements)) {
00169 return false;
00170 }
00171
00172 for (int i = 0; i < MATRICES; ++i) {
00173 if (matrices[i] != other.matrices[i]) {
00174 return false;
00175 }
00176 }
00177
00178 return true;
00179 }
00180
00181 inline bool operator==(const GridBase<ELEMENT_TYPE, DIM>& other) const
00182 {
00183 if (boundingBox() != other.boundingBox()) {
00184 return false;
00185 }
00186
00187 if (edgeElement != other.getEdge()) {
00188 return false;
00189 }
00190
00191 CoordBox<DIM> box = boundingBox();
00192 for (typename CoordBox<DIM>::Iterator i = box.begin();
00193 i != box.end(); ++i) {
00194 if ((*this)[*i] != other.get(*i)) {
00195 return false;
00196 }
00197 }
00198
00199 return true;
00200 }
00201
00202 inline bool operator!=(const UnstructuredGrid& other) const
00203 {
00204 return !(*this == other);
00205 }
00206
00207 inline bool operator!=(const GridBase<ELEMENT_TYPE, DIM>& other) const
00208 {
00209 return !(*this == other);
00210 }
00211
00212 inline std::string toString() const
00213 {
00214 std::ostringstream message;
00215 message << "Unstructured Grid <" << DIM << ">(" << dimension.x() << ")\n"
00216 << "boundingBox: " << boundingBox() << "\n"
00217 << "edgeElement: " << edgeElement;
00218
00219 CoordBox<DIM> box = boundingBox();
00220 int index = 0;
00221 for (typename CoordBox<DIM>::Iterator i = box.begin(); i != box.end(); ++i) {
00222 message << "\nCoord " << *i << ":\n"
00223 << (*this)[*i] << "\n"
00224 << "neighbor: ";
00225
00226 std::vector<std::pair<int, VALUE_TYPE> > neighbor =
00227 matrices[0].getRow(index++);
00228 message << neighbor;
00229 }
00230
00231 message << "\n";
00232 return message.str();
00233 }
00234
00235 virtual void set(const Coord<DIM>& coord, const ELEMENT_TYPE& element)
00236 {
00237 (*this)[coord] = element;
00238 }
00239
00240 virtual void set(const Streak<DIM>& streak, const ELEMENT_TYPE *element)
00241 {
00242 for (Coord<DIM> cursor = streak.origin; cursor.x() < streak.endX; ++cursor.x()) {
00243 (*this)[cursor] = *element;
00244 ++element;
00245 }
00246 }
00247
00248 virtual ELEMENT_TYPE get(const Coord<DIM>& coord) const
00249 {
00250 return (*this)[coord];
00251 }
00252
00253 virtual void get(const Streak<DIM>& streak, ELEMENT_TYPE *element) const
00254 {
00255 Coord<DIM> cursor = streak.origin;
00256 for (; cursor.x() < streak.endX; ++cursor.x()) {
00257 *element = (*this)[cursor];
00258 ++element;
00259 }
00260 }
00261
00262 inline ELEMENT_TYPE& getEdgeElement()
00263 {
00264 return edgeElement;
00265 }
00266
00267 inline const ELEMENT_TYPE& getEdgeElement() const
00268 {
00269 return edgeElement;
00270 }
00271
00272 virtual void setEdge(const ELEMENT_TYPE& element)
00273 {
00274 getEdgeElement() = element;
00275 }
00276
00277 virtual const ELEMENT_TYPE& getEdge() const
00278 {
00279 return getEdgeElement();
00280 }
00281
00282 virtual CoordBox<DIM> boundingBox() const
00283 {
00284 return CoordBox<DIM>( Coord<DIM>(), dimension );
00285 }
00286
00287 protected:
00288 void saveMemberImplementation(
00289 char *target, const Selector<ELEMENT_TYPE>& selector, const Region<DIM>& region) const
00290 {
00291 for (typename Region<DIM>::StreakIterator i = region.beginStreak();
00292 i != region.endStreak(); ++i) {
00293 selector.copyMemberOut(&(*this)[i->origin], target, i->length());
00294 target += selector.sizeOfExternal() * i->length();
00295 }
00296 }
00297
00298 void loadMemberImplementation(
00299 const char *source, const Selector<ELEMENT_TYPE>& selector,
00300 const Region<DIM>& region)
00301 {
00302 for (typename Region<DIM>::StreakIterator i = region.beginStreak();
00303 i != region.endStreak(); ++i) {
00304 selector.copyMemberIn(source, &(*this)[i->origin], i->length());
00305 source += selector.sizeOfExternal() * i->length();
00306 }
00307 }
00308
00309
00310 private:
00311 std::vector<ELEMENT_TYPE> elements;
00312
00313 SellCSigmaSparseMatrixContainer<VALUE_TYPE, C, SIGMA> matrices[MATRICES];
00314 ELEMENT_TYPE edgeElement;
00315 Coord<DIM> dimension;
00316
00317 };
00318
00319 template<typename _CharT, typename _Traits, typename ELEMENT_TYPE, size_t MATRICES, typename VALUE_TYPE, int C, int SIGMA>
00320 std::basic_ostream<_CharT, _Traits>&
00321 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00322 const LibGeoDecomp::UnstructuredGrid<ELEMENT_TYPE, MATRICES, VALUE_TYPE, C, SIGMA>& grid)
00323 {
00324 __os << grid.toString();
00325 return __os;
00326 }
00327
00328 }
00329
00330 #endif