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