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