dune-grid
2.2.0
|
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