24#ifndef DUMUX_FVPRESSURE2P_ADAPTIVE_HH
25#define DUMUX_FVPRESSURE2P_ADAPTIVE_HH
27#include <dune/common/float_cmp.hh>
58 using PrimaryVariables =
typename SolutionTypes::PrimaryVariables;
63 dim = GridView::dimension, dimWorld = GridView::dimensionworld
67 pw = Indices::pressureW,
68 pn = Indices::pressureNw,
69 pGlobal = Indices::pressureGlobal,
70 sw = Indices::saturationW,
71 sn = Indices::saturationNw
75 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = getPropValue<TypeTag, Properties::NumPhases>()
78 using Intersection =
typename GridView::Intersection;
80 using Element =
typename GridView::template Codim<0>::Entity;
82 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
83 using GravityVector = Dune::FieldVector<Scalar, dimWorld>;
84 using FieldMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
108 if (!compressibility_)
110 const auto element = *problem_.gridView().template begin<0>();
111 FluidState fluidState;
112 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
113 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
114 fluidState.setTemperature(problem_.temperature(element));
115 fluidState.setSaturation(wPhaseIdx, 1.);
116 fluidState.setSaturation(nPhaseIdx, 0.);
123 velocity_.initialize();
136 int gridSize = problem_.gridView().size(0);
138 if (problem_.gridAdapt().wasAdapted())
140 this->
A_.setSize(gridSize, gridSize);
141 this->
f_.resize(gridSize);
145 for (
int i = 0; i < gridSize; i++)
147 CellData& cellData = problem_.variables().cellData(i);
149 switch (pressureType_)
152 this->
pressure()[i] = cellData.pressure(wPhaseIdx);
155 this->
pressure()[i] = cellData.pressure(nPhaseIdx);
158 this->
pressure()[i] = cellData.globalPressure();
179 velocity_.calculateVelocity();
197 template<
class MultiWriter>
202 velocity_.addOutputVtkFields(writer);
211 ParentType(problem), problem_(problem), velocity_(problem), gravity_(problem.gravity())
213 if (pressureType_ != pw && pressureType_ != pn && pressureType_ != pGlobal)
215 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
217 if (pressureType_ == pGlobal && compressibility_)
219 DUNE_THROW(Dune::NotImplemented,
"Compressibility not supported for global pressure!");
221 if (saturationType_ != sw && saturationType_ != sn)
223 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
226 density_[wPhaseIdx] = 0.;
227 density_[nPhaseIdx] = 0.;
228 viscosity_[wPhaseIdx] = 0.;
229 viscosity_[nPhaseIdx] = 0.;
235 const GravityVector& gravity_;
237 Scalar density_[numPhases];
238 Scalar viscosity_[numPhases];
240 static const bool compressibility_ = getPropValue<TypeTag, Properties::EnableCompressibility>();
242 static const int pressureType_ = getPropValue<TypeTag, Properties::PressureFormulation>();
244 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
255template<
class TypeTag>
257 ,
const CellData& cellData,
const bool first)
259 auto elementI = intersection.inside();
260 auto elementJ = intersection.outside();
262 if (elementI.level() == elementJ.level() || dim == 3)
264 ParentType::getFlux(entry, intersection, cellData, first);
267 if (getPropValue<TypeTag, Properties::VisitFacesOnlyOnce>() && elementI.level() < elementJ.level())
273 else if (elementJ.level() == elementI.level() + 1)
275 const CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(elementJ));
278 const GlobalPosition& globalPosI = elementI.geometry().center();
279 const GlobalPosition& globalPosJ = elementJ.geometry().center();
281 int globalIdxI = problem_.variables().index(elementI);
282 int globalIdxJ = problem_.variables().index(elementJ);
285 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
286 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
287 Scalar fractionalWI = cellData.fracFlowFunc(wPhaseIdx);
288 Scalar fractionalNwI = cellData.fracFlowFunc(nPhaseIdx);
289 Scalar lambdaWJ = cellDataJ.mobility(wPhaseIdx);
290 Scalar lambdaNwJ = cellDataJ.mobility(nPhaseIdx);
291 Scalar fractionalWJ = cellDataJ.fracFlowFunc(wPhaseIdx);
292 Scalar fractionalNwJ = cellDataJ.fracFlowFunc(nPhaseIdx);
295 Scalar pcI = cellData.capillaryPressure();
296 Scalar pcJ = cellDataJ.capillaryPressure();
299 int isIndexI = intersection.indexInInside();
302 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
305 Scalar faceArea = intersection.geometry().volume();
310 auto elementK = intersection.outside();
315 for (
const auto& intersectionI : intersections(problem_.gridView(), elementI))
317 if (intersectionI.neighbor())
319 auto neighbor2 = intersectionI.outside();
323 if (neighbor2 != elementJ && intersectionI.indexInInside() == isIndexI)
325 globalIdxK = problem_.variables().index(neighbor2);
326 elementK = neighbor2;
332 const CellData& cellDataK = problem_.variables().cellData(globalIdxK);
335 const GlobalPosition& globalPosInterface = intersection.geometry().center();
337 Dune::FieldVector < Scalar, dimWorld > distVec = globalPosInterface - globalPosI;
338 Scalar lI = distVec * unitOuterNormal;
339 distVec = globalPosJ - globalPosInterface;
340 Scalar lJ = distVec * unitOuterNormal;
343 FieldMatrix permeabilityI(0);
344 FieldMatrix permeabilityJ(0);
345 FieldMatrix permeabilityK(0);
347 problem_.spatialParams().meanK(permeabilityI,
348 problem_.spatialParams().intrinsicPermeability(elementI));
349 problem_.spatialParams().meanK(permeabilityJ,
350 problem_.spatialParams().intrinsicPermeability(elementJ));
351 problem_.spatialParams().meanK(permeabilityK,
352 problem_.spatialParams().intrinsicPermeability(elementK));
355 Scalar kI, kJ, kK, kMean, ng;
356 Dune::FieldVector < Scalar, dim > permI(0);
357 Dune::FieldVector < Scalar, dim > permJ(0);
358 Dune::FieldVector < Scalar, dim > permK(0);
360 permeabilityI.mv(unitOuterNormal, permI);
361 permeabilityJ.mv(unitOuterNormal, permJ);
362 permeabilityK.mv(unitOuterNormal, permK);
365 kI = unitOuterNormal * permI;
366 kJ = unitOuterNormal * permJ;
367 kK = unitOuterNormal * permK;
370 kMean = kI * kJ * kK * l / (kJ * kK * lI + kI * (kJ + kK) / 2 * lJ);
372 ng = gravity_ * unitOuterNormal;
374 Scalar fractionalWK = cellDataK.fracFlowFunc(wPhaseIdx);
375 Scalar fractionalNwK = cellDataK.fracFlowFunc(nPhaseIdx);
377 Scalar pcK = cellDataK.capillaryPressure();
378 Scalar pcJK = (pcJ + pcK) / 2;
385 Scalar rhoMeanWIJ = density_[wPhaseIdx];
386 Scalar rhoMeanNwIJ = density_[nPhaseIdx];
387 Scalar rhoMeanWIK = density_[wPhaseIdx];
388 Scalar rhoMeanNwIK = density_[nPhaseIdx];
390 if (compressibility_)
392 rhoMeanWIJ = (lJ * cellData.density(wPhaseIdx) + lI * cellDataJ.density(wPhaseIdx)) / l;
393 rhoMeanNwIJ = (lJ * cellData.density(nPhaseIdx) + lI * cellDataJ.density(nPhaseIdx)) / l;
394 rhoMeanWIK = (lJ * cellData.density(wPhaseIdx) + lI * cellDataK.density(wPhaseIdx)) / l;
395 rhoMeanNwIK = (lJ * cellData.density(nPhaseIdx) + lI * cellDataK.density(nPhaseIdx)) / l;
398 Scalar densityWIJ = density_[wPhaseIdx];
399 Scalar densityNwIJ = density_[nPhaseIdx];
400 Scalar densityWIK = density_[wPhaseIdx];
401 Scalar densityNwIK = density_[nPhaseIdx];
403 Scalar fMeanWIJ = (lJ * fractionalWI + lI * fractionalWJ) / l;
404 Scalar fMeanNwIJ = (lJ * fractionalNwI + lI * fractionalNwJ) / l;
405 Scalar fMeanWIK = (lJ * fractionalWI + lI * fractionalWK) / l;
406 Scalar fMeanNwIK = (lJ * fractionalNwI + lI * fractionalNwK) / l;
408 Scalar potentialWIJ = 0;
409 Scalar potentialNwIJ = 0;
410 Scalar potentialWIK = 0;
411 Scalar potentialNwIK = 0;
417 if (compressibility_)
419 densityWIJ = rhoMeanWIJ;
420 densityNwIJ = rhoMeanNwIJ;
421 densityWIK = rhoMeanWIK;
422 densityNwIK = rhoMeanNwIK;
425 switch (pressureType_)
429 Scalar pressJK = (cellDataJ.globalPressure() + cellDataK.globalPressure()) / 2;
431 potentialWIJ = (cellData.globalPressure() - fMeanNwIJ * pcI - (pressJK - fMeanNwIJ * pcJK)) / l
432 + (densityWIJ - lJ / l * (kI + kK) / kI * (densityWIK - densityWIJ) / 2) * ng;
433 potentialNwIJ = (cellData.globalPressure() + fMeanWIJ * pcI - (pressJK + fMeanWIJ * pcJK)) / l
434 + (densityNwIJ - lJ / l * (kI + kK) / kI * (densityNwIK - densityNwIJ) / 2) * ng;
435 potentialWIK = (cellData.globalPressure() - fMeanNwIK * pcI - (pressJK - fMeanNwIK * pcJK)) / l
436 + (densityWIK - lJ / l * (kI + kK) / kI * (densityWIJ - densityWIK) / 2) * ng;
437 potentialNwIK = (cellData.globalPressure() + fMeanWIK * pcI - (pressJK + fMeanWIK * pcJK)) / l
438 + (densityNwIK - lJ / l * (kI + kK) / kI * (densityNwIJ - densityNwIK) / 2) * ng;
443 potentialWIJ = (cellData.pressure(wPhaseIdx)
444 - 0.5 * (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx))) / l
445 + (densityWIJ - lJ / l * (kI + kK) / kI * (densityWIK - densityWIJ) / 2) * ng;
446 potentialNwIJ = (cellData.pressure(nPhaseIdx)
447 - (0.5 * (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)))) / l
448 + (densityNwIJ - lJ / l * (kI + kK) / kI * (densityNwIK - densityNwIJ) / 2) * ng;
449 potentialWIK = (cellData.pressure(wPhaseIdx)
450 - 0.5 * (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx))) / l
451 + (densityWIK - lJ / l * (kI + kK) / kI * (densityWIJ - densityWIK) / 2) * ng;
452 potentialNwIK = (cellData.pressure(nPhaseIdx)
453 - (0.5 * (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)))) / l
454 + (densityNwIK - lJ / l * (kI + kK) / kI * (densityNwIJ - densityNwIK) / 2) * ng;
461 Scalar lambdaWIJ = (potentialWIJ > 0.) ? lambdaWI : lambdaWJ;
462 lambdaWIJ = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialWIJ, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaWIJ;
463 Scalar lambdaNwIJ = (potentialNwIJ > 0) ? lambdaNwI : lambdaNwJ;
464 lambdaNwIJ = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialNwIJ, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwJ) : lambdaNwIJ;
466 if (compressibility_)
468 densityWIJ = (potentialWIJ > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
469 densityNwIJ = (potentialNwIJ > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
470 densityWIJ = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialWIJ, 0.0, 1.0e-30)) ? rhoMeanWIJ : densityWIJ;
471 densityNwIJ = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialNwIJ, 0.0, 1.0e-30)) ? rhoMeanNwIJ : densityNwIJ;
472 densityWIK = (potentialWIK > 0.) ? cellData.density(wPhaseIdx) : cellDataK.density(wPhaseIdx);
473 densityNwIK = (potentialNwIK > 0.) ? cellData.density(nPhaseIdx) : densityNwIK;
474 densityWIK = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialWIK, 0.0, 1.0e-30)) ? rhoMeanWIK : densityWIK;
475 densityNwIK = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialNwIK, 0.0, 1.0e-30)) ? rhoMeanNwIK : densityNwIK;
479 entry[matrix] = (lambdaWIJ + lambdaNwIJ) * kMean / l * faceArea;
480 entry[rhs] = faceArea * lambdaWIJ * kMean * ng
481 * ((densityWIJ) - (lJ / l) * (kI + kK) / kI * (densityWIK - densityWIJ) / 2);
482 entry[rhs] += faceArea * lambdaNwIJ * kMean * ng
483 * ((densityNwIJ) - (lJ / l) * (kI + kK) / kI * (densityNwIK - densityNwIJ) / 2);
485 switch (pressureType_)
489 entry[rhs] += faceArea * lambdaNwIJ * kMean * (pcJK - pcI) / l;
494 entry[rhs] -= faceArea * lambdaWIJ * kMean * (pcJK - pcI) / l;
500 this->f_[globalIdxI] -= entry[rhs];
501 this->f_[globalIdxJ] += entry[rhs];
504 this->A_[globalIdxI][globalIdxI] += entry[matrix];
506 this->A_[globalIdxI][globalIdxJ] -= entry[matrix];
509 this->A_[globalIdxJ][globalIdxI] -= entry[matrix];
510 this->A_[globalIdxJ][globalIdxJ] += entry[matrix];
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:140
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
Finite Volume discretization of a two-phase flow pressure equation of the sequential IMPES model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:115
void addOutputVtkFields(MultiWriter &writer)
Adds pressure output to the output file.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:416
void updateVelocity()
Velocity update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:308
void update()
Pressure update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:264
Finite volume discretization of a two-phase flow pressure equation of the sequential IMPES model.
Definition: cellcentered/pressureadaptive.hh:45
void initialize()
Initializes the adaptive pressure model.
Definition: cellcentered/pressureadaptive.hh:104
FVPressure2PAdaptive(Problem &problem)
Constructs a FVPressure2PAdaptive object.
Definition: cellcentered/pressureadaptive.hh:210
void update()
Pressure update.
Definition: cellcentered/pressureadaptive.hh:134
void addOutputVtkFields(MultiWriter &writer)
Adds pressure output to the output file.
Definition: cellcentered/pressureadaptive.hh:198
void getFlux(EntryType &, const Intersection &, const CellData &, const bool)
Function which calculates the flux entry.
Definition: cellcentered/pressureadaptive.hh:256
void updateVelocity()
Velocity update.
Definition: cellcentered/pressureadaptive.hh:185
void calculateVelocity()
Velocity calculation.
Definition: cellcentered/pressureadaptive.hh:177
The finite volume base class for the solution of a pressure equation.
Definition: sequential/cellcentered/pressure.hh:49
void initialize()
Initialize pressure model.
Definition: sequential/cellcentered/pressure.hh:213
PressureSolution & pressure()
Returns the vector containing the pressure solution.
Definition: sequential/cellcentered/pressure.hh:120
@ rhs
index for the right hand side entry
Definition: sequential/cellcentered/pressure.hh:88
@ matrix
index for the global matrix entry
Definition: sequential/cellcentered/pressure.hh:89
Matrix A_
Global stiffnes matrix (sparse matrix which is build by the initializeMatrix() function)
Definition: sequential/cellcentered/pressure.hh:324
RHSVector f_
Right hand side vector.
Definition: sequential/cellcentered/pressure.hh:325
Dune::FieldVector< Scalar, 2 > EntryType
Definition: sequential/cellcentered/pressure.hh:78
void initializeMatrix()
Initialize the global matrix of the system of equations to solve.
Definition: sequential/cellcentered/pressure.hh:332
Base class for finite volume velocity reconstruction.
Definition: sequential/cellcentered/velocity.hh:48
Defines the properties required for (immiscible) two-phase sequential models.
Finite Volume discretization of a two-phase flow pressure equation.
Finite volume velocity reconstruction.