2016-07-21 16:01:50 +02:00
/*
Copyright 2016 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
2018-09-07 12:46:42 +02:00
#include "EclFilesComparator.hpp"
2019-05-02 15:01:20 +02:00
2016-07-21 16:01:50 +02:00
#include <opm/common/ErrorMacros.hpp>
2019-05-02 15:01:20 +02:00
#include <opm/io/eclipse/EGrid.hpp>
2016-07-21 16:01:50 +02:00
2016-10-23 23:22:52 +02:00
#include <stdio.h>
2016-07-21 16:01:50 +02:00
#include <algorithm>
2016-08-01 15:47:23 +02:00
#include <cmath>
2019-05-02 15:01:20 +02:00
#include <iostream>
#include <iomanip>
2016-08-01 15:47:23 +02:00
#include <numeric>
2019-05-02 15:01:20 +02:00
#include <set>
2019-05-14 14:12:42 +02:00
#include <type_traits>
2019-05-02 15:01:20 +02:00
#include <vector>
2016-08-04 14:03:45 +02:00
2017-02-16 15:51:11 +01:00
// helper macro to handle error throws or not
#define HANDLE_ERROR(type, message) \
{ \
if (throwOnError) \
OPM_THROW(type, message); \
else { \
std::cerr << message << std::endl; \
++num_errors; \
} \
}
2019-05-24 15:26:01 +02:00
using Opm :: EclIO :: EGrid ;
2017-02-16 15:51:11 +01:00
2019-04-01 09:07:59 +02:00
template < typename T >
2019-05-02 15:01:20 +02:00
void ECLFilesComparator :: printValuesForCell ( const std :: string & keyword , const std :: string & reference , size_t kw_size , size_t cell , EGrid * grid , const T & value1 , const T & value2 ) const {
2019-04-01 09:07:59 +02:00
if ( grid ) {
2019-07-10 09:00:13 +02:00
int nActive = grid -> activeCells ();
int nTot = grid -> totalNumberOfCells ();
2016-07-21 16:01:50 +02:00
2019-07-10 09:00:13 +02:00
if ( static_cast < int > ( kw_size ) == nActive ) {
auto ijk = grid -> ijk_from_active_index ( cell );
2016-07-21 16:01:50 +02:00
2019-07-10 09:00:13 +02:00
ijk [ 0 ] ++ , ijk [ 1 ] ++ , ijk [ 2 ] ++ ;
2016-07-21 16:01:50 +02:00
2019-07-10 09:00:13 +02:00
std :: cout << std :: endl
<< " \n Keyword: " << keyword << ", origin " << reference << " \n "
<< "Global index (zero based) = " << cell << " \n "
<< "Grid coordinate = (" << ijk [ 0 ] << ", " << ijk [ 1 ] << ", " << ijk [ 2 ] << ")" << " \n "
<< "(first value, second value) = (" << value1 << ", " << value2 << ") \n\n " ;
return ;
}
2018-04-20 10:40:00 +02:00
2019-07-10 09:00:13 +02:00
if ( static_cast < int > ( kw_size ) == nTot ) {
2019-04-01 09:07:59 +02:00
2019-07-10 09:00:13 +02:00
auto ijk = grid -> ijk_from_global_index ( cell );
2019-04-01 09:07:59 +02:00
2019-07-10 09:00:13 +02:00
ijk [ 0 ] ++ , ijk [ 1 ] ++ , ijk [ 2 ] ++ ;
2019-04-01 09:07:59 +02:00
2019-07-10 09:00:13 +02:00
std :: cout << std :: endl
<< " \n Keyword: " << keyword << ", origin " << reference << " \n\n "
<< "Global index (zero based) = " << cell << " \n "
<< "Grid coordinate = (" << ijk [ 0 ] << ", " << ijk [ 1 ] << ", " << ijk [ 2 ] << ")" << " \n "
<< "(first value, second value) = (" << value1 << ", " << value2 << ") \n\n " ;
return ;
}
2018-04-20 10:40:00 +02:00
}
2016-08-04 14:03:45 +02:00
std :: cout << std :: endl
2019-04-01 09:07:59 +02:00
<< " \n Keyword: " << keyword << ", origin " << reference << " \n\n "
2018-04-20 10:40:00 +02:00
<< "Value index = " << cell << " \n "
2016-08-04 14:03:45 +02:00
<< "(first value, second value) = (" << value1 << ", " << value2 << ") \n\n " ;
2016-07-21 16:01:50 +02:00
}
2018-04-20 10:40:00 +02:00
2019-05-02 15:01:20 +02:00
template void ECLFilesComparator :: printValuesForCell < bool > ( const std :: string & keyword , const std :: string & reference , size_t kw_size , size_t cell , EGrid * grid , const bool & value1 , const bool & value2 ) const ;
template void ECLFilesComparator :: printValuesForCell < int > ( const std :: string & keyword , const std :: string & reference , size_t kw_size , size_t cell , EGrid * grid , const int & value1 , const int & value2 ) const ;
template void ECLFilesComparator :: printValuesForCell < double > ( const std :: string & keyword , const std :: string & reference , size_t kw_size , size_t cell , EGrid * grid , const double & value1 , const double & value2 ) const ;
template void ECLFilesComparator :: printValuesForCell < std :: string > ( const std :: string & keyword , const std :: string & reference , size_t kw_size , size_t cell , EGrid * grid , const std :: string & value1 , const std :: string & value2 ) const ;
2019-05-14 14:12:42 +02:00
// Hack to work around case where std::vector<bool>::const_reference is not a bool. If it is we will initialize printValuesForCell<char> otherwise printValuesForCell<std::vector<bool>::const_reference>
using boolConstReference = typename std :: vector < bool >:: const_reference ;
using boolTypeHelper = typename std :: remove_const < typename std :: remove_reference < boolConstReference >:: type >:: type ;
using boolType = typename std :: conditional < std :: is_same < boolTypeHelper , bool >:: value , char , boolTypeHelper >:: type ;
2019-05-02 15:01:20 +02:00
template void ECLFilesComparator :: printValuesForCell < boolType > ( const std :: string & keyword , const std :: string & reference , size_t kw_size , size_t cell , EGrid * grid , const boolType & value1 , const boolType & value2 ) const ;
2016-07-21 16:01:50 +02:00
2019-04-01 09:07:59 +02:00
ECLFilesComparator :: ECLFilesComparator ( const std :: string & basename1 ,
2016-08-04 14:03:45 +02:00
const std :: string & basename2 ,
2016-09-23 15:02:36 +02:00
double absToleranceArg , double relToleranceArg ) :
2019-07-10 09:01:16 +02:00
rootName1 ( basename1 ), rootName2 ( basename2 ),
2019-04-01 09:07:59 +02:00
absTolerance ( absToleranceArg ), relTolerance ( relToleranceArg ) {
2016-07-21 16:01:50 +02:00
}
Deviation ECLFilesComparator :: calculateDeviations ( double val1 , double val2 ) {
val1 = std :: abs ( val1 );
val2 = std :: abs ( val2 );
Deviation deviation ;
if ( val1 != 0 || val2 != 0 ) {
deviation . abs = std :: abs ( val1 - val2 );
if ( val1 != 0 && val2 != 0 ) {
deviation . rel = deviation . abs / ( std :: max ( val1 , val2 ));
}
}
return deviation ;
}
double ECLFilesComparator :: median ( std :: vector < double > vec ) {
if ( vec . empty ()) {
return 0 ;
}
else {
2019-04-01 09:07:59 +02:00
size_t n = vec . size () / 2 ;
2019-05-02 15:01:20 +02:00
std :: nth_element ( vec . begin (), vec . begin () + n , vec . end ());
2016-07-21 16:01:50 +02:00
if ( vec . size () % 2 == 0 ) {
2019-04-01 09:07:59 +02:00
return 0.5 * ( vec [ n - 1 ] + vec [ n ]);
2016-07-21 16:01:50 +02:00
}
else {
return vec [ n ];
}
}
}
double ECLFilesComparator :: average ( const std :: vector < double >& vec ) {
if ( vec . empty ()) {
return 0 ;
}
double sum = std :: accumulate ( vec . begin (), vec . end (), 0.0 );
return sum / vec . size ();
}