// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- // vi: set et ts=4 sw=4 sts=4: /* This file is part of the Open Porous Media project (OPM). OPM 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. OPM 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 OPM. If not, see . Consult the COPYING file in the top-level source directory of this module for the precise wording of the license and the list of copyright holders. */ /*! * \file * * \copydoc Opm::FlashIntensiveQuantities */ #ifndef EWOMS_FLASH_INTENSIVE_QUANTITIES_HH #define EWOMS_FLASH_INTENSIVE_QUANTITIES_HH #include "flashproperties.hh" #include "flashindices.hh" #include #include #include #include #include #include namespace Opm { /*! * \ingroup FlashModel * \ingroup IntensiveQuantities * * \brief Contains the intensive quantities of the flash-based compositional multi-phase model */ template class FlashIntensiveQuantities : public GET_PROP_TYPE(TypeTag, DiscIntensiveQuantities) , public DiffusionIntensiveQuantities , public EnergyIntensiveQuantities , public GET_PROP_TYPE(TypeTag, FluxModule)::FluxIntensiveQuantities { typedef typename GET_PROP_TYPE(TypeTag, DiscIntensiveQuantities) ParentType; typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext; typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; typedef typename GET_PROP_TYPE(TypeTag, FluxModule) FluxModule; typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; typedef typename GET_PROP_TYPE(TypeTag, ThreadManager) ThreadManager; // primary variable indices enum { cTot0Idx = Indices::cTot0Idx }; 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 { dimWorld = GridView::dimensionworld }; typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; typedef typename GET_PROP_TYPE(TypeTag, Evaluation) Evaluation; typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; typedef typename GET_PROP_TYPE(TypeTag, FlashSolver) FlashSolver; typedef Dune::FieldVector ComponentVector; typedef Dune::FieldMatrix DimMatrix; typedef typename FluxModule::FluxIntensiveQuantities FluxIntensiveQuantities; typedef Opm::DiffusionIntensiveQuantities DiffusionIntensiveQuantities; typedef Opm::EnergyIntensiveQuantities EnergyIntensiveQuantities; public: //! The type of the object returned by the fluidState() method typedef Opm::CompositionalFluidState FluidState; FlashIntensiveQuantities() { } FlashIntensiveQuantities(const FlashIntensiveQuantities& other) = default; FlashIntensiveQuantities& operator=(const FlashIntensiveQuantities& other) = default; /*! * \copydoc IntensiveQuantities::update */ void update(const ElementContext& elemCtx, unsigned dofIdx, unsigned timeIdx) { ParentType::update(elemCtx, dofIdx, timeIdx); EnergyIntensiveQuantities::updateTemperatures_(fluidState_, elemCtx, dofIdx, timeIdx); const auto& priVars = elemCtx.primaryVars(dofIdx, timeIdx); const auto& problem = elemCtx.problem(); Scalar flashTolerance = EWOMS_GET_PARAM(TypeTag, Scalar, FlashTolerance); // extract the total molar densities of the components ComponentVector cTotal; for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) cTotal[compIdx] = priVars.makeEvaluation(cTot0Idx + compIdx, timeIdx); const auto *hint = elemCtx.thermodynamicHint(dofIdx, timeIdx); if (hint) { // use the same fluid state as the one of the hint, but // make sure that we don't overwrite the temperature // specified by the primary variables Evaluation T = fluidState_.temperature(/*phaseIdx=*/0); fluidState_.assign(hint->fluidState()); fluidState_.setTemperature(T); } else FlashSolver::guessInitial(fluidState_, cTotal); // compute the phase compositions, densities and pressures typename FluidSystem::template ParameterCache paramCache; const MaterialLawParams& materialParams = problem.materialLawParams(elemCtx, dofIdx, timeIdx); FlashSolver::template solve(fluidState_, materialParams, paramCache, cTotal, flashTolerance); // calculate relative permeabilities MaterialLaw::relativePermeabilities(relativePermeability_, materialParams, fluidState_); Opm::Valgrind::CheckDefined(relativePermeability_); // set the phase viscosities for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { paramCache.updatePhase(fluidState_, phaseIdx); const Evaluation& mu = FluidSystem::viscosity(fluidState_, paramCache, phaseIdx); fluidState_.setViscosity(phaseIdx, mu); mobility_[phaseIdx] = relativePermeability_[phaseIdx] / mu; Opm::Valgrind::CheckDefined(mobility_[phaseIdx]); } ///////////// // calculate the remaining quantities ///////////// // porosity porosity_ = problem.porosity(elemCtx, dofIdx, timeIdx); Opm::Valgrind::CheckDefined(porosity_); // intrinsic permeability intrinsicPerm_ = problem.intrinsicPermeability(elemCtx, dofIdx, timeIdx); // update the quantities specific for the velocity model FluxIntensiveQuantities::update_(elemCtx, dofIdx, timeIdx); // energy related quantities EnergyIntensiveQuantities::update_(fluidState_, paramCache, elemCtx, dofIdx, timeIdx); // update the diffusion specific quantities of the intensive quantities DiffusionIntensiveQuantities::update_(fluidState_, paramCache, elemCtx, dofIdx, timeIdx); } /*! * \copydoc ImmiscibleIntensiveQuantities::fluidState */ const FluidState& fluidState() const { return fluidState_; } /*! * \copydoc ImmiscibleIntensiveQuantities::intrinsicPermeability */ const DimMatrix& intrinsicPermeability() const { return intrinsicPerm_; } /*! * \copydoc ImmiscibleIntensiveQuantities::relativePermeability */ const Evaluation& relativePermeability(unsigned phaseIdx) const { return relativePermeability_[phaseIdx]; } /*! * \copydoc ImmiscibleIntensiveQuantities::mobility */ const Evaluation& mobility(unsigned phaseIdx) const { return mobility_[phaseIdx]; } /*! * \copydoc ImmiscibleIntensiveQuantities::porosity */ const Evaluation& porosity() const { return porosity_; } private: DimMatrix intrinsicPerm_; FluidState fluidState_; Evaluation porosity_; Evaluation relativePermeability_[numPhases]; Evaluation mobility_[numPhases]; }; } // namespace Opm #endif