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