// -*- 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 The porous medium flow sub problem
*/
#ifndef DUMUX_DARCY_SUBPROBLEM_HH
#define DUMUX_DARCY_SUBPROBLEM_HH
#include
#include
namespace Dumux {
/*!
* \brief The porous medium flow sub problem
*/
template
class PorousMediumSubProblem : public PorousMediumFlowProblem
{
using ParentType = PorousMediumFlowProblem;
using GridView = typename GetPropType::GridView;
using Scalar = GetPropType;
using PrimaryVariables = GetPropType;
using NumEqVector = GetPropType;
using BoundaryTypes = GetPropType;
using VolumeVariables = GetPropType;
using FVElementGeometry = typename GetPropType::LocalView;
using SubControlVolume = typename FVElementGeometry::SubControlVolume;
using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
using FVGridGeometry = GetPropType;
using GridVariables = GetPropType;
using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
using Indices = typename GetPropType::Indices;
using Element = typename GridView::template Codim<0>::Entity;
using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
using CouplingManager = GetPropType;
public:
PorousMediumSubProblem(std::shared_ptr fvGridGeometry,
std::shared_ptr couplingManager)
: ParentType(fvGridGeometry, "Darcy"), eps_(1e-7), couplingManager_(couplingManager)
{}
/*!
* \name Simulation steering
*/
// \{
/*!
* \brief Return the temperature within the domain in [K].
*
*/
Scalar temperature() const
{ return 273.15 + 10; } // 10°C
// \}
/*!
* \name Boundary conditions
*/
// \{
/*!
* \brief Specifies which kind of boundary condition should be
* used for which equation on a given boundary control volume.
*
* \param element The element
* \param scvf The boundary sub control volume face
*/
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolumeFace &scvf) const
{
BoundaryTypes values;
// set Neumann BCs to all boundaries first
values.setAllNeumann();
// set the coupling boundary condition at the interface
if (couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf))
values.setAllCouplingNeumann();
// set a Dirichlet boundary condition at the bottom
if (onLowerBoundary_(scvf.center()))
values.setAllDirichlet();
return values;
}
/*!
* \brief Evaluate the boundary conditions for a Dirichlet control volume.
*
* \param element The element for which the Dirichlet boundary condition is set
* \param scvf The boundary subcontrolvolumeface
*
* For this method, the \a values parameter stores primary variables.
*/
PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const
{
// set p = 0 at the bottom
PrimaryVariables values(0.0);
values = initial(element);
return values;
}
/*!
* \brief Evaluate the boundary conditions for a Neumann control volume.
*
* \param element The element for which the Neumann boundary condition is set
* \param fvGeomentry The fvGeometry
* \param elemVolVars The element volume variables
* \param scvf The boundary sub control volume face
*
* For this method, the \a values variable stores primary variables.
*/
template
NumEqVector neumann(const Element& element,
const FVElementGeometry& fvGeometry,
const ElementVolumeVariables& elemVolVars,
const ElementFluxVariablesCache& elemFluxVarsCache,
const SubControlVolumeFace& scvf) const
{
// no-flow everywhere ...
NumEqVector values(0.0);
// ... except at the coupling interface
if (couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf))
values[Indices::conti0EqIdx] = couplingManager().couplingData().massCouplingCondition(element, fvGeometry, elemVolVars, scvf);
return values;
}
// \}
/*!
* \name Volume terms
*/
// \{
/*!
* \brief Evaluate the source term for all phases within a given
* sub-control-volume.
*
* \param element The element for which the source term is set
* \param fvGeomentry The fvGeometry
* \param elemVolVars The element volume variables
* \param scv The subcontrolvolume
*/
template
NumEqVector source(const Element &element,
const FVElementGeometry& fvGeometry,
const ElementVolumeVariables& elemVolVars,
const SubControlVolume &scv) const
{ return NumEqVector(0.0); }
// \}
/*!
* \brief Evaluate the initial value for a control volume.
*
* \param element The element
*
* For this method, the \a priVars parameter stores primary
* variables.
*/
PrimaryVariables initial(const Element &element) const
{
return PrimaryVariables(0.0);
}
// \}
//! Set the coupling manager
void setCouplingManager(std::shared_ptr cm)
{ couplingManager_ = cm; }
//! Get the coupling manager
const CouplingManager& couplingManager() const
{ return *couplingManager_; }
private:
bool onLeftBoundary_(const GlobalPosition &globalPos) const
{ return globalPos[0] < this->gridGeometry().bBoxMin()[0] + eps_; }
bool onRightBoundary_(const GlobalPosition &globalPos) const
{ return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; }
bool onLowerBoundary_(const GlobalPosition &globalPos) const
{ return globalPos[1] < this->gridGeometry().bBoxMin()[1] + eps_; }
bool onUpperBoundary_(const GlobalPosition &globalPos) const
{ return globalPos[1] > this->gridGeometry().bBoxMax()[1] - eps_; }
Scalar eps_;
std::shared_ptr couplingManager_;
};
} //end namespace Dumux
#endif