2023-06-29 08:20:38 -05:00
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <limits>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
#define BOOST_TEST_MODULE TestTuningXXXMBE
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
|
|
|
|
|
|
struct Column : public std::vector<std::string> {
|
|
|
|
|
Column(const std::string& name_, const int size = 0, const int num_rows_estimate = 1000) :
|
|
|
|
|
std::vector<std::string>(size), name(name_)
|
|
|
|
|
{
|
|
|
|
|
this->reserve(num_rows_estimate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return vector of double values, invalid elements set to NaN
|
|
|
|
|
std::vector<double> dvalues() const {
|
|
|
|
|
std::vector<double> vec;
|
|
|
|
|
vec.reserve(this->size());
|
|
|
|
|
|
|
|
|
|
const auto& conv_func = [](const std::string& strval) {
|
|
|
|
|
double dval;
|
|
|
|
|
try {
|
|
|
|
|
dval = std::stod(strval);
|
|
|
|
|
} catch (std::invalid_argument& exc) {
|
|
|
|
|
dval = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
|
}
|
|
|
|
|
return dval;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::transform(this->cbegin(), this->cend(), std::back_inserter(vec), conv_func);
|
|
|
|
|
return vec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return vector of double values values, invalid elements set to std::numeric_limits<int>::min()
|
|
|
|
|
std::vector<int> ivalues() const {
|
|
|
|
|
std::vector<int> vec;
|
|
|
|
|
vec.reserve(this->size());
|
|
|
|
|
|
|
|
|
|
const auto& conv_func = [](const std::string& strval) {
|
|
|
|
|
int ival;
|
|
|
|
|
try {
|
2023-06-30 05:21:25 -05:00
|
|
|
|
ival = std::stoi(strval);
|
2023-06-29 08:20:38 -05:00
|
|
|
|
} catch (std::invalid_argument& exc) {
|
|
|
|
|
ival = std::numeric_limits<int>::min();
|
|
|
|
|
}
|
|
|
|
|
return ival;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::transform(this->cbegin(), this->cend(), std::back_inserter(vec), conv_func);
|
|
|
|
|
return vec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string name;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ColumnData {
|
|
|
|
|
ColumnData(const std::string& file_name, const int num_columns_estimate=20) {
|
|
|
|
|
raw_columns.reserve(num_columns_estimate);
|
|
|
|
|
load_file(file_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void load_file(const std::string& file_name) {
|
|
|
|
|
// Open file and read first line with column names
|
|
|
|
|
std::ifstream ifs(file_name);
|
|
|
|
|
std::string line, colname;
|
|
|
|
|
|
|
|
|
|
std::getline(ifs, line);
|
|
|
|
|
std::istringstream iss(line);
|
|
|
|
|
while (iss >> colname) {
|
|
|
|
|
column_names.push_back(colname);
|
|
|
|
|
raw_columns.emplace_back(colname);
|
|
|
|
|
columns[colname] = &(raw_columns.back());
|
|
|
|
|
}
|
|
|
|
|
const int num_columns = column_names.size();
|
|
|
|
|
|
|
|
|
|
// Read remaining lines into std::string vectors
|
|
|
|
|
int lineno = 1;
|
|
|
|
|
while (std::getline(ifs, line)) {
|
|
|
|
|
iss.str(line); iss.clear();
|
|
|
|
|
int i=0;
|
|
|
|
|
while (iss >> colname && i < num_columns) {
|
|
|
|
|
raw_columns[i].push_back(colname);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
2023-06-30 05:21:25 -05:00
|
|
|
|
if (i >= num_columns && iss >> colname) {
|
2023-06-29 08:20:38 -05:00
|
|
|
|
std::cout << "Warning: Ignoring extra column(s) on line " << lineno << std::endl;
|
|
|
|
|
}
|
|
|
|
|
++lineno;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get data vectors of different types
|
2023-06-30 05:21:25 -05:00
|
|
|
|
std::vector<double> get_dvector(const std::string& colname) const { return columns.at(colname)->dvalues(); }
|
|
|
|
|
std::vector<int> get_ivector(const std::string& colname) const { return columns.at(colname)->ivalues(); }
|
2023-06-29 08:20:38 -05:00
|
|
|
|
// Default is to return double values
|
2023-06-30 05:21:25 -05:00
|
|
|
|
std::vector<double> operator[](const std::string& colname) const { return columns.at(colname)->dvalues(); }
|
2023-06-29 08:20:38 -05:00
|
|
|
|
|
|
|
|
|
std::vector<std::string> column_names;
|
|
|
|
|
std::vector<Column> raw_columns;
|
|
|
|
|
std::map<std::string, Column*> columns;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(CheckMassBalanceWithinXXXMBE)
|
|
|
|
|
{
|
|
|
|
|
//std::string case_name(boost::unit_test::framework::master_test_suite().argv[1]);
|
|
|
|
|
std::string case_name("01_TUNING_XXXMBE");
|
|
|
|
|
std::string file_name = case_name + ".INFOITER";
|
|
|
|
|
|
|
|
|
|
ColumnData data(file_name);
|
|
|
|
|
auto rstep = data.get_ivector("ReportStep");
|
|
|
|
|
auto tstep = data.get_ivector("TimeStep");
|
|
|
|
|
auto mbo = data["MB_Oil"];
|
|
|
|
|
auto mbw = data["MB_Water"];
|
|
|
|
|
auto mbg = data["MB_Gas"];
|
|
|
|
|
|
|
|
|
|
const int num_reports = 1 + *std::max_element(rstep.begin(), rstep.end());
|
|
|
|
|
std::vector<double> max_mb;
|
|
|
|
|
max_mb.reserve(num_reports);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Find the maximum mass balance error at each converged time step for each report step..
|
|
|
|
|
const int nrows = rstep.size();
|
|
|
|
|
int rcur = 0;
|
|
|
|
|
int tcur = 0;
|
|
|
|
|
double max_mb_step = std::numeric_limits<double>::min();
|
|
|
|
|
for (int i=0; i<(nrows-1); ++i) {
|
|
|
|
|
if (tcur != tstep[i+1] || rcur != rstep[i+1]) {
|
|
|
|
|
max_mb_step = std::max({mbo[i], mbw[i], mbg[i], max_mb_step});
|
|
|
|
|
tcur = tstep[i+1];
|
|
|
|
|
}
|
|
|
|
|
if (rcur != rstep[i+1]) {
|
|
|
|
|
max_mb.push_back(max_mb_step);
|
|
|
|
|
max_mb_step = std::numeric_limits<double>::min();
|
|
|
|
|
rcur = rstep[i+1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
max_mb.push_back( std::max({mbo.back(), mbw.back(), mbg.back(), max_mb_step}) );
|
|
|
|
|
|
2023-06-30 05:21:25 -05:00
|
|
|
|
BOOST_TEST_MESSAGE("---------------------------------------------------------------------------");
|
|
|
|
|
BOOST_TEST_MESSAGE("Found the following converged max mass balance error (per report step):");
|
2023-06-29 08:20:38 -05:00
|
|
|
|
for (auto& val : max_mb)
|
2023-06-30 05:21:25 -05:00
|
|
|
|
BOOST_TEST_MESSAGE(val);
|
|
|
|
|
BOOST_TEST_MESSAGE("---------------------------------------------------------------------------");
|
2023-06-29 08:20:38 -05:00
|
|
|
|
|
|
|
|
|
|
2024-04-22 09:48:11 -05:00
|
|
|
|
BOOST_CHECK_MESSAGE( max_mb[0] < 1.0e-6, "max_mb[0] (= " << max_mb[0] << ") is not strictly less than 1.0e-6" );
|
|
|
|
|
BOOST_CHECK_MESSAGE( max_mb[1] < 1.0e-8, "max_mb[1] (= " << max_mb[1] << ") is not strictly less than 1.0e-8" );
|
|
|
|
|
BOOST_CHECK_MESSAGE( max_mb[2] < 1.0e-10, "max_mb[2] (= " << max_mb[1] << ") is not strictly less than 1.0e-10" );
|
2023-06-29 08:20:38 -05:00
|
|
|
|
|
|
|
|
|
}
|