Merge pull request #797 from jokva/summary-config-from-eclipsestate
Summary config from eclipsestate
This commit is contained in:
@@ -49,10 +49,11 @@ namespace Opm {
|
||||
};
|
||||
|
||||
auto first = std::find_if( deck.begin(), deck.end(), fn );
|
||||
if( first == deck.end() )
|
||||
throw std::invalid_argument( std::string( "Deck requires a '" ) + keyword + "' section" );
|
||||
|
||||
auto last = std::find_if( first + 1, deck.end(), &isSectionDelimiter );
|
||||
if( first == deck.end() )
|
||||
return { first, first };
|
||||
|
||||
auto last = std::find_if( first + 1, deck.end(), isSectionDelimiter );
|
||||
|
||||
if( last != deck.end() && last->name() == keyword )
|
||||
throw std::invalid_argument( std::string( "Deck contains the '" ) + keyword + "' section multiple times" );
|
||||
|
||||
@@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(IteratorTest) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RUNSPECSection_EmptyDeck) {
|
||||
DeckPtr deck(new Deck());
|
||||
BOOST_REQUIRE_THROW(RUNSPECSection section(*deck), std::invalid_argument);
|
||||
BOOST_REQUIRE_NO_THROW(RUNSPECSection section(*deck));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RUNSPECSection_ReadSimpleDeck) {
|
||||
|
||||
@@ -449,6 +449,17 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< int > Eclipse3DProperties::getRegions( const std::string& kw ) const {
|
||||
if( !this->hasDeckIntGridProperty( kw ) ) return {};
|
||||
|
||||
const auto& property = this->getIntGridProperty( kw );
|
||||
|
||||
std::set< int > regions( property.getData().begin(),
|
||||
property.getData().end() );
|
||||
|
||||
return { regions.begin(), regions.end() };
|
||||
}
|
||||
|
||||
/// Due to the post processor which might be applied to the GridProperty
|
||||
/// objects it is essential that this method use the m_intGridProperties /
|
||||
/// m_doubleGridProperties fields directly and *NOT* use the public methods
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Opm {
|
||||
|
||||
|
||||
const GridProperty<int>& getRegion(const DeckItem& regionItem) const;
|
||||
std::vector< int > getRegions( const std::string& keyword ) const;
|
||||
std::string getDefaultRegionKeyword() const;
|
||||
|
||||
const GridProperty<int>& getIntGridProperty ( const std::string& keyword ) const;
|
||||
|
||||
@@ -49,25 +49,39 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
static IOConfig mkIOConfig( const Deck& deck ) {
|
||||
IOConfig config( deck.getDataFile() );
|
||||
|
||||
if( Section::hasGRID( deck ) )
|
||||
config.handleGridSection( GRIDSection( deck ) );
|
||||
|
||||
if( Section::hasRUNSPEC( deck ) )
|
||||
config.handleRunspecSection( RUNSPECSection( deck ) );
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
EclipseState::EclipseState(std::shared_ptr<const Deck> deckptr, ParseContext parseContext) :
|
||||
EclipseState(*deckptr, parseContext)
|
||||
{}
|
||||
|
||||
EclipseState::EclipseState(const Deck& deck, ParseContext parseContext) :
|
||||
m_deckUnitSystem( deck.getActiveUnitSystem() ),
|
||||
m_parseContext( parseContext ),
|
||||
m_ioConfig( std::make_shared< IOConfig >( mkIOConfig( deck ) ) ),
|
||||
m_tables( deck ),
|
||||
m_inputGrid( std::make_shared<EclipseGrid>(deck, nullptr)),
|
||||
m_eclipseProperties( deck, m_tables, *m_inputGrid)
|
||||
m_inputGrid( std::make_shared<EclipseGrid>(deck, nullptr) ),
|
||||
m_eclipseProperties( deck, m_tables, *m_inputGrid ),
|
||||
m_schedule( std::make_shared<Schedule>( m_parseContext, m_inputGrid, deck, m_ioConfig ) ),
|
||||
m_simulationConfig( std::make_shared<SimulationConfig>( m_parseContext, deck, m_eclipseProperties ) ),
|
||||
m_summaryConfig( deck, *m_schedule, m_eclipseProperties, m_inputGrid->getNXYZ() ),
|
||||
m_nnc( deck, m_inputGrid ),
|
||||
m_deckUnitSystem( deck.getActiveUnitSystem() )
|
||||
|
||||
{
|
||||
// after Eclipse3DProperties has been constructed, we have complete ACTNUM info
|
||||
if (m_eclipseProperties.hasDeckIntGridProperty("ACTNUM"))
|
||||
m_inputGrid->resetACTNUM(m_eclipseProperties.getIntGridProperty("ACTNUM").getData().data());
|
||||
|
||||
initIOConfig(deck);
|
||||
|
||||
m_schedule = ScheduleConstPtr(new Schedule(m_parseContext, getInputGrid(), deck, m_ioConfig));
|
||||
initIOConfigPostSchedule(deck);
|
||||
|
||||
if (deck.hasKeyword( "TITLE" )) {
|
||||
@@ -77,14 +91,9 @@ namespace Opm {
|
||||
m_title = boost::algorithm::join( itemValue, " " );
|
||||
}
|
||||
|
||||
m_initConfig = std::make_shared<const InitConfig>(deck);
|
||||
m_simulationConfig = std::make_shared<const SimulationConfig>(m_parseContext, deck,
|
||||
m_eclipseProperties);
|
||||
|
||||
initTransMult();
|
||||
initFaults(deck);
|
||||
initMULTREGT(deck);
|
||||
m_nnc = NNC(deck, getInputGrid());
|
||||
|
||||
m_messageContainer.appendMessages(m_tables.getMessageContainer());
|
||||
m_messageContainer.appendMessages(m_schedule->getMessageContainer());
|
||||
@@ -104,6 +113,10 @@ namespace Opm {
|
||||
return std::make_shared<EclipseGrid>( m_inputGrid->c_ptr() );
|
||||
}
|
||||
|
||||
const SummaryConfig& EclipseState::getSummaryConfig() const {
|
||||
return this->m_summaryConfig;
|
||||
}
|
||||
|
||||
const Eclipse3DProperties& EclipseState::get3DProperties() const {
|
||||
return m_eclipseProperties;
|
||||
}
|
||||
@@ -166,20 +179,6 @@ namespace Opm {
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void EclipseState::initIOConfig(const Deck& deck) {
|
||||
std::string dataFile = deck.getDataFile();
|
||||
m_ioConfig = std::make_shared<IOConfig>(dataFile);
|
||||
|
||||
if (Section::hasGRID(deck)) {
|
||||
auto gridSection = std::make_shared<const GRIDSection>(deck);
|
||||
m_ioConfig->handleGridSection(gridSection);
|
||||
}
|
||||
if (Section::hasRUNSPEC(deck)) {
|
||||
auto runspecSection = std::make_shared<const RUNSPECSection>(deck);
|
||||
m_ioConfig->handleRunspecSection(runspecSection);
|
||||
}
|
||||
}
|
||||
|
||||
// Hmmm - would have thought this should iterate through the SCHEDULE section as well?
|
||||
void EclipseState::initIOConfigPostSchedule(const Deck& deck) {
|
||||
if (Section::hasSOLUTION(deck)) {
|
||||
@@ -261,17 +260,6 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
std::vector< int > EclipseState::getRegions( const std::string& kw ) const {
|
||||
if( !this->get3DProperties().hasDeckIntGridProperty( kw ) ) return {};
|
||||
|
||||
const auto& property = this->get3DProperties().getIntGridProperty( kw );
|
||||
|
||||
std::set< int > regions( property.getData().begin(),
|
||||
property.getData().end() );
|
||||
|
||||
return { regions.begin(), regions.end() };
|
||||
}
|
||||
|
||||
|
||||
void EclipseState::complainAboutAmbiguousKeyword(const Deck& deck, const std::string& keywordName) {
|
||||
m_messageContainer.error("The " + keywordName + " keyword must be unique in the deck. Ignoring all!");
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
@@ -82,6 +83,7 @@ namespace Opm {
|
||||
std::shared_ptr< const SimulationConfig > getSimulationConfig() const;
|
||||
std::shared_ptr< const EclipseGrid > getInputGrid() const;
|
||||
std::shared_ptr< EclipseGrid > getInputGridCopy() const;
|
||||
const SummaryConfig& getSummaryConfig() const;
|
||||
const MessageContainer& getMessageContainer() const;
|
||||
MessageContainer& getMessageContainer();
|
||||
std::string getTitle() const;
|
||||
@@ -95,8 +97,6 @@ namespace Opm {
|
||||
|
||||
const TableManager& getTableManager() const;
|
||||
|
||||
std::vector< int > getRegions( const std::string& kw ) const;
|
||||
|
||||
// the unit system used by the deck. note that it is rarely needed to convert
|
||||
// units because internally to opm-parser everything is represented by SI
|
||||
// units...
|
||||
@@ -107,7 +107,6 @@ namespace Opm {
|
||||
void applyModifierDeck(const Deck& deck);
|
||||
|
||||
private:
|
||||
void initIOConfig(const Deck& deck);
|
||||
void initIOConfigPostSchedule(const Deck& deck);
|
||||
void initTransMult();
|
||||
void initFaults(const Deck& deck);
|
||||
@@ -118,23 +117,23 @@ namespace Opm {
|
||||
void complainAboutAmbiguousKeyword(const Deck& deck,
|
||||
const std::string& keywordName);
|
||||
|
||||
ParseContext m_parseContext;
|
||||
std::shared_ptr< IOConfig > m_ioConfig;
|
||||
std::shared_ptr< const InitConfig > m_initConfig;
|
||||
std::shared_ptr< const Schedule > m_schedule;
|
||||
const TableManager m_tables;
|
||||
std::shared_ptr<EclipseGrid> m_inputGrid;
|
||||
Eclipse3DProperties m_eclipseProperties;
|
||||
std::shared_ptr< const Schedule > m_schedule;
|
||||
std::shared_ptr< const SimulationConfig > m_simulationConfig;
|
||||
SummaryConfig m_summaryConfig;
|
||||
|
||||
std::string m_title;
|
||||
std::shared_ptr<TransMult> m_transMult;
|
||||
FaultCollection m_faults;
|
||||
NNC m_nnc;
|
||||
|
||||
|
||||
const UnitSystem& m_deckUnitSystem;
|
||||
const ParseContext m_parseContext;
|
||||
const TableManager m_tables;
|
||||
std::shared_ptr<EclipseGrid> m_inputGrid;
|
||||
Eclipse3DProperties m_eclipseProperties;
|
||||
MessageContainer m_messageContainer;
|
||||
const UnitSystem& m_deckUnitSystem;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<EclipseState> EclipseStatePtr;
|
||||
|
||||
@@ -267,6 +267,10 @@ namespace Opm {
|
||||
return m_nz;
|
||||
}
|
||||
|
||||
std::array< int, 3 > EclipseGrid::getNXYZ() const {
|
||||
return {{ int( m_nx ), int( m_ny ), int( m_nz ) }};
|
||||
}
|
||||
|
||||
size_t EclipseGrid::getCartesianSize( ) const {
|
||||
return m_nx * m_ny * m_nz;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace Opm {
|
||||
size_t getNX( ) const;
|
||||
size_t getNY( ) const;
|
||||
size_t getNZ( ) const;
|
||||
std::array< int, 3 > getNXYZ() const;
|
||||
size_t getCartesianSize( ) const;
|
||||
bool isPinchActive( ) const;
|
||||
double getPinchThresholdThickness( ) const;
|
||||
|
||||
@@ -295,11 +295,11 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void IOConfig::handleGridSection(std::shared_ptr<const GRIDSection> gridSection) {
|
||||
m_write_INIT_file = gridSection->hasKeyword("INIT");
|
||||
void IOConfig::handleGridSection( const GRIDSection& gridSection) {
|
||||
m_write_INIT_file = gridSection.hasKeyword("INIT");
|
||||
|
||||
if (gridSection->hasKeyword("GRIDFILE")) {
|
||||
const auto& gridfilekeyword = gridSection->getKeyword("GRIDFILE");
|
||||
if (gridSection.hasKeyword("GRIDFILE")) {
|
||||
const auto& gridfilekeyword = gridSection.getKeyword("GRIDFILE");
|
||||
if (gridfilekeyword.size() > 0) {
|
||||
const auto& rec = gridfilekeyword.getRecord(0);
|
||||
const auto& item1 = rec.getItem(0);
|
||||
@@ -314,17 +314,17 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gridSection->hasKeyword("NOGGF")) {
|
||||
if (gridSection.hasKeyword("NOGGF")) {
|
||||
m_write_EGRID_file = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IOConfig::handleRunspecSection(std::shared_ptr<const RUNSPECSection> runspecSection) {
|
||||
m_FMTIN = runspecSection->hasKeyword("FMTIN"); //Input files are formatted
|
||||
m_FMTOUT = runspecSection->hasKeyword("FMTOUT"); //Output files are to be formatted
|
||||
m_UNIFIN = runspecSection->hasKeyword("UNIFIN"); //Input files are unified
|
||||
m_UNIFOUT = runspecSection->hasKeyword("UNIFOUT"); //Output files are to be unified
|
||||
void IOConfig::handleRunspecSection( const RUNSPECSection& runspecSection) {
|
||||
m_FMTIN = runspecSection.hasKeyword("FMTIN"); //Input files are formatted
|
||||
m_FMTOUT = runspecSection.hasKeyword("FMTOUT"); //Output files are to be formatted
|
||||
m_UNIFIN = runspecSection.hasKeyword("UNIFIN"); //Input files are unified
|
||||
m_UNIFOUT = runspecSection.hasKeyword("UNIFOUT"); //Output files are to be unified
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,8 +142,8 @@ namespace Opm {
|
||||
bool reset_global = false);
|
||||
void handleRPTSCHEDRestart(std::shared_ptr< const TimeMap > timemap, size_t timestep, size_t restart);
|
||||
void handleSolutionSection(std::shared_ptr< const TimeMap > timemap, std::shared_ptr<const SOLUTIONSection> solutionSection);
|
||||
void handleGridSection(std::shared_ptr<const GRIDSection> gridSection);
|
||||
void handleRunspecSection(std::shared_ptr<const RUNSPECSection> runspecSection);
|
||||
void handleGridSection( const GRIDSection& );
|
||||
void handleRunspecSection( const RUNSPECSection& );
|
||||
void setWriteInitialRestartFile(bool writeInitialRestartFile);
|
||||
|
||||
/// This method will internalize variables with information of
|
||||
|
||||
@@ -209,8 +209,8 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
|
||||
IOConfigPtr ioConfigPtr;
|
||||
BOOST_CHECK_NO_THROW(ioConfigPtr = std::make_shared<IOConfig>());
|
||||
|
||||
std::shared_ptr<const GRIDSection> gridSection = std::make_shared<const GRIDSection>(*deck);
|
||||
std::shared_ptr<const RUNSPECSection> runspecSection = std::make_shared<const RUNSPECSection>(*deck);
|
||||
GRIDSection gridSection( *deck );
|
||||
RUNSPECSection runspecSection( *deck );
|
||||
ioConfigPtr->handleGridSection(gridSection);
|
||||
ioConfigPtr->handleRunspecSection(runspecSection);
|
||||
|
||||
@@ -433,8 +433,8 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
|
||||
IOConfigPtr ioConfigPtr3;
|
||||
BOOST_CHECK_NO_THROW(ioConfigPtr3 = std::make_shared<IOConfig>());
|
||||
|
||||
std::shared_ptr<const GRIDSection> gridSection3 = std::make_shared<const GRIDSection>(*deck3);
|
||||
std::shared_ptr<const RUNSPECSection> runspecSection3 = std::make_shared<const RUNSPECSection>(*deck3);
|
||||
GRIDSection gridSection3( *deck3 );
|
||||
RUNSPECSection runspecSection3( *deck3 );
|
||||
ioConfigPtr3->handleGridSection(gridSection3);
|
||||
ioConfigPtr3->handleRunspecSection(runspecSection3);
|
||||
|
||||
@@ -454,8 +454,8 @@ BOOST_AUTO_TEST_CASE(IOConfigTest) {
|
||||
IOConfigPtr ioConfigPtr4;
|
||||
BOOST_CHECK_NO_THROW(ioConfigPtr4 = std::make_shared<IOConfig>());
|
||||
|
||||
std::shared_ptr<const GRIDSection> gridSection4 = std::make_shared<const GRIDSection>(*deck4);
|
||||
std::shared_ptr<const RUNSPECSection> runspecSection4 = std::make_shared<const RUNSPECSection>(*deck4);
|
||||
GRIDSection gridSection4( *deck4 );
|
||||
RUNSPECSection runspecSection4( *deck4 );
|
||||
ioConfigPtr4->handleGridSection(gridSection4);
|
||||
ioConfigPtr4->handleRunspecSection(runspecSection4);
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/SegmentSet.hpp>
|
||||
@@ -46,11 +45,7 @@ namespace Opm {
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<CompsegsPtr> Compsegs::compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword,
|
||||
EclipseGridConstPtr grid) {
|
||||
// the thickness of grid cells will be required in the future for more complete support.
|
||||
// Silence warning about unused argument
|
||||
static_cast<void>(grid);
|
||||
std::vector<CompsegsPtr> Compsegs::compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword ) {
|
||||
|
||||
// only handle the second record here
|
||||
// The first record here only contains the well name
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace Opm {
|
||||
|
||||
class CompletionSet;
|
||||
class DeckKeyword;
|
||||
class EclipseGrid;
|
||||
class SegmentSet;
|
||||
|
||||
struct Compsegs {
|
||||
@@ -53,8 +52,7 @@ namespace Opm {
|
||||
Compsegs(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
|
||||
WellCompletion::DirectionEnum dir_in, double center_depth_in, int segment_number_in);
|
||||
|
||||
static std::vector<std::shared_ptr<Compsegs>> compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword,
|
||||
std::shared_ptr< const EclipseGrid > grid);
|
||||
static std::vector<std::shared_ptr<Compsegs>> compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword );
|
||||
|
||||
// get the segment number information and depth information based on the information from SegmentSet
|
||||
static void processCOMPSEGS(std::vector<std::shared_ptr<Compsegs>>& compsegs, std::shared_ptr< const SegmentSet > segment_set);
|
||||
|
||||
@@ -1312,7 +1312,7 @@ namespace Opm {
|
||||
const std::string& well_name = record1.getItem("WELL").getTrimmedString(0);
|
||||
WellPtr well = getWell(well_name);
|
||||
|
||||
std::vector<CompsegsPtr> compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword(keyword, m_grid);
|
||||
std::vector<CompsegsPtr> compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword( keyword );
|
||||
|
||||
SegmentSetConstPtr current_segmentSet = well->getSegmentSet(currentStep);
|
||||
Compsegs::processCOMPSEGS(compsegs_vector, current_segmentSet);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Section.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
|
||||
@@ -38,6 +39,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@@ -52,30 +54,29 @@ namespace Opm {
|
||||
static inline std::vector< ERT::smspec_node > keywordWG(
|
||||
ecl_smspec_var_type var_type,
|
||||
const DeckKeyword& keyword,
|
||||
const EclipseState& es ) {
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto mknode = [&keyword,var_type]( const std::string& name ) {
|
||||
return ERT::smspec_node( var_type, name, keyword.name() );
|
||||
};
|
||||
|
||||
const auto find = []( ecl_smspec_var_type v, const EclipseState& est ) {
|
||||
const auto find = []( ecl_smspec_var_type v, const Schedule& sc ) {
|
||||
if( v == ECL_SMSPEC_WELL_VAR )
|
||||
return fun::map( wellName, est.getSchedule()->getWells() );
|
||||
return fun::map( wellName, sc.getWells() );
|
||||
else
|
||||
return fun::map( groupName, est.getSchedule()->getGroups() );
|
||||
return fun::map( groupName, sc.getGroups() );
|
||||
};
|
||||
|
||||
const auto& item = keyword.getDataRecord().getDataItem();
|
||||
const auto wgnames = item.size() > 0 && item.hasValue( 0 )
|
||||
? item.getData< std::string >()
|
||||
: find( var_type, es );
|
||||
: find( var_type, schedule );
|
||||
|
||||
return fun::map( mknode, wgnames );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordF(
|
||||
const DeckKeyword& keyword,
|
||||
const EclipseState& /* es */ ) {
|
||||
const DeckKeyword& keyword ) {
|
||||
|
||||
std::vector< ERT::smspec_node > res;
|
||||
res.push_back( ERT::smspec_node( keyword.name() ) );
|
||||
@@ -106,11 +107,9 @@ namespace Opm {
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordB(
|
||||
const DeckKeyword& keyword,
|
||||
const EclipseState& es ) {
|
||||
std::array< int, 3 > dims ) {
|
||||
|
||||
auto dims = dimensions( *es.getInputGrid() );
|
||||
|
||||
const auto mkrecord = [&dims,&keyword]( const DeckRecord& record ) {
|
||||
const auto mkrecord = [dims,&keyword]( const DeckRecord& record ) {
|
||||
auto ijk = getijk( record );
|
||||
return ERT::smspec_node( keyword.name(), dims.data(), ijk.data() );
|
||||
};
|
||||
@@ -120,36 +119,40 @@ namespace Opm {
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordR(
|
||||
const DeckKeyword& keyword,
|
||||
const EclipseState& es ) {
|
||||
const Eclipse3DProperties& props,
|
||||
std::array< int, 3 > dims ) {
|
||||
|
||||
auto dims = dimensions( *es.getInputGrid() );
|
||||
/* RUNSUM is not a region keyword but a directive for how to format and
|
||||
* print output. Unfortunately its *recognised* as a region keyword
|
||||
* because of its structure and position. Hence the special handling of ignoring it.
|
||||
*/
|
||||
if( keyword.name() == "RUNSUM" ) return {};
|
||||
|
||||
const auto mknode = [&dims,&keyword]( int region ) {
|
||||
const auto mknode = [dims,&keyword]( int region ) {
|
||||
return ERT::smspec_node( keyword.name(), dims.data(), region );
|
||||
};
|
||||
|
||||
const auto& item = keyword.getDataRecord().getDataItem();
|
||||
const auto regions = item.size() > 0 && item.hasValue( 0 )
|
||||
? item.getData< int >()
|
||||
: es.getRegions( "FIPNUM" );
|
||||
: props.getRegions( "FIPNUM" );
|
||||
|
||||
return fun::map( mknode, regions );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordC(
|
||||
const DeckKeyword& keyword,
|
||||
const EclipseState& es ) {
|
||||
const Schedule& schedule,
|
||||
std::array< int, 3 > dims ) {
|
||||
|
||||
std::vector< ERT::smspec_node > nodes;
|
||||
const auto& keywordstring = keyword.name();
|
||||
const auto& schedule = es.getSchedule();
|
||||
const auto last_timestep = schedule->getTimeMap()->last();
|
||||
auto dims = dimensions( *es.getInputGrid() );
|
||||
const auto last_timestep = schedule.getTimeMap()->last();
|
||||
|
||||
for( const auto& record : keyword ) {
|
||||
|
||||
if( record.getItem( 0 ).defaultApplied( 0 ) ) {
|
||||
for( const auto& well : schedule->getWells() ) {
|
||||
for( const auto& well : schedule.getWells() ) {
|
||||
|
||||
const auto& name = wellName( well );
|
||||
|
||||
@@ -178,7 +181,7 @@ namespace Opm {
|
||||
}
|
||||
else {
|
||||
/* well specified, block coordinates defaulted */
|
||||
for( const auto& completion : *schedule->getWell( name ).getCompletions( last_timestep ) ) {
|
||||
for( const auto& completion : *schedule.getWell( name ).getCompletions( last_timestep ) ) {
|
||||
auto ijk = getijk( *completion );
|
||||
nodes.emplace_back( keywordstring, name, dims.data(), ijk.data() );
|
||||
}
|
||||
@@ -189,27 +192,40 @@ namespace Opm {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
std::vector< ERT::smspec_node > handleKW( const DeckKeyword& keyword, const EclipseState& es ) {
|
||||
std::vector< ERT::smspec_node > handleKW( const DeckKeyword& keyword,
|
||||
const Schedule& schedule,
|
||||
const Eclipse3DProperties& props,
|
||||
std::array< int, 3 > n_xyz ) {
|
||||
const auto var_type = ecl_smspec_identify_var_type( keyword.name().c_str() );
|
||||
|
||||
switch( var_type ) {
|
||||
case ECL_SMSPEC_WELL_VAR: /* intentional fall-through */
|
||||
case ECL_SMSPEC_GROUP_VAR: return keywordWG( var_type, keyword, es );
|
||||
case ECL_SMSPEC_FIELD_VAR: return keywordF( keyword, es );
|
||||
case ECL_SMSPEC_BLOCK_VAR: return keywordB( keyword, es );
|
||||
case ECL_SMSPEC_REGION_VAR: return keywordR( keyword, es );
|
||||
case ECL_SMSPEC_COMPLETION_VAR: return keywordC( keyword, es );
|
||||
case ECL_SMSPEC_GROUP_VAR: return keywordWG( var_type, keyword, schedule );
|
||||
case ECL_SMSPEC_FIELD_VAR: return keywordF( keyword );
|
||||
case ECL_SMSPEC_BLOCK_VAR: return keywordB( keyword, n_xyz );
|
||||
case ECL_SMSPEC_REGION_VAR: return keywordR( keyword, props, n_xyz );
|
||||
case ECL_SMSPEC_COMPLETION_VAR: return keywordC( keyword, schedule, n_xyz );
|
||||
|
||||
default: return {};
|
||||
}
|
||||
}
|
||||
|
||||
SummaryConfig::SummaryConfig( const Deck& deck, const EclipseState& es ) {
|
||||
SummaryConfig::SummaryConfig( const Deck& deck, const EclipseState& es )
|
||||
: SummaryConfig( deck,
|
||||
*es.getSchedule(),
|
||||
es.get3DProperties(),
|
||||
dimensions( *es.getInputGrid() ) )
|
||||
{}
|
||||
|
||||
SummaryConfig::SummaryConfig( const Deck& deck,
|
||||
const Schedule& schedule,
|
||||
const Eclipse3DProperties& props,
|
||||
std::array< int, 3 > n_xyz ) {
|
||||
|
||||
SUMMARYSection section( deck );
|
||||
const auto handler = [&es]( const DeckKeyword& kw ) {
|
||||
return handleKW( kw, es );
|
||||
};
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto handler = std::bind( handleKW, _1, schedule, props, n_xyz );
|
||||
this->keywords = fun::concat( fun::map( handler, section ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef OPM_SUMMARY_CONFIG_HPP
|
||||
#define OPM_SUMMARY_CONFIG_HPP
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include <ert/ecl/Smspec.hpp>
|
||||
@@ -27,14 +28,20 @@
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class Eclipse3DProperties;
|
||||
class EclipseState;
|
||||
class ParserKeyword;
|
||||
class Schedule;
|
||||
|
||||
class SummaryConfig {
|
||||
public:
|
||||
typedef std::vector< ERT::smspec_node >::const_iterator const_iterator;
|
||||
|
||||
SummaryConfig( const Deck&, const EclipseState& );
|
||||
SummaryConfig( const Deck&, const Schedule&,
|
||||
const Eclipse3DProperties&, std::array< int, 3 > );
|
||||
SummaryConfig( const Deck&, const Schedule&,
|
||||
const Eclipse3DProperties&, int, int, int );
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
@@ -235,3 +235,31 @@ BOOST_AUTO_TEST_CASE(PermxUnitAppliedCorrectly) {
|
||||
BOOST_CHECK_CLOSE(4 * Opm::Metric::Permeability, permx.iget(i, j, 0), 0.0001);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(getRegions) {
|
||||
const char* input =
|
||||
"START -- 0 \n"
|
||||
"10 MAI 2007 / \n"
|
||||
"RUNSPEC\n"
|
||||
"\n"
|
||||
"DIMENS\n"
|
||||
" 2 2 1 /\n"
|
||||
"GRID\n"
|
||||
"DXV \n 2*400 /\n"
|
||||
"DYV \n 2*400 /\n"
|
||||
"DZV \n 1*400 /\n"
|
||||
"REGIONS\n"
|
||||
"FIPNUM\n"
|
||||
"1 1 2 3 /\n";
|
||||
|
||||
auto deck = Opm::Parser().parseString(input, Opm::ParseContext());
|
||||
Setup s( deck );
|
||||
|
||||
std::vector< int > ref = { 1, 2, 3 };
|
||||
const auto regions = s.props.getRegions( "FIPNUM" );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( ref.begin(), ref.end(),
|
||||
regions.begin(), regions.end() );
|
||||
|
||||
BOOST_CHECK( s.props.getRegions( "EQLNUM" ).empty() );
|
||||
}
|
||||
|
||||
@@ -584,31 +584,3 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTSOL) {
|
||||
BOOST_CHECK_EQUAL(true, ioConfig->getWriteRestartFile(0));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(getRegions) {
|
||||
const char* input =
|
||||
"START -- 0 \n"
|
||||
"10 MAI 2007 / \n"
|
||||
"RUNSPEC\n"
|
||||
"\n"
|
||||
"DIMENS\n"
|
||||
" 2 2 1 /\n"
|
||||
"GRID\n"
|
||||
"DXV \n 2*400 /\n"
|
||||
"DYV \n 2*400 /\n"
|
||||
"DZV \n 1*400 /\n"
|
||||
"REGIONS\n"
|
||||
"FIPNUM\n"
|
||||
"1 1 2 3 /\n";
|
||||
|
||||
const auto deck = Parser().parseString(input, ParseContext());
|
||||
EclipseState es( deck, ParseContext() );
|
||||
|
||||
std::vector< int > ref = { 1, 2, 3 };
|
||||
const auto regions = es.getRegions( "FIPNUM" );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( ref.begin(), ref.end(),
|
||||
regions.begin(), regions.end() );
|
||||
|
||||
BOOST_CHECK( es.getRegions( "EQLNUM" ).empty() );
|
||||
}
|
||||
|
||||
@@ -237,7 +237,83 @@ namespace Opm {
|
||||
const double Timestep = day;
|
||||
}
|
||||
|
||||
namespace conversions {
|
||||
/*
|
||||
* It is VERY important that the dim enum has the same order as the
|
||||
* metric and field arrays. C++ does not support designated initializers, so
|
||||
* this cannot be done in a declaration-order independent matter.
|
||||
*/
|
||||
|
||||
enum class dim : int {
|
||||
length,
|
||||
time,
|
||||
density,
|
||||
pressure,
|
||||
temperature_absolute,
|
||||
temperature,
|
||||
viscosity,
|
||||
permeability,
|
||||
liquid_surface_volume,
|
||||
gas_surface_volume,
|
||||
volume,
|
||||
liquid_surface_rate,
|
||||
gas_surface_rate,
|
||||
rate,
|
||||
transmissibility,
|
||||
mass,
|
||||
};
|
||||
|
||||
/* lookup tables for SI-to-unit system
|
||||
*
|
||||
* We assume that all values in the report structures are plain SI units,
|
||||
* but output can be configured to use other (inconsistent) unit systems.
|
||||
* These lookup tables are passed to the convert function that translates
|
||||
* between SI and the target unit.
|
||||
*/
|
||||
|
||||
const double si2metric[] = {
|
||||
1 / Metric::Length,
|
||||
1 / Metric::Time,
|
||||
1 / Metric::Density,
|
||||
1 / Metric::Pressure,
|
||||
1 / Metric::AbsoluteTemperature,
|
||||
1 / Metric::Temperature,
|
||||
1 / Metric::Viscosity,
|
||||
1 / Metric::Permeability,
|
||||
1 / Metric::LiquidSurfaceVolume,
|
||||
1 / Metric::GasSurfaceVolume,
|
||||
1 / Metric::ReservoirVolume,
|
||||
1 / ( Metric::LiquidSurfaceVolume / Metric::Time ),
|
||||
1 / ( Metric::GasSurfaceVolume / Metric::Time ),
|
||||
1 / ( Metric::ReservoirVolume / Metric::Time ),
|
||||
1 / Metric::Transmissibility,
|
||||
1 / Metric::Mass,
|
||||
};
|
||||
|
||||
const double si2field[] = {
|
||||
1 / Field::Length,
|
||||
1 / Field::Time,
|
||||
1 / Field::Density,
|
||||
1 / Field::Pressure,
|
||||
1 / Field::AbsoluteTemperature,
|
||||
1 / Field::Temperature,
|
||||
1 / Field::Viscosity,
|
||||
1 / Field::Permeability,
|
||||
1 / Field::LiquidSurfaceVolume,
|
||||
1 / Field::GasSurfaceVolume,
|
||||
1 / Field::ReservoirVolume,
|
||||
1 / ( Field::LiquidSurfaceVolume / Field::Time ),
|
||||
1 / ( Field::GasSurfaceVolume / Field::Time ),
|
||||
1 / ( Field::ReservoirVolume / Field::Time ),
|
||||
1 / Field::Transmissibility,
|
||||
1 / Field::Mass,
|
||||
};
|
||||
|
||||
inline double from_si( const double* table, dim d, double val ) {
|
||||
return val * table[ static_cast< int >( d ) ];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user