1. Added well collection to Schedule object.

2. Adding wells from Welspecs and setting Oilrate from WCONHIST
This commit is contained in:
Joakim Hove 2013-11-05 15:25:47 +01:00
parent 6d30a6a7fa
commit ffc5dc3c53
8 changed files with 269 additions and 52 deletions

View File

@ -25,31 +25,98 @@ namespace Opm
{
Schedule::Schedule(DeckConstPtr deck) {
if (deck->hasKeyword("SCHEDULE")) {
boost::gregorian::date startDate( defaultStartDate );
if (deck->hasKeyword("START")) {
DeckKeywordConstPtr startKeyword = deck->getKeyword("START");
startDate = TimeMap::dateFromEclipse( startKeyword->getRecord(0));
}
m_timeMap = TimeMapPtr(new TimeMap(startDate));
DeckKeywordConstPtr scheduleKeyword = deck->getKeyword( "SCHEDULE" );
size_t deckIndex = scheduleKeyword->getDeckIndex() + 1;
while (deckIndex < deck->size()) {
DeckKeywordConstPtr keyword = deck->getKeyword( deckIndex );
if (keyword->name() == "DATES")
m_timeMap->addFromDATESKeyword( keyword );
else if (keyword->name() == "TSTEP")
m_timeMap->addFromTSTEPKeyword( keyword );
deckIndex++;
}
initTimeMap( deck );
initWells( deck );
} else
throw std::invalid_argument("Deck does not contain SCHEDULE section.\n");
}
void Schedule::initTimeMap(DeckConstPtr deck) {
boost::gregorian::date startDate( defaultStartDate );
if (deck->hasKeyword("START")) {
DeckKeywordConstPtr startKeyword = deck->getKeyword("START");
startDate = TimeMap::dateFromEclipse( startKeyword->getRecord(0));
}
m_timeMap = TimeMapPtr(new TimeMap(startDate));
DeckKeywordConstPtr scheduleKeyword = deck->getKeyword( "SCHEDULE" );
size_t deckIndex = scheduleKeyword->getDeckIndex() + 1;
while (deckIndex < deck->size()) {
DeckKeywordConstPtr keyword = deck->getKeyword( deckIndex );
if (keyword->name() == "DATES")
m_timeMap->addFromDATESKeyword( keyword );
else if (keyword->name() == "TSTEP")
m_timeMap->addFromTSTEPKeyword( keyword );
deckIndex++;
}
}
void Schedule::initWells(DeckConstPtr deck) {
DeckKeywordConstPtr scheduleKeyword = deck->getKeyword( "SCHEDULE" );
size_t deckIndex = scheduleKeyword->getDeckIndex() + 1;
size_t currentStep = 0;
while (deckIndex < deck->size()) {
DeckKeywordConstPtr keyword = deck->getKeyword( deckIndex );
if (keyword->name() == "TSTEP")
currentStep += keyword->size();
if (keyword->name() == "DATES")
currentStep += keyword->size();
if (keyword->name() == "WELSPECS")
handleWELSPECS( keyword );
if (keyword->name() == "WCONHIST")
handleWCONHIST( keyword , currentStep );
deckIndex++;
}
}
void Schedule::addWell(const std::string& wellName) {
WellPtr well(new Well(wellName , m_timeMap));
m_wells[ wellName ] = well;
}
void Schedule::handleWELSPECS(DeckKeywordConstPtr keyword) {
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
DeckRecordConstPtr record = keyword->getRecord( recordNr );
const std::string& wellName = record->getItem(0)->getString(0);
if (!hasWell(wellName))
addWell(wellName);
{
WellPtr well = getWell(wellName);
well->addWELSPECS( record );
}
}
}
void Schedule::handleWCONHIST(DeckKeywordConstPtr keyword , size_t currentStep) {
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
DeckRecordConstPtr record = keyword->getRecord( recordNr );
const std::string& wellName = record->getItem(0)->getString(0);
double orat = record->getItem("ORAT")->getDouble(0);
WellPtr well = getWell(wellName);
well->setOilRate( currentStep , orat );
}
}
boost::gregorian::date Schedule::getStartDate() const {
return m_timeMap->getStartDate();
}
@ -59,4 +126,24 @@ namespace Opm
return m_timeMap;
}
size_t Schedule::numWells() const {
return m_wells.size();
}
bool Schedule::hasWell(const std::string& wellName) const {
return m_wells.find( wellName ) != m_wells.end();
}
WellPtr Schedule::getWell(const std::string& wellName) const {
if (hasWell(wellName)) {
return m_wells.at(wellName);
}
else
throw std::invalid_argument("Well: " + wellName + " does not exist");
}
}

View File

@ -19,12 +19,15 @@
#ifndef SCHEDULE_HPP
#define SCHEDULE_HPP
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <map>
namespace Opm
{
@ -36,8 +39,21 @@ namespace Opm
Schedule(DeckConstPtr deck);
boost::gregorian::date getStartDate() const;
TimeMapConstPtr getTimeMap() const;
size_t numWells() const;
bool hasWell(const std::string& wellName) const;
WellPtr getWell(const std::string& wellName) const;
private:
TimeMapPtr m_timeMap;
std::map<std::string , WellPtr> m_wells;
void addWell(const std::string& wellName);
void initTimeMap(DeckConstPtr deck);
void initWells(DeckConstPtr deck);
void handleWELSPECS(DeckKeywordConstPtr keyword);
void handleWCONHIST(DeckKeywordConstPtr keyword , size_t currentStep);
};
typedef boost::shared_ptr<Schedule> SchedulePtr;
typedef boost::shared_ptr<const Schedule> ScheduleConstPtr;

View File

@ -17,15 +17,17 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/date_time.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <string>
namespace Opm {
Well::Well(const std::string& name) {
Well::Well(const std::string& name , TimeMapConstPtr timeMap) : m_oilRate( new DynamicState<double>( timeMap , 0.0)) {
m_name = name;
}
@ -33,6 +35,21 @@ namespace Opm {
return m_name;
}
double Well::getOilRate(size_t timeStep) const {
return m_oilRate->get( timeStep );
}
void Well::setOilRate(size_t timeStep, double oilRate) {
m_oilRate->add( timeStep , oilRate );
}
void Well::addWELSPECS(DeckRecordConstPtr deckRecord) {
}
}

View File

@ -21,6 +21,9 @@
#ifndef WELL_HPP_
#define WELL_HPP_
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
@ -28,11 +31,16 @@ namespace Opm {
class Well {
public:
Well(const std::string& name);
Well(const std::string& name, TimeMapConstPtr timeMap);
const std::string& name() const;
double getOilRate(size_t timeStep) const;
void setOilRate(size_t timeStep, double oilRate);
void addWELSPECS(DeckRecordConstPtr deckRecord);
private:
std::string m_name;
boost::shared_ptr<DynamicState<double> > m_oilRate;
};
typedef boost::shared_ptr<Well> WellPtr;
typedef boost::shared_ptr<const Well> WellConstPtr;

View File

@ -32,24 +32,7 @@
using namespace Opm;
BOOST_AUTO_TEST_CASE(CreateScheduleDeckMissingSCHEDULE_Throws) {
DeckPtr deck(new Deck());
BOOST_CHECK_THROW(Schedule schedule(deck) , std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(CreateScheduleDeckMissingReturnsDefaults) {
DeckPtr deck(new Deck());
DeckKeywordPtr keyword(new DeckKeyword("SCHEDULE"));
deck->addKeyword( keyword );
Schedule schedule(deck);
BOOST_CHECK_EQUAL( schedule.getStartDate() , boost::gregorian::date( 1983 , boost::gregorian::Jan , 1));
}
BOOST_AUTO_TEST_CASE(CreateScheduleDeckWithStart) {
DeckPtr createDeck() {
DeckPtr deck(new Deck());
DeckKeywordPtr scheduleKeyword(new DeckKeyword("SCHEDULE"));
DeckKeywordPtr startKeyword(new DeckKeyword("START"));
@ -71,6 +54,29 @@ BOOST_AUTO_TEST_CASE(CreateScheduleDeckWithStart) {
deck->addKeyword( startKeyword );
deck->addKeyword( scheduleKeyword );
return deck;
}
BOOST_AUTO_TEST_CASE(CreateScheduleDeckMissingSCHEDULE_Throws) {
DeckPtr deck(new Deck());
BOOST_CHECK_THROW(Schedule schedule(deck) , std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(CreateScheduleDeckMissingReturnsDefaults) {
DeckPtr deck(new Deck());
DeckKeywordPtr keyword(new DeckKeyword("SCHEDULE"));
deck->addKeyword( keyword );
Schedule schedule(deck);
BOOST_CHECK_EQUAL( schedule.getStartDate() , boost::gregorian::date( 1983 , boost::gregorian::Jan , 1));
}
BOOST_AUTO_TEST_CASE(CreateScheduleDeckWithStart) {
DeckPtr deck = createDeck();
Schedule schedule(deck);
BOOST_CHECK_EQUAL( schedule.getStartDate() , boost::gregorian::date( 1998 , boost::gregorian::Mar , 8));
}
@ -87,3 +93,13 @@ BOOST_AUTO_TEST_CASE(CreateScheduleDeckWithSCHEDULENoThrow) {
}
BOOST_AUTO_TEST_CASE(EmptyScheduleHasNoWells) {
DeckPtr deck = createDeck();
Schedule schedule(deck);
BOOST_CHECK_EQUAL( 0U , schedule.numWells() );
BOOST_CHECK_EQUAL( false , schedule.hasWell("WELL1") );
BOOST_CHECK_THROW( schedule.getWell("WELL2") , std::invalid_argument );
}

View File

@ -28,9 +28,18 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
BOOST_AUTO_TEST_CASE(CreateWellCorrentName) {
Opm::Well well("WELL1");
boost::gregorian::date startDate( 2010 , boost::gregorian::Jan , 1);
Opm::TimeMapPtr timeMap(new Opm::TimeMap(startDate));
for (size_t i = 0; i < 10; i++)
timeMap->addTStep( boost::posix_time::hours( (i+1) * 24 ));
Opm::Well well("WELL1" , timeMap);
BOOST_CHECK_EQUAL( "WELL1" , well.name() );
BOOST_CHECK_EQUAL(0.0 , well.getOilRate( 5 ));
well.setOilRate( 5 , 99 );
BOOST_CHECK_EQUAL(99 , well.getOilRate( 5 ));
BOOST_CHECK_EQUAL(99 , well.getOilRate( 8 ));
}

View File

@ -39,6 +39,25 @@ BOOST_AUTO_TEST_CASE( CreateSchedule ) {
ScheduleConstPtr sched( new Schedule(deck));
TimeMapConstPtr timeMap = sched->getTimeMap();
BOOST_CHECK_EQUAL( boost::gregorian::date( 2007 , boost::gregorian::May , 10 ) , sched->getStartDate());
BOOST_CHECK_EQUAL( 9U , timeMap->size());
}
BOOST_AUTO_TEST_CASE( WellTesting ) {
ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_WELLS2");
DeckPtr deck = parser->parse(scheduleFile.string());
ScheduleConstPtr sched( new Schedule(deck));
BOOST_CHECK_EQUAL( 3U , sched->numWells());
BOOST_CHECK( sched->hasWell("OP_1"));
BOOST_CHECK( sched->hasWell("OP_2"));
BOOST_CHECK( sched->hasWell("OP_3"));
{
WellPtr well1 = sched->getWell("OP_1");
BOOST_CHECK_EQUAL( 14000 , well1->getOilRate( 8 ));
}
}

View File

@ -0,0 +1,45 @@
START
10 MAI 2007 /
SCHEDULE
DATES
10 'JUN' 2007 /
/
DATES
10 JLY 2007 /
10 AUG 2007 /
/
WELSPECS
'OP_1' 'OP' 30 37 1* 'OIL' 7* / Crap1
'OP_2' 'OP' 20 51 1* 'OIL' 7* / Crap2 Crap3
'OP_3' 'OP' 31 18 1* 'OIL' 7* /
/
WCONHIST
'OP_1' 'OPEN' 'ORAT' 4000.000 4.000 1.46402E+006 5* /
'OP_2' 'OPEN' 'ORAT' 7998.000 2.000 1461075.000 5* /
'OP_3' 'OPEN' 'ORAT' 7999.000 1.000 1471824.000 5* /
/
TSTEP
10 2*10 /
WCONHIST
'OP_1' 'OPEN' 'ORAT' 14000.000 4.000 1.46402E+006 5* /
'OP_2' 'OPEN' 'ORAT' 17998.000 2.000 1461075.000 5* /
'OP_3' 'OPEN' 'ORAT' 17999.000 1.000 1471824.000 5* /
/
DATES
10 JLY 2008 /
10 AUG 2008 /
/