Introducing WELSPECS data in constructor to Wells. Throws if WELSPECS with different data for an existing well occurs

This commit is contained in:
Kristian Flikka
2014-01-20 14:52:30 +01:00
parent 9a09fa29af
commit d09975e142
11 changed files with 167 additions and 43 deletions

View File

@@ -133,10 +133,13 @@ namespace Opm {
}
if (!hasWell(wellName)) {
addWell(wellName , currentStep);
addWell(wellName, record, currentStep);
}
addWellToGroup( getGroup(groupName) , getWell(wellName) , currentStep);
WellConstPtr currentWell = getWell(wellName);
checkWELSPECSConsistency(currentWell, record);
addWellToGroup( getGroup(groupName) , getWell(wellName) , currentStep);
needNewTree = handleGroupFromWELSPECS(record->getItem(1)->getString(0), newTree);
}
if (needNewTree) {
@@ -144,6 +147,18 @@ namespace Opm {
}
}
void Schedule::checkWELSPECSConsistency(WellConstPtr well, DeckRecordConstPtr record) const {
if (well->getHeadI() != record->getItem("HEAD_I")->getInt(0)) {
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", HEAD_I deviates from existing value");
}
if (well->getHeadJ() != record->getItem("HEAD_J")->getInt(0)) {
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", HEAD_J deviates from existing value");
}
if (well->getRefDepth() != record->getItem("REF_DEPTH")->getRawDouble(0)) {
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", REF_DEPTH deviates from existing value");
}
}
void Schedule::handleWCONProducer(DeckKeywordConstPtr keyword, size_t currentStep, bool isPredictionMode) {
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
DeckRecordConstPtr record = keyword->getRecord(recordNr);
@@ -271,8 +286,11 @@ namespace Opm {
return m_rootGroupTree->get(timeStep);
}
void Schedule::addWell(const std::string& wellName, size_t timeStep) {
WellPtr well(new Well(wellName, m_timeMap , timeStep));
void Schedule::addWell(const std::string& wellName, DeckRecordConstPtr record, size_t timeStep) {
int headI = record->getItem("HEAD_I")->getInt(0);
int headJ = record->getItem("HEAD_J")->getInt(0);
double refDepth = record->getItem("REF_DEPTH")->getRawDouble(0);
WellPtr well(new Well(wellName, headI, headJ, refDepth, m_timeMap , timeStep));
m_wells[ wellName ] = well;
}

View File

@@ -63,7 +63,8 @@ namespace Opm
void iterateScheduleSection(DeckConstPtr deck);
bool handleGroupFromWELSPECS(const std::string& groupName, GroupTreePtr newTree) const;
void addGroup(const std::string& groupName , size_t timeStep);
void addWell(const std::string& wellName , size_t timeStep);
void addWell(const std::string& wellName, DeckRecordConstPtr record, size_t timeStep);
void checkWELSPECSConsistency(WellConstPtr well, DeckRecordConstPtr record) const;
void handleWELSPECS(DeckKeywordConstPtr keyword, size_t currentStep);
void handleWCONProducer(DeckKeywordConstPtr keyword, size_t currentStep, bool isPredictionMode);
void handleWCONHIST(DeckKeywordConstPtr keyword , size_t currentStep);

View File

@@ -17,9 +17,10 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <boost/date_time.hpp>
#include <boost/lexical_cast.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
@@ -29,15 +30,18 @@
namespace Opm {
Well::Well(const std::string& name , TimeMapConstPtr timeMap , size_t creationTimeStep)
: m_oilRate( new DynamicState<double>( timeMap , 0.0)) ,
m_gasRate(new DynamicState<double>(timeMap, 0.0)),
m_waterRate(new DynamicState<double>(timeMap, 0.0)),
m_injectionRate(new DynamicState<double>(timeMap, 0.0)),
Well::Well(const std::string& name, int headI, int headJ, double refDepth, TimeMapConstPtr timeMap , size_t creationTimeStep)
: m_oilRate( new DynamicState<double>( timeMap , 0.0)) ,
m_gasRate(new DynamicState<double>(timeMap, 0.0)),
m_waterRate(new DynamicState<double>(timeMap, 0.0)),
m_injectionRate(new DynamicState<double>(timeMap, 0.0)),
m_inPredictionMode(new DynamicState<bool>(timeMap, true)),
m_isProducer(new DynamicState<bool>(timeMap, true)) ,
m_completions( new DynamicState<CompletionSetConstPtr>( timeMap , CompletionSetConstPtr( new CompletionSet()) )),
m_groupName( new DynamicState<std::string>( timeMap , "" ))
m_groupName( new DynamicState<std::string>( timeMap , "" )),
m_headI(headI),
m_headJ(headJ),
m_refDepth(refDepth)
{
m_name = name;
m_creationTimeStep = creationTimeStep;
@@ -75,7 +79,6 @@ namespace Opm {
switch2Producer( timeStep );
}
double Well::getWaterRate(size_t timeStep) const {
return m_waterRate->get(timeStep);
}
@@ -85,7 +88,6 @@ namespace Opm {
switch2Producer( timeStep );
}
double Well::getInjectionRate(size_t timeStep) const {
return m_injectionRate->get(timeStep);
}
@@ -122,10 +124,19 @@ namespace Opm {
void Well::setInPredictionMode(size_t timeStep, bool inPredictionMode) {
m_inPredictionMode->add(timeStep, inPredictionMode);
}
void Well::addWELSPECS(DeckRecordConstPtr deckRecord) {
// WELSPECS
int Well::getHeadI() const {
return m_headI;
}
int Well::getHeadJ() const {
return m_headJ;
}
double Well::getRefDepth() const {
return m_refDepth;
}
CompletionSetConstPtr Well::getCompletions(size_t timeStep) {

View File

@@ -33,7 +33,7 @@ namespace Opm {
class Well {
public:
Well(const std::string& name, TimeMapConstPtr timeMap , size_t creationTimeStep);
Well(const std::string& name, int headI, int headJ, double refDepth, TimeMapConstPtr timeMap , size_t creationTimeStep);
const std::string& name() const;
bool hasBeenDefined(size_t timeStep) const;
@@ -48,6 +48,10 @@ namespace Opm {
void setWaterRate(size_t timeStep, double waterRate);
double getInjectionRate(size_t timeStep) const;
void setInjectionRate(size_t timeStep, double injectionRate);
int getHeadI() const;
int getHeadJ() const;
double getRefDepth() const;
bool isInPredictionMode(size_t timeStep) const;
void setInPredictionMode(size_t timeStep, bool isInPredictionMode);
@@ -56,6 +60,7 @@ namespace Opm {
void addWELSPECS(DeckRecordConstPtr deckRecord);
void addCompletions(size_t time_step , const std::vector<CompletionConstPtr>& newCompletions);
CompletionSetConstPtr getCompletions(size_t timeStep);
private:
void switch2Producer(size_t timeStep );
void switch2Injector(size_t timeStep );
@@ -71,6 +76,11 @@ namespace Opm {
std::shared_ptr<DynamicState<bool> > m_isProducer;
std::shared_ptr<DynamicState<CompletionSetConstPtr> > m_completions;
std::shared_ptr<DynamicState<std::string> > m_groupName;
// WELSPECS data - assumes this is not dynamic
int m_headI;
int m_headJ;
double m_refDepth;
};
typedef std::shared_ptr<Well> WellPtr;
typedef std::shared_ptr<const Well> WellConstPtr;

View File

@@ -126,8 +126,8 @@ BOOST_AUTO_TEST_CASE(GroupAddWell) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Group group("G1" , timeMap , 0);
Opm::WellPtr well1(new Opm::Well("WELL1" , timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL2" , timeMap , 0));
Opm::WellPtr well1(new Opm::Well("WELL1" , 0, 0, 0.0, timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL2" , 0, 0, 0.0, timeMap , 0));
BOOST_CHECK_EQUAL(0U , group.numWells(2));
group.addWell( 3 , well1 );
@@ -163,9 +163,9 @@ BOOST_AUTO_TEST_CASE(GroupAddAndDelWell) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Group group("G1" , timeMap , 0);
Opm::WellPtr well1(new Opm::Well("WELL1" , timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL2" , timeMap , 0));
Opm::WellPtr well1(new Opm::Well("WELL1" , 0, 0, 0.0, timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL2" , 0, 0, 0.0, timeMap , 0));
BOOST_CHECK_EQUAL(0U , group.numWells(2));
group.addWell( 3 , well1 );
BOOST_CHECK_EQUAL( 1U , group.numWells(3));

View File

@@ -53,8 +53,8 @@ BOOST_AUTO_TEST_CASE(AddAndDeleteWell) {
Opm::WellSet wellSet;
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::WellPtr well(new Opm::Well("WELL1" , timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL2" , timeMap , 0));
Opm::WellPtr well(new Opm::Well("WELL1" , 0, 0, 0.0, timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL2" , 0, 0, 0.0, timeMap , 0));
wellSet.addWell( well );
BOOST_CHECK_EQUAL(true , wellSet.hasWell("WELL1"));
@@ -78,8 +78,8 @@ BOOST_AUTO_TEST_CASE(AddWellSameName) {
Opm::WellSet wellSet;
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::WellPtr well1(new Opm::Well("WELL" , timeMap, 0));
Opm::WellPtr well2(new Opm::Well("WELL" , timeMap , 0));
Opm::WellPtr well1(new Opm::Well("WELL" , 0, 0, 0.0, timeMap , 0));
Opm::WellPtr well2(new Opm::Well("WELL" , 0, 0, 0.0, timeMap , 0));
wellSet.addWell( well1 );
BOOST_CHECK_EQUAL(true , wellSet.hasWell("WELL"));

View File

@@ -26,6 +26,8 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckStringItem.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
@@ -40,14 +42,14 @@ Opm::TimeMapPtr createXDaysTimeMap(size_t numDays) {
BOOST_AUTO_TEST_CASE(CreateWell_CorrectNameAndDefaultValues) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
BOOST_CHECK_EQUAL( "WELL1" , well.name() );
BOOST_CHECK_EQUAL(0.0 , well.getOilRate( 5 ));
}
BOOST_AUTO_TEST_CASE(CreateWellCreateTimeStepOK) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 5);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 5);
BOOST_CHECK_EQUAL( false , well.hasBeenDefined(0) );
BOOST_CHECK_EQUAL( false , well.hasBeenDefined(4) );
BOOST_CHECK_EQUAL( true , well.hasBeenDefined(5) );
@@ -58,7 +60,7 @@ BOOST_AUTO_TEST_CASE(CreateWellCreateTimeStepOK) {
BOOST_AUTO_TEST_CASE(setOilRate_RateSetCorrect) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getOilRate( 5 ));
well.setOilRate( 5 , 99 );
@@ -68,7 +70,7 @@ BOOST_AUTO_TEST_CASE(setOilRate_RateSetCorrect) {
BOOST_AUTO_TEST_CASE(setPredictionMode_ModeSetCorrect) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
BOOST_CHECK_EQUAL( true, well.isInPredictionMode( 5 ));
well.setInPredictionMode( 5 , false ); // Go to history mode
@@ -80,7 +82,7 @@ BOOST_AUTO_TEST_CASE(setPredictionMode_ModeSetCorrect) {
BOOST_AUTO_TEST_CASE(NewWellZeroCompletions) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
Opm::CompletionSetConstPtr completions = well.getCompletions( 0 );
BOOST_CHECK_EQUAL( 0U , completions->size());
}
@@ -88,7 +90,7 @@ BOOST_AUTO_TEST_CASE(NewWellZeroCompletions) {
BOOST_AUTO_TEST_CASE(UpdateCompletions) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
Opm::CompletionSetConstPtr completions = well.getCompletions( 0 );
BOOST_CHECK_EQUAL( 0U , completions->size());
@@ -126,7 +128,7 @@ BOOST_AUTO_TEST_CASE(UpdateCompletions) {
BOOST_AUTO_TEST_CASE(setGasRate_RateSetCorrect) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getGasRate( 5 ));
well.setGasRate( 5 , 108 );
@@ -138,7 +140,7 @@ BOOST_AUTO_TEST_CASE(setGasRate_RateSetCorrect) {
BOOST_AUTO_TEST_CASE(setWaterRate_RateSetCorrect) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getWaterRate( 5 ));
well.setWaterRate( 5 , 108 );
@@ -149,7 +151,7 @@ BOOST_AUTO_TEST_CASE(setWaterRate_RateSetCorrect) {
BOOST_AUTO_TEST_CASE(setInjectionRate_RateSetCorrect) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap , 0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getInjectionRate( 5 ));
well.setInjectionRate( 5 , 108 );
@@ -160,7 +162,7 @@ BOOST_AUTO_TEST_CASE(setInjectionRate_RateSetCorrect) {
BOOST_AUTO_TEST_CASE(isProducerCorrectlySet) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap ,0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap ,0);
/* 1: Well is created as producer */
BOOST_CHECK_EQUAL( false , well.isInjector(0));
@@ -197,8 +199,7 @@ BOOST_AUTO_TEST_CASE(isProducerCorrectlySet) {
BOOST_AUTO_TEST_CASE(GroupnameCorretlySet) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , timeMap ,0);
Opm::Well well("WELL1" , 0, 0, 0.0, timeMap ,0);
BOOST_CHECK_EQUAL("" , well.getGroupName(2));
@@ -208,3 +209,15 @@ BOOST_AUTO_TEST_CASE(GroupnameCorretlySet) {
well.setGroupName(7 , "NEWGROUP");
BOOST_CHECK_EQUAL("NEWGROUP" , well.getGroupName(7));
}
BOOST_AUTO_TEST_CASE(addWELSPECS_setData_dataSet) {
Opm::TimeMapPtr timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1", 23, 42, 2334.32, timeMap, 3);
BOOST_CHECK(!well.hasBeenDefined(2));
BOOST_CHECK(well.hasBeenDefined(3));
BOOST_CHECK_EQUAL(23, well.getHeadI());
BOOST_CHECK_EQUAL(42, well.getHeadJ());
BOOST_CHECK_EQUAL(2334.32, well.getRefDepth());
}

View File

@@ -313,3 +313,47 @@ BOOST_AUTO_TEST_CASE( WellTestGroupAndWellRelation ) {
BOOST_CHECK_EQUAL( true , group2->hasWell("W_2" , 1));
}
BOOST_AUTO_TEST_CASE(WellTestWELSPECSDataLoaded) {
ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_WELLS2");
DeckPtr deck = parser->parseFile(scheduleFile.string());
ScheduleConstPtr sched(new Schedule(deck));
BOOST_CHECK_EQUAL(3U, sched->numWells());
BOOST_CHECK(sched->hasWell("W_1"));
BOOST_CHECK(sched->hasWell("W_2"));
BOOST_CHECK(sched->hasWell("W_3"));
{
WellConstPtr well1 = sched->getWell("W_1");
BOOST_CHECK(!well1->hasBeenDefined(2));
BOOST_CHECK(well1->hasBeenDefined(3));
BOOST_CHECK_EQUAL(30, well1->getHeadI());
BOOST_CHECK_EQUAL(37, well1->getHeadJ());
BOOST_CHECK_EQUAL(3.33, well1->getRefDepth());
WellConstPtr well2 = sched->getWell("W_2");
BOOST_CHECK(!well2->hasBeenDefined(2));
BOOST_CHECK(well2->hasBeenDefined(3));
BOOST_CHECK_EQUAL(20, well2->getHeadI());
BOOST_CHECK_EQUAL(51, well2->getHeadJ());
BOOST_CHECK_EQUAL(3.92, well2->getRefDepth());
WellConstPtr well3 = sched->getWell("W_3");
BOOST_CHECK(!well3->hasBeenDefined(2));
BOOST_CHECK(well3->hasBeenDefined(3));
BOOST_CHECK_EQUAL(31, well3->getHeadI());
BOOST_CHECK_EQUAL(18, well3->getHeadJ());
BOOST_CHECK_EQUAL(2.33, well3->getRefDepth());
}
}
BOOST_AUTO_TEST_CASE(WellTestWELSPECS_InvalidConfig_Throws) {
ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_WELL_INVALID_WELSPECS");
DeckPtr deck = parser->parseFile(scheduleFile.string());
BOOST_CHECK_THROW(new Schedule(deck), std::invalid_argument);
}

View File

@@ -15,9 +15,9 @@ DATES -- 2,3
/
WELSPECS
'W_1' 'OP' 30 37 1* 'OIL' 7* / Crap1
'W_2' 'OP' 20 51 1* 'OIL' 7* / Crap2 Crap3
'W_3' 'OP' 31 18 1* 'OIL' 7* /
'W_1' 'OP' 30 37 3.33 'OIL' 7* / Crap1
'W_2' 'OP' 20 51 3.92 'OIL' 7* / Crap2 Crap3
'W_3' 'OP' 31 18 2.33 'OIL' 7* /
/
COMPDAT

View File

@@ -15,5 +15,5 @@ TSTEP
WELSPECS
'W_2' 'GROUP2' 30 37 1* 'OIL' 7* /
'W_2' 'GROUP2' 20 51 1* 'OIL' 7* /
/

View File

@@ -0,0 +1,27 @@
START -- 0
10 MAI 2007 /
SCHEDULE
DATES -- 1
10 'JUN' 2007 /
/
WELSPECS
'W_1' 'OP' 30 37 3.33 'OIL' 7* / Crap1
'W_2' 'OP' 20 51 3.92 'OIL' 7* / Crap2 Crap3
'W_3' 'OP' 31 18 2.33 'OIL' 7* /
/
TSTEP -- 4,5,6
10 2*10 /
WELSPECS
'W_1' 'OP' 32 34 3.43 'OIL' 7* / Crap1
/