24#ifndef DUMUX_MIMETICPRESSURE2P_HH
25#define DUMUX_MIMETICPRESSURE2P_HH
27#include <dune/common/exceptions.hh>
78 dim = GridView::dimension, dimWorld = GridView::dimensionworld
82 pw = Indices::pressureW,
83 pn = Indices::pressureNw,
84 pGlobal = Indices::pressureGlobal,
85 sw = Indices::saturationW,
86 sn = Indices::saturationNw,
87 vw = Indices::velocityW,
88 vn = Indices::velocityNw,
90 pressureType = getPropValue<TypeTag, Properties::PressureFormulation>(),
92 saturationType = getPropValue<TypeTag, Properties::SaturationFormulation>(),
96 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx,
97 numPhases = getPropValue<TypeTag, Properties::NumPhases>()
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 ;
107 using TraceType = Dune::BlockVector<Dune::FieldVector<Scalar, 1> >;
112 using ScalarSolutionType =
typename SolutionTypes::ScalarSolution;
117 using DimVector = Dune::FieldVector<Scalar, dim>;
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);
141 DUNE_THROW(Dune::NotImplemented,
"Only saturation formulation sw and sn are implemented!");
145 maxError = max(maxError, (sat - 1.0) / timeStep);
149 maxError = max(maxError, (-sat) / timeStep);
153 lstiff_.setErrorInfo(maxError, timeStep);
154 A_.
assemble(lstiff_, pressTrace_, f_);
182 const auto element = *problem_.gridView().template begin<0>();
183 FluidState fluidState;
184 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
185 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
186 fluidState.setTemperature(problem_.temperature(element));
187 fluidState.setSaturation(wPhaseIdx, 1.);
188 fluidState.setSaturation(nPhaseIdx, 0.);
196 pressTrace_.resize(problem_.gridView().size(1));
197 f_.resize(problem_.gridView().size(1));
198 lstiff_.initialize();
240 template<
class MultiWriter>
243 int size = problem_.gridView().size(0);
244 ScalarSolutionType *potential = writer.allocateManagedBuffer(size);
246 ScalarSolutionType *pressureSecond = 0;
247 ScalarSolutionType *potentialSecond = 0;
248 Dune::BlockVector < DimVector > *velocityWetting = 0;
249 Dune::BlockVector < DimVector > *velocityNonwetting = 0;
251 if (vtkOutputLevel_ > 0)
253 pressure = writer.allocateManagedBuffer(size);
254 pressureSecond = writer.allocateManagedBuffer(size);
255 potentialSecond = writer.allocateManagedBuffer(size);
256 velocityWetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
257 velocityNonwetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
261 for (
const auto& element : elements(problem_.gridView()))
263 int eIdxGlobal = problem_.variables().index(element);
264 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
266 if (pressureType == pw)
268 (*potential)[eIdxGlobal] = cellData.potential(wPhaseIdx);
271 if (pressureType == pn)
273 (*potential)[eIdxGlobal] = cellData.potential(nPhaseIdx);
276 if (vtkOutputLevel_ > 0)
279 if (pressureType == pw)
281 (*pressure)[eIdxGlobal] = cellData.pressure(wPhaseIdx);
282 (*potentialSecond)[eIdxGlobal] = cellData.potential(nPhaseIdx);
283 (*pressureSecond)[eIdxGlobal] = cellData.pressure(nPhaseIdx);
286 if (pressureType == pn)
288 (*pressure)[eIdxGlobal] = cellData.pressure(nPhaseIdx);
289 (*potentialSecond)[eIdxGlobal] = cellData.potential(wPhaseIdx);
290 (*pressureSecond)[eIdxGlobal] = cellData.pressure(wPhaseIdx);
293 const typename Element::Geometry& geometry = element.geometry();
296 const auto refElement = referenceElement(geometry);
298 const int numberOfFaces=refElement.size(1);
299 std::vector<Scalar> fluxW(numberOfFaces,0);
300 std::vector<Scalar> fluxNw(numberOfFaces,0);
303 for (
const auto& intersection : intersections(problem_.gridView(), element))
305 int isIndex = intersection.indexInInside();
307 fluxW[isIndex] += intersection.geometry().volume()
308 * (intersection.centerUnitOuterNormal() * cellData.fluxData().velocity(wPhaseIdx, isIndex));
309 fluxNw[isIndex] += intersection.geometry().volume()
310 * (intersection.centerUnitOuterNormal() * cellData.fluxData().velocity(nPhaseIdx, isIndex));
315 Dune::FieldVector<Scalar, dim> refVelocity;
317 if (refElement.type().isSimplex()) {
318 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
320 refVelocity[dimIdx] = -fluxW[dim - 1 - dimIdx];
321 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
323 refVelocity[dimIdx] += fluxW[fIdx]/(dim + 1);
328 else if (refElement.type().isCube()){
329 for (
int i = 0; i < dim; i++)
330 refVelocity[i] = 0.5 * (fluxW[2*i + 1] - fluxW[2*i]);
334 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
337 const DimVector& localPos = refElement.position(0, 0);
340 const JacobianTransposed jacobianT = geometry.jacobianTransposed(localPos);
343 DimVector elementVelocity(0);
344 jacobianT.umtv(refVelocity, elementVelocity);
345 elementVelocity /= geometry.integrationElement(localPos);
347 (*velocityWetting)[eIdxGlobal] = elementVelocity;
352 if (refElement.type().isSimplex()) {
353 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
355 refVelocity[dimIdx] = -fluxNw[dim - 1 - dimIdx];
356 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
358 refVelocity[dimIdx] += fluxNw[fIdx]/(dim + 1);
363 else if (refElement.type().isCube()){
364 for (
int i = 0; i < dim; i++)
365 refVelocity[i] = 0.5 * (fluxNw[2*i + 1] - fluxNw[2*i]);
369 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
374 jacobianT.umtv(refVelocity, elementVelocity);
375 elementVelocity /= geometry.integrationElement(localPos);
377 (*velocityNonwetting)[eIdxGlobal] = elementVelocity;
381 if (pressureType == pw)
383 writer.attachCellData(*potential,
"wetting potential");
386 if (pressureType == pn)
388 writer.attachCellData(*potential,
"nonwetting potential");
391 if (vtkOutputLevel_ > 0)
393 if (pressureType == pw)
395 writer.attachCellData(*
pressure,
"wetting pressure");
396 writer.attachCellData(*pressureSecond,
"nonwetting pressure");
397 writer.attachCellData(*potentialSecond,
"nonwetting potential");
400 if (pressureType == pn)
402 writer.attachCellData(*
pressure,
"nonwetting pressure");
403 writer.attachCellData(*pressureSecond,
"wetting pressure");
404 writer.attachCellData(*potentialSecond,
"wetting potential");
407 writer.attachCellData(*velocityWetting,
"wetting-velocity", dim);
408 writer.attachCellData(*velocityNonwetting,
"nonwetting-velocity", dim);
422 int numFaces = element.subEntities(1);
423 for (
int i=0; i < numFaces; i++)
425 int fIdxGlobal = A_.
faceMapper().subIndex(element, i, 1);
426 outstream << pressTrace_[fIdxGlobal][0];
438 int numFaces = element.subEntities(1);
439 for (
int i=0; i < numFaces; i++)
441 int fIdxGlobal = A_.
faceMapper().subIndex(element, i, 1);
442 instream >> pressTrace_[fIdxGlobal][0];
453 A_(problem.gridView()), lstiff_(problem_, false, problem_.gridView())
455 if (pressureType != pw && pressureType != pn)
457 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
459 if (saturationType != sw && saturationType != sn)
461 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
463 if (getPropValue<TypeTag, Properties::EnableCompressibility>())
465 DUNE_THROW(Dune::NotImplemented,
"Compressibility not supported!");
468 density_[wPhaseIdx] = 0.0;
469 density_[nPhaseIdx] = 0.0;
470 viscosity_[wPhaseIdx] = 0.0;
471 viscosity_[nPhaseIdx] = 0.0;
473 vtkOutputLevel_ = getParam<int>(
"Vtk.OutputLevel");
478 TraceType pressTrace_;
480 OperatorAssembler A_;
483 Scalar density_[numPhases];
484 Scalar viscosity_[numPhases];
490template<
class TypeTag>
491void MimeticPressure2P<TypeTag>::solve()
493 using Solver = GetPropType<TypeTag, Properties::LinearSolver>;
495 auto verboseLevelSolver = getParam<int>(
"LinearSolver.Verbosity", 0);
497 if (verboseLevelSolver)
498 std::cout <<
"MimeticPressure2P: solve for pressure" << std::endl;
500 auto solver = getSolver<Solver>(problem_);
501 solver.solve(*A_, pressTrace_, f_);
507template<
class TypeTag>
511 for (
const auto& element : elements(problem_.gridView()))
513 int eIdxGlobal = problem_.variables().index(element);
515 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
517 const Scalar satW = cellData.saturation(wPhaseIdx);
519 const auto fluidMatrixInteraction = problem_.spatialParams().fluidMatrixInteractionAtPos(element.geometry().center());
522 const Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx];
523 const Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx];
526 cellData.setMobility(wPhaseIdx, mobilityW);
527 cellData.setMobility(nPhaseIdx, mobilityNw);
530 cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw));
531 cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw));
Local stiffness matrix for the diffusion equation discretized by mimetic FD.
An assembler for the Jacobian matrix based on mimetic FD.
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property
Definition: propertysystem.hh:141
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
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
const FaceMapper & faceMapper()
Definition: croperator.hh:199
void assemble(LocalStiffness &loc, Vector &u, Vector &f)
Assembles global stiffness matrix.
Definition: croperator.hh:227
void initialize()
Initialize the CR operator assembler.
Definition: croperator.hh:113
Base class for local assemblers.
Definition: localstiffness.hh:60
Levelwise assembler.
Definition: operator.hh:45
void calculatePressure(LocalStiffness &loc, Vector &u, Problem &problem)
Definition: operator.hh:91
Mimetic method for the pressure equation.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:64
void updateVelocity()
Velocity update.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:216
void initialize(bool solveTwice=true)
Initializes the model.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:180
void addOutputVtkFields(MultiWriter &writer)
Write data file.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:241
void deserializeEntity(std::istream &instream, const Element &element)
General method for deserialization.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:436
void serializeEntity(std::ostream &outstream, const Element &element)
General method for serialization, output.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:420
void update()
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:223
void updateMaterialLaws()
Constitutive functions are initialized and stored in the variables object.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:508
MimeticPressure2P(Problem &problem)
Constructs a MimeticPressure2P object.
Definition: 2p/sequential/diffusion/mimetic/pressure.hh:451
Defines the basic properties required for a mimetic method.
Finite Volume Diffusion Model.