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.
This commit is contained in:
Jørgen Kvalsvik
2016-02-26 23:41:34 +01:00
parent 5b2ec6be75
commit 357e1e0e53
14 changed files with 543 additions and 447 deletions

View File

@@ -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

View File

@@ -564,7 +564,7 @@ namespace Opm {
const auto KRGRLookup = std::make_shared<KRGREndpointInitializer<>>(deck, es);
const auto IKRGRLookup = std::make_shared<IKRGREndpointInitializer<>>(deck, es);
const auto tempLookup = std::make_shared<GridPropertyTemperatureLookupInitializer<>>(deck, es);
const auto tempLookup = std::make_shared<GridPropertyTemperatureLookupInitializer>(deck, es);
const auto distributeTopLayer = std::make_shared<GridPropertyPostProcessor::DistributeTopLayer>(es);
const auto initPORV = std::make_shared<GridPropertyPostProcessor::InitPORV>(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

View File

@@ -24,8 +24,12 @@
#include <vector>
#include <unordered_map>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/OpmLog/LogUtil.hpp>
/*
This class implements a container (std::unordered_map<std::string ,
Gridproperty<T>>) of Gridproperties. Usage is as follows:
@@ -52,8 +56,8 @@ class GridProperties {
public:
typedef typename GridProperty<T>::SupportedKeywordInfo SupportedKeywordInfo;
GridProperties(std::shared_ptr<const EclipseGrid> eclipseGrid, std::vector< SupportedKeywordInfo >&& supportedKeywords) {
m_eclipseGrid = eclipseGrid;
GridProperties(std::shared_ptr<const EclipseGrid> eclipseGrid, std::vector< SupportedKeywordInfo >&& supportedKeywords) :
m_eclipseGrid( eclipseGrid ) {
for (auto iter = supportedKeywords.begin(); iter != supportedKeywords.end(); ++iter)
m_supportedKeywords[iter->getKeywordName()] = std::move( *iter );

View File

@@ -17,11 +17,385 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
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<bool>& 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<bool>& 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<const Box> inputBox, const DeckKeyword& deckKeyword) {
if (inputBox->isGlobal())
loadFromDeckKeyword( deckKeyword );
else {
const auto& deckItem = getDeckItem(deckKeyword);
const std::vector<size_t>& 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<long long>(indexList.size()));
std::string keywordSize = std::to_string(static_cast<long long>(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<size_t>& 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<size_t>& 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<const Box> inputBox ) {
if (inputBox->isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i)
m_data[i] += shiftValue;
} else {
const std::vector<size_t>& 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<size_t>& 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<T> GridProperty< T >::getEclKW() const {
ERT::EclKW<T> eclKW( getKeywordName(), getCartesianSize());
eclKW.assignVector( getData() );
return eclKW;
}
template< typename T >
ERT::EclKW<T> GridProperty< T >::getEclKW( std::shared_ptr< const EclipseGrid > grid ) const {
ERT::EclKW<T> 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<std::string>(deckItem.size())
+ " input size: " + boost::lexical_cast<std::string>(m_data.size()));
return deckItem;
}
template<>
void GridProperty<int>::setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
m_data[targetIdx] = deckItem.get< int >(sourceIdx);
@@ -37,7 +411,6 @@ bool GridProperty<int>::containsNaN( ) const {
throw std::logic_error("Only <double> and can be meaningfully queried for nan");
}
template<>
bool GridProperty<double>::containsNaN( ) const {
bool return_value = false;
@@ -65,7 +438,11 @@ template<>
const std::string& GridProperty<double>::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 >;

View File

@@ -21,258 +21,101 @@
#include <string>
#include <vector>
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <ert/ecl/EclKW.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp>
/*
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<T>;
where the most relevant specialisations of T are 'int' and 'float'.
*/
namespace Opm {
template <class ValueType>
class GridPropertyBasePostProcessor
{
protected:
GridPropertyBasePostProcessor() { }
class Box;
class DeckItem;
class DeckKeyword;
class EclipseGrid;
public:
virtual void apply(std::vector<ValueType>& 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 DataType>
class GridPropertySupportedKeywordInfo
{
public:
typedef GridPropertyBaseInitializer<DataType> Initializer;
typedef GridPropertyBasePostProcessor<DataType> PostProcessor;
GridPropertySupportedKeywordInfo()
{}
GridPropertySupportedKeywordInfo(const std::string& name,
std::shared_ptr<const Initializer> initializer,
std::shared_ptr<const PostProcessor> 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<const Initializer> 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<DataType>(defaultValue)),
m_dimensionString(dimString)
{}
GridPropertySupportedKeywordInfo(const std::string& name,
const DataType defaultValue,
std::shared_ptr<const PostProcessor> postProcessor,
const std::string& dimString)
: m_keywordName(name),
m_initializer(new Opm::GridPropertyConstantInitializer<DataType>(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<const Initializer> getInitializer() const {
return m_initializer;
}
std::shared_ptr<const PostProcessor> getPostProcessor() const {
return m_postProcessor;
}
bool hasPostProcessor() const {
return static_cast<bool>(m_postProcessor);
}
private:
std::string m_keywordName;
std::shared_ptr<const Initializer> m_initializer;
std::shared_ptr<const PostProcessor> m_postProcessor;
std::string m_dimensionString;
};
template <typename T>
template< typename T >
class GridProperty {
public:
typedef GridPropertySupportedKeywordInfo<T> 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<T>& getData() const;
bool containsNaN() const;
const std::string& getDimensionString() const;
void 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.");
}
void multiplyValueAtIndex(size_t index, T factor) {
m_data[index] *= factor;
}
const std::vector<T>& getData() const {
return m_data;
}
void maskedSet(T value, const std::vector<bool>& mask) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
m_data[g] = value;
}
}
void maskedMultiply(T value, const std::vector<bool>& mask) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
m_data[g] *= value;
}
}
void maskedAdd(T value, const std::vector<bool>& mask) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
m_data[g] += value;
}
}
void 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];
}
}
void 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;
}
}
void multiplyWith( const GridProperty<T>& );
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<bool>& 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 Box>, 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<const Box> inputBox, const DeckKeyword& deckKeyword) {
if (inputBox->isGlobal())
loadFromDeckKeyword( deckKeyword );
else {
const auto& deckItem = getDeckItem(deckKeyword);
const std::vector<size_t>& 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<long long>(indexList.size()));
std::string keywordSize = std::to_string(static_cast<long long>(deckItem.size()));
bool postProcessorRunRequired();
void runPostProcessor();
throw std::invalid_argument("Size mismatch: Box:" + boxSize + " DecKeyword:" + keywordSize);
}
}
}
ERT::EclKW<T> getEclKW() const;
ERT::EclKW<T> getEclKW( std::shared_ptr< const EclipseGrid > ) const;
void 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<size_t>& 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<const Box> inputBox) {
if (inputBox->isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i)
m_data[i] *= scaleFactor;
} else {
const std::vector<size_t>& 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<const Box> inputBox) {
if (inputBox->isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i)
m_data[i] += shiftValue;
} else {
const std::vector<size_t>& 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<const Box> inputBox) {
if (inputBox->isGlobal()) {
std::fill(m_data.begin(), m_data.end(), value);
} else {
const std::vector<size_t>& 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<T> getEclKW() const {
ERT::EclKW<T> eclKW( getKeywordName() , getCartesianSize());
eclKW.assignVector( getData() );
return eclKW;
}
ERT::EclKW<T> getEclKW(std::shared_ptr<const EclipseGrid> grid) const {
ERT::EclKW<T> 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<std::string>(deckItem.size())
+ " input size: " + boost::lexical_cast<std::string>(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

View File

@@ -0,0 +1,50 @@
#include <algorithm>
#include <limits>
#include <vector>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/RtempvdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
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<double>& 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<double>::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<int>& eqlNum = m_eclipseState.getIntGridProperty("EQLNUM")->getData();
for (size_t cellIdx = 0; cellIdx < eqlNum.size(); ++ cellIdx) {
int cellEquilNum = eqlNum[cellIdx];
const RtempvdTable& rtempvdTable = rtempvdTables.getTable<RtempvdTable>(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 >;

View File

@@ -20,19 +20,6 @@
#define ECLIPSE_GRIDPROPERTY_INITIALIZERS_HPP
#include <vector>
#include <string>
#include <exception>
#include <memory>
#include <limits>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <opm/parser/eclipse/EclipseState/Tables/RtempvdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
/*
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 ValueType>
class GridPropertyBaseInitializer
@@ -59,6 +43,17 @@ public:
virtual void apply(std::vector<ValueType>& values) const = 0;
};
template <class ValueType>
class GridPropertyBasePostProcessor
{
protected:
GridPropertyBasePostProcessor() { }
public:
virtual void apply(std::vector<ValueType>& values) const = 0;
};
template <class ValueType>
class GridPropertyConstantInitializer
: public GridPropertyBaseInitializer<ValueType>
@@ -68,23 +63,14 @@ public:
: m_value(value)
{ }
void apply(std::vector<ValueType>& values) const
{
std::fill(values.begin(), values.end(), m_value);
}
void apply(std::vector<ValueType>& 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 EclipseState=Opm::EclipseState,
class Deck=Opm::Deck>
class GridPropertyTemperatureLookupInitializer
: public GridPropertyBaseInitializer<double>
{
@@ -94,28 +80,7 @@ public:
, m_eclipseState(eclipseState)
{ }
void apply(std::vector<double>& 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<double>::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<int>& eqlNum = m_eclipseState.getIntGridProperty("EQLNUM")->getData();
for (size_t cellIdx = 0; cellIdx < eqlNum.size(); ++ cellIdx) {
int cellEquilNum = eqlNum[cellIdx];
const RtempvdTable& rtempvdTable = rtempvdTables.getTable<RtempvdTable>(cellEquilNum);
double cellDepth = std::get<2>(eclipseGrid->getCellCenter(cellIdx));
values[cellIdx] = rtempvdTable.evaluate("Temperature", cellDepth);
}
}
void apply(std::vector<double>& values) const;
private:
const Deck& m_deck;

View File

@@ -22,6 +22,7 @@
#include <set>
#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/FaceDir.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>

View File

@@ -29,6 +29,7 @@ namespace Opm {
template< typename > class GridProperties;
class DeckRecord;
class DeckKeyword;
namespace MULTREGT {

View File

@@ -28,6 +28,8 @@
#include <cassert>
#include <opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SwofTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp>

View File

@@ -38,6 +38,7 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
static const Opm::DeckKeyword createSATNUMKeyword( ) {

View File

@@ -25,6 +25,7 @@
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>

View File

@@ -28,6 +28,7 @@
#include <boost/filesystem.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>

View File

@@ -28,8 +28,9 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/OpmLog/CounterLog.hpp>
#include <opm/parser/eclipse/OpmLog/LogUtil.hpp>
#include <opm/parser/eclipse/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
@@ -37,6 +38,7 @@
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/checkDeck.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>