dune-grid  2.2.0
boundaryiterators.hh
Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set et ts=8 sw=2 sts=2:
00003 
00004 #ifndef DUNE_GRID_IO_FILE_VTK_BOUNDARYITERATORS_HH
00005 #define DUNE_GRID_IO_FILE_VTK_BOUNDARYITERATORS_HH
00006 
00007 #include <iterator>
00008 
00009 #include <dune/common/iteratorfacades.hh>
00010 #include <dune/common/shared_ptr.hh>
00011 
00012 #include <dune/grid/io/file/vtk/corner.hh>
00013 #include <dune/grid/io/file/vtk/corneriterator.hh>
00014 #include <dune/grid/io/file/vtk/functionwriter.hh>
00015 
00016 namespace Dune {
00017 
00020 
00026   namespace VTK {
00027 
00029 
00033     template<typename GV>
00034     class BoundaryIterator
00035       : public ForwardIteratorFacade
00036         < BoundaryIterator<GV>,
00037           const typename GV::Intersection,
00038           const typename GV::Intersection&,
00039           typename std::iterator_traits<typename GV::template Codim<0>::
00040                                         Iterator>::difference_type>
00041     {
00042     public:
00043       // reiterator the facades typedefs here
00044       typedef BoundaryIterator<GV> DerivedType;
00045       typedef const typename GV::Intersection Value;
00046       typedef Value& Reference;
00047       typedef typename GV::template Codim<0>::Iterator ElementIterator;
00048       typedef typename GV::IntersectionIterator IntersectionIterator;
00049       typedef typename std::iterator_traits<ElementIterator>::difference_type
00050               DifferenceType;
00051 
00052     private:
00053       typedef ForwardIteratorFacade<DerivedType, Value, Reference,
00054                                     DifferenceType> Facade;
00055 
00056       const GV* gv;
00057       ElementIterator eit;
00058       shared_ptr<IntersectionIterator> iit;
00059 
00060       bool valid() const {
00061         // we're valid if we're passed-the-end
00062         if(eit == gv->template end<0>()) return true;
00063         // or if we're on a boundary
00064         if((*iit)->boundary() && !(*iit)->neighbor()) return true;
00065         // otherwise we're invalid
00066         return false;
00067       }
00068 
00069       void basic_increment() {
00070         ++*iit;
00071         if(*iit == gv->iend(*eit)) {
00072           iit.reset();
00073           ++eit;
00074           if(eit != gv->template end<0>())
00075             iit.reset(new IntersectionIterator(gv->ibegin(*eit)));
00076         }
00077       }
00078 
00079     public:
00080       Reference dereference() const {
00081         return **iit;
00082       }
00083       bool equals(const DerivedType& other) const {
00084         if(eit != other.eit) return false;
00085 
00086         // this is a bit tricky, since we may not compare iit if we are
00087         // passed-the-end
00088         bool mePassedTheEnd = eit == gv->template end<0>();
00089         bool otherPassedTheEnd = other.eit == other.gv->template end<0>();
00090 
00091         // both passed-the-end => consider them equal
00092         if(mePassedTheEnd && otherPassedTheEnd) return true;
00093 
00094         // one passed the end => not equal
00095         if(mePassedTheEnd || otherPassedTheEnd) return false;
00096 
00097         // none passed-the-end => do their iit iterators match?
00098         return *iit == *other.iit;
00099       }
00100 
00101       void increment() {
00102         basic_increment();
00103         while(!valid()) basic_increment();
00104       }
00105 
00107 
00111       BoundaryIterator(const GV& gv_, const ElementIterator& eit_,
00112                        const IntersectionIterator& iit_)
00113         : gv(&gv_), eit(eit_), iit(new IntersectionIterator(iit_))
00114       {
00115         while(!valid()) basic_increment();
00116       }
00118 
00123       BoundaryIterator(const GV& gv_, const ElementIterator& eit_)
00124         : gv(&gv_), eit(eit_)
00125       {
00126         if(eit != gv->template end<0>())
00127           iit.reset(new IntersectionIterator(gv->ibegin(*eit)));
00128 
00129         while(!valid()) basic_increment();
00130       }
00132 
00136       BoundaryIterator(const GV& gv_, bool end = false)
00137         : gv(&gv_), eit(end ? gv->template end<0>() : gv->template begin<0>())
00138       {
00139         if(eit != gv->template end<0>())
00140           iit.reset(new IntersectionIterator(gv->ibegin(*eit)));
00141 
00142         while(!valid()) basic_increment();
00143       }
00144     };
00145 
00146     template<typename ElementIndexSet>
00147     class IntersectionIndexSet {
00148       const ElementIndexSet& eis;
00149 
00150     public:
00151       IntersectionIndexSet(const ElementIndexSet& eis_)
00152         : eis(eis)
00153       { }
00154     };
00155 
00156     template<typename GV>
00157     class NonConformingBoundaryIteratorFactory {
00158       const GV& gv;
00159 
00160     public:
00161       static const unsigned dimCell = GV::dimension-1;
00162 
00163       typedef typename GV::Intersection Cell;
00164       typedef BoundaryIterator<GV> CellIterator;
00165 
00166       typedef VTK::Corner<Cell> Corner;
00167       typedef VTK::CornerIterator<CellIterator> CornerIterator;
00168 
00169       typedef Corner Point;
00170       typedef CornerIterator PointIterator;
00171 
00172       typedef NonConformingConnectivityWriter<Cell> ConnectivityWriter;
00173       typedef typename GV::CollectiveCommunication CollectiveCommunication;
00174 
00175       explicit NonConformingBoundaryIteratorFactory(const GV& gv_)
00176         : gv(gv_)
00177       { }
00178 
00179       CellIterator beginCells() const {
00180         return CellIterator(gv);
00181       }
00182       CellIterator endCells() const {
00183         return CellIterator(gv, true);
00184       }
00185 
00186       CornerIterator beginCorners() const {
00187         return CornerIterator(beginCells(), endCells());
00188       }
00189       CornerIterator endCorners() const {
00190         return CornerIterator(endCells());
00191       }
00192 
00193       PointIterator beginPoints() const { return beginCorners(); }
00194       PointIterator endPoints() const { return endCorners(); }
00195 
00196       ConnectivityWriter makeConnectivity() const {
00197         return ConnectivityWriter();
00198       }
00199       const CollectiveCommunication& comm() const {
00200         return gv.comm();
00201       }
00202     };
00203 
00204   } // namespace VTK
00205 
00207 
00208 } // namespace Dune
00209 
00210 #endif // DUNE_GRID_IO_FILE_VTK_BOUNDARYITERATORS_HH