From 357e1e0e536ac98c811b5ea29bcb8cc0faf5d641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Fri, 26 Feb 2016 23:41:34 +0100 Subject: [PATCH] Move GridProperty< T > to source file GridProperty< T > has only two sensible types to parametrise, int and double. Moves the implementation and instantiation of GridProperty to GridProperty.cpp. This also applies to GridPropertyInitializers which has also been moved to source files. Results are a cleaner header file (for reading & understanding the interface) and faster compilations. --- opm/parser/eclipse/CMakeLists.txt | 1 + .../eclipse/EclipseState/EclipseState.cpp | 6 +- .../EclipseState/Grid/GridProperties.hpp | 8 +- .../EclipseState/Grid/GridProperty.cpp | 381 +++++++++++++- .../EclipseState/Grid/GridProperty.hpp | 472 +++--------------- .../Grid/GridPropertyInitializers.cpp | 50 ++ .../Grid/GridPropertyInitializers.hpp | 61 +-- .../EclipseState/Grid/MULTREGTScanner.cpp | 1 + .../EclipseState/Grid/MULTREGTScanner.hpp | 1 + .../Grid/SatfuncPropertyInitializers.hpp | 2 + .../Grid/tests/GridPropertyTests.cpp | 1 + .../SatfuncPropertyInitializersTests.cpp | 1 + .../tests/ThresholdPressureTest.cpp | 1 + .../EclipseState/tests/EclipseStateTests.cpp | 4 +- 14 files changed, 543 insertions(+), 447 deletions(-) create mode 100644 opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.cpp diff --git a/opm/parser/eclipse/CMakeLists.txt b/opm/parser/eclipse/CMakeLists.txt index d7e3b8cee..1189570f3 100644 --- a/opm/parser/eclipse/CMakeLists.txt +++ b/opm/parser/eclipse/CMakeLists.txt @@ -115,6 +115,7 @@ EclipseState/Tables/TableIndex.cpp EclipseState/Tables/PvtxTable.cpp EclipseState/Tables/Tables.cpp # +EclipseState/Grid/GridPropertyInitializers.cpp EclipseState/Grid/GridProperty.cpp EclipseState/Grid/Box.cpp EclipseState/Grid/BoxManager.cpp diff --git a/opm/parser/eclipse/EclipseState/EclipseState.cpp b/opm/parser/eclipse/EclipseState/EclipseState.cpp index c8e47065f..24f3eb467 100644 --- a/opm/parser/eclipse/EclipseState/EclipseState.cpp +++ b/opm/parser/eclipse/EclipseState/EclipseState.cpp @@ -564,7 +564,7 @@ namespace Opm { const auto KRGRLookup = std::make_shared>(deck, es); const auto IKRGRLookup = std::make_shared>(deck, es); - const auto tempLookup = std::make_shared>(deck, es); + const auto tempLookup = std::make_shared(deck, es); const auto distributeTopLayer = std::make_shared(es); const auto initPORV = std::make_shared(es); @@ -726,8 +726,8 @@ namespace Opm { // are not supported. (and hopefully never will be) // register the grid properties - m_intGridProperties = std::make_shared< GridProperties< int > >(m_eclipseGrid , makeSupportedIntKeywords() ); - m_doubleGridProperties = std::make_shared< GridProperties< double > >( m_eclipseGrid, makeSupportedDoubleKeywords(*deck, *this) ); + m_intGridProperties.reset( new GridProperties< int >( m_eclipseGrid , makeSupportedIntKeywords() ) ); + m_doubleGridProperties.reset( new GridProperties< double >( m_eclipseGrid, makeSupportedDoubleKeywords(*deck, *this) ) ); // actually create the grid property objects. we need to first // process all integer grid properties before the double ones diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp b/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp index 610715ee8..6ed8a8d63 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp @@ -24,8 +24,12 @@ #include #include +#include #include +#include +#include + /* This class implements a container (std::unordered_map>) of Gridproperties. Usage is as follows: @@ -52,8 +56,8 @@ class GridProperties { public: typedef typename GridProperty::SupportedKeywordInfo SupportedKeywordInfo; - GridProperties(std::shared_ptr eclipseGrid, std::vector< SupportedKeywordInfo >&& supportedKeywords) { - m_eclipseGrid = eclipseGrid; + GridProperties(std::shared_ptr eclipseGrid, std::vector< SupportedKeywordInfo >&& supportedKeywords) : + m_eclipseGrid( eclipseGrid ) { for (auto iter = supportedKeywords.begin(); iter != supportedKeywords.end(); ++iter) m_supportedKeywords[iter->getKeywordName()] = std::move( *iter ); diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp b/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp index 107ec134e..a6b2da4cf 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp @@ -17,11 +17,385 @@ along with OPM. If not, see . */ +#include +#include +#include +#include + +#include + +#include #include #include +#include namespace Opm { + template< typename T > + GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo( + const std::string& name, + std::shared_ptr< Initializer > initializer, + std::shared_ptr< PostProcessor > postProcessor, + const std::string& dimString ) : + m_keywordName( name ), + m_initializer( initializer ), + m_postProcessor( postProcessor ), + m_dimensionString( dimString ) + {} + + template< typename T > + GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo( + const std::string& name, + std::shared_ptr< Initializer > initializer, + const std::string& dimString ) : + m_keywordName(name), + m_initializer(initializer), + m_dimensionString(dimString) + {} + + template< typename T > + GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo( + const std::string& name, + const T defaultValue, + const std::string& dimString ) : + m_keywordName( name ), + m_initializer( new Opm::GridPropertyConstantInitializer< T >(defaultValue) ), + m_dimensionString( dimString ) + {} + + template< typename T > + GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo( + const std::string& name, + const T defaultValue, + std::shared_ptr< PostProcessor > postProcessor, + const std::string& dimString ) : + m_keywordName( name ), + m_initializer( new Opm::GridPropertyConstantInitializer< T >(defaultValue)), + m_postProcessor( postProcessor ), + m_dimensionString( dimString ) + {} + + template< typename T > + const std::string& GridPropertySupportedKeywordInfo< T >::getKeywordName() const { + return this->m_keywordName; + } + + template< typename T > + const std::string& GridPropertySupportedKeywordInfo< T >::getDimensionString() const { + return this->m_dimensionString; + } + + template< typename T > + typename GridPropertySupportedKeywordInfo< T >::Initializer* + GridPropertySupportedKeywordInfo< T >::getInitializer() { + return this->m_initializer.get(); + } + + template< typename T > + typename GridPropertySupportedKeywordInfo< T >::PostProcessor* + GridPropertySupportedKeywordInfo< T >::getPostProcessor() { + return this->m_postProcessor.get(); + } + + template< typename T > + bool GridPropertySupportedKeywordInfo< T >::hasPostProcessor() const { + return bool( this->m_postProcessor ); + } + + template< typename T > + GridProperty< T >::GridProperty( size_t nx, size_t ny, size_t nz, const SupportedKeywordInfo& kwInfo ) : + m_nx( nx ), + m_ny( ny ), + m_nz( nz ), + m_kwInfo( kwInfo ), + m_data( nx * ny * nz ) + { + m_kwInfo.getInitializer()->apply(m_data); + m_hasRunPostProcessor = false; + } + + template< typename T > + size_t GridProperty< T >::getCartesianSize() const { + return m_data.size(); + } + + template< typename T > + size_t GridProperty< T >::getNX() const { + return m_nx; + } + + template< typename T > + size_t GridProperty< T >::getNY() const { + return m_ny; + } + + template< typename T > + size_t GridProperty< T >::getNZ() const { + return m_nz; + } + + template< typename T > + T GridProperty< T >::iget( size_t index ) const { + if (index < m_data.size()) { + return m_data[index]; + } else { + throw std::invalid_argument("Index out of range \n"); + } + } + + template< typename T > + T GridProperty< T >::iget(size_t i , size_t j , size_t k) const { + size_t g = i + j*m_nx + k*m_nx*m_ny; + return iget(g); + } + + template< typename T > + void GridProperty< T >::iset(size_t index, T value) { + if (index < m_data.size()) + m_data[index] = value; + else + throw std::invalid_argument("Index out of range \n"); + } + + template< typename T > + void GridProperty< T >::iset(size_t i , size_t j , size_t k , T value) { + size_t g = i + j*m_nx + k*m_nx*m_ny; + iset(g,value); + } + + template< typename T > + const std::vector< T >& GridProperty< T >::getData() const { + return m_data; + } + + template< typename T > + void GridProperty< T >::multiplyWith( const GridProperty< T >& other ) { + if ((m_nx == other.m_nx) && (m_ny == other.m_ny) && (m_nz == other.m_nz)) { + for (size_t g=0; g < m_data.size(); g++) + m_data[g] *= other.m_data[g]; + } else + throw std::invalid_argument("Size mismatch between properties in mulitplyWith."); + } + + template< typename T > + void GridProperty< T >::multiplyValueAtIndex(size_t index, T factor) { + m_data[index] *= factor; + } + + template< typename T > + void GridProperty< T >::maskedSet( T value, const std::vector< bool >& mask ) { + for (size_t g = 0; g < getCartesianSize(); g++) { + if (mask[g]) + m_data[g] = value; + } + } + + template< typename T > + void GridProperty< T >::maskedMultiply( T value, const std::vector& mask ) { + for (size_t g = 0; g < getCartesianSize(); g++) { + if (mask[g]) + m_data[g] *= value; + } + } + + + template< typename T > + void GridProperty< T >::maskedAdd( T value, const std::vector& mask ) { + for (size_t g = 0; g < getCartesianSize(); g++) { + if (mask[g]) + m_data[g] += value; + } + } + + template< typename T > + void GridProperty< T >::maskedCopy( const GridProperty< T >& other, const std::vector< bool >& mask) { + for (size_t g = 0; g < getCartesianSize(); g++) { + if (mask[g]) + m_data[g] = other.m_data[g]; + } + } + + template< typename T > + void GridProperty< T >::initMask( T value, std::vector< bool >& mask ) const { + mask.resize(getCartesianSize()); + for (size_t g = 0; g < getCartesianSize(); g++) { + if (m_data[g] == value) + mask[g] = true; + else + mask[g] = false; + } + } + + template< typename T > + void GridProperty< T >::loadFromDeckKeyword( const DeckKeyword& deckKeyword ) { + const auto& deckItem = getDeckItem(deckKeyword); + for (size_t dataPointIdx = 0; dataPointIdx < deckItem.size(); ++dataPointIdx) { + if (!deckItem.defaultApplied(dataPointIdx)) + setDataPoint(dataPointIdx, dataPointIdx, deckItem); + } + } + + template< typename T > + void GridProperty< T >::loadFromDeckKeyword( std::shared_ptr inputBox, const DeckKeyword& deckKeyword) { + if (inputBox->isGlobal()) + loadFromDeckKeyword( deckKeyword ); + else { + const auto& deckItem = getDeckItem(deckKeyword); + const std::vector& indexList = inputBox->getIndexList(); + if (indexList.size() == deckItem.size()) { + for (size_t sourceIdx = 0; sourceIdx < indexList.size(); sourceIdx++) { + size_t targetIdx = indexList[sourceIdx]; + if (sourceIdx < deckItem.size() + && !deckItem.defaultApplied(sourceIdx)) + { + setDataPoint(sourceIdx, targetIdx, deckItem); + } + } + } else { + std::string boxSize = std::to_string(static_cast(indexList.size())); + std::string keywordSize = std::to_string(static_cast(deckItem.size())); + + throw std::invalid_argument("Size mismatch: Box:" + boxSize + " DecKeyword:" + keywordSize); + } + } + } + + template< typename T > + void GridProperty< T >::copyFrom( const GridProperty< T >& src, std::shared_ptr< const Box > inputBox ) { + if (inputBox->isGlobal()) { + for (size_t i = 0; i < src.getCartesianSize(); ++i) + m_data[i] = src.m_data[i]; + } else { + const std::vector& indexList = inputBox->getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] = src.m_data[targetIndex]; + } + } + } + + template< typename T > + void GridProperty< T >::scale( T scaleFactor, std::shared_ptr< const Box > inputBox ) { + if (inputBox->isGlobal()) { + for (size_t i = 0; i < m_data.size(); ++i) + m_data[i] *= scaleFactor; + } else { + const std::vector& indexList = inputBox->getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] *= scaleFactor; + } + } + } + + template< typename T > + void GridProperty< T >::add( T shiftValue, std::shared_ptr inputBox ) { + if (inputBox->isGlobal()) { + for (size_t i = 0; i < m_data.size(); ++i) + m_data[i] += shiftValue; + } else { + const std::vector& indexList = inputBox->getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] += shiftValue; + } + } + } + + template< typename T > + void GridProperty< T >::setScalar( T value, std::shared_ptr< const Box > inputBox ) { + if (inputBox->isGlobal()) { + std::fill(m_data.begin(), m_data.end(), value); + } else { + const std::vector& indexList = inputBox->getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] = value; + } + } + } + + template< typename T > + const std::string& GridProperty< T >::getKeywordName() const { + return m_kwInfo.getKeywordName(); + } + + template< typename T > + const typename GridProperty< T >::SupportedKeywordInfo& + GridProperty< T >::getKeywordInfo() const { + return m_kwInfo; + } + + + template< typename T > + bool GridProperty< T >::postProcessorRunRequired() { + return m_kwInfo.hasPostProcessor() && !m_hasRunPostProcessor; + } + + template< typename T > + void GridProperty< T >::runPostProcessor() { + if (postProcessorRunRequired()) { + // This is set here before the post processor has actually + // completed; this is to protect against circular loops if + // the post processor itself calls for the same grid + // property. + m_hasRunPostProcessor = true; + auto postProcessor = m_kwInfo.getPostProcessor(); + postProcessor->apply( m_data ); + } + } + + template< typename T > + ERT::EclKW GridProperty< T >::getEclKW() const { + ERT::EclKW eclKW( getKeywordName(), getCartesianSize()); + eclKW.assignVector( getData() ); + return eclKW; + } + + template< typename T > + ERT::EclKW GridProperty< T >::getEclKW( std::shared_ptr< const EclipseGrid > grid ) const { + ERT::EclKW eclKW( getKeywordName(), grid->getNumActive() ); + size_t activeIndex = 0; + for (size_t g = 0; g < getCartesianSize(); g++) { + if (grid->cellActive( g )) { + eclKW[activeIndex] = iget(g); + activeIndex++; + } + } + + return eclKW; + } + + template< typename T > + void GridProperty< T >::checkLimits( T min, T max ) const { + for (size_t g=0; g < m_data.size(); g++) { + T value = m_data[g]; + if ((value < min) || (value > max)) + throw std::invalid_argument("Property element outside valid limits"); + } + } + + template< typename T > + const DeckItem& GridProperty< T >::getDeckItem( const DeckKeyword& deckKeyword ) { + if (deckKeyword.size() != 1) + throw std::invalid_argument("Grid properties can only have a single record (keyword " + + deckKeyword.name() + ")"); + if (deckKeyword.getRecord(0).size() != 1) + // this is an error of the definition of the ParserKeyword (most likely in + // the corresponding JSON file) + throw std::invalid_argument("Grid properties may only exhibit a single item (keyword " + + deckKeyword.name() + ")"); + + const auto& deckItem = deckKeyword.getRecord(0).getItem(0); + + if (deckItem.size() > m_data.size()) + throw std::invalid_argument("Size mismatch when setting data for:" + getKeywordName() + + " keyword size: " + boost::lexical_cast(deckItem.size()) + + " input size: " + boost::lexical_cast(m_data.size())); + + return deckItem; + } + template<> void GridProperty::setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) { m_data[targetIdx] = deckItem.get< int >(sourceIdx); @@ -37,7 +411,6 @@ bool GridProperty::containsNaN( ) const { throw std::logic_error("Only and can be meaningfully queried for nan"); } - template<> bool GridProperty::containsNaN( ) const { bool return_value = false; @@ -65,7 +438,11 @@ template<> const std::string& GridProperty::getDimensionString() const { return m_kwInfo.getDimensionString(); } + } +template class Opm::GridPropertySupportedKeywordInfo< int >; +template class Opm::GridPropertySupportedKeywordInfo< double >; - +template class Opm::GridProperty< int >; +template class Opm::GridProperty< double >; diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp index eff8cccd5..51f037a36 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp @@ -21,258 +21,101 @@ #include #include -#include -#include #include -#include -#include -#include #include /* This class implemenents a class representing properties which are define over an ECLIPSE grid, i.e. with one value for each logical cartesian cell in the grid. - - The class is implemented as a thin wrapper around std::vector; - where the most relevant specialisations of T are 'int' and 'float'. */ - - - namespace Opm { -template -class GridPropertyBasePostProcessor -{ -protected: - GridPropertyBasePostProcessor() { } + class Box; + class DeckItem; + class DeckKeyword; + class EclipseGrid; -public: - virtual void apply(std::vector& values) const = 0; +template< typename T > +class GridPropertySupportedKeywordInfo { + + typedef GridPropertyBaseInitializer< T > Initializer; + typedef GridPropertyBasePostProcessor< T > PostProcessor; + + public: + GridPropertySupportedKeywordInfo() = default; + + GridPropertySupportedKeywordInfo( + const std::string& name, + std::shared_ptr< Initializer > initializer, + std::shared_ptr< PostProcessor > postProcessor, + const std::string& dimString ); + + GridPropertySupportedKeywordInfo( + const std::string& name, + std::shared_ptr< Initializer > initializer, + const std::string& dimString); + + /* this is a convenience constructor which can be used if the default + * value for the grid property is just a constant. + */ + GridPropertySupportedKeywordInfo( + const std::string& name, + const T defaultValue, + const std::string& dimString ); + + GridPropertySupportedKeywordInfo( + const std::string& name, + const T defaultValue, + std::shared_ptr< PostProcessor > postProcessor, + const std::string& dimString ); + + const std::string& getKeywordName() const; + const std::string& getDimensionString() const; + Initializer* getInitializer(); + PostProcessor* getPostProcessor(); + bool hasPostProcessor() const; + + private: + std::string m_keywordName; + std::shared_ptr< Initializer > m_initializer; + std::shared_ptr< PostProcessor > m_postProcessor; + std::string m_dimensionString; }; - - - -template -class GridPropertySupportedKeywordInfo -{ -public: - typedef GridPropertyBaseInitializer Initializer; - typedef GridPropertyBasePostProcessor PostProcessor; - - GridPropertySupportedKeywordInfo() - {} - - GridPropertySupportedKeywordInfo(const std::string& name, - std::shared_ptr initializer, - std::shared_ptr postProcessor, - const std::string& dimString) - : m_keywordName(name), - m_initializer(initializer), - m_postProcessor(postProcessor), - m_dimensionString(dimString) - {} - - - GridPropertySupportedKeywordInfo(const std::string& name, - std::shared_ptr initializer, - const std::string& dimString) - : m_keywordName(name), - m_initializer(initializer), - m_dimensionString(dimString) - {} - - // this is a convenience constructor which can be used if the default value for the - // grid property is just a constant... - GridPropertySupportedKeywordInfo(const std::string& name, - const DataType defaultValue, - const std::string& dimString) - : m_keywordName(name), - m_initializer(new Opm::GridPropertyConstantInitializer(defaultValue)), - m_dimensionString(dimString) - {} - - GridPropertySupportedKeywordInfo(const std::string& name, - const DataType defaultValue, - std::shared_ptr postProcessor, - const std::string& dimString) - : m_keywordName(name), - m_initializer(new Opm::GridPropertyConstantInitializer(defaultValue)), - m_postProcessor(postProcessor), - m_dimensionString(dimString) - {} - - - - GridPropertySupportedKeywordInfo(const GridPropertySupportedKeywordInfo&) = default; - - - const std::string& getKeywordName() const { - return m_keywordName; - } - - - const std::string& getDimensionString() const { - return m_dimensionString; - } - - - std::shared_ptr getInitializer() const { - return m_initializer; - } - - - std::shared_ptr getPostProcessor() const { - return m_postProcessor; - } - - - bool hasPostProcessor() const { - return static_cast(m_postProcessor); - } - - - -private: - std::string m_keywordName; - std::shared_ptr m_initializer; - std::shared_ptr m_postProcessor; - std::string m_dimensionString; -}; - - - -template +template< typename T > class GridProperty { public: typedef GridPropertySupportedKeywordInfo SupportedKeywordInfo; - GridProperty(size_t nx , size_t ny , size_t nz , const SupportedKeywordInfo& kwInfo) { - m_nx = nx; - m_ny = ny; - m_nz = nz; - m_kwInfo = kwInfo; - m_data.resize( nx * ny * nz ); + GridProperty( size_t nx, size_t ny, size_t nz, const SupportedKeywordInfo& kwInfo ); - m_kwInfo.getInitializer()->apply(m_data); - m_hasRunPostProcessor = false; - } - - size_t getCartesianSize() const { - return m_data.size(); - } - - size_t getNX() const { - return m_nx; - } - - size_t getNY() const { - return m_ny; - } - - size_t getNZ() const { - return m_nz; - } + size_t getCartesianSize() const; + size_t getNX() const; + size_t getNY() const; + size_t getNZ() const; - T iget(size_t index) const { - if (index < m_data.size()) { - return m_data[index]; - } else { - throw std::invalid_argument("Index out of range \n"); - } - } + T iget(size_t index) const; + T iget(size_t i , size_t j , size_t k) const; + void iset(size_t index, T value); + void iset(size_t i , size_t j , size_t k , T value); - - T iget(size_t i , size_t j , size_t k) const { - size_t g = i + j*m_nx + k*m_nx*m_ny; - return iget(g); - } - - void iset(size_t index, T value) { - if (index < m_data.size()) - m_data[index] = value; - else - throw std::invalid_argument("Index out of range \n"); - } - - void iset(size_t i , size_t j , size_t k , T value) { - size_t g = i + j*m_nx + k*m_nx*m_ny; - iset(g,value); - } + const std::vector& getData() const; bool containsNaN() const; - const std::string& getDimensionString() const; - void multiplyWith(const GridProperty& other) { - if ((m_nx == other.m_nx) && (m_ny == other.m_ny) && (m_nz == other.m_nz)) { - for (size_t g=0; g < m_data.size(); g++) - m_data[g] *= other.m_data[g]; - } else - throw std::invalid_argument("Size mismatch between properties in mulitplyWith."); - } - - - void multiplyValueAtIndex(size_t index, T factor) { - m_data[index] *= factor; - } - - const std::vector& getData() const { - return m_data; - } - - - - void maskedSet(T value, const std::vector& mask) { - for (size_t g = 0; g < getCartesianSize(); g++) { - if (mask[g]) - m_data[g] = value; - } - } - - - void maskedMultiply(T value, const std::vector& mask) { - for (size_t g = 0; g < getCartesianSize(); g++) { - if (mask[g]) - m_data[g] *= value; - } - } - - - void maskedAdd(T value, const std::vector& mask) { - for (size_t g = 0; g < getCartesianSize(); g++) { - if (mask[g]) - m_data[g] += value; - } - } - - - void maskedCopy(const GridProperty& other, const std::vector& mask) { - for (size_t g = 0; g < getCartesianSize(); g++) { - if (mask[g]) - m_data[g] = other.m_data[g]; - } - } - - - - void initMask(T value, std::vector& mask) const { - mask.resize(getCartesianSize()); - for (size_t g = 0; g < getCartesianSize(); g++) { - if (m_data[g] == value) - mask[g] = true; - else - mask[g] = false; - } - } - - + void multiplyWith( const GridProperty& ); + void multiplyValueAtIndex( size_t index, T factor ); + void maskedSet( T value, const std::vector< bool >& mask ); + void maskedMultiply( T value, const std::vector< bool >& mask ); + void maskedAdd( T value, const std::vector< bool >& mask ); + void maskedCopy( const GridProperty< T >& other, const std::vector< bool >& mask ); + void initMask( T value, std::vector& mask ) const; /** Due to the convention where it is only neceassary to supply the @@ -281,184 +124,32 @@ public: deckkeyword equals nx*ny*nz. */ - void loadFromDeckKeyword( const DeckKeyword& deckKeyword) { - const auto& deckItem = getDeckItem(deckKeyword); - for (size_t dataPointIdx = 0; dataPointIdx < deckItem.size(); ++dataPointIdx) { - if (!deckItem.defaultApplied(dataPointIdx)) - setDataPoint(dataPointIdx, dataPointIdx, deckItem); - } - } + void loadFromDeckKeyword( const DeckKeyword& ); + void loadFromDeckKeyword( std::shared_ptr, const DeckKeyword& ); + void copyFrom( const GridProperty< T >&, std::shared_ptr< const Box > ); + void scale( T scaleFactor, std::shared_ptr< const Box > ); + void add( T shiftValue, std::shared_ptr< const Box > ); + void setScalar( T value, std::shared_ptr< const Box > ); + const std::string& getKeywordName() const; + const SupportedKeywordInfo& getKeywordInfo() const; - void loadFromDeckKeyword(std::shared_ptr inputBox, const DeckKeyword& deckKeyword) { - if (inputBox->isGlobal()) - loadFromDeckKeyword( deckKeyword ); - else { - const auto& deckItem = getDeckItem(deckKeyword); - const std::vector& indexList = inputBox->getIndexList(); - if (indexList.size() == deckItem.size()) { - for (size_t sourceIdx = 0; sourceIdx < indexList.size(); sourceIdx++) { - size_t targetIdx = indexList[sourceIdx]; - if (sourceIdx < deckItem.size() - && !deckItem.defaultApplied(sourceIdx)) - { - setDataPoint(sourceIdx, targetIdx, deckItem); - } - } - } else { - std::string boxSize = std::to_string(static_cast(indexList.size())); - std::string keywordSize = std::to_string(static_cast(deckItem.size())); + bool postProcessorRunRequired(); + void runPostProcessor(); - throw std::invalid_argument("Size mismatch: Box:" + boxSize + " DecKeyword:" + keywordSize); - } - } - } + ERT::EclKW getEclKW() const; + ERT::EclKW getEclKW( std::shared_ptr< const EclipseGrid > ) const; - - - void copyFrom(const GridProperty& src, std::shared_ptr inputBox) { - if (inputBox->isGlobal()) { - for (size_t i = 0; i < src.getCartesianSize(); ++i) - m_data[i] = src.m_data[i]; - } else { - const std::vector& indexList = inputBox->getIndexList(); - for (size_t i = 0; i < indexList.size(); i++) { - size_t targetIndex = indexList[i]; - m_data[targetIndex] = src.m_data[targetIndex]; - } - } - } - - void scale(T scaleFactor , std::shared_ptr inputBox) { - if (inputBox->isGlobal()) { - for (size_t i = 0; i < m_data.size(); ++i) - m_data[i] *= scaleFactor; - } else { - const std::vector& indexList = inputBox->getIndexList(); - for (size_t i = 0; i < indexList.size(); i++) { - size_t targetIndex = indexList[i]; - m_data[targetIndex] *= scaleFactor; - } - } - } - - - void add(T shiftValue , std::shared_ptr inputBox) { - if (inputBox->isGlobal()) { - for (size_t i = 0; i < m_data.size(); ++i) - m_data[i] += shiftValue; - } else { - const std::vector& indexList = inputBox->getIndexList(); - for (size_t i = 0; i < indexList.size(); i++) { - size_t targetIndex = indexList[i]; - m_data[targetIndex] += shiftValue; - } - } - } - - - - - void setScalar(T value , std::shared_ptr inputBox) { - if (inputBox->isGlobal()) { - std::fill(m_data.begin(), m_data.end(), value); - } else { - const std::vector& indexList = inputBox->getIndexList(); - for (size_t i = 0; i < indexList.size(); i++) { - size_t targetIndex = indexList[i]; - m_data[targetIndex] = value; - } - } - } - - const std::string& getKeywordName() const { - return m_kwInfo.getKeywordName(); - } - - const SupportedKeywordInfo& getKeywordInfo() const { - return m_kwInfo; - } - - - bool postProcessorRunRequired() { - if (m_kwInfo.hasPostProcessor() && !m_hasRunPostProcessor) - return true; - else - return false; - } - - - void runPostProcessor() { - if (postProcessorRunRequired()) { - // This is set here before the post processor has actually - // completed; this is to protect against circular loops if - // the post processor itself calls for the same grid - // property. - m_hasRunPostProcessor = true; - auto postProcessor = m_kwInfo.getPostProcessor(); - postProcessor->apply( m_data ); - } - } - - - ERT::EclKW getEclKW() const { - ERT::EclKW eclKW( getKeywordName() , getCartesianSize()); - eclKW.assignVector( getData() ); - return eclKW; - } - - - ERT::EclKW getEclKW(std::shared_ptr grid) const { - ERT::EclKW eclKW( getKeywordName() , grid->getNumActive()); - size_t activeIndex = 0; - for (size_t g = 0; g < getCartesianSize(); g++) { - if (grid->cellActive( g )) { - eclKW[activeIndex] = iget(g); - activeIndex++; - } - } - - return eclKW; - } - - - - /** Will check that all elements in the property are in the closed interval [min,max]. */ - void checkLimits(T min , T max) const { - for (size_t g=0; g < m_data.size(); g++) { - T value = m_data[g]; - if ((value < min) || (value > max)) - throw std::invalid_argument("Property element outside valid limits"); - } - } + void checkLimits( T min, T max ) const; private: - const DeckItem& getDeckItem( const DeckKeyword& deckKeyword) { - if (deckKeyword.size() != 1) - throw std::invalid_argument("Grid properties can only have a single record (keyword " - + deckKeyword.name() + ")"); - if (deckKeyword.getRecord(0).size() != 1) - // this is an error of the definition of the ParserKeyword (most likely in - // the corresponding JSON file) - throw std::invalid_argument("Grid properties may only exhibit a single item (keyword " - + deckKeyword.name() + ")"); - - const auto& deckItem = deckKeyword.getRecord(0).getItem(0); - - if (deckItem.size() > m_data.size()) - throw std::invalid_argument("Size mismatch when setting data for:" + getKeywordName() + - " keyword size: " + boost::lexical_cast(deckItem.size()) - + " input size: " + boost::lexical_cast(m_data.size())); - - return deckItem; - } - + const DeckItem& getDeckItem( const DeckKeyword& ); void setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem); size_t m_nx,m_ny,m_nz; @@ -467,6 +158,5 @@ private: bool m_hasRunPostProcessor; }; - } #endif diff --git a/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.cpp b/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.cpp new file mode 100644 index 000000000..45cb979d9 --- /dev/null +++ b/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Opm { + + template< typename T > + void GridPropertyConstantInitializer< T >::apply(std::vector< T >& values) const { + std::fill(values.begin(), values.end(), m_value); + } + + void GridPropertyTemperatureLookupInitializer::apply(std::vector& values) const + { + if (!m_deck.hasKeyword("EQLNUM")) { + // if values are defaulted in the TEMPI keyword, but no + // EQLNUM is specified, you will get NaNs... + double nan = std::numeric_limits::quiet_NaN(); + std::fill(values.begin(), values.end(), nan); + return; + } + + auto tables = m_eclipseState.getTableManager(); + auto eclipseGrid = m_eclipseState.getEclipseGrid(); + const TableContainer& rtempvdTables = tables->getRtempvdTables(); + const std::vector& eqlNum = m_eclipseState.getIntGridProperty("EQLNUM")->getData(); + + for (size_t cellIdx = 0; cellIdx < eqlNum.size(); ++ cellIdx) { + int cellEquilNum = eqlNum[cellIdx]; + const RtempvdTable& rtempvdTable = rtempvdTables.getTable(cellEquilNum); + double cellDepth = std::get<2>(eclipseGrid->getCellCenter(cellIdx)); + values[cellIdx] = rtempvdTable.evaluate("Temperature", cellDepth); + } + } +} + +template class Opm::GridPropertyConstantInitializer< int >; +template class Opm::GridPropertyConstantInitializer< double >; + +template class Opm::GridPropertyBaseInitializer< int >; +template class Opm::GridPropertyBaseInitializer< double >; +template class Opm::GridPropertyBasePostProcessor< int >; +template class Opm::GridPropertyBasePostProcessor< double >; diff --git a/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp b/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp index 63f54e07d..3c49e766c 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp @@ -20,19 +20,6 @@ #define ECLIPSE_GRIDPROPERTY_INITIALIZERS_HPP #include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - - /* This classes initialize GridProperty objects. Most commonly, they just get a constant @@ -44,9 +31,6 @@ namespace Opm { // forward definitions class Deck; class EclipseState; -class EnptvdTable; -class ImptvdTable; -class TableContainer; template class GridPropertyBaseInitializer @@ -59,6 +43,17 @@ public: virtual void apply(std::vector& values) const = 0; }; +template +class GridPropertyBasePostProcessor +{ +protected: + GridPropertyBasePostProcessor() { } + +public: + virtual void apply(std::vector& values) const = 0; +}; + + template class GridPropertyConstantInitializer : public GridPropertyBaseInitializer @@ -68,23 +63,14 @@ public: : m_value(value) { } - void apply(std::vector& values) const - { - std::fill(values.begin(), values.end(), m_value); - } + void apply(std::vector& values) const; private: ValueType m_value; }; - - - - // initialize the TEMPI grid property using the temperature vs depth // table (stemming from the TEMPVD or the RTEMPVD keyword) -template class GridPropertyTemperatureLookupInitializer : public GridPropertyBaseInitializer { @@ -94,28 +80,7 @@ public: , m_eclipseState(eclipseState) { } - void apply(std::vector& values) const - { - if (!m_deck.hasKeyword("EQLNUM")) { - // if values are defaulted in the TEMPI keyword, but no - // EQLNUM is specified, you will get NaNs... - double nan = std::numeric_limits::quiet_NaN(); - std::fill(values.begin(), values.end(), nan); - return; - } - - auto tables = m_eclipseState.getTableManager(); - auto eclipseGrid = m_eclipseState.getEclipseGrid(); - const TableContainer& rtempvdTables = tables->getRtempvdTables(); - const std::vector& eqlNum = m_eclipseState.getIntGridProperty("EQLNUM")->getData(); - - for (size_t cellIdx = 0; cellIdx < eqlNum.size(); ++ cellIdx) { - int cellEquilNum = eqlNum[cellIdx]; - const RtempvdTable& rtempvdTable = rtempvdTables.getTable(cellEquilNum); - double cellDepth = std::get<2>(eclipseGrid->getCellCenter(cellIdx)); - values[cellIdx] = rtempvdTable.evaluate("Temperature", cellDepth); - } - } + void apply(std::vector& values) const; private: const Deck& m_deck; diff --git a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp index 4b0884be5..20f535c45 100644 --- a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp index d84e5d97d..35c5d4e4f 100644 --- a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp @@ -29,6 +29,7 @@ namespace Opm { template< typename > class GridProperties; + class DeckRecord; class DeckKeyword; namespace MULTREGT { diff --git a/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp b/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp index ccb2a73c2..47e091bf1 100644 --- a/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include diff --git a/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp b/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp index 2eb6f4384..6714055fb 100644 --- a/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include static const Opm::DeckKeyword createSATNUMKeyword( ) { diff --git a/opm/parser/eclipse/EclipseState/Grid/tests/SatfuncPropertyInitializersTests.cpp b/opm/parser/eclipse/EclipseState/Grid/tests/SatfuncPropertyInitializersTests.cpp index c2ec78b9e..999f91f4a 100644 --- a/opm/parser/eclipse/EclipseState/Grid/tests/SatfuncPropertyInitializersTests.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/tests/SatfuncPropertyInitializersTests.cpp @@ -25,6 +25,7 @@ #include +#include #include #include #include diff --git a/opm/parser/eclipse/EclipseState/SimulationConfig/tests/ThresholdPressureTest.cpp b/opm/parser/eclipse/EclipseState/SimulationConfig/tests/ThresholdPressureTest.cpp index 19c7bcec6..ccd1e566d 100644 --- a/opm/parser/eclipse/EclipseState/SimulationConfig/tests/ThresholdPressureTest.cpp +++ b/opm/parser/eclipse/EclipseState/SimulationConfig/tests/ThresholdPressureTest.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp b/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp index c76f46ba2..1339c9cb7 100644 --- a/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp +++ b/opm/parser/eclipse/EclipseState/tests/EclipseStateTests.cpp @@ -28,8 +28,9 @@ #include #include -#include #include +#include +#include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include