Added post processor to GridProperty

This commit is contained in:
Joakim Hove
2014-10-09 13:19:24 +02:00
parent f8abfe6333
commit 1df2e656a9
2 changed files with 190 additions and 8 deletions

View File

@@ -19,7 +19,6 @@
#ifndef ECLIPSE_GRIDPROPERTY_HPP_
#define ECLIPSE_GRIDPROPERTY_HPP_
#include "GridPropertyInitializers.hpp"
#include <iostream>
#include <string>
#include <vector>
@@ -29,6 +28,7 @@
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridPropertyInitializers.hpp>
/*
This class implemenents a class representing properties which are
@@ -38,22 +38,52 @@
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() { }
public:
virtual void apply(std::vector<ValueType>& values) const = 0;
};
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_dimensionString(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
@@ -61,31 +91,61 @@ public:
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)
: 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>
class GridProperty {
public:
@@ -97,8 +157,9 @@ public:
m_nz = nz;
m_kwInfo = kwInfo;
m_data.resize( nx * ny * nz );
m_kwInfo.getInitializer()->apply(m_data, m_kwInfo.getKeywordName());
m_hasRunPostProcessor = false;
}
size_t getCartesianSize() const {
@@ -251,6 +312,30 @@ public:
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 );
}
}
private:
Opm::DeckItemConstPtr getDeckItem(Opm::DeckKeywordConstPtr deckKeyword) {
if (deckKeyword->size() != 1)
@@ -277,6 +362,7 @@ private:
size_t m_nx,m_ny,m_nz;
SupportedKeywordInfo m_kwInfo;
std::vector<T> m_data;
bool m_hasRunPostProcessor;
};
}

View File

@@ -19,6 +19,7 @@
#include <stdexcept>
#include <iostream>
#include <memory>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE EclipseGridTests
@@ -38,6 +39,9 @@
Opm::DeckKeywordConstPtr createSATNUMKeyword( );
Opm::DeckKeywordConstPtr createTABDIMSKeyword( );
BOOST_AUTO_TEST_CASE(Empty) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("SATNUM" , 77, "1");
@@ -368,6 +372,98 @@ BOOST_AUTO_TEST_CASE(GridPropertyInitializers) {
BOOST_CHECK_EQUAL(sguPropData[2 * 3*3], 0.80);
}
template <class ValueType>
class TestPostProcessorMul : public Opm::GridPropertyBasePostProcessor<ValueType>
{
public:
TestPostProcessorMul(ValueType factor) {
m_factor = factor;
}
void apply(std::vector<ValueType>& values) const {
for (size_t g = 0; g < values.size(); g++)
values[g] *= m_factor;
};
private:
ValueType m_factor;
};
static Opm::DeckPtr createDeck() {
const char *deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"MULTPV \n"
"1000*0.10 / \n"
"PORO \n"
"1000*0.10 / \n"
"EDIT\n"
"\n";
Opm::ParserPtr parser(new Opm::Parser());
return parser->parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(GridPropertyPostProcessors) {
std::shared_ptr<TestPostProcessorMul<double> > testPostP = std::make_shared<TestPostProcessorMul<double> >(2.0);
Opm::GridPropertySupportedKeywordInfo<double> kwInfo1("MULTPV" , 1.0 , "1");
Opm::GridPropertySupportedKeywordInfo<double> kwInfo2("PORO" , 1.0 , testPostP , "1");
Opm::GridProperties<double> properties(10,10,10, std::vector<Opm::GridPropertySupportedKeywordInfo<double> > { kwInfo1 , kwInfo2 });
Opm::DeckPtr deck = createDeck();
Opm::EclipseGrid grid(deck);
{
auto poro = properties.getKeyword("PORO");
auto multpv = properties.getKeyword("MULTPV");
poro->loadFromDeckKeyword( deck->getKeyword("PORO" , 0));
multpv->loadFromDeckKeyword( deck->getKeyword("MULTPV" , 0));
if (poro->postProcessorRunRequired())
poro->runPostProcessor();
if (multpv->postProcessorRunRequired())
multpv->runPostProcessor();
for (size_t g = 0; g < 1000; g++) {
BOOST_CHECK_EQUAL( multpv->iget(g) , 0.10 );
BOOST_CHECK_EQUAL( poro->iget(g) , 0.20 );
}
if (poro->postProcessorRunRequired())
poro->runPostProcessor();
if (multpv->postProcessorRunRequired())
multpv->runPostProcessor();
for (size_t g = 0; g < 1000; g++) {
BOOST_CHECK_EQUAL( multpv->iget(g) , 0.10 );
BOOST_CHECK_EQUAL( poro->iget(g) , 0.20 );
}
}
BOOST_CHECK( !kwInfo1.hasPostProcessor() );
BOOST_CHECK( kwInfo2.hasPostProcessor() );
}