diff --git a/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh b/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh index 42162f9deb60279ea104d1c4a88f47f5d13e841d..80ef62ab19a7e7cfc5ace139c08a2ae3c670d54d 100644 --- a/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh +++ b/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh @@ -216,8 +216,7 @@ public: if (this->gridView().comm().rank() == 0) std::cout << "Writing result file for current time step\n"; - this->resultWriter().beginWrite(this->timeManager().time() + this->timeManager().timeStepSize(), - this->gridView()); + this->resultWriter().beginWrite(this->timeManager().time() + this->timeManager().timeStepSize()); this->asImp_().addOutputVtkFields(); this->resultWriter().endWrite(); // } diff --git a/dumux/boxmodels/common/boxproblem.hh b/dumux/boxmodels/common/boxproblem.hh index 577d442ad04eaace2baf5b9e02c37c615681ac04..1468bdb10934acceda76cb07b93ae75fe775ab67 100644 --- a/dumux/boxmodels/common/boxproblem.hh +++ b/dumux/boxmodels/common/boxproblem.hh @@ -735,7 +735,7 @@ public: // calculate the time _after_ the time was updated Scalar t = timeManager().time() + timeManager().timeStepSize(); createResultWriter_(); - resultWriter_->beginWrite(t, gridView()); + resultWriter_->beginWrite(t); model().addOutputVtkFields(model().curSol(), *resultWriter_); asImp_().addOutputVtkFields(); resultWriter_->endWrite(); @@ -770,7 +770,7 @@ protected: private: // makes sure that the result writer exists void createResultWriter_() - { if (!resultWriter_) resultWriter_ = new VtkMultiWriter(asImp_().name()); }; + { if (!resultWriter_) resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name()); }; std::string simName_; const GridView gridView_; diff --git a/dumux/decoupled/2p2c/fvpressure2p2c.hh b/dumux/decoupled/2p2c/fvpressure2p2c.hh index 69029737ae91f607e48ec1184d7c604c1cfff1f0..bd0733b2d7899a20f9784c848118e5381803a905 100644 --- a/dumux/decoupled/2p2c/fvpressure2p2c.hh +++ b/dumux/decoupled/2p2c/fvpressure2p2c.hh @@ -260,7 +260,7 @@ public: FVPressure2P2C(Problem& problem) : problem_(problem), A_(problem.variables().gridSize(), problem.variables().gridSize(), (2 * dim + 1) * problem.variables().gridSize(), Matrix::random), f_(problem.variables().gridSize()), - debugWriter_("debugOutput2p2c"), gravity(problem.gravity()) + debugWriter_(problem.gridView(), "debugOutput2p2c"), gravity(problem.gravity()) { if (pressureType != pw && pressureType != pn) { diff --git a/dumux/decoupled/common/impetproblem.hh b/dumux/decoupled/common/impetproblem.hh index 52d0a178c4ea3cc46c2be741ef98b6d660896e15..6621d03fdbd3cbd6383f67526af60d8b7afaa4c3 100644 --- a/dumux/decoupled/common/impetproblem.hh +++ b/dumux/decoupled/common/impetproblem.hh @@ -532,9 +532,8 @@ public: std::cout << "Writing result file for current time step\n"; if (!resultWriter_) - resultWriter_ = new VtkMultiWriter(asImp_().name()); - resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize(), - gridView()); + resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name()); + resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize()); model().addOutputVtkFields(*resultWriter_); asImp_().addOutputVtkFields(); resultWriter_->endWrite(); @@ -555,14 +554,14 @@ protected: VtkMultiWriter& resultWriter() { if (!resultWriter_) - resultWriter_ = new VtkMultiWriter(asImp_().name()); + resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name()); return *resultWriter_; } //! \copydoc Dumux::IMPETProblem::resultWriter() VtkMultiWriter& resultWriter() const { if (!resultWriter_) - resultWriter_ = new VtkMultiWriter(asImp_().name()); + resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name()); return *resultWriter_; } diff --git a/dumux/decoupled/common/onemodelproblem.hh b/dumux/decoupled/common/onemodelproblem.hh index fd071cee4b1f3cc8bfc02692158c8efbff80554a..40b4c05402730212584413aa903553c7132f03be 100644 --- a/dumux/decoupled/common/onemodelproblem.hh +++ b/dumux/decoupled/common/onemodelproblem.hh @@ -230,8 +230,8 @@ public: if (gridView().comm().rank() == 0) std::cout << "Writing result file for current time step\n"; if (!resultWriter_) - resultWriter_ = new VtkMultiWriter(asImp_().name()); - resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize(), gridView()); + resultWriter_ = new VtkMultiWriter(gridView(), asImp_().name()); + resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize()); model().addOutputVtkFields(*resultWriter_); asImp_().addOutputVtkFields(); resultWriter_->endWrite(); diff --git a/dumux/io/vtkmultiwriter.hh b/dumux/io/vtkmultiwriter.hh index 49f5a0f27802155e850baaa41b18a677961ea9c3..28942d833c9da21cc6ae1d4e6086f11a620d63ab 100644 --- a/dumux/io/vtkmultiwriter.hh +++ b/dumux/io/vtkmultiwriter.hh @@ -24,6 +24,8 @@ #ifndef VTK_MULTI_WRITER_HH #define VTK_MULTI_WRITER_HH +#include "vtknestedfunction.hh" + #include <dune/common/fvector.hh> #include <dune/istl/bvector.hh> @@ -54,10 +56,27 @@ namespace Dumux { template<class GridView> class VtkMultiWriter { -public: + typedef typename GridView::Grid Grid; + enum { dim = GridView::dimension }; + + typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGVertexLayout> VertexMapper; + typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGElementLayout> ElementMapper; + + // this constructor won't work anymore. Please use the variant + // below which also includes the GridView as an argument. + DUNE_DEPRECATED + VtkMultiWriter(const std::string &simName = "", + std::string multiFileName = "") + {} +public: typedef Dune::VTKWriter<GridView> VtkWriter; - VtkMultiWriter(const std::string &simName = "", std::string multiFileName = "") + VtkMultiWriter(const GridView &gridView, + const std::string &simName = "", + std::string multiFileName = "") + : gridView_(gridView) + , elementMapper_(gridView) + , vertexMapper_(gridView) { simName_ = (simName.empty())?"sim":simName; multiFileName_ = multiFileName; @@ -84,18 +103,32 @@ public: multiFile_.close(); } + /*! + * \brief Updates the internal data structures after mesh + * refinement. + * + * If the grid changes between two calls of beginWrite(), this + * method _must_ be called before the second beginWrite()! + */ + void gridChanged() + { + elementMapper_.update(); + vertexMapper_.update(); + } + /*! * \brief Called when ever a new timestep or a new grid * must be written. */ - void beginWrite(double t, const GridView &gridView) + void beginWrite(double t) { if (!multiFile_.is_open()) { startMultiFile_(multiFileName_); } - curWriter_ = new VtkWriter(gridView, Dune::VTKOptions::conforming); + curWriter_ = new VtkWriter(gridView_, + Dune::VTKOptions::conforming); ++curWriterNum_; curTime_ = t; @@ -104,7 +137,7 @@ public: void beginTimestep(double t, const GridView &gridView) DUNE_DEPRECATED // use beginWrite() - { beginWrite(t, gridView); } + { gridChanged(); beginWrite(t); } /*! * \brief Allocate a managed buffer for a scalar field @@ -116,10 +149,10 @@ public: Dune::BlockVector<Dune::FieldVector<Scalar, nComp> > *allocateManagedBuffer(int nEntities) { typedef Dune::BlockVector<Dune::FieldVector<Scalar, nComp> > VectorField; - - VtkVectorFieldStoreImpl_<VectorField> *vfs = - new VtkVectorFieldStoreImpl_<VectorField>(nEntities); - vectorFields_.push_back(vfs); + + ManagedVectorField_<VectorField> *vfs = + new ManagedVectorField_<VectorField>(nEntities); + managedObjects_.push_back(vfs); return &(vfs->vf); } @@ -145,11 +178,18 @@ public: * In both cases, modifying the buffer between the call to this * method and endWrite() results in _undefined behaviour_. */ - template <class DataArray> - void attachVertexData(DataArray &buf, const char *name, int nComps=1) + template <class DataBuffer> + void attachVertexData(DataBuffer &buf, const char *name, int nComps=1) { - sanitizeBuffer_(buf, nComps); - curWriter_->addVertexData(buf, name, nComps); + typedef typename VtkWriter::VTKFunctionPtr FunctionPtr; + typedef Dumux::VtkNestedFunction<Grid, VertexMapper, DataBuffer> VtkFn; + FunctionPtr fnPtr(new VtkFn(name, + gridView_.grid(), + vertexMapper_, + buf, + /*codim=*/dim, + nComps)); + curWriter_->addVertexData(fnPtr); } template <class DataArray> @@ -172,12 +212,18 @@ public: * In both cases, modifying the buffer between the call to this * method and endWrite() results in _undefined behaviour_. */ - template <class VectorField> - void attachCellData(VectorField &buf, const char *name, int nComps = 1) + template <class DataBuffer> + void attachCellData(DataBuffer &buf, const char *name, int nComps = 1) { - sanitizeBuffer_(buf, nComps); - - curWriter_->addCellData(buf, name); + typedef typename VtkWriter::VTKFunctionPtr FunctionPtr; + typedef Dumux::VtkNestedFunction<Grid, ElementMapper, DataBuffer> VtkFn; + FunctionPtr fnPtr(new VtkFn(name, + gridView_.grid(), + elementMapper_, + buf, + /*codim=*/0, + nComps)); + curWriter_->addCellData(fnPtr); } template <class VectorField> @@ -226,11 +272,11 @@ public: else -- curWriterNum_; - // discard managed buffers + // discard managed objects and the current VTK writer delete curWriter_; - while (vectorFields_.begin() != vectorFields_.end()) { - delete vectorFields_.front(); - vectorFields_.pop_front(); + while (managedObjects_.begin() != managedObjects_.end()) { + delete managedObjects_.front(); + managedObjects_.pop_front(); } // temporarily write the closing XML mumbo-jumbo to the mashup @@ -377,8 +423,8 @@ private: // make sure the field is well defined if running under valgrind // and make sure that all values can be displayed by paraview - template <class Buffer> - void sanitizeBuffer_(Buffer &b, int nComps) + template <class DataBuffer> + void sanitizeBuffer_(DataBuffer &b, int nComps) { for (int i = 0; i < b.size(); ++i) { for (int j = 0; j < nComps; ++j) { @@ -413,20 +459,20 @@ private: /** \todo Please doc me! */ - class VtkVectorFieldStoreBase_ + class ManagedObject_ { public: - virtual ~VtkVectorFieldStoreBase_() + virtual ~ManagedObject_() {} }; /** \todo Please doc me! */ template <class VF> - class VtkVectorFieldStoreImpl_ : public VtkVectorFieldStoreBase_ + class ManagedVectorField_ : public ManagedObject_ { public: - VtkVectorFieldStoreImpl_(int size) + ManagedVectorField_(int size) : vf(size) { } VF vf; @@ -434,7 +480,9 @@ private: // end hack //////////////////////////////////// - bool wasRestarted_; + const GridView gridView_; + ElementMapper elementMapper_; + VertexMapper vertexMapper_; std::string simName_; std::ofstream multiFile_; @@ -448,7 +496,7 @@ private: std::string curOutFileName_; int curWriterNum_; - std::list<VtkVectorFieldStoreBase_*> vectorFields_; + std::list<ManagedObject_*> managedObjects_; }; } diff --git a/dumux/nonlinear/newtoncontroller.hh b/dumux/nonlinear/newtoncontroller.hh index 4ec9ba467ffc3a72f682ffc0df041c53ae5253c0..3f458d2e2f6c6fd11218eb329af3a30acf6035d5 100644 --- a/dumux/nonlinear/newtoncontroller.hh +++ b/dumux/nonlinear/newtoncontroller.hh @@ -116,7 +116,7 @@ struct NewtonConvergenceWriter { timeStepIndex_ = 0; iteration_ = 0; - vtkMultiWriter_ = new VtkMultiWriter("convergence"); + vtkMultiWriter_ = 0; } ~NewtonConvergenceWriter() @@ -131,8 +131,9 @@ struct NewtonConvergenceWriter void beginIteration(const GridView &gv) { ++ iteration_; - vtkMultiWriter_->beginWrite(timeStepIndex_ + iteration_ / 100.0, - gv); + if (!vtkMultiWriter_) + vtkMultiWriter_ = new VtkMultiWriter(gv, "convergence"); + vtkMultiWriter_->beginWrite(timeStepIndex_ + iteration_ / 100.0); }; void writeFields(const SolutionVector &uLastIter, diff --git a/tutorial/tutorialproblem_coupled.hh b/tutorial/tutorialproblem_coupled.hh index b0611b510a762b6495bf1683b412bd685d21732c..37f3e2ee22c07166dbd1cb8bdb0e42e525e65dc4 100644 --- a/tutorial/tutorialproblem_coupled.hh +++ b/tutorial/tutorialproblem_coupled.hh @@ -154,8 +154,9 @@ public: */ bool shouldWriteOutput() const /*@\label{tutorial-coupled:output}@*/ { - return this->timeManager().timeStepIndex() > 0 && - (this->timeManager().timeStepIndex() % 1 == 0); + return + this->timeManager().timeStepIndex() > 0 && + (this->timeManager().timeStepIndex() % 1 == 0); } // Return the temperature within a finite volume. We use constant