233 for (
const auto& vertex : vertices(problem_.gridView()))
235 int vIdxGlobal = problem_.variables().index(vertex);
239 if (interactionVolume.isInnerVolume())
241 if (interactionVolume.getElementNumber() == 4)
243 auto element1 = interactionVolume.getSubVolumeElement(0);
244 auto element2 = interactionVolume.getSubVolumeElement(1);
245 auto element3 = interactionVolume.getSubVolumeElement(2);
246 auto element4 = interactionVolume.getSubVolumeElement(3);
249 int eIdxGlobal1 = problem_.variables().index(element1);
250 int eIdxGlobal2 = problem_.variables().index(element2);
251 int eIdxGlobal3 = problem_.variables().index(element3);
252 int eIdxGlobal4 = problem_.variables().index(element4);
255 CellData& cellData1 = problem_.variables().cellData(eIdxGlobal1);
256 CellData& cellData2 = problem_.variables().cellData(eIdxGlobal2);
257 CellData& cellData3 = problem_.variables().cellData(eIdxGlobal3);
258 CellData& cellData4 = problem_.variables().cellData(eIdxGlobal4);
260 velocity_.calculateInnerInteractionVolumeVelocity(interactionVolume, cellData1, cellData2, cellData3,
264 else if (interactionVolume.getElementNumber() == 3)
266 auto element1 = interactionVolume.getSubVolumeElement(0);
267 auto element2 = interactionVolume.getSubVolumeElement(1);
268 auto element4 = interactionVolume.getSubVolumeElement(3);
271 int eIdxGlobal1 = problem_.variables().index(element1);
272 int eIdxGlobal2 = problem_.variables().index(element2);
273 int eIdxGlobal4 = problem_.variables().index(element4);
276 CellData& cellData1 = problem_.variables().cellData(eIdxGlobal1);
277 CellData& cellData2 = problem_.variables().cellData(eIdxGlobal2);
278 CellData& cellData4 = problem_.variables().cellData(eIdxGlobal4);
280 velocity_.calculateHangingNodeInteractionVolumeVelocity(interactionVolume, cellData1, cellData2,
286 DUNE_THROW(Dune::NotImplemented,
"Unknown interactionvolume type!");
293 for (
int elemIdx = 0; elemIdx < 2 * dim; elemIdx++)
295 bool isOutside =
false;
296 for (
int fIdx = 0; fIdx < dim; fIdx++)
298 int intVolFaceIdx = interactionVolume.getFaceIndexFromSubVolume(elemIdx, fIdx);
299 if (interactionVolume.isOutsideFace(intVolFaceIdx))
310 int eIdxGlobal = problem_.variables().index(interactionVolume.getSubVolumeElement(elemIdx));
312 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
314 velocity_.calculateBoundaryInteractionVolumeVelocity(interactionVolume, cellData, elemIdx);
334 int numVertices = intersection.geometry().corners();
336 auto elementI = intersection.inside();
337 auto elementJ = intersection.outside();
339 int levelI = elementI.level();
340 int levelJ = elementJ.level();
342 int eIdxGlobalI = problem_.variables().index(elementI);
343 int eIdxGlobalJ = problem_.variables().index(elementJ);
345 CellData& cellDataJ = problem_.variables().cellData(eIdxGlobalJ);
347 const auto referenceElement = ReferenceElements::general(elementI.type());
349 int indexInInside = intersection.indexInInside();
350 int indexInOutside = intersection.indexInOutside();
352 int fIdx = indexInInside;
355 fIdx = indexInOutside;
357 std::vector<CellData> cellDataTemp(0);
359 if (levelI != levelJ)
362 cellData.fluxData().setVelocity(wPhaseIdx, indexInInside, vel);
363 cellData.fluxData().setVelocity(nPhaseIdx, indexInInside, vel);
364 cellData.fluxData().setUpwindPotential(wPhaseIdx, indexInInside, 0);
365 cellData.fluxData().setUpwindPotential(nPhaseIdx, indexInInside, 0);
367 cellDataJ.fluxData().setVelocity(wPhaseIdx, indexInOutside, vel);
368 cellDataJ.fluxData().setVelocity(nPhaseIdx, indexInOutside, vel);
369 cellDataJ.fluxData().setUpwindPotential(wPhaseIdx, indexInOutside, 0);
370 cellDataJ.fluxData().setUpwindPotential(nPhaseIdx, indexInOutside, 0);
373 for (
int vIdx = 0; vIdx < numVertices; vIdx++)
375 int localVertIdx = referenceElement.subEntity(fIdx, dim - 1, vIdx, dim);
378 if (levelI >= levelJ)
380 vIdxGlobal = problem_.variables().index(elementI.template subEntity<dim>(localVertIdx));
384 vIdxGlobal = problem_.variables().index(elementJ.template subEntity<dim>(localVertIdx));
389 if (interactionVolume.isInnerVolume())
392 std::vector<int> eIdxGlobal(0);
394 if (interactionVolume.getElementNumber() == 4)
396 auto element1 = interactionVolume.getSubVolumeElement(0);
397 auto element2 = interactionVolume.getSubVolumeElement(1);
398 auto element3 = interactionVolume.getSubVolumeElement(2);
399 auto element4 = interactionVolume.getSubVolumeElement(3);
401 eIdxGlobal.resize(4);
403 eIdxGlobal[0] = problem_.variables().index(element1);
404 eIdxGlobal[1] = problem_.variables().index(element2);
405 eIdxGlobal[2] = problem_.variables().index(element3);
406 eIdxGlobal[3] = problem_.variables().index(element4);
409 cellDataTemp.resize(4);
411 cellDataTemp[0] = problem_.variables().cellData(eIdxGlobal[0]);
412 cellDataTemp[1] = problem_.variables().cellData(eIdxGlobal[1]);
413 cellDataTemp[2] = problem_.variables().cellData(eIdxGlobal[2]);
414 cellDataTemp[3] = problem_.variables().cellData(eIdxGlobal[3]);
416 velocity_.calculateInnerInteractionVolumeVelocity(interactionVolume, cellDataTemp[0], cellDataTemp[1],
419 else if (interactionVolume.getElementNumber() == 3)
421 auto element1 = interactionVolume.getSubVolumeElement(0);
422 auto element2 = interactionVolume.getSubVolumeElement(1);
423 auto element4 = interactionVolume.getSubVolumeElement(3);
425 eIdxGlobal.resize(3);
427 eIdxGlobal[0] = problem_.variables().index(element1);
428 eIdxGlobal[1] = problem_.variables().index(element2);
429 eIdxGlobal[2] = problem_.variables().index(element4);
432 cellDataTemp.resize(3);
434 cellDataTemp[0] = problem_.variables().cellData(eIdxGlobal[0]);
435 cellDataTemp[1] = problem_.variables().cellData(eIdxGlobal[1]);
436 cellDataTemp[2] = problem_.variables().cellData(eIdxGlobal[2]);
439 velocity_.calculateHangingNodeInteractionVolumeVelocity(interactionVolume, cellDataTemp[0], cellDataTemp[1],
444 DUNE_THROW(Dune::NotImplemented,
"Unknown interactionvolume type!");
447 int size = cellDataTemp.size();
448 for (
int i = 0; i < size; i++)
450 if (eIdxGlobal[i] == eIdxGlobalI)
452 if (levelI >= levelJ)
454 cellData.fluxData().setVelocity(wPhaseIdx, indexInInside,
455 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInInside));
456 cellData.fluxData().setVelocity(nPhaseIdx, indexInInside,
457 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInInside));
458 cellData.fluxData().setUpwindPotential(wPhaseIdx, indexInInside,
459 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInInside));
460 cellData.fluxData().setUpwindPotential(nPhaseIdx, indexInInside,
461 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInInside));
465 cellDataJ.fluxData().setVelocity(wPhaseIdx, indexInOutside,
466 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInInside));
467 cellDataJ.fluxData().setVelocity(nPhaseIdx, indexInOutside,
468 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInInside));
469 cellDataJ.fluxData().setUpwindPotential(wPhaseIdx, indexInOutside,
470 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInInside));
471 cellDataJ.fluxData().setUpwindPotential(nPhaseIdx, indexInOutside,
472 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInInside));
478 else if (eIdxGlobal[i] == eIdxGlobalJ)
480 if (levelJ >= levelI)
482 cellDataJ.fluxData().setVelocity(wPhaseIdx, indexInOutside,
483 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInOutside));
484 cellDataJ.fluxData().setVelocity(nPhaseIdx, indexInOutside,
485 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInOutside));
486 cellDataJ.fluxData().setUpwindPotential(wPhaseIdx, indexInOutside,
487 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInOutside));
488 cellDataJ.fluxData().setUpwindPotential(nPhaseIdx, indexInOutside,
489 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInOutside));
493 cellData.fluxData().setVelocity(wPhaseIdx, indexInInside,
494 cellDataTemp[i].fluxData().velocity(wPhaseIdx, indexInOutside));
495 cellData.fluxData().setVelocity(nPhaseIdx, indexInInside,
496 cellDataTemp[i].fluxData().velocity(nPhaseIdx, indexInOutside));
497 cellData.fluxData().setUpwindPotential(wPhaseIdx, indexInInside,
498 cellDataTemp[i].fluxData().upwindPotential(wPhaseIdx, indexInOutside));
499 cellData.fluxData().setUpwindPotential(nPhaseIdx, indexInInside,
500 cellDataTemp[i].fluxData().upwindPotential(nPhaseIdx, indexInOutside));
508 if (levelI == levelJ)
510 cellData.fluxData().setVelocityMarker(indexInInside);
511 cellDataJ.fluxData().setVelocityMarker(indexInOutside);
526 auto element = intersection.inside();
529 int isIndex = intersection.indexInInside();
532 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
534 BoundaryTypes bcType;
536 problem_.boundaryTypes(bcType, intersection);
537 PrimaryVariables boundValues(0.0);
539 if (bcType.isDirichlet(pressEqIdx))
541 problem_.dirichlet(boundValues, intersection);
544 const GlobalPosition& globalPosI = element.geometry().center();
547 const GlobalPosition& globalPosJ = intersection.geometry().center();
550 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
551 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
554 Scalar pcI = cellData.capillaryPressure();
557 GlobalPosition distVec = globalPosJ - globalPosI;
560 Scalar dist = distVec.two_norm();
564 DimMatrix meanPermeability(0);
566 problem_.spatialParams().meanK(meanPermeability, problem_.spatialParams().intrinsicPermeability(element));
568 Dune::FieldVector<Scalar, dim> permeability(0);
569 meanPermeability.mv(unitOuterNormal, permeability);
573 if (bcType.isDirichlet(satEqIdx))
575 switch (saturationType_)
579 satW = boundValues[saturationIdx];
584 satW = 1 - boundValues[saturationIdx];
591 satW = cellData.saturation(wPhaseIdx);
594 Scalar pressBound = boundValues[pressureIdx];
595 Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW);
598 Scalar pressWBound = 0;
599 Scalar pressNwBound = 0;
600 if (pressureType_ == pw)
602 pressWBound = pressBound;
603 pressNwBound = pressBound + pcBound;
605 else if (pressureType_ == pn)
607 pressWBound = pressBound - pcBound;
608 pressNwBound = pressBound;
611 Scalar lambdaWBound = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW)
612 / viscosity_[wPhaseIdx];
613 Scalar lambdaNwBound = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW)
614 / viscosity_[nPhaseIdx];
616 Scalar potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndex);
617 Scalar potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndex);
620 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressWBound);
621 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressNwBound);
623 potentialDiffW += density_[wPhaseIdx] * (distVec * problem_.gravity());
624 potentialDiffNw += density_[nPhaseIdx] * (distVec * problem_.gravity());
627 cellData.fluxData().setUpwindPotential(wPhaseIdx, isIndex, potentialDiffW);
628 cellData.fluxData().setUpwindPotential(nPhaseIdx, isIndex, potentialDiffNw);
631 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWBound;
632 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
633 Scalar lambdaNw = (potentialDiffNw > 0.) ? lambdaNwI : lambdaNwBound;
634 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwBound) : lambdaNw;
637 Scalar scalarPerm = permeability.two_norm();
640 Dune::FieldVector<Scalar, dimWorld> velocityW(unitOuterNormal);
641 Dune::FieldVector<Scalar, dimWorld> velocityNw(unitOuterNormal);
645 Scalar areaScaling = (unitOuterNormal * distVec);
648 Scalar gravityTermW = (problem_.gravity() * distVec) * density_[wPhaseIdx] * areaScaling;
649 Scalar gravityTermNw = (problem_.gravity() * distVec) * density_[nPhaseIdx] * areaScaling;
652 switch (pressureType_)
656 velocityW *= lambdaW * scalarPerm * ((cellData.pressure(wPhaseIdx) - pressBound) / dist + gravityTermW);
657 velocityNw *= lambdaNw * scalarPerm * ((cellData.pressure(wPhaseIdx) - pressBound) / dist + gravityTermNw)
658 + 0.5 * (lambdaNwI + lambdaNwBound) * scalarPerm * (pcI - pcBound) / dist;
663 velocityW *= lambdaW * scalarPerm * ((cellData.pressure(nPhaseIdx) - pressBound) / dist + gravityTermW)
664 - 0.5 * (lambdaWI + lambdaWBound) * scalarPerm * (pcI - pcBound) / dist;
665 velocityNw *= lambdaNw * scalarPerm * ((cellData.pressure(nPhaseIdx) - pressBound) / dist + gravityTermNw);
671 cellData.fluxData().setVelocity(wPhaseIdx, isIndex, velocityW);
672 cellData.fluxData().setVelocity(nPhaseIdx, isIndex, velocityNw);
673 cellData.fluxData().setVelocityMarker(isIndex);
677 else if (bcType.isNeumann(pressEqIdx))
679 problem_.neumann(boundValues, intersection);
681 Dune::FieldVector<Scalar, dimWorld> velocityW(unitOuterNormal);
682 Dune::FieldVector<Scalar, dimWorld> velocityNw(unitOuterNormal);
684 velocityW *= boundValues[wPhaseIdx];
685 velocityNw *= boundValues[nPhaseIdx];
687 velocityW /= density_[wPhaseIdx];
688 velocityNw /= density_[nPhaseIdx];
691 cellData.fluxData().setUpwindPotential(wPhaseIdx, isIndex, boundValues[wPhaseIdx]);
692 cellData.fluxData().setUpwindPotential(nPhaseIdx, isIndex, boundValues[nPhaseIdx]);
694 cellData.fluxData().setVelocity(wPhaseIdx, isIndex, velocityW);
695 cellData.fluxData().setVelocity(nPhaseIdx, isIndex, velocityNw);
696 cellData.fluxData().setVelocityMarker(isIndex);
700 DUNE_THROW(Dune::NotImplemented,
"No valid boundary condition type defined for pressure equation!");