@@ -19,10 +19,11 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
|
||||
static void printDeckDiagnostics(Opm::DeckConstPtr deck, bool printAllKeywords) {
|
||||
static void printDeckDiagnostics(Opm::DeckConstPtr deck, Opm::ParserLogConstPtr parserLog, bool printAllKeywords) {
|
||||
int recognizedKeywords = 0;
|
||||
int unrecognizedKeywords = 0;
|
||||
|
||||
@@ -37,14 +38,11 @@ static void printDeckDiagnostics(Opm::DeckConstPtr deck, bool printAllKeywords)
|
||||
}
|
||||
}
|
||||
{
|
||||
for (size_t iw = 0; iw < deck->numWarnings(); iw++) {
|
||||
const std::pair<std::string,std::pair<std::string,size_t> >& warning = deck->getWarning( iw );
|
||||
const std::pair<std::string,size_t>& location = warning.second;
|
||||
|
||||
std::cout << warning.first << " at " << location.first << ":" << location.second << std::endl;
|
||||
for (size_t iw = 0; iw < parserLog->size(); iw++) {
|
||||
std::cout << parserLog->getFormattedMessage(iw) << "\n";
|
||||
}
|
||||
}
|
||||
std::cout << "Total number of warnings: " << deck->numWarnings() << std::endl;
|
||||
std::cout << "Total number of log messages: " << parserLog->size() << std::endl;
|
||||
std::cout << "Number of recognized keywords: " << recognizedKeywords << std::endl;
|
||||
std::cout << "Number of unrecognized keywords: " << unrecognizedKeywords << std::endl;
|
||||
std::cout << "Total number of keywords: " << deck->size() << std::endl;
|
||||
@@ -68,9 +66,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
Opm::ParserPtr parser(new Opm::Parser());
|
||||
std::string file = argv[1];
|
||||
Opm::DeckConstPtr deck = parser->parseFile(file, true);
|
||||
|
||||
printDeckDiagnostics(deck, printKeywords);
|
||||
Opm::ParserLogPtr parserLog(new Opm::ParserLog);
|
||||
Opm::DeckConstPtr deck = parser->parseFile(file, true, parserLog);
|
||||
|
||||
printDeckDiagnostics(deck, parserLog, printKeywords);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ set( parser_source
|
||||
Parser/ParserEnums.cpp
|
||||
Parser/ParserKeyword.cpp
|
||||
Parser/Parser.cpp
|
||||
Parser/ParserLog.cpp
|
||||
Parser/ParserRecord.cpp
|
||||
Parser/ParserItem.cpp
|
||||
Parser/ParserIntItem.cpp
|
||||
@@ -61,6 +62,8 @@ Parser/ParserStringItem.cpp
|
||||
set (state_source
|
||||
EclipseState/EclipseState.cpp
|
||||
#
|
||||
EclipseState/checkDeck.cpp
|
||||
#
|
||||
EclipseState/Schedule/TimeMap.cpp
|
||||
EclipseState/Schedule/Schedule.cpp
|
||||
EclipseState/Schedule/Well.cpp
|
||||
@@ -108,6 +111,7 @@ Deck/Section.hpp
|
||||
Parser/ParserEnums.hpp
|
||||
Parser/ParserKeyword.hpp
|
||||
Parser/Parser.hpp
|
||||
Parser/ParserLog.hpp
|
||||
Parser/ParserRecord.hpp
|
||||
Parser/ParserItem.hpp
|
||||
Parser/ParserIntItem.hpp
|
||||
@@ -121,6 +125,8 @@ Units/ConversionFactors.hpp
|
||||
#
|
||||
EclipseState/EclipseState.hpp
|
||||
#
|
||||
EclipseState/checkDeck.hpp
|
||||
#
|
||||
EclipseState/Schedule/TimeMap.hpp
|
||||
EclipseState/Schedule/Schedule.hpp
|
||||
EclipseState/Schedule/Well.hpp
|
||||
|
||||
@@ -60,25 +60,6 @@ namespace Opm {
|
||||
return m_keywords->size();
|
||||
}
|
||||
|
||||
size_t Deck::numWarnings() const {
|
||||
return m_warnings.size();
|
||||
}
|
||||
|
||||
void Deck::addWarning(const std::string& warningText , const std::string& filename , size_t lineNR) {
|
||||
std::pair<std::string,size_t> location(filename , lineNR);
|
||||
std::pair<std::string , std::pair<std::string,size_t> > warning(warningText , location);
|
||||
|
||||
m_warnings.push_back( warning );
|
||||
}
|
||||
|
||||
const std::pair<std::string , std::pair<std::string,size_t> >& Deck::getWarning( size_t index ) const {
|
||||
if (index < m_warnings.size())
|
||||
return m_warnings[index];
|
||||
else
|
||||
throw std::invalid_argument("Index out of range");
|
||||
}
|
||||
|
||||
|
||||
void Deck::initUnitSystem() {
|
||||
m_defaultUnits = std::shared_ptr<UnitSystem>( UnitSystem::newMETRIC() );
|
||||
if (hasKeyword("FIELD"))
|
||||
|
||||
@@ -40,11 +40,7 @@ namespace Opm {
|
||||
size_t numKeywords(const std::string& keyword) const;
|
||||
const std::vector<DeckKeywordPtr>& getKeywordList(const std::string& keyword) const;
|
||||
size_t size() const;
|
||||
size_t numWarnings() const;
|
||||
void addWarning(const std::string& warningText , const std::string& filename , size_t lineNR);
|
||||
const std::pair<std::string , std::pair<std::string,size_t> >& getWarning( size_t index ) const;
|
||||
void initUnitSystem();
|
||||
|
||||
std::shared_ptr<UnitSystem> getDefaultUnitSystem() const;
|
||||
std::shared_ptr<UnitSystem> getActiveUnitSystem() const;
|
||||
|
||||
@@ -52,8 +48,6 @@ namespace Opm {
|
||||
KeywordContainerPtr m_keywords;
|
||||
std::shared_ptr<UnitSystem> m_defaultUnits;
|
||||
std::shared_ptr<UnitSystem> m_activeUnits;
|
||||
|
||||
std::vector<std::pair<std::string , std::pair<std::string,size_t> > > m_warnings; //<"Warning Text" , <"Filename" , LineNR>>
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Deck> DeckPtr;
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace Opm {
|
||||
m_keywordName = keywordName;
|
||||
m_deckIndex = -1;
|
||||
m_isDataKeyword = false;
|
||||
m_fileName = "";
|
||||
m_lineNumber = -1;
|
||||
}
|
||||
|
||||
DeckKeyword::DeckKeyword(const std::string& keywordName, bool knownKeyword) {
|
||||
@@ -33,6 +35,35 @@ namespace Opm {
|
||||
m_keywordName = keywordName;
|
||||
m_deckIndex = -1;
|
||||
m_isDataKeyword = false;
|
||||
m_fileName = "";
|
||||
m_lineNumber = -1;
|
||||
}
|
||||
|
||||
void DeckKeyword::setLocation(const std::string& fileName, int lineNumber) {
|
||||
m_fileName = fileName;
|
||||
m_lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
std::shared_ptr<const ParserKeyword> DeckKeyword::getParserKeyword() const {
|
||||
if (!m_parserKeyword)
|
||||
throw std::invalid_argument("No ParserKeyword object available");
|
||||
return m_parserKeyword;
|
||||
}
|
||||
|
||||
bool DeckKeyword::hasParserKeyword() const {
|
||||
return static_cast<bool>(m_parserKeyword);
|
||||
}
|
||||
|
||||
const std::string& DeckKeyword::getFileName() const {
|
||||
return m_fileName;
|
||||
}
|
||||
|
||||
int DeckKeyword::getLineNumber() const {
|
||||
return m_lineNumber;
|
||||
}
|
||||
|
||||
void DeckKeyword::setParserKeyword(std::shared_ptr<const ParserKeyword> &parserKeyword) {
|
||||
m_parserKeyword = parserKeyword;
|
||||
}
|
||||
|
||||
void DeckKeyword::setDataKeyword(bool isDataKeyword_) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
|
||||
namespace Opm {
|
||||
class ParserKeyword;
|
||||
|
||||
class DeckKeyword {
|
||||
public:
|
||||
@@ -22,6 +23,22 @@ namespace Opm {
|
||||
DeckKeyword(const std::string& keywordName, bool knownKeyword);
|
||||
|
||||
std::string name() const;
|
||||
void setLocation(const std::string& fileName, int lineNumber);
|
||||
const std::string& getFileName() const;
|
||||
int getLineNumber() const;
|
||||
|
||||
/*!
|
||||
* \brief Returns the Parser keyword from which the current deck keyword was created from.
|
||||
*
|
||||
* If no parser keyword is available, this method throws
|
||||
* std::invalid_exception. Use hasParserKeyword() to test if one is available..
|
||||
*/
|
||||
std::shared_ptr<const ParserKeyword> getParserKeyword() const;
|
||||
|
||||
bool hasParserKeyword() const;
|
||||
|
||||
void setParserKeyword(std::shared_ptr<const ParserKeyword> &parserKeyword);
|
||||
|
||||
size_t size() const;
|
||||
void addRecord(DeckRecordConstPtr record);
|
||||
DeckRecordConstPtr getRecord(size_t index) const;
|
||||
@@ -45,6 +62,9 @@ namespace Opm {
|
||||
std::vector<DeckRecordConstPtr>::const_iterator end() const;
|
||||
private:
|
||||
std::string m_keywordName;
|
||||
std::string m_fileName;
|
||||
int m_lineNumber;
|
||||
std::shared_ptr<const ParserKeyword> m_parserKeyword;
|
||||
std::vector<DeckRecordConstPtr> m_recordList;
|
||||
bool m_knownKeyword;
|
||||
ssize_t m_deckIndex;
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include <opm/parser/eclipse/Deck/Section.hpp>
|
||||
|
||||
namespace Opm {
|
||||
Section::NullStream Section::nullStream;
|
||||
|
||||
Section::Section(DeckConstPtr deck, const std::string& startKeywordName)
|
||||
: m_name(startKeywordName)
|
||||
{
|
||||
@@ -98,103 +96,141 @@ namespace Opm {
|
||||
return m_keywords.getKeyword(index);
|
||||
}
|
||||
|
||||
bool Section::checkSectionTopology(DeckConstPtr deck, std::ostream& os)
|
||||
bool Section::checkSectionTopology(DeckConstPtr deck,
|
||||
ParserLogPtr parserLog)
|
||||
{
|
||||
if (deck->size() == 0) {
|
||||
os << "empty decks are invalid\n";
|
||||
std::string msg = "empty decks are invalid\n";
|
||||
parserLog->addWarning("", -1, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool deckValid = true;
|
||||
|
||||
if (deck->getKeyword(0)->name() != "RUNSPEC") {
|
||||
os << "The first keyword of a valid deck must be RUNSPEC\n";
|
||||
return false;
|
||||
std::string msg = "The first keyword of a valid deck must be RUNSPEC\n";
|
||||
parserLog->addWarning(deck->getKeyword(0)->getFileName(),
|
||||
deck->getKeyword(0)->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
std::string curSectionName = deck->getKeyword(0)->name();
|
||||
size_t curKwIdx = 1;
|
||||
for (; curKwIdx < deck->size(); ++curKwIdx) {
|
||||
const std::string& curKeywordName = deck->getKeyword(curKwIdx)->name();
|
||||
Opm::DeckKeywordConstPtr curKeyword = deck->getKeyword(curKwIdx);
|
||||
const std::string& curKeywordName = curKeyword->name();
|
||||
if (!isSectionDelimiter(curKeywordName))
|
||||
continue;
|
||||
|
||||
if (curSectionName == "RUNSPEC") {
|
||||
if (curKeywordName != "GRID") {
|
||||
os << "The RUNSPEC section must be followed by GRID instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The RUNSPEC section must be followed by GRID instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "GRID") {
|
||||
if (curKeywordName != "EDIT" && curKeywordName != "PROPS") {
|
||||
os << "The GRID section must be followed by EDIT or PROPS instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The GRID section must be followed by EDIT or PROPS instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "EDIT") {
|
||||
if (curKeywordName != "PROPS") {
|
||||
os << "The EDIT section must be followed by PROPS instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The EDIT section must be followed by PROPS instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "PROPS") {
|
||||
if (curKeywordName != "REGIONS" && curKeywordName != "SOLUTION") {
|
||||
os << "The PROPS section must be followed by REGIONS or SOLUTION instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The PROPS section must be followed by REGIONS or SOLUTION instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "REGIONS") {
|
||||
if (curKeywordName != "SOLUTION") {
|
||||
os << "The REGIONS section must be followed by SOLUTION instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The REGIONS section must be followed by SOLUTION instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "SOLUTION") {
|
||||
if (curKeywordName != "SUMMARY" && curKeywordName != "SCHEDULE") {
|
||||
os << "The SOLUTION section must be followed by SUMMARY or SCHEDULE instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The SOLUTION section must be followed by SUMMARY or SCHEDULE instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "SUMMARY") {
|
||||
if (curKeywordName != "SCHEDULE") {
|
||||
os << "The SUMMARY section must be followed by SCHEDULE instead of "
|
||||
<< curKeywordName << "\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The SUMMARY section must be followed by SCHEDULE instead of "+curKeywordName;
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
curSectionName = curKeywordName;
|
||||
}
|
||||
else if (curSectionName == "SCHEDULE") {
|
||||
// schedule is the last section, so every section delimiter after it is wrong...
|
||||
os << "The SCHEDULE section must be the last one ("
|
||||
<< curKeywordName << " specified after SCHEDULE)\n";
|
||||
return false;
|
||||
std::string msg =
|
||||
"The SCHEDULE section must be the last one ("
|
||||
+curKeywordName+" specified after SCHEDULE)";
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// SCHEDULE is the last section and it is mandatory, so make sure it is there
|
||||
if (curSectionName != "SCHEDULE") {
|
||||
os << "The last section of a valid deck must be SCHEDULE\n";
|
||||
return false;
|
||||
const auto& curKeyword = deck->getKeyword(deck->size() - 1);
|
||||
std::string msg =
|
||||
"The last section of a valid deck must be SCHEDULE (is "+curSectionName+")";
|
||||
parserLog->addWarning(curKeyword->getFileName(),
|
||||
curKeyword->getLineNumber(),
|
||||
msg);
|
||||
deckValid = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return deckValid;
|
||||
}
|
||||
|
||||
bool Section::isSectionDelimiter(const std::string& keywordName) {
|
||||
@@ -216,5 +252,4 @@ namespace Opm {
|
||||
bool Section::hasSection(DeckConstPtr deck, const std::string& startKeywordName) {
|
||||
return deck->hasKeyword(startKeywordName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#define SECTION_HPP
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
#include <iostream>
|
||||
@@ -31,22 +33,6 @@ namespace Opm {
|
||||
|
||||
class Section : public boost::iterator_facade<Section, DeckKeywordPtr, boost::forward_traversal_tag>
|
||||
{
|
||||
// Defining a no-op output stream nullStream.
|
||||
// see https://stackoverflow.com/questions/11826554/standard-no-op-output-stream
|
||||
class NullBuffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
int overflow(int c) { return c; }
|
||||
};
|
||||
class NullStream : public std::ostream
|
||||
{
|
||||
public:
|
||||
NullStream() : std::ostream(&m_sb) {}
|
||||
private:
|
||||
NullBuffer m_sb;
|
||||
};
|
||||
static NullStream nullStream;
|
||||
|
||||
public:
|
||||
Section(DeckConstPtr deck, const std::string& startKeyword);
|
||||
bool hasKeyword( const std::string& keyword ) const;
|
||||
@@ -68,7 +54,7 @@ namespace Opm {
|
||||
|
||||
// returns whether the deck has all mandatory sections and if all sections are in
|
||||
// the right order
|
||||
static bool checkSectionTopology(DeckConstPtr deck, std::ostream& os = nullStream);
|
||||
static bool checkSectionTopology(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
|
||||
private:
|
||||
KeywordContainer m_keywords;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
@@ -119,25 +120,36 @@ BOOST_AUTO_TEST_CASE(size_twokeyword_return2) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DECKWARNING_EMPTYOK) {
|
||||
Deck deck;
|
||||
BOOST_CHECK_EQUAL(0U, deck.numWarnings());
|
||||
ParserLog parserLog;
|
||||
BOOST_CHECK_EQUAL(0U, parserLog.size());
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DECKAddWarning) {
|
||||
Deck deck;
|
||||
deck.addWarning("WARNING" , "FILE" , 100U);
|
||||
BOOST_CHECK_EQUAL(1U, deck.numWarnings());
|
||||
ParserLog parserLog;
|
||||
parserLog.addNote("FILE", 100U, "NOTE");
|
||||
BOOST_CHECK_EQUAL(1U, parserLog.size());
|
||||
|
||||
deck.addWarning("WARNING2" , "FILE2" , 200U);
|
||||
BOOST_CHECK_EQUAL(2U, deck.numWarnings());
|
||||
parserLog.addWarning("FILE2", 200U, "WARNING");
|
||||
BOOST_CHECK_EQUAL(2U, parserLog.size());
|
||||
|
||||
const std::pair<std::string,std::pair<std::string,size_t> >& warning = deck.getWarning( 0 );
|
||||
const std::pair<std::string,size_t>& location = warning.second;
|
||||
parserLog.addError("FILE3", 300U, "ERROR");
|
||||
BOOST_CHECK_EQUAL(3U, parserLog.size());
|
||||
|
||||
BOOST_CHECK_EQUAL( warning.first , "WARNING" );
|
||||
BOOST_CHECK_EQUAL( location.first , "FILE" );
|
||||
BOOST_CHECK_EQUAL( location.second , 100U );
|
||||
BOOST_CHECK_EQUAL(parserLog.getMessageType(0), ParserLog::Note);
|
||||
BOOST_CHECK_EQUAL(parserLog.getDescription(0), "NOTE");
|
||||
BOOST_CHECK_EQUAL(parserLog.getFileName(0), "FILE");
|
||||
BOOST_CHECK_EQUAL(parserLog.getLineNumber(0), 100U);
|
||||
|
||||
BOOST_CHECK_EQUAL(parserLog.getMessageType(1), ParserLog::Warning);
|
||||
BOOST_CHECK_EQUAL(parserLog.getDescription(1), "WARNING");
|
||||
BOOST_CHECK_EQUAL(parserLog.getFileName(1), "FILE2");
|
||||
BOOST_CHECK_EQUAL(parserLog.getLineNumber(1), 200U);
|
||||
|
||||
BOOST_CHECK_EQUAL(parserLog.getMessageType(2), ParserLog::Error);
|
||||
BOOST_CHECK_EQUAL(parserLog.getDescription(2), "ERROR");
|
||||
BOOST_CHECK_EQUAL(parserLog.getFileName(2), "FILE3");
|
||||
BOOST_CHECK_EQUAL(parserLog.getLineNumber(2), 300U);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,8 @@ BOOST_AUTO_TEST_CASE(Section_ValidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST5"));
|
||||
|
||||
BOOST_CHECK(Opm::Section::checkSectionTopology(deck));
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
BOOST_CHECK(Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// deck with all optional sections
|
||||
deck.reset(new Deck());
|
||||
@@ -271,7 +272,7 @@ BOOST_AUTO_TEST_CASE(Section_ValidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST8"));
|
||||
|
||||
BOOST_CHECK(Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
@@ -294,7 +295,8 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST5"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// wrong section order
|
||||
deck.reset(new Deck());
|
||||
@@ -322,7 +324,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST8"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// duplicate section
|
||||
deck.reset(new Deck());
|
||||
@@ -353,7 +355,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST8"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// section after SCHEDULE
|
||||
deck.reset(new Deck());
|
||||
@@ -381,7 +383,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("EDIT"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST3"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// missing RUNSPEC
|
||||
deck.reset(new Deck());
|
||||
@@ -398,7 +400,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST5"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// missing GRID
|
||||
deck.reset(new Deck());
|
||||
@@ -415,7 +417,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST5"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// missing PROPS
|
||||
deck.reset(new Deck());
|
||||
@@ -432,7 +434,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST5"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// missing SOLUTION
|
||||
deck.reset(new Deck());
|
||||
@@ -449,7 +451,7 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SCHEDULE"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST5"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
|
||||
// missing SCHEDULE
|
||||
deck.reset(new Deck());
|
||||
@@ -466,5 +468,5 @@ BOOST_AUTO_TEST_CASE(Section_InvalidDecks) {
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("SOLUTION"));
|
||||
deck->addKeyword(std::make_shared<DeckKeyword>("TEST4"));
|
||||
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck));
|
||||
BOOST_CHECK(!Opm::Section::checkSectionTopology(deck, parserLog));
|
||||
}
|
||||
|
||||
@@ -26,33 +26,26 @@
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
EclipseState::EclipseState(DeckConstPtr deck, bool beStrict)
|
||||
EclipseState::EclipseState(DeckConstPtr deck, ParserLogPtr parserLog)
|
||||
{
|
||||
m_deckUnitSystem = deck->getActiveUnitSystem();
|
||||
|
||||
if (beStrict) {
|
||||
// make sure all mandatory sections are present and that their order is correct
|
||||
std::ostringstream oss;
|
||||
if (!Section::checkSectionTopology(deck, oss))
|
||||
throw std::invalid_argument("Section topology of deck is invalid: "
|
||||
+ oss.str());
|
||||
}
|
||||
|
||||
initPhases(deck);
|
||||
initTables(deck);
|
||||
initEclipseGrid(deck);
|
||||
initSchedule(deck);
|
||||
initTitle(deck);
|
||||
initProperties(deck);
|
||||
initTransMult();
|
||||
initFaults(deck);
|
||||
initMULTREGT(deck);
|
||||
initPhases(deck, parserLog);
|
||||
initTables(deck, parserLog);
|
||||
initEclipseGrid(deck, parserLog);
|
||||
initSchedule(deck, parserLog);
|
||||
initTitle(deck, parserLog);
|
||||
initProperties(deck, parserLog);
|
||||
initTransMult(parserLog);
|
||||
initFaults(deck, parserLog);
|
||||
initMULTREGT(deck, parserLog);
|
||||
}
|
||||
|
||||
std::shared_ptr<const UnitSystem> EclipseState::getDeckUnitSystem() const {
|
||||
@@ -155,36 +148,36 @@ namespace Opm {
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void EclipseState::initTables(DeckConstPtr deck) {
|
||||
initSimpleTables(deck, "ENKRVD", m_enkrvdTables);
|
||||
initSimpleTables(deck, "ENPTVD", m_enptvdTables);
|
||||
initSimpleTables(deck, "IMKRVD", m_imkrvdTables);
|
||||
initSimpleTables(deck, "IMPTVD", m_imptvdTables);
|
||||
initSimpleTables(deck, "PLYADS", m_plyadsTables);
|
||||
initSimpleTables(deck, "PLYMAX", m_plymaxTables);
|
||||
initSimpleTables(deck, "PLYROCK", m_plyrockTables);
|
||||
initSimpleTables(deck, "PLYVISC", m_plyviscTables);
|
||||
initSimpleTables(deck, "PVDG", m_pvdgTables);
|
||||
initSimpleTables(deck, "PVDO", m_pvdoTables);
|
||||
initSimpleTables(deck, "RSVD", m_rsvdTables);
|
||||
initSimpleTables(deck, "RVVD", m_rvvdTables);
|
||||
initSimpleTables(deck, "SGOF", m_sgofTables);
|
||||
initSimpleTables(deck, "SWOF", m_swofTables);
|
||||
initSimpleTables(deck, "TLMIXPAR", m_tlmixparTables);
|
||||
void EclipseState::initTables(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
initSimpleTables(deck, parserLog, "ENKRVD", m_enkrvdTables);
|
||||
initSimpleTables(deck, parserLog, "ENPTVD", m_enptvdTables);
|
||||
initSimpleTables(deck, parserLog, "IMKRVD", m_imkrvdTables);
|
||||
initSimpleTables(deck, parserLog, "IMPTVD", m_imptvdTables);
|
||||
initSimpleTables(deck, parserLog, "PLYADS", m_plyadsTables);
|
||||
initSimpleTables(deck, parserLog, "PLYMAX", m_plymaxTables);
|
||||
initSimpleTables(deck, parserLog, "PLYROCK", m_plyrockTables);
|
||||
initSimpleTables(deck, parserLog, "PLYVISC", m_plyviscTables);
|
||||
initSimpleTables(deck, parserLog, "PVDG", m_pvdgTables);
|
||||
initSimpleTables(deck, parserLog, "PVDO", m_pvdoTables);
|
||||
initSimpleTables(deck, parserLog, "RSVD", m_rsvdTables);
|
||||
initSimpleTables(deck, parserLog, "RVVD", m_rvvdTables);
|
||||
initSimpleTables(deck, parserLog, "SGOF", m_sgofTables);
|
||||
initSimpleTables(deck, parserLog, "SWOF", m_swofTables);
|
||||
initSimpleTables(deck, parserLog, "TLMIXPAR", m_tlmixparTables);
|
||||
|
||||
// the ROCKTAB table comes with additional fun because the number of columns
|
||||
//depends on the presence of the RKTRMDIR keyword...
|
||||
initRocktabTables(deck);
|
||||
initRocktabTables(deck, parserLog);
|
||||
|
||||
initFullTables(deck, "PVTG", m_pvtgTables);
|
||||
initFullTables(deck, "PVTO", m_pvtoTables);
|
||||
initFullTables(deck, parserLog, "PVTG", m_pvtgTables);
|
||||
initFullTables(deck, parserLog, "PVTO", m_pvtoTables);
|
||||
}
|
||||
|
||||
void EclipseState::initSchedule(DeckConstPtr deck) {
|
||||
schedule = ScheduleConstPtr( new Schedule(deck) );
|
||||
void EclipseState::initSchedule(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
schedule = ScheduleConstPtr( new Schedule(deck, parserLog) );
|
||||
}
|
||||
|
||||
void EclipseState::initTransMult() {
|
||||
void EclipseState::initTransMult(ParserLogPtr /*parserLog*/) {
|
||||
EclipseGridConstPtr grid = getEclipseGrid();
|
||||
m_transMult = std::make_shared<TransMult>( grid->getNX() , grid->getNY() , grid->getNZ());
|
||||
|
||||
@@ -204,7 +197,7 @@ namespace Opm {
|
||||
m_transMult->applyMULT(getDoubleGridProperty("MULTZ-"), FaceDir::ZMinus);
|
||||
}
|
||||
|
||||
void EclipseState::initFaults(DeckConstPtr deck) {
|
||||
void EclipseState::initFaults(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
EclipseGridConstPtr grid = getEclipseGrid();
|
||||
m_faults = std::make_shared<FaultCollection>();
|
||||
std::shared_ptr<Opm::GRIDSection> gridSection(new Opm::GRIDSection(deck) );
|
||||
@@ -238,11 +231,11 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
setMULTFLT( gridSection );
|
||||
setMULTFLT(gridSection, parserLog);
|
||||
|
||||
if (Section::hasEDIT(deck)) {
|
||||
std::shared_ptr<Opm::EDITSection> editSection(new Opm::EDITSection(deck) );
|
||||
setMULTFLT( editSection );
|
||||
setMULTFLT(editSection, parserLog);
|
||||
}
|
||||
|
||||
m_transMult->applyMULTFLT( m_faults );
|
||||
@@ -250,7 +243,7 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void EclipseState::setMULTFLT(std::shared_ptr<const Section> section) const {
|
||||
void EclipseState::setMULTFLT(std::shared_ptr<const Section> section, ParserLogPtr /*parserLog*/) const {
|
||||
for (size_t index=0; index < section->count("MULTFLT"); index++) {
|
||||
DeckKeywordConstPtr faultsKeyword = section->getKeyword("MULTFLT" , index);
|
||||
for (auto iter = faultsKeyword->begin(); iter != faultsKeyword->end(); ++iter) {
|
||||
@@ -265,7 +258,7 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void EclipseState::initMULTREGT(DeckConstPtr deck) {
|
||||
void EclipseState::initMULTREGT(DeckConstPtr deck, ParserLogPtr /*parserLog*/) {
|
||||
EclipseGridConstPtr grid = getEclipseGrid();
|
||||
std::shared_ptr<MULTREGTScanner> scanner = std::make_shared<MULTREGTScanner>();
|
||||
|
||||
@@ -291,12 +284,12 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void EclipseState::initEclipseGrid(DeckConstPtr deck) {
|
||||
m_eclipseGrid = EclipseGridConstPtr( new EclipseGrid( deck ));
|
||||
void EclipseState::initEclipseGrid(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
m_eclipseGrid = EclipseGridConstPtr( new EclipseGrid(deck, parserLog));
|
||||
}
|
||||
|
||||
|
||||
void EclipseState::initPhases(DeckConstPtr deck) {
|
||||
void EclipseState::initPhases(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
if (deck->hasKeyword("OIL"))
|
||||
phases.insert(Phase::PhaseEnum::OIL);
|
||||
|
||||
@@ -305,6 +298,10 @@ namespace Opm {
|
||||
|
||||
if (deck->hasKeyword("WATER"))
|
||||
phases.insert(Phase::PhaseEnum::WATER);
|
||||
|
||||
if (phases.size() < 3)
|
||||
parserLog->addNote("", -1,
|
||||
"Only " + std::to_string(phases.size()) + " fluid phases are enabled");
|
||||
}
|
||||
|
||||
|
||||
@@ -312,7 +309,7 @@ namespace Opm {
|
||||
return (phases.count(phase) == 1);
|
||||
}
|
||||
|
||||
void EclipseState::initTitle(DeckConstPtr deck){
|
||||
void EclipseState::initTitle(DeckConstPtr deck, ParserLogPtr /*parserLog*/){
|
||||
if (deck->hasKeyword("TITLE")) {
|
||||
DeckKeywordConstPtr titleKeyword = deck->getKeyword("TITLE");
|
||||
DeckRecordConstPtr record = titleKeyword->getRecord(0);
|
||||
@@ -322,12 +319,14 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void EclipseState::initRocktabTables(DeckConstPtr deck) {
|
||||
void EclipseState::initRocktabTables(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
if (!deck->hasKeyword("ROCKTAB"))
|
||||
return; // ROCKTAB is not featured by the deck...
|
||||
|
||||
if (deck->numKeywords("ROCKTAB") > 1)
|
||||
throw std::invalid_argument("The ROCKTAB keyword must be unique in the deck");
|
||||
if (deck->numKeywords("ROCKTAB") > 1) {
|
||||
complainAboutAmbiguousKeyword(deck, parserLog, "ROCKTAB");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto rocktabKeyword = deck->getKeyword("ROCKTAB");
|
||||
|
||||
@@ -385,9 +384,10 @@ namespace Opm {
|
||||
return m_doubleGridProperties->getKeyword( keyword );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EclipseState::loadGridPropertyFromDeckKeyword(std::shared_ptr<const Box> inputBox , DeckKeywordConstPtr deckKeyword, int enabledTypes) {
|
||||
void EclipseState::loadGridPropertyFromDeckKeyword(std::shared_ptr<const Box> inputBox,
|
||||
DeckKeywordConstPtr deckKeyword,
|
||||
ParserLogPtr parserLog,
|
||||
int enabledTypes) {
|
||||
const std::string& keyword = deckKeyword->name();
|
||||
if (m_intGridProperties->supportsKeyword( keyword )) {
|
||||
if (enabledTypes & IntProperties) {
|
||||
@@ -400,13 +400,15 @@ namespace Opm {
|
||||
gridProperty->loadFromDeckKeyword( inputBox , deckKeyword );
|
||||
}
|
||||
} else {
|
||||
throw std::invalid_argument("Tried to load from unsupported keyword: " + deckKeyword->name());
|
||||
parserLog->addError(deckKeyword->getFileName(),
|
||||
deckKeyword->getLineNumber(),
|
||||
"Tried to load unsupported grid property from keyword: " + deckKeyword->name());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EclipseState::initProperties(DeckConstPtr deck) {
|
||||
void EclipseState::initProperties(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
typedef GridProperties<int>::SupportedKeywordInfo SupportedIntKeywordInfo;
|
||||
static std::vector<SupportedIntKeywordInfo> supportedIntKeywords =
|
||||
{SupportedIntKeywordInfo( "SATNUM" , 1, "1" ),
|
||||
@@ -604,8 +606,8 @@ namespace Opm {
|
||||
|
||||
// first process all integer grid properties as these may be needed in order to
|
||||
// initialize the double properties
|
||||
processGridProperties(deck, /*enabledTypes=*/IntProperties);
|
||||
processGridProperties(deck, /*enabledTypes=*/DoubleProperties);
|
||||
processGridProperties(deck, parserLog, /*enabledTypes=*/IntProperties);
|
||||
processGridProperties(deck, parserLog, /*enabledTypes=*/DoubleProperties);
|
||||
}
|
||||
|
||||
double EclipseState::getSIScaling(const std::string &dimensionString) const
|
||||
@@ -613,61 +615,62 @@ namespace Opm {
|
||||
return m_deckUnitSystem->getDimension(dimensionString)->getSIScaling();
|
||||
}
|
||||
|
||||
void EclipseState::processGridProperties(Opm::DeckConstPtr deck, int enabledTypes) {
|
||||
void EclipseState::processGridProperties(Opm::DeckConstPtr deck, ParserLogPtr parserLog, int enabledTypes) {
|
||||
|
||||
if (Section::hasGRID(deck)) {
|
||||
std::shared_ptr<Opm::GRIDSection> gridSection(new Opm::GRIDSection(deck) );
|
||||
scanSection(gridSection, enabledTypes);
|
||||
scanSection(gridSection, parserLog, enabledTypes);
|
||||
}
|
||||
|
||||
|
||||
if (Section::hasEDIT(deck)) {
|
||||
std::shared_ptr<Opm::EDITSection> editSection(new Opm::EDITSection(deck) );
|
||||
scanSection(editSection, enabledTypes);
|
||||
scanSection(editSection, parserLog, enabledTypes);
|
||||
}
|
||||
|
||||
if (Section::hasPROPS(deck)) {
|
||||
std::shared_ptr<Opm::PROPSSection> propsSection(new Opm::PROPSSection(deck) );
|
||||
scanSection(propsSection, enabledTypes);
|
||||
scanSection(propsSection, parserLog, enabledTypes);
|
||||
}
|
||||
|
||||
if (Section::hasREGIONS(deck)) {
|
||||
std::shared_ptr<Opm::REGIONSSection> regionsSection(new Opm::REGIONSSection(deck) );
|
||||
scanSection(regionsSection, enabledTypes);
|
||||
scanSection(regionsSection, parserLog, enabledTypes);
|
||||
}
|
||||
|
||||
if (Section::hasSOLUTION(deck)) {
|
||||
std::shared_ptr<Opm::SOLUTIONSection> solutionSection(new Opm::SOLUTIONSection(deck) );
|
||||
scanSection(solutionSection, enabledTypes);
|
||||
scanSection(solutionSection, parserLog, enabledTypes);
|
||||
}
|
||||
}
|
||||
|
||||
void EclipseState::scanSection(std::shared_ptr<Opm::Section> section,
|
||||
ParserLogPtr parserLog,
|
||||
int enabledTypes) {
|
||||
BoxManager boxManager(m_eclipseGrid->getNX( ) , m_eclipseGrid->getNY() , m_eclipseGrid->getNZ());
|
||||
for (auto iter = section->begin(); iter != section->end(); ++iter) {
|
||||
DeckKeywordConstPtr deckKeyword = *iter;
|
||||
|
||||
if (supportsGridProperty(deckKeyword->name(), enabledTypes) )
|
||||
loadGridPropertyFromDeckKeyword(boxManager.getActiveBox(), deckKeyword, enabledTypes);
|
||||
loadGridPropertyFromDeckKeyword(boxManager.getActiveBox(), deckKeyword, parserLog, enabledTypes);
|
||||
else {
|
||||
if (deckKeyword->name() == "ADD")
|
||||
handleADDKeyword(deckKeyword , boxManager, enabledTypes);
|
||||
handleADDKeyword(deckKeyword, parserLog, boxManager, enabledTypes);
|
||||
|
||||
if (deckKeyword->name() == "BOX")
|
||||
handleBOXKeyword(deckKeyword , boxManager);
|
||||
handleBOXKeyword(deckKeyword, parserLog, boxManager);
|
||||
|
||||
if (deckKeyword->name() == "COPY")
|
||||
handleCOPYKeyword(deckKeyword , boxManager, enabledTypes);
|
||||
handleCOPYKeyword(deckKeyword, parserLog, boxManager, enabledTypes);
|
||||
|
||||
if (deckKeyword->name() == "EQUALS")
|
||||
handleEQUALSKeyword(deckKeyword , boxManager, enabledTypes);
|
||||
handleEQUALSKeyword(deckKeyword, parserLog, boxManager, enabledTypes);
|
||||
|
||||
if (deckKeyword->name() == "ENDBOX")
|
||||
handleENDBOXKeyword(boxManager);
|
||||
|
||||
if (deckKeyword->name() == "MULTIPLY")
|
||||
handleMULTIPLYKeyword(deckKeyword , boxManager, enabledTypes);
|
||||
handleMULTIPLYKeyword(deckKeyword, parserLog, boxManager, enabledTypes);
|
||||
|
||||
boxManager.endKeyword();
|
||||
}
|
||||
@@ -678,7 +681,7 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void EclipseState::handleBOXKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager) {
|
||||
void EclipseState::handleBOXKeyword(DeckKeywordConstPtr deckKeyword, ParserLogPtr /*parserLog*/, BoxManager& boxManager) {
|
||||
DeckRecordConstPtr record = deckKeyword->getRecord(0);
|
||||
int I1 = record->getItem("I1")->getInt(0) - 1;
|
||||
int I2 = record->getItem("I2")->getInt(0) - 1;
|
||||
@@ -696,13 +699,13 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void EclipseState::handleMULTIPLYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) {
|
||||
for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) {
|
||||
DeckRecordConstPtr record = *iter;
|
||||
void EclipseState::handleMULTIPLYKeyword(DeckKeywordConstPtr deckKeyword, ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes) {
|
||||
for (size_t recordIdx = 0; recordIdx < deckKeyword->size(); ++recordIdx) {
|
||||
DeckRecordConstPtr record = deckKeyword->getRecord(recordIdx);
|
||||
const std::string& field = record->getItem("field")->getString(0);
|
||||
double scaleFactor = record->getItem("factor")->getRawDouble(0);
|
||||
|
||||
setKeywordBox( record , boxManager );
|
||||
setKeywordBox(deckKeyword, recordIdx, parserLog, boxManager);
|
||||
|
||||
if (m_intGridProperties->hasKeyword( field )) {
|
||||
if (enabledTypes & IntProperties) {
|
||||
@@ -728,13 +731,13 @@ namespace Opm {
|
||||
some state dependent semantics regarding endpoint scaling arrays
|
||||
in the PROPS section. That is not supported.
|
||||
*/
|
||||
void EclipseState::handleADDKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) {
|
||||
for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) {
|
||||
DeckRecordConstPtr record = *iter;
|
||||
void EclipseState::handleADDKeyword(DeckKeywordConstPtr deckKeyword, ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes) {
|
||||
for (size_t recordIdx = 0; recordIdx < deckKeyword->size(); ++recordIdx) {
|
||||
DeckRecordConstPtr record = deckKeyword->getRecord(recordIdx);
|
||||
const std::string& field = record->getItem("field")->getString(0);
|
||||
double shiftValue = record->getItem("shift")->getRawDouble(0);
|
||||
|
||||
setKeywordBox( record , boxManager );
|
||||
setKeywordBox(deckKeyword, recordIdx, parserLog, boxManager);
|
||||
|
||||
if (m_intGridProperties->hasKeyword( field )) {
|
||||
if (enabledTypes & IntProperties) {
|
||||
@@ -758,13 +761,13 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void EclipseState::handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) {
|
||||
for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) {
|
||||
DeckRecordConstPtr record = *iter;
|
||||
void EclipseState::handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword, ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes) {
|
||||
for (size_t recordIdx = 0; recordIdx < deckKeyword->size(); ++recordIdx) {
|
||||
DeckRecordConstPtr record = deckKeyword->getRecord(recordIdx);
|
||||
const std::string& field = record->getItem("field")->getString(0);
|
||||
double value = record->getItem("value")->getRawDouble(0);
|
||||
|
||||
setKeywordBox( record , boxManager );
|
||||
setKeywordBox(deckKeyword, recordIdx, parserLog, boxManager);
|
||||
|
||||
if (m_intGridProperties->supportsKeyword( field )) {
|
||||
if (enabledTypes & IntProperties) {
|
||||
@@ -789,13 +792,13 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void EclipseState::handleCOPYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) {
|
||||
for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) {
|
||||
DeckRecordConstPtr record = *iter;
|
||||
void EclipseState::handleCOPYKeyword(DeckKeywordConstPtr deckKeyword, ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes) {
|
||||
for (size_t recordIdx = 0; recordIdx < deckKeyword->size(); ++recordIdx) {
|
||||
DeckRecordConstPtr record = deckKeyword->getRecord(recordIdx);
|
||||
const std::string& srcField = record->getItem("src")->getString(0);
|
||||
const std::string& targetField = record->getItem("target")->getString(0);
|
||||
|
||||
setKeywordBox( record , boxManager );
|
||||
setKeywordBox(deckKeyword, recordIdx, parserLog, boxManager);
|
||||
|
||||
if (m_intGridProperties->hasKeyword( srcField )) {
|
||||
if (enabledTypes & IntProperties)
|
||||
@@ -829,7 +832,9 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void EclipseState::setKeywordBox(DeckRecordConstPtr deckRecord , BoxManager& boxManager) {
|
||||
void EclipseState::setKeywordBox(DeckKeywordConstPtr deckKeyword, size_t recordIdx, ParserLogPtr parserLog, BoxManager& boxManager) {
|
||||
auto deckRecord = deckKeyword->getRecord(recordIdx);
|
||||
|
||||
DeckItemConstPtr I1Item = deckRecord->getItem("I1");
|
||||
DeckItemConstPtr I2Item = deckRecord->getItem("I2");
|
||||
DeckItemConstPtr J1Item = deckRecord->getItem("J1");
|
||||
@@ -865,7 +870,18 @@ namespace Opm {
|
||||
K1Item->getInt(0) - 1,
|
||||
K2Item->getInt(0) - 1);
|
||||
} else if (setCount != 0)
|
||||
throw std::invalid_argument("When using BOX modifiers on keywords you must specify the BOX completely - or not at all.");
|
||||
parserLog->addError(deckKeyword->getFileName(),
|
||||
deckKeyword->getLineNumber(),
|
||||
"BOX modifiers on keywords must be either specified completely or not at all. Ignoring.");
|
||||
}
|
||||
|
||||
void EclipseState::complainAboutAmbiguousKeyword(DeckConstPtr deck, ParserLogPtr parserLog, const std::string& keywordName) const {
|
||||
parserLog->addError("", -1,
|
||||
"The "+keywordName+" keyword must be unique in the deck. Ignoring all!");
|
||||
auto keywords = deck->getKeywordList(keywordName);
|
||||
for (size_t i = 0; i < keywords.size(); ++i)
|
||||
parserLog->addError(keywords[i]->getFileName(), keywords[i]->getLineNumber(),
|
||||
"Ambiguous keyword "+keywordName+" defined here");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECLIPSESTATE_H
|
||||
#define ECLIPSESTATE_H
|
||||
#ifndef OPM_ECLIPSE_STATE_HPP
|
||||
#define OPM_ECLIPSE_STATE_HPP
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
|
||||
@@ -51,9 +53,9 @@
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseState {
|
||||
public:
|
||||
enum EnabledTypes {
|
||||
@@ -63,7 +65,7 @@ namespace Opm {
|
||||
AllProperties = IntProperties | DoubleProperties
|
||||
};
|
||||
|
||||
EclipseState(DeckConstPtr deck, bool beStrict = false);
|
||||
EclipseState(DeckConstPtr deck, ParserLogPtr parserLog = std::make_shared<ParserLog>(&std::cout));
|
||||
|
||||
ScheduleConstPtr getSchedule() const;
|
||||
EclipseGridConstPtr getEclipseGrid() const;
|
||||
@@ -77,7 +79,10 @@ namespace Opm {
|
||||
bool hasIntGridProperty(const std::string& keyword) const;
|
||||
bool hasDoubleGridProperty(const std::string& keyword) const;
|
||||
|
||||
void loadGridPropertyFromDeckKeyword(std::shared_ptr<const Box> inputBox , DeckKeywordConstPtr deckKeyword, int enabledTypes = AllProperties);
|
||||
void loadGridPropertyFromDeckKeyword(std::shared_ptr<const Box> inputBox,
|
||||
DeckKeywordConstPtr deckKeyword,
|
||||
ParserLogPtr parserLog,
|
||||
int enabledTypes = AllProperties);
|
||||
|
||||
std::shared_ptr<const FaultCollection> getFaults() const;
|
||||
std::shared_ptr<const TransMult> getTransMult() const;
|
||||
@@ -110,33 +115,40 @@ namespace Opm {
|
||||
std::shared_ptr<const UnitSystem> getDeckUnitSystem() const;
|
||||
|
||||
private:
|
||||
void initTables(DeckConstPtr deck);
|
||||
void initSchedule(DeckConstPtr deck);
|
||||
void initEclipseGrid(DeckConstPtr deck);
|
||||
void initPhases(DeckConstPtr deck);
|
||||
void initTitle(DeckConstPtr deck);
|
||||
void initProperties(DeckConstPtr deck);
|
||||
void initTransMult();
|
||||
void initFaults(DeckConstPtr deck);
|
||||
void initTables(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initSchedule(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initEclipseGrid(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initPhases(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initTitle(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initProperties(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initTransMult(ParserLogPtr parserLog);
|
||||
void initFaults(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
|
||||
template <class TableType>
|
||||
void initSimpleTables(DeckConstPtr deck,
|
||||
ParserLogPtr parserLog,
|
||||
const std::string& keywordName,
|
||||
std::vector<TableType>& tableVector) {
|
||||
if (!deck->hasKeyword(keywordName))
|
||||
return; // the table is not featured by the deck...
|
||||
|
||||
if (deck->numKeywords(keywordName) > 1)
|
||||
throw std::invalid_argument("The "+keywordName+" keyword must be unique in the deck");
|
||||
if (deck->numKeywords(keywordName) > 1) {
|
||||
complainAboutAmbiguousKeyword(deck, parserLog, keywordName);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& tableKeyword = deck->getKeyword(keywordName);
|
||||
for (size_t tableIdx = 0; tableIdx < tableKeyword->size(); ++tableIdx) {
|
||||
if (tableKeyword->getRecord(tableIdx)->getItem(0)->size() == 0) {
|
||||
// for simple tables, an empty record indicates that the previous table
|
||||
// should be copied...
|
||||
if (tableIdx == 0)
|
||||
throw std::invalid_argument("The first table for keyword "+keywordName+
|
||||
" must be explicitly defined!");
|
||||
if (tableIdx == 0) {
|
||||
parserLog->addError(tableKeyword->getFileName(),
|
||||
tableKeyword->getLineNumber(),
|
||||
"The first table for keyword "+keywordName+
|
||||
" must be explicitly defined! Ignoring keyword");
|
||||
return;
|
||||
}
|
||||
tableVector.push_back(tableVector.back());
|
||||
continue;
|
||||
}
|
||||
@@ -148,13 +160,16 @@ namespace Opm {
|
||||
|
||||
template <class TableType>
|
||||
void initFullTables(DeckConstPtr deck,
|
||||
ParserLogPtr parserLog,
|
||||
const std::string& keywordName,
|
||||
std::vector<TableType>& tableVector) {
|
||||
if (!deck->hasKeyword(keywordName))
|
||||
return; // the table is not featured by the deck...
|
||||
|
||||
if (deck->numKeywords(keywordName) > 1)
|
||||
throw std::invalid_argument("The "+keywordName+" keyword must be unique in the deck");
|
||||
if (deck->numKeywords(keywordName) > 1) {
|
||||
complainAboutAmbiguousKeyword(deck, parserLog, keywordName);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& tableKeyword = deck->getKeyword(keywordName);
|
||||
|
||||
@@ -165,27 +180,29 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void initRocktabTables(DeckConstPtr deck);
|
||||
void initRocktabTables(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
|
||||
void setMULTFLT(std::shared_ptr<const Section> section) const;
|
||||
void initMULTREGT(DeckConstPtr deck);
|
||||
void setMULTFLT(std::shared_ptr<const Section> section, ParserLogPtr parserLog) const;
|
||||
void initMULTREGT(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
|
||||
double getSIScaling(const std::string &dimensionString) const;
|
||||
|
||||
void processGridProperties(Opm::DeckConstPtr deck, int enabledTypes);
|
||||
void scanSection(std::shared_ptr<Opm::Section> section, int enabledTypes);
|
||||
void handleADDKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes);
|
||||
void handleBOXKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager);
|
||||
void handleCOPYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes);
|
||||
void processGridProperties(Opm::DeckConstPtr deck, ParserLogPtr parserLog, int enabledTypes);
|
||||
void scanSection(std::shared_ptr<Opm::Section> section, ParserLogPtr parserLog, int enabledTypes);
|
||||
void handleADDKeyword(DeckKeywordConstPtr deckKeyword , ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes);
|
||||
void handleBOXKeyword(DeckKeywordConstPtr deckKeyword , ParserLogPtr parserLog, BoxManager& boxManager);
|
||||
void handleCOPYKeyword(DeckKeywordConstPtr deckKeyword , ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes);
|
||||
void handleENDBOXKeyword(BoxManager& boxManager);
|
||||
void handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes);
|
||||
void handleMULTIPLYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes);
|
||||
void handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword , ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes);
|
||||
void handleMULTIPLYKeyword(DeckKeywordConstPtr deckKeyword , ParserLogPtr parserLog, BoxManager& boxManager, int enabledTypes);
|
||||
|
||||
void setKeywordBox(DeckRecordConstPtr deckRecord , BoxManager& boxManager);
|
||||
void setKeywordBox(DeckKeywordConstPtr deckKeyword, size_t recordIdx, ParserLogPtr parserLog, BoxManager& boxManager);
|
||||
|
||||
void copyIntKeyword(const std::string& srcField , const std::string& targetField , std::shared_ptr<const Box> inputBox);
|
||||
void copyDoubleKeyword(const std::string& srcField , const std::string& targetField , std::shared_ptr<const Box> inputBox);
|
||||
|
||||
void complainAboutAmbiguousKeyword(DeckConstPtr deck, ParserLogPtr parserLog, const std::string& keywordName) const;
|
||||
|
||||
EclipseGridConstPtr m_eclipseGrid;
|
||||
ScheduleConstPtr schedule;
|
||||
|
||||
|
||||
@@ -66,9 +66,8 @@ namespace Opm {
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
EclipseGrid::EclipseGrid(std::shared_ptr<const Deck> deck)
|
||||
: m_minpv("MINPV"),
|
||||
EclipseGrid::EclipseGrid(std::shared_ptr<const Deck> deck, ParserLogPtr parserLog)
|
||||
: m_minpv("MINPV"),
|
||||
m_pinch("PINCH")
|
||||
{
|
||||
const bool hasRUNSPEC = Section::hasRUNSPEC(deck);
|
||||
@@ -79,18 +78,22 @@ namespace Opm {
|
||||
if (runspecSection->hasKeyword("DIMENS")) {
|
||||
DeckKeywordConstPtr dimens = runspecSection->getKeyword("DIMENS");
|
||||
std::vector<int> dims = getDims(dimens);
|
||||
initGrid(dims, deck);
|
||||
initGrid(dims, deck, parserLog);
|
||||
} else {
|
||||
throw std::invalid_argument("The RUNSPEC section must have the DIMENS keyword with grid dimensions.");
|
||||
const std::string msg = "The RUNSPEC section must have the DIMENS keyword with logically Cartesian grid dimensions.";
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
} else if (hasGRID) {
|
||||
// Look for SPECGRID instead of DIMENS.
|
||||
if (deck->hasKeyword("SPECGRID")) {
|
||||
DeckKeywordConstPtr specgrid = deck->getKeyword("SPECGRID");
|
||||
std::vector<int> dims = getDims(specgrid);
|
||||
initGrid(dims, deck);
|
||||
initGrid(dims, deck, parserLog);
|
||||
} else {
|
||||
throw std::invalid_argument("With no RUNSPEC section, the GRID section must have the SPECGRID keyword with grid dimensions.");
|
||||
const std::string msg = "With no RUNSPEC section, the GRID section must specify the grid dimensions using the SPECGRID keyword.";
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
} else {
|
||||
// The deck contains no relevant section, so it is probably a sectionless GRDECL file.
|
||||
@@ -98,25 +101,29 @@ namespace Opm {
|
||||
if (deck->hasKeyword("SPECGRID")) {
|
||||
DeckKeywordConstPtr specgrid = deck->getKeyword("SPECGRID");
|
||||
std::vector<int> dims = getDims(specgrid);
|
||||
initGrid(dims, deck);
|
||||
initGrid(dims, deck, parserLog);
|
||||
} else if (deck->hasKeyword("DIMENS")) {
|
||||
DeckKeywordConstPtr dimens = deck->getKeyword("DIMENS");
|
||||
std::vector<int> dims = getDims(dimens);
|
||||
initGrid(dims, deck);
|
||||
initGrid(dims, deck, parserLog);
|
||||
} else {
|
||||
throw std::invalid_argument("Must specify grid dimensions with DIMENS or SPECGRID.");
|
||||
const std::string msg = "The deck must specify grid dimensions using either DIMENS or SPECGRID.";
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EclipseGrid::initGrid( const std::vector<int>& dims , DeckConstPtr deck ) {
|
||||
void EclipseGrid::initGrid( const std::vector<int>& dims, DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
if (hasCornerPointKeywords(deck)) {
|
||||
initCornerPointGrid(dims , deck);
|
||||
initCornerPointGrid(dims , deck, parserLog);
|
||||
} else if (hasCartesianKeywords(deck)) {
|
||||
initCartesianGrid(dims , deck);
|
||||
} else {
|
||||
throw std::invalid_argument("The deck must have COORD / ZCORN or D?? + TOPS keywords");
|
||||
const std::string msg = "The deck must have COORD / ZCORN or D?? + TOPS keywords";
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
|
||||
if (deck->hasKeyword("PINCH")) {
|
||||
@@ -222,7 +229,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void EclipseGrid::assertCornerPointKeywords( const std::vector<int>& dims , DeckConstPtr deck ) const
|
||||
void EclipseGrid::assertCornerPointKeywords( const std::vector<int>& dims , DeckConstPtr deck, ParserLogPtr parserLog) const
|
||||
{
|
||||
const int nx = dims[0];
|
||||
const int ny = dims[1];
|
||||
@@ -230,28 +237,46 @@ namespace Opm {
|
||||
{
|
||||
DeckKeywordConstPtr ZCORNKeyWord = deck->getKeyword("ZCORN");
|
||||
|
||||
if (ZCORNKeyWord->getDataSize() != static_cast<size_t>(8*nx*ny*nz))
|
||||
throw std::invalid_argument("Wrong size in ZCORN keyword - expected 8*x*ny*nz = " + boost::lexical_cast<std::string>(8*nx*ny*nz));
|
||||
if (ZCORNKeyWord->getDataSize() != static_cast<size_t>(8*nx*ny*nz)) {
|
||||
const std::string msg =
|
||||
"Wrong size of the ZCORN keyword: Expected 8*x*ny*nz = "
|
||||
+ std::to_string(8*nx*ny*nz) + " is "
|
||||
+ std::to_string(ZCORNKeyWord->getDataSize());
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
DeckKeywordConstPtr COORDKeyWord = deck->getKeyword("COORD");
|
||||
if (COORDKeyWord->getDataSize() != static_cast<size_t>(6*(nx + 1)*(ny + 1)))
|
||||
throw std::invalid_argument("Wrong size in COORD keyword - expected 6*(nx + 1)*(ny + 1) = " + boost::lexical_cast<std::string>(6*(nx + 1)*(ny + 1)));
|
||||
if (COORDKeyWord->getDataSize() != static_cast<size_t>(6*(nx + 1)*(ny + 1))) {
|
||||
const std::string msg =
|
||||
"Wrong size of the COORD keyword: Expected 8*(nx + 1)*(ny + 1) = "
|
||||
+ std::to_string(8*(nx + 1)*(ny + 1)) + " is "
|
||||
+ std::to_string(COORDKeyWord->getDataSize());
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (deck->hasKeyword("ACTNUM")) {
|
||||
DeckKeywordConstPtr ACTNUMKeyWord = deck->getKeyword("ACTNUM");
|
||||
if (ACTNUMKeyWord->getDataSize() != static_cast<size_t>(nx*ny*nz))
|
||||
throw std::invalid_argument("Wrong size in ACTNUM keyword - expected 8*x*ny*nz = " + boost::lexical_cast<std::string>(nx*ny*nz));
|
||||
if (ACTNUMKeyWord->getDataSize() != static_cast<size_t>(nx*ny*nz)) {
|
||||
const std::string msg =
|
||||
"Wrong size of the ACTNUM keyword: Expected nx*ny*nz = "
|
||||
+ std::to_string(nx*ny*nz) + " is "
|
||||
+ std::to_string(ACTNUMKeyWord->getDataSize());
|
||||
parserLog->addError("", -1, msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void EclipseGrid::initCornerPointGrid(const std::vector<int>& dims , DeckConstPtr deck) {
|
||||
assertCornerPointKeywords( dims , deck );
|
||||
void EclipseGrid::initCornerPointGrid(const std::vector<int>& dims , DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
assertCornerPointKeywords( dims , deck, parserLog);
|
||||
{
|
||||
DeckKeywordConstPtr ZCORNKeyWord = deck->getKeyword("ZCORN");
|
||||
DeckKeywordConstPtr COORDKeyWord = deck->getKeyword("COORD");
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef ECLIPSE_GRID_HPP_
|
||||
#define ECLIPSE_GRID_HPP_
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Section.hpp>
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace Opm {
|
||||
public:
|
||||
explicit EclipseGrid(const std::string& filename);
|
||||
explicit EclipseGrid(const ecl_grid_type * src_ptr);
|
||||
explicit EclipseGrid(std::shared_ptr<const Deck> deck);
|
||||
explicit EclipseGrid(std::shared_ptr<const Deck> deck, ParserLogPtr parserLog = std::make_shared<ParserLog>());
|
||||
|
||||
static bool hasCornerPointKeywords(std::shared_ptr<const Deck> deck);
|
||||
static bool hasCartesianKeywords(std::shared_ptr<const Deck> deck);
|
||||
@@ -71,11 +72,11 @@ namespace Opm {
|
||||
Value<double> m_pinch;
|
||||
|
||||
void initCartesianGrid(const std::vector<int>& dims , DeckConstPtr deck);
|
||||
void initCornerPointGrid(const std::vector<int>& dims , DeckConstPtr deck);
|
||||
void assertCornerPointKeywords( const std::vector<int>& dims , DeckConstPtr deck ) const ;
|
||||
void initCornerPointGrid(const std::vector<int>& dims , DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void assertCornerPointKeywords(const std::vector<int>& dims, DeckConstPtr deck, ParserLogPtr parserLog) const ;
|
||||
void initDTOPSGrid(const std::vector<int>& dims , DeckConstPtr deck);
|
||||
void initDVDEPTHZGrid(const std::vector<int>& dims , DeckConstPtr deck);
|
||||
void initGrid( const std::vector<int>& dims , DeckConstPtr deck );
|
||||
void initGrid(const std::vector<int>& dims, DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
static bool hasDVDEPTHZKeywords(DeckConstPtr deck);
|
||||
static bool hasDTOPSKeywords(DeckConstPtr deck);
|
||||
static void assertVectorSize(const std::vector<double>& vector , size_t expectedSize , const std::string& msg);
|
||||
|
||||
@@ -28,22 +28,22 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
Schedule::Schedule(DeckConstPtr deck) {
|
||||
initFromDeck(deck);
|
||||
Schedule::Schedule(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
initFromDeck(deck, parserLog);
|
||||
}
|
||||
|
||||
void Schedule::initFromDeck(DeckConstPtr deck) {
|
||||
createTimeMap(deck);
|
||||
void Schedule::initFromDeck(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
createTimeMap(deck, parserLog);
|
||||
addGroup( "FIELD", 0 );
|
||||
initRootGroupTreeNode(getTimeMap());
|
||||
iterateScheduleSection(deck);
|
||||
iterateScheduleSection(deck, parserLog);
|
||||
}
|
||||
|
||||
void Schedule::initRootGroupTreeNode(TimeMapConstPtr timeMap) {
|
||||
m_rootGroupTree.reset(new DynamicState<GroupTreePtr>(timeMap, GroupTreePtr(new GroupTree())));
|
||||
}
|
||||
|
||||
void Schedule::createTimeMap(DeckConstPtr deck) {
|
||||
void Schedule::createTimeMap(DeckConstPtr deck, ParserLogPtr /*parserLog*/) {
|
||||
boost::posix_time::ptime startTime(defaultStartDate);
|
||||
if (deck->hasKeyword("START")) {
|
||||
DeckKeywordConstPtr startKeyword = deck->getKeyword("START");
|
||||
@@ -53,63 +53,63 @@ namespace Opm {
|
||||
m_timeMap.reset(new TimeMap(startTime));
|
||||
}
|
||||
|
||||
void Schedule::iterateScheduleSection(DeckConstPtr deck) {
|
||||
void Schedule::iterateScheduleSection(DeckConstPtr deck, ParserLogPtr parserLog) {
|
||||
size_t currentStep = 0;
|
||||
|
||||
for (size_t keywordIdx = 0; keywordIdx < deck->size(); ++keywordIdx) {
|
||||
DeckKeywordConstPtr keyword = deck->getKeyword(keywordIdx);
|
||||
|
||||
if (keyword->name() == "DATES") {
|
||||
handleDATES(keyword);
|
||||
handleDATES(keyword, parserLog);
|
||||
currentStep += keyword->size();
|
||||
}
|
||||
|
||||
if (keyword->name() == "TSTEP") {
|
||||
handleTSTEP(keyword);
|
||||
handleTSTEP(keyword, parserLog);
|
||||
currentStep += keyword->getRecord(0)->getItem(0)->size(); // This is a bit weird API.
|
||||
}
|
||||
|
||||
if (keyword->name() == "WELSPECS") {
|
||||
handleWELSPECS(keyword, currentStep);
|
||||
handleWELSPECS(keyword, parserLog, currentStep);
|
||||
}
|
||||
|
||||
if (keyword->name() == "WCONHIST")
|
||||
handleWCONHIST(keyword, currentStep);
|
||||
handleWCONHIST(keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "WCONPROD")
|
||||
handleWCONPROD(keyword, currentStep);
|
||||
handleWCONPROD(keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "WCONINJE")
|
||||
handleWCONINJE(deck, keyword, currentStep);
|
||||
handleWCONINJE(deck, keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "WCONINJH")
|
||||
handleWCONINJH(deck, keyword, currentStep);
|
||||
handleWCONINJH(deck, keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "WGRUPCON")
|
||||
handleWGRUPCON(keyword, currentStep);
|
||||
handleWGRUPCON(keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "COMPDAT")
|
||||
handleCOMPDAT(keyword, currentStep);
|
||||
handleCOMPDAT(keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "WELOPEN")
|
||||
handleWELOPEN(keyword, currentStep);
|
||||
handleWELOPEN(keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "GRUPTREE")
|
||||
handleGRUPTREE(keyword, currentStep);
|
||||
handleGRUPTREE(keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "GCONINJE")
|
||||
handleGCONINJE( deck, keyword , currentStep );
|
||||
handleGCONINJE(deck, keyword, parserLog, currentStep);
|
||||
|
||||
if (keyword->name() == "GCONPROD")
|
||||
handleGCONPROD( keyword , currentStep );
|
||||
handleGCONPROD(keyword, parserLog, currentStep);
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleDATES(DeckKeywordConstPtr keyword) {
|
||||
void Schedule::handleDATES(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/) {
|
||||
m_timeMap->addFromDATESKeyword(keyword);
|
||||
}
|
||||
|
||||
void Schedule::handleTSTEP(DeckKeywordConstPtr keyword) {
|
||||
void Schedule::handleTSTEP(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/) {
|
||||
m_timeMap->addFromTSTEPKeyword(keyword);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Opm {
|
||||
return treeUpdated;
|
||||
}
|
||||
|
||||
void Schedule::handleWELSPECS(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleWELSPECS(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep) {
|
||||
bool needNewTree = false;
|
||||
GroupTreePtr newTree = m_rootGroupTree->get(currentStep)->deepCopy();
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
WellConstPtr currentWell = getWell(wellName);
|
||||
checkWELSPECSConsistency(currentWell, record);
|
||||
checkWELSPECSConsistency(currentWell, keyword, recordNr, parserLog);
|
||||
|
||||
addWellToGroup( getGroup(groupName) , getWell(wellName) , currentStep);
|
||||
bool treeChanged = handleGroupFromWELSPECS(groupName, newTree);
|
||||
@@ -151,24 +151,45 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::checkWELSPECSConsistency(WellConstPtr well, DeckRecordConstPtr record) const {
|
||||
void Schedule::checkWELSPECSConsistency(WellConstPtr well, DeckKeywordConstPtr keyword, size_t recordIdx, ParserLogPtr parserLog) const {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordIdx);
|
||||
if (well->getHeadI() != record->getItem("HEAD_I")->getInt(0) - 1) {
|
||||
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", HEAD_I deviates from existing value");
|
||||
std::string msg =
|
||||
"Unable process WELSPECS for well " + well->name() + ", HEAD_I deviates from existing value";
|
||||
parserLog->addError(keyword->getFileName(),
|
||||
keyword->getLineNumber(),
|
||||
msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
if (well->getHeadJ() != record->getItem("HEAD_J")->getInt(0) - 1) {
|
||||
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", HEAD_J deviates from existing value");
|
||||
std::string msg =
|
||||
"Unable process WELSPECS for well " + well->name() + ", HEAD_J deviates from existing value";
|
||||
parserLog->addError(keyword->getFileName(),
|
||||
keyword->getLineNumber(),
|
||||
msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
if (well->getRefDepthDefaulted() != record->getItem("REF_DEPTH")->defaultApplied(0)) {
|
||||
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", REF_DEPTH defaulted state deviates from existing value");
|
||||
std::string msg =
|
||||
"Unable process WELSPECS for well " + well->name() + ", REF_DEPTH defaulted state deviates from existing value";
|
||||
parserLog->addError(keyword->getFileName(),
|
||||
keyword->getLineNumber(),
|
||||
msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
if (!well->getRefDepthDefaulted()) {
|
||||
if (well->getRefDepth() != record->getItem("REF_DEPTH")->getSIDouble(0)) {
|
||||
throw std::invalid_argument("Unable process WELSPECS for well " + well->name() + ", REF_DEPTH deviates from existing value");
|
||||
std::string msg =
|
||||
"Unable process WELSPECS for well " + well->name() + ", REF_DEPTH deviates from existing value";
|
||||
parserLog->addError(keyword->getFileName(),
|
||||
keyword->getLineNumber(),
|
||||
msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWCONProducer(DeckKeywordConstPtr keyword, size_t currentStep, bool isPredictionMode) {
|
||||
void Schedule::handleWCONProducer(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep, bool isPredictionMode) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
|
||||
@@ -206,9 +227,13 @@ namespace Opm {
|
||||
properties.controlMode = control;
|
||||
}
|
||||
else {
|
||||
throw std::invalid_argument("Tried to set invalid control: " +
|
||||
cmodeString + " for well: " +
|
||||
wellNamePattern);
|
||||
std::string msg =
|
||||
"Tried to set invalid control: " +
|
||||
cmodeString + " for well: " + wellNamePattern;
|
||||
parserLog->addError(keyword->getFileName(),
|
||||
keyword->getLineNumber(),
|
||||
msg);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,15 +243,15 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWCONHIST(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
handleWCONProducer(keyword, currentStep, false);
|
||||
void Schedule::handleWCONHIST(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep) {
|
||||
handleWCONProducer(keyword, parserLog, currentStep, false);
|
||||
}
|
||||
|
||||
void Schedule::handleWCONPROD(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
handleWCONProducer(keyword, currentStep, true);
|
||||
void Schedule::handleWCONPROD(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep) {
|
||||
handleWCONProducer(keyword, parserLog, currentStep, true);
|
||||
}
|
||||
|
||||
void Schedule::handleWCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleWCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
const std::string& wellNamePattern = record->getItem("WELL")->getTrimmedString(0);
|
||||
@@ -235,7 +260,7 @@ namespace Opm {
|
||||
for (auto wellIter=wells.begin(); wellIter != wells.end(); ++wellIter) {
|
||||
WellPtr well = *wellIter;
|
||||
WellInjector::TypeEnum injectorType = WellInjector::TypeFromString( record->getItem("TYPE")->getTrimmedString(0) );
|
||||
WellCommon::StatusEnum status = WellCommon::StatusFromString( record->getItem("STATUS")->getTrimmedString(0));
|
||||
WellCommon::StatusEnum status = WellCommon::StatusFromString( record->getItem("STATUS")->getTrimmedString(0));
|
||||
|
||||
well->setStatus( currentStep , status );
|
||||
WellInjectionProperties properties(well->getInjectionPropertiesCopy(currentStep));
|
||||
@@ -295,7 +320,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleWCONINJH(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleWCONINJH(DeckConstPtr deck, DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
const std::string& wellName = record->getItem("WELL")->getTrimmedString(0);
|
||||
@@ -326,7 +351,7 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWELOPEN(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleWELOPEN(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
const std::string& wellName = record->getItem("WELL")->getTrimmedString(0);
|
||||
@@ -343,7 +368,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleGCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleGCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
const std::string& groupName = record->getItem("GROUP")->getTrimmedString(0);
|
||||
@@ -376,7 +401,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleGCONPROD(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleGCONPROD(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
const std::string& groupName = record->getItem("GROUP")->getTrimmedString(0);
|
||||
@@ -398,7 +423,7 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleCOMPDAT(DeckKeywordConstPtr keyword , size_t currentStep) {
|
||||
void Schedule::handleCOMPDAT(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
std::map<std::string , std::vector< CompletionPtr> > completionMapList = Completion::completionsFromCOMPDATKeyword( keyword );
|
||||
std::map<std::string , std::vector< CompletionPtr> >::iterator iter;
|
||||
|
||||
@@ -409,7 +434,7 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWGRUPCON(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleWGRUPCON(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
DeckRecordConstPtr record = keyword->getRecord(recordNr);
|
||||
const std::string& wellName = record->getItem("WELL")->getTrimmedString(0);
|
||||
@@ -430,7 +455,7 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleGRUPTREE(DeckKeywordConstPtr keyword, size_t currentStep) {
|
||||
void Schedule::handleGRUPTREE(DeckKeywordConstPtr keyword, ParserLogPtr /*parserLog*/, size_t currentStep) {
|
||||
GroupTreePtr currentTree = m_rootGroupTree->get(currentStep);
|
||||
GroupTreePtr newTree = currentTree->deepCopy();
|
||||
for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
@@ -39,7 +40,7 @@ namespace Opm
|
||||
|
||||
class Schedule {
|
||||
public:
|
||||
Schedule(DeckConstPtr deck);
|
||||
Schedule(DeckConstPtr deck, ParserLogPtr parserLog=std::make_shared<ParserLog>());
|
||||
boost::posix_time::ptime getStartTime() const
|
||||
{ return m_timeMap->getStartTime(/*timeStepIdx=*/0); }
|
||||
TimeMapConstPtr getTimeMap() const;
|
||||
@@ -63,28 +64,28 @@ namespace Opm
|
||||
std::shared_ptr<DynamicState<GroupTreePtr> > m_rootGroupTree;
|
||||
|
||||
void addWellToGroup( GroupPtr newGroup , WellPtr well , size_t timeStep);
|
||||
void initFromDeck(DeckConstPtr deck);
|
||||
void createTimeMap(DeckConstPtr deck);
|
||||
void initFromDeck(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void createTimeMap(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
void initRootGroupTreeNode(TimeMapConstPtr timeMap);
|
||||
void iterateScheduleSection(DeckConstPtr deck);
|
||||
void iterateScheduleSection(DeckConstPtr deck, ParserLogPtr parserLog);
|
||||
bool handleGroupFromWELSPECS(const std::string& groupName, GroupTreePtr newTree) const;
|
||||
void addGroup(const std::string& groupName , 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);
|
||||
void handleWCONPROD(DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleWGRUPCON(DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleCOMPDAT(DeckKeywordConstPtr keyword , size_t currentStep);
|
||||
void handleWCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleWCONINJH(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleWELOPEN(DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleGCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleGCONPROD(DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void handleDATES(DeckKeywordConstPtr keyword);
|
||||
void handleTSTEP(DeckKeywordConstPtr keyword);
|
||||
void handleGRUPTREE(DeckKeywordConstPtr keyword, size_t currentStep);
|
||||
void checkWELSPECSConsistency(WellConstPtr well, DeckKeywordConstPtr keyword, size_t recordIdx, ParserLogPtr parserLog) const;
|
||||
void handleWELSPECS(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleWCONProducer(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep, bool isPredictionMode);
|
||||
void handleWCONHIST(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleWCONPROD(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleWGRUPCON(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleCOMPDAT(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleWCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleWCONINJH(DeckConstPtr deck, DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleWELOPEN(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleGCONINJE(DeckConstPtr deck, DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleGCONPROD(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
void handleDATES(DeckKeywordConstPtr keyword, ParserLogPtr parserLog);
|
||||
void handleTSTEP(DeckKeywordConstPtr keyword, ParserLogPtr parserLog);
|
||||
void handleGRUPTREE(DeckKeywordConstPtr keyword, ParserLogPtr parserLog, size_t currentStep);
|
||||
|
||||
double convertInjectionRateToSI(double rawRate, WellInjector::TypeEnum wellType, const Opm::UnitSystem &unitSystem) const;
|
||||
double convertInjectionRateToSI(double rawRate, Phase::PhaseEnum wellPhase, const Opm::UnitSystem &unitSystem) const;
|
||||
|
||||
47
opm/parser/eclipse/EclipseState/checkDeck.cpp
Normal file
47
opm/parser/eclipse/EclipseState/checkDeck.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2014 Andreas Lauser
|
||||
|
||||
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 "checkDeck.hpp"
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Section.hpp>
|
||||
|
||||
namespace Opm {
|
||||
bool checkDeck(DeckConstPtr deck, ParserLogPtr parserLog, size_t enabledChecks) {
|
||||
bool deckValid = true;
|
||||
|
||||
// make sure that the deck does not contain unknown keywords
|
||||
if (enabledChecks & UnknownKeywords) {
|
||||
size_t keywordIdx = 0;
|
||||
for (; keywordIdx < deck->size(); keywordIdx++) {
|
||||
const auto& keyword = deck->getKeyword(keywordIdx);
|
||||
if (!keyword->hasParserKeyword()) {
|
||||
std::string msg("Keyword '" + keyword->name() + "' is unknown.");
|
||||
parserLog->addWarning(keyword->getFileName(), keyword->getLineNumber(), msg);
|
||||
deckValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure all mandatory sections are present and that their order is correct
|
||||
if (enabledChecks & SectionTopology) {
|
||||
deckValid = deckValid && Section::checkSectionTopology(deck, parserLog);
|
||||
}
|
||||
|
||||
return deckValid;
|
||||
}
|
||||
}
|
||||
43
opm/parser/eclipse/EclipseState/checkDeck.hpp
Normal file
43
opm/parser/eclipse/EclipseState/checkDeck.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2014 Andreas Lauser
|
||||
|
||||
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_CHECK_DECK_HPP
|
||||
#define OPM_CHECK_DECK_HPP
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
|
||||
namespace Opm {
|
||||
enum DeckChecks {
|
||||
SectionTopology = 0x0001,
|
||||
|
||||
// KeywordSection check only has an effect of the SectionTopology test is enabled
|
||||
KeywordSection = 0x0002,
|
||||
|
||||
UnknownKeywords = 0x0004,
|
||||
|
||||
AllChecks = 0xffff
|
||||
};
|
||||
|
||||
// some semantical correctness checks of the deck. this method adds a warning to
|
||||
// the deck object if any issue is found ...
|
||||
bool checkDeck(DeckConstPtr deck, ParserLogPtr parserLog, size_t enabledChecks = AllChecks);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/checkDeck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckIntItem.hpp>
|
||||
@@ -122,14 +123,16 @@ static DeckPtr createDeckNoFaults() {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(StrictSemantics) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
|
||||
BOOST_CHECK_THROW(EclipseState(deck, /*beStrict=*/true), std::invalid_argument);
|
||||
// the deck misses a few sections...
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
BOOST_CHECK(!checkDeck(deck, parserLog));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CreatSchedule) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
ScheduleConstPtr schedule = state.getSchedule();
|
||||
EclipseGridConstPtr eclipseGrid = state.getEclipseGrid();
|
||||
|
||||
@@ -140,7 +143,7 @@ BOOST_AUTO_TEST_CASE(CreatSchedule) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PhasesCorrect) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
|
||||
BOOST_CHECK( state.hasPhase( Phase::PhaseEnum::OIL ));
|
||||
BOOST_CHECK( state.hasPhase( Phase::PhaseEnum::GAS ));
|
||||
@@ -150,7 +153,7 @@ BOOST_AUTO_TEST_CASE(PhasesCorrect) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TitleCorrect) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
|
||||
BOOST_CHECK_EQUAL( state.getTitle(), "The title");
|
||||
}
|
||||
@@ -158,7 +161,7 @@ BOOST_AUTO_TEST_CASE(TitleCorrect) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(IntProperties) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
|
||||
BOOST_CHECK_EQUAL( false , state.supportsGridProperty("NONO"));
|
||||
BOOST_CHECK_EQUAL( true , state.supportsGridProperty("SATNUM"));
|
||||
@@ -169,16 +172,18 @@ BOOST_AUTO_TEST_CASE(IntProperties) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PropertiesNotSupportedThrows) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
EclipseState state(deck);
|
||||
DeckKeywordConstPtr swat = deck->getKeyword("SWAT");
|
||||
BOOST_CHECK_EQUAL( false , state.supportsGridProperty("SWAT"));
|
||||
BOOST_CHECK_THROW( state.loadGridPropertyFromDeckKeyword( std::make_shared<const Box>(10,10,10) , swat ) , std::invalid_argument)
|
||||
state.loadGridPropertyFromDeckKeyword(std::make_shared<const Box>(10,10,10), swat, parserLog);
|
||||
BOOST_CHECK(parserLog->numErrors() > 0);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetProperty) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
|
||||
std::shared_ptr<GridProperty<int> > satNUM = state.getIntGridProperty( "SATNUM" );
|
||||
|
||||
@@ -192,7 +197,7 @@ BOOST_AUTO_TEST_CASE(GetProperty) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetTransMult) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
std::shared_ptr<const TransMult> transMult = state.getTransMult();
|
||||
|
||||
|
||||
@@ -204,7 +209,7 @@ BOOST_AUTO_TEST_CASE(GetTransMult) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetFaults) {
|
||||
DeckPtr deck = createDeck();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
std::shared_ptr<const FaultCollection> faults = state.getFaults();
|
||||
|
||||
BOOST_CHECK( faults->hasFault("F1") );
|
||||
@@ -225,7 +230,7 @@ BOOST_AUTO_TEST_CASE(GetFaults) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FaceTransMults) {
|
||||
DeckPtr deck = createDeckNoFaults();
|
||||
EclipseState state(deck, /*beStrict=*/false);
|
||||
EclipseState state(deck);
|
||||
std::shared_ptr<const TransMult> transMult = state.getTransMult();
|
||||
|
||||
for (int i = 0; i < 10; ++ i) {
|
||||
|
||||
@@ -29,20 +29,21 @@
|
||||
using namespace Opm;
|
||||
|
||||
// forward declaration to avoid a pedantic compiler warning
|
||||
EclipseState makeState(const std::string& fileName);
|
||||
EclipseState makeState(const std::string& fileName, ParserLogPtr parserLog);
|
||||
|
||||
EclipseState makeState(const std::string& fileName) {
|
||||
EclipseState makeState(const std::string& fileName, ParserLogPtr parserLog) {
|
||||
ParserPtr parser(new Parser( ));
|
||||
boost::filesystem::path boxFile(fileName);
|
||||
DeckPtr deck = parser->parseFile(boxFile.string() , false);
|
||||
EclipseState state(deck);
|
||||
EclipseState state(deck, parserLog);
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( PARSE_BOX_OK ) {
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1");
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1", parserLog);
|
||||
std::shared_ptr<GridProperty<int> > satnum = state.getIntGridProperty("SATNUM");
|
||||
{
|
||||
size_t i,j,k;
|
||||
@@ -66,7 +67,8 @@ BOOST_AUTO_TEST_CASE( PARSE_BOX_OK ) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( PARSE_MULTIPLY_COPY ) {
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1");
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1", parserLog);
|
||||
std::shared_ptr<GridProperty<int> > satnum = state.getIntGridProperty("SATNUM");
|
||||
std::shared_ptr<GridProperty<int> > fipnum = state.getIntGridProperty("FIPNUM");
|
||||
size_t i,j,k;
|
||||
@@ -89,11 +91,15 @@ BOOST_AUTO_TEST_CASE( PARSE_MULTIPLY_COPY ) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( INCOMPLETE_KEYWORD_BOX) {
|
||||
BOOST_CHECK_THROW( makeState("testdata/integration_tests/BOX/BOXTEST2") , std::invalid_argument);
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
makeState("testdata/integration_tests/BOX/BOXTEST2", parserLog);
|
||||
parserLog->printAll();
|
||||
BOOST_CHECK(parserLog->numErrors() > 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( EQUAL ) {
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1");
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1", parserLog);
|
||||
std::shared_ptr<GridProperty<int> > pvtnum = state.getIntGridProperty("PVTNUM");
|
||||
std::shared_ptr<GridProperty<int> > eqlnum = state.getIntGridProperty("EQLNUM");
|
||||
size_t i,j,k;
|
||||
@@ -114,7 +120,8 @@ BOOST_AUTO_TEST_CASE( EQUAL ) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( PERMX ) {
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1");
|
||||
ParserLogPtr parserLog(new ParserLog());
|
||||
EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1", parserLog);
|
||||
std::shared_ptr<GridProperty<double> > permx = state.getDoubleGridProperty("PERMX");
|
||||
std::shared_ptr<GridProperty<double> > permy = state.getDoubleGridProperty("PERMY");
|
||||
std::shared_ptr<GridProperty<double> > permz = state.getDoubleGridProperty("PERMZ");
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
add_definitions( -DKEYWORD_DIRECTORY="${PROJECT_SOURCE_DIR}/opm/parser/share/keywords")
|
||||
|
||||
add_executable(runCheckDeckValidity CheckDeckValidity.cpp)
|
||||
target_link_libraries(runCheckDeckValidity Parser ${Boost_LIBRARIES})
|
||||
add_test(NAME runCheckDeckValidity WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMAND ${TEST_MEMCHECK_TOOL} ${EXECUTABLE_OUTPUT_PATH}/runCheckDeckValidity)
|
||||
|
||||
add_executable(runIntegrationTests IntegrationTests.cpp)
|
||||
target_link_libraries(runIntegrationTests Parser ${Boost_LIBRARIES})
|
||||
add_test(NAME runIntegrationTests WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} COMMAND ${TEST_MEMCHECK_TOOL} ${EXECUTABLE_OUTPUT_PATH}/runIntegrationTests)
|
||||
|
||||
100
opm/parser/eclipse/IntegrationTests/CheckDeckValidity.cpp
Normal file
100
opm/parser/eclipse/IntegrationTests/CheckDeckValidity.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright 2014 Andreas Lauser
|
||||
|
||||
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 ParserIntegrationTests
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/checkDeck.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( KeywordInCorrectSection ) {
|
||||
Opm::ParserConstPtr parser(new Opm::Parser);
|
||||
|
||||
{
|
||||
const char *correctDeckString =
|
||||
"RUNSPEC\n"
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"GRID\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"BOX\n"
|
||||
"1 3 1 3 1 3 /\n"
|
||||
"PROPS\n"
|
||||
"SOLUTION\n"
|
||||
"SCHEDULE\n";
|
||||
|
||||
auto deck = parser->parseString(correctDeckString);
|
||||
Opm::ParserLogPtr parserLog(new Opm::ParserLog());
|
||||
BOOST_CHECK(Opm::checkDeck(deck, parserLog));
|
||||
}
|
||||
|
||||
{
|
||||
// wrong section ordering
|
||||
const char *correctDeckString =
|
||||
"GRID\n"
|
||||
"RUNSPEC\n"
|
||||
"PROPS\n"
|
||||
"SOLUTION\n"
|
||||
"SCHEDULE\n";
|
||||
|
||||
auto deck = parser->parseString(correctDeckString);
|
||||
Opm::ParserLogPtr parserLog(new Opm::ParserLog());
|
||||
BOOST_CHECK(!Opm::checkDeck(deck, parserLog));
|
||||
BOOST_CHECK(Opm::checkDeck(deck, parserLog, ~Opm::SectionTopology));
|
||||
}
|
||||
|
||||
{
|
||||
// deck contains an unknown keyword "FOO"
|
||||
const char *incorrectDeckString =
|
||||
"RUNSPEC\n"
|
||||
"FOO\n"
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"GRID\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"PROPS\n"
|
||||
"SOLUTION\n"
|
||||
"SCHEDULE\n";
|
||||
|
||||
auto deck = parser->parseString(incorrectDeckString, /*strict=*/false);
|
||||
Opm::ParserLogPtr parserLog(new Opm::ParserLog());
|
||||
BOOST_CHECK(!Opm::checkDeck(deck, parserLog));
|
||||
|
||||
// this is supposed to succeed as we ensure everything except that all keywords
|
||||
// are known
|
||||
BOOST_CHECK(Opm::checkDeck(deck, parserLog, ~Opm::UnknownKeywords));
|
||||
}
|
||||
}
|
||||
@@ -52,8 +52,8 @@ BOOST_AUTO_TEST_CASE( parse_ACTION_OK ) {
|
||||
|
||||
BOOST_REQUIRE_THROW( parser->parseFile( actionFile2.string() , false) , std::invalid_argument );
|
||||
|
||||
|
||||
DeckPtr deck = parser->parseFile(actionFile.string() , false);
|
||||
ParserLogPtr parserLog(new ParserLog);
|
||||
DeckPtr deck = parser->parseFile(actionFile.string() , false, parserLog);
|
||||
DeckKeywordConstPtr kw1 = deck->getKeyword("WCONHIST" , 0);
|
||||
BOOST_CHECK_EQUAL( 3U , kw1->size() );
|
||||
|
||||
@@ -76,18 +76,14 @@ BOOST_AUTO_TEST_CASE( parse_ACTION_OK ) {
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( false , deck->hasKeyword( "DIMENS" ));
|
||||
BOOST_CHECK_EQUAL( 2U , deck->numWarnings() );
|
||||
BOOST_CHECK_EQUAL( 2U , parserLog->size() );
|
||||
{
|
||||
const std::pair<std::string,std::pair<std::string,size_t> >& warning = deck->getWarning( 0 );
|
||||
const std::pair<std::string,size_t>& location = warning.second;
|
||||
BOOST_CHECK_EQUAL( actionFile.string() , location.first);
|
||||
BOOST_CHECK_EQUAL( 2U , location.second);
|
||||
BOOST_CHECK_EQUAL( actionFile.string() , parserLog->getFileName(0));
|
||||
BOOST_CHECK_EQUAL( 2U , parserLog->getLineNumber(0));
|
||||
}
|
||||
{
|
||||
const std::pair<std::string,std::pair<std::string,size_t> >& warning = deck->getWarning( 1 );
|
||||
const std::pair<std::string,size_t>& location = warning.second;
|
||||
BOOST_CHECK_EQUAL( actionFile.string() , location.first);
|
||||
BOOST_CHECK_EQUAL( 6U , location.second);
|
||||
BOOST_CHECK_EQUAL( actionFile.string() , parserLog->getFileName(1));
|
||||
BOOST_CHECK_EQUAL( 6U , parserLog->getLineNumber(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
|
||||
#include <opm/parser/eclipse/RawDeck/RawConsts.hpp>
|
||||
#include <opm/parser/eclipse/RawDeck/RawEnums.hpp>
|
||||
@@ -30,6 +31,7 @@ namespace Opm {
|
||||
|
||||
struct ParserState {
|
||||
DeckPtr deck;
|
||||
ParserLog parserLog;
|
||||
boost::filesystem::path dataFile;
|
||||
boost::filesystem::path rootPath;
|
||||
std::map<std::string, std::string> pathMap;
|
||||
@@ -87,30 +89,42 @@ namespace Opm {
|
||||
is retained in the current implementation.
|
||||
*/
|
||||
|
||||
DeckPtr Parser::parseFile(const std::string &dataFileName, bool strictParsing) const {
|
||||
DeckPtr Parser::parseFile(const std::string &dataFileName, bool strictParsing, ParserLogPtr parserLog) const {
|
||||
|
||||
std::shared_ptr<ParserState> parserState(new ParserState(dataFileName, DeckPtr(new Deck()), getRootPathFromFile(dataFileName), strictParsing));
|
||||
|
||||
parseStream(parserState);
|
||||
applyUnitsToDeck(parserState->deck);
|
||||
|
||||
if (parserLog)
|
||||
*parserLog = parserState->parserLog;
|
||||
|
||||
return parserState->deck;
|
||||
}
|
||||
|
||||
DeckPtr Parser::parseString(const std::string &data, bool strictParsing) const {
|
||||
DeckPtr Parser::parseString(const std::string &data, bool strictParsing, ParserLogPtr parserLog) const {
|
||||
|
||||
std::shared_ptr<ParserState> parserState(new ParserState(data, DeckPtr(new Deck()), strictParsing));
|
||||
|
||||
parseStream(parserState);
|
||||
applyUnitsToDeck(parserState->deck);
|
||||
|
||||
if (parserLog)
|
||||
*parserLog = parserState->parserLog;
|
||||
|
||||
return parserState->deck;
|
||||
}
|
||||
|
||||
DeckPtr Parser::parseStream(std::shared_ptr<std::istream> inputStream, bool strictParsing) const {
|
||||
DeckPtr Parser::parseStream(std::shared_ptr<std::istream> inputStream, bool strictParsing, ParserLogPtr parserLog) const {
|
||||
|
||||
std::shared_ptr<ParserState> parserState(new ParserState(inputStream, DeckPtr(new Deck()), strictParsing));
|
||||
|
||||
parseStream(parserState);
|
||||
applyUnitsToDeck(parserState->deck);
|
||||
|
||||
if (parserLog)
|
||||
*parserLog = parserState->parserLog;
|
||||
|
||||
return parserState->deck;
|
||||
}
|
||||
|
||||
@@ -277,13 +291,20 @@ namespace Opm {
|
||||
ParserKeywordActionEnum action = parserKeyword->getAction();
|
||||
if (action == INTERNALIZE) {
|
||||
DeckKeywordPtr deckKeyword = parserKeyword->parse(parserState->rawKeyword);
|
||||
deckKeyword->setParserKeyword(parserKeyword);
|
||||
parserState->deck->addKeyword(deckKeyword);
|
||||
} else if (action == IGNORE_WARNING)
|
||||
parserState->deck->addWarning( "The keyword " + parserState->rawKeyword->getKeywordName() + " is ignored - this might potentially affect the results" , parserState->dataFile.string() , parserState->rawKeyword->getLineNR());
|
||||
parserState->parserLog.addWarning(parserState->dataFile.string(),
|
||||
parserState->rawKeyword->getLineNR(),
|
||||
"The keyword " + parserState->rawKeyword->getKeywordName() + " is ignored - this might potentially affect the results");
|
||||
} else {
|
||||
DeckKeywordPtr deckKeyword(new DeckKeyword(parserState->rawKeyword->getKeywordName(), false));
|
||||
deckKeyword->setLocation(parserState->rawKeyword->getFilename(),
|
||||
parserState->rawKeyword->getLineNR());
|
||||
parserState->deck->addKeyword(deckKeyword);
|
||||
parserState->deck->addWarning( "The keyword " + parserState->rawKeyword->getKeywordName() + " is not recognized" , parserState->dataFile.string() , parserState->lineNR);
|
||||
parserState->parserLog.addWarning(parserState->dataFile.string(),
|
||||
parserState->lineNR,
|
||||
"The keyword " + parserState->rawKeyword->getKeywordName() + " is not recognized");
|
||||
}
|
||||
}
|
||||
parserState->rawKeyword.reset();
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <opm/parser/eclipse/RawDeck/RawKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserLog.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@@ -46,9 +47,9 @@ namespace Opm {
|
||||
Parser(bool addDefault = true);
|
||||
|
||||
/// The starting point of the parsing process. The supplied file is parsed, and the resulting Deck is returned.
|
||||
DeckPtr parseFile(const std::string &dataFile, bool strictParsing=true) const;
|
||||
DeckPtr parseString(const std::string &data, bool strictParsing=true) const;
|
||||
DeckPtr parseStream(std::shared_ptr<std::istream> inputStream, bool strictParsing=true) const;
|
||||
DeckPtr parseFile(const std::string &dataFile, bool strictParsing=true, ParserLogPtr parserLog = std::make_shared<ParserLog>(&std::cout)) const;
|
||||
DeckPtr parseString(const std::string &data, bool strictParsing=true, ParserLogPtr parserLog = std::make_shared<ParserLog>(&std::cout)) const;
|
||||
DeckPtr parseStream(std::shared_ptr<std::istream> inputStream, bool strictParsing=true, ParserLogPtr parserLog = std::make_shared<ParserLog>(&std::cout)) const;
|
||||
|
||||
/// Method to add ParserKeyword instances, these holding type and size information about the keywords and their data.
|
||||
void addParserKeyword(ParserKeywordConstPtr parserKeyword);
|
||||
|
||||
@@ -469,6 +469,7 @@ namespace Opm {
|
||||
DeckKeywordPtr ParserKeyword::parse(RawKeywordConstPtr rawKeyword) const {
|
||||
if (rawKeyword->isFinished()) {
|
||||
DeckKeywordPtr keyword(new DeckKeyword(rawKeyword->getKeywordName()));
|
||||
keyword->setLocation(rawKeyword->getFilename(), rawKeyword->getLineNR());
|
||||
for (size_t i = 0; i < rawKeyword->size(); i++) {
|
||||
DeckRecordConstPtr deckRecord = m_record->parse(rawKeyword->getRecord(i));
|
||||
keyword->addRecord(deckRecord);
|
||||
|
||||
157
opm/parser/eclipse/Parser/ParserLog.cpp
Normal file
157
opm/parser/eclipse/Parser/ParserLog.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
Copyright 2014 Andreas Lauser
|
||||
|
||||
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 "ParserLog.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
namespace Opm {
|
||||
ParserLog::ParserLog() {
|
||||
m_numErrors = 0;
|
||||
m_numWarnings = 0;
|
||||
m_numNotes = 0;
|
||||
|
||||
setOutStream(NULL);
|
||||
}
|
||||
|
||||
ParserLog::ParserLog(std::ostream* os) {
|
||||
m_numErrors = 0;
|
||||
m_numWarnings = 0;
|
||||
m_numNotes = 0;
|
||||
|
||||
setOutStream(os);
|
||||
}
|
||||
|
||||
void ParserLog::setOutStream(std::ostream* os) {
|
||||
m_outStream = os;
|
||||
}
|
||||
|
||||
size_t ParserLog::size() const {
|
||||
return m_messages.size();
|
||||
}
|
||||
|
||||
size_t ParserLog::numErrors() const {
|
||||
return m_numErrors;
|
||||
}
|
||||
|
||||
size_t ParserLog::numWarnings() const {
|
||||
return m_numWarnings;
|
||||
}
|
||||
|
||||
size_t ParserLog::numNotes() const {
|
||||
return m_numNotes;
|
||||
}
|
||||
|
||||
void ParserLog::addMessage(const std::string& fileName,
|
||||
int lineNumber,
|
||||
MessageType messageType,
|
||||
const std::string& description) {
|
||||
switch (messageType) {
|
||||
case Note:
|
||||
++m_numNotes;
|
||||
break;
|
||||
|
||||
case Warning:
|
||||
++m_numWarnings;
|
||||
break;
|
||||
|
||||
case Error:
|
||||
++m_numErrors;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::invalid_argument("Log messages must be of type Note, Warning or Error");
|
||||
}
|
||||
|
||||
m_messages.push_back(MessageTuple(fileName, lineNumber, messageType, description));
|
||||
|
||||
if (m_outStream) {
|
||||
(*m_outStream) << getFormattedMessage(size() - 1) << "\n";
|
||||
(*m_outStream) << (std::flush);
|
||||
}
|
||||
}
|
||||
|
||||
void ParserLog::addNote(const std::string& fileName,
|
||||
int lineNumber,
|
||||
const std::string& description) {
|
||||
addMessage(fileName, lineNumber, Note, description);
|
||||
}
|
||||
|
||||
void ParserLog::addWarning(const std::string& fileName,
|
||||
int lineNumber,
|
||||
const std::string& description) {
|
||||
addMessage(fileName, lineNumber, Warning, description);
|
||||
}
|
||||
|
||||
void ParserLog::addError(const std::string& fileName,
|
||||
int lineNumber,
|
||||
const std::string& description) {
|
||||
addMessage(fileName, lineNumber, Error, description);
|
||||
}
|
||||
|
||||
const std::string& ParserLog::getFileName(size_t msgIdx) const {
|
||||
assert(msgIdx < size());
|
||||
return std::get<0>(m_messages[msgIdx]);
|
||||
}
|
||||
|
||||
int ParserLog::getLineNumber(size_t msgIdx) const {
|
||||
assert(msgIdx < size());
|
||||
return std::get<1>(m_messages[msgIdx]);
|
||||
}
|
||||
|
||||
int ParserLog::getMessageType(size_t msgIdx) const {
|
||||
assert(msgIdx < size());
|
||||
return std::get<2>(m_messages[msgIdx]);
|
||||
}
|
||||
|
||||
const std::string& ParserLog::getDescription(size_t msgIdx) const {
|
||||
assert(msgIdx < size());
|
||||
return std::get<3>(m_messages[msgIdx]);
|
||||
}
|
||||
|
||||
const std::string ParserLog::getFormattedMessage(size_t msgIdx) const {
|
||||
std::ostringstream oss;
|
||||
if (getLineNumber(msgIdx) > 0) {
|
||||
oss << getFileName(msgIdx) << ":"
|
||||
<< getLineNumber(msgIdx) << ":";
|
||||
}
|
||||
|
||||
switch (getMessageType(msgIdx)) {
|
||||
case Note:
|
||||
oss << " note:";
|
||||
break;
|
||||
case Warning:
|
||||
oss << " warning:";
|
||||
break;
|
||||
case Error:
|
||||
oss << " error:";
|
||||
break;
|
||||
}
|
||||
oss << " " << getDescription(msgIdx);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void ParserLog::printAll(std::ostream& os, size_t enabledTypes) const {
|
||||
for (size_t i = 0; i < size(); ++i)
|
||||
if (enabledTypes & getMessageType(i))
|
||||
os << getFormattedMessage(i) << "\n";
|
||||
}
|
||||
|
||||
} // namespace Opm
|
||||
112
opm/parser/eclipse/Parser/ParserLog.hpp
Normal file
112
opm/parser/eclipse/Parser/ParserLog.hpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright 2014 Andreas Lauser
|
||||
|
||||
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_PARSER_LOG_HPP
|
||||
#define OPM_PARSER_LOG_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
namespace Opm {
|
||||
/*!
|
||||
* \brief Provides a simple sytem for log message which are found by the
|
||||
* Parser/Deck/EclipseState classes during processing the deck.
|
||||
*/
|
||||
class ParserLog {
|
||||
public:
|
||||
enum MessageType {
|
||||
Note = 0x01,
|
||||
Warning = 0x02,
|
||||
Error = 0x04,
|
||||
|
||||
AllTypes = 0xff
|
||||
};
|
||||
|
||||
ParserLog();
|
||||
ParserLog(std::ostream* os);
|
||||
|
||||
void setOutStream(std::ostream* os);
|
||||
|
||||
size_t size() const;
|
||||
size_t numErrors() const;
|
||||
size_t numWarnings() const;
|
||||
size_t numNotes() const;
|
||||
|
||||
void addMessage(const std::string& fileName,
|
||||
int lineNumber,
|
||||
MessageType messageType,
|
||||
const std::string& description);
|
||||
|
||||
void addNote(const std::string& fileName,
|
||||
int lineNumber,
|
||||
const std::string& description);
|
||||
void addWarning(const std::string& fileName,
|
||||
int lineNumber,
|
||||
const std::string& description);
|
||||
void addError(const std::string& fileName,
|
||||
int lineNumber,
|
||||
const std::string& description);
|
||||
|
||||
const std::string& getFileName(size_t msgIdx) const;
|
||||
int getLineNumber(size_t msgIdx) const;
|
||||
int getMessageType(size_t msgIdx) const;
|
||||
const std::string& getDescription(size_t msgIdx) const;
|
||||
|
||||
/*!
|
||||
* \brief This method takes the information provided by the methods above and returns
|
||||
* them in a fully-formatted string.
|
||||
*
|
||||
* It is thus covenience method to convert a log message into a GCC-like format,
|
||||
* e.g. a "Note" message triggered by the file "SPE1DECK.DATA" on line 15 which says
|
||||
* that no grid can be constructed would yield:
|
||||
*
|
||||
* SPE1DECK.DATA:15:note: No grid found.
|
||||
*/
|
||||
const std::string getFormattedMessage(size_t msgIdx) const;
|
||||
|
||||
/*!
|
||||
* \brief Print all issues described in a log object to a std::ostream.
|
||||
*
|
||||
* This is just another convenience method...
|
||||
*/
|
||||
void printAll(std::ostream &os = std::cerr,
|
||||
size_t enabledTypes = AllTypes) const;
|
||||
|
||||
private:
|
||||
typedef std::tuple</*file=*/std::string,
|
||||
/*line=*/int,
|
||||
/*MessageType=*/int,
|
||||
std::string> MessageTuple;
|
||||
std::vector<MessageTuple> m_messages;
|
||||
|
||||
size_t m_numErrors;
|
||||
size_t m_numWarnings;
|
||||
size_t m_numNotes;
|
||||
|
||||
mutable std::ostream* m_outStream;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ParserLog> ParserLogPtr;
|
||||
typedef std::shared_ptr<const ParserLog> ParserLogConstPtr;
|
||||
} // namespace Opm
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user