Handle keyword OPERATE.

This commit is contained in:
Joakim Hove
2016-11-11 14:42:32 +01:00
committed by jokva
parent 0b9843bc10
commit 76f5a4d78b
8 changed files with 169 additions and 1 deletions

View File

@@ -729,6 +729,9 @@ namespace Opm {
else if (deckKeyword.name() == "COPYREG")
handleCOPYREGKeyword(deckKeyword);
else if (deckKeyword.name() == "OPERATE")
handleOPERATEKeyword( deckKeyword , boxManager);
boxManager.endKeyword();
}
}
@@ -753,6 +756,19 @@ namespace Opm {
boxManager.endInputBox();
}
void Eclipse3DProperties::handleOPERATEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) {
for( const auto& record : deckKeyword ) {
const std::string& targetArray = record.getItem("TARGET_ARRAY").get< std::string >(0);
const std::string& srcArray = record.getItem("ARRAY").get< std::string >(0);
if (m_intGridProperties.supportsKeyword( targetArray ))
m_intGridProperties.handleOPERATERecord( record , boxManager);
else if (m_doubleGridProperties.supportsKeyword( targetArray ))
m_doubleGridProperties.handleOPERATERecord( record , boxManager);
else
throw std::invalid_argument("Fatal error processing OPERATE keyword - invalid/undefined keyword: " + targetArray);
}
}
void Eclipse3DProperties::handleEQUALREGKeyword( const DeckKeyword& deckKeyword) {
for( const auto& record : deckKeyword ) {

View File

@@ -87,6 +87,7 @@ namespace Opm {
void handleCOPYREGKeyword( const DeckKeyword& deckKeyword );
void handleEQUALREGKeyword(const DeckKeyword& deckKeyword );
void handleMULTIREGKeyword(const DeckKeyword& deckKeyword );
void handleOPERATEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void loadGridPropertyFromDeckKeyword(const Box& inputBox,
const DeckKeyword& deckKeyword);

View File

@@ -397,6 +397,118 @@ namespace Opm {
}
}
namespace {
/*
The functions in this namespace are those listed as
available operations in the OPERATE keyword.
*/
double MULTA(double, double X, double alpha, double beta) {
return alpha*X + beta;
}
// NB: The POLY function and the MULTIPLY function both use
// the R value in the calculation. That implies that we should
// ideally check that the R property has already been
// initialized with a valid value, For all the other
// operations R only appears on the left side of the equation,
// and can be fully assigned to.
double POLY(double R, double X, double alpha, double beta) {
return R + alpha * std::pow(X , beta );
}
double MULTIPLY(double R, double X, double , double ) {
return R * X;
}
double SLOG(double, double X, double alpha, double beta) {
return pow(10 , alpha + beta * X);
}
double LOG10(double, double X, double , double ) {
return log10(X);
}
double LOGE(double, double X, double , double ) {
return log(X);
}
double INV(double, double X, double , double ) {
return 1.0/X;
}
double MULTX(double, double X, double alpha, double ) {
return alpha * X;
}
double ADDX(double, double X, double alpha, double ) {
return alpha + X;
}
double COPY(double, double X, double, double ) {
return X;
}
double MAXLIM(double, double X, double alpha, double ) {
return std::min( alpha , X );
}
double MINLIM(double, double X, double alpha, double ) {
return std::max( alpha , X );
}
double MULTP(double, double X, double alpha, double beta) {
return alpha * pow(X, beta );
}
double ABS(double, double X, double, double) {
return std::abs(X);
}
}
template <typename T>
void GridProperties<T>::handleOPERATERecord( const DeckRecord& record, BoxManager& boxManager) {
using operate_fptr = decltype( &MULTA );
static const std::map<std::string , operate_fptr> operations = {{"MULTA" , &MULTA},
{"POLY" , &POLY},
{"SLOG" , &SLOG},
{"LOG10" , &LOG10},
{"LOGE" , &LOGE},
{"INV" , &INV},
{"MULTX" , &MULTX},
{"ADDX" , &ADDX},
{"COPY" , &COPY},
{"MAXLIM" , &MAXLIM},
{"MINLIM" , &MINLIM},
{"MULTP" , &MULTP},
{"ABS" , &ABS},
{"MULTIPLY" , &MULTIPLY}};
const std::string& srcArray = record.getItem("ARRAY").get< std::string >(0);
const std::string& targetArray = record.getItem("TARGET_ARRAY").get< std::string >(0);
const std::string& operation = record.getItem("OPERATION").get< std::string >(0);
double alpha = record.getItem("PARAM1").get< double >(0);
double beta = record.getItem("PARAM2").get< double >(0);
if (!supportsKeyword( targetArray))
throw std::invalid_argument("Fatal error processing COPYREG record - invalid/undefined keyword: " + targetArray);
if (!hasKeyword( srcArray ))
throw std::invalid_argument("Fatal error processing COPYREG record - invalid/undefined keyword: " + srcArray);
{
const std::vector<T>& srcData = getKeyword( srcArray ).getData();
std::vector<T>& targetData = getOrCreateProperty( targetArray ).getData();
operate_fptr func = operations.at( operation );
setKeywordBox(record, boxManager);
for (auto index : boxManager.getActiveBox())
targetData[index] = func( targetData[index] , srcData[index] , alpha, beta );
}
}
template< typename T >
void GridProperties<T>::postAddKeyword(const std::string& name,
const T defaultValue,

View File

@@ -127,7 +127,7 @@ namespace Opm {
void handleADDREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleMULTIREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleCOPYREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleOPERATERecord( const DeckRecord& record , BoxManager& boxManager);
/*
Iterators over initialized properties. The overloaded
operator*() opens the pair which comes natively from the

View File

@@ -166,6 +166,12 @@ namespace Opm {
return m_data;
}
template< typename T >
std::vector< T >& GridProperty< T >::getData() {
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)) {
@@ -180,6 +186,8 @@ namespace Opm {
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++) {

View File

@@ -103,7 +103,9 @@ public:
void iset(size_t index, T value);
void iset(size_t i , size_t j , size_t k , T value);
const std::vector<T>& getData() const;
std::vector<T>& getData();
bool containsNaN() const;
const std::string& getDimensionString() const;

View File

@@ -139,4 +139,16 @@ BOOST_AUTO_TEST_CASE( EQUALS ) {
}
BOOST_AUTO_TEST_CASE( OPERATE ) {
EclipseState state = makeState( "testdata/integration_tests/BOX/BOXTEST1" );
const auto& ntg = state.get3DProperties().getDoubleGridProperty( "NTG" );
BOOST_CHECK_EQUAL( ntg.iget( 0,0,0) , 8.50 ); // MULTA
BOOST_CHECK_EQUAL( ntg.iget( 0,5,0) , 5.00 ); // POLY
BOOST_CHECK_EQUAL( ntg.iget( 0,0,1) , 4.0 ); // COPY
BOOST_CHECK_EQUAL( ntg.iget( 0,5,1) , 4.0 ); // MINLIM
BOOST_CHECK_EQUAL( ntg.iget( 0,0,2) , 2.0 ); // MAXLIM
}