25#ifndef DUMUX_FV2DPRESSURE2P2C_ADAPTIVE_HH
26#define DUMUX_FV2DPRESSURE2P2C_ADAPTIVE_HH
29#include <dune/istl/bvector.hh>
30#include <dune/istl/operators.hh>
31#include <dune/istl/solvers.hh>
32#include <dune/istl/preconditioners.hh>
87 using Indices =
typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
92 dim = GridView::dimension, dimWorld = GridView::dimensionworld
96 pw = Indices::pressureW,
97 pn = Indices::pressureN
101 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx,
102 wCompIdx = Indices::wPhaseIdx, nCompIdx = Indices::nPhaseIdx
110 using Intersection =
typename GridView::Intersection;
111 using IntersectionIterator =
typename GridView::IntersectionIterator;
114 using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
115 using TransmissivityMatrix = Dune::FieldVector<Scalar,dim+1>;
116 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
126 return this->problem_;
130 return this->problem_;
139 void getMpfaFlux(
const IntersectionIterator&,
const CellData&);
143 IntersectionIterator&,
144 TransmissivityMatrix&,
145 TransmissivityMatrix&,
152 int gridSize =
problem().gridView().size(0);
155 for(
int i=0; i< gridSize; i++)
170 enableMPFA = getParam<bool>(
"GridAdapt.EnableMultiPointFluxApproximation");
172 if(getParam<int>(
"GridAdapt.MaxInteractionVolumes") != 1)
190 Implementation &asImp_()
191 {
return *
static_cast<Implementation *
>(
this);}
194 const Implementation &asImp_()
const
195 {
return *
static_cast<const Implementation *
>(
this);}
200 const IntersectionIterator&,
201 IntersectionIterator&,
203 TransmissivityMatrix&);
222template<
class TypeTag>
225 int gridSize_ = problem().gridView().size(0);
227 this->A_.setSize (gridSize_,gridSize_);
228 this->f_.resize(gridSize_);
231 for (
const auto& element : elements(problem().gridView()))
234 int globalIdxI = problem().variables().index(element);
235 CellData& cellDataI = problem().variables().cellData(globalIdxI);
241 cellDataI.perimeter() = 0;
244 std::vector<int> foundAdditionals;
246 int numberOfIntersections = 0;
248 const auto isEndIt = problem().gridView().iend(element);
249 for (
auto isIt = problem().gridView().ibegin(element); isIt != isEndIt; ++isIt)
251 const auto& intersection = *isIt;
253 cellDataI.perimeter() += intersection.geometry().volume();
254 numberOfIntersections++;
255 if (intersection.neighbor())
260 if (enableMPFA && (enableSecondHalfEdge && intersection.outside().level() != element.level()))
262 GlobalPosition globalPos3(0.);
264 TransmissivityMatrix T(0.);
265 auto additionalIsIt = isIt;
266 TransmissivityMatrix additionalT(0.);
269 = problem().variables().getMpfaData(intersection, additionalIsIt, T, additionalT, globalPos3, globalIdx3);
270 if (halfedgesStored == 0)
271 halfedgesStored = problem().pressureModel().computeTransmissibilities(isIt,additionalIsIt, T,additionalT,
272 globalPos3, globalIdx3 );
274 if(halfedgesStored == 2)
276 bool increaseRowSize =
true;
278 for (
const auto& intersection2 :
intersections(problem_.gridView(), element))
280 if(!intersection2.neighbor())
282 if(additionalIsIt->outside() == intersection2.outside() )
283 increaseRowSize =
false;
286 for (
unsigned int i = 0; i < foundAdditionals.size(); i++)
287 if(foundAdditionals[i] == problem().variables().index(additionalIsIt->outside()))
288 increaseRowSize =
false;
293 foundAdditionals.push_back(problem().variables().index(additionalIsIt->outside()));
300 cellDataI.fluxData().resize(numberOfIntersections);
301 this->A_.setrowsize(globalIdxI, rowSize);
303 this->A_.endrowsizes();
306 for (
const auto& element : elements(problem().gridView()))
309 int globalIdxI = problem().variables().index(element);
312 this->A_.addindex(globalIdxI, globalIdxI);
315 const auto isEndIt = problem().gridView().iend(element);
316 for (
auto isIt = problem().gridView().ibegin(element); isIt != isEndIt; ++isIt)
318 const auto& intersection = *isIt;
320 if (intersection.neighbor())
323 int globalIdxJ = problem().variables().index(intersection.outside());
326 this->A_.addindex(globalIdxI, globalIdxJ);
329 if (enableMPFA && (enableSecondHalfEdge && intersection.outside().level() != element.level()))
331 GlobalPosition globalPos3(0.);
333 TransmissivityMatrix T(0.);
334 auto additionalIsIt = isIt;
335 TransmissivityMatrix additionalT(0.);
338 = problem().variables().getMpfaData(intersection, additionalIsIt, T, additionalT, globalPos3, globalIdx3);
339 if (halfedgesStored == 0)
340 halfedgesStored = problem().pressureModel().computeTransmissibilities(isIt,additionalIsIt, T,additionalT,
341 globalPos3, globalIdx3 );
343 if(halfedgesStored == 2)
344 this->A_.addindex(globalIdxI, problem().variables().index(additionalIsIt->outside()));
349 this->A_.endindices();
363template<
class TypeTag>
368 BaseType::assemble(
true);
377 for (
const auto& element : elements(problem().gridView()))
380 int globalIdxI = problem().variables().index(element);
383 if (element.partitionType() == Dune::InteriorEntity)
386 CellData& cellDataI = problem().variables().cellData(globalIdxI);
388 Dune::FieldVector<Scalar, 2> entries(0.);
391 problem().pressureModel().getSource(entries, element, cellDataI, first);
392 this->f_[globalIdxI] += entries[rhs];
396 auto isEndIt = problem().gridView().iend(element);
397 for (
auto isIt = problem().gridView().ibegin(element); isIt != isEndIt; ++isIt)
399 const auto& intersection = *isIt;
402 if (intersection.neighbor())
404 auto elementNeighbor = intersection.outside();
406 int globalIdxJ = problem().variables().index(elementNeighbor);
410 bool haveSameLevel = (element.level() == elementNeighbor.level());
415 && (globalIdxI > globalIdxJ) && haveSameLevel
416 && elementNeighbor.partitionType() == Dune::InteriorEntity)
421 if(!haveSameLevel && enableMPFA)
423 problem().pressureModel().getMpfaFlux(isIt, cellDataI);
427 problem().pressureModel().getFlux(entries, intersection, cellDataI, first);
430 this->f_[globalIdxI] -= entries[rhs];
433 this->A_[globalIdxI][globalIdxI] += entries[matrix];
436 this->A_[globalIdxI][globalIdxJ] -= entries[matrix];
440 && elementNeighbor.partitionType() == Dune::InteriorEntity)
442 this->f_[globalIdxJ] += entries[rhs];
443 this->A_[globalIdxJ][globalIdxJ] += entries[matrix];
444 this->A_[globalIdxJ][globalIdxI] -= entries[matrix];
454 problem().pressureModel().getFluxOnBoundary(entries, intersection, cellDataI, first);
457 this->f_[globalIdxI] += entries[rhs];
459 this->A_[globalIdxI][globalIdxI] += entries[matrix];
466 problem().pressureModel().getStorage(entries, element, cellDataI, first);
467 this->f_[globalIdxI] += entries[rhs];
469 this->A_[globalIdxI][globalIdxI] += entries[matrix];
474 this->A_[globalIdxI] = 0.0;
475 this->A_[globalIdxI][globalIdxI] = 1.0;
476 this->f_[globalIdxI] = this->
pressure()[globalIdxI];
506template<
class TypeTag>
508 const CellData& cellDataI)
511 auto elementI = intersectionIterator->inside();
512 int globalIdxI = problem().variables().index(elementI);
515 const GlobalPosition& globalPos = elementI.geometry().center();
518 Scalar volume = elementI.geometry().volume();
519 Scalar perimeter = cellDataI.perimeter();
521 const GlobalPosition& gravity_ = problem().gravity();
524 DimMatrix permeabilityI(problem().spatialParams().intrinsicPermeability(elementI));
527 auto neighbor = intersectionIterator->outside();
528 int globalIdxJ = problem().variables().index(neighbor);
529 CellData& cellDataJ = problem().variables().cellData(globalIdxJ);
532 const GlobalPosition& globalPosNeighbor = neighbor.geometry().center();
535 GlobalPosition distVec = globalPosNeighbor - globalPos;
538 Scalar dist = distVec.two_norm();
540 GlobalPosition unitDistVec(distVec);
543 DimMatrix permeabilityJ
544 = problem().spatialParams().intrinsicPermeability(neighbor);
547 DimMatrix meanPermeability(0);
554 Scalar rhoMeanW = 0.5 * (cellDataI.density(wPhaseIdx) + cellDataJ.density(wPhaseIdx));
555 Scalar rhoMeanNW = 0.5 * (cellDataI.density(nPhaseIdx) + cellDataJ.density(nPhaseIdx));
558 Scalar potentialW = 0;
559 Scalar potentialNW = 0;
562 if (!cellDataJ.hasVolumeDerivatives())
563 this->volumeDerivatives(globalPosNeighbor, neighbor);
565 Scalar dv_dC1 = (cellDataJ.dv(wPhaseIdx)
566 + cellDataI.dv(wPhaseIdx)) / 2;
567 Scalar dv_dC2 = (cellDataJ.dv(nPhaseIdx)
568 + cellDataI.dv(nPhaseIdx)) / 2;
570 Scalar graddv_dC1 = (cellDataJ.dv(wPhaseIdx)
571 - cellDataI.dv(wPhaseIdx)) / dist;
572 Scalar graddv_dC2 = (cellDataJ.dv(nPhaseIdx)
573 - cellDataI.dv(nPhaseIdx)) / dist;
585 Scalar densityW = rhoMeanW;
586 Scalar densityNW = rhoMeanNW;
590 GlobalPosition globalPos3(0.);
592 TransmissivityMatrix T(0.);
594 auto additionalIsIt = intersectionIterator;
595 TransmissivityMatrix additionalT(0.);
597 int halfedgesStored = problem().variables().getMpfaData(*intersectionIterator,
598 additionalIsIt, T, additionalT,
599 globalPos3, globalIdx3 );
600 if (halfedgesStored == 0)
601 halfedgesStored = problem().pressureModel().computeTransmissibilities(intersectionIterator,
602 additionalIsIt, T, additionalT,
603 globalPos3, globalIdx3 );
606 Dune::dgrave <<
"something went wrong getting mpfa data on cell " << globalIdxI << std::endl;
609 CellData& cellData3 = problem().variables().cellData(globalIdx3);
610 Scalar temp1 = globalPos * gravity_;
611 Scalar temp2 = globalPosNeighbor * gravity_;
612 Scalar temp3 = globalPos3 * gravity_;
614 potentialW = (cellDataI.pressure(wPhaseIdx)-temp1*densityW) * T[2]
615 + (cellDataJ.pressure(wPhaseIdx)-temp2*densityW) * T[0]
616 + (cellData3.pressure(wPhaseIdx)-temp3*densityW) * T[1];
617 potentialNW = (cellDataI.pressure(nPhaseIdx)-temp1*densityNW) * T[2]
618 + (cellDataJ.pressure(nPhaseIdx)-temp2*densityNW) * T[0]
619 + (cellData3.pressure(nPhaseIdx)-temp3*densityNW) * T[1];
621 if(halfedgesStored == 2)
623 int AdditionalIdx = problem().variables().index(additionalIsIt->outside());
624 CellData& cellDataAdditional = problem().variables().cellData(AdditionalIdx);
625 potentialW += (cellDataI.pressure(wPhaseIdx)-temp1*densityW) * additionalT[2]
626 + (cellDataJ.pressure(wPhaseIdx)-temp2*densityW) * additionalT[0]
627 + (cellDataAdditional.pressure(wPhaseIdx)
628 -(additionalIsIt->outside().geometry().center()*gravity_)
629 *densityW) * additionalT[1];
630 potentialNW += (cellDataI.pressure(nPhaseIdx)-temp1*densityNW) * additionalT[2]
631 + (cellDataJ.pressure(nPhaseIdx)-temp2*densityNW) * additionalT[0]
632 + (cellDataAdditional.pressure(nPhaseIdx)
633 -(additionalIsIt->outside().geometry().center()*gravity_)
634 *densityNW) * additionalT[1];
639 Scalar lambdaW(0.), lambdaN(0.);
640 Scalar dV_w(0.), dV_n(0.);
641 Scalar gV_w(0.), gV_n(0.);
645 if (potentialW >= 0.)
647 dV_w = (dv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx)
648 + dv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx));
649 lambdaW = cellDataI.mobility(wPhaseIdx);
650 gV_w = (graddv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx)
651 + graddv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx));
652 dV_w *= cellDataI.density(wPhaseIdx);
653 gV_w *= cellDataI.density(wPhaseIdx);
657 dV_w = (dv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx)
658 + dv_dC2 * cellDataJ.massFraction(wPhaseIdx, nCompIdx));
659 lambdaW = cellDataJ.mobility(wPhaseIdx);
660 gV_w = (graddv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx)
661 + graddv_dC2 * cellDataJ.massFraction(wPhaseIdx, nCompIdx));
662 dV_w *= cellDataJ.density(wPhaseIdx);
663 gV_w *= cellDataJ.density(wPhaseIdx);
665 if (potentialNW >= 0.)
667 dV_n = (dv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx)
668 + dv_dC2 * cellDataI.massFraction(nPhaseIdx, nCompIdx));
669 lambdaN = cellDataI.mobility(nPhaseIdx);
670 gV_n = (graddv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx)
671 + graddv_dC2 * cellDataI.massFraction(nPhaseIdx, nCompIdx));
672 dV_n *= cellDataI.density(nPhaseIdx);
673 gV_n *= cellDataI.density(nPhaseIdx);
677 dV_n = (dv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx)
678 + dv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx));
679 lambdaN = cellDataJ.mobility(nPhaseIdx);
680 gV_n = (graddv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx)
681 + graddv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx));
682 dV_n *= cellDataJ.density(nPhaseIdx);
683 gV_n *= cellDataJ.density(nPhaseIdx);
688 this->A_[globalIdxI][globalIdxJ] += (lambdaW * dV_w + lambdaN * dV_n) * T[0];
689 this->A_[globalIdxI][globalIdx3] += (lambdaW * dV_w + lambdaN * dV_n) * T[1];
690 this->A_[globalIdxI][globalIdxI] += (lambdaW * dV_w + lambdaN * dV_n) * T[2];
693 this->f_[globalIdxI] += (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n) * temp2 * T[0];
694 this->f_[globalIdxI] += (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n) * temp3 * T[1];
695 this->f_[globalIdxI] += (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n) * temp1 * T[2];
698 Scalar weightingFactor = volume / perimeter;
699 if(enableVolumeIntegral)
702 this->A_[globalIdxI][globalIdxJ] -= weightingFactor * (lambdaW * gV_w + lambdaN * gV_n)*T[0];
703 this->A_[globalIdxI][globalIdx3] -= weightingFactor * (lambdaW * gV_w + lambdaN * gV_n)*T[1];
704 this->A_[globalIdxI][globalIdxI] -= weightingFactor * (lambdaW * gV_w + lambdaN * gV_n)*T[2];
707 this->f_[globalIdxI] -= weightingFactor * (densityW * lambdaW * gV_w + densityNW * lambdaN * gV_n) * temp2 * T[0];
708 this->f_[globalIdxI] -= weightingFactor * (densityW * lambdaW * gV_w + densityNW * lambdaN * gV_n) * temp3 * T[1];
709 this->f_[globalIdxI] -= weightingFactor * (densityW * lambdaW * gV_w + densityNW * lambdaN * gV_n) * temp1 * T[2];
713 Scalar pcGradient = cellDataI.capillaryPressure() * T[2]
714 + cellDataJ.capillaryPressure() * T[0]
715 + cellData3.capillaryPressure() * T[1];
717 if (this->pressureType == pw)
718 pcGradient *= + lambdaN * dV_n - enableVolumeIntegral * weightingFactor * lambdaN * gV_n;
719 else if (this->pressureType == pn)
720 pcGradient *= - lambdaW * dV_w + enableVolumeIntegral * weightingFactor * lambdaW * gV_w;
722 this->f_[globalIdxI] += pcGradient;
725 if(halfedgesStored == 2)
727 int AdditionalIdx = problem().variables().index(additionalIsIt->outside());
728 CellData& cellDataAdditional = problem().variables().cellData(AdditionalIdx);
731 this->A_[globalIdxI][globalIdxJ] += (lambdaW * dV_w + lambdaN * dV_n) * additionalT[0];
732 this->A_[globalIdxI][AdditionalIdx] += (lambdaW * dV_w + lambdaN * dV_n) * additionalT[1];
733 this->A_[globalIdxI][globalIdxI] += (lambdaW * dV_w + lambdaN * dV_n) * additionalT[2];
736 this->f_[globalIdxI] += (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n) * temp2 * additionalT[0];
737 this->f_[globalIdxI] += (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n)
738 * (additionalIsIt->outside().geometry().center()*gravity_) * additionalT[1];
739 this->f_[globalIdxI] += (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n) * temp1 * additionalT[2];
741 if(enableVolumeIntegral)
744 this->A_[globalIdxI][globalIdxJ] -= weightingFactor * (lambdaW * gV_w + lambdaN * gV_n)*additionalT[0];
745 this->A_[globalIdxI][AdditionalIdx] -= weightingFactor * (lambdaW * gV_w + lambdaN * gV_n)*additionalT[1];
746 this->A_[globalIdxI][globalIdxI] -= weightingFactor * (lambdaW * gV_w + lambdaN * gV_n)*additionalT[2];
749 this->f_[globalIdxI] -= weightingFactor * (densityW * lambdaW * gV_w + densityNW * lambdaN * gV_n) * temp2 * additionalT[0];
750 this->f_[globalIdxI] -= weightingFactor * (densityW * lambdaW * gV_w + densityNW * lambdaN * gV_n)
751 * (additionalIsIt->outside().geometry().center()*gravity_) * additionalT[1];
752 this->f_[globalIdxI] -= weightingFactor * (densityW * lambdaW * gV_w + densityNW * lambdaN * gV_n) * temp1 * additionalT[2];
756 pcGradient = cellDataI.capillaryPressure() * additionalT[2]
757 + cellDataJ.capillaryPressure() * additionalT[0]
758 + cellDataAdditional.capillaryPressure() * additionalT[1];
759 if (this->pressureType == pw)
760 pcGradient *= + lambdaN * dV_n - enableVolumeIntegral * weightingFactor * lambdaN * gV_n;
761 else if (this->pressureType == pn)
762 pcGradient *= - lambdaW * dV_w + enableVolumeIntegral * weightingFactor * lambdaW * gV_w;
764 this->f_[globalIdxI] += pcGradient;
804template <
class TypeTag>
806 IntersectionIterator& additionalIntersectionIt,
807 TransmissivityMatrix& T,
808 TransmissivityMatrix& additionalT,
809 GlobalPosition& globalPos3,
812 const auto& intersection = *isIt;
815 auto element = intersection.inside();
816 auto neighbor = intersection.outside();
817 GlobalPosition globalPos1 = element.geometry().center();
818 GlobalPosition globalPos2 = neighbor.geometry().center();
819 DimMatrix K1(problem().spatialParams().intrinsicPermeability(element));
820 DimMatrix K2(problem().spatialParams().intrinsicPermeability(neighbor));
824 GlobalPosition globalPosFace12 = intersection.geometry().center();
825 GlobalPosition integrationOuterNormaln12 = intersection.centerUnitOuterNormal();
826 integrationOuterNormaln12 *= intersection.geometry().volume() / 2.0;
832 if (nextIs == problem().gridView().iend(element))
833 nextIs = problem().gridView().ibegin(element);
837 auto prevIs = problem().gridView().ibegin(element);
838 auto paceingIt = prevIs;
839 for (++paceingIt; paceingIt != problem().gridView().iend(element); ++paceingIt)
841 if (!paceingIt->neighbor())
843 else if (paceingIt->outside() == intersection.outside())
845 else if (paceingIt == problem().gridView().iend(element))
856 auto isEndIt = problem().gridView().iend(neighbor);
857 for (
auto isIt23 = problem().gridView().ibegin(neighbor); isIt23 != isEndIt; ++isIt23)
859 const auto& intersection23 = *isIt23;
862 if(face13->outside() != intersection.outside())
865 if(!intersection23.neighbor())
870 if (prevIs->neighbor())
872 if (prevIs->outside() == intersection23.outside())
876 additionalIntersectionIt = nextIs;
880 if (nextIs->neighbor())
882 if (nextIs->outside() == intersection23.outside())
886 additionalIntersectionIt = prevIs;
890 if(face13->outside() == intersection.outside())
891 Dune::dgrave <<
"is 13 not found!!!" << std::endl;
894 globalPos3 = face13->outside().geometry().center();
895 globalIdx3 = problem().variables().index(face13->outside());
897 DimMatrix K3(problem().spatialParams().intrinsicPermeability(face13->outside()));
902 GlobalPosition corner123(0.);
905 for (
int i = 0; i < intersection.geometry().corners(); ++i)
907 for (
int j = 0; j < face13->geometry().corners(); ++j)
909 if (face13->geometry().corner(j) == intersection.geometry().corner(i))
911 corner123 = face13->geometry().corner(j);
914 i = intersection.geometry().corners();
922 GlobalPosition globalPosFace23 = face23->geometry().center();
925 Scalar face23vol = face23->geometry().volume();
928 Dune::FieldVector<Scalar,dimWorld> integrationOuterNormaln23 = face23->centerUnitOuterNormal();
929 integrationOuterNormaln23 *= face23vol / 2.0;
932 GlobalPosition nu1(0);
933 R_.umv(globalPosFace12-globalPos2 ,nu1);
935 GlobalPosition nu2(0);
936 R_.umv(globalPos2-globalPosFace23, nu2);
938 GlobalPosition nu3(0);
939 R_.umv(globalPosFace23-globalPos3, nu3);
941 GlobalPosition nu4(0);
942 R_.umv(globalPos3-corner123, nu4);
944 GlobalPosition nu5(0);
945 R_.umv(corner123-globalPos1, nu5);
947 GlobalPosition nu6(0);
948 R_.umv(globalPos1-globalPosFace12, nu6);
950 GlobalPosition nu7(0);
951 R_.umv(corner123-globalPos2, nu7);
954 GlobalPosition Rnu2(0);
956 Scalar T1 = nu1 * Rnu2;
958 GlobalPosition Rnu4(0);
960 Scalar T2 = nu3 * Rnu4;
962 GlobalPosition Rnu6(0);
964 Scalar T3 = nu5 * Rnu6;
967 GlobalPosition K2nu1(0);
969 GlobalPosition K2nu2(0);
971 GlobalPosition K3nu3(0);
973 GlobalPosition K3nu4(0);
975 GlobalPosition K1nu5(0);
977 GlobalPosition K1nu6(0);
979 GlobalPosition Rnu1(0);
982 double omega111 = (integrationOuterNormaln23 * K2nu1)/T1;
983 double omega112 = (integrationOuterNormaln23 * K2nu2)/T1;
984 double omega211 = (integrationOuterNormaln12 * K2nu1)/T1;
985 double omega212 = (integrationOuterNormaln12 * K2nu2)/T1;
986 double omega123 = (integrationOuterNormaln23 * K3nu3)/T2;
987 double omega124 = (integrationOuterNormaln23 * K3nu4)/T2;
988 double omega235 = (integrationOuterNormaln12 * K1nu5)/T3;
989 double omega236 = (integrationOuterNormaln12 * K1nu6)/T3;
990 double chi711 = (nu7 * Rnu1)/T1;
991 double chi712 = (nu7 * Rnu2)/T1;
995 DimMatrix C(0), A(0);
996 Dune::FieldMatrix<Scalar,dim,2*dim-dim+1> D(0), B(0);
1000 C[0][1] = -omega112;
1001 C[1][0] = -omega211;
1002 C[1][1] = -omega212;
1004 D[0][0] = omega111 + omega112;
1005 D[1][0] = omega211 + omega212;
1007 A[0][0] = omega111 - omega124 - omega123*chi711;
1008 A[0][1] = omega112 - omega123*chi712;
1009 A[1][0] = omega211 - omega236*chi711;
1010 A[1][1] = omega212 - omega235 - omega236*chi712;
1012 B[0][0] = omega111 + omega112 + omega123*(1.0 - chi711 - chi712);
1013 B[0][1] = -omega123 - omega124;
1014 B[1][0] = omega211 + omega212 + omega236*(1.0 - chi711 - chi712);
1015 B[1][2] = -omega235 - omega236;
1019 D += B.leftmultiply(C.rightmultiply(A));
1021 if(!enableSecondHalfEdge )
1025 problem().variables().storeMpfaData(intersection, T, globalPos3, globalIdx3);
1034 GlobalPosition corner1245(0.);
1037 auto tempIntersection = face13;
1038 bool corner1245found =
false;
1040 if (tempIntersection == problem().gridView().iend(element))
1041 tempIntersection = problem().gridView().ibegin(element);
1042 while (!corner1245found)
1047 if (tempIntersection == problem().gridView().iend(element))
1048 tempIntersection = problem().gridView().ibegin(element);
1050 if (tempIntersection == isIt)
1054 for (
int i = 0; i < intersection.geometry().corners(); ++i)
1057 for (
int j = 0; j < tempIntersection->geometry().corners(); ++j)
1059 if (tempIntersection->geometry().corner(j) == intersection.geometry().corner(i))
1061 corner1245 = tempIntersection->geometry().corner(j);
1062 additionalIntersectionIt = tempIntersection;
1065 i = intersection.geometry().corners();
1067 corner1245found =
true;
1073 if (!additionalIntersectionIt->neighbor())
1077 problem().variables().storeMpfaData(intersection, T, globalPos3, globalIdx3);
1082 this->transmissibilityAdapter_(isIt, face23, additionalIntersectionIt,
1083 corner1245, additionalT);
1086 problem().variables().storeMpfaData(intersection, additionalIntersectionIt, T,additionalT, globalPos3, globalIdx3);
1119template<
class TypeTag>
1121 const IntersectionIterator& face23_2p2cnaming,
1122 IntersectionIterator& additionalIntersectionIt,
1123 GlobalPosition& corner1234,
1124 TransmissivityMatrix& additionalT)
1126 const auto& intersection = *isIt;
1130 auto isIt23 = additionalIntersectionIt;
1137 bool face14found =
false;
1139 auto tempIntersection = face23_2p2cnaming;
1141 while (!face14found)
1146 if (tempIntersection== problem().gridView().iend(intersection.outside()))
1147 tempIntersection = problem().gridView().ibegin(intersection.outside());
1149 if(!tempIntersection->neighbor())
1153 if (tempIntersection->outside() == intersection.inside())
1157 for (
int i = 0; i < intersection.geometry().corners(); ++i)
1160 for (
int j = 0; j < tempIntersection->geometry().corners(); ++j)
1162 if (tempIntersection->geometry().corner(j) == intersection.geometry().corner(i))
1171 isIt14 = tempIntersection;
1173 i = intersection.geometry().corners();
1194 const GlobalPosition& globalPosFace12 = intersection.geometry().center();
1197 Scalar faceVol12 = intersection.geometry().volume() / 2.0;
1200 Dune::FieldVector<Scalar, dimWorld> unitOuterNormal12 = intersection.centerUnitOuterNormal();
1201 unitOuterNormal12 *=-1;
1204 const GlobalPosition& globalPosFace41 = isIt14->geometry().center();
1207 Scalar faceVol41 = isIt14->geometry().volume() / 2.0;
1210 Dune::FieldVector<Scalar, dimWorld> unitOuterNormal14 = isIt14->centerUnitOuterNormal();
1212 interactionVolume.
setNormal(unitOuterNormal12, 0, 0);
1213 interactionVolume.
setNormal(unitOuterNormal14, 0, 1);
1215 unitOuterNormal14 *= -1;
1216 unitOuterNormal12 *= -1;
1223 auto element2 = intersection.inside();
1228 interactionVolume.
setNormal(unitOuterNormal12, 1, 1);
1234 auto element4 = isIt14->outside();
1240 interactionVolume.
setNormal(unitOuterNormal14, 3, 0);
1245 const auto& intersection23 = *isIt23;
1246 auto element3 = intersection23.outside();
1250 GlobalPosition globalPosFace23 = intersection23.geometry().center();
1251 Scalar faceVol23 = intersection23.geometry().volume() / 2.0;
1253 GlobalPosition unitOuterNormal23 = intersection23.centerUnitOuterNormal();
1255 interactionVolume.
setNormal(unitOuterNormal23, 1, 0);
1256 unitOuterNormal23 *= -1;
1257 interactionVolume.
setNormal(unitOuterNormal23, 2, 1);
1266 Dune::FieldVector<Scalar, dim> unity(1.);
1267 std::vector<Dune::FieldVector<Scalar, dim> > lambda(4, unity);
1269 Dune::FieldMatrix<Scalar,dim,2*dim-dim+1> T;
1270 int triangleType = transmissibilityCalculator_.calculateTransmissibility(
1271 T, interactionVolume, lambda,
1275 if (triangleType == TransmissibilityCalculator::rightTriangle)
1277 additionalIntersectionIt = isIt23;
1281 additionalT[0] = -T[1][2];
1282 additionalT[1] = -T[1][1];
1283 additionalT[2] = -T[1][0];
1285 else if (triangleType == TransmissibilityCalculator::leftTriangle)
1287 additionalIntersectionIt = isIt14;
1291 additionalT[0] = -T[1][0];
1292 additionalT[1] = -T[1][1];
1293 additionalT[2] = -T[1][2];
1297 DUNE_THROW(Dune::MathError,
"No transmissivity for second half edge found!");
1299 return triangleType;
#define GET_PROP_VALUE(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:282
#define GET_PROP_TYPE(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:283
Define some often used mathematical functions.
Simplifies writing multi-file VTK datasets.
Provides methods for transmissibility calculation 2-d.
Defines the properties required for the adaptive sequential 2p2c models.
Finite volume 2p2c pressure model.
void harmonicMeanMatrix(Dune::FieldMatrix< Scalar, m, n > &K, const Dune::FieldMatrix< Scalar, m, n > &Ki, const Dune::FieldMatrix< Scalar, m, n > &Kj)
Calculate the harmonic mean of a fixed-size matrix.
Definition: math.hh:108
Dune::IteratorRange< typename MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper >::Intersections::const_iterator > intersections(const MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper > &glue)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: glue.hh:62
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Property tag VisitFacesOnlyOnce
Type of solution vector or pressure system.
Definition: sequential/pressureproperties.hh:62
Property tag NumPhases
Number of phases in the system.
Definition: porousmediumflow/sequential/properties.hh:69
Property tag PressureCoefficientMatrix
Gives maximum number of intersections of an element and neighboring elements.
Definition: porousmediumflow/sequential/properties.hh:74
Property tag PressureModel
The type of the discretization of a pressure model.
Definition: porousmediumflow/sequential/properties.hh:65
std::string permeability() noexcept
I/O name of permeability.
Definition: name.hh:143
std::string pressure(int phaseIdx) noexcept
I/O name of pressure for multiphase systems.
Definition: name.hh:34
Provides methods for transmissibility calculation in 2-d.
Definition: 2dtransmissibilitycalculator.hh:44
The finite volume model for the solution of the compositional pressure equation.
Definition: fv2dpressureadaptive.hh:78
const Problem & problem() const
Definition: fv2dpressureadaptive.hh:128
bool enableSecondHalfEdge
Definition: fv2dpressureadaptive.hh:209
int computeTransmissibilities(const IntersectionIterator &, IntersectionIterator &, TransmissivityMatrix &, TransmissivityMatrix &, GlobalPosition &, int &)
Computes the transmissibility coefficients for the MPFA-l method.
Definition: fv2dpressureadaptive.hh:805
bool enableMPFA
Enables mpfa method to calculate the fluxes near hanging nodes.
Definition: fv2dpressureadaptive.hh:208
Problem & problem()
Definition: fv2dpressureadaptive.hh:124
int transmissibilityAdapter_(const IntersectionIterator &, const IntersectionIterator &, IntersectionIterator &, GlobalPosition &, TransmissivityMatrix &)
An adapter to use the traditional 2p implementation for the second interaction region.
Definition: fv2dpressureadaptive.hh:1120
void initializeMatrix()
initializes the matrix to store the system of equations
Definition: fv2dpressureadaptive.hh:223
void adaptPressure()
Adapt primary variables vector after adapting the grid.
Definition: fv2dpressureadaptive.hh:150
FV2dPressure2P2CAdaptive(Problem &problem)
Constructs a FV2dPressure2P2CAdaptive object.
Definition: fv2dpressureadaptive.hh:166
void assemble(bool first)
function which assembles the system of equations to be solved
Definition: fv2dpressureadaptive.hh:364
DimMatrix R_
Matrix for vector rotation used in mpfa.
Definition: fv2dpressureadaptive.hh:206
TransmissibilityCalculator transmissibilityCalculator_
The 2p Mpfa pressure module, that is only used for the calulation of transmissibility of the second i...
Definition: fv2dpressureadaptive.hh:211
bool enableVolumeIntegral
Enables the volume integral of the pressure equation.
Definition: fv2dpressureadaptive.hh:207
void getMpfaFlux(const IntersectionIterator &, const CellData &)
Compute flux over an irregular interface using a mpfa method.
Definition: fv2dpressureadaptive.hh:507
The finite volume model for the solution of the compositional pressure equation.
Definition: fvpressure.hh:73
static constexpr int pressureType
gives kind of pressure used ( , , )
Definition: fvpressure.hh:190
Class including the information of an interaction volume of a MPFA L-method that does not change with...
Definition: linteractionvolume.hh:41
void setSubVolumeElement(const Element &element, int subVolumeIdx)
Store an element of the interaction volume.
Definition: linteractionvolume.hh:137
void setFacePosition(const DimVector &pos, int subVolumeIdx, int subVolumeFaceIdxInInside)
Store position of the center of a flux face.
Definition: linteractionvolume.hh:149
void setIndexOnElement(int indexInInside, int subVolumeIdx, int subVolumeFaceIdxInInside)
Store map from local interaction volume numbering to numbering of the Dune reference element.
Definition: linteractionvolume.hh:234
void setNormal(DimVector &normal, int subVolumeIdx, int subVolumeFaceIdxInInside)
Store a flux face normal.
Definition: linteractionvolume.hh:171
void setCenterPosition(DimVector ¢erVertexPos)
Store position of the center vertex of the interaction volume.
Definition: linteractionvolume.hh:127
void setFaceArea(Scalar &faceArea, int subVolumeIdx, int subVolumeFaceIdxInInside)
Store a flux face area.
Definition: linteractionvolume.hh:160
The finite volume base class for the solution of a pressure equation.
Definition: sequential/cellcentered/pressure.hh:48
PressureSolution & pressure()
Returns the vector containing the pressure solution.
Definition: sequential/cellcentered/pressure.hh:119
@ rhs
index for the right hand side entry
Definition: sequential/cellcentered/pressure.hh:87
@ matrix
index for the global matrix entry
Definition: sequential/cellcentered/pressure.hh:88