302 using GridGeometry =
typename GridVariables::GridGeometry;
304 using VV =
typename GridVariables::VolumeVariables;
305 using Scalar =
typename GridVariables::Scalar;
307 using GridView =
typename GridGeometry::GridView;
310 dim = GridView::dimension,
311 dimWorld = GridView::dimensionworld
314 using Element =
typename GridView::template Codim<0>::Entity;
315 using VolVarsVector = Dune::FieldVector<Scalar, dimWorld>;
321 struct VolVarScalarDataInfo { std::function<Scalar(
const VV&)> get; std::string name; Dumux::Vtk::Precision precision_; };
322 struct VolVarVectorDataInfo { std::function<VolVarsVector(
const VV&)> get; std::string name; Dumux::Vtk::Precision precision_; };
333 const SolutionVector&
sol,
334 const std::string&
name,
336 Dune::VTK::DataMode dm = Dune::VTK::conforming,
343 enableVelocityOutput_ = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddVelocity",
false);
344 addProcessRank_ = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddProcessRank",
true);
365 const std::string&
name)
367 volVarScalarDataInfo_.push_back(VolVarScalarDataInfo{f,
name, this->
precision()});
374 template<
class VVV = VolVarsVector,
typename std::enable_if_t<(VVV::dimension > 1),
int> = 0>
376 const std::string&
name)
378 volVarVectorDataInfo_.push_back(VolVarVectorDataInfo{f,
name, this->
precision()});
383 const auto&
problem()
const {
return gridVariables_.curGridVolVars().problem(); }
385 const GridGeometry&
gridGeometry()
const {
return gridVariables_.gridGeometry(); }
386 const SolutionVector&
sol()
const {
return sol_; }
397 void writeConforming_(
double time, Dune::VTK::OutputType type)
override
399 const Dune::VTK::DataMode dm = Dune::VTK::conforming;
406 std::vector<VelocityVector> velocity(velocityOutput_->numFluidPhases());
409 std::vector<double> rank;
412 std::vector<std::vector<Scalar>> volVarScalarData;
413 std::vector<std::vector<VolVarsVector>> volVarVectorData;
416 if (!volVarScalarDataInfo_.empty()
417 || !volVarVectorDataInfo_.empty()
418 || !this->fields().empty()
419 || velocityOutput_->enableOutput()
422 const auto numCells =
gridGeometry().gridView().size(0);
423 const auto numDofs = numDofs_();
426 if (!volVarScalarDataInfo_.empty())
427 volVarScalarData.resize(volVarScalarDataInfo_.size(), std::vector<Scalar>(numDofs));
428 if (!volVarVectorDataInfo_.empty())
429 volVarVectorData.resize(volVarVectorDataInfo_.size(), std::vector<VolVarsVector>(numDofs));
431 if (velocityOutput_->enableOutput())
433 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
436 velocity[phaseIdx].resize(numCells);
438 velocity[phaseIdx].resize(numDofs);
441 if(isBox && dim == 1)
442 velocity[phaseIdx].resize(numCells);
444 velocity[phaseIdx].resize(numDofs);
450 if (addProcessRank_) rank.resize(numCells);
453 auto elemVolVars =
localView(gridVariables_.curGridVolVars());
454 for (
const auto& element : elements(
gridGeometry().gridView(),
Dune::Partitions::interior))
456 const auto eIdxGlobal =
gridGeometry().elementMapper().index(element);
459 if (velocityOutput_->enableOutput())
461 fvGeometry.bind(element);
462 elemVolVars.bind(element, fvGeometry, sol_);
466 fvGeometry.bindElement(element);
467 elemVolVars.bindElement(element, fvGeometry, sol_);
470 if (!volVarScalarDataInfo_.empty() || !volVarVectorDataInfo_.empty())
472 for (
const auto& scv : scvs(fvGeometry))
474 const auto dofIdxGlobal = scv.dofIndex();
475 const auto& volVars = elemVolVars[scv];
478 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
479 volVarScalarData[i][dofIdxGlobal] = volVarScalarDataInfo_[i].get(volVars);
482 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
483 volVarVectorData[i][dofIdxGlobal] = volVarVectorDataInfo_[i].get(volVars);
488 if (velocityOutput_->enableOutput())
490 const auto elemFluxVarsCache =
localView(gridVariables_.gridFluxVarsCache()).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());
506 if constexpr (isBox || isPQ1Bubble)
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() );
515 if constexpr (isPQ1Bubble)
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() );
528 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
530 volVarScalarDataInfo_[i].name, 1, 0,dm, this->
precision()).get() );
531 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
533 volVarVectorDataInfo_[i].name, dimWorld, 0,dm, this->
precision()).get() );
537 if (velocityOutput_->enableOutput())
542 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
544 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
545 dimWorld, dim, dm, this->
precision()).get() );
550 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
552 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
553 dimWorld, 0, dm, this->
precision()).get() );
562 for (
auto&& field : this->
fields())
564 if (field.codim() == 0)
566 else if (field.codim() == dim)
569 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
585 void writeNonConforming_(
double time, Dune::VTK::OutputType type)
override
587 const Dune::VTK::DataMode dm = Dune::VTK::nonconforming;
590 if(!isBox && !isDiamond)
591 DUNE_THROW(Dune::NotImplemented,
592 "Non-conforming output for discretization scheme " << GridGeometry::discMethod
600 if (enableVelocityOutput_ && !velocityOutput_->enableOutput())
601 std::cerr <<
"Warning! Velocity output was enabled in the input file"
602 <<
" but no velocity output policy was set for the VTK output module:"
603 <<
" There will be no velocity output."
604 <<
" Use the addVelocityOutput member function of the VTK output module." << std::endl;
606 std::vector<VelocityVector> velocity(velocityOutput_->numFluidPhases());
609 std::vector<double> rank;
612 using ScalarDataContainer = std::vector< std::vector<Scalar> >;
613 using VectorDataContainer = std::vector< std::vector<VolVarsVector> >;
614 std::vector< ScalarDataContainer > volVarScalarData;
615 std::vector< VectorDataContainer > volVarVectorData;
618 if (!volVarScalarDataInfo_.empty()
619 || !volVarVectorDataInfo_.empty()
620 || !this->fields().empty()
621 || velocityOutput_->enableOutput()
624 const auto numCells =
gridGeometry().gridView().size(0);
625 const auto outputSize = numDofs_();
628 if (!volVarScalarDataInfo_.empty())
629 volVarScalarData.resize(volVarScalarDataInfo_.size(), ScalarDataContainer(numCells));
630 if (!volVarVectorDataInfo_.empty())
631 volVarVectorData.resize(volVarVectorDataInfo_.size(), VectorDataContainer(numCells));
633 if (velocityOutput_->enableOutput())
635 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
637 if((isBox && dim == 1) || isDiamond)
638 velocity[phaseIdx].resize(numCells);
640 velocity[phaseIdx].resize(outputSize);
645 if (addProcessRank_) rank.resize(numCells);
649 auto elemVolVars =
localView(gridVariables_.curGridVolVars());
650 for (
const auto& element : elements(
gridGeometry().gridView(),
Dune::Partitions::interior))
652 const auto eIdxGlobal =
gridGeometry().elementMapper().index(element);
655 if (velocityOutput_->enableOutput())
657 fvGeometry.bind(element);
658 elemVolVars.bind(element, fvGeometry, sol_);
662 fvGeometry.bindElement(element);
663 elemVolVars.bindElement(element, fvGeometry, sol_);
666 const auto numLocalDofs = fvGeometry.numScv();
668 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
669 volVarScalarData[i][eIdxGlobal].resize(numLocalDofs);
670 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
671 volVarVectorData[i][eIdxGlobal].resize(numLocalDofs);
673 if (!volVarScalarDataInfo_.empty() || !volVarVectorDataInfo_.empty())
675 for (
const auto& scv : scvs(fvGeometry))
677 const auto& volVars = elemVolVars[scv];
680 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
681 volVarScalarData[i][eIdxGlobal][scv.localDofIndex()] = volVarScalarDataInfo_[i].get(volVars);
684 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
685 volVarVectorData[i][eIdxGlobal][scv.localDofIndex()] = volVarVectorDataInfo_[i].get(volVars);
690 if (velocityOutput_->enableOutput())
692 const auto elemFluxVarsCache =
localView(gridVariables_.gridFluxVarsCache()).bind(element, fvGeometry, elemVolVars);
693 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
694 velocityOutput_->calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
699 rank[eIdxGlobal] =
static_cast<double>(
gridGeometry().gridView().comm().rank());
707 static constexpr int dofLocCodim = isDiamond ? 1 : dim;
708 for (std::size_t i = 0; i < volVarScalarDataInfo_.size(); ++i)
711 volVarScalarData[i], volVarScalarDataInfo_[i].
name,
715 for (std::size_t i = 0; i < volVarVectorDataInfo_.size(); ++i)
718 volVarVectorData[i], volVarVectorDataInfo_[i].
name,
719 dimWorld, dofLocCodim, dm, this->
precision()
723 if (velocityOutput_->enableOutput())
726 if (dim > 1 && !isDiamond)
727 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
730 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
731 dimWorld, dofLocCodim, dm, this->precision()
736 for (
int phaseIdx = 0; phaseIdx < velocityOutput_->numFluidPhases(); ++phaseIdx)
739 "velocity_" + velocityOutput_->phaseName(phaseIdx) +
" (m/s)",
740 dimWorld, 0, dm, this->precision()
749 rank,
"process rank", 1, 0
753 for (
const auto& field : this->
fields())
755 if (field.codim() == 0)
757 else if (field.codim() == dim || field.codim() == 1)
760 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
775 std::size_t numDofs_()
const
779 if constexpr (isBox || isDiamond || isPQ1Bubble)
785 const GridVariables& gridVariables_;
786 const SolutionVector& sol_;
788 std::vector<VolVarScalarDataInfo> volVarScalarDataInfo_;
789 std::vector<VolVarVectorDataInfo> volVarVectorDataInfo_;
791 std::shared_ptr<VelocityOutput> velocityOutput_;
792 bool enableVelocityOutput_ =
false;
793 bool addProcessRank_ =
true;