Added DeckXXX::equal( ) method.
This commit is contained in:
parent
da55685b62
commit
1f646711d4
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 ));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user