Merge pull request #1452 from joakim-hove/eclstate-aquifer-aquancon
Eclstate aquifer aquancon
This commit is contained in:
@@ -287,10 +287,7 @@ if(ENABLE_ECL_INPUT)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferCTTests.cpp
|
||||
tests/parser/AquifetpTests.cpp
|
||||
tests/parser/AqudimsTests.cpp
|
||||
tests/parser/AquanconTests.cpp
|
||||
tests/parser/AquiferTests.cpp
|
||||
tests/parser/BoxTests.cpp
|
||||
tests/parser/ColumnSchemaTests.cpp
|
||||
tests/parser/ConnectionTests.cpp
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
implement the analytical aquifer models in OPM Flow.
|
||||
*/
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
@@ -34,44 +37,54 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
|
||||
namespace Opm {
|
||||
namespace{
|
||||
struct AquanconRecord;
|
||||
}
|
||||
|
||||
class Aquancon {
|
||||
public:
|
||||
|
||||
struct AquanconOutput{
|
||||
int aquiferID;
|
||||
std::vector<size_t> global_index;
|
||||
std::vector<std::shared_ptr<double>> influx_coeff; // Size = size(global_index)
|
||||
std::vector<double> influx_multiplier; // Size = size(global_index)
|
||||
std::vector<int> reservoir_face_dir; // Size = size(global_index)
|
||||
std::vector<int> record_index;
|
||||
};
|
||||
struct AquancCell {
|
||||
int aquiferID;
|
||||
std::size_t global_index;
|
||||
std::pair<bool, double> influx_coeff;
|
||||
double influx_mult;
|
||||
FaceDir::DirEnum face_dir;
|
||||
|
||||
AquancCell(int aquiferID_arg, std::size_t gi, const std::pair<bool, double>& ic, double im, FaceDir::DirEnum fd) :
|
||||
aquiferID(aquiferID_arg),
|
||||
global_index(gi),
|
||||
influx_coeff(ic),
|
||||
influx_mult(im),
|
||||
face_dir(fd)
|
||||
{}
|
||||
|
||||
AquancCell() = default;
|
||||
|
||||
bool operator==(const AquancCell& other) const {
|
||||
return this->aquiferID == other.aquiferID &&
|
||||
this->global_index == other.global_index &&
|
||||
this->influx_coeff == other.influx_coeff &&
|
||||
this->influx_mult == other.influx_mult &&
|
||||
this->face_dir == other.face_dir;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
Aquancon() = default;
|
||||
Aquancon(const EclipseGrid& grid, const Deck& deck);
|
||||
Aquancon(const std::unordered_map<int, std::vector<Aquancon::AquancCell>>& data);
|
||||
|
||||
const std::vector<Aquancon::AquanconOutput>& getAquOutput() const;
|
||||
const std::unordered_map<int, std::vector<Aquancon::AquancCell>>& data() const;
|
||||
bool operator==(const Aquancon& other) const;
|
||||
bool active() const;
|
||||
|
||||
const std::vector<Aquancon::AquancCell> operator[](int aquiferID) const;
|
||||
private:
|
||||
|
||||
static std::vector<Aquancon::AquanconOutput> logic_application(const std::vector<Aquancon::AquanconOutput>& original_vector);
|
||||
|
||||
static void collate_function(std::vector<Aquancon::AquanconOutput>& output_vector,
|
||||
std::vector<Opm::AquanconRecord>& m_aqurecord,
|
||||
const std::vector<int>& m_aquiferID_per_record, int m_maxAquID);
|
||||
|
||||
static void convert_record_id_to_aquifer_id(std::vector<int>& record_indices_matching_id, int i,
|
||||
const std::vector<int>& m_aquiferID_per_record);
|
||||
|
||||
// for a cell to be inside reservoir, its indices need to be within the reservoir grid dimension range,
|
||||
// and it needs to be active
|
||||
static bool cellInsideReservoirAndActive(const EclipseGrid& grid, int i, int j, int k);
|
||||
|
||||
static bool neighborCellInsideReservoirAndActive(const EclipseGrid& grid, int i, int j, int k, FaceDir::DirEnum faceDir);
|
||||
|
||||
std::vector<Aquancon::AquanconOutput> m_aquoutput;
|
||||
|
||||
std::unordered_map<int, std::vector<Aquancon::AquancCell>> cells;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,23 @@ namespace Opm {
|
||||
struct AQUCT_data{
|
||||
|
||||
AQUCT_data(const DeckRecord& record, const TableManager& tables);
|
||||
AQUCT_data() = default;
|
||||
AQUCT_data(int aqID,
|
||||
int infID,
|
||||
int pvtID,
|
||||
double phi_aq_,
|
||||
double d0_,
|
||||
double C_t_,
|
||||
double r_o_,
|
||||
double k_a_,
|
||||
double c1_,
|
||||
double h_,
|
||||
double theta_,
|
||||
double c2_,
|
||||
const std::pair<bool, double>& p0_,
|
||||
const std::vector<double>& td_,
|
||||
const std::vector<double>& pi_,
|
||||
const std::vector<int>& cell_id_);
|
||||
|
||||
int aquiferID;
|
||||
int inftableID, pvttableID;
|
||||
@@ -67,7 +84,7 @@ namespace Opm {
|
||||
|
||||
bool operator==(const AQUCT_data& other) const;
|
||||
};
|
||||
|
||||
AquiferCT() = default;
|
||||
AquiferCT(const TableManager& tables, const Deck& deck);
|
||||
AquiferCT(const std::vector<AquiferCT::AQUCT_data>& data);
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ class Aquifetp {
|
||||
|
||||
struct AQUFETP_data{
|
||||
AQUFETP_data(const DeckRecord& record);
|
||||
AQUFETP_data() = default;
|
||||
AQUFETP_data(int aquiferID_, int pvttableID_, double J_, double C_t_, double V0_, double d0_, const std::pair<bool, double>& p0_);
|
||||
bool operator==(const AQUFETP_data& other) const;
|
||||
|
||||
int aquiferID;
|
||||
@@ -49,6 +51,7 @@ class Aquifetp {
|
||||
std::pair<bool, double> p0;
|
||||
};
|
||||
|
||||
Aquifetp() = default;
|
||||
Aquifetp(const Deck& deck);
|
||||
Aquifetp(const std::vector<Aquifetp::AQUFETP_data>& data);
|
||||
const std::vector<Aquifetp::AQUFETP_data>& data() const;
|
||||
|
||||
@@ -18,107 +18,100 @@
|
||||
*/
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Aquancon.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
|
||||
namespace Opm {
|
||||
namespace{
|
||||
struct AquanconRecord{
|
||||
std::vector<size_t> global_index_per_record;
|
||||
|
||||
// Variables constants
|
||||
std::vector<std::shared_ptr<double>> influx_coeff_per_record; //Aquifer influx coefficient
|
||||
std::vector<double> influx_mult_per_record; //Aquifer influx coefficient Multiplier
|
||||
// Cell face to connect aquifer to
|
||||
std::vector<int> face_per_record;
|
||||
std::vector<int> record_index_per_record;
|
||||
};
|
||||
namespace{
|
||||
|
||||
void add_cell(std::unordered_map<std::size_t, Aquancon::AquancCell>& work, Aquancon::AquancCell cell) {
|
||||
auto cell_iter = work.find(cell.global_index);
|
||||
if (cell_iter == work.end())
|
||||
work.insert( std::make_pair(cell.global_index, std::move(cell)));
|
||||
else {
|
||||
auto& prev_cell = cell_iter->second;
|
||||
if (prev_cell.aquiferID == cell.aquiferID) {
|
||||
if (prev_cell.influx_coeff.first != cell.influx_coeff.first)
|
||||
throw std::invalid_argument("Can not combine defaulted and not defaulted influx coefficient");
|
||||
|
||||
if (prev_cell.influx_coeff.first) {
|
||||
if (cell.influx_coeff.second == 0)
|
||||
prev_cell.influx_coeff.second = 0;
|
||||
else
|
||||
prev_cell.influx_coeff.second += cell.influx_coeff.second;
|
||||
}
|
||||
} else {
|
||||
std::string msg = "Cell with global index: " + std::to_string(cell.global_index) + " is already connected to Aquifer: " + std::to_string(prev_cell.aquiferID);
|
||||
throw std::invalid_argument( msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Aquancon::Aquancon(const EclipseGrid& grid, const Deck& deck)
|
||||
{
|
||||
if (!deck.hasKeyword("AQUANCON"))
|
||||
return;
|
||||
std::unordered_map<std::size_t, Aquancon::AquancCell> work;
|
||||
for (std::size_t iaq = 0; iaq < deck.count("AQUANCON"); iaq++) {
|
||||
const auto& aquanconKeyword = deck.getKeyword("AQUANCON", iaq);
|
||||
for (const auto& aquanconRecord : aquanconKeyword) {
|
||||
const int aquiferID = aquanconRecord.getItem("AQUIFER_ID").get<int>(0);
|
||||
const int i1 = aquanconRecord.getItem("I1").get<int>(0) - 1;
|
||||
const int i2 = aquanconRecord.getItem("I2").get<int>(0) - 1;
|
||||
const int j1 = aquanconRecord.getItem("J1").get<int>(0) - 1;
|
||||
const int j2 = aquanconRecord.getItem("J2").get<int>(0) - 1;
|
||||
const int k1 = aquanconRecord.getItem("K1").get<int>(0) - 1;
|
||||
const int k2 = aquanconRecord.getItem("K2").get<int>(0) - 1;
|
||||
const double influx_mult = aquanconRecord.getItem("INFLUX_MULT").getSIDouble(0);
|
||||
const FaceDir::DirEnum faceDir
|
||||
= FaceDir::FromString(aquanconRecord.getItem("FACE").getTrimmedString(0));
|
||||
|
||||
std::vector<Opm::AquanconRecord> aqurecords;
|
||||
// Aquifer ID per record
|
||||
std::vector<int> aquiferID_per_record;
|
||||
int m_maxAquID = 0;
|
||||
const std::string& str_inside_reservoir
|
||||
= aquanconRecord.getItem("CONNECT_ADJOINING_ACTIVE_CELL").getTrimmedString(0);
|
||||
const bool allow_aquifer_inside_reservoir = DeckItem::to_bool(str_inside_reservoir);
|
||||
|
||||
const auto& aquanconKeyword = deck.getKeyword("AQUANCON");
|
||||
// Resize the parameter vector container based on row entries in aquancon
|
||||
aqurecords.resize(aquanconKeyword.size());
|
||||
aquiferID_per_record.resize(aquanconKeyword.size());
|
||||
// Loop over the cartesian indices to convert to the global grid index
|
||||
for (int k = k1; k <= k2; k++) {
|
||||
for (int j = j1; j <= j2; j++) {
|
||||
for (int i = i1; i <= i2; i++) {
|
||||
if (grid.cellActive(i, j, k)) { // the cell itself needs to be active
|
||||
if (allow_aquifer_inside_reservoir
|
||||
|| !neighborCellInsideReservoirAndActive(grid, i, j, k, faceDir)) {
|
||||
std::pair<bool, double> influx_coeff = std::make_pair(false, 0);
|
||||
auto global_index = grid.getGlobalIndex(i, j, k);
|
||||
if (aquanconRecord.getItem("INFLUX_COEFF").hasValue(0))
|
||||
influx_coeff = std::make_pair(
|
||||
true, aquanconRecord.getItem("INFLUX_COEFF").getSIDouble(0));
|
||||
|
||||
for (size_t aquanconRecordIdx = 0; aquanconRecordIdx < aquanconKeyword.size(); ++aquanconRecordIdx)
|
||||
{
|
||||
const auto& aquanconRecord = aquanconKeyword.getRecord(aquanconRecordIdx);
|
||||
aquiferID_per_record[aquanconRecordIdx] = aquanconRecord.getItem("AQUIFER_ID").template get<int>(0);
|
||||
|
||||
// offset the indices
|
||||
const int i1 = aquanconRecord.getItem("I1").template get<int>(0) - 1;
|
||||
const int i2 = aquanconRecord.getItem("I2").template get<int>(0) - 1;
|
||||
const int j1 = aquanconRecord.getItem("J1").template get<int>(0) - 1;
|
||||
const int j2 = aquanconRecord.getItem("J2").template get<int>(0) - 1;
|
||||
const int k1 = aquanconRecord.getItem("K1").template get<int>(0) - 1;
|
||||
const int k2 = aquanconRecord.getItem("K2").template get<int>(0) - 1;
|
||||
|
||||
m_maxAquID = (m_maxAquID < aquiferID_per_record[aquanconRecordIdx] )?
|
||||
aquiferID_per_record[aquanconRecordIdx] : m_maxAquID;
|
||||
|
||||
const FaceDir::DirEnum faceDir = FaceDir::FromString(aquanconRecord.getItem("FACE").getTrimmedString(0));
|
||||
|
||||
// whether allow aquifer connections to locate inside reservoir
|
||||
const std::string& str_inside_reservoir = aquanconRecord.getItem("CONNECT_ADJOINING_ACTIVE_CELL").getTrimmedString(0);
|
||||
// not sure whether we should give a warning when input other than "YES" or "NO"
|
||||
const bool allow_aquifer_inside_reservoir = str_inside_reservoir == "YES" ? true : false;
|
||||
|
||||
auto& aqurecord = aqurecords[aquanconRecordIdx];
|
||||
// Loop over the cartesian indices to convert to the global grid index
|
||||
for (int k = k1; k <= k2; k++) {
|
||||
for (int j = j1; j <= j2; j++) {
|
||||
for (int i = i1; i <= i2; i++) {
|
||||
if ( grid.cellActive(i, j, k) ) { // the cell itself needs to be active
|
||||
if ( allow_aquifer_inside_reservoir
|
||||
|| !neighborCellInsideReservoirAndActive(grid, i, j, k, faceDir) ) {
|
||||
aqurecord.global_index_per_record.push_back(grid.getGlobalIndex(i, j, k));
|
||||
}
|
||||
AquancCell cell(aquiferID, global_index, influx_coeff, influx_mult, faceDir);
|
||||
add_cell(work, cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const size_t global_index_per_record_size = aqurecord.global_index_per_record.size();
|
||||
|
||||
aqurecord.influx_coeff_per_record.resize(global_index_per_record_size, nullptr);
|
||||
|
||||
if (aquanconRecord.getItem("INFLUX_COEFF").hasValue(0))
|
||||
{
|
||||
const double influx_coeff = aquanconRecord.getItem("INFLUX_COEFF").getSIDouble(0);
|
||||
|
||||
for (auto& influx: aqurecord.influx_coeff_per_record)
|
||||
{
|
||||
influx.reset(new double(influx_coeff));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const double influx_mult = aquanconRecord.getItem("INFLUX_MULT").getSIDouble(0);
|
||||
|
||||
aqurecord.influx_mult_per_record.resize(global_index_per_record_size, influx_mult);
|
||||
aqurecord.face_per_record.resize(global_index_per_record_size, faceDir);
|
||||
aqurecord.record_index_per_record.resize(global_index_per_record_size, aquanconRecordIdx);
|
||||
}
|
||||
|
||||
// Collate_function
|
||||
collate_function(m_aquoutput, aqurecords, aquiferID_per_record, m_maxAquID);
|
||||
for (const auto& gi_cell : work) {
|
||||
const auto& cell = gi_cell.second;
|
||||
|
||||
// Logic for grid connection applied here
|
||||
m_aquoutput = logic_application(m_aquoutput);
|
||||
this->cells[cell.aquiferID].emplace_back(std::move(cell));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const std::vector<Aquancon::AquancCell> Aquancon::operator[](int aquiferID) const {
|
||||
return this->cells.at( aquiferID );
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Aquancon::cellInsideReservoirAndActive(const Opm::EclipseGrid& grid, const int i, const int j, const int k)
|
||||
{
|
||||
if ( i < 0 || j < 0 || k < 0
|
||||
@@ -153,167 +146,22 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
// This function is used to convert from a per record vector to a per aquifer ID vector.
|
||||
void Aquancon::collate_function(std::vector<Aquancon::AquanconOutput>& output_vector,
|
||||
std::vector<Opm::AquanconRecord>& aqurecords,
|
||||
const std::vector<int>& aquiferID_per_record,
|
||||
const int m_maxAquID)
|
||||
{
|
||||
output_vector.resize(m_maxAquID);
|
||||
// Find record indices at which the aquifer ids are located in
|
||||
for (int i = 1; i <= m_maxAquID; ++i)
|
||||
{
|
||||
std::vector<int> result_id;
|
||||
|
||||
convert_record_id_to_aquifer_id(result_id, i, aquiferID_per_record);
|
||||
Aquancon::Aquancon(const std::unordered_map<int, std::vector<Aquancon::AquancCell>>& data) :
|
||||
cells(data)
|
||||
{}
|
||||
|
||||
// We add the aquifer id into each element of output_vector
|
||||
output_vector.at(i - 1).aquiferID = i;
|
||||
for ( auto record_index_matching_id : result_id)
|
||||
{
|
||||
// This is for the global indices
|
||||
output_vector.at(i - 1).global_index.insert(
|
||||
output_vector.at(i - 1).global_index.end(),
|
||||
aqurecords.at(record_index_matching_id).global_index_per_record.begin(),
|
||||
aqurecords.at(record_index_matching_id).global_index_per_record.end()
|
||||
);
|
||||
// This is for the influx_coeff
|
||||
output_vector.at(i - 1).influx_coeff.insert(
|
||||
output_vector.at(i - 1).influx_coeff.end(),
|
||||
aqurecords.at(record_index_matching_id).influx_coeff_per_record.begin(),
|
||||
aqurecords.at(record_index_matching_id).influx_coeff_per_record.end()
|
||||
);
|
||||
// This is for the influx_multiplier
|
||||
output_vector.at(i - 1).influx_multiplier.insert(
|
||||
output_vector.at(i - 1).influx_multiplier.end(),
|
||||
aqurecords.at(record_index_matching_id).influx_mult_per_record.begin(),
|
||||
aqurecords.at(record_index_matching_id).influx_mult_per_record.end()
|
||||
);
|
||||
// This is for the reservoir_face_dir
|
||||
output_vector.at(i - 1).reservoir_face_dir.insert(
|
||||
output_vector.at(i - 1).reservoir_face_dir.end(),
|
||||
aqurecords.at(record_index_matching_id).face_per_record.begin(),
|
||||
aqurecords.at(record_index_matching_id).face_per_record.end()
|
||||
);
|
||||
// This is for the record index in order for us to know which one is updated
|
||||
output_vector.at(i - 1).record_index.insert(
|
||||
output_vector.at(i - 1).record_index.end(),
|
||||
aqurecords.at(record_index_matching_id).record_index_per_record.begin(),
|
||||
aqurecords.at(record_index_matching_id).record_index_per_record.end()
|
||||
);
|
||||
}
|
||||
}
|
||||
const std::unordered_map<int, std::vector<Aquancon::AquancCell>>& Aquancon::data() const {
|
||||
return this->cells;
|
||||
}
|
||||
|
||||
std::vector<Aquancon::AquanconOutput> Aquancon::logic_application(const std::vector<Aquancon::AquanconOutput>& original_vector)
|
||||
{
|
||||
std::vector<Aquancon::AquanconOutput> output_vector = original_vector;
|
||||
|
||||
// Create a local struct to couple each element for easy sorting
|
||||
struct pair_elements
|
||||
{
|
||||
size_t global_index;
|
||||
std::shared_ptr<double> influx_coeff;
|
||||
double influx_multiplier;
|
||||
int reservoir_face_dir;
|
||||
int record_index;
|
||||
};
|
||||
|
||||
|
||||
// Iterate through each aquifer IDs (This is because each element in the original vector represents an aquifer ID)
|
||||
for (auto aquconvec = output_vector.begin(); aquconvec != output_vector.end(); ++aquconvec)
|
||||
{
|
||||
// Create a working buffer
|
||||
std::vector<pair_elements> working_buffer;
|
||||
for (size_t i = 0; i < aquconvec->global_index.size(); ++i )
|
||||
working_buffer.push_back( { aquconvec->global_index[i],
|
||||
aquconvec->influx_coeff[i],
|
||||
aquconvec->influx_multiplier[i],
|
||||
aquconvec->reservoir_face_dir[i],
|
||||
aquconvec->record_index[i]});
|
||||
|
||||
|
||||
// Sort by ascending order the working_buffer vector in order of priority:
|
||||
// 1) global_index, then 2) record_index
|
||||
|
||||
std::sort( working_buffer.begin(),
|
||||
working_buffer.end(),
|
||||
[](pair_elements& element1, pair_elements& element2) -> bool
|
||||
{
|
||||
if (element1.global_index == element2.global_index)
|
||||
{
|
||||
return element1.record_index < element2.record_index;
|
||||
}
|
||||
else
|
||||
return element1.global_index < element2.global_index;
|
||||
}
|
||||
);
|
||||
|
||||
// We then proceed to obtain unique elements of the global_index, and we apply the
|
||||
// following behaviour (as mentioned in the Eclipse 2014.1 Reference Manual p.345):
|
||||
// If a reservoir cell is defined more than once, its previous value for the
|
||||
// aquifer influx coefficient is added to the present value.
|
||||
|
||||
auto i2 = std::unique( working_buffer.begin(),
|
||||
working_buffer.end(),
|
||||
[](pair_elements& element1, pair_elements& element2) -> bool
|
||||
{
|
||||
// Not entirely clear for the manual; but it would seem
|
||||
// natural that this equality check also included the face?
|
||||
if (element1.global_index == element2.global_index)
|
||||
{
|
||||
if (element1.influx_coeff && element2.influx_coeff)
|
||||
*(element1.influx_coeff) += *(element2.influx_coeff);
|
||||
else {
|
||||
if (element1.influx_coeff || element2.influx_coeff)
|
||||
throw std::invalid_argument("Sorry - can not combine defaulted and not default AQUANCON records");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
working_buffer.resize( std::distance(working_buffer.begin(),i2) );
|
||||
|
||||
// We now resize and fill the output_vector elements
|
||||
aquconvec->global_index.resize(working_buffer.size());
|
||||
aquconvec->influx_coeff.resize(working_buffer.size());
|
||||
aquconvec->influx_multiplier.resize(working_buffer.size());
|
||||
aquconvec->reservoir_face_dir.resize(working_buffer.size());
|
||||
aquconvec->record_index.resize(working_buffer.size());
|
||||
for (size_t i = 0; i < working_buffer.size(); ++i)
|
||||
{
|
||||
aquconvec->global_index.at(i) = working_buffer.at(i).global_index;
|
||||
aquconvec->influx_coeff.at(i) = working_buffer.at(i).influx_coeff;
|
||||
aquconvec->influx_multiplier.at(i) = working_buffer.at(i).influx_multiplier;
|
||||
aquconvec->reservoir_face_dir.at(i) = working_buffer.at(i).reservoir_face_dir;
|
||||
aquconvec->record_index.at(i) = working_buffer.at(i).record_index;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return output_vector;
|
||||
bool Aquancon::operator==(const Aquancon& other) const {
|
||||
return this->cells == other.cells;
|
||||
}
|
||||
|
||||
void Aquancon::convert_record_id_to_aquifer_id(std::vector<int>& record_indices_matching_id,
|
||||
const int i, const std::vector<int>& aquiferID_per_record)
|
||||
{
|
||||
auto it = std::find_if( aquiferID_per_record.begin(), aquiferID_per_record.end(),
|
||||
[&](int id) {
|
||||
return id == i;
|
||||
}
|
||||
);
|
||||
while (it != aquiferID_per_record.end()) {
|
||||
record_indices_matching_id.emplace_back(std::distance(aquiferID_per_record.begin(), it));
|
||||
it = std::find_if(std::next(it), aquiferID_per_record.end(), [&](int id){return id == i;});
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Aquancon::AquanconOutput>& Aquancon::getAquOutput() const
|
||||
{
|
||||
return m_aquoutput;
|
||||
bool Aquancon::active() const {
|
||||
return !this->cells.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ bool AquiferCT::AQUCT_data::operator==(const AquiferCT::AQUCT_data& other) const
|
||||
this->inftableID == other.inftableID &&
|
||||
this->pvttableID == other.pvttableID &&
|
||||
this->phi_aq == other.phi_aq &&
|
||||
this->d0 == other.d0 &&
|
||||
this->C_t == other.C_t &&
|
||||
this->r_o == other.r_o &&
|
||||
this->k_a == other.k_a &&
|
||||
@@ -96,6 +97,40 @@ bool AquiferCT::AQUCT_data::operator==(const AquiferCT::AQUCT_data& other) const
|
||||
this->cell_id == other.cell_id;
|
||||
}
|
||||
|
||||
AquiferCT::AQUCT_data::AQUCT_data(int aqID,
|
||||
int infID,
|
||||
int pvtID,
|
||||
double phi_aq_,
|
||||
double d0_,
|
||||
double C_t_,
|
||||
double r_o_,
|
||||
double k_a_,
|
||||
double c1_,
|
||||
double h_,
|
||||
double theta_,
|
||||
double c2_,
|
||||
const std::pair<bool, double>& p0_,
|
||||
const std::vector<double>& td_,
|
||||
const std::vector<double>& pi_,
|
||||
const std::vector<int>& cell_id_) :
|
||||
aquiferID(aqID),
|
||||
inftableID(infID),
|
||||
pvttableID(pvtID),
|
||||
phi_aq(phi_aq_),
|
||||
d0(d0_),
|
||||
C_t(C_t_),
|
||||
r_o(r_o_),
|
||||
k_a(k_a_),
|
||||
c1(c1_),
|
||||
h(h_),
|
||||
theta(theta_),
|
||||
c2(c2_),
|
||||
p0(p0_),
|
||||
td(td_),
|
||||
pi(pi_),
|
||||
cell_id(cell_id_)
|
||||
{}
|
||||
|
||||
AquiferCT::AquiferCT(const TableManager& tables, const Deck& deck)
|
||||
{
|
||||
using AQUCT = ParserKeywords::AQUCT;
|
||||
|
||||
@@ -52,6 +52,18 @@ bool Aquifetp::AQUFETP_data::operator==(const Aquifetp::AQUFETP_data& other) con
|
||||
this->p0 == other.p0;
|
||||
}
|
||||
|
||||
|
||||
Aquifetp::AQUFETP_data::AQUFETP_data(int aquiferID_, int pvttableID_, double J_, double C_t_, double V0_, double d0_, const std::pair<bool, double>& p0_) :
|
||||
aquiferID(aquiferID_),
|
||||
pvttableID(pvttableID_),
|
||||
J(J_),
|
||||
C_t(C_t_),
|
||||
V0(V0_),
|
||||
d0(d0_),
|
||||
p0(p0_)
|
||||
{}
|
||||
|
||||
|
||||
Aquifetp::Aquifetp(const std::vector<Aquifetp::AQUFETP_data>& data) :
|
||||
m_aqufetp(data)
|
||||
{}
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 TNO.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE AquanconTest
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Aquancon.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
inline Deck createAQUANCONDeck_DEFAULT_INFLUX2() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 2 2 1 1 1 1 J- 1.0 /\n"
|
||||
" 1 2 2 1 1 1 1 J- /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
|
||||
inline Deck createAQUANCONDeck_DEFAULT_INFLUX1() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 1 1 1 1 1 J- /\n"
|
||||
" 1 1 1 1 1 1 1 J- /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAQUANCONDeck() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 1 1 1 1 1 J- 1.0 1.0 NO /\n"
|
||||
" 1 1 3 1 3 3 3 I+ 0.5 1.0 NO /\n"
|
||||
" 1 1 3 1 3 3 3 J+ 0.75 1.0 NO /\n"
|
||||
" 1 1 3 1 3 3 3 J- 2.75 1.0 NO /\n"
|
||||
" 1 2 3 2 3 1 1 I+ 2.75 1.0 NO /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline std::vector<Aquancon::AquanconOutput> init_aquancon(){
|
||||
auto deck = createAQUANCONDeck();
|
||||
EclipseState eclState( deck );
|
||||
Aquancon aqucon( eclState.getInputGrid(), deck);
|
||||
std::vector<Aquancon::AquanconOutput> aquifers = aqucon.getAquOutput();
|
||||
|
||||
return aquifers;
|
||||
}
|
||||
|
||||
inline std::vector<Aquancon::AquanconOutput> fill_result(){
|
||||
auto deck = createAQUANCONDeck();
|
||||
EclipseState eclState( deck );
|
||||
Aquancon aqucon( eclState.getInputGrid(), deck);
|
||||
std::vector<Aquancon::AquanconOutput> aquifers = aqucon.getAquOutput();
|
||||
|
||||
return aquifers;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquanconTest){
|
||||
std::vector< Aquancon::AquanconOutput > aquifers = init_aquancon();
|
||||
std::vector< Aquancon::AquanconOutput > expected_output = fill_result();
|
||||
|
||||
BOOST_CHECK_EQUAL(aquifers.size(), expected_output.size());
|
||||
for (size_t i = 0; i < aquifers.size(); ++i)
|
||||
{
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( aquifers.at(i).global_index.begin(), aquifers.at(i).global_index.end(),
|
||||
expected_output.at(i).global_index.begin(), expected_output.at(i).global_index.end() );
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( aquifers.at(i).influx_multiplier.begin(), aquifers.at(i).influx_multiplier.end(),
|
||||
expected_output.at(i).influx_multiplier.begin(), expected_output.at(i).influx_multiplier.end() );
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( aquifers.at(i).reservoir_face_dir.begin(), aquifers.at(i).reservoir_face_dir.end(),
|
||||
expected_output.at(i).reservoir_face_dir.begin(), expected_output.at(i).reservoir_face_dir.end() );
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( aquifers.at(i).record_index.begin(), aquifers.at(i).record_index.end(),
|
||||
expected_output.at(i).record_index.begin(), expected_output.at(i).record_index.end() );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquanconTest_DEFAULT_INFLUX) {
|
||||
auto deck1 = createAQUANCONDeck_DEFAULT_INFLUX1();
|
||||
EclipseState eclState1( deck1 );
|
||||
BOOST_CHECK_NO_THROW(Aquancon( eclState1.getInputGrid(), deck1));
|
||||
|
||||
auto deck2 = createAQUANCONDeck_DEFAULT_INFLUX2();
|
||||
EclipseState eclState2( deck2 );
|
||||
BOOST_CHECK_THROW(Aquancon( eclState2.getInputGrid(), deck2), std::invalid_argument);
|
||||
}
|
||||
|
||||
// allowing aquifer exists inside the reservoir
|
||||
inline Deck createAQUANCONDeck_ALLOW_INSIDE_AQUAN_OR_NOT() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUFETP\n"
|
||||
" 1 20.0 1000.0 2000. 0.000001 200.0 /\n"
|
||||
" 2 20.0 1000.0 2000. 0.000001 200.0 /\n"
|
||||
"/\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 1 1 1 1 1 J- 2* YES /\n"
|
||||
" 1 2 2 1 1 1 1 J- 2* YES /\n"
|
||||
" 1 2 2 2 2 1 1 J- 2* YES /\n"
|
||||
" 2 1 1 1 1 3 3 J- 2* NO /\n"
|
||||
" 2 2 2 1 1 3 3 J- 2* NO /\n"
|
||||
" 2 2 2 2 2 3 3 J- 2* NO /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquanconTest_ALLOW_AQUIFER_INSIDE_OR_NOT) {
|
||||
auto deck = createAQUANCONDeck_ALLOW_INSIDE_AQUAN_OR_NOT();
|
||||
const EclipseState eclState( deck );
|
||||
const Aquancon aqucon( eclState.getInputGrid(), deck);
|
||||
const std::vector<Aquancon::AquanconOutput>& aquifer_cons = aqucon.getAquOutput();
|
||||
BOOST_CHECK_EQUAL(aquifer_cons[0].global_index.size(), 2);
|
||||
BOOST_CHECK_EQUAL(aquifer_cons[1].global_index.size(), 1);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2017 TNO
|
||||
|
||||
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/>.
|
||||
*/
|
||||
#define BOOST_TEST_MODULE AQUDIMS_TESTS
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/Aqudims.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TEST_CREATE) {
|
||||
Opm::Aqudims aqudims;
|
||||
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAqunum() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumConnectionNumericalAquifer() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumInfluenceTablesCT() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumRowsInfluenceTable() , 36 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAnalyticAquifers() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumRowsAquancon() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAquiferLists() , 0 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAnalyticAquifersSingleList() , 0 );
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 TNO.
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE AquiferCTTest
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/AquiferCT.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
inline Deck createAquiferCTDeck() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUCT\n"
|
||||
" 1 2000.0 1.5 100 .3 3.0e-5 330 10 360.0 1 2 /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAquiferCTDeckDefaultP0() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUCT\n"
|
||||
" 1 2000.0 1* 100 .3 3.0e-5 330 10 360.0 1 2 /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
AquiferCT init_aquiferct(const Deck& deck){
|
||||
EclipseState eclState( deck );
|
||||
return AquiferCT(eclState.getTableManager(), deck);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquiferCTTest){
|
||||
auto deck = createAquiferCTDeck();
|
||||
{
|
||||
auto aquiferct = init_aquiferct(deck);
|
||||
for (const auto& it : aquiferct){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.phi_aq , 0.3);
|
||||
BOOST_CHECK_EQUAL(it.inftableID , 2);
|
||||
BOOST_CHECK(it.p0.first == true);
|
||||
BOOST_CHECK_CLOSE(it.p0.second, 1.5e5, 1e-6);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(aquiferct.size(), 1);
|
||||
}
|
||||
|
||||
auto deck_default_p0 = createAquiferCTDeckDefaultP0();
|
||||
{
|
||||
auto aquiferct = init_aquiferct(deck_default_p0);
|
||||
for (const auto& it : aquiferct){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.phi_aq , 0.3);
|
||||
BOOST_CHECK_EQUAL(it.inftableID , 2);
|
||||
BOOST_CHECK(it.p0.first == false);
|
||||
}
|
||||
auto data = aquiferct.data();
|
||||
AquiferCT aq2(data);
|
||||
BOOST_CHECK( aq2 == aquiferct );
|
||||
}
|
||||
}
|
||||
523
tests/parser/AquiferTests.cpp
Normal file
523
tests/parser/AquiferTests.cpp
Normal file
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
Copyright 2017 TNO.
|
||||
Copyright 2020 Equinor.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE AquiferCTTest
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Aquancon.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/AquiferCT.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Aquifetp.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
inline Deck createAquiferCTDeck() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUCT\n"
|
||||
" 1 2000.0 1.5 100 .3 3.0e-5 330 10 360.0 1 2 /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAquiferCTDeckDefaultP0() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUCT\n"
|
||||
" 1 2000.0 1* 100 .3 3.0e-5 330 10 360.0 1 2 /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
AquiferCT init_aquiferct(const Deck& deck){
|
||||
EclipseState eclState( deck );
|
||||
return AquiferCT(eclState.getTableManager(), deck);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquiferCTTest){
|
||||
auto deck = createAquiferCTDeck();
|
||||
{
|
||||
auto aquiferct = init_aquiferct(deck);
|
||||
for (const auto& it : aquiferct){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.phi_aq , 0.3);
|
||||
BOOST_CHECK_EQUAL(it.inftableID , 2);
|
||||
BOOST_CHECK(it.p0.first == true);
|
||||
BOOST_CHECK_CLOSE(it.p0.second, 1.5e5, 1e-6);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(aquiferct.size(), 1);
|
||||
}
|
||||
|
||||
auto deck_default_p0 = createAquiferCTDeckDefaultP0();
|
||||
{
|
||||
auto aquiferct = init_aquiferct(deck_default_p0);
|
||||
for (const auto& it : aquiferct){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.phi_aq , 0.3);
|
||||
BOOST_CHECK_EQUAL(it.inftableID , 2);
|
||||
BOOST_CHECK(it.p0.first == false);
|
||||
}
|
||||
auto data = aquiferct.data();
|
||||
AquiferCT aq2(data);
|
||||
BOOST_CHECK( aq2 == aquiferct );
|
||||
}
|
||||
}
|
||||
|
||||
inline Deck createAQUANCONDeck_DEFAULT_INFLUX2() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 2 2 1 1 1 1 J- 1.0 /\n"
|
||||
" 1 2 2 1 1 1 1 J- /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
|
||||
inline Deck createAQUANCONDeck_DEFAULT_INFLUX1() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 3 1 1 1 1 J- /\n"
|
||||
"/\n"
|
||||
"AQUANCON\n"
|
||||
" 2 1 1 2 2 1 1 J- /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAQUANCONDeck_DEFAULT_ILLEGAL() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 3 1 1 1 1 J- /\n"
|
||||
"/\n"
|
||||
"AQUANCON\n"
|
||||
" 2 1 2 1 2 1 1 J- /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAQUANCONDeck() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 1 1 1 1 1 J- 1.0 1.0 NO /\n"
|
||||
" 1 1 3 1 3 3 3 I+ 0.5 1.0 NO /\n"
|
||||
" 1 1 3 1 3 3 3 J+ 0.75 1.0 NO /\n"
|
||||
" 1 1 3 1 3 3 3 J- 2.75 1.0 NO /\n"
|
||||
" 1 2 3 2 3 1 1 I+ 2.75 1.0 NO /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquanconTest_DEFAULT_INFLUX) {
|
||||
auto deck1 = createAQUANCONDeck_DEFAULT_INFLUX1();
|
||||
EclipseState eclState1( deck1 );
|
||||
Aquancon aqcon(eclState1.getInputGrid(), deck1);
|
||||
|
||||
const auto& cells_aq1 = aqcon[1];
|
||||
/*
|
||||
The cells I = 0..2 are connected to aquifer 1; cell I==0 is inactive and
|
||||
not counted here ==> a total of 2 cells are connected to aquifer 1.
|
||||
*/
|
||||
BOOST_CHECK_EQUAL(cells_aq1.size(), 2);
|
||||
|
||||
const auto& cells_aq2 = aqcon[2];
|
||||
BOOST_CHECK_EQUAL(cells_aq2.size(), 1);
|
||||
BOOST_CHECK(aqcon.active());
|
||||
|
||||
auto deck2 = createAQUANCONDeck_DEFAULT_INFLUX2();
|
||||
EclipseState eclState2( deck2 );
|
||||
BOOST_CHECK_THROW(Aquancon( eclState2.getInputGrid(), deck2), std::invalid_argument);
|
||||
|
||||
// The cell (2,1,1) is attached to both aquifer 1 and aquifer 2 - that is illegal.
|
||||
auto deck3 = createAQUANCONDeck_DEFAULT_ILLEGAL();
|
||||
EclipseState eclState3( deck3 );
|
||||
BOOST_CHECK_THROW(Aquancon( eclState3.getInputGrid(), deck3), std::invalid_argument);
|
||||
}
|
||||
|
||||
|
||||
// allowing aquifer exists inside the reservoir
|
||||
inline Deck createAQUANCONDeck_ALLOW_INSIDE_AQUAN_OR_NOT() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PORO\n"
|
||||
" 27*0.15 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUFETP\n"
|
||||
" 1 20.0 1000.0 2000. 0.000001 200.0 /\n"
|
||||
" 2 20.0 1000.0 2000. 0.000001 200.0 /\n"
|
||||
"/\n"
|
||||
"AQUANCON\n"
|
||||
" 1 1 1 1 1 1 1 J- 2* YES /\n"
|
||||
" 1 2 2 1 1 1 1 J- 2* YES /\n"
|
||||
" 1 2 2 2 2 1 1 J- 2* YES /\n"
|
||||
" 2 1 1 1 1 3 3 J- 2* NO /\n"
|
||||
" 2 2 2 1 1 3 3 J- 2* NO /\n"
|
||||
" 2 2 2 2 2 3 3 J- 2* NO /\n"
|
||||
"/ \n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquanconTest_ALLOW_AQUIFER_INSIDE_OR_NOT) {
|
||||
auto deck = createAQUANCONDeck_ALLOW_INSIDE_AQUAN_OR_NOT();
|
||||
const EclipseState eclState( deck );
|
||||
const Aquancon aqucon( eclState.getInputGrid(), deck);
|
||||
|
||||
const auto& data = aqucon.data();
|
||||
const Aquancon aq2(data);
|
||||
|
||||
BOOST_CHECK(aqucon == aq2);
|
||||
auto cells1 = aqucon[1];
|
||||
auto cells2 = aqucon[2];
|
||||
BOOST_CHECK_EQUAL(cells1.size() , 2);
|
||||
BOOST_CHECK_EQUAL(cells2.size() , 1);
|
||||
}
|
||||
|
||||
inline Deck createAquifetpDeck() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUFETP\n"
|
||||
"1 70000.0 4.0e3 2.0e9 1.0e-5 500 1 0 0 /\n"
|
||||
"/\n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createNullAquifetpDeck(){
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
;
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAquifetpDeck_defaultPressure(){
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUFETP\n"
|
||||
"1 70000.0 1* 2.0e9 1.0e-5 500 1 0 0 /\n"
|
||||
"/\n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Aquifetp init_aquifetp(Deck& deck){
|
||||
Aquifetp aqufetp(deck);
|
||||
return aqufetp;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquifetpTest){
|
||||
auto aqufetp_deck = createAquifetpDeck();
|
||||
const auto& aquifetp = init_aquifetp(aqufetp_deck);
|
||||
for (const auto& it : aquifetp){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.V0, 2.0e9);
|
||||
BOOST_CHECK_EQUAL(it.J, 500/86400e5);
|
||||
BOOST_CHECK( it.p0.first );
|
||||
}
|
||||
const auto& data = aquifetp.data();
|
||||
Aquifetp aq2(data);
|
||||
BOOST_CHECK(aq2 == aquifetp);
|
||||
|
||||
auto aqufetp_deck_null = createNullAquifetpDeck();
|
||||
const auto& aquifetp_null = init_aquifetp(aqufetp_deck_null);
|
||||
BOOST_CHECK_EQUAL(aquifetp_null.size(), 0);
|
||||
|
||||
auto aqufetp_deck_default = createAquifetpDeck_defaultPressure();
|
||||
const auto& aquifetp_default = init_aquifetp(aqufetp_deck_default);
|
||||
for (const auto& it : aquifetp_default){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.V0, 2.0e9);
|
||||
BOOST_CHECK_EQUAL(it.J, 500/86400e5);
|
||||
BOOST_CHECK( !it.p0.first );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TEST_CREATE) {
|
||||
Opm::Aqudims aqudims;
|
||||
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAqunum() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumConnectionNumericalAquifer() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumInfluenceTablesCT() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumRowsInfluenceTable() , 36 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAnalyticAquifers() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumRowsAquancon() , 1 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAquiferLists() , 0 );
|
||||
BOOST_CHECK_EQUAL( aqudims.getNumAnalyticAquifersSingleList() , 0 );
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 TNO.
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE AquifetpTests
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Aquifetp.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
inline Deck createAquifetpDeck() {
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUFETP\n"
|
||||
"1 70000.0 4.0e3 2.0e9 1.0e-5 500 1 0 0 /\n"
|
||||
"/\n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createNullAquifetpDeck(){
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
;
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Deck createAquifetpDeck_defaultPressure(){
|
||||
const char *deckData =
|
||||
"DIMENS\n"
|
||||
"3 3 3 /\n"
|
||||
"\n"
|
||||
"AQUDIMS\n"
|
||||
"1* 1* 2 100 1 1000 /\n"
|
||||
"GRID\n"
|
||||
"\n"
|
||||
"ACTNUM\n"
|
||||
" 0 8*1 0 8*1 0 8*1 /\n"
|
||||
"DXV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DYV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"DZV\n"
|
||||
"1 1 1 /\n"
|
||||
"\n"
|
||||
"TOPS\n"
|
||||
"9*100 /\n"
|
||||
"\n"
|
||||
"PROPS\n"
|
||||
"AQUTAB\n"
|
||||
" 0.01 0.112 \n"
|
||||
" 0.05 0.229 /\n"
|
||||
"SOLUTION\n"
|
||||
"\n"
|
||||
"AQUFETP\n"
|
||||
"1 70000.0 1* 2.0e9 1.0e-5 500 1 0 0 /\n"
|
||||
"/\n";
|
||||
|
||||
Parser parser;
|
||||
return parser.parseString(deckData);
|
||||
}
|
||||
|
||||
inline Aquifetp init_aquifetp(Deck& deck){
|
||||
Aquifetp aqufetp(deck);
|
||||
return aqufetp;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AquifetpTest){
|
||||
auto aqufetp_deck = createAquifetpDeck();
|
||||
const auto& aquifetp = init_aquifetp(aqufetp_deck);
|
||||
for (const auto& it : aquifetp){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.V0, 2.0e9);
|
||||
BOOST_CHECK_EQUAL(it.J, 500/86400e5);
|
||||
BOOST_CHECK( it.p0.first );
|
||||
}
|
||||
const auto& data = aquifetp.data();
|
||||
Aquifetp aq2(data);
|
||||
BOOST_CHECK(aq2 == aquifetp);
|
||||
|
||||
auto aqufetp_deck_null = createNullAquifetpDeck();
|
||||
const auto& aquifetp_null = init_aquifetp(aqufetp_deck_null);
|
||||
BOOST_CHECK_EQUAL(aquifetp_null.size(), 0);
|
||||
|
||||
auto aqufetp_deck_default = createAquifetpDeck_defaultPressure();
|
||||
const auto& aquifetp_default = init_aquifetp(aqufetp_deck_default);
|
||||
for (const auto& it : aquifetp_default){
|
||||
BOOST_CHECK_EQUAL(it.aquiferID , 1);
|
||||
BOOST_CHECK_EQUAL(it.V0, 2.0e9);
|
||||
BOOST_CHECK_EQUAL(it.J, 500/86400e5);
|
||||
BOOST_CHECK( !it.p0.first );
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user