Hello,

I enclose all the files that I use.

Up to now in tutorialproblem_implicit.hh I introduce a double small_number = 1e-6; which works ok when I initialize the oil saturation profile (snIdx) but it is not effective on swIdx.

Also as I general question I'm wondering which is the correct model to approach this problem. I see that in this case it is used a different model.

NEW_TYPE_TAG(McWhorterProblem, INHERITS_FROM(FVPressureTwoP, FVTransportTwoP, IMPESTwoP, BuckleyLeverettSpatialParams));


And in general, in terms of accuracy and speed should I prefer sequential or implicit setup?

Thanks a lot,

Lorenzo


On 02/11/2018 13:56, Timo Koch wrote:
Hi Lorenzo,

it all depends on your setup. Probably something wrong with your custom material law.

What have you tried so far to fix your issue?

Timo

On 2. Nov 2018, at 11:53, lc <lorenzo.camp...@uniroma1.it <mailto:lorenzo.camp...@uniroma1.it>> wrote:

Hello Dennis,

thank you. I did as you suggested but as I do this, the Newton solver does not converge anymore on any grid level.

Do you have any hints?

Thank you,

Lorenzo

On 02/11/2018 10:45, Dennis Gläser wrote:

Good morning Lorenzo,

per default, the formulation for the 2p model is pw-sn. That means your primary variables are the water pressure and the non-wetting phase saturation (in your case oil I assume). Therefore, Indices::swIdx does not exists as it is not part of your primary variables.

Since you are considering a two-phase system, just set the oil saturation by doing

*values[Indices::snIdx] = 1.0 - std::min(smax, smin + exp_value + small_number);*

This is what you want I guess.

Best wishes,
Dennis


On 02.11.2018 08:37, lc wrote:

Good morning,

I'd like to ask how to impose an initial condition on the water saturation and not on the oil saturation.

Actually, what I implemented is the following:

         const auto pos = fvGeometry.subContVol[scvIdx].global;

        double x_0 = 0.;
        double smin = 0.2121;
        double smax = 0.7856;
        double exp_arg = (0.5 - pow((pos[0]-x_0)/(2.+cos(3.*sqrt(std::abs(pos[1]-75.0)))), 2.) );
        double exp_value = exp_arg >= -100 ? exp(exp_arg) : 0;
        double small_number = 1e-6;

*        values[Indices::snIdx] = std::min(smax, smin + exp_value + small_number);*

but this last line, should be imposed on values[Indices::swIdx] but if I write it I get an error, not declared variable.


Thank you,

Lorenzo





_______________________________________________
Dumux mailing list
Dumux@listserv.uni-stuttgart.de
https://listserv.uni-stuttgart.de/mailman/listinfo/dumux


_______________________________________________
Dumux mailing list
Dumux@listserv.uni-stuttgart.de
https://listserv.uni-stuttgart.de/mailman/listinfo/dumux
_______________________________________________
Dumux mailing list
Dumux@listserv.uni-stuttgart.de <mailto:Dumux@listserv.uni-stuttgart.de>
https://listserv.uni-stuttgart.de/mailman/listinfo/dumux

// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
 *
 * \brief Main file of the tutorial for a fully coupled twophase box model.
 */
#include <config.h> 			/*@\label{tutorial-implicit:include-begin}@*/
#include "tutorialproblem_implicit.hh"  /*@\label{tutorial-implicit:include-problem-header}@*/
#include <dumux/common/start.hh> 	/*@\label{tutorial-implicit:include-end}@*/

//! Prints a usage/help message if something goes wrong or the user asks for help
void usage(const char *progName, const std::string &errorMsg)  /*@\label{tutorial-implicit:usage-function}@*/
{
    std::cout
        <<  "\nUsage: " << progName << " [options]\n";
    if (errorMsg.size() > 0)
        std::cout << errorMsg << "\n";
    std::cout
        << "\n"
        << "The list of mandatory arguments for this program is:\n"
        << "\t-TEnd                The end of the simulation [s]\n"
        << "\t-DtInitial           The initial timestep size [s]\n"
        << "\t-Grid.UpperRight     The x-/y-coordinates of the grid's upper-right corner [m]\n"
        << "\t-Grid.Cells          The grid's x-/y-resolution\n"
        << "\n";
}

int main(int argc, char** argv)
{
    typedef TTAG(TutorialProblemImplicit) TypeTag; 	/*@\label{tutorial-implicit:set-type-tag}@*/
    return Dumux::start<TypeTag>(argc, argv, usage); 	/*@\label{tutorial-implicit:call-start}@*/
}
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
 *
 * \brief The spatial parameters for the fully coupled tutorial problem
 *        which uses the twophase box model.
 */
#ifndef DUMUX_TUTORIAL_SPATIAL_PARAMS_IMPLICIT_HH
#define DUMUX_TUTORIAL_SPATIAL_PARAMS_IMPLICIT_HH

#include <iostream>

// include parent spatialparameters
#include <dumux/material/spatialparams/implicit.hh>

// include material laws
//#include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh> /*@\label{tutorial-implicit:rawLawInclude}@*/
//#include <dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh>
//#include <dumux/material/fluidmatrixinteractions/2p/chebyshev.hh> /*@\label{tutorial-implicit:rawLawInclude}@*/
//#include <dumux/material/fluidmatrixinteractions/2p/brookscorey.hh> /*@\label{tutorial-implicit:rawLawInclude}@*/
//#include <dumux/material/fluidmatrixinteractions/2p/mybrookscorey.hh> /*@\label{tutorial-implicit:rawLawInclude}@*/
//#include <dumux/material/fluidmatrixinteractions/2p/mod_regularizedbrookscorey.hh> /*@\label{tutorial-implicit:rawLawInclude}@*/
#include <dumux/material/fluidmatrixinteractions/2p/mod_brookscorey.hh> /*@\label{tutorial-implicit:rawLawInclude}@*/
//#include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh>
#include <dumux/io/plotmateriallaw.hh>

namespace Dumux {

//forward declaration
template<class TypeTag>
class TutorialSpatialParamsImplicit;

namespace Properties
{
// The spatial parameters TypeTag
NEW_TYPE_TAG(TutorialSpatialParamsImplicit);

// Set the spatial parameters
SET_TYPE_PROP(TutorialSpatialParamsImplicit, SpatialParams, TutorialSpatialParamsImplicit<TypeTag>);

// Set the material law
SET_PROP(TutorialSpatialParamsImplicit, MaterialLaw)
{
private:
    // material law typedefs
    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;

    // select material law to be used
    // typedef RegularizedBrooksCorey<Scalar> RawMaterialLaw;	
    // typedef LinearMaterial<Scalar> RawMaterialLaw;     
    // typedef Chebyshev<Scalar> RawMaterialLaw;     	
    // typedef BrooksCorey<Scalar> RawMaterialLaw;    
    // typedef ModRegularizedBrooksCorey<Scalar> RawMaterialLaw;
    // typedef ModBrooksCorey<Scalar> RawMaterialLaw;    
    // typedef ModBrooksCorey<Scalar> type;		
public:
    // adapter for absolute law
    //typedef EffToAbsLaw<RawMaterialLaw> type;   
    
    // select material law to be used (used absolute)
    typedef ModBrooksCorey<Scalar> type;	

};
}

/*!
 * \ingroup TwoPBoxModel
 *
 * \brief The spatial parameters for the fully coupled tutorial problem
 *        which uses the twophase box model.
 */
template<class TypeTag>
class TutorialSpatialParamsImplicit: public ImplicitSpatialParams<TypeTag> /*@\label{tutorial-implicit:tutorialSpatialParameters}@*/
{
    // Get informations for current implementation via property system
    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
    enum
    {
        dim = Grid::dimension
    };

    // Get object types for function arguments
    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
    typedef typename Grid::Traits::template Codim<0>::Entity Element;

public:

    // get material law from property system
    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
    // determine appropriate parameters depending on selected materialLaw
    typedef typename MaterialLaw::Params MaterialLawParams;    /*@\label{tutorial-implicit:matLawObjectType}@*/


    /*! Intrinsic permeability tensor K \f$[m^2]\f$ depending
     *  on the position in the domain
     *
     *  \param element The finite volume element
     *  \param fvGeometry The finite-volume geometry in the box scheme
     *  \param scvIdx The local vertex index
     *
     *  Alternatively, the function intrinsicPermeabilityAtPos(const GlobalPosition& globalPos)
     *  could be defined, where globalPos is the vector including the global coordinates
     *  of the finite volume.
     */
    const Dune::FieldMatrix<Scalar, dim, dim> &intrinsicPermeability(const Element &element, /*@\label{tutorial-implicit:permeability}@*/
                                                    		     const FVElementGeometry &fvGeometry,
                                                    		     const int scvIdx) const
    { 
    	    //std::cout << "Permeability = "<< K_ << std::endl;
	    return K_; 
    }


    /*! Defines the porosity \f$[-]\f$ of the porous medium depending
     * on the position in the domain
     *
     *  \param element The finite volume element
     *  \param fvGeometry The finite-volume geometry in the box scheme
     *  \param scvIdx The local vertex index
     *
     *  Alternatively, the function porosityAtPos(const GlobalPosition& globalPos)
     *  could be defined, where globalPos is the vector including the global coordinates
     *  of the finite volume.
     */
    Scalar porosity(const Element &element,                    /*@\label{tutorial-implicit:porosity}@*/
                    const FVElementGeometry &fvGeometry,
                    const int scvIdx) const

    { return 0.255; }

    /*! Returns the parameter object for the material law (i.e. Brooks-Corey)
     *  depending on the position in the domain
     *
     *  \param element The finite volume element
     *  \param fvGeometry The finite-volume geometry in the box scheme
     *  \param scvIdx The local vertex index
     *
     *  Alternatively, the function materialLawParamsAtPos(const GlobalPosition& globalPos)
     *  could be defined, where globalPos is the vector including the global coordinates
     *  of the finite volume.
     */
    const MaterialLawParams& materialLawParams(const Element &element,            /*@\label{tutorial-implicit:matLawParams}@*/
                                               const FVElementGeometry &fvGeometry,
                                               const int scvIdx) const
    {
        return materialParams_;
    }

    /*!
     * \brief The constructor
     *
     * \param gridView The grid view
     * \param K_(0) The permeability tensor
     */
    TutorialSpatialParamsImplicit(const GridView& gridView) :
        ImplicitSpatialParams<TypeTag>(gridView),
        K_(0)
    {
        //set main diagonal entries of the permeability tensor to a value
        //setting to one value means: isotropic, homogeneous
        for (int i = 0; i < dim; i++)
            K_[i][i] = 2e-13;

        //set residual saturations
        // materialParams_.setSwr(0.2121);                /*@\label{tutorial-implicit:setLawParams}@*/
        // materialParams_.setSnr(1.-0.7856);

        //parameters of Mod Brooks & Corey Law
        //materialParams_.setPe(500.0);
        //materialParams_.setPe(80000.);
        //materialParams_.setLambda(2);
        //materialParams_.setLambda(-0.476190476190476);

        //parameters of Linear Law
        //materialParams_.setMaxPc(2000.0);
        //materialParams_.setEntryPc(0.);
	
        //parameters of Chebyshev Law
	//materialParams_.setPe(80000.);
        //materialParams_.setAlpha(2.1);
        //materialParams_.setSmin(0.2121);
        //materialParams_.setSmax(0.7856);
        //materialParams_.setLambda(-0.476190476190476);
	
	plotFluidMatrixInteractions_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, bool, Output, PlotFluidMatrixInteractions);
    }


    /*!
     * \brief This is called from the problem and creates a gnuplot output 
     *        of the pc-Sw and Kr curves. It is a good way to check the laws!
     */
    void plotMaterialLaw()
    {
        PlotMaterialLaw<TypeTag> plotMaterialLaw;
        GnuplotInterface<Scalar> gnuplot(plotFluidMatrixInteractions_);
        gnuplot.setOpenPlotWindow(plotFluidMatrixInteractions_);
        plotMaterialLaw.addpcswcurve(gnuplot, materialParams_, 0.2121, 0.7856, "Pc(Sw)", "w lp");
        //plotMaterialLaw.addpcswcurve(gnuplot, materialParams_, 0.24, 0.79, "Pc(Sw)", "w lp");
        //plotMaterialLaw.addpcswcurve(gnuplot, materialParams_, 0., 1., "Pc(Sw)", "w lp");
        gnuplot.setOption("set xrange [0:1]");
        gnuplot.setOption("set label \"residual\\nsaturation\" at 0.1,100000 center");
        gnuplot.plot("pc-Sw");

        gnuplot.resetAll();
        //plotMaterialLaw.addkrcurves(gnuplot, materialParams_, 0.2121, 0.7856, "kr(Sw)");
        //plotMaterialLaw.addkrcurves(gnuplot, materialParams_, 0.22, 0.79, "kr(Sw)");
        plotMaterialLaw.addkrcurves(gnuplot, materialParams_, 0., 1., "kr(Sw)");
        gnuplot.plot("kr");
    }

private:
    Dune::FieldMatrix<Scalar, dim, dim> K_;
    // Object that holds the values/parameters of the selected material law.
    MaterialLawParams materialParams_;                 /*@\label{tutorial-implicit:matParamsObject}@*/
    bool plotFluidMatrixInteractions_;
};
} // end namespace
#endif
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
 *
 * \brief Tutorial problem for a fully coupled twophase box model.
 */
#ifndef DUMUX_TUTORIAL_PROBLEM_IMPLICIT_HH    // guardian macro /*@\label{tutorial-implicit:guardian1}@*/
#define DUMUX_TUTORIAL_PROBLEM_IMPLICIT_HH    // guardian macro /*@\label{tutorial-implicit:guardian2}@*/

// The numerical model
#include <dumux/porousmediumflow/2p/implicit/model.hh>

// The base porous media box problem
#include <dumux/porousmediumflow/implicit/problem.hh>

// Spatially dependent parameters
#include "tutorialspatialparams_implicit.hh"

// The components that are used
//#include <dumux/material/components/chebyshev_h2o.hh>
//#include <dumux/material/components/chebyshev_oil.hh>
//#include <dumux/material/components/h2o.hh>
//#include <dumux/material/components/lnapl.hh>
#include <dumux/material/components/pseudooil.hh>
#include <dumux/material/components/pseudoh2o.hh>

namespace Dumux{
// Forward declaration of the problem class
template <class TypeTag>
class TutorialProblemImplicit;

namespace Properties {
// Create a new type tag for the problem
NEW_TYPE_TAG(TutorialProblemImplicit, INHERITS_FROM(BoxTwoP, TutorialSpatialParamsImplicit)); /*@\label{tutorial-implicit:create-type-tag}@*/

// Set the "Problem" property
SET_PROP(TutorialProblemImplicit, Problem) /*@\label{tutorial-implicit:set-problem}@*/
{ typedef TutorialProblemImplicit<TypeTag> type;};

// Set grid and the grid creator to be used
#if HAVE_DUNE_ALUGRID 
//SET_TYPE_PROP(TutorialProblemImplicit, Grid, Dune::ALUGrid</*dim=*/2, 2, Dune::cube, Dune::nonconforming>); 

// Uncomment the line below to use gmsh grids (and comment the previous one)
SET_TYPE_PROP(TutorialProblemImplicit, Grid, Dune::ALUGrid</*dim=*/2, 2, Dune::simplex, Dune::conforming>); 

#elif HAVE_UG
SET_TYPE_PROP(TutorialProblemImplicit, Grid, Dune::UGGrid<2>);
#else
SET_TYPE_PROP(TutorialProblemImplicit, Grid, Dune::YaspGrid<2>);
#endif // HAVE_DUNE_ALUGRID

// Set the wetting phase
SET_PROP(TutorialProblemImplicit, WettingPhase) 
{
private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
public: typedef FluidSystems::LiquidPhase<Scalar, PseudoH2O<Scalar> > type;
};

// Set the non-wetting phase
SET_PROP(TutorialProblemImplicit, NonwettingPhase)
{
private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
public: typedef FluidSystems::LiquidPhase<Scalar, PseudoOil<Scalar> > type; 
}; 

SET_TYPE_PROP(TutorialProblemImplicit, FluidSystem, TwoPImmiscibleFluidSystem<TypeTag>);

// Disable gravity
SET_BOOL_PROP(TutorialProblemImplicit, ProblemEnableGravity, false); 
}

/*!
 * \ingroup TwoPBoxModel
 *
 * \brief  Tutorial problem for a fully coupled twophase box model.
 */
template <class TypeTag>
class TutorialProblemImplicit : public ImplicitPorousMediaProblem<TypeTag> 
{
    typedef ImplicitPorousMediaProblem<TypeTag> ParentType;
    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;

    // Grid dimension
    enum { dim = GridView::dimension,
           dimWorld = GridView::dimensionworld
    };

    // imported from buckleyleverettproblem.hh -->
    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
    typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase;
    typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase;
    //typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
    // <--

    // Types from DUNE-Grid
    typedef typename GridView::template Codim<0>::Entity Element;
    typedef typename GridView::template Codim<dim>::Entity Vertex;
    typedef typename GridView::Intersection Intersection;
    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;

    // Dumux specific types
    typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;
    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;

public:
    TutorialProblemImplicit(TimeManager &timeManager, const GridView &gridView)
        : ParentType(timeManager, gridView)
        , eps_(1e-6)
    {
#if !(HAVE_DUNE_ALUGRID || HAVE_UG)
      std::cout << "If you want to use simplices instead of cubes, install and use dune-ALUGrid or UGGrid." << std::endl;
#endif // !(HAVE_DUNE_ALUGRID || HAVE_UG)
      
      // points to the plotting class for 
      // capillarity and permeability laws
      this->spatialParams().plotMaterialLaw();

      // here we can set run-time options from input file 
      //upperRight_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, GlobalPosition, Grid, UpperRight);

      //WettingPhase::Component::setViscosity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, ViscosityW));
      //NonwettingPhase::Component::setViscosity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, ViscosityNW));

      //WettingPhase::Component::setDensity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityW));
      //NonwettingPhase::Component::setDensity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityNW));

      //densityNonWetting_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityNW);
    }

    //! Specifies the problem name. This is used as a prefix for files
    //! generated by the simulation.
    std::string name() const
    { return "tutorial_implicit"; }

    //! Returns true if a restart file should be written.
    bool shouldWriteRestartFile() const /*@\label{tutorial-implicit:restart}@*/
    { return false; }

    //! Returns true if the current solution should be written to disk
    //! as a VTK file
    bool shouldWriteOutput() const /*@\label{tutorial-implicit:output}@*/
    {
        return
            (this->timeManager().timeStepIndex() > 0
             && (this->timeManager().timeStepIndex() % 1 == 0));
    }

    //! Returns the temperature within a finite volume. We use constant
    //! 10 degrees Celsius. TODO: which temperature for us?
    Scalar temperature() const
    { return 273.15 + 10.; }

    //! Specifies which kind of boundary condition should be used for
    //! which equation for a finite volume on the boundary.
    void boundaryTypes(BoundaryTypes &bcTypes, const Vertex &vertex) const
    {
        const GlobalPosition &globalPos = vertex.geometry().center();

	// Dirichlet condition on left boundary
        if (globalPos[0] < eps_) 
          bcTypes.setAllDirichlet();

	// Neumann condition on the other boundaries
        else 
          bcTypes.setAllNeumann();
	  //bcTypes.setNeumann(Indices::pressEqIdx);

    }

    //! Evaluates the Dirichlet boundary conditions for a finite volume
    //! on the grid boundary. Here, the 'values' parameter stores
    //! primary variables.
    void dirichlet(PrimaryVariables &values, const Vertex &vertex) const
    {
	const Scalar smax = 0.7856;    
	const Scalar smin = 0.2121;    

        const GlobalPosition &globalPos = vertex.geometry().center();

        if (globalPos[0] < eps_) { // inlet, left boundary

          values[Indices::pwIdx] = 30*1e5; //60.0*1e5;	// pressure
          values[Indices::snIdx] = (1.-smax);		// oil saturation

	} else { // outlet, right boundary

      	  // It should be irrelevant which constant
	  // value of pressure we impose at outlet ...
	  values[Indices::pwIdx] = -30*1e5; 
          values[Indices::snIdx] = (1.-smin);
	}

    }

    //! Evaluates the boundary conditions for a Neumann boundary
    //! segment. Here, the 'values' parameter stores the mass flux in
    //! [kg/(m^2 * s)] in normal direction of each phase. Negative
    //! values mean influx.
    void neumann(PrimaryVariables &values,
                 const Element &element,
                 const FVElementGeometry &fvGeometry,
                 const Intersection &intersection,
                 int scvIdx,
                 int boundaryFaceIdx) const
    {
        const GlobalPosition &globalPos = fvGeometry.boundaryFace[boundaryFaceIdx].ipGlobal;

	// define boundaries of the domain (maybe not necessary, just faster)
        Scalar right = this->bBoxMax()[0]; //std::cout << right << std::endl;
        Scalar left  = this->bBoxMin()[0]; //std::cout << left  << std::endl;
        Scalar up    = this->bBoxMax()[1]; //std::cout << up    << std::endl;
        Scalar down  = this->bBoxMin()[1]; //std::cout << down  << std::endl;

        // everywhere imposes zero-flux
	// then overwrites it
	values = 0.;

        // oil outflow on the right boundary 
        if (globalPos[0] > right - eps_) {

            // oil outflux of 30 g/(m * s) on the right boundary.
            //values[Indices::contiNEqIdx] = 3e-2;
	    
            // no water outflux on the right boundary.
            values[Indices::contiWEqIdx] = 0;

        } else if (globalPos[0] < eps_) {
		const Scalar waterDensity = 1000.0;
		const Scalar oilDensity = 850.0;
	        //values[Indices::wPhaseIdx] = 283.68; // N/m^3
	        values[Indices::wPhaseIdx] = (0.0034722*0.001/(2.*5.1*1e-3*15*800));

		// ... other possible fields
		//Indices::pressureEqIdx
		//Indices::satEqIdx
		//Indices::wPhaseIdx
		//Indices::nPhaseIdx
		//Indices::swIdx
	}
	else {

            // no-flow on the remaining Neumann-boundaries.
	    // actually this is redundant because we have 
	    // already set value = 0. previously
            values[Indices::contiWEqIdx] = 0;
            values[Indices::contiNEqIdx] = 0;
        }
    }

    //! Evaluates the initial value for a control volume. For this
    //! method, the 'values' parameter stores primary variables.
    void initial(PrimaryVariables &values,
                 const Element &element,
                 const FVElementGeometry &fvGeometry,
                 int scvIdx) const
    {
	// Assign p=0, makes the matrix singular, and why should be vacuum?
	// Since it shouldn't make any difference just chooce p!=0
	// TODO: check that it makes no difference
        values[Indices::pwIdx] = 30.*1e5; 

        //values[Indices::snIdx] = (1.0-0.7856);
        //values[Indices::swIdx] = (0.7856);

        // To retrieve x- and y- local coordinates 
        const auto pos = fvGeometry.subContVol[scvIdx].global;
        double x_0 = 0.;
        double smin = 0.2121;
        double smax = 0.7856;
        double exp_arg = (0.5 - pow((pos[0]-x_0)/(2.+cos(3.*sqrt(std::abs(pos[1]-75.0)))), 2.));
        //double exp_arg = 1. - (0.5 - pow((pos[0]-x_0)/(2.+cos(3.*sqrt(std::abs(pos[1]-75.0)))), 2.));
        double exp_value = exp_arg >= -100 ? exp(exp_arg) : 0;
        double small_number = 1e-6; // help the Newton solver convergence

	// Warning: the initial distribution should be defined on sw and not on sn!
        values[Indices::snIdx] = std::min(smax, smin + exp_value + small_number);

	// with this law the Newton solver does not converge easily
	//values[Indices::snIdx] = 1.0 - std::min(smax, smin + exp_value + small_number);
	// values[Indices::snIdx] = std::min(smax, smin + exp_value + small_number);
 	//std::cout << std::min(smax, smin + exp_value + small_number) << " " << 
	//	 1.0 - std::min(smax, smin + exp_value + small_number) << std::endl;

	// from COMSOL
        // min(smax, exp(-((x+wellDistance/2-wellRadius/2)/1/(2+ cos(3*sqrt(max(-y, y)))))^2+1/2+0*1500/(1+max(y, -y)^4))+sMin)
//        values[Indices::snIdx] = std::min(smax, exp(-pow(((pos[0]+150/2-0.1/2)/1/(2 + cos(3*sqrt(std::max(-pos[1], pos[1]))))),2)
//				 +1/2+0*1500/pow(1+std::max(pos[1],-pos[1]),4))+smin);
//        values[Indices::snIdx] = 1.0 - 
//				 std::min(smax, exp(-pow(((pos[0]+150/2-0.1/2)/1/(2 + cos(3*sqrt(std::max(-pos[1], pos[1]))))),2)
//				 +1/2+0*1500/pow(1+std::max(pos[1],-pos[1]),4))+smin);
    }


    //! Evaluates the source term for all phases within a given
    //! sub-control-volume. In this case, the 'values' parameter
    //! stores the rate mass generated or annihilated per volume unit
    //! in [kg / (m^3 * s)]. Positive values mean that mass is created.
    void source(PrimaryVariables &values,
                const Element &element,
                const FVElementGeometry &fvGeometry,
                int scvIdx) const
    {
	// no source term
        values[Indices::contiWEqIdx] = 0.0;
        values[Indices::contiNEqIdx] = 0.0;
    }

private:
    Scalar eps_;
    GlobalPosition upperRight_;
    Scalar swr_, snr_;
    Scalar pLeftBc_;
    Scalar densityNonWetting_;
    bool paraviewOutput_;
};
}

#endif
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
 *
 * \brief Implementation of the capillary pressure and
 *        relative permeability <-> saturation relations 
 *        according to the Chebyshev model.
 *
 */

#ifndef DUMUX_MOD_BROOKS_COREY_HH
#define DUMUX_MOD_BROOKS_COREY_HH

#include "mod_brookscoreyparams.hh"

#include <algorithm>
#include <cmath>
#include <iostream>

namespace Dumux
{
/*!
 * \ingroup fluidmatrixinteractionslaws
 *
 * \brief Implementation of the Chebyshev capillary pressure <->
 *        saturation relation. This class bundles the "raw" curves
 *        as static members and doesn't concern itself converting
 *        absolute to effective saturations and vice versa.
 *
 * For general info: EffToAbsLaw
 *
 *\see ModBrooksCoreyParams
 */
template <class ScalarT, class ParamsT = ModBrooksCoreyParams<ScalarT> >
class ModBrooksCorey
{
public:
    typedef ParamsT     Params;
    typedef typename    Params::Scalar Scalar;


    // Capillarity-saturation law according to the Chebyshev parametrization.
    static Scalar pc(const Params &params, Scalar sw)
    {
        using std::pow;
        using std::min;
        using std::max;

	// eps_smin introduced to avoid pc(0) which would give -inf from the log.
	const Scalar eps_smin = 1e-5;
	const Scalar smin = 0.2121;
	const Scalar smax = 0.7856;

        sw = min(max(sw, 0.2121), 0.7856);

	//if (sw > smax)
        //  return 80000*(pow(-log(smax - smin), 2.1));
        //else if (sw <= smin)
        //  return 80000*(pow(-log(smin - smin + eps_smin), 2.1));

        return 80000*(pow(-log(sw - smin), 2.1));
    }


    // Saturation-capillarity law according to the Chebyshev parametrization.
    static Scalar sw(const Params &params, Scalar pc)
    {
        using std::pow;
        using std::max;

        pc = max(pc, 0.0); // the equation below is undefined for negative pcs

	const Scalar smin = 0.2121;

	//return smin + exp(-(pow(pc/(80000)), 1./2.1));
	DUNE_THROW(Dune::NotImplemented, "mod_brookscoreyparams::Sw");
    }


    // The partial derivative of the capillary pressure
    // w.r.t. the effective saturation according to Chebyshev law.
    static Scalar dpc_dswe(const Params &params, Scalar swe)
    {
        using std::pow;
        using std::min;
        using std::max;

        swe = min(max(swe, 0.0), 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0

        DUNE_THROW(Dune::NotImplemented, "mod_brookscoreyparams::dpc_dsw");
    }

    
    // The partial derivative of the effective saturation 
    // w.r.t. the capillary pressure according to Chebyshev law.
    static Scalar dswe_dpc(const Params &params, Scalar pc)
    {
        using std::pow;
        using std::max;

        pc = max(pc, 0.0); // the equation below is undefined for negative pcs

        DUNE_THROW(Dune::NotImplemented, "mod_brookscoreyparams::dswe_dpc");
    }


    // The relative permeability for the wetting phase of
    // the medium implied by the Chebyshev parameterization
    // given in absolute terms (not effective).
    static Scalar krw(const Params &params, Scalar sw)
    {
        using std::pow;
        using std::min;
        using std::max;

        sw = min(max(sw, 0.2121), 0.7856); 

	const Scalar smin = 0.2121;
  	const Scalar smax = 0.7856;

	//if (sw >= smax) 
        //  return 5.0*pow((smax-smin), 5.);
	//else if (sw <= smin) 
        //  return 0.;

        return 5.0*(sw - smin)*(sw - smin)*(sw - smin)*(sw - smin)*(sw - smin);
    }


    // The derivative of the relative permeability for the 
    // wetting phase with regard to the wetting saturation of the
    // medium implied by the Chebyshev parameterization.
    static Scalar dkrw_dswe(const Params &params, Scalar swe)
    {
        using std::pow;
        using std::min;
        using std::max;

        swe = min(max(swe, 0.0), 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0

        //return 25.0*pow((swe - 0.2121), 4.);
	DUNE_THROW(Dune::NotImplemented, "mod_brookscoreyparams::dkrw_dswe");
    }


    // The relative permeability for the non-wetting phase of
    // the medium implied by the Chebyshev parameterization
    // given in absolute (not effective) terms.
    static Scalar krn(const Params &params, Scalar sw)
    {
        using std::pow;
        using std::min;
        using std::max;

        sw = min(max(sw, 0.2121), 0.7856); 

	const Scalar smin = 0.2121;
  	const Scalar smax = 0.7856;

	//if (sw >= smax)
        //  return 0.;
	//else if (sw <= smin)
        //  return 1.;

	return 16.0*(smax - sw)*(smax - sw)*(smax - sw)*(smax - sw)*(smax - sw);
    }  


    // The derivative of the relative permeability for the
    // non-wetting phase in regard to the wetting saturation of
    // the medium as implied by the Chebyshev parameterization.
    static Scalar dkrn_dswe(const Params &params, Scalar swe)
    {
        using std::pow;
        using std::min;
        using std::max;

        swe = min(max(swe, 0.0), 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0

	//return 80.0*pow((0.7856 - swe), 4.);
	DUNE_THROW(Dune::NotImplemented, "mod_brookscoreyparams::dkrn_dswe");
    }

};
} // end namespace Dumux

#endif // MOD_BROOKS_COREY_HH
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/

/*!
 * \file
 *
 * \brief Specification of the material parameters
 *       for the Brooks Corey constitutive relations.
 */
#ifndef DUMUX_MOD_BROOKS_COREY_PARAMS_HH
#define DUMUX_MOD_BROOKS_COREY_PARAMS_HH

#include <dumux/common/valgrind.hh>

namespace Dumux
{

/*!
 * \brief Specification of the material parameters
 *       for the Brooks Corey constitutive relations.
 *
 *        \ingroup fluidmatrixinteractionsparams
 *
 *\see BrooksCorey
 */
template <class ScalarT>
class ModBrooksCoreyParams
{
public:
    typedef ScalarT Scalar;

    ModBrooksCoreyParams()
    {
        Valgrind::SetUndefined(*this);
    }

    ModBrooksCoreyParams(Scalar pe, Scalar lambda)
        : pe_(pe), lambda_(lambda)
    {
    }

    /*!
     * \brief Returns the entry pressure in \f$\mathrm{[Pa]}\f$
     */
    Scalar pe() const
    { return pe_; }

    /*!
     * \brief Set the entry pressure in \f$\mathrm{[Pa]}\f$]
     */
    void setPe(Scalar v)
    { pe_ = v; }


    /*!
     * \brief Returns the lambda shape parameter \f$\mathrm{[-]}\f$
     */
    Scalar lambda() const
    { return lambda_; }

    /*!
     * \brief Set the lambda shape parameter \f$\mathrm{[-]}\f$
     */
    void setLambda(Scalar v)
    { lambda_ = v; }

private:
    Scalar pe_;
    Scalar lambda_;
};
} // namespace Dumux

#endif
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
 *
 * \brief Properties of pure water \f$H_2O\f$.
 */
#ifndef DUMUX_PSEUDOH2O_HH
#define DUMUX_PSEUDOH2O_HH


#include <dumux/material/components/component.hh>

namespace Dumux
{
/*!
 * \brief Rough estimate for testing purposes of some water.
 */
template <class ScalarT>
class PseudoH2O : public Component<ScalarT, PseudoH2O<ScalarT> >
{
    typedef Component<ScalarT, PseudoH2O<ScalarT> > ParentType;
    typedef ScalarT Scalar;
public:
    /*!
     * \brief A human readable name for the water.
     */
    static std::string name()
    { return "H2O"; }

    /*!
     * \brief Rough estimate of the density of oil [kg/m^3].
     * \param temperature DOC ME!
     * \param pressure DOC ME!
     */
    static Scalar liquidDensity(Scalar temperature, Scalar pressure)
    {
        return density_;
    }

    /*!
     * \brief Rough estimate of the viscosity of oil kg/(ms).
     * \param temperature DOC ME!
     * \param pressure DOC ME!
     */
    static Scalar liquidViscosity(Scalar temperature, Scalar pressure)
    {
        return viscosity_;
    };
    /*!
     * \brief DOC ME!
     * \param viscosity DOC ME!
     */
    static void setViscosity(Scalar viscosity)
    {
        viscosity_ =  viscosity;
    }
    /*!
     * \brief DOC ME!
     * \param density DOC ME!
     */
    static void setDensity(Scalar density)
    {
        density_ =  density;
    }

private:
    static Scalar viscosity_;
    static Scalar density_;
};
template <class ScalarT>
typename PseudoH2O<ScalarT>::Scalar PseudoH2O<ScalarT>::viscosity_ = 0.001;
template <class ScalarT>
typename PseudoH2O<ScalarT>::Scalar PseudoH2O<ScalarT>::density_ = 1000;
} // end namepace

#endif
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
 *   See the file COPYING for full copying permissions.                      *
 *                                                                           *
 *   This program is free software: you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (at your option) any later version.                                     *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
 *
 * \brief Properties of pure water \f$H_2O\f$.
 */
#ifndef DUMUX_PSEUDOOIL_HH
#define DUMUX_PSEUDOOIL_HH


#include <dumux/material/components/component.hh>
//#include "interface_BL.xml"

namespace Dumux
{
/*!
 * \brief Rough estimate for testing purposes of some oil.
 */
template <class ScalarT>
class PseudoOil : public Component<ScalarT, PseudoOil<ScalarT> >
{
    typedef Component<ScalarT, PseudoOil<ScalarT> > ParentType;
    typedef ScalarT Scalar;

public:
    /*!
     * \brief A human readable name for the water.
     */
    static std::string name()
    { return "Oil"; }

    /*!
     * \brief Rough estimate of the density of oil [kg/m^3].
     * \param temperature DOC ME!
     * \param pressure DOC ME!
     */
    static Scalar liquidDensity(Scalar temperature, Scalar pressure)
    {
        return density_;
    }
    //        double densityOil = 1000;
    //        double viscosityWater = interfaceFluidProps.IFP_ViscosityWettingFluid;
    //        double viscosityOil = interfaceFluidProps.IFP_ViscosityNonWettingFluid;

    /*!
     * \brief Rough estimate of the viscosity of oil kg/(ms).
     * \param temperature DOC ME!
     * \param pressure DOC ME!
     */
    static Scalar liquidViscosity(Scalar temperature, Scalar pressure)
    {
        return viscosity_;
    };
    /*!
     * \brief DOC ME!
     * \param viscosity DOC ME!
     */
    static void setViscosity(Scalar viscosity)
    {
        viscosity_ =  viscosity;
    }
    /*!
     * \brief DOC ME!
     * \param density DOC ME!
     */
    static void setDensity(Scalar density)
    {
        density_ =  density;
    }

private:
    static Scalar viscosity_;
    static Scalar density_;
};
template <class ScalarT>
typename PseudoOil<ScalarT>::Scalar PseudoOil<ScalarT>::viscosity_ = 0.104;
template <class ScalarT>
typename PseudoOil<ScalarT>::Scalar PseudoOil<ScalarT>::density_ = 850;
} // end namepace

#endif
_______________________________________________
Dumux mailing list
Dumux@listserv.uni-stuttgart.de
https://listserv.uni-stuttgart.de/mailman/listinfo/dumux

Reply via email to