00001
00002
00003 #ifndef DUNE_P1FUNCTION_HH
00004 #define DUNE_P1FUNCTION_HH
00005
00006
00007 #include<new>
00008 #include<iostream>
00009 #include<vector>
00010 #include<list>
00011 #include<map>
00012 #include<set>
00013
00014
00015 #include<dune/common/fvector.hh>
00016 #include<dune/common/exceptions.hh>
00017 #include<dune/common/tuples.hh>
00018 #include<dune/common/stdstreams.hh>
00019 #include<dune/grid/common/grid.hh>
00020 #include<dune/grid/common/mcmgmapper.hh>
00021 #include<dune/grid/common/universalmapper.hh>
00022 #include<dune/grid/io/file/vtk/vtkwriter.hh>
00023 #include<dune/istl/bvector.hh>
00024 #include<dune/istl/operators.hh>
00025 #include<dune/istl/bcrsmatrix.hh>
00026 #include<dune/istl/owneroverlapcopy.hh>
00027 #include<dune/disc/shapefunctions/lagrangeshapefunctions.hh>
00028
00029
00030 #include"functions.hh"
00031 #include"p0function.hh"
00032
00038 namespace Dune
00039 {
00049 template<class G>
00050 class LeafCommunicate
00051 {
00052 public:
00053 LeafCommunicate (const G& g)
00054 : grid(g)
00055 {}
00056
00057 template<class DataHandle>
00058 void communicate (DataHandle& data, InterfaceType iftype, CommunicationDirection dir) const
00059 {
00060 grid.template communicate<DataHandle>(data,iftype,dir);
00061 }
00062
00063 private:
00064 const G& grid;
00065 };
00066
00067 template<class G>
00068 class LevelCommunicate
00069 {
00070 public:
00071 LevelCommunicate (const G& g, int l)
00072 : grid(g), level(l)
00073 {}
00074
00075 template<class DataHandle>
00076 void communicate (DataHandle& data, InterfaceType iftype, CommunicationDirection dir) const
00077 {
00078 grid.template communicate<DataHandle>(data,iftype,dir,level);
00079 }
00080
00081 private:
00082 const G& grid;
00083 int level;
00084 };
00085
00087 template<class G, class GV, class VM, class LC>
00088 class P1ExtendOverlap {
00089
00090
00091 typedef typename G::ctype DT;
00092 enum {n=G::dimension};
00093 typedef typename GV::IndexSet IS;
00094 typedef typename G::template Codim<0>::Entity Entity;
00095 typedef typename GV::template Codim<0>::Iterator Iterator;
00096 typedef typename GV::template Codim<n>::Iterator VIterator;
00097 typedef typename G::template Codim<0>::EntityPointer EEntityPointer;
00098 typedef typename G::Traits::GlobalIdSet IDS;
00099 typedef typename IDS::IdType IdType;
00100 typedef std::set<IdType> GIDSet;
00101 typedef std::pair<IdType,int> Pair;
00102 typedef std::set<int> ProcSet;
00103
00104
00105 class IdExchange
00106 : public CommDataHandleIF<IdExchange,Pair> {
00107 public:
00109 typedef Pair DataType;
00110
00112 bool contains (int dim, int codim) const
00113 {
00114 return (codim==dim);
00115 }
00116
00118 bool fixedsize (int dim, int codim) const
00119 {
00120 return false;
00121 }
00122
00127 template<class EntityType>
00128 size_t size (EntityType& e) const
00129 {
00130 return myids[vertexmapper.map(e)].size();
00131 }
00132
00134 template<class MessageBuffer, class EntityType>
00135 void gather (MessageBuffer& buff, const EntityType& e) const
00136 {
00137 int alpha=vertexmapper.map(e);
00138 GIDSet& thisset = myids[alpha];
00139 for (typename GIDSet::iterator i=thisset.begin(); i!=thisset.end(); ++i)
00140 {
00141 buff.write(Pair(*i,grid.comm().rank()));
00142 owner[*i] = grid.comm().rank();
00143 }
00144 myprocs[alpha].insert(grid.comm().rank());
00145 }
00146
00151 template<class MessageBuffer, class EntityType>
00152 void scatter (MessageBuffer& buff, const EntityType& e, size_t n)
00153 {
00154 int alpha=vertexmapper.map(e);
00155 GIDSet& thisset = myids[alpha];
00156 int source;
00157 for (size_t i=0; i<n; i++)
00158 {
00159 Pair x;
00160 buff.read(x);
00161 thisset.insert(x.first);
00162 source=x.second;
00163 if (owner.find(x.first)==owner.end())
00164 owner[x.first] = source;
00165 else
00166 owner[x.first] = std::min(owner[x.first],source);
00167 }
00168 myprocs[alpha].insert(source);
00169 }
00170
00172 IdExchange (const G& g, const VM& vm, std::map<int,GIDSet>& ids, std::map<int,ProcSet>& procs,
00173 std::map<IdType,int>& o)
00174 : grid(g), vertexmapper(vm), myids(ids), myprocs(procs), owner(o)
00175 {}
00176
00177 private:
00178 const G& grid;
00179 const VM& vertexmapper;
00180 std::map<int,GIDSet>& myids;
00181 std::map<int,ProcSet>& myprocs;
00182 std::map<IdType,int>& owner;
00183 };
00184
00185
00186 class BorderLinksExchange
00187 : public CommDataHandleIF<BorderLinksExchange,IdType>{
00188 public:
00190 typedef IdType DataType;
00191
00193 bool contains (int dim, int codim) const
00194 {
00195 return (codim==dim);
00196 }
00197
00199 bool fixedsize (int dim, int codim) const
00200 {
00201 return false;
00202 }
00203
00208 template<class EntityType>
00209 size_t size (EntityType& e) const
00210 {
00211 return borderlinks[vertexmapper.map(e)].size();
00212 }
00213
00215 template<class MessageBuffer, class EntityType>
00216 void gather (MessageBuffer& buff, const EntityType& e) const
00217 {
00218 GIDSet& myset = borderlinks[vertexmapper.map(e)];
00219 for (typename GIDSet::iterator i=myset.begin(); i!=myset.end(); ++i)
00220 buff.write(*i);
00221 }
00222
00227 template<class MessageBuffer, class EntityType>
00228 void scatter (MessageBuffer& buff, const EntityType& e, size_t n)
00229 {
00230 GIDSet& myset = borderlinks[vertexmapper.map(e)];
00231 for (size_t i=0; i<n; i++)
00232 {
00233 DataType x;
00234 buff.read(x);
00235 myset.insert(x);
00236 }
00237 }
00238
00240 BorderLinksExchange (const G& g, std::map<int,GIDSet>& bl, const VM& vm)
00241 : grid(g), borderlinks(bl), vertexmapper(vm)
00242 {}
00243
00244 private:
00245 const G& grid;
00246 std::map<int,GIDSet>& borderlinks;
00247 const VM& vertexmapper;
00248 };
00249
00250 public:
00251
00252 enum Attributes {slave=OwnerOverlapCopyAttributeSet::copy,
00253 master=OwnerOverlapCopyAttributeSet::owner,
00254 overlap=OwnerOverlapCopyAttributeSet::overlap};
00255
00256 typedef IndexInfoFromGrid<IdType,int> P1IndexInfoFromGrid;
00257
00259 void fillIndexInfoFromGrid (const G& grid, const GV& gridview, const VM& vertexmapper, P1IndexInfoFromGrid& info)
00260 {
00261
00262
00263
00264
00265 std::map<int,GIDSet> myids;
00266 std::map<int,ProcSet> myprocs;
00267 std::map<IdType,int> owner;
00268 Iterator eendit = gridview.template end<0>();
00269 for (Iterator it = gridview.template begin<0>(); it!=eendit; ++it)
00270 {
00271 Dune::GeometryType gt = it->type();
00272 const typename Dune::ReferenceElementContainer<DT,n>::value_type&
00273 refelem = ReferenceElements<DT,n>::general(gt);
00274
00275 if (it->partitionType()==InteriorEntity)
00276 for (int i=0; i<refelem.size(n); i++)
00277 {
00278 if (it->template entity<n>(i)->partitionType()==BorderEntity)
00279 {
00280 int alpha = vertexmapper.template map<n>(*it,i);
00281 GIDSet& thisset = myids[alpha];
00282 for (int j=0; j<refelem.size(n); j++)
00283 {
00284 IdType beta = grid.globalIdSet().template subId<n>(*it,j);
00285 thisset.insert(beta);
00286 }
00287 }
00288 }
00289 }
00290 IdExchange datahandle(grid,vertexmapper,myids,myprocs,owner);
00291 lc.template communicate<IdExchange>(datahandle,InteriorBorder_InteriorBorder_Interface,ForwardCommunication);
00292
00293
00294 std::map<IdType,int> gid2index;
00295 for (typename std::map<int,GIDSet>::iterator i=myids.begin(); i!=myids.end(); ++i)
00296 for (typename GIDSet::iterator j=(i->second).begin(); j!=(i->second).end(); ++j)
00297 gid2index[*j] = -1;
00298 VIterator vendit = gridview.template end<n>();
00299 for (VIterator it = gridview.template begin<n>(); it!=vendit; ++it)
00300 {
00301 IdType beta = grid.globalIdSet().id(*it);
00302 if (gid2index.find(beta)!=gid2index.end())
00303 {
00304 int alpha = vertexmapper.map(*it);
00305 gid2index[beta] = alpha;
00306 }
00307 }
00308 int extraDOFs = 0;
00309 for (typename std::map<IdType,int>::iterator i=gid2index.begin(); i!=gid2index.end(); ++i)
00310 if (i->second==-1)
00311 {
00312 i->second = vertexmapper.size()+extraDOFs;
00313 extraDOFs++;
00314 }
00315
00316
00317 ProcSet neighbors;
00318 for (typename std::map<int,ProcSet>::iterator i=myprocs.begin(); i!=myprocs.end(); ++i)
00319 for (typename ProcSet::iterator j=(i->second).begin(); j!=(i->second).end(); ++j)
00320 if (*j!=grid.comm().rank())
00321 neighbors.insert(*j);
00322
00323
00324
00325
00326 for (typename ProcSet::iterator p=neighbors.begin(); p!=neighbors.end(); ++p)
00327 {
00328 GIDSet remote;
00329 for (typename std::map<int,ProcSet>::iterator i=myprocs.begin(); i!=myprocs.end(); ++i)
00330 if ((i->second).find(*p)!=(i->second).end())
00331 {
00332 GIDSet& thisset = myids[i->first];
00333 for (typename GIDSet::iterator j=thisset.begin(); j!=thisset.end(); ++j)
00334 remote.insert(*j);
00335 }
00336 }
00337
00338
00339
00340 std::set< Tuple<IdType,int,int> > ownindices;
00341 for (typename std::map<int,GIDSet>::iterator i=myids.begin(); i!=myids.end(); ++i)
00342 for (typename GIDSet::iterator j=(i->second).begin(); j!=(i->second).end(); ++j)
00343 {
00344 int a=slave;
00345 if (owner[*j]==grid.comm().rank()) a=master;
00346 info.addLocalIndex(Tuple<IdType,int,int>(*j,gid2index[*j],a));
00347 }
00348 std::set< Tuple<int,IdType,int> > remoteindices;
00349 for (typename std::map<int,ProcSet>::iterator i=myprocs.begin(); i!=myprocs.end(); ++i)
00350 {
00351 GIDSet& thisset = myids[i->first];
00352 for (typename GIDSet::iterator j=thisset.begin(); j!=thisset.end(); ++j)
00353 for (typename ProcSet::iterator p=(i->second).begin(); p!=(i->second).end(); ++p)
00354 {
00355 int a=slave;
00356 if (owner[*j]==(*p)) a=master;
00357 if (*p!=grid.comm().rank()) info.addRemoteIndex(Tuple<int,IdType,int>(*p,*j,a));
00358 }
00359 }
00360
00361
00362 myids.clear();
00363 gid2index.clear();
00364 myprocs.clear();
00365 owner.clear();
00366 neighbors.clear();
00367
00368 return;
00369 }
00370
00371
00373 void extend (const G& grid, const GV& gridView, const VM& vertexmapper,
00374 std::map<int,GIDSet>& borderlinks, int& extraDOFs, std::map<IdType,int>& gid2index)
00375 {
00376
00377 borderlinks.clear();
00378 extraDOFs = 0;
00379 gid2index.clear();
00380
00381
00382 Iterator eendit = gridView.template end<0>();
00383 for (Iterator it = gridView.template begin<0>(); it!=eendit; ++it)
00384 {
00385 Dune::GeometryType gt = it->type();
00386 const typename Dune::ReferenceElementContainer<DT,n>::value_type&
00387 refelem = ReferenceElements<DT,n>::general(gt);
00388
00389
00390 if (it->partitionType()==InteriorEntity)
00391 for (int i=0; i<refelem.size(n); i++)
00392 if (it->template entity<n>(i)->partitionType()==BorderEntity)
00393 {
00394 int alpha = vertexmapper.template map<n>(*it,i);
00395 GIDSet& myset = borderlinks[alpha];
00396 for (int j=0; j<refelem.size(n); j++)
00397 if (i!=j)
00398 {
00399 IdType beta = grid.globalIdSet().template subId<n>(*it,j);
00400 myset.insert(beta);
00401
00402
00403
00404
00405
00406 }
00407 }
00408 }
00409
00410
00411 BorderLinksExchange datahandle(grid,borderlinks,vertexmapper);
00412 lc.template communicate<BorderLinksExchange>(datahandle,
00413 InteriorBorder_InteriorBorder_Interface,
00414 ForwardCommunication);
00415
00416
00417 for (typename std::map<int,GIDSet>::iterator i=borderlinks.begin(); i!=borderlinks.end(); ++i)
00418 for (typename GIDSet::iterator j=(i->second).begin(); j!=(i->second).end(); ++j)
00419 gid2index[*j] = -1;
00420
00421
00422 VIterator vendit = gridView.template end<n>();
00423 for (VIterator it = gridView.template begin<n>(); it!=gridView.template end<n>(); ++it)
00424 {
00425 IdType beta = grid.globalIdSet().id(*it);
00426 if (gid2index.find(beta)!=gid2index.end())
00427 {
00428 int alpha = vertexmapper.map(*it);
00429 gid2index[beta] = alpha;
00430 }
00431 }
00432
00433
00434 extraDOFs = 0;
00435 for (typename std::map<IdType,int>::iterator i=gid2index.begin(); i!=gid2index.end(); ++i)
00436 if (i->second==-1)
00437 {
00438 i->second = vertexmapper.size()+extraDOFs;
00439 extraDOFs++;
00440 }
00441
00442
00443
00444
00445
00446 }
00447
00448 P1ExtendOverlap (LC lcomm)
00449 : lc(lcomm)
00450 {}
00451
00452 private:
00453 LC lc;
00454 };
00455
00456
00457 template<class G, class RT> class P1FunctionManager;
00458
00459
00461
00472 template<class GV, class RT, class LC, int m=1>
00473 class P1Function
00474 : virtual public GridFunctionGlobalEvalDefault<GV,RT,m>
00475 , virtual public FunctionDefault<typename GV::Grid::ctype,RT,GV::Grid::dimension,m>
00476 , virtual public ElementwiseCInfinityFunction<typename GV::Grid,RT,m>
00477 , virtual public H1Function<typename GV::Grid::ctype,RT,GV::Grid::dimension,m>
00478 , virtual public C0GridFunction<typename GV::Grid,RT,m>
00479 {
00481 typedef typename GV::Grid G;
00482
00484 typedef typename G::ctype DT;
00485
00487 enum {n=G::dimension};
00488
00490 typedef typename G::template Codim<0>::Entity Entity;
00491
00493 template<int dim>
00494 struct P1Layout
00495 {
00496 bool contains (Dune::GeometryType gt)
00497 {
00498 return gt.dim() == 0;
00499 }
00500 };
00501
00503 P1Function (const P1Function&);
00504
00505
00506 typedef typename G::Traits::GlobalIdSet IDS;
00507 typedef typename IDS::IdType IdType;
00508 typedef std::set<IdType> GIDSet;
00509 typedef typename GV::IndexSet IS;
00510
00511 public:
00512 typedef GV GridView;
00513 typedef IS IndexSet;
00514 typedef G Grid;
00515 typedef FieldVector<RT,m> BlockType;
00516 typedef BlockVector<BlockType> RepresentationType;
00517 typedef MultipleCodimMultipleGeomTypeMapper<G,IS,P1Layout> VM;
00518 typedef typename P1ExtendOverlap<G,GV,VM,LC>::P1IndexInfoFromGrid P1IndexInfoFromGrid;
00519
00521 P1Function (const GV& gridView, LC lcomm, bool extendoverlap=false)
00522 : GridFunctionGlobalEvalDefault<GV,RT,m>(gridView)
00523 , gv(gridView), mapper_(gridView.grid(),gridView.indexSet()), lc(lcomm), oldcoeff(0)
00524 {
00525
00526 if (extendoverlap && gv.grid().overlapSize(0)>0)
00527 DUNE_THROW(GridError,"P1Function: extending overlap requires nonoverlapping grid");
00528
00529
00530 extraDOFs = 0;
00531 extendOverlap = extendoverlap;
00532
00533
00534 if (extendoverlap)
00535 {
00536
00537 std::map<int,GIDSet> borderlinks;
00538 std::map<IdType,int> gid2index;
00539
00540
00541 P1ExtendOverlap<G,GV,VM,LC> extender(lc);
00542 extender.extend(gv.grid(),gv,mapper_,borderlinks,extraDOFs,gid2index);
00543 }
00544
00545
00546 oldcoeff = 0;
00547 try {
00548 coeff = new RepresentationType(mapper_.size()+extraDOFs);
00549 }
00550 catch (std::bad_alloc) {
00551 std::cerr << "not enough memory in P1Function" << std::endl;
00552 throw;
00553 }
00554 dverb << "making FE function with " << mapper_.size()+extraDOFs << " components"
00555 << "(" << extraDOFs << " extra degrees of freedom)" << std::endl;
00556 }
00557
00559 ~P1Function ()
00560 {
00561 delete coeff;
00562 if (oldcoeff!=0) delete oldcoeff;
00563 }
00564
00566
00573 virtual RT derivative (int comp, const Dune::FieldVector<int,n>& d, const Dune::FieldVector<DT,n>& x) const
00574 {
00575 DUNE_THROW(NotImplemented, "global derivative not implemented yet");
00576 }
00577
00579
00582 virtual int order () const
00583 {
00584 return 1;
00585 }
00586
00588
00594 virtual RT evallocal (int comp, const Entity& e, const Dune::FieldVector<DT,n>& xi) const
00595 {
00596 RT value=0;
00597 Dune::GeometryType gt = e.type();
00598 for (int i=0; i<Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1).size(); ++i)
00599 value += Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1)[i].evaluateFunction(0,xi)*(*coeff)[mapper_.template map<n>(e,i)][comp];
00600 return value;
00601 }
00602
00604
00609 virtual void evalalllocal (const Entity& e, const Dune::FieldVector<DT,G::dimension>& xi,
00610 Dune::FieldVector<RT,m>& y) const
00611 {
00612 Dune::GeometryType gt = e.type();
00613 y = 0;
00614 for (int i=0; i<Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1).size(); ++i)
00615 {
00616 RT basefuncvalue=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1)[i].evaluateFunction(0,xi);
00617 int index = mapper_.template map<n>(e,i);
00618 for (int c=0; c<m; c++)
00619 y[c] += basefuncvalue * (*coeff)[index][c];
00620 }
00621 }
00622
00624
00632 virtual RT derivativelocal (int comp, const Dune::FieldVector<int,n>& d,
00633 const Entity& e, const Dune::FieldVector<DT,n>& xi) const
00634 {
00635 int dir=-1;
00636 int order=0;
00637 for (int i=0; i<n; i++)
00638 {
00639 order += d[i];
00640 if (d[i]>0) dir=i;
00641 }
00642 assert(dir != -1);
00643 if (order!=1) DUNE_THROW(GridError,"can only evaluate one derivative");
00644
00645 RT value=0;
00646 Dune::GeometryType gt = e.type();
00647 const typename Dune::LagrangeShapeFunctionSetContainer<DT,RT,n>::value_type&
00648 sfs=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1);
00649 Dune::FieldMatrix<DT,n,n> jac = e.geometry().jacobianInverseTransposed(xi);
00650 for (int i=0; i<sfs.size(); ++i)
00651 {
00652 Dune::FieldVector<DT,n> grad(0),temp;
00653 for (int l=0; l<n; l++)
00654 temp[l] = sfs[i].evaluateDerivative(0,l,xi);
00655 jac.umv(temp,grad);
00656 value += grad[dir] * (*coeff)[mapper_.template map<n>(e,i)][comp];
00657 }
00658 return value;
00659 }
00660
00661
00663
00669 void interpolate (const C0GridFunction<G,RT,m>& u)
00670 {
00671 typedef typename GV::template Codim<0>::template Partition<All_Partition>::Iterator Iterator;
00672 std::vector<bool> visited(mapper_.size());
00673 for (int i=0; i<mapper_.size(); i++) visited[i] = false;
00674
00675 Iterator eendit = gv.template end<0,All_Partition>();
00676 for (Iterator it = gv.template begin<0,All_Partition>(); it!=eendit; ++it)
00677 {
00678 Dune::GeometryType gt = it->type();
00679 for (int i=0; i<Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1).size(); ++i)
00680 if (!visited[mapper_.template map<n>(*it,i)])
00681 {
00682 for (int c=0; c<m; c++)
00683 (*coeff)[mapper_.template map<n>(*it,i)][c] =
00684 u.evallocal(c,*it,Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1)[i].position());
00685 visited[mapper_.template map<n>(*it,i)] = true;
00686 }
00687 }
00688 }
00689
00691 void interpolate (const P0Function<GV,RT,m>& u)
00692 {
00693 typedef typename GV::template Codim<0>::Iterator Iterator;
00694 std::vector<char> counter(mapper_.size());
00695 for (int i=0; i<mapper_.size(); i++) counter[i] = 0;
00696
00697 for (int i=0; i<(*coeff).size(); i++)
00698 (*coeff)[i] = 0;
00699 Iterator eendit = gv.template end<0>();
00700 for (Iterator it = gv.template begin<0>(); it!=eendit; ++it)
00701 {
00702 Dune::GeometryType gt = it->type();
00703 for (int i=0; i<Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1).size(); ++i)
00704 {
00705 for (int c=0; c<m; c++)
00706 (*coeff)[mapper_.template map<n>(*it,i)][c] +=
00707 u.evallocal(c,*it,Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1)[i].position());
00708 counter[mapper_.template map<n>(*it,i)] += 1;
00709 }
00710 }
00711 for (int i=0; i<counter.size(); i++)
00712 for (int c=0; c<m; c++)
00713 (*coeff)[i][c] /= counter[i];
00714 }
00715
00717
00721 const RepresentationType& operator* () const
00722 {
00723 return (*coeff);
00724 }
00725
00727
00731 RepresentationType& operator* ()
00732 {
00733 return (*coeff);
00734 }
00735
00736
00738 void fillIndexInfoFromGrid (P1IndexInfoFromGrid& info)
00739 {
00740 P1ExtendOverlap<G,GV,VM,LC> extender(lc);
00741 extender.fillIndexInfoFromGrid(gv.grid(),gv,mapper_,info);
00742 }
00743
00744
00749 void preAdapt ()
00750 {
00751 }
00752
00761 void postAdapt (P1FunctionManager<G,RT>& manager)
00762 {
00763 typedef typename G::template Codim<n>::LeafIterator VLeafIterator;
00764 typedef typename G::template Codim<0>::LeafIterator ELeafIterator;
00765 typedef typename G::template Codim<n>::LevelIterator VLevelIterator;
00766 typedef typename G::template Codim<0>::LevelIterator ELevelIterator;
00767 typedef typename G::template Codim<0>::EntityPointer EEntityPointer;
00768
00769
00770
00771 oldcoeff = coeff;
00772
00773
00774 mapper_.update();
00775
00776
00777 if (extendOverlap)
00778 {
00779
00780 std::map<int,GIDSet> borderlinks;
00781 std::map<IdType,int> gid2index;
00782 extraDOFs = 0;
00783
00784
00785 P1ExtendOverlap<G,GV,VM,LC> extender(lc);
00786 extender.extend(gv.grid(),gv,mapper_,borderlinks,extraDOFs,gid2index);
00787 }
00788
00789
00790 try {
00791 coeff = new RepresentationType(mapper_.size()+extraDOFs);
00792 }
00793 catch (std::bad_alloc) {
00794 std::cerr << "not enough memory in P1Function update" << std::endl;
00795 throw;
00796 }
00797 std::cout << "P1 function enlarged to " << mapper_.size() << " components" << std::endl;
00798
00799
00800 std::vector<bool> visited(mapper_.size());
00801 for (int i=0; i<mapper_.size(); i++) visited[i] = false;
00802
00803
00804 VLeafIterator veendit = gv.grid().template leafend<n>();
00805 for (VLeafIterator it = gv.grid().template leafbegin<n>(); it!=veendit; ++it)
00806 {
00807
00808 int i;
00809 if (manager.savedMap().contains(*it,i))
00810 {
00811
00812
00813
00814
00815
00816
00817 for (int c=0; c<m; c++)
00818 (*coeff)[mapper_.map(*it)][c] = (*oldcoeff)[manager.oldIndex()[i]][c];
00819
00820 visited[mapper_.map(*it)] = true;
00821 }
00822 }
00823
00824
00825
00826 for (int level=1; level<=gv.grid().maxLevel(); ++level)
00827 {
00828 ELevelIterator elendit = gv.grid().template lend<0>(level);
00829 for (ELevelIterator it = gv.grid().template lbegin<0>(level); it!=elendit; ++it)
00830 {
00831 GeometryType gte = it->type();
00832 for (int i=0; i<Dune::LagrangeShapeFunctions<DT,RT,n>::general(gte,1).size(); ++i)
00833 {
00834 int index = mapper_.template map<n>(*it,i);
00835 if (!visited[index])
00836 {
00837
00838 EEntityPointer father=it->father();
00839 GeometryType gtf = father->type();
00840 const FieldVector<DT,n>& cpos=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gte,1)[i].position();
00841 FieldVector<DT,n> pos = it->geometryInFather().global(cpos);
00842 for (int c=0; c<m; c++)
00843 (*coeff)[index][c] = 0;
00844 for (int j=0; j<Dune::LagrangeShapeFunctions<DT,RT,n>::general(gtf,1).size(); ++j)
00845 {
00846 RT basefuncvalue = Dune::LagrangeShapeFunctions<DT,RT,n>::general(gtf,1)[j].evaluateFunction(0,pos);
00847 for (int c=0; c<m; c++)
00848 (*coeff)[index][c] += basefuncvalue * (*coeff)[mapper_.template map<n>(*father,j)][c];
00849
00850
00851
00852
00853 }
00854
00855 visited[index] = true;
00856 }
00857 }
00858 }
00859 }
00860
00861
00862 if (oldcoeff!=0) delete oldcoeff;
00863 oldcoeff = 0;
00864 }
00865
00868 const VM& mapper () const
00869 {
00870 return mapper_;
00871 }
00872
00875 const GV& gridview () const
00876 {
00877 return gv;
00878 }
00879
00881 void vtkout (VTKWriter<GV>& vtkwriter, std::string s) const
00882 {
00883 typename VTKWriter<GV>::VTKFunction *p = new VTKGridFunctionWrapper<GV,RT,m>(*this,s);
00884 vtkwriter.addVertexData(p);
00885 }
00886
00887 private:
00888
00889
00890 const GV gv;
00891
00892
00893 VM mapper_;
00894
00895
00896 LC lc;
00897
00898
00899 int extraDOFs;
00900 bool extendOverlap;
00901
00902
00903 RepresentationType* coeff;
00904
00905
00906 RepresentationType* oldcoeff;
00907 };
00908
00909
00916 template<class G, class RT, int m=1>
00917 class LeafP1Function : public P1Function<typename G::LeafGridView,RT,LeafCommunicate<G>,m>
00918 {
00919 public:
00923 LeafP1Function (const G& grid, bool extendoverlap=false)
00924 : GridFunctionGlobalEvalDefault<typename G::LeafGridView,RT,m>(grid.leafView())
00925 , P1Function<typename G::LeafGridView,RT,LeafCommunicate<G>,m>(grid.leafView(),LeafCommunicate<G>(grid),extendoverlap)
00926 {}
00927 };
00928
00929
00936 template<class G, class RT, int m=1>
00937 class LevelP1Function : public P1Function<typename G::LevelGridView,RT,LevelCommunicate<G>,m>
00938 {
00939 public:
00943 LevelP1Function (const G& grid, int level, bool extendoverlap=false)
00944 : GridFunctionGlobalEvalDefault<typename G::LevelGridView,RT,m>(grid.levelView(level))
00945 , P1Function<typename G::LevelGridView,RT,LevelCommunicate<G>,m>(grid.levelView(level),LevelCommunicate<G>(grid,level),extendoverlap)
00946 {}
00947 };
00948
00949
00959 template<class G, class RT>
00960 class P1FunctionManager {
00961 enum {dim=G::dimension};
00962 typedef typename G::ctype DT;
00963 typedef typename G::template Codim<dim>::LeafIterator VLeafIterator;
00964 typedef typename G::template Codim<0>::EntityPointer EEntityPointer;
00965
00966 template<int dim>
00967 struct P1Layout
00968 {
00969 bool contains (Dune::GeometryType gt)
00970 {
00971 return gt.dim() == 0;
00972 }
00973 };
00974
00975 public:
00976
00978 P1FunctionManager (const G& g) : mapper(g,g.leafIndexSet()), grid(g), savedmap(g)
00979 {
00980
00981 oldindex.resize(mapper.size());
00982
00983
00984 savedmap.clear();
00985
00986
00987 VLeafIterator veendit = grid.template leafend<dim>();
00988 for (VLeafIterator it = grid.template leafbegin<dim>(); it!=veendit; ++it)
00989 {
00990 oldindex[savedmap.map(*it)] = mapper.map(*it);
00991 }
00992 }
00993
00994 const GlobalUniversalMapper<G>& savedMap ()
00995 {
00996 return savedmap;
00997 }
00998
00999 const std::vector<int>& oldIndex ()
01000 {
01001 return oldindex;
01002 }
01003
01004 private:
01005
01006 MultipleCodimMultipleGeomTypeMapper<G,typename G::template Codim<0>::LeafIndexSet,P1Layout> mapper;
01007
01008
01009 const G& grid;
01010
01011
01012 GlobalUniversalMapper<G> savedmap;
01013
01014
01015 std::vector<int> oldindex;
01016 };
01017
01018
01021 }
01022 #endif