309 using GridGeometry =
typename GridVariables::GridGeometry;
311 using VV =
typename GridVariables::VolumeVariables;
312 using Scalar =
typename GridVariables::Scalar;
314 using GridView =
typename GridGeometry::GridView;
317 dim = GridView::dimension,
318 dimWorld = GridView::dimensionworld
321 using Element =
typename GridView::template Codim<0>::Entity;
322 using VolVarsVector = Dune::FieldVector<Scalar, dimWorld>;
325 static constexpr int dofCodim = isBox ? dim : 0;
327 struct VolVarScalarDataInfo { std::function<Scalar(
const VV&)> get; std::string
name; Dumux::Vtk::Precision precision_; };
328 struct VolVarVectorDataInfo { std::function<VolVarsVector(
const VV&)> get; std::string
name; Dumux::Vtk::Precision precision_; };
329 using Field = Vtk::template Field<GridView>;
338 const SolutionVector&
sol,
339 const std::string&
name,
341 Dune::VTK::DataMode dm = Dune::VTK::conforming,
346 , velocityOutput_(std::make_shared<VelocityOutputType>())
367 const std::string&
name)
369 volVarScalarDataInfo_.push_back(VolVarScalarDataInfo{f,
name, this->
precision()});
376 template<
class VVV = VolVarsVector,
typename std::enable_if_t<(VVV::dimension > 1),
int> = 0>
378 const std::string&
name)
380 volVarVectorDataInfo_.push_back(VolVarVectorDataInfo{f,
name, this->
precision()});
385 const auto&
problem()
const {
return gridVariables_.curGridVolVars().problem(); }
387 const GridGeometry&
gridGeometry()
const {
return gridVariables_.gridGeometry(); }
388 const SolutionVector&
sol()
const {
return sol_; }
399 void writeConforming_(
double time, Dune::VTK::OutputType type)
override
401 const Dune::VTK::DataMode dm = Dune::VTK::conforming;
408 std::vector<VelocityVector> velocity(velocityOutput_->numFluidPhases());
412 std::vector<double> rank;
415 std::vector<std::vector<Scalar>> volVarScalarData;
416 std::vector<std::vector<VolVarsVector>> volVarVectorData;
419 if (!volVarScalarDataInfo_.empty()
420 || !volVarVectorDataInfo_.empty()
421 || !this->fields().empty()
422 || velocityOutput_->enableOutput()
425 const auto numCells =
gridGeometry().gridView().size(0);
426 const auto numDofs = numDofs_();
429 if (!volVarScalarDataInfo_.empty())
430 volVarScalarData.resize(volVarScalarDataInfo_.size(), std::vector<Scalar>(numDofs));
431 if (!volVarVectorDataInfo_.empty())
432 volVarVectorData.resize(volVarVectorDataInfo_.size(), std::vector<VolVarsVector>(numDofs));
434 if (velocityOutput_->enableOutput())
436 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
438 if(isBox && dim == 1)
439 velocity[phaseIdx].resize(numCells);
441 velocity[phaseIdx].resize(numDofs);
446 if (addProcessRank) rank.resize(numCells);
448 for (
const auto& element : elements(
gridGeometry().gridView(), Dune::Partitions::interior))
450 const auto eIdxGlobal =
gridGeometry().elementMapper().index(element);
453 auto elemVolVars =
localView(gridVariables_.curGridVolVars());
457 if (velocityOutput_->enableOutput())
459 fvGeometry.bind(element);
460 elemVolVars.bind(element, fvGeometry, sol_);
464 fvGeometry.bindElement(element);
465 elemVolVars.bindElement(element, fvGeometry, sol_);
468 if (!volVarScalarDataInfo_.empty()
469 || !volVarVectorDataInfo_.empty())
471 for (
auto&& scv : scvs(fvGeometry))
473 const auto dofIdxGlobal = scv.dofIndex();
474 const auto& volVars = elemVolVars[scv];
477 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
478 volVarScalarData[i][dofIdxGlobal] = volVarScalarDataInfo_[i].get(volVars);
481 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
482 volVarVectorData[i][dofIdxGlobal] = volVarVectorDataInfo_[i].get(volVars);
487 if (velocityOutput_->enableOutput())
489 auto elemFluxVarsCache =
localView(gridVariables_.gridFluxVarsCache());
490 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
492 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
493 velocityOutput_->calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
498 rank[eIdxGlobal] =
static_cast<double>(
gridGeometry().gridView().comm().rank());
508 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
510 volVarScalarDataInfo_[i].
name, 1, dim, dm, this->
precision()).get() );
511 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
513 volVarVectorDataInfo_[i].
name, dimWorld, dim, dm, this->
precision()).get() );
517 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
519 volVarScalarDataInfo_[i].
name, 1, 0,dm, this->
precision()).get() );
520 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
522 volVarVectorDataInfo_[i].
name, dimWorld, 0,dm, this->
precision()).get() );
526 if (velocityOutput_->enableOutput())
528 if (isBox && dim > 1)
530 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
532 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
533 dimWorld, dim, dm, this->precision()).get() );
538 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
540 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
541 dimWorld, 0, dm, this->precision()).get() );
550 for (
auto&& field : this->
fields())
552 if (field.codim() == 0)
554 else if (field.codim() == dim)
557 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
573 void writeNonConforming_(
double time, Dune::VTK::OutputType type)
override
575 const Dune::VTK::DataMode dm = Dune::VTK::nonconforming;
578 DUNE_THROW(Dune::InvalidStateException,
"Non-conforming output makes no sense for cell-centered schemes!");
586 if (enableVelocityOutput ==
true && !velocityOutput_->enableOutput())
587 std::cerr <<
"Warning! Velocity output was enabled in the input file"
588 <<
" but no velocity output policy was set for the VTK output module:"
589 <<
" There will be no velocity output."
590 <<
" Use the addVelocityOutput member function of the VTK output module." << std::endl;
592 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 auto elemFluxVarsCache =
localView(gridVariables_.gridFluxVarsCache());
682 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
684 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
685 velocityOutput_->calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
690 rank[eIdxGlobal] =
static_cast<double>(
gridGeometry().gridView().comm().rank());
698 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
700 volVarScalarDataInfo_[i].
name, 1, dim, dm, this->
precision()).get() );
702 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
704 volVarVectorDataInfo_[i].
name, dimWorld, dim, dm, this->
precision()).get() );
707 if (velocityOutput_->enableOutput())
711 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
713 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
714 dimWorld, dim, dm, this->precision()).get() );
718 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
720 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
721 dimWorld, 0,dm, this->precision()).get());
729 for (
auto&& field : this->
fields())
731 if (field.codim() == 0)
733 else if (field.codim() == dim)
736 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
752 std::size_t numDofs_()
const {
return dofCodim == dim ?
gridGeometry().vertexMapper().size() :
gridGeometry().elementMapper().size(); }
754 const GridVariables& gridVariables_;
755 const SolutionVector& sol_;
757 std::vector<VolVarScalarDataInfo> volVarScalarDataInfo_;
758 std::vector<VolVarVectorDataInfo> volVarVectorDataInfo_;
760 std::shared_ptr<VelocityOutput> velocityOutput_;