diff --git a/test/porenetwork/2p/main.cc b/test/porenetwork/2p/main.cc index 4a017e43381ef293a04949aa0e70a2b7036a8969..db6a8d0e9e4c30e06227d1ba3c5cfe230ebbedd4 100644 --- a/test/porenetwork/2p/main.cc +++ b/test/porenetwork/2p/main.cc @@ -93,6 +93,7 @@ int main(int argc, char** argv) using SolutionVector = GetPropType; SolutionVector x(leafGridView.size(GridView::dimension)); problem->applyInitialSolution(x); + problem->calculateSumInletVolume(); auto xOld = x; // the grid variables diff --git a/test/porenetwork/2p/params.input b/test/porenetwork/2p/params.input index c406b2fac95e91c8fe030f64cc2daed2f3b03b49..4f994d96b7b64da4d597b9fc637e1b8a27d94987 100644 --- a/test/porenetwork/2p/params.input +++ b/test/porenetwork/2p/params.input @@ -13,6 +13,7 @@ VtpOutputFrequency = -1 # Write every n-th time step. 0 only writes a file if an EnableGravity = false CapillaryPressure = 5000 UseFixedPressureAndSaturationBoundary = false +DistributeByVolume = false [Vtk] AddVelocity = 1 diff --git a/test/porenetwork/2p/problem.hh b/test/porenetwork/2p/problem.hh index f977e8df3d0f6e6d9701d25cfdb5129c1c821010..097121f9e0c7b8bb681e9b53a1fc17aa0801970c 100644 --- a/test/porenetwork/2p/problem.hh +++ b/test/porenetwork/2p/problem.hh @@ -73,7 +73,9 @@ public: { vtpOutputFrequency_ = getParam("Problem.VtpOutputFrequency"); useFixedPressureAndSaturationBoundary_ = getParam("Problem.UseFixedPressureAndSaturationBoundary", false); + distributeByVolume_ = getParam("Problem.DistributeByVolume", true); pc_ = getParam("Problem.CapillaryPressure"); + nonWettingMassFlux_ = getParam("Problem.NonWettingMassFlux", 5e-8); } /*! @@ -158,13 +160,17 @@ public: { PrimaryVariables values(0.0); - // If we do not want to use global phase pressure difference with fixed saturations and pressures, - // we can instead only fix the non-wetting phase pressure and allow the wetting phase saturation to changle freely - // by applying a Nitsche-type boundary condition which tries to minimize the difference between the present pn and the given value + // We fix the mass flux of non-wetting injection at inlet of pore-network + // The total inlet mass flux is distributed according to the ratio + // of pore volume at inlet to the total volumess if (!useFixedPressureAndSaturationBoundary_ && isInletPore_(scv)) - values[snIdx] = (elemVolVars[scv].pressure(nPhaseIdx) - (1e5 + pc_)) * 1e8; - - return values; + { + if (distributeByVolume_) + values[snIdx] = nonWettingMassFlux_ * ( scv.volume()/sumInletPoresVolume_ ); + else + values[snIdx] = nonWettingMassFlux_ * std::pow((this->gridGeometry().poreInscribedRadius(scv.dofIndex())), 4.0)/sumInletPoresVolume_; + } + return values / scv.volume(); } // \} @@ -190,9 +196,29 @@ public: //! Evaluate the initial invasion state of a pore throat bool initialInvasionState(const Element& element) const { return false; } - // \} + //! Loop over the scv in the domain to calculate the sum volume of inner inlet pores + void calculateSumInletVolume() + { + sumInletPoresVolume_ = 0.0; + for (const auto& element : elements(this->gridGeometry().gridView())) + { + auto fvGeometry = localView(this->gridGeometry()); + fvGeometry.bind(element); + for (const auto& scv : scvs(fvGeometry)) + { + if (isInletPore_(scv)) + { + if (distributeByVolume_) + sumInletPoresVolume_ += this->gridGeometry().poreVolume(scv.dofIndex())/this->gridGeometry().coordinationNumber(scv.dofIndex()); + else + sumInletPoresVolume_ += std::pow(this->gridGeometry().poreInscribedRadius(scv.dofIndex()), 4.0); + } + } + } + } + private: bool isInletPore_(const SubControlVolume& scv) const @@ -212,7 +238,10 @@ private: int vtpOutputFrequency_; bool useFixedPressureAndSaturationBoundary_; + bool distributeByVolume_; Scalar pc_; + Scalar nonWettingMassFlux_; + Scalar sumInletPoresVolume_; }; } //end namespace Dumux