Merge pull request #535 from blattms/support-editnnc
Added support for honoring keyword EDITNNC during deck parsing.
This commit is contained in:
@@ -31,6 +31,10 @@ struct NNCdata {
|
||||
size_t cell1;
|
||||
size_t cell2;
|
||||
double trans;
|
||||
NNCdata(size_t c1, size_t c2, double t)
|
||||
: cell1(c1), cell2(c2), trans(t)
|
||||
{}
|
||||
NNCdata() = default;
|
||||
};
|
||||
|
||||
class Deck;
|
||||
|
||||
@@ -22,19 +22,115 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/N.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/E.hpp>
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
void readEditNncs(const std::vector< const DeckKeyword* >&, std::vector<NNCdata>&, const GridDims&);
|
||||
|
||||
void applyEditNncs(std::vector<NNCdata>&, std::vector<NNCdata>&);
|
||||
|
||||
NNC::NNC(const Deck& deck) {
|
||||
GridDims gridDims(deck);
|
||||
const auto& nncs = deck.getKeywordList<ParserKeywords::NNC>();
|
||||
for (size_t idx_nnc = 0; idx_nnc<nncs.size(); ++idx_nnc) {
|
||||
const auto& nnc = *nncs[idx_nnc];
|
||||
for (size_t i = 0; i < nnc.size(); ++i) {
|
||||
std::array<size_t, 3> ijk1;
|
||||
ijk1[0] = static_cast<size_t>(nnc.getRecord(i).getItem(0).get< int >(0)-1);
|
||||
ijk1[1] = static_cast<size_t>(nnc.getRecord(i).getItem(1).get< int >(0)-1);
|
||||
ijk1[2] = static_cast<size_t>(nnc.getRecord(i).getItem(2).get< int >(0)-1);
|
||||
size_t global_index1 = gridDims.getGlobalIndex(ijk1[0],ijk1[1],ijk1[2]);
|
||||
|
||||
std::array<size_t, 3> ijk2;
|
||||
ijk2[0] = static_cast<size_t>(nnc.getRecord(i).getItem(3).get< int >(0)-1);
|
||||
ijk2[1] = static_cast<size_t>(nnc.getRecord(i).getItem(4).get< int >(0)-1);
|
||||
ijk2[2] = static_cast<size_t>(nnc.getRecord(i).getItem(5).get< int >(0)-1);
|
||||
size_t global_index2 = gridDims.getGlobalIndex(ijk2[0],ijk2[1],ijk2[2]);
|
||||
|
||||
const double trans = nnc.getRecord(i).getItem(6).getSIDouble(0);
|
||||
|
||||
addNNC(global_index1, global_index2, trans);
|
||||
}
|
||||
}
|
||||
const auto& tmpEditNncs = deck.getKeywordList<ParserKeywords::EDITNNC>();
|
||||
std::vector<NNCdata> editNncs(tmpEditNncs.size());
|
||||
readEditNncs(tmpEditNncs, editNncs, gridDims);
|
||||
applyEditNncs(m_nnc, editNncs);
|
||||
}
|
||||
|
||||
void applyEditNncs(std::vector<NNCdata>& nncs, std::vector<NNCdata>& editNncs)
|
||||
{
|
||||
auto compare = [](const NNCdata& d1, const NNCdata& d2)
|
||||
{ return d1.cell1 < d2.cell1 ||
|
||||
( d1.cell1 == d2.cell1 && d1.cell2 < d2.cell2 );};
|
||||
std::sort(editNncs.begin(), editNncs.end(), compare);
|
||||
std::sort(nncs.begin(), nncs.end(), compare);
|
||||
|
||||
std::ostringstream warning;
|
||||
warning<<"The following NNC entries in EDITNNC have been ignored: ";
|
||||
bool ignored = false;
|
||||
std::size_t counter = 0;
|
||||
// Assuming that we edit less nncs than we have
|
||||
auto nncIt = nncs.begin();
|
||||
for( const auto& edit: editNncs )
|
||||
{
|
||||
auto candidate = std::lower_bound(nncIt, nncs.end(), edit, compare);
|
||||
bool processed = false;
|
||||
|
||||
for( auto next=candidate; next != nncs.end() &&
|
||||
( next->cell1 == edit.cell1 && next->cell2 == edit.cell2 );
|
||||
++next)
|
||||
{
|
||||
next->trans *= edit.trans;
|
||||
processed = true;
|
||||
}
|
||||
|
||||
if ( ! processed )
|
||||
{
|
||||
warning << edit.cell1 << "->" << edit.cell2 << " ";
|
||||
ignored = true;
|
||||
}
|
||||
++counter;
|
||||
|
||||
if ( candidate != nncs.end() )
|
||||
{
|
||||
// There could be another edit for the same cell, start over.
|
||||
nncIt = candidate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for all other editnnc there will be no nnc.
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( counter < editNncs.size() )
|
||||
{
|
||||
ignored = true;
|
||||
for(auto nnc = editNncs.begin() + counter, end = editNncs.end(); nnc != end; ++nnc)
|
||||
{
|
||||
warning << nnc->cell1 << "->" << nnc->cell2 << " ";
|
||||
}
|
||||
}
|
||||
if ( ignored )
|
||||
{
|
||||
OpmLog::warning(warning.str());
|
||||
}
|
||||
}
|
||||
|
||||
void readEditNncs(const std::vector< const DeckKeyword* >& editNncsKw, std::vector<NNCdata>& editNncs, const GridDims& gridDims)
|
||||
{
|
||||
for (size_t idx_nnc = 0; idx_nnc<editNncsKw.size(); ++idx_nnc) {
|
||||
const auto& nnc = *editNncsKw[idx_nnc];
|
||||
for (size_t i = 0; i < nnc.size(); ++i) {
|
||||
std::array<size_t, 3> ijk1;
|
||||
ijk1[0] = static_cast<size_t>(nnc.getRecord(i).getItem(0).get< int >(0)-1);
|
||||
@@ -48,9 +144,9 @@ namespace Opm
|
||||
ijk2[2] = static_cast<size_t>(nnc.getRecord(i).getItem(5).get< int >(0)-1);
|
||||
size_t global_index2 = gridDims.getGlobalIndex(ijk2[0],ijk2[1],ijk2[2]);
|
||||
|
||||
const double trans = nnc.getRecord(i).getItem(6).getSIDouble(0);
|
||||
const double trans = nnc.getRecord(i).getItem(6).get<double>(0);
|
||||
|
||||
addNNC(global_index1,global_index2,trans);
|
||||
editNncs.emplace_back(global_index1, global_index2, trans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
48
tests/parser/data/integration_tests/NNC/EDITNNC.DATA
Normal file
48
tests/parser/data/integration_tests/NNC/EDITNNC.DATA
Normal file
@@ -0,0 +1,48 @@
|
||||
RUNSPEC
|
||||
|
||||
OIL
|
||||
GAS
|
||||
WATER
|
||||
|
||||
|
||||
DIMENS
|
||||
10 10 1 /
|
||||
|
||||
GRID
|
||||
|
||||
DXV
|
||||
10*1000.0
|
||||
/
|
||||
|
||||
DYV
|
||||
10*1000.0
|
||||
/
|
||||
|
||||
DZ
|
||||
100*20.0
|
||||
/
|
||||
|
||||
TOPS
|
||||
100*10
|
||||
/
|
||||
|
||||
NNC
|
||||
1 1 1 2 1 1 0.5 /
|
||||
1 1 1 1 2 1 1.0 /
|
||||
/
|
||||
|
||||
NNC
|
||||
1 1 1 2 1 1 0.5 /
|
||||
1 2 1 1 2 1 1.0 /
|
||||
2 2 1 2 2 1 1.0 /
|
||||
/
|
||||
|
||||
EDIT
|
||||
|
||||
EDITNNC
|
||||
1 1 1 2 1 1 2.0 /
|
||||
1 2 1 1 2 1 10.0 /
|
||||
3 2 1 3 2 1 10.0 /
|
||||
2 2 1 2 2 1 2.0 /
|
||||
2 2 1 2 2 1 3.0 /
|
||||
/
|
||||
@@ -51,13 +51,15 @@ BOOST_AUTO_TEST_CASE(readDeck)
|
||||
const std::vector<NNCdata>& nncdata = nnc.nncdata();
|
||||
|
||||
// test the NNCs in nnc.DATA
|
||||
// NNCs are orderd lexicographically
|
||||
// Therefore the two equal NNCs are next to each other
|
||||
BOOST_CHECK_EQUAL(nnc.numNNC(), 4);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].cell1, 0);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].cell2, 1);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].trans, 0.5 * Opm::Metric::Transmissibility);
|
||||
BOOST_CHECK_EQUAL(nncdata[1].cell1, 0);
|
||||
BOOST_CHECK_EQUAL(nncdata[1].cell2, 10);
|
||||
BOOST_CHECK_EQUAL(nncdata[1].trans, 1.0 * Opm::Metric::Transmissibility);
|
||||
BOOST_CHECK_EQUAL(nncdata[2].cell1, 0);
|
||||
BOOST_CHECK_EQUAL(nncdata[2].cell2, 10);
|
||||
BOOST_CHECK_EQUAL(nncdata[2].trans, 1.0 * Opm::Metric::Transmissibility);
|
||||
|
||||
}
|
||||
|
||||
@@ -89,3 +91,37 @@ BOOST_AUTO_TEST_CASE(addNNC)
|
||||
BOOST_CHECK_EQUAL(nncdata[0].trans, 2.0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(editNNC)
|
||||
{
|
||||
|
||||
auto eclipseState = Parser::parse(pathprefix() + "NNC/EDITNNC.DATA");
|
||||
const auto& nnc = eclipseState.getInputNNC();
|
||||
BOOST_CHECK(nnc.hasNNC());
|
||||
const std::vector<NNCdata>& nncdata = nnc.nncdata();
|
||||
|
||||
// test the NNCs in nnc.DATA
|
||||
// note that these are ordered lexicographically
|
||||
// 0: 1,1,1 -> 2,1,1
|
||||
BOOST_CHECK_EQUAL(nncdata[0].cell1, 0);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].cell2, 1);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].trans, 1.0 * Opm::Metric::Transmissibility);
|
||||
// 1: 1,1,1 -> 2,1,1
|
||||
BOOST_CHECK_EQUAL(nncdata[0].cell1, 0);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].cell2, 1);
|
||||
BOOST_CHECK_EQUAL(nncdata[0].trans, 1.0 * Opm::Metric::Transmissibility);
|
||||
// 2: 1,1,1 -> 1,2,1
|
||||
BOOST_CHECK_EQUAL(nncdata[2].cell1, 0);
|
||||
BOOST_CHECK_EQUAL(nncdata[2].cell2, 10);
|
||||
BOOST_CHECK_EQUAL(nncdata[2].trans, 1.0 * Opm::Metric::Transmissibility);
|
||||
// 3: 1,2,1 -> 1,2,1
|
||||
BOOST_CHECK_EQUAL(nncdata[3].cell1, 10);
|
||||
BOOST_CHECK_EQUAL(nncdata[3].cell2, 10);
|
||||
BOOST_CHECK_EQUAL(nncdata[3].trans, 10.0 * Opm::Metric::Transmissibility);
|
||||
// 4: 2,2,1 -> 2,2,1
|
||||
BOOST_CHECK_EQUAL(nncdata[4].cell1, 11);
|
||||
BOOST_CHECK_EQUAL(nncdata[4].cell2, 11);
|
||||
BOOST_CHECK_EQUAL(nncdata[4].trans, 6.0 * Opm::Metric::Transmissibility);
|
||||
// There should be no entry due EDITNNC for 3,2,1 -> 3,2,1 as there is no nnc
|
||||
BOOST_CHECK_EQUAL(nnc.numNNC(), 5);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user