13#ifndef DUMUX_TWOP_GRIDDATA_TRANSFER_HH
14#define DUMUX_TWOP_GRIDDATA_TRANSFER_HH
18#include <dune/grid/common/partitionset.hh>
19#include <dune/grid/utility/persistentcontainer.hh>
36template<
class TypeTag>
44 using GridView =
typename GridGeometry::GridView;
45 using FVElementGeometry =
typename GridGeometry::LocalView;
46 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
52 using Element =
typename Grid::template Codim<0>::Entity;
53 using ElementSolution = std::decay_t<decltype(elementSolution(std::declval<Element>(),
54 std::declval<SolutionVector>(),
55 std::declval<GridGeometry>()))>;
58 using Indices =
typename ModelTraits::Indices;
62 AdaptedValues() : associatedMass(0.0) {}
65 PrimaryVariables associatedMass;
69 using PersistentContainer = Dune::PersistentContainer<Grid, AdaptedValues>;
71 static constexpr int dim = Grid::dimension;
72 static constexpr int dimWorld = Grid::dimensionworld;
76 enum { saturationIdx = Indices::saturationIdx };
81 phase0Idx = FluidSystem::phase0Idx,
82 phase1Idx = FluidSystem::phase1Idx,
90 static constexpr auto formulation = ModelTraits::priVarFormulation();
93 static_assert(!FluidSystem::isCompressible(phase0Idx)
94 && !FluidSystem::isCompressible(phase1Idx),
95 "This adaption helper is only mass conservative for incompressible fluids!");
98 static_assert(formulation == p0s1 || formulation == p1s0,
"Chosen formulation not known to the TwoPGridDataTransfer");
110 std::shared_ptr<GridGeometry> gridGeometry,
111 std::shared_ptr<const GridVariables> gridVariables,
115 , gridGeometry_(gridGeometry)
116 , gridVariables_(gridVariables)
118 , adaptionMap_(gridGeometry->gridView().grid(), 0)
129 void store(
const Grid& grid)
override
131 adaptionMap_.resize();
133 for (
auto level = grid.maxLevel(); level >= 0; level--)
135 auto fvGeometry =
localView(*gridGeometry_);
136 for (
const auto& element : elements(grid.levelGridView(level)))
139 auto& adaptedValues = adaptionMap_[element];
142 if (element.isLeaf())
144 fvGeometry.bindElement(element);
147 adaptedValues.u = ElementSolution(element, sol_, *gridGeometry_);
150 for (
const auto& scv : scvs(fvGeometry))
152 VolumeVariables volVars;
153 volVars.update(adaptedValues.u, *problem_, element, scv);
156 adaptedValues.associatedMass[phase1Idx] += poreVolume * volVars.density(phase1Idx) * volVars.saturation(phase1Idx);
157 adaptedValues.associatedMass[phase0Idx] += poreVolume * volVars.density(phase0Idx) * volVars.saturation(phase0Idx);
161 adaptedValues.count = 1;
162 adaptedValues.wasLeaf =
true;
165 if (element.level() > 0)
167 auto& adaptedValuesFather = adaptionMap_[element.father()];
170 if(&adaptedValues != &adaptedValuesFather)
171 storeAdaptionValues(adaptedValues, adaptedValuesFather);
177 if(isBox && !element.isLeaf())
178 adaptedValues.u = ElementSolution(element, sol_, *gridGeometry_);
196 gridGeometry_->update(grid.leafGridView());
205 adaptionMap_.resize();
206 sol_.resize(gridGeometry_->numDofs());
209 std::vector<Scalar> massCoeff;
210 std::vector<Scalar> associatedMass;
214 massCoeff.resize(gridGeometry_->numDofs(), 0.0);
215 associatedMass.resize(gridGeometry_->numDofs(), 0.0);
219 auto fvGeometry =
localView(*gridGeometry_);
220 for (
const auto& element : elements(gridGeometry_->gridView().grid().leafGridView(), Dune::Partitions::interior))
222 if (!element.isNew())
224 const auto& adaptedValues = adaptionMap_[element];
225 fvGeometry.bindElement(element);
228 auto elemSol = adaptedValues.u;
230 elemSol[0] /= adaptedValues.count;
232 const auto elementVolume =
volume(element.geometry(), Extrusion{});
233 for (
const auto& scv : scvs(fvGeometry))
235 VolumeVariables volVars;
236 volVars.update(elemSol, *problem_, element, scv);
239 sol_[scv.dofIndex()] = elemSol[scv.localDofIndex()];
241 const auto dofIdxGlobal = scv.dofIndex();
246 if (!adaptedValues.wasLeaf)
248 if (formulation == p0s1)
250 sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[phase1Idx];
251 sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(phase1Idx) * volVars.porosity();
253 else if (formulation == p1s0)
255 sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[phase0Idx];
256 sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(phase0Idx) * volVars.porosity();
265 if (formulation == p0s1)
267 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase1Idx) * volVars.porosity();
268 associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[phase1Idx];
270 else if (formulation == p1s0)
272 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase0Idx) * volVars.porosity();
273 associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[phase0Idx];
281 assert(
element.hasFather() &&
"new element does not have a father element!");
284 auto fatherElement =
element.father();
285 while(fatherElement.isNew() && fatherElement.level() > 0)
286 fatherElement = fatherElement.father();
290 const auto& adaptedValuesFather = adaptionMap_[fatherElement];
293 Scalar massFather = 0.0;
294 if (formulation == p0s1)
295 massFather = adaptedValuesFather.associatedMass[phase1Idx];
296 else if (formulation == p1s0)
297 massFather = adaptedValuesFather.associatedMass[phase0Idx];
300 auto elemSolSon = adaptedValuesFather.u;
301 elemSolSon[0] /= adaptedValuesFather.count;
303 fvGeometry.bindElement(element);
305 for (
const auto& scv : scvs(fvGeometry))
307 VolumeVariables volVars;
308 volVars.update(elemSolSon, *problem_, element, scv);
311 sol_[scv.dofIndex()] = elemSolSon[0];
314 Scalar massCoeffSon = 0.0;
315 if (formulation == p0s1)
316 massCoeffSon =
Extrusion::volume(fvGeometry, scv) * volVars.density(phase1Idx) * volVars.porosity();
317 else if (formulation == p1s0)
318 massCoeffSon =
Extrusion::volume(fvGeometry, scv) * volVars.density(phase0Idx) * volVars.porosity();
319 sol_[scv.dofIndex()][saturationIdx] =
325 auto& adaptedValuesFather = adaptionMap_[fatherElement];
327 fvGeometry.bindElement(element);
330 ElementSolution elemSolSon(element, sol_, *gridGeometry_);
331 const auto fatherGeometry = fatherElement.geometry();
332 for (
const auto& scv : scvs(fvGeometry))
333 elemSolSon[scv.localDofIndex()] =
evalSolution(fatherElement,
335 adaptedValuesFather.u,
339 const auto fatherElementVolume =
volume(fatherGeometry, Extrusion{});
340 for (
const auto& scv : scvs(fvGeometry))
342 VolumeVariables volVars;
343 volVars.update(elemSolSon, *problem_, element, scv);
345 const auto dofIdxGlobal = scv.dofIndex();
347 if (formulation == p0s1)
349 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase1Idx) * volVars.porosity();
350 associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[phase1Idx];
352 else if (formulation == p1s0)
354 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase0Idx) * volVars.porosity();
355 associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[phase0Idx];
359 sol_[dofIdxGlobal] = elemSolSon[scv.localDofIndex()];
367 for(std::size_t dofIdxGlobal = 0; dofIdxGlobal < gridGeometry_->numDofs(); dofIdxGlobal++)
368 sol_[dofIdxGlobal][saturationIdx] = associatedMass[dofIdxGlobal] / massCoeff[dofIdxGlobal];
372 adaptionMap_.resize(
typename PersistentContainer::Value() );
373 adaptionMap_.shrinkToFit();
374 adaptionMap_.fill(
typename PersistentContainer::Value() );
399 static void storeAdaptionValues(AdaptedValues& adaptedValues,
400 AdaptedValues& adaptedValuesFather)
403 adaptedValuesFather.associatedMass += adaptedValues.associatedMass;
410 auto values = adaptedValues.u[0];
411 values /= adaptedValues.count;
412 adaptedValuesFather.u[0] += values;
415 adaptedValuesFather.count += 1;
418 adaptedValuesFather.wasLeaf =
false;
424 adaptedValuesFather.count = 1;
427 adaptedValuesFather.wasLeaf =
false;
431 std::shared_ptr<const Problem> problem_;
432 std::shared_ptr<GridGeometry> gridGeometry_;
433 std::shared_ptr<const GridVariables> gridVariables_;
434 SolutionVector& sol_;
435 PersistentContainer adaptionMap_;
Interface to be used by classes transferring grid data on adaptive grids.
Interface to be used by classes transferring grid data on adaptive grids.
Definition: adaptive/griddatatransfer.hh:23
Class performing the transfer of data on a grid from before to after adaptation.
Definition: porousmediumflow/2p/griddatatransfer.hh:38
void store(const Grid &grid) override
Stores primary variables and additional data.
Definition: porousmediumflow/2p/griddatatransfer.hh:129
TwoPGridDataTransfer(std::shared_ptr< const Problem > problem, std::shared_ptr< GridGeometry > gridGeometry, std::shared_ptr< const GridVariables > gridVariables, SolutionVector &sol)
Constructor.
Definition: porousmediumflow/2p/griddatatransfer.hh:109
void reconstruct(const Grid &grid) override
Reconstruct missing primary variables (where elements are created/deleted)
Definition: porousmediumflow/2p/griddatatransfer.hh:194
Defines all properties used in Dumux.
Element solution classes and factory functions.
Helper classes to compute the integration elements.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:26
PrimaryVariables evalSolution(const Element &element, const typename Element::Geometry &geometry, const typename FVElementGeometry::GridGeometry &gridGeometry, const CVFEElementSolution< FVElementGeometry, PrimaryVariables > &elemSol, const typename Element::Geometry::GlobalCoordinate &globalPos, bool ignoreState=false)
Interpolates a given box element solution at a given global position. Uses the finite element cache o...
Definition: evalsolution.hh:152
auto volume(const Geometry &geo, unsigned int integrationOrder=4)
The volume of a given geometry.
Definition: volume.hh:159
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
@ p1s0
first phase saturation and second phase pressure as primary variables
@ p0s1
first phase pressure and second phase saturation as primary variables
The available discretization methods in Dumux.
constexpr Box box
Definition: method.hh:147
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:166
Compute the volume of several common geometry types.