1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi: set et ts=4 sw=2 sts=2: 3 4 #ifndef DUNE_GRID_IO_FILE_VTK_FUNCTION_HH 5 #define DUNE_GRID_IO_FILE_VTK_FUNCTION_HH 6 7 #include <string> 8 9 #include <dune/common/exceptions.hh> 10 #include <dune/common/fvector.hh> 11 12 #include <dune/geometry/type.hh> 13 #include <dune/geometry/referenceelements.hh> 14 #include <dune/geometry/multilineargeometry.hh> 15 16 #include <dune/grid/common/mcmgmapper.hh> 17 #include <dune/grid/io/file/vtk/common.hh> 18 19 /** @file 20 @author Peter Bastian, Christian Engwer 21 @brief Functions for VTK output 22 */ 23 24 namespace Dune 25 { 26 //! \addtogroup VTK 27 //! \{ 28 29 ////////////////////////////////////////////////////////////////////// 30 // 31 // Base VTKFunction 32 // 33 34 /** \brief A base class for grid functions with any return type and dimension 35 36 Trick : use double as return type 37 */ 38 template< class GridView > 39 class VTKFunction 40 { 41 public: 42 typedef typename GridView::ctype ctype; 43 enum { dim = GridView::dimension }; 44 typedef typename GridView::template Codim< 0 >::Entity Entity; 45 46 //! return number of components (1 for scalar valued functions, 3 for 47 //! vector valued function in 3D etc.) 48 virtual int ncomps () const = 0; 49 50 //! evaluate single component comp in the entity e at local coordinates xi 51 /*! Evaluate the function in an entity at local coordinates. 52 @param[in] comp number of component to be evaluated 53 @param[in] e reference to grid entity of codimension 0 54 @param[in] xi point in local coordinates of the reference element 55 of e 56 \return value of the component 57 */ 58 virtual double evaluate (int comp, const Entity& e, 59 const Dune::FieldVector<ctype,dim>& xi) const = 0; 60 61 //! get name 62 virtual std::string name () const = 0; 63 64 //! get output precision for the field precision() const65 virtual VTK::Precision precision() const 66 { return VTK::Precision::float32; } 67 68 //! virtual destructor ~VTKFunction()69 virtual ~VTKFunction () {} 70 }; 71 72 ////////////////////////////////////////////////////////////////////// 73 // 74 // P0VTKFunction 75 // 76 77 //! Take a vector and interpret it as cell data for the VTKWriter 78 /** 79 * This class turns a generic vector containing cell data into a 80 * VTKFunction. The vector must allow read access to the data via 81 * operator[]() and store the data in the order given by 82 * MultipleCodimMultipleGeomTypeMapper with a layout class that allows only 83 * elements. Also, it must support the method size(). 84 * 85 * While the number of components of the function is always 1, the vector 86 * may represent a field with multiple components of which one may be 87 * selected. 88 * 89 * \tparam GV Type of GridView the vector applies to. 90 * \tparam V Type of vector. 91 */ 92 template<typename GV, typename V> 93 class P0VTKFunction 94 : public VTKFunction< GV > 95 { 96 //! Base class 97 typedef VTKFunction< GV > Base; 98 //! Mapper for elements 99 typedef MultipleCodimMultipleGeomTypeMapper<GV> Mapper; 100 101 //! store a reference to the vector 102 const V& v; 103 //! name of this function 104 std::string s; 105 //! number of components of the field stored in the vector 106 int ncomps_; 107 //! index of the component of the field in the vector this function is 108 //! responsible for 109 int mycomp_; 110 //! precision with which to output the field 111 VTK::Precision prec_; 112 //! mapper used to map elements to indices 113 Mapper mapper; 114 115 public: 116 typedef typename Base::Entity Entity; 117 typedef typename Base::ctype ctype; 118 using Base::dim; 119 120 //! return number of components ncomps() const121 int ncomps () const override 122 { 123 return 1; 124 } 125 126 //! evaluate evaluate(int,const Entity & e,const Dune::FieldVector<ctype,dim> &) const127 double evaluate (int, const Entity& e, 128 const Dune::FieldVector<ctype,dim>&) const override 129 { 130 return v[mapper.index(e)*ncomps_+mycomp_]; 131 } 132 133 //! get name name() const134 std::string name () const override 135 { 136 return s; 137 } 138 139 //! get output precision for the field precision() const140 VTK::Precision precision() const override 141 { 142 return prec_; 143 } 144 145 //! construct from a vector and a name 146 /** 147 * \param gv GridView to operate on (used to instantiate a 148 * MultipleCodimMultipleGeomeTypeMapper, otherwise no 149 * reference or copy is stored). Note that this must be the 150 * GridView the vector applies to as well as the GridView 151 * later used by the VTKWriter -- i.e. we do not implicitly 152 * restrict or prolongate the data. 153 * \param v_ Reference to the vector holding the data. The reference 154 * is stored internally and must be valid for as long as 155 * this functions evaluate method is used. 156 * \param s_ Name of this function in the VTK file. 157 * \param ncomps Number of components of the field represented by the 158 * vector. 159 * \param mycomp Number of the field component this function is 160 * responsible for. 161 * \param prec the precision with which to output the field 162 */ P0VTKFunction(const GV & gv,const V & v_,const std::string & s_,int ncomps=1,int mycomp=0,VTK::Precision prec=VTK::Precision::float32)163 P0VTKFunction(const GV &gv, const V &v_, const std::string &s_, 164 int ncomps=1, int mycomp=0, VTK::Precision prec = VTK::Precision::float32) 165 : v( v_ ), 166 s( s_ ), 167 ncomps_(ncomps), 168 mycomp_(mycomp), 169 prec_(prec), 170 mapper( gv, mcmgElementLayout() ) 171 { 172 if (v.size()!=(unsigned int)(mapper.size()*ncomps_)) 173 DUNE_THROW(IOError, "P0VTKFunction: size mismatch"); 174 } 175 176 //! destructor ~P0VTKFunction()177 virtual ~P0VTKFunction() {} 178 }; 179 180 ////////////////////////////////////////////////////////////////////// 181 // 182 // P1VTKFunction 183 // 184 185 //! Take a vector and interpret it as point data for the VTKWriter 186 /** 187 * This class turns a generic vector containing point data into a 188 * VTKFunction. The vector must allow read access to the data via 189 * operator[]() and store the data in the order given by 190 * MultipleCodimMultipleGeomTypeMapper with a layout class that allows only 191 * vertices. Also, it must support the method size(). 192 * 193 * While the number of components of the function is always 1, the vector 194 * may represent a field with multiple components of which one may be 195 * selected. 196 * 197 * \tparam GV Type of GridView the vector applies to. 198 * \tparam V Type of vector. 199 */ 200 template<typename GV, typename V> 201 class P1VTKFunction 202 : public VTKFunction< GV > 203 { 204 //! Base class 205 typedef VTKFunction< GV > Base; 206 //! Mapper for vertices 207 typedef MultipleCodimMultipleGeomTypeMapper<GV> Mapper; 208 209 //! store a reference to the vector 210 const V& v; 211 //! name of this function 212 std::string s; 213 //! number of components of the field stored in the vector 214 int ncomps_; 215 //! index of the component of the field in the vector this function is 216 //! responsible for 217 int mycomp_; 218 //! precision with which to output the field 219 VTK::Precision prec_; 220 //! mapper used to map elements to indices 221 Mapper mapper; 222 223 public: 224 typedef typename Base::Entity Entity; 225 typedef typename Base::ctype ctype; 226 using Base::dim; 227 228 //! return number of components ncomps() const229 int ncomps () const override 230 { 231 return 1; 232 } 233 234 //! evaluate evaluate(int comp,const Entity & e,const Dune::FieldVector<ctype,dim> & xi) const235 double evaluate ([[maybe_unused]] int comp, const Entity& e, 236 const Dune::FieldVector<ctype,dim>& xi) const override 237 { 238 const unsigned int myDim = Entity::mydimension; 239 const unsigned int nVertices = e.subEntities(dim); 240 241 std::vector<FieldVector<ctype,1> > cornerValues(nVertices); 242 for (unsigned i=0; i<nVertices; ++i) 243 cornerValues[i] = v[mapper.subIndex(e,i,myDim)*ncomps_+mycomp_]; 244 245 // (Ab)use the MultiLinearGeometry class to do multi-linear interpolation between scalars 246 const MultiLinearGeometry<ctype,dim,1> interpolation(e.type(), cornerValues); 247 return interpolation.global(xi); 248 } 249 250 //! get name name() const251 std::string name () const override 252 { 253 return s; 254 } 255 256 //! get output precision for the field precision() const257 VTK::Precision precision() const override 258 { 259 return prec_; 260 } 261 262 //! construct from a vector and a name 263 /** 264 * \param gv GridView to operate on (used to instantiate a 265 * MultipleCodimMultipleGeomTypeMapper, otherwise no 266 * reference or copy is stored). Note that this must be the 267 * GridView the vector applies to as well as the GridView 268 * later used by the VTKWriter -- i.e. we do not implicitly 269 * restrict or prolongate the data. 270 * \param v_ Reference to the vector holding the data. The reference 271 * is stored internally and must be valid for as long as 272 * this functions evaluate method is used. 273 * \param s_ Name of this function in the VTK file. 274 * \param ncomps Number of components of the field represented by the 275 * vector. 276 * \param mycomp Number of the field component this function is 277 * responsible for. 278 * \param prec the precision with which to output the field 279 */ P1VTKFunction(const GV & gv,const V & v_,const std::string & s_,int ncomps=1,int mycomp=0,VTK::Precision prec=VTK::Precision::float32)280 P1VTKFunction(const GV& gv, const V &v_, const std::string &s_, 281 int ncomps=1, int mycomp=0, VTK::Precision prec = VTK::Precision::float32) 282 : v( v_ ), 283 s( s_ ), 284 ncomps_(ncomps), 285 mycomp_(mycomp), 286 prec_(prec), 287 mapper( gv, mcmgVertexLayout() ) 288 { 289 if (v.size()!=(unsigned int)(mapper.size()*ncomps_)) 290 DUNE_THROW(IOError,"P1VTKFunction: size mismatch"); 291 } 292 293 //! destructor ~P1VTKFunction()294 virtual ~P1VTKFunction() {} 295 }; 296 297 //! \} group VTK 298 299 } // namespace Dune 300 301 #endif // DUNE_GRID_IO_FILE_VTK_FUNCTION_HH 302