dune-grid  2.2.0
functionwriter.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_FUNCTIONWRITER_HH
00005 #define DUNE_GRID_IO_FILE_VTK_FUNCTIONWRITER_HH
00006 
00007 #include <cstddef>
00008 #include <string>
00009 #include <typeinfo>
00010 #include <vector>
00011 
00012 #include <dune/common/exceptions.hh>
00013 #include <dune/common/fvector.hh>
00014 #include <dune/common/shared_ptr.hh>
00015 
00016 #include <dune/geometry/referenceelements.hh>
00017 
00018 #include <dune/grid/io/file/vtk/common.hh>
00019 #include <dune/grid/io/file/vtk/dataarraywriter.hh>
00020 #include <dune/grid/io/file/vtk/pvtuwriter.hh>
00021 #include <dune/grid/io/file/vtk/vtuwriter.hh>
00022 
00023 namespace Dune
00024 {
00027 
00028   namespace VTK {
00029 
00031     template<typename Cell_>
00032     class FunctionWriterBase {
00033       typedef typename Cell_::ctype DF;
00034       static const unsigned mydim = Cell_::mydimension;
00035       typedef GenericReferenceElements<DF, mydim> Refelems;
00036 
00037     public:
00038       typedef FieldVector<DF, mydim> Domain;
00039       typedef Cell_ Cell;
00040 
00042       virtual std::string name() const = 0;
00043 
00045       virtual unsigned ncomps() const = 0;
00046 
00048       virtual void addArray(PVTUWriter& writer) = 0;
00050       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) = 0;
00052 
00057       virtual void write(const Cell& cell, const Domain& xl) {
00058         DUNE_THROW(NotImplemented, "FunctionWriterBase::write(const Cell&, "
00059                    "const Domain&): Either the derived class " <<
00060                    typeid(*this).name() << " failed to implement this method "
00061                    "or this method is not meant to be called on the derived "
00062                    "class and was called in error.");
00063       };
00065 
00069       virtual void write(const Cell& cell, unsigned cornerIndex) {
00070         write(cell,
00071               Refelems::general(cell.type()).position(cornerIndex, mydim));
00072       }
00074       virtual void endWrite() = 0;
00076       virtual ~FunctionWriterBase() {};
00077     };
00078 
00080     //
00081     //  A Generic Function writer for VTKFunctions
00082     //
00083 
00085     template<typename Func>
00086     class VTKFunctionWriter
00087       : public FunctionWriterBase<typename Func::Entity>
00088     {
00089       typedef FunctionWriterBase<typename Func::Entity> Base;
00090       shared_ptr<const Func> func;
00091       shared_ptr<DataArrayWriter<float> > arraywriter;
00092 
00093     public:
00094       VTKFunctionWriter(const shared_ptr<const Func>& func_)
00095         : func(func_)
00096       { }
00097 
00099       virtual std::string name() const { return func->name(); }
00100 
00102       virtual unsigned ncomps() const {
00103         if(func->ncomps() == 2) return 3;
00104         else return func->ncomps();
00105       }
00106 
00108       virtual void addArray(PVTUWriter& writer) {
00109         writer.addArray<float>(name(), ncomps());
00110       }
00111 
00113       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00114         arraywriter.reset(writer.makeArrayWriter<float>(name(), ncomps(),
00115                                                         nitems));
00116         return !arraywriter->writeIsNoop();
00117       }
00118 
00120       virtual void write(const typename Base::Cell& cell,
00121                          const typename Base::Domain& xl) {
00122         for(int d = 0; d < func->ncomps(); ++d)
00123           arraywriter->write(func->evaluate(d, cell, xl));
00124         for(unsigned d = func->ncomps(); d < ncomps(); ++d)
00125           arraywriter->write(0);
00126       }
00127 
00129       virtual void endWrite() {
00130         arraywriter.reset();
00131       }
00132     };
00133 
00135     //
00136     //  Writers for the grid information
00137     //
00138 
00140     template<typename Cell>
00141     class CoordinatesWriter
00142       : public FunctionWriterBase<Cell>
00143     {
00144       typedef FunctionWriterBase<Cell> Base;
00145 
00146       shared_ptr<DataArrayWriter<float> > arraywriter;
00147 
00148     public:
00149 
00151       virtual std::string name() const { return "Coordinates"; }
00152 
00154       virtual unsigned ncomps() const { return 3; }
00155 
00157       virtual void addArray(PVTUWriter& writer) {
00158         writer.addArray<float>(name(), ncomps());
00159       }
00160 
00162       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00163         arraywriter.reset(writer.makeArrayWriter<float>(name(), ncomps(),
00164                                                         nitems));
00165         return !arraywriter->writeIsNoop();
00166       }
00168       virtual void write(const typename Base::Cell& cell,
00169                          const typename Base::Domain& xl) {
00170         FieldVector<typename Base::Cell::ctype, Base::Cell::dimensionworld> xg
00171           = cell.geometry().global(xl);
00172         for(unsigned d = 0; d < 3 && d < Base::Cell::dimensionworld; ++d)
00173           arraywriter->write(xg[d]);
00174         for(unsigned d = Base::Cell::dimensionworld; d < 3; ++d)
00175           arraywriter->write(0);
00176       };
00178       virtual void endWrite() {
00179         arraywriter.reset();
00180       }
00181     };
00182 
00184     template<typename IteratorFactory>
00185     class ConformingConnectivityWriter
00186       : public FunctionWriterBase<typename IteratorFactory::Cell>
00187     {
00188       typedef FunctionWriterBase<typename IteratorFactory::Cell> Base;
00189       static const unsigned mydim = Base::Cell::mydimension;
00190 
00191       const IteratorFactory& factory;
00192       shared_ptr<DataArrayWriter<unsigned> > arraywriter;
00193       std::vector<unsigned> pointIndices;
00194 
00195     public:
00197       ConformingConnectivityWriter(const IteratorFactory& factory_)
00198         : factory(factory_)
00199       { }
00200 
00202       virtual std::string name() const { return "connectivity"; }
00203 
00205       virtual unsigned ncomps() const { return 1; }
00206 
00208       virtual void addArray(PVTUWriter& writer) {
00209         writer.addArray<unsigned>(name(), ncomps());
00210       }
00211 
00213       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00214         arraywriter.reset(writer.makeArrayWriter<unsigned>(name(), ncomps(),
00215                                                            nitems));
00216         if(arraywriter->writeIsNoop())
00217           return false;
00218 
00220         pointIndices.resize(factory.indexSet().size(mydim));
00221         const typename IteratorFactory::PointIterator& pend =
00222           factory.endPoints();
00223         typename IteratorFactory::PointIterator pit = factory.beginPoints();
00224         unsigned counter = 0;
00225         while(pit != pend) {
00226           pointIndices[factory.indexSet().subIndex
00227                        (pit->cell(), pit->duneIndex(), mydim)] = counter;
00228           ++counter;
00229           ++pit;
00230         }
00231         return true;
00232       }
00234       virtual void write(const typename Base::Cell& cell, unsigned cornerIndex)
00235       {
00236         // if pointIndices is empty, we're in writeIsNoop mode
00237         if(pointIndices.size() == 0)
00238           return;
00239         arraywriter->write(pointIndices[factory.indexSet().subIndex
00240                                         (cell, cornerIndex, mydim)]);
00241       }
00243       virtual void endWrite() {
00244         arraywriter.reset();
00245         pointIndices.clear();
00246       }
00247     };
00248 
00250     template<typename Cell>
00251     class NonConformingConnectivityWriter
00252       : public FunctionWriterBase<Cell>
00253     {
00254       shared_ptr<DataArrayWriter<unsigned> > arraywriter;
00255       unsigned counter;
00256 
00257     public:
00259       virtual std::string name() const { return "connectivity"; }
00260 
00262       virtual unsigned ncomps() const { return 1; }
00263 
00265       virtual void addArray(PVTUWriter& writer) {
00266         writer.addArray<unsigned>(name(), ncomps());
00267       }
00268 
00270       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00271         arraywriter.reset(writer.makeArrayWriter<unsigned>(name(), ncomps(),
00272                                                            nitems));
00273         counter = 0;
00274         return !arraywriter->writeIsNoop();
00275       }
00277       virtual void write(const Cell& cell, unsigned cornerIndex)
00278       {
00279         arraywriter->write(counter);
00280         ++counter;
00281       }
00283       virtual void endWrite() {
00284         arraywriter.reset();
00285       }
00286     };
00287 
00289     template<typename Cell>
00290     class OffsetsWriter
00291       : public FunctionWriterBase<Cell>
00292     {
00293       typedef FunctionWriterBase<Cell> Base;
00294 
00295       shared_ptr<DataArrayWriter<unsigned> > arraywriter;
00296       unsigned offset;
00297 
00298     public:
00300       virtual std::string name() const { return "offsets"; }
00301 
00303       virtual unsigned ncomps() const { return 1; }
00304 
00306       virtual void addArray(PVTUWriter& writer) {
00307         writer.addArray<unsigned>(name(), ncomps());
00308       }
00309 
00311       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00312         arraywriter.reset(writer.makeArrayWriter<unsigned>(name(), ncomps(),
00313                                                            nitems));
00314         offset = 0;
00315         return !arraywriter->writeIsNoop();
00316       }
00318       virtual void write(const Cell& cell, const typename Base::Domain&) {
00319         offset += cell.geometry().corners();
00320         arraywriter->write(offset);
00321       };
00323       virtual void endWrite() {
00324         arraywriter.reset();
00325       }
00326     };
00327 
00329     template<typename Cell>
00330     class TypesWriter
00331       : public FunctionWriterBase<Cell>
00332     {
00333       typedef FunctionWriterBase<Cell> Base;
00334 
00335       shared_ptr<DataArrayWriter<unsigned char> > arraywriter;
00336 
00337     public:
00339       virtual std::string name() const { return "types"; }
00340 
00342       virtual unsigned ncomps() const { return 1; }
00343 
00345       virtual void addArray(PVTUWriter& writer) {
00346         writer.addArray<unsigned char>(name(), ncomps());
00347       }
00348 
00350       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00351         arraywriter.reset(writer.makeArrayWriter<unsigned char>
00352                           ( name(), ncomps(), nitems));
00353         return !arraywriter->writeIsNoop();
00354       }
00356       virtual void write(const Cell& cell, const typename Base::Domain&) {
00357         arraywriter->write(geometryType(cell.type()));
00358       };
00360       virtual void endWrite() {
00361         arraywriter.reset();
00362       }
00363     };
00364 
00365   } // namespace VTK
00366 
00368 
00369 } // namespace Dune
00370 
00371 #endif // DUNE_GRID_IO_FILE_VTK_FUNCTIONWRITER_HH