diff --git a/dumux/io/vtkoutputmodule.hh b/dumux/io/vtkoutputmodule.hh index 034e8fc293263de186e01ed44f17910828a7a052..db83bb2e8987439bf19ecae30bc84dc0b671c3da 100644 --- a/dumux/io/vtkoutputmodule.hh +++ b/dumux/io/vtkoutputmodule.hh @@ -23,8 +23,18 @@ #ifndef VTK_OUTPUT_MODULE_HH #define VTK_OUTPUT_MODULE_HH +#include <functional> + #include <dune/common/timer.hh> #include <dune/common/fvector.hh> +#include <dune/common/typetraits.hh> + +#include <dune/geometry/type.hh> +#include <dune/geometry/referenceelements.hh> +#include <dune/geometry/multilineargeometry.hh> + +#include <dune/grid/common/mcmgmapper.hh> +#include <dune/grid/io/file/vtk/function.hh> #include <dune/grid/io/file/vtk/vtkwriter.hh> #include <dune/grid/io/file/vtk/vtksequencewriter.hh> #include <dumux/implicit/properties.hh> @@ -41,9 +51,138 @@ NEW_PROP_TAG(NumPhases); namespace Dumux { -namespace VtkImplDetail +namespace Vtk { - auto defaultAdderFunction = [](auto& m){}; + //! struct that can hold any field that fulfills the VTKFunction interface + template<class GridView> + class Field + { + enum { dim = GridView::dimension }; + using ctype = typename GridView::ctype; + using Element = typename GridView::template Codim<0>::Entity; + using ReferenceElements = typename Dune::ReferenceElements<ctype, dim>; + + // a VTK function that supports both scalar and vector values for each element + template <typename F> + struct VectorP0VTKFunction : Dune::VTKFunction<GridView> + { + const F& field_; + const std::string& name_; + int nComps_; + Dune::MultipleCodimMultipleGeomTypeMapper<GridView> mapper_; + + public: + //! return number of components + virtual int ncomps () const + { return nComps_; } + + //! evaluate + virtual double evaluate (int mycomp, const Element& e, + const Dune::FieldVector<ctype,dim>&) const + { return accessChooser_(mycomp, mapper_.index(e), Dune::is_indexable<decltype(field_[0])>()); } + + //! get name + virtual std::string name () const + { return name_; } + + VectorP0VTKFunction(const GridView &gridView, const F& field, const std::string& name, int nComps) + : field_(field), name_(name), nComps_(nComps), mapper_(gridView, Dune::mcmgElementLayout()) + { + if (field.size()!=(unsigned int)(mapper_.size())) + DUNE_THROW(Dune::IOError, "NestedP0VTKFunction: size mismatch"); + } + private: + double accessChooser_(int mycomp, int i, std::true_type) const + { return field_[i][mycomp]; } + + double accessChooser_(int mycomp, int i, std::false_type) const + { return field_[i]; } + }; + + // a VTK function that supports both scalar and vector values for each vertex + template <typename F> + struct VectorP1VTKFunction : Dune::VTKFunction<GridView> + { + const F& field_; + const std::string& name_; + int nComps_; + Dune::MultipleCodimMultipleGeomTypeMapper<GridView> mapper_; + + public: + //! return number of components + virtual int ncomps () const + { return nComps_; } + + //! evaluate + virtual double evaluate (int mycomp, const Element& e, + const Dune::FieldVector<ctype,dim>& xi) const + { + const unsigned int dim = Element::mydimension; + const unsigned int nVertices = e.subEntities(dim); + + std::vector<Dune::FieldVector<ctype, 1>> cornerValues(nVertices); + for (unsigned i = 0; i < nVertices; ++i) + cornerValues[i] = accessChooser_(mycomp, mapper_.subIndex(e, i, dim), Dune::is_indexable<decltype(field_[0])>()); + + // (Ab)use the MultiLinearGeometry class to do multi-linear interpolation between scalars + const Dune::MultiLinearGeometry<ctype, dim, 1> interpolation(e.type(), cornerValues); + return interpolation.global(xi); + } + + //! get name + virtual std::string name () const + { return name_; } + + VectorP1VTKFunction(const GridView &gridView, const F& field, const std::string& name, int nComps) + : field_(field), name_(name), nComps_(nComps), mapper_(gridView, Dune::mcmgVertexLayout()) + { + if (field.size()!=(unsigned int)(mapper_.size())) + DUNE_THROW(Dune::IOError, "NestedP1VTKFunction: size mismatch"); + } + private: + double accessChooser_(int mycomp, int i, std::true_type) const + { return field_[i][mycomp]; } + + double accessChooser_(int mycomp, int i, std::false_type) const + { return field_[i]; } + }; + + std::string name_; + int codim_; + // can point to anything fulfilling the VTKFunction interface + std::shared_ptr<Dune::VTKFunction<GridView>> field_; + + public: + virtual std::string name () const + { return name_; } + + virtual int ncomps() const + { return field_->ncomps(); } + + virtual double evaluate(int mycomp, + const Element &element, + const Dune::FieldVector< ctype, dim > &xi) const + { return field_->evaluate(mycomp, element, xi); } + + // template constructor selects the right VTKFunction implementation + template <typename F> + Field(const GridView& gridView, F const& f, const std::string& name, int numComp = 1, int codim = 0) + : name_(name), codim_(codim) + { + if (codim == GridView::dimension) + field_ = std::make_shared<VectorP1VTKFunction<F>>(gridView, f, name, numComp); + else if (codim == 0) + field_ = std::make_shared<VectorP0VTKFunction<F>>(gridView, f, name, numComp); + else + DUNE_THROW(Dune::NotImplemented, "Only element or vertex quantities allowed."); + } + + int codim() const + { return codim_; } + + const std::shared_ptr<Dune::VTKFunction<GridView>>& get() const + { return field_; } + }; } /*! @@ -82,9 +221,8 @@ class VtkOutputModule static constexpr bool isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox); static constexpr int dofCodim = isBox ? dim : 0; - struct PriVarScalarDataInfo { unsigned int pvIdx; std::string name; }; - struct PriVarVectorDataInfo { std::vector<unsigned int> pvIdx; std::string name; }; - struct SecondVarScalarDataInfo { std::function<Scalar(const VolumeVariables&)> get; std::string name; }; + struct VolVarScalarDataInfo { std::function<Scalar(const VolumeVariables&)> get; std::string name; }; + using Field = Vtk::template Field<GridView>; public: @@ -107,273 +245,195 @@ public: ////////////////////////////////////////////////////////////////////////////////////////////// //! Methods to conveniently add primary and secondary variables upon initialization - //! Do not call these methods after initialization i.e. not within the time loop + //! Do not call these methods after initialization i.e. _not_ within the time loop ////////////////////////////////////////////////////////////////////////////////////////////// - //! Output a scalar primary variable + //! Output a scalar volume variable //! \param name The name of the vtk field - //! \param pvIdx The index in the primary variables vector - void addPrimaryVariable(const std::string& name, unsigned int pvIdx) + //! \param f A function taking a VolumeVariables object and returning the desired scalar + DUNE_DEPRECATED_MSG("Will be removed after next release. Please use addVolumeVariable(function, name) instead!") + void addSecondaryVariable(const std::string& name, std::function<Scalar(const VolumeVariables&)>&& f) { - priVarScalarDataInfo_.push_back(PriVarScalarDataInfo{pvIdx, name}); + volVarScalarDataInfo_.push_back(VolVarScalarDataInfo{f, name}); } - //! Output a vector primary variable + //! Output a scalar volume variable //! \param name The name of the vtk field - //! \param pvIndices A vector of indices in the primary variables vector to group for vector visualization - void addPrimaryVariable(const std::string& name, std::vector<unsigned int> pvIndices) + //! \param f A function taking a VolumeVariables object and returning the desired scalar + void addVolumeVariable(std::function<Scalar(const VolumeVariables&)>&& f, const std::string& name) { - assert(pvIndices.size() < 4 && "Vtk doesn't support vector dimensions greater than 3!"); - priVarVectorDataInfo_.push_back(PriVarVectorDataInfo{pvIndices, name}); + volVarScalarDataInfo_.push_back(VolVarScalarDataInfo{f, name}); } - //! Output a secondary scalar variable + //! Add a scalar or vector valued field + //! \param v The scalar field to be added //! \param name The name of the vtk field - //! \param f A function taking a VolumeVariables object and returning the desired scalar - void addSecondaryVariable(const std::string& name, std::function<Scalar(const VolumeVariables&)>&& f) + //! \param nComp Number of components of the vector (maximum 3) + template<typename Vector> + void addField(const Vector& v, const std::string& name, int nComp = 1) { - secondVarScalarDataInfo_.push_back(SecondVarScalarDataInfo{f, name}); + if (v.size() == gridGeom_.gridView().size(0)) + fields_.emplace_back(gridGeom_.gridView(), v, name, nComp, 0); + else if (v.size() == gridGeom_.gridView().size(dim)) + fields_.emplace_back(gridGeom_.gridView(), v, name, nComp, dim); + else + DUNE_THROW(Dune::RangeError, "Size mismatch of added field!"); } ////////////////////////////////////////////////////////////////////////////////////////////// - //! Methods to add addtional (non-standardized) scalar or vector fields to the output queue - //! Call these methods on the output module obtained as argument of the addVtkOutputFields function + //! Writing data ////////////////////////////////////////////////////////////////////////////////////////////// - //! Output a scalar field - //! \param name The name of the vtk field - //! \param codim The codimension of the entities the vtk field lives on (options: 0 := elements, dim := vertices) - //! \returns A reference to the resized scalar field to be filled with the actual data - std::vector<Scalar>& createScalarField(const std::string& name, int codim) - { - scalarFields_.emplace_back(std::make_pair(std::vector<Scalar>(gridGeom_.gridView().size(codim)), name)); - return scalarFields_.back().first; - } - - //! Output a vector field - //! \param name The name of the vtk field - //! \param codim The codimension of the entities the vtk field lives on (options: 0 := elements, dim := vertices) - //! \returns A reference to the resized vector field to be filled with the actual data - std::vector<GlobalPosition>& createVectorField(const std::string& name, int codim) - { - vectorFields_.emplace_back(std::make_pair(std::vector<GlobalPosition>(gridGeom_.gridView().size(codim)), name)); - return vectorFields_.back().first; - } - //! Write the data for this timestep to file in four steps - //! (1) Allow user to register additional (non-standardized) fields - //! (2) We assemble all registered variable fields - //! (3) We register them with the vtk writer - //! (4) The writer writes the output for us - //! (5) Clear the writer for the next time step - template<typename AdderFunction = decltype(VtkImplDetail::defaultAdderFunction)> - void write(double time, - const AdderFunction& addVtkOutputFields = VtkImplDetail::defaultAdderFunction, - Dune::VTK::OutputType type = Dune::VTK::ascii) + //! (1) We assemble all registered variable fields + //! (2) We register them with the vtk writer + //! (3) The writer writes the output for us + //! (4) Clear the writer for the next time step + void write(double time, Dune::VTK::OutputType type = Dune::VTK::ascii) { Dune::Timer timer; - ////////////////////////////////////////////////////////////// - //! (1) Register addtional (non-standardized) data fields with the vtk writer - //! Using the add scalar field or vector field methods - ////////////////////////////////////////////////////////////// - addVtkOutputFields(asImp_()); - - //! Abort if no data was registered - //! \todo This is not necessary anymore once the old style multiwriter is removed - if (priVarScalarDataInfo_.empty() - && priVarVectorDataInfo_.empty() - && secondVarScalarDataInfo_.empty() - && scalarFields_.empty() - && vectorFields_.empty()) - return; ////////////////////////////////////////////////////////////// - //! (2) Assemble all variable fields with registered info + //! (1) Assemble all variable fields with registered info ////////////////////////////////////////////////////////////// - auto numCells = gridGeom_.gridView().size(0); - auto numDofs = asImp_().numDofs_(); - - // get fields for all primary variables - std::vector<std::vector<Scalar>> priVarScalarData(priVarScalarDataInfo_.size(), std::vector<Scalar>(numDofs)); - - std::vector<std::vector<Scalar>> priVarVectorData(priVarVectorDataInfo_.size()); - for (std::size_t i = 0; i < priVarVectorDataInfo_.size(); ++i) - priVarVectorData[i].resize(numDofs*priVarVectorDataInfo_[i].pvIdx.size()); - - // get fields for all secondary variables - std::vector<std::vector<Scalar>> secondVarScalarData(secondVarScalarDataInfo_.size(), std::vector<Scalar>(numDofs)); // instatiate the velocity output VelocityOutput velocityOutput(problem_, gridGeom_, gridVariables_, sol_); std::array<std::vector<GlobalPosition>, numPhases> velocity; - if (velocityOutput.enableOutput()) - { - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - if(isBox && dim == 1) - velocity[phaseIdx].resize(numCells); - else - velocity[phaseIdx].resize(numDofs); - } - } - - // maybe allocate space for the process rank - std::vector<Scalar> rank; + // process rank static const std::string modelParamGroup = GET_PROP_VALUE(TypeTag, ModelParameterGroup); static bool addProcessRank = getParamFromGroup<bool>(modelParamGroup, "Vtk.AddProcessRank"); - if (addProcessRank) rank.resize(numCells); + std::vector<double> rank; - for (const auto& element : elements(gridGeom_.gridView(), Dune::Partitions::interior)) - { - const auto eIdxGlobal = gridGeom_.elementMapper().index(element); + // volume variable data + std::vector<std::vector<Scalar>> volVarScalarData; - // cell-centered models - if(!isBox) - { - //! primary variable data - for (std::size_t i = 0; i < priVarScalarDataInfo_.size(); ++i) - priVarScalarData[i][eIdxGlobal] = asImp_().getPriVarData_(eIdxGlobal, priVarScalarDataInfo_[i].pvIdx); - - for (std::size_t i = 0; i < priVarVectorDataInfo_.size(); ++i) - for (std::size_t j = 0; j < priVarVectorDataInfo_[i].pvIdx.size(); ++j) - priVarVectorData[i][eIdxGlobal*priVarVectorDataInfo_[i].pvIdx.size() + j] - = asImp_().getPriVarData_(eIdxGlobal, priVarVectorDataInfo_[i].pvIdx[j]); - } + //! Abort if no data was registered + if (!volVarScalarDataInfo_.empty() + || !fields_.empty() + || velocityOutput.enableOutput() + || addProcessRank) + { + const auto numCells = gridGeom_.gridView().size(0); + const auto numDofs = asImp_().numDofs_(); - auto fvGeometry = localView(gridGeom_); - auto elemVolVars = localView(gridVariables_.curGridVolVars()); + // get fields for all volume variables + if (!volVarScalarDataInfo_.empty()) + volVarScalarData.resize(volVarScalarDataInfo_.size(), std::vector<Scalar>(numDofs)); - // If velocity output is enabled we need to bind to the whole stencil - // otherwise element-local data is sufficient if (velocityOutput.enableOutput()) - fvGeometry.bind(element); - else - fvGeometry.bindElement(element); - - // If velocity output is enabled we need to bind to the whole stencil - // otherwise element-local data is sufficient - if (velocityOutput.enableOutput()) - elemVolVars.bind(element, fvGeometry, sol_); - else - elemVolVars.bindElement(element, fvGeometry, sol_); - - for (auto&& scv : scvs(fvGeometry)) { - const auto dofIdxGlobal = scv.dofIndex(); - - // for box model do the privars here - if (isBox) + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - //! primary variable data - for (std::size_t i = 0; i < priVarScalarDataInfo_.size(); ++i) - priVarScalarData[i][dofIdxGlobal] = asImp_().getPriVarData_(dofIdxGlobal, priVarScalarDataInfo_[i].pvIdx); + if(isBox && dim == 1) + velocity[phaseIdx].resize(numCells); + else + velocity[phaseIdx].resize(numDofs); + } + } - for (std::size_t i = 0; i < priVarVectorDataInfo_.size(); ++i) - for (std::size_t j = 0; j < priVarVectorDataInfo_[i].pvIdx.size(); ++j) - priVarVectorData[i][dofIdxGlobal*priVarVectorDataInfo_[i].pvIdx.size() + j] - = asImp_().getPriVarData_(dofIdxGlobal,priVarVectorDataInfo_[i].pvIdx[j]); + // maybe allocate space for the process rank + if (addProcessRank) rank.resize(numCells); - } + for (const auto& element : elements(gridGeom_.gridView(), Dune::Partitions::interior)) + { + const auto eIdxGlobal = gridGeom_.elementMapper().index(element); - // secondary variables - const auto& volVars = elemVolVars[scv]; + auto fvGeometry = localView(gridGeom_); + auto elemVolVars = localView(gridVariables_.curGridVolVars()); - for (std::size_t i = 0; i < secondVarScalarDataInfo_.size(); ++i) - secondVarScalarData[i][dofIdxGlobal] = secondVarScalarDataInfo_[i].get(volVars); - } + // If velocity output is enabled we need to bind to the whole stencil + // otherwise element-local data is sufficient + if (velocityOutput.enableOutput()) + fvGeometry.bind(element); + else + fvGeometry.bindElement(element); - // velocity output - if (velocityOutput.enableOutput()) - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - velocityOutput.calculateVelocity(velocity[phaseIdx], elemVolVars, fvGeometry, element, phaseIdx); + // If velocity output is enabled we need to bind to the whole stencil + // otherwise element-local data is sufficient + if (velocityOutput.enableOutput()) + elemVolVars.bind(element, fvGeometry, sol_); + else if (!volVarScalarDataInfo_.empty()) + elemVolVars.bindElement(element, fvGeometry, sol_); - //! the rank - if (addProcessRank) - rank[eIdxGlobal] = gridGeom_.gridView().comm().rank(); - } + if (!volVarScalarDataInfo_.empty()) + { + for (auto&& scv : scvs(fvGeometry)) + { + const auto dofIdxGlobal = scv.dofIndex(); + const auto& volVars = elemVolVars[scv]; + + for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i) + volVarScalarData[i][dofIdxGlobal] = volVarScalarDataInfo_[i].get(volVars); + } + } - ////////////////////////////////////////////////////////////// - //! (3) Register data fields with the vtk writer - ////////////////////////////////////////////////////////////// + // velocity output + if (velocityOutput.enableOutput()) + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + velocityOutput.calculateVelocity(velocity[phaseIdx], elemVolVars, fvGeometry, element, phaseIdx); - // primary variables - for (std::size_t i = 0; i < priVarScalarDataInfo_.size(); ++i) - addDofDataForWriter_(sequenceWriter_, priVarScalarData[i], priVarScalarDataInfo_[i].name); + //! the rank + if (addProcessRank) + rank[eIdxGlobal] = static_cast<double>(gridGeom_.gridView().comm().rank()); + } - for (std::size_t i = 0; i < priVarVectorDataInfo_.size(); ++i) - addDofDataForWriter_(sequenceWriter_, priVarVectorData[i], priVarVectorDataInfo_[i].name, priVarVectorDataInfo_[i].pvIdx.size()); + ////////////////////////////////////////////////////////////// + //! (2) Register data fields with the vtk writer + ////////////////////////////////////////////////////////////// - // secondary variables - for (std::size_t i = 0; i < secondVarScalarDataInfo_.size(); ++i) - addDofDataForWriter_(sequenceWriter_, secondVarScalarData[i], secondVarScalarDataInfo_[i].name); + // volume variables if any + for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i) + addDofDataForWriter_(sequenceWriter_, volVarScalarData[i], volVarScalarDataInfo_[i].name); - // the velocity field - if (velocityOutput.enableOutput()) - { - if (isBox && dim > 1) - { - using NestedFunction = VtkNestedFunction<GridView, VertexMapper, std::vector<GlobalPosition>>; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - sequenceWriter_.addVertexData(std::make_shared<NestedFunction>("velocity_" + std::string(FluidSystem::phaseName(phaseIdx)) + " (m/s)", - gridGeom_.gridView(), gridGeom_.vertexMapper(), - velocity[phaseIdx], dim, dimWorld)); - } - // cell-centered models - else + // the velocity field + if (velocityOutput.enableOutput()) { - using NestedFunction = VtkNestedFunction<GridView, ElementMapper, std::vector<GlobalPosition>>; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - sequenceWriter_.addCellData(std::make_shared<NestedFunction>("velocity_" + std::string(FluidSystem::phaseName(phaseIdx)) + " (m/s)", - gridGeom_.gridView(), gridGeom_.elementMapper(), - velocity[phaseIdx], 0, dimWorld)); + if (isBox && dim > 1) + { + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + sequenceWriter_.addVertexData(Field(gridGeom_.gridView(), velocity[phaseIdx], + "velocity_" + std::string(FluidSystem::phaseName(phaseIdx)) + " (m/s)", + dimWorld, dim).get()); + } + // cell-centered models + else + { + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + sequenceWriter_.addCellData(Field(gridGeom_.gridView(), velocity[phaseIdx], + "velocity_" + std::string(FluidSystem::phaseName(phaseIdx)) + " (m/s)", + dimWorld, 0).get()); + } } - } - // the process rank - if (addProcessRank) - sequenceWriter_.addCellData(rank, "process rank"); + // the process rank + if (addProcessRank) + sequenceWriter_.addCellData(Field(gridGeom_.gridView(), rank, "process rank", 1, 0).get()); - // also register additional (non-standardized) user fields - for (auto&& field : scalarFields_) - { - if (field.first.size() == std::size_t(gridGeom_.gridView().size(0))) - sequenceWriter_.addCellData(field.first, field.second); - else if (field.first.size() == std::size_t(gridGeom_.gridView().size(dim))) - sequenceWriter_.addVertexData(field.first, field.second); - else - DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk scalar field!"); - } + // sequenceWriter_.addCellData(rank, "process rank"); - for (auto&& field : vectorFields_) - { - if (field.first.size() == std::size_t(gridGeom_.gridView().size(0))) - { - using NestedFunction = VtkNestedFunction<GridView, ElementMapper, std::vector<GlobalPosition>>; - sequenceWriter_.addCellData(std::make_shared<NestedFunction>(field.second, - gridGeom_.gridView(), gridGeom_.elementMapper(), - field.first, 0, dimWorld)); - } - else if (field.first.size() == std::size_t(gridGeom_.gridView().size(dim))) + // also register additional (non-standardized) user fields if any + for (auto&& field : fields_) { - using NestedFunction = VtkNestedFunction<GridView, VertexMapper, std::vector<GlobalPosition>>; - sequenceWriter_.addVertexData(std::make_shared<NestedFunction>(field.second, - gridGeom_.gridView(), gridGeom_.vertexMapper(), - field.first, dim, dimWorld)); + if (field.codim() == 0) + sequenceWriter_.addCellData(field.get()); + else if (field.codim() == dim) + sequenceWriter_.addVertexData(field.get()); + else + DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk scalar field!"); } - else - DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk vector field!"); } ////////////////////////////////////////////////////////////// - //! (4) The writer writes the output for us + //! (3) The writer writes the output for us ////////////////////////////////////////////////////////////// sequenceWriter_.write(time, type); ////////////////////////////////////////////////////////////// - //! (5) Clear all fields and writer for the next time step + //! (4) Clear the writer ////////////////////////////////////////////////////////////// - clear(); + writer_->clear(); //! output timer.stop(); @@ -383,49 +443,6 @@ public: } } - //! clear all data in the writer - void clear() - { - writer_->clear(); - scalarFields_.clear(); - vectorFields_.clear(); - } - - /*! - * \brief This method writes the complete state of the vtk writer - * to the harddisk. - * - * The file will start with the prefix returned by the name() - * method, has the current time of the simulation clock in it's - * name and uses the extension <tt>.drs</tt>. (Dumux ReStart - * file.) See Restart for details. - * - * \tparam Restarter The serializer type - * - * \param res The serializer object - */ - template <class Restarter> - void serialize(Restarter &res) - { - // TODO implement - } - - /*! - * \brief This method restores the complete state of the vtk writer - * from disk. - * - * It is the inverse of the serialize() method. - * - * \tparam Restarter The deserializer type - * - * \param res The deserializer object - */ - template <class Restarter> - void deserialize(Restarter &res) - { - // TODO implement - } - private: template<typename Writer, typename... Args> @@ -475,12 +492,8 @@ private: std::shared_ptr<Dune::VTKWriter<GridView>> writer_; Dune::VTKSequenceWriter<GridView> sequenceWriter_; - std::vector<PriVarScalarDataInfo> priVarScalarDataInfo_; - std::vector<PriVarVectorDataInfo> priVarVectorDataInfo_; - std::vector<SecondVarScalarDataInfo> secondVarScalarDataInfo_; - - std::list<std::pair<std::vector<Scalar>, std::string>> scalarFields_; - std::list<std::pair<std::vector<GlobalPosition>, std::string>> vectorFields_; + std::vector<VolVarScalarDataInfo> volVarScalarDataInfo_; //! Registered volume variables + std::vector<Field> fields_; //! Registered scalar and vector fields }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/1p/implicit/vtkoutputfields.hh b/dumux/porousmediumflow/1p/implicit/vtkoutputfields.hh index f8e90b5266ecaadae995073a8a3d6d18d09c1a5b..18eb8a0222795d999d9ae3226642d91dd2262720 100644 --- a/dumux/porousmediumflow/1p/implicit/vtkoutputfields.hh +++ b/dumux/porousmediumflow/1p/implicit/vtkoutputfields.hh @@ -40,7 +40,7 @@ public: template <class VtkOutputModule> static void init(VtkOutputModule& vtk) { - vtk.addPrimaryVariable("pressure", Indices::pressureIdx); + vtk.addSecondaryVariable("pressure", [](const auto& volVars){ return volVars.pressure(); }); } };