GridProperty: Collect Paired Assignment in Single Operation

This commit introduces a new helper function

    void GridProperty<>::setElement(i, val, dflt)

that handles paired assignments to 'm_data' and 'm_defaulted'[%].
This simplifies the bookkeeping and implementation of the various
assignment and value operations.

While here, also add a unit test to demonstrate expected behaviour
of the m_defaulted flag.  The only really questionable setting is
what happens if the deck applies a relative operator (e.g., ADD or
MULTIPLY) to a value that would otherwise be defaulted.  In the
current implementation the m_defaulted flag will remain set in this
case, but it arguably should be switched to unset (false).

[%]: Suggested by [at]akva2
This commit is contained in:
Bård Skaflestad 2019-07-12 06:44:07 +02:00
parent e79d1396df
commit a886a2334b
3 changed files with 207 additions and 61 deletions

View File

@ -309,6 +309,9 @@ public:
private:
const DeckItem& getDeckItem( const DeckKeyword& );
void setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem);
void setElement(const typename std::vector<T>::size_type i,
const T value,
const bool defaulted = false);
size_t m_nx, m_ny, m_nz;
SupportedKeywordInfo m_kwInfo;

View File

@ -173,8 +173,7 @@ namespace Opm {
template< typename T >
void GridProperty< T >::iset(size_t index, T value) {
this->m_data.at( index ) = value;
this->m_defaulted.at( index ) = false;
this->setElement(index, value);
}
template< typename T >
@ -218,10 +217,8 @@ namespace Opm {
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;
m_defaulted[g] = false;
}
if (mask[g])
this->setElement(g, value);
}
this->assigned = true;
}
@ -246,10 +243,8 @@ namespace Opm {
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];
m_defaulted[g] = other.m_defaulted[g];
}
if (mask[g])
this->setElement(g, other.m_data[g], other.m_defaulted[g]);
}
this->assigned = other.deckAssigned();
}
@ -304,54 +299,33 @@ namespace Opm {
template< typename T >
void GridProperty< T >::copyFrom( const GridProperty< T >& src, const Box& inputBox ) {
if (inputBox.isGlobal()) {
for (size_t i = 0; i < src.getCartesianSize(); ++i) {
m_data[i] = src.m_data[i];
m_defaulted[i] = src.m_defaulted[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];
m_defaulted[targetIndex] = src.m_defaulted[targetIndex];
}
}
if (inputBox.isGlobal())
for (size_t i = 0; i < src.getCartesianSize(); ++i)
this->setElement(i, src.m_data[i], src.m_defaulted[i]);
else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, src.m_data[i], src.m_defaulted[i]);
this->assigned = src.deckAssigned();
}
template< typename T >
void GridProperty< T >::maxvalue( T value, const Box& inputBox ) {
if (inputBox.isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i) {
m_data[i] = std::min(value,m_data[i]);
m_defaulted[i] = false;
}
} 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] = std::min(value,m_data[targetIndex]);
m_defaulted[targetIndex] = false;
}
}
if (inputBox.isGlobal())
for (size_t i = 0; i < m_data.size(); ++i)
this->setElement(i, std::min(value, this->m_data[i]));
else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, std::min(value, this->m_data[i]));
}
template< typename T >
void GridProperty< T >::minvalue( T value, const Box& inputBox ) {
if (inputBox.isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i) {
m_data[i] = std::max(value,m_data[i]);
m_defaulted[i] = false;
}
} 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] = std::max(value,m_data[targetIndex]);
m_defaulted[targetIndex] = false;
}
}
if (inputBox.isGlobal())
for (size_t i = 0; i < m_data.size(); ++i)
this->setElement(i, std::max(value, this->m_data[i]));
else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, std::max(value, this->m_data[i]));
}
template< typename T >
@ -387,14 +361,9 @@ namespace Opm {
if (inputBox.isGlobal()) {
std::fill(m_data.begin(), m_data.end(), value);
m_defaulted.assign(m_defaulted.size(), false);
} 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;
m_defaulted[targetIndex] = false;
}
}
} else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, value);
this->assigned = true;
}
@ -448,16 +417,21 @@ namespace Opm {
template<>
void GridProperty<int>::setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
m_data[targetIdx] = deckItem.get< int >(sourceIdx);
m_defaulted[targetIdx] = false;
this->setElement(targetIdx, deckItem.get< int >(sourceIdx));
}
template<>
void GridProperty<double>::setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
m_data[targetIdx] = deckItem.getSIDouble(sourceIdx);
m_defaulted[targetIdx] = false;
this->setElement(targetIdx, deckItem.getSIDouble(sourceIdx));
}
template <typename T>
void GridProperty<T>::setElement(const typename std::vector<T>::size_type i, const T value, const bool defaulted) {
this->m_data[i] = value;
this->m_defaulted[i] = defaulted;
}
template<>
bool GridProperty<int>::containsNaN( ) const {
throw std::logic_error("Only <double> and can be meaningfully queried for nan");

View File

@ -61,6 +61,8 @@ static const Opm::DeckKeyword createTABDIMSKeyword( ) {
return deck.getKeyword("TABDIMS");
}
BOOST_AUTO_TEST_SUITE(Basic_Proprty_Contents)
BOOST_AUTO_TEST_CASE(Empty) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("SATNUM" , 77, "1");
@ -570,3 +572,170 @@ BOOST_AUTO_TEST_CASE(hasKeyword_assertKeyword) {
BOOST_CHECK_THROW( gridProperties.getKeyword( "NOT-SUPPORTED" ), std::invalid_argument );
}
BOOST_AUTO_TEST_SUITE_END()
// =====================================================================
BOOST_AUTO_TEST_SUITE(Defaulted_Flag)
namespace {
struct Setup
{
Setup(const ::Opm::Deck& deck)
: tabMgr{ deck }
, eGrid { deck }
, props { deck, tabMgr, eGrid }
{}
Setup(const std::string& input)
: Setup(::Opm::Parser{}.parseString(input))
{}
::Opm::TableManager tabMgr;
::Opm::EclipseGrid eGrid;
::Opm::Eclipse3DProperties props;
};
} // Anonymous
BOOST_AUTO_TEST_CASE(EndScale_Horizontal)
{
const auto input = std::string { R"(
RUNSPEC
TITLE
Defaulted SOWCR
DIMENS
5 5 1 /
OIL
WATER
METRIC
ENDSCALE
/
TABDIMS
/
GRID
DXV
5*100
/
DYV
5*100
/
DZV
10
/
TOPS
25*2000 /
PROPS
SWOF
0.0 0.0 1.0 0.0
1.0 1.0 0.0 0.0
/
SOWCR
1* 1* 1* 1* 1*
1* 0.2 0.3 0.4 1*
1* 0.3 1* 0.5 1*
1* 0.4 0.5 0.6 1*
1* 1* 1* 1* 1* /
SWL
0.1 0.1 0.1 0.1 0.1
0.1 0.2 0.3 0.4 0.1
0.1 0.3 0.1 0.5 0.1
0.1 0.4 0.5 0.6 0.1
0.1 0.1 0.1 0.1 0.1 /
BOX
1 5 2 2 1 1 /
SWU
5*0.23 /
EQUALS
SWU 0.8 2 2 3 4 1 1 / Two elements
SWU 0.7 4 4 3 3 1 1 / Single element
/
-- Adds value to a defaulted value, should still be treated as defaulted
ADD
SWU 0.05 3 3 5 5 1 1 /
/
-- Assigns new value (no longer defaulted)
MINVALUE
SWU 0.3 5 5 5 5 1 1 /
/
END)" };
const auto cse = Setup{ input };
{
BOOST_CHECK(cse.props.hasDeckDoubleGridProperty("SOWCR"));
const auto& sowcr = cse.props.getDoubleGridProperty("SOWCR");
const auto& dflt = sowcr.wasDefaulted();
const auto T = true;
const auto F = false;
const auto expect_dflt = std::vector<bool> {
T, T, T, T, T,
T, F, F, F, T,
T, F, T, F, T,
T, F, F, F, T,
T, T, T, T, T,
};
BOOST_CHECK_EQUAL_COLLECTIONS(dflt .begin(), dflt .end(),
expect_dflt.begin(), expect_dflt.end());
}
{
BOOST_CHECK(cse.props.hasDeckDoubleGridProperty("SWL"));
const auto& swl = cse.props.getDoubleGridProperty("SWL");
const auto& dflt = swl.wasDefaulted();
const auto expect_dflt =
std::vector<bool>(cse.eGrid.getNumActive(), false);
BOOST_CHECK_EQUAL_COLLECTIONS(dflt .begin(), dflt .end(),
expect_dflt.begin(), expect_dflt.end());
}
{
BOOST_CHECK(cse.props.hasDeckDoubleGridProperty("SWU"));
const auto& swu = cse.props.getDoubleGridProperty("SWU");
const auto& dflt = swu.wasDefaulted();
const auto T = true;
const auto F = false;
const auto expect_dflt = std::vector<bool> {
T, T, T, T, T,
F, F, F, F, F,
T, F, T, F, T,
T, F, T, T, T,
T, T, T, T, F,
};
BOOST_CHECK_EQUAL_COLLECTIONS(dflt .begin(), dflt .end(),
expect_dflt.begin(), expect_dflt.end());
}
}
BOOST_AUTO_TEST_SUITE_END()