Added DeckXXX::equal( ) method.

This commit is contained in:
Joakim Hove 2017-08-30 16:23:27 +02:00
parent da55685b62
commit 1f646711d4
7 changed files with 185 additions and 0 deletions

View File

@ -79,6 +79,25 @@ namespace Opm {
type_tag getType() const;
/*
The comparison can be adjusted with the cmp_default and
cmp_numeric flags. If cmp_default is set to true the
comparison will take the defaulted status of the items into
account, i.e. two items will compare differently if one is
defaulted and the other has the default value explicitly
set. The default behaviour is cmp_default == false -
i.e. only the actual values in the items will be compared,
itrespective of whether they have been set explicitly or
have been defaulted.
*/
bool equal(const DeckItem& other, bool cmp_default, bool cmp_numeric) const;
/*
The operator== is implemented based on the equal( ) method,
with the arguments cmp_default=false and cmp_numeric=true.
*/
bool operator==(const DeckItem& other) const;
bool operator!=(const DeckItem& other) const;
private:
std::vector< double > dval;
std::vector< int > ival;

View File

@ -66,6 +66,10 @@ namespace Opm {
const_iterator begin() const;
const_iterator end() const;
bool equal_data(const DeckKeyword& other, bool cmp_default = false, bool cmp_numeric = true) const;
bool equal(const DeckKeyword& other, bool cmp_default = false, bool cmp_numeric = true) const;
bool operator==(const DeckKeyword& other) const;
bool operator!=(const DeckKeyword& other) const;
private:
std::string m_keywordName;

View File

@ -61,6 +61,10 @@ namespace Opm {
const_iterator begin() const;
const_iterator end() const;
bool equal(const DeckRecord& other, bool cmp_default, bool cmp_numeric) const;
bool operator==(const DeckRecord& other) const;
bool operator!=(const DeckRecord& other) const;
private:
std::vector< DeckItem > m_items;

View File

@ -240,6 +240,78 @@ type_tag DeckItem::getType() const {
return this->type;
}
namespace {
bool double_equal(double value1, double value2, double abs_eps , double rel_eps) {
bool equal = true;
double diff = std::fabs(value1 - value2);
if (diff > abs_eps) {
double scale = std::max(std::fabs(value1), std::fabs(value2));
if (diff > scale * rel_eps) {
equal = false;
}
}
return equal;
}
}
bool DeckItem::equal(const DeckItem& other, bool cmp_default, bool cmp_numeric) const {
double rel_eps = 1e-4;
double abs_eps = 1e-4;
if (this->type != other.type)
return false;
if (this->size() != other.size())
return false;
if (this->item_name != other.item_name)
return false;
if (cmp_default)
if (this->defaulted != other.defaulted)
return false;
switch( this->type ) {
case type_tag::integer:
if (this->ival != other.ival)
return false;
break;
case type_tag::string:
if (this->sval != other.sval)
return false;
break;
case type_tag::fdouble:
if (cmp_numeric) {
const std::vector<double>& this_data = this->dval;
const std::vector<double>& other_data = other.dval;
for (size_t i=0; i < this_data.size(); i++) {
if (!double_equal( this_data[i] , other_data[i], rel_eps, abs_eps))
return false;
}
} else {
if (this->dval != other.dval)
return false;
}
break;
default:
break;
}
return true;
}
bool DeckItem::operator==(const DeckItem& other) const {
bool cmp_default = false;
bool cmp_numeric = true;
return this->equal( other , cmp_default, cmp_numeric);
}
bool DeckItem::operator!=(const DeckItem& other) const {
return !(*this == other);
}
/*
* Explicit template instantiations. These must be manually maintained and
* updated with changes in DeckItem so that code is emitted.

View File

@ -120,5 +120,35 @@ namespace Opm {
return this->getDataRecord().getDataItem().getSIDoubleData();
}
bool DeckKeyword::equal_data(const DeckKeyword& other, bool cmp_default, bool cmp_numeric) const {
if (this->size() != other.size())
return false;
for (size_t index = 0; index < this->size(); index++) {
const auto& this_record = this->getRecord( index );
const auto& other_record = other.getRecord( index );
if (!this_record.equal( other_record , cmp_default, cmp_numeric))
return false;
}
return true;
}
bool DeckKeyword::equal(const DeckKeyword& other, bool cmp_default, bool cmp_numeric) const {
if (this->name() != other.name())
return false;
return this->equal_data(other, cmp_default, cmp_numeric);
}
bool DeckKeyword::operator==(const DeckKeyword& other) const {
bool cmp_default = false;
bool cmp_numeric = true;
return this->equal( other , cmp_default, cmp_numeric);
}
bool DeckKeyword::operator!=(const DeckKeyword& other) const {
return !(*this == other);
}
}

View File

@ -130,4 +130,27 @@ namespace Opm {
return this->m_items.end();
}
bool DeckRecord::equal(const DeckRecord& other, bool cmp_default, bool cmp_numeric) const {
if (this->size() != other.size())
return false;
for (size_t index = 0; index < this->size(); index++) {
const auto& this_item = this->getItem( index );
const auto& other_item = other.getItem( index );
if (!this_item.equal( other_item , cmp_default, cmp_numeric))
return false;
}
return true;
}
bool DeckRecord::operator==(const DeckRecord& other) const {
bool cmp_default = false;
bool cmp_numeric = true;
return this->equal( other , cmp_default, cmp_numeric);
}
bool DeckRecord::operator!=(const DeckRecord& other) const {
return !(*this == other);
}
}

View File

@ -597,3 +597,36 @@ ABC";
BOOST_CHECK_EQUAL( expected, s.str());
}
BOOST_AUTO_TEST_CASE(DeckItemEqual) {
DeckItem item1("TEST1" , int());
DeckItem item2("TEST2" , int());
DeckItem item3("TEST1" , double());
DeckItem item4("TEST1" , int());
DeckItem item5("TEST1" , double());
BOOST_CHECK( item1 != item2 );
BOOST_CHECK( item1 != item3 );
BOOST_CHECK( item1 == item1 );
BOOST_CHECK( item1 == item4 );
item4.push_back(100);
BOOST_CHECK( item1 != item4 );
item1.push_back(100);
BOOST_CHECK( item1 == item4 );
item4.push_backDefault( 200 );
item1.push_back( 200 );
BOOST_CHECK( item1 == item4 );
BOOST_CHECK( !item1.equal( item4 , true , true));
item3.push_back(1.0);
item5.push_back(1.0);
BOOST_CHECK( item3.equal( item5 , false, true ));
BOOST_CHECK( item3.equal( item5 , false, false ));
item3.push_back(1.0);
item5.push_back(1.0 - 1e-8);
BOOST_CHECK( item3.equal( item5 , false, true ));
BOOST_CHECK( !item3.equal( item5 , false, false ));
}