dune-grid  2.1.1
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/grid/common/genericreferenceelements.hh>
00017 #include <dune/grid/io/file/vtk/common.hh>
00018 #include <dune/grid/io/file/vtk/dataarraywriter.hh>
00019 #include <dune/grid/io/file/vtk/pvtuwriter.hh>
00020 #include <dune/grid/io/file/vtk/vtuwriter.hh>
00021 
00022 namespace Dune
00023 {
00026 
00027   namespace VTK {
00028 
00030     template<typename Cell_>
00031     class FunctionWriterBase {
00032       typedef typename Cell_::ctype DF;
00033       static const unsigned mydim = Cell_::mydimension;
00034       typedef GenericReferenceElements<DF, mydim> Refelems;
00035 
00036     public:
00037       typedef FieldVector<DF, mydim> Domain;
00038       typedef Cell_ Cell;
00039 
00041       virtual std::string name() const = 0;
00042 
00044       virtual unsigned ncomps() const = 0;
00045 
00047       virtual void addArray(PVTUWriter& writer) = 0;
00049       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) = 0;
00051 
00056       virtual void write(const Cell& cell, const Domain& xl) {
00057         DUNE_THROW(NotImplemented, "FunctionWriterBase::write(const Cell&, "
00058                    "const Domain&): Either the derived class " <<
00059                    typeid(*this).name() << " failed to implement this method "
00060                    "or this method is not meant to be called on the derived "
00061                    "class and was called in error.");
00062       };
00064 
00068       virtual void write(const Cell& cell, unsigned cornerIndex) {
00069         write(cell,
00070               Refelems::general(cell.type()).position(cornerIndex, mydim));
00071       }
00073       virtual void endWrite() = 0;
00075       virtual ~FunctionWriterBase() {};
00076     };
00077 
00079     //
00080     //  A Generic Function writer for VTKFunctions
00081     //
00082 
00084     template<typename Func>
00085     class VTKFunctionWriter
00086       : public FunctionWriterBase<typename Func::Entity>
00087     {
00088       typedef FunctionWriterBase<typename Func::Entity> Base;
00089       shared_ptr<const Func> func;
00090       shared_ptr<DataArrayWriter<float> > arraywriter;
00091 
00092     public:
00093       VTKFunctionWriter(const shared_ptr<const Func>& func_)
00094         : func(func_)
00095       { }
00096 
00098       virtual std::string name() const { return func->name(); }
00099 
00101       virtual unsigned ncomps() const {
00102         if(func->ncomps() == 2) return 3;
00103         else return func->ncomps();
00104       }
00105 
00107       virtual void addArray(PVTUWriter& writer) {
00108         writer.addArray<float>(name(), ncomps());
00109       }
00110 
00112       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00113         arraywriter.reset(writer.makeArrayWriter<float>(name(), ncomps(),
00114                                                         nitems));
00115         return !arraywriter->writeIsNoop();
00116       }
00117 
00119       virtual void write(const typename Base::Cell& cell,
00120                          const typename Base::Domain& xl) {
00121         for(int d = 0; d < func->ncomps(); ++d)
00122           arraywriter->write(func->evaluate(d, cell, xl));
00123         for(unsigned d = func->ncomps(); d < ncomps(); ++d)
00124           arraywriter->write(0);
00125       }
00126 
00128       virtual void endWrite() {
00129         arraywriter.reset();
00130       }
00131     };
00132 
00134     //
00135     //  Writers for the grid information
00136     //
00137 
00139     template<typename Cell>
00140     class CoordinatesWriter
00141       : public FunctionWriterBase<Cell>
00142     {
00143       typedef FunctionWriterBase<Cell> Base;
00144 
00145       shared_ptr<DataArrayWriter<float> > arraywriter;
00146 
00147     public:
00148 
00150       virtual std::string name() const { return "Coordinates"; }
00151 
00153       virtual unsigned ncomps() const { return 3; }
00154 
00156       virtual void addArray(PVTUWriter& writer) {
00157         writer.addArray<float>(name(), ncomps());
00158       }
00159 
00161       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00162         arraywriter.reset(writer.makeArrayWriter<float>(name(), ncomps(),
00163                                                         nitems));
00164         return !arraywriter->writeIsNoop();
00165       }
00167       virtual void write(const typename Base::Cell& cell,
00168                          const typename Base::Domain& xl) {
00169         FieldVector<typename Base::Cell::ctype, Base::Cell::dimensionworld> xg
00170           = cell.geometry().global(xl);
00171         for(unsigned d = 0; d < 3 && d < Base::Cell::dimensionworld; ++d)
00172           arraywriter->write(xg[d]);
00173         for(unsigned d = Base::Cell::dimensionworld; d < 3; ++d)
00174           arraywriter->write(0);
00175       };
00177       virtual void endWrite() {
00178         arraywriter.reset();
00179       }
00180     };
00181 
00183     template<typename IteratorFactory>
00184     class ConformingConnectivityWriter
00185       : public FunctionWriterBase<typename IteratorFactory::Cell>
00186     {
00187       typedef FunctionWriterBase<typename IteratorFactory::Cell> Base;
00188       static const unsigned mydim = Base::Cell::mydimension;
00189 
00190       const IteratorFactory& factory;
00191       shared_ptr<DataArrayWriter<unsigned> > arraywriter;
00192       std::vector<unsigned> pointIndices;
00193 
00194     public:
00196       ConformingConnectivityWriter(const IteratorFactory& factory_)
00197         : factory(factory_)
00198       { }
00199 
00201       virtual std::string name() const { return "connectivity"; }
00202 
00204       virtual unsigned ncomps() const { return 1; }
00205 
00207       virtual void addArray(PVTUWriter& writer) {
00208         writer.addArray<unsigned>(name(), ncomps());
00209       }
00210 
00212       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00213         arraywriter.reset(writer.makeArrayWriter<unsigned>(name(), ncomps(),
00214                                                            nitems));
00215         if(arraywriter->writeIsNoop())
00216           return false;
00217 
00219         pointIndices.resize(factory.indexSet().size(mydim));
00220         const typename IteratorFactory::PointIterator& pend =
00221           factory.endPoints();
00222         typename IteratorFactory::PointIterator pit = factory.beginPoints();
00223         unsigned counter = 0;
00224         while(pit != pend) {
00225           pointIndices[factory.indexSet().subIndex
00226                        (pit->cell(), pit->duneIndex(), mydim)] = counter;
00227           ++counter;
00228           ++pit;
00229         }
00230         return true;
00231       }
00233       virtual void write(const typename Base::Cell& cell, unsigned cornerIndex)
00234       {
00235         // if pointIndices is empty, we're in writeIsNoop mode
00236         if(pointIndices.size() == 0)
00237           return;
00238         arraywriter->write(pointIndices[factory.indexSet().subIndex
00239                                         (cell, cornerIndex, mydim)]);
00240       }
00242       virtual void endWrite() {
00243         arraywriter.reset();
00244         pointIndices.clear();
00245       }
00246     };
00247 
00249     template<typename Cell>
00250     class NonConformingConnectivityWriter
00251       : public FunctionWriterBase<Cell>
00252     {
00253       shared_ptr<DataArrayWriter<unsigned> > arraywriter;
00254       unsigned counter;
00255 
00256     public:
00258       virtual std::string name() const { return "connectivity"; }
00259 
00261       virtual unsigned ncomps() const { return 1; }
00262 
00264       virtual void addArray(PVTUWriter& writer) {
00265         writer.addArray<unsigned>(name(), ncomps());
00266       }
00267 
00269       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00270         arraywriter.reset(writer.makeArrayWriter<unsigned>(name(), ncomps(),
00271                                                            nitems));
00272         counter = 0;
00273         return !arraywriter->writeIsNoop();
00274       }
00276       virtual void write(const Cell& cell, unsigned cornerIndex)
00277       {
00278         arraywriter->write(counter);
00279         ++counter;
00280       }
00282       virtual void endWrite() {
00283         arraywriter.reset();
00284       }
00285     };
00286 
00288     template<typename Cell>
00289     class OffsetsWriter
00290       : public FunctionWriterBase<Cell>
00291     {
00292       typedef FunctionWriterBase<Cell> Base;
00293 
00294       shared_ptr<DataArrayWriter<unsigned> > arraywriter;
00295       unsigned offset;
00296 
00297     public:
00299       virtual std::string name() const { return "offsets"; }
00300 
00302       virtual unsigned ncomps() const { return 1; }
00303 
00305       virtual void addArray(PVTUWriter& writer) {
00306         writer.addArray<unsigned>(name(), ncomps());
00307       }
00308 
00310       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00311         arraywriter.reset(writer.makeArrayWriter<unsigned>(name(), ncomps(),
00312                                                            nitems));
00313         offset = 0;
00314         return !arraywriter->writeIsNoop();
00315       }
00317       virtual void write(const Cell& cell, const typename Base::Domain&) {
00318         offset += cell.geometry().corners();
00319         arraywriter->write(offset);
00320       };
00322       virtual void endWrite() {
00323         arraywriter.reset();
00324       }
00325     };
00326 
00328     template<typename Cell>
00329     class TypesWriter
00330       : public FunctionWriterBase<Cell>
00331     {
00332       typedef FunctionWriterBase<Cell> Base;
00333 
00334       shared_ptr<DataArrayWriter<unsigned char> > arraywriter;
00335 
00336     public:
00338       virtual std::string name() const { return "types"; }
00339 
00341       virtual unsigned ncomps() const { return 1; }
00342 
00344       virtual void addArray(PVTUWriter& writer) {
00345         writer.addArray<unsigned char>(name(), ncomps());
00346       }
00347 
00349       virtual bool beginWrite(VTUWriter& writer, std::size_t nitems) {
00350         arraywriter.reset(writer.makeArrayWriter<unsigned char>
00351                           ( name(), ncomps(), nitems));
00352         return !arraywriter->writeIsNoop();
00353       }
00355       virtual void write(const Cell& cell, const typename Base::Domain&) {
00356         arraywriter->write(geometryType(cell.type()));
00357       };
00359       virtual void endWrite() {
00360         arraywriter.reset();
00361       }
00362     };
00363 
00364   } // namespace VTK
00365 
00367 
00368 } // namespace Dune
00369 
00370 #endif // DUNE_GRID_IO_FILE_VTK_FUNCTIONWRITER_HH