SyFi 0.3
|
00001 // Copyright (C) 2006-2009 Kent-Andre Mardal and Simula Research Laboratory. 00002 // Licensed under the GNU GPL Version 2, or (at your option) any later version. 00003 00004 #ifndef DOFT_IS_INCLUDED 00005 #define DOFT_IS_INCLUDED 00006 00007 #include <map> 00008 #include <vector> 00009 #include <iterator> 00010 #include <iostream> 00011 00012 template <class D, class C> 00013 class DofT 00014 { 00015 protected: 00016 bool create_index2dof, create_dof2loc; 00017 int counter; 00018 int emax; 00019 int imax; 00020 // the structures loc2dof, dof2index, and doc2loc are completely dynamic 00021 // they are all initialized and updated by insert_dof(int e, int i, ex Li) 00022 00023 // (int e, int i) -> int j 00024 std::map< std::pair<int,int>, int> loc2dof; 00025 // (ex Lj) -> int j 00026 std::map<D,int,C> dof2index; 00027 typename std::map<D,int,C>:: iterator iter; 00028 00029 // (int j) -> ex Lj 00030 std::map<int,D> index2dof; 00031 // (ex j) -> vector< pair<e1, i1>, .. pair<en, in> > 00032 std::map <int, std::vector<std::pair<int,int> > > dof2loc; 00033 00034 public: 00035 DofT( bool create_index2dof_ = false, bool create_dof2loc_ = false ) 00036 { 00037 counter = -1; 00038 emax = -1; 00039 imax = -1; 00040 create_index2dof = create_index2dof_; 00041 create_dof2loc = create_dof2loc_; 00042 } 00043 ~DofT() {} 00044 // to update the internal structures 00045 int insert_dof(int e, int i, D Li); 00046 00047 // helper functions when the dofs have been set 00048 // These do not modify the internal structure 00049 int glob_dof(int e, int i); 00050 int glob_dof(D Lj); 00051 D glob_dof(int j); 00052 int size() const; 00053 int num_elements() const { return emax+1; } 00054 int num_basis_functions() const { return imax+1; } 00055 std::vector<std::pair<int, int> > glob2loc(int j); 00056 void clear(); 00057 }; 00058 00059 template <class D, class C> 00060 int 00061 DofT<D, C> :: size() const 00062 { 00063 return counter+1; 00064 } 00065 00066 00067 template <class D, class C> 00068 int 00069 DofT<D, C>:: insert_dof(int e, int i, D Li) 00070 { 00071 00072 if (e > emax) emax = e; 00073 if (i > imax) imax = i; 00074 00075 // first we update loc2dof, which always should be updated 00076 std::pair<int,int> index; 00077 index.first = e; 00078 index.second = i; 00079 int return_dof; 00080 00081 // check if the dof is new, if so 00082 // update counter, dof2index and create 00083 // a new vector in dof2loc 00084 iter = dof2index.find(Li); 00085 //dof is new 00086 if ( iter == dof2index.end() ) 00087 { 00088 counter++; 00089 return_dof = counter; 00090 dof2index[Li] = counter; 00091 loc2dof[index] = counter; 00092 if ( create_index2dof) 00093 { 00094 std::pair<int, D> p(counter, Li); 00095 index2dof.insert(p); 00096 // index2dof[counter] = Li; 00097 // 00098 } 00099 if ( create_dof2loc ) 00100 { 00101 std::vector<std::pair<int,int> > v; 00102 dof2loc[counter] = v; 00103 } 00104 } // dof is not new 00105 else 00106 { 00107 loc2dof[index] = (*iter).second; 00108 return_dof = (*iter).second; 00109 } 00110 00111 // insert (e,i) in dof2loc[Li] 00112 if (create_dof2loc) 00113 { 00114 dof2loc[return_dof].push_back(index); 00115 } 00116 00117 return return_dof; 00118 } 00119 00120 00121 template <class D, class C> 00122 int 00123 DofT<D, C>:: glob_dof(int e, int i) 00124 { 00125 std::pair<int,int> index; 00126 index.first = e; 00127 index.second = i; 00128 if ( loc2dof.find(index) != loc2dof.end()) 00129 { 00130 return (*(loc2dof.find(index))).second; 00131 } 00132 else 00133 { 00134 return -1; 00135 } 00136 } 00137 00138 00139 template <class D, class C> 00140 int 00141 DofT<D, C>:: glob_dof(D Lj) 00142 { 00143 if ( dof2index.find(Lj) != dof2index.end()) 00144 { 00145 return (*(dof2index.find(Lj))).second; 00146 } 00147 else 00148 { 00149 return -1; 00150 } 00151 } 00152 00153 00154 template <class D, class C> 00155 D 00156 DofT<D, C>:: glob_dof(int j) 00157 { 00158 if ( create_index2dof) 00159 { 00160 if ( index2dof.find(j) != index2dof.end() ) 00161 { 00162 return (*(index2dof.find(j))).second; 00163 } 00164 else 00165 { 00166 std::cout <<"not found "<<std::endl; 00167 return D(); 00168 } 00169 } 00170 else 00171 { 00172 std::cout <<"This structure has not been created "<<std::endl; 00173 std::cout <<"You must turn on the create_index2dof flag before initialization!"<<std::endl; 00174 return D(); 00175 } 00176 } 00177 00178 00179 template <class D, class C> 00180 std::vector<std::pair<int, int> > 00181 DofT<D, C>:: glob2loc(int j) 00182 { 00183 if ( create_dof2loc ) 00184 { 00185 return dof2loc[j]; 00186 } 00187 else 00188 { 00189 std::cout <<"This structure has not been created "<<std::endl; 00190 std::cout <<"You must turn on the create_dof2loc flag before initialization!"<<std::endl; 00191 return std::vector<std::pair<int,int> >(); 00192 } 00193 00194 } 00195 00196 00197 template <class D, class C> 00198 void 00199 DofT<D,C>:: clear() 00200 { 00201 counter = -1; 00202 emax = -1; 00203 imax = -1; 00204 00205 loc2dof.clear(); 00206 dof2index.clear(); 00207 index2dof.clear(); 00208 dof2loc.clear(); 00209 } 00210 #endif