Runspec object; move phases from TableManager

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.
This commit is contained in:
Jørgen Kvalsvik
2016-10-31 16:47:59 +01:00
parent 4ad9b17449
commit 21aaceaed9
20 changed files with 268 additions and 151 deletions

View File

@@ -70,6 +70,7 @@ set (state_source
EclipseState/EclipseState.cpp
EclipseState/EclipseConfig.cpp
EclipseState/Eclipse3DProperties.cpp
EclipseState/Runspec.cpp
#
EclipseState/checkDeck.cpp
#
@@ -172,6 +173,7 @@ Units/Units.hpp
EclipseState/EclipseState.hpp
EclipseState/EclipseConfig.hpp
EclipseState/Eclipse3DProperties.hpp
EclipseState/Runspec.hpp
#
EclipseState/checkDeck.hpp
#

View File

@@ -58,6 +58,7 @@ namespace Opm {
m_schedule( std::make_shared<Schedule>( m_parseContext, m_inputGrid, deck ) ),
m_eclipseProperties( deck, m_tables, m_inputGrid ),
m_eclipseConfig( deck, m_eclipseProperties, m_gridDims, *m_schedule , parseContext),
m_runspec( deck ),
m_transMult( m_inputGrid.getNX(), m_inputGrid.getNY(), m_inputGrid.getNZ(),
m_eclipseProperties, deck.getKeywordList( "MULTREGT" ) ),
m_inputNnc( deck, m_gridDims ),
@@ -65,6 +66,10 @@ namespace Opm {
{
m_inputGrid.resetACTNUM(m_eclipseProperties.getIntGridProperty("ACTNUM").getData().data());
if( this->runspec().phases().size() < 3 )
m_messageContainer.info("Only " + std::to_string( this->runspec().phases().size() )
+ " fluid phases are enabled" );
if (deck.hasKeyword( "TITLE" )) {
const auto& titleKeyword = deck.getKeyword( "TITLE" );
const auto& item = titleKeyword.getRecord( 0 ).getItem( 0 );
@@ -155,6 +160,10 @@ namespace Opm {
return m_eclipseConfig;
}
const Runspec& EclipseState::runspec() const {
return this->m_runspec;
}
/// [[deprecated]] --- use cfg().simulation()
const SimulationConfig& EclipseState::getSimulationConfig() const {
return m_eclipseConfig.getSimulationConfig();

View File

@@ -29,6 +29,7 @@
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@@ -107,6 +108,8 @@ namespace Opm {
void applyModifierDeck(const Deck& deck);
const Runspec& runspec() const;
private:
void initIOConfigPostSchedule(const Deck& deck);
void initTransMult();
@@ -124,6 +127,7 @@ namespace Opm {
std::shared_ptr< const Schedule > m_schedule;
Eclipse3DProperties m_eclipseProperties;
EclipseConfig m_eclipseConfig;
Runspec m_runspec;
TransMult m_transMult;
NNC m_inputNnc;
UnitSystem m_deckUnitSystem;

View File

@@ -696,9 +696,6 @@ namespace Opm {
satnum.checkLimits( 1 , numSatTables );
// All table lookup assumes three-phase model
assert( tableManager->getNumPhases() == 3 );
// acctually assign the defaults. if the ENPVD keyword was specified in the deck,
// this currently cannot be done because we would need the Z-coordinate of the
// cell and we would need to know how the simulator wants to interpolate between

View File

@@ -0,0 +1,74 @@
/*
Copyright 2016 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 <ostream>
#include <type_traits>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
namespace Opm {
Phase get_phase( const std::string& str ) {
if( str == "OIL" ) return Phase::OIL;
if( str == "GAS" ) return Phase::GAS;
if( str == "WAT" ) return Phase::WATER;
if( str == "WATER" ) return Phase::WATER;
throw std::invalid_argument( "Unknown phase '" + str + "'" );
}
std::ostream& operator<<( std::ostream& stream, const Phase& p ) {
switch( p ) {
case Phase::OIL: return stream << "OIL";
case Phase::GAS: return stream << "GAS";
case Phase::WATER: return stream << "WATER";
}
return stream;
}
using un = std::underlying_type< Phase >::type;
Phases::Phases( bool oil, bool gas, bool wat ) noexcept :
bits( (oil ? (1 << static_cast< un >( Phase::OIL ) ) : 0) |
(gas ? (1 << static_cast< un >( Phase::GAS ) ) : 0) |
(wat ? (1 << static_cast< un >( Phase::WATER ) ) : 0) )
{}
bool Phases::active( Phase p ) const noexcept {
return this->bits[ static_cast< int >( p ) ];
}
size_t Phases::size() const noexcept {
return this->bits.count();
}
Runspec::Runspec( const Deck& deck ) :
Runspec( Phases{ deck.hasKeyword( "OIL" ),
deck.hasKeyword( "GAS" ),
deck.hasKeyword( "WATER" ) } )
{}
Runspec::Runspec( const Phases& p ) noexcept : active_phases( p ) {}
const Phases& Runspec::phases() const noexcept {
return this->active_phases;
}
}

View File

@@ -0,0 +1,65 @@
/*
Copyright 2016 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/>.
*/
#ifndef OPM_RUNSPEC_HPP
#define OPM_RUNSPEC_HPP
#include <bitset>
#include <iosfwd>
#include <string>
namespace Opm {
class Deck;
enum class Phase {
OIL = 0,
GAS = 1,
WATER = 2,
};
Phase get_phase( const std::string& );
std::ostream& operator<<( std::ostream&, const Phase& );
class Phases {
public:
Phases() noexcept = default;
Phases( bool oil, bool gas, bool wat ) noexcept;
bool active( Phase ) const noexcept;
size_t size() const noexcept;
private:
std::bitset< 3 > bits;
};
class Runspec {
public:
explicit Runspec( const Deck& );
explicit Runspec( const Phases& ) noexcept;
const Phases& phases() const noexcept;
private:
Phases active_phases;
};
}
#endif // OPM_RUNSPEC_HPP

View File

@@ -96,9 +96,9 @@ namespace Opm {
/**********************************************************************/
void Group::setInjectionPhase(size_t time_step , Phase::PhaseEnum phase){
void Group::setInjectionPhase(size_t time_step, Phase phase){
if (m_injection.phase.size() == time_step + 1) {
Phase::PhaseEnum currentPhase = m_injection.phase.get(time_step);
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
@@ -123,7 +123,7 @@ namespace Opm {
m_injection.phase.update( time_step , phase );
}
Phase::PhaseEnum Group::getInjectionPhase( size_t time_step ) const {
Phase Group::getInjectionPhase( size_t time_step ) const {
return m_injection.phase.get( time_step );
}

View File

@@ -22,6 +22,7 @@
#define GROUP_HPP_
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <memory>
@@ -38,7 +39,7 @@ namespace Opm {
struct InjectionData {
InjectionData( const TimeMap& );
DynamicState< Phase::PhaseEnum > phase;
DynamicState< Phase > phase;
DynamicState< GroupInjection::ControlEnum > controlMode;
DynamicState< double > rate;
DynamicState< double > surfaceFlowMaxRate;
@@ -74,8 +75,8 @@ namespace Opm {
void setInjectionGroup(size_t timeStep, bool isInjectionGroup_);
/******************************************************************/
void setInjectionPhase(size_t time_step , Phase::PhaseEnum phase);
Phase::PhaseEnum getInjectionPhase(size_t time_step) const;
void setInjectionPhase(size_t time_step, Phase);
Phase getInjectionPhase(size_t time_step) const;
void setInjectionControlMode(size_t time_step , GroupInjection::ControlEnum ControlMode);
GroupInjection::ControlEnum getInjectionControlMode( size_t time_step) const;

View File

@@ -76,7 +76,6 @@ namespace Opm {
m_modifierDeck( *m_timeMap, nullptr ),
m_tuning( *m_timeMap ),
m_messageLimits( *m_timeMap )
{
m_controlModeWHISTCTL = WellProducer::CMODE_UNDEFINED;
addGroup( "FIELD", 0 );
@@ -979,7 +978,7 @@ namespace Opm {
auto& group = this->m_groups.at( groupName );
{
Phase::PhaseEnum phase = Phase::PhaseEnumFromString( record.getItem("PHASE").getTrimmedString(0) );
Phase phase = get_phase( record.getItem("PHASE").getTrimmedString(0) );
group.setInjectionPhase( currentStep , phase );
}
{
@@ -987,7 +986,7 @@ namespace Opm {
group.setInjectionControlMode( currentStep , controlMode );
}
Phase::PhaseEnum wellPhase = Phase::PhaseEnumFromString( record.getItem("PHASE").getTrimmedString(0));
Phase wellPhase = get_phase( record.getItem("PHASE").getTrimmedString(0));
// calculate SI injection rates for the group
double surfaceInjectionRate = record.getItem("SURFACE_TARGET").get< double >(0);
@@ -1363,7 +1362,7 @@ namespace Opm {
// We change from eclipse's 1 - n, to a 0 - n-1 solution
int headI = record.getItem("HEAD_I").get< int >(0) - 1;
int headJ = record.getItem("HEAD_J").get< int >(0) - 1;
Phase::PhaseEnum preferredPhase = Phase::PhaseEnumFromString(record.getItem("PHASE").getTrimmedString(0));
Phase preferredPhase = get_phase(record.getItem("PHASE").getTrimmedString(0));
Value<double> refDepth("REF_DEPTH");
const auto& refDepthItem = record.getItem("REF_DEPTH");
@@ -1535,7 +1534,7 @@ namespace Opm {
}
}
double Schedule::convertInjectionRateToSI(double rawRate, Phase::PhaseEnum wellPhase, const Opm::UnitSystem& unitSystem) {
double Schedule::convertInjectionRateToSI(double rawRate, Phase wellPhase, const Opm::UnitSystem& unitSystem) {
switch (wellPhase) {
case Phase::OIL:
case Phase::WATER:
@@ -1607,5 +1606,4 @@ namespace Opm {
bool Schedule::hasOilVaporizationProperties(){
return m_oilvaporizationproperties.size() > 0;
}
}

View File

@@ -101,6 +101,7 @@ namespace Opm
DynamicVector<std::shared_ptr<Deck> > m_modifierDeck;
Tuning m_tuning;
MessageLimits m_messageLimits;
MessageContainer m_messages;
WellProducer::ControlModeEnum m_controlModeWHISTCTL;
@@ -145,7 +146,7 @@ namespace Opm
void checkUnhandledKeywords( const SCHEDULESection& ) const;
static double convertInjectionRateToSI(double rawRate, WellInjector::TypeEnum wellType, const Opm::UnitSystem &unitSystem);
static double convertInjectionRateToSI(double rawRate, Phase::PhaseEnum wellPhase, const Opm::UnitSystem &unitSystem);
static double convertInjectionRateToSI(double rawRate, Phase wellPhase, const Opm::UnitSystem &unitSystem);
static bool convertEclipseStringToBool(const std::string& eclipseString);
};

View File

@@ -262,37 +262,6 @@ namespace Opm {
/*****************************************************************/
namespace Phase {
const std::string PhaseEnum2String( PhaseEnum enumValue ) {
switch( enumValue ) {
case OIL:
return "OIL";
case GAS:
return "GAS";
case WATER:
return "WATER";
default:
throw std::invalid_argument("unhandled enum value");
}
}
PhaseEnum PhaseEnumFromString( const std::string& stringValue ) {
if (stringValue == "OIL")
return OIL;
else if (stringValue == "WATER")
return WATER;
else if (stringValue == "WAT")
return WATER;
else if (stringValue == "GAS")
return GAS;
else
throw std::invalid_argument("Unknown enum state string: " + stringValue );
}
}
/*****************************************************************/
namespace WellProducer {
const std::string ControlMode2String( ControlModeEnum enumValue ) {

View File

@@ -69,20 +69,6 @@ namespace Opm {
}
namespace Phase {
enum PhaseEnum {
OIL = 1,
GAS = 2,
WATER = 4
};
const std::string PhaseEnum2String( PhaseEnum enumValue );
PhaseEnum PhaseEnumFromString( const std::string& stringValue );
}
namespace WellInjector {
enum TypeEnum {
WATER = 1,

View File

@@ -33,7 +33,7 @@
namespace Opm {
Well::Well(const std::string& name_, int headI,
int headJ, Value<double> refDepth , Phase::PhaseEnum preferredPhase,
int headJ, Value<double> refDepth , Phase preferredPhase,
std::shared_ptr< const TimeMap > timeMap, size_t creationTimeStep,
WellCompletion::CompletionOrderEnum completionOrdering,
bool allowCrossFlow, bool automaticShutIn)
@@ -91,7 +91,7 @@ namespace Opm {
}
double Well::production_rate( Phase::PhaseEnum phase, size_t timestep ) const {
double Well::production_rate( Phase phase, size_t timestep ) const {
if( !this->isProducer( timestep ) ) return 0.0;
const auto& p = this->getProductionProperties( timestep );
@@ -102,11 +102,11 @@ namespace Opm {
case Phase::GAS: return p.GasRate;
}
throw std::logic_error( "Unreachable state. Invalid PhaseEnum value. "
throw std::logic_error( "Unreachable state. Invalid Phase value. "
"This is likely a programming error." );
}
double Well::injection_rate( Phase::PhaseEnum phase, size_t timestep ) const {
double Well::injection_rate( Phase phase, size_t timestep ) const {
if( !this->isInjector( timestep ) ) return 0.0;
const auto& i = this->getInjectionProperties( timestep );
@@ -283,7 +283,7 @@ namespace Opm {
}
Phase::PhaseEnum Well::getPreferredPhase() const {
Phase Well::getPreferredPhase() const {
return m_preferredPhase;
}

View File

@@ -25,10 +25,11 @@
#include <string>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
@@ -45,7 +46,7 @@ namespace Opm {
class Well {
public:
Well(const std::string& name, int headI,
int headJ, Value<double> refDepth , Phase::PhaseEnum preferredPhase,
int headJ, Value<double> refDepth , Phase preferredPhase,
std::shared_ptr< const TimeMap > timeMap, size_t creationTimeStep,
WellCompletion::CompletionOrderEnum completionOrdering = WellCompletion::TRACK,
bool allowCrossFlow = true, bool automaticShutIn = true);
@@ -61,7 +62,7 @@ namespace Opm {
int getHeadI() const;
int getHeadJ() const;
double getRefDepth() const;
Phase::PhaseEnum getPreferredPhase() const;
Phase getPreferredPhase() const;
bool isAvailableForGroupControl(size_t timeStep) const;
void setAvailableForGroupControl(size_t timeStep, bool isAvailableForGroupControl);
@@ -92,8 +93,8 @@ namespace Opm {
* water_injector.injection_rate( gas ) == 0
* * Mixed injection is not supported and always returns 0.
*/
double production_rate( Phase::PhaseEnum phase, size_t timestep ) const;
double injection_rate( Phase::PhaseEnum phase, size_t timestep ) const;
double production_rate( Phase phase, size_t timestep ) const;
double injection_rate( Phase phase, size_t timestep ) const;
bool setProductionProperties(size_t timeStep , const WellProductionProperties properties);
WellProductionProperties getProductionPropertiesCopy(size_t timeStep) const;
@@ -166,7 +167,7 @@ namespace Opm {
int m_headI;
int m_headJ;
mutable Value<double> m_refDepth;
Phase::PhaseEnum m_preferredPhase;
Phase m_preferredPhase;
WellCompletion::CompletionOrderEnum m_comporder;
bool m_allowCrossFlow;

View File

@@ -217,46 +217,6 @@ BOOST_AUTO_TEST_CASE(TestGroupProductionExceedLimitActionEnumLoop) {
BOOST_CHECK_EQUAL("RATE" , GroupProductionExceedLimit::ActionEnum2String(GroupProductionExceedLimit::ActionEnumFromString( "RATE" ) ));
}
/*****************************************************************/
BOOST_AUTO_TEST_CASE(TestPhaseEnum2String) {
BOOST_CHECK_EQUAL( "OIL" , Phase::PhaseEnum2String(Phase::OIL));
BOOST_CHECK_EQUAL( "GAS" , Phase::PhaseEnum2String(Phase::GAS));
BOOST_CHECK_EQUAL( "WATER" , Phase::PhaseEnum2String(Phase::WATER));
}
BOOST_AUTO_TEST_CASE(TestPhaseEnumFromString) {
BOOST_CHECK_THROW( Phase::PhaseEnumFromString("XXX") , std::invalid_argument );
BOOST_CHECK_EQUAL( Phase::OIL , Phase::PhaseEnumFromString("OIL"));
BOOST_CHECK_EQUAL( Phase::WATER , Phase::PhaseEnumFromString("WATER"));
BOOST_CHECK_EQUAL( Phase::WATER , Phase::PhaseEnumFromString("WAT"));
BOOST_CHECK_EQUAL( Phase::GAS , Phase::PhaseEnumFromString("GAS"));
}
BOOST_AUTO_TEST_CASE(TestPhaseEnumLoop) {
BOOST_CHECK_EQUAL( Phase::OIL , Phase::PhaseEnumFromString( Phase::PhaseEnum2String( Phase::OIL ) ));
BOOST_CHECK_EQUAL( Phase::WATER , Phase::PhaseEnumFromString( Phase::PhaseEnum2String( Phase::WATER ) ));
BOOST_CHECK_EQUAL( Phase::GAS , Phase::PhaseEnumFromString( Phase::PhaseEnum2String( Phase::GAS ) ));
BOOST_CHECK_EQUAL( "OIL" , Phase::PhaseEnum2String(Phase::PhaseEnumFromString( "OIL" ) ));
BOOST_CHECK_EQUAL( "GAS" , Phase::PhaseEnum2String(Phase::PhaseEnumFromString( "GAS" ) ));
BOOST_CHECK_EQUAL( "WATER" , Phase::PhaseEnum2String(Phase::PhaseEnumFromString( "WATER" ) ));
}
BOOST_AUTO_TEST_CASE(TestPhaseEnumMask) {
BOOST_CHECK_EQUAL( 0 , Phase::OIL & Phase::GAS );
BOOST_CHECK_EQUAL( 0 , Phase::OIL & Phase::WATER );
BOOST_CHECK_EQUAL( 0 , Phase::WATER & Phase::GAS );
}
/*****************************************************************/
BOOST_AUTO_TEST_CASE(TestInjectorEnum2String) {

View File

@@ -79,7 +79,6 @@ namespace Opm {
hasEnptvd (deck.hasKeyword("ENPTVD")),
hasEqlnum (deck.hasKeyword("EQLNUM"))
{
initPhases( deck );
initDims( deck );
initSimpleTables( deck );
initFullTables(deck, "PVTG", m_pvtgTables);
@@ -89,29 +88,6 @@ namespace Opm {
initVFPInjTables(deck, m_vfpinjTables);
}
void TableManager::initPhases(const Deck& deck) {
if (deck.hasKeyword("OIL"))
phases.insert(Phase::PhaseEnum::OIL);
if (deck.hasKeyword("GAS"))
phases.insert(Phase::PhaseEnum::GAS);
if (deck.hasKeyword("WATER"))
phases.insert(Phase::PhaseEnum::WATER);
if (phases.size() < 3)
m_messages.info("Only " + std::to_string(static_cast<long long>(phases.size())) + " fluid phases are enabled");
}
size_t TableManager::getNumPhases() const{
return phases.size();
}
bool TableManager::hasPhase(enum Phase::PhaseEnum phase) const {
return (phases.count(phase) == 1);
}
void TableManager::initDims(const Deck& deck) {
using namespace Opm::ParserKeywords;
if (deck.hasKeyword<TABDIMS>()) {

View File

@@ -104,11 +104,6 @@ namespace Opm {
const std::map<int, VFPProdTable>& getVFPProdTables() const;
const std::map<int, VFPInjTable>& getVFPInjTables() const;
bool hasPhase(enum Phase::PhaseEnum phase) const;
/// number of phases, [gas, oil, water] = 3
size_t getNumPhases() const;
/// deck has keyword "IMPTVD" --- Imbition end-point versus depth tables
bool useImptvd() const;
@@ -129,7 +124,6 @@ namespace Opm {
void addTables( const std::string& tableName , size_t numTables);
void initSimpleTables(const Deck& deck);
void initRTempTables(const Deck& deck);
void initPhases(const Deck& deck);
void initDims(const Deck& deck);
void initRocktabTables(const Deck& deck);
void initGasvisctTables(const Deck& deck);
@@ -240,8 +234,6 @@ namespace Opm {
std::shared_ptr<Tabdims> m_tabdims;
std::shared_ptr<Eqldims> m_eqldims;
std::set<enum Phase::PhaseEnum> phases;
const bool hasImptvd;// if deck has keyword IMPTVD
const bool hasEnptvd;// if deck has keyword ENPTVD
const bool hasEqlnum;// if deck has keyword EQLNUM

View File

@@ -1,4 +1,5 @@
foreach(tapp EclipseStateTests Eclipse3DPropertiesTests)
foreach(tapp EclipseStateTests Eclipse3DPropertiesTests
RunspecTests)
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})

View File

@@ -246,15 +246,13 @@ BOOST_AUTO_TEST_CASE(CreateSimulationConfig) {
BOOST_CHECK_EQUAL(simConf.getThresholdPressure().size(), 3);
}
BOOST_AUTO_TEST_CASE(PhasesCorrect) {
auto deck = createDeck();
EclipseState state( deck, ParseContext() );
const auto& tm = state.getTableManager();
BOOST_CHECK( tm.hasPhase( Phase::PhaseEnum::OIL ));
BOOST_CHECK( tm.hasPhase( Phase::PhaseEnum::GAS ));
BOOST_CHECK( ! tm.hasPhase( Phase::PhaseEnum::WATER ));
const auto& phases = state.runspec().phases();
BOOST_CHECK( phases.active( Phase::OIL ) );
BOOST_CHECK( phases.active( Phase::GAS ) );
BOOST_CHECK( !phases.active( Phase::WATER ) );
}
BOOST_AUTO_TEST_CASE(TitleCorrect) {

View File

@@ -0,0 +1,83 @@
/*
Copyright 2016 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/>.
*/
#define BOOST_TEST_MODULE RunspecTests
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
using namespace Opm;
BOOST_AUTO_TEST_CASE(PhaseFromString) {
BOOST_CHECK_THROW( get_phase("XXX") , std::invalid_argument );
BOOST_CHECK_THROW( get_phase("WATE") , std::invalid_argument );
BOOST_CHECK_THROW( get_phase("OI") , std::invalid_argument );
BOOST_CHECK_THROW( get_phase("OILL") , std::invalid_argument );
BOOST_CHECK_EQUAL( Phase::OIL , get_phase("OIL") );
BOOST_CHECK_EQUAL( Phase::WATER, get_phase("WATER") );
BOOST_CHECK_EQUAL( Phase::WATER, get_phase("WAT") );
BOOST_CHECK_EQUAL( Phase::GAS , get_phase("GAS") );
}
BOOST_AUTO_TEST_CASE(TwoPhase) {
const std::string input = R"(
RUNSPEC
OIL
WATER
)";
Parser parser;
ParseContext parseContext;
auto deck = parser.parseString(input, parseContext);
Runspec runspec( deck );
const auto& phases = runspec.phases();
BOOST_CHECK_EQUAL( 2, phases.size() );
BOOST_CHECK( phases.active( Phase::OIL ) );
BOOST_CHECK( !phases.active( Phase::GAS ) );
BOOST_CHECK( phases.active( Phase::WATER ) );
}
BOOST_AUTO_TEST_CASE(ThreePhase) {
const std::string input = R"(
RUNSPEC
OIL
GAS
WATER
)";
Parser parser;
ParseContext parseContext;
auto deck = parser.parseString(input, parseContext);
Runspec runspec( deck );
const auto& phases = runspec.phases();
BOOST_CHECK_EQUAL( 3, phases.size() );
BOOST_CHECK( phases.active( Phase::OIL ) );
BOOST_CHECK( phases.active( Phase::GAS ) );
BOOST_CHECK( phases.active( Phase::WATER ) );
}