entitykey.hh

00001 #ifndef MACROGRIDENTITYKEY_HH
00002 #define MACROGRIDENTITYKEY_HH
00003 
00004 #include <vector>
00005 #include <dune/grid/alugrid/3d/topology.hh>
00006 namespace Dune {
00007 namespace {
00008 template < class A> class EntityKey {
00009   inline EntityKey () ;
00010   std::vector<A> key_,origKey_;
00011   bool origKeySet_;
00012  public :
00013   inline EntityKey (const EntityKey < A > &k) : key_(k.key_.size()), origKey_(k.key_.size()), origKeySet_(k. origKeySet_) {
00014     for (size_t i=0;i<key_.size();i++) {
00015       key_[i]=k.key_[i];
00016       origKey_[i]=k.origKey_[i];
00017     }
00018   }
00019  inline EntityKey& operator=(const EntityKey < A > &k) {
00020     assert(key_.size()==k.key_.size());
00021     for (size_t i=0;i<key_.size();i++) {
00022       key_[i]=k.key_[i];
00023       origKey_[i]=k.origKey_[i];
00024     }
00025     origKeySet_ = k.origKeySet_;
00026   }
00027   inline EntityKey (std::vector<A>& key,bool setOrigKey=true) : key_(key.size()), origKey_(key.size()), origKeySet_(setOrigKey) {
00028     for (size_t i=0;i<key_.size();i++) {
00029       key_[i]=key[i];
00030       origKey_[i]=key_[i];
00031     }
00032     std::sort(key_.begin(),key_.end());
00033   }
00034   inline EntityKey (std::vector<A>& key,int N,int offset,bool setOrigKey=true) : key_(N), origKey_(N), origKeySet_(setOrigKey) {
00035     for (size_t i=0;i<key_.size();i++) {
00036       key_[i]=key[(i+offset)%key.size()];
00037       origKey_[i]=key[(i+offset)%key.size()];
00038     }
00039     std::sort(key_.begin(),key_.end());
00040   }
00041   inline void orientation (int base,std::vector<std::vector<double> >& vtx) {
00042     if (key_.size()==3)  {
00043       assert( (size_t) origKey_[0] < vtx.size() );
00044       std::vector<double>& p0 = vtx[origKey_[0]];
00045       assert( (size_t) origKey_[1] < vtx.size() );
00046       std::vector<double>& p1 = vtx[origKey_[1]];
00047       assert( (size_t) origKey_[2] < vtx.size() );
00048       std::vector<double>& p2 = vtx[origKey_[2]];
00049       assert( (size_t) base < vtx.size() );
00050       std::vector<double>& q  = vtx[base];
00051       double n[3];
00052       n[0] = (p1[1]-p0[1])*(p2[2]-p0[2])-(p2[1]-p0[1])*(p1[2]-p0[2]);
00053       n[1] = (p1[2]-p0[2])*(p2[0]-p0[0])-(p2[2]-p0[2])*(p1[0]-p0[0]);
00054       n[2] = (p1[0]-p0[0])*(p2[1]-p0[1])-(p2[0]-p0[0])*(p1[1]-p0[1]);
00055       double test = n[0]*(q[0]-p0[0])+n[1]*(q[1]-p0[1])+n[2]*(q[2]-p0[2]);
00056       bool reorient = (test>0);
00057       if (reorient) {
00058         A key1=origKey_[1];
00059         origKey_[1]=origKey_[2];
00060         origKey_[2]=key1;
00061       }
00062     }
00063   }
00064   inline bool operator < (const EntityKey <A> &k) const {
00065     // assert(k.key_.size()==key_.size());
00066     return key_<k.key_;
00067   }
00068   inline void print() const {
00069     for (size_t i=0;i<key_.size();i++) {
00070       std::cerr << key_[i] << " ";
00071     }
00072     std::cerr << std::endl;
00073   }
00074   const A& operator[](int i) const {
00075     return key_[i];
00076   }
00077   bool origKeySet() const {
00078     return origKeySet_;
00079   }
00080   const A& origKey(int i) const {
00081     return origKey_[i];
00082   }
00083   int size() const {
00084     return key_.size();
00085   }
00086 } ;
00087 class ElementFaceUtil {
00088  public:
00089   inline static int nofFaces(int dimw,std::vector<int>& element) {
00090     if (dimw==1) 
00091       return 2;
00092     else if (dimw==2) 
00093       switch (element.size()) {
00094       case 3: return 3; break; 
00095       case 4: return 4; break; 
00096       }
00097     else if (dimw==3) 
00098       switch (element.size()) {
00099       case 4: return 4; break; 
00100       case 8: return 6; break; 
00101       }
00102     return -1;
00103   }
00104   inline static int faceSize(int dimw,bool simpl) {
00105     if (dimw==1) 
00106       return 1;
00107     else if (dimw==2) 
00108       return 2;
00109     else if (dimw==3) 
00110       return ((simpl)?3:4);
00111     return -1;
00112   }
00113   template <int dimworld>
00114   inline static EntityKey<int> 
00115   generateCubeFace(std::vector<int>& element,int f) {
00116     ReferenceCube<double,dimworld> ref;
00117     int size=ref.size(f,1,dimworld);
00118     std::vector<int> k(size);
00119     /*
00120     for (int i=0;i<size;i++) {
00121       k[i] = element[ref.subEntity(f,1,i,dimworld)];
00122     }
00123     if (dimworld==3) {
00124       if (f==2 || f==1 || f==5) {
00125         int ktmp=k[0];
00126         k[0]=k[1];
00127         k[1]=ktmp;
00128       }
00129       else {
00130         int ktmp=k[2];
00131         k[2]=k[3];
00132         k[3]=ktmp;
00133       }
00134     }
00135     */
00136     int face=ElementTopologyMapping<hexa>::dune2aluFace(f);
00137     for (int i=0;i<size;i++) {
00138       // int idxdune = ref.subEntity(f,1,i,dimworld);
00139       int idx = ElementTopologyMapping<hexa>::alu2duneFaceVertex(face,i);
00140       int idxdune = ref.subEntity(f,1,idx,dimworld);
00141       k[size-1-i] = element[idxdune];
00142     }    
00143     return EntityKey<int> (k);
00144   }
00145   template <int dimworld>
00146   inline static EntityKey<int> 
00147   generateSimplexFace(std::vector<int>& element,int f) {
00148     ReferenceSimplex<double,dimworld> ref;
00149     int size=ref.size(f,1,dimworld);
00150     std::vector<int> k(size);
00151     for (int i=0;i<size;i++) {
00152       k[i] = element[ref.subEntity(f,1,i,dimworld)];
00153     }
00154     return EntityKey<int> (k);
00155   }
00156   inline static EntityKey<int> 
00157   generateFace(int dimw,std::vector<int>& element,int f) {
00158     if (element.size()==size_t(dimw+1)) { // Simplex element
00159       if (dimw==3) 
00160         return generateSimplexFace<3>(element,f);
00161       else if (dimw==2) 
00162         return generateSimplexFace<2>(element,f);
00163       else if (dimw==1) 
00164         return generateSimplexFace<1>(element,f);
00165     }
00166     else { // Cube element
00167       if (dimw==3) 
00168         return generateCubeFace<3>(element,f);
00169       else if (dimw==2) 
00170         return generateCubeFace<2>(element,f);
00171       else if (dimw==1) 
00172         return generateCubeFace<1>(element,f);
00173     }
00174     DUNE_THROW(DGFException,"WRONG DIMENSION");
00175     return generateCubeFace<1>(element,f);
00176   }
00177 };
00178 }
00179 }
00180 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)