Hello,

I'm trying to implement a random distribution of K in my domain. I followed
the example of 1p provided in DuMux-test. But I am having the following
error :


*/home/ggl/dumux/dumux/test/porousmediumflow/co2/implicit/test_boxco2.cc:79:58:
  required from here/usr/include/c++/7/ext/new_allocator.h:136:4: error: no
matching function for call to
‘Dumux::HeterogeneousSpatialParams<Dumux::Properties::TTag::HeterogeneousBoxProblem>::HeterogeneousSpatialParams(const
Dune::GridView<Dune::ALU3dLeafGridViewTraits<const Dune::ALUGrid<2, 2,
(Dune::ALUGridElementType)1, (Dune::ALUGridRefinementType)1>,
(Dune::PartitionIteratorType)4> >&)’  { ::new((void *)__p)
_Up(std::forward<_Args>(__args)...); }*

Do you have any suggestions on how can I fixe it.
PS : Please find attached the problem and spatialparameters files.
Regards,

Kenza
// -*- 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 Definition of a problem, where CO2 is injected in a reservoir.
 */
#ifndef DUMUX_HETEROGENEOUS_PROBLEM_HH
#define DUMUX_HETEROGENEOUS_PROBLEM_HH

#include <fstream>

#include <dumux/porousmediumflow/co2/implicit/model.hh>
#include <dumux/porousmediumflow/co2/implicit/volumevariables.hh>
#include <dumux/material/fluidsystems/brineco2.hh>
#include <dumux/porousmediumflow/implicit/problem.hh>
#include <dumux/implicit/box/intersectiontovertexbc.hh>

#include <dumux/linear/amgbackend.hh>

#include "heterogeneousspatialparameters.hh"
#include "heterogeneousco2tables.hh"

namespace Dumux
{

template <class TypeTag>
class HeterogeneousProblem;

namespace Properties
{
NEW_TYPE_TAG(HeterogeneousProblem, INHERITS_FROM(TwoPTwoC, HeterogeneousSpatialParams));
NEW_TYPE_TAG(HeterogeneousBoxProblem, INHERITS_FROM(BoxModel, HeterogeneousProblem));
NEW_TYPE_TAG(HeterogeneousCCProblem, INHERITS_FROM(CCModel, HeterogeneousProblem));

// Set the grid type
#if HAVE_DUNE_ALUGRID
SET_TYPE_PROP(HeterogeneousProblem, Grid, Dune::ALUGrid<2, 2, Dune::cube, Dune::nonconforming>);
#else
SET_TYPE_PROP(HeterogeneousProblem, Grid, Dune::YaspGrid<2>);
#endif

// Set the problem property
SET_TYPE_PROP(HeterogeneousProblem, Problem, HeterogeneousProblem<TypeTag>);

// Set fluid configuration
SET_TYPE_PROP(HeterogeneousProblem, FluidSystem, BrineCO2FluidSystem<TypeTag>);

// Set the CO2 table to be used; in this case not the the default table
SET_TYPE_PROP(HeterogeneousProblem, CO2Table, HeterogeneousCO2Tables::CO2Tables);

// Set the salinity mass fraction of the brine in the reservoir
SET_SCALAR_PROP(HeterogeneousProblem, ProblemSalinity, 1e-3);

//! the CO2 Model and VolumeVariables properties
SET_TYPE_PROP(HeterogeneousProblem, Model, CO2Model<TypeTag>);
SET_TYPE_PROP(HeterogeneousProblem, VolumeVariables, CO2VolumeVariables<TypeTag>);

// Solver settings for the tests using AMG
SET_TYPE_PROP(HeterogeneousBoxProblem, LinearSolver, Dumux::AMGBackend<TypeTag> );
SET_TYPE_PROP(HeterogeneousCCProblem, LinearSolver, Dumux::AMGBackend<TypeTag> );

// Use Moles
SET_BOOL_PROP(HeterogeneousProblem, UseMoles, false);
}


/*!
 * \ingroup CO2Model
 * \ingroup ImplicitTestProblems
 * \brief Definition of a problem, where CO2 is injected in a reservoir.
 *
 * The domain is sized 200m times 100m and consists of four layers, a
 * permeable reservoir layer at the bottom, a barrier rock layer with reduced permeability, another reservoir layer
 * and at the top a barrier rock layer with a very low permeablility.
 *
 * CO2 is injected at the permeable bottom layer
 * from the left side. The domain is initially filled with brine.
 *
 * The grid is unstructered and permeability and porosity for the elements are read in from the grid file. The grid file
 * also contains so-called boundary ids which can be used assigned during the grid creation in order to differentiate
 * between different parts of the boundary.
 * These boundary ids can be imported into the problem where the boundary conditions can then be assigned accordingly.
 *
 * The model is able to use either mole or mass fractions. The property useMoles can be set to either true or false in the
 * problem file. Make sure that the according units are used in the problem setup. The default setting for useMoles is false.
 *
 * To run the simulation execute the following line in shell (works with the box and cell centered spatial discretization method):
 * <tt>./test_ccco2 </tt> or <tt>./test_boxco2 </tt>
 */
template <class TypeTag >
class HeterogeneousProblem : public ImplicitPorousMediaProblem<TypeTag>
{

    typedef ImplicitPorousMediaProblem<TypeTag> ParentType;
    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;

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

    // copy some indices for convenience
    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
    enum {
        lPhaseIdx = Indices::wPhaseIdx,
        gPhaseIdx = Indices::nPhaseIdx
    };
    enum {
        wCompIdx = FluidSystem::wCompIdx,
        nCompIdx = FluidSystem::nCompIdx
    };
    enum {
        BrineIdx = FluidSystem::BrineIdx,
        CO2Idx = FluidSystem::CO2Idx
    };
    enum {
        conti0EqIdx = Indices::conti0EqIdx,
        contiCO2EqIdx = conti0EqIdx + CO2Idx
    };

    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
    typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;

    typedef typename GridView::template Codim<0>::Entity Element;
    typedef typename GridView::template Codim<dim>::Entity Vertex;
    typedef typename GridView::Intersection Intersection;

    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
    typedef typename GET_PROP_TYPE(TypeTag, GridCreator) GridCreator;

    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
    typedef typename GET_PROP_TYPE(TypeTag, CO2Table) CO2Table;
    typedef Dumux::CO2<Scalar, CO2Table> CO2;
    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
    enum { dofCodim = isBox ? dim : 0 };
    //! property that defines whether mole or mass fractions are used
    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);

public:


/*,
        : ParentType(timeManager, GridCreator::grid().leafGridView())/*,

          //Boundary Id Setup:
          injectionTop_(1),
          injectionBottom_(2),
          dirichletBoundary_(3),
          noFlowBoundary_(4),
          intersectionToVertexBC_(*this)
*/

    /*!
     * \brief The constructor
     *
     * \param timeManager The time manager
     * \param gridView The grid view
     */
    HeterogeneousProblem(TimeManager &timeManager,
                     const GridView &gridView)
        : ParentType(timeManager, GridCreator::grid().leafGridView()) /*,

          //Boundary Id Setup:
          injectionTop_(1),
          injectionBottom_(2),
          dirichletBoundary_(3),
          noFlowBoundary_(4),
          intersectionToVertexBC_(*this)		*/
		    {
            nTemperature_       = GET_RUNTIME_PARAM(TypeTag, int, FluidSystem.NTemperature);
            nPressure_          = GET_RUNTIME_PARAM(TypeTag, int, FluidSystem.NPressure);
            pressureLow_        = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.PressureLow);
            pressureHigh_       = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.PressureHigh);
            temperatureLow_     = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.TemperatureLow);
            temperatureHigh_    = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.TemperatureHigh);
            depthBOR_           = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.DepthBOR);
            name_               = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name);
            injectionRate_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.InjectionRate);
			timepulsedebut1_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.TimePulseDebut1);
			timepulsefin1_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.TimePulseFin1);
			timepulsedebut2_    = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.TimePulseDebut2);
			timepulsefin2_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.TimePulseFin2);
			resultsTime1_       = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ResultsTime1);
            resultsTime2_       = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ResultsTime2);
            resultsTime3_       = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ResultsTime3);
			injecttop_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.InjectTop);
			injectbot_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.InjectBot);
			injectright_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.InjectRight);
			injectleft_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.InjectLeft);
			celltemp_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.CellTemp);
			hzdp_      = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.HZdp);
			
			

        /* Alternative syntax:
         * typedef typename GET_PROP(TypeTag, ParameterTree) ParameterTree;
         * const Dune::ParameterTree &tree = ParameterTree::tree();
         * nTemperature_       = tree.template get<int>("FluidSystem.nTemperature");
         *
         * + We see what we do
         * - Reporting whether it was used does not work
         * - Overwriting on command line not possible
        */

        // set the spatial parameters by reading the DGF grid file
//        this->spatialParams().setParams();

        // initialize the tables of the fluid system
        FluidSystem::init(/*Tmin=*/temperatureLow_,
                          /*Tmax=*/temperatureHigh_,
                          /*nT=*/nTemperature_,
                          /*pmin=*/pressureLow_,
                          /*pmax=*/pressureHigh_,
                          /*np=*/nPressure_);

        //stating in the console whether mole or mass fractions are used
        if(useMoles)
        {
            std::cout<<"problem uses mole fractions"<<std::endl;
        }
        else
        {
            std::cout<<"problem uses mass fractions"<<std::endl;
        }
		
		this->timeManager().startNextEpisode(resultsTime1_);
    }

    /*!
     * \brief User defined output after the time integration
     *
     * Will be called diretly after the time integration.
     */
    void postTimeStep()
    {
        // Calculate storage terms
        PrimaryVariables storageL, storageG;
        this->model().globalPhaseStorage(storageL, lPhaseIdx);
        this->model().globalPhaseStorage(storageG, gPhaseIdx);

        // Write mass balance information for rank 0
        if (this->gridView().comm().rank() == 0) {
            std::cout<<"Storage: liquid=[" << storageL << "]"
                     << " gas=[" << storageG << "]\n";
        }
    }

    /*!
     * \brief Append all quantities of interest which can be derived
     *        from the solution of the current time step to the VTK
     *        writer.
     */
    void addOutputVtkFields()
    {
        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;

         // get the number of degrees of freedom
         unsigned numDofs = this->model().numDofs();
         unsigned numElements = this->gridView().size(0);

         //create required scalar fields
         ScalarField *Kxx = this->resultWriter().allocateManagedBuffer(numElements);
         ScalarField *cellPorosity = this->resultWriter().allocateManagedBuffer(numElements);
         ScalarField *boxVolume = this->resultWriter().allocateManagedBuffer(numDofs);
         (*boxVolume) = 0;

         //Fill the scalar fields with values
         ScalarField *rank = this->resultWriter().allocateManagedBuffer(numElements);

         FVElementGeometry fvGeometry;
         VolumeVariables volVars;

         for (const auto& element : elements(this->gridView()))
         {
             int eIdx = this->elementMapper().index(element);
             (*rank)[eIdx] = this->gridView().comm().rank();
             fvGeometry.update(this->gridView(), element);


             for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
             {
                 int dofIdxGlobal = this->model().dofMapper().subIndex(element, scvIdx, dofCodim);
                 volVars.update(this->model().curSol()[dofIdxGlobal],
                                *this,
                                element,
                                fvGeometry,
                                scvIdx,
                                false);
                 (*boxVolume)[dofIdxGlobal] += fvGeometry.subContVol[scvIdx].volume;
             }
             (*Kxx)[eIdx] = this->spatialParams().intrinsicPermeability(element, fvGeometry, /*element data*/ 0);
             (*cellPorosity)[eIdx] = this->spatialParams().porosity(element, fvGeometry, /*element data*/ 0);
         }

         //pass the scalar fields to the vtkwriter
         this->resultWriter().attachDofData(*Kxx, "Kxx", false); //element data
         this->resultWriter().attachDofData(*cellPorosity, "cellwisePorosity", false); //element data
         this->resultWriter().attachDofData(*boxVolume, "boxVolume", isBox);
    }

    /*!
     * \name Problem parameters
     */
    // \{

    /*!
     * \brief The problem name.
     *
     * This is used as a prefix for files generated by the simulation.
     */
    const std::string name() const
    { return name_; }
	
	void episodeEnd()
    {
        Scalar sim_time_ = this->timeManager().time();
        // Start new episode if episode is over
        if(sim_time_ < resultsTime2_){
            this->timeManager().startNextEpisode(resultsTime1_);
            std::cout<<"Episode index is set to: "<<this->timeManager().episodeIndex()<<std::endl;
            std::cout<<"Next episode length is: "<<resultsTime1_<<std::endl;
            std::cout<<"Next epidode time is : "<<sim_time_+resultsTime1_<<std::endl;
        }else{
            this->timeManager().startNextEpisode(resultsTime3_);
            std::cout<<"Episode index is set to: "<<this->timeManager().episodeIndex()<<std::endl;
            std::cout<<"Next episode length is: "<<resultsTime3_<<std::endl;
            std::cout<<"Next epidode time is : "<<sim_time_+resultsTime3_<<std::endl;
        }
    }

    bool shouldWriteOutput() const
    {
        return
        this->timeManager().timeStepIndex() == 0 || this->timeManager().episodeWillBeFinished() ||
        this->timeManager().willBeFinished();
    }


    bool shouldWriteRestartFile() const
    {
        return
        this->timeManager().timeStepIndex() == 0 || this->timeManager().episodeIsFinished() ||
        this->timeManager().willBeFinished();
    }
    /*!
     * \brief Returns the temperature within the domain.
     *
     * \param globalPos The position
     *
     * This problem assumes a geothermal gradient with
     * a surface temperature of 10 degrees Celsius.
     */
    Scalar temperatureAtPos(const GlobalPosition &globalPos) const
    {
        return temperature_(globalPos);
    }

    /*!
     * \brief Returns the source term
     *
     * \param values Stores the source values for the conservation equations in
     *               \f$ [ \textnormal{unit of primary variable} / (m^\textrm{dim} \cdot s )] \f$
     * \param globalPos The global position
     */
	 
    void sourceAtPos (PrimaryVariables & values,
                           const GlobalPosition &globalPos) const
    {
        values = 0;
        Scalar sim_time_ = this->timeManager().time();
        if (((globalPos[1] < injecttop_ + eps_ && globalPos[1] > injectbot_ - eps_) &&  (globalPos[0] < injectright_ + eps_ && globalPos[0] > injectleft_ - eps_))
		&& (sim_time_ > timepulsedebut1_ && sim_time_ < timepulsefin1_))
		{ 
		values[contiCO2EqIdx] = injectionRate_;
		} 
        
    }


	
/*	
    void Source (PrimaryVariables &values,
                 const Element &element,
                 const FVElementGeometry &fvGeometry,
                 const Intersection &intersection,
                 int scvIdx,
                 int boundaryFaceIdx) const
    {
		GlobalPosition globalPos;
         if (isBox)
             globalPos = element.geometry().corner(scvIdx);
         else
             globalPos = intersection.geometry().center();
        values = 0;
        Scalar sim_time_ = this->timeManager().time();
        if (((globalPos[1] < injecttop_ + eps_ && globalPos[1] > injectbot_ - eps_) &&  (globalPos[0] < injectright_ + eps_ && globalPos[0] > injectleft_ - eps_))
		&& (sim_time_ > timepulsedebut1_ && sim_time_ < timepulsefin1_))
		{ 
		values[contiCO2EqIdx] = injectionRate_;
		} 
        
    }
*/	
    // \}

    /*!
     * \name Boundary conditions
     */
    // \{

    /*!
     * \brief Specifies which kind of boundary condition should be
     *        used for which equation on a given boundary segment.
     *
     * \param values The boundary types for the conservation equations
     * \param vertex The vertex for which the boundary type is set
     */
/*    void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const
    {
        intersectionToVertexBC_.boundaryTypes(values, vertex);
    }
*/
    /*!
     * \brief Specifies which kind of boundary condition should be
     *        used for which equation on a given boundary segment.
     *
     * \param values The boundary types for the conservation equations
     * \param intersection specifies the intersection at which boundary
     *           condition is to set
     */
	 
/*	 
    void boundaryTypes(BoundaryTypes &values, const Intersection &intersection) const
    {
#if DUNE_VERSION_NEWER(DUNE_ALUGRID, 2, 6)
        int boundaryId = intersection.impl().boundaryId();
#else
        int boundaryId = intersection.boundaryId();
#endif
        if (boundaryId < 1 || boundaryId > 4)
        {
            std::cout<<"invalid boundaryId: "<<boundaryId<<std::endl;
            DUNE_THROW(Dune::InvalidStateException, "Invalid " << boundaryId);
        }
        if (boundaryId == dirichletBoundary_)
            values.setAllDirichlet();
        else
            values.setAllNeumann();
    }
*/


   /*!
     * \brief Specifies which kind of boundary condition should be
     *        used for which equation on a given boundary segment
     *
     * \param values Stores the value of the boundary type
     * \param globalPos The global position
     */
    void boundaryTypesAtPos(BoundaryTypes &values,
                            const GlobalPosition &globalPos) const
    {
 /*       if (globalPos[1] < injecttop_ + eps_ && globalPos[1] > injectbot_ - eps_ && globalPos[0] < eps_) 
            values.setAllNeumann();
		*/
		if (globalPos[0] < eps_  || globalPos[0] > 1.5 - eps_)
            values.setAllDirichlet();
        else
            values.setAllNeumann();
		
	}	
		

    /*!
     * \brief Evaluates the boundary conditions for a Dirichlet
     *        boundary segment
     *
     * \param values Stores the Dirichlet values for the conservation equations in
     *               \f$ [ \textnormal{unit of primary variable} ] \f$
     * \param globalPos The global position
     */
    void dirichletAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const
    {
        initial_(values, globalPos);
    }

    /*!
     * \brief Evaluate the boundary conditions for a Neumann
     *        boundary segment.
     *
      * \param values Stores the Neumann values for the conservation equations in
     *               \f$ [ \textnormal{unit of conserved quantity} / (m^(dim-1) \cdot s )] \f$
     * \param element The finite element
     * \param fvGeometry The finite volume geometry of the element
     * \param intersection The intersection between element and boundary
     * \param scvIdx The local index of the sub-control volume
     * \param boundaryFaceIdx The index of the boundary face
     *
     * The \a values store the mass flux of each phase normal to the boundary.
     * Negative values indicate an inflow.
     *
     * Depending on whether useMoles is set on true or false, the flux has to be given either in
     * kg/(m^2*s) or mole/(m^2*s) in the input file!! Convertion with molar mass obtained from fluid system FluidSystem::molarMass(nCompIdx)
     */
    void neumann(PrimaryVariables &values,
                 const Element &element,
                 const FVElementGeometry &fvGeometry,
                 const Intersection &intersection,
                 int scvIdx,
                 int boundaryFaceIdx) const
    {
		values = 0; 
/*		GlobalPosition globalPos;
         if (isBox)
             globalPos = element.geometry().corner(scvIdx);
         else
             globalPos = intersection.geometry().center();
		
		Scalar sim_time_ = this->timeManager().time();
        if (globalPos[1] < injecttop_ + eps_ && globalPos[1] > injectbot_ - eps_ && globalPos[0] < eps_ && 
		((sim_time_ > timepulsedebut1_ && sim_time_ < timepulsefin1_) || (sim_time_ > timepulsedebut2_ && sim_time_ < timepulsefin2_)))		
		{
           values[contiCO2EqIdx] = -1*injectionRate_; // kg/(s*m)
//		   std::cout<<"Injection rate will be : "<<-1*injectionRate_<<std::endl;
        } */
	}
/*
	void neumannAtPos(PrimaryVariables &values,
                      const GlobalPosition &globalPos) const
    {
        values = 0;

		Scalar sim_time_ = this->timeManager().time();
        if (globalPos[1] < injecttop_ + eps_ && globalPos[1] > injectbot_ - eps_ && globalPos[0] < eps_ && 
		((sim_time_ > timepulsedebut1_ && sim_time_ < timepulsefin1_) || (sim_time_ > timepulsedebut2_ && sim_time_ < timepulsefin2_)))		
		{
           values[contiCO2EqIdx] = -1*injectionRate_; // kg/(s*m)
		   std::cout<<"Injection rate will be : "<<-1*injectionRate_<<std::endl;
        } 
		
    }
*/
    // \}

    /*!
     * \name Volume terms
     */
    // \{

    /*!
     * \brief Evaluates the initial values for a control volume
     *
     * \param values Stores the initial values for the conservation equations in
     *               \f$ [ \textnormal{unit of primary variables} ] \f$
     * \param globalPos The global position
     */
    void initialAtPos(PrimaryVariables &values,
                      const GlobalPosition &globalPos) const
    {
        initial_(values, globalPos);
    }

    /*!
     * \brief Return the initial phase state inside a control volume.
     *
     * \param globalPos The global position
     */
    int initialPhasePresenceAtPos(const GlobalPosition &globalPos) const
    { return Indices::wPhaseOnly; }

    // \}

private:
    /*!
     * \brief Evaluates the initial values for a control volume 
     *
     * The internal method for the initial condition
     *
     * \param values Stores the initial values for the conservation equations in
     *               \f$ [ \textnormal{unit of primary variables} ] \f$
     * \param globalPos The global position
     */
    void initial_(PrimaryVariables &values,
                  const GlobalPosition &globalPos) const
    {
        Scalar temp = temperature_(globalPos);
        Scalar densityW = FluidSystem::Brine::liquidDensity(temp, 1e5);

        Scalar pl =  1e5 +  densityW*this->gravity()[dimWorld-1]*(globalPos[dimWorld-1] - depthBOR_);
		if (globalPos[0] < eps_ )
            pl = pl + hzdp_;
		
        Scalar moleFracLiquidCO2 = 0.00;
        Scalar moleFracLiquidBrine = 1.0 - moleFracLiquidCO2;

        Scalar meanM =
            FluidSystem::molarMass(BrineIdx)*moleFracLiquidBrine +
            FluidSystem::molarMass(CO2Idx)*moleFracLiquidCO2;
        if(useMoles) // mole-fraction formulation
        {
            values[Indices::switchIdx] = moleFracLiquidCO2;
        }
        else // mass-fraction formulation
        {
            Scalar massFracLiquidCO2 = moleFracLiquidCO2*FluidSystem::molarMass(CO2Idx)/meanM;
            values[Indices::switchIdx] = massFracLiquidCO2;
        }
        values[Indices::pressureIdx] = pl;
    }

    Scalar temperature_(const GlobalPosition globalPos) const
    {
        Scalar T = celltemp_ ;//+ (depthBOR_ - globalPos[dimWorld-1])*0.03;
        return T;
    }

    Scalar depthBOR_;
    Scalar injectionRate_;
	Scalar timepulsefin1_;
	Scalar timepulsedebut1_;
	Scalar timepulsefin2_;
	Scalar timepulsedebut2_;
	Scalar injecttop_;
	Scalar injectbot_;
	Scalar injectright_;
	Scalar injectleft_;
	Scalar celltemp_;
	Scalar hzdp_; 
	Scalar resultsTime1_;
    Scalar resultsTime2_;
    Scalar resultsTime3_;

    int nTemperature_;
    int nPressure_;

    std::string name_ ;

    Scalar pressureLow_, pressureHigh_;
    Scalar temperatureLow_, temperatureHigh_;
/*
    int injectionTop_;
    int injectionBottom_;
    int dirichletBoundary_;
    int noFlowBoundary_;
*/	
	static constexpr Scalar eps_ = 1.5e-7;

//    const IntersectionToVertexBC<TypeTag> intersectionToVertexBC_;
};
} //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 Definition of the spatial parameters for the heterogeneous
 *        problem which uses the non-isothermal or isothermal CO2
 *        fully implicit model.
 */

#ifndef DUMUX_HETEROGENEOUS_SPATIAL_PARAMS_HH
#define DUMUX_HETEROGENEOUS_SPATIAL_PARAMS_HH

#include <dumux/material/spatialparams/implicit.hh>
#include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
#include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh>

#include <dumux/porousmediumflow/co2/implicit/model.hh>

#include <random>


namespace Dumux {

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

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

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

// Set the material Law
SET_PROP(HeterogeneousSpatialParams, MaterialLaw)
{
private:
    // define the material law which is parameterized by effective
    // saturations
    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
    typedef RegularizedBrooksCorey<Scalar> EffMaterialLaw;
public:
    // define the material law parameterized by absolute saturations
    typedef EffToAbsLaw<EffMaterialLaw> type;
};
}

/*!
 * \ingroup CO2Model
 * \ingroup ImplicitTestProblems
 * \brief Definition of the spatial parameters for the heterogeneous
 *        problem which uses the non-isothermal or isothermal CO2
 *        fully implicit model.
 */
template<class TypeTag>
class HeterogeneousSpatialParams : public ImplicitSpatialParams<TypeTag>
{
    typedef ImplicitSpatialParams<TypeTag> ParentType;
    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
    typedef typename GET_PROP_TYPE(TypeTag, GridCreator) GridCreator;
    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;

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

    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
    typedef typename GridView::template Codim<0>::Entity Element;

public:

    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
    typedef typename MaterialLaw::Params MaterialLawParams;
	
	
//  	using PermeabilityType = Scalar;
    HeterogeneousSpatialParams(std::shared_ptr<const FVElementGeometry> fvGeometry)
    : ParentType(fvGeometry), K_(fvGeometry->gridView().size(0), 0.0)

    /*!
     * \brief The constructor
     *
     * \param gridView The grid view
     */
	 
	
//    HeterogeneousSpatialParams(const GridView &gridView)
//        : ParentType(gridView), gridView_(gridView)
    {
//        /*
//         * Layer Index Setup:
//         */
//        barrierTop_ = 1;
//        barrierMiddle_ = 2;
//        reservoir_ = 3;

        // heat conductivity of granite
        lambdaSolid_ = 2.8;

        //Set the permeability for the layers
//        barrierTopK_ = 1e-17; //sqm
        coucheK_ = 2.5e-10; //sqm
        reservoirK_ = 5e-10; //sqm
		
		std::mt19937 rand(0);
        std::lognormal_distribution<Scalar> K(std::log(reservoirK_), std::log(reservoirK_)*0.1);
        std::lognormal_distribution<Scalar> KLens(std::log(coucheK_), std::log(coucheK_)*0.1);
        for (const auto& element : elements(fvGeometry->gridView()))
        {
            const auto eIdx = fvGeometry->elementMapper().index(element);
            const auto globalPos = element.geometry().center();
            K_[eIdx] = barrierMiddle_(globalPos) || barrierTop_(globalPos) ? KLens(rand) : K(rand);
        }
    


        //Set the effective porosity of the layers
//        barrierTopPorosity_ = 0.001;
        couchePorosity_ = 0.36;
        reservoirPorosity_ = 0.36;

        // Same material parameters for every layer
//        materialParams_.setSwr(0.2);
//        materialParams_.setSnr(0.05);
//        materialParams_.setLambda(2.0);
//        materialParams_.setPe(1e4);
	
// parameters for the Brooks-Corey law
        coucheParams_.setPe(849.55);
        reservoirParams_.setPe(531.7);
        coucheParams_.setLambda(5.57);
        reservoirParams_.setLambda(3.94);
		coucheParams_.setSwr(0.0);
		coucheParams_.setSnr(0.0);
		reservoirParams_.setSwr(0.0);
		reservoirParams_.setSnr(0.0);		
    }

    ~HeterogeneousSpatialParams()
    {}

    /*!
     * \brief Reads layer information from the grid
     *
     */
/*    void setParams()
    {
        int numElements = gridView_.size(0);
        paramIdx_.resize(numElements);

        for (const auto& element : elements(gridView_))
        {
            int eIdx = gridView_.indexSet().index(element);
            int param = GridCreator::parameters(element)[0];
            paramIdx_[eIdx] = param;
        }
    }
*/
    /*!
     * \brief Returns the scalar intrinsic permeability \f$[m^2]\f$
     *
     * \param element The finite element
     * \param fvGeometry The finite volume geometry of the element
     * \param scvIdx The local index of the sub-control volume
     */
 
    const Scalar intrinsicPermeability(const Element &element,
                                       const FVElementGeometry &fvGeometry,
                                       int scvIdx) const

    {
        const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
        if (barrierMiddle_(globalPos) || barrierTop_(globalPos)) //modif par kenza barrierMiddle_ et barrierTop_(globalPos) 
            return coucheK_;
        return reservoirK_;
    }
          Scalar porosity(const Element &element,
                    const FVElementGeometry &fvGeometry,
                    const int scvIdx) const
    {
        const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
        if (barrierMiddle_(globalPos) || barrierTop_(globalPos)) 
            return couchePorosity_;
        return reservoirPorosity_;
    }

 

/*    {
        //Get the global index of the element
        int eIdx = gridView_.indexSet().index(element);

//        if (paramIdx_[eIdx] == barrierTop_)
//            return barrierTopK_;
        else if (paramIdx_[eIdx] == barrierMiddle_)
            return barrierMiddleK_;
        else
            return reservoirK_;
    }
*/

    /*!
     * \brief Returns the porosity \f$[-]\f$
     *
     * \param element The finite element
     * \param fvGeometry The finite volume geometry of the element
     * \param scvIdx The local index of the sub-control volume
     */
 /*   Scalar porosity(const Element &element,
                    const FVElementGeometry &fvGeometry,
                    int scvIdx) const
    {
        //Get the global index of the element
        int eIdx = gridView_.indexSet().index(element);

//        if (paramIdx_[eIdx] == barrierTop_)
//            return barrierTopPorosity_;
        else if (paramIdx_[eIdx] == barrierMiddle_)
            return barrierMiddlePorosity_;
        else
            return reservoirPorosity_;
    }
*/

    /*!
     * \brief Returns the parameter object for the Brooks-Corey material law
     *
     * \param element The finite element
     * \param fvGeometry The finite volume geometry of the element
     * \param scvIdx The local index of the sub-control volume
     */
	 
	     const MaterialLawParams& materialLawParams(const Element &element,
                                               const FVElementGeometry &fvGeometry,
                                               const int scvIdx) const
    {
        const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
        if (barrierMiddle_(globalPos) || barrierTop_(globalPos)) 
            return coucheParams_;
        return reservoirParams_;
	}	
/*		
    const MaterialLawParams& materialLawParams(const Element &element,
                                                const FVElementGeometry &fvGeometry,
                                                int scvIdx) const
    {
        return materialParams_;
    }
*/
    /*!
     * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix.
     *
     * This is only required for non-isothermal models.
     *
     * \param element The finite element
     * \param fvGeometry The finite volume geometry
     * \param scvIdx The local index of the sub-control volume
     */
    Scalar solidHeatCapacity(const Element &element,
                             const FVElementGeometry &fvGeometry,
                             const int scvIdx) const
    {
        return 790; // specific heat capacity of granite [J / (kg K)]
    }

    /*!
     * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix.
     *
     * This is only required for non-isothermal models.
     *
     * \param element The finite element
     * \param fvGeometry The finite volume geometry
     * \param scvIdx The local index of the sub-control volume
     */
    Scalar solidDensity(const Element &element,
                        const FVElementGeometry &fvGeometry,
                        const int scvIdx) const
    {
        return 2700; // density of granite [kg/m^3]
    }

    /*!
     * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the solid
     *
     * This is only required for non-isothermal models.
     *
     * \param element The finite element
     * \param fvGeometry The finite volume geometry of the element
     * \param scvIdx The local index of the sub-control volume
     */
    Scalar solidThermalConductivity(const Element &element,
                                    const FVElementGeometry &fvGeometry,
                                    const int scvIdx) const
    {
        return lambdaSolid_;
    }

    const std::vector<Scalar>& getKField() const
    { return K_; }

private:
    //bool isFineMaterial_(const GlobalPosition &globalPos) const
    //{ return globalPos[dimWorld-1] > layerBottom_; }

    bool barrierTop_(const GlobalPosition &globalPos) const
    {
//            if (globalPos[1] < 9 + eps_ || globalPos[1] > 18 - eps_ || globalPos[0] < 40 + eps_)
            if (globalPos[1] < globalPos[0] * 0.02 + 1.35) // couche fine avec une epaisseure non uniforme

                return false;
        
        return true;
		}
		
    bool barrierMiddle_(const GlobalPosition &globalPos) const
   {
            if (globalPos[1] < 0.7 + eps_ || globalPos[1] > 0.78 - eps_ || globalPos[0] > 0.8 - eps_)
  //         if (globalPos[1] < globalPos[0] * 0.05 + 25) // couche fine avec une epaisseure non uniforme

              return false;
        
     return true;
		}

	


private:

//    int barrierTop_;
    int couche_;
    int reservoir_;


//    Scalar barrierTopPorosity_;
    Scalar couchePorosity_;
    Scalar reservoirPorosity_;

//    Scalar barrierTopK_;
    Scalar coucheK_;
    Scalar reservoirK_;
	
    Scalar lambdaSolid_;

    MaterialLawParams coucheParams_;
    MaterialLawParams reservoirParams_;

    std::vector<Scalar> K_;
    static constexpr Scalar eps_ = 1.5e-7;


    const GridView gridView_;
    std::vector<int> paramIdx_;
};

}

#endif
_______________________________________________
Dumux mailing list
[email protected]
https://listserv.uni-stuttgart.de/mailman/listinfo/dumux

Reply via email to