25#ifndef POROUSMEDIUMFLOW_BOXDFM_VTK_OUTPUT_MODULE_HH
26#define POROUSMEDIUMFLOW_BOXDFM_VTK_OUTPUT_MODULE_HH
30#include <dune/grid/common/gridfactory.hh>
31#include <dune/geometry/referenceelements.hh>
32#include <dune/grid/common/mcmgmapper.hh>
55template<
class Gr
idVariables,
class SolutionVector,
class FractureGr
id>
59 using GridGeometry =
typename GridVariables::GridGeometry;
60 using VV =
typename GridVariables::VolumeVariables;
61 using FluidSystem =
typename VV::FluidSystem;
62 using Scalar =
typename GridVariables::Scalar;
64 using GridView =
typename GridGeometry::GridView;
65 using FractureGridView =
typename FractureGrid::LeafGridView;
66 using FractureMapper = Dune::MultipleCodimMultipleGeomTypeMapper<FractureGridView>;
70 dim = GridView::dimension,
71 dimWorld = GridView::dimensionworld
74 using GridIndexType =
typename GridView::IndexSet::IndexType;
75 using Element =
typename GridView::template Codim<0>::Entity;
76 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
77 using ReferenceElements =
typename Dune::ReferenceElements<typename GridView::ctype, dim>;
79 using Field = Vtk::template Field<GridView>;
80 using FractureField = Vtk::template Field<FractureGridView>;
82 static_assert(dim > 1,
"Box-Dfm output only works for dim > 1");
83 static_assert(FractureGrid::dimension == int(dim-1),
"Fracture grid must be of codimension one!");
84 static_assert(FractureGrid::dimensionworld == int(dimWorld),
"Fracture grid has to has the same coordinate dimension!");
85 static_assert(GridGeometry::discMethod ==
DiscretizationMethod::box,
"Box-Dfm output module can only be used with the box scheme!");
89 template<
class FractureGr
idAdapter >
91 const SolutionVector&
sol,
92 const std::string&
name,
93 const FractureGridAdapter& fractureGridAdapter,
95 Dune::VTK::DataMode dm = Dune::VTK::conforming,
100 initializeFracture_(fractureGridAdapter);
112 void write(
double time, Dune::VTK::OutputType type = Dune::VTK::ascii)
118 if (dm == Dune::VTK::conforming)
119 writeConforming_(time, type);
120 else if (dm == Dune::VTK::nonconforming)
121 writeNonConforming_(time, type);
123 DUNE_THROW(Dune::NotImplemented,
"Output for provided vtk data mode");
128 std::cout <<
"Writing output for problem \"" << this->
name() <<
"\". Took " << timer.elapsed() <<
" seconds." << std::endl;
133 void writeConforming_(
double time, Dune::VTK::OutputType type)
140 std::vector<typename ParentType::VelocityOutput::VelocityVector> velocity;
143 static bool addProcessRank = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddProcessRank");
144 std::vector<double> rank;
147 std::vector<std::vector<Scalar>> volVarScalarData;
148 std::vector<std::vector<Scalar>> volVarScalarDataFracture;
149 std::vector<std::vector<GlobalPosition>> volVarVectorData;
150 std::vector<std::vector<GlobalPosition>> volVarVectorDataFracture;
154 const auto& fractureGridView = fractureGrid_->leafGridView();
161 || !this->fields().empty()
162 || this->velocityOutput().enableOutput()
165 const auto numCells = gridView.size(0);
166 const auto numDofs = gridView.size(dim);
167 const auto numFractureVert = fractureGridView.size(FractureGridView::dimension);
173 volVarScalarDataFracture.resize(
volVarScalarDataInfo.size(), std::vector<Scalar>(numFractureVert));
178 volVarVectorDataFracture.resize(
volVarVectorDataInfo.size(), std::vector<GlobalPosition>(numFractureVert));
183 velocity[phaseIdx].resize(numDofs);
186 if (addProcessRank) rank.resize(numCells);
188 for (
const auto& element : elements(gridView, Dune::Partitions::interior))
190 const auto eIdxGlobal = this->
gridGeometry().elementMapper().index(element);
199 fvGeometry.bind(element);
200 elemVolVars.bind(element, fvGeometry, this->
sol());
204 fvGeometry.bindElement(element);
205 elemVolVars.bindElement(element, fvGeometry, this->
sol());
210 for (
auto&& scv : scvs(fvGeometry))
212 const auto dofIdxGlobal = scv.dofIndex();
213 const auto& volVars = elemVolVars[scv];
215 if (!scv.isOnFracture())
225 volVarScalarDataFracture[i][vertexToFractureVertexIdx_[dofIdxGlobal]] =
volVarScalarDataInfo[i].get(volVars);
227 volVarVectorDataFracture[i][vertexToFractureVertexIdx_[dofIdxGlobal]] =
volVarVectorDataInfo[i].get(volVars);
236 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
244 rank[eIdxGlobal] =
static_cast<double>(gridView.comm().rank());
262 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureVertexMapper_, volVarVectorDataFracture[i],
271 "velocity_" + std::string(this->
velocityOutput().phaseName(phaseIdx)) +
" (m/s)",
272 dimWorld, dim).get() );
278 "process rank", 1, 0).get() );
281 for (
auto&& field : this->
fields())
283 if (field.codim() == 0)
285 else if (field.codim() == dim)
288 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
296 fractureSequenceWriter_->write(time, type);
302 fractureWriter_->clear();
306 void writeNonConforming_(
double time, Dune::VTK::OutputType type)
313 std::vector<typename ParentType::VelocityOutput::VelocityVector> velocity;
316 static bool addProcessRank = getParamFromGroup<bool>(this->
paramGroup(),
"Vtk.AddProcessRank");
317 std::vector<double> rank;
320 using ScalarDataContainer = std::vector< std::vector<Scalar> >;
321 using VectorDataContainer = std::vector< std::vector<GlobalPosition> >;
322 std::vector< ScalarDataContainer > volVarScalarData;
323 std::vector< ScalarDataContainer > volVarScalarDataFracture;
324 std::vector< VectorDataContainer > volVarVectorData;
325 std::vector< VectorDataContainer > volVarVectorDataFracture;
329 const auto& fractureGridView = fractureGrid_->leafGridView();
336 || !this->fields().empty()
337 || this->velocityOutput().enableOutput()
340 const auto numCells = gridView.size(0);
341 const auto numDofs = gridView.size(dim);
342 const auto numFractureCells = fractureGridView.size(0);
348 volVarScalarDataFracture.resize(
volVarScalarDataInfo.size(), ScalarDataContainer(numFractureCells));
353 volVarVectorDataFracture.resize(
volVarVectorDataInfo.size(), VectorDataContainer(numFractureCells));
358 velocity[phaseIdx].resize(numDofs);
361 if (addProcessRank) rank.resize(numCells);
363 for (
const auto& element : elements(gridView, Dune::Partitions::interior))
365 const auto eIdxGlobal = this->
gridGeometry().elementMapper().index(element);
366 const auto numCorners = element.subEntities(dim);
373 volVarScalarData[i][eIdxGlobal].resize(numCorners);
375 volVarVectorData[i][eIdxGlobal].resize(numCorners);
381 fvGeometry.bind(element);
382 elemVolVars.bind(element, fvGeometry, this->
sol());
386 fvGeometry.bindElement(element);
387 elemVolVars.bindElement(element, fvGeometry, this->
sol());
392 for (
auto&& scv : scvs(fvGeometry))
394 const auto& volVars = elemVolVars[scv];
396 if (!scv.isOnFracture())
405 const auto fIdx = scv.facetIndexInElement();
406 const auto& localMap = fractureElementMap_[eIdxGlobal];
407 const auto fracEIdx = std::find_if(localMap.begin(), localMap.end(), [fIdx] (
const auto& p) { return p.first == fIdx; })->second;
420 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
428 rank[eIdxGlobal] =
static_cast<double>(gridView.comm().rank());
441 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureElementMapper_, volVarScalarDataFracture[i],
451 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureElementMapper_, volVarVectorDataFracture[i],
461 "velocity_" + std::string(this->
velocityOutput().phaseName(phaseIdx)) +
" (m/s)",
462 dimWorld, dim).get() );
468 "process rank", 1, 0).get() );
471 for (
auto&& field : this->
fields())
473 if (field.codim() == 0)
475 else if (field.codim() == dim)
478 DUNE_THROW(Dune::RangeError,
"Cannot add wrongly sized vtk scalar field!");
486 fractureSequenceWriter_->write(time, type);
492 fractureWriter_->clear();
496 template<
class FractureGr
idAdapter >
497 void initializeFracture_(
const FractureGridAdapter& fractureGridAdapter)
501 Dune::GridFactory<FractureGrid> gridFactory;
504 std::size_t fracVertexCount = 0;
505 vertexToFractureVertexIdx_.resize(gridView.size(dim));
506 for (
const auto& v : vertices(gridView))
508 if (fractureGridAdapter.isOnFacetGrid(v))
510 gridFactory.insertVertex(v.geometry().center());
511 vertexToFractureVertexIdx_[
gridGeometry.vertexMapper().index(v)] = fracVertexCount++;
516 std::size_t fractureElementCount = 0;
517 fractureElementMap_.resize(gridView.size(0));
518 std::set< std::pair<GridIndexType, unsigned int> > handledFacets;
519 for (
const auto& element : elements(gridView))
521 const auto eIdxGlobal =
gridGeometry.elementMapper().index(element);
522 const auto referenceElement = ReferenceElements::general(element.type());
524 for (
const auto& is : intersections(gridView, element))
527 const auto& isGeometry = is.geometry();
528 const auto numCorners = isGeometry.corners();
529 const auto indexInInside = is.indexInInside();
531 std::vector<GridIndexType> isVertexIndices(numCorners);
532 for (
unsigned int i = 0; i < numCorners; ++i)
533 isVertexIndices[i] =
gridGeometry.vertexMapper().subIndex(element,
534 referenceElement.subEntity(indexInInside, 1, i, dim),
538 bool insertFacet =
false;
539 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
545 const auto outsideEIdx =
gridGeometry.elementMapper().index(is.outside());
546 const auto idxInOutside = is.indexInOutside();
547 const auto pair = std::make_pair(outsideEIdx, idxInOutside);
548 if (handledFacets.count( pair ) != 0)
553 const auto& outsideMap = fractureElementMap_[outsideEIdx];
554 auto it = std::find_if(outsideMap.begin(), outsideMap.end(), [idxInOutside] (
const auto& p) { return p.first == idxInOutside; });
555 fractureElementMap_[eIdxGlobal].push_back( std::make_pair(indexInInside, it->second) );
563 std::for_each( isVertexIndices.begin(),
564 isVertexIndices.end(),
565 [&] (
auto& idx) { idx = this->vertexToFractureVertexIdx_[idx]; } );
568 gridFactory.insertElement(isGeometry.type(), isVertexIndices);
571 handledFacets.insert( std::make_pair(eIdxGlobal, indexInInside) );
572 fractureElementMap_[eIdxGlobal].push_back( std::make_pair(indexInInside, fractureElementCount) );
573 fractureElementCount++;
579 fractureGrid_ = std::shared_ptr<FractureGrid>(gridFactory.createGrid());
582 const auto& fractureGridView = fractureGrid_->leafGridView();
583 fractureVertexMapper_ = std::make_unique<FractureMapper>(fractureGridView, Dune::mcmgVertexLayout());
584 fractureElementMapper_ = std::make_unique<FractureMapper>(fractureGridView, Dune::mcmgElementLayout());
587 std::vector<GridIndexType> insToVertexIdx(fractureGridView.size(FractureGridView::dimension));
588 std::vector<GridIndexType> insToElemIdx(fractureGridView.size(0));
589 for (
const auto& v : vertices(fractureGridView)) insToVertexIdx[ gridFactory.insertionIndex(v) ] = fractureVertexMapper_->index(v);
590 for (
const auto& e : elements(fractureGridView)) insToElemIdx[ gridFactory.insertionIndex(e) ] = fractureElementMapper_->index(e);
593 for (GridIndexType dofIdx = 0; dofIdx < gridView.size(GridView::dimension); ++dofIdx)
595 vertexToFractureVertexIdx_[dofIdx] = insToVertexIdx[ vertexToFractureVertexIdx_[dofIdx] ];
598 for (
auto& elemLocalMap : fractureElementMap_)
599 for (
auto& dataPair : elemLocalMap)
600 dataPair.second = insToElemIdx[ dataPair.second ];
603 fractureWriter_ = std::make_shared< Dune::VTKWriter<FractureGridView> >(fractureGridView, this->
dataMode());
604 fractureSequenceWriter_ = std::make_unique< Dune::VTKSequenceWriter<FractureGridView> >(fractureWriter_, this->
name() +
"_fracture");
607 std::shared_ptr<FractureGrid> fractureGrid_;
609 std::unique_ptr<FractureMapper> fractureVertexMapper_;
610 std::unique_ptr<FractureMapper> fractureElementMapper_;
612 std::shared_ptr<Dune::VTKWriter<FractureGridView>> fractureWriter_;
613 std::unique_ptr< Dune::VTKSequenceWriter<FractureGridView> > fractureSequenceWriter_;
616 std::vector<GridIndexType> vertexToFractureVertexIdx_;
619 std::vector< std::vector<std::pair<GridIndexType, unsigned int>> > fractureElementMap_;
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
virtual int numFluidPhases() const
returns the number of phases
Definition: io/velocityoutput.hh:67
virtual void calculateVelocity(VelocityVector &velocity, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVarsCache &elemFluxVarsCache, int phaseIdx) const
Definition: io/velocityoutput.hh:71
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: io/vtkoutputmodule.hh:60
const std::string & paramGroup() const
the parameter group for getting parameter from the parameter tree
Definition: io/vtkoutputmodule.hh:100
Dune::VTK::DataMode dataMode() const
Definition: io/vtkoutputmodule.hh:202
Dune::VTKWriter< GridView > & writer()
Definition: io/vtkoutputmodule.hh:205
Dune::VTKSequenceWriter< GridView > & sequenceWriter()
Definition: io/vtkoutputmodule.hh:206
const std::string & name() const
Definition: io/vtkoutputmodule.hh:201
const std::vector< Field > & fields() const
Definition: io/vtkoutputmodule.hh:208
bool verbose() const
Definition: io/vtkoutputmodule.hh:200
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: io/vtkoutputmodule.hh:313
const GridVariables & gridVariables() const
Definition: io/vtkoutputmodule.hh:392
const VelocityOutput & velocityOutput() const
Definition: io/vtkoutputmodule.hh:400
const SolutionVector & sol() const
Definition: io/vtkoutputmodule.hh:394
const GridGeometry & gridGeometry() const
Definition: io/vtkoutputmodule.hh:393
const std::vector< VolVarScalarDataInfo > & volVarScalarDataInfo() const
Definition: io/vtkoutputmodule.hh:396
const std::vector< VolVarVectorDataInfo > & volVarVectorDataInfo() const
Definition: io/vtkoutputmodule.hh:397
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: porousmediumflow/boxdfm/vtkoutputmodule.hh:57
void write(double time, Dune::VTK::OutputType type=Dune::VTK::ascii)
Writing data.
Definition: porousmediumflow/boxdfm/vtkoutputmodule.hh:112
BoxDfmVtkOutputModule(const GridVariables &gridVariables, const SolutionVector &sol, const std::string &name, const FractureGridAdapter &fractureGridAdapter, const std::string ¶mGroup="", Dune::VTK::DataMode dm=Dune::VTK::conforming, bool verbose=true)
The constructor.
Definition: porousmediumflow/boxdfm/vtkoutputmodule.hh:90
A VTK output module to simplify writing dumux simulation data to VTK format.