// -*- 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 base porous media box problem #include #include namespace Dumux { /*! * \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 = typename GetPropType::GridView; 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 = Dumux::BoundaryTypes::numEq()>; using FVGridGeometry = GetPropType; using FVElementGeometry = typename GetPropType::LocalView; using FluidSystem = GetPropType; using NumEqVector = 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->gridGeometry().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->gridGeometry().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. */ NumEqVector neumannAtPos(const GlobalPosition &globalPos) const { // initialize values to zero, i.e. no-flow Neumann boundary conditions NumEqVector values(0.0); Scalar up = this->gridGeometry().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 */ NumEqVector sourceAtPos(const GlobalPosition &globalPos) const { // we do not define any sources NumEqVector values(0.0); return values; } private: Scalar eps_; //! small epsilon value Scalar depthBOR_; //! depth at the bottom of the reservoir }; } // end namespace Dumux #endif