3.1-git
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/geometry/referenceelements.hh>
32#include <dune/grid/common/mcmgmapper.hh>
33
35
36namespace Dumux {
37
55template<class GridVariables, class SolutionVector, class FractureGrid>
56class BoxDfmVtkOutputModule : public VtkOutputModule<GridVariables, SolutionVector>
57{
59 using GridGeometry = typename GridVariables::GridGeometry;
60 using VV = typename GridVariables::VolumeVariables;
61 using FluidSystem = typename VV::FluidSystem;
62 using Scalar = typename GridVariables::Scalar;
63
64 using GridView = typename GridGeometry::GridView;
65 using FractureGridView = typename FractureGrid::LeafGridView;
66 using FractureMapper = Dune::MultipleCodimMultipleGeomTypeMapper<FractureGridView>;
67
68 enum
69 {
70 dim = GridView::dimension,
71 dimWorld = GridView::dimensionworld
72 };
73
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>;
78
79 using Field = Vtk::template Field<GridView>;
80 using FractureField = Vtk::template Field<FractureGridView>;
81
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!");
86public:
87
89 template< class FractureGridAdapter >
91 const SolutionVector& sol,
92 const std::string& name,
93 const FractureGridAdapter& fractureGridAdapter,
94 const std::string& paramGroup = "",
95 Dune::VTK::DataMode dm = Dune::VTK::conforming,
96 bool verbose = true)
98 {
99 // create the fracture grid and all objects needed on it
100 initializeFracture_(fractureGridAdapter);
101 }
102
106
112 void write(double time, Dune::VTK::OutputType type = Dune::VTK::ascii)
113 {
114 Dune::Timer timer;
115
116 // write to file depending on data mode
117 const auto dm = this->dataMode();
118 if (dm == Dune::VTK::conforming)
119 writeConforming_(time, type);
120 else if (dm == Dune::VTK::nonconforming)
121 writeNonConforming_(time, type);
122 else
123 DUNE_THROW(Dune::NotImplemented, "Output for provided vtk data mode");
124
126 timer.stop();
127 if (this->verbose())
128 std::cout << "Writing output for problem \"" << this->name() << "\". Took " << timer.elapsed() << " seconds." << std::endl;
129 }
130
131private:
133 void writeConforming_(double time, Dune::VTK::OutputType type)
134 {
138
139 // instatiate the velocity output
140 std::vector<typename ParentType::VelocityOutput::VelocityVector> velocity;
141
142 // process rank
143 static bool addProcessRank = getParamFromGroup<bool>(this->paramGroup(), "Vtk.AddProcessRank");
144 std::vector<double> rank;
145
146 // volume variable data
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;
151
152 // some references for convenience
153 const auto& gridView = this->gridGeometry().gridView();
154 const auto& fractureGridView = fractureGrid_->leafGridView();
155 const auto& volVarScalarDataInfo = this->volVarScalarDataInfo();
156 const auto& volVarVectorDataInfo = this->volVarVectorDataInfo();
157
159 if (!volVarScalarDataInfo.empty()
160 || !volVarVectorDataInfo.empty()
161 || !this->fields().empty()
162 || this->velocityOutput().enableOutput()
163 || addProcessRank)
164 {
165 const auto numCells = gridView.size(0);
166 const auto numDofs = gridView.size(dim);
167 const auto numFractureVert = fractureGridView.size(FractureGridView::dimension);
168
169 // get fields for all volume variables
170 if (!this->volVarScalarDataInfo().empty())
171 {
172 volVarScalarData.resize(volVarScalarDataInfo.size(), std::vector<Scalar>(numDofs));
173 volVarScalarDataFracture.resize(volVarScalarDataInfo.size(), std::vector<Scalar>(numFractureVert));
174 }
175 if (!this->volVarVectorDataInfo().empty())
176 {
177 volVarVectorData.resize(volVarVectorDataInfo.size(), std::vector<GlobalPosition>(numDofs));
178 volVarVectorDataFracture.resize(volVarVectorDataInfo.size(), std::vector<GlobalPosition>(numFractureVert));
179 }
180
181 if (this->velocityOutput().enableOutput())
182 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
183 velocity[phaseIdx].resize(numDofs);
184
185 // maybe allocate space for the process rank
186 if (addProcessRank) rank.resize(numCells);
187
188 for (const auto& element : elements(gridView, Dune::Partitions::interior))
189 {
190 const auto eIdxGlobal = this->gridGeometry().elementMapper().index(element);
191
192 auto fvGeometry = localView(this->gridGeometry());
193 auto elemVolVars = localView(this->gridVariables().curGridVolVars());
194
195 // If velocity output is enabled we need to bind to the whole stencil
196 // otherwise element-local data is sufficient
197 if (this->velocityOutput().enableOutput())
198 {
199 fvGeometry.bind(element);
200 elemVolVars.bind(element, fvGeometry, this->sol());
201 }
202 else
203 {
204 fvGeometry.bindElement(element);
205 elemVolVars.bindElement(element, fvGeometry, this->sol());
206 }
207
208 if (!volVarScalarDataInfo.empty() || !volVarVectorDataInfo.empty())
209 {
210 for (auto&& scv : scvs(fvGeometry))
211 {
212 const auto dofIdxGlobal = scv.dofIndex();
213 const auto& volVars = elemVolVars[scv];
214
215 if (!scv.isOnFracture())
216 {
217 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
218 volVarScalarData[i][dofIdxGlobal] = volVarScalarDataInfo[i].get(volVars);
219 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
220 volVarVectorData[i][dofIdxGlobal] = volVarVectorDataInfo[i].get(volVars);
221 }
222 else
223 {
224 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
225 volVarScalarDataFracture[i][vertexToFractureVertexIdx_[dofIdxGlobal]] = volVarScalarDataInfo[i].get(volVars);
226 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
227 volVarVectorDataFracture[i][vertexToFractureVertexIdx_[dofIdxGlobal]] = volVarVectorDataInfo[i].get(volVars);
228 }
229 }
230 }
231
232 // velocity output
233 if (this->velocityOutput().enableOutput())
234 {
235 auto elemFluxVarsCache = localView(this->gridVariables().gridFluxVarsCache());
236 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
237
238 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
239 this->velocityOutput().calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
240 }
241
243 if (addProcessRank)
244 rank[eIdxGlobal] = static_cast<double>(gridView.comm().rank());
245 }
246
250
251 // volume variables if any
252 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
253 {
254 this->sequenceWriter().addVertexData(volVarScalarData[i], volVarScalarDataInfo[i].name);
255 fractureSequenceWriter_->addVertexData(volVarScalarDataFracture[i], volVarScalarDataInfo[i].name);
256 }
257
258 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
259 {
260 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().vertexMapper(), volVarVectorData[i],
261 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim).get() );
262 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureVertexMapper_, volVarVectorDataFracture[i],
263 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim-1).get() );
264 }
265
266 // the velocity field
267 if (this->velocityOutput().enableOutput())
268 {
269 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
270 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().vertexMapper(), velocity[phaseIdx],
271 "velocity_" + std::string(this->velocityOutput().phaseName(phaseIdx)) + " (m/s)",
272 /*numComp*/dimWorld, /*codim*/dim).get() );
273 }
274
275 // the process rank
276 if (addProcessRank)
277 this->sequenceWriter().addCellData( Field(gridView, this->gridGeometry().elementMapper(), rank,
278 "process rank", /*numComp*/1, /*codim*/0).get() );
279
280 // also register additional (non-standardized) user fields if any (only on matrix grid)
281 for (auto&& field : this->fields())
282 {
283 if (field.codim() == 0)
284 this->sequenceWriter().addCellData(field.get());
285 else if (field.codim() == dim)
286 this->sequenceWriter().addVertexData(field.get());
287 else
288 DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk scalar field!");
289 }
290 }
291
295 this->sequenceWriter().write(time, type);
296 fractureSequenceWriter_->write(time, type);
297
301 this->writer().clear();
302 fractureWriter_->clear();
303 }
304
306 void writeNonConforming_(double time, Dune::VTK::OutputType type)
307 {
311
312 // instatiate the velocity output
313 std::vector<typename ParentType::VelocityOutput::VelocityVector> velocity;
314
315 // process rank
316 static bool addProcessRank = getParamFromGroup<bool>(this->paramGroup(), "Vtk.AddProcessRank");
317 std::vector<double> rank;
318
319 // volume variable data (indexing: volvardata/element/localcorner)
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;
326
327 // some references for convenience
328 const auto& gridView = this->gridGeometry().gridView();
329 const auto& fractureGridView = fractureGrid_->leafGridView();
330 const auto& volVarScalarDataInfo = this->volVarScalarDataInfo();
331 const auto& volVarVectorDataInfo = this->volVarVectorDataInfo();
332
334 if (!volVarScalarDataInfo.empty()
335 || !volVarVectorDataInfo.empty()
336 || !this->fields().empty()
337 || this->velocityOutput().enableOutput()
338 || addProcessRank)
339 {
340 const auto numCells = gridView.size(0);
341 const auto numDofs = gridView.size(dim);
342 const auto numFractureCells = fractureGridView.size(0);
343
344 // get fields for all volume variables
345 if (!this->volVarScalarDataInfo().empty())
346 {
347 volVarScalarData.resize(volVarScalarDataInfo.size(), ScalarDataContainer(numCells));
348 volVarScalarDataFracture.resize(volVarScalarDataInfo.size(), ScalarDataContainer(numFractureCells));
349 }
350 if (!this->volVarVectorDataInfo().empty())
351 {
352 volVarVectorData.resize(volVarVectorDataInfo.size(), VectorDataContainer(numCells));
353 volVarVectorDataFracture.resize(volVarVectorDataInfo.size(), VectorDataContainer(numFractureCells));
354 }
355
356 if (this->velocityOutput().enableOutput())
357 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
358 velocity[phaseIdx].resize(numDofs);
359
360 // maybe allocate space for the process rank
361 if (addProcessRank) rank.resize(numCells);
362
363 for (const auto& element : elements(gridView, Dune::Partitions::interior))
364 {
365 const auto eIdxGlobal = this->gridGeometry().elementMapper().index(element);
366 const auto numCorners = element.subEntities(dim);
367
368 auto fvGeometry = localView(this->gridGeometry());
369 auto elemVolVars = localView(this->gridVariables().curGridVolVars());
370
371 // resize element-local data containers (for bulk grid)
372 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
373 volVarScalarData[i][eIdxGlobal].resize(numCorners);
374 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
375 volVarVectorData[i][eIdxGlobal].resize(numCorners);
376
377 // If velocity output is enabled we need to bind to the whole stencil
378 // otherwise element-local data is sufficient
379 if (this->velocityOutput().enableOutput())
380 {
381 fvGeometry.bind(element);
382 elemVolVars.bind(element, fvGeometry, this->sol());
383 }
384 else
385 {
386 fvGeometry.bindElement(element);
387 elemVolVars.bindElement(element, fvGeometry, this->sol());
388 }
389
390 if (!volVarScalarDataInfo.empty() || !volVarVectorDataInfo.empty())
391 {
392 for (auto&& scv : scvs(fvGeometry))
393 {
394 const auto& volVars = elemVolVars[scv];
395
396 if (!scv.isOnFracture())
397 {
398 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
399 volVarScalarData[i][eIdxGlobal][scv.localDofIndex()] = volVarScalarDataInfo[i].get(volVars);
400 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
401 volVarVectorData[i][eIdxGlobal][scv.localDofIndex()] = volVarVectorDataInfo[i].get(volVars);
402 }
403 else
404 {
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;
408 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
409 volVarScalarDataFracture[i][fracEIdx].push_back(volVarScalarDataInfo[i].get(volVars));
410 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
411 volVarVectorDataFracture[i][fracEIdx].push_back(volVarVectorDataInfo[i].get(volVars));
412 }
413 }
414 }
415
416 // velocity output
417 if (this->velocityOutput().enableOutput())
418 {
419 auto elemFluxVarsCache = localView(this->gridVariables().gridFluxVarsCache());
420 elemFluxVarsCache.bind(element, fvGeometry, elemVolVars);
421
422 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
423 this->velocityOutput().calculateVelocity(velocity[phaseIdx], element, fvGeometry, elemVolVars, elemFluxVarsCache, phaseIdx);
424 }
425
427 if (addProcessRank)
428 rank[eIdxGlobal] = static_cast<double>(gridView.comm().rank());
429 }
430
434
435 // volume variables if any
436 for (std::size_t i = 0; i < volVarScalarDataInfo.size(); ++i)
437 {
438 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().elementMapper(), volVarScalarData[i],
439 volVarScalarDataInfo[i].name, /*numComp*/1, /*codim*/dim,
440 /*nonconforming*/this->dataMode()).get() );
441 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureElementMapper_, volVarScalarDataFracture[i],
442 volVarScalarDataInfo[i].name, /*numComp*/1, /*codim*/dim-1,
443 /*nonconforming*/this->dataMode()).get() );
444 }
445
446 for (std::size_t i = 0; i < volVarVectorDataInfo.size(); ++i)
447 {
448 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().elementMapper(), volVarVectorData[i],
449 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim,
450 /*nonconforming*/this->dataMode()).get() );
451 fractureSequenceWriter_->addVertexData( FractureField(fractureGridView, *fractureElementMapper_, volVarVectorDataFracture[i],
452 volVarVectorDataInfo[i].name, /*numComp*/dimWorld, /*codim*/dim-1,
453 /*nonconforming*/this->dataMode()).get() );
454 }
455
456 // the velocity field
457 if (this->velocityOutput().enableOutput())
458 {
459 for (int phaseIdx = 0; phaseIdx < this->velocityOutput().numFluidPhases(); ++phaseIdx)
460 this->sequenceWriter().addVertexData( Field(gridView, this->gridGeometry().vertexMapper(), velocity[phaseIdx],
461 "velocity_" + std::string(this->velocityOutput().phaseName(phaseIdx)) + " (m/s)",
462 /*numComp*/dimWorld, /*codim*/dim).get() );
463 }
464
465 // the process rank
466 if (addProcessRank)
467 this->sequenceWriter().addCellData( Field(gridView, this->gridGeometry().elementMapper(), rank,
468 "process rank", /*numComp*/1, /*codim*/0).get() );
469
470 // also register additional (non-standardized) user fields if any (only on matrix grid)
471 for (auto&& field : this->fields())
472 {
473 if (field.codim() == 0)
474 this->sequenceWriter().addCellData(field.get());
475 else if (field.codim() == dim)
476 this->sequenceWriter().addVertexData(field.get());
477 else
478 DUNE_THROW(Dune::RangeError, "Cannot add wrongly sized vtk scalar field!");
479 }
480 }
481
485 this->sequenceWriter().write(time, type);
486 fractureSequenceWriter_->write(time, type);
487
491 this->writer().clear();
492 fractureWriter_->clear();
493 }
494
496 template< class FractureGridAdapter >
497 void initializeFracture_(const FractureGridAdapter& fractureGridAdapter)
498 {
499 const auto& gridGeometry = this->gridGeometry();
500 const auto& gridView = gridGeometry.gridView();
501 Dune::GridFactory<FractureGrid> gridFactory;
502
503 // insert fracture vertices
504 std::size_t fracVertexCount = 0;
505 vertexToFractureVertexIdx_.resize(gridView.size(dim));
506 for (const auto& v : vertices(gridView))
507 {
508 if (fractureGridAdapter.isOnFacetGrid(v))
509 {
510 gridFactory.insertVertex(v.geometry().center());
511 vertexToFractureVertexIdx_[gridGeometry.vertexMapper().index(v)] = fracVertexCount++;
512 }
513 }
514
515 // insert fracture elements
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))
520 {
521 const auto eIdxGlobal = gridGeometry.elementMapper().index(element);
522 const auto referenceElement = ReferenceElements::general(element.type());
523
524 for (const auto& is : intersections(gridView, element))
525 {
526 // obtain all vertex indices on this intersection
527 const auto& isGeometry = is.geometry();
528 const auto numCorners = isGeometry.corners();
529 const auto indexInInside = is.indexInInside();
530
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),
535 dim);
536
537 // determine if this is a fracture facet & if it has to be inserted
538 bool insertFacet = false;
539 if (fractureGridAdapter.composeFacetElement(isVertexIndices))
540 {
541 insertFacet = true;
542 if (!is.boundary())
543 {
544 // only proceed if facet has not been handled yet
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)
549 {
550 insertFacet = false;
551
552 // obtain the fracture grid elem idx from outside map and insert to map
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) );
556 }
557 }
558 }
559
560 if (insertFacet)
561 {
562 // transform intersection vertex indices to frac grid indices
563 std::for_each( isVertexIndices.begin(),
564 isVertexIndices.end(),
565 [&] (auto& idx) { idx = this->vertexToFractureVertexIdx_[idx]; } );
566
567 // insert the element
568 gridFactory.insertElement(isGeometry.type(), isVertexIndices);
569
570 // insert to set of handled facets
571 handledFacets.insert( std::make_pair(eIdxGlobal, indexInInside) );
572 fractureElementMap_[eIdxGlobal].push_back( std::make_pair(indexInInside, fractureElementCount) );
573 fractureElementCount++;
574 }
575 }
576 }
577
578 // make grid and get grid view
579 fractureGrid_ = std::shared_ptr<FractureGrid>(gridFactory.createGrid());
580
581 // update fracture mappers
582 const auto& fractureGridView = fractureGrid_->leafGridView();
583 fractureVertexMapper_ = std::make_unique<FractureMapper>(fractureGridView, Dune::mcmgVertexLayout());
584 fractureElementMapper_ = std::make_unique<FractureMapper>(fractureGridView, Dune::mcmgElementLayout());
585
586 // obtain map fracture insertion indices -> fracture grid indices
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);
591
592 // update vertex index map
593 for (GridIndexType dofIdx = 0; dofIdx < gridView.size(GridView::dimension); ++dofIdx)
594 if (gridGeometry.dofOnFracture(dofIdx))
595 vertexToFractureVertexIdx_[dofIdx] = insToVertexIdx[ vertexToFractureVertexIdx_[dofIdx] ];
596
597 // update fracture element map
598 for (auto& elemLocalMap : fractureElementMap_)
599 for (auto& dataPair : elemLocalMap)
600 dataPair.second = insToElemIdx[ dataPair.second ];
601
602 // instantiate writers for the fracture
603 fractureWriter_ = std::make_shared< Dune::VTKWriter<FractureGridView> >(fractureGridView, this->dataMode());
604 fractureSequenceWriter_ = std::make_unique< Dune::VTKSequenceWriter<FractureGridView> >(fractureWriter_, this->name() + "_fracture");
605 }
606
607 std::shared_ptr<FractureGrid> fractureGrid_;
608
609 std::unique_ptr<FractureMapper> fractureVertexMapper_;
610 std::unique_ptr<FractureMapper> fractureElementMapper_;
611
612 std::shared_ptr<Dune::VTKWriter<FractureGridView>> fractureWriter_;
613 std::unique_ptr< Dune::VTKSequenceWriter<FractureGridView> > fractureSequenceWriter_;
614
615 // maps to a bulk grid vertex the vertex index within the fracture grid
616 std::vector<GridIndexType> vertexToFractureVertexIdx_;
617
618 // maps to the local facet indices of an element the corresponding fracture element indices
619 std::vector< std::vector<std::pair<GridIndexType, unsigned int>> > fractureElementMap_;
620};
621
622} // end namespace Dumux
623
624#endif
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
Dune::IteratorRange< typename MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper >::Intersections::const_iterator > intersections(const MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper > &glue)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: glue.hh:62
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
void resize(const Vector &v, std::size_t size)
Definition: test_isvalid.cc:26
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:66
const GridVariables & gridVariables() const
Definition: io/vtkoutputmodule.hh:234
const std::string & paramGroup() const
the parameter group for getting parameter from the parameter tree
Definition: io/vtkoutputmodule.hh:119
bool verbose() const
Definition: io/vtkoutputmodule.hh:237
Dune::VTKSequenceWriter< GridView > & sequenceWriter()
Definition: io/vtkoutputmodule.hh:242
const VelocityOutput & velocityOutput() const
Definition: io/vtkoutputmodule.hh:249
const std::string & name() const
Definition: io/vtkoutputmodule.hh:238
Dune::VTK::DataMode dataMode() const
Definition: io/vtkoutputmodule.hh:239
Dune::VTKWriter< GridView > & writer()
Definition: io/vtkoutputmodule.hh:241
const SolutionVector & sol() const
Definition: io/vtkoutputmodule.hh:235
const GridGeometry & gridGeometry() const
Definition: io/vtkoutputmodule.hh:233
const std::vector< Field > & fields() const
Definition: io/vtkoutputmodule.hh:246
const std::vector< VolVarScalarDataInfo > & volVarScalarDataInfo() const
Definition: io/vtkoutputmodule.hh:244
const std::vector< VolVarVectorDataInfo > & volVarVectorDataInfo() const
Definition: io/vtkoutputmodule.hh:245
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 &paramGroup="", 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.