dune-common 2.1.1
|
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 00002 // vi: set et ts=4 sw=4 sts=4: 00003 00004 #ifndef DUNE_GEOMETRY_TYPE_HH 00005 #define DUNE_GEOMETRY_TYPE_HH 00006 00007 #include <cassert> 00008 00013 #include <dune/common/exceptions.hh> 00014 00015 namespace Dune { 00016 00024 class GeometryType 00025 { 00026 public: 00029 enum BasicType { 00030 simplex, 00031 cube, 00032 pyramid, 00033 prism, 00034 extended, 00035 none 00036 }; 00037 00039 enum Binary { 00040 b0001 = 1, 00041 b0011 = 3, 00042 b0101 = 5, 00043 b0111 = 7 00044 }; 00045 private: 00046 00048 unsigned int topologyId_; 00049 00051 unsigned char dim_ : 7; 00052 00054 bool none_ : 1; 00055 00056 public: 00058 GeometryType () 00059 : topologyId_(0), dim_(0), none_(true) 00060 {} 00061 00063 GeometryType(BasicType basicType, unsigned int dim) 00064 : topologyId_(0), dim_(dim), none_(false) 00065 { 00066 if (dim < 2) 00067 return; 00068 switch( basicType ) 00069 { 00070 case GeometryType::simplex: 00071 makeSimplex(dim); 00072 break; 00073 case GeometryType::cube: 00074 makeCube(dim); 00075 break; 00076 case GeometryType::pyramid: 00077 if (dim == 3) 00078 makePyramid(); 00079 break; 00080 case GeometryType::prism: 00081 if (dim == 3) 00082 makePrism(); 00083 break; 00084 case GeometryType::none: 00085 makeNone(dim); 00086 break; 00087 default: 00088 DUNE_THROW( RangeError, 00089 "Invalid basic geometry type: " << basicType << " for dimension " << dim << "." ); 00090 } 00091 } 00092 00094 GeometryType(unsigned int topologyId, unsigned int dim) 00095 : topologyId_(topologyId), dim_(dim), none_(false) 00096 {} 00097 00108 template<class TopologyType> 00109 explicit GeometryType(TopologyType t) 00110 : topologyId_(TopologyType::id), dim_(TopologyType::dimension), none_(false) 00111 {} 00112 00114 explicit GeometryType(unsigned int dim) 00115 : topologyId_(0), dim_(dim), none_(false) 00116 { 00117 assert(dim < 2); 00118 } 00119 00121 explicit GeometryType(int dim) 00122 : topologyId_(0), dim_(dim), none_(false) 00123 { 00124 assert(dim < 2); 00125 } 00126 00129 00131 void makeVertex() { 00132 none_ = false; 00133 dim_ = 0; 00134 topologyId_ = 0; 00135 } 00136 00138 void makeLine() { 00139 none_ = false; 00140 dim_ = 1; 00141 topologyId_ = 0; 00142 } 00143 00145 void makeTriangle() { 00146 makeSimplex(2); 00147 } 00148 00150 void makeQuadrilateral() { 00151 makeCube(2); 00152 } 00153 00155 void makeTetrahedron() { 00156 makeSimplex(3); 00157 } 00158 00160 void makePyramid() { 00161 none_ = false; 00162 dim_ = 3; 00163 topologyId_ = b0011; 00164 } 00165 00167 void makePrism() { 00168 none_ = false; 00169 dim_ = 3; 00170 topologyId_ = b0101; // (1 << (dim_-1)) - 1; 00171 } 00172 00174 void makeHexahedron() { 00175 makeCube(3); 00176 } 00177 00179 void makeSimplex(unsigned int dim) { 00180 none_ = false; 00181 dim_ = dim; 00182 topologyId_ = 0; 00183 } 00184 00186 void makeCube(unsigned int dim) { 00187 none_ = false; 00188 dim_ = dim; 00189 topologyId_ = ((dim>1) ? ((1 << dim) - 1) : 0); 00190 } 00191 00193 void makeNone(unsigned int dim) { 00194 none_ = true; 00195 dim_ = dim; 00196 topologyId_ = 0; 00197 } 00198 00205 bool isVertex() const { 00206 return dim_==0; 00207 } 00208 00210 bool isLine() const { 00211 return dim_==1; 00212 } 00213 00215 bool isTriangle() const { 00216 return ! none_ && dim_==2 && (topologyId_ | 1) == b0001; 00217 } 00218 00220 bool isQuadrilateral() const { 00221 return ! none_ && dim_==2 && (topologyId_ | 1) == b0011; 00222 } 00223 00225 bool isTetrahedron() const { 00226 return ! none_ && dim_==3 && (topologyId_ | 1) == b0001; 00227 } 00228 00230 bool isPyramid() const { 00231 return ! none_ && dim_==3 && (topologyId_ | 1) == b0011; 00232 } 00233 00235 bool isPrism() const { 00236 return ! none_ && dim_==3 && (topologyId_ | 1) == b0101; 00237 } 00238 00240 bool isHexahedron() const { 00241 return ! none_ && dim_==3 && (topologyId_ | 1) == b0111; 00242 } 00243 00245 bool isSimplex() const { 00246 return ! none_ && (topologyId_ | 1) == 1; 00247 } 00248 00250 bool isCube() const { 00251 return ! none_ && ((topologyId_ ^ ((1 << dim_)-1)) >> 1 == 0); 00252 } 00253 00255 bool isNone() const { 00256 return none_; 00257 } 00258 00260 unsigned int dim() const { 00261 return dim_; 00262 } 00263 00265 BasicType basicType() const DUNE_DEPRECATED { 00266 if (isSimplex()) 00267 return GeometryType::simplex; 00268 if (isCube()) 00269 return GeometryType::cube; 00270 if (isPyramid()) 00271 return GeometryType::pyramid; 00272 if (isPrism()) 00273 return GeometryType::prism; 00274 if (isNone()) 00275 return GeometryType::none; 00276 return GeometryType::extended; 00277 } 00278 00280 unsigned int id() const { 00281 return topologyId_; 00282 } 00283 00289 bool operator==(const GeometryType& other) const { 00290 return ( ( none_ == other.none_ ) 00291 && ( ( none_ == true ) 00292 || ( ( dim_ == other.dim_ ) 00293 && ( (topologyId_ >> 1) == (other.topologyId_ >> 1) ) 00294 ) 00295 ) 00296 ); 00297 } 00298 00300 bool operator!=(const GeometryType& other) const { 00301 return ! ((*this)==other); 00302 } 00303 00305 bool operator < (const GeometryType& other) const { 00306 return ( ( none_ < other.none_ ) 00307 || ( !( other.none_ < none_ ) 00308 && ( ( dim_ < other.dim_ ) 00309 || ( (other.dim_ == dim_) 00310 && ((topologyId_ >> 1) < (other.topologyId_ >> 1) ) 00311 ) 00312 ) 00313 ) 00314 ); 00315 } 00316 }; 00317 00319 inline std::ostream& operator<< (std::ostream& s, const GeometryType& a) 00320 { 00321 if (a.isSimplex()) 00322 { 00323 s << "(simplex, " << a.dim() << ")"; 00324 return s; 00325 } 00326 if (a.isCube()) 00327 { 00328 s << "(cube, " << a.dim() << ")"; 00329 return s; 00330 } 00331 if (a.isPyramid()) 00332 { 00333 s << "(pyramid, 3)"; 00334 return s; 00335 } 00336 if (a.isPrism()) 00337 { 00338 s << "(prism, 3)"; 00339 return s; 00340 } 00341 if (a.isNone()) 00342 { 00343 s << "(none, " << a.dim() << ")"; 00344 return s; 00345 } 00346 s << "(other [" << a.id() << "], " << a.dim() << ")"; 00347 return s; 00348 } 00349 00351 inline std::ostream& operator<< (std::ostream& s, GeometryType::BasicType type) 00352 { 00353 switch (type) { 00354 case GeometryType::simplex: 00355 s << "simplex"; 00356 break; 00357 case GeometryType::cube: 00358 s << "cube"; 00359 break; 00360 case GeometryType::pyramid: 00361 s << "pyramid"; 00362 break; 00363 case GeometryType::prism: 00364 s << "prism"; 00365 break; 00366 case GeometryType::extended: 00367 s << "other"; 00368 case GeometryType::none: 00369 s << "none"; 00370 break; 00371 default: 00372 DUNE_THROW(Exception, "invalid GeometryType::BasicType"); 00373 } 00374 return s; 00375 } 00376 } 00377 00378 #endif