diff --git a/test/boxmodels/MpNc/obstacleproblem.hh b/test/boxmodels/MpNc/obstacleproblem.hh index 6c71a31c1cb92451b99959af28b0e02737762b4e..6811b2c1ff2a7925c838cdacb663bb231930f107 100644 --- a/test/boxmodels/MpNc/obstacleproblem.hh +++ b/test/boxmodels/MpNc/obstacleproblem.hh @@ -29,31 +29,17 @@ #ifndef DUMUX_OBSTACLEPROBLEM_HH #define DUMUX_OBSTACLEPROBLEM_HH -#define USE_2P2C 0 -#define OBSTACLE_FIND_CONVERGENCE_RADIUS 0 - #include <dune/common/parametertreeparser.hh> #include <dune/grid/io/file/dgfparser/dgfug.hh> #include <dune/grid/io/file/dgfparser/dgfs.hh> #include <dune/grid/io/file/dgfparser/dgfyasp.hh> -#if USE_2P2C -#include <dumux/boxmodels/2p2c/2p2cmodel.hh> -#else #include <dumux/boxmodels/MpNc/MpNcmodel.hh> -#endif - -/* -#include <dumux/material/fluidsystems/simple_h2o_n2_system.hh> -#include <dumux/material/fluidsystems/simple_h2o_n2_tce_system.hh> -#include <dumux/material/fluidsystems/h2o_n2_system.hh> -#include <dumux/material/fluidsystems/h2o_n2_o2_system.hh> -#include <dumux/material/fluidsystems/h2o_h2_o2_system.hh> -#include <dumux/material/fluidsystems/h2o_h2_n2_o2_system.hh> -*/ #include <dumux/material/MpNcfluidsystems/h2on2fluidsystem.hh> +#include <dumux/material/MpNcconstraintsolvers/computefromreferencephase.hh> +#include <dumux/material/MpNcfluidstates/equilibriumfluidstate.hh> #include "obstaclespatialparameters.hh" @@ -65,11 +51,7 @@ class ObstacleProblem; namespace Properties { -#if USE_2P2C -NEW_TYPE_TAG(ObstacleProblem, INHERITS_FROM(BoxTwoPTwoC, ObstacleSpatialParameters)); -#else NEW_TYPE_TAG(ObstacleProblem, INHERITS_FROM(BoxMPNC, ObstacleSpatialParameters)); -#endif // Set the grid type SET_TYPE_PROP(ObstacleProblem, Grid, Dune::YaspGrid<2>); @@ -90,7 +72,6 @@ public: // Dumux::Simple_H2O_N2_TCE_System<TypeTag> ); //Dumux::H2O_N2_System<TypeTag> ); -#if ! USE_2P2C // Enable smooth upwinding? SET_BOOL_PROP(ObstacleProblem, EnableSmoothUpwinding, false); @@ -99,7 +80,6 @@ SET_BOOL_PROP(ObstacleProblem, EnableDiffusion, false); // Use the chopped Newton method? SET_BOOL_PROP(ObstacleProblem, NewtonEnableChop, true); -#endif // Enable gravity SET_BOOL_PROP(ObstacleProblem, EnableGravity, true); @@ -144,18 +124,10 @@ SET_INT_PROP(ObstacleProblem, NumericDifferenceMethod, +1); */ template <class TypeTag> class ObstacleProblem -#if USE_2P2C - : public TwoPTwoCProblem<TypeTag> -#else : public MPNCProblem<TypeTag> -#endif { - typedef ObstacleProblem<TypeTag> ThisType; -#if USE_2P2C - typedef TwoPTwoCProblem<TypeTag> ParentType; -#else + typedef ObstacleProblem<TypeTag> ThisType; typedef MPNCProblem<TypeTag> ParentType; -#endif typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView; typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar; @@ -163,6 +135,8 @@ class ObstacleProblem typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables; typedef typename GET_PROP_TYPE(TypeTag, PTAG(BoundaryTypes)) BoundaryTypes; typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem; + typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLaw)) MaterialLaw; + typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLawParams)) MaterialLawParams; enum { // Grid and world dimension @@ -173,8 +147,10 @@ class ObstacleProblem numComponents = GET_PROP_VALUE(TypeTag, PTAG(NumComponents)), gPhaseIdx = FluidSystem::gPhaseIdx, - //oPhaseIdx = FluidSystem::oPhaseIdx, lPhaseIdx = FluidSystem::lPhaseIdx, + + H2OIdx = FluidSystem::H2OIdx, + N2Idx = FluidSystem::N2Idx, }; typedef typename GridView::template Codim<0>::Entity Element; @@ -184,12 +160,10 @@ class ObstacleProblem typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry; typedef Dune::FieldVector<typename GridView::Grid::ctype, dimWorld> GlobalPosition; - typedef typename GET_PROP_TYPE(TypeTag, PTAG(TimeManager)) TimeManager; + typedef Dune::FieldVector<Scalar, numPhases> PhaseVector; -#if USE_2P2C - typedef typename GET_PROP_TYPE(TypeTag, PTAG(TwoPTwoCIndices)) Indices; + typedef typename GET_PROP_TYPE(TypeTag, PTAG(TimeManager)) TimeManager; -#else // ! USE_2P2C // copy some indices for convenience typedef typename GET_PROP_TYPE(TypeTag, PTAG(MPNCIndices)) Indices; enum { @@ -197,7 +171,7 @@ class ObstacleProblem S0Idx = Indices::S0Idx, p0Idx = Indices::p0Idx, }; -#endif // USE_2P2C + public: ObstacleProblem(TimeManager &timeManager, const GridView &gridView) : ParentType(timeManager, gridView) @@ -208,86 +182,12 @@ public: Scalar Tmin = temperature_ - 1.0; Scalar Tmax = temperature_ + 1.0; int nT = 10; + Scalar pmin = 0.75 * 1e5; Scalar pmax = 1.25 * 2e5; int np = 1000; - FluidSystem::init(Tmin, Tmax, nT, pmin, pmax, np); - } - - /*! - * \brief Called by Dumux::TimeManager in order to do a time - * integration on the model. - */ - void timeIntegration() - { -#if !OBSTACLE_FIND_CONVERGENCE_RADIUS - if (GET_PROP_VALUE(TypeTag, PTAG(NewtonWriteConvergence))) - this->newtonController().setMaxSteps(40); - ParentType::timeIntegration(); -#else - std::cout << "Finding convergence radius\n"; - this->newtonController().setVerbose(false); - this->newtonController().setMaxSteps(40); - this->newtonController().setTargetSteps(20); - Scalar successDt = 0.0; - const int maxFails = 10; - for (int i = 0; true; ++i) { - std::cout << "Try dt of " << this->timeManager().timeStepSize() << "\n"; - std::cout.flush(); - - if (i == maxFails && this->gridView().comm().rank() == 0) - DUNE_THROW(Dune::MathError, - "Newton solver didn't converge after " - << maxFails - << " timestep divisions. dt=" - << this->timeManager().timeStepSize()); - - if (this->model().update(this->newtonMethod(), - this->newtonController())) - { - // sucessfull update. remember time step size - successDt = this->timeManager().timeStepSize(); - this->model().updateFailed(); - break; - } - - if (i > 0 && this->gridView().comm().rank() == 0) - std::cout << "Newton solver did not converge. Retrying with time step of " - << this->timeManager().timeStepSize() << "sec\n"; - // update failed - Scalar dt = this->timeManager().timeStepSize(); - Scalar nextDt = dt / 2; - this->timeManager().setTimeStepSize(nextDt); - std::cout << "Failed for dt=" << dt << ". Try with half dt of " << nextDt << "\n"; - } - - // increase time step until the update fails - while (true) - { - if (!this->model().update(this->newtonMethod(), - this->newtonController())) - break; - - // sucessfull update. increase time step size - successDt = this->timeManager().timeStepSize(); - Scalar nextDt = successDt*1.25; - this->timeManager().setTimeStepSize(nextDt); - if (this->timeManager().timeStepSize() < nextDt) { - std::cout << "End of simulation reached!\n"; - break; - }; - std::cout << "Increase dt to " << nextDt << "\n"; - std::cout.flush(); - this->model().updateFailed(); - } - - // do a last update with the largest successful time step - this->newtonController().setVerbose(true); - this->timeManager().setTimeStepSize(successDt); - std::cout << "Convergence radius is " << successDt << "\n"; - this->model().update(this->newtonMethod(), this->newtonController()); -#endif + FluidSystem::init(Tmin, Tmax, nT, pmin, pmax, np); } /*! @@ -339,7 +239,7 @@ public: /*! * \brief Returns the temperature [K] within the domain. */ - Scalar temperature() const + Scalar temperatureAtPos(const GlobalPosition &globalPos) const { return temperature_; }; // \} @@ -449,96 +349,88 @@ public: return ParentType::shouldWriteRestartFile(); } - -#if USE_2P2C - /*! - * \brief Return the initial phase state inside a control volume. - */ - int initialPhasePresence(const Vertex &vert, - int &globalIdx, - const GlobalPosition &globalPos) const - { - if (onInlet_(globalPos)) - return Indices::lPhaseOnly; - else - return Indices::gPhaseOnly; - }; -#endif - private: // the internal method for the initial condition void initial_(PrimaryVariables &values, const GlobalPosition &globalPos) const { - Scalar pg; - if (onInlet_(globalPos)) - pg = 2e5; - else - pg = 1e5; - + typedef Dumux::EquilibriumFluidState<Scalar, FluidSystem> EquilibriumFluidState; + EquilibriumFluidState fs; -#if USE_2P2C - values[Indices::plIdx] = pg; + int refPhaseIdx; + int otherPhaseIdx; - if (onInlet_(globalPos)) - values[Indices::SgOrXIdx] = 0.0; // X^a_w - else - values[Indices::SgOrXIdx] = 0.0; // X^w_g -#else + // set the fluid temperatures + fs.setTemperature(this->temperatureAtPos(globalPos)); + if (onInlet_(globalPos)) { - // only liquid - Scalar S[numPhases]; - Scalar p[numPhases]; - Scalar xl[numComponents]; - Scalar beta[numComponents]; - - p[gPhaseIdx] = pg; - p[lPhaseIdx] = pg; - - S[lPhaseIdx] = 1.0; - S[gPhaseIdx] = 0.0; - - xl[FluidSystem::H2OIdx] = 1.0; - xl[FluidSystem::N2Idx] = 0.0; - beta[FluidSystem::H2OIdx] = FluidSystem::H2O::vaporPressure(temperature_); - beta[FluidSystem::N2Idx] = Dumux::BinaryCoeff::H2O_N2::henry(temperature_); - - // assign the primary variables - for (int i = 0; i < numComponents; ++i) - values[fug0Idx + i] = xl[i]*beta[i]; - - for (int i = 0; i < numPhases - 1; ++i) - values[S0Idx + i] = S[i]; - - values[p0Idx] = p[0]; + // only liquid on inlet + refPhaseIdx = lPhaseIdx; + otherPhaseIdx = gPhaseIdx; + + // set liquid saturation + fs.setSaturation(lPhaseIdx, 1.0); + + // set pressure of the liquid phase + fs.setPressure(lPhaseIdx, 2e5); + + // set the liquid composition to pure water + fs.setMoleFraction(lPhaseIdx, N2Idx, 1.0); + fs.setMoleFraction(lPhaseIdx, H2OIdx, 0.0); } else { - // only gas - Scalar S[numPhases]; - Scalar xg[numComponents]; - Scalar p[numPhases]; - - S[lPhaseIdx] = 0.0; - S[gPhaseIdx] = 1.0; - - p[lPhaseIdx] = pg; - p[gPhaseIdx] = pg; - - - xg[FluidSystem::H2OIdx] = 0.01; - xg[FluidSystem::N2Idx] = 0.99; - - - // assign the primary variables - for (int i = 0; i < numComponents; ++i) - values[fug0Idx + i] = xg[i]*pg; - - for (int i = 0; i < numPhases - 1; ++i) - values[S0Idx + i] = S[i]; - - values[p0Idx] = p[0]; - } -#endif // USE_2P2C + // elsewhere, only gas + refPhaseIdx = gPhaseIdx; + otherPhaseIdx = lPhaseIdx; + + // set gas saturation + fs.setSaturation(gPhaseIdx, 1.0); + + // set pressure of the gas phase + fs.setPressure(gPhaseIdx, 1e5); + + // set the gas composition to 99% nitrogen and 1% steam + fs.setMoleFraction(gPhaseIdx, N2Idx, 0.99); + fs.setMoleFraction(gPhaseIdx, H2OIdx, 0.01); + }; + + // set the other saturation + fs.setSaturation(otherPhaseIdx, 1.0 - fs.saturation(refPhaseIdx)); + + // calulate the capillary pressure + const MaterialLawParams &matParams = + this->spatialParameters().materialLawParamsAtPos(globalPos); + PhaseVector pC; + MaterialLaw::capillaryPressures(pC, matParams, fs); + fs.setPressure(otherPhaseIdx, + fs.pressure(refPhaseIdx) + + (pC[otherPhaseIdx] - pC[refPhaseIdx])); + + // make the fluid state consistent with local thermodynamic + // equilibrium + typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase; + + typename FluidSystem::ParameterCache paramCache; + ComputeFromReferencePhase::solve(fs, + paramCache, + refPhaseIdx, + /*setViscosity=*/false, + /*setEnthalpy=*/false); + + /////////// + // assign the primary variables + /////////// + + // all N component fugacities + for (int compIdx = 0; compIdx < numComponents; ++compIdx) + values[fug0Idx + compIdx] = fs.fugacity(refPhaseIdx, compIdx); + + // first M - 1 saturations + for (int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) + values[S0Idx + phaseIdx] = fs.saturation(phaseIdx); + + // first pressure + values[p0Idx] = fs.pressure(/*phaseIdx=*/0); } bool onInlet_(const GlobalPosition &globalPos) const diff --git a/test/boxmodels/MpNc/obstaclespatialparameters.hh b/test/boxmodels/MpNc/obstaclespatialparameters.hh index ddbac95ebde0f4dc0b98ebd2663685d3c9daf95f..e5d4a44bffd5b14aed7e9b0325dcdd8867b06c1c 100644 --- a/test/boxmodels/MpNc/obstaclespatialparameters.hh +++ b/test/boxmodels/MpNc/obstaclespatialparameters.hh @@ -27,13 +27,9 @@ #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh> #include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh> -#if USE_2P2C -#include <dumux/boxmodels/2p2c/2p2cmodel.hh> -#else #include <dumux/boxmodels/MpNc/MpNcmodel.hh> #include <dumux/material/fluidmatrixinteractions/Mp/Mplinearmaterial.hh> #include <dumux/material/fluidmatrixinteractions/Mp/2padapter.hh> -#endif namespace Dumux { @@ -65,11 +61,7 @@ private: typedef RegularizedLinearMaterial<Scalar> EffMaterialLaw; typedef EffToAbsLaw<EffMaterialLaw> TwoPMaterialLaw; public: -#if USE_2P2C - typedef TwoPMaterialLaw type; -#else typedef TwoPAdapter<lPhaseIdx, TwoPMaterialLaw> type; -#endif }; } @@ -261,11 +253,8 @@ public: * \param scvIdx The index of the sub-control volume. * \return the material parameters object */ - const MaterialLawParams& materialLawParams(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &pos) const { - const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineMaterialParams_; else