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
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
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 int face=ElementTopologyMapping<hexa>::dune2aluFace(f);
00137 for (int i=0;i<size;i++) {
00138
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)) {
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 {
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