// -*- 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 . *
*****************************************************************************/
/*!
* \file
*
* \brief Tutorial problem for a fully coupled two phase-two component box model.
*/
#ifndef DUMUX_EXERCISE_FLUIDSYSTEM_B_PROBLEM_HH
#define DUMUX_EXERCISE_FLUIDSYSTEM_B_PROBLEM_HH
// The grid manager
#include
// The numerical model
#include
// The box discretization
#include
// The base porous media box problem
#include
// Spatially dependent parameters
#include "spatialparams.hh"
// The fluid system that is created in this exercise
#include "fluidsystems/h2omycompressiblecomponent.hh"
namespace Dumux{
// Forward declaration of the problem class
template class ExerciseFluidsystemProblemTwoPTwoC;
namespace Properties {
// Create a new type tag for the problem
// Create new type tags
namespace TTag {
struct ExerciseFluidsystemTwoPTwoC { using InheritsFrom = std::tuple; };
} // end namespace TTag
// Set the "Problem" property
template
struct Problem { using type = ExerciseFluidsystemProblemTwoPTwoC; };
// Set the spatial parameters
SET_TYPE_PROP(ExerciseFluidsystemTwoPTwoC, SpatialParams,
ExerciseFluidsystemSpatialParams,
GetPropType>);
// Set grid and the grid creator to be used
template
struct Grid { using type = Dune::YaspGrid<2>; };
// The fluid system property
template
struct FluidSystem
{
private:
using Scalar = GetPropType;
public:
using type = FluidSystems::H2OMyCompressibleComponent;
};
}
/*!
* \ingroup TwoPBoxModel
*
* \brief Tutorial problem for a fully coupled two phase-two component box model.
*/
template
class ExerciseFluidsystemProblemTwoPTwoC : public PorousMediumFlowProblem
{
using ParentType = PorousMediumFlowProblem;
using GridView = GetPropType;
using Scalar = GetPropType;
// Grid dimension
enum { dim = GridView::dimension,
dimWorld = GridView::dimensionworld
};
using Element = typename GridView::template Codim<0>::Entity;
using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
// Dumux specific types
using Indices = typename GetPropType::Indices;
using PrimaryVariables = GetPropType;
using BoundaryTypes = GetPropType;
using FVGridGeometry = GetPropType;
using FVElementGeometry = typename GetPropType::LocalView;
using FluidSystem = GetPropType;
public:
ExerciseFluidsystemProblemTwoPTwoC(std::shared_ptr fvGridGeometry)
: ParentType(fvGridGeometry)
, eps_(3e-6)
{
// initialize the fluid system
FluidSystem::init();
// set the depth of the bottom of the reservoir
depthBOR_ = this->fvGridGeometry().bBoxMax()[dimWorld-1];
}
/*!
* \name Problem parameters
*/
// \{
/*!
* \brief Returns the temperature \f$ K \f$
*/
Scalar temperature() const
{ return 283.15; }
/*!
* \name Boundary conditions
*/
// \{
/*!
* \brief Specifies which kind of boundary condition should be
* used for which equation on a given boundary segment.
*
* \param globalPos The position for which the bc type should be evaluated
*/
BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
{
BoundaryTypes bcTypes;
if (globalPos[0] < eps_ || globalPos[0] > this->fvGridGeometry().bBoxMax()[0] - eps_)
bcTypes.setAllDirichlet();
else
bcTypes.setAllNeumann();
return bcTypes;
}
/*!
* \brief Evaluates the boundary conditions for a Dirichlet
* boundary segment
*
* \param globalPos The global position
*/
PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
{
// use initial as Dirichlet conditions
return initialAtPos(globalPos);
}
/*!
* \brief Evaluate the boundary conditions for a neumann
* boundary segment.
*
* \param globalPos The position of the integration point of the boundary segment.
*/
PrimaryVariables neumannAtPos(const GlobalPosition &globalPos) const
{
// initialize values to zero, i.e. no-flow Neumann boundary conditions
PrimaryVariables values(0.0);
Scalar up = this->fvGridGeometry().bBoxMax()[dimWorld-1];
// extraction of oil (30 g/m/s) on a segment of the upper boundary
if (globalPos[dimWorld-1] > up - eps_ && globalPos[0] > 20 && globalPos[0] < 40)
{
// we solve for the mole balance, so we have to divide by the molar mass
values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0;
values[Indices::conti0EqIdx + FluidSystem::NAPLIdx] = -3e-2/FluidSystem::MyCompressibleComponent::molarMass();
}
else
{
// no-flow on the remaining Neumann-boundaries.
values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0;
values[Indices::conti0EqIdx + FluidSystem::NAPLIdx] = 0;
}
return values;
}
// \}
/*!
* \name Volume terms
*/
// \{
/*!
* \brief Evaluate the initial value for a control volume.
* \param globalPos The position for which the initial condition should be evaluated
*
* For this method, the \a values parameter stores primary
* variables.
*/
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
{
PrimaryVariables values(0.0);
// tell the primary variables the phase state, i.e. which phase/phases
// is/are present, because this changes the meaning of the primary variable
// value at the index Indices::switchIdx
values.setState(Indices::firstPhaseOnly);
// use hydrostatic pressure distribution with 2 bar at the top and zero saturation
values[Indices::pressureIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); // 200 kPa = 2 bar
values[Indices::switchIdx] = 0.0;
return values;
}
// \}
/*!
* \brief Returns the source term
* \param globalPos The global position
*/
PrimaryVariables sourceAtPos(const GlobalPosition &globalPos) const
{
// we do not define any sources
PrimaryVariables values(0.0);
return values;
}
private:
Scalar eps_; //! small epsilon value
Scalar depthBOR_; //! depth at the bottom of the reservoir
};
} // end namespace Dumux
#endif