00001
00002
00003 #ifndef DUNE_P1MGTRANSFER_HH
00004 #define DUNE_P1MGTRANSFER_HH
00005
00006 #include<set>
00007 #include<map>
00008
00009 #include<dune/common/exceptions.hh>
00010 #include<dune/common/fvector.hh>
00011 #include<dune/common/fmatrix.hh>
00012 #include<dune/common/geometrytype.hh>
00013
00014 #include<dune/grid/common/grid.hh>
00015 #include<dune/grid/common/mcmgmapper.hh>
00016 #include<dune/grid/utility/intersectiongetter.hh>
00017
00018 #include<dune/istl/bvector.hh>
00019 #include<dune/istl/bcrsmatrix.hh>
00020
00021 #include<dune/disc/shapefunctions/lagrangeshapefunctions.hh>
00022 #include<dune/disc/operators/localstiffness.hh>
00023
00030 namespace Dune
00031 {
00046 template<class G, class RT, int m=1>
00047 class P1MGTransfer
00048 {
00049 public:
00050
00051 typedef FieldMatrix<RT,m,m> BlockType;
00052 typedef BCRSMatrix<BlockType> RepresentationType;
00053 typedef typename RepresentationType::RowIterator rowiterator;
00054 typedef typename RepresentationType::ColIterator coliterator;
00055
00056
00057 template<int dim>
00058 struct P1Layout
00059 {
00060 bool contains (Dune::GeometryType gt)
00061 {
00062 return gt.dim() == 0;
00063 }
00064 };
00065
00066 typedef typename G::ctype DT;
00067 typedef typename G::LevelGridView GridView;
00068 enum {n=G::dimension};
00069 typedef typename G::template Codim<0>::Entity Entity;
00070 typedef typename GridView::template Codim<0>::Iterator ElementLevelIterator;
00071 typedef typename GridView::template Codim<n>::Iterator VertexLevelIterator;
00072 typedef typename GridView::template Codim<0>::EntityPointer EntityPointer;
00073 typedef typename GridView::IndexSet IS;
00074 typedef MultipleCodimMultipleGeomTypeMapper<G,IS,P1Layout> VM;
00075
00076 typedef std::set<int> IntSet;
00077 typedef std::map<int,IntSet> Graph;
00078
00082 P1MGTransfer (const G& grid_, int level_)
00083 : grid(grid_), coarseview(grid.levelView(level_-1)),
00084 fineview(grid.levelView(level_)), level(level_)
00085 {
00086
00087 if (level==0)
00088 DUNE_THROW(Exception,"P1MGTransfer: level greater 0 required");
00089
00090
00091 VM finemapper(grid,grid.levelIndexSet(level));
00092 VM coarsemapper(grid,grid.levelIndexSet(level-1));
00093
00094
00095 Graph graph;
00096
00097
00098 std::vector<bool> treated(finemapper.size(),false);
00099
00100
00101
00102 for (ElementLevelIterator it = fineview.template begin<0>();
00103 it!=fineview.template end<0>(); ++it)
00104 {
00105
00106 GeometryType gt = it->type();
00107
00108
00109 const EntityPointer father = it->father();
00110
00111
00112 GeometryType gtf = father->type();
00113
00114
00115
00116 for (int i=0; i<it->template count<n>(); i++)
00117 {
00118
00119 int indexi = finemapper.template map<n>(*it,i);
00120
00121
00122 if (treated[indexi]) continue;
00123
00124
00125 const FieldVector<DT,n>& cpos=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1)[i].position();
00126 FieldVector<DT,n> pos = it->geometryInFather().global(cpos);
00127
00128
00129 for (int j=0; j<father-> template count<n>(); j++)
00130 {
00131
00132 RT phi = Dune::LagrangeShapeFunctions<DT,RT,n>::general(gtf,1)[j].evaluateFunction(0,pos);
00133
00134
00135 int indexj = coarsemapper.template map<n>(*father,j);
00136
00137
00138 if (std::abs(phi)>1E-6) graph[indexi].insert(indexj);
00139 }
00140 treated[indexi] = true;
00141 }
00142 }
00143
00144
00145 int nnz=0;
00146 for (Graph::iterator i=graph.begin(); i!=graph.end(); ++i)
00147 nnz += i->second.size();
00148
00149
00150 std::cout << grid.comm().rank() << ": making " << finemapper.size() << "x"
00151 << coarsemapper.size() << " transfer matrix with " << nnz
00152 << " nonzeroes" << std::endl;
00153 A = new RepresentationType(finemapper.size(),coarsemapper.size(),nnz,RepresentationType::random);
00154
00155
00156 for (Graph::iterator i=graph.begin(); i!=graph.end(); ++i)
00157 A->setrowsize(i->first,i->second.size());
00158 A->endrowsizes();
00159
00160
00161 for (Graph::iterator i=graph.begin(); i!=graph.end(); ++i)
00162 for (IntSet::iterator j=i->second.begin(); j!=i->second.end(); ++j)
00163 A->addindex(i->first,*j);
00164 A->endindices();
00165
00166
00167 graph.clear();
00168
00169
00170 for (int compi=0; compi<m; compi++)
00171 skipflag[compi] = new std::vector<bool>(finemapper.size(),false);
00172 for (int compi=0; compi<m; compi++)
00173 coarseskipflag[compi] = new std::vector<bool>(coarsemapper.size(),false);
00174 }
00175
00176
00180 void assemble (LocalStiffness<GridView,RT,m>& loc)
00181 {
00182
00183 VM finemapper(grid,grid.levelIndexSet(level));
00184 VM coarsemapper(grid,grid.levelIndexSet(level-1));
00185
00186
00187 (*A) = 0;
00188 for (int compi=0; compi<m; compi++)
00189 for (int i=0; i<finemapper.size(); i++)
00190 (*skipflag[compi])[i] = false;
00191 for (int compi=0; compi<m; compi++)
00192 for (int i=0; i<coarsemapper.size(); i++)
00193 (*coarseskipflag[compi])[i] = false;
00194
00195
00196 for (ElementLevelIterator it = coarseview.template begin<0>();
00197 it!=coarseview.template end<0>(); ++it)
00198 {
00199
00200 GeometryType gt = it->type();
00201
00202
00203 loc.assembleBoundaryCondition(*it);
00204
00205
00206
00207 for (int i=0; i<it->template count<n>(); i++)
00208 {
00209
00210 int indexi = coarsemapper.template map<n>(*it,i);
00211
00212
00213 for (int compi=0; compi<m; compi++)
00214 if (loc.bc(i)[compi]==BoundaryConditions::process ||
00215 loc.bc(i)[compi]==BoundaryConditions::dirichlet)
00216 (*coarseskipflag[compi])[indexi] = true;
00217 }
00218 }
00219
00220
00221 std::vector<bool> treated(finemapper.size(),false);
00222
00223
00224 for (ElementLevelIterator it = fineview.template begin<0>();
00225 it!=fineview.template end<0>(); ++it)
00226 {
00227
00228 GeometryType gt = it->type();
00229
00230
00231 const EntityPointer father = it->father();
00232
00233
00234 GeometryType gtf = father->type();
00235
00236
00237 loc.assembleBoundaryCondition(*it);
00238
00239
00240
00241 for (int i=0; i<it->template count<n>(); i++)
00242 {
00243
00244 int indexi = finemapper.template map<n>(*it,i);
00245
00246
00247 for (int compi=0; compi<m; compi++)
00248 if (loc.bc(i)[compi]==BoundaryConditions::process ||
00249 loc.bc(i)[compi]==BoundaryConditions::dirichlet)
00250 (*skipflag[compi])[indexi] = true;
00251
00252
00253 if (treated[indexi]) continue;
00254
00255
00256 const FieldVector<DT,n>& cpos=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1)[i].position();
00257 FieldVector<DT,n> pos = it->geometryInFather().global(cpos);
00258
00259
00260 for (int j=0; j<father->template count<n>(); ++j)
00261 {
00262
00263 RT phi = Dune::LagrangeShapeFunctions<DT,RT,n>::general(gtf,1)[j].evaluateFunction(0,pos);
00264
00265
00266 if (std::abs(phi)>1E-6)
00267 {
00268
00269 int indexj = coarsemapper.template map<n>(*father,j);
00270
00271
00272 BlockType D;
00273 for (int compi=0; compi<m; compi++)
00274 {
00275 double scale=1.0;
00276 if ((*coarseskipflag[compi])[indexj]) scale=0;
00277 for (int compj=0; compj<m; compj++)
00278 if (compi==compj)
00279 D[compi][compj] = phi*scale;
00280 else
00281 D[compi][compj] = 0.0;
00282 }
00283
00284
00285 (*A)[indexi][indexj] = D;
00286 }
00287 }
00288
00289
00290 treated[indexi] = true;
00291 }
00292 }
00293 }
00294
00295
00296 bool skipFlag (int compi, int indexi) const
00297 {
00298 return (*skipflag[compi])[indexi];
00299 }
00300
00301
00302 bool coarseSkipFlag (int compi, int indexi) const
00303 {
00304 return (*coarseskipflag[compi])[indexi];
00305 }
00306
00308 const RepresentationType& operator* () const
00309 {
00310 return *A;
00311 }
00312
00314 RepresentationType& operator* ()
00315 {
00316 return *A;
00317 }
00318
00320
00321
00322 ~P1MGTransfer ()
00323 {
00324 delete A;
00325 for (int compi=0; compi<m; compi++)
00326 delete skipflag[compi];
00327 for (int compi=0; compi<m; compi++)
00328 delete coarseskipflag[compi];
00329 }
00330
00331 private:
00332
00333
00334 P1MGTransfer (const P1MGTransfer&) {}
00335 P1MGTransfer& operator= (const P1MGTransfer&) {}
00336
00337
00338 const G& grid;
00339 const GridView& fineview;
00340 const GridView& coarseview;
00341 int level;
00342 RepresentationType* A;
00343 std::vector<bool>* skipflag[m];
00344 std::vector<bool>* coarseskipflag[m];
00345 };
00346
00347
00348
00350 }
00351 #endif