diff --git a/dumux/boxmodels/1p/1pindices.hh b/dumux/boxmodels/1p/1pindices.hh index 237d2a79d7a1e0eccd80a586334b49dcbe760d81..1e77e5c0f69bb91f6ebc9c597f6c27c8ded97d1a 100644 --- a/dumux/boxmodels/1p/1pindices.hh +++ b/dumux/boxmodels/1p/1pindices.hh @@ -1,45 +1,3 @@ -// -*- 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 Defines the indices for the one-phase box model. - */ -#ifndef DUMUX_1P_INDICES_HH -#define DUMUX_1P_INDICES_HH +#warning This file is deprecated. Include dumux/implicit/1p/1pindices.hh instead. -namespace Dumux -{ -// \{ - -/*! - * \ingroup OnePBoxModel - * \ingroup BoxIndices - * \brief Indices for the one-phase model. - */ -struct OnePIndices -{ - static const int conti0EqIdx = 0; //index for the mass balance - static const int pressureIdx = 0; //index of the primary variable -}; - -// \} -} // end namepace - -#endif +#include <dumux/implicit/1p/1pindices.hh> diff --git a/dumux/boxmodels/1p/1plocalresidual.hh b/dumux/boxmodels/1p/1plocalresidual.hh index 0666c4459a1d978129b423ddefb08362046da5fe..3d67251f345c5ba204411e9d368e2f86daa3db8f 100644 --- a/dumux/boxmodels/1p/1plocalresidual.hh +++ b/dumux/boxmodels/1p/1plocalresidual.hh @@ -1,169 +1,3 @@ -// -*- 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 Element-wise calculation of the Jacobian matrix for problems - * using the one-phase box model. - */ -#ifndef DUMUX_1P_LOCAL_RESIDUAL_HH -#define DUMUX_1P_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/1p/1plocalresidual.hh instead. -#include <dumux/boxmodels/common/boxlocalresidual.hh> - -#include "1pvolumevariables.hh" -#include "1pproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup OnePBoxModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the one-phase box model. - */ -template<class TypeTag> -class OnePLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ - typedef OnePLocalResidual<TypeTag> ThisType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - enum { dim = GridView::dimension }; - typedef Dune::FieldVector<Scalar, dim> DimVector; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - //index of the mass balance equation - enum { - conti0EqIdx = Indices::conti0EqIdx //index for the mass balance - }; - //index of the primary variable - enum{ - pressureIdx = Indices::pressureIdx //index for the primary variable - }; - -public: - - /*! - * \brief Constructor. Sets the upwind weight. - */ - OnePLocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - upwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the rate of change of all conservation - * quantites (e.g. phase mass) within a sub-control - * volume of a finite volume element for the OneP - * model. - * - * This function should not include the source and sink terms. - * \param storage The phase mass within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, const bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - // partial time derivative of the wetting phase mass - storage[conti0EqIdx] = volVars.density() * volVars.porosity(); - } - - - /*! - * \brief Evaluate the mass flux over a face of a sub-control - * volume. - * - * \param flux The flux over the SCV (sub-control-volume) face - * \param faceIdx The index of the SCV face - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, const int faceIdx, const bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - - const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(/*phaseIdx=*/0)); - const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(/*phaseIdx=*/0)); - flux[conti0EqIdx] = - (( upwindWeight_)*up.density() - + - (1 - upwindWeight_)*dn.density()) - * - fluxVars.volumeFlux(/*phaseIdx=*/0); - } - - /*! - * \brief Calculate the source term of the equation. - * - * \param source The source/sink in the SCV - * \param scvIdx The index of the SCV - * - */ - void computeSource(PrimaryVariables &source, const int scvIdx) - { - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - - /*! - * \brief Return the temperature given the solution vector of a - * finite volume. - */ - template <class PrimaryVariables> - Scalar temperature(const PrimaryVariables &priVars) - { return this->problem_.temperature(); /* constant temperature */ } - -private: - ThisType &asImp_() - { return *static_cast<ThisType *>(this); } - - const ThisType &asImp_() const - { return *static_cast<const ThisType *>(this); } - - Scalar upwindWeight_; -}; - -} - -#endif +#include <dumux/implicit/1p/1plocalresidual.hh> diff --git a/dumux/boxmodels/1p/1pmodel.hh b/dumux/boxmodels/1p/1pmodel.hh index 40afc0384823a7d9f9d6f9d678f8e83df9fc301c..7789e1723a7f54cacd1adeb6b1254a6f3dc7e6b9 100644 --- a/dumux/boxmodels/1p/1pmodel.hh +++ b/dumux/boxmodels/1p/1pmodel.hh @@ -1,125 +1,3 @@ -// -*- 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 Base class for all models which use the one-phase, - * box model. - * Adaption of the BOX scheme to the one-phase flow model. - */ +#warning This file is deprecated. Include dumux/implicit/1p/1pmodel.hh instead. -#ifndef DUMUX_1P_MODEL_HH -#define DUMUX_1P_MODEL_HH - -#include <dumux/boxmodels/common/boxmodel.hh> - -#include "1plocalresidual.hh" - -namespace Dumux -{ -/*! - * \ingroup OnePBoxModel - * \brief A single-phase, isothermal flow model using the box scheme. - * - * Single-phase, isothermal flow model, which solves the mass - * continuity equation - * \f[ - \phi \frac{\partial \varrho}{\partial t} + \text{div} (- \varrho \frac{\textbf K}{\mu} ( \textbf{grad}\, p -\varrho {\textbf g})) = q, - * \f] - * discretized using a vertex-centered finite volume (box) scheme as - * spatial and the implicit Euler method as time discretization. The - * model supports compressible as well as incompressible fluids. - */ -template<class TypeTag > -class OnePBoxModel : public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - enum { dim = GridView::dimension }; - -public: - /*! - * \brief \copybrief Dumux::BoxModel::addOutputVtkFields - * - * Specialization for the OnePBoxModel, adding the pressure and - * the process rank to the VTK writer. - */ - template<class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - - // create the required scalar fields - unsigned numVertices = this->problem_().gridView().size(dim); - ScalarField *p = writer.allocateManagedBuffer(numVertices); - ScalarField *K = writer.allocateManagedBuffer(numVertices); - - unsigned numElements = this->gridView_().size(0); - ScalarField *rank = writer.allocateManagedBuffer(numElements); - - FVElementGeometry fvGeometry; - VolumeVariables volVars; - ElementBoundaryTypes elemBcTypes; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - int idx = this->problem_().model().elementMapper().map(*elemIt); - (*rank)[idx] = this->gridView_().comm().rank(); - - fvGeometry.update(this->gridView_(), *elemIt); - elemBcTypes.update(this->problem_(), *elemIt, fvGeometry); - - int numVerts = elemIt->template count<dim> (); - for (int i = 0; i < numVerts; ++i) - { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); - volVars.update(sol[globalIdx], - this->problem_(), - *elemIt, - fvGeometry, - i, - false); - const SpatialParams &spatialParams = this->problem_().spatialParams(); - - (*p)[globalIdx] = volVars.pressure(); - (*K)[globalIdx]= spatialParams.intrinsicPermeability(*elemIt, - fvGeometry, - i); - } - } - - writer.attachVertexData(*p, "p"); - writer.attachVertexData(*K, "K"); - writer.attachCellData(*rank, "process rank"); - } -}; -} - -#include "1ppropertydefaults.hh" - -#endif +#include <dumux/implicit/1p/1pmodel.hh> diff --git a/dumux/boxmodels/1p/1pproperties.hh b/dumux/boxmodels/1p/1pproperties.hh index 87112a4110d6a823f4d6887a939103d395f8672f..199501cedabe7058143c8f425247d8ee202e1104 100644 --- a/dumux/boxmodels/1p/1pproperties.hh +++ b/dumux/boxmodels/1p/1pproperties.hh @@ -1,65 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup OnePBoxModel - * \file - * - * \brief Defines the properties required for the one-phase BOX model. - */ -#ifndef DUMUX_1P_PROPERTIES_DATA_HH -#define DUMUX_1P_PROPERTIES_DATA_HH +#warning This file is deprecated. Include dumux/implicit/1p/1pproperties.hh instead. -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ -// \{ -/////////////////////////////////////////////////////////////////////////// -// properties for the isothermal single phase model -/////////////////////////////////////////////////////////////////////////// -namespace Properties { - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the isothermal single phase problems -NEW_TYPE_TAG(BoxOneP, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(Indices); //!< Enumerations for the model -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters object -NEW_PROP_TAG(FluidSystem); //!< The type of the fluid system to use -NEW_PROP_TAG(Fluid); //!< The fluid used for the default fluid system -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< Returns weight of the upwind cell when calculating fluxes -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation -NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient -// \} -} - -} // end namepace - -#endif +#include <dumux/implicit/1p/1pproperties.hh> diff --git a/dumux/boxmodels/1p/1ppropertydefaults.hh b/dumux/boxmodels/1p/1ppropertydefaults.hh index 27ef59c662aafc4cb4478282093415cc983cb97c..11d855fb5f8bdaf35e4e1ee1e352f4cd53daee6e 100644 --- a/dumux/boxmodels/1p/1ppropertydefaults.hh +++ b/dumux/boxmodels/1p/1ppropertydefaults.hh @@ -1,109 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup OnePBoxModel - * \file - * - * \brief Defines the properties required for the one-phase BOX model. - */ -#ifndef DUMUX_1P_PROPERTY_DEFAULTS_HH -#define DUMUX_1P_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/1p/1ppropertydefaults.hh instead. -#include <dumux/boxmodels/common/boxproperties.hh> - -#include "1pmodel.hh" -#include "1plocalresidual.hh" -#include "1pvolumevariables.hh" -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include "1pindices.hh" - -#include <dumux/material/fluidsystems/gasphase.hh> -#include <dumux/material/fluidsystems/liquidphase.hh> -#include <dumux/material/components/nullcomponent.hh> -#include <dumux/material/fluidsystems/1pfluidsystem.hh> -#include <dumux/material/spatialparams/boxspatialparams1p.hh> - -namespace Dumux -{ -// \{ - -/////////////////////////////////////////////////////////////////////////// -// default property values for the isothermal single phase model -/////////////////////////////////////////////////////////////////////////// -namespace Properties { -SET_INT_PROP(BoxOneP, NumEq, 1); //!< set the number of equations to 1 -SET_INT_PROP(BoxOneP, NumPhases, 1); //!< The number of phases in the 1p model is 1 - -//! The local residual function -SET_TYPE_PROP(BoxOneP, - LocalResidual, - OnePLocalResidual<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxOneP, Model, OnePBoxModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxOneP, VolumeVariables, OnePVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxOneP, FluxVariables, BoxDarcyFluxVariables<TypeTag>); - -//! The indices required by the isothermal single-phase model -SET_TYPE_PROP(BoxOneP, Indices, OnePIndices); - -//! The spatial parameters to be employed. -//! Use BoxSpatialParamsOneP by default. -SET_TYPE_PROP(BoxOneP, SpatialParams, BoxSpatialParamsOneP<TypeTag>); - -//! The weight of the upwind control volume when calculating -//! fluxes. Use central differences by default. -SET_SCALAR_PROP(BoxOneP, ImplicitMassUpwindWeight, 0.5); - -//! weight for the upwind mobility in the velocity calculation -//! fluxes. Use central differences by default. -SET_SCALAR_PROP(BoxOneP, ImplicitMobilityUpwindWeight, 0.5); - -//! The fluid system to use by default -SET_TYPE_PROP(BoxOneP, FluidSystem, Dumux::FluidSystems::OneP<typename GET_PROP_TYPE(TypeTag, Scalar), typename GET_PROP_TYPE(TypeTag, Fluid)>); - -SET_PROP(BoxOneP, Fluid) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -// enable gravity by default -SET_BOOL_PROP(BoxOneP, ProblemEnableGravity, true); - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55); - -// \} -} // end namepace Properties - -} // end namepace Dumux - -#endif +#include <dumux/implicit/1p/1ppropertydefaults.hh> diff --git a/dumux/boxmodels/1p/1pvolumevariables.hh b/dumux/boxmodels/1p/1pvolumevariables.hh index b262b85b77815dfd744427625070b9b8af7b5a1f..72921b9f851ecfafcafba53d295f981bc587b948 100644 --- a/dumux/boxmodels/1p/1pvolumevariables.hh +++ b/dumux/boxmodels/1p/1pvolumevariables.hh @@ -1,203 +1,3 @@ -// -*- 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 Quantities required by the one-phase box model defined on a vertex. - */ -#ifndef DUMUX_1P_VOLUME_VARIABLES_HH -#define DUMUX_1P_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/1p/1pvolumevariables.hh instead. -#include "1pproperties.hh" -#include <dumux/boxmodels/common/boxvolumevariables.hh> - -#include <dumux/material/fluidstates/immisciblefluidstate.hh> - -namespace Dumux -{ - -/*! - * \ingroup OnePBoxModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are constant within a - * finite volume in the one-phase model. - */ -template <class TypeTag> -class OnePVolumeVariables : public BoxVolumeVariables<TypeTag> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - -public: - //! Type of the fluid state - typedef Dumux::ImmiscibleFluidState<Scalar, FluidSystem> FluidState; - - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { - ParentType::update(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - - completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_); - // porosity - porosity_ = problem.spatialParams().porosity(element, - fvGeometry, - scvIdx); - - // energy related quantities not contained in the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - }; - - /*! - * \copydoc BoxModel::completeFluidState - */ - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const int scvIdx, - FluidState& fluidState) - { - Scalar t = Implementation::temperature_(priVars, problem, element, - fvGeometry, scvIdx); - fluidState.setTemperature(t); - - fluidState.setPressure(/*phaseIdx=*/0, priVars[Indices::pressureIdx]); - - // saturation in a single phase is always 1 and thus redundant - // to set. But since we use the fluid state shared by the - // immiscible multi-phase models, so we have to set it here... - fluidState.setSaturation(/*phaseIdx=*/0, 1.0); - - typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState, /*phaseIdx=*/0); - - Scalar value = FluidSystem::density(fluidState, paramCache, /*phaseIdx=*/0); - fluidState.setDensity(/*phaseIdx=*/0, value); - - value = FluidSystem::viscosity(fluidState, paramCache, /*phaseIdx=*/0); - fluidState.setViscosity(/*phaseIdx=*/0, value); - } - - /*! - * \brief Return temperature \f$\mathrm{[K]}\f$ inside the sub-control volume. - * - * Note that we assume thermodynamic equilibrium, i.e. the - * temperatures of the rock matrix and of all fluid phases are - * identical. - */ - Scalar temperature() const - { return fluidState_.temperature(); } - - /*! - * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within - * the control volume. - */ - Scalar pressure() const - { return fluidState_.pressure(/*phaseIdx=*/0); } - - /*! - * \brief Return the mass density \f$\mathrm{[kg/m^3]}\f$ of a given phase within the - * control volume. - */ - Scalar density() const - { return fluidState_.density(/*phaseIdx=*/0); } - - /*! - * \brief Return the dynamic viscosity \f$\mathrm{[Pa s]}\f$ of the fluid within the - * control volume. - */ - Scalar viscosity() const - { return fluidState_.viscosity(/*phaseIdx=*/0); } - - /*! - * \brief Returns the mobility. - * - * This function enables the use of BoxDarcyFluxVariables - * with the 1p box model, ALTHOUGH the term mobility is - * usually not employed in the one phase context. - * - * \param phaseIdx The phase index - */ - Scalar mobility(int phaseIdx = 0) const - { return 1.0/fluidState_.viscosity(phaseIdx); } - - /*! - * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume. - */ - Scalar porosity() const - { return porosity_; } - - /*! - * \brief Return the fluid state of the control volume. - */ - const FluidState &fluidState() const - { return fluidState_; } - -protected: - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - /*! - * \brief Called by update() to compute the energy related quantities. - */ - void updateEnergy_(const PrimaryVariables &sol, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { } - - FluidState fluidState_; - Scalar porosity_; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; - -} - -#endif +#include <dumux/implicit/1p/1pvolumevariables.hh> diff --git a/dumux/boxmodels/1p2c/1p2cfluxvariables.hh b/dumux/boxmodels/1p2c/1p2cfluxvariables.hh index 81a09a609889ad456799bb5b921f587de3daeb1f..f2bc12ec3166139b94d6c23449368c5451307fc8 100644 --- a/dumux/boxmodels/1p2c/1p2cfluxvariables.hh +++ b/dumux/boxmodels/1p2c/1p2cfluxvariables.hh @@ -1,494 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes of fluid phases over a face of a finite volume. - * - * This means pressure and mole-fraction gradients, phase densities at - * the integration point, etc. - * - */ -#ifndef DUMUX_1P2C_FLUX_VARIABLES_HH -#define DUMUX_1P2C_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2cfluxvariables.hh instead. -#include "1p2cproperties.hh" - -#include <dumux/common/math.hh> -#include <dumux/common/valgrind.hh> - -namespace Dumux -{ - -/*! - * \ingroup OnePTwoCBoxModel - * \ingroup BoxFluxVariables - * \brief This template class contains the data which is required to - * calculate the fluxes of the fluid phases over a face of a - * finite volume for the one-phase, two-component model. - * - * This means pressure and mole-fraction gradients, phase densities at - * the intergration point, etc. - */ -template <class TypeTag> -class OnePTwoCFluxVariables -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - transportCompIdx = Indices::transportCompIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GridView::ctype CoordScalar; - typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dim> DimVector; - typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvfIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - OnePTwoCFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : fvGeometry_(fvGeometry), faceIdx_(faceIdx), onBoundary_(onBoundary) - { - viscosity_ = Scalar(0); - molarDensity_ = Scalar(0); - density_ = Scalar(0); - potentialGrad_ = Scalar(0); - moleFractionGrad_ = Scalar(0); - - calculateGradients_(problem, element, elemVolVars); - calculateK_(problem, element, elemVolVars); - calculateVelocities_(problem, element, elemVolVars); - calculatePorousDiffCoeff_(problem, element, elemVolVars); - calculateDispersionTensor_(problem, element, elemVolVars); - }; - -public: - /*! - * \brief Return the pressure potential multiplied with the - * intrinsic permeability and the face normal which - * goes from vertex i to vertex j. - * - * Note that the length of the face's normal is the area of the - * phase, so this is not the actual velocity but the integral of - * the velocity over the face's area. Also note that the phase - * mobility is not yet included here since this would require a - * decision on the upwinding approach (which is done in the - * actual model). - */ - Scalar KmvpNormal() const - { return KmvpNormal_; } - - /*! - * \brief Return the pressure potential multiplied with the - * intrinsic permeability as vector (for velocity output). - */ - DimVector Kmvp() const - { return Kmvp_; } - - /*! - * \brief The face of the current sub-control volume. This may be either - * an inner sub-control-volume face or a SCV face on the boundary. - */ - const SCVFace &face() const - { - if (onBoundary_) - return fvGeometry_.boundaryFace[faceIdx_]; - else - return fvGeometry_.subContVolFace[faceIdx_]; - } - - /*! - * \brief Return the intrinsic permeability tensor \f$\mathrm{[m^2]}\f$. - */ - const DimMatrix &intrinsicPermeability() const - { return K_; } - - /*! - * \brief Return the dispersion tensor \f$\mathrm{[m^2/s]}\f$. - */ - const DimMatrix &dispersionTensor() const - { return dispersionTensor_; } - - /*! - * \brief Return the pressure potential gradient \f$\mathrm{[Pa/m]}\f$. - */ - const DimVector &potentialGrad() const - { return potentialGrad_; } - - - /*! - * \brief Return the mole-fraction gradient of a component in a phase \f$\mathrm{[mol/mol/m)]}\f$. - * - * \param compIdx The index of the considered component - */ - const DimVector &moleFractionGrad(int compIdx) const - { - if (compIdx != 1) - { DUNE_THROW(Dune::InvalidStateException, - "The 1p2c model is supposed to need " - "only the concentration gradient of " - "the second component!"); } - return moleFractionGrad_; - }; - - /*! - * \brief The binary diffusion coefficient for each fluid phase in the porous medium \f$\mathrm{[m^2/s]}\f$. - */ - Scalar porousDiffCoeff() const - { - // TODO: tensorial porousDiffCoeff_usion coefficients - return porousDiffCoeff_; - }; - - /*! - * \brief Return viscosity \f$\mathrm{[Pa s]}\f$ of a phase at the integration - * point. - */ - Scalar viscosity() const - { return viscosity_;} - - /*! - * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase at the integration - * point. - */ - Scalar molarDensity() const - { return molarDensity_; } - - /*! - * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase at the integration - * point. - */ - Scalar density() const - { return density_; } - - /*! - * \brief Given the intrinsic permeability times the pressure - * potential gradient and SCV face normal for a phase, - * return the local index of the upstream control volume - * for a given phase. - * - * \param normalFlux The flux over a face of the sub-control volume - */ - int upstreamIdx(Scalar normalFlux) const - { return (normalFlux >= 0)?face().i:face().j; } - - /*! - * \brief Given the intrinsic permeability times the pressure - * potential gradient and SCV face normal for a phase, - * return the local index of the downstream control volume - * for a given phase. - * - * \param normalFlux The flux over a face of the sub-control volume - */ - int downstreamIdx(Scalar normalFlux) const - { return (normalFlux > 0)?face().j:face().i; } - - /*! - * \brief Return the local index of the upstream control volume - * for a given phase. - */ - int upstreamIdx() const - { return upstreamIdx_; } - - /*! - * \brief Return the local index of the downstream control volume - * for a given phase. - */ - int downstreamIdx() const - { return downstreamIdx_; } - -protected: - - /*! - * \brief Calculation of the pressure and mole-/mass-fraction gradients. - * - * \param problem The considered problem file - * \param element The considered element of the grid - * \param elemVolVars The parameters stored in the considered element - */ - void calculateGradients_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - const VolumeVariables &volVarsI = elemVolVars[face().i]; - const VolumeVariables &volVarsJ = elemVolVars[face().j]; - - DimVector tmp; - //The decision of the if-statement depends on the function useTwoPointGradient(const Element &element, - //int vertexI,int vertexJ) defined in test/tissue_tumor_spatialparameters.hh - if (!problem.spatialParams().useTwoPointGradient(element, face().i, face().j)) { - // use finite-element gradients - tmp = 0.0; - for (int idx = 0; - idx < fvGeometry_.numFAP; - idx++) // loop over adjacent vertices - { - // FE gradient at vertex idx - const DimVector &feGrad = face().grad[idx]; - - // index for the element volume variables - int volVarsIdx = face().fapIndices[idx]; - - // the pressure gradient - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].pressure(); - potentialGrad_ += tmp; - - // the mole-fraction gradient - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].moleFraction(transportCompIdx); - moleFractionGrad_ += tmp; - - // phase viscosity - viscosity_ += elemVolVars[volVarsIdx].viscosity()*face().shapeValue[idx]; - - //phase molar density - molarDensity_ += elemVolVars[volVarsIdx].molarDensity()*face().shapeValue[idx]; - - //phase density - density_ += elemVolVars[volVarsIdx].density()*face().shapeValue[idx]; - } - } - else { - // use two-point gradients - const GlobalPosition &globalPosI = element.geometry().corner(face().i); - const GlobalPosition &globalPosJ = element.geometry().corner(face().j); - tmp = globalPosI; - tmp -= globalPosJ; - Scalar dist = tmp.two_norm(); - - tmp = face().normal; - tmp /= face().normal.two_norm()*dist; - - potentialGrad_ = tmp; - potentialGrad_ *= volVarsJ.pressure() - volVarsI.pressure(); - moleFractionGrad_ = tmp; - moleFractionGrad_ *= volVarsJ.moleFraction(transportCompIdx) - volVarsI.moleFraction(transportCompIdx); - } - - /////////////// - // correct the pressure gradients by the gravitational acceleration - /////////////// - if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, EnableGravity)) { - // calculate the phase density at the integration point. we - // only do this if the wetting phase is present in both cells - Scalar rhoI = elemVolVars[face().i].density(); - Scalar rhoJ = elemVolVars[face().j].density(); - Scalar density = (rhoI + rhoJ)/2; - - // estimate the gravitational acceleration at a given SCV face - // using the arithmetic mean - DimVector f(problem.boxGravity(element, fvGeometry_, face().i)); - f += problem.boxGravity(element, fvGeometry_, face().j); - f /= 2; - - // make it a force - f *= density; - - // calculate the final potential gradient - potentialGrad_ -= f; - } - } - - /*! - * \brief Calculation of the harmonic mean of the intrinsic permeability - * uses the meanK function in the boxspatialparameters.hh file in the folder - * material/spatialparameters - * - * \param problem The considered problem file - * \param element The considered element of the grid - * \param elemVolVars The parameters stored in the considered element - */ - void calculateK_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - const SpatialParams &sp = problem.spatialParams(); - sp.meanK(K_, - sp.intrinsicPermeability(element, - fvGeometry_, - face().i), - sp.intrinsicPermeability(element, - fvGeometry_, - face().j)); - - } - - /*! - * \brief Calculation of the velocity normal to face using Darcy's law. - * Tensorial permeability is multiplied with the potential gradient and the face normal. - * Identify upstream node of face. - * - * \param problem The considered problem file - * \param element The considered element of the grid - * \param elemVolVars The parameters stored in the considered element - */ - void calculateVelocities_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - K_.mv(potentialGrad_, Kmvp_); - KmvpNormal_ = -(Kmvp_*face().normal); - - // set the upstream and downstream vertices - upstreamIdx_ = face().i; - downstreamIdx_ = face().j; - - if (KmvpNormal_ < 0) - { - std::swap(upstreamIdx_, - downstreamIdx_); - } - } - /*! - * \brief Calculation of the effective diffusion coefficient. - * - * \param problem The considered problem file - * \param element The considered element of the grid - * \param elemVolVars The parameters stored in the considered element - */ - void calculatePorousDiffCoeff_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - const VolumeVariables &volVarsI = elemVolVars[face().i]; - const VolumeVariables &volVarsJ = elemVolVars[face().j]; - - // Diffusion coefficient in the porous medium - porousDiffCoeff_ - = harmonicMean(volVarsI.porosity() * volVarsI.tortuosity() * volVarsI.diffCoeff(), - volVarsJ.porosity() * volVarsJ.tortuosity() * volVarsJ.diffCoeff()); -// = 1./2*(volVarsI.porosity() * volVarsI.tortuosity() * volVarsI.diffCoeff() + -// volVarsJ.porosity() * volVarsJ.tortuosity() * volVarsJ.diffCoeff()); - } - - /*! - * \brief Calculation of the dispersion. - * - * \param problem The considered problem file - * \param element The considered element of the grid - * \param elemVolVars The parameters stored in the considered element - */ - void calculateDispersionTensor_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - const VolumeVariables &volVarsI = elemVolVars[face().i]; - const VolumeVariables &volVarsJ = elemVolVars[face().j]; - - //calculate dispersivity at the interface: [0]: alphaL = longitudinal disp. [m], [1] alphaT = transverse disp. [m] - Scalar dispersivity[2]; - dispersivity[0] = 0.5 * (volVarsI.dispersivity()[0] + volVarsJ.dispersivity()[0]); - dispersivity[1] = 0.5 * (volVarsI.dispersivity()[1] + volVarsJ.dispersivity()[1]); - - //calculate velocity at interface: v = -1/mu * vDarcy = -1/mu * K * grad(p) - DimVector velocity; - Valgrind::CheckDefined(potentialGrad()); - Valgrind::CheckDefined(K_); - K_.mv(potentialGrad(), velocity); - velocity /= - 0.5 * (volVarsI.viscosity() + volVarsJ.viscosity()); - - //matrix multiplication of the velocity at the interface: vv^T - dispersionTensor_ = 0; - for (int i=0; i<dim; i++) - for (int j = 0; j<dim; j++) - dispersionTensor_[i][j]=velocity[i]*velocity[j]; - - //normalize velocity product --> vv^T/||v||, [m/s] - Scalar vNorm = velocity.two_norm(); - - dispersionTensor_ /= vNorm; - if (vNorm < 1e-20) - dispersionTensor_ = 0; - - //multiply with dispersivity difference: vv^T/||v||*(alphaL - alphaT), [m^2/s] --> alphaL = longitudinal disp., alphaT = transverse disp. - dispersionTensor_ *= (dispersivity[0] - dispersivity[1]); - - //add ||v||*alphaT to the main diagonal:vv^T/||v||*(alphaL - alphaT) + ||v||*alphaT, [m^2/s] - for (int i = 0; i<dim; i++) - dispersionTensor_[i][i] += vNorm*dispersivity[1]; - } - - const FVElementGeometry &fvGeometry_; - const int faceIdx_; - const bool onBoundary_; - - //! pressure potential gradient - DimVector potentialGrad_; - //! mole-fraction gradient - DimVector moleFractionGrad_; - //! the effective diffusion coefficent in the porous medium - Scalar porousDiffCoeff_; - - //! the dispersion tensor in the porous medium - DimMatrix dispersionTensor_; - - //! the intrinsic permeability tensor - DimMatrix K_; - // intrinsic permeability times pressure potential gradient - DimVector Kmvp_; - // projected on the face normal - Scalar KmvpNormal_; - - // local index of the upwind vertex for each phase - int upstreamIdx_; - // local index of the downwind vertex for each phase - int downstreamIdx_; - - //! viscosity of the fluid at the integration point - Scalar viscosity_; - - //! molar densities of the fluid at the integration point - Scalar molarDensity_, density_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/1p2c/1p2cfluxvariables.hh> diff --git a/dumux/boxmodels/1p2c/1p2cindices.hh b/dumux/boxmodels/1p2c/1p2cindices.hh index 90a3d14f79a2f5466dfa2f22d193706a10c36a4a..d380cea9ff9c9470876cb0d544993fe621aec0e8 100644 --- a/dumux/boxmodels/1p2c/1p2cindices.hh +++ b/dumux/boxmodels/1p2c/1p2cindices.hh @@ -1,63 +1,3 @@ -// -*- 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 Defines the primary variable and equation indices used by - * the 1p2c model - */ +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2cindices.hh instead. -#ifndef DUMUX_1P2C_INDICES_HH -#define DUMUX_1P2C_INDICES_HH - -#include "1p2cproperties.hh" - -namespace Dumux -{ -// \{ - -/*! - * \ingroup OnePTwoCBoxModel - * \ingroup BoxIndices - * \brief The indices for the isothermal single-phase, two-component model. - */ -template <class TypeTag, int PVOffset = 0> -struct OnePTwoCIndices -{ - - //! Set the default phase used by the fluid system to the first one - static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx); - - //! Component indices - static const int phaseCompIdx = phaseIdx;//!< The index of the main component of the considered phase - static const int transportCompIdx = (unsigned int)(1-phaseIdx); //!< The index of the transported (minor) component; ASSUMES phase indices of 0 and 1 - - // Equation indices - static const int conti0EqIdx = PVOffset + 0; //!< continuity equation index - static const int transportEqIdx = PVOffset + 1; //!< transport equation index - - // primary variable indices - static const int pressureIdx = PVOffset + 0; //!< pressure - static const int massOrMoleFracIdx = PVOffset + 1; //!< mole fraction of the second component -}; - -// \} -} - -#endif +#include <dumux/implicit/1p2c/1p2cindices.hh> diff --git a/dumux/boxmodels/1p2c/1p2clocalresidual.hh b/dumux/boxmodels/1p2c/1p2clocalresidual.hh index 6d34e380d7c6c7c0a9959992a53fd6810ac9954b..4976a836bc15215de20b5a4d08c22e82465cdfb8 100644 --- a/dumux/boxmodels/1p2c/1p2clocalresidual.hh +++ b/dumux/boxmodels/1p2c/1p2clocalresidual.hh @@ -1,297 +1,3 @@ -// -*- 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 Element-wise calculation the local Jacobian for the single-phase, - * two-component model in the BOX scheme. - */ +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2clocalresidual.hh instead. -#ifndef DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH -#define DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH -#define VELOCITY_OUTPUT 1 //1 turns velocity output on, 0 turns it off - -#include <dumux/boxmodels/common/boxmodel.hh> - -#include <dumux/boxmodels/1p2c/1p2cproperties.hh> -#include <dumux/boxmodels/1p2c/1p2cvolumevariables.hh> -#include <dumux/boxmodels/1p2c/1p2cfluxvariables.hh> - -#include <dune/common/collectivecommunication.hh> -#include <vector> -#include <iostream> - -namespace Dumux -{ -/*! - * - * \ingroup OnePTwoCBoxModel - * \ingroup BoxLocalResidual - * \brief Calculate the local Jacobian for the single-phase, - * two-component model in the BOX scheme. - * - * This class is used to fill the gaps in BoxLocalResidual for the 1p2c flow and transport. - */ -template<class TypeTag> -class OnePTwoCLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ -protected: - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::IntersectionIterator IntersectionIterator; - - enum { dim = GridView::dimension }; - typedef Dune::FieldVector<Scalar, dim> DimVector; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { - numEq = GET_PROP_VALUE(TypeTag, NumEq), - - //phase index - phaseIdx = Indices::phaseIdx, - transportCompIdx = Indices::transportCompIdx - }; - // indices of the primary variables - enum { - pressuerIdx = Indices::pressureIdx, - massOrMoleFracIdx = Indices::massOrMoleFracIdx - }; - // indices of the equations - enum { - conti0EqIdx = Indices::conti0EqIdx, - transportEqIdx = Indices::transportEqIdx - }; - - //! property that defines whether mole or mass fractions are used - static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); - - - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - OnePTwoCLocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - upwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the amount of all conservation quantities - * (e.g. phase mass) within a finite volume. - * - * \param storage The mass of the component within the sub-control volume - * \param scvIdx The index of the considered face of the sub-control volume - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, const bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - storage = 0; - if(!useMoles) - { - // storage term of continuity equation - massfractions - storage[conti0EqIdx] += - volVars.fluidState().density(phaseIdx)*volVars.porosity(); - //storage term of the transport equation - massfractions - storage[transportEqIdx] += - volVars.fluidState().density(phaseIdx) * volVars.fluidState().massFraction(phaseIdx, transportCompIdx) * volVars.porosity(); - } - else - { - // storage term of continuity equation- molefractions - //careful: molarDensity changes with moleFrac! - storage[conti0EqIdx] += volVars.molarDensity()*volVars.porosity(); - // storage term of the transport equation - molefractions - storage[transportEqIdx] += - volVars.fluidState().molarDensity(phaseIdx)*volVars.fluidState().moleFraction(phaseIdx, transportCompIdx) * - volVars.porosity(); - } - - } - - /*! - * \brief Evaluate the mass flux over a face of a sub-control - * volume. - * - * \param flux The flux over the SCV (sub-control-volume) face for each component - * \param faceIdx The index of the considered face of the sub control volume - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, const int faceIdx, const bool onBoundary=false) const - { - flux = 0; - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - - asImp_()->computeAdvectiveFlux(flux, fluxVars); - asImp_()->computeDiffusiveFlux(flux, fluxVars); - } - - /*! - * \brief Evaluate the advective mass flux of all components over - * a face of a sub-control volume. - * - * \param flux The advective flux over the sub-control-volume face for each component - * \param fluxVars The flux variables at the current SCV - */ - void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - //////// - // advective fluxes of all components in all phases - //////// - - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &up = - this->curVolVars_(fluxVars.upstreamIdx()); - const VolumeVariables &dn = - this->curVolVars_(fluxVars.downstreamIdx()); - - if(!useMoles) - { - // total mass flux - massfraction - //KmvpNormal is the Darcy velocity multiplied with the normal vector, calculated in 1p2cfluxvariables.hh - flux[conti0EqIdx] += - fluxVars.KmvpNormal() * - (( upwindWeight_)*up.density()/up.viscosity() - + - ((1 - upwindWeight_)*dn.density()/dn.viscosity())); - - // advective flux of the second component - massfraction - flux[transportEqIdx] += - fluxVars.KmvpNormal() * - (( upwindWeight_)*up.fluidState().density(phaseIdx) * up.fluidState().massFraction(phaseIdx, transportCompIdx)/up.viscosity() - + - (1 - upwindWeight_)*dn.fluidState().density(phaseIdx)*dn.fluidState().massFraction(phaseIdx, transportCompIdx)/dn.viscosity()); - } - else - { - // total mass flux - molefraction - //KmvpNormal is the Darcy velocity multiplied with the normal vector, calculated in 1p2cfluxvariables.hh - flux[conti0EqIdx] += - fluxVars.KmvpNormal() * - (( upwindWeight_)*up.molarDensity()/up.viscosity() - + - ((1 - upwindWeight_)*dn.molarDensity()/dn.viscosity())); - - // advective flux of the second component -molefraction - flux[transportEqIdx] += - fluxVars.KmvpNormal() * - (( upwindWeight_)*up.molarDensity() * up.fluidState().moleFraction(phaseIdx, transportCompIdx)/up.viscosity() - + - (1 - upwindWeight_)*dn.molarDensity() * dn.fluidState().moleFraction(phaseIdx, transportCompIdx)/dn.viscosity()); - } - - } - - /*! - * \brief Adds the diffusive mass flux of all components over - * a face of a sub-control volume. - * - * \param flux The diffusive flux over the sub-control-volume face for each component - * \param fluxVars The flux variables at the current SCV - */ - void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - Scalar tmp(0); - - // diffusive flux of second component - if(!useMoles) - { - // diffusive flux of the second component - massfraction - tmp = -(fluxVars.moleFractionGrad(transportCompIdx)*fluxVars.face().normal); - tmp *= fluxVars.porousDiffCoeff() * fluxVars.molarDensity(); - - // dispersive flux of second component - massfraction - DimVector normalDisp; - fluxVars.dispersionTensor().mv(fluxVars.face().normal, normalDisp); - tmp -= fluxVars.molarDensity()* - (normalDisp * fluxVars.moleFractionGrad(transportCompIdx)); - - // convert it to a mass flux and add it - flux[transportEqIdx] += tmp * FluidSystem::molarMass(transportCompIdx); - } - else - { - // diffusive flux of the second component - molefraction - tmp = -(fluxVars.moleFractionGrad(transportCompIdx)*fluxVars.face().normal); - tmp *= fluxVars.porousDiffCoeff() * fluxVars.molarDensity(); - - // dispersive flux of second component - molefraction - DimVector normalDisp; - fluxVars.dispersionTensor().mv(fluxVars.face().normal, normalDisp); - tmp -= fluxVars.molarDensity()* - (normalDisp * fluxVars.moleFractionGrad(transportCompIdx)); - - flux[transportEqIdx] += tmp; - } - } - - /*! - * \brief Calculate the source term of the equation - * \param source The source/sink in the SCV for each component - * \param scvIdx The index of the vertex of the sub control volume - * - */ - void computeSource(PrimaryVariables &source, const int scvIdx) - { - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - - Implementation *asImp_() - { return static_cast<Implementation *> (this); } - const Implementation *asImp_() const - { return static_cast<const Implementation *> (this); } - -private: - Scalar upwindWeight_; -}; - -} - -#endif +#include <dumux/implicit/1p2c/1p2clocalresidual.hh> diff --git a/dumux/boxmodels/1p2c/1p2cmodel.hh b/dumux/boxmodels/1p2c/1p2cmodel.hh index 3b70302f8581ff7ad664753fdd8c5b17f78c403e..f11ef929fb12013908a76a06fb629c23cccbe68f 100644 --- a/dumux/boxmodels/1p2c/1p2cmodel.hh +++ b/dumux/boxmodels/1p2c/1p2cmodel.hh @@ -1,326 +1,3 @@ -// -*- 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 Base class for all models which use the single-phase, - * two-component box model. - * Adaption of the BOX scheme to the one-phase two-component flow model. - */ +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2cmodel.hh instead. -#ifndef DUMUX_ONEP_TWOC_MODEL_HH -#define DUMUX_ONEP_TWOC_MODEL_HH - -#include "1p2cproperties.hh" -#include "1p2clocalresidual.hh" - -#include <dumux/boxmodels/common/boxmodel.hh> - -namespace Dumux -{ - -/*! - * \ingroup OnePTwoCBoxModel - * \brief Adaption of the BOX scheme to the one-phase two-component flow model. - * - * This model implements a one-phase flow of a compressible fluid, that consists of two components, - * using a standard Darcy - * approach as the equation for the conservation of momentum: - \f[ - v_{D} = - \frac{\textbf K}{\mu} - \left(\text{grad} p - \varrho {\textbf g} \right) - \f] - * - * Gravity can be enabled or disabled via the property system. - * By inserting this into the continuity equation, one gets - \f[ - \Phi \frac{\partial \varrho}{\partial t} - \text{div} \left\{ - \varrho \frac{\textbf K}{\mu} \left(\text{grad}\, p - \varrho {\textbf g} \right) - \right\} = q \;, - \f] - * - * The transport of the components is described by the following equation: - \f[ - \Phi \frac{ \partial \varrho x}{\partial t} - \text{div} \left( \varrho \frac{{\textbf K} x}{\mu} \left( \text{grad}\, p - - \varrho {\textbf g} \right) + \varrho \tau \Phi D \text{grad} x \right) = q. - \f] - * - * All equations are discretized using a fully-coupled vertex-centered - * finite volume (box) scheme as spatial and - * the implicit Euler method as time discretization. - * - * The primary variables are the pressure \f$p\f$ and the mole or mass fraction of dissolved component \f$x\f$. - */ - -template<class TypeTag > -class OnePTwoCBoxModel : public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dim> DimVector; - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - OnePTwoCBoxModel() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - upwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - } - - /*! - * \brief \copybrief Dumux::BoxModel::addOutputVtkFields - * - * Specialization for the OnePTwoCBoxModel, adding pressure, - * mass and mole fractions, and the process rank to the VTK writer. - */ - template<class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - - // create the required scalar fields - unsigned numVertices = this->problem_().gridView().size(dim); - ScalarField &pressure = *writer.allocateManagedBuffer(numVertices); - ScalarField &delp = *writer.allocateManagedBuffer(numVertices); - ScalarField &moleFraction0 = *writer.allocateManagedBuffer(numVertices); - ScalarField &moleFraction1 = *writer.allocateManagedBuffer(numVertices); - ScalarField &massFraction0 = *writer.allocateManagedBuffer(numVertices); - ScalarField &massFraction1 = *writer.allocateManagedBuffer(numVertices); - ScalarField &rho = *writer.allocateManagedBuffer(numVertices); - ScalarField &mu = *writer.allocateManagedBuffer(numVertices); -#ifdef VELOCITY_OUTPUT // check if velocity output is demanded - ScalarField &velocityX = *writer.allocateManagedBuffer(numVertices); - ScalarField &velocityY = *writer.allocateManagedBuffer(numVertices); - ScalarField &velocityZ = *writer.allocateManagedBuffer(numVertices); - //use vertical faces for vx and horizontal faces for vy calculation - std::vector<DimVector> boxSurface(numVertices); - // initialize velocity fields - for (unsigned int i = 0; i < numVertices; ++i) - { - - velocityX[i] = 0; - if (dim > 1) - { - velocityY[i] = 0; - } - if (dim > 2) - { - velocityZ[i] = 0; - } - boxSurface[i] = Scalar(0.0); // initialize the boundary surface of the fv-boxes - } -#endif - unsigned numElements = this->gridView_().size(0); - ScalarField &rank = - *writer.allocateManagedBuffer(numElements); - - FVElementGeometry fvGeometry; - VolumeVariables volVars; - ElementBoundaryTypes elemBcTypes; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - int idx = this->problem_().model().elementMapper().map(*elemIt); - rank[idx] = this->gridView_().comm().rank(); - - fvGeometry.update(this->gridView_(), *elemIt); - elemBcTypes.update(this->problem_(), *elemIt, fvGeometry); - - int numVerts = elemIt->template count<dim> (); - for (int i = 0; i < numVerts; ++i) - { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); - volVars.update(sol[globalIdx], - this->problem_(), - *elemIt, - fvGeometry, - i, - false); - - pressure[globalIdx] = volVars.pressure(); - delp[globalIdx] = volVars.pressure() - 1e5; - moleFraction0[globalIdx] = volVars.moleFraction(0); - moleFraction1[globalIdx] = volVars.moleFraction(1); - massFraction0[globalIdx] = volVars.massFraction(0); - massFraction1[globalIdx] = volVars.massFraction(1); - rho[globalIdx] = volVars.density(); - mu[globalIdx] = volVars.viscosity(); - } - -#ifdef VELOCITY_OUTPUT // check if velocity output is demanded - // In the box method, the velocity is evaluated on the FE-Grid. However, to get an - // average apparent velocity at the vertex, all contributing velocities have to be interpolated. - DimVector velocity; - - ElementVolumeVariables elemVolVars; - elemVolVars.update(this->problem_(), - *elemIt, - fvGeometry, - false /* isOldSol? */); - // loop over the phases - for (int faceIdx = 0; faceIdx < fvGeometry.numEdges; faceIdx++) - { - velocity = 0.0; - //prepare the flux calculations (set up and prepare geometry, FE gradients) - FluxVariables fluxVars(this->problem_(), - *elemIt, - fvGeometry, - faceIdx, - elemVolVars); - - //use vertical faces for vx and horizontal faces for vy calculation - DimVector xVector(0), yVector(0); - xVector[0] = 1; yVector[1] = 1; - - Dune::SeqScalarProduct<DimVector> sp; - - Scalar xDir = std::abs(sp.dot(fluxVars.face().normal, xVector)); - Scalar yDir = std::abs(sp.dot(fluxVars.face().normal, yVector)); - - // up+downstream node - const VolumeVariables &up = - elemVolVars[fluxVars.upstreamIdx()]; - const VolumeVariables &dn = - elemVolVars[fluxVars.downstreamIdx()]; - - //get surface area to weight velocity at the IP with the surface area - Scalar scvfArea = fluxVars.face().normal.two_norm(); - - int vertIIdx = this->problem_().vertexMapper().map( - *elemIt, fluxVars.face().i, dim); - int vertJIdx = this->problem_().vertexMapper().map( - *elemIt, fluxVars.face().j, dim); - - //use vertical faces (horizontal noraml vector) to calculate vx - //in case of heterogeneities it seams to be better to define intrinisc permeability elementwise - if(xDir > yDir)//(fluxVars.face().normal[0] > 1e-10 || fluxVars.face().normal[0] < -1e-10)// (xDir > yDir) - { - // get darcy velocity - //calculate (v n) n/A - Scalar tmp = fluxVars.KmvpNormal(); - velocity = fluxVars.face().normal; - velocity *= tmp; - velocity /= scvfArea; - velocity *= (upwindWeight_ / up.viscosity() + - (1 - upwindWeight_)/ dn.viscosity()); - - // add surface area for weighting purposes - boxSurface[vertIIdx][0] += scvfArea; - boxSurface[vertJIdx][0] += scvfArea; - - velocityX[vertJIdx] += velocity[0]; - velocityX[vertIIdx] += velocity[0]; - - } - if (yDir > xDir)//(fluxVars.face().normal[1] > 1e-10 || fluxVars.face().normal[1] < -1e-10)// (yDir > xDir) - { - // get darcy velocity - //calculate (v n) n/A - Scalar tmp = fluxVars.KmvpNormal(); - velocity = fluxVars.face().normal; - velocity *= tmp; - velocity /= scvfArea; - velocity *= (upwindWeight_ / up.viscosity() + - (1 - upwindWeight_)/ dn.viscosity()); - - // add surface area for weighting purposes - boxSurface[vertIIdx][1] += scvfArea; - boxSurface[vertJIdx][1] += scvfArea; - - velocityY[vertJIdx] += velocity[1]; - velocityY[vertIIdx] += velocity[1]; - } - } -#endif - } -#ifdef VELOCITY_OUTPUT - // normalize the velocities at the vertices - // calculate the bounding box of the grid view - VertexIterator vIt = this->gridView_().template begin<dim>(); - const VertexIterator vEndIt = this->gridView_().template end<dim>(); - for (; vIt!=vEndIt; ++vIt) - { - int i = this->problem_().vertexMapper().map(*vIt); - - //use vertical faces for vx and horizontal faces for vy calculation - velocityX[i] /= boxSurface[i][0]; - if (dim >= 2) - { - velocityY[i] /= boxSurface[i][1]; - } - if (dim == 3) - { - velocityZ[i] /= boxSurface[i][2]; - } - } -#endif - writer.attachVertexData(pressure, "P"); - writer.attachVertexData(delp, "delp"); -#ifdef VELOCITY_OUTPUT // check if velocity output is demanded - writer.attachVertexData(velocityX, "Vx"); - writer.attachVertexData(velocityY, "Vy"); - if (dim > 2) - writer.attachVertexData(velocityZ, "Vz"); -#endif - char nameMoleFraction0[42], nameMoleFraction1[42]; - snprintf(nameMoleFraction0, 42, "x_%s", FluidSystem::componentName(0)); - snprintf(nameMoleFraction1, 42, "x_%s", FluidSystem::componentName(1)); - writer.attachVertexData(moleFraction0, nameMoleFraction0); - writer.attachVertexData(moleFraction1, nameMoleFraction1); - - char nameMassFraction0[42], nameMassFraction1[42]; - snprintf(nameMassFraction0, 42, "X_%s", FluidSystem::componentName(0)); - snprintf(nameMassFraction1, 42, "X_%s", FluidSystem::componentName(1)); - writer.attachVertexData(massFraction0, nameMassFraction0); - writer.attachVertexData(massFraction1, nameMassFraction1); - writer.attachVertexData(rho, "rho"); - writer.attachVertexData(mu, "mu"); - writer.attachCellData(rank, "process rank"); - } - -private: - Scalar upwindWeight_; -}; -} - -#include "1p2cpropertydefaults.hh" - -#endif +#include <dumux/implicit/1p2c/1p2cmodel.hh> diff --git a/dumux/boxmodels/1p2c/1p2cproperties.hh b/dumux/boxmodels/1p2c/1p2cproperties.hh index 38d03eba340725dacb6339633aa9b3d13a56dac7..1cb49916cff71cf00518c4605313dfadf65e43d0 100644 --- a/dumux/boxmodels/1p2c/1p2cproperties.hh +++ b/dumux/boxmodels/1p2c/1p2cproperties.hh @@ -1,68 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup OnePTwoCBoxModel - * \file - * - * \brief Defines the properties required for the single-phase, - * two-component BOX model. - */ - -#ifndef DUMUX_1P2C_PROPERTIES_HH -#define DUMUX_1P2C_PROPERTIES_HH - - -#include<dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ -// \{ -namespace Properties -{ - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the isothermal single-phase, two-component problems -NEW_TYPE_TAG(BoxOnePTwoC, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(PhaseIdx); //!< A phase index in to allow that a two-phase fluidsystem is used -NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system -NEW_PROP_TAG(Indices); //!< Enumerations for the model -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters -NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The default value of the upwind weight -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(UseMoles); //!Defines whether mole (true) or mass (false) fractions are used -NEW_PROP_TAG(Scaling); //!Defines Scaling of the model -NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient -} -// \} -} - -#endif +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2cproperties.hh instead. +#include <dumux/implicit/1p2c/1p2cproperties.hh> diff --git a/dumux/boxmodels/1p2c/1p2cpropertydefaults.hh b/dumux/boxmodels/1p2c/1p2cpropertydefaults.hh index 79cd1e11f38ddc0eda14785adf0da441df29682b..6926aa995f0d5be63896d03239478aaf7be0e33c 100644 --- a/dumux/boxmodels/1p2c/1p2cpropertydefaults.hh +++ b/dumux/boxmodels/1p2c/1p2cpropertydefaults.hh @@ -1,96 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup OnePTwoCBoxModel - * \file - * - * \brief Defines some default values for the properties of the the - * single-phase, two-component BOX model. - */ - -#ifndef DUMUX_1P2C_PROPERTY_DEFAULTS_HH -#define DUMUX_1P2C_PROPERTY_DEFAULTS_HH - -#include "1p2cproperties.hh" - -#include "1p2cmodel.hh" -#include "1p2clocalresidual.hh" -#include "1p2cvolumevariables.hh" -#include "1p2cfluxvariables.hh" -#include "1p2cindices.hh" - -#include <dumux/material/spatialparams/boxspatialparams1p.hh> - -namespace Dumux -{ -// \{ -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Property values -////////////////////////////////////////////////////////////////// - -SET_INT_PROP(BoxOnePTwoC, NumEq, 2); //!< set the number of equations to 2 -SET_INT_PROP(BoxOnePTwoC, NumPhases, 1); //!< The number of phases in the 1p2c model is 1 -SET_INT_PROP(BoxOnePTwoC, NumComponents, 2); //!< The number of components in the 1p2c model is 2 -SET_SCALAR_PROP(BoxOnePTwoC, Scaling, 1); //!< Scaling of the model is set to 1 by default -SET_BOOL_PROP(BoxOnePTwoC, UseMoles, false); //!< Define that mass fractions are used in the balance equations - -//! Use the 1p2c local residual function for the 1p2c model -SET_TYPE_PROP(BoxOnePTwoC, LocalResidual, OnePTwoCLocalResidual<TypeTag>); - -//! define the model -SET_TYPE_PROP(BoxOnePTwoC, Model, OnePTwoCBoxModel<TypeTag>); - -//! define the VolumeVariables -SET_TYPE_PROP(BoxOnePTwoC, VolumeVariables, OnePTwoCVolumeVariables<TypeTag>); - -//! define the FluxVariables -SET_TYPE_PROP(BoxOnePTwoC, FluxVariables, OnePTwoCFluxVariables<TypeTag>); - -//! set default upwind weight to 1.0, i.e. fully upwind -SET_SCALAR_PROP(BoxOnePTwoC, ImplicitMassUpwindWeight, 1.0); - -//! Set the indices used by the 1p2c model -SET_TYPE_PROP(BoxOnePTwoC, Indices, Dumux::OnePTwoCIndices<TypeTag, 0>); - -//! The spatial parameters to be employed. -//! Use BoxSpatialParamsOneP by default. -SET_TYPE_PROP(BoxOnePTwoC, SpatialParams, BoxSpatialParamsOneP<TypeTag>); - -//! Set the phaseIndex per default to zero (important for two-phase fluidsystems). -SET_INT_PROP(BoxOnePTwoC, PhaseIdx, 0); - -// enable gravity by default -SET_BOOL_PROP(BoxOnePTwoC, ProblemEnableGravity, true); - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55); -} -// \} -} - -#endif +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2cpropertydefaults.hh instead. +#include <dumux/implicit/1p2c/1p2cpropertydefaults.hh> diff --git a/dumux/boxmodels/1p2c/1p2cvolumevariables.hh b/dumux/boxmodels/1p2c/1p2cvolumevariables.hh index 5e1620dc9b12f73199afdb60d7728d277d9503a2..377fb44810875f7e20c39828cb1fa5b1abcb6b48 100644 --- a/dumux/boxmodels/1p2c/1p2cvolumevariables.hh +++ b/dumux/boxmodels/1p2c/1p2cvolumevariables.hh @@ -1,284 +1,3 @@ -// -*- 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 Quantities required by the single-phase, two-component box - * model defined on a vertex. - */ -#ifndef DUMUX_1P2C_VOLUME_VARIABLES_HH -#define DUMUX_1P2C_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/1p2c/1p2cvolumevariables.hh instead. -#include <dumux/boxmodels/common/boxvolumevariables.hh> -#include <dumux/material/fluidstates/compositionalfluidstate.hh> - -#include "1p2cproperties.hh" - -namespace Dumux -{ - -/*! - * \ingroup OnePTwoCBoxModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are constant within a - * finite volume in the single-phase, two-component model. - */ -template <class TypeTag> -class OnePTwoCVolumeVariables : public BoxVolumeVariables<TypeTag> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - phaseIdx = Indices::phaseIdx, - phaseCompIdx = Indices::phaseCompIdx, - transportCompIdx = Indices::transportCompIdx - }; - //indices of primary variables - enum{ - pressureIdx = Indices::pressureIdx, - massOrMoleFracIdx = Indices::massOrMoleFracIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { dim = GridView::dimension }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar,dim> DimVector; - -public: - //! The type returned by the fluidState() method - typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> FluidState; - - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { - ParentType::update(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - - //calculate all secondary variables from the primary variables and store results in fluidstate - completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_); - - porosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx); - tortuosity_ = problem.spatialParams().tortuosity(element, fvGeometry, scvIdx); - dispersivity_ = problem.spatialParams().dispersivity(element, fvGeometry, scvIdx); - - // Second instance of a parameter cache. - // Could be avoided if diffusion coefficients also - // became part of the fluid state. - typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState_, phaseIdx); - - diffCoeff_ = FluidSystem::binaryDiffusionCoefficient(fluidState_, - paramCache, - phaseIdx, - phaseCompIdx, - transportCompIdx); - - Valgrind::CheckDefined(porosity_); - Valgrind::CheckDefined(tortuosity_); - Valgrind::CheckDefined(dispersivity_); - Valgrind::CheckDefined(diffCoeff_); - - // energy related quantities not contained in the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - /*! - * \copydoc BoxModel::completeFluidState - */ - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const int scvIdx, - FluidState& fluidState) - { - Scalar T = Implementation::temperature_(priVars, problem, element, - fvGeometry, scvIdx); - fluidState.setTemperature(T); - - fluidState.setPressure(phaseIdx, priVars[pressureIdx]); - - Scalar x1 = priVars[massOrMoleFracIdx]; //mole or mass fraction of component 1 - if(!useMoles) //mass-fraction formulation - { - // convert mass to mole fractions - Scalar M0 = FluidSystem::molarMass(phaseCompIdx); - Scalar M1 = FluidSystem::molarMass(transportCompIdx); - //meanMolarMass if x1_ is a massfraction - Scalar meanMolarMass = M0*M1/(M1 + x1*(M0 - M1)); - - x1 *= meanMolarMass/M1; - } - fluidState.setMoleFraction(phaseIdx, phaseCompIdx, 1 - x1); - fluidState.setMoleFraction(phaseIdx, transportCompIdx, x1); - - typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState, phaseIdx); - - Scalar value; - value = FluidSystem::density(fluidState, paramCache, phaseIdx); - fluidState.setDensity(phaseIdx, value); - value = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); - fluidState.setViscosity(phaseIdx, value); - } - - /*! - * \brief Return the fluid configuration at the given primary - * variables - */ - const FluidState &fluidState() const - { return fluidState_; } - - /*! - * \brief Return density \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase. - */ - Scalar density() const - { return fluidState_.density(phaseIdx); } - - /*! - * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase. - */ - Scalar molarDensity() const - { return fluidState_.molarDensity(phaseIdx);} - - /*! - * \brief Return mole fraction \f$\mathrm{[mol/mol]}\f$ of a component in the phase. - * - * \param compIdx The index of the component - */ - Scalar moleFraction(int compIdx) const - { return fluidState_.moleFraction(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); } - - /*! - * \brief Return mass fraction \f$\mathrm{[kg/kg]}\f$ of a component in the phase. - * - * \param compIdx The index of the component - */ - Scalar massFraction(int compIdx) const - { return fluidState_.massFraction(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); } - - /*! - * \brief Return concentration \f$\mathrm{[mol/m^3]}\f$ of a component in the phase. - * - * \param compIdx The index of the component - */ - Scalar molarity(int compIdx) const - { return fluidState_.molarity(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); } - - /*! - * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within - * the control volume. - */ - Scalar pressure() const - { return fluidState_.pressure(phaseIdx); } - - /*! - * \brief Return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ in the fluid. - */ - Scalar diffCoeff() const - { return diffCoeff_; } - - /*! - * \brief Return the tortuosity \f$\mathrm{[-]}\f$ of the streamlines of the fluid. - */ - Scalar tortuosity() const - { return tortuosity_; } - - /*! - * \brief Returns the dispersivity of the fluid's streamlines. - */ - const DimVector &dispersivity() const - { return dispersivity_; } - - /*! - * \brief Return temperature \f$\mathrm{[K]}\f$ inside the sub-control volume. - * - * Note that we assume thermodynamic equilibrium, i.e. the - * temperature of the rock matrix and of all fluid phases are - * identical. - */ - Scalar temperature() const - { return fluidState_.temperature(phaseIdx); } - - /*! - * \brief Return the dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of a given phase - * within the control volume. - */ - Scalar viscosity() const - { return fluidState_.viscosity(phaseIdx); } - - /*! - * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume. - */ - Scalar porosity() const - { return porosity_; } - -protected: - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - /*! - * \brief Called by update() to compute the energy related quantities. - */ - void updateEnergy_(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { } - - Scalar porosity_; //!< Effective porosity within the control volume - Scalar tortuosity_; - DimVector dispersivity_; - Scalar diffCoeff_; - FluidState fluidState_; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; - -}// end namepace - -#endif +#include <dumux/implicit/1p2c/1p2cvolumevariables.hh> diff --git a/dumux/boxmodels/2p/2pindices.hh b/dumux/boxmodels/2p/2pindices.hh index a36d15fdd2a6376ffe77cbcfab5f66279eee7f01..b74414a46e03fc1d8c6de238bbf4332f26b6c816 100644 --- a/dumux/boxmodels/2p/2pindices.hh +++ b/dumux/boxmodels/2p/2pindices.hh @@ -1,110 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/2p/2pindices.hh instead. -/*! - * \file - * - * \brief Defines the indices required for the two-phase box model. - */ -#ifndef DUMUX_BOX_2P_INDICES_HH -#define DUMUX_BOX_2P_INDICES_HH - -#include "2pproperties.hh" - -namespace Dumux -{ -// \{ - -/*! - * \ingroup TwoPBoxModel - * \ingroup BoxIndices - * \brief The common indices for the isothermal two-phase model. - */ - -struct TwoPFormulation -{ - static const int pwSn = 0; //!< Pw and Sn as primary variables - static const int pnSw = 1; //!< Pn and Sw as primary variables -}; - -template <class TypeTag> -struct TwoPCommonIndices -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - // Phase indices - static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase - static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase -}; - -/*! - * \brief The indices for the \f$p_w-S_n\f$ formulation of the - * isothermal two-phase model. - * - * \tparam TypeTag The problem type tag - * \tparam formulation The formulation, either pwSn or pnSw - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, - int formulation = TwoPFormulation::pwSn, - int PVOffset = 0> -struct TwoPIndices -: public TwoPCommonIndices<TypeTag>, TwoPFormulation -{ - // Primary variable indices - static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int saturationIdx = PVOffset + 1; //!< Index of the saturation of the non-wetting/wetting phase - - // indices of the primary variables - static const int pwIdx = PVOffset + 0; //!< Pressure index of the wetting phase - static const int SnIdx = PVOffset + 1; //!< Saturation index of the wetting phase - - // indices of the equations - static const int contiWEqIdx = PVOffset + 0; //!< Index of the continuity equation of the wetting phase - static const int contiNEqIdx = PVOffset + 1; //!< Index of the continuity equation of the non-wetting phase -}; - -/*! - * \brief The indices for the \f$p_w-S_n\f$ formulation of the - * isothermal two-phase model. - * - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, int PVOffset> -struct TwoPIndices<TypeTag, TwoPFormulation::pnSw, PVOffset> -: public TwoPCommonIndices<TypeTag>, TwoPFormulation -{ - // Primary variable indices - static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int saturationIdx = PVOffset + 1; //!< Index of the saturation of the non-wetting/wetting phase - - // indices of the primary variables - static const int pnIdx = PVOffset + 0; //!< Pressure index of the wetting phase - static const int SwIdx = PVOffset + 1; //!< Saturation index of the wetting phase - - // indices of the equations - static const int contiNEqIdx = PVOffset + 0; //!< Index of the continuity equation of the non-wetting phase - static const int contiWEqIdx = PVOffset + 1; //!< Index of the continuity equation of the wetting phase -}; - -// \} -} // namespace Dumux - - -#endif +#include <dumux/implicit/2p/2pindices.hh> diff --git a/dumux/boxmodels/2p/2plocalresidual.hh b/dumux/boxmodels/2p/2plocalresidual.hh index c72e5046c87fe192a1c68ea4bc0daceffe8475c8..62290c56de30b3c211305da7ce7876837dfb96fe 100644 --- a/dumux/boxmodels/2p/2plocalresidual.hh +++ b/dumux/boxmodels/2p/2plocalresidual.hh @@ -1,212 +1,3 @@ -// -*- 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 Element-wise calculation of the residual for the two-phase box model. - */ -#ifndef DUMUX_TWOP_LOCAL_RESIDUAL_BASE_HH -#define DUMUX_TWOP_LOCAL_RESIDUAL_BASE_HH +#warning This file is deprecated. Include dumux/implicit/2p/2plocalresidual.hh instead. -#include <dumux/boxmodels/common/boxmodel.hh> - -#include "2pproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup TwoPBoxModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the two-phase box model. - * - * This class is also used for the non-isothermal model, which means - * that it uses static polymorphism. - */ -template<class TypeTag> -class TwoPLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ -protected: - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum - { - contiWEqIdx = Indices::contiWEqIdx, - contiNEqIdx = Indices::contiNEqIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - enum { dimWorld = GridView::dimensionworld }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dimWorld> Vector; - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - TwoPLocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within a finite sub-control volume. - * - * \param storage The phase mass within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit Euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - // wetting phase mass - storage[contiWEqIdx] = volVars.density(wPhaseIdx) * volVars.porosity() - * volVars.saturation(wPhaseIdx); - - // non-wetting phase mass - storage[contiNEqIdx] = volVars.density(nPhaseIdx) * volVars.porosity() - * volVars.saturation(nPhaseIdx); - } - - /*! - * \brief Evaluates the mass flux over a face of a sub-control - * volume. - * - * \param flux The flux over the SCV (sub-control-volume) face for each phase - * \param faceIdx The index of the SCV face - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, int faceIdx, const bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - flux = 0; - asImp_()->computeAdvectiveFlux(flux, fluxVars); - asImp_()->computeDiffusiveFlux(flux, fluxVars); - } - - /*! - * \brief Evaluates the advective mass flux of all components over - * a face of a sub-control volume. - * - * \param flux The advective flux over the sub-control-volume face for each phase - * \param fluxVars The flux variables at the current SCV - * - * This method is called by compute flux and is mainly there for - * derived models to ease adding equations selectively. - */ - void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - // loop over all phases - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx)); - const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx)); - - // add advective flux of current phase - int eqIdx = (phaseIdx == wPhaseIdx) ? contiWEqIdx : contiNEqIdx; - flux[eqIdx] += - fluxVars.volumeFlux(phaseIdx) - * - (( massUpwindWeight_)*up.density(phaseIdx) - + - (1 - massUpwindWeight_)*dn.density(phaseIdx)); - } - } - - /*! - * \brief Adds the diffusive flux to the flux vector over - * the face of a sub-control volume. - * - * \param flux The diffusive flux over the sub-control-volume face for each phase - * \param fluxData The flux variables at the current SCV - * - * It doesn't do anything in two-phase model but is used by the - * non-isothermal two-phase models to calculate diffusive heat - * fluxes - */ - void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxData) const - { - // diffusive fluxes - flux += 0.0; - } - - /*! - * \brief Calculate the source term of the equation - * - * \param q The source/sink in the SCV for each phase - * \param scvIdx The index of the SCV - * - */ - void computeSource(PrimaryVariables &q, int scvIdx) const - { - // retrieve the source term intrinsic to the problem - this->problem_().boxSDSource(q, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - - -protected: - Implementation *asImp_() - { - return static_cast<Implementation *> (this); - } - const Implementation *asImp_() const - { - return static_cast<const Implementation *> (this); - } - -private: - Scalar massUpwindWeight_; - -}; - -} - -#endif +#include <dumux/implicit/2p/2plocalresidual.hh> diff --git a/dumux/boxmodels/2p/2pmodel.hh b/dumux/boxmodels/2p/2pmodel.hh index 5a46820d2c3375556e9af53b3978061145af7214..817b2761558e248a68faeb9d5885a8b344737771 100644 --- a/dumux/boxmodels/2p/2pmodel.hh +++ b/dumux/boxmodels/2p/2pmodel.hh @@ -1,366 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/2p/2pmodel.hh instead. -/*! -* \file -* -* \brief Adaption of the box scheme to the two-phase flow model. -*/ - -#ifndef DUMUX_TWOP_MODEL_HH -#define DUMUX_TWOP_MODEL_HH - -#include "2pproperties.hh" -#include "2plocalresidual.hh" - -namespace Dumux -{ - -/*! - * \ingroup TwoPBoxModel - * \brief A two-phase, isothermal flow model using the box scheme. - * - * This model implements two-phase flow of two immiscible fluids - * \f$\alpha \in \{ w, n \}\f$ using a standard multiphase Darcy - * approach as the equation for the conservation of momentum, i.e. - \f[ - v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \textbf{K} - \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} {\textbf g} \right) - \f] - * - * By inserting this into the equation for the conservation of the - * phase mass, one gets - \f[ - \phi \frac{\partial \varrho_\alpha S_\alpha}{\partial t} - - - \text{div} \left\{ - \varrho_\alpha \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right) - \right\} - q_\alpha = 0 \;, - \f] - * - * These equations are discretized by a fully-coupled vertex centered finite volume - * (box) scheme as spatial and the implicit Euler method as time - * discretization. - * - * By using constitutive relations for the capillary pressure \f$p_c = - * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking - * advantage of the fact that \f$S_w + S_n = 1\f$, the number of - * unknowns can be reduced to two. Currently the model supports - * choosing either \f$p_w\f$ and \f$S_n\f$ or \f$p_n\f$ and \f$S_w\f$ - * as primary variables. The formulation which ought to be used can be - * specified by setting the <tt>Formulation</tt> property to either - * <tt>TwoPCommonIndices::pWsN</tt> or <tt>TwoPCommonIndices::pNsW</tt>. By - * default, the model uses \f$p_w\f$ and \f$S_n\f$. - */ -template<class TypeTag > -class TwoPModel : public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - nPhaseIdx = Indices::nPhaseIdx, - wPhaseIdx = Indices::wPhaseIdx, - pressureIdx = Indices::pressureIdx, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::ctype CoordScalar; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, numPhases> PhasesVector; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - -public: - /*! - * \brief Append all quantities of interest which can be derived - * from the solution of the current time step to the VTK - * writer. - * - * \param sol The global solution vector - * \param writer The writer for multi-file VTK datasets - */ - template<class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - bool velocityOutput = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocity); - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField; - - // get the number of degrees of freedom and the number of vertices - unsigned numDofs = this->numDofs(); - unsigned numVertices = this->problem_().gridView().size(dim); - - // velocity output currently only works for vertex data - if (numDofs != numVertices) - velocityOutput = false; - - // create the required scalar fields - ScalarField *pW = writer.allocateManagedBuffer(numDofs); - ScalarField *pN = writer.allocateManagedBuffer(numDofs); - ScalarField *pC = writer.allocateManagedBuffer(numDofs); - ScalarField *Sw = writer.allocateManagedBuffer(numDofs); - ScalarField *Sn = writer.allocateManagedBuffer(numDofs); - ScalarField *rhoW = writer.allocateManagedBuffer(numDofs); - ScalarField *rhoN = writer.allocateManagedBuffer(numDofs); - ScalarField *mobW = writer.allocateManagedBuffer(numDofs); - ScalarField *mobN = writer.allocateManagedBuffer(numDofs); - ScalarField *poro = writer.allocateManagedBuffer(numDofs); - ScalarField *Te = writer.allocateManagedBuffer(numDofs); - ScalarField *cellNum =writer.allocateManagedBuffer (numDofs); - VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs); - VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs); - - if(velocityOutput) // check if velocity output is demanded - { - // initialize velocity fields - for (unsigned int i = 0; i < numVertices; ++i) - { - (*velocityN)[i] = Scalar(0); - (*velocityW)[i] = Scalar(0); - (*cellNum)[i] = Scalar(0.0); - } - } - unsigned numElements = this->gridView_().size(0); - ScalarField *rank = writer.allocateManagedBuffer(numElements); - - FVElementGeometry fvGeometry; - VolumeVariables volVars; - ElementVolumeVariables elemVolVars; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - if(velocityOutput && !elemIt->geometry().type().isCube()){ - DUNE_THROW(Dune::InvalidStateException, - "Currently, velocity output only works for cubes. " - "Please set the EnableVelocityOutput property to false!"); - } - int idx = this->elementMapper().map(*elemIt); - (*rank)[idx] = this->gridView_().comm().rank(); - - fvGeometry.update(this->gridView_(), *elemIt); - - if (numDofs == numElements) // element data - { - volVars.update(sol[idx], - this->problem_(), - *elemIt, - fvGeometry, - /*scvIdx=*/0, - false); - - (*pW)[idx] = volVars.pressure(wPhaseIdx); - (*pN)[idx] = volVars.pressure(nPhaseIdx); - (*pC)[idx] = volVars.capillaryPressure(); - (*Sw)[idx] = volVars.saturation(wPhaseIdx); - (*Sn)[idx] = volVars.saturation(nPhaseIdx); - (*rhoW)[idx] = volVars.density(wPhaseIdx); - (*rhoN)[idx] = volVars.density(nPhaseIdx); - (*mobW)[idx] = volVars.mobility(wPhaseIdx); - (*mobN)[idx] = volVars.mobility(nPhaseIdx); - (*poro)[idx] = volVars.porosity(); - (*Te)[idx] = volVars.temperature(); - } - else // vertex data - { - int numVerts = elemIt->template count<dim> (); - for (int scvIdx = 0; scvIdx < numVerts; ++scvIdx) - { - int globalIdx = this->vertexMapper().map(*elemIt, scvIdx, dim); - volVars.update(sol[globalIdx], - this->problem_(), - *elemIt, - fvGeometry, - scvIdx, - false); - - (*pW)[globalIdx] = volVars.pressure(wPhaseIdx); - (*pN)[globalIdx] = volVars.pressure(nPhaseIdx); - (*pC)[globalIdx] = volVars.capillaryPressure(); - (*Sw)[globalIdx] = volVars.saturation(wPhaseIdx); - (*Sn)[globalIdx] = volVars.saturation(nPhaseIdx); - (*rhoW)[globalIdx] = volVars.density(wPhaseIdx); - (*rhoN)[globalIdx] = volVars.density(nPhaseIdx); - (*mobW)[globalIdx] = volVars.mobility(wPhaseIdx); - (*mobN)[globalIdx] = volVars.mobility(nPhaseIdx); - (*poro)[globalIdx] = volVars.porosity(); - (*Te)[globalIdx] = volVars.temperature(); - if(velocityOutput) - { - (*cellNum)[globalIdx] += 1; - } - } - - if(velocityOutput) - { - // calculate vertex velocities - GlobalPosition tmpVelocity[numPhases]; - - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - tmpVelocity[phaseIdx] = Scalar(0.0); - } - - typedef Dune::BlockVector<Dune::FieldVector<Scalar, dim> > SCVVelocities; - SCVVelocities scvVelocityW(8), scvVelocityN(8); - - scvVelocityW = 0; - scvVelocityN = 0; - - ElementVolumeVariables elemVolVars; - - elemVolVars.update(this->problem_(), - *elemIt, - fvGeometry, - false /* oldSol? */); - - for (int faceIdx = 0; faceIdx < fvGeometry.numEdges; faceIdx++) - { - - FluxVariables fluxVars(this->problem_(), - *elemIt, - fvGeometry, - faceIdx, - elemVolVars); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // local position of integration point - const Dune::FieldVector<Scalar, dim>& localPosIP = fvGeometry.subContVolFace[faceIdx].ipLocal; - - // Transformation of the global normal vector to normal vector in the reference element - const typename Element::Geometry::JacobianTransposed& jacobianT1 = - elemIt->geometry().jacobianTransposed(localPosIP); - - const GlobalPosition globalNormal = fluxVars.face().normal; - GlobalPosition localNormal; - jacobianT1.mv(globalNormal, localNormal); - // note only works for cubes - const Scalar localArea = pow(2,-(dim-1)); - - localNormal /= localNormal.two_norm(); - - // Get the Darcy velocities. The Darcy velocities are divided by the area of the subcontrolvolumeface - // in the reference element. - PhasesVector q; - q[phaseIdx] = fluxVars.volumeFlux(phaseIdx) / localArea; - - // transform the normal Darcy velocity into a vector - tmpVelocity[phaseIdx] = localNormal; - tmpVelocity[phaseIdx] *= q[phaseIdx]; - - if(phaseIdx == wPhaseIdx){ - scvVelocityW[fluxVars.face().i] += tmpVelocity[phaseIdx]; - scvVelocityW[fluxVars.face().j] += tmpVelocity[phaseIdx]; - } - else if(phaseIdx == nPhaseIdx){ - scvVelocityN[fluxVars.face().i] += tmpVelocity[phaseIdx]; - scvVelocityN[fluxVars.face().j] += tmpVelocity[phaseIdx]; - } - } - } - typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElements; - const Dune::FieldVector<Scalar, dim> &localPos - = ReferenceElements::general(elemIt->geometry().type()).position(0, 0); - - // get the transposed Jacobian of the element mapping - const typename Element::Geometry::JacobianTransposed& jacobianT2 - = elemIt->geometry().jacobianTransposed(localPos); - - // transform vertex velocities from local to global coordinates - for (int i = 0; i < numVerts; ++i) - { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); - // calculate the subcontrolvolume velocity by the Piola transformation - Dune::FieldVector<CoordScalar, dim> scvVelocity(0); - - jacobianT2.mtv(scvVelocityW[i], scvVelocity); - scvVelocity /= elemIt->geometry().integrationElement(localPos); - // add up the wetting phase subcontrolvolume velocities for each vertex - (*velocityW)[globalIdx] += scvVelocity; - - jacobianT2.mtv(scvVelocityN[i], scvVelocity); - scvVelocity /= elemIt->geometry().integrationElement(localPos); - // add up the nonwetting phase subcontrolvolume velocities for each vertex - (*velocityN)[globalIdx] += scvVelocity; - } - } - } - } - - if (numDofs == numElements) // element data - { - writer.attachCellData(*Sn, "Sn"); - writer.attachCellData(*Sw, "Sw"); - writer.attachCellData(*pN, "pn"); - writer.attachCellData(*pW, "pw"); - writer.attachCellData(*pC, "pc"); - writer.attachCellData(*rhoW, "rhoW"); - writer.attachCellData(*rhoN, "rhoN"); - writer.attachCellData(*mobW, "mobW"); - writer.attachCellData(*mobN, "mobN"); - writer.attachCellData(*poro, "porosity"); - writer.attachCellData(*Te, "temperature"); - } - else // vertex data - { - writer.attachVertexData(*Sn, "Sn"); - writer.attachVertexData(*Sw, "Sw"); - writer.attachVertexData(*pN, "pn"); - writer.attachVertexData(*pW, "pw"); - writer.attachVertexData(*pC, "pc"); - writer.attachVertexData(*rhoW, "rhoW"); - writer.attachVertexData(*rhoN, "rhoN"); - writer.attachVertexData(*mobW, "mobW"); - writer.attachVertexData(*mobN, "mobN"); - writer.attachVertexData(*poro, "porosity"); - writer.attachVertexData(*Te, "temperature"); - if(velocityOutput) // check if velocity output is demanded - { - // divide the vertex velocities by the number of adjacent scvs i.e. cells - for(unsigned int globalIdx = 0; globalIdx < numVertices; ++globalIdx){ - (*velocityW)[globalIdx] /= (*cellNum)[globalIdx]; - (*velocityN)[globalIdx] /= (*cellNum)[globalIdx]; - } - writer.attachVertexData(*velocityW, "velocityW", dim); - writer.attachVertexData(*velocityN, "velocityN", dim); - } - } - writer.attachCellData(*rank, "process rank"); - } -}; -} - -#include "2ppropertydefaults.hh" - -#endif +#include <dumux/implicit/2p/2pmodel.hh> diff --git a/dumux/boxmodels/2p/2pproperties.hh b/dumux/boxmodels/2p/2pproperties.hh index c86ab53d93fa832969b322f1e378bc07ef8400a4..6221b178cbdbea9c3d2ad7e9622f3f7fa849a33d 100644 --- a/dumux/boxmodels/2p/2pproperties.hh +++ b/dumux/boxmodels/2p/2pproperties.hh @@ -1,76 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPBoxModel - */ -/*! - * \file - * - * \brief Defines the properties required for the twophase BOX model. - */ +#warning This file is deprecated. Include dumux/implicit/2p/2pproperties.hh instead. -#ifndef DUMUX_2P_PROPERTIES_HH -#define DUMUX_2P_PROPERTIES_HH - -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ - - - -//////////////////////////////// -// properties -//////////////////////////////// -namespace Properties -{ - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the two-phase problems -NEW_TYPE_TAG(BoxTwoP, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the weight of the upwind direction in the mass conservation equations -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation -NEW_PROP_TAG(Formulation); //!< The formulation of the model -NEW_PROP_TAG(Indices); //!< Enumerations for the model -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters -NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the spatial parameters) -NEW_PROP_TAG(MaterialLawParams); //!< The context material law (extracted from the spatial parameters) -NEW_PROP_TAG(WettingPhase); //!< The wetting phase for two-phase models -NEW_PROP_TAG(NonwettingPhase); //!< The non-wetting phase for two-phase models -NEW_PROP_TAG(FluidSystem); //!<The fluid systems including the information about the phases -NEW_PROP_TAG(FluidState); //!<The phases state -NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output -NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient -} - -} - -#endif +#include <dumux/implicit/2p/2pproperties.hh> diff --git a/dumux/boxmodels/2p/2ppropertydefaults.hh b/dumux/boxmodels/2p/2ppropertydefaults.hh index 2cd202b4304ec00019fdd7b0c2f6f878d2c3b04f..07738b3e7f97a8b9f3fca3a6a1daf41b5c882f56 100644 --- a/dumux/boxmodels/2p/2ppropertydefaults.hh +++ b/dumux/boxmodels/2p/2ppropertydefaults.hh @@ -1,148 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup TwoPBoxModel - * \ingroup BoxProperties - * \ingroup Properties - * \file - * - * \brief Defines default values for the properties required by the - * twophase box model. - */ -#ifndef DUMUX_2P_PROPERTY_DEFAULTS_HH -#define DUMUX_2P_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/2p/2ppropertydefaults.hh instead. -#include "2pmodel.hh" -#include "2pindices.hh" -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include "2pvolumevariables.hh" -#include "2pproperties.hh" - -#include <dumux/material/fluidsystems/gasphase.hh> -#include <dumux/material/fluidsystems/liquidphase.hh> -#include <dumux/material/components/nullcomponent.hh> -#include <dumux/material/fluidsystems/2pimmisciblefluidsystem.hh> -#include <dumux/material/fluidstates/immisciblefluidstate.hh> -#include <dumux/material/spatialparams/boxspatialparams.hh> - -namespace Dumux -{ -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Property defaults -////////////////////////////////////////////////////////////////// -SET_INT_PROP(BoxTwoP, NumEq, 2); //!< set the number of equations to 2 -SET_INT_PROP(BoxTwoP, NumPhases, 2); //!< The number of phases in the 2p model is 2 - -//! Set the default formulation to pWsN -SET_INT_PROP(BoxTwoP, - Formulation, - TwoPFormulation::pwSn); - -//! Use the 2p local jacobian operator for the 2p model -SET_TYPE_PROP(BoxTwoP, - LocalResidual, - TwoPLocalResidual<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxTwoP, Model, TwoPModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxTwoP, VolumeVariables, TwoPVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxTwoP, FluxVariables, BoxDarcyFluxVariables<TypeTag>); - -//! the upwind weight for the mass conservation equations. -SET_SCALAR_PROP(BoxTwoP, ImplicitMassUpwindWeight, 1.0); - -//! weight for the upwind mobility in the velocity calculation -SET_SCALAR_PROP(BoxTwoP, ImplicitMobilityUpwindWeight, 1.0); - -//! The indices required by the isothermal 2p model -SET_TYPE_PROP(BoxTwoP, - Indices, - TwoPIndices<TypeTag, GET_PROP_VALUE(TypeTag, Formulation), 0>); - -//! The spatial parameters to be employed. -//! Use BoxSpatialParams by default. -SET_TYPE_PROP(BoxTwoP, SpatialParams, BoxSpatialParams<TypeTag>); - -/*! - * \brief Set the property for the material parameters by extracting - * it from the material law. - */ -SET_TYPE_PROP(BoxTwoP, - MaterialLawParams, - typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params); - -SET_PROP(BoxTwoP, WettingPhase) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -SET_PROP(BoxTwoP, NonwettingPhase) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -SET_PROP(BoxTwoP, FluidSystem) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; - -public: - typedef Dumux::FluidSystems::TwoPImmiscible<Scalar, - WettingPhase, - NonwettingPhase> type; -}; - -SET_PROP(BoxTwoP, FluidState) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; -public: - typedef ImmiscibleFluidState<Scalar, FluidSystem> type; -}; - -// disable velocity output by default -SET_BOOL_PROP(BoxTwoP, VtkAddVelocity, false); - -// enable gravity by default -SET_BOOL_PROP(BoxTwoP, ProblemEnableGravity, true); - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55); -} -// - -} - -#endif +#include <dumux/implicit/2p/2ppropertydefaults.hh> diff --git a/dumux/boxmodels/2p/2pvolumevariables.hh b/dumux/boxmodels/2p/2pvolumevariables.hh index 24e953f6a7665bfda0414f8e121a628a96dfcb78..4bb3d42d0e1e9d8dacb8b27c55a8617f24ba9978 100644 --- a/dumux/boxmodels/2p/2pvolumevariables.hh +++ b/dumux/boxmodels/2p/2pvolumevariables.hh @@ -1,279 +1,3 @@ -// -*- 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 Contains the quantities which are constant within a - * finite volume in the two-phase model. - */ -#ifndef DUMUX_2P_VOLUME_VARIABLES_HH -#define DUMUX_2P_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2p/2pvolumevariables.hh instead. -#include "2pproperties.hh" - -#include <dumux/boxmodels/common/boxvolumevariables.hh> - -#include <dune/common/fvector.hh> - -namespace Dumux -{ -/*! - * \ingroup TwoPBoxModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the two-phase model. - */ -template <class TypeTag> -class TwoPVolumeVariables : public BoxVolumeVariables<TypeTag> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pwSn = Indices::pwSn, - pnSw = Indices::pnSw, - pressureIdx = Indices::pressureIdx, - saturationIdx = Indices::saturationIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - formulation = GET_PROP_VALUE(TypeTag, Formulation) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - -public: - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx, - bool isOldSol) - { - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_); - - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - - mobility_[wPhaseIdx] = - MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx)) - / fluidState_.viscosity(wPhaseIdx); - - mobility_[nPhaseIdx] = - MaterialLaw::krn(materialParams, fluidState_.saturation(wPhaseIdx)) - / fluidState_.viscosity(nPhaseIdx); - - // porosity - porosity_ = problem.spatialParams().porosity(element, - fvGeometry, - scvIdx); - - // energy related quantities not belonging to the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - /*! - * \copydoc BoxModel::completeFluidState - */ - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - int scvIdx, - FluidState& fluidState) - { - Scalar t = Implementation::temperature_(priVars, problem, element, - fvGeometry, scvIdx); - fluidState.setTemperature(t); - - // material law parameters - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - const typename MaterialLaw::Params &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - - - if (int(formulation) == pwSn) { - Scalar Sn = priVars[saturationIdx]; - fluidState.setSaturation(nPhaseIdx, Sn); - fluidState.setSaturation(wPhaseIdx, 1 - Sn); - - Scalar pW = priVars[pressureIdx]; - fluidState.setPressure(wPhaseIdx, pW); - fluidState.setPressure(nPhaseIdx, - pW + MaterialLaw::pC(materialParams, 1 - Sn)); - } - else if (int(formulation) == pnSw) { - Scalar Sw = priVars[saturationIdx]; - fluidState.setSaturation(wPhaseIdx, Sw); - fluidState.setSaturation(nPhaseIdx, 1 - Sw); - - Scalar pN = priVars[pressureIdx]; - fluidState.setPressure(nPhaseIdx, pN); - fluidState.setPressure(wPhaseIdx, - pN - MaterialLaw::pC(materialParams, Sw)); - } - - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typename FluidSystem::ParameterCache paramCache; - paramCache.updateAll(fluidState); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // compute and set the viscosity - Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); - fluidState.setViscosity(phaseIdx, mu); - - // compute and set the density - Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx); - fluidState.setDensity(phaseIdx, rho); - - // compute and set the enthalpy - Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx); - fluidState.setEnthalpy(phaseIdx, h); - } - } - - /*! - * \brief Returns the phase state for the control-volume. - */ - const FluidState &fluidState() const - { return fluidState_; } - - /*! - * \brief Returns the effective saturation of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar saturation(int phaseIdx) const - { return fluidState_.saturation(phaseIdx); } - - /*! - * \brief Returns the mass density of a given phase within the - * control volume. - * - * \param phaseIdx The phase index - */ - Scalar density(int phaseIdx) const - { return fluidState_.density(phaseIdx); } - - /*! - * \brief Returns the effective pressure of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar pressure(int phaseIdx) const - { return fluidState_.pressure(phaseIdx); } - - /*! - * \brief Returns the capillary pressure within the control volume [Pa]. - */ - Scalar capillaryPressure() const - { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); } - - /*! - * \brief Returns temperature inside the sub-control volume. - * - * Note that we assume thermodynamic equilibrium, i.e. the - * temperature of the rock matrix and of all fluid phases are - * identical. - */ - Scalar temperature() const - { return fluidState_.temperature(/*phaseIdx=*/0); } - - /*! - * \brief Returns the effective mobility of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar mobility(int phaseIdx) const - { return mobility_[phaseIdx]; } - - /*! - * \brief Returns the average porosity within the control volume. - */ - Scalar porosity() const - { return porosity_; } - -protected: - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - template<class ParameterCache> - static Scalar enthalpy_(const FluidState& fluidState, - const ParameterCache& paramCache, - int phaseIdx) - { - return 0; - } - - /*! - * \brief Called by update() to compute the energy related quantities - */ - void updateEnergy_(const PrimaryVariables &sol, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int vertIdx, - bool isOldSol) - { } - - FluidState fluidState_; - Scalar porosity_; - Scalar mobility_[numPhases]; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; - -} - -#endif +#include <dumux/implicit/2p/2pvolumevariables.hh> diff --git a/dumux/boxmodels/2p2c/2p2cfluxvariables.hh b/dumux/boxmodels/2p2c/2p2cfluxvariables.hh index f93b15a39b546cfaa71444f2423a0b304efad0b6..59a2b85300b8560529e04a575e371cfae9a7f09c 100644 --- a/dumux/boxmodels/2p2c/2p2cfluxvariables.hh +++ b/dumux/boxmodels/2p2c/2p2cfluxvariables.hh @@ -1,246 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes of components over a face of a finite volume for - * the two-phase, two-component model. - */ -#ifndef DUMUX_2P2C_FLUX_VARIABLES_HH -#define DUMUX_2P2C_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cfluxvariables.hh instead. -#include <dumux/common/math.hh> -#include <dumux/common/spline.hh> - -#include "2p2cproperties.hh" - -namespace Dumux -{ - -/*! - * \ingroup TwoPTwoCModel - * \ingroup BoxFluxVariables - * \brief This template class contains the data which is required to - * calculate all fluxes of components over a face of a finite - * volume for the two-phase, two-component model. - * - * This means pressure and concentration gradients, phase densities at - * the integration point, etc. - */ -template <class TypeTag> -class TwoPTwoCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables) -{ - typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { dim = GridView::dimension }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dim> DimVector; - typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary Distinguishes if we are on a SCV face or on a boundary face - */ - TwoPTwoCFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : BaseFluxVariables(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary) - { - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - density_[phaseIdx] = Scalar(0); - molarDensity_[phaseIdx] = Scalar(0); - moleFractionGrad_[phaseIdx] = Scalar(0); - } - - calculateValues_(problem, element, elemVolVars); - } - -protected: - void calculateValues_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // calculate densities at the integration points of the face - DimVector tmp(0.0); - for (int idx = 0; - idx < this->fvGeometry_.numFAP; - idx++) // loop over adjacent vertices - { - // index for the element volume variables - int volVarsIdx = this->face().fapIndices[idx]; - - for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++) - { - density_[phaseIdx] += elemVolVars[volVarsIdx].density(phaseIdx)* - this->face().shapeValue[idx]; - molarDensity_[phaseIdx] += elemVolVars[volVarsIdx].molarDensity(phaseIdx)* - this->face().shapeValue[idx]; - } - } - - calculateGradients_(problem, element, elemVolVars); - calculatePorousDiffCoeff_(problem, element, elemVolVars); - } - - void calculateGradients_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // calculate gradients - DimVector tmp(0.0); - for (int idx = 0; - idx < this->fvGeometry_.numFAP; - idx++) // loop over adjacent vertices - { - // FE gradient at vertex idx - const DimVector &feGrad = this->face().grad[idx]; - - // index for the element volume variables - int volVarsIdx = this->face().fapIndices[idx]; - - // the mole fraction gradient of the wetting phase - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(wPhaseIdx, nCompIdx); - moleFractionGrad_[wPhaseIdx] += tmp; - - // the mole fraction gradient of the non-wetting phase - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(nPhaseIdx, wCompIdx); - moleFractionGrad_[nPhaseIdx] += tmp; - } - } - - Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &vDat) - { - static const Scalar eps = 1e-2; - const Scalar sat = vDat[scvIdx].density(phaseIdx); - if (sat > eps) - return 0.5; - if (sat <= 0) - return 0; - - static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1 - 0, 0.5, // y0, y1 - 0, 0); // m0, m1 - return sp.eval(sat); - } - - void calculatePorousDiffCoeff_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - const VolumeVariables &volVarsI = elemVolVars[this->face().i]; - const VolumeVariables &volVarsJ = elemVolVars[this->face().j]; - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // make sure to only calculate diffusion coefficients - // for phases which exist in both finite volumes - if (volVarsI.saturation(phaseIdx) <= 0 || - volVarsJ.saturation(phaseIdx) <= 0) - { - porousDiffCoeff_[phaseIdx] = 0.0; - continue; - } - - // calculate tortuosity at the nodes i and j needed - // for porous media diffusion coefficient - Scalar tauI = - 1.0/(volVarsI.porosity() * volVarsI.porosity()) * - pow(volVarsI.porosity() * volVarsI.saturation(phaseIdx), 7.0/3); - Scalar tauJ = - 1.0/(volVarsJ.porosity() * volVarsJ.porosity()) * - pow(volVarsJ.porosity() * volVarsJ.saturation(phaseIdx), 7.0/3); - // Diffusion coefficient in the porous medium - - // -> harmonic mean - porousDiffCoeff_[phaseIdx] = harmonicMean(volVarsI.porosity() * volVarsI.saturation(phaseIdx) * tauI * volVarsI.diffCoeff(phaseIdx), - volVarsJ.porosity() * volVarsJ.saturation(phaseIdx) * tauJ * volVarsJ.diffCoeff(phaseIdx)); - } - } - -public: - /*! - * \brief The binary diffusion coefficient for each fluid phase. - */ - Scalar porousDiffCoeff(int phaseIdx) const - { return porousDiffCoeff_[phaseIdx]; }; - - /*! - * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase. - */ - Scalar density(int phaseIdx) const - { return density_[phaseIdx]; } - - /*! - * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase. - */ - Scalar molarDensity(int phaseIdx) const - { return molarDensity_[phaseIdx]; } - - /*! - * \brief The mole fraction gradient of the dissolved component in a phase. - */ - const DimVector &moleFractionGrad(int phaseIdx) const - { return moleFractionGrad_[phaseIdx]; }; - -protected: - // mole fraction gradients - DimVector moleFractionGrad_[numPhases]; - - // density of each face at the integration point - Scalar density_[numPhases], molarDensity_[numPhases]; - - // the diffusion coefficient for the porous medium - Scalar porousDiffCoeff_[numPhases]; -}; - -} // end namespace - -#endif +#include <dumux/implicit/2p2c/2p2cfluxvariables.hh> diff --git a/dumux/boxmodels/2p2c/2p2cindices.hh b/dumux/boxmodels/2p2c/2p2cindices.hh index 1f00b2540e8f1675dce024eaa69798655fa6b331..4d552c52b9b02cbb2f03c6ee5f622673d235dc76 100644 --- a/dumux/boxmodels/2p2c/2p2cindices.hh +++ b/dumux/boxmodels/2p2c/2p2cindices.hh @@ -1,129 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cindices.hh instead. -/*! - * \file - * - * \brief Defines the indices required for the 2p2c BOX model. - */ -#ifndef DUMUX_2P2C_INDICES_HH -#define DUMUX_2P2C_INDICES_HH - -#include "2p2cproperties.hh" - -namespace Dumux -{ -// \{ - -/*! - * \ingroup TwoPTwoCModel - * \ingroup BoxIndices - * \brief Enumerates the formulations which the 2p2c model accepts. - */ -struct TwoPTwoCFormulation -{ - enum { - pwSn, - pnSw - }; -}; - -/*! - * \brief The indices for the isothermal TwoPTwoC model. - * - * \tparam formulation The formulation, either pwSn or pnSw. - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, - int formulation = TwoPTwoCFormulation::pwSn, - int PVOffset = 0> -class TwoPTwoCIndices -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - // Phase indices - static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase - static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase - - // Component indices - static const int wCompIdx = FluidSystem::wCompIdx; //!< Index of the primary component of the wetting phase - static const int nCompIdx = FluidSystem::nCompIdx; //!< Index of the primary component of the non-wetting phase - - // present phases (-> 'pseudo' primary variable) - static const int wPhaseOnly = 1; //!< Only the wetting phase is present - static const int nPhaseOnly = 0; //!< Only the non-wetting phase is present - static const int bothPhases = 2; //!< Both phases are present - - // Primary variable indices - static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int switchIdx = PVOffset + 1; //!< Index of the either the saturation or the mass fraction of the non-wetting/wetting phase - - static const int pwIdx = pressureIdx; //!< Index for wetting phase pressure in a solution vector - static const int SnOrXIdx = switchIdx; //!< Index of the either the saturation of the non-wetting phase or the mass fraction secondary component in the only phase - - // equation indices - static const int conti0EqIdx = PVOffset; //!< Index of the mass conservation equation for the first component - static const int contiWEqIdx = conti0EqIdx + wCompIdx; //!< Index of the mass conservation equation for the liquid's primary component - static const int contiNEqIdx = conti0EqIdx + nCompIdx; //!< Index of the mass conservation equation for the gas' primary component -}; - -/*! - * \brief The indices for the isothermal TwoPTwoC model in the pn-Sw - * formulation. - * - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, int PVOffset> -class TwoPTwoCIndices<TypeTag, TwoPTwoCFormulation::pnSw, PVOffset> -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - // Phase indices - static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase - static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase - - // Component indices - static const int wCompIdx = FluidSystem::wCompIdx; //!< Index of the primary component of the wetting phase - static const int nCompIdx = FluidSystem::nCompIdx; //!< Index of the primary component of the non-wetting phase - - // present phases (-> 'pseudo' primary variable) - static const int wPhaseOnly = 1; //!< Only the wetting phase is present - static const int nPhaseOnly = 2; //!< Only the non-wetting phase is present - static const int bothPhases = 3; //!< Both phases are present - - // Primary variable indices - static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int switchIdx = PVOffset + 1; //!< Index of the either the saturation or the mass fraction of the non-wetting/wetting phase - - static const int pnIdx = pressureIdx; //!< Index for non-wetting phase pressure in a solution vector - static const int SwOrXIdx = switchIdx; //!< Index of the either the saturation of the liquid phase or the mass fraction of the secondary component in the only phase - - // Equation indices - static const int conti0EqIdx = PVOffset; //!< Index of the mass conservation equation for the first component - static const int contiWEqIdx = conti0EqIdx + wCompIdx; //!< Index of the mass conservation equation for the liquid's primary component - static const int contiNEqIdx = conti0EqIdx + nCompIdx; //!< Index of the mass conservation equation for the gas' primary component -}; - -// \} - -} - -#endif +#include <dumux/implicit/2p2c/2p2cindices.hh> diff --git a/dumux/boxmodels/2p2c/2p2clocalresidual.hh b/dumux/boxmodels/2p2c/2p2clocalresidual.hh index d36494883f10c84618339cde1355aca940c97ba1..4ba462a3d952a98d705b440f9ed66ebe5f6ddae7 100644 --- a/dumux/boxmodels/2p2c/2p2clocalresidual.hh +++ b/dumux/boxmodels/2p2c/2p2clocalresidual.hh @@ -1,383 +1,3 @@ -// -*- 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 Element-wise calculation of the Jacobian matrix for problems - * using the two-phase two-component box model. - */ +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2clocalresidual.hh instead. -#ifndef DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH -#define DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH - -#include <dumux/boxmodels/common/boxmodel.hh> -#include <dumux/common/math.hh> - -#include "2p2cproperties.hh" -#include "2p2cvolumevariables.hh" -#include "2p2cfluxvariables.hh" -#include "2p2cnewtoncontroller.hh" - -#include <iostream> -#include <vector> - -namespace Dumux -{ -/*! - * \ingroup TwoPTwoCModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the two-phase two-component box model. - * - * This class is used to fill the gaps in BoxLocalResidual for the 2P-2C flow. - */ -template<class TypeTag> -class TwoPTwoCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ - protected: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - enum - { - numEq = GET_PROP_VALUE(TypeTag, NumEq), - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum - { - contiWEqIdx = Indices::contiWEqIdx, - contiNEqIdx = Indices::contiNEqIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::IntersectionIterator IntersectionIterator; - - static constexpr unsigned int replaceCompEqIdx = - GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx); - - public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - TwoPTwoCLocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the storage term of the current solution in a - * single phase. - * - * \param element The element - * \param phaseIdx The index of the fluid phase - */ - void evalPhaseStorage(const Element &element, const int phaseIdx) - { - FVElementGeometry fvGeometry; - fvGeometry.update(this->gridView_(), element); - ElementBoundaryTypes bcTypes; - bcTypes.update(this->problem_(), element, fvGeometry); - ElementVolumeVariables elemVolVars; - elemVolVars.update(this->problem_(), element, fvGeometry, false); - - this->storageTerm_.resize(fvGeometry.numSCV); - this->storageTerm_ = 0; - - this->elemPtr_ = &element; - this->fvElemGeomPtr_ = &fvGeometry; - this->bcTypesPtr_ = &bcTypes; - this->prevVolVarsPtr_ = 0; - this->curVolVarsPtr_ = &elemVolVars; - evalPhaseStorage_(phaseIdx); - } - - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within a sub-control volume. - * - * The result should be averaged over the volume (e.g. phase mass - * inside a sub-control volume divided by the volume) - * - * \param storage The mass of the component within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() - : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - // compute storage term of all components within all phases - storage = 0; - - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx) - { - unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx; - storage[eqIdx] += volVars.density(phaseIdx) - * volVars.saturation(phaseIdx) - * volVars.fluidState().massFraction(phaseIdx, compIdx); - } - // this is only processed, if one component mass balance equation - // is replaced by the total mass balance equation - if (replaceCompEqIdx < numComponents) - storage[replaceCompEqIdx] += - volVars.density(phaseIdx) - * volVars.saturation(phaseIdx); - } - storage *= volVars.porosity(); - } - - /*! - * \brief Evaluates the total flux of all conservation quantities - * over a face of a sub-control volume. - * - * \param flux The flux over the SCV (sub-control-volume) face for each component - * \param faceIdx The index of the SCV face - * \param onBoundary Evaluate flux at inner SCV face or on a boundary face - */ - void computeFlux(PrimaryVariables &flux, const int faceIdx, bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - - flux = 0; - asImp_()->computeAdvectiveFlux(flux, fluxVars); - Valgrind::CheckDefined(flux); - asImp_()->computeDiffusiveFlux(flux, fluxVars); - Valgrind::CheckDefined(flux); - } - - /*! - * \brief Evaluates the advective mass flux of all components over - * a face of a sub-control volume. - * - * \param flux The advective flux over the sub-control-volume face for each component - * \param fluxVars The flux variables at the current SCV face - */ - void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - //////// - // advective fluxes of all components in all phases - //////// - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &up = - this->curVolVars_(fluxVars.upstreamIdx(phaseIdx)); - const VolumeVariables &dn = - this->curVolVars_(fluxVars.downstreamIdx(phaseIdx)); - - for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx) - { - unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx; - // add advective flux of current component in current - // phase - if (massUpwindWeight_ > 0.0) - // upstream vertex - flux[eqIdx] += - fluxVars.volumeFlux(phaseIdx) - * massUpwindWeight_ - * up.density(phaseIdx) - * up.fluidState().massFraction(phaseIdx, compIdx); - if (massUpwindWeight_ < 1.0) - // downstream vertex - flux[eqIdx] += - fluxVars.volumeFlux(phaseIdx) - * (1 - massUpwindWeight_) - * dn.density(phaseIdx) - * dn.fluidState().massFraction(phaseIdx, compIdx); - - Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx)); - Valgrind::CheckDefined(up.density(phaseIdx)); - Valgrind::CheckDefined(up.fluidState().massFraction(phaseIdx, compIdx)); - Valgrind::CheckDefined(dn.density(phaseIdx)); - Valgrind::CheckDefined(dn.fluidState().massFraction(phaseIdx, compIdx)); - } - // flux of the total mass balance; - // this is only processed, if one component mass balance equation - // is replaced by a total mass balance equation - if (replaceCompEqIdx < numComponents) - { - // upstream vertex - if (massUpwindWeight_ > 0.0) - flux[replaceCompEqIdx] += - fluxVars.volumeFlux(phaseIdx) - * massUpwindWeight_ - * up.density(phaseIdx); - // downstream vertex - if (massUpwindWeight_ < 1.0) - flux[replaceCompEqIdx] += - fluxVars.volumeFlux(phaseIdx) - * (1 - massUpwindWeight_) - * dn.density(phaseIdx); - Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx)); - Valgrind::CheckDefined(up.density(phaseIdx)); - Valgrind::CheckDefined(dn.density(phaseIdx)); - - } - - } - } - - /*! - * \brief Adds the diffusive mass flux of all components over - * a face of a sub-control volume. - * - * \param flux The diffusive flux over the sub-control-volume face for each component - * \param fluxVars The flux variables at the current sub control volume face - */ - void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - // add diffusive flux of gas component in liquid phase - Scalar tmp = fluxVars.moleFractionGrad(wPhaseIdx)*fluxVars.face().normal; - tmp *= -1; - tmp *= - fluxVars.porousDiffCoeff(wPhaseIdx) * - fluxVars.molarDensity(wPhaseIdx); - // add the diffusive fluxes only to the component mass balance - if (replaceCompEqIdx != contiNEqIdx) - flux[contiNEqIdx] += tmp * FluidSystem::molarMass(nCompIdx); - if (replaceCompEqIdx != contiWEqIdx) - flux[contiWEqIdx] -= tmp * FluidSystem::molarMass(wCompIdx); - - // add diffusive flux of liquid component in non-wetting phase - tmp = fluxVars.moleFractionGrad(nPhaseIdx)*fluxVars.face().normal; - tmp *= -1; - tmp *= - fluxVars.porousDiffCoeff(nPhaseIdx) * - fluxVars.molarDensity(nPhaseIdx); - // add the diffusive fluxes only to the component mass balance - if (replaceCompEqIdx != contiWEqIdx) - flux[contiWEqIdx] += tmp * FluidSystem::molarMass(wCompIdx); - if (replaceCompEqIdx != contiNEqIdx) - flux[contiNEqIdx] -= tmp * FluidSystem::molarMass(nCompIdx); - } - - /*! - * \brief Calculate the source term of the equation - * - * \param source The source/sink in the sub-control volume for each component - * \param scvIdx The index of the sub-control volume - */ - void computeSource(PrimaryVariables& source, const int scvIdx) - { - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - - protected: - void evalPhaseStorage_(const int phaseIdx) - { - // evaluate the storage terms of a single phase - for (int i=0; i < this->fvGeometry_().numSCV; i++) { - PrimaryVariables &storage = this->storageTerm_[i]; - const ElementVolumeVariables &elemVolVars = this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[i]; - - // compute storage term of all components within all phases - storage = 0; - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - { - int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx; - storage[eqIdx] += volVars.density(phaseIdx) - * volVars.saturation(phaseIdx) - * volVars.fluidState().massFraction(phaseIdx, compIdx); - } - - storage *= volVars.porosity(); - storage *= this->fvGeometry_().subContVol[i].volume; - } - } - - /*! - * \brief Return the equation index of the first mass-balance equation - * of the component (used for loops); if one component mass balance - * is replaced by the total mass balance, this is the index - * of the remaining component mass-balance equation. - */ - unsigned int contiCompIdx1_() const { - switch (replaceCompEqIdx) - { - case contiWEqIdx: return contiNEqIdx; - case contiNEqIdx: return contiWEqIdx; - default: return 0; - } - } - - /*! - * \brief Return the equation index of the second mass balance - * of the component (used for loops); - * if one component mass balance is replaced by the total mass balance - * (replaceCompEqIdx < 2), this index is the same as contiCompIdx1(). - */ - unsigned int contiCompIdx2_() const { - switch (replaceCompEqIdx) - { - case contiWEqIdx: return contiNEqIdx; - case contiNEqIdx: return contiWEqIdx; - default: return numComponents-1; - } - } - - Implementation *asImp_() - { return static_cast<Implementation *> (this); } - const Implementation *asImp_() const - { return static_cast<const Implementation *> (this); } - - private: - Scalar massUpwindWeight_; -}; - -} // end namespace - -#endif +#include <dumux/implicit/2p2c/2p2clocalresidual.hh> diff --git a/dumux/boxmodels/2p2c/2p2cmodel.hh b/dumux/boxmodels/2p2c/2p2cmodel.hh index b3b395a54dc607c5bf8ebc0f66ec10fefe70ce61..d4a14aaa6770c727e65e78d0eb861e501e12c7fc 100644 --- a/dumux/boxmodels/2p2c/2p2cmodel.hh +++ b/dumux/boxmodels/2p2c/2p2cmodel.hh @@ -1,825 +1,3 @@ -// -*- 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 Adaption of the BOX scheme to the two-phase two-component flow model. - */ -#ifndef DUMUX_2P2C_MODEL_HH -#define DUMUX_2P2C_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cmodel.hh instead. -#include "2p2cproperties.hh" -#include "2p2clocalresidual.hh" - -namespace Dumux -{ -/*! - * \ingroup TwoPTwoCModel - * \brief Adaption of the BOX scheme to the two-phase two-component flow model. - * - * This model implements two-phase two-component flow of two compressible and - * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the two components - * \f$\kappa \in \{ w, a \}\f$. The standard multiphase Darcy - * approach is used as the equation for the conservation of momentum: - * \f[ - v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} - \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right) - * \f] - * - * By inserting this into the equations for the conservation of the - * components, one gets one transport equation for each component - * \f{eqnarray*} - && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa S_\alpha )} - {\partial t} - - \sum_\alpha \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} - (\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g}) \right\} - \nonumber \\ \nonumber \\ - &-& \sum_\alpha \text{div} \left\{{\bf D}_{\alpha, pm}^\kappa \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\} - - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a\} \, , - \alpha \in \{w, g\} - \f} - * - * This is discretized using a fully-coupled vertex - * centered finite volume (box) scheme as spatial and - * the implicit Euler method as temporal discretization. - * - * By using constitutive relations for the capillary pressure \f$p_c = - * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking - * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of - * unknowns can be reduced to two. - * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$ - * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be - * specified by setting the <tt>Formulation</tt> property to either - * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By - * default, the model uses \f$p_w\f$ and \f$S_n\f$. - * Moreover, the second primary variable depends on the phase state, since a - * primary variable switch is included. The phase state is stored for all nodes - * of the system. Following cases can be distinguished: - * <ul> - * <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>), - * as long as \f$ 0 < S_\alpha < 1\f$</li>. - * <li> Only wetting phase is present: The mass fraction of, e.g., air in the wetting phase \f$X^a_w\f$ is used, - * as long as the maximum mass fraction is not exceeded \f$(X^a_w<X^a_{w,max})\f$</li> - * <li> Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase, \f$X^w_n\f$, is used, - * as long as the maximum mass fraction is not exceeded \f$(X^w_n<X^w_{n,max})\f$</li> - * </ul> - */ - -template<class TypeTag> -class TwoPTwoCModel: public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, - - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases, - - pwSn = TwoPTwoCFormulation::pwSn, - pnSw = TwoPTwoCFormulation::pnSw, - formulation = GET_PROP_VALUE(TypeTag, Formulation) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::ctype CoordScalar; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef typename GridView::template Codim<dim>::Entity Vertex; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, numPhases> PhasesVector; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - -public: - /*! - * \brief Initialize the static data with the initial solution. - * - * \param problem The problem to be solved - */ - void init(Problem &problem) - { - ParentType::init(problem); - - unsigned numDofs = this->numDofs(); - unsigned numVertices = this->problem_().gridView().size(dim); - - staticVertexDat_.resize(numDofs); - - setSwitched_(false); - - // check, if velocity output can be used (works only for cubes so far) - velocityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocity); - ElementIterator eIt = this->gridView_().template begin<0>(); - ElementIterator eEndIt = this->gridView_().template end<0>(); - for (; eIt != eEndIt; ++eIt) - { - if(eIt->geometry().type().isCube() == false){ - velocityOutput_ = false; - } - - if (numDofs != numVertices) // i.e. cell-centered discretization - { - velocityOutput_ = false; - - int globalIdx = this->dofMapper().map(*eIt); - const GlobalPosition &globalPos = eIt->geometry().center(); - - // initialize phase presence - staticVertexDat_[globalIdx].phasePresence - = this->problem_().initialPhasePresence(*(this->gridView_().template begin<dim>()), - globalIdx, globalPos); - staticVertexDat_[globalIdx].wasSwitched = false; - - staticVertexDat_[globalIdx].oldPhasePresence - = staticVertexDat_[globalIdx].phasePresence; - } - } - - if (velocityOutput_ != GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocity)) - std::cout << "ATTENTION: Velocity output only works for cubes and is set to false for simplices\n"; - - if (numDofs == numVertices) // i.e. vertex-centered discretization - { - VertexIterator vIt = this->gridView_().template begin<dim> (); - const VertexIterator &vEndIt = this->gridView_().template end<dim> (); - for (; vIt != vEndIt; ++vIt) - { - int globalIdx = this->dofMapper().map(*vIt); - const GlobalPosition &globalPos = vIt->geometry().corner(0); - - // initialize phase presence - staticVertexDat_[globalIdx].phasePresence - = this->problem_().initialPhasePresence(*vIt, globalIdx, - globalPos); - staticVertexDat_[globalIdx].wasSwitched = false; - - staticVertexDat_[globalIdx].oldPhasePresence - = staticVertexDat_[globalIdx].phasePresence; - } - } - } - - /*! - * \brief Compute the total storage inside one phase of all - * conservation quantities. - * - * \param storage Contains the storage of each component for one phase - * \param phaseIdx The phase index - */ - void globalPhaseStorage(PrimaryVariables &storage, const int phaseIdx) - { - storage = 0; - - ElementIterator eIt = this->gridView_().template begin<0>(); - const ElementIterator eEndIt = this->gridView_().template end<0>(); - for (; eIt != eEndIt; ++eIt) { - this->localResidual().evalPhaseStorage(*eIt, phaseIdx); - - for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i) - storage += this->localResidual().storageTerm()[i]; - } - - if (this->gridView_().comm().size() > 1) - storage = this->gridView_().comm().sum(storage); - } - - /*! - * \brief Called by the update() method if applying the newton - * method was unsuccessful. - */ - void updateFailed() - { - ParentType::updateFailed(); - - setSwitched_(false); - resetPhasePresence_(); - }; - - /*! - * \brief Called by the problem if a time integration was - * successful, post processing of the solution is done and the - * result has been written to disk. - * - * This should prepare the model for the next time integration. - */ - void advanceTimeLevel() - { - ParentType::advanceTimeLevel(); - - // update the phase state - updateOldPhasePresence_(); - setSwitched_(false); - } - - /*! - * \brief Return true if the primary variables were switched for - * at least one vertex after the last timestep. - */ - bool switched() const - { - return switchFlag_; - } - - /*! - * \brief Returns the phase presence of the current or the old solution of a vertex. - * - * \param globalIdx The global vertex index - * \param oldSol Evaluate function with solution of current or previous time step - */ - int phasePresence(int globalIdx, bool oldSol) const - { - return oldSol ? staticVertexDat_[globalIdx].oldPhasePresence - : staticVertexDat_[globalIdx].phasePresence; - } - - /*! - * \brief Append all quantities of interest which can be derived - * from the solution of the current time step to the VTK - * writer. - * - * \param sol The solution vector - * \param writer The writer for multi-file VTK datasets - */ - template<class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField; - - // create the required scalar fields - unsigned numDofs = this->numDofs(); - unsigned numVertices = this->problem_().gridView().size(dim); - - // velocity output currently only works for vertex data - if (numDofs != numVertices) - velocityOutput_ = false; - - ScalarField *sN = writer.allocateManagedBuffer(numDofs); - ScalarField *sW = writer.allocateManagedBuffer(numDofs); - ScalarField *pN = writer.allocateManagedBuffer(numDofs); - ScalarField *pW = writer.allocateManagedBuffer(numDofs); - ScalarField *pC = writer.allocateManagedBuffer(numDofs); - ScalarField *rhoW = writer.allocateManagedBuffer(numDofs); - ScalarField *rhoN = writer.allocateManagedBuffer(numDofs); - ScalarField *mobW = writer.allocateManagedBuffer(numDofs); - ScalarField *mobN = writer.allocateManagedBuffer(numDofs); - ScalarField *phasePresence = writer.allocateManagedBuffer(numDofs); - ScalarField *massFrac[numPhases][numComponents]; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - massFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numDofs); - ScalarField *temperature = writer.allocateManagedBuffer(numDofs); - ScalarField *poro = writer.allocateManagedBuffer(numDofs); - ScalarField *cellNum =writer.allocateManagedBuffer (numDofs); - VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs); - VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs); - - if(velocityOutput_) // check if velocity output is demanded - { - // initialize velocity fields - for (unsigned int i = 0; i < numDofs; ++i) - { - (*velocityN)[i] = Scalar(0); - (*velocityW)[i] = Scalar(0); - (*cellNum)[i] = Scalar(0.0); - } - } - - unsigned numElements = this->gridView_().size(0); - ScalarField *rank = writer.allocateManagedBuffer(numElements); - - FVElementGeometry fvGeometry; - VolumeVariables volVars; - - ElementIterator eIt = this->gridView_().template begin<0>(); - ElementIterator eEndIt = this->gridView_().template end<0>(); - for (; eIt != eEndIt; ++eIt) - { - int idx = this->elementMapper().map(*eIt); - (*rank)[idx] = this->gridView_().comm().rank(); - fvGeometry.update(this->gridView_(), *eIt); - - for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx) - { - int globalIdx; - if (numDofs == numElements) // element data - globalIdx = idx; - else - globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim); - - volVars.update(sol[globalIdx], - this->problem_(), - *eIt, - fvGeometry, - scvIdx, - false); - (*sN)[globalIdx] = volVars.saturation(nPhaseIdx); - (*sW)[globalIdx] = volVars.saturation(wPhaseIdx); - (*pN)[globalIdx] = volVars.pressure(nPhaseIdx); - (*pW)[globalIdx] = volVars.pressure(wPhaseIdx); - (*pC)[globalIdx] = volVars.capillaryPressure(); - (*rhoW)[globalIdx] = volVars.fluidState().density(wPhaseIdx); - (*rhoN)[globalIdx] = volVars.fluidState().density(nPhaseIdx); - (*mobW)[globalIdx] = volVars.mobility(wPhaseIdx); - (*mobN)[globalIdx] = volVars.mobility(nPhaseIdx); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - { - (*massFrac[phaseIdx][compIdx])[globalIdx] - = volVars.fluidState().massFraction(phaseIdx, compIdx); - - Valgrind::CheckDefined((*massFrac[phaseIdx][compIdx])[globalIdx][0]); - } - (*poro)[globalIdx] = volVars.porosity(); - (*temperature)[globalIdx] = volVars.temperature(); - (*phasePresence)[globalIdx] - = staticVertexDat_[globalIdx].phasePresence; - if(velocityOutput_) - { - (*cellNum)[globalIdx] += 1; - } - } - - if(velocityOutput_) - { - // calculate vertex velocities - GlobalPosition tmpVelocity[numPhases]; - - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - tmpVelocity[phaseIdx] = Scalar(0.0); - } - - typedef Dune::BlockVector<Dune::FieldVector<Scalar, dim> > SCVVelocities; - SCVVelocities scvVelocityW(8), scvVelocityN(8); - - scvVelocityW = 0; - scvVelocityN = 0; - - ElementVolumeVariables elemVolVars; - - elemVolVars.update(this->problem_(), - *eIt, - fvGeometry, - false /* oldSol? */); - - for (int faceIdx = 0; faceIdx < fvGeometry.numEdges; faceIdx++) - { - - FluxVariables fluxVars(this->problem_(), - *eIt, - fvGeometry, - faceIdx, - elemVolVars); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // local position of integration point - const Dune::FieldVector<Scalar, dim>& localPosIP = fvGeometry.subContVolFace[faceIdx].ipLocal; - - // Transformation of the global normal vector to normal vector in the reference element - const typename Element::Geometry::JacobianTransposed jacobianT1 = - eIt->geometry().jacobianTransposed(localPosIP); - const GlobalPosition globalNormal = fluxVars.face().normal; - - GlobalPosition localNormal(0); - jacobianT1.mv(globalNormal, localNormal); - // note only works for cubes - const Scalar localArea = pow(2,-(dim-1)); - - localNormal /= localNormal.two_norm(); - - // Get the Darcy velocities. The Darcy velocities are divided by the area of the subcontrolvolume - // face in the reference element. - PhasesVector flux; - flux[phaseIdx] = fluxVars.volumeFlux(phaseIdx) / localArea; - - // transform the normal Darcy velocity into a vector - tmpVelocity[phaseIdx] = localNormal; - tmpVelocity[phaseIdx] *= flux[phaseIdx]; - - if(phaseIdx == wPhaseIdx){ - scvVelocityW[fluxVars.face().i] += tmpVelocity[phaseIdx]; - scvVelocityW[fluxVars.face().j] += tmpVelocity[phaseIdx]; - } - else if(phaseIdx == nPhaseIdx){ - scvVelocityN[fluxVars.face().i] += tmpVelocity[phaseIdx]; - scvVelocityN[fluxVars.face().j] += tmpVelocity[phaseIdx]; - } - } - } - - typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElements; - const Dune::FieldVector<Scalar, dim>& localPos = - ReferenceElements::general(eIt->geometry().type()).position(0, 0); - - // get the transposed Jacobian of the element mapping - const typename Element::Geometry::JacobianTransposed jacobianT2 = - eIt->geometry().jacobianTransposed(localPos); - - // transform vertex velocities from local to global coordinates - for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx) - { - int globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim); - // calculate the subcontrolvolume velocity by the Piola transformation - Dune::FieldVector<CoordScalar, dim> scvVelocity(0); - - jacobianT2.mtv(scvVelocityW[scvIdx], scvVelocity); - scvVelocity /= eIt->geometry().integrationElement(localPos); - // add up the wetting phase subcontrolvolume velocities for each vertex - (*velocityW)[globalIdx] += scvVelocity; - - jacobianT2.mtv(scvVelocityN[scvIdx], scvVelocity); - scvVelocity /= eIt->geometry().integrationElement(localPos); - // add up the nonwetting phase subcontrolvolume velocities for each vertex - (*velocityN)[globalIdx] += scvVelocity; - } - } // velocity output - } // loop over elements - - if(velocityOutput_) - { - // divide the vertex velocities by the number of adjacent scvs i.e. cells - for(unsigned int globalIdx = 0; globalIdx < numDofs; ++globalIdx){ - (*velocityW)[globalIdx] /= (*cellNum)[globalIdx]; - (*velocityN)[globalIdx] /= (*cellNum)[globalIdx]; - } - } - - if (numDofs == numElements) // element data - { - writer.attachCellData(*sN, "Sn"); - writer.attachCellData(*sW, "Sw"); - writer.attachCellData(*pN, "pN"); - writer.attachCellData(*pW, "pW"); - writer.attachCellData(*pC, "pC"); - writer.attachCellData(*rhoW, "rhoW"); - writer.attachCellData(*rhoN, "rhoN"); - writer.attachCellData(*mobW, "mobW"); - writer.attachCellData(*mobN, "mobN"); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - { - std::ostringstream oss; - oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx); - writer.attachCellData(*massFrac[phaseIdx][compIdx], oss.str()); - } - } - writer.attachCellData(*poro, "porosity"); - writer.attachCellData(*temperature, "temperature"); - writer.attachCellData(*phasePresence, "phase presence"); - } - else - { - writer.attachVertexData(*sN, "Sn"); - writer.attachVertexData(*sW, "Sw"); - writer.attachVertexData(*pN, "pN"); - writer.attachVertexData(*pW, "pW"); - writer.attachVertexData(*pC, "pC"); - writer.attachVertexData(*rhoW, "rhoW"); - writer.attachVertexData(*rhoN, "rhoN"); - writer.attachVertexData(*mobW, "mobW"); - writer.attachVertexData(*mobN, "mobN"); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - { - std::ostringstream oss; - oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx); - writer.attachVertexData(*massFrac[phaseIdx][compIdx], oss.str()); - } - } - writer.attachVertexData(*poro, "porosity"); - writer.attachVertexData(*temperature, "temperature"); - writer.attachVertexData(*phasePresence, "phase presence"); - - if(velocityOutput_) // check if velocity output is demanded - { - writer.attachVertexData(*velocityW, "velocityW", dim); - writer.attachVertexData(*velocityN, "velocityN", dim); - } - } - - writer.attachCellData(*rank, "process rank"); - } - - /*! - * \brief Write the current solution to a restart file. - * - * \param outStream The output stream of one vertex for the restart file - * \param entity The entity, either a vertex or an element - */ - template<class Entity> - void serializeEntity(std::ostream &outStream, const Entity &entity) - { - // write primary variables - ParentType::serializeEntity(outStream, entity); - - int globalIdx = this->dofMapper().map(entity); - if (!outStream.good()) - DUNE_THROW(Dune::IOError, "Could not serialize entity " << globalIdx); - - outStream << staticVertexDat_[globalIdx].phasePresence << " "; - } - - /*! - * \brief Reads the current solution from a restart file. - * - * \param inStream The input stream of one vertex from the restart file - * \param entity The entity, either a vertex or an element - */ - template<class Entity> - void deserializeEntity(std::istream &inStream, const Entity &entity) - { - // read primary variables - ParentType::deserializeEntity(inStream, entity); - - // read phase presence - int globalIdx = this->dofMapper().map(entity); - if (!inStream.good()) - DUNE_THROW(Dune::IOError, - "Could not deserialize entity " << globalIdx); - - inStream >> staticVertexDat_[globalIdx].phasePresence; - staticVertexDat_[globalIdx].oldPhasePresence - = staticVertexDat_[globalIdx].phasePresence; - - } - - /*! - * \brief Update the static data of all vertices in the grid. - * - * \param curGlobalSol The current global solution - * \param oldGlobalSol The previous global solution - */ - void updateStaticData(SolutionVector &curGlobalSol, - const SolutionVector &oldGlobalSol) - { - bool wasSwitched = false; - - for (unsigned i = 0; i < staticVertexDat_.size(); ++i) - staticVertexDat_[i].visited = false; - - unsigned numDofs = this->numDofs(); - unsigned numVertices = this->problem_().gridView().size(dim); - - FVElementGeometry fvGeometry; - static VolumeVariables volVars; - ElementIterator eIt = this->gridView_().template begin<0> (); - const ElementIterator &eEndIt = this->gridView_().template end<0> (); - for (; eIt != eEndIt; ++eIt) - { - fvGeometry.update(this->gridView_(), *eIt); - for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx) - { - int globalIdx; - - if (numDofs != numVertices) - globalIdx = this->elementMapper().map(*eIt); - else - globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim); - - if (staticVertexDat_[globalIdx].visited) - continue; - - staticVertexDat_[globalIdx].visited = true; - volVars.update(curGlobalSol[globalIdx], - this->problem_(), - *eIt, - fvGeometry, - scvIdx, - false); - const GlobalPosition &globalPos = eIt->geometry().corner(scvIdx); - if (primaryVarSwitch_(curGlobalSol, - volVars, - globalIdx, - globalPos)) - { - this->jacobianAssembler().markVertexRed(globalIdx); - wasSwitched = true; - } - } - } - - // make sure that if there was a variable switch in an - // other partition we will also set the switch flag - // for our partition. - if (this->gridView_().comm().size() > 1) - wasSwitched = this->gridView_().comm().max(wasSwitched); - - setSwitched_(wasSwitched); - } - -protected: - /*! - * \brief Data which is attached to each vertex and is not only - * stored locally. - */ - struct StaticVars - { - int phasePresence; - bool wasSwitched; - - int oldPhasePresence; - bool visited; - }; - - /*! - * \brief Reset the current phase presence of all vertices to the old one. - * - * This is done after an update failed. - */ - void resetPhasePresence_() - { - for (unsigned int idx = 0; idx < staticVertexDat_.size(); ++idx) - { - staticVertexDat_[idx].phasePresence - = staticVertexDat_[idx].oldPhasePresence; - staticVertexDat_[idx].wasSwitched = false; - } - } - - /*! - * \brief Set the old phase of all verts state to the current one. - */ - void updateOldPhasePresence_() - { - for (unsigned int idx = 0; idx < staticVertexDat_.size(); ++idx) - { - staticVertexDat_[idx].oldPhasePresence - = staticVertexDat_[idx].phasePresence; - staticVertexDat_[idx].wasSwitched = false; - } - } - - /*! - * \brief Set whether there was a primary variable switch after in - * the last timestep. - */ - void setSwitched_(bool yesno) - { - switchFlag_ = yesno; - } - - // perform variable switch at a vertex; Returns true if a - // variable switch was performed. - bool primaryVarSwitch_(SolutionVector &globalSol, - const VolumeVariables &volVars, int globalIdx, - const GlobalPosition &globalPos) - { - // evaluate primary variable switch - bool wouldSwitch = false; - int phasePresence = staticVertexDat_[globalIdx].phasePresence; - int newPhasePresence = phasePresence; - - // check if a primary var switch is necessary - if (phasePresence == nPhaseOnly) - { - // calculate mole fraction in the hypothetic wetting phase - Scalar xww = volVars.fluidState().moleFraction(wPhaseIdx, wCompIdx); - Scalar xwn = volVars.fluidState().moleFraction(wPhaseIdx, nCompIdx); - - Scalar xwMax = 1.0; - if (xww + xwn > xwMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xwMax *= 1.02; - - // if the sum of the mole fractions would be larger than - // 100%, wetting phase appears - if (xww + xwn > xwMax) - { - // wetting phase appears - std::cout << "wetting phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xww + xwn: " - << xww + xwn << std::endl; - newPhasePresence = bothPhases; - if (formulation == pnSw) - globalSol[globalIdx][switchIdx] = 0.0; - else if (formulation == pwSn) - globalSol[globalIdx][switchIdx] = 1.0; - } - } - else if (phasePresence == wPhaseOnly) - { - // calculate fractions of the partial pressures in the - // hypothetic nonwetting phase - Scalar xnw = volVars.fluidState().moleFraction(nPhaseIdx, wCompIdx); - Scalar xnn = volVars.fluidState().moleFraction(nPhaseIdx, nCompIdx); - - Scalar xgMax = 1.0; - if (xnw + xnn > xgMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xgMax *= 1.02; - - // if the sum of the mole fractions would be larger than - // 100%, nonwetting phase appears - if (xnw + xnn > xgMax) - { - // nonwetting phase appears - std::cout << "nonwetting phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xnw + xnn: " - << xnw + xnn << std::endl; - newPhasePresence = bothPhases; - if (formulation == pnSw) - globalSol[globalIdx][switchIdx] = 0.999; - else if (formulation == pwSn) - globalSol[globalIdx][switchIdx] = 0.001; - } - } - else if (phasePresence == bothPhases) - { - Scalar Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(nPhaseIdx) <= Smin) - { - wouldSwitch = true; - // nonwetting phase disappears - std::cout << "Nonwetting phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = wPhaseOnly; - - globalSol[globalIdx][switchIdx] - = volVars.fluidState().massFraction(wPhaseIdx, nCompIdx); - } - else if (volVars.saturation(wPhaseIdx) <= Smin) - { - wouldSwitch = true; - // wetting phase disappears - std::cout << "Wetting phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = nPhaseOnly; - - globalSol[globalIdx][switchIdx] - = volVars.fluidState().massFraction(nPhaseIdx, wCompIdx); - } - } - - staticVertexDat_[globalIdx].phasePresence = newPhasePresence; - staticVertexDat_[globalIdx].wasSwitched = wouldSwitch; - return phasePresence != newPhasePresence; - } - -protected: - // parameters given in constructor - std::vector<StaticVars> staticVertexDat_; - bool switchFlag_; - bool velocityOutput_; -}; - -} - -#include "2p2cpropertydefaults.hh" - -#endif +#include <dumux/implicit/2p2c/2p2cmodel.hh> diff --git a/dumux/boxmodels/2p2c/2p2cnewtoncontroller.hh b/dumux/boxmodels/2p2c/2p2cnewtoncontroller.hh index 374ccf593149887af75b61ee6a69d648e48b9727..d432f72a469d4ea2877bada3adead3efccc9b352 100644 --- a/dumux/boxmodels/2p2c/2p2cnewtoncontroller.hh +++ b/dumux/boxmodels/2p2c/2p2cnewtoncontroller.hh @@ -1,110 +1,3 @@ -// -*- 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 A 2p2c specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * which allows the newton method to abort quicker if the solution is - * way out of bounds. - */ -#ifndef DUMUX_2P2C_NEWTON_CONTROLLER_HH -#define DUMUX_2P2C_NEWTON_CONTROLLER_HH +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cnewtoncontroller.hh instead. -#include "2p2cproperties.hh" - -#include <dumux/nonlinear/newtoncontroller.hh> - -namespace Dumux { - -/*! - * \ingroup Newton - * \ingroup TwoPTwoCModel - * \brief A 2p2c specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * which allows the newton method to abort quicker if the solution is - * way out of bounds. - */ -template <class TypeTag> -class TwoPTwoCNewtonController : public NewtonController<TypeTag> -{ - typedef NewtonController<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - -public: - TwoPTwoCNewtonController(const Problem &problem) - : ParentType(problem) - {} - - /*! - * \brief - * Suggest a new time step size based either on the number of newton - * iterations required or on the variable switch - * - * \param uCurrentIter The current global solution vector - * \param uLastIter The previous global solution vector - * - */ - void newtonEndStep(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - int succeeded; - try { - // call the method of the base class - this->method().model().updateStaticData(uCurrentIter, uLastIter); - ParentType::newtonEndStep(uCurrentIter, uLastIter); - - succeeded = 1; - if (this->gridView_().comm().size() > 1) - succeeded = this->gridView_().comm().min(succeeded); - } - catch (Dumux::NumericalProblem &e) - { - std::cout << "rank " << this->problem_().gridView().comm().rank() - << " caught an exception while updating:" << e.what() - << "\n"; - succeeded = 0; - if (this->gridView_().comm().size() > 1) - succeeded = this->gridView_().comm().min(succeeded); - } - - if (!succeeded) { - DUNE_THROW(NumericalProblem, - "A process did not succeed in linearizing the system"); - } - } - - /*! - * \brief - * Returns true if the current solution can be considered to - * be accurate enough - */ - bool newtonConverged() - { - if (this->method().model().switched()) - return false; - - return ParentType::newtonConverged(); - } -}; -} - -#endif +#include <dumux/implicit/2p2c/2p2cnewtoncontroller.hh> diff --git a/dumux/boxmodels/2p2c/2p2cproperties.hh b/dumux/boxmodels/2p2c/2p2cproperties.hh index 030351420579d6bccabc52fb81a638853962312e..e220a2e971608f70075e6c0332a4f7483dac4e50 100644 --- a/dumux/boxmodels/2p2c/2p2cproperties.hh +++ b/dumux/boxmodels/2p2c/2p2cproperties.hh @@ -1,70 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPTwoCModel - */ -/*! - * \file - * - * \brief Defines the properties required for the 2p2c BOX model. - */ -#ifndef DUMUX_2P2C_PROPERTIES_HH -#define DUMUX_2P2C_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cproperties.hh instead. -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the isothermal single phase problems -NEW_TYPE_TAG(BoxTwoPTwoC, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system -NEW_PROP_TAG(Indices); //!< Enumerations for the model -NEW_PROP_TAG(Formulation); //!< The formulation of the model -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters -NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations - -NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the spatial parameters) -NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters) - -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind weight for the mass conservation equations -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation -NEW_PROP_TAG(ReplaceCompEqIdx); //!< The index of the total mass balance equation, if one component balance is replaced (ReplaceCompEqIdx < NumComponents) -NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output -NEW_PROP_TAG(BaseFluxVariables); //! The base flux variables -NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient -} -} - -#endif +#include <dumux/implicit/2p2c/2p2cproperties.hh> diff --git a/dumux/boxmodels/2p2c/2p2cpropertydefaults.hh b/dumux/boxmodels/2p2c/2p2cpropertydefaults.hh index 98c9a1f33379c8cbad0711b009a853027be3ea12..79d76668eaf098a7ed6329c769ce1c3c24f0723b 100644 --- a/dumux/boxmodels/2p2c/2p2cpropertydefaults.hh +++ b/dumux/boxmodels/2p2c/2p2cpropertydefaults.hh @@ -1,160 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPTwoCModel - * \file - * - * \brief Defines default values for most properties required by the - * 2p2c box model. - */ -#ifndef DUMUX_2P2C_PROPERTY_DEFAULTS_HH -#define DUMUX_2P2C_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cpropertydefaults.hh instead. -#include "2p2cmodel.hh" -#include "2p2cindices.hh" -#include "2p2cfluxvariables.hh" -#include "2p2cvolumevariables.hh" -#include "2p2cproperties.hh" -#include "2p2cnewtoncontroller.hh" - -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include <dumux/material/spatialparams/boxspatialparams.hh> - -namespace Dumux -{ - -namespace Properties { -////////////////////////////////////////////////////////////////// -// Property values -////////////////////////////////////////////////////////////////// - -/*! - * \brief Set the property for the number of components. - * - * We just forward the number from the fluid system and use an static - * assert to make sure it is 2. - */ -SET_PROP(BoxTwoPTwoC, NumComponents) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - public: - static const int value = FluidSystem::numComponents; - - static_assert(value == 2, - "Only fluid systems with 2 components are supported by the 2p-2c model!"); -}; - -/*! - * \brief Set the property for the number of fluid phases. - * - * We just forward the number from the fluid system and use an static - * assert to make sure it is 2. - */ -SET_PROP(BoxTwoPTwoC, NumPhases) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - public: - static const int value = FluidSystem::numPhases; - static_assert(value == 2, - "Only fluid systems with 2 phases are supported by the 2p-2c model!"); -}; - -SET_INT_PROP(BoxTwoPTwoC, NumEq, 2); //!< set the number of equations to 2 - -//! Set the default formulation to pw-Sn -SET_INT_PROP(BoxTwoPTwoC, - Formulation, - TwoPTwoCFormulation::pwSn); - -//! set as default that no component mass balance is replaced by the total mass balance -SET_INT_PROP(BoxTwoPTwoC, ReplaceCompEqIdx, 2); - -/*! - * \brief Set the property for the material parameters by extracting - * it from the material law. - */ -SET_PROP(BoxTwoPTwoC, MaterialLawParams) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - - public: - typedef typename MaterialLaw::Params type; -}; - -//! Use the 2p2c local jacobian operator for the 2p2c model -SET_TYPE_PROP(BoxTwoPTwoC, - LocalResidual, - TwoPTwoCLocalResidual<TypeTag>); - -//! Use the 2p2c specific newton controller for the 2p2c model -SET_TYPE_PROP(BoxTwoPTwoC, NewtonController, TwoPTwoCNewtonController<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxTwoPTwoC, Model, TwoPTwoCModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxTwoPTwoC, VolumeVariables, TwoPTwoCVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxTwoPTwoC, FluxVariables, TwoPTwoCFluxVariables<TypeTag>); - -//! define the base flux variables to realize Darcy flow -SET_TYPE_PROP(BoxTwoPTwoC, BaseFluxVariables, BoxDarcyFluxVariables<TypeTag>); - -//! the upwind weight for the mass conservation equations. -SET_SCALAR_PROP(BoxTwoPTwoC, ImplicitMassUpwindWeight, 1.0); - -//! set default mobility upwind weight to 1.0, i.e. fully upwind -SET_SCALAR_PROP(BoxTwoPTwoC, ImplicitMobilityUpwindWeight, 1.0); - -//! The indices required by the isothermal 2p2c model -SET_PROP(BoxTwoPTwoC, Indices) -{ private: - enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) }; - public: - typedef TwoPTwoCIndices<TypeTag, Formulation, 0> type; -}; - -//! The spatial parameters to be employed. -//! Use BoxSpatialParams by default. -SET_TYPE_PROP(BoxTwoPTwoC, SpatialParams, BoxSpatialParams<TypeTag>); - -// disable velocity output by default -SET_BOOL_PROP(BoxTwoPTwoC, VtkAddVelocity, false); - -// enable gravity by default -SET_BOOL_PROP(BoxTwoPTwoC, ProblemEnableGravity, true); - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55);} - -} - -#endif +#include <dumux/implicit/2p2c/2p2cpropertydefaults.hh> diff --git a/dumux/boxmodels/2p2c/2p2cvolumevariables.hh b/dumux/boxmodels/2p2c/2p2cvolumevariables.hh index f097db5c2005ac0753e8cd476923435474c6eb65..e8b66cb1bb5f75831e40ffd63c09e5f07909be16 100644 --- a/dumux/boxmodels/2p2c/2p2cvolumevariables.hh +++ b/dumux/boxmodels/2p2c/2p2cvolumevariables.hh @@ -1,455 +1,3 @@ -// -*- 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 Contains the quantities which are constant within a - * finite volume in the two-phase, two-component model. - */ -#ifndef DUMUX_2P2C_VOLUME_VARIABLES_HH -#define DUMUX_2P2C_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2p2c/2p2cvolumevariables.hh instead. -#include <dumux/boxmodels/common/boxmodel.hh> -#include <dumux/common/math.hh> - -#include <dune/common/collectivecommunication.hh> -#include <vector> -#include <iostream> - -#include "2p2cproperties.hh" -#include "2p2cindices.hh" - -#include <dumux/material/fluidstates/compositionalfluidstate.hh> -#include <dumux/material/constraintsolvers/computefromreferencephase.hh> -#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> - -namespace Dumux -{ - -/*! - * \ingroup TwoPTwoCModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the two-phase, two-component model. - */ -template <class TypeTag> -class TwoPTwoCVolumeVariables : public BoxVolumeVariables<TypeTag> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - - // present phases - enum { - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases - }; - - // formulations - enum { - formulation = GET_PROP_VALUE(TypeTag, Formulation), - pwSn = TwoPTwoCFormulation::pwSn, - pnSw = TwoPTwoCFormulation::pnSw - }; - - // primary variable indices - enum { - switchIdx = Indices::switchIdx, - pressureIdx = Indices::pressureIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { dim = GridView::dimension}; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition; - typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase; - -public: - //! The type of the object returned by the fluidState() method - typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> FluidState; - - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_, isOldSol); - - ///////////// - // calculate the remaining quantities - ///////////// - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - - // Second instance of a parameter cache. - // Could be avoided if diffusion coefficients also - // became part of the fluid state. - typename FluidSystem::ParameterCache paramCache; - paramCache.updateAll(fluidState_); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // relative permeabilities - Scalar kr; - if (phaseIdx == wPhaseIdx) - kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx)); - else // ATTENTION: krn requires the wetting phase saturation - // as parameter! - kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx)); - relativePermeability_[phaseIdx] = kr; - Valgrind::CheckDefined(relativePermeability_[phaseIdx]); - - // binary diffusion coefficients - diffCoeff_[phaseIdx] = - FluidSystem::binaryDiffusionCoefficient(fluidState_, - paramCache, - phaseIdx, - wCompIdx, - nCompIdx); - Valgrind::CheckDefined(diffCoeff_[phaseIdx]); - } - - // porosity - porosity_ = problem.spatialParams().porosity(element, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(porosity_); - - // energy related quantities not contained in the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - /*! - * \copydoc BoxModel::completeFluidState - * \param isOldSol Specifies whether this is the previous solution or the current one - */ - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - int scvIdx, - FluidState& fluidState, - bool isOldSol = false) - { - Scalar t = Implementation::temperature_(priVars, problem, element, - fvGeometry, scvIdx); - fluidState.setTemperature(t); - - unsigned numDofs = problem.model().numDofs(); - unsigned numVertices = problem.gridView().size(dim); - - int globalIdx; - if (numDofs != numVertices) // element data - globalIdx = problem.model().dofMapper().map(element); - else - globalIdx = problem.model().dofMapper().map(element, scvIdx, dim); - - int phasePresence = problem.model().phasePresence(globalIdx, isOldSol); - - ///////////// - // set the saturations - ///////////// - Scalar Sn; - if (phasePresence == nPhaseOnly) - Sn = 1.0; - else if (phasePresence == wPhaseOnly) { - Sn = 0.0; - } - else if (phasePresence == bothPhases) { - if (formulation == pwSn) - Sn = priVars[switchIdx]; - else if (formulation == pnSw) - Sn = 1.0 - priVars[switchIdx]; - else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid."); - } - else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); - fluidState.setSaturation(wPhaseIdx, 1 - Sn); - fluidState.setSaturation(nPhaseIdx, Sn); - - ///////////// - // set the pressures of the fluid phases - ///////////// - - // calculate capillary pressure - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - Scalar pC = MaterialLaw::pC(materialParams, 1 - Sn); - - if (formulation == pwSn) { - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pC); - } - else if (formulation == pnSw) { - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pC); - } - else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid."); - - ///////////// - // calculate the phase compositions - ///////////// - typename FluidSystem::ParameterCache paramCache; - - // now comes the tricky part: calculate phase compositions - if (phasePresence == bothPhases) { - // both phases are present, phase compositions are a - // result of the the nonwetting <-> wetting equilibrium. This is - // the job of the "MiscibleMultiPhaseComposition" - // constraint solver - MiscibleMultiPhaseComposition::solve(fluidState, - paramCache, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - - } - else if (phasePresence == nPhaseOnly) { - // only the nonwetting phase is present, i.e. nonwetting phase - // composition is stored explicitly. - - // extract _mass_ fractions in the nonwetting phase - Scalar massFractionN[numComponents]; - massFractionN[wCompIdx] = priVars[switchIdx]; - massFractionN[nCompIdx] = 1 - massFractionN[wCompIdx]; - - // calculate average molar mass of the nonwetting phase - Scalar M1 = FluidSystem::molarMass(wCompIdx); - Scalar M2 = FluidSystem::molarMass(nCompIdx); - Scalar X2 = massFractionN[nCompIdx]; - Scalar avgMolarMass = M1*M2/(M2 + X2*(M1 - M2)); - - // convert mass to mole fractions and set the fluid state - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, massFractionN[wCompIdx]*avgMolarMass/M1); - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, massFractionN[nCompIdx]*avgMolarMass/M2); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver - ComputeFromReferencePhase::solve(fluidState, - paramCache, - nPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - else if (phasePresence == wPhaseOnly) { - // only the wetting phase is present, i.e. wetting phase - // composition is stored explicitly. - - // extract _mass_ fractions in the nonwetting phase - Scalar massFractionW[numComponents]; - massFractionW[nCompIdx] = priVars[switchIdx]; - massFractionW[wCompIdx] = 1 - massFractionW[nCompIdx]; - - // calculate average molar mass of the nonwetting phase - Scalar M1 = FluidSystem::molarMass(wCompIdx); - Scalar M2 = FluidSystem::molarMass(nCompIdx); - Scalar X2 = massFractionW[nCompIdx]; - Scalar avgMolarMass = M1*M2/(M2 + X2*(M1 - M2)); - - // convert mass to mole fractions and set the fluid state - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, massFractionW[wCompIdx]*avgMolarMass/M1); - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, massFractionW[nCompIdx]*avgMolarMass/M2); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver - ComputeFromReferencePhase::solve(fluidState, - paramCache, - wPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // compute and set the enthalpy - Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx); - fluidState.setEnthalpy(phaseIdx, h); - } - } - - /*! - * \brief Returns the phase state for the control-volume. - */ - const FluidState &fluidState() const - { return fluidState_; } - - /*! - * \brief Returns the effective saturation of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar saturation(const int phaseIdx) const - { return fluidState_.saturation(phaseIdx); } - - /*! - * \brief Returns the mass density of a given phase within the - * control volume. - * - * \param phaseIdx The phase index - */ - Scalar density(const int phaseIdx) const - { return fluidState_.density(phaseIdx); } - - /*! - * \brief Returns the mass density of a given phase within the - * control volume. - * - * \param phaseIdx The phase index - */ - Scalar molarDensity(const int phaseIdx) const - { return fluidState_.density(phaseIdx) / fluidState_.averageMolarMass(phaseIdx); } - - /*! - * \brief Returns the effective pressure of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar pressure(const int phaseIdx) const - { return fluidState_.pressure(phaseIdx); } - - /*! - * \brief Returns temperature inside the sub-control volume. - * - * Note that we assume thermodynamic equilibrium, i.e. the - * temperature of the rock matrix and of all fluid phases are - * identical. - */ - Scalar temperature() const - { return fluidState_.temperature(/*phaseIdx=*/0); } - - /*! - * \brief Returns the relative permeability of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar relativePermeability(const int phaseIdx) const - { - return relativePermeability_[phaseIdx]; - } - - /*! - * \brief Returns the effective mobility of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar mobility(const int phaseIdx) const - { - return relativePermeability_[phaseIdx]/fluidState_.viscosity(phaseIdx); - } - - /*! - * \brief Returns the effective capillary pressure within the control volume. - */ - Scalar capillaryPressure() const - { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); } - - /*! - * \brief Returns the average porosity within the control volume. - */ - Scalar porosity() const - { return porosity_; } - - /*! - * \brief Returns the binary diffusion coefficients for a phase - */ - Scalar diffCoeff(int phaseIdx) const - { return diffCoeff_[phaseIdx]; } - - -protected: - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - template<class ParameterCache> - static Scalar enthalpy_(const FluidState& fluidState, - const ParameterCache& paramCache, - const int phaseIdx) - { - return 0; - } - - /*! - * \brief Called by update() to compute the energy related quantities - */ - void updateEnergy_(const PrimaryVariables &sol, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int vertIdx, - bool isOldSol) - { } - - Scalar porosity_; //!< Effective porosity within the control volume - Scalar relativePermeability_[numPhases]; //!< Relative permeability within the control volume - Scalar diffCoeff_[numPhases]; //!< Binary diffusion coefficients for the phases - FluidState fluidState_; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } - - -}; - -} // end namespace - -#endif +#include <dumux/implicit/2p2c/2p2cvolumevariables.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh b/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh index ca2b2a55f02ed9d8c1dcf259e7f0bae960b59a88..c0857615e66d2c432712b2797acd40fcfd6854f9 100644 --- a/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh +++ b/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh @@ -1,146 +1,3 @@ -// -*- 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 This file contains data which is required to calculate - * the heat fluxes over a face of a finite volume. - * - * This means temperature gradients and the normal matrix - * heat flux. - */ -#ifndef DUMUX_2P2CNI_FLUX_VARIABLES_HH -#define DUMUX_2P2CNI_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cnifluxvariables.hh instead. -#include <dumux/common/math.hh> -#include <dumux/boxmodels/2p2c/2p2cfluxvariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup TwoPTwoCNIModel - * \ingroup BoxFluxVariables - * \brief This template class contains data which is required to - * calculate the heat fluxes over a face of a finite - * volume for the non-isothermal two-phase, two-component model. - * The mass fluxes are computed in the parent class. - * - * This means temperature gradients and the normal matrix - * heat flux. - */ -template <class TypeTag> -class TwoPTwoCNIFluxVariables : public TwoPTwoCFluxVariables<TypeTag> -{ - typedef TwoPTwoCFluxVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { dimWorld = GridView::dimensionworld }; - typedef Dune::FieldVector<Scalar, dimWorld> DimVector; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param elemGeom The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - */ - TwoPTwoCNIFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int faceIdx, - const ElementVolumeVariables &elemVolVars, - bool onBoundary = false) - : ParentType(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary) - { - faceIdx_ = faceIdx; - - calculateValues_(problem, element, elemVolVars); - } - - /*! - * \brief The total heat flux \f$\mathrm{[J/s]}\f$ due to heat conduction - * of the rock matrix over the sub-control volume face in - * direction of the face normal. - */ - Scalar normalMatrixHeatFlux() const - { return normalMatrixHeatFlux_; } - - DimVector temperatureGradient() const - { return temperatureGrad_; } - -protected: - void calculateValues_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // calculate temperature gradient using finite element - // gradients - temperatureGrad_ = 0; - DimVector tmp(0.0); - for (int idx = 0; idx < this->fvGeometry_.numFAP; idx++) - { - tmp = this->face().grad[idx]; - - // index for the element volume variables - int volVarsIdx = this->face().fapIndices[idx]; - - tmp *= elemVolVars[volVarsIdx].temperature(); - temperatureGrad_ += tmp; - } - - // The spatial parameters calculates the actual heat flux vector - if (this->face().i != this->face().j) - problem.spatialParams().matrixHeatFlux(tmp, - *this, - elemVolVars, - temperatureGrad_, - element, - this->fvGeometry_, - faceIdx_); - else // heat flux at outflow boundaries - problem.spatialParams().boundaryMatrixHeatFlux(tmp, - *this, - elemVolVars, - this->face(), - element, - this->fvGeometry_); - - // project the heat flux vector on the face's normal vector - normalMatrixHeatFlux_ = tmp*this->face().normal; - } - -private: - Scalar normalMatrixHeatFlux_; - DimVector temperatureGrad_; - int faceIdx_; -}; - -} // end namespace - -#endif +#include <dumux/implicit/2p2cni/2p2cnifluxvariables.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cniindices.hh b/dumux/boxmodels/2p2cni/2p2cniindices.hh index 4eefa0d50543d448d861ed30a7aa14df23f73fef..9d204053be7145f55c5d3f801f4633e05d9b46b7 100644 --- a/dumux/boxmodels/2p2cni/2p2cniindices.hh +++ b/dumux/boxmodels/2p2cni/2p2cniindices.hh @@ -1,51 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cniindices.hh instead. -/*! - * \file - * - * \brief Defines the indices used by the 2p2cni box model - */ -#ifndef DUMUX_2P2CNI_INDICES_HH -#define DUMUX_2P2CNI_INDICES_HH - -#include <dumux/boxmodels/2p2c/2p2cindices.hh> - -namespace Dumux -{ -// \{ - -/*! - * \ingroup TwoPTwoCNIModel - * \ingroup BoxIndices - * \brief Enumerations for the non-isothermal 2-phase 2-component model - * - * \tparam formulation The formulation, either pwSn or pnSw. - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, int formulation, int PVOffset> -class TwoPTwoCNIIndices : public TwoPTwoCIndices<TypeTag, formulation, PVOffset> -{ -public: - static const int temperatureIdx = PVOffset + 2; //! The index for temperature in primary variable vectors. - static const int energyEqIdx = PVOffset + 2; //! The index for energy in equation vectors. -}; - -} -#endif +#include <dumux/implicit/2p2cni/2p2cniindices.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh b/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh index 2b1b43f40e332bf7b4285b5071e76a80c83d9afe..e214b9b5f48a406152083e70155a4a522787e621 100644 --- a/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh +++ b/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh @@ -1,175 +1,3 @@ -// -*- 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 Element-wise calculation of the Jacobian matrix for problems - * using the non-isothermal two-phase two-component box model. - * - */ -#ifndef DUMUX_NEW_2P2CNI_LOCAL_RESIDUAL_HH -#define DUMUX_NEW_2P2CNI_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cnilocalresidual.hh instead. -#include <dumux/boxmodels/2p2c/2p2clocalresidual.hh> - -#include <dumux/boxmodels/2p2cni/2p2cnivolumevariables.hh> -#include <dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh> -#include <dumux/boxmodels/2p2cni/2p2cniproperties.hh> - -namespace Dumux -{ -/*! - * \ingroup TwoPTwoCNIModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the two-phase two-component box model. - */ -template<class TypeTag> -class TwoPTwoCNILocalResidual : public TwoPTwoCLocalResidual<TypeTag> -{ - typedef TwoPTwoCLocalResidual<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - energyEqIdx = Indices::energyEqIdx, - temperatureIdx = Indices::temperatureIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - TwoPTwoCNILocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within a sub-control volume. - * - * The result should be averaged over the volume (e.g. phase mass - * inside a sub control volume divided by the volume) - * - * \param storage The storage of the conservation quantity (mass or energy) within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const - { - // compute the storage term for phase mass - ParentType::computeStorage(storage, scvIdx, usePrevSol); - - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit Euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - // compute the energy storage - storage[energyEqIdx] = - volVars.porosity()*(volVars.density(wPhaseIdx) * - volVars.internalEnergy(wPhaseIdx) * - volVars.saturation(wPhaseIdx) - + - volVars.density(nPhaseIdx) * - volVars.internalEnergy(nPhaseIdx) * - volVars.saturation(nPhaseIdx)) - + - // heat capacity is already multiplied by the density - // of the porous material and the porosity in the problem file - volVars.temperature()*volVars.heatCapacity(); - } - - /*! - * \brief Evaluates the advective mass flux and the heat flux - * over a face of a subcontrol volume and writes the result in - * the flux vector. - * - * \param flux The advective flux over the SCV (sub-control-volume) face for each component - * \param fluxVars The flux variables at the current SCV face - * - * This method is called by compute flux (base class) - */ - void computeAdvectiveFlux(PrimaryVariables &flux, - const FluxVariables &fluxVars) const - { - // advective mass flux - ParentType::computeAdvectiveFlux(flux, fluxVars); - - // advective heat flux in all phases - flux[energyEqIdx] = 0; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // vertex data of the upstream and the downstream vertices - const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx)); - const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx)); - - flux[energyEqIdx] += - fluxVars.volumeFlux(phaseIdx) * (massUpwindWeight_ * // upstream vertex - ( up.density(phaseIdx) * - up.enthalpy(phaseIdx)) - + - (1-massUpwindWeight_) * // downstream vertex - ( dn.density(phaseIdx) * - dn.enthalpy(phaseIdx)) ); - } - } - - /*! - * \brief Adds the diffusive heat flux to the flux vector over - * the face of a sub-control volume. - * - * \param flux The diffusive flux over the SCV (sub-control-volume) face for each conservation quantity (mass, energy) - * \param fluxVars The flux variables at the current SCV face - * - * This method is called by compute flux (base class) - */ - void computeDiffusiveFlux(PrimaryVariables &flux, - const FluxVariables &fluxVars) const - { - // diffusive mass flux - ParentType::computeDiffusiveFlux(flux, fluxVars); - - // diffusive heat flux - flux[temperatureIdx] += - fluxVars.normalMatrixHeatFlux(); - } - -private: - Scalar massUpwindWeight_; - -}; - -} - -#endif +#include <dumux/implicit/2p2cni/2p2cnilocalresidual.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cnimodel.hh b/dumux/boxmodels/2p2cni/2p2cnimodel.hh index 6dac22eb31546d0fe9552c31ad9e719fbf4d1b40..38c9b72e68855e676db122ca8eed6d918b9c58a3 100644 --- a/dumux/boxmodels/2p2cni/2p2cnimodel.hh +++ b/dumux/boxmodels/2p2cni/2p2cnimodel.hh @@ -1,98 +1,3 @@ -// -*- 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 Adaption of the BOX scheme to the non-isothermal two-phase two-component flow model. - */ -#ifndef DUMUX_NEW_2P2CNI_MODEL_HH -#define DUMUX_NEW_2P2CNI_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cnimodel.hh instead. -#include <dumux/boxmodels/2p2c/2p2cmodel.hh> - -namespace Dumux { -/*! - * \ingroup TwoPTwoCNIModel - * \brief Adaption of the BOX scheme to the non-isothermal two-phase two-component flow model. - * - * This model implements a non-isothermal two-phase flow of two compressible and partly miscible fluids - * \f$\alpha \in \{ w, n \}\f$. Thus each component \f$\kappa \{ w, a \}\f$ can be present in - * each phase. - * Using the standard multiphase Darcy approach a mass balance equation is - * solved: - * \f{eqnarray*} - && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa S_\alpha )}{\partial t} - - \sum_\alpha \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} - (\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g}) \right\}\\ - &-& \sum_\alpha \text{div} \left\{{\bf D}_{\alpha, pm}^\kappa \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\} - - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a\} \, , - \alpha \in \{w, n\} - * \f} - * For the energy balance, local thermal equilibrium is assumed which results in one - * energy conservation equation for the porous solid matrix and the fluids: - * \f{eqnarray*} - && \phi \frac{\partial \left( \sum_\alpha \varrho_\alpha u_\alpha S_\alpha \right)}{\partial t} - + \left( 1 - \phi \right) \frac{\partial (\varrho_s c_s T)}{\partial t} - - \sum_\alpha \text{div} \left\{ \varrho_\alpha h_\alpha - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left( \text{grad}\, - p_\alpha - - \varrho_\alpha \mathbf{g} \right) \right\} \\ - &-& \text{div} \left( \lambda_{pm} \text{grad} \, T \right) - - q^h = 0 \qquad \alpha \in \{w, n\} - \f} - * - * This is discretized using a fully-coupled vertex - * centered finite volume (box) scheme as spatial and - * the implicit Euler method as temporal discretization. - * - * By using constitutive relations for the capillary pressure \f$p_c = - * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking - * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of - * unknowns can be reduced to two. - * If both phases are present the primary variables are, like in the nonisothermal two-phase model, either \f$p_w\f$, \f$S_n\f$ and - * temperature or \f$p_n\f$, \f$S_w\f$ and temperature. The formulation which ought to be used can be - * specified by setting the <tt>Formulation</tt> property to either - * <tt>TwoPTwoCIndices::pWsN</tt> or <tt>TwoPTwoCIndices::pNsW</tt>. By - * default, the model uses \f$p_w\f$ and \f$S_n\f$. - * In case that only one phase (nonwetting or wetting phase) is present the second primary - * variable represents a mass fraction. The correct assignment of the second - * primary variable is performed by a phase state dependent primary variable switch. The phase state is stored for all nodes of the system. The following cases can be distinguished: - * <ul> - * <li> - * Both phases are present: The saturation is used (either\f$S_n\f$ or \f$S_w\f$, dependent on the chosen formulation). - * </li> - * <li> - * Only wetting phase is present: The mass fraction of air in the wetting phase \f$X^a_w\f$ is used. - * </li> - * <li> - * Only non-wetting phase is present: The mass fraction of water in the non-wetting phase, \f$X^w_n\f$, is used. - * </li> - * </ul> - */ -template<class TypeTag> -class TwoPTwoCNIModel : public TwoPTwoCModel<TypeTag> -{ -}; - -} - -#include "2p2cnipropertydefaults.hh" - -#endif +#include <dumux/implicit/2p2cni/2p2cnimodel.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cniproperties.hh b/dumux/boxmodels/2p2cni/2p2cniproperties.hh index 6e221dea1e1d067a61d20ebfb05069eef62bc31a..188d9a2f58f426b49188191c506f7ea93aebf5d2 100644 --- a/dumux/boxmodels/2p2cni/2p2cniproperties.hh +++ b/dumux/boxmodels/2p2cni/2p2cniproperties.hh @@ -1,47 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPTwoCNIModel - * \file - * - * \brief Defines the properties required for the non-isothermal two-phase, - * two-component BOX model. - */ -#ifndef DUMUX_2P2CNI_PROPERTIES_HH -#define DUMUX_2P2CNI_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cniproperties.hh instead. -#include <dumux/boxmodels/2p2c/2p2cproperties.hh> - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the non-isothermal two-phase, two-component problems -NEW_TYPE_TAG(BoxTwoPTwoCNI, INHERITS_FROM(BoxTwoPTwoC)); -} -} - -#endif +#include <dumux/implicit/2p2cni/2p2cniproperties.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cnipropertydefaults.hh b/dumux/boxmodels/2p2cni/2p2cnipropertydefaults.hh index efc97a991cf380d352991ca83ccbca96713a6587..119ecfe60416819ef4321184c286cb5402e80019 100644 --- a/dumux/boxmodels/2p2cni/2p2cnipropertydefaults.hh +++ b/dumux/boxmodels/2p2cni/2p2cnipropertydefaults.hh @@ -1,76 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPTwoCNIModel - * \file - * - * \brief Defines default values for most properties required by the 2p2cni - * box model. - */ -#ifndef DUMUX_2P2CNI_PROPERTY_DEFAULTS_HH -#define DUMUX_2P2CNI_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cnipropertydefaults.hh instead. -#include <dumux/boxmodels/2p2c/2p2cpropertydefaults.hh> - -#include "2p2cnimodel.hh" -#include "2p2cniindices.hh" -#include "2p2cnilocalresidual.hh" -#include "2p2cnivolumevariables.hh" -#include "2p2cnifluxvariables.hh" - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Property values -////////////////////////////////////////////////////////////////// - -SET_INT_PROP(BoxTwoPTwoCNI, NumEq, 3); //!< set the number of equations to 3 - -//! Use the 2p2cni local jacobian operator for the 2p2cni model -SET_TYPE_PROP(BoxTwoPTwoCNI, - LocalResidual, - TwoPTwoCNILocalResidual<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxTwoPTwoCNI, Model, TwoPTwoCNIModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxTwoPTwoCNI, VolumeVariables, TwoPTwoCNIVolumeVariables<TypeTag>); - - -//! the FluxVariables property -SET_TYPE_PROP(BoxTwoPTwoCNI, FluxVariables, TwoPTwoCNIFluxVariables<TypeTag>); - -//! The indices required by the non-isothermal 2p2c model -SET_PROP(BoxTwoPTwoCNI, Indices) -{ private: - enum { formulation = GET_PROP_VALUE(TypeTag, Formulation) }; - public: - typedef TwoPTwoCNIIndices<TypeTag, formulation, 0> type; -}; - -} - -} -#endif +#include <dumux/implicit/2p2cni/2p2cnipropertydefaults.hh> diff --git a/dumux/boxmodels/2p2cni/2p2cnivolumevariables.hh b/dumux/boxmodels/2p2cni/2p2cnivolumevariables.hh index c6712a89e036d04c7bc037a43ab0e192bb0f5ba7..0264914f887c030fbb02eca029f6c256269c60e1 100644 --- a/dumux/boxmodels/2p2cni/2p2cnivolumevariables.hh +++ b/dumux/boxmodels/2p2cni/2p2cnivolumevariables.hh @@ -1,144 +1,3 @@ -// -*- 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 Contains the quantities which are constant within a - * finite volume in the non-isothermal two-phase, two-component - * model. - */ -#ifndef DUMUX_2P2CNI_VOLUME_VARIABLES_HH -#define DUMUX_2P2CNI_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2p2cni/2p2cnivolumevariables.hh instead. -#include <dumux/boxmodels/2p2c/2p2cvolumevariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup TwoPTwoCNIModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the non-isothermal two-phase, two-component - * model. - */ -template <class TypeTag> -class TwoPTwoCNIVolumeVariables : public TwoPTwoCVolumeVariables<TypeTag> -{ - //! \cond 0 - typedef TwoPTwoCVolumeVariables<TypeTag> ParentType; - typedef typename ParentType::FluidState FluidState; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { temperatureIdx = Indices::temperatureIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - //! \endcond - -public: - /*! - * \brief Returns the total internal energy of a phase in the - * sub-control volume. - * - * \param phaseIdx The phase index - */ - Scalar internalEnergy(const int phaseIdx) const - { return this->fluidState_.internalEnergy(phaseIdx); }; - - /*! - * \brief Returns the total enthalpy of a phase in the sub-control - * volume. - * - * \param phaseIdx The phase index - */ - Scalar enthalpy(const int phaseIdx) const - { return this->fluidState_.enthalpy(phaseIdx); }; - - /*! - * \brief Returns the total heat capacity \f$\mathrm{[J/(K*m^3]}\f$ of the rock matrix in - * the sub-control volume. - */ - Scalar heatCapacity() const - { return heatCapacity_; }; - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of the fluid phase in - * the sub-control volume. - */ - Scalar thermalConductivity(const int phaseIdx) const - { return FluidSystem::thermalConductivity(this->fluidState_, phaseIdx); }; - - -protected: - // this method gets called by the parent class. since this method - // is protected, we are friends with our parent.. - friend class TwoPTwoCVolumeVariables<TypeTag>; - - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return priVars[temperatureIdx]; - } - - template<class ParameterCache> - static Scalar enthalpy_(const FluidState& fluidState, - const ParameterCache& paramCache, - const int phaseIdx) - { - return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); - } - - /*! - * \brief Update all quantities for a given control volume. - * - * \param sol The solution primary variables - * \param problem The problem - * \param element The element - * \param fvGeometry The current finite volume geometry of the element - * \param scvIdx The local index of the SCV (sub-control volume) - * \param isOldSol Evaluate function with solution of current or previous time step - */ - void updateEnergy_(const PrimaryVariables &sol, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - bool isOldSol) - { - // compute and set the heat capacity of the solid phase - heatCapacity_ = problem.spatialParams().heatCapacity(element, fvGeometry, scvIdx); - Valgrind::CheckDefined(heatCapacity_); - }; - - Scalar heatCapacity_; -}; - -} // end namespace - -#endif +#include <dumux/implicit/2p2cni/2p2cnivolumevariables.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh b/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh index 93ca3137d6bba43107bc859f0656bdde8596549c..87f83150894deb9593fbff76c8131b3eb7f98533 100644 --- a/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh +++ b/dumux/boxmodels/2pdfm/2pdfmfluxvariables.hh @@ -1,234 +1,3 @@ -/***************************************************************************** - * 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 This file contains the data which is required to calculate - * all fluxes of fluid phases over a face of a finite volume in the - * two phase discrete fracture-matrix model. - */ -#ifndef DUMUX_BOXMODELS_2PDFM_FLUX_VARIABLES_HH -#define DUMUX_BOXMODELS_2PDFM_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmfluxvariables.hh instead. -#include <dumux/common/math.hh> -#include <dumux/common/parameters.hh> -#include <dumux/common/valgrind.hh> -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> - -#include "2pdfmproperties.hh" - -namespace Dumux -{ - -/*! - * \ingroup TwoPDFMBoxModel - * \ingroup BoxDFMFluxVariables - * \brief Contains the data which is required to calculate the fluxes of - * the fluid phases over a face of a finite volume for the two-phase - * discrete fracture-matrix model. - * - * This means pressure and concentration gradients, phase densities at - * the intergration point, etc. - */ -template <class TypeTag> -class TwoPDFMFluxVariables : public BoxDarcyFluxVariables<TypeTag> -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases) - }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dimWorld> Vector; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - typedef Dune::FieldVector<Scalar, dim> LocalPosition; - typedef Dune::FieldVector<Scalar, numPhases> PhasesVector; - -public: - /*! - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - TwoPDFMFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : BoxDarcyFluxVariables<TypeTag>(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary), - fvGeometry_(fvGeometry), faceIdx_(faceIdx), onBoundary_(onBoundary) - { - faceSCV_ = &this->face(); - - for (int phase = 0; phase < numPhases; ++phase) - { - potentialGradFracture_[phase] = 0.0; - } - - calculateGradientsInFractures_(problem, element, elemVolVars, faceIdx); - calculateVelocitiesFracture_(problem, element, elemVolVars, faceIdx); - }; - -public: - /*! - * \brief Calculates the velocities in the lower-dimenstional fracture. - * - * \param problem The problem - * \param element The finite element - * \param elemVolVars The volume variables of the current element - * \param faceIdx The local index of the SCV (sub-control-volume) face - */ - void calculateVelocitiesFracture_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars, - int faceIdx) - { - isFracture_ = problem.spatialParams().isEdgeFracture(element, faceIdx); - fractureWidth_ = problem.spatialParams().fractureWidth(element, faceIdx); - - Scalar KFracture, KFi, KFj; //permeabilities of the fracture - if (isFracture_) - { - KFi = problem.spatialParams(). - intrinsicPermeabilityFracture(element, this->fvGeometry_, this->face().i); - KFj = problem.spatialParams(). - intrinsicPermeabilityFracture(element, this->fvGeometry_, this->face().j); - } - else - { - KFi = 0; - KFj = 0; - } - - KFracture = Dumux::harmonicMean(KFi, KFj); - - // temporary vector for the Darcy velocity - Scalar vDarcyFracture = 0; - for (int phase=0; phase < numPhases; phase++) - { - vDarcyFracture = - (KFracture * potentialGradFracture_[phase]); - - Valgrind::CheckDefined(KFracture); - Valgrind::CheckDefined(fractureWidth_); - vDarcyFracture_[phase] = (vDarcyFracture * fractureWidth_); - Valgrind::CheckDefined(vDarcyFracture_[phase]); - } - - // set the upstream and downstream vertices - for (int phase = 0; phase < numPhases; ++phase) - { - upstreamFractureIdx[phase] = faceSCV_->i; - downstreamFractureIdx[phase] = faceSCV_->j; - - if (vDarcyFracture_[phase] < 0) - { - std::swap(upstreamFractureIdx[phase], - downstreamFractureIdx[phase]); - } - } - } - - /*! - * \brief Return the pressure potential gradient in the lower dimensional fracture. - * - * \param phaseIdx The index of the fluid phase - */ - const Scalar &potentialGradFracture(int phaseIdx) const - { - return potentialGradFracture_[phaseIdx]; - } - - - PhasesVector vDarcyFracture_; - - int upstreamFractureIdx[numPhases]; - int downstreamFractureIdx[numPhases]; -protected: - // gradients - Scalar potentialGradFracture_[numPhases]; - const FVElementGeometry &fvGeometry_; - int faceIdx_; - const bool onBoundary_; - bool isFracture_; - Scalar fractureWidth_; - const SCVFace *faceSCV_; - -private: - /*! - * \brief Calculates the gradients in the lower-dimenstional fracture. - * - * \param problem The problem - * \param element The finite element - * \param elemVolVars The volume variables of the current element - * \param faceIdx The local index of the SCV (sub-control-volume) face - */ - void calculateGradientsInFractures_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars, - int faceIdx) - { - // calculate gradients, loop over adjacent vertices - for (int idx = 0; idx < this->fvGeometry_.numFAP; idx++) - { - int i = this->face().i; - int j = this->face().j; - - // compute sum of pressure gradients for each phaseGlobalPosition - for (int phase = 0; phase < numPhases; phase++) - { - const GlobalPosition localIdx_i = element.geometry().corner(i); - const GlobalPosition localIdx_j = element.geometry().corner(j); - - isFracture_ = problem.spatialParams().isEdgeFracture(element, faceIdx); - - if (isFracture_) - { - GlobalPosition diff_ij = localIdx_j; - diff_ij -= localIdx_i; - potentialGradFracture_[phase] = - (elemVolVars[j].pressure(phase) - elemVolVars[i].pressure(phase)) - / diff_ij.two_norm(); - } - else - { - potentialGradFracture_[phase] = 0; - } - } - } - } -}; - -} // end namepace - -#endif // DUMUX_BOXMODELS_2PDFM_FLUX_VARIABLES_HH +#include <dumux/implicit/2pdfm/2pdfmfluxvariables.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmindices.hh b/dumux/boxmodels/2pdfm/2pdfmindices.hh index 6326b0508fa69ac17ec754eea8b63dffd54481a6..c0af545212a5c68e897d55d09e1d33a69426417d 100644 --- a/dumux/boxmodels/2pdfm/2pdfmindices.hh +++ b/dumux/boxmodels/2pdfm/2pdfmindices.hh @@ -1,64 +1,3 @@ -/***************************************************************************** - * 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmindices.hh instead. -/*! - * \file - * - * \brief Defines the indices required for the finite volume in the - * two phase discrete fracture-matrix model. - */ -#ifndef DUMUX_BOXMODELS_2PDFM_INDICES_HH -#define DUMUX_BOXMODELS_2PDFM_INDICES_HH - -#include<dumux/boxmodels/2p/2pindices.hh> - -namespace Dumux -{ -// \{ - -/*! - * \ingroup TwoPDFMBoxModel - * \ingroup BoxIndices - * \brief The common indices for the \f$p_w-S_n\f$ formulation of the - * isothermal two-phase discrete fracture-matrix model. - * - * \tparam TypeTag The problem type tag - * \tparam formulation The formulation, either pwSn or pnSw - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, - int formulation = TwoPFormulation::pwSn, - int PVOffset = 0> -struct TwoPDFMIndices : public TwoPIndices <TypeTag, formulation, PVOffset> -{ - // Primary variable indices - static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int saturationIdx = PVOffset + 1; //!< Index of the saturation of the non-wetting/wetting phase - - // indices of the primary variables - static const int pwIdx = PVOffset + 0; //!< Pressure index of the wetting phase - static const int SnIdx = PVOffset + 1; //!< Saturation index of the wetting phase - - // indices of the equations - static const int contiWEqIdx = PVOffset + 0; //!< Index of the continuity equation of the wetting phase - static const int contiNEqIdx = PVOffset + 1; //!< Index of the continuity equation of the non-wetting phase -}; - -// \} -} // namespace Dumux - -#endif // DUMUX_BOXMODELS_2PDFM_INDICES_HH +#include <dumux/implicit/2pdfm/2pdfmindices.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh b/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh index 3ab534a7b2bbc2b7514cd1fbf283f2c04f45fa04..1bf4d536493e7a7d21b31f4deec5195f620d6823 100644 --- a/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh +++ b/dumux/boxmodels/2pdfm/2pdfmlocalresidual.hh @@ -1,335 +1,3 @@ -/***************************************************************************** - * 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 Element-wise calculation of the residual for the finite volume in the - * two phase discrete fracture-matrix model. - */ -#ifndef DUMUX_BOXMODELS_2PDFM_LOCAL_RESIDUAL_HH -#define DUMUX_BOXMODELS_2PDFM_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmlocalresidual.hh instead. -#include <dumux/boxmodels/2p/2plocalresidual.hh> -#include "2pdfmproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup TwoPDFMBoxModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the two-phase discrete fracture box model. - */ -template<class TypeTag> -class TwoPDFMLocalResidual : public TwoPLocalResidual<TypeTag> -{ -protected: - typedef TwoPLocalResidual<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum - { - contiWEqIdx = Indices::contiWEqIdx, - contiNEqIdx = Indices::contiNEqIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases) - }; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef Dune::UGGrid<2> GridType; - typedef typename GridType::ctype DT; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim<dim>::Entity Vertex; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dimWorld> Vector; - - typedef Dune::FieldVector<Scalar, dim> LocalPosition; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - TwoPDFMLocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within a finite sub-control volume. - * - * \param storage The phase mass within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit Euler method. - ParentType::computeStorage(storage,scvIdx,usePrevSol); - computeStorageFracture(storage,scvIdx,usePrevSol); - } - - /*! - * \brief Evaluate the storage term of the current solution in a - * lower-dimensional fracture. - * - * \param storage The phase mass within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorageFracture(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const - { - const ElementVolumeVariables &elemDat = usePrevSol ? this->prevVolVars_() - : this->curVolVars_(); - const VolumeVariables &vertDat = elemDat[scvIdx]; - const Element &elem = this->element_(); - bool isFracture = this->problem_().spatialParams().isVertexFracture(elem, scvIdx); - /* - * Sn = w_F * SnF + w_M * SnM - * First simple case before determining the real w_F is to assume that it is 0 - * and w_M = 1 - * - */ - /////////////////////////////////////////////////////////////////////// - Scalar w_F, w_M; //volumetric fractions of fracture and matrix; - Scalar fractureVolume = 0.0; - w_F = 0.0; - /* - * Calculate the fracture volume fraction w_F = 0.5 * Fwidth * 0.5 * Length - */ - Dune::GeometryType gt = elem.geometry().type(); - const typename Dune::GenericReferenceElementContainer<DT,dim>::value_type& - refElem = Dune::GenericReferenceElements<DT,dim>::general(gt); - - Scalar vol; //subcontrol volume - FVElementGeometry fvelem = this->fvGeometry_(); - vol = fvelem.subContVol[scvIdx].volume; - for (int faceIdx=0; faceIdx<refElem.size(1); faceIdx++) - { - SCVFace face = fvelem.subContVolFace[faceIdx]; - int i=face.i; - int j=face.j; - - if (this->problem_().spatialParams().isEdgeFracture(elem, faceIdx) - && (i == scvIdx || j == scvIdx)) - { - Scalar fracture_width = this->problem_().spatialParams().fractureWidth(elem, faceIdx); - - const GlobalPosition global_i = elem.geometry().corner(i); - const GlobalPosition global_j = elem.geometry().corner(j); - GlobalPosition diff_ij = global_j; - diff_ij -=global_i; - Scalar fracture_length = 0.5*diff_ij.two_norm(); - //half is taken from the other element - fractureVolume += 0.5 * fracture_length * fracture_width; - } - } - w_F = fractureVolume/vol; - w_M = 1-w_F; - /////////////////////////////////////////////////////////////////////// - Scalar storageFracture[numPhases]; - Scalar storageMatrix [numPhases]; - storageFracture[wPhaseIdx] = 0.0; - storageFracture[nPhaseIdx] = 0.0; - storageMatrix[wPhaseIdx] = 0.0; - storageMatrix[nPhaseIdx] = 0.0; - // const GlobalPosition &globalPos = elem.geometry().corner(scvIdx); - - Scalar dSM_dSF = vertDat.dSM_dSF(); - if (!this->problem_().useInterfaceCondition()) - { - dSM_dSF = 1.0; - } - - if (isFracture) - { - for (int phaseIdx = 0; phaseIdx<2; phaseIdx++) - { - storageFracture[phaseIdx] = vertDat.density(phaseIdx) - * vertDat.porosityFracture() - * w_F - * vertDat.saturationFracture(phaseIdx); - storageMatrix[phaseIdx] = vertDat.density(phaseIdx) - * vertDat.porosity() - * w_M - * dSM_dSF - * vertDat.saturationMatrix(phaseIdx); - } - } - else - { - for (int phaseIdx = 0; phaseIdx < 2; phaseIdx++) - { - storageFracture[phaseIdx] = 0.0; - storageMatrix[phaseIdx] = vertDat.density(phaseIdx) - * vertDat.porosity() - * vertDat.saturation(phaseIdx); - } - - } - // wetting phase mass - storage[contiWEqIdx] = storageFracture[wPhaseIdx] - + storageMatrix[wPhaseIdx]; - - // non-wetting phase mass - storage[contiNEqIdx] = storageFracture[nPhaseIdx] - + storageMatrix[nPhaseIdx]; - } - - /*! - * \brief Evaluates the mass flux over a face of a sub-control - * volume. - * - * \param flux The flux over the SCV (sub-control-volume) face for each phase - * \param faceIdx The index of the SCV face - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, int faceIdx, const bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - flux = 0; - asImp_()->computeAdvectiveFlux(flux, fluxVars); - asImp_()->computeAdvectiveFluxFracture(flux, fluxVars); - asImp_()->computeDiffusiveFlux(flux, fluxVars); - asImp_()->computeDiffusiveFluxFracture(flux, fluxVars); - } - - /*! - * \brief Adds the flux vector in the lower dimensional fracture to the - * flux vector over the face of a sub-control volume. - * - * This method is called by compute flux and is mainly there for - * derived models to ease adding equations selectively. - * - * \param flux The advective flux over the sub-control-volume face for each phase - * \param fluxVars The flux variables at the current SCV - */ - void computeAdvectiveFluxFracture(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - //////// - // advective fluxes of all components in all phases - //////// - Vector tmpVec; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // calculate the flux in direction of the - // current fracture - // - // v = - (K grad p) * n - // - // (the minus comes from the Darcy law which states that - // the flux is from high to low pressure potentials.) - - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &upFracture = - this->curVolVars_(fluxVars.upstreamFractureIdx[phaseIdx]); - const VolumeVariables &dnFracture = - this->curVolVars_(fluxVars.downstreamFractureIdx[phaseIdx]); - - Scalar fractureFlux = - 0.5 * fluxVars.vDarcyFracture_[phaseIdx] - * ( massUpwindWeight_ // upstream vertex - * (upFracture.density(phaseIdx) - * upFracture.mobilityFracture(phaseIdx)) - + (1 - massUpwindWeight_) // downstream vertex - * (dnFracture.density(phaseIdx) - * dnFracture.mobilityFracture(phaseIdx))); - - flux[phaseIdx] += fractureFlux; - } - } - - /*! - * \brief Adds the diffusive flux of the fracture to the flux vector over - * the face of a sub-control volume. - * - * \param flux The diffusive flux over the sub-control-volume face for each phase - * \param fluxData The flux variables at the current SCV - * - * It doesn't do anything in two-phase model but is used by the - * non-isothermal two-phase models to calculate diffusive heat - * fluxes - */ - void computeDiffusiveFluxFracture(PrimaryVariables &flux, const FluxVariables &fluxData) const - { - // diffusive fluxes - flux += 0.0; - } - - /*! - * \brief Calculate the source term of the equation - * - * \param source The source/sink in the SCV for each phase - * \param scvIdx The index of the SCV - * - */ - void computeSource(PrimaryVariables &source, int scvIdx) const - { - // retrieve the source term intrinsic to the problem - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - -protected: - Implementation *asImp_() - { - return static_cast<Implementation *> (this); - } - const Implementation *asImp_() const - { - return static_cast<const Implementation *> (this); - } - -private: - Scalar massUpwindWeight_; -}; - -} // end namespace - -#endif // DUMUX_BOXMODELS_2PDFM_LOCAL_RESIDUAL_HH +#include <dumux/implicit/2pdfm/2pdfmlocalresidual.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmmodel.hh b/dumux/boxmodels/2pdfm/2pdfmmodel.hh index 07b9c92fd06861973664b4a72c5781f91a712098..85973c3e8574f63768497e6d70f6c44f53f9cc36 100644 --- a/dumux/boxmodels/2pdfm/2pdfmmodel.hh +++ b/dumux/boxmodels/2pdfm/2pdfmmodel.hh @@ -1,390 +1,3 @@ -/***************************************************************************** - * 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmmodel.hh instead. -/*! -* \file -* -* \brief Adaption of the box scheme to the two-phase flow in discrete fracture-matrix -* model. -*/ - -#ifndef DUMUX_BOXMODELS_2PDFM_MODEL_HH -#define DUMUX_BOXMODELS_2PDFM_MODEL_HH - -#include <dumux/boxmodels/2p/2pmodel.hh> - -#include "2pdfmproperties.hh" -#include "2pdfmlocalresidual.hh" -#include "2pdfmproblem.hh" - -namespace Dumux -{ - -/*! - * \ingroup TwoPDFMBoxModel - * \brief A two-phase, isothermal flow model using the box scheme. - * - * This model implements two-phase flow of two immiscible fluids - * \f$\alpha \in \{ w, n \}\f$ using a standard multiphase Darcy - * approach as the equation for the conservation of momentum, i.e. - \f[ - v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \textbf{K} - \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} {\textbf g} \right) - \f] - * - * By inserting this into the equation for the conservation of the - * phase mass, one gets - \f[ - \phi \frac{\partial \varrho_\alpha S_\alpha}{\partial t} - - - \text{div} \left\{ - \varrho_\alpha \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right) - \right\} - q_\alpha = 0 \;, - \f] - * - * These equations are discretized by a fully-coupled vertex centered finite volume - * (box) scheme as spatial and the implicit Euler method as time - * discretization. - * - * By using constitutive relations for the capillary pressure \f$p_c = - * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking - * advantage of the fact that \f$S_w + S_n = 1\f$, the number of - * unknowns can be reduced to two. Currently the model supports - * choosing either \f$p_w\f$ and \f$S_n\f$ or \f$p_n\f$ and \f$S_w\f$ - * as primary variables. The formulation which ought to be used can be - * specified by setting the <tt>Formulation</tt> property to either - * <tt>TwoPCommonIndices::pWsN</tt> or <tt>TwoPCommonIndices::pNsW</tt>. By - * default, the model uses \f$p_w\f$ and \f$S_n\f$. - */ -template<class TypeTag > -class TwoPDFMModel : public TwoPModel<TypeTag> -{ - typedef TwoPModel<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - nPhaseIdx = Indices::nPhaseIdx, - wPhaseIdx = Indices::wPhaseIdx, - pressureIdx = Indices::pressureIdx, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::ctype CoordScalar; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, numPhases> PhasesVector; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - -public: - /*! - * \brief Returns the relative weight of a primary variable for - * calculating relative errors. - * - * \param globalIdx The global index of the vertex - * \param pvIdx The index of the primary variable - */ - DUNE_DEPRECATED - Scalar primaryVarWeight(int globalIdx, int pvIdx) const - { - if (pressureIdx == pvIdx) - { - return std::min(10.0 / this->prevSol()[globalIdx][pvIdx], 1.0); - } - - return 1.0; - } - - /*! - * \brief Append all quantities of interest which can be derived - * from the solution of the current time step to the VTK - * writer. - * - * \param sol The global solution vector - * \param writer The writer for multi-file VTK datasets - */ - template<class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, MultiWriter &writer) - { - bool velocityOutput = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocity); - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField; - - // get the number of degrees of freedom and the number of vertices - unsigned numDofs = this->numDofs(); - unsigned numVertices = this->problem_().gridView().size(dim); - - // velocity output currently only works for vertex data - if (numDofs != numVertices) - { - velocityOutput = false; - } - - // create the required scalar fields - ScalarField *pW = writer.allocateManagedBuffer(numDofs); - ScalarField *pN = writer.allocateManagedBuffer(numDofs); - ScalarField *pC = writer.allocateManagedBuffer(numDofs); - ScalarField *Sw = writer.allocateManagedBuffer(numDofs); - ScalarField *Sn = writer.allocateManagedBuffer(numDofs); - ScalarField *rhoW = writer.allocateManagedBuffer(numDofs); - ScalarField *rhoN = writer.allocateManagedBuffer(numDofs); - ScalarField *mobW = writer.allocateManagedBuffer(numDofs); - ScalarField *mobN = writer.allocateManagedBuffer(numDofs); - ScalarField *poro = writer.allocateManagedBuffer(numDofs); - ScalarField *Te = writer.allocateManagedBuffer(numDofs); - ScalarField *cellNum =writer.allocateManagedBuffer (numDofs); - VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs); - VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs); - - if(velocityOutput) // check if velocity output is demanded - { - // initialize velocity fields - for (unsigned int i = 0; i < numVertices; ++i) - { - (*velocityN)[i] = Scalar(0); - (*velocityW)[i] = Scalar(0); - (*cellNum)[i] = Scalar(0.0); - } - } - unsigned numElements = this->gridView_().size(0); - ScalarField *rank = writer.allocateManagedBuffer(numElements); - - FVElementGeometry fvGeometry; - VolumeVariables volVars; - ElementVolumeVariables elemVolVars; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - if(velocityOutput && !elemIt->geometry().type().isCube()){ - DUNE_THROW(Dune::InvalidStateException, - "Currently, velocity output only works for cubes. " - "Please set the EnableVelocityOutput property to false!"); - } - int idx = this->elementMapper().map(*elemIt); - (*rank)[idx] = this->gridView_().comm().rank(); - - fvGeometry.update(this->gridView_(), *elemIt); - - if (numDofs == numElements) // element data - { - volVars.update(sol[idx], - this->problem_(), - *elemIt, - fvGeometry, - /*scvIdx=*/0, - false); - - (*pW)[idx] = volVars.pressure(wPhaseIdx); - (*pN)[idx] = volVars.pressure(nPhaseIdx); - (*pC)[idx] = volVars.capillaryPressure(); - (*Sw)[idx] = volVars.saturation(wPhaseIdx); - (*Sn)[idx] = volVars.saturation(nPhaseIdx); - (*rhoW)[idx] = volVars.density(wPhaseIdx); - (*rhoN)[idx] = volVars.density(nPhaseIdx); - (*mobW)[idx] = volVars.mobility(wPhaseIdx); - (*mobN)[idx] = volVars.mobility(nPhaseIdx); - (*poro)[idx] = volVars.porosity(); - (*Te)[idx] = volVars.temperature(); - } - else // vertex data - { - int numVerts = elemIt->template count<dim> (); - for (int scvIdx = 0; scvIdx < numVerts; ++scvIdx) - { - int globalIdx = this->vertexMapper().map(*elemIt, scvIdx, dim); - volVars.update(sol[globalIdx], - this->problem_(), - *elemIt, - fvGeometry, - scvIdx, - false); - - (*pW)[globalIdx] = volVars.pressure(wPhaseIdx); - (*pN)[globalIdx] = volVars.pressure(nPhaseIdx); - (*pC)[globalIdx] = volVars.capillaryPressure(); - (*Sw)[globalIdx] = volVars.saturation(wPhaseIdx); - (*Sn)[globalIdx] = volVars.saturation(nPhaseIdx); - (*rhoW)[globalIdx] = volVars.density(wPhaseIdx); - (*rhoN)[globalIdx] = volVars.density(nPhaseIdx); - (*mobW)[globalIdx] = volVars.mobility(wPhaseIdx); - (*mobN)[globalIdx] = volVars.mobility(nPhaseIdx); - (*poro)[globalIdx] = volVars.porosity(); - (*Te)[globalIdx] = volVars.temperature(); - if(velocityOutput) - { - (*cellNum)[globalIdx] += 1; - } - } - - if(velocityOutput) - { - // calculate vertex velocities - GlobalPosition tmpVelocity[numPhases]; - - for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - tmpVelocity[phaseIdx] = Scalar(0.0); - } - - typedef Dune::BlockVector<Dune::FieldVector<Scalar, dim> > SCVVelocities; - SCVVelocities scvVelocityW(8), scvVelocityN(8); - - scvVelocityW = 0; - scvVelocityN = 0; - - ElementVolumeVariables elemVolVars; - - elemVolVars.update(this->problem_(), - *elemIt, - fvGeometry, - false /* oldSol? */); - - for (int faceIdx = 0; faceIdx < fvGeometry.numEdges; faceIdx++) - { - FluxVariables fluxVars(this->problem_(), - *elemIt, - fvGeometry, - faceIdx, - elemVolVars); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // local position of integration point - const Dune::FieldVector<Scalar, dim>& localPosIP = fvGeometry.subContVolFace[faceIdx].ipLocal; - - // Transformation of the global normal vector to normal vector in the reference element - const typename Element::Geometry::JacobianTransposed& jacobianT1 = - elemIt->geometry().jacobianTransposed(localPosIP); - - const GlobalPosition globalNormal = fluxVars.face().normal; - GlobalPosition localNormal; - jacobianT1.mv(globalNormal, localNormal); - // note only works for cubes - const Scalar localArea = pow(2,-(dim-1)); - - localNormal /= localNormal.two_norm(); - - // Get the Darcy velocities. The Darcy velocities are divided by the area of the subcontrolvolumeface - // in the reference element. - PhasesVector q; - q[phaseIdx] = fluxVars.volumeFlux(phaseIdx) / localArea; - - // transform the normal Darcy velocity into a vector - tmpVelocity[phaseIdx] = localNormal; - tmpVelocity[phaseIdx] *= q[phaseIdx]; - - if(phaseIdx == wPhaseIdx) - { - scvVelocityW[fluxVars.face().i] += tmpVelocity[phaseIdx]; - scvVelocityW[fluxVars.face().j] += tmpVelocity[phaseIdx]; - } - else if(phaseIdx == nPhaseIdx) - { - scvVelocityN[fluxVars.face().i] += tmpVelocity[phaseIdx]; - scvVelocityN[fluxVars.face().j] += tmpVelocity[phaseIdx]; - } - } - } - typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElements; - const Dune::FieldVector<Scalar, dim> &localPos - = ReferenceElements::general(elemIt->geometry().type()).position(0, 0); - - // get the transposed Jacobian of the element mapping - const typename Element::Geometry::JacobianTransposed& jacobianT2 - = elemIt->geometry().jacobianTransposed(localPos); - - // transform vertex velocities from local to global coordinates - for (int i = 0; i < numVerts; ++i) - { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); - // calculate the subcontrolvolume velocity by the Piola transformation - Dune::FieldVector<CoordScalar, dim> scvVelocity(0); - - jacobianT2.mtv(scvVelocityW[i], scvVelocity); - scvVelocity /= elemIt->geometry().integrationElement(localPos); - // add up the wetting phase subcontrolvolume velocities for each vertex - (*velocityW)[globalIdx] += scvVelocity; - - jacobianT2.mtv(scvVelocityN[i], scvVelocity); - scvVelocity /= elemIt->geometry().integrationElement(localPos); - // add up the nonwetting phase subcontrolvolume velocities for each vertex - (*velocityN)[globalIdx] += scvVelocity; - } - } - } - } - - if (numDofs == numElements) // element data - { - writer.attachCellData(*Sn, "Sn"); - writer.attachCellData(*Sw, "Sw"); - writer.attachCellData(*pN, "pn"); - writer.attachCellData(*pW, "pw"); - writer.attachCellData(*pC, "pc"); - writer.attachCellData(*rhoW, "rhoW"); - writer.attachCellData(*rhoN, "rhoN"); - writer.attachCellData(*mobW, "mobW"); - writer.attachCellData(*mobN, "mobN"); - writer.attachCellData(*poro, "porosity"); - writer.attachCellData(*Te, "temperature"); - } - else // vertex data - { - writer.attachVertexData(*Sn, "Sn"); - writer.attachVertexData(*Sw, "Sw"); - writer.attachVertexData(*pN, "pn"); - writer.attachVertexData(*pW, "pw"); - writer.attachVertexData(*pC, "pc"); - writer.attachVertexData(*rhoW, "rhoW"); - writer.attachVertexData(*rhoN, "rhoN"); - writer.attachVertexData(*mobW, "mobW"); - writer.attachVertexData(*mobN, "mobN"); - writer.attachVertexData(*poro, "porosity"); - writer.attachVertexData(*Te, "temperature"); - if(velocityOutput) // check if velocity output is demanded - { - // divide the vertex velocities by the number of adjacent scvs i.e. cells - for(unsigned int globalIdx = 0; globalIdx < numVertices; ++globalIdx) - { - (*velocityW)[globalIdx] /= (*cellNum)[globalIdx]; - (*velocityN)[globalIdx] /= (*cellNum)[globalIdx]; - } - writer.attachVertexData(*velocityW, "velocityW", dim); - writer.attachVertexData(*velocityN, "velocityN", dim); - } - } - writer.attachCellData(*rank, "process rank"); - } -}; -} // end namespace - -#include "2pdfmpropertydefaults.hh" - -#endif // DUMUX_BOXMODELS_2PDFM_MODEL_HH +#include <dumux/implicit/2pdfm/2pdfmmodel.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmproblem.hh b/dumux/boxmodels/2pdfm/2pdfmproblem.hh index fd65e2b68dd2fc9909b991d4f7b4631367888dc1..55ec33b4c7d79b1792d7e2e4a8ba6e8e59adeeb0 100644 --- a/dumux/boxmodels/2pdfm/2pdfmproblem.hh +++ b/dumux/boxmodels/2pdfm/2pdfmproblem.hh @@ -1,79 +1,3 @@ -/***************************************************************************** - * 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 Base class for all problems which use the two-phase DFM box model - */ -#ifndef DUMUX_BOXMODELS_2PDFM_PROBLEM_HH -#define DUMUX_BOXMODELS_2PDFM_PROBLEM_HH +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmproblem.hh instead. -#include <dumux/boxmodels/common/porousmediaboxproblem.hh> -#include "2pdfmproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup BoxBaseProblems - * \ingroup TwoPBoxModel - * \brief Base class for all problems which use the two-phase box model - */ -template<class TypeTag> -class TwoPDFMProblem : public PorousMediaBoxProblem<TypeTag> -{ - typedef PorousMediaBoxProblem<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - -public: - /*! - * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view - * \param verbose Turn verbosity on or off - */ - DUNE_DEPRECATED_MSG("use PorousMediaBoxProblem instead") - TwoPDFMProblem(TimeManager &timeManager, - const GridView &gridView, - bool verbose = true) - : ParentType(timeManager, gridView) - {} - - /*! - * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view - * \param spatialParams The spatial parameters object - * \param verbose Turn verbosity on or off - */ - TwoPDFMProblem(TimeManager &timeManager, - const GridView &gridView, - SpatialParams &spatialParams, - bool verbose = true) - : ParentType(timeManager, gridView) - { - this->newSpatialParams_ = false; - delete this->spatialParams_; - this->spatialParams_ = &spatialParams; - } -}; -} // end namespace - -#endif // DUMUX_BOXMODELS_2PDFM_PROBLEM_HH +#include <dumux/implicit/2pdfm/2pdfmproblem.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmproperties.hh b/dumux/boxmodels/2pdfm/2pdfmproperties.hh index 7d0d2631e056a07bd93b21f6ee3b1d5c4637b3be..277d6411cd2f62c69bce21a1f533ce1cd7e8c55e 100644 --- a/dumux/boxmodels/2pdfm/2pdfmproperties.hh +++ b/dumux/boxmodels/2pdfm/2pdfmproperties.hh @@ -1,69 +1,3 @@ -/***************************************************************************** - * 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 Defines the properties required for the two phase DFM BOX model. - * - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPDFMBoxModel - */ +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmproperties.hh instead. -#ifndef DUMUX_BOXMODELS_2PDFM_PROPERTIES_HH -#define DUMUX_BOXMODELS_2PDFM_PROPERTIES_HH - -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ - -//////////////////////////////// -// properties -//////////////////////////////// -namespace Properties -{ - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for 2pDFM problems -NEW_TYPE_TAG(BoxTwoPDFM, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the weight of the upwind direction in the mass conservation equations -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation -NEW_PROP_TAG(Formulation); //!< The formulation of the model -NEW_PROP_TAG(TwoPDFMIndices); //!< Enumerations for the 2pDFM models -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters -NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the spatial parameters) -NEW_PROP_TAG(MaterialLawParams); //!< The context material law (extracted from the spatial parameters) -NEW_PROP_TAG(WettingPhase); //!< The wetting phase for two-phase models -NEW_PROP_TAG(NonwettingPhase); //!< The non-wetting phase for two-phase models -NEW_PROP_TAG(FluidSystem); //!<The fluid systems including the information about the phases -NEW_PROP_TAG(FluidState); //!<The phases state -NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output -} // end namespace Properties -} // end namespace Dumux - -#endif // DUMUX_BOXMODELS_2PDFM_PROPERTIES_HH +#include <dumux/implicit/2pdfm/2pdfmproperties.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh b/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh index 84121c23b0f4ed368d4a5e8b78a18fde2697976c..609ae77881ef1a085ca841029ac5e352e7009d97 100644 --- a/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh +++ b/dumux/boxmodels/2pdfm/2pdfmpropertydefaults.hh @@ -1,144 +1,3 @@ -/***************************************************************************** - * 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 Defines default values for the properties required by the - * 2pDFM box model. - * - * \ingroup Properties - * \ingroup TwoPDFMBoxModel - * \ingroup BoxProperties - */ -#ifndef DUMUX_BOXMODELS_2PDFM_PROPERTY_DEFAULTS_HH -#define DUMUX_BOXMODELS_2PDFM_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmpropertydefaults.hh instead. -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include <dumux/material/components/nullcomponent.hh> -#include <dumux/material/fluidstates/immisciblefluidstate.hh> -#include <dumux/material/fluidsystems/2pimmisciblefluidsystem.hh> -#include <dumux/material/fluidsystems/gasphase.hh> -#include <dumux/material/fluidsystems/liquidphase.hh> -#include <dumux/material/spatialparams/boxspatialparams.hh> - -#include "2pdfmmodel.hh" -#include "2pdfmproblem.hh" -#include "2pdfmindices.hh" -#include "2pdfmfluxvariables.hh" -#include "2pdfmvolumevariables.hh" -#include "2pdfmproperties.hh" - -namespace Dumux -{ -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Property defaults -////////////////////////////////////////////////////////////////// -SET_INT_PROP(BoxTwoPDFM, NumEq, 2); //!< set the number of equations to 2 -SET_INT_PROP(BoxTwoPDFM, NumPhases, 2); //!< The number of phases in the 2p model is 2 - -//! Set the default formulation to pWsN -SET_INT_PROP(BoxTwoPDFM, - Formulation, - TwoPFormulation::pwSn); - -//! Use the 2p local jacobian operator for the 2p model -SET_TYPE_PROP(BoxTwoPDFM, - LocalResidual, - TwoPDFMLocalResidual<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxTwoPDFM, Model, TwoPDFMModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxTwoPDFM, VolumeVariables, TwoPDFMVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxTwoPDFM, FluxVariables, TwoPDFMFluxVariables<TypeTag>); - -//! the upwind weight for the mass conservation equations. -SET_SCALAR_PROP(BoxTwoPDFM, ImplicitMassUpwindWeight, 1.0); - -//! weight for the upwind mobility in the velocity calculation -SET_SCALAR_PROP(BoxTwoPDFM, ImplicitMobilityUpwindWeight, 1.0); - -//! The indices required by the isothermal 2pDFM model -SET_PROP(BoxTwoPDFM, Indices) -{ private: - enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) }; - public: - typedef TwoPDFMIndices<TypeTag, Formulation, 0> type; -}; - - -//! The spatial parameters to be employed. -//! Use BoxSpatialParams by default. -SET_TYPE_PROP(BoxTwoPDFM, SpatialParams, BoxSpatialParams<TypeTag>); - -/*! - * \brief Set the property for the material parameters by extracting - * it from the material law. - */ -SET_TYPE_PROP(BoxTwoPDFM, - MaterialLawParams, - typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params); - -SET_PROP(BoxTwoPDFM, WettingPhase) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -SET_PROP(BoxTwoPDFM, NonwettingPhase) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -SET_PROP(BoxTwoPDFM, FluidSystem) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; - -public: - typedef Dumux::FluidSystems::TwoPImmiscible<Scalar, - WettingPhase, - NonwettingPhase> type; -}; - -SET_PROP(BoxTwoPDFM, FluidState) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; -public: - typedef ImmiscibleFluidState<Scalar, FluidSystem> type; -}; - -// disable velocity output by default -SET_BOOL_PROP(BoxTwoPDFM, VtkAddVelocity, false); - -// enable gravity by default -SET_BOOL_PROP(BoxTwoPDFM, ProblemEnableGravity, true); -} // end namespace Properties -} // end namespace Dumux - -#endif // DUMUX_BOXMODELS_2PDFM_PROPERTY_DEFAULTS_HH +#include <dumux/implicit/2pdfm/2pdfmpropertydefaults.hh> diff --git a/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh b/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh index 520d902aa38bb5fbf6fcf2bc4acf5f08de7f6ff5..0967498503243527c65dba4719c89af3d9de7ee0 100644 --- a/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh +++ b/dumux/boxmodels/2pdfm/2pdfmvolumevariables.hh @@ -1,386 +1,3 @@ -/***************************************************************************** - * 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 Contains the quantities which are constant within a - * finite volume in the two-phase discrete fracture-matrix model. - */ -#ifndef DUMUX_BOXMODELS_2PDFM_VOLUME_VARIABLES_HH -#define DUMUX_BOXMODELS_2PDFM_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2pdfm/2pdfmvolumevariables.hh instead. -#include <dune/common/fvector.hh> - -#include <dumux/boxmodels/2p/2pvolumevariables.hh> - -#include "2pdfmproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup TwoPDFMBoxModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the two-phase discrete fracture-matrix model. - */ -template <class TypeTag> -class TwoPDFMVolumeVariables : public TwoPVolumeVariables<TypeTag> -{ - typedef TwoPVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pwSn = Indices::pwSn, - pnSw = Indices::pnSw, - pressureIdx = Indices::pressureIdx, - saturationIdx = Indices::saturationIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - formulation = GET_PROP_VALUE(TypeTag, Formulation) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef Dune::UGGrid<2> GridType; - typedef typename GridType::ctype DT; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - typedef Dune::FieldVector<Scalar, dim> LocalPosition; - -public: - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx, - bool isOldSol) - { - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - this->completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_); - - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - - mobilityMatrix_[wPhaseIdx] = - MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx)) - / fluidState_.viscosity(wPhaseIdx); - - mobilityMatrix_[nPhaseIdx] = - MaterialLaw::krn(materialParams, fluidState_.saturation(wPhaseIdx)) - / fluidState_.viscosity(nPhaseIdx); - - // porosity - porosityMatrix_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx); - - // energy related quantities not belonging to the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - asImp_().updateFracture(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - /*! - * \brief Construct the volume variables for all fracture vertices. - * - * \param priVars Primary variables. - * \param problem The problem which needs to be simulated. - * \param element The DUNE Codim<0> entity for which the volume variables ought to be calculated - * \param fvGeometry The finite volume geometry of the element - * \param scvIdx Sub-control volume index - * \param isOldSol Tells whether the model's previous or current solution should be used. - */ - void updateFracture(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx, - bool isOldSol) - { - PrimaryVariables varsFracture; - const MaterialLawParams &materialParamsMatrix = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - Scalar pressure[numPhases]; - Scalar pMatrix[numPhases]; - Scalar pFract[numPhases]; - - satNMatrix_ = priVars[saturationIdx]; - satWMatrix_ = 1.0 - satNMatrix_; - satN_ = satNMatrix_; - satW_ = satWMatrix_; - - pCMatrix_ = MaterialLaw::pC(materialParamsMatrix, satWMatrix_); - pC_ = pCMatrix_; - //pressures - pMatrix[wPhaseIdx] = priVars[pressureIdx]; - pMatrix[nPhaseIdx] = pMatrix[wPhaseIdx] + pCMatrix_; - //Initialize pFract with the same values as the ones in the matrix - pFract[wPhaseIdx] = pMatrix[wPhaseIdx]; - pFract[nPhaseIdx] = satNMatrix_; - - varsFracture[pressureIdx] = pFract[wPhaseIdx]; - varsFracture[saturationIdx] = pFract[wPhaseIdx]; - - this->completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidStateFracture_); - - //Checks if the node is on a fracture - isNodeOnFracture_ = problem.spatialParams().isVertexFracture(element, scvIdx); - - /////////////////////////////////////////////////////////////////////////////// - if (isNodeOnFracture_) - { - const MaterialLawParams &materialParamsFracture = - problem.spatialParams().materialLawParamsFracture(element, fvGeometry, scvIdx); - - satNFracture_ = priVars[saturationIdx]; - satWFracture_ = 1 - satNFracture_; - pCFracture_ = MaterialLaw::pC(materialParamsFracture, satWFracture_); - pFract[wPhaseIdx] = priVars[pressureIdx]; - pFract[nPhaseIdx] = pFract[wPhaseIdx] + pCFracture_; - pEntryMatrix_ = MaterialLaw::pC(materialParamsMatrix, 1); - - //use interface condition - extended capillary pressure inteface condition - if (problem.useInterfaceCondition()) - { - interfaceCondition(materialParamsMatrix); - } - pC_ = pCFracture_; - satW_ = satWFracture_; //for plotting we are interested in the saturations of the fracture - satN_ = satNFracture_; - mobilityFracture_[wPhaseIdx] = - MaterialLaw::krw(materialParamsFracture, fluidStateFracture_.saturation(wPhaseIdx)) - / fluidStateFracture_.viscosity(wPhaseIdx); - - mobilityFracture_[nPhaseIdx] = - MaterialLaw::krn(materialParamsFracture, fluidStateFracture_.saturation(wPhaseIdx)) - / fluidStateFracture_.viscosity(nPhaseIdx); - - // derivative resulted from BrooksCorey pc_Sw formulation - dSM_dSF_ = (1 - problem.spatialParams().SwrM_) / (1 - problem.spatialParams().SwrF_) - * pow((problem.spatialParams().pdM_/ problem.spatialParams().pdF_),problem.spatialParams().lambdaM_) - * (problem.spatialParams().lambdaM_ / problem.spatialParams().lambdaF_) - * pow((satWFracture_ - problem.spatialParams().SwrF_ ) / (1 - problem.spatialParams().SwrF_), - (problem.spatialParams().lambdaM_ / problem.spatialParams().lambdaF_) - 1); - }// end if (node) - /////////////////////////////////////////////////////////////////////////////// - else - { - /* the values of pressure and saturation of the fractures in the volumes where - there are no fracture are set unphysical*/ - satNFracture_ = -1; - satWFracture_ = -1; - pCFracture_ = -1e100; - pFract[wPhaseIdx] = -1e100; - pFract[nPhaseIdx] = -1e100; - pEntryMatrix_ = -1e100; - mobilityFracture_[wPhaseIdx] = 0.0; - mobilityFracture_[nPhaseIdx] = 0.0; - } - /////////////////////////////////////////////////////////////////////////////// - pressure[wPhaseIdx] = priVars[pressureIdx]; - pressure[nPhaseIdx] = pressure[wPhaseIdx] + pC_; - - porosityFracture_ = problem.spatialParams().porosityFracture(element, - fvGeometry, - scvIdx); - } - - /*! - * \brief Extended capillary pressure saturation interface condition - * - * \param materialParamsMatrix the material law o calculate the Sw as inverse of capillary pressure function - * - * This method is called by updateFracture - */ - void interfaceCondition(const MaterialLawParams &materialParamsMatrix) - { - /*2nd condition Niessner, J., R. Helmig, H. Jakobs, and J.E. Roberts. 2005, eq.10 - * if the capillary pressure in the fracture is smaller than the entry pressure - * in the matrix than in the matrix - * */ - if (pCFracture_ <= pEntryMatrix_) - { - satWMatrix_ = 1.0; - satNMatrix_ = 1 - satWMatrix_; - } - //3rd condition Niessner, J., R. Helmig, H. Jakobs, and J.E. Roberts. 2005, eq.10 - else - { - /* - * Inverse capillary pressure function SwM = pcM^(-1)(pcF(SwF)) - */ - satWMatrix_ = MaterialLaw::Sw(materialParamsMatrix, pCFracture_); - satNMatrix_ = 1 - satWMatrix_; - } - } - - /*! - * \brief Calculates the volume of the fracture inside the SCV - */ - Scalar calculateSCVFractureVolume ( const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) - { - Scalar volSCVFracture; - Dune::GeometryType gt = element.geometry().type(); - const typename Dune::GenericReferenceElementContainer<DT,dim>::value_type& - refElem = Dune::GenericReferenceElements<DT,dim>::general(gt); - - for (int faceIdx=0; faceIdx<refElem.size(1); faceIdx++) - { - SCVFace face = fvGeometry.subContVolFace[faceIdx]; - int i=face.i; - int j=face.j; - - if (problem.spatialParams().isEdgeFracture(element, faceIdx) - && (i == scvIdx || j == scvIdx)) - { - Scalar fracture_width = problem.spatialParams().fractureWidth(); - - const GlobalPosition global_i = element.geometry().corner(i); - const GlobalPosition global_j = element.geometry().corner(j); - GlobalPosition diff_ij = global_j; - diff_ij -=global_i; - //fracture length in the subcontrol volume is half d_ij - Scalar fracture_length = 0.5*diff_ij.two_norm(); - - volSCVFracture += 0.5 * fracture_length * fracture_width; - } - } - return volSCVFracture; - } - - /*! - * \brief Returns the effective saturation fracture of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar saturationFracture(int phaseIdx) const - { - if (phaseIdx == wPhaseIdx) - return satWFracture_; - else - return satNFracture_; - } - Scalar saturationMatrix(int phaseIdx) const - { - if (phaseIdx == wPhaseIdx) - return satWMatrix_; - else - return satNMatrix_; - } - - /*! - * \brief Returns the effective mobility of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar mobility(int phaseIdx) const - { return mobilityMatrix_[phaseIdx]; } - - /*! - * \brief Returns the effective mobility of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar mobilityFracture(int phaseIdx) const - { return mobilityFracture_[phaseIdx]; } - - /*! - * \brief Returns the average porosity within the matrix control volume. - */ - Scalar porosity() const - { return porosityMatrix_; } - - /*! - * \brief Returns the average porosity within the fracture. - */ - Scalar porosityFracture() const - { return porosityFracture_; } - - /*! - * \brief Returns the average permeability within the fracture. - */ - Scalar permeabilityFracture() const - { return permeabilityFracture_; } - - /*! - * \brief Returns the derivative dSM/dSF - */ - Scalar dSM_dSF() const - { return dSM_dSF_;} - -protected: - FluidState fluidState_; - FluidState fluidStateFracture_; - Scalar porosityMatrix_; - Scalar porosityFracture_; - Scalar permeability_; - Scalar permeabilityFracture_; - Scalar mobilityMatrix_[numPhases]; - Scalar mobilityFracture_[numPhases]; - - Scalar satW_; - Scalar satWFracture_; - Scalar satWMatrix_; - Scalar satN_; - Scalar satNFracture_; - Scalar satNMatrix_; - - Scalar pC_; - Scalar pCFracture_; - Scalar pCMatrix_; - Scalar pEntryMatrix_; - Scalar dSM_dSF_; - - bool isNodeOnFracture_; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; -} // end namespace - -#endif // DUMUX_BOXMODELS_2PDFM_VOLUME_VARIABLES_HH +#include <dumux/implicit/2pdfm/2pdfmvolumevariables.hh> diff --git a/dumux/boxmodels/2pni/2pnifluxvariables.hh b/dumux/boxmodels/2pni/2pnifluxvariables.hh index ae3f474f72ab4a59268b01270180a60b9f832788..fe60e69e5505495d47216d686f85925a73644d3f 100644 --- a/dumux/boxmodels/2pni/2pnifluxvariables.hh +++ b/dumux/boxmodels/2pni/2pnifluxvariables.hh @@ -1,127 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes (mass and energy) of all phases over a face of a finite volume. - * - * This means pressure and temperature gradients, phase densities at - * the integration point, etc. - */ -#ifndef DUMUX_2PNI_FLUX_VARIABLES_HH -#define DUMUX_2PNI_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2pni/2pnifluxvariables.hh instead. -#include <dumux/common/math.hh> -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup TwoPNIModel - * \ingroup BoxFluxVariables - * \brief This template class contains the data which is required to - * calculate all fluxes (mass and energy) of all phases over a - * face of a finite volume for the non-isothermal two-phase model. - * - * This means pressure and concentration gradients, phase densities at - * the integration point, etc. - */ -template <class TypeTag> -class TwoPNIFluxVariables : public BoxDarcyFluxVariables<TypeTag> -{ - typedef BoxDarcyFluxVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { dimWorld = GridView::dimensionworld }; - - typedef typename GridView::ctype CoordScalar; - typedef Dune::FieldVector<CoordScalar, dimWorld> Vector; - -public: - - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - - TwoPNIFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : ParentType(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary) - { - // calculate temperature gradient using finite element - // gradients - Vector temperatureGrad(0); - for (int idx = 0; idx < fvGeometry.numFAP; idx++) - { - Vector feGrad = this->face().grad[idx]; - - // index for the element volume variables - int volVarsIdx = this->face().fapIndices[idx]; - - feGrad *= elemVolVars[volVarsIdx].temperature(); - temperatureGrad += feGrad; - } - - // The spatial parameters calculates the actual heat flux vector - Vector heatFlux; - problem.spatialParams().matrixHeatFlux(heatFlux, - *this, - elemVolVars, - temperatureGrad, - element, - fvGeometry, - faceIdx); - // project the heat flux vector on the face's normal vector - normalMatrixHeatFlux_ = heatFlux * this->face().normal; - } - - /*! - * \brief The total heat flux \f$\mathrm{[J/s]}\f$ due to heat conduction - * of the rock matrix over the sub-control volume's face in - * direction of the face normal. - */ - Scalar normalMatrixHeatFlux() const - { return normalMatrixHeatFlux_; } - -private: - Scalar normalMatrixHeatFlux_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/2pni/2pnifluxvariables.hh> diff --git a/dumux/boxmodels/2pni/2pniindices.hh b/dumux/boxmodels/2pni/2pniindices.hh index 2eafe784d386eb5dfea4c824e6f28ffbe6cb0a09..0bf09c090446c9d9352b59b0f0b9a1708151afcf 100644 --- a/dumux/boxmodels/2pni/2pniindices.hh +++ b/dumux/boxmodels/2pni/2pniindices.hh @@ -1,48 +1,3 @@ -// -*- 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 Defines the indices used by the non-isotherm two-phase BOX model. - */ -#ifndef DUMUX_2PNI_INDICES_HH -#define DUMUX_2PNI_INDICES_HH +#warning This file is deprecated. Include dumux/implicit/2pni/2pniindices.hh instead. -#include <dumux/boxmodels/2p/2pindices.hh> - -namespace Dumux -{ -// \{ - -/*! - * \ingroup TwoPNIModel - * \ingroup BoxIndices - * \brief Enumerations for the non-isothermal two-phase model - */ -template <class TypeTag, int PVOffset = 0> -class TwoPNIIndices : public TwoPIndices<TypeTag, PVOffset> -{ -public: - static const int temperatureIdx = PVOffset + 2; //! The primary variable index for temperature - static const int energyEqIdx = PVOffset + 2; //! The equation index of the energy equation -}; -// \} -} - -#endif +#include <dumux/implicit/2pni/2pniindices.hh> diff --git a/dumux/boxmodels/2pni/2pnilocalresidual.hh b/dumux/boxmodels/2pni/2pnilocalresidual.hh index bb1f1e3b900c310b1b955164693ff9f8b10c5499..f675534b0b994f7f5aa2e1af121e72561d936c44 100644 --- a/dumux/boxmodels/2pni/2pnilocalresidual.hh +++ b/dumux/boxmodels/2pni/2pnilocalresidual.hh @@ -1,182 +1,3 @@ -// -*- 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 Element-wise calculation of the Jacobian matrix for problems - * using the non-isothermal two-phase box model. - * - */ -#ifndef DUMUX_NEW_2PNI_LOCAL_RESIDUAL_HH -#define DUMUX_NEW_2PNI_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/2pni/2pnilocalresidual.hh instead. -#include "2pniproperties.hh" - -#include <dumux/boxmodels/2p/2plocalresidual.hh> - -#include <dumux/boxmodels/2pni/2pnivolumevariables.hh> -#include <dumux/boxmodels/2pni/2pnifluxvariables.hh> - -namespace Dumux -{ -/*! - * \ingroup TwoPNIModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the non-isothermal two-phase box model. - */ - -template<class TypeTag> -class TwoPNILocalResidual : public TwoPLocalResidual<TypeTag> -{ - typedef TwoPLocalResidual<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - temperatureIdx = Indices::temperatureIdx, - energyEqIdx = Indices::energyEqIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - enum { dimWorld = GridView::dimensionworld }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dimWorld> Vector; - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - TwoPNILocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the amount all conservation quantites - * (e.g. phase mass and energy storage) within a sub-control volume. - * - * The result should be averaged over the volume (e.g. phase mass - * inside a sub control volume divided by the volume) - * - * \param storage The phase mass within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const - { - // compute the storage term for phase mass - ParentType::computeStorage(storage, scvIdx, usePrevSol); - - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - // compute the energy storage - storage[temperatureIdx] = - volVars.porosity()*(volVars.density(wPhaseIdx) * - volVars.internalEnergy(wPhaseIdx) * - volVars.saturation(wPhaseIdx) - + - volVars.density(nPhaseIdx) * - volVars.internalEnergy(nPhaseIdx) * - volVars.saturation(nPhaseIdx)) - + volVars.temperature()*volVars.heatCapacity(); - } - - /*! - * \brief Evaluates the advective mass flux and the heat flux - * over a face of a subcontrol volume and writes the result in - * the flux vector. - * - * \param flux The advective flux over the sub-control-volume face for each phase - * \param fluxVars The flux variables at the current SCV - * - * - * This method is called by compute flux (base class) - */ - void computeAdvectiveFlux(PrimaryVariables &flux, - const FluxVariables &fluxVars) const - { - // advective mass flux - ParentType::computeAdvectiveFlux(flux, fluxVars); - - // advective heat flux in all phases - flux[energyEqIdx] = 0; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx)); - const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx)); - - // add advective energy flux in current phase - flux[energyEqIdx] += - fluxVars.volumeFlux(phaseIdx) - * - (( massUpwindWeight_)* - up.density(phaseIdx)* - up.enthalpy(phaseIdx) - + - (1 - massUpwindWeight_)* - dn.density(phaseIdx)* - dn.enthalpy(phaseIdx)); - } - } - - /*! - * \brief Adds the diffusive heat flux to the flux vector over - * the face of a sub-control volume. - * - * \param flux The diffusive flux over the sub-control-volume face for each phase - * \param fluxVars The flux variables at the current SCV - * - */ - void computeDiffusiveFlux(PrimaryVariables &flux, - const FluxVariables &fluxVars) const - { - // diffusive mass flux - ParentType::computeDiffusiveFlux(flux, fluxVars); - - // diffusive heat flux - flux[energyEqIdx] += fluxVars.normalMatrixHeatFlux(); - } - -private: - Scalar massUpwindWeight_; - -}; - -} - -#endif +#include <dumux/implicit/2pni/2pnilocalresidual.hh> diff --git a/dumux/boxmodels/2pni/2pnimodel.hh b/dumux/boxmodels/2pni/2pnimodel.hh index 81352b3569dcaffd96326cdcc17e3df62df2c44b..33f26c05dedfd885d070700fccb9e815384197a0 100644 --- a/dumux/boxmodels/2pni/2pnimodel.hh +++ b/dumux/boxmodels/2pni/2pnimodel.hh @@ -1,93 +1,3 @@ -// -*- 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 Adaption of the BOX scheme to the non-isothermal twophase flow model. - */ -#ifndef DUMUX_2PNI_MODEL_HH -#define DUMUX_2PNI_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/2pni/2pnimodel.hh instead. -#include <dumux/boxmodels/2p/2pmodel.hh> - -namespace Dumux { - -/*! - * \ingroup TwoPNIBoxModel - * \brief A two-phase, non-isothermal flow model using the box scheme. - * - * This model implements a non-isothermal two-phase flow for two - * immiscible fluids \f$\alpha \in \{ w, n \}\f$. Using the standard - * multiphase Darcy approach, the mass conservation equations for both - * phases can be described as follows: - * \f[ - \phi \frac{\partial \phi \varrho_\alpha S_\alpha}{\partial t} - - - \text{div} - \left\{ - \varrho_\alpha \frac{k_{r\alpha}}{\mu_\alpha} \mathrm{K} - \left( \textrm{grad}\, p_\alpha - \varrho_{\alpha} \mathbf{g} \right) - \right\} - - - q_\alpha = 0 \qquad \alpha \in \{w, n\} - \f] - * - * For the energy balance, local thermal equilibrium is assumed. This - * results in one energy conservation equation for the porous solid - * matrix and the fluids: - - \f{align*}{ - \frac{\partial \phi \sum_\alpha \varrho_\alpha u_\alpha S_\alpha}{\partial t} - & + - \left( 1 - \phi \right) \frac{\partial (\varrho_s c_s T)}{\partial t} - - - \sum_\alpha \text{div} - \left\{ - \varrho_\alpha h_\alpha - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} - \left( \textbf{grad}\,p_\alpha - \varrho_\alpha \mbox{\bf g} \right) - \right\} \\ - & - \text{div} \left(\lambda_{pm} \textbf{grad} \, T \right) - - q^h = 0, \qquad \alpha \in \{w, n\} \;, - \f} - * where \f$h_\alpha\f$ is the specific enthalpy of a fluid phase - * \f$\alpha\f$ and \f$u_\alpha = h_\alpha - - * p_\alpha/\varrho_\alpha\f$ is the specific internal energy of the - * phase. - * - * The equations are discretized using a fully-coupled vertex centered - * finite volume (box) scheme as spatial and the implicit Euler method - * as time discretization. - * - * Currently the model supports choosing either \f$p_w\f$, \f$S_n\f$ - * and \f$T\f$ or \f$p_n\f$, \f$S_w\f$ and \f$T\f$ as primary - * variables. The formulation which ought to be used can be specified - * by setting the <tt>Formulation</tt> property to either - * <tt>TwoPNIIndices::pWsN</tt> or <tt>TwoPIndices::pNsW</tt>. By - * default, the model uses \f$p_w\f$, \f$S_n\f$ and \f$T\f$. - */ -template<class TypeTag> -class TwoPNIModel: public TwoPModel<TypeTag> -{}; - -} - -#include "2pnipropertydefaults.hh" - -#endif +#include <dumux/implicit/2pni/2pnimodel.hh> diff --git a/dumux/boxmodels/2pni/2pniproperties.hh b/dumux/boxmodels/2pni/2pniproperties.hh index d58ba13095b3d7599f197642b036cba63c1beb50..f647a9ad4bef18e096198c76ce553da76234aa44 100644 --- a/dumux/boxmodels/2pni/2pniproperties.hh +++ b/dumux/boxmodels/2pni/2pniproperties.hh @@ -1,47 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPNIBoxModel - * \file - * - * \brief Defines the properties required for the non-isotherm two-phase BOX model. - */ -#ifndef DUMUX_2PNI_PROPERTIES_HH -#define DUMUX_2PNI_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/2pni/2pniproperties.hh instead. -#include <dumux/boxmodels/2p/2pproperties.hh> - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the non-isothermal two-phase problems -NEW_TYPE_TAG(BoxTwoPNI, INHERITS_FROM(BoxTwoP)); - -} -} - -#endif +#include <dumux/implicit/2pni/2pniproperties.hh> diff --git a/dumux/boxmodels/2pni/2pnipropertydefaults.hh b/dumux/boxmodels/2pni/2pnipropertydefaults.hh index 2a96f75eb1146062bbc5de3f3bcae0ce3f0adf80..bf13b70f50306eb04fb3534556a07095469d2141 100644 --- a/dumux/boxmodels/2pni/2pnipropertydefaults.hh +++ b/dumux/boxmodels/2pni/2pnipropertydefaults.hh @@ -1,72 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup TwoPNIBoxModel - * \file - * - * \brief Defines the default values for most of the properties - * required by the non-isotherm two-phase box model. - */ +#warning This file is deprecated. Include dumux/implicit/2pni/2pnipropertydefaults.hh instead. -#ifndef DUMUX_2PNI_PROPERTY_DEFAULTS_HH -#define DUMUX_2PNI_PROPERTY_DEFAULTS_HH - -#include "2pniproperties.hh" -#include "2pnimodel.hh" -#include "2pnilocalresidual.hh" -#include "2pnivolumevariables.hh" -#include "2pnifluxvariables.hh" -#include "2pniindices.hh" - -namespace Dumux -{ - - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Property values -////////////////////////////////////////////////////////////////// - -SET_INT_PROP(BoxTwoPNI, NumEq, 3); //!< set the number of equations to 3 - -//! Use the 2pni local jacobian operator for the 2pni model -SET_TYPE_PROP(BoxTwoPNI, - LocalResidual, - TwoPNILocalResidual<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxTwoPNI, Model, TwoPNIModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxTwoPNI, VolumeVariables, TwoPNIVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxTwoPNI, FluxVariables, TwoPNIFluxVariables<TypeTag>); - -//! The indices required by the non-isothermal two-phase model -SET_TYPE_PROP(BoxTwoPNI, Indices, TwoPNIIndices<TypeTag, 0>); - -} - -} - -#endif +#include <dumux/implicit/2pni/2pnipropertydefaults.hh> diff --git a/dumux/boxmodels/2pni/2pnivolumevariables.hh b/dumux/boxmodels/2pni/2pnivolumevariables.hh index eec5780365e527563d8f6ff12ab408c7fc4710f2..aff5be90bbd81646814e0d175dbd2a8a444910b6 100644 --- a/dumux/boxmodels/2pni/2pnivolumevariables.hh +++ b/dumux/boxmodels/2pni/2pnivolumevariables.hh @@ -1,124 +1,3 @@ -// -*- 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 Contains the quantities which are are constant within a - * finite volume in the non-isothermal two-phase model. - */ -#ifndef DUMUX_2PNI_VOLUME_VARIABLES_HH -#define DUMUX_2PNI_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/2pni/2pnivolumevariables.hh instead. -#include <dumux/boxmodels/2p/2pvolumevariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup TwoPNIModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are constant within a - * finite volume in the non-isothermal two-phase model. - */ -template <class TypeTag> -class TwoPNIVolumeVariables : public TwoPVolumeVariables<TypeTag> -{ - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { temperatureIdx = Indices::temperatureIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - -public: - /*! - * \brief Returns the total internal energy of a phase in the - * sub-control volume. - * - * \param phaseIdx The phase index - * - */ - Scalar internalEnergy(int phaseIdx) const - { return this->fluidState_.internalEnergy(phaseIdx); }; - - /*! - * \brief Returns the total enthalpy of a phase in the sub-control - * volume. - * - * \param phaseIdx The phase index - */ - Scalar enthalpy(int phaseIdx) const - { return this->fluidState_.enthalpy(phaseIdx); }; - - /*! - * \brief Returns the total heat capacity \f$\mathrm{[J/K*m^3]}\f$ of the rock matrix in - * the sub-control volume. - */ - Scalar heatCapacity() const - { return heatCapacity_; }; - -protected: - // this method gets called by the parent class. since this method - // is protected, we are friends with our parent.. - friend class TwoPVolumeVariables<TypeTag>; - - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) - { - return priVars[Indices::temperatureIdx]; - } - - template<class ParameterCache> - static Scalar enthalpy_(const FluidState& fluidState, - const ParameterCache& paramCache, - int phaseIdx) - { - return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); - } - - /*! - * \brief Called by update() to compute the energy related quantities - */ - void updateEnergy_(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx, - bool isOldSol) - { - // copmute and set the heat capacity of the solid phase - heatCapacity_ = problem.spatialParams().heatCapacity(element, fvGeometry, scvIdx); - Valgrind::CheckDefined(heatCapacity_); - } - - Scalar heatCapacity_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/2pni/2pnivolumevariables.hh> diff --git a/dumux/boxmodels/3p3c/3p3cfluxvariables.hh b/dumux/boxmodels/3p3c/3p3cfluxvariables.hh index a687fb3d64382bc18de6b9b8fd98678ffba70937..86d5929b66e120ff384c90f2d4b72fd981300cb4 100644 --- a/dumux/boxmodels/3p3c/3p3cfluxvariables.hh +++ b/dumux/boxmodels/3p3c/3p3cfluxvariables.hh @@ -1,335 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes of components over a face of a finite volume for - * the two-phase, two-component model. - */ -/*! - * \ingroup ThreePThreeCModel - */ -#ifndef DUMUX_3P3C_FLUX_VARIABLES_HH -#define DUMUX_3P3C_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cfluxvariables.hh instead. -#include <dumux/common/math.hh> -#include <dumux/common/spline.hh> - -#include "3p3cproperties.hh" - -namespace Dumux -{ - -/*! - * \brief This template class contains the data which is required to - * calculate all fluxes of components over a face of a finite - * volume for the two-phase, two-component model. - * - * This means pressure and concentration gradients, phase densities at - * the integration point, etc. - */ -template <class TypeTag> -class ThreePThreeCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables) -{ - typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld, - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - - typedef Dune::FieldVector<Scalar, dim> DimVector; - typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - gCompIdx = Indices::gCompIdx - }; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - ThreePThreeCFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : BaseFluxVariables(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary) - { - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - density_[phaseIdx] = Scalar(0); - molarDensity_[phaseIdx] = Scalar(0); - massFractionCompWGrad_[phaseIdx] = Scalar(0); - massFractionCompNGrad_[phaseIdx] = Scalar(0); - massFractionCompGGrad_[phaseIdx] = Scalar(0); - moleFractionCompWGrad_[phaseIdx] = Scalar(0); - moleFractionCompNGrad_[phaseIdx] = Scalar(0); - moleFractionCompGGrad_[phaseIdx] = Scalar(0); - } - - calculateGradients_(problem, element, elemVolVars); - calculateporousDiffCoeff_(problem, element, elemVolVars); - }; - -private: - void calculateGradients_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // calculate gradients - DimVector tmp(0.0); - for (int idx = 0; - idx < this->fvGeometry_.numFAP; - idx++) // loop over adjacent vertices - { - // FE gradient at vertex idx - const DimVector &feGrad = this->face().grad[idx]; - - // index for the element volume variables - int volVarsIdx = this->face().fapIndices[idx]; - - // the concentration gradient of the components - // component in the phases - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(wPhaseIdx, wCompIdx); - massFractionCompWGrad_[wPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(nPhaseIdx, wCompIdx); - massFractionCompWGrad_[nPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(gPhaseIdx, wCompIdx); - massFractionCompWGrad_[gPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(wPhaseIdx, nCompIdx); - massFractionCompNGrad_[wPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(nPhaseIdx, nCompIdx); - massFractionCompNGrad_[nPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(gPhaseIdx, nCompIdx); - massFractionCompNGrad_[gPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(wPhaseIdx, gCompIdx); - massFractionCompGGrad_[wPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(nPhaseIdx, gCompIdx); - massFractionCompGGrad_[nPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().massFraction(gPhaseIdx, gCompIdx); - massFractionCompGGrad_[gPhaseIdx] += tmp; - - // the molar concentration gradients of the components - // in the phases - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(wPhaseIdx, wCompIdx); - moleFractionCompWGrad_[wPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(nPhaseIdx, wCompIdx); - moleFractionCompWGrad_[nPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(gPhaseIdx, wCompIdx); - moleFractionCompWGrad_[gPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(wPhaseIdx, nCompIdx); - moleFractionCompNGrad_[wPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(nPhaseIdx, nCompIdx); - moleFractionCompNGrad_[nPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(gPhaseIdx, nCompIdx); - moleFractionCompNGrad_[gPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(wPhaseIdx, gCompIdx); - moleFractionCompGGrad_[wPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(nPhaseIdx, gCompIdx); - moleFractionCompGGrad_[nPhaseIdx] += tmp; - - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(gPhaseIdx, gCompIdx); - moleFractionCompGGrad_[gPhaseIdx] += tmp; - } - } - - Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &elemVolVars) - { - static const Scalar eps = 1e-2; - const Scalar sat = elemVolVars[scvIdx].density(phaseIdx); - if (sat > eps) - return 0.5; - if (sat <= 0) - return 0; - - static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1 - 0, 0.5, // y0, y1 - 0, 0); // m0, m1 - return sp.eval(sat); - } - - void calculateporousDiffCoeff_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - - const VolumeVariables &volVarsI = elemVolVars[this->face().i]; - const VolumeVariables &volVarsJ = elemVolVars[this->face().j]; - - Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficientMatrix_i = volVarsI.diffusionCoefficient(); - Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficientMatrix_j = volVarsJ.diffusionCoefficient(); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // make sure to calculate only diffusion coefficents - // for phases which exist in both finite volumes - /* \todo take care: This should be discussed once again - * as long as a meaningful value can be found for the required mole fraction - * diffusion should work even without this one here */ - if (volVarsI.saturation(phaseIdx) <= 0 || - volVarsJ.saturation(phaseIdx) <= 0) - { - porousDiffCoeff_[phaseIdx][wCompIdx] = 0.0; - porousDiffCoeff_[phaseIdx][nCompIdx] = 0.0; - porousDiffCoeff_[phaseIdx][gCompIdx] = 0.0; - continue; - } - - // calculate tortuosity at the nodes i and j needed - // for porous media diffusion coefficient - - Scalar tauI = - 1.0/(volVarsI.porosity() * volVarsI.porosity()) * - pow(volVarsI.porosity() * volVarsI.saturation(phaseIdx), 7.0/3); - Scalar tauJ = - 1.0/(volVarsJ.porosity() * volVarsJ.porosity()) * - pow(volVarsJ.porosity() * volVarsJ.saturation(phaseIdx), 7.0/3); - // Diffusion coefficient in the porous medium - - // -> harmonic mean - porousDiffCoeff_[phaseIdx][wCompIdx] = harmonicMean(volVarsI.porosity() * volVarsI.saturation(phaseIdx) * tauI * diffusionCoefficientMatrix_i[phaseIdx][wCompIdx], - volVarsJ.porosity() * volVarsJ.saturation(phaseIdx) * tauJ * diffusionCoefficientMatrix_j[phaseIdx][wCompIdx]); - porousDiffCoeff_[phaseIdx][nCompIdx] = harmonicMean(volVarsI.porosity() * volVarsI.saturation(phaseIdx) * tauI * diffusionCoefficientMatrix_i[phaseIdx][nCompIdx], - volVarsJ.porosity() * volVarsJ.saturation(phaseIdx) * tauJ * diffusionCoefficientMatrix_j[phaseIdx][nCompIdx]); - porousDiffCoeff_[phaseIdx][gCompIdx] = harmonicMean(volVarsI.porosity() * volVarsI.saturation(phaseIdx) * tauI * diffusionCoefficientMatrix_i[phaseIdx][gCompIdx], - volVarsJ.porosity() * volVarsJ.saturation(phaseIdx) * tauJ * diffusionCoefficientMatrix_j[phaseIdx][gCompIdx]); - - } - } - -public: - /*! - * \brief The diffusivity matrix - */ - Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff() const - { return porousDiffCoeff_; }; - - /*! - * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase. - */ - Scalar density(int phaseIdx) const - { return density_[phaseIdx]; } - - /*! - * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase. - */ - Scalar molarDensity(int phaseIdx) const - { return molarDensity_[phaseIdx]; } - - const DimVector &massFractionCompWGrad(int phaseIdx) const - {return massFractionCompWGrad_[phaseIdx];} - - const DimVector &massFractionCompNGrad(int phaseIdx) const - { return massFractionCompNGrad_[phaseIdx]; }; - - const DimVector &massFractionCompGGrad(int phaseIdx) const - { return massFractionCompGGrad_[phaseIdx]; }; - - const DimVector &moleFractionCompWGrad(int phaseIdx) const - { return moleFractionCompWGrad_[phaseIdx]; }; - - const DimVector &moleFractionCompNGrad(int phaseIdx) const - { return moleFractionCompNGrad_[phaseIdx]; }; - - const DimVector &moleFractionCompGGrad(int phaseIdx) const - { return moleFractionCompGGrad_[phaseIdx]; }; - -protected: - // gradients - DimVector massFractionCompWGrad_[numPhases]; - DimVector massFractionCompNGrad_[numPhases]; - DimVector massFractionCompGGrad_[numPhases]; - DimVector moleFractionCompWGrad_[numPhases]; - DimVector moleFractionCompNGrad_[numPhases]; - DimVector moleFractionCompGGrad_[numPhases]; - - // density of each face at the integration point - Scalar density_[numPhases], molarDensity_[numPhases]; - - // the diffusivity matrix for the porous medium - Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/3p3c/3p3cfluxvariables.hh> diff --git a/dumux/boxmodels/3p3c/3p3cindices.hh b/dumux/boxmodels/3p3c/3p3cindices.hh index 33935edd82a69ea0bae55cf30686f83231529fe3..e0c8e76c208da86e3cb443ab9baa88eb07c372d6 100644 --- a/dumux/boxmodels/3p3c/3p3cindices.hh +++ b/dumux/boxmodels/3p3c/3p3cindices.hh @@ -1,85 +1,3 @@ -// -*- 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 Defines the indices required for the 3p3c BOX model. - */ -#ifndef DUMUX_3P3C_INDICES_HH -#define DUMUX_3P3C_INDICES_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cindices.hh instead. -#include "3p3cproperties.hh" - -namespace Dumux -{ - -/*! - * \brief The indices for the isothermal ThreePThreeC model. - * - * \tparam formulation The formulation, only pgSwSn - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, int PVOffset = 0> -class ThreePThreeCIndices -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - // Phase indices - static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< index of the wetting liquid phase - static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< index of the nonwetting liquid phase - static const int gPhaseIdx = FluidSystem::gPhaseIdx; //!< index of the gas phase - - // Component indices to indicate the main component - // of the corresponding phase at atmospheric pressure 1 bar - // and room temperature 20°C: - static const int wCompIdx = FluidSystem::wCompIdx; - static const int nCompIdx = FluidSystem::nCompIdx; - static const int gCompIdx = FluidSystem::gCompIdx; - - // present phases (-> 'pseudo' primary variable) - static const int threePhases = 1; //!< All three phases are present - static const int wPhaseOnly = 2; //!< Only the water phase is present - static const int gnPhaseOnly = 3; //!< Only gas and NAPL phases are present - static const int wnPhaseOnly = 4; //!< Only water and NAPL phases are present - static const int gPhaseOnly = 5; //!< Only gas phase is present - static const int wgPhaseOnly = 6; //!< Only water and gas phases are present - - // Primary variable indices - static const int pressureIdx = PVOffset + 0; //!< Index for gas phase pressure in a solution vector - static const int switch1Idx = PVOffset + 1; //!< Index 1 of saturation or mole fraction - static const int switch2Idx = PVOffset + 2; //!< Index 2 of saturation or mole fraction - - static const int pgIdx = pressureIdx; //!< Index for gas phase pressure in a solution vector - static const int SOrX1Idx = switch1Idx; //!< Index of the either the saturation of the gas phase or the mass fraction secondary component if a phase is not present - static const int SOrX2Idx = switch2Idx; //!< Index of the either the saturation of the gas phase or the mass fraction secondary component if a phase is not present - - // equation indices - static const int conti0EqIdx = PVOffset + wCompIdx; //!< Index of the mass conservation equation for the water component - static const int conti1EqIdx = conti0EqIdx + nCompIdx; //!< Index of the mass conservation equation for the contaminant component - static const int conti2EqIdx = conti0EqIdx + gCompIdx; //!< Index of the mass conservation equation for the gas component - - static const int contiWEqIdx = conti0EqIdx + wCompIdx; //!< index of the mass conservation equation for the water component - static const int contiNEqIdx = conti0EqIdx + nCompIdx; //!< index of the mass conservation equation for the contaminant component - static const int contiGEqIdx = conti0EqIdx + gCompIdx; //!< index of the mass conservation equation for the air component -}; - -} - -#endif +#include <dumux/implicit/3p3c/3p3cindices.hh> diff --git a/dumux/boxmodels/3p3c/3p3clocalresidual.hh b/dumux/boxmodels/3p3c/3p3clocalresidual.hh index 03b0e2474f66552e8b767c0243c4f891e77deba3..de91429f2b517eec720db1a4dc3653e4e155c738 100644 --- a/dumux/boxmodels/3p3c/3p3clocalresidual.hh +++ b/dumux/boxmodels/3p3c/3p3clocalresidual.hh @@ -1,264 +1,3 @@ -// -*- 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 Element-wise calculation of the Jacobian matrix for problems - * using the two-phase two-component box model. - */ -#ifndef DUMUX_3P3C_LOCAL_RESIDUAL_HH -#define DUMUX_3P3C_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3clocalresidual.hh instead. -#include <dumux/boxmodels/common/boxmodel.hh> -#include <dumux/common/math.hh> - -#include "3p3cproperties.hh" -#include "3p3cvolumevariables.hh" -#include "3p3cfluxvariables.hh" -#include "3p3cnewtoncontroller.hh" -#include "3p3cproperties.hh" - -#include <iostream> -#include <vector> - -//#define VELOCITY_OUTPUT 1 // uncomment this line if an output of the velocity is needed - -namespace Dumux -{ -/*! - * \ingroup ThreePThreeCModel - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the two-phase two-component box model. - * - * This class is used to fill the gaps in BoxLocalResidual for the 3P3C flow. - */ -template<class TypeTag> -class ThreePThreeCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ -protected: - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents), - - conti0EqIdx = Indices::conti0EqIdx,//!< Index of the mass conservation equation for the water component - conti1EqIdx = Indices::conti1EqIdx,//!< Index of the mass conservation equation for the contaminant component - conti2EqIdx = Indices::conti2EqIdx,//!< Index of the mass conservation equation for the gas component - - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - gCompIdx = Indices::gCompIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - -public: - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within a sub-control volume. - * - * The result should be averaged over the volume (e.g. phase mass - * inside a sub control volume divided by the volume) - * - * \param storage The mass of the component within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemVolVars = - usePrevSol - ? this->prevVolVars_() - : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - // compute storage term of all components within all phases - storage = 0; - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - { - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - storage[conti0EqIdx + compIdx] += - volVars.porosity() - * volVars.saturation(phaseIdx) - * volVars.molarDensity(phaseIdx) - * volVars.fluidState().moleFraction(phaseIdx, compIdx); - } - } - } - - /*! - * \brief Evaluates the total flux of all conservation quantities - * over a face of a sub-control volume. - * - * \param flux The flux over the SCV (sub-control-volume) face for each component - * \param faceIdx The index of the SCV face - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, const int faceIdx, const bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - - flux = 0; - asImp_()->computeAdvectiveFlux(flux, fluxVars); - asImp_()->computeDiffusiveFlux(flux, fluxVars); - } - - /*! - * \brief Evaluates the advective mass flux of all components over - * a face of a subcontrol volume. - * - * \param flux The advective flux over the sub-control-volume face for each component - * \param fluxVars The flux variables at the current SCV - */ - - void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - Scalar massUpwindWeight = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - - //////// - // advective fluxes of all components in all phases - //////// - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx)); - const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx)); - - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - { - // add advective flux of current component in current - // phase - // if alpha > 0 und alpha < 1 then both upstream and downstream - // nodes need their contribution - // if alpha == 1 (which is mostly the case) then, the downstream - // node is not evaluated - int eqIdx = conti0EqIdx + compIdx; - flux[eqIdx] += fluxVars.volumeFlux(phaseIdx) - * (massUpwindWeight - * up.fluidState().molarDensity(phaseIdx) - * up.fluidState().moleFraction(phaseIdx, compIdx) - + - (1.0 - massUpwindWeight) - * dn.fluidState().molarDensity(phaseIdx) - * dn.fluidState().moleFraction(phaseIdx, compIdx)); - } - } - } - - /*! - * \brief Adds the diffusive mass flux of all components over - * a face of a subcontrol volume. - * - * \param flux The diffusive flux over the sub-control-volume face for each component - * \param fluxVars The flux variables at the current SCV - */ - - void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const - { - // TODO: reference!? Dune::FieldMatrix<Scalar, numPhases, numComponents> averagedPorousDiffCoeffMatrix = fluxVars.porousDiffCoeff(); - // add diffusive flux of gas component in liquid phase - Scalar tmp = - fluxVars.porousDiffCoeff()[wPhaseIdx][gCompIdx] * fluxVars.molarDensity(wPhaseIdx); - tmp *= (fluxVars.moleFractionCompGGrad(wPhaseIdx) * fluxVars.face().normal); - Scalar jGW = tmp; - - tmp = - fluxVars.porousDiffCoeff()[wPhaseIdx][nCompIdx] * fluxVars.molarDensity(wPhaseIdx); - tmp *= (fluxVars.moleFractionCompNGrad(wPhaseIdx) * fluxVars.face().normal); - Scalar jNW = tmp; - - Scalar jWW = -(jGW+jNW); - - tmp = - fluxVars.porousDiffCoeff()[gPhaseIdx][wCompIdx] * fluxVars.molarDensity(gPhaseIdx); - tmp *= (fluxVars.moleFractionCompWGrad(gPhaseIdx) * fluxVars.face().normal); - Scalar jWG = tmp; - - tmp = - fluxVars.porousDiffCoeff()[gPhaseIdx][nCompIdx] * fluxVars.molarDensity(gPhaseIdx); - tmp *= (fluxVars.moleFractionCompNGrad(gPhaseIdx) * fluxVars.face().normal); - Scalar jNG = tmp; - - Scalar jGG = -(jWG+jNG); - - tmp = - fluxVars.porousDiffCoeff()[nPhaseIdx][wCompIdx] * fluxVars.molarDensity(nPhaseIdx); - tmp *= (fluxVars.moleFractionCompWGrad(nPhaseIdx) * fluxVars.face().normal); - Scalar jWN = tmp; - - tmp = - fluxVars.porousDiffCoeff()[nPhaseIdx][gCompIdx] * fluxVars.molarDensity(nPhaseIdx); - tmp *= (fluxVars.moleFractionCompGGrad(nPhaseIdx) * fluxVars.face().normal); - Scalar jGN = tmp; - - Scalar jNN = -(jGN+jWN); - - flux[conti0EqIdx] += jWW+jWG+jWN; - flux[conti1EqIdx] += jNW+jNG+jNN; - flux[conti2EqIdx] += jGW+jGG+jGN; - } - - /*! - * \brief Calculate the source term of the equation - * - * \param source The source/sink in the SCV for each component - * \param scvIdx The index of the SCV - */ - void computeSource(PrimaryVariables &source, const int scvIdx) - { - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - -protected: - Implementation *asImp_() - { - return static_cast<Implementation *> (this); - } - - const Implementation *asImp_() const - { - return static_cast<const Implementation *> (this); - } -}; - -} // end namepace - -#endif +#include <dumux/implicit/3p3c/3p3clocalresidual.hh> diff --git a/dumux/boxmodels/3p3c/3p3cmodel.hh b/dumux/boxmodels/3p3c/3p3cmodel.hh index c12cadbb93c8ed1289cdab906c0185f883aaefbd..83dc5615ab1f489baeec85f88b37f1b0abe2cd03 100644 --- a/dumux/boxmodels/3p3c/3p3cmodel.hh +++ b/dumux/boxmodels/3p3c/3p3cmodel.hh @@ -1,952 +1,3 @@ -// -*- 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 Adaption of the BOX scheme to the three-phase three-component flow model. - * - * The model is designed for simulating three fluid phases with water, gas, and - * a liquid contaminant (NAPL - non-aqueous phase liquid) - */ -#ifndef DUMUX_3P3C_MODEL_HH -#define DUMUX_3P3C_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cmodel.hh instead. -#include <dumux/material/fluidstates/compositionalfluidstate.hh> - -#include "3p3cproperties.hh" -#include "3p3clocalresidual.hh" - -namespace Dumux -{ -/*! - * \ingroup ThreePThreeCModel - * \brief Adaption of the BOX scheme to the three-phase three-component flow model. - * - * This model implements three-phase three-component flow of three fluid phases - * \f$\alpha \in \{ water, gas, NAPL \}\f$ each composed of up to three components - * \f$\kappa \in \{ water, air, contaminant \}\f$. The standard multiphase Darcy - * approach is used as the equation for the conservation of momentum: - * \f[ - v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} - \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right) - * \f] - * - * By inserting this into the equations for the conservation of the - * components, one transport equation for each component is obtained as - * \f{eqnarray*} - && \phi \frac{\partial (\sum_\alpha \varrho_{\text{mol}, \alpha} x_\alpha^\kappa - S_\alpha )}{\partial t} - - \sum\limits_\alpha \text{div} \left\{ \frac{k_{r\alpha}}{\mu_\alpha} - \varrho_{\text{mol}, \alpha} x_\alpha^\kappa \mbox{\bf K} - (\text{grad}\, p_\alpha - \varrho_{\text{mass}, \alpha} \mbox{\bf g}) \right\} - \nonumber \\ - \nonumber \\ - && - \sum\limits_\alpha \text{div} \left\{ D_{pm}^\kappa \varrho_{\text{mol}, - \alpha } \text{grad}\, x_\alpha^\kappa \right\} - - q^\kappa = 0 \qquad \forall \kappa , \; \forall \alpha - \f} - * - * Note that these balance equations are molar. - * - * The equations are discretized using a fully-coupled vertex - * centered finite volume (BOX) scheme as spatial scheme and - * the implicit Euler method as temporal discretization. - * - * The model uses commonly applied auxiliary conditions like - * \f$S_w + S_n + S_g = 1\f$ for the saturations and - * \f$x^w_\alpha + x^a_\alpha + x^c_\alpha = 1\f$ for the mole fractions. - * Furthermore, the phase pressures are related to each other via - * capillary pressures between the fluid phases, which are functions of - * the saturation, e.g. according to the approach of Parker et al. - * - * The used primary variables are dependent on the locally present fluid phases - * An adaptive primary variable switch is included. The phase state is stored for all nodes - * of the system. The following cases can be distinguished: - * <ul> - * <li> All three phases are present: Primary variables are two saturations \f$(S_w\f$ and \f$S_n)\f$, and a pressure, in this case \f$p_g\f$. </li> - * <li> Only the water phase is present: Primary variables are now the mole fractions of air and contaminant in the water phase \f$(x_w^a\f$ and \f$x_w^c)\f$, as well as the gas pressure, which is, of course, in a case where only the water phase is present, just the same as the water pressure. </li> - * <li> Gas and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_g^w\f$, \f$p_g)\f$. </li> - * <li> Water and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_w^a\f$, \f$p_g)\f$. </li> - * <li> Only gas phase is present: Primary variables \f$(x_g^w\f$, \f$x_g^c\f$, \f$p_g)\f$. </li> - * <li> Water and gas phases are present: Primary variables \f$(S_w\f$, \f$x_w^g\f$, \f$p_g)\f$. </li> - * </ul> - */ -template<class TypeTag> -class ThreePThreeCModel: public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld, - - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents), - - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - - - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - gCompIdx = Indices::gCompIdx, - - threePhases = Indices::threePhases, - wPhaseOnly = Indices::wPhaseOnly, - gnPhaseOnly = Indices::gnPhaseOnly, - wnPhaseOnly = Indices::wnPhaseOnly, - gPhaseOnly = Indices::gPhaseOnly, - wgPhaseOnly = Indices::wgPhaseOnly - - }; - - - typedef typename GridView::template Codim<dim>::Entity Vertex; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; -public: - /*! - * \brief Initialize the static data with the initial solution. - * - * \param problem The problem to be solved - */ - void init(Problem &problem) - { - ParentType::init(problem); - - staticVertexDat_.resize(this->gridView_().size(dim)); - - setSwitched_(false); - - VertexIterator it = this->gridView_().template begin<dim> (); - const VertexIterator &endit = this->gridView_().template end<dim> (); - for (; it != endit; ++it) - { - int globalIdx = this->dofMapper().map(*it); - const GlobalPosition &globalPos = it->geometry().corner(0); - - // initialize phase presence - staticVertexDat_[globalIdx].phasePresence - = this->problem_().initialPhasePresence(*it, globalIdx, - globalPos); - staticVertexDat_[globalIdx].wasSwitched = false; - - staticVertexDat_[globalIdx].oldPhasePresence - = staticVertexDat_[globalIdx].phasePresence; - } - } - - /*! - * \brief Compute the total storage inside one phase of all - * conservation quantities. - * - * \param dest Contains the storage of each component for one phase - * \param phaseIdx The phase index - */ - void globalPhaseStorage(PrimaryVariables &dest, int phaseIdx) - { - dest = 0; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - const ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - this->localResidual().evalPhaseStorage(*elemIt, phaseIdx); - - for (int i = 0; i < elemIt->template count<dim>(); ++i) - dest += this->localResidual().residual(i); - } - - if (this->gridView_().comm().size() > 1) - dest = this->gridView_().comm().sum(dest); - } - - /*! - * \brief Called by the update() method if applying the newton - * method was unsuccessful. - */ - void updateFailed() - { - ParentType::updateFailed(); - - setSwitched_(false); - resetPhasePresence_(); - }; - - /*! - * \brief Called by the problem if a time integration was - * successful, post processing of the solution is done and the - * result has been written to disk. - * - * This should prepare the model for the next time integration. - */ - void advanceTimeLevel() - { - ParentType::advanceTimeLevel(); - - // update the phase state - updateOldPhasePresence_(); - setSwitched_(false); - } - - /*! - * \brief Return true if the primary variables were switched for - * at least one vertex after the last timestep. - */ - bool switched() const - { - return switchFlag_; - } - - /*! - * \brief Returns the phase presence of the current or the old solution of a vertex. - * - * \param globalVertexIdx The global vertex index - * \param oldSol Evaluate function with solution of current or previous time step - */ - int phasePresence(int globalVertexIdx, bool oldSol) const - { - return - oldSol - ? staticVertexDat_[globalVertexIdx].oldPhasePresence - : staticVertexDat_[globalVertexIdx].phasePresence; - } - - /*! - * \brief Append all quantities of interest which can be derived - * from the solution of the current time step to the VTK - * writer. - * - * \param sol The solution vector - * \param writer The writer for multi-file VTK datasets - */ - template<class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - - // create the required scalar fields - unsigned numVertices = this->problem_().gridView().size(dim); - - ScalarField *saturation[numPhases]; - ScalarField *pressure[numPhases]; - ScalarField *density[numPhases]; - - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { - saturation[phaseIdx] = writer.allocateManagedBuffer(numVertices); - pressure[phaseIdx] = writer.allocateManagedBuffer(numVertices); - density[phaseIdx] = writer.allocateManagedBuffer(numVertices); - } - - ScalarField *phasePresence = writer.allocateManagedBuffer (numVertices); - ScalarField *moleFraction[numPhases][numComponents]; - for (int i = 0; i < numPhases; ++i) - for (int j = 0; j < numComponents; ++j) - moleFraction[i][j] = writer.allocateManagedBuffer (numVertices); - ScalarField *temperature = writer.allocateManagedBuffer (numVertices); - ScalarField *poro = writer.allocateManagedBuffer(numVertices); - ScalarField *perm = writer.allocateManagedBuffer(numVertices); - - unsigned numElements = this->gridView_().size(0); - ScalarField *rank = - writer.allocateManagedBuffer (numElements); - - FVElementGeometry fvGeometry; - VolumeVariables volVars; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - int idx = this->problem_().elementMapper().map(*elemIt); - (*rank)[idx] = this->gridView_().comm().rank(); - fvGeometry.update(this->gridView_(), *elemIt); - - int numVerts = elemIt->template count<dim> (); - for (int i = 0; i < numVerts; ++i) - { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); - volVars.update(sol[globalIdx], - this->problem_(), - *elemIt, - fvGeometry, - i, - false); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { - (*saturation[phaseIdx])[globalIdx] = volVars.fluidState().saturation(phaseIdx); - (*pressure[phaseIdx])[globalIdx] = volVars.fluidState().pressure(phaseIdx); - (*density[phaseIdx])[globalIdx] = volVars.fluidState().density(phaseIdx); - } - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - (*moleFraction[phaseIdx][compIdx])[globalIdx] = - volVars.fluidState().moleFraction(phaseIdx, - compIdx); - - Valgrind::CheckDefined((*moleFraction[phaseIdx][compIdx])[globalIdx]); - } - } - - (*poro)[globalIdx] = volVars.porosity(); - (*perm)[globalIdx] = volVars.permeability(); - (*temperature)[globalIdx] = volVars.temperature(); - (*phasePresence)[globalIdx] = staticVertexDat_[globalIdx].phasePresence; - } - - } - - writer.attachVertexData(*saturation[wPhaseIdx], "Sw"); - writer.attachVertexData(*saturation[nPhaseIdx], "Sn"); - writer.attachVertexData(*saturation[gPhaseIdx], "Sg"); - writer.attachVertexData(*pressure[wPhaseIdx], "pw"); - writer.attachVertexData(*pressure[nPhaseIdx], "pn"); - writer.attachVertexData(*pressure[gPhaseIdx], "pg"); - writer.attachVertexData(*density[wPhaseIdx], "rhow"); - writer.attachVertexData(*density[nPhaseIdx], "rhon"); - writer.attachVertexData(*density[gPhaseIdx], "rhog"); - - for (int i = 0; i < numPhases; ++i) - { - for (int j = 0; j < numComponents; ++j) - { - std::ostringstream oss; - oss << "x^" - << FluidSystem::phaseName(i) - << "_" - << FluidSystem::componentName(j); - writer.attachVertexData(*moleFraction[i][j], oss.str().c_str()); - } - } - writer.attachVertexData(*poro, "porosity"); - writer.attachVertexData(*perm, "permeability"); - writer.attachVertexData(*temperature, "temperature"); - writer.attachVertexData(*phasePresence, "phase presence"); - writer.attachCellData(*rank, "process rank"); - } - - /*! - * \brief Write the current solution to a restart file. - * - * \param outStream The output stream of one vertex for the restart file - * \param vert The vertex - */ - void serializeEntity(std::ostream &outStream, const Vertex &vert) - { - // write primary variables - ParentType::serializeEntity(outStream, vert); - - int vertIdx = this->dofMapper().map(vert); - if (!outStream.good()) - DUNE_THROW(Dune::IOError, "Could not serialize vertex " << vertIdx); - - outStream << staticVertexDat_[vertIdx].phasePresence << " "; - } - - /*! - * \brief Reads the current solution for a vertex from a restart - * file. - * - * \param inStream The input stream of one vertex from the restart file - * \param vert The vertex - */ - void deserializeEntity(std::istream &inStream, const Vertex &vert) - { - // read primary variables - ParentType::deserializeEntity(inStream, vert); - - // read phase presence - int vertIdx = this->dofMapper().map(vert); - if (!inStream.good()) - DUNE_THROW(Dune::IOError, - "Could not deserialize vertex " << vertIdx); - - inStream >> staticVertexDat_[vertIdx].phasePresence; - staticVertexDat_[vertIdx].oldPhasePresence - = staticVertexDat_[vertIdx].phasePresence; - - } - - /*! - * \brief Update the static data of all vertices in the grid. - * - * \param curGlobalSol The current global solution - * \param oldGlobalSol The previous global solution - */ - void updateStaticData(SolutionVector &curGlobalSol, - const SolutionVector &oldGlobalSol) - { - bool wasSwitched = false; - - for (unsigned i = 0; i < staticVertexDat_.size(); ++i) - staticVertexDat_[i].visited = false; - - FVElementGeometry fvGeometry; - static VolumeVariables volVars; - ElementIterator it = this->gridView_().template begin<0> (); - const ElementIterator &endit = this->gridView_().template end<0> (); - for (; it != endit; ++it) - { - fvGeometry.update(this->gridView_(), *it); - for (int i = 0; i < fvGeometry.numVertices; ++i) - { - int globalIdx = this->vertexMapper().map(*it, i, dim); - - if (staticVertexDat_[globalIdx].visited) - continue; - - staticVertexDat_[globalIdx].visited = true; - volVars.update(curGlobalSol[globalIdx], - this->problem_(), - *it, - fvGeometry, - i, - false); - const GlobalPosition &global = it->geometry().corner(i); - if (primaryVarSwitch_(curGlobalSol, - volVars, - globalIdx, - global)) - wasSwitched = true; - } - } - - // make sure that if there was a variable switch in an - // other partition we will also set the switch flag - // for our partition. - if (this->gridView_().comm().size() > 1) - wasSwitched = this->gridView_().comm().max(wasSwitched); - - setSwitched_(wasSwitched); - } - -protected: - /*! - * \brief Data which is attached to each vertex and is not only - * stored locally. - */ - struct StaticVars - { - int phasePresence; - bool wasSwitched; - - int oldPhasePresence; - bool visited; - }; - - /*! - * \brief Reset the current phase presence of all vertices to the old one. - * - * This is done after an update failed. - */ - void resetPhasePresence_() - { - int numVertices = this->gridView_().size(dim); - for (int i = 0; i < numVertices; ++i) - { - staticVertexDat_[i].phasePresence - = staticVertexDat_[i].oldPhasePresence; - staticVertexDat_[i].wasSwitched = false; - } - } - - /*! - * \brief Set the old phase of all verts state to the current one. - */ - void updateOldPhasePresence_() - { - int numVertices = this->gridView_().size(dim); - for (int i = 0; i < numVertices; ++i) - { - staticVertexDat_[i].oldPhasePresence - = staticVertexDat_[i].phasePresence; - staticVertexDat_[i].wasSwitched = false; - } - } - - /*! - * \brief Set whether there was a primary variable switch after in - * the last timestep. - */ - void setSwitched_(bool yesno) - { - switchFlag_ = yesno; - } - - // perform variable switch at a vertex; Returns true if a - // variable switch was performed. - bool primaryVarSwitch_(SolutionVector &globalSol, - const VolumeVariables &volVars, - int globalIdx, - const GlobalPosition &globalPos) - { - // evaluate primary variable switch - bool wouldSwitch = false; - int phasePresence = staticVertexDat_[globalIdx].phasePresence; - int newPhasePresence = phasePresence; - - // check if a primary var switch is necessary - if (phasePresence == threePhases) - { - Scalar Smin = 0; - if (staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(gPhaseIdx) <= Smin) - { - wouldSwitch = true; - // gas phase disappears - std::cout << "Gas phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sg: " - << volVars.saturation(gPhaseIdx) << std::endl; - newPhasePresence = wnPhaseOnly; - - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(wPhaseIdx, gCompIdx); - } - else if (volVars.saturation(wPhaseIdx) <= Smin) - { - wouldSwitch = true; - // water phase disappears - std::cout << "Water phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = gnPhaseOnly; - - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - } - else if (volVars.saturation(nPhaseIdx) <= Smin) - { - wouldSwitch = true; - // NAPL phase disappears - std::cout << "NAPL phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = wgPhaseOnly; - - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - } - } - else if (phasePresence == wPhaseOnly) - { - bool gasFlag = 0; - bool nonwettingFlag = 0; - // calculate fractions of the partial pressures in the - // hypothetical gas phase - Scalar xwg = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - Scalar xgg = volVars.fluidState().moleFraction(gPhaseIdx, gCompIdx); - Scalar xng = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - /* take care: - for xgg in case wPhaseOnly we compute xgg=henry_air*x2w - for xwg in case wPhaseOnly we compute xwg=pwsat - for xng in case wPhaseOnly we compute xng=henry_NAPL*x1w - */ - - Scalar xgMax = 1.0; - if (xwg + xgg + xng > xgMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xgMax *= 1.02; - - // if the sum of the mole fractions would be larger than - // 100%, gas phase appears - if (xwg + xgg + xng > xgMax) - { - // gas phase appears - std::cout << "gas phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xwg + xgg + xng: " - << xwg + xgg + xng << std::endl; - gasFlag = 1; - } - - // calculate fractions in the hypothetical NAPL phase - Scalar xnn = volVars.fluidState().moleFraction(nPhaseIdx, nCompIdx); - /* take care: - for xnn in case wPhaseOnly we compute xnn=henry_mesitylene*x1w, - where a hypothetical gas pressure is assumed for the Henry - x0n is set to NULL (all NAPL phase is dirty) - x2n is set to NULL (all NAPL phase is dirty) - */ - - Scalar xnMax = 1.0; - if (xnn > xnMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xnMax *= 1.02; - - // if the sum of the hypothetical mole fractions would be larger than - // 100%, NAPL phase appears - if (xnn > xnMax) - { - // NAPL phase appears - std::cout << "NAPL phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xnn: " - << xnn << std::endl; - nonwettingFlag = 1; - } - - if ((gasFlag == 1) && (nonwettingFlag == 0)) - { - newPhasePresence = wgPhaseOnly; - globalSol[globalIdx][switch1Idx] = 0.9999; - globalSol[globalIdx][switch2Idx] = 0.0001; - } - else if ((gasFlag == 1) && (nonwettingFlag == 1)) - { - newPhasePresence = threePhases; - globalSol[globalIdx][switch1Idx] = 0.9999; - globalSol[globalIdx][switch2Idx] = 0.0001; - } - else if ((gasFlag == 0) && (nonwettingFlag == 1)) - { - newPhasePresence = wnPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(wPhaseIdx, gCompIdx); - globalSol[globalIdx][switch2Idx] = 0.0001; - } - } - else if (phasePresence == gnPhaseOnly) - { - bool nonwettingFlag = 0; - bool wettingFlag = 0; - - Scalar Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(nPhaseIdx) <= Smin) - { - wouldSwitch = true; - // NAPL phase disappears - std::cout << "NAPL phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - nonwettingFlag = 1; - } - - - // calculate fractions of the hypothetical water phase - Scalar xww = volVars.fluidState().moleFraction(wPhaseIdx, wCompIdx); - /* - take care:, xww, if no water is present, then take xww=xwg*pg/pwsat . - If this is larger than 1, then water appears - */ - Scalar xwMax = 1.0; - if (xww > xwMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xwMax *= 1.02; - - // if the sum of the mole fractions would be larger than - // 100%, gas phase appears - if (xww > xwMax) - { - // water phase appears - std::cout << "water phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xww=xwg*pg/pwsat : " - << xww << std::endl; - wettingFlag = 1; - } - - if ((wettingFlag == 1) && (nonwettingFlag == 0)) - { - newPhasePresence = threePhases; - globalSol[globalIdx][switch1Idx] = 0.0001; - globalSol[globalIdx][switch2Idx] = volVars.saturation(nPhaseIdx); - } - else if ((wettingFlag == 1) && (nonwettingFlag == 1)) - { - newPhasePresence = wgPhaseOnly; - globalSol[globalIdx][switch1Idx] = 0.0001; - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - } - else if ((wettingFlag == 0) && (nonwettingFlag == 1)) - { - newPhasePresence = gPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - } - } - else if (phasePresence == wnPhaseOnly) - { - bool nonwettingFlag = 0; - bool gasFlag = 0; - - Scalar Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(nPhaseIdx) <= Smin) - { - wouldSwitch = true; - // NAPL phase disappears - std::cout << "NAPL phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - nonwettingFlag = 1; - } - - // calculate fractions of the partial pressures in the - // hypothetical gas phase - Scalar xwg = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - Scalar xgg = volVars.fluidState().moleFraction(gPhaseIdx, gCompIdx); - Scalar xng = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - /* take care: - for xgg in case wPhaseOnly we compute xgg=henry_air*x2w - for xwg in case wPhaseOnly we compute xwg=pwsat - for xng in case wPhaseOnly we compute xng=henry_NAPL*x1w - */ - Scalar xgMax = 1.0; - if (xwg + xgg + xng > xgMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xgMax *= 1.02; - - // if the sum of the mole fractions would be larger than - // 100%, gas phase appears - if (xwg + xgg + xng > xgMax) - { - // gas phase appears - std::cout << "gas phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xwg + xgg + xng: " - << xwg + xgg + xng << std::endl; - gasFlag = 1; - } - - if ((gasFlag == 1) && (nonwettingFlag == 0)) - { - newPhasePresence = threePhases; - globalSol[globalIdx][switch1Idx] = volVars.saturation(wPhaseIdx); - globalSol[globalIdx][switch2Idx] = volVars.saturation(nPhaseIdx);; - } - else if ((gasFlag == 1) && (nonwettingFlag == 1)) - { - newPhasePresence = wgPhaseOnly; - globalSol[globalIdx][switch1Idx] = volVars.saturation(wPhaseIdx); - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - } - else if ((gasFlag == 0) && (nonwettingFlag == 1)) - { - newPhasePresence = wPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(wPhaseIdx, gCompIdx); - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(wPhaseIdx, nCompIdx); - } - } - else if (phasePresence == gPhaseOnly) - { - bool nonwettingFlag = 0; - bool wettingFlag = 0; - - // calculate fractions in the hypothetical NAPL phase - Scalar xnn = volVars.fluidState().moleFraction(nPhaseIdx, nCompIdx); - /* - take care:, xnn, if no NAPL phase is there, take xnn=xng*pg/pcsat - if this is larger than 1, then NAPL appears - */ - - Scalar xnMax = 1.0; - if (xnn > xnMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xnMax *= 1.02; - - // if the sum of the hypothetical mole fraction would be larger than - // 100%, NAPL phase appears - if (xnn > xnMax) - { - // NAPL phase appears - std::cout << "NAPL phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xnn: " - << xnn << std::endl; - nonwettingFlag = 1; - } - // calculate fractions of the hypothetical water phase - Scalar xww = volVars.fluidState().moleFraction(wPhaseIdx, wCompIdx); - /* - take care:, xww, if no water is present, then take xww=xwg*pg/pwsat . - If this is larger than 1, then water appears - */ - Scalar xwMax = 1.0; - if (xww > xwMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xwMax *= 1.02; - - // if the sum of the mole fractions would be larger than - // 100%, gas phase appears - if (xww > xwMax) - { - // water phase appears - std::cout << "water phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xww=xwg*pg/pwsat : " - << xww << std::endl; - wettingFlag = 1; - } - if ((wettingFlag == 1) && (nonwettingFlag == 0)) - { - newPhasePresence = wgPhaseOnly; - globalSol[globalIdx][switch1Idx] = 0.0001; - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - } - else if ((wettingFlag == 1) && (nonwettingFlag == 1)) - { - newPhasePresence = threePhases; - globalSol[globalIdx][switch1Idx] = 0.0001; - globalSol[globalIdx][switch2Idx] = 0.0001; - } - else if ((wettingFlag == 0) && (nonwettingFlag == 1)) - { - newPhasePresence = gnPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - globalSol[globalIdx][switch2Idx] = 0.0001; - } - } - else if (phasePresence == wgPhaseOnly) - { - bool nonwettingFlag = 0; - bool gasFlag = 0; - bool wettingFlag = 0; - - // get the fractions in the hypothetical NAPL phase - Scalar xnn = volVars.fluidState().moleFraction(nPhaseIdx, nCompIdx); - - // take care: if the NAPL phase is not present, take - // xnn=xng*pg/pcsat if this is larger than 1, then NAPL - // appears - Scalar xnMax = 1.0; - if (xnn > xnMax) - wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) - xnMax *= 1.02; - - // if the sum of the hypothetical mole fraction would be larger than - // 100%, NAPL phase appears - if (xnn > xnMax) - { - // NAPL phase appears - std::cout << "NAPL phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xnn: " - << xnn << std::endl; - nonwettingFlag = 1; - } - - Scalar Smin = -1.e-6; - if (staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(gPhaseIdx) <= Smin) - { - wouldSwitch = true; - // gas phase disappears - std::cout << "Gas phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sg: " - << volVars.saturation(gPhaseIdx) << std::endl; - gasFlag = 1; - } - - Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(wPhaseIdx) <= Smin) - { - wouldSwitch = true; - // gas phase disappears - std::cout << "Water phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - wettingFlag = 1; - } - - if ((gasFlag == 0) && (nonwettingFlag == 1) && (wettingFlag == 1)) - { - newPhasePresence = gnPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - globalSol[globalIdx][switch2Idx] = 0.0001; - } - else if ((gasFlag == 0) && (nonwettingFlag == 1) && (wettingFlag == 0)) - { - newPhasePresence = threePhases; - globalSol[globalIdx][switch1Idx] = volVars.saturation(wPhaseIdx); - globalSol[globalIdx][switch2Idx] = 0.0; - } - else if ((gasFlag == 1) && (nonwettingFlag == 0) && (wettingFlag == 0)) - { - newPhasePresence = wPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(wPhaseIdx, gCompIdx); - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(wPhaseIdx, nCompIdx); - } - else if ((gasFlag == 0) && (nonwettingFlag == 0) && (wettingFlag == 1)) - { - newPhasePresence = gPhaseOnly; - globalSol[globalIdx][switch1Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, wCompIdx); - globalSol[globalIdx][switch2Idx] - = volVars.fluidState().moleFraction(gPhaseIdx, nCompIdx); - } - } - - staticVertexDat_[globalIdx].phasePresence = newPhasePresence; - staticVertexDat_[globalIdx].wasSwitched = wouldSwitch; - return phasePresence != newPhasePresence; - } - - // parameters given in constructor - std::vector<StaticVars> staticVertexDat_; - bool switchFlag_; -}; - -} - -#include "3p3cpropertydefaults.hh" - -#endif +#include <dumux/implicit/3p3c/3p3cmodel.hh> diff --git a/dumux/boxmodels/3p3c/3p3cnewtoncontroller.hh b/dumux/boxmodels/3p3c/3p3cnewtoncontroller.hh index f0d47996da1c20f38990ffcd6ba7b2ac139bce26..a4cc0227c468e31e6bbaee0b340fba722fc7a80b 100644 --- a/dumux/boxmodels/3p3c/3p3cnewtoncontroller.hh +++ b/dumux/boxmodels/3p3c/3p3cnewtoncontroller.hh @@ -1,85 +1,3 @@ -// -*- 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 A 3p3c specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * which allows the newton method to abort quicker if the solution is - * way out of bounds. - */ -#ifndef DUMUX_3P3C_NEWTON_CONTROLLER_HH -#define DUMUX_3P3C_NEWTON_CONTROLLER_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cnewtoncontroller.hh instead. -#include "3p3cproperties.hh" - -#include <dumux/nonlinear/newtoncontroller.hh> - -namespace Dumux { -/*! - * \ingroup ThreePThreeCModel - * \brief A 3p3c specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * which allows the newton method to abort quicker if the solution is - * way out of bounds. - */ -template <class TypeTag> -class ThreePThreeCNewtonController : public NewtonController<TypeTag> -{ - typedef NewtonController<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - -public: - ThreePThreeCNewtonController(const Problem &problem) - : ParentType(problem) - {}; - - - /*! - * \brief Called after each Newton update - * - * \param uCurrentIter The current global solution vector - * \param uLastIter The previous global solution vector - */ - void newtonEndStep(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - // call the method of the base class - this->method().model().updateStaticData(uCurrentIter, uLastIter); - ParentType::newtonEndStep(uCurrentIter, uLastIter); - } - - - /*! - * \brief Returns true if the current solution can be considered to - * be accurate enough - */ - bool newtonConverged() - { - if (this->method().model().switched()) - return false; - - return ParentType::newtonConverged(); - }; -}; -} - -#endif +#include <dumux/implicit/3p3c/3p3cnewtoncontroller.hh> diff --git a/dumux/boxmodels/3p3c/3p3cproperties.hh b/dumux/boxmodels/3p3c/3p3cproperties.hh index 90ddfaa0d319d62a161300afdd72bad477b7679c..41c8ce24f1b5921d75b0b87a4c73ca53ab039a76 100644 --- a/dumux/boxmodels/3p3c/3p3cproperties.hh +++ b/dumux/boxmodels/3p3c/3p3cproperties.hh @@ -1,66 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup ThreePThreeCModel - */ -/*! - * \file - * - * \brief Defines the properties required for the 3p3c BOX model. - */ -#ifndef DUMUX_3P3C_PROPERTIES_HH -#define DUMUX_3P3C_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cproperties.hh instead. -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the isothermal single phase problems -NEW_TYPE_TAG(BoxThreePThreeC, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system -NEW_PROP_TAG(Indices); //!< Enumerations for the model -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters -NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations - -NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the spatial parameters) -NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters) - -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind parameter for the mobility -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation -NEW_PROP_TAG(UseConstraintSolver); //!< Determines whether a constraint solver should be used explicitly -NEW_PROP_TAG(BaseFluxVariables); //! The base flux variables -NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient -} -} - -#endif +#include <dumux/implicit/3p3c/3p3cproperties.hh> diff --git a/dumux/boxmodels/3p3c/3p3cpropertydefaults.hh b/dumux/boxmodels/3p3c/3p3cpropertydefaults.hh index 421ddab7bcc7ccb9ec0b190e62f43ce9a2fc054d..c51c6010673f656a7646d9bf30be47b233fb0232 100644 --- a/dumux/boxmodels/3p3c/3p3cpropertydefaults.hh +++ b/dumux/boxmodels/3p3c/3p3cpropertydefaults.hh @@ -1,143 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup ThreePThreeCModel - */ -/*! - * \file - * - * \brief Defines default values for most properties required by the - * 3p3c box model. - */ -#ifndef DUMUX_3P3C_PROPERTY_DEFAULTS_HH -#define DUMUX_3P3C_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cpropertydefaults.hh instead. -#include "3p3cindices.hh" - -#include "3p3cmodel.hh" -#include "3p3cindices.hh" -#include "3p3cfluxvariables.hh" -#include "3p3cvolumevariables.hh" -#include "3p3cproperties.hh" -#include "3p3cnewtoncontroller.hh" -// #include "3p3cboundaryvariables.hh" - -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include <dumux/material/spatialparams/boxspatialparams.hh> - -namespace Dumux -{ - -namespace Properties { -////////////////////////////////////////////////////////////////// -// Property values -////////////////////////////////////////////////////////////////// - -/*! - * \brief Set the property for the number of components. - * - * We just forward the number from the fluid system and use an static - * assert to make sure it is 2. - */ -SET_PROP(BoxThreePThreeC, NumComponents) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - public: - static const int value = FluidSystem::numComponents; - - static_assert(value == 3, - "Only fluid systems with 3 components are supported by the 3p3c model!"); -}; - -/*! - * \brief Set the property for the number of fluid phases. - * - * We just forward the number from the fluid system and use an static - * assert to make sure it is 2. - */ -SET_PROP(BoxThreePThreeC, NumPhases) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - public: - static const int value = FluidSystem::numPhases; - static_assert(value == 3, - "Only fluid systems with 3 phases are supported by the 3p3c model!"); -}; - -SET_INT_PROP(BoxThreePThreeC, NumEq, 3); //!< set the number of equations to 2 - -/*! - * \brief Set the property for the material parameters by extracting - * it from the material law. - */ -SET_TYPE_PROP(BoxThreePThreeC, MaterialLawParams, typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params); - -//! The local residual function of the conservation equations -SET_TYPE_PROP(BoxThreePThreeC, LocalResidual, ThreePThreeCLocalResidual<TypeTag>); - -//! Use the 3p3c specific newton controller for the 3p3c model -SET_TYPE_PROP(BoxThreePThreeC, NewtonController, ThreePThreeCNewtonController<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxThreePThreeC, Model, ThreePThreeCModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxThreePThreeC, VolumeVariables, ThreePThreeCVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxThreePThreeC, FluxVariables, ThreePThreeCFluxVariables<TypeTag>); - -//! define the base flux variables to realize Darcy flow -SET_TYPE_PROP(BoxThreePThreeC, BaseFluxVariables, BoxDarcyFluxVariables<TypeTag>); - -//! the upwind factor for the mobility. -SET_SCALAR_PROP(BoxThreePThreeC, ImplicitMassUpwindWeight, 1.0); - -//! set default mobility upwind weight to 1.0, i.e. fully upwind -SET_SCALAR_PROP(BoxThreePThreeC, ImplicitMobilityUpwindWeight, 1.0); - -//! Determines whether a constraint solver should be used explicitly -SET_BOOL_PROP(BoxThreePThreeC, UseConstraintSolver, false); - -//! The indices required by the isothermal 3p3c model -SET_TYPE_PROP(BoxThreePThreeC, Indices, ThreePThreeCIndices<TypeTag, /*PVOffset=*/0>); - -//! The spatial parameters to be employed. -//! Use BoxSpatialParams by default. -SET_TYPE_PROP(BoxThreePThreeC, SpatialParams, BoxSpatialParams<TypeTag>); - -// enable gravity by default -SET_BOOL_PROP(BoxThreePThreeC, ProblemEnableGravity, true); - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55); - -} - -} - -#endif +#include <dumux/implicit/3p3c/3p3cpropertydefaults.hh> diff --git a/dumux/boxmodels/3p3c/3p3cvolumevariables.hh b/dumux/boxmodels/3p3c/3p3cvolumevariables.hh index ce6349ef8c6464a5a958152c5b1ab9039c53db0d..1e0adf216dd58aabca714f8abcf4316750a89783 100644 --- a/dumux/boxmodels/3p3c/3p3cvolumevariables.hh +++ b/dumux/boxmodels/3p3c/3p3cvolumevariables.hh @@ -1,732 +1,3 @@ -// -*- 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 Contains the quantities which are constant within a - * finite volume in the two-phase, two-component model. - */ -#ifndef DUMUX_3P3C_VOLUME_VARIABLES_HH -#define DUMUX_3P3C_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/3p3c/3p3cvolumevariables.hh instead. -#include <dumux/boxmodels/common/boxmodel.hh> -#include <dumux/common/math.hh> - -#include <dune/common/collectivecommunication.hh> -#include <vector> -#include <iostream> - -#include "3p3cproperties.hh" - -#include <dumux/material/constants.hh> -#include <dumux/material/fluidstates/compositionalfluidstate.hh> -#include <dumux/material/constraintsolvers/computefromreferencephase.hh> -#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> - -namespace Dumux -{ - -/*! - * \ingroup ThreePThreeCModel - * \brief Contains the quantities which are are constant within a - * finite volume in the two-phase, two-component model. - */ -template <class TypeTag> -class ThreePThreeCVolumeVariables : public BoxVolumeVariables<TypeTag> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - - // constraint solvers - typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition; - typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - dim = GridView::dimension, - - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents), - - wCompIdx = Indices::wCompIdx, - gCompIdx = Indices::gCompIdx, - nCompIdx = Indices::nCompIdx, - - wPhaseIdx = Indices::wPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - pressureIdx = Indices::pressureIdx - }; - - // present phases - enum { - threePhases = Indices::threePhases, - wPhaseOnly = Indices::wPhaseOnly, - gnPhaseOnly = Indices::gnPhaseOnly, - wnPhaseOnly = Indices::wnPhaseOnly, - gPhaseOnly = Indices::gPhaseOnly, - wgPhaseOnly = Indices::wgPhaseOnly - }; - - typedef typename GridView::template Codim<0>::Entity Element; - - static const Scalar R; // universial gas constant - -public: - //! The type of the object returned by the fluidState() method - typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> FluidState; - - - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - bool isOldSol) - { - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - bool useConstraintSolver = GET_PROP_VALUE(TypeTag, UseConstraintSolver); - - // capillary pressure parameters - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - - int globalVertIdx = problem.model().dofMapper().map(element, scvIdx, dim); - int phasePresence = problem.model().phasePresence(globalVertIdx, isOldSol); - - Scalar temp = Implementation::temperature_(priVars, problem, element, fvGeometry, scvIdx); - fluidState_.setTemperature(temp); - - /* first the saturations */ - if (phasePresence == threePhases) - { - Sw_ = priVars[switch1Idx]; - Sn_ = priVars[switch2Idx]; - Sg_ = 1. - Sw_ - Sn_; - } - else if (phasePresence == wPhaseOnly) - { - Sw_ = 1.; - Sn_ = 0.; - Sg_ = 0.; - } - else if (phasePresence == gnPhaseOnly) - { - Sw_ = 0.; - Sn_ = priVars[switch2Idx]; - Sg_ = 1. - Sn_; - } - else if (phasePresence == wnPhaseOnly) - { - Sn_ = priVars[switch2Idx]; - Sw_ = 1. - Sn_; - Sg_ = 0.; - } - else if (phasePresence == gPhaseOnly) - { - Sw_ = 0.; - Sn_ = 0.; - Sg_ = 1.; - } - else if (phasePresence == wgPhaseOnly) - { - Sw_ = priVars[switch1Idx]; - Sn_ = 0.; - Sg_ = 1. - Sw_; - } - else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); - Valgrind::CheckDefined(Sg_); - - fluidState_.setSaturation(wPhaseIdx, Sw_); - fluidState_.setSaturation(gPhaseIdx, Sg_); - fluidState_.setSaturation(nPhaseIdx, Sn_); - - /* now the pressures */ - pg_ = priVars[pressureIdx]; - - // calculate capillary pressures - Scalar pCGW = MaterialLaw::pCGW(materialParams, Sw_); - Scalar pCNW = MaterialLaw::pCNW(materialParams, Sw_); - Scalar pCGN = MaterialLaw::pCGN(materialParams, Sw_ + Sn_); - - Scalar pcAlpha = MaterialLaw::pCAlpha(materialParams, Sn_); - Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file - - pn_ = pg_- pcAlpha * pCGN - (1.-pcAlpha)*(pCGW - pcNW1); - pw_ = pn_ - pcAlpha * pCNW - (1.-pcAlpha)*pcNW1; - - fluidState_.setPressure(wPhaseIdx, pw_); - fluidState_.setPressure(gPhaseIdx, pg_); - fluidState_.setPressure(nPhaseIdx, pn_); - - // calculate and set all fugacity coefficients. this is - // possible because we require all phases to be an ideal - // mixture, i.e. fugacity coefficients are not supposed to - // depend on composition! - typename FluidSystem::ParameterCache paramCache; - // assert(FluidSystem::isIdealGas(gPhaseIdx)); - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { - assert(FluidSystem::isIdealMixture(phaseIdx)); - - for (int compIdx = 0; compIdx < numComponents; ++ compIdx) { - Scalar phi = FluidSystem::fugacityCoefficient(fluidState_, paramCache, phaseIdx, compIdx); - fluidState_.setFugacityCoefficient(phaseIdx, compIdx, phi); - } - } - - // now comes the tricky part: calculate phase composition - if (phasePresence == threePhases) { - // all phases are present, phase compositions are a - // result of the the gas <-> liquid equilibrium. This is - // the job of the "MiscibleMultiPhaseComposition" - // constraint solver ... - if (useConstraintSolver) { - MiscibleMultiPhaseComposition::solve(fluidState_, - paramCache, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - // ... or calculated explicitly this way ... - else { - Scalar partPressH2O = FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx, - wCompIdx) * pw_; - Scalar partPressNAPL = FluidSystem::fugacityCoefficient(fluidState_, - nPhaseIdx, - nCompIdx) * pn_; - Scalar partPressAir = pg_ - partPressH2O - partPressNAPL; - - Scalar xgn = partPressNAPL/pg_; - Scalar xgw = partPressH2O/pg_; - Scalar xgg = partPressAir/pg_; - - // actually, it's nothing else than Henry coefficient - Scalar xwn = partPressNAPL - / (FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,nCompIdx) - * pw_); - Scalar xwg = partPressAir - / (FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,gCompIdx) - * pw_); - Scalar xww = 1.-xwg-xwn; - - Scalar xnn = 1.-2.e-10; - Scalar xna = 1.e-10; - Scalar xnw = 1.e-10; - - fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); - fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); - fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); - fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); - fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); - fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); - fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); - fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); - - Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); - Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); - Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); - - fluidState_.setDensity(wPhaseIdx, rhoW); - fluidState_.setDensity(gPhaseIdx, rhoG); - fluidState_.setDensity(nPhaseIdx, rhoN); - } - } - else if (phasePresence == wPhaseOnly) { - // only the water phase is present, water phase composition is - // stored explicitly. - - // extract mole fractions in the water phase - Scalar xwg = priVars[switch1Idx]; - Scalar xwn = priVars[switch2Idx]; - Scalar xww = 1 - xwg - xwn; - - // write water mole fractions in the fluid state - fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); - fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver ... - if (useConstraintSolver) - { - ComputeFromReferencePhase::solve(fluidState_, - paramCache, - wPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - // ... or calculated explicitly this way ... - else { - // note that the gas phase is actually not existing! - // thus, this is used as phase switch criterion - Scalar xgg = xwg * FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,gCompIdx) - * pw_ / pg_; - Scalar xgn = xwn * FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,nCompIdx) - * pw_ / pg_; - Scalar xgw = FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,wCompIdx) - * pw_ / pg_; - - - // note that the gas phase is actually not existing! - // thus, this is used as phase switch criterion - Scalar xnn = xwn * FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,nCompIdx) - * pw_; - Scalar xna = 1.e-10; - Scalar xnw = 1.e-10; - - fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); - fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); - fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); - fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); - fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); - fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); - - Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); - Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); - Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); - - fluidState_.setDensity(wPhaseIdx, rhoW); - fluidState_.setDensity(gPhaseIdx, rhoG); - fluidState_.setDensity(nPhaseIdx, rhoN); - } - } - else if (phasePresence == gnPhaseOnly) { - // only gas and NAPL phases are present - // we have all (partly hypothetical) phase pressures - // and temperature and the mole fraction of water in - // the gas phase - - // we have all (partly hypothetical) phase pressures - // and temperature and the mole fraction of water in - // the gas phase - Scalar partPressNAPL = fluidState_.fugacityCoefficient(nPhaseIdx, nCompIdx)*pn_; - - Scalar xgw = priVars[switch1Idx]; - Scalar xgn = partPressNAPL/pg_; - Scalar xgg = 1.-xgw-xgn; - - // write mole fractions in the fluid state - fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); - fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); - fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver - ComputeFromReferencePhase::solve(fluidState_, - paramCache, - gPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - else if (phasePresence == wnPhaseOnly) { - // only water and NAPL phases are present - Scalar pPartialC = fluidState_.fugacityCoefficient(nPhaseIdx,nCompIdx)*pn_; - Scalar henryC = fluidState_.fugacityCoefficient(wPhaseIdx,nCompIdx)*pw_; - - Scalar xwg = priVars[switch1Idx]; - Scalar xwn = pPartialC/henryC; - Scalar xww = 1.-xwg-xwn; - - // write mole fractions in the fluid state - fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); - fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver - ComputeFromReferencePhase::solve(fluidState_, - paramCache, - wPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - else if (phasePresence == gPhaseOnly) { - // only the gas phase is present, gas phase composition is - // stored explicitly here below. - - const Scalar xgw = priVars[switch1Idx]; - const Scalar xgn = priVars[switch2Idx]; - Scalar xgg = 1 - xgw - xgn; - - // write mole fractions in the fluid state - fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); - fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); - fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver ... - if (useConstraintSolver) - { - ComputeFromReferencePhase::solve(fluidState_, - paramCache, - gPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - // ... or calculated explicitly this way ... - else { - - // note that the water phase is actually not existing! - // thus, this is used as phase switch criterion - Scalar xww = xgw * pg_ - / (FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,wCompIdx) - * pw_); - Scalar xwn = 1.e-10; - Scalar xwg = 1.e-10; - - // note that the NAPL phase is actually not existing! - // thus, this is used as phase switch criterion - Scalar xnn = xgn * pg_ - / (FluidSystem::fugacityCoefficient(fluidState_, - nPhaseIdx,nCompIdx) - * pn_); - Scalar xna = 1.e-10; - Scalar xnw = 1.e-10; - - fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); - fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); - fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); - fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); - fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); - - Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); - Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); - Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); - - fluidState_.setDensity(wPhaseIdx, rhoW); - fluidState_.setDensity(gPhaseIdx, rhoG); - fluidState_.setDensity(nPhaseIdx, rhoN); - } - } - else if (phasePresence == wgPhaseOnly) { - // only water and gas phases are present - Scalar xgn = priVars[switch2Idx]; - Scalar partPressH2O = fluidState_.fugacityCoefficient(wPhaseIdx, wCompIdx)*pw_; - - Scalar xgw = partPressH2O/pg_; - Scalar xgg = 1.-xgn-xgw; - - // write mole fractions in the fluid state - fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); - fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); - fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); - - // calculate the composition of the remaining phases (as - // well as the densities of all phases). this is the job - // of the "ComputeFromReferencePhase" constraint solver ... - if (useConstraintSolver) - { - ComputeFromReferencePhase::solve(fluidState_, - paramCache, - gPhaseIdx, - /*setViscosity=*/true, - /*setInternalEnergy=*/false); - } - // ... or calculated explicitly this way ... - else { - // actually, it's nothing else than Henry coefficient - Scalar xwn = xgn * pg_ - / (FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,nCompIdx) - * pw_); - Scalar xwg = xgg * pg_ - / (FluidSystem::fugacityCoefficient(fluidState_, - wPhaseIdx,gCompIdx) - * pw_); - Scalar xww = 1.-xwg-xwn; - - // note that the NAPL phase is actually not existing! - // thus, this is used as phase switch criterion - Scalar xnn = xgn * pg_ - / (FluidSystem::fugacityCoefficient(fluidState_, - nPhaseIdx,nCompIdx) - * pn_);; - Scalar xna = 1.e-10; - Scalar xnw = 1.e-10; - - fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); - fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); - fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); - fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); - fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); - - Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); - Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); - Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); - - fluidState_.setDensity(wPhaseIdx, rhoW); - fluidState_.setDensity(gPhaseIdx, rhoG); - fluidState_.setDensity(nPhaseIdx, rhoN); - } - } - else - assert(false); // unhandled phase state - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // Mobilities - const Scalar mu = - FluidSystem::viscosity(fluidState_, - paramCache, - phaseIdx); - fluidState_.setViscosity(phaseIdx,mu); - - Scalar kr; - kr = MaterialLaw::kr(materialParams, phaseIdx, - fluidState_.saturation(wPhaseIdx), - fluidState_.saturation(nPhaseIdx), - fluidState_.saturation(gPhaseIdx)); - mobility_[phaseIdx] = kr / mu; - Valgrind::CheckDefined(mobility_[phaseIdx]); - } - - // material dependent parameters for NAPL adsorption - bulkDensTimesAdsorpCoeff_ = - MaterialLaw::bulkDensTimesAdsorpCoeff(materialParams); - - /* ATTENTION: The conversion to effective diffusion parameters - * for the porous media happens at another place! - */ - - // diffusivity coefficents - diffusionCoefficient_[gPhaseIdx][wCompIdx] = - FluidSystem::diffusionCoefficient(fluidState_, - paramCache, - gPhaseIdx, - wCompIdx); - diffusionCoefficient_[gPhaseIdx][nCompIdx] = - FluidSystem::diffusionCoefficient(fluidState_, - paramCache, - gPhaseIdx, - nCompIdx); - diffusionCoefficient_[gPhaseIdx][gCompIdx] = 0.0; // dummy, should not be used ! - - diffusionCoefficient_[wPhaseIdx][gCompIdx] = - FluidSystem::diffusionCoefficient(fluidState_, - paramCache, - wPhaseIdx, - gCompIdx); - diffusionCoefficient_[wPhaseIdx][nCompIdx] = - FluidSystem::diffusionCoefficient(fluidState_, - paramCache, - wPhaseIdx, - nCompIdx); - diffusionCoefficient_[wPhaseIdx][wCompIdx] = 0.0; // dummy, should not be used ! - - /* no diffusion in NAPL phase considered at the moment */ - diffusionCoefficient_[nPhaseIdx][nCompIdx] = 0.0; - diffusionCoefficient_[nPhaseIdx][wCompIdx] = 0.0; - diffusionCoefficient_[nPhaseIdx][gCompIdx] = 0.0; - - Valgrind::CheckDefined(diffusionCoefficient_); - - // porosity - porosity_ = problem.spatialParams().porosity(element, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(porosity_); - - // permeability - permeability_ = problem.spatialParams().intrinsicPermeability(element, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(permeability_); - - // energy related quantities not contained in the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - /*! - * \brief Returns the phase state for the control-volume. - */ - const FluidState &fluidState() const - { return fluidState_; } - - /*! - * \brief Returns the effective saturation of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar saturation(const int phaseIdx) const - { return fluidState_.saturation(phaseIdx); } - - /*! - * \brief Returns the mass density of a given phase within the - * control volume. - * - * \param phaseIdx The phase index - */ - Scalar density(const int phaseIdx) const - { return fluidState_.density(phaseIdx); } - - /*! - * \brief Returns the molar density of a given phase within the - * control volume. - * - * \param phaseIdx The phase index - */ - Scalar molarDensity(const int phaseIdx) const - { return fluidState_.density(phaseIdx) / fluidState_.averageMolarMass(phaseIdx); } - - /*! - * \brief Returns the effective pressure of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar pressure(const int phaseIdx) const - { return fluidState_.pressure(phaseIdx); } - - /*! - * \brief Returns temperature inside the sub-control volume. - * - * Note that we assume thermodynamic equilibrium, i.e. the - * temperatures of the rock matrix and of all fluid phases are - * identical. - */ - Scalar temperature() const - { return fluidState_.temperature(/*phaseIdx=*/0); } - - /*! - * \brief Returns the effective mobility of a given phase within - * the control volume. - * - * \param phaseIdx The phase index - */ - Scalar mobility(const int phaseIdx) const - { - return mobility_[phaseIdx]; - } - - /*! - * \brief Returns the effective capillary pressure within the control volume. - */ - Scalar capillaryPressure() const - { return fluidState_.capillaryPressure(); } - - /*! - * \brief Returns the average porosity within the control volume. - */ - Scalar porosity() const - { return porosity_; } - - /*! - * \brief Returns the permeability within the control volume. - */ - Scalar permeability() const - { return permeability_; } - - /*! - * \brief Returns the diffusivity coefficient matrix - */ - Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficient() const - { return diffusionCoefficient_; } - - /*! - * \brief Returns the adsorption information - */ - Scalar bulkDensTimesAdsorpCoeff() const - { return bulkDensTimesAdsorpCoeff_; } - - -protected: - - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - /*! - * \brief Called by update() to compute the energy related quantities - */ - void updateEnergy_(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - bool isOldSol) - { } - - Scalar Sw_, Sg_, Sn_, pg_, pw_, pn_; - - Scalar moleFrac_[numPhases][numComponents]; - Scalar massFrac_[numPhases][numComponents]; - - Scalar porosity_; //!< Effective porosity within the control volume - Scalar permeability_; //!< Effective porosity within the control volume - Scalar mobility_[numPhases]; //!< Effective mobility within the control volume - Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL - /* We need a tensor here !! */ - //!< Binary diffusion coefficients of the 3 components in the phases - Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficient_; - FluidState fluidState_; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; - -template <class TypeTag> -const typename ThreePThreeCVolumeVariables<TypeTag>::Scalar ThreePThreeCVolumeVariables<TypeTag>::R = Constants<typename GET_PROP_TYPE(TypeTag, Scalar)>::R; - -} // end namepace - -#endif +#include <dumux/implicit/3p3c/3p3cvolumevariables.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cnifluxvariables.hh b/dumux/boxmodels/3p3cni/3p3cnifluxvariables.hh index 83b40fd83590893f258c5a494816b3518db96748..00bd8ea3919fa31bd2d18e8b0d753644ac4ec442 100644 --- a/dumux/boxmodels/3p3cni/3p3cnifluxvariables.hh +++ b/dumux/boxmodels/3p3cni/3p3cnifluxvariables.hh @@ -1,129 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes (mass of components and energy) over a face of a finite volume. - * - * This means pressure, concentration and temperature gradients, phase - * densities at the integration point, etc. - */ -#ifndef DUMUX_3P3CNI_FLUX_VARIABLES_HH -#define DUMUX_3P3CNI_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cnifluxvariables.hh instead. -#include <dumux/common/math.hh> -#include <dumux/boxmodels/3p3c/3p3cfluxvariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup ThreePThreeCNIModel - * \brief This template class contains the data which is required to - * calculate all fluxes (mass of components and energy) over a face of a finite - * volume for the non-isothermal three-phase, three-component model. - * - * This means pressure and concentration gradients, phase densities at - * the integration point, etc. - */ -template <class TypeTag> -class ThreePThreeCNIFluxVariables : public ThreePThreeCFluxVariables<TypeTag> -{ - typedef ThreePThreeCFluxVariables<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - - typedef typename GridView::ctype CoordScalar; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - - typedef Dune::FieldVector<CoordScalar, dim> DimVector; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - ThreePThreeCNIFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : ParentType(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary) - { - // calculate temperature gradient using finite element - // gradients - DimVector temperatureGrad(0); - DimVector tmp(0.0); - for (int vertIdx = 0; vertIdx < fvGeometry.numFAP; vertIdx++) - { - tmp = this->face().grad[vertIdx]; - - // index for the element volume variables - int volVarsIdx = this->face().fapIndices[vertIdx]; - - tmp *= elemVolVars[volVarsIdx].temperature(); - temperatureGrad += tmp; - } - - // The spatial parameters calculates the actual heat flux vector - problem.spatialParams().matrixHeatFlux(tmp, - *this, - elemVolVars, - temperatureGrad, - element, - fvGeometry, - faceIdx); - // project the heat flux vector on the face's normal vector - normalMatrixHeatFlux_ = tmp*this->face().normal; - } - - /*! - * \brief The total heat flux \f$\mathrm{[J/s]}\f$ due to heat conduction - * of the rock matrix over the sub-control volume's face in - * direction of the face normal. - */ - Scalar normalMatrixHeatFlux() const - { return normalMatrixHeatFlux_; } - -private: - Scalar normalMatrixHeatFlux_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/3p3cni/3p3cnifluxvariables.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cniindices.hh b/dumux/boxmodels/3p3cni/3p3cniindices.hh index 753a23a5406829f2502372a6d86144eeee8ce33d..8b1d4d0e706b5ff8ffb3dcd60e5c8e23d665059b 100644 --- a/dumux/boxmodels/3p3cni/3p3cniindices.hh +++ b/dumux/boxmodels/3p3cni/3p3cniindices.hh @@ -1,51 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cniindices.hh instead. -/*! - * \file - * - * \brief Defines the indices used by the 3p3cni box model - */ -#ifndef DUMUX_3P3CNI_INDICES_HH -#define DUMUX_3P3CNI_INDICES_HH - -#include <dumux/boxmodels/3p3c/3p3cindices.hh> - -namespace Dumux -{ -/*! - * \ingroup ThreePThreeCNIModel - */ -// \{ - -/*! - * \brief Enumerations for the non-isothermal 3-phase 3-component model - * - * \tparam PVOffset The first index in a primary variable vector. - */ -template <class TypeTag, int PVOffset> -class ThreePThreeCNIIndices : public ThreePThreeCIndices<TypeTag, PVOffset> -{ -public: - static const int temperatureIdx = PVOffset + 3; //! The index for temperature in primary variable vectors. - static const int energyEqIdx = PVOffset + 3; //! The index for energy in equation vectors. -}; - -} -#endif +#include <dumux/implicit/3p3cni/3p3cniindices.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cnilocalresidual.hh b/dumux/boxmodels/3p3cni/3p3cnilocalresidual.hh index 5dfb6dce3746a11cd1813fa9b5aa3b7370377fdc..87b3f3749265237adcf77c748f06b4153c922da7 100644 --- a/dumux/boxmodels/3p3cni/3p3cnilocalresidual.hh +++ b/dumux/boxmodels/3p3cni/3p3cnilocalresidual.hh @@ -1,193 +1,3 @@ -// -*- 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 Element-wise calculation of the Jacobian matrix for problems - * using the non-isothermal three-phase three-component box model. - * - */ -#ifndef DUMUX_NEW_3P3CNI_LOCAL_RESIDUAL_HH -#define DUMUX_NEW_3P3CNI_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cnilocalresidual.hh instead. -#include <dumux/boxmodels/3p3c/3p3clocalresidual.hh> - - -#include "3p3cnivolumevariables.hh" -#include "3p3cnifluxvariables.hh" - -#include "3p3cniproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup ThreePThreeCNIModel - * \brief Element-wise calculation of the Jacobian matrix for problems - * using the three-phase three-component box model. - */ -template<class TypeTag> -class ThreePThreeCNILocalResidual : public ThreePThreeCLocalResidual<TypeTag> -{ - typedef ThreePThreeCLocalResidual<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { - - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - - energyEqIdx = Indices::energyEqIdx, - temperatureIdx = Indices::temperatureIdx, - - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx - }; - - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - -public: - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within a sub-control volume. - * - * The result should be averaged over the volume (e.g. phase mass - * inside a sub control volume divided by the volume) - * - * \param storage The storage of the conservation quantitiy (mass or energy) within the sub-control volume - * \param scvIdx The SCV (sub-control-volume) index - * \param usePrevSol Evaluate function with solution of current or previous time step - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const - { - // compute the storage term for phase mass - ParentType::computeStorage(storage, scvIdx, usePrevSol); - - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemDat = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &vertDat = elemDat[scvIdx]; - - // compute the energy storage - Scalar wdens = vertDat.density(wPhaseIdx); - Scalar ndens = vertDat.density(nPhaseIdx); - Scalar gdens = vertDat.density(gPhaseIdx); - Scalar wInEnerg = vertDat.internalEnergy(wPhaseIdx); - Scalar nInEnerg = vertDat.internalEnergy(nPhaseIdx); - Scalar gInEnerg = vertDat.internalEnergy(gPhaseIdx); - Scalar wsat = vertDat.saturation(wPhaseIdx); - Scalar nsat = vertDat.saturation(nPhaseIdx); - Scalar gsat = vertDat.saturation(gPhaseIdx); - Scalar temp = vertDat.temperature(); - Scalar heatCap = vertDat.heatCapacity(); - Scalar poro = vertDat.porosity(); - - storage[energyEqIdx] = temp*heatCap - + poro * (gdens*gInEnerg*gsat - + wdens*wInEnerg*wsat - + ndens*nInEnerg*nsat); - /* - vertDat.porosity()*(vertDat.density(wPhaseIdx) * - vertDat.internalEnergy(wPhaseIdx) * - vertDat.saturation(wPhaseIdx) - + - vertDat.density(nPhaseIdx) * - vertDat.internalEnergy(nPhaseIdx) * - vertDat.saturation(nPhaseIdx) - + - vertDat.density(gPhaseIdx) * - vertDat.internalEnergy(gPhaseIdx) * - vertDat.saturation(gPhaseIdx)) - + - vertDat.temperature()*vertDat.heatCapacity(); - */ - } - - /*! - * \brief Evaluates the advective mass flux and the heat flux - * over a face of a subcontrol volume and writes the result in - * the flux vector. - * - * \param flux The advective flux over the SCV (sub-control-volume) face for each component - * \param fluxData The flux variables at the current SCV face - * - * This method is called by compute flux (base class) - */ - void computeAdvectiveFlux(PrimaryVariables &flux, - const FluxVariables &fluxData) const - { - // advective mass flux - ParentType::computeAdvectiveFlux(flux, fluxData); - - static const Scalar massUpwindWeight = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - - // advective heat flux in all phases - flux[energyEqIdx] = 0; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // vertex data of the upstream and the downstream vertices - const VolumeVariables &up = this->curVolVars_(fluxData.upstreamIdx(phaseIdx)); - const VolumeVariables &dn = this->curVolVars_(fluxData.downstreamIdx(phaseIdx)); - - flux[energyEqIdx] += - fluxData.volumeFlux(phaseIdx) * ( - massUpwindWeight * // upstream vertex - ( up.density(phaseIdx) * - up.enthalpy(phaseIdx)) - + - (1-massUpwindWeight) * // downstream vertex - ( dn.density(phaseIdx) * - dn.enthalpy(phaseIdx)) ); - } - } - - /*! - * \brief Adds the diffusive heat flux to the flux vector over - * the face of a sub-control volume. - * - * \param flux The diffusive flux over the SCV (sub-control-volume) face for each conservation quantity (mass, energy) - * \param fluxData The flux variables at the current SCV face - * - * This method is called by compute flux (base class) - */ - void computeDiffusiveFlux(PrimaryVariables &flux, - const FluxVariables &fluxData) const - { - // diffusive mass flux - ParentType::computeDiffusiveFlux(flux, fluxData); - - // diffusive heat flux - flux[temperatureIdx] += - fluxData.normalMatrixHeatFlux(); - } -}; - -} - -#endif +#include <dumux/implicit/3p3cni/3p3cnilocalresidual.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cnimodel.hh b/dumux/boxmodels/3p3cni/3p3cnimodel.hh index 7873dee5ce10b3f22ad9096a3b8274a8ef5eb431..483d985a13ce962bec8a6f313f208b55eaf004c6 100644 --- a/dumux/boxmodels/3p3cni/3p3cnimodel.hh +++ b/dumux/boxmodels/3p3cni/3p3cnimodel.hh @@ -1,108 +1,3 @@ -// -*- 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 Adaption of the BOX scheme to the non-isothermal three-phase three-component flow model. - */ -#ifndef DUMUX_NEW_3P3CNI_MODEL_HH -#define DUMUX_NEW_3P3CNI_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cnimodel.hh instead. -#include <dumux/boxmodels/3p3c/3p3cmodel.hh> - -namespace Dumux { -/*! - * \ingroup ThreePThreeCNIModel - * \brief Adaption of the BOX scheme to the non-isothermal three-phase three-component flow model. - * - * This model implements three-phase three-component flow of three fluid phases - * \f$\alpha \in \{ water, gas, NAPL \}\f$ each composed of up to three components - * \f$\kappa \in \{ water, air, contaminant \}\f$. The standard multiphase Darcy - * approach is used as the equation for the conservation of momentum: - * \f[ - v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K} - \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right) - * \f] - * - * By inserting this into the equations for the conservation of the - * components, one transport equation for each component is obtained as - * \f{eqnarray*} - && \phi \frac{\partial (\sum_\alpha \varrho_{\text{mol}, \alpha} x_\alpha^\kappa - S_\alpha )}{\partial t} - - \sum\limits_\alpha \text{div} \left\{ \frac{k_{r\alpha}}{\mu_\alpha} - \varrho_{\text{mol}, \alpha} x_\alpha^\kappa \mbox{\bf K} - (\text{grad}\; p_\alpha - \varrho_{\text{mass}, \alpha} \mbox{\bf g}) \right\} - \nonumber \\ - \nonumber \\ - && - \sum\limits_\alpha \text{div} \left\{ D_{pm}^\kappa \varrho_{\text{mol}, - \alpha } \text{grad} \; x_\alpha^\kappa \right\} - - q^\kappa = 0 \qquad \forall \kappa , \; \forall \alpha - \f} - * - * Note that these balance equations above are molar. - * In addition to that, a single balance of thermal energy is formulated - * for the fluid-filled porous medium under the assumption of local thermal - * equilibrium - * \f{eqnarray*} - && \phi \frac{\partial \left( \sum_\alpha \varrho_\alpha u_\alpha S_\alpha \right)}{\partial t} - + \left( 1 - \phi \right) \frac{\partial (\varrho_s c_s T)}{\partial t} - - \sum_\alpha \text{div} \left\{ \varrho_\alpha h_\alpha - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K} \left( \text{grad}\, - p_\alpha - - \varrho_\alpha \mathbf{g} \right) \right\} \\ - &-& \text{div} \left( \lambda_{pm} \text{grad} \, T \right) - - q^h = 0 \qquad \alpha \in \{w, n, g\} - \f} - * - - * - * The equations are discretized using a fully-coupled vertex - * centered finite volume (BOX) scheme as spatial scheme and - * the implicit Euler method as temporal discretization. - * - * The model uses commonly applied auxiliary conditions like - * \f$S_w + S_n + S_g = 1\f$ for the saturations and - * \f$x^w_\alpha + x^a_\alpha + x^c_\alpha = 1\f$ for the mole fractions. - * Furthermore, the phase pressures are related to each other via - * capillary pressures between the fluid phases, which are functions of - * the saturation, e.g. according to the approach of Parker et al. - * - * The used primary variables are dependent on the locally present fluid phases - * An adaptive primary variable switch is included. The phase state is stored for all nodes - * of the system. The following cases can be distinguished: - * <ul> - * <li> All three phases are present: Primary variables are two saturations \f$(S_w\f$ and \f$S_n)\f$, a pressure, in this case \f$p_g\f$, and the temperature \f$T\f$. </li> - * <li> Only the water phase is present: Primary variables are now the mole fractions of air and contaminant in the water phase \f$(x_w^a\f$ and \f$x_w^c)\f$, as well as temperature and the gas pressure, which is, of course, in a case where only the water phase is present, just the same as the water pressure. </li> - * <li> Gas and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_g^w\f$, \f$p_g\f$, \f$T)\f$. </li> - * <li> Water and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_w^a\f$, \f$p_g\f$, \f$T)\f$. </li> - * <li> Only gas phase is present: Primary variables \f$(x_g^w\f$, \f$x_g^c\f$, \f$p_g\f$, \f$T)\f$. </li> - * <li> Water and gas phases are present: Primary variables \f$(S_w\f$, \f$x_w^g\f$, \f$p_g\f$, \f$T)\f$. </li> - * </ul> - * - */ -template<class TypeTag> -class ThreePThreeCNIModel : public ThreePThreeCModel<TypeTag> -{ -}; - -} - -#include "3p3cnipropertydefaults.hh" - -#endif +#include <dumux/implicit/3p3cni/3p3cnimodel.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cniproperties.hh b/dumux/boxmodels/3p3cni/3p3cniproperties.hh index 0c69522f031f43ad070b9f7fe13f954a50935508..be3d0ab1a849276a5fb4520a0f214769205329b6 100644 --- a/dumux/boxmodels/3p3cni/3p3cniproperties.hh +++ b/dumux/boxmodels/3p3cni/3p3cniproperties.hh @@ -1,47 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup ThreePThreeCNIModel - */ -/*! - * \file - * - * \brief Defines the properties required for the non-isothermal three-phase, - * three-component BOX model. - */ -#ifndef DUMUX_3P3CNI_PROPERTIES_HH -#define DUMUX_3P3CNI_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cniproperties.hh instead. -#include <dumux/boxmodels/3p3c/3p3cproperties.hh> - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for the non-isothermal three-phase, three-component problems -NEW_TYPE_TAG(BoxThreePThreeCNI, INHERITS_FROM(BoxThreePThreeC)); -} -} - -#endif +#include <dumux/implicit/3p3cni/3p3cniproperties.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cnipropertydefaults.hh b/dumux/boxmodels/3p3cni/3p3cnipropertydefaults.hh index a00787502d2ccebdbc70a11c2232339c11380555..976567084fc09f056849cb24995ecd4802c0c607 100644 --- a/dumux/boxmodels/3p3cni/3p3cnipropertydefaults.hh +++ b/dumux/boxmodels/3p3cni/3p3cnipropertydefaults.hh @@ -1,71 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup ThreePThreeCNIModel - */ -/*! - * \file - * - * \brief Defines default values for most properties required by the 3p3cni - * box model. - */ -#ifndef DUMUX_3P3CNI_PROPERTY_DEFAULTS_HH -#define DUMUX_3P3CNI_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cnipropertydefaults.hh instead. -#include <dumux/boxmodels/3p3c/3p3cpropertydefaults.hh> - -#include "3p3cnimodel.hh" -#include "3p3cniindices.hh" -#include "3p3cnilocalresidual.hh" -#include "3p3cnivolumevariables.hh" -#include "3p3cnifluxvariables.hh" - -namespace Dumux -{ - -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// Property values -////////////////////////////////////////////////////////////////// - -SET_INT_PROP(BoxThreePThreeCNI, NumEq, 4); //!< set the number of equations to 4 - -//! Use the 3p3cni local jacobian operator for the 3p3cni model -SET_TYPE_PROP(BoxThreePThreeCNI, - LocalResidual, - ThreePThreeCNILocalResidual<TypeTag>); - -//! the Model property -SET_TYPE_PROP(BoxThreePThreeCNI, Model, ThreePThreeCNIModel<TypeTag>); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxThreePThreeCNI, VolumeVariables, ThreePThreeCNIVolumeVariables<TypeTag>); - - -//! the FluxVariables property -SET_TYPE_PROP(BoxThreePThreeCNI, FluxVariables, ThreePThreeCNIFluxVariables<TypeTag>); - -//! The indices required by the non-isothermal 3p3c model -SET_TYPE_PROP(BoxThreePThreeCNI, Indices, ThreePThreeCNIIndices<TypeTag, 0>); - -} - -} -#endif +#include <dumux/implicit/3p3cni/3p3cnipropertydefaults.hh> diff --git a/dumux/boxmodels/3p3cni/3p3cnivolumevariables.hh b/dumux/boxmodels/3p3cni/3p3cnivolumevariables.hh index d24cecadf1f319d1c8f52a15a7c23c8437d9a865..fb0c6036609f374a0ac9be096558887cea129299 100644 --- a/dumux/boxmodels/3p3cni/3p3cnivolumevariables.hh +++ b/dumux/boxmodels/3p3cni/3p3cnivolumevariables.hh @@ -1,157 +1,3 @@ -// -*- 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 Contains the quantities which are constant within a - * finite volume in the non-isothermal three-phase, three-component - * model. - */ -#ifndef DUMUX_3P3CNI_VOLUME_VARIABLES_HH -#define DUMUX_3P3CNI_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/3p3cni/3p3cnivolumevariables.hh instead. -#include <dumux/boxmodels/3p3c/3p3cvolumevariables.hh> - - -namespace Dumux -{ - -/*! - * \ingroup ThreePThreeCNIModel - * \brief Contains the quantities which are are constant within a - * finite volume in the non-isothermal three-phase, three-component - * model. - */ -template <class TypeTag> -class ThreePThreeCNIVolumeVariables : public ThreePThreeCVolumeVariables<TypeTag> -{ - //! \cond 0 - typedef ThreePThreeCVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { temperatureIdx = Indices::temperatureIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - //! \endcond - -public: - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - bool isOldSol) - { - // vertex update data for the mass balance - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - typename FluidSystem::ParameterCache paramCache; - paramCache.updateAll(this->fluidState()); - - // the internal energies and the enthalpies - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - Scalar h = FluidSystem::enthalpy(this->fluidState_, paramCache, phaseIdx); - this->fluidState_.setEnthalpy(phaseIdx, h); - } - }; - - /*! - * \brief Returns the total internal energy of a phase in the - * sub-control volume. - * - * \param phaseIdx The phase index - */ - Scalar internalEnergy(int phaseIdx) const - { return this->fluidState_.internalEnergy(phaseIdx); }; - - /*! - * \brief Returns the total enthalpy of a phase in the sub-control - * volume. - * - * \param phaseIdx The phase index - */ - Scalar enthalpy(int phaseIdx) const - { return this->fluidState_.enthalpy(phaseIdx); }; - - /*! - * \brief Returns the total heat capacity \f$\mathrm{[J/(K*m^3]}\f$ of the rock matrix in - * the sub-control volume. - */ - Scalar heatCapacity() const - { return heatCapacity_; }; - -protected: - // this method gets called by the parent class. since this method - // is protected, we are friends with our parent.. - friend class ThreePThreeCVolumeVariables<TypeTag>; - - static Scalar temperature_(const PrimaryVariables &primaryVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return primaryVars[temperatureIdx]; - } - - /*! - * \brief Update all quantities for a given control volume. - * - * \param priVars The solution primary variables - * \param problem The problem - * \param element The element - * \param fvGeometry Evaluate function with solution of current or previous time step - * \param scvIdx The local index of the SCV (sub-control volume) - * \param isOldSol Evaluate function with solution of current or previous time step - */ - void updateEnergy_(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - bool isOldSol) - { - // copmute and set the heat capacity of the solid phase - heatCapacity_ = problem.spatialParams().heatCapacity(element, fvGeometry, scvIdx); - Valgrind::CheckDefined(heatCapacity_); - }; - - Scalar heatCapacity_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/3p3cni/3p3cnivolumevariables.hh> diff --git a/dumux/boxmodels/co2/co2model.hh b/dumux/boxmodels/co2/co2model.hh index fcf6360603539d17202fc20fa62ff5df9c69345a..8757ae3500698aa9944746212dfb076f436e7d49 100644 --- a/dumux/boxmodels/co2/co2model.hh +++ b/dumux/boxmodels/co2/co2model.hh @@ -1,283 +1,3 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * Copyright (C) 2012 by * - * Institute for Modelling Hydraulic and Environmental Systems * - * University of Stuttgart, Germany * - * email: <givenname>.<name>@iws.uni-stuttgart.de * - * * - * 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 Adaption of the BOX scheme to the two-phase two-component flow model without constraint solver. - */ -#ifndef DUMUX_CO2_MODEL_HH -#define DUMUX_CO2_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/co2/co2model.hh instead. -#include <dumux/boxmodels/2p2c/2p2cmodel.hh> - -namespace Dumux -{ -/*! - * \ingroup CO2Model - * \brief Adaption of the BOX scheme to the non-isothermal two-phase two-component flow model. - * See TwoPTwoCModel for reference to the equations used. - * The CO2 model is derived from the 2p2c model. In the CO2 model the phase switch criterion - * is different from the 2p2c model. - * The phase switch occurs when the equilibrium concentration - * of a component in a phase is exceeded, instead of the sum of the components in the virtual phase - * (the phase which is not present) being greater that unity as done in the 2p2c model. - * The CO2VolumeVariables do not use a constraint solver for calculating the mole fractions as is the - * case in the 2p2c model. Instead mole fractions are calculated in the FluidSystem with a given - * temperature, pressurem and salinity. - * - */ - -template<class TypeTag> -class CO2Model: public TwoPTwoCModel<TypeTag> -{ - - - typedef TwoPTwoCModel<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, BaseModel) BaseType; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, - - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases, - - pwSn = TwoPTwoCFormulation::pwSn, - pnSw = TwoPTwoCFormulation::pnSw, - formulation = GET_PROP_VALUE(TypeTag, Formulation) - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::ctype CoordScalar; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef typename GridView::template Codim<dim>::Entity Vertex; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, numPhases> PhasesVector; - typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - - public: - - - /*! - * \brief Update the static data of all vertices in the grid. - * - * \param curGlobalSol The current global solution - * \param oldGlobalSol The previous global solution - */ - void updateStaticData(SolutionVector &curGlobalSol, - const SolutionVector &oldGlobalSol) - { - bool wasSwitched = false; - - for (unsigned i = 0; i < ParentType::staticVertexDat_.size(); ++i) - ParentType::staticVertexDat_[i].visited = false; - - unsigned numDofs = this->numDofs(); - unsigned numVertices = this->problem_().gridView().size(dim); - - FVElementGeometry fvGeometry; - static VolumeVariables volVars; - ElementIterator eIt = this->gridView_().template begin<0> (); - const ElementIterator &eEndIt = this->gridView_().template end<0> (); - for (; eIt != eEndIt; ++eIt) - { - fvGeometry.update(this->gridView_(), *eIt); - for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx) - { - int globalIdx; - - if (numDofs != numVertices) - globalIdx = this->elementMapper().map(*eIt); - else - globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim); - - if (ParentType::staticVertexDat_[globalIdx].visited) - continue; - - ParentType::staticVertexDat_[globalIdx].visited = true; - volVars.update(curGlobalSol[globalIdx], - this->problem_(), - *eIt, - fvGeometry, - scvIdx, - false); - const GlobalPosition &globalPos = eIt->geometry().corner(scvIdx); - if (primaryVarSwitch_(curGlobalSol, - volVars, - globalIdx, - globalPos)) - { - this->jacobianAssembler().markVertexRed(globalIdx); - wasSwitched = true; - } - } - } - - // make sure that if there was a variable switch in an - // other partition we will also set the switch flag - // for our partition. - if (this->gridView_().comm().size() > 1) - wasSwitched = this->gridView_().comm().max(wasSwitched); - - ParentType::setSwitched_(wasSwitched); - } - - protected: - - - /*! - * \brief Set the old phase of all verts state to the current one. - */ - bool primaryVarSwitch_(SolutionVector &globalSol, - const VolumeVariables &volVars, int globalIdx, - const GlobalPosition &globalPos) - { - typename FluidSystem::ParameterCache paramCache; - // evaluate primary variable switch - bool wouldSwitch = false; - int phasePresence = ParentType::staticVertexDat_[globalIdx].phasePresence; - int newPhasePresence = phasePresence; - - // check if a primary var switch is necessary - if (phasePresence == nPhaseOnly) - { - - Scalar xnw = volVars.fluidState().moleFraction(nPhaseIdx, wCompIdx); - Scalar xnwMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, nPhaseIdx); - - if(xnw > xnwMax) - wouldSwitch = true; - - if (ParentType::staticVertexDat_[globalIdx].wasSwitched) - xnwMax *= 1.02; - - //If mole fraction is higher than the equilibrium mole fraction make a phase switch - if(xnw > xnwMax) - { - // wetting phase appears - std::cout << "wetting phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xnw > xnwMax: " - << xnw << " > "<< xnwMax << std::endl; - newPhasePresence = bothPhases; - if (formulation == pnSw) - globalSol[globalIdx][switchIdx] = 0.0; - else if (formulation == pwSn) - globalSol[globalIdx][switchIdx] = 1.0; - } - } - else if (phasePresence == wPhaseOnly) - { - - Scalar xwn = volVars.fluidState().moleFraction(wPhaseIdx, nCompIdx); - Scalar xwnMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, wPhaseIdx); - - //If mole fraction is higher than the equilibrium mole fraction make a phase switch - if(xwn > xwnMax) - wouldSwitch = true; - if (ParentType::staticVertexDat_[globalIdx].wasSwitched) - xwnMax *= 1.02; - - - if(xwn > xwnMax) - { - // non-wetting phase appears - std::cout << "non-wetting phase appears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", xwn > xwnMax: " - << xwn << " > "<< xwnMax << std::endl; - - newPhasePresence = bothPhases; - if (formulation == pnSw) - globalSol[globalIdx][switchIdx] = 0.999; - else if (formulation == pwSn) - globalSol[globalIdx][switchIdx] = 0.001; - } - } - else if (phasePresence == bothPhases) - { - Scalar Smin = 0.0; - if (ParentType::staticVertexDat_[globalIdx].wasSwitched) - Smin = -0.01; - - if (volVars.saturation(nPhaseIdx) <= Smin) - { - wouldSwitch = true; - // nonwetting phase disappears - std::cout << "Nonwetting phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = wPhaseOnly; - - globalSol[globalIdx][switchIdx] - = volVars.fluidState().massFraction(wPhaseIdx, nCompIdx); - } - else if (volVars.saturation(wPhaseIdx) <= Smin) - { - wouldSwitch = true; - // wetting phase disappears - std::cout << "Wetting phase disappears at vertex " << globalIdx - << ", coordinates: " << globalPos << ", Sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = nPhaseOnly; - - globalSol[globalIdx][switchIdx] - = volVars.fluidState().massFraction(nPhaseIdx, wCompIdx); - } - } - - ParentType::staticVertexDat_[globalIdx].phasePresence = newPhasePresence; - ParentType::staticVertexDat_[globalIdx].wasSwitched = wouldSwitch; - return phasePresence != newPhasePresence; - } - - -}; - -} - -#endif +#include <dumux/implicit/co2/co2model.hh> diff --git a/dumux/boxmodels/co2/co2volumevariables.hh b/dumux/boxmodels/co2/co2volumevariables.hh index 0d0e41b3a138434a0676b7244bd789e36a0361ca..c824b526103e22afa42fd1129d6d273b53151168 100644 --- a/dumux/boxmodels/co2/co2volumevariables.hh +++ b/dumux/boxmodels/co2/co2volumevariables.hh @@ -1,404 +1,3 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * Copyright (C) 2012 by * - * Institute for Modelling Hydraulic and Environmental Systems * - * University of Stuttgart, Germany * - * email: <givenname>.<name>@iws.uni-stuttgart.de * - * * - * 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/>. * - *****************************************************************************/ -#ifndef DUMUX_CO2_VOLUME_VARIABLES_HH -#define DUMUX_CO2_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/co2/co2volumevariables.hh instead. -#include <dumux/boxmodels/2p2c/2p2cvolumevariables.hh> - -namespace Dumux -{ -/*! - * \ingroup CO2Model - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the non-isothermal two-phase, two-component - * model. - */ -template <class TypeTag> -class CO2VolumeVariables: public TwoPTwoCVolumeVariables<TypeTag> -{ - typedef TwoPTwoCVolumeVariables<TypeTag> ParentType; - typedef BoxVolumeVariables<TypeTag> BaseClassType; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -// typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents) - }; - - enum { - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - - // present phases - enum { - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases - }; - - // formulations - enum { - formulation = GET_PROP_VALUE(TypeTag, Formulation), - pwSn = TwoPTwoCFormulation::pwSn, - pnSw = TwoPTwoCFormulation::pnSw - }; - - // primary variable indices - enum { - switchIdx = Indices::switchIdx, - pressureIdx = Indices::pressureIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { dim = GridView::dimension}; - - static const Scalar R; // universial nonwetting constant - -public: - //! The type of the object returned by the fluidState() method - typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> FluidState; - - - /*! - * \brief Update all quantities for a given control volume. - * - * \param priVars The primary variables - * \param problem The problem - * \param element The element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvIdx The local index of the SCV (sub-control volume) - * \param isOldSol Evaluate function with solution of current or previous time step - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { - // Update BoxVolVars but not 2p2cvolvars - // ToDo: Is BaseClassType the right name? - BaseClassType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - unsigned numDofs = problem.model().numDofs(); - unsigned numVertices = problem.gridView().size(dim); - - int globalIdx; - if (numDofs != numVertices) // element data - globalIdx = problem.model().dofMapper().map(element); - else - globalIdx = problem.model().dofMapper().map(element, scvIdx, dim); - - int phasePresence = problem.model().phasePresence(globalIdx, isOldSol); - - Scalar temp = Implementation::temperature_(priVars, problem, element, fvGeometry, scvIdx); - ParentType::fluidState_.setTemperature(temp); - - ///////////// - // set the saturations - ///////////// - Scalar Sn; - if (phasePresence == nPhaseOnly) - Sn = 1.0; - else if (phasePresence == wPhaseOnly) { - Sn = 0.0; - } - else if (phasePresence == bothPhases) { - if (formulation == pwSn) - Sn = priVars[switchIdx]; - else if (formulation == pnSw) - Sn = 1.0 - priVars[switchIdx]; - else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid."); - } - else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); - ParentType::fluidState_.setSaturation(wPhaseIdx, 1 - Sn); - ParentType::fluidState_.setSaturation(nPhaseIdx, Sn); - - // capillary pressure parameters - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - - - Scalar pC = MaterialLaw::pC(materialParams, 1 - Sn); - - if (formulation == pwSn) { - ParentType::fluidState_.setPressure(wPhaseIdx, priVars[pressureIdx]); - ParentType::fluidState_.setPressure(nPhaseIdx, priVars[pressureIdx] + pC); - } - else if (formulation == pnSw) { - ParentType::fluidState_.setPressure(nPhaseIdx, priVars[pressureIdx]); - ParentType::fluidState_.setPressure(wPhaseIdx, priVars[pressureIdx] - pC); - } - else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid."); - - ///////////// - // calculate the phase compositions - ///////////// - typename FluidSystem::ParameterCache paramCache; - - - // calculate phase composition - if (phasePresence == bothPhases) { - - //Get the equilibrium mole fractions from the FluidSystem and set them in the fluidState - //xCO2 = equilibrium mole fraction of CO2 in the liquid phase - //yH2O = equilibrium mole fraction of H2O in the gas phase - - Scalar xwCO2 = FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar xgH2O = FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, nPhaseIdx); - Scalar xwH2O = 1 - xwCO2; - Scalar xgCO2 = 1 - xgH2O; - - ParentType::fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xwH2O); - ParentType::fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwCO2); - ParentType::fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xgH2O); - ParentType::fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xgCO2); - - - //Get the phase densities from the FluidSystem and set them in the fluidState - - Scalar rhoW = FluidSystem::density(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar rhoN = FluidSystem::density(ParentType::fluidState_, paramCache, nPhaseIdx); - - ParentType::fluidState_.setDensity(wPhaseIdx, rhoW); - ParentType::fluidState_.setDensity(nPhaseIdx, rhoN); - - - //Get the phase viscosities from the FluidSystem and set them in the fluidState - - Scalar muW = FluidSystem::viscosity(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar muN = FluidSystem::viscosity(ParentType::fluidState_, paramCache, nPhaseIdx); - - ParentType::fluidState_.setViscosity(wPhaseIdx, muW); - ParentType::fluidState_.setViscosity(nPhaseIdx, muN); - - } - else if (phasePresence == nPhaseOnly) { - // only the nonwetting phase is present, i.e. nonwetting phase - // composition is stored explicitly. - - // extract _mass_ fractions in the nonwetting phase - Scalar massFractionN[numComponents]; - massFractionN[wCompIdx] = priVars[switchIdx]; - massFractionN[nCompIdx] = 1 - massFractionN[wCompIdx]; - - // calculate average molar mass of the nonwetting phase - Scalar M1 = FluidSystem::molarMass(wCompIdx); - Scalar M2 = FluidSystem::molarMass(nCompIdx); - Scalar X2 = massFractionN[nCompIdx]; - Scalar avgMolarMass = M1*M2/(M2 + X2*(M1 - M2)); - - // convert mass to mole fractions and set the fluid state - ParentType::fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, massFractionN[wCompIdx]*avgMolarMass/M1); - ParentType::fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, massFractionN[nCompIdx]*avgMolarMass/M2); - - // TODO give values for non-existing wetting phase - Scalar xwCO2 = FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar xwH2O = 1 - xwCO2; -// Scalar xwCO2 = FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, wPhaseIdx, nPhaseOnly); -// Scalar xwH2O = 1 - xwCO2; - ParentType::fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwCO2); - ParentType::fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xwH2O); - - - //Get the phase densities from the FluidSystem and set them in the fluidState - - Scalar rhoW = FluidSystem::density(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar rhoN = FluidSystem::density(ParentType::fluidState_, paramCache, nPhaseIdx); - - ParentType::fluidState_.setDensity(wPhaseIdx, rhoW); - ParentType::fluidState_.setDensity(nPhaseIdx, rhoN); - - //Get the phase viscosities from the FluidSystem and set them in the fluidState - - Scalar muW = FluidSystem::viscosity(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar muN = FluidSystem::viscosity(ParentType::fluidState_, paramCache, nPhaseIdx); - - ParentType::fluidState_.setViscosity(wPhaseIdx, muW); - ParentType::fluidState_.setViscosity(nPhaseIdx, muN); - } - else if (phasePresence == wPhaseOnly) { - // only the wetting phase is present, i.e. wetting phase - // composition is stored explicitly. - - // extract _mass_ fractions in the nonwetting phase - Scalar massFractionW[numComponents]; - massFractionW[nCompIdx] = priVars[switchIdx]; - massFractionW[wCompIdx] = 1 - massFractionW[nCompIdx]; - - // calculate average molar mass of the nonwetting phase - Scalar M1 = FluidSystem::molarMass(wCompIdx); - Scalar M2 = FluidSystem::molarMass(nCompIdx); - Scalar X2 = massFractionW[nCompIdx]; - Scalar avgMolarMass = M1*M2/(M2 + X2*(M1 - M2)); - - // convert mass to mole fractions and set the fluid state - ParentType::fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, massFractionW[wCompIdx]*avgMolarMass/M1); - ParentType::fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, massFractionW[nCompIdx]*avgMolarMass/M2); - - // TODO give values for non-existing nonwetting phase - Scalar xnH2O = FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, nPhaseIdx); - Scalar xnCO2 = 1 - xnH2O; //FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, nPhaseIdx); -// Scalar xnH2O = FluidSystem::equilibriumMoleFraction(ParentType::fluidState_, paramCache, nPhaseIdx, wPhaseOnly); -// Scalar xnCO2 = 1 - xnH2O; - ParentType::fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnCO2); - ParentType::fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnH2O); - - - Scalar rhoW = FluidSystem::density(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar rhoN = FluidSystem::density(ParentType::fluidState_, paramCache, nPhaseIdx); - - ParentType::fluidState_.setDensity(wPhaseIdx, rhoW); - ParentType::fluidState_.setDensity(nPhaseIdx, rhoN); - - //Get the phase viscosities from the FluidSystem and set them in the fluidState - - Scalar muW = FluidSystem::viscosity(ParentType::fluidState_, paramCache, wPhaseIdx); - Scalar muN = FluidSystem::viscosity(ParentType::fluidState_, paramCache, nPhaseIdx); - - ParentType::fluidState_.setViscosity(wPhaseIdx, muW); - ParentType::fluidState_.setViscosity(nPhaseIdx, muN); - } - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // compute and set the enthalpy - Scalar h = Implementation::enthalpy_(ParentType::fluidState_, paramCache, phaseIdx); - ParentType::fluidState_.setEnthalpy(phaseIdx, h); - } - - paramCache.updateAll(ParentType::fluidState_); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // relative permeabilities - Scalar kr; - if (phaseIdx == wPhaseIdx) - kr = MaterialLaw::krw(materialParams, this->saturation(wPhaseIdx)); - else // ATTENTION: krn requires the liquid saturation - // as parameter! - kr = MaterialLaw::krn(materialParams, this->saturation(wPhaseIdx)); - ParentType::relativePermeability_[phaseIdx] = kr; - Valgrind::CheckDefined(ParentType::relativePermeability_[phaseIdx]); - - // binary diffusion coefficents - ParentType::diffCoeff_[phaseIdx] = - FluidSystem::binaryDiffusionCoefficient(ParentType::fluidState_, - paramCache, - phaseIdx, - wCompIdx, - nCompIdx); - Valgrind::CheckDefined(ParentType::diffCoeff_[phaseIdx]); - } - - // porosity - ParentType::porosity_ = problem.spatialParams().porosity(element, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(ParentType::porosity_); -// if(phasePresence == bothPhases) -// { -// std::cout<<"globalIdx = "<<globalIdx<<std::endl; -// std::cout<<"scvIdx = "<<globalIdx<<std::endl; -// std::cout<<"Sn = "<<ParentType::fluidState_.saturation(nPhaseIdx)<<std::endl; -// std::cout<<"Sw = "<<ParentType::fluidState_.saturation(wPhaseIdx)<<std::endl; -// std::cout<<"mobilityN = "<<ParentType::mobility(nPhaseIdx)<<std::endl; -// std::cout<<"xgH2O = "<<ParentType::fluidState_.moleFraction(nPhaseIdx, wCompIdx)<<std::endl; -// std::cout<<"xgCO2 = "<<ParentType::fluidState_.moleFraction(nPhaseIdx, nCompIdx)<<std::endl; -// std::cout<<"xwH2O = "<<ParentType::fluidState_.moleFraction(wPhaseIdx, wCompIdx)<<std::endl; -// std::cout<<"xwCO2 = "<<ParentType::fluidState_.moleFraction(wPhaseIdx, nCompIdx)<<std::endl; -// std::cout<<"XgH2O = "<<ParentType::fluidState_.massFraction(nPhaseIdx, wCompIdx)<<std::endl; -// std::cout<<"XgCO2 = "<<ParentType::fluidState_.massFraction(nPhaseIdx, nCompIdx)<<std::endl; -// std::cout<<"XwH2O = "<<ParentType::fluidState_.massFraction(wPhaseIdx, wCompIdx)<<std::endl; -// std::cout<<"XwCO2 = "<<ParentType::fluidState_.massFraction(wPhaseIdx, nCompIdx)<<std::endl; -// } - - // energy related quantities not contained in the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - - - -protected: - - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - template<class ParameterCache> - static Scalar enthalpy_(const FluidState& fluidState, - const ParameterCache& paramCache, - const int phaseIdx) - { - return 0; - } - - void updateEnergy_(const PrimaryVariables &sol, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int vertIdx, - bool isOldSol) - { } - - - -private: - - - - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; - -} // end namepace - -#endif +#include <dumux/implicit/co2/co2volumevariables.hh> diff --git a/dumux/boxmodels/co2ni/co2nimodel.hh b/dumux/boxmodels/co2ni/co2nimodel.hh index 987f1b193c7bbd0b2edb23acf45416c1a7be83e0..56e5758e511c06072a3c4903ec103ddf9a2c8c03 100644 --- a/dumux/boxmodels/co2ni/co2nimodel.hh +++ b/dumux/boxmodels/co2ni/co2nimodel.hh @@ -1,56 +1,3 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * Copyright (C) 2012 by * - * Institute for Modelling Hydraulic and Environmental Systems * - * University of Stuttgart, Germany * - * email: <givenname>.<name>@iws.uni-stuttgart.de * - * * - * 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 Adaption of the BOX scheme to the non-isothermal two-phase two-component flow model without constraint solver. - */ -#ifndef DUMUX_CO2NI_MODEL_HH -#define DUMUX_CO2NI_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/co2ni/co2nimodel.hh instead. -#include <dumux/boxmodels/co2/co2model.hh> - -namespace Dumux { -/*! - * \ingroup CO2NIModel - * \brief Adaption of the BOX scheme to the non-isothermal two-phase two-component flow model. - * See TwoPTwoCNI model for reference to the equations. - * The CO2NI model is derived from the CO2 model. In the CO2 model the phase switch criterion - * is different from the 2p2c model. - * The phase switch occurs when the equilibrium concentration - * of a component in a phase is exceeded instead of the sum of the components in the virtual phase - * (the phase which is not present) being greater that unity as done in the 2p2c model. - * The CO2VolumeVariables do not use a constraint solver for calculating the mole fractions as is the - * case in the 2p2c model. Instead mole fractions are calculated in the FluidSystem with a given - * temperature, pressure and salinity. - * - */ -template<class TypeTag> -class CO2NIModel : public CO2Model<TypeTag> -{ -}; - -} - -#include <dumux/boxmodels/2p2cni/2p2cnipropertydefaults.hh> - -#endif +#include <dumux/implicit/co2ni/co2nimodel.hh> diff --git a/dumux/boxmodels/co2ni/co2nivolumevariables.hh b/dumux/boxmodels/co2ni/co2nivolumevariables.hh index 9609d0095be6f17b8786ec8890e1761a88268634..69b7bcfdd473c54a76d31091a92cfb9c3d0749d4 100644 --- a/dumux/boxmodels/co2ni/co2nivolumevariables.hh +++ b/dumux/boxmodels/co2ni/co2nivolumevariables.hh @@ -1,139 +1,3 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * Copyright (C) 2012 by * - * Institute for Modelling Hydraulic and Environmental Systems * - * University of Stuttgart, Germany * - * email: <givenname>.<name>@iws.uni-stuttgart.de * - * * - * 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 Contains the quantities which are constant within a - * finite volume in the non-isothermal two-phase, two-component - * model. - */ -#ifndef DUMUX_CO2NI_VOLUME_VARIABLES_HH -#define DUMUX_CO2NI_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/co2ni/co2nivolumevariables.hh instead. -#include <dumux/boxmodels/co2/co2volumevariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup CO2NIModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the non-isothermal two-phase, two-component - * model. - */ -template <class TypeTag> -class CO2NIVolumeVariables : public CO2VolumeVariables<TypeTag> -{ - //! \cond 0 - typedef CO2VolumeVariables<TypeTag> ParentType; - typedef typename ParentType::FluidState FluidState; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { temperatureIdx = Indices::temperatureIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - //! \endcond - -public: - /*! - * \brief Returns the total internal energy of a phase in the - * sub-control volume. - * - * \param phaseIdx The phase index - */ - Scalar internalEnergy(const int phaseIdx) const - { return this->fluidState_.internalEnergy(phaseIdx); }; - - /*! - * \brief Returns the total enthalpy of a phase in the sub-control - * volume. - * - * \param phaseIdx The phase index - */ - Scalar enthalpy(const int phaseIdx) const - { return this->fluidState_.enthalpy(phaseIdx); }; - - /*! - * \brief Returns the total heat capacity \f$\mathrm{[J/(K*m^3]}\f$ of the rock matrix in - * the sub-control volume. - */ - Scalar heatCapacity() const - { return heatCapacity_; }; - -protected: - // this method gets called by the parent class. since this method - // is protected, we are friends with our parent.. - friend class CO2VolumeVariables<TypeTag>; - - static Scalar temperature_(const PrimaryVariables &priVars, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return priVars[temperatureIdx]; - } - - template<class ParameterCache> - static Scalar enthalpy_(const FluidState& fluidState, - const ParameterCache& paramCache, - const int phaseIdx) - { - return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx); - } - - /*! - * \brief Update all quantities for a given control volume. - * - * \param sol The solution primary variables - * \param problem The problem - * \param element The element - * \param fvGeometry Evaluate function with solution of current or previous time step - * \param scvIdx The local index of the SCV (sub-control volume) - * \param isOldSol Evaluate function with solution of current or previous time step - */ - void updateEnergy_(const PrimaryVariables &sol, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - bool isOldSol) - { - // copmute and set the heat capacity of the solid phase - heatCapacity_ = problem.spatialParams().heatCapacity(element, fvGeometry, scvIdx); - Valgrind::CheckDefined(heatCapacity_); - }; - - Scalar heatCapacity_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/co2ni/co2nivolumevariables.hh> diff --git a/dumux/boxmodels/common/boxassembler.hh b/dumux/boxmodels/common/boxassembler.hh index 18e196c3e8aaa65aae8cc43edbdf6ce6846a5973..ac6b886f8398e6a7acd7e09c903167e911f177b5 100644 --- a/dumux/boxmodels/common/boxassembler.hh +++ b/dumux/boxmodels/common/boxassembler.hh @@ -1,858 +1,3 @@ -// -*- 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 An assembler for the global Jacobian matrix for models using the box discretization. - */ -#ifndef DUMUX_BOX_ASSEMBLER_HH -#define DUMUX_BOX_ASSEMBLER_HH +#warning This file is deprecated. Include dumux/implicit/box/boxassembler.hh instead. -#include <dune/grid/common/gridenums.hh> - -#include <dumux/boxmodels/common/boxproperties.hh> -#include <dumux/linear/vertexborderlistfromgrid.hh> -#include <dumux/linear/foreignoverlapfrombcrsmatrix.hh> -#include <dumux/parallel/vertexhandles.hh> - -namespace Dumux { - -/*! - * \brief An assembler for the global Jacobian matrix for models using the box discretization. - */ -template<class TypeTag> -class BoxAssembler -{ - typedef typename GET_PROP_TYPE(TypeTag, Model) Model; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper; - - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) JacobianMatrix; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - enum{ dim = GridView::dimension }; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim<dim>::EntityPointer VertexPointer; - - enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) }; - typedef Dune::FieldMatrix<Scalar, numEq, numEq> MatrixBlock; - typedef Dune::FieldVector<Scalar, numEq> VectorBlock; - - // copying the jacobian assembler is not a good idea - BoxAssembler(const BoxAssembler &); - -public: - /*! - * \brief The colors of elements and vertices required for partial - * Jacobian reassembly. - */ - enum EntityColor { - /*! - * Vertex/element that needs to be reassembled because some - * relative error is above the tolerance - */ - Red = 0, - - /*! - * Vertex/element that needs to be reassembled because a - * neighboring element/vertex is red - */ - Yellow = 1, - - /*! - * Yellow vertex has only non-green neighbor elements. - * - * This means that its relative error is below the tolerance, - * but its defect can be linearized without any additional - * cost. This is just an "internal" color which is not used - * ouside of the jacobian assembler. - */ - Orange = 2, - - /*! - * Vertex/element that does not need to be reassembled - */ - Green = 3 - }; - - BoxAssembler() - { - problemPtr_ = 0; - matrix_ = 0; - - // set reassemble accuracy to 0, so that if partial reassembly - // of the jacobian matrix is disabled, the reassemble accuracy - // is always smaller than the current relative tolerance - reassembleAccuracy_ = 0.0; - } - - ~BoxAssembler() - { - delete matrix_; - } - - /*! - * \brief Initialize the jacobian assembler. - * - * At this point we can assume that all objects in the problem and - * the model have been allocated. We can not assume that they are - * fully initialized, though. - * - * \param problem The problem object - */ - void init(Problem& problem) - { - problemPtr_ = &problem; - - // initialize the BCRS matrix - createMatrix_(); - - // initialize the jacobian matrix and the right hand side - // vector - *matrix_ = 0; - reuseMatrix_ = false; - - int numVerts = gridView_().size(dim); - int numElems = gridView_().size(0); - - residual_.resize(numVerts); - - // initialize the storage part of the Jacobian matrix. Since - // we only need this if Jacobian matrix recycling is enabled, - // we do not waste space if it is disabled - if (enableJacobianRecycling_()) { - storageJacobian_.resize(numVerts); - storageTerm_.resize(numVerts); - } - - if (gridView_().comm().size() > 1) - totalElems_ = gridView_().comm().sum(numElems); - else - totalElems_ = numElems; - - // initialize data needed for partial reassembly - if (enablePartialReassemble_()) { - vertexColor_.resize(numVerts); - vertexDelta_.resize(numVerts); - elementColor_.resize(numElems); - } - reassembleAll(); - } - - /*! - * \brief Assemble the global Jacobian of the residual and the residual for the current solution. - * - * The current state of affairs (esp. the previous and the current - * solutions) is represented by the model object. - */ - void assemble() - { - bool printReassembleStatistics = enablePartialReassemble_() && !reuseMatrix_; - int succeeded; - try { - assemble_(); - succeeded = 1; - if (gridView_().comm().size() > 1) - succeeded = gridView_().comm().min(succeeded); - } - catch (Dumux::NumericalProblem &e) - { - std::cout << "rank " << problem_().gridView().comm().rank() - << " caught an exception while assembling:" << e.what() - << "\n"; - succeeded = 0; - if (gridView_().comm().size() > 1) - succeeded = gridView_().comm().min(succeeded); - } - - if (!succeeded) { - DUNE_THROW(NumericalProblem, - "A process did not succeed in linearizing the system"); - } - - if (printReassembleStatistics) - { - if (gridView_().comm().size() > 1) - { - greenElems_ = gridView_().comm().sum(greenElems_); - reassembleAccuracy_ = gridView_().comm().max(nextReassembleAccuracy_); - } - else - { - reassembleAccuracy_ = nextReassembleAccuracy_; - } - - problem_().newtonController().endIterMsg() - << ", reassembled " - << totalElems_ - greenElems_ << "/" << totalElems_ - << " (" << 100*Scalar(totalElems_ - greenElems_)/totalElems_ << "%) elems @accuracy=" - << reassembleAccuracy_; - } - - // reset all vertex colors to green - for (unsigned int i = 0; i < vertexColor_.size(); ++i) { - vertexColor_[i] = Green; - } - } - - /*! - * \brief If Jacobian matrix recycling is enabled, this method - * specifies whether the next call to assemble() just - * rescales the storage term or does a full reassembly - * - * \param yesno If true, only rescale; else do full Jacobian assembly. - */ - void setMatrixReuseable(const bool yesno = true) - { - if (enableJacobianRecycling_()) - reuseMatrix_ = yesno; - } - - /*! - * \brief If partial Jacobian matrix reassembly is enabled, this - * method causes all elements to be reassembled in the next - * assemble() call. - */ - void reassembleAll() - { - // do not reuse the current linearization - reuseMatrix_ = false; - - // do not use partial reassembly for the next iteration - nextReassembleAccuracy_ = 0.0; - if (enablePartialReassemble_()) { - std::fill(vertexColor_.begin(), - vertexColor_.end(), - Red); - std::fill(elementColor_.begin(), - elementColor_.end(), - Red); - std::fill(vertexDelta_.begin(), - vertexDelta_.end(), - 0.0); - } - } - - /*! - * \brief Returns the largest relative error of a "green" vertex - * for the most recent call of the assemble() method. - * - * This only has an effect if partial Jacobian reassembly is - * enabled. If it is disabled, then this method always returns 0. - * - * This returns the _actual_ relative computed seen by - * computeColors(), not the tolerance which it was given. - */ - Scalar reassembleAccuracy() const - { return reassembleAccuracy_; } - - /*! - * \brief Update the distance where the non-linear system was - * originally insistently linearized and the point where it - * will be linerized the next time. - * - * This only has an effect if partial reassemble is enabled. - */ - void updateDiscrepancy(const SolutionVector &u, - const SolutionVector &uDelta) - { - if (!enablePartialReassemble_()) - return; - - // update the vector with the distances of the current - // evaluation point used for linearization from the original - // evaluation point - for (unsigned int i = 0; i < vertexDelta_.size(); ++i) { - PrimaryVariables currentPriVars(u[i]); - PrimaryVariables nextPriVars(currentPriVars); - nextPriVars -= uDelta[i]; - - // we need to add the distance the solution was moved for - // this vertex - Scalar dist = model_().relativeErrorVertex(i, - currentPriVars, - nextPriVars); - vertexDelta_[i] += std::abs(dist); - } - - } - - /*! - * \brief Force to reassemble a given vertex next time the - * assemble() method is called. - * - * \param globalVertIdx The global index of the vertex which ought - * to be red. - */ - void markVertexRed(const int globalVertIdx) - { - if (!enablePartialReassemble_()) - return; - - vertexColor_[globalVertIdx] = Red; - } - - /*! - * \brief Determine the colors of vertices and elements for partial - * reassembly given a relative tolerance. - * - * The following approach is used: - * - * - Set all vertices and elements to 'green' - * - Mark all vertices as 'red' which exhibit an relative error above - * the tolerance - * - Mark all elements which feature a 'red' vetex as 'red' - * - Mark all vertices which are not 'red' and are part of a - * 'red' element as 'yellow' - * - Mark all elements which are not 'red' and contain a - * 'yellow' vertex as 'yellow' - * - * \param relTol The relative error below which a vertex won't be - * reassembled. Note that this specifies the - * worst-case relative error between the last - * linearization point and the current solution and - * _not_ the delta vector of the Newton iteration! - */ - void computeColors(const Scalar relTol) - { - if (!enablePartialReassemble_()) - return; - - ElementIterator elemIt = gridView_().template begin<0>(); - ElementIterator elemEndIt = gridView_().template end<0>(); - - // mark the red vertices and update the tolerance of the - // linearization which actually will get achieved - nextReassembleAccuracy_ = 0; - for (unsigned int i = 0; i < vertexColor_.size(); ++i) { - if (vertexDelta_[i] > relTol) - // mark vertex as red if discrepancy is larger than - // the relative tolerance - vertexColor_[i] = Red; - else - nextReassembleAccuracy_ = - std::max(nextReassembleAccuracy_, vertexDelta_[i]); - } - - // Mark all red elements - for (; elemIt != elemEndIt; ++elemIt) { - // find out whether the current element features a red - // vertex - bool isRed = false; - int numVerts = elemIt->template count<dim>(); - for (int i=0; i < numVerts; ++i) { - int globalI = vertexMapper_().map(*elemIt, i, dim); - if (vertexColor_[globalI] == Red) { - isRed = true; - break; - } - } - - // if yes, the element color is also red, else it is not - // red, i.e. green for the mean time - int globalElemIdx = elementMapper_().map(*elemIt); - if (isRed) - elementColor_[globalElemIdx] = Red; - else - elementColor_[globalElemIdx] = Green; - } - - // Mark yellow vertices (as orange for the mean time) - elemIt = gridView_().template begin<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - int elemIdx = this->elementMapper_().map(*elemIt); - if (elementColor_[elemIdx] != Red) - continue; // non-red elements do not tint vertices - // yellow! - - int numVerts = elemIt->template count<dim>(); - for (int i=0; i < numVerts; ++i) { - int globalI = vertexMapper_().map(*elemIt, i, dim); - // if a vertex is already red, don't recolor it to - // yellow! - if (vertexColor_[globalI] != Red) { - vertexColor_[globalI] = Orange; - } - } - } - - // at this point we communicate the yellow vertices to the - // neighboring processes because a neigbor process may not see - // the red vertex for yellow border vertices - VertexHandleMin<EntityColor, std::vector<EntityColor>, VertexMapper> - minHandle(vertexColor_, vertexMapper_()); - gridView_().communicate(minHandle, - Dune::InteriorBorder_InteriorBorder_Interface, - Dune::ForwardCommunication); - - // Mark yellow elements - elemIt = gridView_().template begin<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - int elemIdx = this->elementMapper_().map(*elemIt); - if (elementColor_[elemIdx] == Red) { - continue; // element is red already! - } - - // check whether the element features a yellow - // (resp. orange at this point) vertex - bool isYellow = false; - int numVerts = elemIt->template count<dim>(); - for (int i=0; i < numVerts; ++i) { - int globalI = vertexMapper_().map(*elemIt, i, dim); - if (vertexColor_[globalI] == Orange) { - isYellow = true; - break; - } - } - - if (isYellow) - elementColor_[elemIdx] = Yellow; - } - - // Demote orange vertices to yellow ones if it has at least - // one green element as a neighbor. - elemIt = gridView_().template begin<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - int elemIdx = this->elementMapper_().map(*elemIt); - if (elementColor_[elemIdx] != Green) - continue; // yellow and red elements do not make - // orange vertices yellow! - - int numVerts = elemIt->template count<dim>(); - for (int i=0; i < numVerts; ++i) { - int globalI = vertexMapper_().map(*elemIt, i, dim); - // if a vertex is orange, recolor it to yellow! - if (vertexColor_[globalI] == Orange) - vertexColor_[globalI] = Yellow; - } - } - - // demote the border orange vertices - VertexHandleMax<EntityColor, std::vector<EntityColor>, VertexMapper> - maxHandle(vertexColor_, - vertexMapper_()); - gridView_().communicate(maxHandle, - Dune::InteriorBorder_InteriorBorder_Interface, - Dune::ForwardCommunication); - - // promote the remaining orange vertices to red - for (unsigned int i=0; i < vertexColor_.size(); ++i) { - // if a vertex is green or yellow don't do anything! - if (vertexColor_[i] == Green || vertexColor_[i] == Yellow) - continue; - - // make sure the vertex is red (this is a no-op vertices - // which are already red!) - vertexColor_[i] = Red; - - // set the error of this vertex to 0 because the system - // will be consistently linearized at this vertex - vertexDelta_[i] = 0.0; - } - } - - /*! - * \brief Returns the reassemble color of a vertex - * - * \param element An element which contains the vertex - * \param vertIdx The local index of the vertex in the element. - */ - int vertexColor(const Element &element, const int vertIdx) const - { - if (!enablePartialReassemble_()) - return Red; // reassemble unconditionally! - - int globalIdx = vertexMapper_().map(element, vertIdx, dim); - return vertexColor_[globalIdx]; - } - - /*! - * \brief Returns the reassemble color of a vertex - * - * \param globalVertIdx The global index of the vertex. - */ - int vertexColor(const int globalVertIdx) const - { - if (!enablePartialReassemble_()) - return Red; // reassemble unconditionally! - return vertexColor_[globalVertIdx]; - } - - /*! - * \brief Returns the Jacobian reassemble color of an element - * - * \param element The Codim-0 DUNE entity - */ - int elementColor(const Element &element) const - { - if (!enablePartialReassemble_()) - return Red; // reassemble unconditionally! - - int globalIdx = elementMapper_().map(element); - return elementColor_[globalIdx]; - } - - /*! - * \brief Returns the Jacobian reassemble color of an element - * - * \param globalElementIdx The global index of the element. - */ - int elementColor(const int globalElementIdx) const - { - if (!enablePartialReassemble_()) - return Red; // reassemble unconditionally! - return elementColor_[globalElementIdx]; - } - - /*! - * \brief Return constant reference to global Jacobian matrix. - */ - const JacobianMatrix& matrix() const - { return *matrix_; } - JacobianMatrix& matrix() - { return *matrix_; } - - /*! - * \brief Return constant reference to global residual vector. - */ - const SolutionVector& residual() const - { return residual_; } - SolutionVector& residual() - { return residual_; } - -private: - static bool enableJacobianRecycling_() - { return GET_PARAM_FROM_GROUP(TypeTag, bool, Implicit, EnableJacobianRecycling); } - static bool enablePartialReassemble_() - { return GET_PARAM_FROM_GROUP(TypeTag, bool, Implicit, EnablePartialReassemble); } - - // Construct the BCRS matrix for the global jacobian - void createMatrix_() - { - int numVerticesGlobal = gridView_().size(dim); - - // allocate raw matrix - matrix_ = new JacobianMatrix(numVerticesGlobal, numVerticesGlobal, JacobianMatrix::random); - - // find out the global indices of the neighboring vertices of - // each vertex - typedef std::set<int> NeighborSet; - std::vector<NeighborSet> neighbors(numVerticesGlobal); - ElementIterator eIt = gridView_().template begin<0>(); - const ElementIterator eEndIt = gridView_().template end<0>(); - for (; eIt != eEndIt; ++eIt) { - const Element &elem = *eIt; - int numVerticesLocal = elem.template count<dim>(); - - // if the element is not in the interior or the process - // border, all dofs just contain main-diagonal entries - if (elem.partitionType() != Dune::InteriorEntity && - elem.partitionType() != Dune::BorderEntity) - { - for (int i = 0; i < numVerticesLocal; ++i) { - int globalI = vertexMapper_().map(*eIt, i, dim); - neighbors[globalI].insert(globalI); - } - } - else - { - // loop over all element vertices - for (int i = 0; i < numVerticesLocal - 1; ++i) { - int globalI = vertexMapper_().map(*eIt, i, dim); - for (int j = i + 1; j < numVerticesLocal; ++j) { - int globalJ = vertexMapper_().map(*eIt, j, dim); - // make sure that vertex j is in the neighbor set - // of vertex i and vice-versa - neighbors[globalI].insert(globalJ); - neighbors[globalJ].insert(globalI); - } - } - } - } - - // make vertices neighbors to themselfs - for (int i = 0; i < numVerticesGlobal; ++i) { - neighbors[i].insert(i); - } - - // allocate space for the rows of the matrix - for (int i = 0; i < numVerticesGlobal; ++i) { - matrix_->setrowsize(i, neighbors[i].size()); - } - matrix_->endrowsizes(); - - // fill the rows with indices. each vertex talks to all of its - // neighbors. (it also talks to itself since vertices are - // sometimes quite egocentric.) - for (int i = 0; i < numVerticesGlobal; ++i) { - typename NeighborSet::iterator nIt = neighbors[i].begin(); - typename NeighborSet::iterator nEndIt = neighbors[i].end(); - for (; nIt != nEndIt; ++nIt) { - matrix_->addindex(i, *nIt); - } - } - matrix_->endindices(); - } - - // reset the global linear system of equations. if partial - // reassemble is enabled, this means that the jacobian matrix must - // only be erased partially! - void resetSystem_() - { - // do not do anything if we can re-use the current linearization - if (reuseMatrix_) - return; - - // reset the right hand side. - residual_ = 0.0; - - if (!enablePartialReassemble_()) { - // If partial reassembly of the jacobian is not enabled, - // we can just reset everything! - (*matrix_) = 0; - - // reset the parts needed for Jacobian recycling - if (enableJacobianRecycling_()) { - int numVerticesGlobal = matrix_->N(); - for (int i=0; i < numVerticesGlobal; ++ i) { - storageJacobian_[i] = 0; - storageTerm_[i] = 0; - } - } - - return; - } - - // reset all entries corrosponding to a red or yellow vertex - for (unsigned int rowIdx = 0; rowIdx < matrix_->N(); ++rowIdx) { - if (vertexColor_[rowIdx] == Green) - continue; // the equations for this control volume are - // already below the treshold - - // here we have yellow or red vertices... - - // reset the parts needed for Jacobian recycling - if (enableJacobianRecycling_()) { - storageJacobian_[rowIdx] = 0; - storageTerm_[rowIdx] = 0; - } - - // set all matrix entries in the row to 0 - typedef typename JacobianMatrix::ColIterator ColIterator; - ColIterator colIt = (*matrix_)[rowIdx].begin(); - const ColIterator &colEndIt = (*matrix_)[rowIdx].end(); - for (; colIt != colEndIt; ++colIt) { - (*colIt) = 0.0; - } - } - } - - // linearize the whole system - void assemble_() - { - resetSystem_(); - - // if we can "recycle" the current linearization, we do it - // here and be done with it... - Scalar curDt = problem_().timeManager().timeStepSize(); - if (reuseMatrix_) { - int numVerticesGlobal = storageJacobian_.size(); - for (int i = 0; i < numVerticesGlobal; ++i) { - // rescale the mass term of the jacobian matrix - MatrixBlock &J_i_i = (*matrix_)[i][i]; - - J_i_i -= storageJacobian_[i]; - storageJacobian_[i] *= oldDt_/curDt; - J_i_i += storageJacobian_[i]; - - // use the flux term plus the source term as the new - // residual (since the delta in the d(storage)/dt is 0 - // for the first iteration and the residual is - // approximately 0 in the last iteration, the flux - // term plus the source term must be equal to the - // negative change of the storage term of the last - // iteration of the last time step...) - residual_[i] = storageTerm_[i]; - residual_[i] *= -1; - } - - reuseMatrix_ = false; - oldDt_ = curDt; - return; - } - - oldDt_ = curDt; - greenElems_ = 0; - - // reassemble the elements... - ElementIterator elemIt = gridView_().template begin<0>(); - ElementIterator elemEndIt = gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - const Element &elem = *elemIt; - if (elem.partitionType() != Dune::InteriorEntity && - elem.partitionType() != Dune::BorderEntity) - { - assembleGhostElement_(elem); - } - else - { - assembleElement_(elem); - } - } - } - - // assemble a non-ghost element - void assembleElement_(const Element &elem) - { - if (enablePartialReassemble_()) { - int globalElemIdx = model_().elementMapper().map(elem); - if (elementColor_[globalElemIdx] == Green) { - ++greenElems_; - - assembleGreenElement_(elem); - return; - } - } - - model_().localJacobian().assemble(elem); - - int numVerticesLocal = elem.template count<dim>(); - for (int i=0; i < numVerticesLocal; ++ i) { - int globI = vertexMapper_().map(elem, i, dim); - - // update the right hand side - residual_[globI] += model_().localJacobian().residual(i); - for (int j = 0; j < residual_[globI].dimension; ++j) - assert(std::isfinite(residual_[globI][j])); - if (enableJacobianRecycling_()) { - storageTerm_[globI] += - model_().localJacobian().storageTerm(i); - } - - // only update the jacobian matrix for non-green vertices - if (vertexColor(globI) != Green) { - if (enableJacobianRecycling_()) - storageJacobian_[globI] += - model_().localJacobian().storageJacobian(i); - - // update the jacobian matrix - for (int j=0; j < numVerticesLocal; ++ j) { - int globJ = vertexMapper_().map(elem, j, dim); - (*matrix_)[globI][globJ] += - model_().localJacobian().mat(i,j); - } - } - } - } - - // "assemble" a green element. green elements only get the - // residual updated, but the jacobian is left alone... - void assembleGreenElement_(const Element &elem) - { - model_().localResidual().eval(elem); - - int numVerticesLocal = elem.template count<dim>(); - for (int i=0; i < numVerticesLocal; ++ i) { - int globI = vertexMapper_().map(elem, i, dim); - - // update the right hand side - residual_[globI] += model_().localResidual().residual(i); - if (enableJacobianRecycling_()) - storageTerm_[globI] += model_().localResidual().storageTerm(i); - } - } - - // "assemble" a ghost element - void assembleGhostElement_(const Element &elem) - { - int numVerticesLocal = elem.template count<dim>(); - for (int i=0; i < numVerticesLocal; ++i) { - const VertexPointer vp = elem.template subEntity<dim>(i); - - if (vp->partitionType() == Dune::InteriorEntity || - vp->partitionType() == Dune::BorderEntity) - { - // do not change the non-ghost vertices - continue; - } - - // set main diagonal entries for the vertex - int vIdx = vertexMapper_().map(*vp); - typedef typename JacobianMatrix::block_type BlockType; - BlockType &J = (*matrix_)[vIdx][vIdx]; - for (int j = 0; j < BlockType::rows; ++j) - J[j][j] = 1.0; - - // set residual for the vertex - residual_[vIdx] = 0; - } - } - - - Problem &problem_() - { return *problemPtr_; } - const Problem &problem_() const - { return *problemPtr_; } - const Model &model_() const - { return problem_().model(); } - Model &model_() - { return problem_().model(); } - const GridView &gridView_() const - { return problem_().gridView(); } - const VertexMapper &vertexMapper_() const - { return problem_().vertexMapper(); } - const ElementMapper &elementMapper_() const - { return problem_().elementMapper(); } - - Problem *problemPtr_; - - // the jacobian matrix - JacobianMatrix *matrix_; - // the right-hand side - SolutionVector residual_; - - // attributes required for jacobian matrix recycling - bool reuseMatrix_; - // The storage part of the local Jacobian - std::vector<MatrixBlock> storageJacobian_; - std::vector<VectorBlock> storageTerm_; - // time step size of last assembly - Scalar oldDt_; - - - // attributes required for partial jacobian reassembly - std::vector<EntityColor> vertexColor_; - std::vector<EntityColor> elementColor_; - std::vector<Scalar> vertexDelta_; - - int totalElems_; - int greenElems_; - - Scalar nextReassembleAccuracy_; - Scalar reassembleAccuracy_; -}; - -} // namespace Dumux - -#endif +#include <dumux/implicit/box/boxassembler.hh> diff --git a/dumux/boxmodels/common/boxdarcyfluxvariables.hh b/dumux/boxmodels/common/boxdarcyfluxvariables.hh index 6e5d3df449f65a22a12966497c6a5a2c0a6e800c..953d7a3b62db147c1499a5cbfd613ff4ef0848a8 100644 --- a/dumux/boxmodels/common/boxdarcyfluxvariables.hh +++ b/dumux/boxmodels/common/boxdarcyfluxvariables.hh @@ -1,313 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes of fluid phases over a face of a finite volume. - * - * This means pressure and temperature gradients, phase densities at - * the integration point, etc. - */ -#ifndef DUMUX_BOX_DARCY_FLUX_VARIABLES_HH -#define DUMUX_BOX_DARCY_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/box/boxdarcyfluxvariables.hh instead. -#include "boxproperties.hh" - -#include <dumux/common/parameters.hh> -#include <dumux/common/math.hh> - -namespace Dumux -{ - -namespace Properties -{ -// forward declaration of properties -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); -NEW_PROP_TAG(SpatialParams); -NEW_PROP_TAG(NumPhases); -NEW_PROP_TAG(ProblemEnableGravity); -} - -/*! - * \ingroup BoxModel - * \ingroup BoxFluxVariables - * \brief Evaluates the normal component of the Darcy velocity - * on a (sub)control volume face. - */ -template <class TypeTag> -class BoxDarcyFluxVariables -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { dim = GridView::dimension} ; - enum { dimWorld = GridView::dimensionworld} ; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases)} ; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldMatrix<Scalar, dimWorld, dimWorld> Tensor; - typedef Dune::FieldVector<Scalar, dimWorld> DimVector; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - BoxDarcyFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : fvGeometry_(fvGeometry), faceIdx_(faceIdx), onBoundary_(onBoundary) - { - mobilityUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MobilityUpwindWeight); - calculateGradients_(problem, element, elemVolVars); - calculateNormalVelocity_(problem, element, elemVolVars); - } - -public: - /*! - * \brief Return the volumetric flux over a face of a given phase. - * - * This is the calculated velocity multiplied by the unit normal - * and the area of the face. - * face().normal - * has already the magnitude of the area. - * - * \param phaseIdx index of the phase - */ - Scalar volumeFlux(const unsigned int phaseIdx) const - { return volumeFlux_[phaseIdx]; } - - /*! - * \brief Return the velocity of a given phase. - * - * This is the full velocity vector on the - * face (without being multiplied with normal). - * - * \param phaseIdx index of the phase - */ - DimVector velocity(const unsigned int phaseIdx) const - { return velocity_[phaseIdx] ; } - - /*! - * \brief Return intrinsic permeability multiplied with potential - * gradient multiplied with normal. - * I.e. everything that does not need upwind decisions. - * - * \param phaseIdx index of the phase - */ - Scalar kGradPNormal(const unsigned int phaseIdx) const - { return kGradPNormal_[phaseIdx] ; } - - /*! - * \brief Return the local index of the downstream control volume - * for a given phase. - * - * \param phaseIdx index of the phase - */ - const unsigned int downstreamIdx(const unsigned phaseIdx) const - { return downstreamIdx_[phaseIdx]; } - - /*! - * \brief Return the local index of the upstream control volume - * for a given phase. - * - * \param phaseIdx index of the phase - */ - const unsigned int upstreamIdx(const unsigned phaseIdx) const - { return upstreamIdx_[phaseIdx]; } - - /*! - * \brief Return the SCV (sub-control-volume) face. This may be either - * a face within the element or a face on the element boundary, - * depending on the value of onBoundary_. - */ - const SCVFace &face() const - { - if (onBoundary_) - return fvGeometry_.boundaryFace[faceIdx_]; - else - return fvGeometry_.subContVolFace[faceIdx_]; - } - -protected: - const FVElementGeometry &fvGeometry_; //!< Information about the geometry of discretization - const unsigned int faceIdx_; //!< The index of the sub control volume face - const bool onBoundary_; //!< Specifying whether we are currently on the boundary of the simulation domain - unsigned int upstreamIdx_[numPhases] , downstreamIdx_[numPhases]; //!< local index of the upstream / downstream vertex - Scalar volumeFlux_[numPhases] ; //!< Velocity multiplied with normal (magnitude=area) - DimVector velocity_[numPhases] ; //!< The velocity as determined by Darcy's law or by the Forchheimer relation - Scalar kGradPNormal_[numPhases] ; //!< Permeability multiplied with gradient in potential, multiplied with normal (magnitude=area) - DimVector kGradP_[numPhases] ; //!< Permeability multiplied with gradient in potential - DimVector gradPotential_[numPhases] ; //!< Gradient of potential, which drives flow - Scalar mobilityUpwindWeight_; //!< Upwind weight for mobility. Set to one for full upstream weighting - - /* - * \brief Calculation of the potential gradients - * - * \param problem The problem - * \param element The finite element - * \param elemVolVars The volume variables of the current element - * are calculated for interior SCV faces or boundary faces, default=false - */ - void calculateGradients_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // loop over all phases - for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++) - { - gradPotential_[phaseIdx]= 0.0 ; - for (int idx = 0; - idx < fvGeometry_.numFAP; - idx++) // loop over adjacent vertices - { - // FE gradient at vertex idx - const DimVector &feGrad = face().grad[idx]; - - // index for the element volume variables - int volVarsIdx = face().fapIndices[idx]; - - // the pressure gradient - DimVector tmp(feGrad); - tmp *= elemVolVars[volVarsIdx].fluidState().pressure(phaseIdx); - gradPotential_[phaseIdx] += tmp; - } - - // correct the pressure gradient by the gravitational acceleration - if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, EnableGravity)) - { - // estimate the gravitational acceleration at a given SCV face - // using the arithmetic mean - DimVector g(problem.boxGravity(element, fvGeometry_, face().i)); - g += problem.boxGravity(element, fvGeometry_, face().j); - g /= 2; - - // calculate the phase density at the integration point. we - // only do this if the wetting phase is present in both cells - Scalar SI = elemVolVars[face().i].fluidState().saturation(phaseIdx); - Scalar SJ = elemVolVars[face().j].fluidState().saturation(phaseIdx); - Scalar rhoI = elemVolVars[face().i].fluidState().density(phaseIdx); - Scalar rhoJ = elemVolVars[face().j].fluidState().density(phaseIdx); - Scalar fI = std::max(0.0, std::min(SI/1e-5, 0.5)); - Scalar fJ = std::max(0.0, std::min(SJ/1e-5, 0.5)); - if (fI + fJ == 0) - // doesn't matter because no wetting phase is present in - // both cells! - fI = fJ = 0.5; - const Scalar density = (fI*rhoI + fJ*rhoJ)/(fI + fJ); - - // make gravity acceleration a force - DimVector f(g); - f *= density; - - // calculate the final potential gradient - gradPotential_[phaseIdx] -= f; - } // gravity - } // loop over all phases - } - - /* - * \brief Actual calculation of the normal Darcy velocities. - * - * \param problem The problem - * \param element The finite element - * \param elemVolVars The volume variables of the current element - */ - void calculateNormalVelocity_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // calculate the mean intrinsic permeability - const SpatialParams &spatialParams = problem.spatialParams(); - Tensor K; - spatialParams.meanK(K, - spatialParams.intrinsicPermeability(element, - fvGeometry_, - face().i), - spatialParams.intrinsicPermeability(element, - fvGeometry_, - face().j)); - // loop over all phases - for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++) - { - // calculate the flux in the normal direction of the - // current sub control volume face: - // - // v = - (K_f grad phi) * n - // with K_f = rho g / mu K - // - // Mind, that the normal has the length of it's area. - // This means that we are actually calculating - // Q = - (K grad phi) dot n /|n| * A - - - K.mv(gradPotential_[phaseIdx], kGradP_[phaseIdx]); - kGradPNormal_[phaseIdx] = kGradP_[phaseIdx]*face().normal; - - // determine the upwind direction - if (kGradPNormal_[phaseIdx] < 0) - { - upstreamIdx_[phaseIdx] = face().i; - downstreamIdx_[phaseIdx] = face().j; - } - else - { - upstreamIdx_[phaseIdx] = face().j; - downstreamIdx_[phaseIdx] = face().i; - } - - // obtain the upwind volume variables - const VolumeVariables& upVolVars = elemVolVars[ upstreamIdx(phaseIdx) ]; - const VolumeVariables& downVolVars = elemVolVars[ downstreamIdx(phaseIdx) ]; - - // the minus comes from the Darcy relation which states that - // the flux is from high to low potentials. - // set the velocity - velocity_[phaseIdx] = kGradP_[phaseIdx]; - velocity_[phaseIdx] *= - ( mobilityUpwindWeight_*upVolVars.mobility(phaseIdx) - + (1.0 - mobilityUpwindWeight_)*downVolVars.mobility(phaseIdx)) ; - - // set the volume flux - volumeFlux_[phaseIdx] = velocity_[phaseIdx] * face().normal ; - }// loop all phases - } -}; - -} // end namespace - -#endif +#include <dumux/implicit/box/boxdarcyfluxvariables.hh> diff --git a/dumux/boxmodels/common/boxelementboundarytypes.hh b/dumux/boxmodels/common/boxelementboundarytypes.hh index fe7e02a09ce90f0c40ed2a1b37d71bef74c8de5b..ab2a07ecc6a2d53157ac89e15da68dadd9bd42ab 100644 --- a/dumux/boxmodels/common/boxelementboundarytypes.hh +++ b/dumux/boxmodels/common/boxelementboundarytypes.hh @@ -1,148 +1,3 @@ -// -*- 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 Boundary types gathered on an element - */ -#ifndef DUMUX_BOX_ELEMENT_BOUNDARY_TYPES_HH -#define DUMUX_BOX_ELEMENT_BOUNDARY_TYPES_HH +#warning This file is deprecated. Include dumux/implicit/box/boxelementboundarytypes.hh instead. -#include "boxproperties.hh" - -#include <dumux/common/valgrind.hh> - -namespace Dumux -{ - -/*! - * \ingroup BoxModel - * \ingroup BoxBoundaryTypes - * - * \brief This class stores an array of BoundaryTypes objects - */ -template<class TypeTag> -class BoxElementBoundaryTypes : public std::vector<typename GET_PROP_TYPE(TypeTag, BoundaryTypes) > -{ - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef std::vector<BoundaryTypes> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - - enum { dim = GridView::dimension }; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<dim>::EntityPointer VertexPointer; - -public: - /*! - * \brief Copy constructor. - * - * Copying a the boundary types of an element should be explicitly - * requested - */ - explicit BoxElementBoundaryTypes(const BoxElementBoundaryTypes &v) - : ParentType(v) - {} - - /*! - * \brief Default constructor. - */ - BoxElementBoundaryTypes() - { - hasDirichlet_ = false; - hasNeumann_ = false; - hasOutflow_ = false; - } - - /*! - * \brief Update the boundary types for all vertices of an element. - * - * \param problem The problem object which needs to be simulated - * \param element The DUNE Codim<0> entity for which the boundary - * types should be collected - */ - void update(const Problem &problem, - const Element &element) - { - int numVerts = element.template count<dim>(); - this->resize(numVerts); - - hasDirichlet_ = false; - hasNeumann_ = false; - hasOutflow_ = false; - - for (int i = 0; i < numVerts; ++i) { - (*this)[i].reset(); - - if (problem.model().onBoundary(element, i)) { - const VertexPointer vptr = element.template subEntity<dim>(i); - problem.boundaryTypes((*this)[i], *vptr); - - hasDirichlet_ = hasDirichlet_ || (*this)[i].hasDirichlet(); - hasNeumann_ = hasNeumann_ || (*this)[i].hasNeumann(); - hasOutflow_ = hasOutflow_ || (*this)[i].hasOutflow(); - } - } - } - - /*! - * \brief Update the boundary types for all vertices of an element. - * - * \param problem The problem object which needs to be simulated - * \param element The DUNE Codim<0> entity for which the boundary - * types should be collected - * \param fvGeometry The element's finite volume geometry - */ - void update(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry) - { update(problem, element); } - - /*! - * \brief Returns whether the element has a vertex which contains - * a Dirichlet value. - */ - bool hasDirichlet() const - { return hasDirichlet_; } - - /*! - * \brief Returns whether the element potentially features a - * Neumann boundary segment. - */ - bool hasNeumann() const - { return hasNeumann_; } - - /*! - * \brief Returns whether the element potentially features an - * outflow boundary segment. - */ - bool hasOutflow() const - { return hasOutflow_; } - -protected: - bool hasDirichlet_; - bool hasNeumann_; - bool hasOutflow_; -}; - -} // namespace Dumux - -#endif +#include <dumux/implicit/box/boxelementboundarytypes.hh> diff --git a/dumux/boxmodels/common/boxelementvolumevariables.hh b/dumux/boxmodels/common/boxelementvolumevariables.hh index c791bee09bb4a4da9a6e051fd86f9e09e22ba811..c4568652b87dcce79a52840e8d94e0830f14467f 100644 --- a/dumux/boxmodels/common/boxelementvolumevariables.hh +++ b/dumux/boxmodels/common/boxelementvolumevariables.hh @@ -1,138 +1,3 @@ -// -*- 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 Volume variables gathered on an element - */ -#ifndef DUMUX_BOX_ELEMENT_VOLUME_VARIABLES_HH -#define DUMUX_BOX_ELEMENT_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/box/boxelementvolumevariables.hh instead. -#include "boxproperties.hh" - - -namespace Dumux -{ - -/*! - * \ingroup BoxModel - * - * \brief This class stores an array of VolumeVariables objects, one - * volume variables object for each of the element's vertices - */ -template<class TypeTag> -class BoxElementVolumeVariables : public std::vector<typename GET_PROP_TYPE(TypeTag, VolumeVariables) > -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { dim = GridView::dimension }; - enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) }; - -public: - /*! - * \brief The constructor. - */ - BoxElementVolumeVariables() - { } - - /*! - * \brief Construct the volume variables for all of vertices of an element. - * - * \param problem The problem which needs to be simulated. - * \param element The DUNE Codim<0> entity for which the volume variables ought to be calculated - * \param fvGeometry The finite volume geometry of the element - * \param oldSol Tells whether the model's previous or current solution should be used. - */ - void update(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const bool oldSol) - { - const SolutionVector &globalSol = - oldSol? - problem.model().prevSol(): - problem.model().curSol(); - const VertexMapper &vertexMapper = problem.vertexMapper(); - // we assert that the i-th shape function is - // associated to the i-th vert of the element. - int numVertices = element.template count<dim>(); - this->resize(numVertices); - for (int scvIdx = 0; scvIdx < numVertices; scvIdx++) { - const PrimaryVariables &priVars - = globalSol[vertexMapper.map(element, scvIdx, dim)]; - - // reset evaluation point to zero - (*this)[scvIdx].setEvalPoint(0); - - (*this)[scvIdx].update(priVars, - problem, - element, - fvGeometry, - scvIdx, - oldSol); - } - } - - /*! - * \brief Construct the volume variables for all of vertices of an - * element given a solution vector computed by PDELab. - * - * \tparam ElementSolutionVector The container type which stores the - * primary variables of the element - * using _local_ indices - * - * \param problem The problem which needs to be simulated. - * \param element The DUNE Codim<0> entity for which the volume variables ought to be calculated - * \param fvGeometry The finite volume geometry of the element - * \param elementSolVector The local solution for the element using PDELab ordering - */ - template<typename ElementSolutionVector> - void updatePDELab(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const ElementSolutionVector& elementSolVector) - { - int numVertices = element.template count<dim>(); - this->resize(numVertices); - for (int scvIdx = 0; scvIdx < numVertices; scvIdx++) - { - PrimaryVariables priVars(0); - for (int eqnIdx = 0; eqnIdx < numEq; eqnIdx++) - priVars[eqnIdx] = elementSolVector[scvIdx + eqnIdx*numVertices]; - (*this)[scvIdx].update(priVars, - problem, - element, - fvGeometry, - scvIdx, - false); - - } - } -}; - -} // namespace Dumux - -#endif +#include <dumux/implicit/box/boxelementvolumevariables.hh> diff --git a/dumux/boxmodels/common/boxforchheimerfluxvariables.hh b/dumux/boxmodels/common/boxforchheimerfluxvariables.hh index e7f7e3bf32bf8ee2093a7f34a03caa935562e82c..186d17e2c90598e68cf1c48c091540469b4eefea 100644 --- a/dumux/boxmodels/common/boxforchheimerfluxvariables.hh +++ b/dumux/boxmodels/common/boxforchheimerfluxvariables.hh @@ -1,358 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes of fluid phases over a face of a finite volume, - * according to the Forchheimer-relation between velocity and pressure. - * - */ -#ifndef DUMUX_BOX_FORCHHEIMER_FLUX_VARIABLES_HH -#define DUMUX_BOX_FORCHHEIMER_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/box/boxforchheimerfluxvariables.hh instead. -#include "boxproperties.hh" - -#include <dumux/common/parameters.hh> -#include <dumux/common/math.hh> -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> - -namespace Dumux -{ - -namespace Properties -{ -// forward declaration of properties -NEW_PROP_TAG(MobilityUpwindWeight); -NEW_PROP_TAG(SpatialParams); -NEW_PROP_TAG(NumPhases); -NEW_PROP_TAG(ProblemEnableGravity); -} - -/*! - * \ingroup BoxModel - * \ingroup BoxFluxVariables - * \brief Evaluates the normal component of the Forchheimer velocity - * on a (sub)control volume face. - * - * The commonly used Darcy relation looses it's validity for \f$ Re < 1\f$. - * If one encounters flow velocities in porous media above this Reynolds number, - * the Forchheimer relation can be used. Like the Darcy relation, it relates - * the gradient in potential to velocity. - * However, this relation is not linear (as in the Darcy case) any more. - * - * Therefore, a Newton scheme is implemented in this class in order to calculate a - * velocity from the current set of variables. This velocity can subsequently be used - * e.g. by the localresidual. - * - * For Reynolds numbers above \f$ 500\f$ the (Standard) forchheimer relation also - * looses it's validity. - * - * The Forchheimer equation looks as follows: - * \f[ \nabla \left({p_\alpha + \rho_\alpha g z} \right)= - \frac{\mu_\alpha}{k_{r \alpha} K} \underline{v_\alpha} - \frac{c_F}{\eta_{\alpha r} \sqrt{K}} \rho_\alpha |\underline{v_\alpha}| \underline{v_\alpha} \f] - * - * For the formulation that is actually used in this class, see the documentation of the function calculating the residual. - * - * - This algorithm does not find a solution if the fluid is incompressible and the - * initial pressure distribution is uniform. - * - This algorithm assumes the relative passabilities to have the same functional - * form as the relative permeabilities. - */ -template <class TypeTag> -class BoxForchheimerFluxVariables - : public BoxDarcyFluxVariables<TypeTag> -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { dim = GridView::dimension} ; - enum { dimWorld = GridView::dimensionworld} ; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases)} ; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldMatrix<Scalar, dimWorld, dimWorld> Tensor; - typedef Dune::FieldVector<Scalar, dimWorld> DimVector; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - /*! - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - BoxForchheimerFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : BoxDarcyFluxVariables<TypeTag>(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary) - { - calculateNormalVelocity_(problem, element, elemVolVars); - } - -protected: - /*! - * \brief Function for calculation of velocities. - * - * \param problem The problem - * \param element The finite element - * \param elemVolVars The volume variables of the current element - */ - void calculateNormalVelocity_(const Problem &problem, - const Element &element, - const ElementVolumeVariables &elemVolVars) - { - // calculate the mean intrinsic permeability - const SpatialParams &spatialParams = problem.spatialParams(); - Tensor K; - spatialParams.meanK(K, - spatialParams.intrinsicPermeability(element, - this->fvGeometry_, - this->face().i), - spatialParams.intrinsicPermeability(element, - this->fvGeometry_, - this->face().j)); - - // obtain the Forchheimer coefficient from the spatial parameters - const Scalar forchCoeff = spatialParams.forchCoeff(element, - this->fvGeometry_, - this->face().i); - - // Make sure the permeability matrix does not have off-diagonal entries - assert( isDiagonal_(K) ); - - Tensor sqrtK(0.0); - for (int i = 0; i < dim; ++i) - sqrtK[i][i] = std::sqrt(K[i][i]); - - // loop over all phases - for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++) - { - // initial guess of velocity: Darcy relation - // first taken from base class, later overwritten in base class - DimVector velocity = this-> velocity(phaseIdx); - - DimVector deltaV; // the change in velocity between Newton iterations - DimVector residual(10e10); // the residual (function value that is to be minimized ) of the equation that is to be fulfilled - DimVector tmp; // temporary variable for numerical differentiation - Tensor gradF; // slope of equation that is to be solved - - // search by means of the Newton method for a root of Forchheimer equation - for (int k = 0; residual.two_norm() > 1e-12 ; ++k) { - - if (k >= 30) - DUNE_THROW(NumericalProblem, "could not determine forchheimer velocity within "<< k <<" iterations"); - - // calculate current value of Forchheimer equation - forchheimerResidual_(residual, - forchCoeff, - sqrtK, - K, - velocity, - elemVolVars, - this->gradPotential_[phaseIdx], - phaseIdx); - - // newton's method: slope (gradF) and current value (residual) of function is known, - forchheimerDerivative_(gradF, - forchCoeff, - sqrtK, - velocity, - elemVolVars, - phaseIdx); - - // solve for change in velocity ("x-Axis intercept") - gradF.solve(deltaV, residual); - velocity -= deltaV; - } - - this->velocity_[phaseIdx] = velocity ; // store the converged velocity solution - this->volumeFlux_[phaseIdx] = velocity * this->face().normal; // velocity dot normal times cross sectional area is volume flux - }// end loop over all phases - } - - /*! \brief Function for calculation of Forchheimer relation. - * - * The relative passability \f$ \eta_r\f$ is the "Forchheimer-equivalent" to the relative permeability \f$ k_r\f$. - * We use the same function as for \f$ k_r \f$ (VG, BC, linear) other authors use a simple power law e.g.: \f$\eta_{rw} = S_w^3\f$ - * - * Some rearrangements have been made to the original Forchheimer relation: - * - * \f[ \underline{v_\alpha} + c_F \sqrt{K} \frac{\rho_\alpha}{\mu_\alpha } |\underline{v_\alpha}| \underline{v_\alpha} + \frac{k_{r \alpha}}{\mu_\alpha} K \nabla \left(p_\alpha + \rho_\alpha g z \right)= 0 \f] - * - * This already includes the assumption \f$ k_r(S_w) = \eta_r(S_w)\f$: - * - \f$\eta_{rw} = S_w^x\f$ looks very similar to e.g. Van Genuchten relative permeabilities - * - Fichot, et al. (2006), Nuclear Engineering and Design, state that several authors claim that \f$ k_r(S_w), \eta_r(S_w)\f$ can be chosen equal - * - It leads to the equation not degenerating for the case of \f$S_w=1\f$, because I do not need to multiply with two different functions, and therefore there are terms not being zero. - * - If this assumption is not to be made: Some regularization needs to be introduced ensuring that not all terms become zero for \f$S_w=1\f$. - * - * As long as the correct velocity is not found yet, the above equation is not fulfilled, but - * the left hand side yields some residual. This function calculates the left hand side of the - * equation and returns the residual. - * - * \param residual The current function value for the given velocity - * \param forchCoeff The Forchheimer coefficient - * \param sqrtK A diagonal matrix whose entries are square roots of the permeability matrix entries - * \param K The permeability matrix - * \param velocity The current velocity approximation. - * \param elemVolVars The volume variables of the current element - * \param gradPotential The gradient in potential - * \param phaseIdx The index of the currently considered phase - */ - void forchheimerResidual_(DimVector & residual, - const Scalar forchCoeff, - const Tensor & sqrtK, - const Tensor & K, - const DimVector & velocity, - const ElementVolumeVariables & elemVolVars, - const DimVector & gradPotential , - const unsigned int phaseIdx) const - { - const VolumeVariables upVolVars = elemVolVars[this->upstreamIdx(phaseIdx)]; - const VolumeVariables downVolVars = elemVolVars[this->downstreamIdx(phaseIdx)]; - - // Obtaining the physical quantities - const Scalar mobility = this->mobilityUpwindWeight_ * upVolVars.mobility(phaseIdx) - + (1.-this->mobilityUpwindWeight_)* downVolVars.mobility(phaseIdx) ; - - const Scalar viscosity = this->mobilityUpwindWeight_ * upVolVars.fluidState().viscosity(phaseIdx) - + (1.-this->mobilityUpwindWeight_)* downVolVars.fluidState().viscosity(phaseIdx) ; - - const Scalar density = this->mobilityUpwindWeight_ * upVolVars.fluidState().density(phaseIdx) - + (1.-this->mobilityUpwindWeight_) * downVolVars.fluidState().density(phaseIdx) ; - - // residual = v - residual = velocity; - - // residual += k_r/mu K grad p - K.usmv(mobility, gradPotential, residual); - - // residual += c_F rho / mu abs(v) sqrt(K) v - sqrtK.usmv(forchCoeff * density / viscosity * velocity.two_norm(), velocity, residual); - } - - - /*! \brief Function for calculation of the gradient of Forchheimer relation with respect to velocity. - * - * This function already exploits that \f$ \sqrt{K}\f$ is a diagonal matrix. Therefore, we only have - * to deal with the main entries. - * The gradient of the Forchheimer relations looks as follows (mind that \f$ \sqrt{K}\f$ is a tensor): - * - * \f[ f\left(\underline{v_\alpha}\right) = - * \left( - * \begin{array}{ccc} - * 1 & 0 &0 \\ - * 0 & 1 &0 \\ - * 0 & 0 &1 \\ - * \end{array} - * \right) - * + - * c_F \frac{\rho_\alpha}{\mu_\alpha} |\underline{v}_\alpha| \sqrt{K} - * + - * c_F \frac{\rho_\alpha}{\mu_\alpha}\frac{1}{|\underline{v}_\alpha|} \sqrt{K} - * \left( - * \begin{array}{ccc} - * v_x^2 & v_xv_y & v_xv_z \\ - * v_yv_x & v_{y}^2 & v_yv_z \\ - * v_zv_x & v_zv_y &v_{z}^2 \\ - * \end{array} - * \right) - * \f] - * - * \param derivative The gradient of the forchheimer equation - * \param forchCoeff Forchheimer coefficient - * \param sqrtK A diagonal matrix whose entries are square roots of the permeability matrix entries. - * \param velocity The current velocity approximation. - * \param elemVolVars The volume variables of the current element - * \param phaseIdx The index of the currently considered phase - */ - void forchheimerDerivative_(Tensor & derivative, - const Scalar forchCoeff, - const Tensor & sqrtK, - const DimVector & velocity, - const ElementVolumeVariables & elemVolVars, - const unsigned int phaseIdx) const - { - const VolumeVariables upVolVars = elemVolVars[this->upstreamIdx(phaseIdx)]; - const VolumeVariables downVolVars = elemVolVars[this->downstreamIdx(phaseIdx)]; - - // Obtaining the physical quantities - const Scalar viscosity = this->mobilityUpwindWeight_ * upVolVars.fluidState().viscosity(phaseIdx) - + (1.-this->mobilityUpwindWeight_)* downVolVars.fluidState().viscosity(phaseIdx) ; - - const Scalar density = this->mobilityUpwindWeight_ * upVolVars.fluidState().density(phaseIdx) - + (1.-this->mobilityUpwindWeight_) * downVolVars.fluidState().density(phaseIdx) ; - - // Initialize because for low velocities, we add and do not set the entries. - derivative = 0.; - - const Scalar absV = velocity.two_norm() ; - // This part of the derivative is only calculated if the velocity is sufficiently small: do not divide by zero! - // This should not be very bad because the derivative is only intended to give an approximation of the gradient of the - // function that goes into the Newton scheme. - // This is important in the case of a one-phase region in two-phase flow. The non-existing phase has a velocity of zero (kr=0). - // f = sqrtK * vTimesV (this is a matrix) - // f *= forchCoeff density / |velocity| / viscosity (multiply all entries with scalars) - if(absV > 1e-20) - for (int i=0; i<dim; i++) - for (int k=0; k<dim; k++) - derivative[i][k]= sqrtK[i][i] * velocity[i] * velocity[k] * forchCoeff * density / absV / viscosity; - - // add on the main diagonal: - // 1 + sqrtK_i forchCoeff density |v| / viscosity - for (int i=0; i<dim; i++) - derivative[i][i] += (1.0 + ( sqrtK[i][i]*forchCoeff * density * absV / viscosity ) ) ; - } - - /*! - * \brief Check whether all off-diagonal entries of a tensor are zero. - * - * \param K the tensor that is to be checked. - * - * \return True iff all off-diagonals are zero. - * - */ - const bool isDiagonal_(const Tensor & K) const - { - for (int i = 0; i < dim; i++) { - for (int k = 0; k < dim; k++) { - if ((i != k) && (std::abs(K[i][k]) >= 1e-25)) { - return false; - } - } - } - return true; - } -}; - -} // end namespace - -#endif +#include <dumux/implicit/box/boxforchheimerfluxvariables.hh> diff --git a/dumux/boxmodels/common/boxfvelementgeometry.hh b/dumux/boxmodels/common/boxfvelementgeometry.hh index fd0b5c89e2042c345529f0d9c7534e608d98aedf..7110d1c4bac09f796c9a259918cc97e6ee0def8c 100644 --- a/dumux/boxmodels/common/boxfvelementgeometry.hh +++ b/dumux/boxmodels/common/boxfvelementgeometry.hh @@ -1,933 +1,3 @@ -// -*- 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 Represents the finite volume geometry of a single element in - * the box scheme. - */ -#ifndef DUMUX_BOX_FV_ELEMENTGEOMETRY_HH -#define DUMUX_BOX_FV_ELEMENTGEOMETRY_HH - -#include <dune/common/version.hh> -#include <dune/geometry/referenceelements.hh> -#include <dune/grid/common/intersectioniterator.hh> -#include <dune/localfunctions/lagrange/pqkfactory.hh> - -#include <dumux/common/parameters.hh> -#include <dumux/common/propertysystem.hh> -#include "boxproperties.hh" - -namespace Dumux -{ -namespace Properties -{ -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(ImplicitUseTwoPointFlux); -} - -///////////////////// -// HACK: Functions to initialize the subcontrol volume data -// structures of BoxFVElementGeomerty. -// -// this is a work around to be able to to use specialization for -// doing this. it is required since it is not possible to -// specialize member functions of template classes because of some -// weird reason I didn't really get... - -//! \cond INTERNAL - -template <typename BoxFVElementGeometry, int dim> -class _BoxFVElemGeomHelper -{ -public: - static void fillSubContVolData(BoxFVElementGeometry &eg, int numVertices) - { - DUNE_THROW(Dune::NotImplemented, "_BoxFVElemGeomHelper::fillSubContVolData dim = " << dim); - } -}; - -template <typename BoxFVElementGeometry> -class _BoxFVElemGeomHelper<BoxFVElementGeometry, 1> -{ -public: - enum { dim = 1 }; - static void fillSubContVolData(BoxFVElementGeometry &eg, int numVertices) - { - // 1D - eg.subContVol[0].volume = 0.5*eg.elementVolume; - eg.subContVol[1].volume = 0.5*eg.elementVolume; - } -}; - -template <typename BoxFVElementGeometry> -class _BoxFVElemGeomHelper<BoxFVElementGeometry, 2> -{ -public: - enum { dim = 2 }; - - static void fillSubContVolData(BoxFVElementGeometry &eg, int numVertices) - { - switch (numVertices) { - case 3: // 2D, triangle - eg.subContVol[0].volume = eg.elementVolume/3; - eg.subContVol[1].volume = eg.elementVolume/3; - eg.subContVol[2].volume = eg.elementVolume/3; - break; - case 4: // 2D, quadrilinear - eg.subContVol[0].volume = eg.quadrilateralArea(eg.subContVol[0].global, eg.edgeCoord[2], eg.elementGlobal, eg.edgeCoord[0]); - eg.subContVol[1].volume = eg.quadrilateralArea(eg.subContVol[1].global, eg.edgeCoord[1], eg.elementGlobal, eg.edgeCoord[2]); - eg.subContVol[2].volume = eg.quadrilateralArea(eg.subContVol[2].global, eg.edgeCoord[0], eg.elementGlobal, eg.edgeCoord[3]); - eg.subContVol[3].volume = eg.quadrilateralArea(eg.subContVol[3].global, eg.edgeCoord[3], eg.elementGlobal, eg.edgeCoord[1]); - break; - default: - DUNE_THROW(Dune::NotImplemented, "_BoxFVElemGeomHelper::fillSubContVolData dim = " << dim << ", numVertices = " << numVertices); - } - } -}; - -template <typename BoxFVElementGeometry> -class _BoxFVElemGeomHelper<BoxFVElementGeometry, 3> -{ -public: - enum { dim = 3 }; - - static void fillSubContVolData(BoxFVElementGeometry &eg, int numVertices) - { - switch (numVertices) { - case 4: // 3D, tetrahedron - for (int k = 0; k < eg.numVertices; k++) - eg.subContVol[k].volume = eg.elementVolume / 4.0; - break; - case 5: // 3D, pyramid - eg.subContVol[0].volume = eg.hexahedronVolume(eg.subContVol[0].global, - eg.edgeCoord[2], - eg.faceCoord[0], - eg.edgeCoord[0], - eg.edgeCoord[4], - eg.faceCoord[3], - eg.elementGlobal, - eg.faceCoord[1]); - eg.subContVol[1].volume = eg.hexahedronVolume(eg.subContVol[1].global, - eg.edgeCoord[1], - eg.faceCoord[0], - eg.edgeCoord[2], - eg.edgeCoord[5], - eg.faceCoord[2], - eg.elementGlobal, - eg.faceCoord[3]); - eg.subContVol[2].volume = eg.hexahedronVolume(eg.subContVol[2].global, - eg.edgeCoord[0], - eg.faceCoord[0], - eg.edgeCoord[3], - eg.edgeCoord[6], - eg.faceCoord[1], - eg.elementGlobal, - eg.faceCoord[4]); - eg.subContVol[3].volume = eg.hexahedronVolume(eg.subContVol[3].global, - eg.edgeCoord[3], - eg.faceCoord[0], - eg.edgeCoord[1], - eg.edgeCoord[7], - eg.faceCoord[4], - eg.elementGlobal, - eg.faceCoord[2]); - eg.subContVol[4].volume = eg.elementVolume - - eg.subContVol[0].volume - - eg.subContVol[1].volume - - eg.subContVol[2].volume - - eg.subContVol[3].volume; - break; - case 6: // 3D, prism - eg.subContVol[0].volume = eg.hexahedronVolume(eg.subContVol[0].global, - eg.edgeCoord[3], - eg.faceCoord[3], - eg.edgeCoord[4], - eg.edgeCoord[0], - eg.faceCoord[0], - eg.elementGlobal, - eg.faceCoord[1]); - eg.subContVol[1].volume = eg.hexahedronVolume(eg.subContVol[1].global, - eg.edgeCoord[5], - eg.faceCoord[3], - eg.edgeCoord[3], - eg.edgeCoord[1], - eg.faceCoord[2], - eg.elementGlobal, - eg.faceCoord[0]); - eg.subContVol[2].volume = eg.hexahedronVolume(eg.subContVol[2].global, - eg.edgeCoord[4], - eg.faceCoord[3], - eg.edgeCoord[5], - eg.edgeCoord[2], - eg.faceCoord[1], - eg.elementGlobal, - eg.faceCoord[2]); - eg.subContVol[3].volume = eg.hexahedronVolume(eg.edgeCoord[0], - eg.faceCoord[0], - eg.elementGlobal, - eg.faceCoord[1], - eg.subContVol[3].global, - eg.edgeCoord[6], - eg.faceCoord[4], - eg.edgeCoord[7]); - eg.subContVol[4].volume = eg.hexahedronVolume(eg.edgeCoord[1], - eg.faceCoord[2], - eg.elementGlobal, - eg.faceCoord[0], - eg.subContVol[4].global, - eg.edgeCoord[8], - eg.faceCoord[4], - eg.edgeCoord[6]); - eg.subContVol[5].volume = eg.hexahedronVolume(eg.edgeCoord[2], - eg.faceCoord[1], - eg.elementGlobal, - eg.faceCoord[2], - eg.subContVol[5].global, - eg.edgeCoord[7], - eg.faceCoord[4], - eg.edgeCoord[8]); - break; - case 8: // 3D, hexahedron - eg.subContVol[0].volume = eg.hexahedronVolume(eg.subContVol[0].global, - eg.edgeCoord[6], - eg.faceCoord[4], - eg.edgeCoord[4], - eg.edgeCoord[0], - eg.faceCoord[2], - eg.elementGlobal, - eg.faceCoord[0]); - eg.subContVol[1].volume = eg.hexahedronVolume(eg.subContVol[1].global, - eg.edgeCoord[5], - eg.faceCoord[4], - eg.edgeCoord[6], - eg.edgeCoord[1], - eg.faceCoord[1], - eg.elementGlobal, - eg.faceCoord[2]); - eg.subContVol[2].volume = eg.hexahedronVolume(eg.subContVol[2].global, - eg.edgeCoord[4], - eg.faceCoord[4], - eg.edgeCoord[7], - eg.edgeCoord[2], - eg.faceCoord[0], - eg.elementGlobal, - eg.faceCoord[3]); - eg.subContVol[3].volume = eg.hexahedronVolume(eg.subContVol[3].global, - eg.edgeCoord[7], - eg.faceCoord[4], - eg.edgeCoord[5], - eg.edgeCoord[3], - eg.faceCoord[3], - eg.elementGlobal, - eg.faceCoord[1]); - eg.subContVol[4].volume = eg.hexahedronVolume(eg.edgeCoord[0], - eg.faceCoord[2], - eg.elementGlobal, - eg.faceCoord[0], - eg.subContVol[4].global, - eg.edgeCoord[10], - eg.faceCoord[5], - eg.edgeCoord[8]); - eg.subContVol[5].volume = eg.hexahedronVolume(eg.edgeCoord[1], - eg.faceCoord[1], - eg.elementGlobal, - eg.faceCoord[2], - eg.subContVol[5].global, - eg.edgeCoord[9], - eg.faceCoord[5], - eg.edgeCoord[10]); - eg.subContVol[6].volume = eg.hexahedronVolume(eg.edgeCoord[2], - eg.faceCoord[0], - eg.elementGlobal, - eg.faceCoord[3], - eg.subContVol[6].global, - eg.edgeCoord[8], - eg.faceCoord[5], - eg.edgeCoord[11]); - eg.subContVol[7].volume = eg.hexahedronVolume(eg.edgeCoord[3], - eg.faceCoord[3], - eg.elementGlobal, - eg.faceCoord[1], - eg.subContVol[7].global, - eg.edgeCoord[11], - eg.faceCoord[5], - eg.edgeCoord[9]); - break; - default: - DUNE_THROW(Dune::NotImplemented, "_BoxFVElemGeomHelper::fillSubContVolData dim = " << dim << ", numVertices = " << numVertices); - } - } -}; - -//! \endcond - -// END HACK -///////////////////// - -/*! - * \brief Represents the finite volume geometry of a single element in - * the box scheme. - * - * The box scheme is a vertex centered finite volume approach. This - * means that each vertex corrosponds to a control volume which - * intersects each of the vertex' neighboring elements. If only - * looking at a single element of the primary grid (which is what this - * class does), the element is subdivided into multiple fragments of - * control volumes called sub-control volumes. Each of the element's - * vertices corrosponds to exactly one sub-control volume in this - * scenario. - * - * For the box methods the sub-control volumes are constructed by - * connecting the element's center with each edge of the element. - */ -template<class TypeTag> -class BoxFVElementGeometry -{ - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - enum{dim = GridView::dimension}; - enum{dimWorld = GridView::dimensionworld}; - - typedef BoxFVElementGeometry<TypeTag> ThisType; - - /** \todo Please doc me! */ - friend class _BoxFVElemGeomHelper<ThisType, dim>; - - typedef _BoxFVElemGeomHelper<ThisType, dim> BoxFVElemGeomHelper; - - enum{maxNC = (dim < 3 ? 4 : 8)}; - enum{maxNE = (dim < 3 ? 4 : 12)}; - enum{maxNF = (dim < 3 ? 1 : 6)}; - enum{maxCOS = (dim < 3 ? 2 : 4)}; - enum{maxBF = (dim < 3 ? 8 : 24)}; - enum{maxNFAP = (dim < 3 ? 4 : 8)}; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GridView::ctype CoordScalar; - typedef typename GridView::Traits::template Codim<0>::Entity Element; - typedef typename Element::Geometry Geometry; - typedef Dune::FieldVector<Scalar,dimWorld> Vector; - typedef Dune::FieldVector<CoordScalar,dimWorld> GlobalPosition; - typedef Dune::FieldVector<CoordScalar,dim> LocalPosition; - typedef typename GridView::IntersectionIterator IntersectionIterator; -#if DUNE_VERSION_NEWER_REV(DUNE_GRID, 2, 3, 0) - typedef typename Geometry::JacobianInverseTransposed JacobianInverseTransposed; -#else - typedef typename Geometry::Jacobian JacobianInverseTransposed; -#endif - - typedef Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1> LocalFiniteElementCache; - typedef typename LocalFiniteElementCache::FiniteElementType LocalFiniteElement; - typedef typename LocalFiniteElement::Traits::LocalBasisType::Traits LocalBasisTraits; - typedef typename LocalBasisTraits::JacobianType ShapeJacobian; - - Scalar quadrilateralArea(const GlobalPosition& p0, const GlobalPosition& p1, const GlobalPosition& p2, const GlobalPosition& p3) - { - return 0.5*fabs((p3[0] - p1[0])*(p2[1] - p0[1]) - (p3[1] - p1[1])*(p2[0] - p0[0])); - } - - void crossProduct(Vector& c, const Vector& a, const Vector& b) - { - c[0] = a[1]*b[2] - a[2]*b[1]; - c[1] = a[2]*b[0] - a[0]*b[2]; - c[2] = a[0]*b[1] - a[1]*b[0]; - } - - Scalar pyramidVolume (const GlobalPosition& p0, const GlobalPosition& p1, const GlobalPosition& p2, const GlobalPosition& p3, const GlobalPosition& p4) - { - Vector a(p2); a -= p0; - Vector b(p3); b -= p1; - - Vector n; - crossProduct(n, a, b); - - a = p4; a -= p0; - - return 1.0/6.0*(n*a); - } - - Scalar prismVolume (const GlobalPosition& p0, const GlobalPosition& p1, const GlobalPosition& p2, const GlobalPosition& p3, const GlobalPosition& p4, const GlobalPosition& p5) - { - Vector a(p4); - for (int k = 0; k < dimWorld; ++k) - a[k] -= p0[k]; - Vector b(p1); - for (int k = 0; k < dimWorld; ++k) - b[k] -= p3[k]; - Vector m; - crossProduct(m, a, b); - - a = p1; - for (int k = 0; k < dimWorld; ++k) - a[k] -= p0[k]; - b = p2; - for (int k = 0; k < dimWorld; ++k) - b[k] -= p0[k]; - Vector n; - crossProduct(n, a, b); - n += m; - - a = p5; - for (int k = 0; k < dimWorld; ++k) - a[k] -= p0[k]; - - return fabs(1.0/6.0*(n*a)); - } - - Scalar hexahedronVolume (const GlobalPosition& p0, const GlobalPosition& p1, const GlobalPosition& p2, const GlobalPosition& p3, - const GlobalPosition& p4, const GlobalPosition& p5, const GlobalPosition& p6, const GlobalPosition& p7) - { - return - prismVolume(p0,p1,p2,p4,p5,p6) - + prismVolume(p0,p2,p3,p4,p6,p7); - } - - void normalOfQuadrilateral3D(Vector &normal, const GlobalPosition& p0, const GlobalPosition& p1, const GlobalPosition& p2, const GlobalPosition& p3) - { - Vector a(p2); - for (int k = 0; k < dimWorld; ++k) - a[k] -= p0[k]; - Vector b(p3); - for (int k = 0; k < dimWorld; ++k) - b[k] -= p1[k]; - - crossProduct(normal, a, b); - normal *= 0.5; - } - - Scalar quadrilateralArea3D(const GlobalPosition& p0, const GlobalPosition& p1, const GlobalPosition& p2, const GlobalPosition& p3) - { - Vector normal; - normalOfQuadrilateral3D(normal, p0, p1, p2, p3); - return normal.two_norm(); - } - - void getFaceIndices(int numVertices, int k, int& leftFace, int& rightFace) - { - static const int edgeToFaceTet[2][6] = { - {1, 0, 3, 2, 1, 3}, - {0, 2, 0, 1, 3, 2} - }; - static const int edgeToFacePyramid[2][8] = { - {1, 2, 3, 4, 1, 3, 4, 2}, - {0, 0, 0, 0, 3, 2, 1, 4} - }; - static const int edgeToFacePrism[2][9] = { - {1, 0, 2, 0, 1, 2, 4, 4, 4}, - {0, 2, 1, 3, 3, 3, 0, 1, 2} - }; - static const int edgeToFaceHex[2][12] = { - {0, 2, 3, 1, 4, 1, 2, 4, 0, 5, 5, 3}, - {2, 1, 0, 3, 0, 4, 4, 3, 5, 1, 2, 5} - }; - - switch (numVertices) { - case 4: - leftFace = edgeToFaceTet[0][k]; - rightFace = edgeToFaceTet[1][k]; - break; - case 5: - leftFace = edgeToFacePyramid[0][k]; - rightFace = edgeToFacePyramid[1][k]; - break; - case 6: - leftFace = edgeToFacePrism[0][k]; - rightFace = edgeToFacePrism[1][k]; - break; - case 8: - leftFace = edgeToFaceHex[0][k]; - rightFace = edgeToFaceHex[1][k]; - break; - default: - DUNE_THROW(Dune::NotImplemented, "BoxFVElementGeometry :: getFaceIndices for numVertices = " << numVertices); - break; - } - } - - void getEdgeIndices(int numVertices, int face, int vert, int& leftEdge, int& rightEdge) - { - static const int faceAndVertexToLeftEdgeTet[4][4] = { - { 0, 0, 2, -1}, - { 0, 0, -1, 3}, - { 1, -1, 1, 3}, - {-1, 2, 2, 4} - }; - static const int faceAndVertexToRightEdgeTet[4][4] = { - { 1, 2, 1, -1}, - { 3, 4, -1, 4}, - { 3, -1, 5, 5}, - {-1, 4, 5, 5} - }; - static const int faceAndVertexToLeftEdgePyramid[5][5] = { - { 0, 2, 3, 1, -1}, - { 0, -1, 0, -1, 4}, - {-1, 1, -1, 1, 5}, - { 2, 2, -1, -1, 4}, - {-1, -1, 3, 3, 7} - }; - static const int faceAndVertexToRightEdgePyramid[5][5] = { - { 2, 1, 0, 3, -1}, - { 4, -1, 6, -1, 6}, - {-1, 5, -1, 7, 7}, - { 4, 5, -1, -1, 5}, - {-1, -1, 6, 7, 6} - }; - static const int faceAndVertexToLeftEdgePrism[5][6] = { - { 3, 3, -1, 0, 1, -1}, - { 4, -1, 4, 0, -1, 2}, - {-1, 5, 5, -1, 1, 2}, - { 3, 3, 5, -1, -1, -1}, - {-1, -1, -1, 6, 6, 8} - }; - static const int faceAndVertexToRightEdgePrism[5][6] = { - { 0, 1, -1, 6, 6, -1}, - { 0, -1, 2, 7, -1, 7}, - {-1, 1, 2, -1, 8, 8}, - { 4, 5, 4, -1, -1, -1}, - {-1, -1, -1, 7, 8, 7} - }; - static const int faceAndVertexToLeftEdgeHex[6][8] = { - { 0, -1, 4, -1, 8, -1, 2, -1}, - {-1, 5, -1, 3, -1, 1, -1, 9}, - { 6, 1, -1, -1, 0, 10, -1, -1}, - {-1, -1, 2, 7, -1, -1, 11, 3}, - { 4, 6, 7, 5, -1, -1, -1, -1}, - {-1, -1, -1, -1, 10, 9, 8, 11} - }; - static const int faceAndVertexToRightEdgeHex[6][8] = { - { 4, -1, 2, -1, 0, -1, 8, -1}, - {-1, 1, -1, 5, -1, 9, -1, 3}, - { 0, 6, -1, -1, 10, 1, -1, -1}, - {-1, -1, 7, 3, -1, -1, 2, 11}, - { 6, 5, 4, 7, -1, -1, -1, -1}, - {-1, -1, -1, -1, 8, 10, 11, 9} - }; - - switch (numVertices) { - case 4: - leftEdge = faceAndVertexToLeftEdgeTet[face][vert]; - rightEdge = faceAndVertexToRightEdgeTet[face][vert]; - break; - case 5: - leftEdge = faceAndVertexToLeftEdgePyramid[face][vert]; - rightEdge = faceAndVertexToRightEdgePyramid[face][vert]; - break; - case 6: - leftEdge = faceAndVertexToLeftEdgePrism[face][vert]; - rightEdge = faceAndVertexToRightEdgePrism[face][vert]; - break; - case 8: - leftEdge = faceAndVertexToLeftEdgeHex[face][vert]; - rightEdge = faceAndVertexToRightEdgeHex[face][vert]; - break; - default: - DUNE_THROW(Dune::NotImplemented, "BoxFVElementGeometry :: getFaceIndices for numVertices = " << numVertices); - break; - } - } - -public: - int boundaryFaceIndex(const int face, const int vertInFace) const - { - return (face*maxCOS + vertInFace); - } - - struct SubControlVolume //! FV intersected with element - { - LocalPosition local; //!< local vert position - GlobalPosition global; //!< global vert position - LocalPosition localCenter; //!< local position of scv center - Scalar volume; //!< volume of scv - Dune::FieldVector<Vector, maxNC> grad; //! derivative of shape function associated with the sub control volume - Dune::FieldVector<Vector, maxNC> gradCenter; //! derivative of shape function at the center of the sub control volume - Dune::FieldVector<Scalar, maxNC> shapeValue; //! value of shape function associated with the sub control volume - bool inner; - }; - - struct SubControlVolumeFace //! interior face of a sub control volume - { - int i,j; //!< scvf seperates corner i and j of elem - LocalPosition ipLocal; //!< integration point in local coords - GlobalPosition ipGlobal; //!< integration point in global coords - Vector normal; //!< normal on face pointing to CV j or outward of the domain with length equal to |scvf| - Scalar area; //!< area of face - Dune::FieldVector<Vector, maxNC> grad; //!< derivatives of shape functions at ip - Dune::FieldVector<Scalar, maxNC> shapeValue; //!< value of shape functions at ip - Dune::FieldVector<int, maxNFAP> fapIndices; //!< indices w.r.t.neighbors of the flux approximation points - }; - - typedef SubControlVolumeFace BoundaryFace; //!< compatibility typedef - - LocalPosition elementLocal; //!< local coordinate of element center - GlobalPosition elementGlobal; //!< global coordinate of element center - Scalar elementVolume; //!< element volume - SubControlVolume subContVol[maxNC]; //!< data of the sub control volumes - SubControlVolumeFace subContVolFace[maxNE]; //!< data of the sub control volume faces - BoundaryFace boundaryFace[maxBF]; //!< data of the boundary faces - GlobalPosition edgeCoord[maxNE]; //!< global coordinates of the edge centers - GlobalPosition faceCoord[maxNF]; //!< global coordinates of the face centers - int numVertices; //!< number of verts - int numEdges; //!< number of edges - int numFaces; //!< number of faces (0 in < 3D) - int numSCV; //!< number of subcontrol volumes - int numFAP; //!< number of flux approximation points - - const LocalFiniteElementCache feCache_; - - void update(const GridView& gridView, const Element& element) - { - const Geometry& geometry = element.geometry(); - Dune::GeometryType gt = geometry.type(); - - const typename Dune::GenericReferenceElementContainer<CoordScalar,dim>::value_type& - referenceElement = Dune::GenericReferenceElements<CoordScalar,dim>::general(gt); - - const LocalFiniteElement - &localFiniteElement = feCache_.get(gt); - - elementVolume = geometry.volume(); - elementLocal = referenceElement.position(0,0); - elementGlobal = geometry.global(elementLocal); - - numVertices = referenceElement.size(dim); - numEdges = referenceElement.size(dim-1); - numFaces = (dim<3)?0:referenceElement.size(1); - numSCV = numVertices; - - bool useTwoPointFlux - = GET_PARAM_FROM_GROUP(TypeTag, bool, Implicit, UseTwoPointFlux); - if (useTwoPointFlux) - numFAP = 2; - else - numFAP = numVertices; - - // corners: - for (int vert = 0; vert < numVertices; vert++) { - subContVol[vert].local = referenceElement.position(vert, dim); - subContVol[vert].global = geometry.global(subContVol[vert].local); - subContVol[vert].inner = true; - } - - // edges: - for (int edge = 0; edge < numEdges; edge++) { - edgeCoord[edge] = geometry.global(referenceElement.position(edge, dim-1)); - } - - // faces: - for (int face = 0; face < numFaces; face++) { - faceCoord[face] = geometry.global(referenceElement.position(face, 1)); - } - - // fill sub control volume data use specialization for this - // \todo maybe it would be a good idea to migrate everything - // which is dependend of the grid's dimension to - // _BoxFVElemGeomHelper in order to benefit from more aggressive - // compiler optimizations... - BoxFVElemGeomHelper::fillSubContVolData(*this, numVertices); - - // fill sub control volume face data: - for (int k = 0; k < numEdges; k++) { // begin loop over edges / sub control volume faces - int i = referenceElement.subEntity(k, dim-1, 0, dim); - int j = referenceElement.subEntity(k, dim-1, 1, dim); - if (numEdges == 4 && (i == 2 || j == 2)) - std::swap(i, j); - subContVolFace[k].i = i; - subContVolFace[k].j = j; - - // calculate the local integration point and - // the face normal. note that since dim is a - // constant which is known at compile time - // the compiler can optimize away all if - // cases which don't apply. - LocalPosition ipLocal; - Vector diffVec; - if (dim==1) { - subContVolFace[k].ipLocal = 0.5; - subContVolFace[k].normal = 1.0; - ipLocal = subContVolFace[k].ipLocal; - } - else if (dim==2) { - ipLocal = referenceElement.position(k, dim-1) + elementLocal; - ipLocal *= 0.5; - subContVolFace[k].ipLocal = ipLocal; - diffVec = elementGlobal - edgeCoord[k]; - subContVolFace[k].normal[0] = diffVec[1]; - subContVolFace[k].normal[1] = -diffVec[0]; - - diffVec = subContVol[j].global; - for (int m = 0; m < dimWorld; ++m) - diffVec[m] -= subContVol[i].global[m]; - // make sure the normal points to the right direction - if (subContVolFace[k].normal * diffVec < 0) - subContVolFace[k].normal *= -1; - - } - else if (dim==3) { - int leftFace; - int rightFace; - getFaceIndices(numVertices, k, leftFace, rightFace); - ipLocal = referenceElement.position(k, dim-1) + elementLocal - + referenceElement.position(leftFace, 1) - + referenceElement.position(rightFace, 1); - ipLocal *= 0.25; - subContVolFace[k].ipLocal = ipLocal; - normalOfQuadrilateral3D(subContVolFace[k].normal, - edgeCoord[k], faceCoord[rightFace], - elementGlobal, faceCoord[leftFace]); - } - - if (useTwoPointFlux) - { - GlobalPosition distVec = subContVol[i].global; - distVec -= subContVol[j].global; - distVec /= distVec.two_norm2(); - - // gradients using a two-point flux approximation - for (int idx = 0; idx < 2; idx++) - { - subContVolFace[k].grad[idx] = distVec; - subContVolFace[k].shapeValue[idx] = 0.5; - } - subContVolFace[k].grad[1] *= -1.0; - - subContVolFace[k].fapIndices[0] = subContVolFace[k].i; - subContVolFace[k].fapIndices[1] = subContVolFace[k].j; - } - else - { - // get the global integration point and the Jacobian inverse - subContVolFace[k].ipGlobal = geometry.global(ipLocal); - JacobianInverseTransposed jacInvT = - geometry.jacobianInverseTransposed(ipLocal); - - // calculate the shape function gradients - //typedef Dune::FieldVector< Dune::FieldVector< CoordScalar, dim >, 1 > ShapeJacobian; - typedef Dune::FieldVector< Scalar, 1 > ShapeValue; - std::vector<ShapeJacobian> localJac; - std::vector<ShapeValue> shapeVal; - localFiniteElement.localBasis().evaluateJacobian(subContVolFace[k].ipLocal, localJac); - localFiniteElement.localBasis().evaluateFunction(subContVolFace[k].ipLocal, shapeVal); - for (int vert = 0; vert < numVertices; vert++) { - jacInvT.mv(localJac[vert][0], subContVolFace[k].grad[vert]); - subContVolFace[k].shapeValue[vert] = Scalar(shapeVal[vert]); - subContVolFace[k].fapIndices[vert] = vert; - } - } - } // end loop over edges / sub control volume faces - - // fill boundary face data: - IntersectionIterator endit = gridView.iend(element); - for (IntersectionIterator it = gridView.ibegin(element); it != endit; ++it) - if (it->boundary()) - { - int face = it->indexInInside(); - int numVerticesOfFace = referenceElement.size(face, 1, dim); - for (int vertInFace = 0; vertInFace < numVerticesOfFace; vertInFace++) - { - int vertInElement = referenceElement.subEntity(face, 1, vertInFace, dim); - int bfIdx = boundaryFaceIndex(face, vertInFace); - subContVol[vertInElement].inner = false; - switch ((short) dim) { - case 1: - boundaryFace[bfIdx].ipLocal = referenceElement.position(vertInElement, dim); - boundaryFace[bfIdx].area = 1.0; - break; - case 2: - boundaryFace[bfIdx].ipLocal = referenceElement.position(vertInElement, dim) - + referenceElement.position(face, 1); - boundaryFace[bfIdx].ipLocal *= 0.5; - boundaryFace[bfIdx].area = 0.5*it->geometry().volume(); - break; - case 3: - int leftEdge; - int rightEdge; - getEdgeIndices(numVertices, face, vertInElement, leftEdge, rightEdge); - boundaryFace[bfIdx].ipLocal = referenceElement.position(vertInElement, dim) - + referenceElement.position(face, 1) - + referenceElement.position(leftEdge, dim-1) - + referenceElement.position(rightEdge, dim-1); - boundaryFace[bfIdx].ipLocal *= 0.25; - boundaryFace[bfIdx].area = quadrilateralArea3D(subContVol[vertInElement].global, - edgeCoord[rightEdge], faceCoord[face], edgeCoord[leftEdge]); - break; - default: - DUNE_THROW(Dune::NotImplemented, "BoxFVElementGeometry for dim = " << dim); - } - boundaryFace[bfIdx].ipGlobal = geometry.global(boundaryFace[bfIdx].ipLocal); - boundaryFace[bfIdx].i = vertInElement; - boundaryFace[bfIdx].j = vertInElement; - - // ASSUME constant normal - Dune::FieldVector<CoordScalar, dim-1> localDimM1(0); - boundaryFace[bfIdx].normal = it->unitOuterNormal(localDimM1); - boundaryFace[bfIdx].normal *= boundaryFace[bfIdx].area; - - typedef Dune::FieldVector< Scalar, 1 > ShapeValue; - std::vector<ShapeJacobian> localJac; - std::vector<ShapeValue> shapeVal; - localFiniteElement.localBasis().evaluateJacobian(boundaryFace[bfIdx].ipLocal, localJac); - localFiniteElement.localBasis().evaluateFunction(boundaryFace[bfIdx].ipLocal, shapeVal); - - JacobianInverseTransposed jacInvT = - geometry.jacobianInverseTransposed(boundaryFace[bfIdx].ipLocal); - for (int vert = 0; vert < numVertices; vert++) - { - jacInvT.mv(localJac[vert][0], boundaryFace[bfIdx].grad[vert]); - boundaryFace[bfIdx].shapeValue[vert] = Scalar(shapeVal[vert]); - boundaryFace[bfIdx].fapIndices[vert] = vert; - } - } - } - - bool evalGradientsAtSCVCenter = GET_PROP_VALUE(TypeTag, EvalGradientsAtSCVCenter); - if(evalGradientsAtSCVCenter) - { - // calculate gradients at the center of the scv - for (int scvIdx = 0; scvIdx < numVertices; scvIdx++){ - if (dim == 2) - { - switch (scvIdx) - { - case 0: - if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 0.25; - subContVol[scvIdx].localCenter[1] = 0.25; - } - else { - subContVol[scvIdx].localCenter[0] = 1.0/6.0; - subContVol[scvIdx].localCenter[1] = 1.0/6.0; - } - break; - case 1: - if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 0.75; - subContVol[scvIdx].localCenter[1] = 0.25; - } - else { - subContVol[scvIdx].localCenter[0] = 4.0/6.0; - subContVol[scvIdx].localCenter[1] = 1.0/6.0; - } - break; - case 2: - if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 0.25; - subContVol[scvIdx].localCenter[1] = 0.75; - } - else { - subContVol[scvIdx].localCenter[0] = 1.0/6.0; - subContVol[scvIdx].localCenter[1] = 4.0/6.0; - } - break; - case 3: - subContVol[scvIdx].localCenter[0] = 0.75; - subContVol[scvIdx].localCenter[1] = 0.75; - break; - } - } - - else if (dim == 3) - { - switch (scvIdx) - { - case 0: - if (numVertices == 8) { - subContVol[scvIdx].localCenter[0] = 0.25; - subContVol[scvIdx].localCenter[1] = 0.25; - subContVol[scvIdx].localCenter[2] = 0.25; - } - else if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 3.0/16.0; - subContVol[scvIdx].localCenter[1] = 3.0/16.0; - subContVol[scvIdx].localCenter[2] = 3.0/16.0; - } - break; - case 1: - if (numVertices == 8) { - subContVol[scvIdx].localCenter[0] = 0.75; - subContVol[scvIdx].localCenter[1] = 0.25; - subContVol[scvIdx].localCenter[2] = 0.25; - } - else if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 7.0/16.0; - subContVol[scvIdx].localCenter[1] = 3.0/16.0; - subContVol[scvIdx].localCenter[2] = 3.0/16.0; - } - break; - case 2: - if (numVertices == 8) { - subContVol[scvIdx].localCenter[0] = 0.25; - subContVol[scvIdx].localCenter[1] = 0.75; - subContVol[scvIdx].localCenter[2] = 0.25; - } - else if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 3.0/16.0; - subContVol[scvIdx].localCenter[1] = 7.0/16.0; - subContVol[scvIdx].localCenter[2] = 3.0/16.0; - } - break; - case 3: - if (numVertices == 8) { - subContVol[scvIdx].localCenter[0] = 0.75; - subContVol[scvIdx].localCenter[1] = 0.75; - subContVol[scvIdx].localCenter[2] = 0.25; - } - else if (numVertices == 4) { - subContVol[scvIdx].localCenter[0] = 3.0/16.0; - subContVol[scvIdx].localCenter[1] = 3.0/16.0; - subContVol[scvIdx].localCenter[2] = 7.0/16.0; - } - break; - case 4: - subContVol[scvIdx].localCenter[0] = 0.25; - subContVol[scvIdx].localCenter[1] = 0.25; - subContVol[scvIdx].localCenter[2] = 0.75; - break; - case 5: - subContVol[scvIdx].localCenter[0] = 0.75; - subContVol[scvIdx].localCenter[1] = 0.25; - subContVol[scvIdx].localCenter[2] = 0.75; - break; - case 6: - subContVol[scvIdx].localCenter[0] = 0.25; - subContVol[scvIdx].localCenter[1] = 0.75; - subContVol[scvIdx].localCenter[2] = 0.75; - break; - case 7: - subContVol[scvIdx].localCenter[0] = 0.75; - subContVol[scvIdx].localCenter[1] = 0.75; - subContVol[scvIdx].localCenter[2] = 0.75; - break; - } - } - std::vector<ShapeJacobian> localJac; - localFiniteElement.localBasis().evaluateJacobian(subContVol[scvIdx].localCenter, localJac); - - JacobianInverseTransposed jacInvT = - geometry.jacobianInverseTransposed(subContVol[scvIdx].localCenter); - for (int vert = 0; vert < numVertices; vert++) - jacInvT.mv(localJac[vert][0], subContVol[scvIdx].gradCenter[vert]); - } - } - } -}; - -} - -#endif +#warning This file is deprecated. Include dumux/implicit/box/boxfvelementgeometry.hh instead. +#include <dumux/implicit/box/boxfvelementgeometry.hh> diff --git a/dumux/boxmodels/common/boxlocaljacobian.hh b/dumux/boxmodels/common/boxlocaljacobian.hh index 7fc5140d2545e0ba467331e73bb39df09999ead6..f9326416f21caa5c19f970f35aedbed3d920b3a7 100644 --- a/dumux/boxmodels/common/boxlocaljacobian.hh +++ b/dumux/boxmodels/common/boxlocaljacobian.hh @@ -1,534 +1,3 @@ -// -*- 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 Caculates the Jacobian of the local residual for box models - */ -#ifndef DUMUX_BOX_LOCAL_JACOBIAN_HH -#define DUMUX_BOX_LOCAL_JACOBIAN_HH +#warning This file is deprecated. Include dumux/implicit/box/boxlocaljacobian.hh instead. -#include <dune/istl/matrix.hh> - -#include <dumux/common/math.hh> -#include "boxelementboundarytypes.hh" - -namespace Dumux -{ -/*! - * \ingroup BoxModel - * \ingroup BoxLocalJacobian - * \brief Calculates the Jacobian of the local residual for box models - * - * The default behavior is to use numeric differentiation, i.e. - * forward or backward differences (2nd order), or central - * differences (3rd order). The method used is determined by the - * "NumericDifferenceMethod" property: - * - * - if the value of this property is smaller than 0, backward - * differences are used, i.e.: - * \f[ - \frac{\partial f(x)}{\partial x} \approx \frac{f(x) - f(x - \epsilon)}{\epsilon} - * \f] - * - * - if the value of this property is 0, central - * differences are used, i.e.: - * \f[ - \frac{\partial f(x)}{\partial x} \approx \frac{f(x + \epsilon) - f(x - \epsilon)}{2 \epsilon} - * \f] - * - * - if the value of this property is larger than 0, forward - * differences are used, i.e.: - * \f[ - \frac{\partial f(x)}{\partial x} \approx \frac{f(x + \epsilon) - f(x)}{\epsilon} - * \f] - * - * Here, \f$ f \f$ is the residual function for all equations, \f$x\f$ - * is the value of a sub-control volume's primary variable at the - * evaluation point and \f$\epsilon\f$ is a small value larger than 0. - */ -template<class TypeTag> -class BoxLocalJacobian -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, LocalJacobian) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) LocalResidual; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Model) Model; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, JacobianAssembler) JacobianAssembler; - - enum { - numEq = GET_PROP_VALUE(TypeTag, NumEq), - dim = GridView::dimension, - - Green = JacobianAssembler::Green - }; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldMatrix<Scalar, numEq, numEq> MatrixBlock; - typedef Dune::Matrix<MatrixBlock> LocalBlockMatrix; - - // copying a local jacobian is not a good idea - BoxLocalJacobian(const BoxLocalJacobian &); - -public: - BoxLocalJacobian() - { - numericDifferenceMethod_ = GET_PARAM_FROM_GROUP(TypeTag, int, Implicit, NumericDifferenceMethod); - Valgrind::SetUndefined(problemPtr_); - } - - - /*! - * \brief Initialize the local Jacobian object. - * - * At this point we can assume that everything has been allocated, - * although some objects may not yet be completely initialized. - * - * \param prob The problem which we want to simulate. - */ - void init(Problem &prob) - { - problemPtr_ = &prob; - localResidual_.init(prob); - - // assume quadrilinears as elements with most vertices - A_.setSize(2<<dim, 2<<dim); - storageJacobian_.resize(2<<dim); - } - - /*! - * \brief Assemble an element's local Jacobian matrix of the - * defect. - * - * \param element The DUNE Codim<0> entity which we look at. - */ - void assemble(const Element &element) - { - // set the current grid element and update the element's - // finite volume geometry - elemPtr_ = &element; - fvElemGeom_.update(gridView_(), element); - reset_(); - - bcTypes_.update(problem_(), element_(), fvElemGeom_); - - // this is pretty much a HACK because the internal state of - // the problem is not supposed to be changed during the - // evaluation of the residual. (Reasons: It is a violation of - // abstraction, makes everything more prone to errors and is - // not thread save.) The real solution are context objects! - problem_().updateCouplingParams(element_()); - - // set the hints for the volume variables - model_().setHints(element, prevVolVars_, curVolVars_); - - // update the secondary variables for the element at the last - // and the current time levels - prevVolVars_.update(problem_(), - element_(), - fvElemGeom_, - true /* isOldSol? */); - - curVolVars_.update(problem_(), - element_(), - fvElemGeom_, - false /* isOldSol? */); - - // update the hints of the model - model_().updateCurHints(element, curVolVars_); - - // calculate the local residual - localResidual().eval(element_(), - fvElemGeom_, - prevVolVars_, - curVolVars_, - bcTypes_); - residual_ = localResidual().residual(); - storageTerm_ = localResidual().storageTerm(); - - model_().updatePVWeights(element_(), curVolVars_); - - // calculate the local jacobian matrix - int numVertices = fvElemGeom_.numVertices; - ElementSolutionVector partialDeriv(numVertices); - PrimaryVariables storageDeriv; - for (int j = 0; j < numVertices; j++) { - for (int pvIdx = 0; pvIdx < numEq; pvIdx++) { - asImp_().evalPartialDerivative_(partialDeriv, - storageDeriv, - j, - pvIdx); - - // update the local stiffness matrix with the current partial - // derivatives - updateLocalJacobian_(j, - pvIdx, - partialDeriv, - storageDeriv); - } - } - } - - /*! - * \brief Returns a reference to the object which calculates the - * local residual. - */ - const LocalResidual &localResidual() const - { return localResidual_; } - - /*! - * \brief Returns a reference to the object which calculates the - * local residual. - */ - LocalResidual &localResidual() - { return localResidual_; } - - /*! - * \brief Returns the Jacobian of the equations at vertex i to the - * primary variables at vertex j. - * - * \param i The local vertex (or sub-control volume) index on which - * the equations are defined - * \param j The local vertex (or sub-control volume) index which holds - * primary variables - */ - const MatrixBlock &mat(const int i, const int j) const - { return A_[i][j]; } - - /*! - * \brief Returns the Jacobian of the storage term at vertex i. - * - * \param i The local vertex (or sub-control volume) index - */ - const MatrixBlock &storageJacobian(const int i) const - { return storageJacobian_[i]; } - - /*! - * \brief Returns the residual of the equations at vertex i. - * - * \param i The local vertex (or sub-control volume) index on which - * the equations are defined - */ - const PrimaryVariables &residual(const int i) const - { return residual_[i]; } - - /*! - * \brief Returns the storage term for vertex i. - * - * \param i The local vertex (or sub-control volume) index on which - * the equations are defined - */ - const PrimaryVariables &storageTerm(const int i) const - { return storageTerm_[i]; } - - /*! - * \brief Returns the epsilon value which is added and removed - * from the current solution. - * - * \param scvIdx The local index of the element's vertex for - * which the local derivative ought to be calculated. - * \param pvIdx The index of the primary variable which gets varied - */ - Scalar numericEpsilon(const int scvIdx, - const int pvIdx) const - { - // define the base epsilon as the geometric mean of 1 and the - // resolution of the scalar type. E.g. for standard 64 bit - // floating point values, the resolution is about 10^-16 and - // the base epsilon is thus approximately 10^-8. - /* - static const Scalar baseEps - = Dumux::geometricMean<Scalar>(std::numeric_limits<Scalar>::epsilon(), 1.0); - */ - static const Scalar baseEps = 1e-10; - assert(std::numeric_limits<Scalar>::epsilon()*1e4 < baseEps); - // the epsilon value used for the numeric differentiation is - // now scaled by the absolute value of the primary variable... - Scalar priVar = this->curVolVars_[scvIdx].priVar(pvIdx); - return baseEps*(std::abs(priVar) + 1.0); - } - -protected: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } - - /*! - * \brief Returns a reference to the problem. - */ - const Problem &problem_() const - { - Valgrind::CheckDefined(problemPtr_); - return *problemPtr_; - }; - - /*! - * \brief Returns a reference to the grid view. - */ - const GridView &gridView_() const - { return problem_().gridView(); } - - /*! - * \brief Returns a reference to the element. - */ - const Element &element_() const - { - Valgrind::CheckDefined(elemPtr_); - return *elemPtr_; - }; - - /*! - * \brief Returns a reference to the model. - */ - const Model &model_() const - { return problem_().model(); }; - - /*! - * \brief Returns a reference to the jacobian assembler. - */ - const JacobianAssembler &jacAsm_() const - { return model_().jacobianAssembler(); } - - /*! - * \brief Returns a reference to the vertex mapper. - */ - const VertexMapper &vertexMapper_() const - { return problem_().vertexMapper(); }; - - /*! - * \brief Reset the local jacobian matrix to 0 - */ - void reset_() - { - int n = element_().template count<dim>(); - for (int i = 0; i < n; ++ i) { - storageJacobian_[i] = 0.0; - for (int j = 0; j < n; ++ j) { - A_[i][j] = 0.0; - } - } - } - - /*! - * \brief Compute the partial derivatives to a primary variable at - * an degree of freedom. - * - * This method can be overwritten by the implementation if a - * better scheme than numerical differentiation is available. - * - * The default implementation of this method uses numeric - * differentiation, i.e. forward or backward differences (2nd - * order), or central differences (3rd order). The method used is - * determined by the "NumericDifferenceMethod" property: - * - * - if the value of this property is smaller than 0, backward - * differences are used, i.e.: - * \f[ - \frac{\partial f(x)}{\partial x} \approx \frac{f(x) - f(x - \epsilon)}{\epsilon} - * \f] - * - * - if the value of this property is 0, central - * differences are used, i.e.: - * \f[ - \frac{\partial f(x)}{\partial x} \approx \frac{f(x + \epsilon) - f(x - \epsilon)}{2 \epsilon} - * \f] - * - * - if the value of this property is larger than 0, forward - * differences are used, i.e.: - * \f[ - \frac{\partial f(x)}{\partial x} \approx \frac{f(x + \epsilon) - f(x)}{\epsilon} - * \f] - * - * Here, \f$ f \f$ is the residual function for all equations, \f$x\f$ - * is the value of a sub-control volume's primary variable at the - * evaluation point and \f$\epsilon\f$ is a small value larger than 0. - * - * \param partialDeriv The vector storing the partial derivatives of all - * equations - * \param storageDeriv the mass matrix contributions - * \param scvIdx The sub-control volume index of the current - * finite element for which the partial derivative - * ought to be calculated - * \param pvIdx The index of the primary variable at the scvIdx' - * sub-control volume of the current finite element - * for which the partial derivative ought to be - * calculated - */ - void evalPartialDerivative_(ElementSolutionVector &partialDeriv, - PrimaryVariables &storageDeriv, - const int scvIdx, - const int pvIdx) - { - int globalIdx = vertexMapper_().map(element_(), scvIdx, dim); - - PrimaryVariables priVars(model_().curSol()[globalIdx]); - VolumeVariables origVolVars(curVolVars_[scvIdx]); - - curVolVars_[scvIdx].setEvalPoint(&origVolVars); - Scalar eps = asImp_().numericEpsilon(scvIdx, pvIdx); - Scalar delta = 0; - - if (numericDifferenceMethod_ >= 0) { - // we are not using backward differences, i.e. we need to - // calculate f(x + \epsilon) - - // deflect primary variables - priVars[pvIdx] += eps; - delta += eps; - - // calculate the residual - curVolVars_[scvIdx].update(priVars, - problem_(), - element_(), - fvElemGeom_, - scvIdx, - false); - localResidual().eval(element_(), - fvElemGeom_, - prevVolVars_, - curVolVars_, - bcTypes_); - - // store the residual and the storage term - partialDeriv = localResidual().residual(); - storageDeriv = localResidual().storageTerm()[scvIdx]; - } - else { - // we are using backward differences, i.e. we don't need - // to calculate f(x + \epsilon) and we can recycle the - // (already calculated) residual f(x) - partialDeriv = residual_; - storageDeriv = storageTerm_[scvIdx]; - } - - - if (numericDifferenceMethod_ <= 0) { - // we are not using forward differences, i.e. we don't - // need to calculate f(x - \epsilon) - - // deflect the primary variables - priVars[pvIdx] -= delta + eps; - delta += eps; - - // calculate residual again - curVolVars_[scvIdx].update(priVars, - problem_(), - element_(), - fvElemGeom_, - scvIdx, - false); - localResidual().eval(element_(), - fvElemGeom_, - prevVolVars_, - curVolVars_, - bcTypes_); - partialDeriv -= localResidual().residual(); - storageDeriv -= localResidual().storageTerm()[scvIdx]; - } - else { - // we are using forward differences, i.e. we don't need to - // calculate f(x - \epsilon) and we can recycle the - // (already calculated) residual f(x) - partialDeriv -= residual_; - storageDeriv -= storageTerm_[scvIdx]; - } - - // divide difference in residuals by the magnitude of the - // deflections between the two function evaluation - partialDeriv /= delta; - storageDeriv /= delta; - - // restore the original state of the element's volume variables - curVolVars_[scvIdx] = origVolVars; - -#if HAVE_VALGRIND - for (unsigned i = 0; i < partialDeriv.size(); ++i) - Valgrind::CheckDefined(partialDeriv[i]); -#endif - } - - /*! - * \brief Updates the current local Jacobian matrix with the - * partial derivatives of all equations in regard to the - * primary variable 'pvIdx' at vertex 'scvIdx' . - */ - void updateLocalJacobian_(const int scvIdx, - const int pvIdx, - const ElementSolutionVector &partialDeriv, - const PrimaryVariables &storageDeriv) - { - // store the derivative of the storage term - for (int eqIdx = 0; eqIdx < numEq; eqIdx++) { - storageJacobian_[scvIdx][eqIdx][pvIdx] = storageDeriv[eqIdx]; - } - - for (int i = 0; i < fvElemGeom_.numVertices; i++) - { - // Green vertices are not to be changed! - if (jacAsm_().vertexColor(element_(), i) != Green) { - for (int eqIdx = 0; eqIdx < numEq; eqIdx++) { - // A[i][scvIdx][eqIdx][pvIdx] is the rate of change of - // the residual of equation 'eqIdx' at vertex 'i' - // depending on the primary variable 'pvIdx' at vertex - // 'scvIdx'. - this->A_[i][scvIdx][eqIdx][pvIdx] = partialDeriv[i][eqIdx]; - Valgrind::CheckDefined(this->A_[i][scvIdx][eqIdx][pvIdx]); - } - } - } - } - - const Element *elemPtr_; - FVElementGeometry fvElemGeom_; - - ElementBoundaryTypes bcTypes_; - - // The problem we would like to solve - Problem *problemPtr_; - - // secondary variables at the previous and at the current time - // levels - ElementVolumeVariables prevVolVars_; - ElementVolumeVariables curVolVars_; - - LocalResidual localResidual_; - - LocalBlockMatrix A_; - std::vector<MatrixBlock> storageJacobian_; - - ElementSolutionVector residual_; - ElementSolutionVector storageTerm_; - - int numericDifferenceMethod_; -}; -} - -#endif +#include <dumux/implicit/box/boxlocaljacobian.hh> diff --git a/dumux/boxmodels/common/boxlocalresidual.hh b/dumux/boxmodels/common/boxlocalresidual.hh index 8c02754133eec4a5cde1c8afdbff9bbc3d93ece1..7850f07526c58b4825bdbfdcb737afaa58c2fd3f 100644 --- a/dumux/boxmodels/common/boxlocalresidual.hh +++ b/dumux/boxmodels/common/boxlocalresidual.hh @@ -1,742 +1,3 @@ -// -*- 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 Calculates the residual of models based on the box scheme element-wise. - */ -#ifndef DUMUX_BOX_LOCAL_RESIDUAL_HH -#define DUMUX_BOX_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/box/boxlocalresidual.hh instead. -#include <dune/istl/matrix.hh> -#include <dune/grid/common/geometry.hh> - -#include <dumux/common/valgrind.hh> - -#include "boxproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup BoxModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the residual matrix for models - * based on the box scheme. - * - * \todo Please doc me more! - */ -template<class TypeTag> -class BoxLocalResidual -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Model) Model; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - enum { - numEq = GET_PROP_VALUE(TypeTag, NumEq), - dim = GridView::dimension - }; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<dim>::EntityPointer VertexPointer; - typedef typename GridView::IntersectionIterator IntersectionIterator; - - typedef typename GridView::Grid::ctype CoordScalar; - typedef typename Dune::GenericReferenceElements<CoordScalar, dim> ReferenceElements; - typedef typename Dune::GenericReferenceElement<CoordScalar, dim> ReferenceElement; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - // copying the local residual class is not a good idea - BoxLocalResidual(const BoxLocalResidual &); - -public: - BoxLocalResidual() - { } - - ~BoxLocalResidual() - { } - - /*! - * \brief Initialize the local residual. - * - * This assumes that all objects of the simulation have been fully - * allocated but not necessarily initialized completely. - * - * \param problem The representation of the physical problem to be - * solved. - */ - void init(Problem &problem) - { problemPtr_ = &problem; } - - /*! - * \brief Compute the local residual, i.e. the deviation of the - * equations from zero. - * - * \param element The DUNE Codim<0> entity for which the residual - * ought to be calculated - */ - void eval(const Element &element) - { - FVElementGeometry fvGeometry; - - fvGeometry.update(gridView_(), element); - fvElemGeomPtr_ = &fvGeometry; - - ElementVolumeVariables volVarsPrev, volVarsCur; - // update the hints - model_().setHints(element, volVarsPrev, volVarsCur); - - volVarsPrev.update(problem_(), - element, - fvGeometry_(), - true /* oldSol? */); - volVarsCur.update(problem_(), - element, - fvGeometry_(), - false /* oldSol? */); - - ElementBoundaryTypes bcTypes; - bcTypes.update(problem_(), element, fvGeometry_()); - - // this is pretty much a HACK because the internal state of - // the problem is not supposed to be changed during the - // evaluation of the residual. (Reasons: It is a violation of - // abstraction, makes everything more prone to errors and is - // not thread save.) The real solution are context objects! - problem_().updateCouplingParams(element); - - asImp_().eval(element, fvGeometry_(), volVarsPrev, volVarsCur, bcTypes); - } - - /*! - * \brief Compute the storage term for the current solution. - * - * This can be used to figure out how much of each conservation - * quantity is inside the element. - * - * \param element The DUNE Codim<0> entity for which the storage - * term ought to be calculated - */ - void evalStorage(const Element &element) - { - elemPtr_ = &element; - - FVElementGeometry fvGeometry; - fvGeometry.update(gridView_(), element); - fvElemGeomPtr_ = &fvGeometry; - - ElementBoundaryTypes bcTypes; - bcTypes.update(problem_(), element, fvGeometry_()); - bcTypesPtr_ = &bcTypes; - - // no previous volume variables! - prevVolVarsPtr_ = 0; - - ElementVolumeVariables volVars; - - // update the hints - model_().setHints(element, volVars); - - // calculate volume current variables - volVars.update(problem_(), element, fvGeometry_(), false); - curVolVarsPtr_ = &volVars; - - asImp_().evalStorage_(); - } - - /*! - * \brief Compute the flux term for the current solution. - * - * \param element The DUNE Codim<0> entity for which the residual - * ought to be calculated - * \param curVolVars The volume averaged variables for all - * sub-contol volumes of the element - */ - void evalFluxes(const Element &element, - const ElementVolumeVariables &curVolVars) - { - elemPtr_ = &element; - - FVElementGeometry fvGeometry; - fvGeometry.update(gridView_(), element); - fvElemGeomPtr_ = &fvGeometry; - - ElementBoundaryTypes bcTypes; - bcTypes.update(problem_(), element, fvGeometry_()); - - residual_.resize(fvGeometry_().numVertices); - residual_ = 0; - - bcTypesPtr_ = &bcTypes; - prevVolVarsPtr_ = 0; - curVolVarsPtr_ = &curVolVars; - asImp_().evalFluxes_(); - } - - /*! - * \brief Compute the local residual, i.e. the deviation of the - * equations from zero. - * - * \param element The DUNE Codim<0> entity for which the residual - * ought to be calculated - * \param fvGeometry The finite-volume geometry of the element - * \param prevVolVars The volume averaged variables for all - * sub-control volumes of the element at the previous - * time level - * \param curVolVars The volume averaged variables for all - * sub-control volumes of the element at the current - * time level - * \param bcTypes The types of the boundary conditions for all - * vertices of the element - */ - void eval(const Element &element, - const FVElementGeometry &fvGeometry, - const ElementVolumeVariables &prevVolVars, - const ElementVolumeVariables &curVolVars, - const ElementBoundaryTypes &bcTypes) - { - Valgrind::CheckDefined(prevVolVars); - Valgrind::CheckDefined(curVolVars); - -#if !defined NDEBUG && HAVE_VALGRIND - for (int i=0; i < fvGeometry.numVertices; i++) { - prevVolVars[i].checkDefined(); - curVolVars[i].checkDefined(); - } -#endif // HAVE_VALGRIND - - elemPtr_ = &element; - fvElemGeomPtr_ = &fvGeometry; - bcTypesPtr_ = &bcTypes; - prevVolVarsPtr_ = &prevVolVars; - curVolVarsPtr_ = &curVolVars; - - // resize the vectors for all terms - int numVerts = fvGeometry_().numVertices; - residual_.resize(numVerts); - storageTerm_.resize(numVerts); - - residual_ = 0.0; - storageTerm_ = 0.0; - - asImp_().evalFluxes_(); - -#if !defined NDEBUG && HAVE_VALGRIND - for (int i=0; i < fvGeometry_().numVertices; i++) - Valgrind::CheckDefined(residual_[i]); -#endif // HAVE_VALGRIND - - asImp_().evalVolumeTerms_(); - -#if !defined NDEBUG && HAVE_VALGRIND - for (int i=0; i < fvGeometry_().numVertices; i++) { - Valgrind::CheckDefined(residual_[i]); - } -#endif // HAVE_VALGRIND - - // evaluate the boundary conditions - asImp_().evalBoundary_(); - -#if !defined NDEBUG && HAVE_VALGRIND - for (int i=0; i < fvGeometry_().numVertices; i++) - Valgrind::CheckDefined(residual_[i]); -#endif // HAVE_VALGRIND - } - - /*! - * \brief Returns the local residual for all sub-control - * volumes of the element. - */ - const ElementSolutionVector &residual() const - { return residual_; } - - /*! - * \brief Returns the local residual for a given sub-control - * volume of the element. - * - * \param scvIdx The local index of the sub-control volume - * (i.e. the element's local vertex index) - */ - const PrimaryVariables &residual(const int scvIdx) const - { return residual_[scvIdx]; } - - /*! - * \brief Returns the storage term for all sub-control volumes of the - * element. - */ - const ElementSolutionVector &storageTerm() const - { return storageTerm_; } - - /*! - * \brief Returns the storage term for a given sub-control volumes - * of the element. - */ - const PrimaryVariables &storageTerm(const int scvIdx) const - { return storageTerm_[scvIdx]; } - -protected: - Implementation &asImp_() - { - assert(static_cast<Implementation*>(this) != 0); - return *static_cast<Implementation*>(this); - } - - const Implementation &asImp_() const - { - assert(static_cast<const Implementation*>(this) != 0); - return *static_cast<const Implementation*>(this); - } - - /*! - * \brief Evaluate the boundary conditions - * of the current element. - */ - void evalBoundary_() - { - if (bcTypes_().hasNeumann() || bcTypes_().hasOutflow()) - asImp_().evalBoundaryFluxes_(); -#if !defined NDEBUG && HAVE_VALGRIND - for (int i=0; i < fvGeometry_().numVertices; i++) - Valgrind::CheckDefined(residual_[i]); -#endif // HAVE_VALGRIND - - if (bcTypes_().hasDirichlet()) - asImp_().evalDirichlet_(); - } - - /*! - * \brief Set the values of the Dirichlet boundary control volumes - * of the current element. - */ - void evalDirichlet_() - { - PrimaryVariables dirichletValues(0); - for (int scvIdx = 0; scvIdx < fvGeometry_().numVertices; ++scvIdx) { - const BoundaryTypes &bcTypes = bcTypes_(scvIdx); - - if (bcTypes.hasDirichlet()) { - // ask the problem for the dirichlet values - const VertexPointer vPtr = element_().template subEntity<dim>(scvIdx); - Valgrind::SetUndefined(dirichletValues); - asImp_().problem_().dirichlet(dirichletValues, *vPtr); - - // set the dirichlet conditions - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - if (bcTypes.isDirichlet(eqIdx)) { - int pvIdx = bcTypes.eqToDirichletIndex(eqIdx); - assert(0 <= pvIdx && pvIdx < numEq); - Valgrind::CheckDefined(dirichletValues[pvIdx]); - - residual_[scvIdx][eqIdx] = - curPriVar_(scvIdx, pvIdx) - dirichletValues[pvIdx]; - - storageTerm_[scvIdx][eqIdx] = 0.0; - } - } - } - } - } - - /*! - * \brief Add all Neumann and outflow boundary conditions to the local - * residual. - */ - void evalBoundaryFluxes_() - { - Dune::GeometryType geoType = element_().geometry().type(); - const ReferenceElement &refElement = ReferenceElements::general(geoType); - - IntersectionIterator isIt = gridView_().ibegin(element_()); - const IntersectionIterator &endIt = gridView_().iend(element_()); - for (; isIt != endIt; ++isIt) - { - // handle only faces on the boundary - if (isIt->boundary()) { - // Assemble the boundary for all vertices of the current - // face - int faceIdx = isIt->indexInInside(); - int numFaceVerts = refElement.size(faceIdx, 1, dim); - for (int faceVertIdx = 0; - faceVertIdx < numFaceVerts; - ++faceVertIdx) - { - int scvIdx = refElement.subEntity(faceIdx, - 1, - faceVertIdx, - dim); - - int boundaryFaceIdx = - fvGeometry_().boundaryFaceIndex(faceIdx, faceVertIdx); - - // add the residual of all vertices of the boundary - // segment - asImp_().evalNeumannSegment_(isIt, - scvIdx, - boundaryFaceIdx); - // evaluate the outflow conditions at the boundary face - // ATTENTION: This is so far a beta version that is only for the 2p2c and 2p2cni model - // available and not thoroughly tested. - asImp_().evalOutflowSegment_(isIt, - scvIdx, - boundaryFaceIdx); - } - } - } - } - - /*! - * \brief Add Neumann boundary conditions for a single sub-control - * volume face to the local residual. - */ - void evalNeumannSegment_(const IntersectionIterator &isIt, - const int scvIdx, - const int boundaryFaceIdx) - { - // temporary vector to store the neumann boundary fluxes - PrimaryVariables neumannFlux(0.0); - const BoundaryTypes &bcTypes = bcTypes_(scvIdx); - - // deal with neumann boundaries - if (bcTypes.hasNeumann()) { - Valgrind::SetUndefined(neumannFlux); - problem_().boxSDNeumann(neumannFlux, - element_(), - fvGeometry_(), - *isIt, - scvIdx, - boundaryFaceIdx, - curVolVars_()); - neumannFlux *= - fvGeometry_().boundaryFace[boundaryFaceIdx].area - * curVolVars_(scvIdx).extrusionFactor(); - Valgrind::CheckDefined(neumannFlux); - - // set the neumann conditions - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - if (!bcTypes.isNeumann(eqIdx)) - continue; - residual_[scvIdx][eqIdx] += neumannFlux[eqIdx]; - } - } - } - - /*! - * \brief Add outflow boundary conditions for a single sub-control - * volume face to the local residual. - * - * \param isIt The intersection iterator of current element - * \param scvIdx The index of the considered face of the sub-control volume - * \param boundaryFaceIdx The index of the considered boundary face of the sub control volume - */ - void evalOutflowSegment_(const IntersectionIterator &isIt, - const int scvIdx, - const int boundaryFaceIdx) - { - const BoundaryTypes &bcTypes = this->bcTypes_(scvIdx); - // deal with outflow boundaries - if (bcTypes.hasOutflow()) - { - //calculate outflow fluxes - PrimaryVariables values(0.0); - asImp_().computeFlux(values, boundaryFaceIdx, true); - Valgrind::CheckDefined(values); - - for (int equationIdx = 0; equationIdx < numEq; ++equationIdx) - { - if (!bcTypes.isOutflow(equationIdx) ) - continue; - // deduce outflow - this->residual_[scvIdx][equationIdx] += values[equationIdx]; - } - } - } - - /*! - * \brief Add the flux terms to the local residual of all - * sub-control volumes of the current element. - */ - void evalFluxes_() - { - // calculate the mass flux over the faces and subtract - // it from the local rates - for (int scvfIdx = 0; scvfIdx < fvGeometry_().numEdges; scvfIdx++) - { - int i = fvGeometry_().subContVolFace[scvfIdx].i; - int j = fvGeometry_().subContVolFace[scvfIdx].j; - - PrimaryVariables flux; - - Valgrind::SetUndefined(flux); - asImp_().computeFlux(flux, scvfIdx); - Valgrind::CheckDefined(flux); - - Scalar extrusionFactor = - (curVolVars_(i).extrusionFactor() - + curVolVars_(j).extrusionFactor()) - / 2; - flux *= extrusionFactor; - - // The balance equation for a finite volume is: - // - // dStorage/dt = Flux + Source - // - // where the 'Flux' and the 'Source' terms represent the - // mass per second which _ENTER_ the finite - // volume. Re-arranging this, we get - // - // dStorage/dt - Source - Flux = 0 - // - // Since the flux calculated by computeFlux() goes _OUT_ - // of sub-control volume i and _INTO_ sub-control volume - // j, we need to add the flux to finite volume i and - // subtract it from finite volume j - residual_[i] += flux; - residual_[j] -= flux; - } - } - - /*! - * \brief Set the local residual to the storage terms of all - * sub-control volumes of the current element. - */ - void evalStorage_() - { - storageTerm_.resize(fvGeometry_().numVertices); - storageTerm_ = 0; - - // calculate the amount of conservation each quantity inside - // all sub control volumes - for (int scvIdx = 0; scvIdx < fvGeometry_().numVertices; scvIdx++) { - Valgrind::SetUndefined(storageTerm_[scvIdx]); - asImp_().computeStorage(storageTerm_[scvIdx], scvIdx, /*isOldSol=*/false); - storageTerm_[scvIdx] *= - fvGeometry_().subContVol[scvIdx].volume - * curVolVars_(scvIdx).extrusionFactor(); - Valgrind::CheckDefined(storageTerm_[scvIdx]); - } - } - - /*! - * \brief Add the change in the storage terms and the source term - * to the local residual of all sub-control volumes of the - * current element. - */ - void evalVolumeTerms_() - { - // evaluate the volume terms (storage + source terms) - for (int scvIdx = 0; scvIdx < fvGeometry_().numVertices; scvIdx++) - { - Scalar extrusionFactor = - curVolVars_(scvIdx).extrusionFactor(); - - PrimaryVariables values(0.0); - - // mass balance within the element. this is the - // \f$\frac{m}{\partial t}\f$ term if using implicit - // euler as time discretization. - // - // TODO (?): we might need a more explicit way for - // doing the time discretization... - Valgrind::SetUndefined(storageTerm_[scvIdx]); - Valgrind::SetUndefined(values); - asImp_().computeStorage(storageTerm_[scvIdx], scvIdx, false); - asImp_().computeStorage(values, scvIdx, true); - Valgrind::CheckDefined(storageTerm_[scvIdx]); - Valgrind::CheckDefined(values); - - storageTerm_[scvIdx] -= values; - storageTerm_[scvIdx] *= - fvGeometry_().subContVol[scvIdx].volume - / problem_().timeManager().timeStepSize() - * extrusionFactor; - residual_[scvIdx] += storageTerm_[scvIdx]; - - // subtract the source term from the local rate - Valgrind::SetUndefined(values); - asImp_().computeSource(values, scvIdx); - Valgrind::CheckDefined(values); - values *= fvGeometry_().subContVol[scvIdx].volume * extrusionFactor; - residual_[scvIdx] -= values; - - // make sure that only defined quantities were used - // to calculate the residual. - Valgrind::CheckDefined(residual_[scvIdx]); - } - } - - /*! - * \brief Returns a reference to the problem. - */ - const Problem &problem_() const - { return *problemPtr_; }; - - /*! - * \brief Returns a reference to the model. - */ - const Model &model_() const - { return problem_().model(); }; - - /*! - * \brief Returns a reference to the vertex mapper. - */ - const VertexMapper &vertexMapper_() const - { return problem_().vertexMapper(); }; - - /*! - * \brief Returns a reference to the grid view. - */ - const GridView &gridView_() const - { return problem_().gridView(); } - - /*! - * \brief Returns a reference to the current element. - */ - const Element &element_() const - { - Valgrind::CheckDefined(elemPtr_); - return *elemPtr_; - } - - /*! - * \brief Returns a reference to the current element's finite - * volume geometry. - */ - const FVElementGeometry &fvGeometry_() const - { - Valgrind::CheckDefined(fvElemGeomPtr_); - return *fvElemGeomPtr_; - } - - /*! - * \brief Returns a reference to the primary variables of - * the last time step of the i'th - * sub-control volume of the current element. - */ - const PrimaryVariables &prevPriVars_(const int i) const - { - return prevVolVars_(i).priVars(); - } - - /*! - * \brief Returns a reference to the primary variables of the i'th - * sub-control volume of the current element. - */ - const PrimaryVariables &curPriVars_(const int i) const - { - return curVolVars_(i).priVars(); - } - - /*! - * \brief Returns the j'th primary of the i'th sub-control volume - * of the current element. - */ - Scalar curPriVar_(const int i, const int j) const - { - return curVolVars_(i).priVar(j); - } - - /*! - * \brief Returns a reference to the current volume variables of - * all sub-control volumes of the current element. - */ - const ElementVolumeVariables &curVolVars_() const - { - Valgrind::CheckDefined(curVolVarsPtr_); - return *curVolVarsPtr_; - } - - /*! - * \brief Returns a reference to the volume variables of the i-th - * sub-control volume of the current element. - */ - const VolumeVariables &curVolVars_(const int i) const - { - return curVolVars_()[i]; - } - - /*! - * \brief Returns a reference to the previous time step's volume - * variables of all sub-control volumes of the current - * element. - */ - const ElementVolumeVariables &prevVolVars_() const - { - Valgrind::CheckDefined(prevVolVarsPtr_); - return *prevVolVarsPtr_; - } - - /*! - * \brief Returns a reference to the previous time step's volume - * variables of the i-th sub-control volume of the current - * element. - */ - const VolumeVariables &prevVolVars_(const int i) const - { - return prevVolVars_()[i]; - } - - /*! - * \brief Returns a reference to the boundary types of all - * sub-control volumes of the current element. - */ - const ElementBoundaryTypes &bcTypes_() const - { - Valgrind::CheckDefined(bcTypesPtr_); - return *bcTypesPtr_; - } - - /*! - * \brief Returns a reference to the boundary types of the i-th - * sub-control volume of the current element. - */ - const BoundaryTypes &bcTypes_(const int i) const - { - return bcTypes_()[i]; - } - -protected: - ElementSolutionVector storageTerm_; - ElementSolutionVector residual_; - - // The problem we would like to solve - Problem *problemPtr_; - - const Element *elemPtr_; - const FVElementGeometry *fvElemGeomPtr_; - - // current and previous secondary variables for the element - const ElementVolumeVariables *prevVolVarsPtr_; - const ElementVolumeVariables *curVolVarsPtr_; - - const ElementBoundaryTypes *bcTypesPtr_; -}; - -} - -#endif +#include <dumux/implicit/box/boxlocalresidual.hh> diff --git a/dumux/boxmodels/common/boxmodel.hh b/dumux/boxmodels/common/boxmodel.hh index 567d706dd7fafb52f8c4a9115904b634eefc243a..c0b766d422311476400919d45cadd488deb221d9 100644 --- a/dumux/boxmodels/common/boxmodel.hh +++ b/dumux/boxmodels/common/boxmodel.hh @@ -1,927 +1,3 @@ -// -*- 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 Base class for models using box discretization - */ -#ifndef DUMUX_BOX_MODEL_HH -#define DUMUX_BOX_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/box/boxmodel.hh instead. -#include "boxproperties.hh" -#include "boxpropertydefaults.hh" - -#include "boxelementvolumevariables.hh" -#include "boxlocaljacobian.hh" -#include "boxlocalresidual.hh" - -#include <dumux/parallel/vertexhandles.hh> - -#include <dune/grid/common/geometry.hh> - -namespace Dumux -{ - -/*! - * \ingroup BoxModel - * - * \brief The base class for the vertex centered finite volume - * discretization scheme. - */ -template<class TypeTag> -class BoxModel -{ - typedef typename GET_PROP_TYPE(TypeTag, Model) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper; - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, DofMapper) DofMapper; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, JacobianAssembler) JacobianAssembler; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - - enum { - numEq = GET_PROP_VALUE(TypeTag, NumEq), - dim = GridView::dimension - }; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, LocalJacobian) LocalJacobian; - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) LocalResidual; - typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod; - typedef typename GET_PROP_TYPE(TypeTag, NewtonController) NewtonController; - - typedef typename GridView::ctype CoordScalar; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim<dim>::Entity Vertex; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - typedef typename GridView::IntersectionIterator IntersectionIterator; - - typedef typename Dune::GenericReferenceElements<CoordScalar, dim> ReferenceElements; - typedef typename Dune::GenericReferenceElement<CoordScalar, dim> ReferenceElement; - - // copying a model is not a good idea - BoxModel(const BoxModel &); - -public: - /*! - * \brief The constructor. - */ - BoxModel() - { - enableHints_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Implicit, EnableHints); - } - - ~BoxModel() - { delete jacAsm_; } - - /*! - * \brief Apply the initial conditions to the model. - * - * \param problem The object representing the problem which needs to - * be simulated. - */ - void init(Problem &problem) - { - problemPtr_ = &problem; - - updateBoundaryIndices_(); - - int nDofs = asImp_().numDofs(); - uCur_.resize(nDofs); - uPrev_.resize(nDofs); - boxVolume_.resize(nDofs); - - localJacobian_.init(problem_()); - jacAsm_ = new JacobianAssembler(); - jacAsm_->init(problem_()); - - asImp_().applyInitialSolution_(); - - // resize the hint vectors - if (enableHints_) { - int nVerts = gridView_().size(dim); - curHints_.resize(nVerts); - prevHints_.resize(nVerts); - hintsUsable_.resize(nVerts); - std::fill(hintsUsable_.begin(), - hintsUsable_.end(), - false); - } - - // also set the solution of the "previous" time step to the - // initial solution. - uPrev_ = uCur_; - } - - void setHints(const Element &element, - ElementVolumeVariables &prevVolVars, - ElementVolumeVariables &curVolVars) const - { - if (!enableHints_) - return; - - int n = element.template count<dim>(); - prevVolVars.resize(n); - curVolVars.resize(n); - for (int i = 0; i < n; ++i) { - int globalIdx = vertexMapper().map(element, i, dim); - - if (!hintsUsable_[globalIdx]) { - curVolVars[i].setHint(NULL); - prevVolVars[i].setHint(NULL); - } - else { - curVolVars[i].setHint(&curHints_[globalIdx]); - prevVolVars[i].setHint(&prevHints_[globalIdx]); - } - } - } - - void setHints(const Element &element, - ElementVolumeVariables &curVolVars) const - { - if (!enableHints_) - return; - - int n = element.template count<dim>(); - curVolVars.resize(n); - for (int i = 0; i < n; ++i) { - int globalIdx = vertexMapper().map(element, i, dim); - - if (!hintsUsable_[globalIdx]) - curVolVars[i].setHint(NULL); - else - curVolVars[i].setHint(&curHints_[globalIdx]); - } - } - - void updatePrevHints() - { - if (!enableHints_) - return; - - prevHints_ = curHints_; - } - - void updateCurHints(const Element &element, - const ElementVolumeVariables &elemVolVars) const - { - if (!enableHints_) - return; - - for (unsigned int i = 0; i < elemVolVars.size(); ++i) { - int globalIdx = vertexMapper().map(element, i, dim); - curHints_[globalIdx] = elemVolVars[i]; - if (!hintsUsable_[globalIdx]) - prevHints_[globalIdx] = elemVolVars[i]; - hintsUsable_[globalIdx] = true; - } - } - - - /*! - * \brief Compute the global residual for an arbitrary solution - * vector. - * - * \param residual Stores the result - * \param u The solution for which the residual ought to be calculated - */ - Scalar globalResidual(SolutionVector &residual, - const SolutionVector &u) - { - SolutionVector tmp(curSol()); - curSol() = u; - Scalar res = globalResidual(residual); - curSol() = tmp; - return res; - } - - /*! - * \brief Compute the global residual for the current solution - * vector. - * - * \param residual Stores the result - */ - Scalar globalResidual(SolutionVector &residual) - { - residual = 0; - - ElementIterator elemIt = gridView_().template begin<0>(); - const ElementIterator elemEndIt = gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - localResidual().eval(*elemIt); - - for (int i = 0; i < elemIt->template count<dim>(); ++i) { - int globalI = vertexMapper().map(*elemIt, i, dim); - residual[globalI] += localResidual().residual(i); - } - } - - // calculate the square norm of the residual - Scalar result2 = residual.two_norm2(); - if (gridView_().comm().size() > 1) - result2 = gridView_().comm().sum(result2); - - // add up the residuals on the process borders - if (gridView_().comm().size() > 1) { - VertexHandleSum<PrimaryVariables, SolutionVector, VertexMapper> - sumHandle(residual, vertexMapper()); - gridView_().communicate(sumHandle, - Dune::InteriorBorder_InteriorBorder_Interface, - Dune::ForwardCommunication); - } - - return std::sqrt(result2); - } - - /*! - * \brief Compute the integral over the domain of the storage - * terms of all conservation quantities. - * - * \param storage Stores the result - */ - void globalStorage(PrimaryVariables &storage) - { - storage = 0; - - ElementIterator elemIt = gridView_().template begin<0>(); - const ElementIterator elemEndIt = gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - localResidual().evalStorage(*elemIt); - - for (int i = 0; i < elemIt->template count<dim>(); ++i) - storage += localResidual().storageTerm()[i]; - } - - if (gridView_().comm().size() > 1) - storage = gridView_().comm().sum(storage); - } - - /*! - * \brief Returns the volume \f$\mathrm{[m^3]}\f$ of a given control volume. - * - * \param globalIdx The global index of the control volume's - * associated vertex - */ - Scalar boxVolume(const int globalIdx) const - { return boxVolume_[globalIdx][0]; } - - /*! - * \brief Reference to the current solution as a block vector. - */ - const SolutionVector &curSol() const - { return uCur_; } - - /*! - * \brief Reference to the current solution as a block vector. - */ - SolutionVector &curSol() - { return uCur_; } - - /*! - * \brief Reference to the previous solution as a block vector. - */ - const SolutionVector &prevSol() const - { return uPrev_; } - - /*! - * \brief Reference to the previous solution as a block vector. - */ - SolutionVector &prevSol() - { return uPrev_; } - - /*! - * \brief Returns the operator assembler for the global jacobian of - * the problem. - */ - JacobianAssembler &jacobianAssembler() - { return *jacAsm_; } - - /*! - * \copydoc jacobianAssembler() - */ - const JacobianAssembler &jacobianAssembler() const - { return *jacAsm_; } - - /*! - * \brief Returns the local jacobian which calculates the local - * stiffness matrix for an arbitrary element. - * - * The local stiffness matrices of the element are used by - * the jacobian assembler to produce a global linerization of the - * problem. - */ - LocalJacobian &localJacobian() - { return localJacobian_; } - /*! - * \copydoc localJacobian() - */ - const LocalJacobian &localJacobian() const - { return localJacobian_; } - - /*! - * \brief Returns the local residual function. - */ - LocalResidual &localResidual() - { return localJacobian().localResidual(); } - /*! - * \copydoc localResidual() - */ - const LocalResidual &localResidual() const - { return localJacobian().localResidual(); } - - /*! - * \brief Returns the relative error between two vectors of - * primary variables. - * - * \param vertexIdx The global index of the control volume's - * associated vertex - * \param priVars1 The first vector of primary variables - * \param priVars2 The second vector of primary variables - * - * \todo The vertexIdx argument is pretty hacky. it is required by - * models with pseudo primary variables (i.e. the primary - * variable switching models). the clean solution would be - * to access the pseudo primary variables from the primary - * variables. - */ - Scalar relativeErrorVertex(const int vertexIdx, - const PrimaryVariables &priVars1, - const PrimaryVariables &priVars2) - { - Scalar result = 0.0; - for (int j = 0; j < numEq; ++j) { - Scalar eqErr = std::abs(priVars1[j] - priVars2[j]); - eqErr /= std::max<Scalar>(1.0, std::abs(priVars1[j] + priVars2[j])/2); - - result = std::max(result, eqErr); - } - return result; - } - - /*! - * \brief Try to progress the model to the next timestep. - * - * \param solver The non-linear solver - * \param controller The controller which specifies the behaviour - * of the non-linear solver - */ - bool update(NewtonMethod &solver, - NewtonController &controller) - { -#if HAVE_VALGRIND - for (size_t i = 0; i < curSol().size(); ++i) - Valgrind::CheckDefined(curSol()[i]); -#endif // HAVE_VALGRIND - - asImp_().updateBegin(); - - bool converged = solver.execute(controller); - if (converged) { - asImp_().updateSuccessful(); - } - else - asImp_().updateFailed(); - -#if HAVE_VALGRIND - for (size_t i = 0; i < curSol().size(); ++i) { - Valgrind::CheckDefined(curSol()[i]); - } -#endif // HAVE_VALGRIND - - return converged; - } - - - /*! - * \brief Called by the update() method before it tries to - * apply the newton method. This is primary a hook - * which the actual model can overload. - */ - void updateBegin() - { } - - - /*! - * \brief Called by the update() method if it was - * successful. This is primary a hook which the actual - * model can overload. - */ - void updateSuccessful() - { } - - /*! - * \brief Called by the update() method if it was - * unsuccessful. This is primary a hook which the actual - * model can overload. - */ - void updateFailed() - { - // Reset the current solution to the one of the - // previous time step so that we can start the next - // update at a physically meaningful solution. - uCur_ = uPrev_; - curHints_ = prevHints_; - - jacAsm_->reassembleAll(); - } - - /*! - * \brief Called by the problem if a time integration was - * successful, post processing of the solution is done and - * the result has been written to disk. - * - * This should prepare the model for the next time integration. - */ - void advanceTimeLevel() - { - // make the current solution the previous one. - uPrev_ = uCur_; - prevHints_ = curHints_; - - updatePrevHints(); - } - - /*! - * \brief Serializes the current state of the model. - * - * \tparam Restarter The type of the serializer class - * - * \param res The serializer object - */ - template <class Restarter> - void serialize(Restarter &res) - { res.template serializeEntities<dim>(asImp_(), this->gridView_()); } - - /*! - * \brief Deserializes the state of the model. - * - * \tparam Restarter The type of the serializer class - * - * \param res The serializer object - */ - template <class Restarter> - void deserialize(Restarter &res) - { - res.template deserializeEntities<dim>(asImp_(), this->gridView_()); - prevSol() = curSol(); - } - - /*! - * \brief Write the current solution for a vertex to a restart - * file. - * - * \param outstream The stream into which the vertex data should - * be serialized to - * \param vertex The DUNE Codim<dim> entity which's data should be - * serialized - */ - void serializeEntity(std::ostream &outstream, - const Vertex &vertex) - { - int vertIdx = dofMapper().map(vertex); - - // write phase state - if (!outstream.good()) { - DUNE_THROW(Dune::IOError, - "Could not serialize vertex " - << vertIdx); - } - - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - outstream << curSol()[vertIdx][eqIdx] << " "; - } - } - - /*! - * \brief Reads the current solution variables for a vertex from a - * restart file. - * - * \param instream The stream from which the vertex data should - * be deserialized from - * \param vertex The DUNE Codim<dim> entity which's data should be - * deserialized - */ - void deserializeEntity(std::istream &instream, - const Vertex &vertex) - { - int vertIdx = dofMapper().map(vertex); - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - if (!instream.good()) - DUNE_THROW(Dune::IOError, - "Could not deserialize vertex " - << vertIdx); - instream >> curSol()[vertIdx][eqIdx]; - } - } - - /*! - * \brief Returns the number of global degrees of freedoms (DOFs) - */ - size_t numDofs() const - { return gridView_().size(dim); } - - /*! - * \brief Mapper for the entities where degrees of freedoms are - * defined to indices. - * - * This usually means a mapper for vertices. - */ - const DofMapper &dofMapper() const - { return problem_().vertexMapper(); } - - /*! - * \brief Mapper for vertices to indices. - */ - const VertexMapper &vertexMapper() const - { return problem_().vertexMapper(); } - - /*! - * \brief Mapper for elements to indices. - */ - const ElementMapper &elementMapper() const - { return problem_().elementMapper(); } - - /*! - * \brief Resets the Jacobian matrix assembler, so that the - * boundary types can be altered. - */ - void resetJacobianAssembler () - { - delete jacAsm_; - jacAsm_ = new JacobianAssembler; - jacAsm_->init(problem_()); - } - - /*! - * \brief Update the weights of all primary variables within an - * element given the complete set of volume variables - * - * \param element The DUNE codim 0 entity - * \param volVars All volume variables for the element - */ - void updatePVWeights(const Element &element, - const ElementVolumeVariables &volVars) const - { } - - /*! - * \brief Add the vector fields for analysing the convergence of - * the newton method to the a VTK multi writer. - * - * \tparam MultiWriter The type of the VTK multi writer - * - * \param writer The VTK multi writer object on which the fields should be added. - * \param u The solution function - * \param deltaU The delta of the solution function before and after the Newton update - */ - template <class MultiWriter> - void addConvergenceVtkFields(MultiWriter &writer, - const SolutionVector &u, - const SolutionVector &deltaU) - { - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - - SolutionVector residual(u); - asImp_().globalResidual(residual, u); - - // create the required scalar fields - unsigned numVertices = this->gridView_().size(dim); - - // global defect of the two auxiliary equations - ScalarField* def[numEq]; - ScalarField* delta[numEq]; - ScalarField* x[numEq]; - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - x[eqIdx] = writer.allocateManagedBuffer(numVertices); - delta[eqIdx] = writer.allocateManagedBuffer(numVertices); - def[eqIdx] = writer.allocateManagedBuffer(numVertices); - } - - VertexIterator vIt = this->gridView_().template begin<dim>(); - VertexIterator vEndIt = this->gridView_().template end<dim>(); - for (; vIt != vEndIt; ++ vIt) - { - int globalIdx = vertexMapper().map(*vIt); - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - (*x[eqIdx])[globalIdx] = u[globalIdx][eqIdx]; - (*delta[eqIdx])[globalIdx] = - deltaU[globalIdx][eqIdx]; - (*def[eqIdx])[globalIdx] = residual[globalIdx][eqIdx]; - } - } - - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - std::ostringstream oss; - oss.str(""); oss << "x_" << eqIdx; - writer.attachVertexData(*x[eqIdx], oss.str()); - oss.str(""); oss << "delta_" << eqIdx; - writer.attachVertexData(*delta[eqIdx], oss.str()); - oss.str(""); oss << "defect_" << eqIdx; - writer.attachVertexData(*def[eqIdx], oss.str()); - } - - asImp_().addOutputVtkFields(u, writer); - } - - /*! - * \brief Add the quantities of a time step which ought to be written to disk. - * - * This should be overwritten by the actual model if any secondary - * variables should be written out. Read: This should _always_ be - * overwritten by well behaved models! - * - * \tparam MultiWriter The type of the VTK multi writer - * - * \param sol The global vector of primary variable values. - * \param writer The VTK multi writer where the fields should be added. - */ - template <class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField; - - // create the required scalar fields - unsigned numVertices = this->gridView_().size(dim); - - // global defect of the two auxiliary equations - ScalarField* x[numEq]; - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - x[eqIdx] = writer.allocateManagedBuffer(numVertices); - } - - VertexIterator vIt = this->gridView_().template begin<dim>(); - VertexIterator vEndIt = this->gridView_().template end<dim>(); - for (; vIt != vEndIt; ++ vIt) - { - int globalIdx = vertexMapper().map(*vIt); - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - (*x[eqIdx])[globalIdx] = sol[globalIdx][eqIdx]; - } - } - - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - std::ostringstream oss; - oss << "primaryVar_" << eqIdx; - writer.attachVertexData(*x[eqIdx], oss.str()); - } - } - - /*! - * \brief Reference to the grid view of the spatial domain. - */ - const GridView &gridView() const - { return problem_().gridView(); } - - /*! - * \brief Returns true if the vertex with 'globalVertIdx' is - * located on the grid's boundary. - * - * \param globalVertIdx The global index of the control volume's - * associated vertex - */ - bool onBoundary(const int globalVertIdx) const - { return boundaryIndices_[globalVertIdx]; } - - /*! - * \brief Returns true if a vertex is located on the grid's - * boundary. - * - * \param element A DUNE Codim<0> entity which contains the control - * volume's associated vertex. - * \param vIdx The local vertex index inside element - */ - bool onBoundary(const Element &element, const int vIdx) const - { return onBoundary(vertexMapper().map(element, vIdx, dim)); } - - /*! - * \brief Fill the fluid state according to the primary variables. - * - * Taking the information from the primary variables, - * the fluid state is filled with every information that is - * necessary to evaluate the model's local residual. - * - * \param priVars The primary variables of the model. - * \param problem The problem at hand. - * \param element The current element. - * \param fvGeometry The finite volume element geometry. - * \param scvIdx The index of the subcontrol volume. - * \param fluidState The fluid state to fill. - */ - template <class FluidState> - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const int scvIdx, - FluidState& fluidState) - { - VolumeVariables::completeFluidState(priVars, problem, element, - fvGeometry, scvIdx, fluidState); - } -protected: - /*! - * \brief A reference to the problem on which the model is applied. - */ - Problem &problem_() - { return *problemPtr_; } - /*! - * \copydoc problem_() - */ - const Problem &problem_() const - { return *problemPtr_; } - - /*! - * \brief Reference to the grid view of the spatial domain. - */ - const GridView &gridView_() const - { return problem_().gridView(); } - - /*! - * \brief Reference to the local residal object - */ - LocalResidual &localResidual_() - { return localJacobian_.localResidual(); } - - /*! - * \brief Applies the initial solution for all vertices of the grid. - */ - void applyInitialSolution_() - { - // first set the whole domain to zero - uCur_ = Scalar(0.0); - boxVolume_ = Scalar(0.0); - - FVElementGeometry fvGeometry; - - // iterate through leaf grid and evaluate initial - // condition at the center of each sub control volume - // - // TODO: the initial condition needs to be unique for - // each vertex. we should think about the API... - ElementIterator eIt = gridView_().template begin<0>(); - const ElementIterator &eEndIt = gridView_().template end<0>(); - for (; eIt != eEndIt; ++eIt) { - // deal with the current element - fvGeometry.update(gridView_(), *eIt); - - // loop over all element vertices, i.e. sub control volumes - for (int scvIdx = 0; scvIdx < fvGeometry.numVertices; scvIdx++) - { - // map the local vertex index to the global one - int globalIdx = vertexMapper().map(*eIt, - scvIdx, - dim); - - // let the problem do the dirty work of nailing down - // the initial solution. - PrimaryVariables initPriVars; - Valgrind::SetUndefined(initPriVars); - problem_().initial(initPriVars, - *eIt, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(initPriVars); - - // add up the initial values of all sub-control - // volumes. If the initial values disagree for - // different sub control volumes, the initial value - // will be the arithmetic mean. - initPriVars *= fvGeometry.subContVol[scvIdx].volume; - boxVolume_[globalIdx] += fvGeometry.subContVol[scvIdx].volume; - uCur_[globalIdx] += initPriVars; - Valgrind::CheckDefined(uCur_[globalIdx]); - } - } - - // add up the primary variables and the volumes of the boxes - // which cross process borders - if (gridView_().comm().size() > 1) { - VertexHandleSum<Dune::FieldVector<Scalar, 1>, - Dune::BlockVector<Dune::FieldVector<Scalar, 1> >, - VertexMapper> sumVolumeHandle(boxVolume_, vertexMapper()); - gridView_().communicate(sumVolumeHandle, - Dune::InteriorBorder_InteriorBorder_Interface, - Dune::ForwardCommunication); - - VertexHandleSum<PrimaryVariables, SolutionVector, VertexMapper> - sumPVHandle(uCur_, vertexMapper()); - gridView_().communicate(sumPVHandle, - Dune::InteriorBorder_InteriorBorder_Interface, - Dune::ForwardCommunication); - } - - // divide all primary variables by the volume of their boxes - int n = gridView_().size(dim); - for (int i = 0; i < n; ++i) { - uCur_[i] /= boxVolume(i); - } - } - - /*! - * \brief Find all indices of boundary vertices. - * - * For this we need to loop over all intersections (which is slow - * in general). If the DUNE grid interface would provide a - * onBoundary() method for entities this could be done in a much - * nicer way (actually this would not be necessary) - */ - void updateBoundaryIndices_() - { - boundaryIndices_.resize(numDofs()); - std::fill(boundaryIndices_.begin(), boundaryIndices_.end(), false); - - ElementIterator eIt = gridView_().template begin<0>(); - ElementIterator eEndIt = gridView_().template end<0>(); - for (; eIt != eEndIt; ++eIt) { - Dune::GeometryType geoType = eIt->geometry().type(); - const ReferenceElement &refElement = ReferenceElements::general(geoType); - - IntersectionIterator isIt = gridView_().ibegin(*eIt); - IntersectionIterator isEndIt = gridView_().iend(*eIt); - for (; isIt != isEndIt; ++isIt) { - if (isIt->boundary()) { - // add all vertices on the intersection to the set of - // boundary vertices - int faceIdx = isIt->indexInInside(); - int numFaceVerts = refElement.size(faceIdx, 1, dim); - for (int faceVertIdx = 0; - faceVertIdx < numFaceVerts; - ++faceVertIdx) - { - int elemVertIdx = refElement.subEntity(faceIdx, - 1, - faceVertIdx, - dim); - int globalVertIdx = vertexMapper().map(*eIt, elemVertIdx, dim); - boundaryIndices_[globalVertIdx] = true; - } - } - } - } - } - - // the hint cache for the previous and the current volume - // variables - mutable std::vector<bool> hintsUsable_; - mutable std::vector<VolumeVariables> curHints_; - mutable std::vector<VolumeVariables> prevHints_; - - // the problem we want to solve. defines the constitutive - // relations, matxerial laws, etc. - Problem *problemPtr_; - - // calculates the local jacobian matrix for a given element - LocalJacobian localJacobian_; - // Linearizes the problem at the current time step using the - // local jacobian - JacobianAssembler *jacAsm_; - - // the set of all indices of vertices on the boundary - std::vector<bool> boundaryIndices_; - - // cur is the current iterative solution, prev the converged - // solution of the previous time step - SolutionVector uCur_; - SolutionVector uPrev_; - - Dune::BlockVector<Dune::FieldVector<Scalar, 1> > boxVolume_; - -private: - /*! - * \brief Returns whether messages should be printed - */ - bool verbose_() const - { return gridView_().comm().rank() == 0; } - - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } - - bool enableHints_; -}; -} - -#endif +#include <dumux/implicit/box/boxmodel.hh> diff --git a/dumux/boxmodels/common/boxproblem.hh b/dumux/boxmodels/common/boxproblem.hh index 3a52ac48383aa0955cf9f9ef101f55d31cc9738b..2a70a0ccd82e7940b5bf03af3c3c2af5c1c76037 100644 --- a/dumux/boxmodels/common/boxproblem.hh +++ b/dumux/boxmodels/common/boxproblem.hh @@ -1,835 +1,3 @@ -// -*- 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 Base class for all problems which use the box scheme - */ -#ifndef DUMUX_BOX_PROBLEM_HH -#define DUMUX_BOX_PROBLEM_HH +#warning This file is deprecated. Include dumux/implicit/box/boxproblem.hh instead. -#include "boxproperties.hh" - -#include <dumux/io/vtkmultiwriter.hh> -#include <dumux/io/restart.hh> - -namespace Dumux -{ -/*! - * \ingroup BoxModel - * \ingroup BoxBaseProblems - * \brief Base class for all problems which use the box scheme. - * - * \note All quantities are specified assuming a threedimensional - * world. Problems discretized using 2D grids are assumed to be - * extruded by \f$1 m\f$ and 1D grids are assumed to have a - * cross section of \f$1m \times 1m\f$. - */ -template<class TypeTag> -class BoxProblem -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Problem) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef Dumux::VtkMultiWriter<GridView> VtkMultiWriter; - - typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod; - typedef typename GET_PROP_TYPE(TypeTag, NewtonController) NewtonController; - - typedef typename GET_PROP_TYPE(TypeTag, Model) Model; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper; - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<dim>::Entity Vertex; - typedef typename GridView::template Codim<dim>::Iterator VertexIterator; - typedef typename GridView::Intersection Intersection; - - typedef typename GridView::Grid::ctype CoordScalar; - typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition; - - // copying a problem is not a good idea - BoxProblem(const BoxProblem &); - -public: - /*! - * \brief Constructor - * - * \param timeManager The TimeManager which is used by the simulation - * \param gridView The simulation's idea about physical space - */ - BoxProblem(TimeManager &timeManager, const GridView &gridView) - : gridView_(gridView) - , bboxMin_(std::numeric_limits<double>::max()) - , bboxMax_(-std::numeric_limits<double>::max()) - , elementMapper_(gridView) - , vertexMapper_(gridView) - , timeManager_(&timeManager) - , newtonMethod_(asImp_()) - , newtonCtl_(asImp_()) - { - // calculate the bounding box of the local partition of the grid view - VertexIterator vIt = gridView.template begin<dim>(); - const VertexIterator vEndIt = gridView.template end<dim>(); - for (; vIt!=vEndIt; ++vIt) { - for (int i=0; i<dim; i++) { - bboxMin_[i] = std::min(bboxMin_[i], vIt->geometry().corner(0)[i]); - bboxMax_[i] = std::max(bboxMax_[i], vIt->geometry().corner(0)[i]); - } - } - - // communicate to get the bounding box of the whole domain - if (gridView.comm().size() > 1) - for (int i = 0; i < dim; ++i) { - bboxMin_[i] = gridView.comm().min(bboxMin_[i]); - bboxMax_[i] = gridView.comm().max(bboxMax_[i]); - } - - // set a default name for the problem - simName_ = "sim"; - - resultWriter_ = NULL; - } - - ~BoxProblem() - { - delete resultWriter_; - }; - - - /*! - * \brief Called by the Dumux::TimeManager in order to - * initialize the problem. - * - * If you overload this method don't forget to call - * ParentType::init() - */ - void init() - { - // set the initial condition of the model - model().init(asImp_()); - } - - /*! - * \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 - { - // forward it to the method which only takes the global coordinate - asImp_().boundaryTypesAtPos(values, vertex.geometry().center()); - } - - /*! - * \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 pos The position of the finite volume in global coordinates - */ - void boundaryTypesAtPos(BoundaryTypes &values, - const GlobalPosition &pos) const - { - // Throw an exception (there is no reasonable default value - // for Dirichlet conditions) - DUNE_THROW(Dune::InvalidStateException, - "The problem does not provide " - "a boundaryTypes() method."); - } - - - /*! - * \brief Evaluate the boundary conditions for a dirichlet - * control volume. - * - * \param values The dirichlet values for the primary variables - * \param vertex The vertex representing the "half volume on the boundary" - * - * For this method, the \a values parameter stores primary variables. - */ - void dirichlet(PrimaryVariables &values, - const Vertex &vertex) const - { - // forward it to the method which only takes the global coordinate - asImp_().dirichletAtPos(values, vertex.geometry().center()); - } - - /*! - * \brief Evaluate the boundary conditions for a dirichlet - * control volume. - * - * \param values The dirichlet values for the primary variables - * \param pos The position of the center of the finite volume - * for which the dirichlet condition ought to be - * set in global coordinates - * - * For this method, the \a values parameter stores primary variables. - */ - void dirichletAtPos(PrimaryVariables &values, - const GlobalPosition &pos) const - { - // Throw an exception (there is no reasonable default value - // for Dirichlet conditions) - DUNE_THROW(Dune::InvalidStateException, - "The problem specifies that some boundary " - "segments are dirichlet, but does not provide " - "a dirichlet() method."); - } - - /*! - * \brief Evaluate the boundary conditions for a neumann - * boundary segment. - * - * This is the method for the case where the Neumann condition is - * potentially solution dependent and requires some box method - * specific things. - * - * \param values The neumann values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param is The intersection between element and boundary - * \param scvIdx The local vertex index - * \param boundaryFaceIdx The index of the boundary face - * \param elemVolVars All volume variables for the element - * - * For this method, the \a values parameter stores the mass flux - * in normal direction of each phase. Negative values mean influx. - */ - void boxSDNeumann(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const Intersection &is, - const int scvIdx, - const int boundaryFaceIdx, - const ElementVolumeVariables &elemVolVars) const - { - // forward it to the interface without the volume variables - asImp_().neumann(values, - element, - fvGeometry, - is, - scvIdx, - boundaryFaceIdx); - } - - /*! - * \brief Evaluate the boundary conditions for a neumann - * boundary segment. - * - * \param values The neumann values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param is The intersection between element and boundary - * \param scvIdx The local vertex index - * \param boundaryFaceIdx The index of the boundary face - * - * For this method, the \a values parameter stores the mass flux - * in normal direction of each phase. Negative values mean influx. - */ - void neumann(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const Intersection &is, - const int scvIdx, - const int boundaryFaceIdx) const - { - // forward it to the interface with only the global position - asImp_().neumannAtPos(values, fvGeometry.boundaryFace[boundaryFaceIdx].ipGlobal); - } - - /*! - * \brief Evaluate the boundary conditions for a neumann - * boundary segment. - * - * \param values The neumann values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ - * \param pos The position of the boundary face's integration point in global coordinates - * - * For this method, the \a values parameter stores the mass flux - * in normal direction of each phase. Negative values mean influx. - */ - void neumannAtPos(PrimaryVariables &values, - const GlobalPosition &pos) const - { - // Throw an exception (there is no reasonable default value - // for Neumann conditions) - DUNE_THROW(Dune::InvalidStateException, - "The problem specifies that some boundary " - "segments are neumann, but does not provide " - "a neumannAtPos() method."); - } - - /*! - * \brief Evaluate the source term for all phases within a given - * sub-control-volume. - * - * This is the method for the case where the source term is - * potentially solution dependent and requires some box method - * specific things. - * - * \param values The source and sink values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvIdx The local vertex index - * \param elemVolVars All volume variables for the element - * - * For this method, the \a values parameter stores the rate mass - * generated or annihilate per volume unit. Positive values mean - * that mass is created, negative ones mean that it vanishes. - */ - void boxSDSource(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const ElementVolumeVariables &elemVolVars) const - { - // forward to solution independent, box specific interface - asImp_().source(values, element, fvGeometry, scvIdx); - } - - /*! - * \brief Evaluate the source term for all phases within a given - * sub-control-volume. - * - * \param values The source and sink values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvIdx The local vertex index - * - * For this method, the \a values parameter stores the rate mass - * generated or annihilate per volume unit. Positive values mean - * that mass is created, negative ones mean that it vanishes. - */ - void source(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - // forward to generic interface - asImp_().sourceAtPos(values, fvGeometry.subContVol[scvIdx].global); - } - - /*! - * \brief Evaluate the source term for all phases within a given - * sub-control-volume. - * - * \param values The source and sink values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ - * \param pos The position of the center of the finite volume - * for which the source term ought to be - * specified in global coordinates - * - * For this method, the \a values parameter stores the rate mass - * generated or annihilate per volume unit. Positive values mean - * that mass is created, negative ones mean that it vanishes. - */ - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &pos) const - { - DUNE_THROW(Dune::InvalidStateException, - "The problem does not provide " - "a sourceAtPos() method."); - } - - /*! - * \brief Evaluate the initial value for a control volume. - * - * \param values The initial values for the primary variables - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvIdx The local vertex index - * - * For this method, the \a values parameter stores primary - * variables. - */ - void initial(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - // forward to generic interface - asImp_().initialAtPos(values, fvGeometry.subContVol[scvIdx].global); - } - - /*! - * \brief Evaluate the initial value for a control volume. - * - * \param values The dirichlet values for the primary variables - * \param pos The position of the center of the finite volume - * for which the initial values ought to be - * set (in global coordinates) - * - * For this method, the \a values parameter stores primary variables. - */ - void initialAtPos(PrimaryVariables &values, - const GlobalPosition &pos) const - { - // Throw an exception (there is no reasonable default value - // for Dirichlet conditions) - DUNE_THROW(Dune::InvalidStateException, - "The problem does not provide " - "a initialAtPos() method."); - } - - /*! - * \brief Return how much the domain is extruded at a given sub-control volume. - * - * This means the factor by which a lower-dimensional (1D or 2D) - * entity needs to be expanded to get a full dimensional cell. The - * default is 1.0 which means that 1D problems are actually - * thought as pipes with a cross section of 1 m^2 and 2D problems - * are assumed to extend 1 m to the back. - */ - Scalar boxExtrusionFactor(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - // forward to generic interface - return asImp_().extrusionFactorAtPos(fvGeometry.subContVol[scvIdx].global); - } - - /*! - * \brief Return how much the domain is extruded at a given position. - * - * This means the factor by which a lower-dimensional (1D or 2D) - * entity needs to be expanded to get a full dimensional cell. The - * default is 1.0 which means that 1D problems are actually - * thought as pipes with a cross section of 1 m^2 and 2D problems - * are assumed to extend 1 m to the back. - */ - Scalar extrusionFactorAtPos(const GlobalPosition &pos) const - { return 1.0; } - - /*! - * \brief If model coupling is used, this updates the parameters - * required to calculate the coupling fluxes between the - * sub-models. - * - * By default it does nothing - * - * \param element The DUNE Codim<0> entity for which the coupling - * parameters should be computed. - */ - void updateCouplingParams(const Element &element) const - {} - - /*! - * \name Simulation steering - */ - // \{ - - /*! - * \brief Called by the time manager before the time integration. - */ - void preTimeStep() - {} - - /*! - * \brief Called by Dumux::TimeManager in order to do a time - * integration on the model. - */ - void timeIntegration() - { - const int maxFails = 10; - for (int i = 0; i < maxFails; ++i) { - if (model_.update(newtonMethod_, newtonCtl_)) - return; - - Scalar dt = timeManager().timeStepSize(); - Scalar nextDt = dt / 2; - timeManager().setTimeStepSize(nextDt); - - // update failed - std::cout << "Newton solver did not converge with dt="<<dt<<" seconds. Retrying with time step of " - << nextDt << " seconds\n"; - } - - DUNE_THROW(Dune::MathError, - "Newton solver didn't converge after " - << maxFails - << " time-step divisions. dt=" - << timeManager().timeStepSize()); - } - - /*! - * \brief Returns the newton method object - */ - NewtonMethod &newtonMethod() - { return newtonMethod_; } - - /*! - * \copydoc newtonMethod() - */ - const NewtonMethod &newtonMethod() const - { return newtonMethod_; } - - /*! - * \brief Returns the newton contoller object - */ - NewtonController &newtonController() - { return newtonCtl_; } - - /*! - * \copydoc newtonController() - */ - const NewtonController &newtonController() const - { return newtonCtl_; } - - /*! - * \brief Called by Dumux::TimeManager whenever a solution for a - * time step has been computed and the simulation time has - * been updated. - * - * \param dt The current time-step size - */ - Scalar nextTimeStepSize(const Scalar dt) - { - return std::min(GET_PARAM_FROM_GROUP(TypeTag, Scalar, TimeManager, MaxTimeStepSize), - newtonCtl_.suggestTimeStepSize(dt)); - }; - - /*! - * \brief Returns true if a restart file should be written to - * disk. - * - * The default behavior is to write one restart file every 5 time - * steps. This file is intended to be overwritten by the - * implementation. - */ - bool shouldWriteRestartFile() const - { - return timeManager().timeStepIndex() > 0 && - (timeManager().timeStepIndex() % 10 == 0); - } - - /*! - * \brief Returns true if the current solution should be written to - * disk (i.e. as a VTK file) - * - * The default behavior is to write out every the solution for - * very time step. This file is intended to be overwritten by the - * implementation. - */ - bool shouldWriteOutput() const - { return true; } - - /*! - * \brief Called by the time manager after the time integration to - * do some post processing on the solution. - */ - void postTimeStep() - { } - - /*! - * \brief Called by the time manager after everything which can be - * done about the current time step is finished and the - * model should be prepared to do the next time integration. - */ - void advanceTimeLevel() - { - model_.advanceTimeLevel(); - } - - /*! - * \brief Called when the end of an simulation episode is reached. - * - * Typically a new episode should be started in this method. - */ - void episodeEnd() - { - std::cerr << "The end of an episode is reached, but the problem " - << "does not override the episodeEnd() method. " - << "Doing nothing!\n"; - }; - // \} - - /*! - * \brief The problem name. - * - * This is used as a prefix for files generated by the simulation. - * It could be either overwritten by the problem files, or simply - * declared over the setName() function in the application file. - */ - const char *name() const - { - return simName_.c_str(); - } - - /*! - * \brief Set the problem name. - * - * This static method sets the simulation name, which should be - * called before the application problem is declared! If not, the - * default name "sim" will be used. - * - * \param newName The problem's name - */ - void setName(const char *newName) - { - simName_ = newName; - } - - - /*! - * \brief Returns the number of the current VTK file. - */ - int currentVTKFileNumber() - { - createResultWriter_(); - return resultWriter_->curWriterNum(); - } - - /*! - * \brief The GridView which used by the problem. - */ - const GridView &gridView() const - { return gridView_; } - - /*! - * \brief The coordinate of the corner of the GridView's bounding - * box with the smallest values. - */ - const GlobalPosition &bboxMin() const - { return bboxMin_; } - - /*! - * \brief The coordinate of the corner of the GridView's bounding - * box with the largest values. - */ - const GlobalPosition &bboxMax() const - { return bboxMax_; } - - /*! - * \brief Returns the mapper for vertices to indices. - */ - const VertexMapper &vertexMapper() const - { return vertexMapper_; } - - /*! - * \brief Returns the mapper for elements to indices. - */ - const ElementMapper &elementMapper() const - { return elementMapper_; } - - /*! - * \brief Returns TimeManager object used by the simulation - */ - TimeManager &timeManager() - { return *timeManager_; } - - /*! - * \copydoc timeManager() - */ - const TimeManager &timeManager() const - { return *timeManager_; } - - /*! - * \brief Returns numerical model used for the problem. - */ - Model &model() - { return model_; } - - /*! - * \copydoc model() - */ - const Model &model() const - { return model_; } - // \} - - /*! - * \name Restart mechanism - */ - // \{ - - /*! - * \brief This method writes the complete state of the simulation - * to the harddisk. - * - * The file will start with the prefix returned by the name() - * method, has the current time of the simulation clock in it's - * name and uses the extension <tt>.drs</tt>. (Dumux ReStart - * file.) See Dumux::Restart for details. - */ - void serialize() - { - typedef Dumux::Restart Restarter; - Restarter res; - res.serializeBegin(asImp_()); - if (gridView().comm().rank() == 0) - std::cout << "Serialize to file '" << res.fileName() << "'\n"; - - timeManager().serialize(res); - asImp_().serialize(res); - res.serializeEnd(); - } - - /*! - * \brief This method writes the complete state of the problem - * to the harddisk. - * - * The file will start with the prefix returned by the name() - * method, has the current time of the simulation clock in it's - * name and uses the extension <tt>.drs</tt>. (Dumux ReStart - * file.) See Dumux::Restart for details. - * - * \tparam Restarter The serializer type - * - * \param res The serializer object - */ - template <class Restarter> - void serialize(Restarter &res) - { - createResultWriter_(); - resultWriter_->serialize(res); - model().serialize(res); - } - - /*! - * \brief Load a previously saved state of the whole simulation - * from disk. - * - * \param tRestart The simulation time on which the program was - * written to disk. - */ - void restart(const Scalar tRestart) - { - typedef Dumux::Restart Restarter; - - Restarter res; - - res.deserializeBegin(asImp_(), tRestart); - if (gridView().comm().rank() == 0) - std::cout << "Deserialize from file '" << res.fileName() << "'\n"; - timeManager().deserialize(res); - asImp_().deserialize(res); - res.deserializeEnd(); - } - - /*! - * \brief This method restores the complete state of the problem - * from disk. - * - * It is the inverse of the serialize() method. - * - * \tparam Restarter The deserializer type - * - * \param res The deserializer object - */ - template <class Restarter> - void deserialize(Restarter &res) - { - createResultWriter_(); - resultWriter_->deserialize(res); - model().deserialize(res); - } - - // \} - - /*! - * \brief Adds additional VTK output data to the VTKWriter. Function is called by writeOutput(). - */ - void addOutputVtkFields() - {} - - /*! - * \brief Write the relevant secondary variables of the current - * solution into an VTK output file. - */ - void writeOutput(const bool verbose = true) - { - // write the current result to disk - if (asImp_().shouldWriteOutput()) { - if (verbose && gridView().comm().rank() == 0) - std::cout << "Writing result file for \"" << asImp_().name() << "\"\n"; - - // calculate the time _after_ the time was updated - Scalar t = timeManager().time() + timeManager().timeStepSize(); - createResultWriter_(); - resultWriter_->beginWrite(t); - model().addOutputVtkFields(model().curSol(), *resultWriter_); - asImp_().addOutputVtkFields(); - resultWriter_->endWrite(); - } - } - -protected: - //! Returns the implementation of the problem (i.e. static polymorphism) - Implementation &asImp_() - { return *static_cast<Implementation *>(this); } - - //! \copydoc asImp_() - const Implementation &asImp_() const - { return *static_cast<const Implementation *>(this); } - - //! Returns the applied VTK-writer for the output - VtkMultiWriter& resultWriter() - { - createResultWriter_(); - return *resultWriter_; - } - //! \copydoc Dumux::IMPETProblem::resultWriter() - VtkMultiWriter& resultWriter() const - { - createResultWriter_(); - return *resultWriter_; - } - - -private: - // makes sure that the result writer exists - void createResultWriter_() - { if (!resultWriter_) resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name()); }; - - std::string simName_; - const GridView gridView_; - - GlobalPosition bboxMin_; - GlobalPosition bboxMax_; - - ElementMapper elementMapper_; - VertexMapper vertexMapper_; - - TimeManager *timeManager_; - - Model model_; - - NewtonMethod newtonMethod_; - NewtonController newtonCtl_; - - VtkMultiWriter *resultWriter_; -}; - -} - -#endif +#include <dumux/implicit/box/boxproblem.hh> diff --git a/dumux/boxmodels/common/boxproperties.hh b/dumux/boxmodels/common/boxproperties.hh index 9fd7fffa05baccd592c719d7b8a1b22552dbda67..93714edda517bbc167963c2e3dac13e5ebfbe6c9 100644 --- a/dumux/boxmodels/common/boxproperties.hh +++ b/dumux/boxmodels/common/boxproperties.hh @@ -1,142 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_BOX_PROPERTIES_HH -#define DUMUX_BOX_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/box/boxproperties.hh instead. -#include <dumux/common/propertysystem.hh> - -#include <dumux/common/basicproperties.hh> -#include <dumux/linear/linearsolverproperties.hh> -#include <dumux/nonlinear/newtonmethod.hh> - -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup BoxModel - * \file - * \brief Specify the shape functions, operator assemblers, etc - * used for the BoxModel. - */ -namespace Dumux -{ - -namespace Properties -{ -/*! - * \ingroup BoxModel - */ -// \{ - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for models based on the box-scheme -NEW_TYPE_TAG(BoxModel, INHERITS_FROM(NewtonMethod, LinearSolverTypeTag, ImplicitModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(Grid); //!< The type of the DUNE grid -NEW_PROP_TAG(GridView); //!< The type of the grid view - -NEW_PROP_TAG(FVElementGeometry); //! The type of the finite-volume geometry in the box scheme -NEW_PROP_TAG(EvalGradientsAtSCVCenter); //! Evaluate shape function gradients additionally at the sub-control volume center - -NEW_PROP_TAG(Problem); //!< The type of the problem -NEW_PROP_TAG(BaseModel); //!< The type of the base class of the model -NEW_PROP_TAG(Model); //!< The type of the model -NEW_PROP_TAG(NumEq); //!< Number of equations in the system of PDEs -NEW_PROP_TAG(BaseLocalResidual); //!< The type of the base class of the local residual -NEW_PROP_TAG(LocalResidual); //!< The type of the local residual function -NEW_PROP_TAG(LocalJacobian); //!< The type of the local jacobian operator - -NEW_PROP_TAG(JacobianAssembler); //!< Assembles the global jacobian matrix -NEW_PROP_TAG(JacobianMatrix); //!< Type of the global jacobian matrix -NEW_PROP_TAG(BoundaryTypes); //!< Stores the boundary types of a single degree of freedom -NEW_PROP_TAG(ElementBoundaryTypes); //!< Stores the boundary types on an element - -NEW_PROP_TAG(PrimaryVariables); //!< A vector of primary variables within a sub-control volume -NEW_PROP_TAG(SolutionVector); //!< Vector containing all primary variable vector of the grid -NEW_PROP_TAG(ElementSolutionVector); //!< A vector of primary variables within a sub-control volume - -NEW_PROP_TAG(VolumeVariables); //!< The secondary variables within a sub-control volume -NEW_PROP_TAG(ElementVolumeVariables); //!< The secondary variables of all sub-control volumes in an element -NEW_PROP_TAG(FluxVariables); //!< Data required to calculate a flux over a face -NEW_PROP_TAG(BoundaryVariables); //!< Data required to calculate fluxes over boundary faces (outflow) - -// high level simulation control -NEW_PROP_TAG(TimeManager); //!< Manages the simulation time -NEW_PROP_TAG(NewtonMethod); //!< The type of the newton method -NEW_PROP_TAG(NewtonController); //!< The type of the newton controller - -//! Specify whether the jacobian matrix of the last iteration of a -//! time step should be re-used as the jacobian of the first iteration -//! of the next time step. -NEW_PROP_TAG(ImplicitEnableJacobianRecycling); - -//! Specify whether the jacobian matrix should be only reassembled for -//! elements where at least one vertex is above the specified -//! tolerance -NEW_PROP_TAG(ImplicitEnablePartialReassemble); -/*! - * \brief Specify the maximum size of a time integration [s]. - * - * The default is to not limit the step size. - */ -NEW_PROP_TAG(TimeManagerMaxTimeStepSize); - -/*! - * \brief Specify which kind of method should be used to numerically - * calculate the partial derivatives of the residual. - * - * -1 means backward differences, 0 means central differences, 1 means - * forward differences. By default we use central differences. - */ -NEW_PROP_TAG(ImplicitNumericDifferenceMethod); - -/*! - * \brief Specify whether to use the already calculated solutions as - * starting values of the volume variables. - * - * This only makes sense if the calculation of the volume variables is - * very expensive (e.g. for non-linear fugacity functions where the - * solver converges faster). - */ -NEW_PROP_TAG(ImplicitEnableHints); - -//! indicates whether two-point flux should be used -NEW_PROP_TAG(ImplicitUseTwoPointFlux); - -// mappers from local to global indices - -//! maper for vertices -NEW_PROP_TAG(VertexMapper); -//! maper for elements -NEW_PROP_TAG(ElementMapper); -//! maper for degrees of freedom -NEW_PROP_TAG(DofMapper); - -} -} - -// \} - -#endif +#include <dumux/implicit/box/boxproperties.hh> diff --git a/dumux/boxmodels/common/boxpropertydefaults.hh b/dumux/boxmodels/common/boxpropertydefaults.hh index 50ec31e2c739645f2125237261153b82f95a6dfd..1b1a8fb08f043b9dcc84e412f2aac859ec3f0a12 100644 --- a/dumux/boxmodels/common/boxpropertydefaults.hh +++ b/dumux/boxmodels/common/boxpropertydefaults.hh @@ -1,207 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup BoxModel - * \file - * - * \brief Default properties for box models - */ -#ifndef DUMUX_BOX_PROPERTY_DEFAULTS_HH -#define DUMUX_BOX_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/box/boxpropertydefaults.hh instead. -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> - -#include "boxassembler.hh" -#include "boxmodel.hh" -#include "boxfvelementgeometry.hh" -#include "boxelementboundarytypes.hh" -#include "boxlocaljacobian.hh" -#include "boxlocalresidual.hh" -#include "boxelementvolumevariables.hh" -#include "boxvolumevariables.hh" - -#include <dumux/common/boundarytypes.hh> -#include <dumux/common/timemanager.hh> - -#include "boxproperties.hh" - -#include <limits> - -namespace Dumux { - -// forward declaration -template<class TypeTag> -class BoxModel; - -namespace Properties { -////////////////////////////////////////////////////////////////// -// Some defaults for very fundamental properties -////////////////////////////////////////////////////////////////// - -//! Set the default type for the time manager -SET_TYPE_PROP(BoxModel, TimeManager, Dumux::TimeManager<TypeTag>); - -////////////////////////////////////////////////////////////////// -// Properties -////////////////////////////////////////////////////////////////// - -//! Use the leaf grid view if not defined otherwise -SET_TYPE_PROP(BoxModel, - GridView, - typename GET_PROP_TYPE(TypeTag, Grid)::LeafGridView); - -//! Set the default for the FVElementGeometry -SET_TYPE_PROP(BoxModel, FVElementGeometry, Dumux::BoxFVElementGeometry<TypeTag>); - -//! Disable evaluation of shape function gradients at the sub-control volume center by default -// The shape function gradients at the sub-control volume center are currently only -// needed for the stokes and the linear elastic models -SET_BOOL_PROP(BoxModel, EvalGradientsAtSCVCenter, false); - -//! Set the default for the ElementBoundaryTypes -SET_TYPE_PROP(BoxModel, ElementBoundaryTypes, Dumux::BoxElementBoundaryTypes<TypeTag>); - -//! use the plain newton method for the box scheme by default -SET_TYPE_PROP(BoxModel, NewtonMethod, Dumux::NewtonMethod<TypeTag>); - -//! use the plain newton controller for the box scheme by default -SET_TYPE_PROP(BoxModel, NewtonController, Dumux::NewtonController<TypeTag>); - -//! Mapper for the grid view's vertices. -SET_TYPE_PROP(BoxModel, - VertexMapper, - Dune::MultipleCodimMultipleGeomTypeMapper<typename GET_PROP_TYPE(TypeTag, GridView), - Dune::MCMGVertexLayout>); - -//! Mapper for the grid view's elements. -SET_TYPE_PROP(BoxModel, - ElementMapper, - Dune::MultipleCodimMultipleGeomTypeMapper<typename GET_PROP_TYPE(TypeTag, GridView), - Dune::MCMGElementLayout>); - -//! Mapper for the degrees of freedoms. -SET_TYPE_PROP(BoxModel, DofMapper, typename GET_PROP_TYPE(TypeTag, VertexMapper)); - -//! Set the BaseLocalResidual to BoxLocalResidual -SET_TYPE_PROP(BoxModel, BaseLocalResidual, Dumux::BoxLocalResidual<TypeTag>); - -//! Set the BaseModel to BoxModel -SET_TYPE_PROP(BoxModel, BaseModel, Dumux::BoxModel<TypeTag>); - -//! The local jacobian operator for the box scheme -SET_TYPE_PROP(BoxModel, LocalJacobian, Dumux::BoxLocalJacobian<TypeTag>); - -/*! - * \brief The type of a solution for the whole grid at a fixed time. - */ -SET_TYPE_PROP(BoxModel, - SolutionVector, - Dune::BlockVector<typename GET_PROP_TYPE(TypeTag, PrimaryVariables)>); - -/*! - * \brief The type of a solution for a whole element. - */ -SET_TYPE_PROP(BoxModel, - ElementSolutionVector, - Dune::BlockVector<typename GET_PROP_TYPE(TypeTag, PrimaryVariables)>); - -/*! - * \brief A vector of primary variables. - */ -SET_TYPE_PROP(BoxModel, - PrimaryVariables, - Dune::FieldVector<typename GET_PROP_TYPE(TypeTag, Scalar), - GET_PROP_VALUE(TypeTag, NumEq)>); - -/*! - * \brief The volume variable class. - * - * This should almost certainly be overloaded by the model... - */ -SET_TYPE_PROP(BoxModel, VolumeVariables, Dumux::BoxVolumeVariables<TypeTag>); - -/*! - * \brief An array of secondary variable containers. - */ -SET_TYPE_PROP(BoxModel, ElementVolumeVariables, Dumux::BoxElementVolumeVariables<TypeTag>); - -/*! - * \brief Boundary types at a single degree of freedom. - */ -SET_TYPE_PROP(BoxModel, - BoundaryTypes, - Dumux::BoundaryTypes<GET_PROP_VALUE(TypeTag, NumEq)>); - -/*! - * \brief Assembler for the global jacobian matrix. - */ -SET_TYPE_PROP(BoxModel, JacobianAssembler, Dumux::BoxAssembler<TypeTag>); - -//! use an unlimited time step size by default -SET_SCALAR_PROP(BoxModel, TimeManagerMaxTimeStepSize, 1e100); - -//! use forward differences to calculate the jacobian by default -SET_INT_PROP(BoxModel, ImplicitNumericDifferenceMethod, +1); - -//! do not use hints by default -SET_BOOL_PROP(BoxModel, ImplicitEnableHints, false); - -// disable jacobian matrix recycling by default -SET_BOOL_PROP(BoxModel, ImplicitEnableJacobianRecycling, false); - -// disable partial reassembling by default -SET_BOOL_PROP(BoxModel, ImplicitEnablePartialReassemble, false); - -// disable two-point-flux by default -SET_BOOL_PROP(BoxModel, ImplicitUseTwoPointFlux, false); - -//! Set the type of a global jacobian matrix from the solution types -SET_PROP(BoxModel, JacobianMatrix) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) }; - typedef typename Dune::FieldMatrix<Scalar, numEq, numEq> MatrixBlock; -public: - typedef typename Dune::BCRSMatrix<MatrixBlock> type; -}; - -// use the stabilized BiCG solver preconditioned by the ILU-0 by default -SET_TYPE_PROP(BoxModel, LinearSolver, Dumux::BoxBiCGStabILU0Solver<TypeTag> ); - -// if the deflection of the newton method is large, we do not -// need to solve the linear approximation accurately. Assuming -// that the initial value for the delta vector u is quite -// close to the final value, a reduction of 6 orders of -// magnitude in the defect should be sufficient... -SET_SCALAR_PROP(BoxModel, LinearSolverResidualReduction, 1e-6); - -//! set the default number of maximum iterations for the linear solver -SET_INT_PROP(BoxModel, LinearSolverMaxIterations, 250); - -//! set number of equations of the mathematical model as default -SET_INT_PROP(BoxModel, LinearSolverBlockSize, GET_PROP_VALUE(TypeTag, NumEq)); - -} // namespace Properties -} // namespace Dumux - -#endif +#include <dumux/implicit/box/boxpropertydefaults.hh> diff --git a/dumux/boxmodels/common/boxvolumevariables.hh b/dumux/boxmodels/common/boxvolumevariables.hh index 0c0bb6d8f6516e166c31d4ffce1e3613c52be5a1..2044415b8271f31f186cf715d4e32da010aef972 100644 --- a/dumux/boxmodels/common/boxvolumevariables.hh +++ b/dumux/boxmodels/common/boxvolumevariables.hh @@ -1,190 +1,3 @@ -// -*- 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 Base class for the model specific class which provides - * access to all volume averaged quantities. - */ -#ifndef DUMUX_BOX_VOLUME_VARIABLES_HH -#define DUMUX_BOX_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/box/boxvolumevariables.hh instead. -#include "boxproperties.hh" - -#include <dumux/common/valgrind.hh> - -namespace Dumux -{ - -/*! - * \ingroup BoxModel - * \ingroup BoxVolumeVariables - * \brief Base class for the model specific class which provides - * access to all volume averaged quantities. - */ -template <class TypeTag> -class BoxVolumeVariables -{ - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - -public: - // default constructor - BoxVolumeVariables() - { evalPoint_ = 0; }; - - // copy constructor - BoxVolumeVariables(const BoxVolumeVariables &v) - { - evalPoint_ = 0; - priVars_ = v.priVars_; - extrusionFactor_ = v.extrusionFactor_; - }; - - /*! - * \brief Assignment operator - */ - BoxVolumeVariables &operator=(const BoxVolumeVariables &v) - { - evalPoint_ = 0; - priVars_ = v.priVars_; - extrusionFactor_ = v.extrusionFactor_; - - return *this; - }; - - /*! - * \brief Sets the evaluation point used by the local jacobian. - * - * The evaluation point is only used by semi-smooth models. - */ - void setEvalPoint(const Implementation *ep) - { - evalPoint_ = ep; - Valgrind::CheckDefined(evalPoint_); - } - - /*! - * \brief Returns the evaluation point used by the local jacobian. - * - * The evaluation point is only used by semi-smooth models. - */ - const Implementation &evalPoint() const - { return (evalPoint_ == 0)?asImp_():*evalPoint_; } - - /*! - * \brief Set the volume variables which should be used as initial - * conditions for complex calculations. - */ - void setHint(const Implementation *hint) - {}; - - /*! - * \brief Update all quantities for a given control volume - * - * \param priVars A vector containing the primary variables for the control volume - * \param problem The object specifying the problem which ought to - * be simulated - * \param element An element which contains part of the control volume - * \param fvGeometry The finite volume geometry for the element - * \param scvIdx Local index of the sub control volume which is inside the element - * \param isOldSol Specifies whether this is the previous solution or the current one - * - * \todo Eliminate the 'isOldSol' parameter. This implies that the - * 'pseudo-primary variables' must be somehow be stored - * inside the PrimaryVariables. (e.g. we need to know the - * phase state in the 2p2c model) - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { - Valgrind::CheckDefined(priVars); - priVars_ = priVars; - extrusionFactor_ = problem.boxExtrusionFactor(element, fvGeometry, scvIdx); - } - - /*! - * \brief Return the vector of primary variables - */ - const PrimaryVariables &priVars() const - { return priVars_; } - - /*! - * \brief Return a component of primary variable vector - * - * \param pvIdx The index of the primary variable of interest - */ - Scalar priVar(const int pvIdx) const - { - return priVars_[pvIdx]; - } - - /*! - * \brief Return how much the sub-control volume is extruded. - * - * This means the factor by which a lower-dimensional (1D or 2D) - * entity needs to be expanded to get a full dimensional cell. The - * default is 1.0 which means that 1D problems are actually - * thought as pipes with a cross section of 1 m^2 and 2D problems - * are assumed to extend 1 m to the back. - */ - Scalar extrusionFactor() const - { return extrusionFactor_; } - - /*! - * \brief If running in valgrind this makes sure that all - * quantities in the volume variables are defined. - */ - void checkDefined() const - { -#if !defined NDEBUG && HAVE_VALGRIND - Valgrind::CheckDefined(priVars_); - Valgrind::CheckDefined(evalPoint_); - if (evalPoint_ && evalPoint_ != this) - evalPoint_->checkDefined(); -#endif - }; - -protected: - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - // the evaluation point of the local jacobian - const Implementation *evalPoint_; - - PrimaryVariables priVars_; - Scalar extrusionFactor_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/box/boxvolumevariables.hh> diff --git a/dumux/boxmodels/common/intersectiontovertexbc.hh b/dumux/boxmodels/common/intersectiontovertexbc.hh index f57fddb43478d9a7a55c6d708dd07a2f46f02851..308f35e497312c6a3f698cf81a967c67ad7ed5a9 100644 --- a/dumux/boxmodels/common/intersectiontovertexbc.hh +++ b/dumux/boxmodels/common/intersectiontovertexbc.hh @@ -1,112 +1,3 @@ -/***************************************************************************** - * Copyright (C) 2010 by Bernd Flemisch * - * Institute for Modelling Hydraulic and Environmental Systems * - * University of Stuttgart, Germany * - * email: <givenname>.<name>@iws.uni-stuttgart.de * - * * - * 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 Base class for all problems which use the box scheme - */ -#ifndef DUMUX_INTERSECTIONTOVERTEXBC_HH -#define DUMUX_INTERSECTIONTOVERTEXBC_HH - -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ - -template<typename TypeTag> -class IntersectionToVertexBC -{ - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - - enum { - numEq = GET_PROP_VALUE(TypeTag, NumEq), - dim = GridView::dimension, - }; - - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::IntersectionIterator IntersectionIterator; - typedef typename GridView::template Codim<dim>::Entity Vertex; - - typedef typename Dune::GenericReferenceElements<Scalar, dim> ReferenceElements; - typedef typename Dune::GenericReferenceElement<Scalar, dim> ReferenceElement; - -public: - IntersectionToVertexBC(const Problem& problem) - : problem_(problem) - { - vertexBC.resize(problem.vertexMapper().size()); - for (int vertIdx = 0; vertIdx < vertexBC.size(); vertIdx++) - vertexBC[vertIdx].setAllNeumann(); - - ElementIterator eIt = problem.gridView().template begin<0>(); - const ElementIterator elemEndIt = problem.gridView().template end<0>(); - for (; eIt != elemEndIt; ++eIt) { - Dune::GeometryType geoType = eIt->geometry().type(); - const ReferenceElement &refElem = ReferenceElements::general(geoType); - - IntersectionIterator isIt = problem.gridView().ibegin(*eIt); - IntersectionIterator isEndIt = problem.gridView().iend(*eIt); - for (; isIt != isEndIt; ++isIt) { - if (!isIt->boundary()) - continue; - - BoundaryTypes bcTypes; - problem.boundaryTypes(bcTypes, *isIt); - - if (!bcTypes.hasDirichlet()) - continue; - - int faceIdx = isIt->indexInInside(); - int numFaceVerts = refElem.size(faceIdx, 1, dim); - for (int faceVertIdx = 0; faceVertIdx < numFaceVerts; ++faceVertIdx) - { - int elemVertIdx = refElem.subEntity(faceIdx, 1, faceVertIdx, dim); - int globalVertIdx = problem.vertexMapper().map(*eIt, elemVertIdx, dim); - - for (int eqIdx = 0; eqIdx < numEq; eqIdx++) - if (bcTypes.isDirichlet(eqIdx)) - vertexBC[globalVertIdx].setDirichlet(eqIdx); - } - } - } - } - - void boundaryTypes(BoundaryTypes& values, const Vertex& vertex) const - { - values.setAllNeumann(); - - int vertIdx = problem_.vertexMapper().map(vertex); - const BoundaryTypes& bcTypes = vertexBC[vertIdx]; - - for (int eqIdx = 0; eqIdx < numEq; eqIdx++) - if (bcTypes.isDirichlet(eqIdx)) - values.setDirichlet(eqIdx); - } - -private: - const Problem& problem_; - std::vector<BoundaryTypes> vertexBC; -}; -} - -#endif +#warning This file is deprecated. Include dumux/implicit/box/intersectiontovertexbc.hh instead. +#include <dumux/implicit/box/intersectiontovertexbc.hh> diff --git a/dumux/boxmodels/common/porousmediaboxproblem.hh b/dumux/boxmodels/common/porousmediaboxproblem.hh index 151f953703dda7486e0b29b1cc9f5cf5fa8014e2..e253d280d008ddee741a9547461c85717b6b2345 100644 --- a/dumux/boxmodels/common/porousmediaboxproblem.hh +++ b/dumux/boxmodels/common/porousmediaboxproblem.hh @@ -1,197 +1,3 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * 2012 by Bernd Flemisch * - * 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 Base class for all problems which use the two-phase box model - */ -#ifndef DUMUX_POROUS_MEDIA_BOX_PROBLEM_HH -#define DUMUX_POROUS_MEDIA_BOX_PROBLEM_HH +#warning This file is deprecated. Include dumux/implicit/box/porousmediaboxproblem.hh instead. -#include "boxproperties.hh" - -#include <dumux/boxmodels/common/boxproblem.hh> - -namespace Dumux -{ -namespace Properties -{ -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters object -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -} - -/*! - * \ingroup BoxBaseProblems - * \brief Base class for all porous media box problems - */ -template<class TypeTag> -class PorousMediaBoxProblem : public BoxProblem<TypeTag> -{ - typedef BoxProblem<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - enum { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GridView::ctype CoordScalar; - typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dim> DimVector; - -public: - /*! - * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view - * \param verbose Turn verbosity on or off - */ - PorousMediaBoxProblem(TimeManager &timeManager, - const GridView &gridView, - const bool verbose = true) - : ParentType(timeManager, gridView), - gravity_(0) - { - newSpatialParams_ = true; - spatialParams_ = new SpatialParams(gridView); - - if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, EnableGravity)) - gravity_[dim-1] = -9.81; - } - - ~PorousMediaBoxProblem() - { - if (newSpatialParams_) - delete spatialParams_; - } - - /*! - * \name Problem parameters - */ - // \{ - - /*! - * \brief Returns the temperature \f$\mathrm{[K]}\f$ within a control volume. - * - * This is the discretization specific interface for the box - * method. By default it just calls temperature(pos). - * - * \param element The DUNE Codim<0> enitiy which intersects with - * the finite volume. - * \param fvGeometry The finite volume geometry of the element. - * \param scvIdx The local index of the sub control volume inside the element - */ - Scalar boxTemperature(const Element &element, - const FVElementGeometry fvGeometry, - const int scvIdx) const - { return asImp_().temperatureAtPos(fvGeometry.subContVol[scvIdx].global); } - - /*! - * \brief Returns the temperature \f$\mathrm{[K]}\f$ at a given global position. - * - * This is not specific to the discretization. By default it just - * calls temperature(). - * - * \param pos The position in global coordinates where the temperature should be specified. - */ - Scalar temperatureAtPos(const GlobalPosition &pos) const - { return asImp_().temperature(); } - - /*! - * \brief Returns the temperature \f$\mathrm{[K]}\f$ for an isothermal problem. - * - * This is not specific to the discretization. By default it just - * throws an exception so it must be overloaded by the problem if - * no energy equation is used. - */ - Scalar temperature() const - { DUNE_THROW(Dune::NotImplemented, "temperature() method not implemented by the actual problem"); }; - - /*! - * \brief Returns the acceleration due to gravity \f$\mathrm{[m/s^2]}\f$. - * - * This is the box discretization specific interface. By default - * it just calls gravityAtPos(). - */ - const DimVector &boxGravity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { return asImp_().gravityAtPos(fvGeometry.subContVol[scvIdx].global); } - - /*! - * \brief Returns the acceleration due to gravity \f$\mathrm{[m/s^2]}\f$. - * - * This is discretization independent interface. By default it - * just calls gravity(). - */ - const DimVector &gravityAtPos(const GlobalPosition &pos) const - { return asImp_().gravity(); } - - /*! - * \brief Returns the acceleration due to gravity \f$\mathrm{[m/s^2]}\f$. - * - * This method is used for problems where the gravitational - * acceleration does not depend on the spatial position. The - * default behaviour is that if the <tt>EnableGravity</tt> - * property is true, \f$\boldsymbol{g} = ( 0,\dots,\ -9.81)^T \f$ holds, - * else \f$\boldsymbol{g} = ( 0,\dots, 0)^T \f$. - */ - const DimVector &gravity() const - { return gravity_; } - - /*! - * \brief Returns the spatial parameters object. - */ - SpatialParams &spatialParams() - { return *spatialParams_; } - - /*! - * \brief Returns the spatial parameters object. - */ - const SpatialParams &spatialParams() const - { return *spatialParams_; } - - // \} - -protected: - //! Returns the implementation of the problem (i.e. static polymorphism) - Implementation &asImp_() - { return *static_cast<Implementation *>(this); } - //! \copydoc asImp_() - const Implementation &asImp_() const - { return *static_cast<const Implementation *>(this); } - - DimVector gravity_; - - // fluids and material properties - SpatialParams* spatialParams_; - bool newSpatialParams_; -}; - -} - -#endif +#include <dumux/implicit/box/porousmediaboxproblem.hh> diff --git a/dumux/boxmodels/mpnc/diffusion/diffusion.hh b/dumux/boxmodels/mpnc/diffusion/diffusion.hh index 1df1d41a50172aef8a5a14862e3fbcbec38f9f37..49acbfbbffdc26bb7ce157d966585b16ac7343f2 100644 --- a/dumux/boxmodels/mpnc/diffusion/diffusion.hh +++ b/dumux/boxmodels/mpnc/diffusion/diffusion.hh @@ -1,150 +1,3 @@ -// -*- 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 This file contains parts to calculate the diffusive flux in - * the fully coupled two-phase N-component model - */ -#ifndef DUMUX_MPNC_DIFFUSION_HH -#define DUMUX_MPNC_DIFFUSION_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/diffusion/diffusion.hh instead. -#include <dune/common/fmatrix.hh> -#include <dune/common/fvector.hh> - -#include <dumux/boxmodels/mpnc/mpncproperties.hh> - -namespace Dumux { - -template <class TypeTag, bool enableDiffusion> -class MPNCDiffusion -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents)}; - enum { nPhaseIdx = FluidSystem::nPhaseIdx }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef Dune::FieldMatrix<Scalar, numComponents, numComponents> ComponentMatrix; - typedef Dune::FieldVector<Scalar, numComponents> ComponentVector; - -public: - static void flux(ComponentVector &fluxes, - const unsigned int phaseIdx, - const FluxVariables &fluxVars, - const Scalar molarDensity) - { - if (phaseIdx == nPhaseIdx) - gasFlux_(fluxes, fluxVars, molarDensity); - else if (phaseIdx == wPhaseIdx){ - #if MACROSCALE_DIFFUSION_ONLY_GAS - return ; // in the case that only the diffusion in the gas phase is considered, the liquidFlux should not be called - #endif - liquidFlux_(fluxes, fluxVars, molarDensity); - } - else - DUNE_THROW(Dune::InvalidStateException, - "Invalid phase index: " << phaseIdx); - } - -protected: - static void liquidFlux_(ComponentVector &fluxes, - const FluxVariables &fluxVars, - const Scalar molarDensity) - { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - // TODO: tensorial diffusion coefficients - const Scalar xGrad = fluxVars.moleFractionGrad(wPhaseIdx, compIdx)*fluxVars.face().normal; - fluxes[compIdx] = - - xGrad * - molarDensity * - fluxVars.face().normal.two_norm() * // because we want a mole flux and not an area specific flux - fluxVars.porousDiffCoeffL(compIdx) ; - } - } - - static void gasFlux_(ComponentVector &fluxes, - const FluxVariables &fluxVars, - const Scalar molarDensity) - { - // Stefan-Maxwell equation - // - // See: R. Reid, et al.: "The Properties of Liquids and - // Gases", 4th edition, 1987, McGraw-Hill, p 596 - - // TODO: tensorial diffusion coefficients - ComponentMatrix M(0); - - for (int compIIdx = 0; compIIdx < numComponents - 1; ++compIIdx) { - for (int compJIdx = 0; compJIdx < numComponents; ++compJIdx) { - Scalar Dij = fluxVars.porousDiffCoeffG(compIIdx, compJIdx); - if (Dij) { - M[compIIdx][compJIdx] += fluxVars.moleFraction(nPhaseIdx, compIIdx) / Dij; - M[compIIdx][compIIdx] -= fluxVars.moleFraction(nPhaseIdx, compJIdx) / Dij; - } - } - } - - for (int compIIdx = 0; compIIdx < numComponents; ++compIIdx) { - M[numComponents - 1][compIIdx] = 1.0; - } - - ComponentVector rightHandSide ; // see source cited above - for (int compIIdx = 0; compIIdx < numComponents - 1; ++compIIdx) { - rightHandSide[compIIdx] = molarDensity*(fluxVars.moleFractionGrad(nPhaseIdx, compIIdx)*fluxVars.face().normal); - } - rightHandSide[numComponents - 1] = 0.0; - - M.solve(fluxes, rightHandSide); - } - - // return whether a concentration can be assumed to be a trace - // component in the context of diffusion - static Scalar isTraceComp_(Scalar x) - { return x < 0.5/numComponents; } -}; - -/*! - * \brief Specialization of the diffusion module for the case where - * diffusion is disabled. - * - * This class just does nothing. - */ -template <class TypeTag> -class MPNCDiffusion<TypeTag, false> -{ - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef Dune::FieldVector<Scalar, numComponents> ComponentVector; - -public: - static void flux(ComponentVector &fluxes, - const unsigned int phaseIdx, - const FluxVariables &fluxVars, - const Scalar molarDensity) - { fluxes = 0; } -}; - -} - -#endif // DUMUX_MPNC_DIFFUSION_HH +#include <dumux/implicit/mpnc/diffusion/diffusion.hh> diff --git a/dumux/boxmodels/mpnc/diffusion/fluxvariables.hh b/dumux/boxmodels/mpnc/diffusion/fluxvariables.hh index 7ed8570e087336f5ca7462db18b079209af1e1ed..2d58e9dba03c3b2d28ddecc7bbf1ed88340b7f0d 100644 --- a/dumux/boxmodels/mpnc/diffusion/fluxvariables.hh +++ b/dumux/boxmodels/mpnc/diffusion/fluxvariables.hh @@ -1,221 +1,3 @@ -// -*- 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 This file contains the diffusion module for the flux data of - * the fully coupled two-phase N-component model - */ -#ifndef DUMUX_MPNC_DIFFUSION_FLUX_VARIABLES_HH -#define DUMUX_MPNC_DIFFUSION_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/diffusion/fluxvariables.hh instead. -#include <dune/common/fvector.hh> - -#include "../mpncproperties.hh" - -namespace Dumux { - -template<class TypeTag, bool enableDiffusion> -class MPNCFluxVariablesDiffusion -{ - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - - enum{dim = GridView::dimension}; - enum{numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - enum{numComponents = GET_PROP_VALUE(TypeTag, NumComponents)}; - enum{wPhaseIdx = FluidSystem::wPhaseIdx}; - enum{nPhaseIdx = FluidSystem::nPhaseIdx}; - - typedef Dune::FieldVector<Scalar, dim> DimVector; - -public: - MPNCFluxVariablesDiffusion() - {} - - void update(const Problem & problem, - const Element & element, - const FVElementGeometry & fvGeometry, - const SCVFace & face, - const ElementVolumeVariables & elemVolVars) - { - const unsigned int i = face.i; - const unsigned int j = face.j; - - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx){ - for (int compIdx = 0; compIdx < numComponents; ++compIdx){ - moleFraction_[phaseIdx][compIdx] = 0. ; - moleFractionGrad_[phaseIdx][compIdx] = 0. ; - } - } - - - DimVector tmp ; - for (int idx = 0; - idx < fvGeometry.numFAP; - idx++) // loop over adjacent vertices - { - // FE gradient at vertex idx - const DimVector & feGrad = face.grad[idx]; - - // index for the element volume variables - int volVarsIdx = face.fapIndices[idx]; - - for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++){ - for (int compIdx = 0; compIdx < numComponents; ++compIdx){ - - // calculate mole fractions at the integration points of the face - moleFraction_[phaseIdx][compIdx] += elemVolVars[volVarsIdx].fluidState().moleFraction(phaseIdx, compIdx)* - face.shapeValue[idx]; - - // calculate mole fraction gradients - tmp = feGrad; - tmp *= elemVolVars[volVarsIdx].fluidState().moleFraction(phaseIdx, compIdx); - moleFractionGrad_[phaseIdx][compIdx] += tmp; - } - } - } - - // initialize the diffusion coefficients to zero - for (int i = 0; i < numComponents; ++i) { - porousDiffCoeffL_[i] = 0.0; - for (int j = 0; j < numComponents; ++j) - porousDiffCoeffG_[i][j] = 0.0; - } - - // calculate the diffusion coefficients at the integration - // point in the porous medium - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // make sure to only calculate diffusion coefficents - // for phases which exist in both finite volumes - if (elemVolVars[i].fluidState().saturation(phaseIdx) <= 1e-4 || - elemVolVars[j].fluidState().saturation(phaseIdx) <= 1e-4) - { - continue; - } - - // reduction factor for the diffusion coefficients in the - // porous medium in nodes i and j. this is the tortuosity - // times porosity times phase saturation at the nodes i - // and j - // - // TODO (?): move this calculation to the soil (possibly - // that's a bad idea, though) - Scalar red_i = - elemVolVars[i].fluidState().saturation(phaseIdx)/elemVolVars[i].porosity() * - pow(elemVolVars[i].porosity() * elemVolVars[i].fluidState().saturation(phaseIdx), 7.0/3); - Scalar red_j = - elemVolVars[j].fluidState().saturation(phaseIdx)/elemVolVars[j].porosity() * - pow(elemVolVars[j].porosity() * elemVolVars[j].fluidState().saturation(phaseIdx), 7.0/3); - - if (phaseIdx == wPhaseIdx) { - // Liquid phase diffusion coefficients in the porous medium - for (int i = 0; i < numComponents; ++i) { - // -> arithmetic mean - porousDiffCoeffL_[i] - = 1./2*(red_i * elemVolVars[i].diffCoeff(wPhaseIdx, 0, i) + - red_j * elemVolVars[j].diffCoeff(wPhaseIdx, 0, i)); - } - } - else { - // Gas phase diffusion coefficients in the porous medium - for (int i = 0; i < numComponents; ++i) { - for (int j = 0; j < numComponents; ++j) { - // -> arithmetic mean - porousDiffCoeffG_[i][j] - = 1./2*(red_i * elemVolVars[i].diffCoeff(nPhaseIdx, i, j) + - red_j * elemVolVars[j].diffCoeff(nPhaseIdx, i, j)); - } - } - } - } - } - - Scalar porousDiffCoeffL(const unsigned int compIdx) const - { - // TODO: tensorial diffusion coefficients - return porousDiffCoeffL_[compIdx]; - } - - Scalar porousDiffCoeffG(const unsigned int compIIdx, - const unsigned int compJIdx) const - { - // TODO: tensorial diffusion coefficients - return porousDiffCoeffG_[compIIdx][compJIdx]; - } - - Scalar moleFraction(const unsigned int phaseIdx, - const unsigned int compIdx) const - { return moleFraction_[phaseIdx][compIdx]; } - - const DimVector &moleFractionGrad(const unsigned int phaseIdx, - const unsigned int compIdx) const - { return moleFractionGrad_[phaseIdx][compIdx];} - -protected: - // the diffusion coefficients for the porous medium for the - // liquid phase - Scalar porousDiffCoeffL_[numComponents]; - - // the diffusion coefficients for the porous medium for the - // gas phase - Scalar porousDiffCoeffG_[numComponents][numComponents]; - - // the concentration gradients of all components in all phases - DimVector moleFractionGrad_[numPhases][numComponents]; - - // the mole fractions of each component at the integration point - Scalar moleFraction_[numPhases][numComponents]; -}; - - -template<class TypeTag> -class MPNCFluxVariablesDiffusion<TypeTag, false> -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - MPNCFluxVariablesDiffusion() - {} - - void update(const Problem & problem, - const Element & element, - const FVElementGeometry & fvGeometry, - const SCVFace & face, - const ElementVolumeVariables & elemVolVars) - { - } -}; - -} - -#endif // DUMUX_MPNC_DIFFUSION_FLUX_VARIABLES_HH +#include <dumux/implicit/mpnc/diffusion/fluxvariables.hh> diff --git a/dumux/boxmodels/mpnc/diffusion/volumevariables.hh b/dumux/boxmodels/mpnc/diffusion/volumevariables.hh index 6c7e523467e97edc541f925442bde60da7dcfc77..d74791045b079a435dc8afacca621f97ab03ac1b 100644 --- a/dumux/boxmodels/mpnc/diffusion/volumevariables.hh +++ b/dumux/boxmodels/mpnc/diffusion/volumevariables.hh @@ -1,164 +1,3 @@ -// -*- 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 This file contains the diffusion module for the vertex data - * of the fully coupled two-phase N-component model - */ -#ifndef DUMUX_MPNC_DIFFUSION_VOLUME_VARIABLES_HH -#define DUMUX_MPNC_DIFFUSION_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/diffusion/volumevariables.hh instead. -#include <dumux/common/valgrind.hh> -#include <dumux/boxmodels/mpnc/mpncproperties.hh> - -namespace Dumux { - -template<class TypeTag, bool enableDiffusion> -class MPNCVolumeVariablesDiffusion -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - enum { nPhaseIdx = FluidSystem::nPhaseIdx }; - -public: - - MPNCVolumeVariablesDiffusion() - {} - - void update(FluidState &fluidState, - ParameterCache ¶mCache, - const VolumeVariables &volVars, - const Problem &problem) - { - Valgrind::SetUndefined(*this); - - // diffusion coefficents in liquid - diffCoeffL_[0] = 0.0; - for (int compIdx = 1; compIdx < numComponents; ++compIdx) { - diffCoeffL_[compIdx] = - FluidSystem::binaryDiffusionCoefficient(fluidState, - paramCache, - wPhaseIdx, - 0, - compIdx); - } - Valgrind::CheckDefined(diffCoeffL_); - - // diffusion coefficents in gas - for (int compIIdx = 0; compIIdx < numComponents; ++compIIdx) { - diffCoeffG_[compIIdx][compIIdx] = 0; - for (int compJIdx = compIIdx + 1; compJIdx < numComponents; ++compJIdx) { - diffCoeffG_[compIIdx][compJIdx] = - FluidSystem::binaryDiffusionCoefficient(fluidState, - paramCache, - nPhaseIdx, - compIIdx, - compJIdx); - - // fill the symmetric part of the diffusion coefficent - // matrix - diffCoeffG_[compJIdx][compIIdx] = diffCoeffG_[compIIdx][compJIdx]; - } - } - Valgrind::CheckDefined(diffCoeffG_); - } - - - Scalar diffCoeff(const unsigned int phaseIdx, - const unsigned int compIIdx, - const unsigned int compJIdx) const - { - if (phaseIdx == nPhaseIdx) - // TODO: tensorial diffusion coefficients - return diffCoeffG_[compIIdx][compJIdx]; - - const unsigned int i = std::min(compIIdx, compJIdx); - const unsigned int j = std::max(compIIdx, compJIdx); - if (i != 0) - return 0; - return diffCoeffL_[j]; - } - - /*! - * \brief If running under valgrind this produces an error message - * if some of the object's attributes is undefined. - */ - void checkDefined() const - { - Valgrind::CheckDefined(diffCoeffL_); - Valgrind::CheckDefined(diffCoeffG_); - } - - -protected: - // the diffusion coefficients for the porous medium for the - // liquid phase - Scalar diffCoeffL_[numComponents]; - - // the diffusion coefficients for the porous medium for the - // gas phase - Scalar diffCoeffG_[numComponents][numComponents]; -}; - -// dummy class for the case where diffusion is disabled -template<class TypeTag> -class MPNCVolumeVariablesDiffusion<TypeTag, false> -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - -public: - MPNCVolumeVariablesDiffusion() - {} - - void update(FluidState &fluidState, - ParameterCache ¶mCache, - const VolumeVariables &volVars, - const Problem &problem) - { } - - Scalar diffCoeffL(const unsigned int compIdx) const - { return 0; } - - Scalar diffCoeffG(const unsigned int compIIdx, const unsigned int compJIdx) const - { return 0; } - - /*! - * \brief If running under valgrind this produces an error message - * if some of the object's attributes is undefined. - */ - void checkDefined() const - { } -}; - -} - -#endif // DUMUX_MPNC_DIFFUSION_VOLUME_VARIABLES_HH +#include <dumux/implicit/mpnc/diffusion/volumevariables.hh> diff --git a/dumux/boxmodels/mpnc/energy/mpncfluxvariablesenergy.hh b/dumux/boxmodels/mpnc/energy/mpncfluxvariablesenergy.hh index a345453e1513dc8b02ceb728c76fbe55e6352766..d089bc72cfdd9e6341da3cc9b00a3a455ffa1a9f 100644 --- a/dumux/boxmodels/mpnc/energy/mpncfluxvariablesenergy.hh +++ b/dumux/boxmodels/mpnc/energy/mpncfluxvariablesenergy.hh @@ -1,205 +1,3 @@ -// -*- 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 Contains the quantities to calculate the energy flux in the - * MpNc box model. - */ -#ifndef DUMUX_MPNC_ENERGY_FLUX_VARIABLES_HH -#define DUMUX_MPNC_ENERGY_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/energy/mpncfluxvariablesenergy.hh instead. -#include <dune/common/fmatrix.hh> -#include <dune/common/fvector.hh> - -#include <dumux/boxmodels/mpnc/mpncproperties.hh> -#include <dumux/common/spline.hh> - -namespace Dumux -{ - -template <class TypeTag, bool enableEnergy/*=false*/, bool kineticEnergyTransfer/*=false*/> -class MPNCFluxVariablesEnergy -{ - static_assert(!(kineticEnergyTransfer && !enableEnergy), - "No kinetic energy transfer may only be enabled " - "if energy is enabled in general."); - static_assert(!kineticEnergyTransfer, - "No kinetic energy transfer module included, " - "but kinetic energy transfer enabled."); - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - MPNCFluxVariablesEnergy() - { - } - - void update(const Problem & problem, - const Element & element, - const FVElementGeometry & fvGeometry, - const SCVFace & face, - const FluxVariables & fluxVars, - const ElementVolumeVariables & elemVolVars) - {} -}; - -template <class TypeTag> -class MPNCFluxVariablesEnergy<TypeTag, /*enableEnergy=*/true, /*kineticEnergyTransfer=*/false> -{ - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - typedef typename GridView::ctype CoordScalar; - typedef typename GridView::template Codim<0>::Entity Element; - - enum{dim = GridView::dimension}; - enum{dimWorld = GridView::dimensionworld}; - enum{nPhaseIdx = FluidSystem::nPhaseIdx}; - enum{wPhaseIdx = FluidSystem::wPhaseIdx}; - enum{numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - - typedef Dune::FieldVector<CoordScalar, dimWorld> DimVector; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - -public: - MPNCFluxVariablesEnergy() - {} - - void update(const Problem & problem, - const Element & element, - const FVElementGeometry & fvGeometry, - const SCVFace & face, - const FluxVariables & fluxVars, - const ElementVolumeVariables & elemVolVars) - { - // calculate temperature gradient using finite element - // gradients - DimVector tmp(0.0); - DimVector temperatureGradient(0.); - for (int idx = 0; idx < fvGeometry.numFAP; idx++) - { - tmp = face.grad[idx]; - - // index for the element volume variables - int volVarsIdx = face.fapIndices[idx]; - - tmp *= elemVolVars[volVarsIdx].fluidState().temperature(/*phaseIdx=*/0); - temperatureGradient += tmp; - } - - // project the heat flux vector on the face's normal vector - temperatureGradientNormal_ = temperatureGradient * face.normal; - - - lambdaPm_ = lumpedLambdaPm(problem, - element, - fvGeometry, - face, - elemVolVars) ; - - } - - Scalar lumpedLambdaPm(const Problem &problem, - const Element &element, - const FVElementGeometry & fvGeometry, - const SCVFace & face, - const ElementVolumeVariables & elemVolVars) - { - // arithmetic mean of the liquid saturation and the porosity - const unsigned int i = face.i; - const unsigned int j = face.j; - - const FluidState &fsI = elemVolVars[i].fluidState(); - const FluidState &fsJ = elemVolVars[j].fluidState(); - const Scalar Swi = fsI.saturation(wPhaseIdx); - const Scalar Swj = fsJ.saturation(wPhaseIdx); - - typename FluidSystem::ParameterCache paramCacheI, paramCacheJ; - paramCacheI.updateAll(fsI); - paramCacheJ.updateAll(fsJ); - - const Scalar Sw = std::max<Scalar>(0.0, 0.5*(Swi + Swj)); - - // const Scalar lambdaDry = 0.583; // W / (K m) // works, orig - // const Scalar lambdaWet = 1.13; // W / (K m) // works, orig - - const Scalar lambdaSoilI = problem.spatialParams().soilThermalConductivity(element, fvGeometry, i); - const Scalar lambdaSoilJ = problem.spatialParams().soilThermalConductivity(element, fvGeometry, i); - const Scalar lambdaDry = 0.5 * (lambdaSoilI + FluidSystem::thermalConductivity(fsI, paramCacheI, nPhaseIdx)); // W / (K m) - const Scalar lambdaWet = 0.5 * (lambdaSoilJ + FluidSystem::thermalConductivity(fsJ, paramCacheJ, wPhaseIdx)) ; // W / (K m) - - // the heat conductivity of the matrix. in general this is a - // tensorial value, but we assume isotropic heat conductivity. - // This is the Sommerton approach with lambdaDry = - // lambdaSn100%. Taken from: H. Class: "Theorie und - // numerische Modellierung nichtisothermer Mehrphasenprozesse - // in NAPL-kontaminierten poroesen Medien", PhD Thesis, University of - // Stuttgart, Institute of Hydraulic Engineering, p. 57 - - Scalar result; - if (Sw < 0.1) { - // regularization - Dumux::Spline<Scalar> sp(0, 0.1, // x1, x2 - 0, sqrt(0.1), // y1, y2 - 5*0.5/sqrt(0.1), 0.5/sqrt(0.1)); // m1, m2 - result = lambdaDry + sp.eval(Sw)*(lambdaWet - lambdaDry); - } - else - result = lambdaDry + std::sqrt(Sw)*(lambdaWet - lambdaDry); - - return result; - } - - /*! - * \brief The lumped / average conductivity of solid plus phases \f$[W/mK]\f$. - */ - Scalar lambdaPm() const - { return lambdaPm_; } - - /*! - * \brief The normal of the gradient of temperature . - */ - Scalar temperatureGradientNormal() const - { - return temperatureGradientNormal_; - } - -private: - Scalar lambdaPm_; - Scalar temperatureGradientNormal_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/energy/mpncfluxvariablesenergy.hh> diff --git a/dumux/boxmodels/mpnc/energy/mpncindicesenergy.hh b/dumux/boxmodels/mpnc/energy/mpncindicesenergy.hh index 05a8b33ce2b740f86f4ce88138d37234da19f91f..dc4baae63e2ff757f74942cf17da258a7d6b5d04 100644 --- a/dumux/boxmodels/mpnc/energy/mpncindicesenergy.hh +++ b/dumux/boxmodels/mpnc/energy/mpncindicesenergy.hh @@ -1,75 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \brief The indices for the non-isothermal part of the compositional - * multi-phase model. - */ -#ifndef DUMUX_MPNC_INDICES_ENERGY_HH -#define DUMUX_MPNC_INDICES_ENERGY_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/energy/mpncindicesenergy.hh instead. -namespace Dumux -{ -/*! - * \brief The indices for the energy equation. - * - * This is a dummy class for the isothermal case. - */ -template <int PVOffset, bool enableEnergy/*=false*/, bool kineticEnergyTransfer/*=false*/> -struct MPNCEnergyIndices -{ - static_assert(!(kineticEnergyTransfer && !enableEnergy), - "No kinetic energy transfer may only be enabled " - "if energy is enabled in general."); - static_assert(!kineticEnergyTransfer, - "No kinetic energy transfer module included, " - "but kinetic energy transfer enabled."); -public: - /*! - * \brief This module does not define any primary variables in the - * isothermal case. - */ - static const unsigned int NumPrimaryVars = 0; -}; - -/*! - * \brief The indices required for the energy equation. - */ -template <int PVOffset> -struct MPNCEnergyIndices<PVOffset, /*isNonIsothermal=*/true, /*kineticEnergyTransfer*/false> -{ -public: - /*! - * \brief This module defines one new primary variable. - */ - static const unsigned int NumPrimaryVars = 1; - - /*! - * \brief Index for the temperature in a vector of primary - * variables. - */ - static const unsigned int temperatureIdx = PVOffset + 0; - /*! - * \brief Equation index of the energy equation. - */ - static const unsigned int energyEqIdx = PVOffset + 0; -}; - -} - -#endif +#include <dumux/implicit/mpnc/energy/mpncindicesenergy.hh> diff --git a/dumux/boxmodels/mpnc/energy/mpnclocalresidualenergy.hh b/dumux/boxmodels/mpnc/energy/mpnclocalresidualenergy.hh index 67c3b8b9ee1cd079e421d1a05b378bcfd5b6ec25..7235c4c210cbf8751be856277faf55f7db7ddace 100644 --- a/dumux/boxmodels/mpnc/energy/mpnclocalresidualenergy.hh +++ b/dumux/boxmodels/mpnc/energy/mpnclocalresidualenergy.hh @@ -1,233 +1,3 @@ -// -*- 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 This file contains the parts of the local residual to - * calculate the heat flux in the fully coupled two-phase - * N-component model - */ -#ifndef DUMUX_MPNC_LOCAL_RESIDUAL_ENERGY_HH -#define DUMUX_MPNC_LOCAL_RESIDUAL_ENERGY_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/energy/mpnclocalresidualenergy.hh instead. -#include <dumux/boxmodels/mpnc/mpncproperties.hh> - -namespace Dumux { - -/*! - * \brief Specialization of the energy module for the isothermal case. - * - * This class just does nothing. - */ -template <class TypeTag, bool enableEnergy/*=false*/, bool kineticEnergyTransfer /*=false*/> -class MPNCLocalResidualEnergy -{ - static_assert(!(kineticEnergyTransfer && !enableEnergy), - "No kinetic energy transfer may only be enabled " - "if energy is enabled in general."); - static_assert(!kineticEnergyTransfer, - "No kinetic energy transfer module included, " - "but kinetic energy transfer enabled."); - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - - typedef typename Dune::FieldVector<Scalar, numComponents> ComponentVector; - -public: - static void computeStorage(PrimaryVariables &storage, - const VolumeVariables &volVars) - { - // do nothing, we're isothermal! - } - - - static void addPhaseStorage(PrimaryVariables &storage, - const VolumeVariables &volVars, - const unsigned int phaseIdx) - { - // do nothing, we're isothermal! - } - - static void phaseEnthalpyFlux(PrimaryVariables &enthalpyFlux, - const unsigned int phaseIdx, - const PrimaryVariables &compMolFlux, - const ElementVolumeVariables &volVars, - const FluxVariables &fluxVars) - { - // do nothing, we're isothermal! - } - - static void heatConduction(PrimaryVariables &heatConduction, - const ElementVolumeVariables &volVars, - const FluxVariables &fluxVars) - { - // do nothing, we're isothermal! - } - - - static void computeFlux(PrimaryVariables & flux, - const FluxVariables & fluxVars, - const ElementVolumeVariables & volVars, - const ComponentVector molarPhaseComponentValuesMassTransport[numPhases]) - { - // do nothing, we're isothermal! - } - - static void computeSource(PrimaryVariables &source, - const VolumeVariables &volVars, - const ComponentVector componentIntoPhaseMassTransfer[numPhases]) - { - // do nothing, we're isothermal! - } -}; - - -template <class TypeTag> -class MPNCLocalResidualEnergy<TypeTag, /*enableEnergy=*/true, /*kineticenergyTransfer=*/false> -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { dim = GridView::dimension }; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { conti0EqIdx = Indices::conti0EqIdx }; - enum { energyEqIdx = Indices::energyEqIdx }; - - typedef typename Dune::FieldVector<Scalar, numComponents> ComponentVector; - -public: - static void computeStorage(PrimaryVariables &storage, - const VolumeVariables &volVars) - { - storage[energyEqIdx] = 0; - - // energy of the fluids - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - addPhaseStorage(storage, volVars, phaseIdx); - } - - // heat stored in the rock matrix - storage[energyEqIdx] += - volVars.fluidState().temperature(/*phaseIdx=*/0) - * volVars.soilDensity() - * (1.0 - volVars.porosity()) - * volVars.heatCapacity(); - } - - static void addPhaseStorage(PrimaryVariables &storage, - const VolumeVariables &volVars, - const unsigned int phaseIdx) - { - const FluidState &fs = volVars.fluidState(); - - // energy of the fluid - storage[energyEqIdx] += - fs.density(phaseIdx) - * fs.internalEnergy(phaseIdx) - * fs.saturation(phaseIdx) - * volVars.porosity(); - } - - static void computeFlux(PrimaryVariables & flux, - const FluxVariables & fluxVars, - const ElementVolumeVariables & elemVolVars, - const ComponentVector molarPhaseComponentValuesMassTransport[numPhases]) - { - flux[energyEqIdx] = 0.0; - - // fluid phases transport enthalpy individually - for(int phaseIdx=0; phaseIdx<numPhases; ++phaseIdx) - computePhaseEnthalpyFlux(flux, - fluxVars, - elemVolVars, - phaseIdx, - molarPhaseComponentValuesMassTransport[phaseIdx]); - - //conduction is treated lumped in this model - computeHeatConduction(flux, - fluxVars, - elemVolVars); - } - - static void computePhaseEnthalpyFlux(PrimaryVariables & flux, - const FluxVariables & fluxVars, - const ElementVolumeVariables & elemVolVars, - const unsigned int phaseIdx, - const ComponentVector & molarComponentValuesMassTransport) - { - Scalar massFlux = 0; - - // calculate the mass flux in the phase i.e. make mass flux out of mole flux and add up the fluxes of a phase - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - massFlux += molarComponentValuesMassTransport[compIdx] - * FluidSystem::molarMass(compIdx); - - unsigned int upIdx = fluxVars.face().i; - if (massFlux < 0) upIdx = fluxVars.face().j; - - // use the phase enthalpy of the upstream vertex to calculate - // the enthalpy transport - const VolumeVariables &up = elemVolVars[upIdx]; - flux[energyEqIdx] += up.fluidState().enthalpy(phaseIdx) * massFlux; - } - - static void computeHeatConduction(PrimaryVariables & flux, - const FluxVariables & fluxVars, - const ElementVolumeVariables & elemVolVars) - { - //lumped heat conduction of the rock matrix and the fluid phases - Scalar lumpedConductivity = fluxVars.fluxVarsEnergy().lambdaPm() ; - Scalar temperatureGradientNormal = fluxVars.fluxVarsEnergy().temperatureGradientNormal() ; - Scalar lumpedHeatConduction = - lumpedConductivity * temperatureGradientNormal ; - flux[energyEqIdx] += lumpedHeatConduction ; - } - - - - static void computeSource(PrimaryVariables &source, - const VolumeVariables &volVars, - const ComponentVector componentIntoPhaseMassTransfer[numPhases]) - { - source[energyEqIdx] = 0.0; - } -}; - - - - - -} - -#endif // DUMUX_MPNC_ENERGY_HH +#include <dumux/implicit/mpnc/energy/mpnclocalresidualenergy.hh> diff --git a/dumux/boxmodels/mpnc/energy/mpncvolumevariablesenergy.hh b/dumux/boxmodels/mpnc/energy/mpncvolumevariablesenergy.hh index 185884fdc3aef1b6e315e173ec95716ca4675284..313e62680661972301e3cedad63e699bcc5a6f26 100644 --- a/dumux/boxmodels/mpnc/energy/mpncvolumevariablesenergy.hh +++ b/dumux/boxmodels/mpnc/energy/mpncvolumevariablesenergy.hh @@ -1,207 +1,3 @@ -// -*- 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 Contains the energy part of volume variables of the M-phase, - * N-component model. - */ -#ifndef DUMUX_MPNC_ENERGY_VOLUME_VARIABLES_HH -#define DUMUX_MPNC_ENERGY_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/energy/mpncvolumevariablesenergy.hh instead. -#include <dumux/boxmodels/mpnc/mpncproperties.hh> -#include <dumux/material/fluidstates/compositionalfluidstate.hh> - -namespace Dumux -{ -/*! - * \brief Contains the energy related quantities which are constant within a - * finite volume in the two-phase, N-component model. - * - * This is the dummy class for the isothermal case. Note that we're - * only isothermal in the sense that the temperature at a location and - * a time is specified outside of the model! - */ -template <class TypeTag, bool enableEnergy/*=false*/, bool kineticEnergyTransfer /*=don't care*/> -class MPNCVolumeVariablesEnergy -{ - static_assert(!(kineticEnergyTransfer && !enableEnergy), - "No kinetic energy transfer may only be enabled " - "if energy is enabled in general."); - static_assert(!kineticEnergyTransfer, - "No kinetic energy transfer module included, " - "but kinetic energy transfer enabled."); - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - -public: - /*! - * \brief Update the temperature of the sub-control volume. - */ - void updateTemperatures(FluidState &fs, - ParameterCache ¶mCache, - const PrimaryVariables &priVars, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx, - const Problem &problem) const - { - Scalar T = problem.boxTemperature(element, fvGeometry, scvIdx); - fs.setTemperature(T); - } - - - /*! - * \brief Update the enthalpy and the internal energy for a given - * control volume. - * - * Since we are isothermal, we don't need to do anything! - */ - void update(FluidState &fs, - ParameterCache ¶mCache, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx, - const Problem &problem) - { - } - - /*! - * \brief If running under valgrind this produces an error message - * if some of the object's attributes is undefined. - */ - void checkDefined() const - { - } -}; - -/*! - * \brief Contains the energy related quantities which are constant within a - * finite volume in the two-phase, N-component model. - */ -template <class TypeTag> -class MPNCVolumeVariablesEnergy<TypeTag, /*enableEnergy=*/true, /*kineticEnergyTransfer=*/false> -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { temperatureIdx = Indices::temperatureIdx }; - enum { numEnergyEqs = Indices::NumPrimaryEnergyVars}; - enum { temperature0Idx = Indices::temperatureIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - -public: - /*! - * \brief Update the temperature of the sub-control volume. - */ - void updateTemperatures(FluidState &fs, - ParameterCache ¶mCache, - const PrimaryVariables &sol, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx, - const Problem &problem) const - { - // retrieve temperature from solution vector - Scalar T = sol[temperatureIdx]; - fs.setTemperature(T); - } - - /*! - * \brief Update the enthalpy and the internal energy for a given - * control volume. - */ - void update(FluidState &fs, - ParameterCache ¶mCache, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx, - const Problem &problem) - { - Valgrind::SetUndefined(*this); - - // heat capacities of the fluids plus the porous medium - heatCapacity_ = - problem.spatialParams().heatCapacity(element, fvGeometry, scvIdx); - Valgrind::CheckDefined(heatCapacity_); - - soilDensity_ = - problem.spatialParams().soilDensity(element, fvGeometry, scvIdx); - Valgrind::CheckDefined(soilDensity_); - - // set the enthalpies - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - Scalar h = FluidSystem::enthalpy(fs, paramCache, phaseIdx); - fs.setEnthalpy(phaseIdx, h); - } - } - - /*! - * \brief Returns the total heat capacity [J/(K m^3)] of the rock matrix in - * the sub-control volume. - */ - Scalar heatCapacity() const - { return heatCapacity_; }; - - /*! - * \brief Returns the total density of the given soil [kg / m^3] in - * the sub-control volume. - */ - Scalar soilDensity() const - { return soilDensity_; }; - - /*! - * \brief If running under valgrind this produces an error message - * if some of the object's attributes is undefined. - */ - void checkDefined() const - { - Valgrind::CheckDefined(heatCapacity_); - Valgrind::CheckDefined(soilDensity_); - }; - -protected: - Scalar heatCapacity_; - Scalar soilDensity_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/energy/mpncvolumevariablesenergy.hh> diff --git a/dumux/boxmodels/mpnc/energy/mpncvtkwriterenergy.hh b/dumux/boxmodels/mpnc/energy/mpncvtkwriterenergy.hh index 558d881b8d31d1c91c10579b7fb59ec739f00ad8..a940d55d0cf5477b46fabe1337c84c93e32660d7 100644 --- a/dumux/boxmodels/mpnc/energy/mpncvtkwriterenergy.hh +++ b/dumux/boxmodels/mpnc/energy/mpncvtkwriterenergy.hh @@ -1,218 +1,3 @@ -// -*- 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 VTK writer module for the energy related quantities of the - * MpNc model. - */ -#ifndef DUMUX_MPNC_VTK_WRITER_ENERGY_HH -#define DUMUX_MPNC_VTK_WRITER_ENERGY_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/energy/mpncvtkwriterenergy.hh instead. -#include "../mpncvtkwritermodule.hh" - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * - * \brief VTK writer module for the energy related quantities of the - * MpNc model. - * - * This is the specialization for the case without energy. - */ -template<class TypeTag, - bool enableEnergy /* = false */, - bool enableKineticEnergy /* = false */> -class MPNCVtkWriterEnergy : public MPNCVtkWriterModule<TypeTag> -{ - static_assert(enableKineticEnergy == false, - "If you enable kinetic energy transfer between fluids, you" - "also have to enable the energy in general!"); - - typedef MPNCVtkWriterModule<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { dim = GridView::dimension }; - - typedef typename ParentType::ScalarVector ScalarVector; - typedef typename ParentType::PhaseVector PhaseVector; - -public: - MPNCVtkWriterEnergy(const Problem &problem) - : ParentType(problem) - { - temperatureOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddTemperatures); - } - - /*! - * \brief Allocate memory for the scalar fields we would like to - * write to the VTK file. - */ - template <class MultiWriter> - void allocBuffers(MultiWriter &writer) - { - if (temperatureOutput_) this->resizeScalarBuffer_(temperature_); - } - - /*! - * \brief Modify the internal buffers according to the volume - * variables seen on an element - */ - void processElement(const Element &elem, - const FVElementGeometry &fvGeometry, - const ElementVolumeVariables &elemVolVars, - const ElementBoundaryTypes &elemBcTypes) - { - int numLocalVertices = elem.geometry().corners(); - for (int localVertexIdx = 0; localVertexIdx < numLocalVertices; ++localVertexIdx) { - const unsigned int globalIdx = this->problem_.vertexMapper().map(elem, localVertexIdx, dim); - const VolumeVariables &volVars = elemVolVars[localVertexIdx]; - - if (temperatureOutput_) - temperature_[globalIdx] = volVars.fluidState().temperature(/*phaseIdx=*/0); - } - } - - /*! - * \brief Add all buffers to the VTK output writer. - */ - template <class MultiWriter> - void commitBuffers(MultiWriter &writer) - { - if (temperatureOutput_) - this->commitScalarBuffer_(writer, "T", temperature_); - } - -private: - bool temperatureOutput_; - - ScalarVector temperature_; -}; - -/*! - * \ingroup MPNCModel - * - * \brief VTK writer module for the energy related quantities of the - * MpNc model. - * - * This is the specialization for the case with an energy equation but - * local thermal equilibrium. (i.e. no kinetic energy transfer) - */ -template<class TypeTag> -class MPNCVtkWriterEnergy<TypeTag, /* enableEnergy = */ true, /* enableKineticEnergy = */ false > - : public MPNCVtkWriterModule<TypeTag> -{ - typedef MPNCVtkWriterModule<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { dim = GridView::dimension }; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - - typedef typename ParentType::ScalarVector ScalarVector; - typedef typename ParentType::PhaseVector PhaseVector; - - -public: - MPNCVtkWriterEnergy(const Problem &problem) - : ParentType(problem) - { - temperatureOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddTemperatures); - enthalpyOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddEnthalpies); - internalEnergyOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddInternalEnergies); - } - - /*! - * \brief Allocate memory for the scalar fields we would like to - * write to the VTK file. - */ - template <class MultiWriter> - void allocBuffers(MultiWriter &writer) - { - if (temperatureOutput_) this->resizeScalarBuffer_(temperature_); - if (enthalpyOutput_) this->resizePhaseBuffer_(enthalpy_); - if (internalEnergyOutput_) this->resizePhaseBuffer_(internalEnergy_); - } - - /*! - * \brief Modify the internal buffers according to the volume - * variables seen on an element - */ - void processElement(const Element &elem, - const FVElementGeometry &fvGeometry, - const ElementVolumeVariables &elemVolVars, - const ElementBoundaryTypes &elemBcTypes) - { - const unsigned int numLocalVertices = elem.geometry().corners(); - for (int localVertexIdx = 0; localVertexIdx < numLocalVertices; ++localVertexIdx) { - int gobalIdx = this->problem_.vertexMapper().map(elem, localVertexIdx, dim); - const VolumeVariables &volVars = elemVolVars[localVertexIdx]; - - if (temperatureOutput_) temperature_[gobalIdx] = volVars.fluidState().temperature(/*phaseIdx=*/0); - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { - if (enthalpyOutput_) - enthalpy_[phaseIdx][gobalIdx] = volVars.fluidState().temperature(phaseIdx); - if (internalEnergyOutput_) - internalEnergy_[phaseIdx][gobalIdx] = volVars.fluidState().internalEnergy(phaseIdx); - } - } - } - - /*! - * \brief Add all buffers to the VTK output writer. - */ - template <class MultiWriter> - void commitBuffers(MultiWriter &writer) - { - if (temperatureOutput_) - this->commitScalarBuffer_(writer, "T", temperature_); - if (enthalpyOutput_) - this->commitPhaseBuffer_(writer, "h_%s", enthalpy_); - if (internalEnergyOutput_) - this->commitPhaseBuffer_(writer, "u_%s", internalEnergy_); - } - -private: - bool temperatureOutput_; - bool enthalpyOutput_; - bool internalEnergyOutput_; - - ScalarVector temperature_; - PhaseVector enthalpy_; - PhaseVector internalEnergy_; -}; - -} - -#endif +#include <dumux/implicit/mpnc/energy/mpncvtkwriterenergy.hh> diff --git a/dumux/boxmodels/mpnc/mass/mpncindicesmass.hh b/dumux/boxmodels/mpnc/mass/mpncindicesmass.hh index 06c037fc68408bfb6d5f768dead51fd8dbe30429..dac05b32d3f4751cbcbfced63dbef9edeb8d04e3 100644 --- a/dumux/boxmodels/mpnc/mass/mpncindicesmass.hh +++ b/dumux/boxmodels/mpnc/mass/mpncindicesmass.hh @@ -1,84 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \brief The indices for the mass flow part of the compositional - * multi-phase model. - */ -#ifndef DUMUX_MPNC_MASS_INDICES_HH -#define DUMUX_MPNC_MASS_INDICES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mass/mpncindicesmass.hh instead. -#include <dumux/boxmodels/mpnc/mpncproperties.hh> - -namespace Dumux -{ -/*! - * \brief The indices required for conservation of mass. - * - * This is the specialization for the case without kinetic mass - * transfer (i.e. assuming chemical equilibrium) - */ -template <int PVOffset, - class TypeTag, - bool enableKinetic /*=false*/> -class MPNCMassIndices -{ - static_assert(!enableKinetic, - "No kinetic mass transfer module included, " - "but kinetic mass transfer enabled."); - - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - -public: - /*! - * \brief This module defines one new primary variable. - */ - static const unsigned int NumPrimaryVars = numComponents; - - /*! - * \brief Index for the fugacity of the first component in the - * first phase in a vector of primary variables. - * - * The next numComponents indices represent the remaining - * fugacities: - * - * fug0Idx + 0 = fugacity of component 0 - * fug0Idx + 1 = fugacity of component 1 - * ... - * fug0Idx + N - 1 = fugacity of component N - */ - static const unsigned int fug0Idx = PVOffset + 0; - - /*! - * \brief Equation index of the mass conservation equation for the - * first component. - * - * The next numComponents indices represent the equations of all - * components in all phases: - * - * conti00EqIdx + 0 = continuity of component 0 - * conti00EqIdx + 1 = continuity of component 1 - * ... - * conti00EqIdx + N - 1 = continuity of component N - */ - static const unsigned int conti0EqIdx = PVOffset + 0; -}; - -} - -#endif +#include <dumux/implicit/mpnc/mass/mpncindicesmass.hh> diff --git a/dumux/boxmodels/mpnc/mass/mpnclocalresidualmass.hh b/dumux/boxmodels/mpnc/mass/mpnclocalresidualmass.hh index 77adf6935539ac3203b35c8f649e56b78d93f883..c53ca565aca829002c9c905ebfd31e99626b1dc1 100644 --- a/dumux/boxmodels/mpnc/mass/mpnclocalresidualmass.hh +++ b/dumux/boxmodels/mpnc/mass/mpnclocalresidualmass.hh @@ -1,369 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_LOCAL_RESIDUAL_MASS_HH -#define DUMUX_MPNC_LOCAL_RESIDUAL_MASS_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mass/mpnclocalresidualmass.hh instead. -#include <dune/common/fvector.hh> - -#include <dumux/boxmodels/mpnc/mpncproperties.hh> -#include <dumux/material/constraintsolvers/compositionfromfugacities.hh> -#include <dumux/common/math.hh> -#include <dumux/common/spline.hh> - -#include "../diffusion/diffusion.hh" -#include "../energy/mpnclocalresidualenergy.hh" - -namespace Dumux -{ -/*! - * \brief The mass conservation part of the Mp-Nc model. - * - * This is the class represents methods which are shared amongst all - * mass conservation modules. - */ -template<class TypeTag> -class MPNCLocalResidualMassCommon -{ -protected: - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - - enum { dim = GridView::dimension }; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { enableDiffusion = GET_PROP_VALUE(TypeTag, EnableDiffusion) }; - enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) }; - enum { enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy) }; - - typedef typename Dune::FieldVector<Scalar, dim> DimVector; - typedef typename Dune::FieldVector<Scalar, numComponents> ComponentVector; - typedef MPNCDiffusion<TypeTag, enableDiffusion> Diffusion; - typedef MPNCLocalResidualEnergy<TypeTag, enableEnergy, enableKineticEnergy> EnergyResid; - -public: - /*! - * \brief Evaluate the amount moles within a sub-control volume in - * a phase. - * - * The result should be averaged over the volume. - */ - static void computePhaseStorage(ComponentVector &storage, - const VolumeVariables &volVars, - const unsigned int phaseIdx) - { - // compute storage term of all components within all phases - storage = 0; - for (int compIdx = 0; compIdx < numComponents; ++ compIdx) { - storage[compIdx] += - volVars.fluidState().saturation(phaseIdx)* - volVars.fluidState().molarity(phaseIdx, compIdx); - } - - storage *= volVars.porosity(); - } - - /*! - * \brief Evaluates the advective flux of all conservation - * quantities over a face of a subcontrol volume via a - * fluid phase. - */ - static void computeAdvectivePhaseFlux(ComponentVector &flux, - const FluxVariables &fluxVars, - const unsigned int phaseIdx) - { - - const Scalar volumeFlux = fluxVars.volumeFlux(phaseIdx) ; - #ifndef NDEBUG - if (!std::isfinite(volumeFlux)) - DUNE_THROW(NumericalProblem, "Calculated non-finite normal flux"); - #endif - - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - const Scalar massUpwindWeight = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - - static bool enableSmoothUpwinding_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Implicit, EnableSmoothUpwinding); - - // data attached to upstream and the downstream vertices - // of the current phase - unsigned int upIdx = fluxVars.upstreamIdx(phaseIdx); - unsigned int dnIdx = fluxVars.downstreamIdx(phaseIdx); - - const VolumeVariables &up = fluxVars.volVars(upIdx); - const VolumeVariables &dn = fluxVars.volVars(dnIdx); - - //////// - // advective fluxes of all components in the phase - //////// - for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx) { - // add advective flux of current component in current - // phase. we use full upwinding. - if (enableSmoothUpwinding_) { - const Scalar kGradPNormal = fluxVars.kGradPNormal(phaseIdx); - const Scalar mobUp = up.mobility(phaseIdx); - const Scalar conUp = up.fluidState().molarity(phaseIdx, compIdx); - - const Scalar mobDn = dn.mobility(phaseIdx); - const Scalar conDn = dn.fluidState().molarity(phaseIdx, compIdx); - - const Scalar mobConUp = mobUp*conUp; - const Scalar mobConDn = mobDn*conDn; - const Scalar meanMobCon = Dumux::harmonicMean(mobConUp, mobConDn); - - const Scalar x = std::abs(kGradPNormal); - const Scalar sign = (kGradPNormal > 0)?-1:1; - - // the direction from upstream to downstream - //GlobalPosition delta = this->curElement_().geometry().corner(upIdx); - //delta -= this->curElement_().geometry().corner(dnIdx); - - // approximate the mean viscosity at the face - const Scalar meanVisc = (up.fluidState().viscosity(phaseIdx) + - dn.fluidState().viscosity(phaseIdx))/2; - - // put the mean viscosity and permeanbility in - // relation to the viscosity of water at - // approximatly 20 degrees Celsius. - const Scalar pGradRef = 10; // [Pa/m] - const Scalar muRef = 1e-3; // [Ns/m^2] - const Scalar Kref = 1e-12; // [m^2] = approx 1 Darcy - - const Scalar faceArea = fluxVars.face().normal.two_norm(); - const Scalar eps = pGradRef * Kref * faceArea * meanVisc/muRef; // * (1e3/18e-3)/meanC; - - Scalar compFlux; - if (x >= eps) { - // we only do tricks if x is below the epsilon - // value - compFlux = x*mobConUp; - } - else { - const Scalar xPos[] = { 0, eps }; - const Scalar yPos[] = { 0, eps*mobConUp }; - const Spline<Scalar> sp2(xPos, yPos, meanMobCon, mobConUp); - compFlux = sp2.eval(x); - } - #ifndef NDEBUG - if (!std::isfinite(compFlux)) - DUNE_THROW(NumericalProblem, "Calculated non-finite normal flux in smooth upwinding"); - #endif - - flux[compIdx] = sign*compFlux; - } - else - {// not use smooth upwinding - flux[compIdx] = - volumeFlux * - (( massUpwindWeight)*up.fluidState().molarity(phaseIdx, compIdx) - + - ( 1. - massUpwindWeight)*dn.fluidState().molarity(phaseIdx, compIdx) ); - - - } - } - } - - - /*! - * \brief Evaluates the advective flux of all conservation - * quantities over a face of a subcontrol volume via a - * fluid phase. - */ - static void computeDiffusivePhaseFlux(ComponentVector &flux, - const FluxVariables &fluxVars, - const unsigned int phaseIdx) - { - if (!enableDiffusion) { - flux = 0.0; - return; - } - - - const VolumeVariables &volVarsI = fluxVars.volVars(fluxVars.face().i); - const VolumeVariables &volVarsJ = fluxVars.volVars(fluxVars.face().j); - if (volVarsI.fluidState().saturation(phaseIdx) < 1e-4 || - volVarsJ.fluidState().saturation(phaseIdx) < 1e-4) - { - return; // phase is not present in one of the finite volumes - } - - // approximate the total concentration of the phase at the - // integration point by the arithmetic mean of the - // concentration of the sub-control volumes - Scalar molarDensityAtIP; - molarDensityAtIP = volVarsI.fluidState().molarDensity(phaseIdx); - molarDensityAtIP += volVarsJ.fluidState().molarDensity(phaseIdx); - molarDensityAtIP /= 2; - - Diffusion::flux(flux, phaseIdx, fluxVars, molarDensityAtIP); - } -}; - -/*! - * \brief The mass conservation part of the Mp-Nc model. - * - * This is the specialization for the case where kinetic mass transfer - * is _not_ considered. - */ -template<class TypeTag, bool enableKinetic /*=false*/> -class MPNCLocalResidualMass -{ - static_assert(!enableKinetic, - "No kinetic mass transfer module included, " - "but kinetic mass transfer enabled."); - - typedef MPNCLocalResidualMassCommon<TypeTag> MassCommon; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { conti0EqIdx = Indices::conti0EqIdx }; - enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) }; - enum { enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy) }; - - typedef typename Dune::FieldVector<Scalar, numComponents> ComponentVector; - typedef MPNCLocalResidualEnergy<TypeTag, enableEnergy, enableKineticEnergy> EnergyResid; - -public: - /*! - * \brief Calculate the storage for all mass balance equations - */ - static void computeStorage(PrimaryVariables &storage, - const VolumeVariables &volVars) - { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - storage[conti0EqIdx + compIdx] = 0.0; - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - addPhaseStorage(storage, volVars, phaseIdx); - } - } - - /*! - * \brief Calculate the storage for all mass balance equations - * within a single fluid phase - */ - static void addPhaseStorage(PrimaryVariables &storage, - const VolumeVariables &volVars, - const unsigned int phaseIdx) - { - // calculate the component-wise mass storage - ComponentVector phaseComponentValues; - MassCommon::computePhaseStorage(phaseComponentValues, - volVars, - phaseIdx); - - // copy to the primary variables - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - storage[conti0EqIdx + compIdx] += phaseComponentValues[compIdx]; - } - - /*! - * \brief Calculate the storage for all mass balance equations - */ - static void computeFlux(PrimaryVariables &flux, - const FluxVariables &fluxVars, - const ElementVolumeVariables & elemVolVars) - { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - flux[conti0EqIdx + compIdx] = 0.0; - - ComponentVector phaseComponentValuesAdvection(0.); - ComponentVector phaseComponentValuesDiffusion(0.); - ComponentVector phaseComponentValuesMassTransport[numPhases]; // what goes into the energy module - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - MassCommon::computeAdvectivePhaseFlux(phaseComponentValuesAdvection, fluxVars, phaseIdx); - Valgrind::CheckDefined(phaseComponentValuesAdvection); - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - flux[conti0EqIdx + compIdx] += - phaseComponentValuesAdvection[compIdx]; - - MassCommon::computeDiffusivePhaseFlux(phaseComponentValuesDiffusion, fluxVars, phaseIdx); - Valgrind::CheckDefined(phaseComponentValuesDiffusion); - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - flux[conti0EqIdx + compIdx] += - phaseComponentValuesDiffusion[compIdx]; - - // Right now I think that adding the two contributions individually into the flux is best for debugging and understanding. - // The Energy module needs both contributions. - phaseComponentValuesMassTransport[phaseIdx] = phaseComponentValuesDiffusion + phaseComponentValuesAdvection ; - Valgrind::CheckDefined(flux); - } - - // \todo - // - // The computeflux() of the Energy module needs a - // component-wise flux (for the diffusive enthalpy transport) - // It makes some sense calling energy from here, because energy - // is carried by mass. However, it is not really a clean - // solution. - - // energy transport in fluid phases - EnergyResid::computeFlux(flux, - fluxVars, - elemVolVars, - phaseComponentValuesMassTransport); - Valgrind::CheckDefined(flux); - } - - - - /*! - * \brief Calculate the source terms for all mass balance - * equations - */ - static void computeSource(PrimaryVariables &source, - const VolumeVariables &volVars) - { - static_assert(not enableKineticEnergy, // enableKinetic is disabled, in this specialization - "In the case of kinetic energy transfer the advective energy transport between the phases has to be considered. " - "It is hard (technically) to say how much mass got transfered in the case of chemical equilibrium. " - "Therefore, kineticEnergy and no kinetic mass does not fit (yet)."); - - // mass transfer is not considered in this mass module - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - source[conti0EqIdx + compIdx] = 0.0; - - - PrimaryVariables tmpPriVars(0); - // Similar to the compute Flux, the energy residual needs to be called from the - // mass residual. - ComponentVector dummy[numPhases]; - for (int iDummy =0; iDummy <numPhases; ++iDummy) - dummy[iDummy] = 0.; - EnergyResid::computeSource(tmpPriVars, - volVars, - dummy); - source += tmpPriVars; - Valgrind::CheckDefined(source); - } -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/mass/mpnclocalresidualmass.hh> diff --git a/dumux/boxmodels/mpnc/mass/mpncvolumevariablesmass.hh b/dumux/boxmodels/mpnc/mass/mpncvolumevariablesmass.hh index 625b89ae582bf696af1f15b0b2d7184711df7600..9ee0b4ad4341881991665ec26e5e8f421ca230ad 100644 --- a/dumux/boxmodels/mpnc/mass/mpncvolumevariablesmass.hh +++ b/dumux/boxmodels/mpnc/mass/mpncvolumevariablesmass.hh @@ -1,131 +1,3 @@ -// -*- 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 Contains the mass conservation part of the volume variables - */ -#ifndef DUMUX_MPNC_VOLUME_VARIABLES_MASS_HH -#define DUMUX_MPNC_VOLUME_VARIABLES_MASS_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mass/mpncvolumevariablesmass.hh instead. -#include <dumux/boxmodels/mpnc/mpncproperties.hh> - -#include <dumux/material/fluidstates/compositionalfluidstate.hh> - -namespace Dumux -{ -/*! - * \brief The compositional part of the volume variables if chemical - * equilibrium _is_ assumed - */ -template <class TypeTag, bool enableKinetic /* = false */> -class MPNCVolumeVariablesMass -{ - static_assert(!enableKinetic, - "No kinetic mass transfer module included, " - "but kinetic mass transfer enabled."); - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, ConstraintSolver) ConstraintSolver; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { fug0Idx = Indices::fug0Idx }; - - typedef Dune::FieldVector<Scalar, numComponents> ComponentVector; - -public: - /*! - * \brief Update composition of all phases in the mutable - * parameters from the primary variables. - */ - void update(FluidState &fs, - ParameterCache ¶mCache, - const PrimaryVariables &priVars, - const VolumeVariables *hint, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx) - { - ComponentVector fug; - // retrieve component fugacities - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - fug[compIdx] = priVars[fug0Idx + compIdx]; - - // calculate phase compositions - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // initial guess - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - Scalar x_ij = 1.0/numComponents; - if (hint) - // use the hint for the initial mole fraction! - x_ij = hint->fluidState().moleFraction(phaseIdx, compIdx); - - // set initial guess of the component's mole fraction - fs.setMoleFraction(phaseIdx, - compIdx, - x_ij); - - } - - // calculate the phase composition from the component - // fugacities - if (!hint) - // if no hint was given, we ask the constraint solver - // to make an initial guess - ConstraintSolver::guessInitial(fs, paramCache, phaseIdx, fug); - ConstraintSolver::solve(fs, paramCache, phaseIdx, fug); - - /* - std::cout << "final composition: " << FluidSystem::phaseName(phaseIdx) << "=" - << fs.moleFrac(phaseIdx, 0) << " " - << fs.moleFrac(phaseIdx, 1) << " " - << fs.moleFrac(phaseIdx, 2) << " " - << fs.moleFrac(phaseIdx, 3) << " " - << fs.moleFrac(phaseIdx, 4) << " " - << fs.moleFrac(phaseIdx, 5) << " " - << fs.moleFrac(phaseIdx, 6) << "\n"; - */ - - } - } - - /*! - * \brief If running in valgrind this makes sure that all - * quantities in the volume variables are defined. - */ - void checkDefined() const - { - } -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/mass/mpncvolumevariablesmass.hh> diff --git a/dumux/boxmodels/mpnc/mass/mpncvtkwritermass.hh b/dumux/boxmodels/mpnc/mass/mpncvtkwritermass.hh index 23583d24820c1ebd3bcacc03e2e7a38cdacdefe8..dde019f92a21e968cba7f7db113b2101f3568700 100644 --- a/dumux/boxmodels/mpnc/mass/mpncvtkwritermass.hh +++ b/dumux/boxmodels/mpnc/mass/mpncvtkwritermass.hh @@ -1,118 +1,3 @@ -// -*- 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 VTK writer module for the mass related quantities of the - * MpNc model. - */ -#ifndef DUMUX_MPNC_VTK_WRITER_MASS_HH -#define DUMUX_MPNC_VTK_WRITER_MASS_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mass/mpncvtkwritermass.hh instead. -#include "../mpncvtkwritermodule.hh" - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * - * \brief VTK writer module for the mass related quantities of the - * MpNc model. - * - * This is the specialization for the case _without_ kinetic mass - * transfer between phases. - */ -template<class TypeTag, bool enableKinetic /* = false */> -class MPNCVtkWriterMass : public MPNCVtkWriterModule<TypeTag> -{ - static_assert(!enableKinetic, - "No kinetic mass transfer module included, " - "but kinetic mass transfer enabled."); - - typedef MPNCVtkWriterModule<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { dim = GridView::dimension }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - - typedef typename ParentType::ComponentVector ComponentVector; - bool fugacityOutput_; - -public: - MPNCVtkWriterMass(const Problem &problem) - : ParentType(problem) - { - fugacityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddFugacities); - } - - /*! - * \brief Allocate memory for the scalar fields we would like to - * write to the VTK file. - */ - template <class MultiWriter> - void allocBuffers(MultiWriter &writer) - { - if (fugacityOutput_) this->resizeComponentBuffer_(fugacity_); - } - - /*! - * \brief Modify the internal buffers according to the volume - * variables seen on an element - */ - void processElement(const Element &elem, - const FVElementGeometry &fvElemGeom, - const ElementVolumeVariables &elemVolVars, - const ElementBoundaryTypes &elemBcTypes) - { - int numLocalVertices = elem.geometry().corners(); - for (int localVertexIdx = 0; localVertexIdx < numLocalVertices; ++localVertexIdx) { - int globalIdx = this->problem_.vertexMapper().map(elem, localVertexIdx, dim); - const VolumeVariables &volVars = elemVolVars[localVertexIdx]; - - if (fugacityOutput_) { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - fugacity_[compIdx][globalIdx] = volVars.fluidState().fugacity(compIdx); - } - } - } - } - - /*! - * \brief Add all buffers to the VTK output writer. - */ - template <class MultiWriter> - void commitBuffers(MultiWriter &writer) - { - if (fugacityOutput_) - this->commitComponentBuffer_(writer, "f_%s", fugacity_); - } - -private: - ComponentVector fugacity_; -}; - -} - -#endif +#include <dumux/implicit/mpnc/mass/mpncvtkwritermass.hh> diff --git a/dumux/boxmodels/mpnc/mpncfluxvariables.hh b/dumux/boxmodels/mpnc/mpncfluxvariables.hh index 2ef164033882985270ce522cfd91156256bb3f97..3744272e4821e282f388961fa8e2177ab3e5ad8c 100644 --- a/dumux/boxmodels/mpnc/mpncfluxvariables.hh +++ b/dumux/boxmodels/mpnc/mpncfluxvariables.hh @@ -1,174 +1,3 @@ -// -*- 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 This file contains the data which is required to calculate - * all fluxes of components over a face of a finite volume. - * - * This means pressure, concentration and temperature gradients, phase - * densities at the integration point, etc. - */ -#ifndef DUMUX_MPNC_FLUX_VARIABLES_HH -#define DUMUX_MPNC_FLUX_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncfluxvariables.hh instead. -#include <dumux/common/spline.hh> - -#include "diffusion/fluxvariables.hh" -#include "energy/mpncfluxvariablesenergy.hh" -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include <dumux/boxmodels/common/boxforchheimerfluxvariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup MPNCModel - * \ingroup BoxFluxVariables - * \brief This template class contains the data which is required to - * calculate all fluxes of components over a face of a finite - * volume for the two-phase, three-component model. - * - * This means pressure and concentration gradients, phase densities at - * the intergration point, etc. - */ -template <class TypeTag> -class MPNCFluxVariables - : public GET_PROP_TYPE(TypeTag, BaseFluxVariables) -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables; - - enum {dim= GridView::dimension}; - enum {numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - enum {enableDiffusion = GET_PROP_VALUE(TypeTag, EnableDiffusion)}; - enum {enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy)}; - enum {enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic)}; - enum {enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy)}; - - typedef Dune::FieldVector<Scalar, dim> DimVector; - typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename FVElementGeometry::SubControlVolumeFace SCVFace; - typedef MPNCFluxVariablesDiffusion<TypeTag, enableDiffusion> FluxVariablesDiffusion; - typedef MPNCFluxVariablesEnergy<TypeTag, enableEnergy, enableKineticEnergy> FluxVariablesEnergy; - -public: - /* - * \brief The constructor - * - * \param problem The problem - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param faceIdx The local index of the SCV (sub-control-volume) face - * \param elemVolVars The volume variables of the current element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - MPNCFluxVariables(const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int faceIdx, - const ElementVolumeVariables &elemVolVars, - const bool onBoundary = false) - : BaseFluxVariables(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary), - fvGeometry_(fvGeometry), faceIdx_(faceIdx), elemVolVars_(elemVolVars), onBoundary_(onBoundary) - { - // velocities can be obtained from the Parent class. - - // update the flux data of the energy module (i.e. isothermal - // or non-isothermal) - fluxVarsEnergy_.update(problem, element, fvGeometry, this->face(), *this, elemVolVars); - - // update the flux data of the diffusion module (i.e. with or - // without diffusion) - fluxVarsDiffusion_.update(problem, element, fvGeometry, this->face(), elemVolVars); - - extrusionFactor_ = - (elemVolVars[this->face().i].extrusionFactor() - + elemVolVars[this->face().j].extrusionFactor()) / 2; - } - - /*! - * \brief Returns a reference to the volume - * variables of the i-th sub-control volume of the current - * element. - */ - const VolumeVariables &volVars(const unsigned int idx) const - { return elemVolVars_[idx]; } - - /*! - * \brief Returns th extrusion factor for the sub-control volume face - */ - Scalar extrusionFactor() const - { return extrusionFactor_; } - - //////////////////////////////////////////////// - // forward calls to the diffusion module - Scalar porousDiffCoeffL(const unsigned int compIdx) const - { return fluxVarsDiffusion_.porousDiffCoeffL(compIdx); } - - Scalar porousDiffCoeffG(const unsigned int compIIdx, - const unsigned int compJIdx) const - { return fluxVarsDiffusion_.porousDiffCoeffG(compIIdx, compJIdx); } - - const Scalar moleFraction(const unsigned int phaseIdx, - const unsigned int compIdx) const - { return fluxVarsDiffusion_.moleFraction(phaseIdx, compIdx); } - - const DimVector &moleFractionGrad(const unsigned int phaseIdx, - const unsigned int compIdx) const - { return fluxVarsDiffusion_.moleFractionGrad(phaseIdx, compIdx); } - - // end of forward calls to the diffusion module - //////////////////////////////////////////////// - - //////////////////////////////////////////////// - // forward calls to the temperature module - const DimVector &temperatureGrad() const - { return fluxVarsEnergy_.temperatureGrad(); } - - const FluxVariablesEnergy &fluxVarsEnergy() const - { return fluxVarsEnergy_; } - // end of forward calls to the temperature module - //////////////////////////////////////////////// - -private: - const FVElementGeometry &fvGeometry_; - const unsigned int faceIdx_; - const ElementVolumeVariables &elemVolVars_; - const bool onBoundary_; - - // The extrusion factor for the sub-control volume face - Scalar extrusionFactor_; - - FluxVariablesDiffusion fluxVarsDiffusion_; - FluxVariablesEnergy fluxVarsEnergy_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/mpncfluxvariables.hh> diff --git a/dumux/boxmodels/mpnc/mpncindices.hh b/dumux/boxmodels/mpnc/mpncindices.hh index 2e80219300592faf203037f813bae460ba5902b4..cccd6b77eba0dfc9109fbd68c6beaff46bec1b31 100644 --- a/dumux/boxmodels/mpnc/mpncindices.hh +++ b/dumux/boxmodels/mpnc/mpncindices.hh @@ -1,117 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_INDICES_HH -#define DUMUX_MPNC_INDICES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncindices.hh instead. -#include "mpncproperties.hh" - -#include "mass/mpncindicesmass.hh" -#include "energy/mpncindicesenergy.hh" - -namespace Dumux -{ - -/*! - * \ingroup MPNCModel - * \ingroup BoxIndices - * \brief Enumerates the formulations which the 2p2c model accepts. - */ -struct MpNcPressureFormulation -{ - enum { - mostWettingFirst, - leastWettingFirst - }; -}; - -/*! - * \ingroup MPNCModel - * \ingroup BoxIndices - * \brief The primary variable and equation indices for the MpNc - * model. - */ -template <class TypeTag, int BasePVOffset = 0> -struct MPNCIndices : - public MPNCMassIndices<BasePVOffset, - TypeTag, - GET_PROP_VALUE(TypeTag, EnableKinetic) >, - public MPNCEnergyIndices<BasePVOffset + - MPNCMassIndices<0, TypeTag, GET_PROP_VALUE(TypeTag, EnableKinetic) >::NumPrimaryVars, - GET_PROP_VALUE(TypeTag, EnableEnergy), - GET_PROP_VALUE(TypeTag, EnableKineticEnergy)> -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) }; - enum { enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic) }; //mass transfer - enum { enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy) }; // energy transfer - enum { numPhases = FluidSystem::numPhases }; - - typedef MPNCMassIndices<BasePVOffset, TypeTag, enableKinetic> MassIndices; - typedef MPNCEnergyIndices<BasePVOffset + MassIndices::NumPrimaryVars, enableEnergy, enableKineticEnergy> EnergyIndices; - -public: - /*! - * \brief The number of primary variables / equations. - */ - // temperature + Mass Balance + constraints for switch stuff - static const unsigned int NumPrimaryVars = - MassIndices::NumPrimaryVars + - EnergyIndices::NumPrimaryVars + - numPhases; - - /*! - * \brief The number of primary variables / equations of the energy module. - */ - static const unsigned int NumPrimaryEnergyVars = - EnergyIndices::NumPrimaryVars ; - - /*! - * \brief Index of the saturation of the first phase in a vector - * of primary variables. - * - * The following (numPhases - 1) primary variables represent the - * saturations for the phases [1, ..., numPhases - 1] - */ - static const unsigned int S0Idx = - MassIndices::NumPrimaryVars + - EnergyIndices::NumPrimaryVars; - - /*! - * \brief Index of the first phase' pressure in a vector of - * primary variables. - */ - static const unsigned int p0Idx = - MassIndices::NumPrimaryVars + - EnergyIndices::NumPrimaryVars + - numPhases - 1; - - /*! - * \brief Index of the first phase NCP equation. - * - * The index for the remaining phases are consecutive. - */ - static const unsigned int phase0NcpIdx = - MassIndices::NumPrimaryVars + - EnergyIndices::NumPrimaryVars; -}; - -} - -#endif +#include <dumux/implicit/mpnc/mpncindices.hh> diff --git a/dumux/boxmodels/mpnc/mpnclocalresidual.hh b/dumux/boxmodels/mpnc/mpnclocalresidual.hh index 5513b4452992988ac3a23dc5d815a11ba8245b20..8396b80e64c42f58bdf57844166ad9a5446a772e 100644 --- a/dumux/boxmodels/mpnc/mpnclocalresidual.hh +++ b/dumux/boxmodels/mpnc/mpnclocalresidual.hh @@ -1,247 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_LOCAL_RESIDUAL_HH -#define DUMUX_MPNC_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpnclocalresidual.hh instead. -#include "mpncfluxvariables.hh" -#include "diffusion/diffusion.hh" -#include "energy/mpnclocalresidualenergy.hh" -#include "mass/mpnclocalresidualmass.hh" - -#include <dumux/boxmodels/common/boxmodel.hh> -#include <dumux/common/math.hh> - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * \ingroup BoxLocalResidual - * \brief two-phase, N-component specific details needed to - * approximately calculate the local defect in the BOX scheme. - * - * This class is used to fill the gaps in BoxLocalResidual for the - * two-phase, N-component twophase flow. - */ -template<class TypeTag> -class MPNCLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - -protected: - typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, BaseLocalResidual) ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - enum {numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - enum {enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy)}; - enum {enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy)}; - enum {enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic)}; - enum {phase0NcpIdx = Indices::phase0NcpIdx}; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - - typedef MPNCLocalResidualEnergy<TypeTag, enableEnergy, enableKineticEnergy> EnergyResid; - typedef MPNCLocalResidualMass<TypeTag, enableKinetic> MassResid; - -public: - /*! - * \brief Evaluate the amount all conservation quantites - * (e.g. phase mass) within a sub-control volume. - * - * The result should be averaged over the volume (e.g. phase mass - * inside a sub control volume divided by the volume) - */ - void computeStorage(PrimaryVariables &storage, - const unsigned int scvIdx, - const bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_(); - const VolumeVariables &volVars = elemVolVars[scvIdx]; - - storage =0; - - // compute mass and energy storage terms - MassResid::computeStorage(storage, volVars); - Valgrind::CheckDefined(storage); - EnergyResid::computeStorage(storage, volVars); - Valgrind::CheckDefined(storage); - } - - /*! - * \brief Evaluate the amount all conservation quantities - * (e.g. phase mass) within all sub-control volumes of an - * element. - */ - void addPhaseStorage(PrimaryVariables &phaseStorage, - const Element &element, - const unsigned int phaseIdx) const - { - // create a finite volume element geometry - FVElementGeometry fvGeometry; - fvGeometry.update(this->gridView_(), element); - - // calculate volume variables - ElementVolumeVariables elemVolVars; - this->model_().setHints(element, elemVolVars); - elemVolVars.update(this->problem_(), - element, - fvGeometry, - /*useOldSolution=*/false); - - // calculate the phase storage for all sub-control volumes - for (int scvIdx=0; - scvIdx < fvGeometry.numSCV; - scvIdx++) - { - PrimaryVariables tmpPriVars(0.0); - - // compute mass and energy storage terms in terms of - // averaged quantities - MassResid::addPhaseStorage(tmpPriVars, - elemVolVars[scvIdx], - phaseIdx); - EnergyResid::addPhaseStorage(tmpPriVars, - elemVolVars[scvIdx], - phaseIdx); - - // multiply with volume of sub-control volume - tmpPriVars *= fvGeometry.subContVol[scvIdx].volume; - - // Add the storage of the current SCV to the total storage - phaseStorage += tmpPriVars; - } - } - - /*! - * \brief Calculate the source term of the equation - */ - void computeSource(PrimaryVariables &source, - const unsigned int scvIdx) - { - Valgrind::SetUndefined(source); - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_() ); - const VolumeVariables &volVars = this->curVolVars_(scvIdx); - - PrimaryVariables tmp(0); - MassResid::computeSource(tmp, volVars); - source += tmp; - Valgrind::CheckDefined(source); - - /* - * EnergyResid also called in the MassResid - * 1) Makes some sense because energy is also carried by mass - * 2) The mass transfer between the phases is needed. - */ -// tmp = 0.; -// EnergyResid::computeSource(tmp, volVars); -// source += tmp; -// Valgrind::CheckDefined(source); - }; - - - /*! - * \brief Evaluates the total flux of all conservation quantities - * over a face of a subcontrol volume. - * - * \param flux The flux over the SCV (sub-control-volume) face for each component - * \param faceIdx The index of the SCV face - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, - const unsigned int faceIdx, const bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - - flux = 0.0; - MassResid::computeFlux(flux, fluxVars, this->curVolVars_() ); - Valgrind::CheckDefined(flux); -/* - * EnergyResid also called in the MassResid - * 1) Makes some sense because energy is also carried by mass - * 2) The component-wise mass flux in each phase is needed. - */ - } - - /*! - * \brief Compute the local residual, i.e. the deviation of the - * equations from zero. - */ - void eval(const Element &element) - { ParentType::eval(element); } - - /*! - * \brief Evaluate the local residual. - */ - void eval(const Element &element, - const FVElementGeometry &fvGeometry, - const ElementVolumeVariables &prevVolVars, - const ElementVolumeVariables &curVolVars, - const ElementBoundaryTypes &bcType) - { - ParentType::eval(element, - fvGeometry, - prevVolVars, - curVolVars, - bcType); - - for (int i = 0; i < this->fvGeometry_().numSCV; ++i) { - // add the two auxiliary equations, make sure that the - // dirichlet boundary condition is conserved - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - if (!bcType[i].isDirichlet(phase0NcpIdx + phaseIdx)) - { - this->residual_[i][phase0NcpIdx + phaseIdx] = - this->curVolVars_(i).phaseNcp(phaseIdx); - } - } - } - } - -protected: - Implementation &asImp_() - { return *static_cast<Implementation *>(this); } - const Implementation &asImp_() const - { return *static_cast<const Implementation *>(this); } -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/mpnclocalresidual.hh> diff --git a/dumux/boxmodels/mpnc/mpncmodel.hh b/dumux/boxmodels/mpnc/mpncmodel.hh index 8d783cca51b73632d272b69f143d683c1f933173..499b345331fc319c1f18b526855bedcbcf3c82c0 100644 --- a/dumux/boxmodels/mpnc/mpncmodel.hh +++ b/dumux/boxmodels/mpnc/mpncmodel.hh @@ -1,188 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_MODEL_HH -#define DUMUX_MPNC_MODEL_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncmodel.hh instead. -#include "mpncproperties.hh" -#include "mpncvtkwriter.hh" - -#include <dumux/boxmodels/common/boxmodel.hh> - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * \brief A fully implicit model for M-phase, N-component flow using - * vertex centered finite volumes. - * - * This model implements a \f$M\f$-phase flow of a fluid mixture - * composed of \f$N\f$ chemical species. The phases are denoted by - * lower index \f$\alpha \in \{ 1, \dots, M \}\f$. All fluid phases - * are mixtures of \f$N \geq M - 1\f$ chemical species which are - * denoted by the upper index \f$\kappa \in \{ 1, \dots, N \} \f$. - * - * The momentum approximation can be selected via "BaseFluxVariables": - * Darcy (BoxDarcyFluxVariables) and Forchheimer (BoxForchheimerFluxVariables) - * relations are available for all Box models. - * - * By inserting this into the equations for the conservation of the - * mass of each component, one gets one mass-continuity equation for - * each component \f$\kappa\f$ - * \f[ - \sum_{\kappa} \left( - \phi \frac{\partial \left(\varrho_\alpha x_\alpha^\kappa S_\alpha\right)}{\partial t} - + - \mathrm{div}\; - \left\{ - v_\alpha - \frac{\varrho_\alpha}{\overline M_\alpha} x_\alpha^\kappa - \right\} - \right) - = q^\kappa - \f] - * with \f$\overline M_\alpha\f$ being the average molar mass of the - * phase \f$\alpha\f$: \f[ \overline M_\alpha = \sum_\kappa M^\kappa - * \; x_\alpha^\kappa \f] - * - * For the missing \f$M\f$ model assumptions, the model assumes that - * if a fluid phase is not present, the sum of the mole fractions of - * this fluid phase is smaller than \f$1\f$, i.e. - * \f[ - * \forall \alpha: S_\alpha = 0 \implies \sum_\kappa x_\alpha^\kappa \leq 1 - * \f] - * - * Also, if a fluid phase may be present at a given spatial location - * its saturation must be positive: - * \f[ \forall \alpha: \sum_\kappa x_\alpha^\kappa = 1 \implies S_\alpha \geq 0 \f] - * - * Since at any given spatial location, a phase is always either - * present or not present, one of the strict equalities on the - * right hand side is always true, i.e. - * \f[ \forall \alpha: S_\alpha \left( \sum_\kappa x_\alpha^\kappa - 1 \right) = 0 \f] - * always holds. - * - * These three equations constitute a non-linear complementarity - * problem, which can be solved using so-called non-linear - * complementarity functions \f$\Phi(a, b)\f$ which have the property - * \f[\Phi(a,b) = 0 \iff a \geq0 \land b \geq0 \land a \cdot b = 0 \f] - * - * Several non-linear complementarity functions have been suggested, - * e.g. the Fischer-Burmeister function - * \f[ \Phi(a,b) = a + b - \sqrt{a^2 + b^2} \;. \f] - * This model uses - * \f[ \Phi(a,b) = \min \{a, b \}\;, \f] - * because of its piecewise linearity. - * - * These equations are then discretized using a fully-implicit vertex - * centered finite volume scheme (often known as 'box'-scheme) for - * spatial discretization and the implicit Euler method as temporal - * discretization. - * - * The model assumes local thermodynamic equilibrium and uses the - * following primary variables: - * - The component fugacities \f$f^1, \dots, f^{N}\f$ - * - The pressure of the first phase \f$p_1\f$ - * - The saturations of the first \f$M-1\f$ phases \f$S_1, \dots, S_{M-1}\f$ - * - Temperature \f$T\f$ if the energy equation is enabled - */ -template<class TypeTag> -class MPNCModel : public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef Dumux::MPNCVtkWriter<TypeTag> MPNCVtkWriter; - - enum {enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy)}; - enum {enableDiffusion = GET_PROP_VALUE(TypeTag, EnableDiffusion)}; - enum {enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic)}; - enum {enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy)}; - enum {enableSmoothUpwinding = GET_PROP_VALUE(TypeTag, ImplicitEnableSmoothUpwinding)}; - enum {enablePartialReassemble = GET_PROP_VALUE(TypeTag, ImplicitEnablePartialReassemble)}; - enum {enableJacobianRecycling = GET_PROP_VALUE(TypeTag, ImplicitEnableJacobianRecycling)}; - enum {numDiffMethod = GET_PROP_VALUE(TypeTag, ImplicitNumericDifferenceMethod)}; - enum {numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - enum {numComponents = GET_PROP_VALUE(TypeTag, NumComponents)}; - enum {numEq = GET_PROP_VALUE(TypeTag, NumEq)}; - -public: - ~MPNCModel() - { delete vtkWriter_; }; - - void init(Problem &problem) - { - ParentType::init(problem); - vtkWriter_ = new MPNCVtkWriter(problem); - - if (this->gridView_().comm().rank() == 0) - std::cout - << "Initializing M-phase N-component model: \n" - << " phases: " << numPhases << "\n" - << " components: " << numComponents << "\n" - << " equations: " << numEq << "\n" - << " kinetic mass transfer: " << enableKinetic<< "\n" - << " kinetic energy transfer: " << enableKineticEnergy<< "\n" - << " diffusion: " << enableDiffusion << "\n" - << " energy equation: " << enableEnergy << "\n" - << " smooth upwinding: " << enableSmoothUpwinding << "\n" - << " partial jacobian reassembly: " << enablePartialReassemble << "\n" - << " numeric differentiation method: " << numDiffMethod << " (-1: backward, 0: central, +1 forward)\n" - << " jacobian recycling: " << enableJacobianRecycling << "\n"; - } - - /*! - * \brief Compute the total storage inside one phase of all - * conservation quantities. - */ - void globalPhaseStorage(PrimaryVariables &phaseStorage, const unsigned int phaseIdx) - { - phaseStorage = 0; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - const ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - this->localResidual().addPhaseStorage(phaseStorage, *elemIt, phaseIdx); - } - - if (this->gridView_().comm().size() > 1) - phaseStorage = this->gridView_().comm().sum(phaseStorage); - } - - /*! - * \brief Add the result of the current timestep to the VTK output. - */ - template <class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, - MultiWriter &writer) - { - vtkWriter_->addCurrentSolution(writer); - } - - MPNCVtkWriter *vtkWriter_; -}; - -} - -#include "mpncpropertydefaults.hh" - -#endif +#include <dumux/implicit/mpnc/mpncmodel.hh> diff --git a/dumux/boxmodels/mpnc/mpncnewtoncontroller.hh b/dumux/boxmodels/mpnc/mpncnewtoncontroller.hh index 005def2ce29dd0d960017a49f2e8122bb2cd70c8..fc6caf8fc9072b2290ef95e1347779364fb02352 100644 --- a/dumux/boxmodels/mpnc/mpncnewtoncontroller.hh +++ b/dumux/boxmodels/mpnc/mpncnewtoncontroller.hh @@ -1,266 +1,3 @@ -// -*- 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 A MpNc specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * which allows the newton method to abort quicker if the solution is - * way out of bounds. - */ -#ifndef DUMUX_MPNC_NEWTON_CONTROLLER_HH -#define DUMUX_MPNC_NEWTON_CONTROLLER_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncnewtoncontroller.hh instead. -#include "mpncproperties.hh" - -#include <dumux/nonlinear/newtoncontroller.hh> -#include <algorithm> - -namespace Dumux { - -template <class TypeTag, bool enableKinetic /* = false */> -class MpNcNewtonChop -{ - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { fug0Idx = Indices::fug0Idx }; - enum { S0Idx = Indices::S0Idx }; - enum { p0Idx = Indices::p0Idx }; - -public: - static void chop(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - for (unsigned int i = 0; i < uLastIter.size(); ++i) { - for (unsigned int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) - saturationChop_(uCurrentIter[i][S0Idx + phaseIdx], - uLastIter[i][S0Idx + phaseIdx]); - pressureChop_(uCurrentIter[i][p0Idx], uLastIter[i][p0Idx]); - for (unsigned int comp = 0; comp < numComponents; ++comp) { - pressureChop_(uCurrentIter[i][fug0Idx + comp], uLastIter[i][fug0Idx + comp]); - } - - } - }; - -private: - static void clampValue_(Scalar &val, - const Scalar minVal, - const Scalar maxVal) - { - val = std::max(minVal, std::min(val, maxVal)); - }; - - static void pressureChop_(Scalar &val, - const Scalar oldVal) - { - const Scalar maxDelta = std::max(oldVal/4.0, 10e3); - clampValue_(val, oldVal - maxDelta, oldVal + maxDelta); - val = std::max(0.0, val); // don't allow negative pressures - } - - static void saturationChop_(Scalar &val, - const Scalar oldVal) - { - const Scalar maxDelta = 0.25; - clampValue_(val, oldVal - maxDelta, oldVal + maxDelta); - clampValue_(val, -0.001, 1.001); - } - -}; - -template <class TypeTag> -class MpNcNewtonChop<TypeTag, /*enableKinetic=*/true> -{ - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { moleFrac00Idx = Indices::moleFrac00Idx }; - enum { S0Idx = Indices::S0Idx }; - enum { p0Idx = Indices::p0Idx }; - -public: - static void chop(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - for (int i = 0; i < uLastIter.size(); ++i) { - for (int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) - saturationChop_(uCurrentIter[i][S0Idx + phaseIdx], - uLastIter[i][S0Idx + phaseIdx]); - pressureChop_(uCurrentIter[i][p0Idx], uLastIter[i][p0Idx]); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - moleFracChop_(uCurrentIter[i][moleFrac00Idx + phaseIdx*numComponents + compIdx], - uLastIter[i][moleFrac00Idx + phaseIdx*numComponents + compIdx]); - } - } - - } - } - -private: - static void clampValue_(Scalar &val, - const Scalar minVal, - const Scalar maxVal) - { - val = std::max(minVal, std::min(val, maxVal)); - }; - - static void pressureChop_(Scalar &val, - const Scalar oldVal) - { - const Scalar maxDelta = std::max(oldVal/4.0, 10e3); - clampValue_(val, oldVal - maxDelta, oldVal + maxDelta); - val = std::max(0.0, val); // don't allow negative pressures - } - - static void saturationChop_(Scalar &val, - const Scalar oldVal) - { - const Scalar maxDelta = 0.25; - clampValue_(val, oldVal - maxDelta, oldVal + maxDelta); - clampValue_(val, -0.001, 1.001); - } - - static void moleFracChop_(Scalar &val, - const Scalar oldVal) - { - // no component mole fraction can change by more than 20% per iteration - const Scalar maxDelta = 0.20; - clampValue_(val, oldVal - maxDelta, oldVal + maxDelta); - clampValue_(val, -0.001, 1.001); - } - -}; - -/*! - * \ingroup Newton - * \brief A MpNc specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * which allows the newton method to abort quicker if the solution is - * way out of bounds. - */ -template <class TypeTag> -class MPNCNewtonController : public NewtonController<TypeTag> -{ - typedef NewtonController<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - - enum {numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents)}; - enum {enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic)}; - enum {p0Idx = Indices::p0Idx}; - enum {S0Idx = Indices::S0Idx}; - - typedef MpNcNewtonChop<TypeTag, enableKinetic> NewtonChop; - -public: - MPNCNewtonController(const Problem &problem) - : ParentType(problem) - { - enableChop_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Newton, EnableChop); - Dune::FMatrixPrecision<>::set_singular_limit(1e-35); - }; - - void newtonUpdate(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - if (this->enableRelativeCriterion_ || this->enablePartialReassemble_) - this->newtonUpdateRelError(uLastIter, deltaU); - - // compute the vertex and element colors for partial - // reassembly - if (this->enablePartialReassemble_) { - const Scalar minReasmTol = 1e-2*this->tolerance_; - const Scalar maxReasmTol = 1e1*this->tolerance_; - Scalar reassembleTol = std::max(minReasmTol, std::min(maxReasmTol, this->error_/1e4)); - - this->model_().jacobianAssembler().updateDiscrepancy(uLastIter, deltaU); - this->model_().jacobianAssembler().computeColors(reassembleTol); - } - - this->writeConvergence_(uLastIter, deltaU); - - if (GET_PARAM_FROM_GROUP(TypeTag, bool, Newton, UseLineSearch)) { - lineSearchUpdate_(uCurrentIter, uLastIter, deltaU); - } - else { - for (unsigned int i = 0; i < uLastIter.size(); ++i) { - uCurrentIter[i] = uLastIter[i]; - uCurrentIter[i] -= deltaU[i]; - } - - if (this->numSteps_ < 2 && enableChop_) { - // put crash barriers along the update path at the - // beginning... - NewtonChop::chop(uCurrentIter, uLastIter); - } - - if (this->enableAbsoluteCriterion_) - { - SolutionVector tmp(uLastIter); - this->absoluteError_ = this->method().model().globalResidual(tmp, uCurrentIter); - this->absoluteError_ /= this->initialAbsoluteError_; - } - } - } - -private: - void lineSearchUpdate_(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - Scalar lambda = 1.0; - Scalar globDef; - - SolutionVector tmp(uLastIter); - Scalar oldGlobDef = this->model_().globalResidual(tmp, uLastIter); - while (true) { - uCurrentIter = deltaU; - uCurrentIter *= -lambda; - uCurrentIter += uLastIter; - - globDef = this->model_().globalResidual(tmp, uCurrentIter); - if (globDef < oldGlobDef || lambda <= 1.0/64) { - this->endIterMsg() << ", defect " << oldGlobDef << "->" << globDef << "@lambda=1/" << 1/lambda; - return; - } - - // try with a smaller update - lambda /= 2; - } - } - - bool enableChop_; -}; -} - -#endif +#include <dumux/implicit/mpnc/mpncnewtoncontroller.hh> diff --git a/dumux/boxmodels/mpnc/mpncproperties.hh b/dumux/boxmodels/mpnc/mpncproperties.hh index 3a4dc02af599115d5ab38dee6e963db8983c71c0..54e0694f5a72a4070654609db7d05e71dc8f5f0e 100644 --- a/dumux/boxmodels/mpnc/mpncproperties.hh +++ b/dumux/boxmodels/mpnc/mpncproperties.hh @@ -1,136 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_PROPERTIES_HH -#define DUMUX_MPNC_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncproperties.hh instead. -#include <dumux/boxmodels/common/boxproperties.hh> - -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup BoxMpNcModel - * \file - * \brief Defines the properties required for the Mp-Nc box model. - */ -namespace Dumux -{ -namespace Properties -{ - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -/*! - * \brief Define the type tag for the compositional twophase box model. - */ -NEW_TYPE_TAG(BoxMPNC, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system -NEW_PROP_TAG(Indices); //!< Enumerations for the model - -NEW_PROP_TAG(BaseFluxVariables); //!< The type of velocity calculation that is to be used - -NEW_PROP_TAG(PressureFormulation); //!< The formulation of the model - -NEW_PROP_TAG(MPNCVtkCommonModule); //!< Vtk writer module for writing the common quantities into the VTK output file -NEW_PROP_TAG(MPNCVtkMassModule); //!< Vtk writer module for writing the mass related quantities into the VTK output file -NEW_PROP_TAG(MPNCVtkEnergyModule); //!< Vtk writer module for writing the energy related quantities into the VTK output file -NEW_PROP_TAG(MPNCVtkCustomModule); //!< Vtk writer module for writing the user-specified quantities into the VTK output file - -NEW_PROP_TAG(VelocityAveragingInModel);//!< Should the averaging of velocities be done in the model? - -//! specify which quantities are written to the vtk output files -NEW_PROP_TAG(VtkAddPorosity); -NEW_PROP_TAG(VtkAddPermeability); -NEW_PROP_TAG(VtkAddBoundaryTypes); -NEW_PROP_TAG(VtkAddSaturations); -NEW_PROP_TAG(VtkAddPressures); -NEW_PROP_TAG(VtkAddVarPressures); -NEW_PROP_TAG(VtkAddVelocities); -NEW_PROP_TAG(VtkAddDensities); -NEW_PROP_TAG(VtkAddMobilities); -NEW_PROP_TAG(VtkAddAverageMolarMass); -NEW_PROP_TAG(VtkAddMassFractions); -NEW_PROP_TAG(VtkAddMoleFractions); -NEW_PROP_TAG(VtkAddMolarities); -NEW_PROP_TAG(VtkAddFugacities); -NEW_PROP_TAG(VtkAddFugacityCoefficients); -NEW_PROP_TAG(VtkAddTemperatures); -NEW_PROP_TAG(VtkAddEnthalpies); -NEW_PROP_TAG(VtkAddInternalEnergies); - -NEW_PROP_TAG(VtkAddxEquil); - -NEW_PROP_TAG(VtkAddReynolds); -NEW_PROP_TAG(VtkAddPrandtl); -NEW_PROP_TAG(VtkAddNusselt); -NEW_PROP_TAG(VtkAddInterfacialArea); - -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters - -NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the soil) -NEW_PROP_TAG(MaterialLawParams); //!< The context material law (extracted from the soil) - -//! The compositional twophase system of fluids which is considered -NEW_PROP_TAG(FluidSystem); - -//! The thermodynamic constraint solver which calculates the -//! composition of any phase given all component fugacities. -NEW_PROP_TAG(CompositionFromFugacitiesSolver); -NEW_PROP_TAG(ConstraintSolver); - -//! Enable the energy equation? -NEW_PROP_TAG(EnableEnergy); - -//! Enable diffusive fluxes? -NEW_PROP_TAG(EnableDiffusion); - -//! Enable kinetic resolution of mass transfer processes? -NEW_PROP_TAG(EnableKinetic); - -//! Enable kinetic resolution of energy transfer processes? -NEW_PROP_TAG(EnableKineticEnergy); - -//! Enable gravity? -NEW_PROP_TAG(ProblemEnableGravity); - -//! Use the smooth upwinding method? -NEW_PROP_TAG(ImplicitEnableSmoothUpwinding); - -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the weight of the upwind direction in the mass conservation equations - -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation - -//! Chop the Newton update at the beginning of the non-linear solver? -NEW_PROP_TAG(NewtonEnableChop); - -//! Which type of fluidstate should be used? -NEW_PROP_TAG(FluidState); - -//! Property for the forchheimer coefficient -NEW_PROP_TAG(SpatialParamsForchCoeff); -} -} - -#endif +#include <dumux/implicit/mpnc/mpncproperties.hh> diff --git a/dumux/boxmodels/mpnc/mpncpropertydefaults.hh b/dumux/boxmodels/mpnc/mpncpropertydefaults.hh index 578332fc70d9769d438e681d18e0a194cebd152d..00ff46142c16475d0ffb663401956b51223c4862 100644 --- a/dumux/boxmodels/mpnc/mpncpropertydefaults.hh +++ b/dumux/boxmodels/mpnc/mpncpropertydefaults.hh @@ -1,286 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_PROPERTY_DEFAULTS_HH -#define DUMUX_MPNC_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncpropertydefaults.hh instead. -#include "mpncindices.hh" - -#include "mpncmodel.hh" -#include "mpncindices.hh" -#include "mpnclocalresidual.hh" -#include "mpncfluxvariables.hh" -#include "mpncvolumevariables.hh" -#include "mpncproperties.hh" -#include "mpncnewtoncontroller.hh" -#include "mpncvtkwritermodule.hh" -#include "mpncvtkwritercommon.hh" -#include "mass/mpncvtkwritermass.hh" -#include "energy/mpncvtkwriterenergy.hh" - -#include <dumux/material/constraintsolvers/compositionfromfugacities.hh> -#include <dumux/material/spatialparams/boxspatialparams.hh> - - -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup BoxMpNcModel - * \file - * \brief Default properties for the Mp-Nc box model. - */ -namespace Dumux -{ -namespace Properties -{ -////////////////////////////////////////////////////////////////// -// default property values -////////////////////////////////////////////////////////////////// - - -//! Set the default pressure formulation to the pressure of the (most) wetting phase -SET_INT_PROP(BoxMPNC, - PressureFormulation, - MpNcPressureFormulation::mostWettingFirst); - -/*! - * \brief Set the property for the number of components. - * - * We just forward the number from the fluid system. - */ -SET_PROP(BoxMPNC, NumComponents) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - static const unsigned int value = FluidSystem::numComponents; -}; - -/*! - * \brief Set the property for the number of fluid phases. - * - * We just forward the number from the fluid system and use an static - * assert to make sure it is 2. - */ -SET_PROP(BoxMPNC, NumPhases) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - static const unsigned int value = FluidSystem::numPhases; -}; - -/*! - * \brief Set the property for the number of equations and primary variables. - */ -SET_PROP(BoxMPNC, NumEq) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - -public: - static const unsigned int value = Indices::NumPrimaryVars; -}; - -/*! - * \brief Set the property for the material parameters by extracting - * it from the material law. - */ -SET_PROP(BoxMPNC, MaterialLawParams) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - -public: - typedef typename MaterialLaw::Params type; -}; - -/*! - * \brief Set the thermodynamic constraint solver which calculates the - * composition of any phase given all component fugacities. - * - * \deprecated version. Use "ConstraintSolver" instead of "CompositionFromFugacitiesSolver" - */ -SET_PROP(BoxMPNC, CompositionFromFugacitiesSolver) // DEPRECATED version. Use "ConstraintSolver" instead of "CompositionFromFugacitiesSolver" -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - typedef Dumux::CompositionFromFugacities<Scalar, FluidSystem> type; // DEPRECATED version. Use "ConstraintSolver" instead of "CompositionFromFugacitiesSolver" -}; - -/*! - * \brief Set the thermodynamic constraint solver which calculates the - * composition of any phase given all component fugacities. - */ -SET_PROP(BoxMPNC, ConstraintSolver) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - -public: - typedef typename GET_PROP_TYPE(TypeTag, CompositionFromFugacitiesSolver) type; -}; - - -//! Use the MpNc local jacobian operator for the MpNc model -SET_TYPE_PROP(BoxMPNC, - LocalResidual, - MPNCLocalResidual<TypeTag>); - -//! Use the MpNc specific newton controller for the MpNc model -SET_PROP(BoxMPNC, NewtonController) -{public: - typedef MPNCNewtonController<TypeTag> type; -}; - -//! the Model property -SET_TYPE_PROP(BoxMPNC, Model, MPNCModel<TypeTag>); - -//! use an isothermal model by default -SET_BOOL_PROP(BoxMPNC, EnableEnergy, false); - -//! disable diffusion by default -SET_BOOL_PROP(BoxMPNC, EnableDiffusion, false); - -//! disable kinetic mass transfer by default -SET_BOOL_PROP(BoxMPNC, EnableKinetic, false); - -//! disable kinetic energy transfer by default -SET_BOOL_PROP(BoxMPNC, EnableKineticEnergy, false); - -//! enable smooth upwinding by default -SET_BOOL_PROP(BoxMPNC, ImplicitEnableSmoothUpwinding, false); - -//! the VolumeVariables property -SET_TYPE_PROP(BoxMPNC, VolumeVariables, MPNCVolumeVariables<TypeTag>); - -//! the FluxVariables property -SET_TYPE_PROP(BoxMPNC, FluxVariables, MPNCFluxVariables<TypeTag>); - -//! the Base of the Fluxvariables property (Darcy / Forchheimer) -SET_TYPE_PROP(BoxMPNC, BaseFluxVariables, BoxDarcyFluxVariables<TypeTag>); - -//! truncate the newton update for the first few Newton iterations of a time step -SET_BOOL_PROP(BoxMPNC, NewtonEnableChop, true); - -//! The indices required by the mpnc model -SET_TYPE_PROP(BoxMPNC, Indices, MPNCIndices<TypeTag, 0>); - -//! the upwind weight for the mass conservation equations. -SET_SCALAR_PROP(BoxMPNC, ImplicitMassUpwindWeight, 1.0); - -//! weight for the upwind mobility in the velocity calculation -SET_SCALAR_PROP(BoxMPNC, ImplicitMobilityUpwindWeight, 1.0); - -//! The spatial parameters to be employed. -//! Use BoxSpatialParams by default. -SET_TYPE_PROP(BoxMPNC, SpatialParams, BoxSpatialParams<TypeTag>); - -//! The VTK writer module for common quantities -SET_PROP(BoxMPNC, MPNCVtkCommonModule) -{ - typedef MPNCVtkWriterCommon<TypeTag> type; -}; - -//! The VTK writer module for quantities which are specific for each -//! mass module -SET_PROP(BoxMPNC, MPNCVtkMassModule) -{ -private: enum { enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic) }; -public: typedef MPNCVtkWriterMass<TypeTag, enableKinetic> type; -}; - -//! The VTK writer module for quantities which are specific for each -//! energy module -SET_PROP(BoxMPNC, MPNCVtkEnergyModule) -{ -private: - enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) }; - enum { enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy) }; -public: - typedef MPNCVtkWriterEnergy<TypeTag, enableEnergy, enableKineticEnergy> type; -}; - -//! The VTK writer for user specified data (does nothing by default) -SET_PROP(BoxMPNC, MPNCVtkCustomModule) -{ typedef MPNCVtkWriterModule<TypeTag> type; }; - -/*! - * \brief The fluid state which is used by the volume variables to - * store the thermodynamic state. This should be chosen - * appropriately for the model ((non-)isothermal, equilibrium, ...). - * This can be done in the problem. - */ -SET_PROP(BoxMPNC, FluidState){ - private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - public: - typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type; -}; - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55); - - -//!< Should the averaging of velocities be done in the Model? (By default in the output) -SET_BOOL_PROP(BoxMPNC, VelocityAveragingInModel, false); - -//! Specify what to add to the VTK output by default -SET_BOOL_PROP(BoxMPNC, VtkAddPorosity, true); -SET_BOOL_PROP(BoxMPNC, VtkAddPermeability, false); -SET_BOOL_PROP(BoxMPNC, VtkAddBoundaryTypes, false); -SET_BOOL_PROP(BoxMPNC, VtkAddSaturations, true); -SET_BOOL_PROP(BoxMPNC, VtkAddPressures, true); -SET_BOOL_PROP(BoxMPNC, VtkAddVarPressures, false); -SET_BOOL_PROP(BoxMPNC, VtkAddVelocities, false); -SET_BOOL_PROP(BoxMPNC, VtkAddDensities, true); -SET_BOOL_PROP(BoxMPNC, VtkAddMobilities, true); -SET_BOOL_PROP(BoxMPNC, VtkAddAverageMolarMass, false); -SET_BOOL_PROP(BoxMPNC, VtkAddMassFractions, false); -SET_BOOL_PROP(BoxMPNC, VtkAddMoleFractions, true); -SET_BOOL_PROP(BoxMPNC, VtkAddMolarities, false); -SET_BOOL_PROP(BoxMPNC, VtkAddFugacities, false); -SET_BOOL_PROP(BoxMPNC, VtkAddFugacityCoefficients, false); -SET_BOOL_PROP(BoxMPNC, VtkAddTemperatures, false); -SET_BOOL_PROP(BoxMPNC, VtkAddEnthalpies, true); -SET_BOOL_PROP(BoxMPNC, VtkAddInternalEnergies, false); -SET_BOOL_PROP(BoxMPNC, VtkAddReynolds, false); -SET_BOOL_PROP(BoxMPNC, VtkAddPrandtl, false); -SET_BOOL_PROP(BoxMPNC, VtkAddNusselt, false); -SET_BOOL_PROP(BoxMPNC, VtkAddInterfacialArea, false); -SET_BOOL_PROP(BoxMPNC, VtkAddxEquil, false); - -// enable gravity by default -SET_BOOL_PROP(BoxMPNC, ProblemEnableGravity, true); - -} - -} - -#endif +#include <dumux/implicit/mpnc/mpncpropertydefaults.hh> diff --git a/dumux/boxmodels/mpnc/mpncvolumevariables.hh b/dumux/boxmodels/mpnc/mpncvolumevariables.hh index bba2e1b0f7550cfbb5354d0dcbcd35352bce1269..542d66e2e93541bea8f1d5d28f657f492a005664 100644 --- a/dumux/boxmodels/mpnc/mpncvolumevariables.hh +++ b/dumux/boxmodels/mpnc/mpncvolumevariables.hh @@ -1,368 +1,3 @@ -// -*- 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 Contains the secondary variables (Quantities which are - * constant within a finite volume) of the M-phase, N-component - * model. - */ -#ifndef DUMUX_MPNC_VOLUME_VARIABLES_HH -#define DUMUX_MPNC_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncvolumevariables.hh instead. -#include "diffusion/volumevariables.hh" -#include "energy/mpncvolumevariablesenergy.hh" -#include "mass/mpncvolumevariablesmass.hh" -#include "mpncvolumevariablesia.hh" - -#include <dumux/boxmodels/common/boxvolumevariables.hh> -#include <dumux/material/constraintsolvers/ncpflash.hh> - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * \ingroup BoxVolumeVariables - * \brief Contains the quantities which are are constant within a - * finite volume in the M-phase, N-component model. - */ -template <class TypeTag> -class MPNCVolumeVariables - : public BoxVolumeVariables<TypeTag> - , public MPNCVolumeVariablesIA<TypeTag, GET_PROP_VALUE(TypeTag, EnableKinetic), GET_PROP_VALUE(TypeTag, EnableKineticEnergy)> - , public MPNCVolumeVariablesMass<TypeTag, GET_PROP_VALUE(TypeTag, EnableKinetic)> - , public MPNCVolumeVariablesDiffusion<TypeTag, GET_PROP_VALUE(TypeTag, EnableDiffusion) || GET_PROP_VALUE(TypeTag, EnableKinetic)> - , public MPNCVolumeVariablesEnergy<TypeTag, GET_PROP_VALUE(TypeTag, EnableEnergy), GET_PROP_VALUE(TypeTag, EnableKineticEnergy)> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - - enum {dimWorld=GridView::dimensionworld}; - typedef Dune::FieldVector<Scalar,dimWorld> GlobalPosition; - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; - enum {nPhaseIdx = FluidSystem::nPhaseIdx}; - - // formulations - enum { - pressureFormulation = GET_PROP_VALUE(TypeTag, PressureFormulation), - mostWettingFirst = MpNcPressureFormulation::mostWettingFirst, - leastWettingFirst = MpNcPressureFormulation::leastWettingFirst - }; - - enum {numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; - enum {numComponents = GET_PROP_VALUE(TypeTag, NumComponents)}; - enum {enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy)}; - enum {enableKinetic = GET_PROP_VALUE(TypeTag, EnableKinetic)}; - enum {enableKineticEnergy = GET_PROP_VALUE(TypeTag, EnableKineticEnergy)}; - enum {enableDiffusion = GET_PROP_VALUE(TypeTag, EnableDiffusion) || enableKinetic}; - enum {S0Idx = Indices::S0Idx}; - enum {p0Idx = Indices::p0Idx}; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef MPNCVolumeVariablesMass<TypeTag, enableKinetic> MassVolumeVariables; - typedef MPNCVolumeVariablesEnergy<TypeTag, enableEnergy, enableKineticEnergy> EnergyVolumeVariables; - typedef MPNCVolumeVariablesIA<TypeTag, enableKinetic, enableKineticEnergy> IAVolumeVariables; - typedef MPNCVolumeVariablesDiffusion<TypeTag, enableDiffusion> DiffusionVolumeVariables; - -public: - MPNCVolumeVariables() - { hint_ = NULL; }; - - /*! - * \brief Set the volume variables which should be used as initial - * conditions for complex calculations. - */ - void setHint(const Implementation *hint) - { - hint_ = hint; - } - - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx, - const bool isOldSol) - { - Valgrind::CheckDefined(priVars); - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - ParentType::checkDefined(); - - ParameterCache paramCache; - - ///////////// - // set the phase saturations - ///////////// - Scalar sumSat = 0; - for (int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) { - sumSat += priVars[S0Idx + phaseIdx]; - fluidState_.setSaturation(phaseIdx, priVars[S0Idx + phaseIdx]); - } - Valgrind::CheckDefined(sumSat); - fluidState_.setSaturation(numPhases - 1, 1.0 - sumSat); - - ///////////// - // set the fluid phase temperatures - ///////////// - EnergyVolumeVariables::updateTemperatures(fluidState_, - paramCache, - priVars, - element, - fvGeometry, - scvIdx, - problem); - - ///////////// - // set the phase pressures - ///////////// - // capillary pressure parameters - const MaterialLawParams &materialParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - // capillary pressures - Scalar capPress[numPhases]; - MaterialLaw::capillaryPressures(capPress, materialParams, fluidState_); - // add to the pressure of the first fluid phase - - // depending on which pressure is stored in the primary variables - if(pressureFormulation == mostWettingFirst){ - // This means that the pressures are sorted from the most wetting to the least wetting-1 in the primary variables vector. - // For two phases this means that there is one pressure as primary variable: pw - const Scalar pw = priVars[p0Idx]; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - fluidState_.setPressure(phaseIdx, pw - capPress[0] + capPress[phaseIdx]); - } - else if(pressureFormulation == leastWettingFirst){ - // This means that the pressures are sorted from the least wetting to the most wetting-1 in the primary variables vector. - // For two phases this means that there is one pressure as primary variable: pn - const Scalar pn = priVars[p0Idx]; - for (int phaseIdx = numPhases-1; phaseIdx >= 0; --phaseIdx) - fluidState_.setPressure(phaseIdx, pn - capPress[numPhases-1] + capPress[phaseIdx]); - } - else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << pressureFormulation << " is invalid."); - - ///////////// - // set the fluid compositions - ///////////// - MassVolumeVariables::update(fluidState_, - paramCache, - priVars, - hint_, - problem, - element, - fvGeometry, - scvIdx); - MassVolumeVariables::checkDefined(); - - ///////////// - // Porosity - ///////////// - - // porosity - porosity_ = problem.spatialParams().porosity(element, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(porosity_); - - ///////////// - // Phase mobilities - ///////////// - - // relative permeabilities - MaterialLaw::relativePermeabilities(relativePermeability_, - materialParams, - fluidState_); - - // dynamic viscosities - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // viscosities - Scalar mu = FluidSystem::viscosity(fluidState_, paramCache, phaseIdx); - fluidState_.setViscosity(phaseIdx, mu); - } - - ///////////// - // diffusion - ///////////// - - // update the diffusion part of the volume data - DiffusionVolumeVariables::update(fluidState_, paramCache, *this, problem); - DiffusionVolumeVariables::checkDefined(); - - ///////////// - // energy - ///////////// - - // update the remaining parts of the energy module - EnergyVolumeVariables::update(fluidState_, - paramCache, - element, - fvGeometry, - scvIdx, - problem); - EnergyVolumeVariables::checkDefined(); - - // make sure the quantities in the fluid state are well-defined - fluidState_.checkDefined(); - - // specific interfacial area, - // well also all the dimensionless numbers :-) - // well, also the mass transfer rate - IAVolumeVariables::update(*this, - fluidState_, - paramCache, - priVars, - problem, - element, - fvGeometry, - scvIdx); - IAVolumeVariables::checkDefined(); - checkDefined(); - } - - /*! - * \brief Return the fluid configuration at the given primary - * variables - */ - const FluidState &fluidState() const - { return fluidState_; } - - /*! - * \brief Returns the effective mobility of a given phase within - * the control volume. - */ - Scalar mobility(const unsigned int phaseIdx) const - { - return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); - } - - /*! - * \brief Returns the viscosity of a given phase within - * the control volume. - */ - Scalar viscosity(const unsigned int phaseIdx) const - { return fluidState_.viscosity(phaseIdx); } - - /*! - * \brief Returns the relative permeability of a given phase within - * the control volume. - */ - Scalar relativePermeability(const unsigned int phaseIdx) const - { return relativePermeability_[phaseIdx]; } - - /*! - * \brief Returns the average porosity within the control volume. - */ - Scalar porosity() const - { return porosity_; } - - /*! - * \brief Returns true iff the fluid state is in the active set - * for a phase, - */ - bool isPhaseActive(const unsigned int phaseIdx) const - { - return - phasePresentIneq(fluidState(), phaseIdx) - - phaseNotPresentIneq(fluidState(), phaseIdx) - >= 0; - } - - /*! - * \brief Returns the value of the NCP-function for a phase. - */ - Scalar phaseNcp(const unsigned int phaseIdx) const - { - Scalar aEval = phaseNotPresentIneq(this->evalPoint().fluidState(), phaseIdx); - Scalar bEval = phasePresentIneq(this->evalPoint().fluidState(), phaseIdx); - if (aEval > bEval) - return phasePresentIneq(fluidState(), phaseIdx); - return phaseNotPresentIneq(fluidState(), phaseIdx); - }; - - /*! - * \brief Returns the value of the inequality where a phase is - * present. - */ - Scalar phasePresentIneq(const FluidState &fluidState, - const unsigned int phaseIdx) const - { return fluidState.saturation(phaseIdx); } - - /*! - * \brief Returns the value of the inequality where a phase is not - * present. - */ - Scalar phaseNotPresentIneq(const FluidState &fluidState, - const unsigned int phaseIdx) const - { - // difference of sum of mole fractions in the phase from 100% - Scalar a = 1; - for (int compIdx = 0; compIdx < numComponents; ++compIdx) - a -= fluidState.moleFraction(phaseIdx, compIdx); - return a; - } - - /*! - * \brief If running in valgrind this makes sure that all - * quantities in the volume variables are defined. - */ - void checkDefined() const - { -#if !defined NDEBUG && HAVE_VALGRIND - ParentType::checkDefined(); - - Valgrind::CheckDefined(porosity_); - Valgrind::CheckDefined(hint_); - Valgrind::CheckDefined(relativePermeability_); - - fluidState_.checkDefined(); -#endif - } - -protected: - Scalar porosity_; //!< Effective porosity within the control volume - Scalar relativePermeability_[numPhases]; //!< Effective relative permeability within the control volume - - const Implementation *hint_; - - //! Mass fractions of each component within each phase - FluidState fluidState_; -}; - -} // end namepace - -#endif +#include <dumux/implicit/mpnc/mpncvolumevariables.hh> diff --git a/dumux/boxmodels/mpnc/mpncvolumevariablesia.hh b/dumux/boxmodels/mpnc/mpncvolumevariablesia.hh index 7e62cb7ed967666e2997b910e658589d44dc75ef..7123f7441f7cf048c23614c57b9b0eb8348e2027 100644 --- a/dumux/boxmodels/mpnc/mpncvolumevariablesia.hh +++ b/dumux/boxmodels/mpnc/mpncvolumevariablesia.hh @@ -1,85 +1,3 @@ -// -*- 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 This class contains the volume variables required for the - * modules which require the specific interfacial area between - * fluid phases. - */ -#ifndef DUMUX_MPNC_VOLUME_VARIABLES_IA_HH -#define DUMUX_MPNC_VOLUME_VARIABLES_IA_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncvolumevariablesia.hh instead. -#include <dumux/boxmodels/mpnc/mpncproperties.hh> - -namespace Dumux -{ - -/*! - * \brief This class contains the volume variables required for the - * modules which require the specific interfacial area between - * fluid phases. - * - * This is the specialization for the cases which do _not_ require - * specific interfacial area. - */ -template <class TypeTag, bool enableKinetic /* = false */, bool enableKineticEnergy /* = false */> -class MPNCVolumeVariablesIA -{ - static_assert(not enableKinetic and not enableKineticEnergy, - "The kinetic energy modules need specific interfacial area " - "but no suitable specialization of the IA volume variables module " - "has been included."); - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename FluidSystem::ParameterCache ParameterCache; - typedef typename GridView::template Codim<0>::Entity Element; - -public: - /*! - * \brief Updates the volume specific interfacial area [m^2 / m^3] between the phases. - */ - void update(const VolumeVariables & volVars, - const FluidState &fluidState, - const ParameterCache ¶mCache, - const PrimaryVariables &priVars, - const Problem &problem, - const Element & element, - const FVElementGeometry & fvGeometry, - const unsigned int scvIdx) - { - } - - /*! - * \brief If running in valgrind this makes sure that all - * quantities in the volume variables are defined. - */ - void checkDefined() const - { } -}; - -} // namespace Dumux - -#endif +#include <dumux/implicit/mpnc/mpncvolumevariablesia.hh> diff --git a/dumux/boxmodels/mpnc/mpncvtkwriter.hh b/dumux/boxmodels/mpnc/mpncvtkwriter.hh index afc912214ed28c084d369f4389752a1019e66a64..0a97ddcdd24cacc1535ac4e77d1094f9d8623eb0 100644 --- a/dumux/boxmodels/mpnc/mpncvtkwriter.hh +++ b/dumux/boxmodels/mpnc/mpncvtkwriter.hh @@ -1,126 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_VTK_WRITER_HH -#define DUMUX_MPNC_VTK_WRITER_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncvtkwriter.hh instead. -#include "mpncproperties.hh" - -#include <dumux/io/vtkmultiwriter.hh> - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * \brief Writes the VTK output files for a - * solution of the Mp-Nc model. - */ -template<class TypeTag> -class MPNCVtkWriter -{ - typedef typename GET_PROP_TYPE(TypeTag, MPNCVtkCommonModule) MPNCVtkCommonModule; - typedef typename GET_PROP_TYPE(TypeTag, MPNCVtkMassModule) MPNCVtkMassModule; - typedef typename GET_PROP_TYPE(TypeTag, MPNCVtkEnergyModule) MPNCVtkEnergyModule; - typedef typename GET_PROP_TYPE(TypeTag, MPNCVtkCustomModule) MPNCVtkCustomModule; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - -public: - MPNCVtkWriter(const Problem &problem) - : problem_(problem) - , commonWriter_(problem) - , massWriter_(problem) - , energyWriter_(problem) - , customWriter_(problem) - { - } - - /*! - * \brief Add the current solution to the VtkMultiWriter. - */ - template <class MultiWriter> - void addCurrentSolution(MultiWriter &writer) - { - // tell sub-writers to allocate their buffers - commonWriter_.allocBuffers(writer); - massWriter_.allocBuffers(writer); - energyWriter_.allocBuffers(writer); - customWriter_.allocBuffers(writer); - - // iterate over grid - FVElementGeometry fvGeometry; - ElementVolumeVariables elemVolVars; - ElementBoundaryTypes elemBcTypes; - - ElementIterator elemIt = problem_.gridView().template begin<0>(); - ElementIterator elemEndIt = problem_.gridView().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - fvGeometry.update(problem_.gridView(), *elemIt); - elemBcTypes.update(problem_, *elemIt); - this->problem_.model().setHints(*elemIt, elemVolVars); - elemVolVars.update(problem_, - *elemIt, - fvGeometry, - false); - this->problem_.model().updateCurHints(*elemIt, elemVolVars); - - // tell the sub-writers to do what ever they need to with - // their internal buffers when a given element is seen. - commonWriter_.processElement(*elemIt, - fvGeometry, - elemVolVars, - elemBcTypes); - massWriter_.processElement(*elemIt, - fvGeometry, - elemVolVars, - elemBcTypes); - energyWriter_.processElement(*elemIt, - fvGeometry, - elemVolVars, - elemBcTypes); - customWriter_.processElement(*elemIt, - fvGeometry, - elemVolVars, - elemBcTypes); - } - - // write everything to the output file - commonWriter_.commitBuffers(writer); - massWriter_.commitBuffers(writer); - energyWriter_.commitBuffers(writer); - customWriter_.commitBuffers(writer); - } - -private: - const Problem &problem_; - - MPNCVtkCommonModule commonWriter_; - MPNCVtkMassModule massWriter_; - MPNCVtkEnergyModule energyWriter_; - MPNCVtkCustomModule customWriter_; -}; - -} - -#endif +#include <dumux/implicit/mpnc/mpncvtkwriter.hh> diff --git a/dumux/boxmodels/mpnc/mpncvtkwritercommon.hh b/dumux/boxmodels/mpnc/mpncvtkwritercommon.hh index 6a83d7dae20e0c8e3caa9260acebfd1dda65c36c..d43da50121a35353d5b897300540996199b67f1d 100644 --- a/dumux/boxmodels/mpnc/mpncvtkwritercommon.hh +++ b/dumux/boxmodels/mpnc/mpncvtkwritercommon.hh @@ -1,283 +1,3 @@ -// -*- 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 VTK writer module for the common quantities of the MpNc - * model. - */ -#ifndef DUMUX_MPNC_VTK_WRITER_COMMON_HH -#define DUMUX_MPNC_VTK_WRITER_COMMON_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncvtkwritercommon.hh instead. -#include "mpncvtkwritermodule.hh" - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * - * \brief VTK writer module for the common quantities of the MpNc - * model. - */ -template<class TypeTag> -class MPNCVtkWriterCommon : public MPNCVtkWriterModule<TypeTag> -{ - typedef MPNCVtkWriterModule<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename ParentType::ScalarVector ScalarVector; - typedef typename ParentType::PhaseVector PhaseVector; - typedef typename ParentType::ComponentVector ComponentVector; - typedef typename ParentType::PhaseComponentMatrix PhaseComponentMatrix; - - enum { dim = GridView::dimension }; - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) }; - - typedef Dune::FieldVector<Scalar, dim> DimVector; - typedef Dune::BlockVector<DimVector> DimField; - typedef Dune::array<DimField, numPhases> PhaseDimField; - -public: - MPNCVtkWriterCommon(const Problem &problem) - : ParentType(problem) - { - porosityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddPorosity); - permeabilityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddPermeability); - boundaryTypesOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddBoundaryTypes); - saturationOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddSaturations); - pressureOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddPressures); - velocityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocities); - densityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddDensities); - mobilityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddMobilities); - averageMolarMassOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddAverageMolarMass); - massFracOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddMassFractions); - moleFracOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddMoleFractions); - molarityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddMolarities); - } - - /*! - * \brief Allocate memory for the scalar fields we would like to - * write to the VTK file. - */ - template <class MultiWriter> - void allocBuffers(MultiWriter &writer) - { - if (porosityOutput_) - this->resizeScalarBuffer_(porosity_); - if (permeabilityOutput_) - this->resizeScalarBuffer_(permeability_); - if (boundaryTypesOutput_) - this->resizeScalarBuffer_(boundaryTypes_); - - if (velocityOutput_) { - Scalar nVerts = this->problem_.gridView().size(dim); - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { - velocity_[phaseIdx].resize(nVerts); - velocity_[phaseIdx] = 0; - } - this->resizeScalarBuffer_(boxSurface_); - } - - if (saturationOutput_) this->resizePhaseBuffer_(saturation_); - if (pressureOutput_) this->resizePhaseBuffer_(pressure_); - if (densityOutput_) this->resizePhaseBuffer_(density_); - if (mobilityOutput_) this->resizePhaseBuffer_(mobility_); - if (averageMolarMassOutput_) this->resizePhaseBuffer_(averageMolarMass_); - if (moleFracOutput_) this->resizePhaseComponentBuffer_(moleFrac_); - if (massFracOutput_) this->resizePhaseComponentBuffer_(massFrac_); - if (molarityOutput_) this->resizePhaseComponentBuffer_(molarity_); - } - - /*! - * \brief Modify the internal buffers according to the volume - * variables seen on an element - */ - void processElement(const Element &elem, - const FVElementGeometry &fvGeometry, - const ElementVolumeVariables &elemVolVars, - const ElementBoundaryTypes &elemBcTypes) - { - int numLocalVertices = elem.geometry().corners(); - for (int localVertexIdx = 0; localVertexIdx < numLocalVertices; ++localVertexIdx) { - int globalIdx = this->problem_.vertexMapper().map(elem, localVertexIdx, dim); - const VolumeVariables &volVars = elemVolVars[localVertexIdx]; - - if (porosityOutput_) porosity_[globalIdx] = volVars.porosity(); - - // works for scalar permeability in spatialparameters - if (permeabilityOutput_) permeability_[globalIdx] = this->problem_.spatialParams().intrinsicPermeability(elem,fvGeometry,localVertexIdx); - - // calculate a single value for the boundary type: use one - // bit for each equation and set it to 1 if the equation - // is used for a dirichlet condition - int tmp = 0; - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - if (elemBcTypes[localVertexIdx].isDirichlet(eqIdx)) - tmp += (1 << eqIdx); - } - if (boundaryTypesOutput_) boundaryTypes_[globalIdx] = tmp; - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - if (saturationOutput_) saturation_[phaseIdx][globalIdx] = volVars.fluidState().saturation(phaseIdx); - if (pressureOutput_) pressure_[phaseIdx][globalIdx] = volVars.fluidState().pressure(phaseIdx); - if (densityOutput_) density_[phaseIdx][globalIdx] = volVars.fluidState().density(phaseIdx); - if (mobilityOutput_) mobility_[phaseIdx][globalIdx] = volVars.mobility(phaseIdx); - if (averageMolarMassOutput_) averageMolarMass_[phaseIdx][globalIdx] = volVars.fluidState().averageMolarMass(phaseIdx); - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - if (moleFracOutput_) moleFrac_[phaseIdx][compIdx][globalIdx] = volVars.fluidState().moleFraction(phaseIdx, compIdx); - if (massFracOutput_) massFrac_[phaseIdx][compIdx][globalIdx] = volVars.fluidState().massFraction(phaseIdx, compIdx); - if (molarityOutput_) molarity_[phaseIdx][compIdx][globalIdx] = volVars.fluidState().molarity(phaseIdx, compIdx); - } - } - } - - // calculate velocities if requested by the problem - if (velocityOutput_) { - for (int faceIdx = 0; faceIdx < fvGeometry.numEdges; ++ faceIdx) { - int i = fvGeometry.subContVolFace[faceIdx].i; - int I = this->problem_.vertexMapper().map(elem, i, dim); - - int j = fvGeometry.subContVolFace[faceIdx].j; - int J = this->problem_.vertexMapper().map(elem, j, dim); - - FluxVariables fluxVars(this->problem_, - elem, - fvGeometry, - faceIdx, - elemVolVars); - - Scalar scvfArea = fvGeometry.subContVolFace[faceIdx].normal.two_norm(); - scvfArea *= fluxVars.extrusionFactor(); - - boxSurface_[I] += scvfArea; - boxSurface_[J] += scvfArea; - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - Dune::FieldVector<Scalar, dim> velocity; - velocity = fluxVars.velocity(phaseIdx); - velocity *= scvfArea; - velocity_[phaseIdx][I] += velocity; - velocity_[phaseIdx][J] += velocity; - - } // end for all phases - } // end for all faces - } // end if velocityOutput_ - } - - /*! - * \brief Add all buffers to the VTK output writer. - */ - template <class MultiWriter> - void commitBuffers(MultiWriter &writer) - { - if (saturationOutput_) - this->commitPhaseBuffer_(writer, "S_%s", saturation_); - - if (pressureOutput_) - this->commitPhaseBuffer_(writer, "p_%s", pressure_); - - if (densityOutput_) - this->commitPhaseBuffer_(writer, "rho_%s", density_); - - if (averageMolarMassOutput_) - this->commitPhaseBuffer_(writer, "M_%s", averageMolarMass_); - - if (mobilityOutput_) - this->commitPhaseBuffer_(writer, "lambda_%s", mobility_); - - if (porosityOutput_) - this->commitScalarBuffer_(writer, "porosity", porosity_); - - if (boundaryTypesOutput_) - this->commitScalarBuffer_(writer, "boundary types", boundaryTypes_); - - if (moleFracOutput_) - this->commitPhaseComponentBuffer_(writer, "x_%s^%s", moleFrac_); - - if (massFracOutput_) - this->commitPhaseComponentBuffer_(writer, "X_%s^%s", massFrac_); - - if(molarityOutput_) - this->commitPhaseComponentBuffer_(writer, "c_%s^%s", molarity_); - - if (velocityOutput_) { - int nVerts = this->problem_.gridView().size(dim); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - // first, divide the velocity field by the - // respective finite volume's surface area - for (int i = 0; i < nVerts; ++i) - velocity_[phaseIdx][i] /= boxSurface_[i]; - // commit the phase velocity - std::ostringstream oss; - oss << "velocity_" << FluidSystem::phaseName(phaseIdx); - writer.attachVertexData(velocity_[phaseIdx], - oss.str(), - dim); - } - } - } - -private: - bool porosityOutput_; - bool permeabilityOutput_ ; - bool boundaryTypesOutput_; - bool saturationOutput_; - bool pressureOutput_; - bool velocityOutput_; - bool densityOutput_; - bool mobilityOutput_; - bool massFracOutput_; - bool moleFracOutput_; - bool molarityOutput_; - bool averageMolarMassOutput_; - - PhaseVector saturation_; - PhaseVector pressure_; - PhaseVector density_; - PhaseVector mobility_; - PhaseVector averageMolarMass_; - - PhaseDimField velocity_; - ScalarVector boxSurface_; - - ScalarVector porosity_; - ScalarVector permeability_; - ScalarVector temperature_; - ScalarVector boundaryTypes_; - - PhaseComponentMatrix moleFrac_; - PhaseComponentMatrix massFrac_; - PhaseComponentMatrix molarity_; - - ComponentVector fugacity_; -}; - -} - -#endif +#include <dumux/implicit/mpnc/mpncvtkwritercommon.hh> diff --git a/dumux/boxmodels/mpnc/mpncvtkwritermodule.hh b/dumux/boxmodels/mpnc/mpncvtkwritermodule.hh index 061903c030d5ac7c5d75f68d31533505a6d1cab3..9befe9507e6c827320f07bce3944a5b365290dfa 100644 --- a/dumux/boxmodels/mpnc/mpncvtkwritermodule.hh +++ b/dumux/boxmodels/mpnc/mpncvtkwritermodule.hh @@ -1,256 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -#ifndef DUMUX_MPNC_VTK_BASE_WRITER_HH -#define DUMUX_MPNC_VTK_BASE_WRITER_HH +#warning This file is deprecated. Include dumux/implicit/mpnc/mpncvtkwritermodule.hh instead. -#include <cstdio> - -#include <dune/common/array.hh> -#include <dune/istl/bvector.hh> - -#include <dumux/io/vtkmultiwriter.hh> -#include "mpncproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup MPNCModel - * - * \brief A VTK writer module which adheres to the required API but - * does nothing. - * - * This class also provides some convenience methods for buffer - * management. - */ -template<class TypeTag> -class MPNCVtkWriterModule -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GridView::template Codim<0>::Entity Element; - - enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) }; - enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; - enum { dim = GridView::dimension }; - -public: - typedef std::vector<Dune::FieldVector<Scalar, 1> > ScalarVector; - typedef Dune::array<ScalarVector, numPhases> PhaseVector; - typedef Dune::array<ScalarVector, numComponents> ComponentVector; - typedef Dune::array<ComponentVector, numPhases> PhaseComponentMatrix; - - MPNCVtkWriterModule(const Problem &problem) - : problem_(problem) - { - } - - /*! - * \brief Allocate memory for the scalar fields we would like to - * write to the VTK file. - */ - template <class MultiWriter> - void allocBuffers(MultiWriter &writer) - { - } - - /*! - * \brief Modify the internal buffers according to the volume - * variables seen on an element - */ - void processElement(const Element &elem, - const FVElementGeometry &fvGeometry, - const ElementVolumeVariables &elemCurVolVars, - const ElementBoundaryTypes &elemBcTypes) - { - } - - /*! - * \brief Add all buffers to the VTK output writer. - */ - template <class MultiWriter> - void commitBuffers(MultiWriter &writer) - { - } - -protected: - /*! - * \brief Allocate the space for a buffer storing a scalar quantity - */ - void resizeScalarBuffer_(ScalarVector &buffer, - bool vertexCentered = true) - { - Scalar n; // numVertices for vertexCentereed, numVolumes for volume centered - if (vertexCentered) - n = problem_.gridView().size(dim); - else - n = problem_.gridView().size(0); - - buffer.resize(n); - std::fill(buffer.begin(), buffer.end(), 0.0); - } - - /*! - * \brief Allocate the space for a buffer storing a phase-specific - * quantity - */ - void resizePhaseBuffer_(PhaseVector &buffer, - bool vertexCentered = true) - { - Scalar n; // numVertices for vertexCentereed, numVolumes for volume centered - if (vertexCentered) - n = problem_.gridView().size(dim); - else - n = problem_.gridView().size(0); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - buffer[phaseIdx].resize(n); - std::fill(buffer[phaseIdx].begin(), buffer[phaseIdx].end(), 0.0); - } - } - - /*! - * \brief Allocate the space for a buffer storing a component - * specific quantity - */ - void resizeComponentBuffer_(ComponentVector &buffer, - bool vertexCentered = true) - { - Scalar n;// numVertices for vertexCentereed, numVolumes for volume centered - if (vertexCentered) - n = problem_.gridView().size(dim); - else - n = problem_.gridView().size(0); - - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - buffer[compIdx].resize(n); - std::fill(buffer[compIdx].begin(), buffer[compIdx].end(), 0.0); - } - } - - /*! - * \brief Allocate the space for a buffer storing a phase and - * component specific buffer - */ - void resizePhaseComponentBuffer_(PhaseComponentMatrix &buffer, - bool vertexCentered = true) - { - Scalar n;// numVertices for vertexCentereed, numVolumes for volume centered - if (vertexCentered) - n = problem_.gridView().size(dim); - else - n = problem_.gridView().size(0); - - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - buffer[phaseIdx][compIdx].resize(n); - std::fill(buffer[phaseIdx][compIdx].begin(), buffer[phaseIdx][compIdx].end(), 0.0); - } - } - } - - /*! - * \brief Add a phase-specific buffer to the VTK result file. - */ - template <class MultiWriter> - void commitScalarBuffer_(MultiWriter &writer, - const char *name, - ScalarVector &buffer, - bool vertexCentered = true) - { - if (vertexCentered) - writer.attachVertexData(buffer, name, 1); - else - writer.attachCellData(buffer, name, 1); - } - - /*! - * \brief Add a phase-specific buffer to the VTK result file. - */ - template <class MultiWriter> - void commitPhaseBuffer_(MultiWriter &writer, - const char *pattern, - PhaseVector &buffer, - bool vertexCentered = true) - { - char name[512]; - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - snprintf(name, 512, pattern, FluidSystem::phaseName(phaseIdx)); - - if (vertexCentered) - writer.attachVertexData(buffer[phaseIdx], name, 1); - else - writer.attachCellData(buffer[phaseIdx], name, 1); - } - } - - /*! - * \brief Add a component-specific buffer to the VTK result file. - */ - template <class MultiWriter> - void commitComponentBuffer_(MultiWriter &writer, - const char *pattern, - ComponentVector &buffer, - bool vertexCentered = true) - { - char name[512]; - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - snprintf(name, 512, pattern, FluidSystem::componentName(compIdx)); - - if (vertexCentered) - writer.attachVertexData(buffer[compIdx], name, 1); - else - writer.attachCellData(buffer[compIdx], name, 1); - } - } - - /*! - * \brief Add a phase and component specific quantities to the output. - */ - template <class MultiWriter> - void commitPhaseComponentBuffer_(MultiWriter &writer, - const char *pattern, - PhaseComponentMatrix &buffer, - bool vertexCentered = true) - { - char name[512]; - for (int phaseIdx= 0; phaseIdx < numPhases; ++phaseIdx) { - for (int compIdx = 0; compIdx < numComponents; ++compIdx) { - snprintf(name, 512, pattern, - FluidSystem::phaseName(phaseIdx), - FluidSystem::componentName(compIdx)); - - if (vertexCentered) - writer.attachVertexData(buffer[phaseIdx][compIdx], name, 1); - else - writer.attachCellData(buffer[phaseIdx][compIdx], name, 1); - } - } - } - - const Problem &problem_; -}; - -} - -#endif +#include <dumux/implicit/mpnc/mpncvtkwritermodule.hh> diff --git a/dumux/boxmodels/richards/richardsindices.hh b/dumux/boxmodels/richards/richardsindices.hh index 47e341a02aee3d3e5a87d99ea3909bc4f27dffda..b7b43a3d80a9f9045df9c35065fb4674be415c98 100644 --- a/dumux/boxmodels/richards/richardsindices.hh +++ b/dumux/boxmodels/richards/richardsindices.hh @@ -1,67 +1,3 @@ -// -*- 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 Index names for the Richards model. - */ -#ifndef DUMUX_RICHARDS_INDICES_HH -#define DUMUX_RICHARDS_INDICES_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardsindices.hh instead. -#include "richardsproperties.hh" - -namespace Dumux -{ -// \{ - -/*! - * \ingroup RichardsModel - * \ingroup BoxIndices - * \brief Index names for the Richards model. - */ - -template <class TypeTag> -struct RichardsIndices -{ - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - ////////// - // primary variable indices - ////////// - - //! Primary variable index for the wetting phase pressure - static const int pwIdx = 0; - - ////////// - // equation indices - ////////// - //! Equation index for the mass conservation of the wetting phase - static const int contiEqIdx = 0; - - ////////// - // phase indices - ////////// - static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase; - static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase; -}; -// \} - -} // end namepace - -#endif +#include <dumux/implicit/richards/richardsindices.hh> diff --git a/dumux/boxmodels/richards/richardslocalresidual.hh b/dumux/boxmodels/richards/richardslocalresidual.hh index b1064f54c039118f09b8b3b6dc5fd58066713edb..6958456b0815c5e3208d679e6250298d61e965b0 100644 --- a/dumux/boxmodels/richards/richardslocalresidual.hh +++ b/dumux/boxmodels/richards/richardslocalresidual.hh @@ -1,158 +1,3 @@ -// -*- 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 Element-wise calculation of the residual for the Richards box model. - */ -#ifndef DUMUX_RICHARDS_LOCAL_RESIDUAL_HH -#define DUMUX_RICHARDS_LOCAL_RESIDUAL_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardslocalresidual.hh instead. -#include <dumux/boxmodels/common/boxlocalresidual.hh> - -#include "richardsvolumevariables.hh" - -namespace Dumux -{ -/*! - * \ingroup RichardsModel - * \ingroup BoxLocalResidual - * \brief Element-wise calculation of the residual for the Richards box model. - */ -template<class TypeTag> -class RichardsLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual) -{ - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - contiEqIdx = Indices::contiEqIdx, - wPhaseIdx = Indices::wPhaseIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - enum { dim = GridView::dimension}; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector<Scalar, dim> DimVector; - -public: - /*! - * \brief Constructor. Sets the upwind weight. - */ - RichardsLocalResidual() - { - // retrieve the upwind weight for the mass conservation equations. Use the value - // specified via the property system as default, and overwrite - // it by the run-time parameter from the Dune::ParameterTree - massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight); - }; - - /*! - * \brief Evaluate the rate of change of all conservation - * quantites (e.g. phase mass) within a sub control - * volume of a finite volume element for the Richards - * model. - * - * This function should not include the source and sink terms. - * - * \param storage Stores the average mass per unit volume for each phase \f$\mathrm{[kg/m^3]}\f$ - * \param scvIdx The sub control volume index of the current element - * \param usePrevSol Calculate the storage term of the previous solution - * instead of the model's current solution. - */ - void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const - { - // if flag usePrevSol is set, the solution from the previous - // time step is used, otherwise the current solution is - // used. The secondary variables are used accordingly. This - // is required to compute the derivative of the storage term - // using the implicit euler method. - const VolumeVariables &volVars = - usePrevSol ? - this->prevVolVars_(scvIdx) : - this->curVolVars_(scvIdx); - - // partial time derivative of the wetting phase mass - storage[contiEqIdx] = - volVars.density(wPhaseIdx) - * volVars.saturation(wPhaseIdx) - * volVars.porosity(); - } - - - /*! - * \brief Evaluates the mass flux over a face of a subcontrol - * volume. - * - * \param flux Stores the total mass fluxes over a sub-control volume face - * of the current element \f$\mathrm{[kg/s]}\f$ - * \param faceIdx The sub control volume face index inside the current - * element - * \param onBoundary A boolean variable to specify whether the flux variables - * are calculated for interior SCV faces or boundary faces, default=false - */ - void computeFlux(PrimaryVariables &flux, const int faceIdx, bool onBoundary=false) const - { - FluxVariables fluxVars(this->problem_(), - this->element_(), - this->fvGeometry_(), - faceIdx, - this->curVolVars_(), - onBoundary); - - // data attached to upstream and the downstream vertices - // of the current phase - const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(wPhaseIdx)); - const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(wPhaseIdx)); - - flux[contiEqIdx] = - fluxVars.volumeFlux(wPhaseIdx) - * - (( massUpwindWeight_)*up.density(wPhaseIdx) - + - (1 - massUpwindWeight_)*dn.density(wPhaseIdx)); - } - - /*! - * \brief Calculate the source term of the equation - * - * \param source Stores the average source term of all phases inside a - * sub-control volume of the current element \f$\mathrm{[kg/(m^3 * s)]}\f$ - * \param scvIdx The sub control volume index inside the current - * element - */ - void computeSource(PrimaryVariables &source, const int scvIdx) - { - this->problem_().boxSDSource(source, - this->element_(), - this->fvGeometry_(), - scvIdx, - this->curVolVars_()); - } - -private: - Scalar massUpwindWeight_; -}; - -} - -#endif +#include <dumux/implicit/richards/richardslocalresidual.hh> diff --git a/dumux/boxmodels/richards/richardsmodel.hh b/dumux/boxmodels/richards/richardsmodel.hh index ff71be4f6f4650369cc860b576874639e0c697ec..285950bbbf2e8a92a9454e46859071a791ec2e17 100644 --- a/dumux/boxmodels/richards/richardsmodel.hh +++ b/dumux/boxmodels/richards/richardsmodel.hh @@ -1,208 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ +#warning This file is deprecated. Include dumux/implicit/richards/richardsmodel.hh instead. -/*! -* \file -* -* \brief Adaption of the box scheme to the Richards model. -*/ -#ifndef DUMUX_RICHARDS_MODEL_HH -#define DUMUX_RICHARDS_MODEL_HH - -#include <dumux/boxmodels/common/boxmodel.hh> - -#include "richardslocalresidual.hh" -#include "richardsproblem.hh" - -namespace Dumux -{ -/*! - * \ingroup RichardsModel - * - * \brief This model which implements a variant of the Richards' - * equation for quasi-twophase flow. - * - * In the unsaturated zone, Richards' equation - \f[ - \frac{\partial\;\phi S_w \rho_w}{\partial t} - - - \text{div} \left( - \rho_w \frac{k_{rw}}{\mu_w} \; \mathbf{K} \; - \text{\textbf{grad}}\left( - p_w - g\rho_w - \right) - \right) - = - q_w, - \f] - * is frequently used to - * approximate the water distribution above the groundwater level. - * - * It can be derived from the two-phase equations, i.e. - \f[ - \frac{\partial\;\phi S_\alpha \rho_\alpha}{\partial t} - - - \text{div} \left( - \rho_\alpha \frac{k_{r\alpha}}{\mu_\alpha}\; \mathbf{K} \; - \text{\textbf{grad}}\left( - p_\alpha - g\rho_\alpha - \right) - \right) - = - q_\alpha, - \f] - * where \f$\alpha \in \{w, n\}\f$ is the fluid phase, - * \f$\rho_\alpha\f$ is the fluid density, \f$S_\alpha\f$ is the fluid - * saturation, \f$\phi\f$ is the porosity of the soil, - * \f$k_{r\alpha}\f$ is the relative permeability for the fluid, - * \f$\mu_\alpha\f$ is the fluid's dynamic viscosity, \f$\mathbf{K}\f$ is the - * intrinsic permeability, \f$p_\alpha\f$ is the fluid pressure and - * \f$g\f$ is the potential of the gravity field. - * - * In contrast to the full two-phase model, the Richards model assumes - * gas as the non-wetting fluid and that it exhibits a much lower - * viscosity than the (liquid) wetting phase. (For example at - * atmospheric pressure and at room temperature, the viscosity of air - * is only about \f$1\%\f$ of the viscosity of liquid water.) As a - * consequence, the \f$\frac{k_{r\alpha}}{\mu_\alpha}\f$ term - * typically is much larger for the gas phase than for the wetting - * phase. For this reason, the Richards model assumes that - * \f$\frac{k_{rn}}{\mu_n}\f$ is infinitly large. This implies that - * the pressure of the gas phase is equivalent to the static pressure - * distribution and that therefore, mass conservation only needs to be - * considered for the wetting phase. - * - * The model thus choses the absolute pressure of the wetting phase - * \f$p_w\f$ as its only primary variable. The wetting phase - * saturation is calculated using the inverse of the capillary - * pressure, i.e. - \f[ - S_w = p_c^{-1}(p_n - p_w) - \f] - * holds, where \f$p_n\f$ is a given reference pressure. Nota bene, - * that the last step is assumes that the capillary - * pressure-saturation curve can be uniquely inverted, so it is not - * possible to set the capillary pressure to zero when using the - * Richards model! - */ -template<class TypeTag > -class RichardsModel : public GET_PROP_TYPE(TypeTag, BaseModel) -{ - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - nPhaseIdx = Indices::nPhaseIdx, - wPhaseIdx = Indices::wPhaseIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - enum { dim = GridView::dimension }; - -public: - /*! - * \brief All relevant primary and secondary of a given - * solution to an ouput writer. - * - * \param sol The current solution which ought to be written to disk - * \param writer The Dumux::VtkMultiWriter which is be used to write the data - */ - template <class MultiWriter> - void addOutputVtkFields(const SolutionVector &sol, MultiWriter &writer) - { - typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - - // create the required scalar fields - unsigned numVertices = this->problem_().gridView().size(dim); - ScalarField *pW = writer.allocateManagedBuffer(numVertices); - ScalarField *pN = writer.allocateManagedBuffer(numVertices); - ScalarField *pC = writer.allocateManagedBuffer(numVertices); - ScalarField *Sw = writer.allocateManagedBuffer(numVertices); - ScalarField *Sn = writer.allocateManagedBuffer(numVertices); - ScalarField *rhoW = writer.allocateManagedBuffer(numVertices); - ScalarField *rhoN = writer.allocateManagedBuffer(numVertices); - ScalarField *mobW = writer.allocateManagedBuffer(numVertices); - ScalarField *mobN = writer.allocateManagedBuffer(numVertices); - ScalarField *poro = writer.allocateManagedBuffer(numVertices); - ScalarField *Te = writer.allocateManagedBuffer(numVertices); - - unsigned numElements = this->gridView_().size(0); - ScalarField *rank = - writer.allocateManagedBuffer (numElements); - - FVElementGeometry fvElemGeom; - VolumeVariables volVars; - - ElementIterator elemIt = this->gridView_().template begin<0>(); - ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) - { - int idx = this->problem_().model().elementMapper().map(*elemIt); - (*rank)[idx] = this->gridView_().comm().rank(); - - fvElemGeom.update(this->gridView_(), *elemIt); - - int numVerts = elemIt->template count<dim> (); - for (int i = 0; i < numVerts; ++i) - { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); - volVars.update(sol[globalIdx], - this->problem_(), - *elemIt, - fvElemGeom, - i, - false); - - (*pW)[globalIdx] = volVars.pressure(wPhaseIdx); - (*pN)[globalIdx] = volVars.pressure(nPhaseIdx); - (*pC)[globalIdx] = volVars.capillaryPressure(); - (*Sw)[globalIdx] = volVars.saturation(wPhaseIdx); - (*Sn)[globalIdx] = volVars.saturation(nPhaseIdx); - (*rhoW)[globalIdx] = volVars.density(wPhaseIdx); - (*rhoN)[globalIdx] = volVars.density(nPhaseIdx); - (*mobW)[globalIdx] = volVars.mobility(wPhaseIdx); - (*mobN)[globalIdx] = volVars.mobility(nPhaseIdx); - (*poro)[globalIdx] = volVars.porosity(); - (*Te)[globalIdx] = volVars.temperature(); - } - } - - writer.attachVertexData(*Sn, "Sn"); - writer.attachVertexData(*Sw, "Sw"); - writer.attachVertexData(*pN, "pn"); - writer.attachVertexData(*pW, "pw"); - writer.attachVertexData(*pC, "pc"); - writer.attachVertexData(*rhoW, "rhoW"); - writer.attachVertexData(*rhoN, "rhoN"); - writer.attachVertexData(*mobW, "mobW"); - writer.attachVertexData(*mobN, "mobN"); - writer.attachVertexData(*poro, "porosity"); - writer.attachVertexData(*Te, "temperature"); - writer.attachCellData(*rank, "process rank"); - } -}; -} - -#include "richardspropertydefaults.hh" - -#endif +#include <dumux/implicit/richards/richardsmodel.hh> diff --git a/dumux/boxmodels/richards/richardsnewtoncontroller.hh b/dumux/boxmodels/richards/richardsnewtoncontroller.hh index 635f6a6288b012305ce6192a4669d173ca17221a..d9533022167bb3e4d3df308dd97603ff2412f54a 100644 --- a/dumux/boxmodels/richards/richardsnewtoncontroller.hh +++ b/dumux/boxmodels/richards/richardsnewtoncontroller.hh @@ -1,125 +1,3 @@ -// -*- 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 A newton solver specific to the Richards problem. - */ -#ifndef DUMUX_RICHARDS_NEWTON_CONTROLLER_HH -#define DUMUX_RICHARDS_NEWTON_CONTROLLER_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardsnewtoncontroller.hh instead. -#include "richardsproperties.hh" - -#include <dumux/nonlinear/newtoncontroller.hh> - -namespace Dumux { -/*! - * \ingroup Newton - * \brief A Richards model specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * and can thus do update smarter than the plain Newton controller. - */ -template <class TypeTag> -class RichardsNewtonController : public NewtonController<TypeTag> -{ - typedef NewtonController<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { pwIdx = Indices::pwIdx }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - enum { dim = GridView::dimension }; -public: - /*! - * \brief Constructor - */ - RichardsNewtonController(const Problem &problem) - : ParentType(problem) - {} - - /*! - * \brief Update the current solution of the newton method - * - * This is basically the step - * \f[ u^{k+1} = u^k - \Delta u^k \f] - * - * \param uCurrentIter The solution after the current Newton iteration \f$ u^{k+1} \f$ - * \param uLastIter The solution after the last Newton iteration \f$ u^k \f$ - * \param deltaU The vector of differences between the last - * iterative solution and the next one \f$ \Delta u^k \f$ - */ - void newtonUpdate(SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - ParentType::newtonUpdate(uCurrentIter, uLastIter, deltaU); - - if (!GET_PARAM_FROM_GROUP(TypeTag, bool, Newton, UseLineSearch)) - { - // do not clamp anything after 5 iterations - if (this->numSteps_ > 4) - return; - - // clamp saturation change to at most 20% per iteration - FVElementGeometry fvGeometry; - const GridView &gridView = this->problem_().gridView(); - ElementIterator elemIt = gridView.template begin<0>(); - const ElementIterator elemEndIt = gridView.template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - fvGeometry.update(gridView, *elemIt); - for (int i = 0; i < fvGeometry.numSCV; ++i) { - int globI = this->problem_().vertexMapper().map(*elemIt, i, dim); - - // calculate the old wetting phase saturation - const SpatialParams &spatialParams = this->problem_().spatialParams(); - const MaterialLawParams &mp = spatialParams.materialLawParams(*elemIt, fvGeometry, i); - Scalar pcMin = MaterialLaw::pC(mp, 1.0); - Scalar pW = uLastIter[globI][pwIdx]; - Scalar pN = std::max(this->problem_().referencePressure(*elemIt, fvGeometry, i), - pW + pcMin); - Scalar pcOld = pN - pW; - Scalar SwOld = std::max<Scalar>(0.0, MaterialLaw::Sw(mp, pcOld)); - - // convert into minimum and maximum wetting phase - // pressures - Scalar pwMin = pN - MaterialLaw::pC(mp, SwOld - 0.2); - Scalar pwMax = pN - MaterialLaw::pC(mp, SwOld + 0.2); - - // clamp the result - pW = uCurrentIter[globI][pwIdx]; - pW = std::max(pwMin, std::min(pW, pwMax)); - uCurrentIter[globI][pwIdx] = pW; - - } - } - } - } -}; -} - -#endif +#include <dumux/implicit/richards/richardsnewtoncontroller.hh> diff --git a/dumux/boxmodels/richards/richardsproblem.hh b/dumux/boxmodels/richards/richardsproblem.hh index 99fcf05746e2e0b27b21b34ec65f3e4490424e22..c057ef78562de92492b172d8830d77d5f8b090fc 100644 --- a/dumux/boxmodels/richards/richardsproblem.hh +++ b/dumux/boxmodels/richards/richardsproblem.hh @@ -1,92 +1,3 @@ -// -*- 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 Base class for all problems which use the box scheme - */ -#ifndef DUMUX_RICHARDS_PROBLEM_HH -#define DUMUX_RICHARDS_PROBLEM_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardsproblem.hh instead. -#include <dumux/boxmodels/common/porousmediaboxproblem.hh> - -#include "richardsproperties.hh" - -namespace Dumux -{ -/*! - * \ingroup RichardsModel - * \ingroup BoxBaseProblems - * \brief Base class for all problems which use the two-phase box model - * - * For a description of the Richards model, see Dumux::RichardsModel - */ -template<class TypeTag> -class RichardsBoxProblem : public PorousMediaBoxProblem<TypeTag> -{ - typedef PorousMediaBoxProblem<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - -public: - /*! - * \brief The constructor. - * - * The overloaded class must allocate all data structures - * required, but _must not_ do any calls to the model, the - * jacobian assembler, etc inside the constructor. - * - * If the problem requires information from these, the - * BoxProblem::init() method be overloaded. - * - * \param timeManager The TimeManager which keeps track of time - * \param gridView The GridView used by the problem. - */ - RichardsBoxProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView) - {} - - /*! - * \name Problem parameters - */ - // \{ - /*! - * \brief Returns the reference pressure \f$\mathrm{[Pa]}\f$ of the non-wetting - * phase within a control volume. - * - * This method MUST be overwritten by the actual problem. - * - * \param element The DUNE Codim<0> enitiy which intersects with - * the finite volume. - * \param fvGeometry The finite volume geometry of the element. - * \param scvIdx The local index of the sub control volume inside the element - */ - Scalar referencePressure(const Element &element, - const FVElementGeometry fvGeometry, - const int scvIdx) const - { DUNE_THROW(Dune::NotImplemented, "referencePressure() method not implemented by the actual problem"); }; - // \} -}; - -} - -#endif +#include <dumux/implicit/richards/richardsproblem.hh> diff --git a/dumux/boxmodels/richards/richardsproperties.hh b/dumux/boxmodels/richards/richardsproperties.hh index fb1f3bd65be340b6c6d682da83939ec948d73eed..f7c2bc20b7648e911aedd6cdaab82b58951f5262 100644 --- a/dumux/boxmodels/richards/richardsproperties.hh +++ b/dumux/boxmodels/richards/richardsproperties.hh @@ -1,70 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup RichardsModel - * \file - * - * \brief Contains the property declarations for the Richards box - * model. - */ -#ifndef DUMUX_RICHARDS_PROPERTIES_HH -#define DUMUX_RICHARDS_PROPERTIES_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardsproperties.hh instead. -#include <dumux/boxmodels/common/boxproperties.hh> - -namespace Dumux -{ -// \{ -/////////////////////////////////////////////////////////////////////////// -// properties for the isothermal richards model -/////////////////////////////////////////////////////////////////////////// -namespace Properties { - -////////////////////////////////////////////////////////////////// -// Type tags -////////////////////////////////////////////////////////////////// - -//! The type tag for problems discretized using the Richards model -NEW_TYPE_TAG(BoxRichards, INHERITS_FROM(BoxModel)); - -////////////////////////////////////////////////////////////////// -// Property tags -////////////////////////////////////////////////////////////////// - -NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system -NEW_PROP_TAG(Indices); //!< Enumerations used by the model -NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters -NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (by default extracted from the spatial parameters) -NEW_PROP_TAG(MaterialLawParams); //!< The type of the parameter object for the material law (by default extracted from the spatial parameters) -NEW_PROP_TAG(FluidSystem); //!< The fluid system to be used for the Richards model -NEW_PROP_TAG(WettingPhase); //!< Fluid which represents the wetting phase -NEW_PROP_TAG(NonwettingPhase); //!< Fluid which represents the non-wetting phase -NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem -NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the weight of the upwind direction in the mass conservation equations -NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< The value of the weight for the upwind mobility in the velocity calculation -NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient - -// \} -} - -} // end namepace - -#endif +#include <dumux/implicit/richards/richardsproperties.hh> diff --git a/dumux/boxmodels/richards/richardspropertydefaults.hh b/dumux/boxmodels/richards/richardspropertydefaults.hh index e7b6df30d46b037a7f393455cb61191641c248f8..9ee08bf3914d289d24b8b2331097473547caad7c 100644 --- a/dumux/boxmodels/richards/richardspropertydefaults.hh +++ b/dumux/boxmodels/richards/richardspropertydefaults.hh @@ -1,168 +1,3 @@ -// -*- 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/>. * - *****************************************************************************/ -/*! - * \ingroup Properties - * \ingroup BoxProperties - * \ingroup RichardsModel - * \file - * - * \brief Contains the default definitions for the properties required - * by the Richards box model. - */ -#ifndef DUMUX_RICHARDS_PROPERTY_DEFAULTS_HH -#define DUMUX_RICHARDS_PROPERTY_DEFAULTS_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardspropertydefaults.hh instead. -#include "richardsmodel.hh" -#include "richardsproblem.hh" -#include "richardsindices.hh" -#include <dumux/boxmodels/common/boxdarcyfluxvariables.hh> -#include "richardsvolumevariables.hh" -#include "richardsproperties.hh" -#include "richardsnewtoncontroller.hh" - -#include <dumux/material/components/nullcomponent.hh> -#include <dumux/material/fluidsystems/2pimmisciblefluidsystem.hh> -#include <dumux/material/spatialparams/boxspatialparams.hh> - -namespace Dumux -{ -// \{ - -namespace Properties { -////////////////////////////////////////////////////////////////// -// Properties values -////////////////////////////////////////////////////////////////// -//! Number of equations required by the model -SET_INT_PROP(BoxRichards, NumEq, 1); -//! Number of fluid phases considered -SET_INT_PROP(BoxRichards, NumPhases, 2); - -//! The local residual operator -SET_TYPE_PROP(BoxRichards, - LocalResidual, - RichardsLocalResidual<TypeTag>); - -//! The global model used -SET_TYPE_PROP(BoxRichards, Model, RichardsModel<TypeTag>); - -//! The class for the volume averaged quantities -SET_TYPE_PROP(BoxRichards, VolumeVariables, RichardsVolumeVariables<TypeTag>); - -//! The class for the quantities required for the flux calculation -SET_TYPE_PROP(BoxRichards, FluxVariables, BoxDarcyFluxVariables<TypeTag>); - -//! The class of the newton controller -SET_TYPE_PROP(BoxRichards, NewtonController, RichardsNewtonController<TypeTag>); - -//! The upwind weight for the mass conservation equations -SET_SCALAR_PROP(BoxRichards, ImplicitMassUpwindWeight, 1.0); - -//! weight for the upwind mobility in the velocity calculation -SET_SCALAR_PROP(BoxRichards, ImplicitMobilityUpwindWeight, 1.0); - -//! The class with all index definitions for the model -SET_TYPE_PROP(BoxRichards, Indices, RichardsIndices<TypeTag>); - -//! The spatial parameters to be employed. -//! Use BoxSpatialParams by default. -SET_TYPE_PROP(BoxRichards, SpatialParams, BoxSpatialParams<TypeTag>); - -/*! - * \brief Set type of the parameter objects for the material law - * - * By default this is just retrieved from the material law. - */ -SET_PROP(BoxRichards, MaterialLawParams) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - -public: - typedef typename MaterialLaw::Params type; -}; - -/*! - * \brief The wetting phase used. - * - * By default we use the null-phase, i.e. this has to be defined by - * the problem for the program to work. Please be aware that you - * should be careful to use the Richards model in conjunction with - * liquid non-wetting phases. This is only meaningful if the viscosity - * of the liquid phase is _much_ lower than the viscosity of the - * wetting phase. - */ -SET_PROP(BoxRichards, WettingPhase) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::LiquidPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -/*! - * \brief The wetting phase used. - * - * By default we use the null-phase, i.e. this has to be defined by - * the problem for the program to work. This doed not need to be - * specified by the problem for the Richards model to work because the - * Richards model does not conserve the non-wetting phase. - */ -SET_PROP(BoxRichards, NonwettingPhase) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef Dumux::GasPhase<Scalar, Dumux::NullComponent<Scalar> > type; -}; - -/*! - *\brief The fluid system used by the model. - * - * By default this uses the immiscible twophase fluid system. The - * actual fluids used are specified using in the problem definition by - * the WettingPhase and NonwettingPhase properties. Be aware that - * using different fluid systems in conjunction with the Richards - * model only makes very limited sense. - */ -SET_PROP(BoxRichards, FluidSystem) -{ private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; - -public: - typedef Dumux::FluidSystems::TwoPImmiscible<Scalar, - WettingPhase, - NonwettingPhase> type; -}; - -// enable gravity by default -SET_BOOL_PROP(BoxRichards, ProblemEnableGravity, true); - -//! default value for the forchheimer coefficient -// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90. -// Actually the Forchheimer coefficient is also a function of the dimensions of the -// porous medium. Taking it as a constant is only a first approximation -// (Nield, Bejan, Convection in porous media, 2006, p. 10) -SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55); - -// \} -} - -} // end namepace - -#endif +#include <dumux/implicit/richards/richardspropertydefaults.hh> diff --git a/dumux/boxmodels/richards/richardsvolumevariables.hh b/dumux/boxmodels/richards/richardsvolumevariables.hh index d32e107dadff01f9a8307037f0f654feaa2106cc..374ef27beea941c51101b1a5096ab52abcdb7458 100644 --- a/dumux/boxmodels/richards/richardsvolumevariables.hh +++ b/dumux/boxmodels/richards/richardsvolumevariables.hh @@ -1,280 +1,3 @@ -// -*- 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 Volume averaged quantities required by the Richards model. - */ -#ifndef DUMUX_RICHARDS_VOLUME_VARIABLES_HH -#define DUMUX_RICHARDS_VOLUME_VARIABLES_HH +#warning This file is deprecated. Include dumux/implicit/richards/richardsvolumevariables.hh instead. -#include "richardsproperties.hh" - -#include <dumux/material/fluidstates/immisciblefluidstate.hh> -#include <dumux/boxmodels/common/boxvolumevariables.hh> - -namespace Dumux -{ - -/*! - * \ingroup RichardsModel - * \ingroup BoxVolumeVariables - * \brief Volume averaged quantities required by the Richards model. - * - * This contains the quantities which are are constant within a finite - * volume in the Richards model - */ -template <class TypeTag> -class RichardsVolumeVariables : public BoxVolumeVariables<TypeTag> -{ - typedef BoxVolumeVariables<TypeTag> ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pwIdx = Indices::pwIdx, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::template Codim<0>::Entity Element; - -public: - //! The type returned by the fluidState() method - typedef Dumux::ImmiscibleFluidState<Scalar, FluidSystem> FluidState; - - /*! - * \copydoc BoxVolumeVariables::update - */ - void update(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { - assert(!FluidSystem::isLiquid(nPhaseIdx)); - - ParentType::update(priVars, - problem, - element, - fvGeometry, - scvIdx, - isOldSol); - - completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_); - - ////////// - // specify the other parameters - ////////// - const MaterialLawParams &matParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - relativePermeabilityWetting_ = - MaterialLaw::krw(matParams, - fluidState_.saturation(wPhaseIdx)); - - porosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx); - - // energy related quantities not contained in the fluid state - asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol); - } - - /*! - * \copydoc BoxModel::completeFluidState - */ - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const int scvIdx, - FluidState& fluidState) - { - // temperature - Scalar t = Implementation::temperature_(priVars, problem, element, - fvGeometry, scvIdx); - fluidState.setTemperature(t); - - // pressures - Scalar pnRef = problem.referencePressure(element, fvGeometry, scvIdx); - const MaterialLawParams &matParams = - problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - Scalar minPc = MaterialLaw::pC(matParams, 1.0); - fluidState.setPressure(wPhaseIdx, priVars[pwIdx]); - fluidState.setPressure(nPhaseIdx, std::max(pnRef, priVars[pwIdx] + minPc)); - - // saturations - Scalar Sw = MaterialLaw::Sw(matParams, fluidState.pressure(nPhaseIdx) - fluidState.pressure(wPhaseIdx)); - fluidState.setSaturation(wPhaseIdx, Sw); - fluidState.setSaturation(nPhaseIdx, 1 - Sw); - - // density and viscosity - typename FluidSystem::ParameterCache paramCache; - paramCache.updateAll(fluidState); - fluidState.setDensity(wPhaseIdx, FluidSystem::density(fluidState, paramCache, wPhaseIdx)); - fluidState.setDensity(nPhaseIdx, 1e-10); - - fluidState.setViscosity(wPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, wPhaseIdx)); - fluidState.setViscosity(nPhaseIdx, 1e-10); - } - - /*! - * \brief Return the fluid configuration at the given primary - * variables - */ - const FluidState &fluidState() const - { return fluidState_; } - - /*! - * \brief Returns the average porosity [] within the control volume. - * - * The porosity is defined as the ratio of the pore space to the - * total volume, i.e. \f[ \Phi := \frac{V_{pore}}{V_{pore} + V_{rock}} \f] - */ - Scalar porosity() const - { return porosity_; } - - /*! - * \brief Returns the average absolute saturation [] of a given - * fluid phase within the finite volume. - * - * The saturation of a fluid phase is defined as the fraction of - * the pore volume filled by it, i.e. - * \f[ S_\alpha := \frac{V_\alpha}{V_{pore}} = \phi \frac{V_\alpha}{V} \f] - * - * \param phaseIdx The index of the fluid phase - */ - Scalar saturation(const int phaseIdx) const - { return fluidState_.saturation(phaseIdx); } - - /*! - * \brief Returns the average mass density \f$\mathrm{[kg/m^3]}\f$ of a given - * fluid phase within the control volume. - * - * \param phaseIdx The index of the fluid phase - */ - Scalar density(const int phaseIdx) const - { return fluidState_.density(phaseIdx); } - - /*! - * \brief Returns the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within - * the control volume. - * - * For the non-wetting phase (i.e. the gas phase), we assume - * infinite mobility, which implies that the non-wetting phase - * pressure is equal to the finite volume's reference pressure - * defined by the problem. - * - * \param phaseIdx The index of the fluid phase - */ - Scalar pressure(const int phaseIdx) const - { return fluidState_.pressure(phaseIdx); } - - /*! - * \brief Returns average temperature \f$\mathrm{[K]}\f$ inside the control volume. - * - * Note that we assume thermodynamic equilibrium, i.e. the - * temperature of the rock matrix and of all fluid phases are - * identical. - */ - Scalar temperature() const - { return fluidState_.temperature(); } - - /*! - * \brief Returns the effective mobility \f$\mathrm{[1/(Pa*s)]}\f$ of a given phase within - * the control volume. - * - * The mobility of a fluid phase is defined as the relative - * permeability of the phase (given by the chosen material law) - * divided by the dynamic viscosity of the fluid, i.e. - * \f[ \lambda_\alpha := \frac{k_{r\alpha}}{\mu_\alpha} \f] - * - * \param phaseIdx The index of the fluid phase - */ - Scalar mobility(const int phaseIdx) const - { return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); } - - /*! - * \brief Returns relative permeability [-] of a given phase within - * the control volume. - * - * \param phaseIdx The index of the fluid phase - */ - Scalar relativePermeability(const int phaseIdx) const - { - if (phaseIdx == wPhaseIdx) - return relativePermeabilityWetting_; - return 1; - } - - /*! - * \brief Returns the effective capillary pressure \f$\mathrm{[Pa]}\f$ within the - * control volume. - * - * The capillary pressure is defined as the difference in - * pressures of the non-wetting and the wetting phase, i.e. - * \f[ p_c = p_n - p_w \f] - */ - Scalar capillaryPressure() const - { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); } - -protected: - static Scalar temperature_(const PrimaryVariables &primaryVariables, - const Problem& problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) - { - return problem.boxTemperature(element, fvGeometry, scvIdx); - } - - /*! - * \brief Called by update() to compute the energy related quantities - */ - void updateEnergy_(const PrimaryVariables &priVars, - const Problem &problem, - const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx, - const bool isOldSol) - { } - - FluidState fluidState_; - Scalar relativePermeabilityWetting_; - Scalar porosity_; - -private: - Implementation &asImp_() - { return *static_cast<Implementation*>(this); } - - const Implementation &asImp_() const - { return *static_cast<const Implementation*>(this); } -}; - -} - -#endif +#include <dumux/implicit/richards/richardsvolumevariables.hh> diff --git a/dumux/implicit/common/implicitproblem.hh b/dumux/implicit/common/implicitproblem.hh index c455443807b5b990d59e43d0bad635b32fd87f98..3a52ac48383aa0955cf9f9ef101f55d31cc9738b 100644 --- a/dumux/implicit/common/implicitproblem.hh +++ b/dumux/implicit/common/implicitproblem.hh @@ -217,7 +217,7 @@ public: * potentially solution dependent and requires some box method * specific things. * - * \param values The neumann values for the conservation equations [kg / (m^2 *s )] + * \param values The neumann values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ * \param element The finite element * \param fvGeometry The finite-volume geometry in the box scheme * \param is The intersection between element and boundary @@ -249,7 +249,7 @@ public: * \brief Evaluate the boundary conditions for a neumann * boundary segment. * - * \param values The neumann values for the conservation equations [kg / (m^2 *s )] + * \param values The neumann values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ * \param element The finite element * \param fvGeometry The finite-volume geometry in the box scheme * \param is The intersection between element and boundary @@ -274,7 +274,7 @@ public: * \brief Evaluate the boundary conditions for a neumann * boundary segment. * - * \param values The neumann values for the conservation equations [kg / (m^2 *s )] + * \param values The neumann values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ * \param pos The position of the boundary face's integration point in global coordinates * * For this method, the \a values parameter stores the mass flux @@ -299,7 +299,7 @@ public: * potentially solution dependent and requires some box method * specific things. * - * \param values The source and sink values for the conservation equations + * \param values The source and sink values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ * \param element The finite element * \param fvGeometry The finite-volume geometry in the box scheme * \param scvIdx The local vertex index @@ -323,7 +323,7 @@ public: * \brief Evaluate the source term for all phases within a given * sub-control-volume. * - * \param values The source and sink values for the conservation equations + * \param values The source and sink values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ * \param element The finite element * \param fvGeometry The finite-volume geometry in the box scheme * \param scvIdx The local vertex index @@ -345,7 +345,7 @@ public: * \brief Evaluate the source term for all phases within a given * sub-control-volume. * - * \param values The source and sink values for the conservation equations + * \param values The source and sink values for the conservation equations in units of \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ * \param pos The position of the center of the finite volume * for which the source term ought to be * specified in global coordinates diff --git a/dumux/implicit/mpnc/mpncindices.hh b/dumux/implicit/mpnc/mpncindices.hh index eb1cc5b0736d3b741ed03c48ad5a955f0226df30..2e80219300592faf203037f813bae460ba5902b4 100644 --- a/dumux/implicit/mpnc/mpncindices.hh +++ b/dumux/implicit/mpnc/mpncindices.hh @@ -26,6 +26,20 @@ namespace Dumux { + +/*! + * \ingroup MPNCModel + * \ingroup BoxIndices + * \brief Enumerates the formulations which the 2p2c model accepts. + */ +struct MpNcPressureFormulation +{ + enum { + mostWettingFirst, + leastWettingFirst + }; +}; + /*! * \ingroup MPNCModel * \ingroup BoxIndices diff --git a/dumux/implicit/mpnc/mpncproperties.hh b/dumux/implicit/mpnc/mpncproperties.hh index a8833bb7cd2051e7e4556a5584f23847c6930d6e..3a4dc02af599115d5ab38dee6e963db8983c71c0 100644 --- a/dumux/implicit/mpnc/mpncproperties.hh +++ b/dumux/implicit/mpnc/mpncproperties.hh @@ -51,6 +51,8 @@ NEW_PROP_TAG(Indices); //!< Enumerations for the model NEW_PROP_TAG(BaseFluxVariables); //!< The type of velocity calculation that is to be used +NEW_PROP_TAG(PressureFormulation); //!< The formulation of the model + NEW_PROP_TAG(MPNCVtkCommonModule); //!< Vtk writer module for writing the common quantities into the VTK output file NEW_PROP_TAG(MPNCVtkMassModule); //!< Vtk writer module for writing the mass related quantities into the VTK output file NEW_PROP_TAG(MPNCVtkEnergyModule); //!< Vtk writer module for writing the energy related quantities into the VTK output file @@ -60,6 +62,7 @@ NEW_PROP_TAG(VelocityAveragingInModel);//!< Should the averaging of velocities b //! specify which quantities are written to the vtk output files NEW_PROP_TAG(VtkAddPorosity); +NEW_PROP_TAG(VtkAddPermeability); NEW_PROP_TAG(VtkAddBoundaryTypes); NEW_PROP_TAG(VtkAddSaturations); NEW_PROP_TAG(VtkAddPressures); diff --git a/dumux/implicit/mpnc/mpncpropertydefaults.hh b/dumux/implicit/mpnc/mpncpropertydefaults.hh index 0ead27ef49ade35d95b3420fa2eb967a236a0744..578332fc70d9769d438e681d18e0a194cebd152d 100644 --- a/dumux/implicit/mpnc/mpncpropertydefaults.hh +++ b/dumux/implicit/mpnc/mpncpropertydefaults.hh @@ -52,6 +52,12 @@ namespace Properties // default property values ////////////////////////////////////////////////////////////////// + +//! Set the default pressure formulation to the pressure of the (most) wetting phase +SET_INT_PROP(BoxMPNC, + PressureFormulation, + MpNcPressureFormulation::mostWettingFirst); + /*! * \brief Set the property for the number of components. * @@ -247,6 +253,7 @@ SET_BOOL_PROP(BoxMPNC, VelocityAveragingInModel, false); //! Specify what to add to the VTK output by default SET_BOOL_PROP(BoxMPNC, VtkAddPorosity, true); +SET_BOOL_PROP(BoxMPNC, VtkAddPermeability, false); SET_BOOL_PROP(BoxMPNC, VtkAddBoundaryTypes, false); SET_BOOL_PROP(BoxMPNC, VtkAddSaturations, true); SET_BOOL_PROP(BoxMPNC, VtkAddPressures, true); diff --git a/dumux/implicit/mpnc/mpncvolumevariables.hh b/dumux/implicit/mpnc/mpncvolumevariables.hh index 409218898f666c9855d2deb26067b5cec5b21b0b..bba2e1b0f7550cfbb5354d0dcbcd35352bce1269 100644 --- a/dumux/implicit/mpnc/mpncvolumevariables.hh +++ b/dumux/implicit/mpnc/mpncvolumevariables.hh @@ -64,6 +64,19 @@ class MPNCVolumeVariables typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + + enum {dimWorld=GridView::dimensionworld}; + typedef Dune::FieldVector<Scalar,dimWorld> GlobalPosition; + enum {wPhaseIdx = FluidSystem::wPhaseIdx}; + enum {nPhaseIdx = FluidSystem::nPhaseIdx}; + + // formulations + enum { + pressureFormulation = GET_PROP_VALUE(TypeTag, PressureFormulation), + mostWettingFirst = MpNcPressureFormulation::mostWettingFirst, + leastWettingFirst = MpNcPressureFormulation::leastWettingFirst + }; + enum {numPhases = GET_PROP_VALUE(TypeTag, NumPhases)}; enum {numComponents = GET_PROP_VALUE(TypeTag, NumComponents)}; enum {enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy)}; @@ -138,7 +151,6 @@ public: ///////////// // set the phase pressures ///////////// - // capillary pressure parameters const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); @@ -146,9 +158,23 @@ public: Scalar capPress[numPhases]; MaterialLaw::capillaryPressures(capPress, materialParams, fluidState_); // add to the pressure of the first fluid phase - Scalar p0 = priVars[p0Idx]; - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) - fluidState_.setPressure(phaseIdx, p0 - capPress[0] + capPress[phaseIdx]); + + // depending on which pressure is stored in the primary variables + if(pressureFormulation == mostWettingFirst){ + // This means that the pressures are sorted from the most wetting to the least wetting-1 in the primary variables vector. + // For two phases this means that there is one pressure as primary variable: pw + const Scalar pw = priVars[p0Idx]; + for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + fluidState_.setPressure(phaseIdx, pw - capPress[0] + capPress[phaseIdx]); + } + else if(pressureFormulation == leastWettingFirst){ + // This means that the pressures are sorted from the least wetting to the most wetting-1 in the primary variables vector. + // For two phases this means that there is one pressure as primary variable: pn + const Scalar pn = priVars[p0Idx]; + for (int phaseIdx = numPhases-1; phaseIdx >= 0; --phaseIdx) + fluidState_.setPressure(phaseIdx, pn - capPress[numPhases-1] + capPress[phaseIdx]); + } + else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << pressureFormulation << " is invalid."); ///////////// // set the fluid compositions @@ -240,7 +266,9 @@ public: * the control volume. */ Scalar mobility(const unsigned int phaseIdx) const - { return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); } + { + return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); + } /*! * \brief Returns the viscosity of a given phase within diff --git a/dumux/implicit/mpnc/mpncvtkwritercommon.hh b/dumux/implicit/mpnc/mpncvtkwritercommon.hh index c92536bf6dfce21f96e696ff48a13e115e038cad..6a83d7dae20e0c8e3caa9260acebfd1dda65c36c 100644 --- a/dumux/implicit/mpnc/mpncvtkwritercommon.hh +++ b/dumux/implicit/mpnc/mpncvtkwritercommon.hh @@ -68,6 +68,7 @@ public: : ParentType(problem) { porosityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddPorosity); + permeabilityOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddPermeability); boundaryTypesOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddBoundaryTypes); saturationOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddSaturations); pressureOutput_ = GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddPressures); @@ -89,6 +90,8 @@ public: { if (porosityOutput_) this->resizeScalarBuffer_(porosity_); + if (permeabilityOutput_) + this->resizeScalarBuffer_(permeability_); if (boundaryTypesOutput_) this->resizeScalarBuffer_(boundaryTypes_); @@ -127,6 +130,9 @@ public: if (porosityOutput_) porosity_[globalIdx] = volVars.porosity(); + // works for scalar permeability in spatialparameters + if (permeabilityOutput_) permeability_[globalIdx] = this->problem_.spatialParams().intrinsicPermeability(elem,fvGeometry,localVertexIdx); + // calculate a single value for the boundary type: use one // bit for each equation and set it to 1 if the equation // is used for a dirichlet condition @@ -239,6 +245,7 @@ public: private: bool porosityOutput_; + bool permeabilityOutput_ ; bool boundaryTypesOutput_; bool saturationOutput_; bool pressureOutput_; @@ -260,6 +267,7 @@ private: ScalarVector boxSurface_; ScalarVector porosity_; + ScalarVector permeability_; ScalarVector temperature_; ScalarVector boundaryTypes_;