3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
2dpressurevelocityadaptive.hh
Go to the documentation of this file.
1/*****************************************************************************
2 * See the file COPYING for full copying permissions. *
3 * *
4 * This program is free software: you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation, either version 3 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 *****************************************************************************/
22#ifndef DUMUX_MPFAL2DPRESSUREVELOCITIES2P_ADAPTIVE_HH
23#define DUMUX_MPFAL2DPRESSUREVELOCITIES2P_ADAPTIVE_HH
24
25#include <dune/common/float_cmp.hh>
26
27#include "2dpressureadaptive.hh"
28#include "2dvelocityadaptive.hh"
29
30namespace Dumux {
31
47template<class TypeTag> class FvMpfaL2dPressureVelocity2pAdaptive: public FvMpfaL2dPressure2pAdaptive<TypeTag>
48{
50
52
53 enum
54 {
55 dim = GridView::dimension, dimWorld = GridView::dimensionworld
56 };
57
63 using PrimaryVariables = typename SolutionTypes::PrimaryVariables;
64
66
68
71
72 using Grid = typename GridView::Grid;
73 using IndexSet = typename GridView::IndexSet;
74 using Intersection = typename GridView::Intersection;
75
76 using Geometry = typename Grid::template Codim<0>::Entity::Geometry;
77 using JacobianTransposed = typename Geometry::JacobianTransposed ;
78
80
81 enum
82 {
83 pw = Indices::pressureW,
84 pn = Indices::pressureNw,
85 sw = Indices::saturationW,
86 sn = Indices::saturationNw
87 };
88 enum
89 {
90 wPhaseIdx = Indices::wPhaseIdx,
91 nPhaseIdx = Indices::nPhaseIdx,
92 pressureIdx = Indices::pressureIdx,
93 saturationIdx = Indices::saturationIdx,
94 pressEqIdx = Indices::pressureEqIdx,
95 satEqIdx = Indices::satEqIdx,
96 numPhases = getPropValue<TypeTag, Properties::NumPhases>()
97 };
98
99 using Element = typename GridView::template Codim<0>::Entity;
100
101 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
102 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
103 using DimVector = Dune::FieldVector<Scalar, dim>;
104
105public:
112 ParentType(problem), problem_(problem), velocity_(problem)
113 {
114 density_[wPhaseIdx] = 0.;
115 density_[nPhaseIdx] = 0.;
116 viscosity_[wPhaseIdx] = 0.;
117 viscosity_[nPhaseIdx] = 0.;
118
119 calcVelocityInTransport_ = getParam<bool>("MPFA.CalcVelocityInTransport");
120 }
121
123 void calculateVelocity();
124
126 void calculateVelocity(const Intersection&, CellData&);
127 void calculateVelocityOnBoundary(const Intersection& intersection, CellData& cellData);
128
131 {
132 this->updateMaterialLaws();
133
134 this->storePressureSolution();
135
138 }
139
146 {
147 const auto element = *problem_.gridView().template begin<0>();
148 FluidState fluidState;
149 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
150 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
151 fluidState.setTemperature(problem_.temperature(element));
152 fluidState.setSaturation(wPhaseIdx, 1.);
153 fluidState.setSaturation(nPhaseIdx, 0.);
154 density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
155 density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
156 viscosity_[wPhaseIdx] = FluidSystem::viscosity(fluidState, wPhaseIdx);
157 viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
158
160 velocity_.initialize();
163
164 return;
165 }
166
172 void update()
173 {
177 }
178
185 {
186 return calcVelocityInTransport_;
187 }
188
199 template<class MultiWriter>
200 void addOutputVtkFields(MultiWriter &writer)
201 {
203 velocity_.addOutputVtkFields(writer);
204 }
205
206private:
207 Problem& problem_;
209
210 Scalar density_[numPhases];
211 Scalar viscosity_[numPhases];
212 bool calcVelocityInTransport_;
213
215 static const int pressureType_ = getPropValue<TypeTag, Properties::PressureFormulation>();
217 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
218};
219// end of template
220
226template<class TypeTag>
228{
229 // run through all elements
230 for (const auto& vertex : vertices(problem_.gridView()))
231 {
232 int vIdxGlobal = problem_.variables().index(vertex);
233
234 InteractionVolume& interactionVolume = this->interactionVolumes_[vIdxGlobal];
235
236 if (interactionVolume.isInnerVolume())
237 {
238 if (interactionVolume.getElementNumber() == 4)
239 {
240 auto element1 = interactionVolume.getSubVolumeElement(0);
241 auto element2 = interactionVolume.getSubVolumeElement(1);
242 auto element3 = interactionVolume.getSubVolumeElement(2);
243 auto element4 = interactionVolume.getSubVolumeElement(3);
244
245 // cell index
246 int eIdxGlobal1 = problem_.variables().index(element1);
247 int eIdxGlobal2 = problem_.variables().index(element2);
248 int eIdxGlobal3 = problem_.variables().index(element3);
249 int eIdxGlobal4 = problem_.variables().index(element4);
250
251 //get the cell Data
252 CellData& cellData1 = problem_.variables().cellData(eIdxGlobal1);
253 CellData& cellData2 = problem_.variables().cellData(eIdxGlobal2);
254 CellData& cellData3 = problem_.variables().cellData(eIdxGlobal3);
255 CellData& cellData4 = problem_.variables().cellData(eIdxGlobal4);
256
257 velocity_.calculateInnerInteractionVolumeVelocity(interactionVolume, cellData1, cellData2, cellData3,
258 cellData4, this->innerBoundaryVolumeFaces_);
259
260 }
261 else if (interactionVolume.getElementNumber() == 3)
262 {
263 auto element1 = interactionVolume.getSubVolumeElement(0);
264 auto element2 = interactionVolume.getSubVolumeElement(1);
265 auto element4 = interactionVolume.getSubVolumeElement(3);
266
267 // cell index
268 int eIdxGlobal1 = problem_.variables().index(element1);
269 int eIdxGlobal2 = problem_.variables().index(element2);
270 int eIdxGlobal4 = problem_.variables().index(element4);
271
272 //get the cell Data
273 CellData& cellData1 = problem_.variables().cellData(eIdxGlobal1);
274 CellData& cellData2 = problem_.variables().cellData(eIdxGlobal2);
275 CellData& cellData4 = problem_.variables().cellData(eIdxGlobal4);
276
277 velocity_.calculateHangingNodeInteractionVolumeVelocity(interactionVolume, cellData1, cellData2,
278 cellData4, this->innerBoundaryVolumeFaces_);
279
280 }
281 else
282 {
283 DUNE_THROW(Dune::NotImplemented, "Unknown interactionvolume type!");
284 }
285 }
286
287 // at least one face on boundary!
288 else
289 {
290 for (int elemIdx = 0; elemIdx < 2 * dim; elemIdx++)
291 {
292 bool isOutside = false;
293 for (int fIdx = 0; fIdx < dim; fIdx++)
294 {
295 int intVolFaceIdx = interactionVolume.getFaceIndexFromSubVolume(elemIdx, fIdx);
296 if (interactionVolume.isOutsideFace(intVolFaceIdx))
297 {
298 isOutside = true;
299 break;
300 }
301 }
302 if (isOutside)
303 {
304 continue;
305 }
306 // cell index
307 int eIdxGlobal = problem_.variables().index(interactionVolume.getSubVolumeElement(elemIdx));
308 //get the cell Data
309 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
310
311 velocity_.calculateBoundaryInteractionVolumeVelocity(interactionVolume, cellData, elemIdx);
312 }
313
314 } // end boundaries
315
316 } // end vertex iterator
317 return;
318} // end method calcTotalVelocity
319
328template<class TypeTag>
329void FvMpfaL2dPressureVelocity2pAdaptive<TypeTag>::calculateVelocity(const Intersection& intersection, CellData& cellData)
330{
331 int numVertices = intersection.geometry().corners();
332
333 auto elementI = intersection.inside();
334 auto elementJ = intersection.outside();
335
336 int levelI = elementI.level();
337 int levelJ = elementJ.level();
338
339 int eIdxGlobalI = problem_.variables().index(elementI);
340 int eIdxGlobalJ = problem_.variables().index(elementJ);
341
342 CellData& cellDataJ = problem_.variables().cellData(eIdxGlobalJ);
343
344 const auto refElement = referenceElement(elementI);
345
346 int indexInInside = intersection.indexInInside();
347 int indexInOutside = intersection.indexInOutside();
348
349 int fIdx = indexInInside;
350
351 if (levelI < levelJ)
352 fIdx = indexInOutside;
353
354 std::vector<CellData> cellDataTemp(0);
355
356 if (levelI != levelJ)
357 {
358 DimVector vel(0);
359 cellData.fluxData().setVelocity(wPhaseIdx, indexInInside, vel);
360 cellData.fluxData().setVelocity(nPhaseIdx, indexInInside, vel);
361 cellData.fluxData().setUpwindPotential(wPhaseIdx, indexInInside, 0);
362 cellData.fluxData().setUpwindPotential(nPhaseIdx, indexInInside, 0);
363
364 cellDataJ.fluxData().setVelocity(wPhaseIdx, indexInOutside, vel);
365 cellDataJ.fluxData().setVelocity(nPhaseIdx, indexInOutside, vel);
366 cellDataJ.fluxData().setUpwindPotential(wPhaseIdx, indexInOutside, 0);
367 cellDataJ.fluxData().setUpwindPotential(nPhaseIdx, indexInOutside, 0);
368 }
369
370 for (int vIdx = 0; vIdx < numVertices; vIdx++)
371 {
372 int localVertIdx = refElement.subEntity(fIdx, dim - 1, vIdx, dim);
373
374 int vIdxGlobal = 0;
375 if (levelI >= levelJ)
376 {
377 vIdxGlobal = problem_.variables().index(elementI.template subEntity<dim>(localVertIdx));
378 }
379 else
380 {
381 vIdxGlobal = problem_.variables().index(elementJ.template subEntity<dim>(localVertIdx));
382 }
383
384 InteractionVolume& interactionVolume = this->interactionVolumes_[vIdxGlobal];
385
386 if (interactionVolume.isInnerVolume())
387 {
388 // cell index vector
389 std::vector<int> eIdxGlobal(0);
390
391 if (interactionVolume.getElementNumber() == 4)
392 {
393 auto element1 = interactionVolume.getSubVolumeElement(0);
394 auto element2 = interactionVolume.getSubVolumeElement(1);
395 auto element3 = interactionVolume.getSubVolumeElement(2);
396 auto element4 = interactionVolume.getSubVolumeElement(3);
397
398 eIdxGlobal.resize(4);
399
400 eIdxGlobal[0] = problem_.variables().index(element1);
401 eIdxGlobal[1] = problem_.variables().index(element2);
402 eIdxGlobal[2] = problem_.variables().index(element3);
403 eIdxGlobal[3] = problem_.variables().index(element4);
404
405 //cell Data vector
406 cellDataTemp.resize(4);
407
408 cellDataTemp[0] = problem_.variables().cellData(eIdxGlobal[0]);
409 cellDataTemp[1] = problem_.variables().cellData(eIdxGlobal[1]);
410 cellDataTemp[2] = problem_.variables().cellData(eIdxGlobal[2]);
411 cellDataTemp[3] = problem_.variables().cellData(eIdxGlobal[3]);
412
413 velocity_.calculateInnerInteractionVolumeVelocity(interactionVolume, cellDataTemp[0], cellDataTemp[1],
414 cellDataTemp[2], cellDataTemp[3], this->innerBoundaryVolumeFaces_);
415 }
416 else if (interactionVolume.getElementNumber() == 3)
417 {
418 auto element1 = interactionVolume.getSubVolumeElement(0);
419 auto element2 = interactionVolume.getSubVolumeElement(1);
420 auto element4 = interactionVolume.getSubVolumeElement(3);
421
422 eIdxGlobal.resize(3);
423
424 eIdxGlobal[0] = problem_.variables().index(element1);
425 eIdxGlobal[1] = problem_.variables().index(element2);
426 eIdxGlobal[2] = problem_.variables().index(element4);
427
428 //cell Data vector
429 cellDataTemp.resize(3);
430
431 cellDataTemp[0] = problem_.variables().cellData(eIdxGlobal[0]);
432 cellDataTemp[1] = problem_.variables().cellData(eIdxGlobal[1]);
433 cellDataTemp[2] = problem_.variables().cellData(eIdxGlobal[2]);
434
435
436 velocity_.calculateHangingNodeInteractionVolumeVelocity(interactionVolume, cellDataTemp[0], cellDataTemp[1],
437 cellDataTemp[2], this->innerBoundaryVolumeFaces_);
438 }
439 else
440 {
441 DUNE_THROW(Dune::NotImplemented, "Unknown interactionvolume type!");
442 }
443
444 int size = cellDataTemp.size();
445 for (int i = 0; i < size; i++)
446 {
447 if (eIdxGlobal[i] == eIdxGlobalI)
448 {
449 if (levelI >= levelJ)
450 {
451 cellData.fluxData().setVelocity(wPhaseIdx, indexInInside,
452 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInInside));
453 cellData.fluxData().setVelocity(nPhaseIdx, indexInInside,
454 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInInside));
455 cellData.fluxData().setUpwindPotential(wPhaseIdx, indexInInside,
456 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInInside));
457 cellData.fluxData().setUpwindPotential(nPhaseIdx, indexInInside,
458 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInInside));
459
460 if (levelI > levelJ)
461 {
462 cellDataJ.fluxData().setVelocity(wPhaseIdx, indexInOutside,
463 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInInside));
464 cellDataJ.fluxData().setVelocity(nPhaseIdx, indexInOutside,
465 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInInside));
466 cellDataJ.fluxData().setUpwindPotential(wPhaseIdx, indexInOutside,
467 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInInside));
468 cellDataJ.fluxData().setUpwindPotential(nPhaseIdx, indexInOutside,
469 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInInside));
470
471 }
472 }
473
474 }
475 else if (eIdxGlobal[i] == eIdxGlobalJ)
476 {
477 if (levelJ >= levelI)
478 {
479 cellDataJ.fluxData().setVelocity(wPhaseIdx, indexInOutside,
480 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInOutside));
481 cellDataJ.fluxData().setVelocity(nPhaseIdx, indexInOutside,
482 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInOutside));
483 cellDataJ.fluxData().setUpwindPotential(wPhaseIdx, indexInOutside,
484 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInOutside));
485 cellDataJ.fluxData().setUpwindPotential(nPhaseIdx, indexInOutside,
486 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInOutside));
487
488 if (levelJ > levelI)
489 {
490 cellData.fluxData().setVelocity(wPhaseIdx, indexInInside,
491 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInOutside));
492 cellData.fluxData().setVelocity(nPhaseIdx, indexInInside,
493 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInOutside));
494 cellData.fluxData().setUpwindPotential(wPhaseIdx, indexInInside,
495 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInOutside));
496 cellData.fluxData().setUpwindPotential(nPhaseIdx, indexInInside,
497 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInOutside));
498
499 }
500 }
501 }
502 }
503 }
504 }
505 if (levelI == levelJ)
506 {
507 cellData.fluxData().setVelocityMarker(indexInInside);
508 cellDataJ.fluxData().setVelocityMarker(indexInOutside);
509 }
510}
511
520template<class TypeTag>
521void FvMpfaL2dPressureVelocity2pAdaptive<TypeTag>::calculateVelocityOnBoundary(const Intersection& intersection, CellData& cellData)
522{
523 auto element = intersection.inside();
524
525 //get face index
526 int isIndex = intersection.indexInInside();
527
528 //get face normal
529 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
530
531 BoundaryTypes bcType;
532 //get boundary type
533 problem_.boundaryTypes(bcType, intersection);
534 PrimaryVariables boundValues(0.0);
535
536 if (bcType.isDirichlet(pressEqIdx))
537 {
538 problem_.dirichlet(boundValues, intersection);
539
540 // get global coordinates of cell centers
541 const GlobalPosition& globalPosI = element.geometry().center();
542
543 // center of face in global coordinates
544 const GlobalPosition& globalPosJ = intersection.geometry().center();
545
546 // get mobilities and fractional flow factors
547 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
548 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
549
550 // get capillary pressure
551 Scalar pcI = cellData.capillaryPressure();
552
553 // distance vector between barycenters
554 GlobalPosition distVec = globalPosJ - globalPosI;
555
556 // compute distance between cell centers
557 Scalar dist = distVec.two_norm();
558
559 //permeability vector at boundary
560 // compute vectorized permeabilities
561 DimMatrix meanPermeability(0);
562
563 problem_.spatialParams().meanK(meanPermeability, problem_.spatialParams().intrinsicPermeability(element));
564
565 Dune::FieldVector<Scalar, dim> permeability(0);
566 meanPermeability.mv(unitOuterNormal, permeability);
567
568 //determine saturation at the boundary -> if no saturation is known directly at the boundary use the cell saturation
569 Scalar satW = 0;
570 if (bcType.isDirichlet(satEqIdx))
571 {
572 switch (saturationType_)
573 {
574 case sw:
575 {
576 satW = boundValues[saturationIdx];
577 break;
578 }
579 case sn:
580 {
581 satW = 1 - boundValues[saturationIdx];
582 break;
583 }
584 }
585 }
586 else
587 {
588 satW = cellData.saturation(wPhaseIdx);
589 }
590
591 const Scalar pressBound = boundValues[pressureIdx];
592
593 const auto fluidMatrixInteraction = problem_.spatialParams().fluidMatrixInteractionAtPos(element.geometry().center());
594 const Scalar pcBound = fluidMatrixInteraction.pc(satW);
595
596 //determine phase pressures from primary pressure variable
597 Scalar pressWBound = 0;
598 Scalar pressNwBound = 0;
599 if (pressureType_ == pw)
600 {
601 pressWBound = pressBound;
602 pressNwBound = pressBound + pcBound;
603 }
604 else if (pressureType_ == pn)
605 {
606 pressWBound = pressBound - pcBound;
607 pressNwBound = pressBound;
608 }
609
610 const Scalar lambdaWBound = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx];
611 const Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx];
612
613 Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex);
614 Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex);
615
616 //calculate potential gradient
617 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressWBound);
618 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressNwBound);
619
620 potentialDiffW += density_[wPhaseIdx] * (distVec * problem_.gravity());
621 potentialDiffNw += density_[nPhaseIdx] * (distVec * problem_.gravity());
622
623 //store potential gradients for further calculations
624 cellData.fluxData().setUpwindPotential(wPhaseIdx, isIndex, potentialDiffW);
625 cellData.fluxData().setUpwindPotential(nPhaseIdx, isIndex, potentialDiffNw);
626
627 //do the upwinding of the mobility depending on the phase potentials
628 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWBound;
629 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
630 Scalar lambdaNw = (potentialDiffNw > 0.) ? lambdaNwI : lambdaNwBound;
631 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwBound) : lambdaNw;
632
633
634 Scalar scalarPerm = permeability.two_norm();
635
636 //calculate the gravity term
637 Dune::FieldVector<Scalar, dimWorld> velocityW(unitOuterNormal);
638 Dune::FieldVector<Scalar, dimWorld> velocityNw(unitOuterNormal);
639
640 //calculate unit distVec
641 distVec /= dist;
642 Scalar areaScaling = (unitOuterNormal * distVec);
643 //this treatment of g allows to account for gravity flux through faces where the face normal
644 //has no z component (e.g. parallelepiped grids)
645 Scalar gravityTermW = (problem_.gravity() * distVec) * density_[wPhaseIdx] * areaScaling;
646 Scalar gravityTermNw = (problem_.gravity() * distVec) * density_[nPhaseIdx] * areaScaling;
647
648 //calculate velocity depending on the pressure used -> use pc = pn - pw
649 switch (pressureType_)
650 {
651 case pw:
652 {
653 velocityW *= lambdaW * scalarPerm * ((cellData.pressure(wPhaseIdx) - pressBound) / dist + gravityTermW);
654 velocityNw *= lambdaNw * scalarPerm * ((cellData.pressure(wPhaseIdx) - pressBound) / dist + gravityTermNw)
655 + 0.5 * (lambdaNwI + lambdaNwBound) * scalarPerm * (pcI - pcBound) / dist;
656 break;
657 }
658 case pn:
659 {
660 velocityW *= lambdaW * scalarPerm * ((cellData.pressure(nPhaseIdx) - pressBound) / dist + gravityTermW)
661 - 0.5 * (lambdaWI + lambdaWBound) * scalarPerm * (pcI - pcBound) / dist;
662 velocityNw *= lambdaNw * scalarPerm * ((cellData.pressure(nPhaseIdx) - pressBound) / dist + gravityTermNw);
663 break;
664 }
665 }
666
667 //store velocities
668 cellData.fluxData().setVelocity(wPhaseIdx, isIndex, velocityW);
669 cellData.fluxData().setVelocity(nPhaseIdx, isIndex, velocityNw);
670 cellData.fluxData().setVelocityMarker(isIndex);
671
672 } //end dirichlet boundary
673
674 else if (bcType.isNeumann(pressEqIdx))
675 {
676 problem_.neumann(boundValues, intersection);
677
678 Dune::FieldVector<Scalar, dimWorld> velocityW(unitOuterNormal);
679 Dune::FieldVector<Scalar, dimWorld> velocityNw(unitOuterNormal);
680
681 velocityW *= boundValues[wPhaseIdx];
682 velocityNw *= boundValues[nPhaseIdx];
683
684 velocityW /= density_[wPhaseIdx];
685 velocityNw /= density_[nPhaseIdx];
686
687 //store potential gradients for further calculations
688 cellData.fluxData().setUpwindPotential(wPhaseIdx, isIndex, boundValues[wPhaseIdx]);
689 cellData.fluxData().setUpwindPotential(nPhaseIdx, isIndex, boundValues[nPhaseIdx]);
690
691 cellData.fluxData().setVelocity(wPhaseIdx, isIndex, velocityW);
692 cellData.fluxData().setVelocity(nPhaseIdx, isIndex, velocityNw);
693 cellData.fluxData().setVelocityMarker(isIndex);
694 } //end neumann boundary
695 else
696 {
697 DUNE_THROW(Dune::NotImplemented, "No valid boundary condition type defined for pressure equation!");
698 }
699}
700
701}
702// end of Dune namespace
703#endif
Velocity calculation on adaptive grids using a 2-d MPFA L-method.
Grid adaptive finite volume MPFA L-method discretization of a two-phase pressure equation of the sequ...
Definition: adapt.hh:29
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 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
Grid adaptive finite volume MPFA L-method discretization of a two-phase flow pressure equation of the...
Definition: 2dpressureadaptive.hh:75
FVMPFALInteractionVolume< TypeTag > InteractionVolume
Type of the interaction volume objects.
Definition: 2dpressureadaptive.hh:152
void addOutputVtkFields(MultiWriter &writer)
Adds pressure output to the output file.
Definition: 2dpressureadaptive.hh:374
void storePressureSolution()
Globally stores the pressure solution.
Definition: 2dpressureadaptive.hh:231
void initialize()
Initializes the pressure model.
Definition: 2dpressureadaptive.hh:200
void updateMaterialLaws()
constitutive functions are initialized and stored in the variables object
Definition: 2dpressureadaptive.hh:2546
void update()
Pressure update.
Definition: 2dpressureadaptive.hh:298
Class for the calculation of velocities from the pressure solution of an IMPES scheme using a grid ad...
Definition: 2dpressurevelocityadaptive.hh:48
void addOutputVtkFields(MultiWriter &writer)
Adds velocity output to the output file.
Definition: 2dpressurevelocityadaptive.hh:200
void updateVelocity()
Function for updating the velocity field if iterations are necessary in the transport solution.
Definition: 2dpressurevelocityadaptive.hh:130
bool calculateVelocityInTransport()
Indicates if velocity is reconstructed in the pressure step or in the transport step.
Definition: 2dpressurevelocityadaptive.hh:184
FvMpfaL2dPressureVelocity2pAdaptive(Problem &problem)
Constructs a FvMpfaL2dPressureVelocity2pAdaptive object.
Definition: 2dpressurevelocityadaptive.hh:111
void initialize()
Initializes pressure and velocity.
Definition: 2dpressurevelocityadaptive.hh:145
void calculateVelocityOnBoundary(const Intersection &intersection, CellData &cellData)
Calculates the velocity at a boundary.
Definition: 2dpressurevelocityadaptive.hh:521
void calculateVelocity()
Calculates the velocities at all cell-cell interfaces.
Definition: 2dpressurevelocityadaptive.hh:227
void update()
Pressure and velocity update.
Definition: 2dpressurevelocityadaptive.hh:172
Class for calculating 2-d velocities from cell-wise constant pressure values.
Definition: 2dvelocityadaptive.hh:54
Class including the information of an interaction volume of a MPFA L-method that does not change with...
Definition: linteractionvolume.hh:41
bool isInnerVolume()
Returns true if the interaction volume is completely inside the model domain.
Definition: linteractionvolume.hh:316
int getElementNumber()
Get number of stored elements.
Definition: linteractionvolume.hh:246
Element getSubVolumeElement(int subVolumeIdx)
Get an element of the interaction volume.
Definition: linteractionvolume.hh:281
int getFaceIndexFromSubVolume(int subVolumeIdx, int subVolumeFaceIdx)
Map from local interaction volume numbering on element to numbering on interaction volume.
Definition: linteractionvolume.hh:270
bool isOutsideFace(int subVolumeFaceIdx)
Returns true if an interaction volume flux face is outside the model domain.
Definition: linteractionvolume.hh:301
The finite volume base class for the solution of a pressure equation.
Definition: sequential/cellcentered/pressure.hh:49