24#ifndef DUMUX_IO_VTK_OUTPUT_MODULE_HH
25#define DUMUX_IO_VTK_OUTPUT_MODULE_HH
31#include <dune/common/timer.hh>
32#include <dune/common/fvector.hh>
33#include <dune/common/typetraits.hh>
35#include <dune/geometry/type.hh>
36#include <dune/geometry/multilineargeometry.hh>
38#include <dune/grid/common/mcmgmapper.hh>
39#include <dune/grid/common/partitionset.hh>
40#include <dune/grid/io/file/vtk/vtkwriter.hh>
41#include <dune/grid/io/file/vtk/vtksequencewriter.hh>
42#include <dune/grid/common/partitionset.hh>
59template<
class Gr
idGeometry>
62 using GridView =
typename GridGeometry::GridView;
63 using Field = Vtk::template Field<GridView>;
64 static constexpr int dim = GridView::dimension;
76 const std::string&
name,
78 Dune::VTK::DataMode dm = Dune::VTK::conforming,
86 const auto precisionString = getParamFromGroup<std::string>(
paramGroup,
"Vtk.Precision",
"Float32");
89 writer_ = std::make_shared<Dune::VTKWriter<GridView>>(
gridGeometry.gridView(), dm, coordPrecision);
90 sequenceWriter_ = std::make_unique<Dune::VTKSequenceWriter<GridView>>(writer_,
name);
91 addProcessRank_ = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddProcessRank",
true);
98 {
return paramGroup_; }
109 template<
typename Vector>
111 const std::string&
name,
125 template<
typename Vector>
127 const std::string&
name,
132 const auto nComp = getNumberOfComponents_(v);
134 const auto numElemDofs =
gridGeometry().elementMapper().size();
135 const auto numVertexDofs =
gridGeometry().vertexMapper().size();
140 if(numElemDofs == numVertexDofs)
141 DUNE_THROW(Dune::InvalidStateException,
"Automatic deduction of FieldType failed. Please explicitly specify FieldType::element or FieldType::vertex.");
143 if(v.size() == numElemDofs)
145 else if(v.size() == numVertexDofs)
148 DUNE_THROW(Dune::RangeError,
"Size mismatch of added field!");
154 if(v.size() != numElemDofs)
155 DUNE_THROW(Dune::RangeError,
"Size mismatch of added field!");
158 if(v.size() != numVertexDofs)
159 DUNE_THROW(Dune::RangeError,
"Size mismatch of added field!");
164 fields_.emplace_back(gridGeometry_.gridView(), gridGeometry_.elementMapper(), v,
name, nComp, 0, dm_,
precision);
166 fields_.emplace_back(gridGeometry_.gridView(), gridGeometry_.vertexMapper(), v,
name, nComp, dim, dm_,
precision);
174 void write(
double time, Dune::VTK::OutputType type = Dune::VTK::ascii)
179 if (dm_ == Dune::VTK::conforming)
180 writeConforming_(time, type);
181 else if (dm_ == Dune::VTK::nonconforming)
182 writeNonConforming_(time, type);
184 DUNE_THROW(Dune::NotImplemented,
"Output for provided VTK data mode");
189 std::cout << Fmt::format(
"Writing output for problem \"{}\". Took {:.2g} seconds.\n", name_, timer.elapsed());
196 const std::string&
name()
const {
return name_; }
197 Dune::VTK::DataMode
dataMode()
const {
return dm_; }
198 Dumux::Vtk::Precision
precision()
const {
return precision_; }
200 Dune::VTKWriter<GridView>&
writer() {
return *writer_; }
203 const std::vector<Field>&
fields()
const {
return fields_; }
207 virtual void writeConforming_(
double time, Dune::VTK::OutputType type)
214 std::vector<int> rank;
217 if (!fields_.empty() || addProcessRank_)
219 const auto numCells = gridGeometry_.gridView().size(0);
224 rank.resize(numCells);
226 for (
const auto& element : elements(gridGeometry_.gridView(), Dune::Partitions::interior))
228 const auto eIdxGlobal = gridGeometry_.elementMapper().index(element);
229 rank[eIdxGlobal] = gridGeometry_.gridView().comm().rank();
239 this->
sequenceWriter().addCellData(Field(gridGeometry_.gridView(), gridGeometry_.elementMapper(), rank,
"process rank", 1, 0).get());
242 for (
auto&& field : fields_)
244 if (field.codim() == 0)
246 else if (field.codim() == dim)
249 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
265 virtual void writeNonConforming_(
double time, Dune::VTK::OutputType type)
267 DUNE_THROW(Dune::NotImplemented,
"Non-conforming VTK output");
271 template<
class Vector>
272 std::size_t getNumberOfComponents_(
const Vector& v)
274 if constexpr (Dune::IsIndexable<decltype(std::declval<Vector>()[0])>::value)
280 const GridGeometry& gridGeometry_;
282 const std::string paramGroup_;
283 Dune::VTK::DataMode dm_;
285 Dumux::Vtk::Precision precision_;
287 std::shared_ptr<Dune::VTKWriter<GridView>> writer_;
288 std::unique_ptr<Dune::VTKSequenceWriter<GridView>> sequenceWriter_;
290 std::vector<Field> fields_;
292 bool addProcessRank_ =
true;
307template<
class Gr
idVariables,
class SolutionVector>
311 using GridGeometry =
typename GridVariables::GridGeometry;
313 using VV =
typename GridVariables::VolumeVariables;
314 using Scalar =
typename GridVariables::Scalar;
316 using GridView =
typename GridGeometry::GridView;
319 dim = GridView::dimension,
320 dimWorld = GridView::dimensionworld
323 using Element =
typename GridView::template Codim<0>::Entity;
324 using VolVarsVector = Dune::FieldVector<Scalar, dimWorld>;
327 static constexpr int dofCodim = isBox ? dim : 0;
329 struct VolVarScalarDataInfo { std::function<Scalar(
const VV&)> get; std::string
name; Dumux::Vtk::Precision precision_; };
330 struct VolVarVectorDataInfo { std::function<VolVarsVector(
const VV&)> get; std::string
name; Dumux::Vtk::Precision precision_; };
331 using Field = Vtk::template Field<GridView>;
340 const SolutionVector&
sol,
341 const std::string&
name,
343 Dune::VTK::DataMode dm = Dune::VTK::conforming,
350 enableVelocityOutput_ = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddVelocity",
false);
351 addProcessRank_ = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddProcessRank",
true);
372 const std::string&
name)
374 volVarScalarDataInfo_.push_back(VolVarScalarDataInfo{f,
name, this->
precision()});
381 template<
class VVV = VolVarsVector,
typename std::enable_if_t<(VVV::dimension > 1),
int> = 0>
383 const std::string&
name)
385 volVarVectorDataInfo_.push_back(VolVarVectorDataInfo{f,
name, this->
precision()});
390 const auto&
problem()
const {
return gridVariables_.curGridVolVars().problem(); }
392 const GridGeometry&
gridGeometry()
const {
return gridVariables_.gridGeometry(); }
393 const SolutionVector&
sol()
const {
return sol_; }
404 void writeConforming_(
double time, Dune::VTK::OutputType type)
override
406 const Dune::VTK::DataMode dm = Dune::VTK::conforming;
413 std::vector<VelocityVector> velocity(velocityOutput_->numFluidPhases());
416 std::vector<double> rank;
419 std::vector<std::vector<Scalar>> volVarScalarData;
420 std::vector<std::vector<VolVarsVector>> volVarVectorData;
423 if (!volVarScalarDataInfo_.empty()
424 || !volVarVectorDataInfo_.empty()
425 || !this->fields().empty()
426 || velocityOutput_->enableOutput()
429 const auto numCells =
gridGeometry().gridView().size(0);
430 const auto numDofs = numDofs_();
433 if (!volVarScalarDataInfo_.empty())
434 volVarScalarData.resize(volVarScalarDataInfo_.size(), std::vector<Scalar>(numDofs));
435 if (!volVarVectorDataInfo_.empty())
436 volVarVectorData.resize(volVarVectorDataInfo_.size(), std::vector<VolVarsVector>(numDofs));
438 if (velocityOutput_->enableOutput())
440 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
442 if(isBox && dim == 1)
443 velocity[phaseIdx].resize(numCells);
445 velocity[phaseIdx].resize(numDofs);
450 if (addProcessRank_) rank.resize(numCells);
453 auto elemVolVars =
localView(gridVariables_.curGridVolVars());
455 for (
const auto& element : elements(
gridGeometry().gridView(), Dune::Partitions::interior))
457 const auto eIdxGlobal =
gridGeometry().elementMapper().index(element);
460 if (velocityOutput_->enableOutput())
462 fvGeometry.bind(element);
463 elemVolVars.bind(element, fvGeometry, sol_);
467 fvGeometry.bindElement(element);
468 elemVolVars.bindElement(element, fvGeometry, sol_);
471 if (!volVarScalarDataInfo_.empty()
472 || !volVarVectorDataInfo_.empty())
474 for (
auto&& scv : scvs(fvGeometry))
476 const auto dofIdxGlobal = scv.dofIndex();
477 const auto& volVars = elemVolVars[scv];
480 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
481 volVarScalarData[i][dofIdxGlobal] = volVarScalarDataInfo_[i].get(volVars);
484 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
485 volVarVectorData[i][dofIdxGlobal] = volVarVectorDataInfo_[i].get(volVars);
490 if (velocityOutput_->enableOutput())
492 const auto elemFluxVarsCache =
localView(gridVariables_.gridFluxVarsCache()).bind(element, fvGeometry, elemVolVars);
494 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
495 velocityOutput_->calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
500 rank[eIdxGlobal] =
static_cast<double>(
gridGeometry().gridView().comm().rank());
510 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
512 volVarScalarDataInfo_[i].
name, 1, dim, dm, this->
precision()).get() );
513 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
515 volVarVectorDataInfo_[i].
name, dimWorld, dim, dm, this->
precision()).get() );
519 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
521 volVarScalarDataInfo_[i].
name, 1, 0,dm, this->
precision()).get() );
522 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
524 volVarVectorDataInfo_[i].
name, dimWorld, 0,dm, this->
precision()).get() );
528 if (velocityOutput_->enableOutput())
530 if (isBox && dim > 1)
532 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
534 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
535 dimWorld, dim, dm, this->precision()).get() );
540 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
542 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
543 dimWorld, 0, dm, this->precision()).get() );
552 for (
auto&& field : this->
fields())
554 if (field.codim() == 0)
556 else if (field.codim() == dim)
559 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
575 void writeNonConforming_(
double time, Dune::VTK::OutputType type)
override
577 const Dune::VTK::DataMode dm = Dune::VTK::nonconforming;
580 DUNE_THROW(Dune::InvalidStateException,
"Non-conforming output makes no sense for cell-centered schemes!");
587 if (enableVelocityOutput_ && !velocityOutput_->enableOutput())
588 std::cerr <<
"Warning! Velocity output was enabled in the input file"
589 <<
" but no velocity output policy was set for the VTK output module:"
590 <<
" There will be no velocity output."
591 <<
" Use the addVelocityOutput member function of the VTK output module." << std::endl;
593 std::vector<VelocityVector> velocity(velocityOutput_->numFluidPhases());
596 std::vector<double> rank;
599 using ScalarDataContainer = std::vector< std::vector<Scalar> >;
600 using VectorDataContainer = std::vector< std::vector<VolVarsVector> >;
601 std::vector< ScalarDataContainer > volVarScalarData;
602 std::vector< VectorDataContainer > volVarVectorData;
605 if (!volVarScalarDataInfo_.empty()
606 || !volVarVectorDataInfo_.empty()
607 || !this->fields().empty()
608 || velocityOutput_->enableOutput()
611 const auto numCells =
gridGeometry().gridView().size(0);
612 const auto numDofs = numDofs_();
615 if (!volVarScalarDataInfo_.empty())
616 volVarScalarData.resize(volVarScalarDataInfo_.size(), ScalarDataContainer(numCells));
617 if (!volVarVectorDataInfo_.empty())
618 volVarVectorData.resize(volVarVectorDataInfo_.size(), VectorDataContainer(numCells));
620 if (velocityOutput_->enableOutput())
622 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
624 if(isBox && dim == 1)
625 velocity[phaseIdx].resize(numCells);
627 velocity[phaseIdx].resize(numDofs);
632 if (addProcessRank_) rank.resize(numCells);
634 for (
const auto& element : elements(
gridGeometry().gridView(), Dune::Partitions::interior))
636 const auto eIdxGlobal =
gridGeometry().elementMapper().index(element);
640 auto elemVolVars =
localView(gridVariables_.curGridVolVars());
643 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
644 volVarScalarData[i][eIdxGlobal].resize(
numCorners);
645 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
646 volVarVectorData[i][eIdxGlobal].resize(
numCorners);
650 if (velocityOutput_->enableOutput())
652 fvGeometry.bind(element);
653 elemVolVars.bind(element, fvGeometry, sol_);
657 fvGeometry.bindElement(element);
658 elemVolVars.bindElement(element, fvGeometry, sol_);
661 if (!volVarScalarDataInfo_.empty()
662 || !volVarVectorDataInfo_.empty())
664 for (
auto&& scv : scvs(fvGeometry))
666 const auto& volVars = elemVolVars[scv];
669 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
670 volVarScalarData[i][scv.elementIndex()][scv.localDofIndex()] = volVarScalarDataInfo_[i].get(volVars);
673 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
674 volVarVectorData[i][scv.elementIndex()][scv.localDofIndex()] = volVarVectorDataInfo_[i].get(volVars);
679 if (velocityOutput_->enableOutput())
681 const auto elemFluxVarsCache =
localView(gridVariables_.gridFluxVarsCache()).bind(element, fvGeometry, elemVolVars);
683 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
684 velocityOutput_->calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
689 rank[eIdxGlobal] =
static_cast<double>(
gridGeometry().gridView().comm().rank());
697 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
699 volVarScalarDataInfo_[i].
name, 1, dim, dm, this->
precision()).get() );
701 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
703 volVarVectorDataInfo_[i].
name, dimWorld, dim, dm, this->
precision()).get() );
706 if (velocityOutput_->enableOutput())
710 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
712 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
713 dimWorld, dim, dm, this->precision()).get() );
717 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
719 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
720 dimWorld, 0,dm, this->precision()).get());
728 for (
auto&& field : this->
fields())
730 if (field.codim() == 0)
732 else if (field.codim() == dim)
735 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
751 std::size_t numDofs_()
const {
return dofCodim == dim ?
gridGeometry().vertexMapper().size() :
gridGeometry().elementMapper().size(); }
753 const GridVariables& gridVariables_;
754 const SolutionVector& sol_;
756 std::vector<VolVarScalarDataInfo> volVarScalarDataInfo_;
757 std::vector<VolVarVectorDataInfo> volVarVectorDataInfo_;
759 std::shared_ptr<VelocityOutput> velocityOutput_;
760 bool enableVelocityOutput_ =
false;
761 bool addProcessRank_ =
true;
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
The available discretization methods in Dumux.
Vtk field types available in Dumux.
Dune style VTK functions.
Formatting based on the fmt-library which implements std::format of C++20.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
Precision stringToPrecision(std::string_view precisionName)
Maps a string (e.g. from input) to a Dune precision type.
Definition: precision.hh:39
FieldType
Identifier for vtk field types.
Definition: fieldtype.hh:34
constexpr Box box
Definition: method.hh:139
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:215
Velocity output for implicit (porous media) models.
Definition: io/velocityoutput.hh:41
std::vector< Dune::FieldVector< Scalar, dimWorld > > VelocityVector
Definition: io/velocityoutput.hh:50
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: io/vtkoutputmodule.hh:61
Dumux::Vtk::Precision precision() const
Definition: io/vtkoutputmodule.hh:198
const std::string & paramGroup() const
the parameter group for getting parameter from the parameter tree
Definition: io/vtkoutputmodule.hh:97
void write(double time, Dune::VTK::OutputType type=Dune::VTK::ascii)
Definition: io/vtkoutputmodule.hh:174
VtkOutputModuleBase(const GridGeometry &gridGeometry, const std::string &name, const std::string ¶mGroup="", Dune::VTK::DataMode dm=Dune::VTK::conforming, bool verbose=true)
Definition: io/vtkoutputmodule.hh:75
Dune::VTK::DataMode dataMode() const
Definition: io/vtkoutputmodule.hh:197
Dune::VTKWriter< GridView > & writer()
Definition: io/vtkoutputmodule.hh:200
Dune::VTKSequenceWriter< GridView > & sequenceWriter()
Definition: io/vtkoutputmodule.hh:201
const std::string & name() const
Definition: io/vtkoutputmodule.hh:196
const std::vector< Field > & fields() const
Definition: io/vtkoutputmodule.hh:203
virtual ~VtkOutputModuleBase()=default
void addField(const Vector &v, const std::string &name, Dumux::Vtk::Precision precision, Vtk::FieldType fieldType=Vtk::FieldType::automatic)
Add a scalar or vector valued vtk field.
Definition: io/vtkoutputmodule.hh:126
bool verbose() const
Definition: io/vtkoutputmodule.hh:195
void addField(const Vector &v, const std::string &name, Vtk::FieldType fieldType=Vtk::FieldType::automatic)
Add a scalar or vector valued vtk field.
Definition: io/vtkoutputmodule.hh:110
const GridGeometry & gridGeometry() const
Definition: io/vtkoutputmodule.hh:193
export field type
Definition: io/vtkoutputmodule.hh:69
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: io/vtkoutputmodule.hh:309
const auto & problem() const
Definition: io/vtkoutputmodule.hh:390
const GridVariables & gridVariables() const
Definition: io/vtkoutputmodule.hh:391
void addVolumeVariable(std::function< VolVarsVector(const VolumeVariables &)> &&f, const std::string &name)
Definition: io/vtkoutputmodule.hh:382
VV VolumeVariables
export type of the volume variables for the outputfields
Definition: io/vtkoutputmodule.hh:337
void addVolumeVariable(std::function< Scalar(const VolumeVariables &)> &&f, const std::string &name)
Definition: io/vtkoutputmodule.hh:371
void addVelocityOutput(std::shared_ptr< VelocityOutputType > velocityOutput)
Add a velocity output policy.
Definition: io/vtkoutputmodule.hh:365
const VelocityOutput & velocityOutput() const
Definition: io/vtkoutputmodule.hh:399
const SolutionVector & sol() const
Definition: io/vtkoutputmodule.hh:393
const GridGeometry & gridGeometry() const
Definition: io/vtkoutputmodule.hh:392
VtkOutputModule(const GridVariables &gridVariables, const SolutionVector &sol, const std::string &name, const std::string ¶mGroup="", Dune::VTK::DataMode dm=Dune::VTK::conforming, bool verbose=true)
Definition: io/vtkoutputmodule.hh:339
const std::vector< VolVarScalarDataInfo > & volVarScalarDataInfo() const
Definition: io/vtkoutputmodule.hh:395
const std::vector< VolVarVectorDataInfo > & volVarVectorDataInfo() const
Definition: io/vtkoutputmodule.hh:396