24#ifndef DUMUX_MIMETICPRESSURE2PADAPTIVE_HH
25#define DUMUX_MIMETICPRESSURE2PADAPTIVE_HH
67 using SpatialParams =
typename GET_PROP_TYPE(TypeTag, SpatialParams);
68 using MaterialLaw =
typename SpatialParams::MaterialLaw;
70 using Indices =
typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
72 using FluidSystem =
typename GET_PROP_TYPE(TypeTag, FluidSystem);
73 using FluidState =
typename GET_PROP_TYPE(TypeTag, FluidState);
77 dim = GridView::dimension, dimWorld = GridView::dimensionworld
81 pw = Indices::pressureW,
82 pn = Indices::pressureNw,
83 pGlobal = Indices::pressureGlobal,
84 Sw = Indices::saturationW,
85 Sn = Indices::saturationNw,
86 vw = Indices::velocityW,
87 vn = Indices::velocityNw,
95 wPhaseIdx = Indices::wPhaseIdx,
96 nPhaseIdx = Indices::nPhaseIdx,
100 using Element =
typename GridView::Traits::template Codim<0>::Entity;
101 using Grid =
typename GridView::Grid;
103 using Geometry =
typename Element::Geometry;
104 using JacobianTransposed =
typename Geometry::JacobianTransposed ;
106 using DimVector = Dune::FieldVector<Scalar, dim>;
108 using LocalStiffness =
typename GET_PROP_TYPE(TypeTag, LocalStiffness);
109 using TraceType = Dune::BlockVector<Dune::FieldVector<Scalar, 1> >;
113 using SolutionTypes =
typename GET_PROP(TypeTag, SolutionTypes);
114 using ScalarSolutionType =
typename SolutionTypes::ScalarSolution;
120 void initializeMatrix();
123 void assemble(
bool first)
125 Scalar timeStep = problem_.timeManager().timeStepSize();
126 Scalar maxError = 0.0;
127 int size = problem_.gridView().size(0);
128 for (
int i = 0; i < size; i++)
132 switch (saturationType)
135 sat = problem_.variables().cellData(i).saturation(wPhaseIdx);
138 sat = problem_.variables().cellData(i).saturation(nPhaseIdx);
143 maxError = max(maxError, (sat - 1.0) / timeStep);
147 maxError = max(maxError, (-sat) / timeStep);
151 lstiff_.setErrorInfo(maxError, timeStep);
152 A_.
assemble(lstiff_, pressTrace_, f_);
181 const auto element = *problem_.gridView().template begin<0>();
182 FluidState fluidState;
183 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
184 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
185 fluidState.setTemperature(problem_.temperature(element));
186 fluidState.setSaturation(wPhaseIdx, 1.);
187 fluidState.setSaturation(nPhaseIdx, 0.);
195 lstiff_.initialize();
230 if (problem_.gridAdapt().wasAdapted())
251 template<
class MultiWriter>
254 int size = problem_.gridView().size(0);
255 ScalarSolutionType *potential = writer.allocateManagedBuffer(size);
257 ScalarSolutionType *pressureSecond = 0;
258 ScalarSolutionType *potentialSecond = 0;
259 Dune::BlockVector < DimVector > *velocityWetting = 0;
260 Dune::BlockVector < DimVector > *velocityNonwetting = 0;
262 if (vtkOutputLevel_ > 0)
264 pressure = writer.allocateManagedBuffer(size);
265 pressureSecond = writer.allocateManagedBuffer(size);
266 potentialSecond = writer.allocateManagedBuffer(size);
267 velocityWetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
268 velocityNonwetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
272 for (
const auto& element : elements(problem_.gridView()))
274 int eIdxGlobal = problem_.variables().index(element);
275 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
277 if (pressureType == pw)
279 (*potential)[eIdxGlobal] = cellData.potential(wPhaseIdx);
282 if (pressureType == pn)
284 (*potential)[eIdxGlobal] = cellData.potential(nPhaseIdx);
287 if (vtkOutputLevel_ > 0)
290 if (pressureType == pw)
292 (*pressure)[eIdxGlobal] = cellData.pressure(wPhaseIdx);
293 (*potentialSecond)[eIdxGlobal] = cellData.potential(nPhaseIdx);
294 (*pressureSecond)[eIdxGlobal] = cellData.pressure(nPhaseIdx);
297 if (pressureType == pn)
299 (*pressure)[eIdxGlobal] = cellData.pressure(nPhaseIdx);
300 (*potentialSecond)[eIdxGlobal] = cellData.potential(wPhaseIdx);
301 (*pressureSecond)[eIdxGlobal] = cellData.pressure(wPhaseIdx);
304 const typename Element::Geometry& geometry = element.geometry();
307 using ReferenceElements = Dune::ReferenceElements<Scalar, dim>;
308 const auto refElement = ReferenceElements::general(geometry.type());
310 const int numberOfFaces=refElement.size(1);
311 std::vector<Scalar> fluxW(numberOfFaces,0);
312 std::vector<Scalar> fluxNw(numberOfFaces,0);
315 for (
const auto& intersection :
intersections(problem_.gridView(), element))
317 int isIndex = intersection.indexInInside();
319 fluxW[isIndex] += intersection.geometry().volume()
320 * (intersection.centerUnitOuterNormal() * cellData.fluxData().velocity(wPhaseIdx, isIndex));
321 fluxNw[isIndex] += intersection.geometry().volume()
322 * (intersection.centerUnitOuterNormal() * cellData.fluxData().velocity(nPhaseIdx, isIndex));
327 Dune::FieldVector<Scalar, dim> refVelocity;
329 if (refElement.type().isSimplex()) {
330 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
332 refVelocity[dimIdx] = -fluxW[dim - 1 - dimIdx];
333 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
335 refVelocity[dimIdx] += fluxW[fIdx]/(dim + 1);
340 else if (refElement.type().isCube()){
341 for (
int i = 0; i < dim; i++)
342 refVelocity[i] = 0.5 * (fluxW[2*i + 1] - fluxW[2*i]);
346 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
349 const DimVector& localPos = refElement.position(0, 0);
352 const JacobianTransposed jacobianT = geometry.jacobianTransposed(localPos);
355 DimVector elementVelocity(0);
356 jacobianT.umtv(refVelocity, elementVelocity);
357 elementVelocity /= geometry.integrationElement(localPos);
359 (*velocityWetting)[eIdxGlobal] = elementVelocity;
364 if (refElement.type().isSimplex()) {
365 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
367 refVelocity[dimIdx] = -fluxNw[dim - 1 - dimIdx];
368 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
370 refVelocity[dimIdx] += fluxNw[fIdx]/(dim + 1);
375 else if (refElement.type().isCube()){
376 for (
int i = 0; i < dim; i++)
377 refVelocity[i] = 0.5 * (fluxNw[2*i + 1] - fluxNw[2*i]);
381 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
386 jacobianT.umtv(refVelocity, elementVelocity);
387 elementVelocity /= geometry.integrationElement(localPos);
389 (*velocityNonwetting)[eIdxGlobal] = elementVelocity;
393 if (pressureType == pw)
395 writer.attachCellData(*potential,
"wetting potential");
398 if (pressureType == pn)
400 writer.attachCellData(*potential,
"nonwetting potential");
403 if (vtkOutputLevel_ > 0)
405 if (pressureType == pw)
407 writer.attachCellData(*
pressure,
"wetting pressure");
408 writer.attachCellData(*pressureSecond,
"nonwetting pressure");
409 writer.attachCellData(*potentialSecond,
"nonwetting potential");
412 if (pressureType == pn)
414 writer.attachCellData(*
pressure,
"nonwetting pressure");
415 writer.attachCellData(*pressureSecond,
"wetting pressure");
416 writer.attachCellData(*potentialSecond,
"wetting potential");
419 writer.attachCellData(*velocityWetting,
"wetting-velocity", dim);
420 writer.attachCellData(*velocityNonwetting,
"non-wetting-velocity", dim);
434 int numFaces = element.subEntities(1);
435 for (
int i=0; i < numFaces; i++)
438 outstream << pressTrace_[isIdxGlobal][0];
450 int numFaces = element.subEntities(1);
451 for (
int i=0; i < numFaces; i++)
454 instream >> pressTrace_[isIdxGlobal][0];
465 A_(problem.gridView()), lstiff_(problem_, false, problem_.gridView(), A_.intersectionMapper())
467 if (pressureType != pw && pressureType != pn)
469 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
471 if (saturationType != Sw && saturationType != Sn)
473 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
477 DUNE_THROW(Dune::NotImplemented,
"Compressibility not supported!");
480 density_[wPhaseIdx] = 0.0;
481 density_[nPhaseIdx] = 0.0;
482 viscosity_[wPhaseIdx] = 0.0;
483 viscosity_[nPhaseIdx] = 0.0;
485 vtkOutputLevel_ = getParam<int>(
"Vtk.OutputLevel");
490 TraceType pressTrace_;
492 OperatorAssembler A_;
495 Scalar density_[numPhases];
496 Scalar viscosity_[numPhases];
502template<
class TypeTag>
503void MimeticPressure2PAdaptive<TypeTag>::solve()
505 using Solver =
typename GET_PROP_TYPE(TypeTag, LinearSolver);
507 int verboseLevelSolver = getParam<int>(
"LinearSolver.Verbosity");
509 if (verboseLevelSolver)
510 std::cout <<
"MimeticPressure2PAdaptive: solve for pressure" << std::endl;
512 auto solver = getSolver<Solver>(problem_);
513 solver.solve(*A_, pressTrace_, f_);
522template<
class TypeTag>
526 for (
const auto& element : elements(problem_.gridView()))
528 int eIdxGlobal = problem_.variables().index(element);
530 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
532 Scalar satW = cellData.saturation(wPhaseIdx);
535 Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW)
536 / viscosity_[wPhaseIdx];
537 Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW)
538 / viscosity_[nPhaseIdx];
541 cellData.setMobility(wPhaseIdx, mobilityW);
542 cellData.setMobility(nPhaseIdx, mobilityNw);
545 cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw));
546 cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw));
#define GET_PROP_VALUE(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:282
#define GET_PROP(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:281
#define GET_PROP_TYPE(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:283
Local stiffness matrix for the diffusion equation discretized by mimetic FD.
An assembler for the Jacobian matrix based on mimetic FD.
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
Property tag PressureRHSVector
Type of the right hand side vector given to the linear solver.
Definition: sequential/pressureproperties.hh:60
Property tag EnableCompressibility
Returns whether compressibility is allowed.
Definition: porousmediumflow/2p/sequential/properties.hh:55
Property tag SaturationFormulation
The formulation of the saturation model.
Definition: porousmediumflow/2p/sequential/properties.hh:53
Property tag NumPhases
Number of phases in the system.
Definition: porousmediumflow/sequential/properties.hh:69
Property tag PressureCoefficientMatrix
Gives maximum number of intersections of an element and neighboring elements.
Definition: porousmediumflow/sequential/properties.hh:74
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string pressure(int phaseIdx) noexcept
I/O name of pressure for multiphase systems.
Definition: name.hh:34
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
int subIndex(int elemIdx, int fIdx)
Map interface fIdx'th interface of element index to array index.
Definition: intersectionmapper.hh:236
unsigned int size() const
Definition: intersectionmapper.hh:292
const IntersectionMapper & intersectionMapper()
Definition: croperatoradaptive.hh:130
void assemble(LocalStiffness &loc, Vector &u, Vector &f)
Assembles global stiffness matrix.
Definition: croperatoradaptive.hh:232
void adapt()
Definition: croperatoradaptive.hh:111
Base class for local assemblers.
Definition: localstiffness.hh:60
Levelwise assembler.
Definition: operatoradaptive.hh:45
void calculatePressure(LocalStiffness &loc, Vector &u, Problem &problem)
Definition: operatoradaptive.hh:91
Mimetic method for the pressure equation.
Definition: mimetic/pressureadaptive.hh:62
void adapt()
Definition: mimetic/pressureadaptive.hh:206
void updateVelocity()
Velocity update.
Definition: mimetic/pressureadaptive.hh:221
void initialize(bool solveTwice=true)
Initializes the model.
Definition: mimetic/pressureadaptive.hh:179
MimeticPressure2PAdaptive(Problem &problem)
Constructs a MimeticPressure2PAdaptive object.
Definition: mimetic/pressureadaptive.hh:463
void update()
updates the model
Definition: mimetic/pressureadaptive.hh:228
void updateMaterialLaws()
Constitutive functions are initialized and stored in the variables object.
Definition: mimetic/pressureadaptive.hh:523
void serializeEntity(std::ostream &outstream, const Element &element)
General method for serialization, output.
Definition: mimetic/pressureadaptive.hh:432
void addOutputVtkFields(MultiWriter &writer)
Write data file.
Definition: mimetic/pressureadaptive.hh:252
void deserializeEntity(std::istream &instream, const Element &element)
General method for deserialization.
Definition: mimetic/pressureadaptive.hh:448
Defines the basic properties required for a mimetic method.
Finite Volume Diffusion Model.