24#ifndef DUMUX_FVPRESSURE2P_HH
25#define DUMUX_FVPRESSURE2P_HH
27#include <dune/common/float_cmp.hh>
124 using MaterialLaw =
typename SpatialParams::MaterialLaw;
133 using PrimaryVariables =
typename SolutionTypes::PrimaryVariables;
137 using ScalarSolutionType =
typename SolutionTypes::ScalarSolution;
141 dim = GridView::dimension, dimWorld = GridView::dimensionworld
145 pw = Indices::pressureW,
146 pn = Indices::pressureNw,
147 pGlobal = Indices::pressureGlobal,
148 sw = Indices::saturationW,
149 sn = Indices::saturationNw,
150 pressureIdx = Indices::pressureIdx,
151 saturationIdx = Indices::saturationIdx,
152 eqIdxPress = Indices::pressureEqIdx,
153 eqIdxSat = Indices::satEqIdx
157 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = getPropValue<TypeTag, Properties::NumPhases>()
160 using Element =
typename GridView::Traits::template Codim<0>::Entity;
161 using Intersection =
typename GridView::Intersection;
163 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
164 using GravityVector = Dune::FieldVector<Scalar, dimWorld>;
165 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
178 void getSource(
EntryType& entry,
const Element& element,
const CellData& cellData,
const bool first);
181 void getStorage(
EntryType& entry,
const Element& element,
const CellData& cellData,
const bool first);
184 void getFlux(
EntryType& entry,
const Intersection& intersection,
const CellData& cellData,
const bool first);
188 const Intersection& intersection,
const CellData& cellData,
const bool first);
204 if (!compressibility_)
206 const auto element = *problem_.gridView().template begin<0>();
207 FluidState fluidState;
208 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
209 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
210 fluidState.setTemperature(problem_.temperature(element));
211 fluidState.setSaturation(wPhaseIdx, 1.);
212 fluidState.setSaturation(nPhaseIdx, 0.);
226 PressureSolutionVector pressureOld(this->
pressure());
231 PressureSolutionVector pressureDiff(pressureOld);
234 Scalar pressureNorm = pressureDiff.infinity_norm();
235 pressureNorm /= pressureOld.infinity_norm();
237 while (pressureNorm > 1e-5 && numIter < 10)
243 pressureDiff = pressureOld;
245 pressureNorm = pressureDiff.infinity_norm();
247 pressureNorm /= pressureOld.infinity_norm();
265 timeStep_ = problem_.timeManager().timeStepSize();
268 if (!compressibility_)
271 int size = problem_.gridView().size(0);
272 for (
int i = 0; i < size; i++)
275 switch (saturationType_)
278 sat = problem_.variables().cellData(i).saturation(wPhaseIdx);
281 sat = problem_.variables().cellData(i).saturation(nPhaseIdx);
287 maxError_ = max(maxError_, (sat - 1.0) / timeStep_);
292 maxError_ = max(maxError_, (-sat) / timeStep_);
312 int size = problem_.gridView().size(0);
313 for (
int i = 0; i < size; i++)
315 CellData& cellData = problem_.variables().cellData(i);
316 cellData.fluxData().resetVelocity();
324 for (
const auto& element : elements(problem_.gridView()))
326 asImp_().storePressureSolution(element);
339 int eIdxGlobal = problem_.variables().index(element);
340 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
342 if (compressibility_)
344 density_[wPhaseIdx] = cellData.density(wPhaseIdx);
345 density_[nPhaseIdx] = cellData.density(nPhaseIdx);
348 switch (pressureType_)
352 Scalar pressW = this->
pressure()[eIdxGlobal];
353 Scalar pc = cellData.capillaryPressure();
355 cellData.setPressure(wPhaseIdx, pressW);
356 cellData.setPressure(nPhaseIdx, pressW + pc);
358 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
359 Scalar potW = pressW + gravityDiff * density_[wPhaseIdx];
360 Scalar potNw = pressW + pc + gravityDiff * density_[nPhaseIdx];
362 cellData.setPotential(wPhaseIdx, potW);
363 cellData.setPotential(nPhaseIdx, potNw);
369 Scalar pressNw = this->
pressure()[eIdxGlobal];
370 Scalar pc = cellData.capillaryPressure();
372 cellData.setPressure(nPhaseIdx, pressNw);
373 cellData.setPressure(wPhaseIdx, pressNw - pc);
375 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
376 Scalar potW = pressNw - pc + gravityDiff * density_[wPhaseIdx];
377 Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx];
379 cellData.setPotential(wPhaseIdx, potW);
380 cellData.setPotential(nPhaseIdx, potNw);
386 Scalar press = this->
pressure()[eIdxGlobal];
387 cellData.setGlobalPressure(press);
389 Scalar pc = cellData.capillaryPressure();
390 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
393 Scalar potW = press - cellData.fracFlowFunc(nPhaseIdx) * pc + gravityDiff * density_[wPhaseIdx];
394 Scalar potNw = press - cellData.fracFlowFunc(wPhaseIdx) * pc + gravityDiff * density_[nPhaseIdx];
396 cellData.setPotential(wPhaseIdx, potW);
397 cellData.setPotential(nPhaseIdx, potNw);
402 cellData.fluxData().resetVelocity();
414 template<
class MultiWriter>
417 int size = problem_.gridView().size(0);
418 ScalarSolutionType *
pressure = writer.allocateManagedBuffer(size);
419 ScalarSolutionType *pressureSecond = 0;
420 ScalarSolutionType *pc = 0;
421 ScalarSolutionType *potentialW = 0;
422 ScalarSolutionType *potentialNw = 0;
423 ScalarSolutionType *mobilityW = 0;
424 ScalarSolutionType *mobilityNW = 0;
426 if (vtkOutputLevel_ > 0)
428 pressureSecond = writer.allocateManagedBuffer(size);
429 pc = writer.allocateManagedBuffer(size);
430 mobilityW = writer.allocateManagedBuffer(size);
431 mobilityNW = writer.allocateManagedBuffer(size);
433 if (vtkOutputLevel_ > 1)
435 potentialW = writer.allocateManagedBuffer(size);
436 potentialNw = writer.allocateManagedBuffer(size);
439 for (
int i = 0; i < size; i++)
441 CellData& cellData = problem_.variables().cellData(i);
443 if (pressureType_ == pw)
445 (*pressure)[i] = cellData.pressure(wPhaseIdx);
446 if (vtkOutputLevel_ > 0)
448 (*pressureSecond)[i] = cellData.pressure(nPhaseIdx);
451 else if (pressureType_ == pn)
453 (*pressure)[i] = cellData.pressure(nPhaseIdx);
454 if (vtkOutputLevel_ > 0)
456 (*pressureSecond)[i] = cellData.pressure(wPhaseIdx);
459 else if (pressureType_ == pGlobal)
461 (*pressure)[i] = cellData.globalPressure();
463 if (vtkOutputLevel_ > 0)
465 (*pc)[i] = cellData.capillaryPressure();
466 (*mobilityW)[i] = cellData.mobility(wPhaseIdx);
467 (*mobilityNW)[i] = cellData.mobility(nPhaseIdx);
468 if (compressibility_)
470 (*mobilityW)[i] = (*mobilityW)[i]/cellData.density(wPhaseIdx);
471 (*mobilityNW)[i] = (*mobilityNW)[i]/cellData.density(nPhaseIdx);
474 if (vtkOutputLevel_ > 1)
476 (*potentialW)[i] = cellData.potential(wPhaseIdx);
477 (*potentialNw)[i] = cellData.potential(nPhaseIdx);
481 if (pressureType_ == pw)
483 writer.attachCellData(*
pressure,
"wetting pressure");
484 if (vtkOutputLevel_ > 0)
486 writer.attachCellData(*pressureSecond,
"nonwetting pressure");
489 else if (pressureType_ == pn)
491 writer.attachCellData(*
pressure,
"nonwetting pressure");
492 if (vtkOutputLevel_ > 0)
494 writer.attachCellData(*pressureSecond,
"wetting pressure");
497 if (pressureType_ == pGlobal)
500 writer.attachCellData(*
pressure,
"global pressure");
503 if (vtkOutputLevel_ > 0)
505 writer.attachCellData(*pc,
"capillary pressure");
506 writer.attachCellData(*mobilityW,
"wetting mobility");
507 writer.attachCellData(*mobilityNW,
"nonwetting mobility");
509 if (vtkOutputLevel_ > 1)
511 writer.attachCellData(*potentialW,
"wetting potential");
512 writer.attachCellData(*potentialNw,
"nonwetting potential");
515 if (compressibility_)
517 if (vtkOutputLevel_ > 0)
519 ScalarSolutionType *densityWetting = writer.allocateManagedBuffer(size);
520 ScalarSolutionType *densityNonwetting = writer.allocateManagedBuffer(size);
521 ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer(size);
522 ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer(size);
524 for (
int i = 0; i < size; i++)
526 CellData& cellData = problem_.variables().cellData(i);
527 (*densityWetting)[i] = cellData.density(wPhaseIdx);
528 (*densityNonwetting)[i] = cellData.density(nPhaseIdx);
529 (*viscosityWetting)[i] = cellData.viscosity(wPhaseIdx);
530 (*viscosityNonwetting)[i] = cellData.viscosity(nPhaseIdx);
533 writer.attachCellData(*densityWetting,
"wetting density");
534 writer.attachCellData(*densityNonwetting,
"nonwetting density");
535 writer.attachCellData(*viscosityWetting,
"wetting viscosity");
536 writer.attachCellData(*viscosityNonwetting,
"nonwetting viscosity");
547 ParentType(problem), problem_(problem), gravity_(problem.gravity()), maxError_(0.), timeStep_(1.)
549 if (pressureType_ != pw && pressureType_ != pn && pressureType_ != pGlobal)
551 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
553 if (pressureType_ == pGlobal && compressibility_)
555 DUNE_THROW(Dune::NotImplemented,
"Compressibility not supported for global pressure!");
557 if (saturationType_ != sw && saturationType_ != sn)
559 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
562 ErrorTermFactor_ = getParam<Scalar>(
"Impet.ErrorTermFactor");
563 ErrorTermLowerBound_ = getParam<Scalar>(
"Impet.ErrorTermLowerBound");
564 ErrorTermUpperBound_ = getParam<Scalar>(
"Impet.ErrorTermUpperBound");
566 density_[wPhaseIdx] = 0.;
567 density_[nPhaseIdx] = 0.;
568 viscosity_[wPhaseIdx] = 0.;
569 viscosity_[nPhaseIdx] = 0.;
571 vtkOutputLevel_ = getParam<int>(
"Vtk.OutputLevel");
576 Implementation &asImp_()
577 {
return *
static_cast<Implementation *
>(
this); }
580 const Implementation &asImp_()
const
581 {
return *
static_cast<const Implementation *
>(
this); }
584 const GravityVector& gravity_;
588 Scalar ErrorTermFactor_;
589 Scalar ErrorTermLowerBound_;
590 Scalar ErrorTermUpperBound_;
592 Scalar density_[numPhases];
593 Scalar viscosity_[numPhases];
597 static const bool compressibility_ = getPropValue<TypeTag, Properties::EnableCompressibility>();
599 static const int pressureType_ = getPropValue<TypeTag, Properties::PressureFormulation>();
601 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
611template<
class TypeTag>
613 ,
const CellData& cellData,
const bool first)
616 Scalar volume = element.geometry().volume();
619 PrimaryVariables sourcePhase(0.0);
620 problem_.source(sourcePhase, element);
622 if (!compressibility_)
624 sourcePhase[wPhaseIdx] /= density_[wPhaseIdx];
625 sourcePhase[nPhaseIdx] /= density_[nPhaseIdx];
628 entry[rhs] = volume * (sourcePhase[wPhaseIdx] + sourcePhase[nPhaseIdx]);
655template<
class TypeTag>
657 ,
const CellData& cellData,
const bool first)
660 if (compressibility_ && !first)
663 Scalar volume = element.geometry().volume();
665 Scalar
porosity = problem_.spatialParams().porosity(element);
667 switch (saturationType_)
671 entry[rhs] = -(cellData.volumeCorrection()/timeStep_ *
porosity * volume
672 * (cellData.density(wPhaseIdx) - cellData.density(nPhaseIdx)));
677 entry[rhs] = -(cellData.volumeCorrection()/timeStep_ *
porosity * volume
678 * (cellData.density(nPhaseIdx) - cellData.density(wPhaseIdx)));
683 else if (!compressibility_ && !first)
688 switch (saturationType_)
691 sat = cellData.saturation(wPhaseIdx);
694 sat = cellData.saturation(nPhaseIdx);
698 Scalar volume = element.geometry().volume();
700 Scalar error = (sat > 1.0) ? sat - 1.0 : 0.0;
701 if (sat < 0.0) {error = sat;}
705 Scalar errorAbs = abs(error);
707 if ((errorAbs*timeStep_ > 1e-6) && (errorAbs > ErrorTermLowerBound_ * maxError_) && (!problem_.timeManager().willBeFinished()))
709 entry[rhs] = ErrorTermFactor_ * error * volume;
719template<
class TypeTag>
721 ,
const CellData& cellData,
const bool first)
723 auto elementI = intersection.inside();
724 auto elementJ = intersection.outside();
726 const CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(elementJ));
729 const GlobalPosition& globalPosI = elementI.geometry().center();
730 const GlobalPosition& globalPosJ = elementJ.geometry().center();
733 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
734 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
735 Scalar lambdaWJ = cellDataJ.mobility(wPhaseIdx);
736 Scalar lambdaNwJ = cellDataJ.mobility(nPhaseIdx);
739 Scalar pcI = cellData.capillaryPressure();
740 Scalar pcJ = cellDataJ.capillaryPressure();
743 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
746 Scalar faceArea = intersection.geometry().volume();
749 GlobalPosition distVec = globalPosJ - globalPosI;
752 Scalar dist = distVec.two_norm();
755 DimMatrix meanPermeability(0);
757 problem_.spatialParams().meanK(meanPermeability, problem_.spatialParams().intrinsicPermeability(elementI),
758 problem_.spatialParams().intrinsicPermeability(elementJ));
764 Scalar rhoMeanNw = 0;
765 if (compressibility_)
767 rhoMeanW = 0.5 * (cellData.density(wPhaseIdx) + cellDataJ.density(wPhaseIdx));
768 rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + cellDataJ.density(nPhaseIdx));
772 Scalar potentialDiffW = 0;
773 Scalar potentialDiffNw = 0;
778 potentialDiffW = cellData.potential(wPhaseIdx) - cellDataJ.potential(wPhaseIdx);
779 potentialDiffNw = cellData.potential(nPhaseIdx) - cellDataJ.potential(nPhaseIdx);
781 if (compressibility_)
783 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
784 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
786 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
787 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
789 potentialDiffW = cellData.pressure(wPhaseIdx) - cellDataJ.pressure(wPhaseIdx);
790 potentialDiffNw = cellData.pressure(nPhaseIdx) - cellDataJ.pressure(nPhaseIdx);
792 potentialDiffW += density_[wPhaseIdx] * (distVec * gravity_);
793 potentialDiffNw += density_[nPhaseIdx] * (distVec * gravity_);
798 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWJ;
799 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaW;
800 Scalar lambdaNw = (potentialDiffNw > 0) ? lambdaNwI : lambdaNwJ;
801 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwJ) : lambdaNw;
803 if (compressibility_)
805 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
806 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
808 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
809 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
814 entry[matrix] = (lambdaW + lambdaNw) * scalarPerm / dist * faceArea;
819 Scalar areaScaling = (unitOuterNormal * distVec);
821 entry[rhs] = (lambdaW * density_[wPhaseIdx] + lambdaNw * density_[nPhaseIdx]) * scalarPerm * (gravity_ * distVec) * faceArea * areaScaling;
823 if (pressureType_ == pw)
826 entry[rhs] += 0.5 * (lambdaNwI + lambdaNwJ) * scalarPerm * (pcI - pcJ) / dist * faceArea;
828 else if (pressureType_ == pn)
831 entry[rhs] -= 0.5 * (lambdaWI + lambdaWJ) * scalarPerm * (pcI - pcJ) / dist * faceArea;
843template<
class TypeTag>
845const Intersection& intersection,
const CellData& cellData,
const bool first)
847 auto element = intersection.inside();
850 const GlobalPosition& globalPosI = element.geometry().center();
853 const GlobalPosition& globalPosJ = intersection.geometry().center();
856 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
857 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
858 Scalar fractionalWI = cellData.fracFlowFunc(wPhaseIdx);
859 Scalar fractionalNwI = cellData.fracFlowFunc(nPhaseIdx);
862 Scalar pcI = cellData.capillaryPressure();
865 int isIndexI = intersection.indexInInside();
868 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
871 Scalar faceArea = intersection.geometry().volume();
874 GlobalPosition distVec = globalPosJ - globalPosI;
877 Scalar dist = distVec.two_norm();
879 BoundaryTypes bcType;
880 problem_.boundaryTypes(bcType, intersection);
881 PrimaryVariables boundValues(0.0);
883 if (bcType.isDirichlet(eqIdxPress))
885 problem_.dirichlet(boundValues, intersection);
889 DimMatrix meanPermeability(0);
891 problem_.spatialParams().meanK(meanPermeability,
892 problem_.spatialParams().intrinsicPermeability(element));
900 if (bcType.isDirichlet(eqIdxSat))
902 switch (saturationType_)
906 satW = boundValues[saturationIdx];
907 satNw = 1 - boundValues[saturationIdx];
912 satW = 1 - boundValues[saturationIdx];
913 satNw = boundValues[saturationIdx];
920 satW = cellData.saturation(wPhaseIdx);
921 satNw = cellData.saturation(nPhaseIdx);
923 Scalar
temperature = problem_.temperature(element);
926 Scalar pressBound = boundValues[pressureIdx];
929 Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW);
934 if (pressureType_ == pw)
937 pressNw = pressBound + pcBound;
939 else if (pressureType_ == pn)
941 pressW = pressBound - pcBound;
942 pressNw = pressBound;
945 Scalar densityWBound = density_[wPhaseIdx];
946 Scalar densityNwBound = density_[nPhaseIdx];
947 Scalar viscosityWBound = viscosity_[wPhaseIdx];
948 Scalar viscosityNwBound = viscosity_[nPhaseIdx];
950 Scalar rhoMeanNw = 0;
952 if (compressibility_)
954 FluidState fluidState;
955 fluidState.setSaturation(wPhaseIdx, satW);
956 fluidState.setSaturation(nPhaseIdx, satNw);
958 fluidState.setPressure(wPhaseIdx, pressW);
959 fluidState.setPressure(nPhaseIdx, pressNw);
966 rhoMeanW = 0.5 * (cellData.density(wPhaseIdx) + densityWBound);
967 rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + densityNwBound);
970 Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW)
972 Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW)
975 Scalar fractionalWBound = lambdaWBound / (lambdaWBound + lambdaNwBound);
976 Scalar fractionalNwBound = lambdaNwBound / (lambdaWBound + lambdaNwBound);
978 Scalar fMeanW = 0.5 * (fractionalWI + fractionalWBound);
979 Scalar fMeanNw = 0.5 * (fractionalNwI + fractionalNwBound);
981 Scalar potentialDiffW = 0;
982 Scalar potentialDiffNw = 0;
986 potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndexI);
987 potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndexI);
989 if (compressibility_)
991 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : densityWBound;
992 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : densityNwBound;
994 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
995 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
999 switch (pressureType_)
1003 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressBound);
1004 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressBound - pcBound);
1009 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressBound + pcBound);
1010 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressBound);
1015 potentialDiffW = (cellData.globalPressure() - pressBound - fMeanNw * (pcI - pcBound));
1016 potentialDiffNw = (cellData.globalPressure() - pressBound + fMeanW * (pcI - pcBound));
1021 potentialDiffW += density_[wPhaseIdx] * (distVec * gravity_);
1022 potentialDiffNw += density_[nPhaseIdx] * (distVec * gravity_);
1026 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWBound;
1027 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
1028 Scalar lambdaNw = (potentialDiffNw > 0.) ? lambdaNwI : lambdaNwBound;
1029 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwBound) : lambdaNw;
1031 if (compressibility_)
1033 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : densityWBound;
1034 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
1035 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : densityNwBound;
1036 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
1041 entry[matrix] = (lambdaW + lambdaNw) * scalarPerm / dist * faceArea;
1042 entry[rhs] = entry[matrix] * pressBound;
1047 Scalar areaScaling = (unitOuterNormal * distVec);
1049 entry[rhs] -= (lambdaW * density_[wPhaseIdx] + lambdaNw * density_[nPhaseIdx]) * scalarPerm * (gravity_ * distVec)
1050 * faceArea * areaScaling;
1052 if (pressureType_ == pw)
1055 entry[rhs] -= 0.5 * (lambdaNwI + lambdaNwBound) * scalarPerm * (pcI - pcBound) / dist * faceArea;
1057 else if (pressureType_ == pn)
1060 entry[rhs] += 0.5 * (lambdaWI + lambdaWBound) * scalarPerm * (pcI - pcBound) / dist * faceArea;
1064 else if (bcType.isNeumann(eqIdxPress))
1066 problem_.neumann(boundValues, intersection);
1068 if (!compressibility_)
1070 boundValues[wPhaseIdx] /= density_[wPhaseIdx];
1071 boundValues[nPhaseIdx] /= density_[nPhaseIdx];
1073 entry[rhs] = -(boundValues[wPhaseIdx] + boundValues[nPhaseIdx]) * faceArea;
1077 DUNE_THROW(Dune::NotImplemented,
"No valid boundary condition type defined for pressure equation!");
1089template<
class TypeTag>
1092 for (
const auto& element : elements(problem_.gridView()))
1094 int eIdxGlobal = problem_.variables().index(element);
1096 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
1098 Scalar
temperature = problem_.temperature(element);
1102 Scalar satW = cellData.saturation(wPhaseIdx);
1104 Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW);
1109 if (pressureType_ == pw)
1111 pressW = cellData.pressure(wPhaseIdx);
1112 pressNw = pressW + pc;
1114 else if (pressureType_ == pn)
1116 pressNw = cellData.pressure(nPhaseIdx);
1117 pressW = pressNw - pc;
1120 if (compressibility_)
1122 FluidState& fluidState = cellData.fluidState();
1125 fluidState.setPressure(wPhaseIdx, pressW);
1126 fluidState.setPressure(nPhaseIdx, pressNw);
1135 fluidState.setDensity(wPhaseIdx, density_[wPhaseIdx]);
1136 fluidState.setDensity(nPhaseIdx, density_[nPhaseIdx]);
1139 fluidState.setViscosity(wPhaseIdx, viscosity_[wPhaseIdx]);
1140 fluidState.setViscosity(nPhaseIdx, viscosity_[nPhaseIdx]);
1144 cellData.setCapillaryPressure(pc);
1146 if (pressureType_ != pGlobal)
1148 cellData.setPressure(wPhaseIdx, pressW);
1149 cellData.setPressure(nPhaseIdx, pressNw);
1154 Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[wPhaseIdx];
1155 Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[nPhaseIdx];
1157 if (compressibility_)
1159 mobilityW *= density_[wPhaseIdx];
1160 mobilityNw *= density_[nPhaseIdx];
1164 cellData.setMobility(wPhaseIdx, mobilityW);
1165 cellData.setMobility(nPhaseIdx, mobilityNw);
1168 cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw));
1169 cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw));
1171 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
1173 Scalar potW = pressW + gravityDiff * density_[wPhaseIdx];
1174 Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx];
1176 if (pressureType_ == pGlobal)
1178 potW = cellData.globalPressure() - cellData.fracFlowFunc(nPhaseIdx) * pc + gravityDiff * density_[wPhaseIdx];
1179 potNw = cellData.globalPressure() - cellData.fracFlowFunc(wPhaseIdx) * pc + gravityDiff * density_[nPhaseIdx];
1182 cellData.setPotential(wPhaseIdx, potW);
1183 cellData.setPotential(nPhaseIdx, potNw);
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 temperature() noexcept
I/O name of temperature for equilibrium models.
Definition: name.hh:51
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string permeability() noexcept
I/O name of permeability.
Definition: name.hh:143
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
std::string porosity() noexcept
I/O name of porosity.
Definition: name.hh:139
Finite Volume discretization of a two-phase flow pressure equation of the sequential IMPES model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:113
void storePressureSolution(const Element &element)
Stores the pressure solution of a cell.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:337
void storePressureSolution()
Globally stores the pressure solution.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:321
void getFlux(EntryType &entry, const Intersection &intersection, const CellData &cellData, const bool first)
Function which calculates the flux entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:720
FVPressure2P(Problem &problem)
Constructs a FVPressure2P object.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:546
void updateMaterialLaws()
Updates and stores constitutive relations.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:1090
void getFluxOnBoundary(EntryType &entry, const Intersection &intersection, const CellData &cellData, const bool first)
Function which calculates the boundary flux entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:844
void initialize(bool solveTwice=true)
Initializes the pressure model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:200
void getSource(EntryType &entry, const Element &element, const CellData &cellData, const bool first)
Function which calculates the source entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:612
void getStorage(EntryType &entry, const Element &element, const CellData &cellData, const bool first)
Function which calculates the storage entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:656
void addOutputVtkFields(MultiWriter &writer)
Adds pressure output to the output file.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:415
void updateVelocity()
Velocity update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:307
void update()
Pressure update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:263
The finite volume base class for the solution of a pressure equation.
Definition: sequential/cellcentered/pressure.hh:49
void assemble(bool first)
Function which assembles the system of equations to be solved.
Definition: sequential/cellcentered/pressure.hh:401
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
void solve()
Solves the global system of equations to get the spatial distribution of the pressure.
Definition: sequential/cellcentered/pressure.hh:527
void update()
Pressure update.
Definition: sequential/cellcentered/pressure.hh:228
Dune::FieldVector< Scalar, 2 > EntryType
Definition: sequential/cellcentered/pressure.hh:78
Specifies the properties for immiscible 2p diffusion/pressure models.
Finite Volume Diffusion Model.