There has never really been a natural home for initial properties that aren't InitConfig, meaning information such as phases in the deck and other runspec information hasn't had a natural home. This patch introduces the Runspec object on EclipseState for phase information and other similar properties that are interesting and static for when setting up parameters etc. for simulation, that aren't all that interesting once simulation starts. An additional benefit is a leaner implementation for the phase enum and some stricter semantics via enum classes.
309 lines
10 KiB
C++
309 lines
10 KiB
C++
/*
|
|
Copyright 2013 Statoil ASA.
|
|
|
|
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 3 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/>.
|
|
*/
|
|
|
|
|
|
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/WellSet.hpp>
|
|
|
|
#define INVALID_GROUP_RATE -999e100
|
|
#define INVALID_EFFICIENCY_FACTOR 0.0
|
|
|
|
|
|
namespace Opm {
|
|
GroupProduction::ProductionData::ProductionData(const TimeMap& timeMap) :
|
|
controlMode( timeMap , GroupProduction::NONE ),
|
|
exceedAction( timeMap , GroupProductionExceedLimit::NONE ),
|
|
oilTarget( timeMap , INVALID_GROUP_RATE),
|
|
waterTarget( timeMap , INVALID_GROUP_RATE ),
|
|
gasTarget( timeMap , INVALID_GROUP_RATE ),
|
|
liquidTarget( timeMap , INVALID_GROUP_RATE ),
|
|
reservoirVolumeTarget( timeMap , INVALID_GROUP_RATE )
|
|
{}
|
|
|
|
GroupInjection::InjectionData::InjectionData(const TimeMap& timeMap) :
|
|
phase( timeMap, Phase::WATER ),
|
|
controlMode( timeMap, NONE ),
|
|
rate( timeMap, 0 ),
|
|
surfaceFlowMaxRate( timeMap, 0 ),
|
|
reservoirFlowMaxRate( timeMap, 0 ),
|
|
targetReinjectFraction( timeMap, 0 ),
|
|
targetVoidReplacementFraction( timeMap, 0 )
|
|
{}
|
|
|
|
/*****************************************************************/
|
|
|
|
Group::Group(const std::string& name_, const TimeMap& timeMap , size_t creationTimeStep) :
|
|
m_injection( timeMap ),
|
|
m_production( timeMap ),
|
|
m_wells( timeMap, std::make_shared< const WellSet >() ),
|
|
m_isProductionGroup( timeMap, false),
|
|
m_isInjectionGroup( timeMap, false),
|
|
m_efficiencyFactor( timeMap, 1.0),
|
|
m_transferEfficiencyFactor( timeMap, 1)
|
|
{
|
|
m_name = name_;
|
|
m_creationTimeStep = creationTimeStep;
|
|
}
|
|
|
|
|
|
const std::string& Group::name() const {
|
|
return m_name;
|
|
}
|
|
|
|
|
|
bool Group::hasBeenDefined(size_t timeStep) const {
|
|
if (timeStep < m_creationTimeStep)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
bool Group::isProductionGroup(size_t timeStep) const {
|
|
return bool( m_isProductionGroup.get(timeStep) );
|
|
}
|
|
|
|
bool Group::isInjectionGroup(size_t timeStep) const {
|
|
return bool( m_isInjectionGroup.get(timeStep) );
|
|
}
|
|
|
|
void Group::setProductionGroup(size_t timeStep, bool isProductionGroup_) {
|
|
m_isProductionGroup.update(timeStep, isProductionGroup_);
|
|
}
|
|
|
|
void Group::setInjectionGroup(size_t timeStep, bool isInjectionGroup_) {
|
|
m_isInjectionGroup.update(timeStep, isInjectionGroup_);
|
|
}
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
|
void Group::setInjectionPhase(size_t time_step, Phase phase){
|
|
if (m_injection.phase.size() == time_step + 1) {
|
|
Phase currentPhase = m_injection.phase.get(time_step);
|
|
/*
|
|
The ECLIPSE documentation of the GCONINJE keyword seems
|
|
to indicate that a group can inject more than one phase
|
|
simultaneously. This should be implemented in the input
|
|
file as:
|
|
|
|
GCONINJE
|
|
'GROUP' 'PHASE1' 'RATE' ... /
|
|
'GROUP' 'PHASE2' 'RATE' ... /
|
|
...
|
|
/
|
|
|
|
I.e. the same group occurs more than once at the same
|
|
time step, with different phases. This seems quite
|
|
weird, and we do currently not support it. Changing the
|
|
injected phase from one time step to the next is
|
|
supported.
|
|
*/
|
|
if (phase != currentPhase)
|
|
throw std::invalid_argument("Sorry - we currently do not support injecting multiple phases at the same time.");
|
|
}
|
|
m_injection.phase.update( time_step , phase );
|
|
}
|
|
|
|
Phase Group::getInjectionPhase( size_t time_step ) const {
|
|
return m_injection.phase.get( time_step );
|
|
}
|
|
|
|
void Group::setInjectionRate( size_t time_step , double rate) {
|
|
m_injection.rate.update( time_step , rate);
|
|
}
|
|
|
|
double Group::getInjectionRate( size_t time_step ) const {
|
|
return m_injection.rate.get( time_step );
|
|
}
|
|
|
|
void Group::setInjectionControlMode(size_t time_step , GroupInjection::ControlEnum controlMode) {
|
|
m_injection.controlMode.update( time_step , controlMode );
|
|
}
|
|
|
|
GroupInjection::ControlEnum Group::getInjectionControlMode( size_t time_step) const {
|
|
return m_injection.controlMode.get( time_step );
|
|
}
|
|
|
|
void Group::setSurfaceMaxRate( size_t time_step , double rate) {
|
|
m_injection.surfaceFlowMaxRate.update( time_step , rate);
|
|
}
|
|
|
|
double Group::getSurfaceMaxRate( size_t time_step ) const {
|
|
return m_injection.surfaceFlowMaxRate.get( time_step );
|
|
}
|
|
|
|
void Group::setReservoirMaxRate( size_t time_step , double rate) {
|
|
m_injection.reservoirFlowMaxRate.update( time_step , rate);
|
|
}
|
|
|
|
double Group::getReservoirMaxRate( size_t time_step ) const {
|
|
return m_injection.reservoirFlowMaxRate.get( time_step );
|
|
}
|
|
|
|
void Group::setTargetReinjectFraction( size_t time_step , double rate) {
|
|
m_injection.targetReinjectFraction.update( time_step , rate);
|
|
}
|
|
|
|
double Group::getTargetReinjectFraction( size_t time_step ) const {
|
|
return m_injection.targetReinjectFraction.get( time_step );
|
|
}
|
|
|
|
void Group::setTargetVoidReplacementFraction( size_t time_step , double rate) {
|
|
m_injection.targetVoidReplacementFraction.update( time_step , rate);
|
|
}
|
|
|
|
double Group::getTargetVoidReplacementFraction( size_t time_step ) const {
|
|
return m_injection.targetVoidReplacementFraction.get( time_step );
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void Group::setProductionControlMode( size_t time_step , GroupProduction::ControlEnum controlMode) {
|
|
m_production.controlMode.update(time_step , controlMode );
|
|
}
|
|
|
|
GroupProduction::ControlEnum Group::getProductionControlMode( size_t time_step ) const {
|
|
return m_production.controlMode.get(time_step);
|
|
}
|
|
|
|
|
|
GroupProductionExceedLimit::ActionEnum Group::getProductionExceedLimitAction( size_t time_step ) const {
|
|
return m_production.exceedAction.get(time_step);
|
|
}
|
|
|
|
|
|
void Group::setProductionExceedLimitAction( size_t time_step , GroupProductionExceedLimit::ActionEnum action) {
|
|
m_production.exceedAction.update(time_step , action);
|
|
}
|
|
|
|
|
|
void Group::setOilTargetRate(size_t time_step , double oilTargetRate) {
|
|
m_production.oilTarget.update(time_step , oilTargetRate);
|
|
}
|
|
|
|
|
|
double Group::getOilTargetRate(size_t time_step) const {
|
|
return m_production.oilTarget.get(time_step);
|
|
}
|
|
|
|
|
|
void Group::setGasTargetRate(size_t time_step , double gasTargetRate) {
|
|
m_production.gasTarget.update(time_step , gasTargetRate);
|
|
}
|
|
|
|
|
|
double Group::getGasTargetRate(size_t time_step) const {
|
|
return m_production.gasTarget.get(time_step);
|
|
}
|
|
|
|
|
|
void Group::setWaterTargetRate(size_t time_step , double waterTargetRate) {
|
|
m_production.waterTarget.update(time_step , waterTargetRate);
|
|
}
|
|
|
|
|
|
double Group::getWaterTargetRate(size_t time_step) const {
|
|
return m_production.waterTarget.get(time_step);
|
|
}
|
|
|
|
|
|
void Group::setLiquidTargetRate(size_t time_step , double liquidTargetRate) {
|
|
m_production.liquidTarget.update(time_step , liquidTargetRate);
|
|
}
|
|
|
|
|
|
double Group::getLiquidTargetRate(size_t time_step) const {
|
|
return m_production.liquidTarget.get(time_step);
|
|
}
|
|
|
|
|
|
void Group::setReservoirVolumeTargetRate(size_t time_step , double reservoirVolumeTargetRate) {
|
|
m_production.reservoirVolumeTarget.update(time_step , reservoirVolumeTargetRate);
|
|
}
|
|
|
|
|
|
double Group::getReservoirVolumeTargetRate(size_t time_step) const {
|
|
return m_production.reservoirVolumeTarget.get(time_step);
|
|
}
|
|
|
|
|
|
void Group::setGroupEfficiencyFactor(size_t time_step, double factor) {
|
|
m_efficiencyFactor.update(time_step , factor);
|
|
}
|
|
|
|
double Group::getGroupEfficiencyFactor(size_t time_step) const {
|
|
return m_efficiencyFactor.get(time_step);
|
|
}
|
|
|
|
void Group::setTransferGroupEfficiencyFactor(size_t time_step, bool transfer) {
|
|
m_transferEfficiencyFactor.update(time_step , transfer);
|
|
}
|
|
|
|
|
|
bool Group::getTransferGroupEfficiencyFactor(size_t time_step) const {
|
|
return m_transferEfficiencyFactor.get(time_step);
|
|
}
|
|
|
|
/*****************************************************************/
|
|
|
|
std::shared_ptr< const WellSet > Group::wellMap(size_t time_step) const {
|
|
return m_wells.get(time_step);
|
|
}
|
|
|
|
|
|
bool Group::hasWell(const std::string& wellName , size_t time_step) const {
|
|
return this->wellMap(time_step)->hasWell( wellName );
|
|
}
|
|
|
|
|
|
const Well* Group::getWell(const std::string& wellName , size_t time_step) const {
|
|
return this->wellMap( time_step )->getWell( wellName );
|
|
}
|
|
|
|
const WellSet& Group::getWells( size_t time_step ) const {
|
|
return *this->wellMap( time_step );
|
|
}
|
|
|
|
size_t Group::numWells(size_t time_step) const {
|
|
return wellMap(time_step)->size();
|
|
}
|
|
|
|
void Group::addWell(size_t time_step, Well* well ) {
|
|
auto wellSet = wellMap(time_step);
|
|
std::shared_ptr< WellSet > newWellSet( wellSet->shallowCopy() );
|
|
|
|
newWellSet->addWell(well);
|
|
m_wells.update(time_step , newWellSet);
|
|
}
|
|
|
|
|
|
void Group::delWell(size_t time_step, const std::string& wellName) {
|
|
auto wellSet = wellMap(time_step);
|
|
std::shared_ptr< WellSet > newWellSet( wellSet->shallowCopy() );
|
|
|
|
newWellSet->delWell(wellName);
|
|
m_wells.update(time_step , newWellSet);
|
|
}
|
|
|
|
}
|