utility/gridinfo.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_UTILITY_GRIDINFO_HH
00005 #define DUNE_GRID_UTILITY_GRIDINFO_HH
00006 
00007 #include <algorithm>
00008 #include <cstddef>
00009 #include <functional>
00010 #include <limits>
00011 #include <map>
00012 #include <ostream>
00013 #include <string>
00014 #include <vector>
00015 
00016 #include <dune/common/classname.hh>
00017 #include <dune/common/exceptions.hh>
00018 #include <dune/common/forloop.hh>
00019 #include <dune/common/fvector.hh>
00020 #include <dune/common/geometrytype.hh>
00021 
00022 #include <dune/grid/common/genericreferenceelements.hh>
00023 #include <dune/grid/utility/mockgeometry.hh>
00024 
00025 namespace Dune {
00026 
00028   template<class ctype>
00029   struct EntityInfo {
00031     std::size_t count;
00033 
00038     ctype volumeMin;
00040 
00045     ctype volumeMax;
00046 
00048 
00053     EntityInfo() :
00054       count(0), volumeMin(std::numeric_limits<ctype>::infinity()),
00055       volumeMax(-std::numeric_limits<ctype>::infinity())
00056     { }
00057   };
00058 
00060 
00066   struct GridViewInfoGTCompare :
00067     public std::binary_function<GeometryType, GeometryType, bool>
00068   {
00070     inline bool operator()(const GeometryType &a, const GeometryType &b) const
00071     {
00072       return a.dim() < b.dim() ||
00073         (a.dim() == b.dim() && (a.isNone() < b.isNone() ||
00074           (a.isNone() == b.isNone() && (a.id() >> 1) < (b.id() >> 1))));
00075       // topologyId is set to 0 for None, so no harm im comparing them even if
00076       // isNone()==true
00077     }
00078   };
00079 
00081 
00086   template<class ctype>
00087   struct GridViewInfo :
00088     public std::map<GeometryType, EntityInfo<ctype>, GridViewInfoGTCompare>
00089   {
00091     std::string gridName;
00093     std::string gridViewName;
00095 
00099     std::string partitionName;
00100 
00102 
00115     void print(std::ostream &stream, std::string prefix) const {
00116       if(!gridName.empty()) {
00117         stream << prefix << gridName << ":\n";
00118         prefix += "  ";
00119       }
00120       if(!gridViewName.empty()) {
00121         stream << prefix << gridViewName << ":\n";
00122         prefix += "  ";
00123       }
00124       if(!partitionName.empty()) {
00125         stream << prefix << partitionName << ":\n";
00126         prefix += "  ";
00127       }
00128 
00129       typedef typename GridViewInfo::const_iterator Iterator;
00130       std::size_t dim = ~0;
00131       const Iterator &end = this->end();
00132       for(Iterator it = this->begin(); it != end; ++it) {
00133         if(it->first.dim() != dim) {
00134           dim = it->first.dim();
00135           stream << prefix << "Dim = " << dim << ":\n";
00136         }
00137         stream << prefix << "  " << it->first << ": Count = "
00138                << it->second.count << ", Volume range = "
00139                << "(" << it->second.volumeMin << ".."
00140                << it->second.volumeMax << ")\n";
00141       }
00142     }
00143   };
00144 
00146 
00151   template<class ctype>
00152   std::ostream &operator<<(std::ostream &stream,
00153                            const GridViewInfo<ctype> &info)
00154   {
00155     info.print(stream, "");
00156     return stream;
00157   }
00158 
00159 #ifndef DOXYGEN
00160 
00161   template<int codim>
00162   struct FillGridInfoOperation {
00163     template<class Geometry, class RefElem>
00164     static void apply(const Geometry &geo, const RefElem &refelem,
00165                       GridViewInfo<typename Geometry::ctype> &gridViewInfo)
00166     {
00167       typedef typename Geometry::ctype ctype;
00168       static const std::size_t dimw = Geometry::coorddimension;
00169       static const std::size_t dim = Geometry::mydimension;
00170       std::vector<FieldVector<ctype, dimw> > coords;
00171       for(int i = 0; i < refelem.size(codim); ++i) {
00172         GeometryType gt = refelem.type(i, codim);
00173         coords.clear();
00174         coords.resize( refelem.size(i, codim, dim) );
00175         for(std::size_t corner = 0; corner < coords.size(); ++corner)
00176           coords[ corner ] = geo.corner( refelem.subEntity( i, codim, corner, dim ) );
00177         MockGeometry<ctype, dim-codim, dimw> mygeo(gt, coords);
00178 
00179         ctype volume = mygeo.volume();
00180         EntityInfo<ctype> &ei = gridViewInfo[mygeo.type()];
00181         ei.volumeMin = std::min(ei.volumeMin, volume);
00182         ei.volumeMax = std::max(ei.volumeMax, volume);
00183       }
00184     }
00185   };
00186 #endif // !DOXYGEN
00187 
00189 
00193   template<class GV>
00194   void fillGridViewInfoSerial(const GV &gv,
00195                               GridViewInfo<typename GV::ctype> &gridViewInfo)
00196   {
00197     typedef typename GV::ctype ctype;
00198     static const std::size_t dim = GV::dimension;
00199     typedef typename GV::template Codim<0>::Iterator EIterator;
00200     typedef typename GV::IntersectionIterator IIterator;
00201     typedef typename GV::IndexSet IndexSet;
00202 
00203     typedef typename GridViewInfo<ctype>::iterator InfoIterator;
00204 
00205     typedef GenericReferenceElements<ctype, dim> RefElems;
00206 
00207     gridViewInfo.gridName = className<typename GV::Grid>();
00208     gridViewInfo.gridViewName = className<GV>();
00209     gridViewInfo.partitionName = "";
00210     gridViewInfo.clear();
00211 
00212     const EIterator &eend = gv.template end<0>();
00213     for(EIterator eit = gv.template begin<0>(); eit != eend; ++eit) {
00214       ctype volume = eit->geometry().volume();
00215       EntityInfo<ctype> &ei = gridViewInfo[eit->type()];
00216       ei.volumeMin = std::min(ei.volumeMin, volume);
00217       ei.volumeMax = std::max(ei.volumeMax, volume);
00218 
00219       if(!eit->type().isNone())
00220         ForLoop<FillGridInfoOperation, 1, dim>::
00221           apply(eit->geometry(), RefElems::general(eit->type()), gridViewInfo);
00222     }
00223 
00224     GeometryType gt;
00225     gt.makeNone(dim);
00226     if(gridViewInfo.count(gt) > 0) {
00227       for(std::size_t codim = 0; codim < dim; ++codim) {
00228         gt.makeNone(dim-codim);
00229         EntityInfo<ctype> & ei = gridViewInfo[gt];
00230         ei.volumeMin = ei.volumeMax = std::numeric_limits<ctype>::quiet_NaN();
00231       }
00232       gt.makeNone(0);
00233       EntityInfo<ctype> & ei = gridViewInfo[gt];
00234       ei.volumeMin = ei.volumeMax = 0;
00235     }
00236 
00237     const InfoIterator &end = gridViewInfo.end();
00238     const IndexSet &is = gv.indexSet();
00239     for(InfoIterator it = gridViewInfo.begin(); it != end; ++it) {
00240       it->second.count = is.size(it->first);
00241       if(it->second.count == 0)
00242         DUNE_THROW(Exception, "Found Entities of geomentry type " <<
00243                    it->first << " while iterating through the grid, but "
00244                    "indexSet.size() == 0 for that geometry type");
00245     }
00246 
00247   }
00248 
00249 } // namespace Dune
00250 
00251 
00252 #endif // DUNE_GRID_UTILITY_GRIDINFO_HH

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].