3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
porousmediumflow/boxdfm/vtkoutputmodule.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef POROUSMEDIUMFLOW_BOXDFM_VTK_OUTPUT_MODULE_HH
26#define POROUSMEDIUMFLOW_BOXDFM_VTK_OUTPUT_MODULE_HH
27
28#include <set>
29
30#include <dune/grid/common/gridfactory.hh>
31#include <dune/grid/common/mcmgmapper.hh>
32
34
35namespace Dumux {
36
54template<class GridVariables, class SolutionVector, class FractureGrid>
55class BoxDfmVtkOutputModule : public VtkOutputModule<GridVariables, SolutionVector>
56{
58 using GridGeometry = typename GridVariables::GridGeometry;
59 using VV = typename GridVariables::VolumeVariables;
60 using FluidSystem = typename VV::FluidSystem;
61 using Scalar = typename GridVariables::Scalar;
62
63 using GridView = typename GridGeometry::GridView;
64 using FractureGridView = typename FractureGrid::LeafGridView;
65 using FractureMapper = Dune::MultipleCodimMultipleGeomTypeMapper<FractureGridView>;
66
67 enum
68 {
69 dim = GridView::dimension,
70 dimWorld = GridView::dimensionworld
71 };
72
73 using GridIndexType = typename GridView::IndexSet::IndexType;
74 using Element = typename GridView::template Codim<0>::Entity;
75 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
76
77 using Field = Vtk::template Field<GridView>;
78 using FractureField = Vtk::template Field<FractureGridView>;
79
80 static_assert(dim > 1, "Box-Dfm output only works for dim > 1");
81 static_assert(FractureGrid::dimension == int(dim-1), "Fracture grid must be of codimension one!");
82 static_assert(FractureGrid::dimensionworld == int(dimWorld), "Fracture grid has to has the same coordinate dimension!");
83 static_assert(GridGeometry::discMethod == DiscretizationMethod::box, "Box-Dfm output module can only be used with the box scheme!");
84public:
85
87 template< class FractureGridAdapter >
89 const SolutionVector& sol,
90 const std::string& name,
91 const FractureGridAdapter& fractureGridAdapter,
92 const std::string& paramGroup = "",
93 Dune::VTK::DataMode dm = Dune::VTK::conforming,
94 bool verbose = true)
96 {
97 // create the fracture grid and all objects needed on it
98 initializeFracture_(fractureGridAdapter);
99 }
100
104
110 void write(double time, Dune::VTK::OutputType type = Dune::VTK::ascii)
111 {
112 Dune::Timer timer;
113
114 // write to file depending on data mode
115 const auto dm = this->dataMode();
116 if (dm == Dune::VTK::conforming)
117 writeConforming_(time, type);
118 else if (dm == Dune::VTK::nonconforming)
119 writeNonConforming_(time, type);
120 else
121 DUNE_THROW(Dune::NotImplemented, "Output for provided vtk data mode");
122
124 timer.stop();
125 if (this->verbose())
126 std::cout << "Writing output for problem \"" << this->name() << "\". Took " << timer.elapsed() << " seconds." << std::endl;
127 }
128
129private:
131 void writeConforming_(double time, Dune::VTK::OutputType type)
132 {
136
137 // instatiate the velocity output
138 std::vector<typename ParentType::VelocityOutput::VelocityVector> velocity;
139
140 // process rank
141 static bool addProcessRank = getParamFromGroup<bool>(this->paramGroup(), "Vtk.AddProcessRank");
142 std::vector<double> rank;
143
144 // volume variable data
145 std::vector<std::vector<Scalar>> volVarScalarData;
146 std::vector<std::vector<Scalar>> volVarScalarDataFracture;
147 std::vector<std::vector<GlobalPosition>> volVarVectorData;
148 std::vector<std::vector<GlobalPosition>> volVarVectorDataFracture;
149
150 // some references for convenience
151 const auto& gridView = this->gridGeometry().gridView();
152 const auto& fractureGridView = fractureGrid_->leafGridView();
153 const auto& volVarScalarDataInfo = this->volVarScalarDataInfo();
154 const auto& volVarVectorDataInfo = this->volVarVectorDataInfo();
155
157 if (!volVarScalarDataInfo.empty()
158 || !volVarVectorDataInfo.empty()
159 || !this->fields().empty()
160 || this->velocityOutput().enableOutput()
161 || addProcessRank)
162 {
163 const auto numCells = gridView.size(0);
164 const auto numDofs = gridView.size(dim);
165 const auto numFractureVert = fractureGridView.size(FractureGridView::dimension);
166
167 // get fields for all volume variables
168 if (!this->volVarScalarDataInfo().empty())
169 {
170 volVarScalarData.resize(volVarScalarDataInfo.size(), std::vector<Scalar>(numDofs));
171 volVarScalarDataFracture.resize(volVarScalarDataInfo.size(), std::vector<Scalar>(numFractureVert));
172 }
173 if (!this->volVarVectorDataInfo().empty())
174 {
175 volVarVectorData.resize(volVarVectorDataInfo.size(), std::vector<GlobalPosition>(numDofs));
176 volVarVectorDataFracture.resize(volVarVectorDataInfo.size(), std::vector<GlobalPosition>(numFractureVert));
177 }
178
179 if (this->velocityOutput().enableOutput())
180 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
181 velocity[phaseIdx].resize(numDofs);
182
183 // maybe allocate space for the process rank
184 if (addProcessRank) rank.resize(numCells);
185
186 for (const auto& element : elements(gridView, Dune::Partitions::interior))
187 {
188 const auto eIdxGlobal = this->gridGeometry().elementMapper().index(element);
189
190 auto fvGeometry = localView(this->gridGeometry());
191 auto elemVolVars = localView(this->gridVariables().curGridVolVars());
192
193 // If velocity output is enabled we need to bind to the whole stencil
194 // otherwise element-local data is sufficient
195 if (this->velocityOutput().enableOutput())
196 {
197 fvGeometry.bind(element);
198 elemVolVars.bind(element, fvGeometry, this->sol());
199 }
200 else
201 {
202 fvGeometry.bindElement(element);
203 elemVolVars.bindElement(element, fvGeometry, this->sol());
204 }
205
206 if (!volVarScalarDataInfo.empty() || !volVarVectorDataInfo.empty())
207 {
208 for (auto&& scv : scvs(fvGeometry))
209 {
210 const auto dofIdxGlobal = scv.dofIndex();
211 const auto& volVars = elemVolVars[scv];
212
213 if (!scv.isOnFracture())
214 {
215 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
216 volVarScalarData[i][dofIdxGlobal] = volVarScalarDataInfo[i].get(volVars);
217 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
218 volVarVectorData[i][dofIdxGlobal] = volVarVectorDataInfo[i].get(volVars);
219 }
220 else
221 {
222 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
223 volVarScalarDataFracture[i][vertexToFractureVertexIdx_[dofIdxGlobal]] = volVarScalarDataInfo[i].get(volVars);
224 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
225 volVarVectorDataFracture[i][vertexToFractureVertexIdx_[dofIdxGlobal]] = volVarVectorDataInfo[i].get(volVars);
226 }
227 }
228 }
229
230 // velocity output
231 if (this->velocityOutput().enableOutput())
232 {
233 auto elemFluxVarsCache = localView(this->gridVariables().gridFluxVarsCache());
234 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
235
236 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
237 this->velocityOutput().calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
238 }
239
241 if (addProcessRank)
242 rank[eIdxGlobal] = static_cast<double>(gridView.comm().rank());
243 }
244
248
249 // volume variables if any
250 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
251 {
252 this->sequenceWriter().addVertexData(volVarScalarData[i], volVarScalarDataInfo[i].name);
253 fractureSequenceWriter_->addVertexData(volVarScalarDataFracture[i], volVarScalarDataInfo[i].name);
254 }
255
256 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
257 {
258 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().vertexMapper(), volVarVectorData[i],
259 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim).get() );
260 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureVertexMapper_, volVarVectorDataFracture[i],
261 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim-1).get() );
262 }
263
264 // the velocity field
265 if (this->velocityOutput().enableOutput())
266 {
267 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
268 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().vertexMapper(), velocity[phaseIdx],
269 "velocity_" + std::string(this->velocityOutput().phaseName(phaseIdx)) + " (m/s)",
270 /*numComp*/dimWorld, /*codim*/dim).get() );
271 }
272
273 // the process rank
274 if (addProcessRank)
275 this->sequenceWriter().addCellData( Field(gridView, this->gridGeometry().elementMapper(), rank,
276 "process rank", /*numComp*/1, /*codim*/0).get() );
277
278 // also register additional (non-standardized) user fields if any (only on matrix grid)
279 for (auto&& field : this->fields())
280 {
281 if (field.codim() == 0)
282 this->sequenceWriter().addCellData(field.get());
283 else if (field.codim() == dim)
284 this->sequenceWriter().addVertexData(field.get());
285 else
286 DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk scalar field!");
287 }
288 }
289
293 this->sequenceWriter().write(time, type);
294 fractureSequenceWriter_->write(time, type);
295
299 this->writer().clear();
300 fractureWriter_->clear();
301 }
302
304 void writeNonConforming_(double time, Dune::VTK::OutputType type)
305 {
309
310 // instatiate the velocity output
311 std::vector<typename ParentType::VelocityOutput::VelocityVector> velocity;
312
313 // process rank
314 static bool addProcessRank = getParamFromGroup<bool>(this->paramGroup(), "Vtk.AddProcessRank");
315 std::vector<double> rank;
316
317 // volume variable data (indexing: volvardata/element/localcorner)
318 using ScalarDataContainer = std::vector< std::vector<Scalar> >;
319 using VectorDataContainer = std::vector< std::vector<GlobalPosition> >;
320 std::vector< ScalarDataContainer > volVarScalarData;
321 std::vector< ScalarDataContainer > volVarScalarDataFracture;
322 std::vector< VectorDataContainer > volVarVectorData;
323 std::vector< VectorDataContainer > volVarVectorDataFracture;
324
325 // some references for convenience
326 const auto& gridView = this->gridGeometry().gridView();
327 const auto& fractureGridView = fractureGrid_->leafGridView();
328 const auto& volVarScalarDataInfo = this->volVarScalarDataInfo();
329 const auto& volVarVectorDataInfo = this->volVarVectorDataInfo();
330
332 if (!volVarScalarDataInfo.empty()
333 || !volVarVectorDataInfo.empty()
334 || !this->fields().empty()
335 || this->velocityOutput().enableOutput()
336 || addProcessRank)
337 {
338 const auto numCells = gridView.size(0);
339 const auto numDofs = gridView.size(dim);
340 const auto numFractureCells = fractureGridView.size(0);
341
342 // get fields for all volume variables
343 if (!this->volVarScalarDataInfo().empty())
344 {
345 volVarScalarData.resize(volVarScalarDataInfo.size(), ScalarDataContainer(numCells));
346 volVarScalarDataFracture.resize(volVarScalarDataInfo.size(), ScalarDataContainer(numFractureCells));
347 }
348 if (!this->volVarVectorDataInfo().empty())
349 {
350 volVarVectorData.resize(volVarVectorDataInfo.size(), VectorDataContainer(numCells));
351 volVarVectorDataFracture.resize(volVarVectorDataInfo.size(), VectorDataContainer(numFractureCells));
352 }
353
354 if (this->velocityOutput().enableOutput())
355 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
356 velocity[phaseIdx].resize(numDofs);
357
358 // maybe allocate space for the process rank
359 if (addProcessRank) rank.resize(numCells);
360
361 for (const auto& element : elements(gridView, Dune::Partitions::interior))
362 {
363 const auto eIdxGlobal = this->gridGeometry().elementMapper().index(element);
364 const auto numCorners = element.subEntities(dim);
365
366 auto fvGeometry = localView(this->gridGeometry());
367 auto elemVolVars = localView(this->gridVariables().curGridVolVars());
368
369 // resize element-local data containers (for bulk grid)
370 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
371 volVarScalarData[i][eIdxGlobal].resize(numCorners);
372 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
373 volVarVectorData[i][eIdxGlobal].resize(numCorners);
374
375 // If velocity output is enabled we need to bind to the whole stencil
376 // otherwise element-local data is sufficient
377 if (this->velocityOutput().enableOutput())
378 {
379 fvGeometry.bind(element);
380 elemVolVars.bind(element, fvGeometry, this->sol());
381 }
382 else
383 {
384 fvGeometry.bindElement(element);
385 elemVolVars.bindElement(element, fvGeometry, this->sol());
386 }
387
388 if (!volVarScalarDataInfo.empty() || !volVarVectorDataInfo.empty())
389 {
390 for (auto&& scv : scvs(fvGeometry))
391 {
392 const auto& volVars = elemVolVars[scv];
393
394 if (!scv.isOnFracture())
395 {
396 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
397 volVarScalarData[i][eIdxGlobal][scv.localDofIndex()] = volVarScalarDataInfo[i].get(volVars);
398 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
399 volVarVectorData[i][eIdxGlobal][scv.localDofIndex()] = volVarVectorDataInfo[i].get(volVars);
400 }
401 else
402 {
403 const auto fIdx = scv.facetIndexInElement();
404 const auto& localMap = fractureElementMap_[eIdxGlobal];
405 const auto fracEIdx = std::find_if(localMap.begin(), localMap.end(), [fIdx] (const auto& p) { return p.first == fIdx; })->second;
406 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
407 volVarScalarDataFracture[i][fracEIdx].push_back(volVarScalarDataInfo[i].get(volVars));
408 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
409 volVarVectorDataFracture[i][fracEIdx].push_back(volVarVectorDataInfo[i].get(volVars));
410 }
411 }
412 }
413
414 // velocity output
415 if (this->velocityOutput().enableOutput())
416 {
417 auto elemFluxVarsCache = localView(this->gridVariables().gridFluxVarsCache());
418 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
419
420 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
421 this->velocityOutput().calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
422 }
423
425 if (addProcessRank)
426 rank[eIdxGlobal] = static_cast<double>(gridView.comm().rank());
427 }
428
432
433 // volume variables if any
434 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
435 {
436 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().elementMapper(), volVarScalarData[i],
437 volVarScalarDataInfo[i].name, /*numComp*/1, /*codim*/dim,
438 /*nonconforming*/this->dataMode()).get() );
439 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureElementMapper_, volVarScalarDataFracture[i],
440 volVarScalarDataInfo[i].name, /*numComp*/1, /*codim*/dim-1,
441 /*nonconforming*/this->dataMode()).get() );
442 }
443
444 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
445 {
446 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().elementMapper(), volVarVectorData[i],
447 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim,
448 /*nonconforming*/this->dataMode()).get() );
449 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureElementMapper_, volVarVectorDataFracture[i],
450 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim-1,
451 /*nonconforming*/this->dataMode()).get() );
452 }
453
454 // the velocity field
455 if (this->velocityOutput().enableOutput())
456 {
457 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
458 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().vertexMapper(), velocity[phaseIdx],
459 "velocity_" + std::string(this->velocityOutput().phaseName(phaseIdx)) + " (m/s)",
460 /*numComp*/dimWorld, /*codim*/dim).get() );
461 }
462
463 // the process rank
464 if (addProcessRank)
465 this->sequenceWriter().addCellData( Field(gridView, this->gridGeometry().elementMapper(), rank,
466 "process rank", /*numComp*/1, /*codim*/0).get() );
467
468 // also register additional (non-standardized) user fields if any (only on matrix grid)
469 for (auto&& field : this->fields())
470 {
471 if (field.codim() == 0)
472 this->sequenceWriter().addCellData(field.get());
473 else if (field.codim() == dim)
474 this->sequenceWriter().addVertexData(field.get());
475 else
476 DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk scalar field!");
477 }
478 }
479
483 this->sequenceWriter().write(time, type);
484 fractureSequenceWriter_->write(time, type);
485
489 this->writer().clear();
490 fractureWriter_->clear();
491 }
492
494 template< class FractureGridAdapter >
495 void initializeFracture_(const FractureGridAdapter& fractureGridAdapter)
496 {
497 const auto& gridGeometry = this->gridGeometry();
498 const auto& gridView = gridGeometry.gridView();
499 Dune::GridFactory<FractureGrid> gridFactory;
500
501 // insert fracture vertices
502 std::size_t fracVertexCount = 0;
503 vertexToFractureVertexIdx_.resize(gridView.size(dim));
504 for (const auto& v : vertices(gridView))
505 {
506 if (fractureGridAdapter.isOnFacetGrid(v))
507 {
508 gridFactory.insertVertex(v.geometry().center());
509 vertexToFractureVertexIdx_[gridGeometry.vertexMapper().index(v)] = fracVertexCount++;
510 }
511 }
512
513 // insert fracture elements
514 std::size_t fractureElementCount = 0;
515 fractureElementMap_.resize(gridView.size(0));
516 std::set< std::pair<GridIndexType, unsigned int> > handledFacets;
517 for (const auto& element : elements(gridView))
518 {
519 const auto eIdxGlobal = gridGeometry.elementMapper().index(element);
520 const auto refElement = referenceElement(element);
521
522 for (const auto& is : intersections(gridView, element))
523 {
524 // obtain all vertex indices on this intersection
525 const auto& isGeometry = is.geometry();
526 const auto numCorners = isGeometry.corners();
527 const auto indexInInside = is.indexInInside();
528
529 std::vector<GridIndexType> isVertexIndices(numCorners);
530 for (unsigned int i = 0; i < numCorners; ++i)
531 isVertexIndices[i] = gridGeometry.vertexMapper().subIndex(element,
532 refElement.subEntity(indexInInside, 1, i, dim),
533 dim);
534
535 // determine if this is a fracture facet & if it has to be inserted
536 bool insertFacet = false;
537 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
538 {
539 insertFacet = true;
540 if (!is.boundary())
541 {
542 // only proceed if facet has not been handled yet
543 const auto outsideEIdx = gridGeometry.elementMapper().index(is.outside());
544 const auto idxInOutside = is.indexInOutside();
545 const auto pair = std::make_pair(outsideEIdx, idxInOutside);
546 if (handledFacets.count( pair ) != 0)
547 {
548 insertFacet = false;
549
550 // obtain the fracture grid elem idx from outside map and insert to map
551 const auto& outsideMap = fractureElementMap_[outsideEIdx];
552 auto it = std::find_if(outsideMap.begin(), outsideMap.end(), [idxInOutside] (const auto& p) { return p.first == idxInOutside; });
553 fractureElementMap_[eIdxGlobal].push_back( std::make_pair(indexInInside, it->second) );
554 }
555 }
556 }
557
558 if (insertFacet)
559 {
560 // transform intersection vertex indices to frac grid indices
561 std::for_each( isVertexIndices.begin(),
562 isVertexIndices.end(),
563 [&] (auto& idx) { idx = this->vertexToFractureVertexIdx_[idx]; } );
564
565 // insert the element
566 gridFactory.insertElement(isGeometry.type(), isVertexIndices);
567
568 // insert to set of handled facets
569 handledFacets.insert( std::make_pair(eIdxGlobal, indexInInside) );
570 fractureElementMap_[eIdxGlobal].push_back( std::make_pair(indexInInside, fractureElementCount) );
571 fractureElementCount++;
572 }
573 }
574 }
575
576 // make grid and get grid view
577 fractureGrid_ = std::shared_ptr<FractureGrid>(gridFactory.createGrid());
578
579 // update fracture mappers
580 const auto& fractureGridView = fractureGrid_->leafGridView();
581 fractureVertexMapper_ = std::make_unique<FractureMapper>(fractureGridView, Dune::mcmgVertexLayout());
582 fractureElementMapper_ = std::make_unique<FractureMapper>(fractureGridView, Dune::mcmgElementLayout());
583
584 // obtain map fracture insertion indices -> fracture grid indices
585 std::vector<GridIndexType> insToVertexIdx(fractureGridView.size(FractureGridView::dimension));
586 std::vector<GridIndexType> insToElemIdx(fractureGridView.size(0));
587 for (const auto& v : vertices(fractureGridView)) insToVertexIdx[ gridFactory.insertionIndex(v) ] = fractureVertexMapper_->index(v);
588 for (const auto& e : elements(fractureGridView)) insToElemIdx[ gridFactory.insertionIndex(e) ] = fractureElementMapper_->index(e);
589
590 // update vertex index map
591 for (GridIndexType dofIdx = 0; dofIdx < gridView.size(GridView::dimension); ++dofIdx)
592 if (gridGeometry.dofOnFracture(dofIdx))
593 vertexToFractureVertexIdx_[dofIdx] = insToVertexIdx[ vertexToFractureVertexIdx_[dofIdx] ];
594
595 // update fracture element map
596 for (auto& elemLocalMap : fractureElementMap_)
597 for (auto& dataPair : elemLocalMap)
598 dataPair.second = insToElemIdx[ dataPair.second ];
599
600 // instantiate writers for the fracture
601 fractureWriter_ = std::make_shared< Dune::VTKWriter<FractureGridView> >(fractureGridView, this->dataMode());
602 fractureSequenceWriter_ = std::make_unique< Dune::VTKSequenceWriter<FractureGridView> >(fractureWriter_, this->name() + "_fracture");
603 }
604
605 std::shared_ptr<FractureGrid> fractureGrid_;
606
607 std::unique_ptr<FractureMapper> fractureVertexMapper_;
608 std::unique_ptr<FractureMapper> fractureElementMapper_;
609
610 std::shared_ptr<Dune::VTKWriter<FractureGridView>> fractureWriter_;
611 std::unique_ptr< Dune::VTKSequenceWriter<FractureGridView> > fractureSequenceWriter_;
612
613 // maps to a bulk grid vertex the vertex index within the fracture grid
614 std::vector<GridIndexType> vertexToFractureVertexIdx_;
615
616 // maps to the local facet indices of an element the corresponding fracture element indices
617 std::vector< std::vector<std::pair<GridIndexType, unsigned int>> > fractureElementMap_;
618};
619
620} // end namespace Dumux
621
622#endif
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
Definition: adapt.hh:29
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:61
const std::string & paramGroup() const
the parameter group for getting parameter from the parameter tree
Definition: io/vtkoutputmodule.hh:94
Dune::VTK::DataMode dataMode() const
Definition: io/vtkoutputmodule.hh:194
Dune::VTKWriter< GridView > & writer()
Definition: io/vtkoutputmodule.hh:197
Dune::VTKSequenceWriter< GridView > & sequenceWriter()
Definition: io/vtkoutputmodule.hh:198
const std::string & name() const
Definition: io/vtkoutputmodule.hh:193
const std::vector< Field > & fields() const
Definition: io/vtkoutputmodule.hh:200
bool verbose() const
Definition: io/vtkoutputmodule.hh:192
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: io/vtkoutputmodule.hh:305
const GridVariables & gridVariables() const
Definition: io/vtkoutputmodule.hh:384
const VelocityOutput & velocityOutput() const
Definition: io/vtkoutputmodule.hh:392
const SolutionVector & sol() const
Definition: io/vtkoutputmodule.hh:386
const GridGeometry & gridGeometry() const
Definition: io/vtkoutputmodule.hh:385
const std::vector< VolVarScalarDataInfo > & volVarScalarDataInfo() const
Definition: io/vtkoutputmodule.hh:388
const std::vector< VolVarVectorDataInfo > & volVarVectorDataInfo() const
Definition: io/vtkoutputmodule.hh:389
A VTK output module to simplify writing dumux simulation data to VTK format.
Definition: porousmediumflow/boxdfm/vtkoutputmodule.hh:56
void write(double time, Dune::VTK::OutputType type=Dune::VTK::ascii)
Writing data.
Definition: porousmediumflow/boxdfm/vtkoutputmodule.hh:110
BoxDfmVtkOutputModule(const GridVariables &gridVariables, const SolutionVector &sol, const std::string &name, const FractureGridAdapter &fractureGridAdapter, const std::string &paramGroup="", Dune::VTK::DataMode dm=Dune::VTK::conforming, bool verbose=true)
The constructor.
Definition: porousmediumflow/boxdfm/vtkoutputmodule.hh:88
A VTK output module to simplify writing dumux simulation data to VTK format.