Merge pull request #326 from joakim-hove/wellsmanager-crash

Wellsmanager crash
This commit is contained in:
Joakim Hove
2014-10-17 08:06:14 +02:00
10 changed files with 291 additions and 55 deletions

View File

@@ -68,6 +68,7 @@ EclipseState/Schedule/TimeMap.cpp
EclipseState/Schedule/Schedule.cpp
EclipseState/Schedule/Well.cpp
EclipseState/Schedule/WellProductionProperties.cpp
EclipseState/Schedule/WellInjectionProperties.cpp
EclipseState/Schedule/WellSet.cpp
EclipseState/Schedule/Group.cpp
EclipseState/Schedule/Completion.cpp
@@ -131,6 +132,7 @@ EclipseState/Schedule/TimeMap.hpp
EclipseState/Schedule/Schedule.hpp
EclipseState/Schedule/Well.hpp
EclipseState/Schedule/WellProductionProperties.hpp
EclipseState/Schedule/WellInjectionProperties.hpp
EclipseState/Schedule/WellSet.hpp
EclipseState/Schedule/Group.hpp
EclipseState/Schedule/DynamicState.hpp

View File

@@ -20,6 +20,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <boost/algorithm/string.hpp>
@@ -229,7 +230,7 @@ namespace Opm {
else {
std::string msg =
"Tried to set invalid control: " +
cmodeString + " for well: " + wellNamePattern;
cmodeString + " for well: " + well->name();
parserLog->addError(keyword->getFileName(),
keyword->getLineNumber(),
msg);

View File

@@ -84,7 +84,8 @@ namespace Opm {
RESV = 2 ,
BHP = 4 ,
THP = 8 ,
GRUP = 16
GRUP = 16 ,
CMODE_UNDEFINED = 512
};
/*
The elements in this enum are used as bitmasks to keep track
@@ -105,15 +106,16 @@ namespace Opm {
namespace WellProducer {
enum ControlModeEnum {
ORAT = 1,
WRAT = 2,
GRAT = 4,
LRAT = 8,
CRAT = 16,
RESV = 32,
BHP = 64,
THP = 128,
GRUP = 256
ORAT = 1,
WRAT = 2,
GRAT = 4,
LRAT = 8,
CRAT = 16,
RESV = 32,
BHP = 64,
THP = 128,
GRUP = 256,
CMODE_UNDEFINED = 1024
};
/*
@@ -121,6 +123,10 @@ namespace Opm {
WCONPROD. The elements in this enum are used as bitmasks to
keep track of which controls are present, i.e. the 2^n
structure must be intact.
The properties are initialized with the CMODE_UNDEFINED
value, but the undefined value is never assigned apart from
that; and it is not part of the string conversion routines.
*/

View File

@@ -26,6 +26,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp>
#include <boost/optional.hpp>
@@ -35,46 +36,6 @@
namespace Opm {
typedef struct WellInjectionProperties {
double surfaceInjectionRate;
double reservoirInjectionRate;
double BHPLimit;
double THPLimit;
bool predictionMode;
int injectionControls;
WellInjector::TypeEnum injectorType;
WellInjector::ControlModeEnum controlMode;
WellInjectionProperties() {
surfaceInjectionRate=0.0;
reservoirInjectionRate=0.0;
BHPLimit=0.0;
THPLimit=0.0;
predictionMode=true;
injectionControls=0;
injectorType = WellInjector::WATER;
controlMode = WellInjector::RATE;
}
bool hasInjectionControl(WellInjector::ControlModeEnum controlModeArg) const {
if (injectionControls & controlModeArg)
return true;
else
return false;
}
void dropInjectionControl(WellInjector::ControlModeEnum controlModeArg) {
if ((injectionControls & controlModeArg) != 0) {
injectionControls -= controlModeArg;
}
}
void addInjectionControl(WellInjector::ControlModeEnum controlModeArg) {
if ((injectionControls & controlModeArg) == 0) {
injectionControls += controlModeArg;
}
}
} WellInjectionProperties;
class Well {

View File

@@ -0,0 +1,19 @@
#include <opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp>
#include <string>
#include <vector>
namespace Opm {
WellInjectionProperties::WellInjectionProperties() {
surfaceInjectionRate=0.0;
reservoirInjectionRate=0.0;
BHPLimit=0.0;
THPLimit=0.0;
predictionMode=true;
injectionControls=0;
injectorType = WellInjector::WATER;
controlMode = WellInjector::CMODE_UNDEFINED;
}
}

View File

@@ -0,0 +1,60 @@
/*
Copyright 2014 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 WELLINJECTIONPROPERTIES_HPP_HEADER_INCLUDED
#define WELLINJECTIONPROPERTIES_HPP_HEADER_INCLUDED
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
namespace Opm {
struct WellInjectionProperties {
double surfaceInjectionRate;
double reservoirInjectionRate;
double BHPLimit;
double THPLimit;
bool predictionMode;
int injectionControls;
WellInjector::TypeEnum injectorType;
WellInjector::ControlModeEnum controlMode;
WellInjectionProperties();
bool hasInjectionControl(WellInjector::ControlModeEnum controlModeArg) const {
if (injectionControls & controlModeArg)
return true;
else
return false;
}
void dropInjectionControl(WellInjector::ControlModeEnum controlModeArg) {
if ((injectionControls & controlModeArg) != 0) {
injectionControls -= controlModeArg;
}
}
void addInjectionControl(WellInjector::ControlModeEnum controlModeArg) {
if ((injectionControls & controlModeArg) == 0) {
injectionControls += controlModeArg;
}
}
};
}
#endif

View File

@@ -53,7 +53,19 @@ namespace Opm {
if (!record->getItem("BHP")->defaultApplied(0)) {
p.addProductionControl(WellProducer::BHP);
}
{
const auto cmodeItem = record->getItem("CMODE");
if (!cmodeItem->defaultApplied(0)) {
const WellProducer::ControlModeEnum cmode = WellProducer::ControlModeFromString( cmodeItem->getString(0) );
if (p.hasProductionControl( cmode ))
p.controlMode = cmode;
else
throw std::invalid_argument("Setting CMODE to unspecified control");
}
}
return p;
}
@@ -86,6 +98,18 @@ namespace Opm {
}
}
{
const auto cmodeItem = record->getItem("CMODE");
if (!cmodeItem->defaultApplied(0)) {
const WellProducer::ControlModeEnum cmode = WellProducer::ControlModeFromString( cmodeItem->getString(0) );
if (p.hasProductionControl( cmode ))
p.controlMode = cmode;
else
throw std::invalid_argument("Setting CMODE to unspecified control");
}
}
return p;
}
@@ -100,7 +124,7 @@ namespace Opm {
ResVRate = 0.0;
BHPLimit = 0.0;
THPLimit = 0.0;
controlMode = WellProducer::ORAT;
controlMode = WellProducer::CMODE_UNDEFINED;
// private: property
productionControls = 0;

View File

@@ -18,6 +18,7 @@
*/
#include <opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp>
#define BOOST_TEST_MODULE WellPropertiesTest
#include <boost/test/unit_test.hpp>
@@ -30,6 +31,18 @@
namespace {
namespace WCONHIST {
std::string
all_specified_CMODE_BHP()
{
const std::string input =
"WCONHIST\n"
"'P' 'OPEN' 'BHP' 1 2 3/\n/\n";
return input;
}
std::string
all_specified()
{
@@ -93,6 +106,32 @@ namespace {
return Opm::WellProductionProperties::history(record);
}
} // namespace WCONHIST
namespace WCONPROD {
std::string
all_specified_CMODE_BHP()
{
const std::string input =
"WCONPROD\n"
"'P' 'OPEN' 'BHP' 1 2 3/\n/\n";
return input;
}
Opm::WellProductionProperties
properties(const std::string& input)
{
Opm::Parser parser;
Opm::DeckPtr deck = parser.parseString(input);
Opm::DeckKeywordConstPtr kwd = deck->getKeyword("WCONHIST");
Opm::DeckRecordConstPtr record = kwd->getRecord(0);
return Opm::WellProductionProperties::prediction(record);
}
}
} // namespace anonymous
BOOST_AUTO_TEST_CASE(WCH_All_Specified_BHP_Defaulted)
@@ -108,6 +147,8 @@ BOOST_AUTO_TEST_CASE(WCH_All_Specified_BHP_Defaulted)
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::LRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::RESV));
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::ORAT);
// BHP must be explicitly provided/specified
BOOST_REQUIRE(! p.hasProductionControl(Opm::WellProducer::BHP));
}
@@ -124,6 +165,7 @@ BOOST_AUTO_TEST_CASE(WCH_ORAT_Defaulted_BHP_Defaulted)
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::GRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::LRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::RESV));
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::WRAT);
// BHP must be explicitly provided/specified
BOOST_REQUIRE(! p.hasProductionControl(Opm::WellProducer::BHP));
@@ -141,7 +183,8 @@ BOOST_AUTO_TEST_CASE(WCH_OWRAT_Defaulted_BHP_Defaulted)
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::GRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::LRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::RESV));
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::GRAT);
// BHP must be explicitly provided/specified
BOOST_REQUIRE(! p.hasProductionControl(Opm::WellProducer::BHP));
}
@@ -158,6 +201,7 @@ BOOST_AUTO_TEST_CASE(WCH_Rates_Defaulted_BHP_Defaulted)
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::GRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::LRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::RESV));
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::LRAT);
// BHP must be explicitly provided/specified
BOOST_REQUIRE(! p.hasProductionControl(Opm::WellProducer::BHP));
@@ -176,6 +220,25 @@ BOOST_AUTO_TEST_CASE(WCH_Rates_Defaulted_BHP_Specified)
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::LRAT));
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::RESV));
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::RESV);
// BHP must be explicitly provided/specified
BOOST_REQUIRE(p.hasProductionControl(Opm::WellProducer::BHP));
}
BOOST_AUTO_TEST_CASE(BHP_CMODE)
{
BOOST_CHECK_THROW( WCONHIST::properties(WCONHIST::all_specified_CMODE_BHP()) , std::invalid_argument);
BOOST_CHECK_THROW( WCONPROD::properties(WCONPROD::all_specified_CMODE_BHP()) , std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(CMODE_DEFAULT) {
const Opm::WellProductionProperties Pproperties;
const Opm::WellInjectionProperties Iproperties;
BOOST_CHECK_EQUAL( Pproperties.controlMode , Opm::WellProducer::CMODE_UNDEFINED );
BOOST_CHECK_EQUAL( Iproperties.controlMode , Opm::WellInjector::CMODE_UNDEFINED );
}

View File

@@ -102,6 +102,7 @@ BOOST_AUTO_TEST_CASE(WellTesting) {
BOOST_CHECK_EQUAL( WellProducer::ORAT , prop3.controlMode);
BOOST_CHECK( prop3.hasProductionControl(WellProducer::ORAT));
BOOST_CHECK( prop3.hasProductionControl(WellProducer::GRAT));
BOOST_CHECK( prop3.hasProductionControl(WellProducer::WRAT));
}
// BOOST_CHECK( !well2->getProductionProperties(8).hasProductionControl(WellProducer::GRAT));
@@ -566,6 +567,28 @@ BOOST_AUTO_TEST_CASE(OpmCode) {
ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/wells_group.data");
DeckPtr deck = parser->parseFile(scheduleFile.string());
ScheduleConstPtr sched(new Schedule(deck));
BOOST_CHECK_NO_THROW( new Schedule(deck) );
}
BOOST_AUTO_TEST_CASE(WELLS_SHUT) {
ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_SHUT_WELL");
DeckPtr deck = parser->parseFile(scheduleFile.string());
ScheduleConstPtr sched(new Schedule(deck));
WellConstPtr well1 = sched->getWell("W1");
WellConstPtr well2 = sched->getWell("W2");
WellConstPtr well3 = sched->getWell("W3");
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well1->getStatus(1));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well2->getStatus(1));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well3->getStatus(1));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well1->getStatus(2));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well2->getStatus(2));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well3->getStatus(2));
}