2016-03-14 07:21:47 -05:00
|
|
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
// vi: set et ts=4 sw=4 sts=4:
|
2015-07-29 06:43:17 -05:00
|
|
|
/*
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
2016-03-14 07:21:47 -05:00
|
|
|
|
|
|
|
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.
|
2015-07-29 06:43:17 -05:00
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
*
|
2019-09-05 10:04:39 -05:00
|
|
|
* \copydoc Opm::EclEquilInitializer
|
2015-07-29 06:43:17 -05:00
|
|
|
*/
|
|
|
|
#ifndef EWOMS_ECL_EQUIL_INITIALIZER_HH
|
|
|
|
#define EWOMS_ECL_EQUIL_INITIALIZER_HH
|
|
|
|
|
2018-01-02 05:43:56 -06:00
|
|
|
#include "equil/initstateequil.hh"
|
2018-01-02 05:43:56 -06:00
|
|
|
|
2019-09-16 03:58:20 -05:00
|
|
|
#include <opm/models/utils/propertysystem.hh>
|
2019-09-16 04:22:14 -05:00
|
|
|
#include <opm/models/blackoil/blackoilproperties.hh>
|
2016-01-17 14:15:27 -06:00
|
|
|
|
2017-12-14 08:54:31 -06:00
|
|
|
#include <opm/material/fluidstates/BlackOilFluidState.hpp>
|
2017-01-18 09:46:53 -06:00
|
|
|
#include <opm/material/fluidmatrixinteractions/EclMaterialLawManager.hpp>
|
2015-07-29 06:43:17 -05:00
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2018-06-14 09:06:05 -05:00
|
|
|
BEGIN_PROPERTIES
|
|
|
|
|
2016-01-17 14:15:27 -06:00
|
|
|
NEW_PROP_TAG(Simulator);
|
|
|
|
NEW_PROP_TAG(FluidSystem);
|
|
|
|
NEW_PROP_TAG(GridView);
|
|
|
|
NEW_PROP_TAG(Scalar);
|
|
|
|
NEW_PROP_TAG(MaterialLaw);
|
2018-04-11 05:39:33 -05:00
|
|
|
NEW_PROP_TAG(EnableTemperature);
|
2018-01-30 04:46:23 -06:00
|
|
|
NEW_PROP_TAG(EnableEnergy);
|
2018-06-14 09:06:05 -05:00
|
|
|
|
|
|
|
END_PROPERTIES
|
|
|
|
|
2019-09-05 10:04:39 -05:00
|
|
|
namespace Opm {
|
2016-01-17 14:15:27 -06:00
|
|
|
|
2015-07-29 06:43:17 -05:00
|
|
|
/*!
|
|
|
|
* \ingroup EclBlackOilSimulator
|
|
|
|
*
|
|
|
|
* \brief Computes the initial condition based on the EQUIL keyword from ECL.
|
|
|
|
*
|
|
|
|
* So far, it uses the "initStateEquil()" function from opm-core. Since this method is
|
|
|
|
* very much glued into the opm-core data structures, it should be reimplemented in the
|
|
|
|
* medium to long term for some significant memory savings and less significant
|
|
|
|
* performance improvements.
|
|
|
|
*/
|
|
|
|
template <class TypeTag>
|
|
|
|
class EclEquilInitializer
|
|
|
|
{
|
|
|
|
typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
|
|
|
|
typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
|
|
|
|
typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
|
|
|
|
typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
|
|
|
|
typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
|
2018-10-18 05:55:49 -05:00
|
|
|
typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
|
2015-07-29 06:43:17 -05:00
|
|
|
|
|
|
|
enum { numPhases = FluidSystem::numPhases };
|
|
|
|
enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
|
|
|
|
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
|
|
|
|
enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
|
|
|
|
|
|
|
|
enum { numComponents = FluidSystem::numComponents };
|
|
|
|
enum { oilCompIdx = FluidSystem::oilCompIdx };
|
|
|
|
enum { gasCompIdx = FluidSystem::gasCompIdx };
|
|
|
|
enum { waterCompIdx = FluidSystem::waterCompIdx };
|
|
|
|
|
|
|
|
enum { dimWorld = GridView::dimensionworld };
|
2018-01-30 09:15:47 -06:00
|
|
|
enum { enableTemperature = GET_PROP_VALUE(TypeTag, EnableTemperature) };
|
2018-01-30 04:46:23 -06:00
|
|
|
enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) };
|
2020-01-13 04:00:33 -06:00
|
|
|
enum { enableBrine = GET_PROP_VALUE(TypeTag, EnableBrine) };
|
2018-01-30 04:46:23 -06:00
|
|
|
|
2018-10-18 05:55:49 -05:00
|
|
|
public:
|
2018-01-30 09:15:47 -06:00
|
|
|
// NB: setting the enableEnergy argument to true enables storage of enthalpy and
|
|
|
|
// internal energy!
|
2018-01-30 04:46:23 -06:00
|
|
|
typedef Opm::BlackOilFluidState<Scalar,
|
|
|
|
FluidSystem,
|
2018-01-30 09:15:47 -06:00
|
|
|
enableTemperature,
|
2018-10-18 05:55:49 -05:00
|
|
|
enableEnergy,
|
|
|
|
Indices::gasEnabled,
|
2020-01-13 04:00:33 -06:00
|
|
|
enableBrine,
|
2018-10-18 05:55:49 -05:00
|
|
|
Indices::numPhases
|
|
|
|
> ScalarFluidState;
|
|
|
|
|
2015-07-29 06:43:17 -05:00
|
|
|
|
2017-01-18 09:46:53 -06:00
|
|
|
template <class EclMaterialLawManager>
|
2015-07-29 06:43:17 -05:00
|
|
|
EclEquilInitializer(const Simulator& simulator,
|
2017-11-28 02:45:48 -06:00
|
|
|
EclMaterialLawManager& materialLawManager)
|
2015-07-29 06:43:17 -05:00
|
|
|
: simulator_(simulator)
|
|
|
|
{
|
2018-02-01 09:26:58 -06:00
|
|
|
const auto& vanguard = simulator.vanguard();
|
2018-02-08 10:59:14 -06:00
|
|
|
const auto& eclState = vanguard.eclState();
|
2015-07-29 06:43:17 -05:00
|
|
|
|
2018-02-01 09:26:58 -06:00
|
|
|
unsigned numElems = vanguard.grid().size(0);
|
|
|
|
unsigned numCartesianElems = vanguard.cartesianSize();
|
2017-11-17 07:51:20 -06:00
|
|
|
|
2018-01-02 05:43:56 -06:00
|
|
|
EQUIL::DeckDependent::InitialStateComputer<TypeTag> initialState(materialLawManager,
|
2018-02-08 10:59:14 -06:00
|
|
|
eclState,
|
2018-02-01 09:26:58 -06:00
|
|
|
vanguard.grid(),
|
2018-01-02 05:43:56 -06:00
|
|
|
simulator.problem().gravity()[dimWorld - 1]);
|
2016-11-22 07:28:54 -06:00
|
|
|
|
2015-07-29 06:43:17 -05:00
|
|
|
// copy the result into the array of initial fluid states
|
2016-01-17 14:15:21 -06:00
|
|
|
initialFluidStates_.resize(numCartesianElems);
|
2016-11-22 07:28:54 -06:00
|
|
|
for (unsigned int elemIdx = 0; elemIdx < numElems; ++elemIdx) {
|
2018-02-01 09:26:58 -06:00
|
|
|
unsigned cartesianElemIdx = vanguard.cartesianIndex(elemIdx);
|
2016-11-07 08:14:07 -06:00
|
|
|
auto& fluidState = initialFluidStates_[cartesianElemIdx];
|
2015-07-29 06:43:17 -05:00
|
|
|
|
2015-08-26 09:04:10 -05:00
|
|
|
// get the PVT region index of the current element
|
2016-11-22 07:28:54 -06:00
|
|
|
unsigned regionIdx = simulator_.problem().pvtRegionIndex(elemIdx);
|
2017-12-14 08:54:31 -06:00
|
|
|
fluidState.setPvtRegionIndex(regionIdx);
|
2015-08-26 09:04:10 -05:00
|
|
|
|
2015-07-29 06:43:17 -05:00
|
|
|
// set the phase saturations
|
2015-11-18 04:54:35 -06:00
|
|
|
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
2017-12-14 08:54:31 -06:00
|
|
|
if (FluidSystem::phaseIsActive(phaseIdx))
|
|
|
|
fluidState.setSaturation(phaseIdx, initialState.saturation()[phaseIdx][elemIdx]);
|
2018-10-18 05:55:49 -05:00
|
|
|
else if (Indices::numPhases == 3)
|
2017-12-14 08:54:31 -06:00
|
|
|
fluidState.setSaturation(phaseIdx, 0.0);
|
2015-07-29 06:43:17 -05:00
|
|
|
}
|
|
|
|
|
2017-12-14 08:54:31 -06:00
|
|
|
if (FluidSystem::enableDissolvedGas())
|
|
|
|
fluidState.setRs(initialState.rs()[elemIdx]);
|
2018-10-18 05:55:49 -05:00
|
|
|
else if (Indices::gasEnabled)
|
2017-12-14 08:54:31 -06:00
|
|
|
fluidState.setRs(0.0);
|
|
|
|
|
|
|
|
if (FluidSystem::enableVaporizedOil())
|
|
|
|
fluidState.setRv(initialState.rv()[elemIdx]);
|
2018-10-18 05:55:49 -05:00
|
|
|
else if (Indices::gasEnabled)
|
2017-12-14 08:54:31 -06:00
|
|
|
fluidState.setRv(0.0);
|
|
|
|
|
|
|
|
|
2018-02-08 10:59:14 -06:00
|
|
|
// set the temperature.
|
2018-01-30 09:15:47 -06:00
|
|
|
if (enableTemperature || enableEnergy)
|
|
|
|
fluidState.setTemperature(initialState.temperature()[elemIdx]);
|
2015-07-29 06:43:17 -05:00
|
|
|
|
2019-02-06 04:18:51 -06:00
|
|
|
// set the phase pressures, invB factor and density
|
2018-10-18 05:55:49 -05:00
|
|
|
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
|
|
|
if (!FluidSystem::phaseIsActive(phaseIdx))
|
|
|
|
continue;
|
2017-11-28 02:45:48 -06:00
|
|
|
fluidState.setPressure(phaseIdx, initialState.press()[phaseIdx][elemIdx]);
|
2019-02-06 04:18:51 -06:00
|
|
|
|
|
|
|
const auto& b = FluidSystem::inverseFormationVolumeFactor(fluidState, phaseIdx, regionIdx);
|
|
|
|
fluidState.setInvB(phaseIdx, b);
|
|
|
|
|
|
|
|
const auto& rho = FluidSystem::density(fluidState, phaseIdx, regionIdx);
|
|
|
|
fluidState.setDensity(phaseIdx, rho);
|
|
|
|
|
2018-10-18 05:55:49 -05:00
|
|
|
}
|
2016-02-17 11:40:48 -06:00
|
|
|
}
|
2015-07-29 06:43:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Return the initial thermodynamic state which should be used as the initial
|
|
|
|
* condition.
|
|
|
|
*
|
|
|
|
* This is supposed to correspond to hydrostatic conditions.
|
|
|
|
*/
|
2015-11-18 04:54:35 -06:00
|
|
|
const ScalarFluidState& initialFluidState(unsigned elemIdx) const
|
2016-01-17 14:15:21 -06:00
|
|
|
{
|
2018-02-01 09:26:58 -06:00
|
|
|
const auto& vanguard = simulator_.vanguard();
|
2016-01-17 14:15:21 -06:00
|
|
|
|
2018-02-01 09:26:58 -06:00
|
|
|
unsigned cartesianElemIdx = vanguard.cartesianIndex(elemIdx);
|
2016-01-17 14:15:21 -06:00
|
|
|
return initialFluidStates_[cartesianElemIdx];
|
|
|
|
}
|
2015-07-29 06:43:17 -05:00
|
|
|
|
|
|
|
protected:
|
|
|
|
const Simulator& simulator_;
|
|
|
|
|
|
|
|
std::vector<ScalarFluidState> initialFluidStates_;
|
|
|
|
};
|
2019-09-05 10:04:39 -05:00
|
|
|
} // namespace Opm
|
2015-07-29 06:43:17 -05:00
|
|
|
|
|
|
|
#endif
|