Reorder MULTREGTScanner Implementation File

Mostly to group related functions and have the same order in the
declaration and the implementation files.  While here, replace an
'enum' with a strong enum since the type does not need to support
arithmetic operations.
This commit is contained in:
Bård Skaflestad
2023-08-28 17:09:45 +02:00
parent 383dbf27a9
commit f6676fcc1a
3 changed files with 383 additions and 337 deletions

View File

@@ -40,7 +40,8 @@ namespace Opm {
namespace Opm {
namespace MULTREGT {
enum NNCBehaviourEnum {
enum class NNCBehaviourEnum
{
NNC = 1,
NONNC = 2,
ALL = 3,
@@ -60,13 +61,15 @@ namespace Opm {
MULTREGT::NNCBehaviourEnum nnc_behaviour;
std::string region_name;
bool operator==(const MULTREGTRecord& data) const {
return src_value == data.src_value &&
target_value == data.target_value &&
trans_mult == data.trans_mult &&
directions == data.directions &&
nnc_behaviour == data.nnc_behaviour &&
region_name == data.region_name;
bool operator==(const MULTREGTRecord& data) const
{
return (src_value == data.src_value)
&& (target_value == data.target_value)
&& (trans_mult == data.trans_mult)
&& (directions == data.directions)
&& (nnc_behaviour == data.nnc_behaviour)
&& (region_name == data.region_name)
;
}
template<class Serializer>
@@ -92,25 +95,31 @@ namespace Opm {
static MULTREGTScanner serializationTestObject();
bool operator==(const MULTREGTScanner& data) const;
MULTREGTScanner& operator=(const MULTREGTScanner& data);
double getRegionMultiplier(std::size_t globalCellIdx1,
std::size_t globalCellIdx2,
FaceDir::DirEnum faceDir) const;
bool operator==(const MULTREGTScanner& data) const;
MULTREGTScanner& operator=(const MULTREGTScanner& data);
template<class Serializer>
template <class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(gridDims);
serializer(default_region);
serializer(m_records);
serializer(m_searchMap);
serializer(regions);
}
private:
using MULTREGTSearchMap = std::map< std::pair<int, int>, std::vector<MULTREGTRecord>::size_type>;
using MULTREGTSearchMap = std::map<
std::pair<int, int>,
std::vector<MULTREGTRecord>::size_type
>;
GridDims gridDims{};
const FieldPropsManager* fp{nullptr};

View File

@@ -27,6 +27,8 @@
#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
#include <opm/input/eclipse/Deck/DeckRecord.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/M.hpp>
#include <algorithm>
#include <array>
#include <cassert>
@@ -43,8 +45,9 @@ namespace {
std::vector<int> unique(std::vector<int> data)
{
std::sort(data.begin(), data.end());
data.erase(std::unique(data.begin(), data.end()), data.end());
return { data.begin(), std::unique(data.begin(), data.end()) };
return data;
}
bool is_adjacent(const int x, const int y)
@@ -81,66 +84,64 @@ namespace Opm {
namespace MULTREGT {
std::string RegionNameFromDeckValue(const std::string& stringValue) {
if (stringValue == "O")
return "OPERNUM";
std::string RegionNameFromDeckValue(const std::string& stringValue)
{
if (stringValue == "O") { return "OPERNUM"; }
if (stringValue == "F") { return "FLUXNUM"; }
if (stringValue == "M") { return "MULTNUM"; }
if (stringValue == "F")
return "FLUXNUM";
if (stringValue == "M")
return "MULTNUM";
throw std::invalid_argument("The input string: " + stringValue + " was invalid. Expected: O/F/M");
throw std::invalid_argument {
"The input string: " + stringValue + " was invalid. Expected: O/F/M"
};
}
NNCBehaviourEnum NNCBehaviourFromString(const std::string& stringValue) {
if (stringValue == "ALL")
return ALL;
NNCBehaviourEnum NNCBehaviourFromString(const std::string& stringValue)
{
if (stringValue == "ALL") { return NNCBehaviourEnum::ALL; }
if (stringValue == "NNC") { return NNCBehaviourEnum::NNC; }
if (stringValue == "NONNC") { return NNCBehaviourEnum::NONNC; }
if (stringValue == "NOAQUNNC") { return NNCBehaviourEnum::NOAQUNNC; }
if (stringValue == "NNC")
return NNC;
if (stringValue == "NONNC")
return NONNC;
if (stringValue == "NOAQUNNC")
return NOAQUNNC;
throw std::invalid_argument("The input string: " + stringValue + " was invalid. Expected: ALL/NNC/NONNC/NOAQUNNC");
throw std::invalid_argument {
"The input string: " + stringValue + " was invalid. Expected: ALL/NNC/NONNC/NOAQUNNC"
};
}
} // namespace MULTREGT
/*****************************************************************/
/*
Observe that the (REGION1 -> REGION2) pairs behave like keys;
i.e. for the MULTREGT keyword
// -----------------------------------------------------------------------
MULTREGT
2 4 0.75 Z ALL M /
2 4 2.50 XY ALL F /
/
// Later records with the same region IDs overwrite earlier. As an
// example, in the MULTREGT keyword
//
// MULTREGT
// 2 4 0.75 Z ALL M /
// 2 4 2.50 XY ALL F /
// /
//
// the second record will overwrite the first. We enforce this
// behaviour through maps keyed on 'pair<region1,region2>'.
//
// This function starts with some initial preprocessing to create a map
// which looks like this:
//
// searchMap = {
// "MULTNUM" : {
// std::pair(1,2) : recordIx,
// std::pair(4,7) : recordIx,
// ...
// },
// "FLUXNUM" : {
// std::pair(4,8) : recordIx,
// std::pair(1,4) : recordIx,
// ...
// },
// ...
// }
//
// Then it will go through the different regions and look for interfaces
// with the wanted region values.
The first record is completely overweritten by the second
record, this is because the both have the (2 -> 4) region
identifiers. This behaviourt is ensured by using a map with
std::pair<region1,region2> as key.
This function starts with some initial preprocessing to create a
map which looks like this:
searchMap = {"MULTNUM" : {std::pair(1,2) : std::tuple(TransFactor , Face , Region),
std::pair(4,7) : std::tuple(TransFactor , Face , Region),
...},
"FLUXNUM" : {std::pair(4,8) : std::tuple(TransFactor , Face , Region),
std::pair(1,4) : std::tuple(TransFactor , Face , Region),
...}}
Then it will go through the different regions and looking for
interface with the wanted region values.
*/
MULTREGTScanner::MULTREGTScanner(const GridDims& gridDims_arg,
const FieldPropsManager* fp_arg,
const std::vector<const DeckKeyword*>& keywords)
@@ -148,19 +149,21 @@ namespace Opm {
, fp { fp_arg }
, default_region { this->fp->default_region() }
{
for (const auto* keywordPtr : keywords)
this->addKeyword(*keywordPtr);
for (const auto* keywordRecordPtr : keywords) {
this->addKeyword(*keywordRecordPtr);
}
MULTREGTSearchMap searchPairs;
for (auto recordIx = 0*this->m_records.size(); recordIx < this->m_records.size(); ++recordIx) {
const auto& record = this->m_records[recordIx];
const std::string& region_name = record.region_name;
if (this->fp->has_int(region_name)) {
int srcRegion = record.src_value;
int targetRegion = record.target_value;
const auto srcRegion = record.src_value;
const auto targetRegion = record.target_value;
// the MULTREGT keyword is directional independent
// i.e. we add it both ways to the lookup map.
// The MULTREGT keyword is directionally independent meaning
// we add both directions, symmetrically, to the lookup
// table.
if (srcRegion != targetRegion) {
std::pair<int,int> pair1{ srcRegion, targetRegion };
std::pair<int,int> pair2{ targetRegion, srcRegion };
@@ -168,28 +171,37 @@ namespace Opm {
searchPairs[pair2] = recordIx;
}
}
else
throw std::logic_error(
"MULTREGT record is based on region: "
+ region_name
+ " which is not in the deck");
else {
throw std::logic_error {
"MULTREGT record is based on region: "
+ region_name
+ " which is not in the deck"
};
}
if (this->regions.count(region_name) == 0)
if (this->regions.count(region_name) == 0) {
this->regions[region_name] = this->fp->get_global_int(region_name);
}
}
for (const auto& [regPair, recordIx] : searchPairs) {
const std::string& keyword = this->m_records[recordIx].region_name;
m_searchMap[keyword][regPair] = recordIx;
this->m_searchMap[keyword][regPair] = recordIx;
}
}
MULTREGTScanner::MULTREGTScanner(const MULTREGTScanner& rhs)
{
*this = rhs;
}
MULTREGTScanner MULTREGTScanner::serializationTestObject()
{
MULTREGTScanner result;
result.gridDims = GridDims::serializationTestObject();
result.m_records = {{4, 5, 6.0, 7, MULTREGT::ALL, "test1"}};
result.m_records = {{4, 5, 6.0, 7, MULTREGT::NNCBehaviourEnum::ALL, "test1"}};
result.m_searchMap["MULTNUM"].emplace(std::piecewise_construct,
std::forward_as_tuple(std::make_pair(1, 2)),
std::forward_as_tuple(0));
@@ -199,61 +211,27 @@ namespace Opm {
return result;
}
MULTREGTScanner::MULTREGTScanner(const MULTREGTScanner& data) {
*this = data;
bool MULTREGTScanner::operator==(const MULTREGTScanner& data) const
{
return (this->gridDims == data.gridDims)
&& (this->default_region == data.default_region)
&& (this->m_records == data.m_records)
&& (this->m_searchMap == data.m_searchMap)
&& (this->regions == data.regions)
;
}
void MULTREGTScanner::assertKeywordSupported( const DeckKeyword& deckKeyword) {
for (const auto& deckRecord : deckKeyword) {
const auto& srcItem = deckRecord.getItem("SRC_REGION");
const auto& targetItem = deckRecord.getItem("TARGET_REGION");
auto nnc_behaviour = MULTREGT::NNCBehaviourFromString(deckRecord.getItem("NNC_MULT").get<std::string>(0));
MULTREGTScanner& MULTREGTScanner::operator=(const MULTREGTScanner& data)
{
this->gridDims = data.gridDims;
this->fp = data.fp;
this->default_region = data.default_region;
if (!srcItem.defaultApplied(0) && !targetItem.defaultApplied(0))
if (srcItem.get<int>(0) == targetItem.get<int>(0))
throw std::invalid_argument("Sorry - MULTREGT applied internally to a region is not yet supported");
this->m_records = data.m_records;
this->m_searchMap = data.m_searchMap;
this->regions = data.regions;
if (nnc_behaviour == MULTREGT::NOAQUNNC)
throw std::invalid_argument("Sorry - currently we do not support \'NOAQUNNC\' for MULTREGT.");
}
}
void MULTREGTScanner::addKeyword(const DeckKeyword& deckKeyword) {
assertKeywordSupported( deckKeyword );
for (const auto& deckRecord : deckKeyword) {
std::vector<int> src_regions;
std::vector<int> target_regions;
std::string region_name = this->default_region;
const auto& srcItem = deckRecord.getItem("SRC_REGION");
const auto& targetItem = deckRecord.getItem("TARGET_REGION");
const auto& regionItem = deckRecord.getItem("REGION_DEF");
double trans_mult = deckRecord.getItem("TRAN_MULT").get<double>(0);
auto directions = FaceDir::FromMULTREGTString( deckRecord.getItem("DIRECTIONS").get<std::string>(0));
auto nnc_behaviour = MULTREGT::NNCBehaviourFromString(deckRecord.getItem("NNC_MULT").get<std::string>(0));
if (regionItem.defaultApplied(0)) {
if (!m_records.empty())
region_name = m_records.back().region_name;
} else
region_name = MULTREGT::RegionNameFromDeckValue( regionItem.get<std::string>(0) );
if (srcItem.defaultApplied(0) || srcItem.get<int>(0) < 0)
src_regions = unique(this->fp->get_int(region_name));
else
src_regions.push_back(srcItem.get<int>(0));
if (targetItem.defaultApplied(0) || targetItem.get<int>(0) < 0)
target_regions = unique(fp->get_int(region_name));
else
target_regions.push_back(targetItem.get<int>(0));
for (int src_region : src_regions) {
for (int target_region : target_regions)
m_records.push_back({src_region, target_region, trans_mult, directions, nnc_behaviour, region_name});
}
}
return *this;
}
// This function will check the region values in globalIndex1 and
@@ -275,64 +253,133 @@ namespace Opm {
// -----------
// | 2 | 1 | => MultTrans( i+1,j,k,FaceDir::XMinus ) *= 0.50
// -----------
double MULTREGTScanner::getRegionMultiplier(const std::size_t globalIndex1,
const std::size_t globalIndex2,
const FaceDir::DirEnum faceDir) const
{
const auto is_adj = is_adjacent(this->gridDims, globalIndex1, globalIndex2);
if (this->m_searchMap.empty()) {
return 1.0;
}
for (auto iter = m_searchMap.begin(); iter != m_searchMap.end(); iter++) {
const auto& region_data = this->regions.at( iter->first );
const MULTREGTSearchMap& map = (*iter).second;
auto regPairFound = [faceDir, this](const auto& regMap, auto regPairPos)
{
return (regPairPos != regMap.end())
&& ((this->m_records[regPairPos->second].directions & faceDir) != 0);
};
int regionId1 = region_data[globalIndex1];
int regionId2 = region_data[globalIndex2];
auto ignoreMultiplierRecord =
[is_adj = is_adjacent(this->gridDims, globalIndex1, globalIndex2)]
(const MULTREGT::NNCBehaviourEnum nnc_behaviour)
{
// We ignore the record if either of the following conditions hold
//
// 1. Cells are adjacent, but record stipulates NNCs only
// 2. Connection is an NNC, but record stipulates no NNCs
return ( is_adj && (nnc_behaviour == MULTREGT::NNCBehaviourEnum::NNC))
|| (!is_adj && (nnc_behaviour == MULTREGT::NNCBehaviourEnum::NONNC));
};
std::pair<int,int> pair{ regionId1, regionId2 };
if (map.count(pair) != 1 || !(this->m_records[map.at(pair)].directions & faceDir)) {
pair = std::pair<int,int>{regionId2 , regionId1};
if (map.count(pair) != 1 || !(this->m_records[map.at(pair)].directions & faceDir))
continue;
}
const MULTREGTRecord& record = this->m_records[map.at(pair)];
for (const auto& [regName, regMap] : this->m_searchMap) {
const auto& region_data = this->regions.at(regName);
bool applyMultiplier = true;
const int regionId1 = region_data[globalIndex1];
const int regionId2 = region_data[globalIndex2];
if (record.nnc_behaviour == MULTREGT::NNC){
applyMultiplier = true;
if (is_adj)
applyMultiplier = false;
}
else if (record.nnc_behaviour == MULTREGT::NONNC){
applyMultiplier = false;
if (is_adj)
applyMultiplier = true;
auto regPairPos = regMap.find({ regionId1, regionId2 });
if ((regionId1 != regionId2) && !regPairFound(regMap, regPairPos)) {
// 1 -> 2 not found. Try reverse direction.
regPairPos = regMap.find({ regionId2, regionId1 });
}
if (applyMultiplier)
if (! regPairFound(regMap, regPairPos)) {
// Neither 1->2 nor 2->1 found. Move on to next region set.
continue;
}
const auto& record = this->m_records[regPairPos->second];
const auto applyMultiplier =
(record.nnc_behaviour == MULTREGT::NNCBehaviourEnum::ALL) ||
! ignoreMultiplierRecord(record.nnc_behaviour);
if (applyMultiplier) {
return record.trans_mult;
}
}
return 1.0;
}
bool MULTREGTScanner::operator==(const MULTREGTScanner& data) const {
return this->gridDims == data.gridDims &&
this->m_records == data.m_records &&
this->regions == data.regions &&
this->m_searchMap == data.m_searchMap &&
this->default_region == data.default_region;
void MULTREGTScanner::assertKeywordSupported(const DeckKeyword& deckKeyword)
{
using Kw = ParserKeywords::MULTREGT;
for (const auto& deckRecord : deckKeyword) {
const auto& srcItem = deckRecord.getItem<Kw::SRC_REGION>();
const auto& targetItem = deckRecord.getItem<Kw::TARGET_REGION>();
if (!srcItem.defaultApplied(0) && !targetItem.defaultApplied(0)) {
if (srcItem.get<int>(0) == targetItem.get<int>(0)) {
throw std::invalid_argument {
"Sorry - MULTREGT applied internally to a region is not yet supported"
};
}
}
const auto nnc_behaviour = MULTREGT::
NNCBehaviourFromString(deckRecord.getItem("NNC_MULT").get<std::string>(0));
if (nnc_behaviour == MULTREGT::NNCBehaviourEnum::NOAQUNNC) {
throw std::invalid_argument {
"Sorry - currently we do not support 'NOAQUNNC' for MULTREGT."
};
}
}
}
MULTREGTScanner& MULTREGTScanner::operator=(const MULTREGTScanner& data) {
gridDims = data.gridDims;
fp = data.fp;
m_records = data.m_records;
m_searchMap = data.m_searchMap;
regions = data.regions;
default_region = data.default_region;
void MULTREGTScanner::addKeyword(const DeckKeyword& deckKeyword)
{
using Kw = ParserKeywords::MULTREGT;
return *this;
this->assertKeywordSupported(deckKeyword);
for (const auto& deckRecord : deckKeyword) {
std::vector<int> src_regions;
std::vector<int> target_regions;
std::string region_name = this->default_region;
const auto& srcItem = deckRecord.getItem<Kw::SRC_REGION>();
const auto& targetItem = deckRecord.getItem<Kw::TARGET_REGION>();
const auto& regionItem = deckRecord.getItem<Kw::REGION_DEF>();
const auto trans_mult = deckRecord.getItem<Kw::TRAN_MULT>().get<double>(0);
const auto directions = FaceDir::FromMULTREGTString(deckRecord.getItem<Kw::DIRECTIONS>().get<std::string>(0));
const auto nnc_behaviour = MULTREGT::NNCBehaviourFromString(deckRecord.getItem<Kw::NNC_MULT>().get<std::string>(0));
if (regionItem.defaultApplied(0)) {
if (!m_records.empty())
region_name = m_records.back().region_name;
} else
region_name = MULTREGT::RegionNameFromDeckValue( regionItem.get<std::string>(0) );
if (srcItem.defaultApplied(0) || srcItem.get<int>(0) < 0) {
src_regions = unique(this->fp->get_int(region_name));
}
else {
src_regions.push_back(srcItem.get<int>(0));
}
if (targetItem.defaultApplied(0) || targetItem.get<int>(0) < 0) {
target_regions = unique(fp->get_int(region_name));
}
else {
target_regions.push_back(targetItem.get<int>(0));
}
for (int src_region : src_regions) {
for (int target_region : target_regions) {
m_records.push_back({src_region, target_region, trans_mult, directions, nnc_behaviour, region_name});
}
}
}
}
} // namespace Opm

View File

@@ -17,27 +17,31 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#define BOOST_TEST_MODULE MULTREGTScannerTests
#include <boost/test/unit_test.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Deck/DeckSection.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
#include <opm/input/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
#include <opm/input/eclipse/Deck/DeckSection.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/M.hpp>
#include <array>
#include <initializer_list>
#include <stdexcept>
#include <vector>
BOOST_AUTO_TEST_CASE(TestRegionName) {
BOOST_CHECK_EQUAL( "FLUXNUM" , Opm::MULTREGT::RegionNameFromDeckValue( "F"));
@@ -48,58 +52,58 @@ BOOST_AUTO_TEST_CASE(TestRegionName) {
BOOST_CHECK_THROW( Opm::MULTREGT::RegionNameFromDeckValue("X") , std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(TestNNCBehaviourEnum) {
BOOST_CHECK_EQUAL( Opm::MULTREGT::ALL , Opm::MULTREGT::NNCBehaviourFromString( "ALL"));
BOOST_CHECK_EQUAL( Opm::MULTREGT::NNC , Opm::MULTREGT::NNCBehaviourFromString( "NNC"));
BOOST_CHECK_EQUAL( Opm::MULTREGT::NONNC , Opm::MULTREGT::NNCBehaviourFromString( "NONNC"));
BOOST_CHECK_EQUAL( Opm::MULTREGT::NOAQUNNC , Opm::MULTREGT::NNCBehaviourFromString( "NOAQUNNC"));
BOOST_CHECK_MESSAGE(Opm::MULTREGT::NNCBehaviourEnum::ALL == Opm::MULTREGT::NNCBehaviourFromString("ALL"),
R"(Behaviour("ALL") must be ALL)");
BOOST_CHECK_MESSAGE(Opm::MULTREGT::NNCBehaviourEnum::NNC == Opm::MULTREGT::NNCBehaviourFromString("NNC"),
R"(Behaviour("NNC") must be NNC)");
BOOST_CHECK_THROW( Opm::MULTREGT::NNCBehaviourFromString( "Invalid") , std::invalid_argument);
}
static Opm::Deck createInvalidMULTREGTDeck() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 3 3 2 /\n"
"GRID\n"
"DX\n"
"18*0.25 /\n"
"DY\n"
"18*0.25 /\n"
"DZ\n"
"18*0.25 /\n"
"TOPS\n"
"9*0.25 /\n"
"FLUXNUM\n"
"1 1 2\n"
"1 1 2\n"
"1 1 2\n"
"3 4 5\n"
"3 4 5\n"
"3 4 5\n"
"/\n"
"MULTREGT\n"
"1 2 0.50 G ALL M / -- Invalid direction\n"
"/\n"
"MULTREGT\n"
"1 2 0.50 X ALL G / -- Invalid region \n"
"/\n"
"MULTREGT\n"
"1 2 0.50 X ALL M / -- Region not in deck \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
BOOST_CHECK_MESSAGE(Opm::MULTREGT::NNCBehaviourEnum::NONNC == Opm::MULTREGT::NNCBehaviourFromString("NONNC"),
R"(Behaviour("NONNC") must be NONNC)");
BOOST_CHECK_MESSAGE(Opm::MULTREGT::NNCBehaviourEnum::NOAQUNNC == Opm::MULTREGT::NNCBehaviourFromString("NOAQUNNC"),
R"(Behaviour("NOAQUNNC") must be NOAQUNNC)");
BOOST_CHECK_THROW(Opm::MULTREGT::NNCBehaviourFromString("Invalid"), std::invalid_argument);
}
namespace {
Opm::Deck createInvalidMULTREGTDeck()
{
return Opm::Parser{}.parseString(R"(RUNSPEC
DIMENS
3 3 2 /
GRID
DX
18*0.25 /
DY
18*0.25 /
DZ
18*0.25 /
TOPS
9*0.25 /
FLUXNUM
1 1 2
1 1 2
1 1 2
3 4 5
3 4 5
3 4 5
/
MULTREGT
1 2 0.50 G ALL M / -- Invalid direction
/
MULTREGT
1 2 0.50 X ALL G / -- Invalid region
/
MULTREGT
1 2 0.50 X ALL M / -- Region not in deck
/
EDIT
)");
}
} // Anonymous namespace
BOOST_AUTO_TEST_CASE(InvalidInput) {
Opm::Deck deck = createInvalidMULTREGTDeck();
@@ -127,45 +131,39 @@ BOOST_AUTO_TEST_CASE(InvalidInput) {
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( grid, &fp, keywords2 ); , std::logic_error );
}
static Opm::Deck createNotSupportedMULTREGTDeck() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 3 3 2 /\n"
"GRID\n"
"DX\n"
"18*0.25 /\n"
"DY\n"
"18*0.25 /\n"
"DZ\n"
"18*0.25 /\n"
"TOPS\n"
"9*0.25 /\n"
"FLUXNUM\n"
"1 1 2\n"
"1 1 2\n"
"1 1 2\n"
"3 4 5\n"
"3 4 5\n"
"3 4 5\n"
"/\n"
"MULTREGT\n"
"1 2 0.50 X NOAQUNNC F / -- Not support NOAQUNNC behaviour \n"
"/\n"
"MULTREGT\n"
"2 2 0.50 X ALL M / -- Region values equal \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
namespace {
Opm::Deck createNotSupportedMULTREGTDeck()
{
return Opm::Parser{}.parseString(R"(RUNSPEC
DIMENS
3 3 2 /
GRID
DX
18*0.25 /
DY
18*0.25 /
DZ
18*0.25 /
TOPS
9*0.25 /
FLUXNUM
1 1 2
1 1 2
1 1 2
3 4 5
3 4 5
3 4 5
/
MULTREGT
1 2 0.50 X NOAQUNNC F / -- Not support NOAQUNNC behaviour
/
MULTREGT
2 2 0.50 X ALL M / -- Region values equal
/
EDIT
)");
}
} // Anonymous namespace
BOOST_AUTO_TEST_CASE(NotSupported) {
Opm::Deck deck = createNotSupportedMULTREGTDeck();
@@ -188,45 +186,42 @@ BOOST_AUTO_TEST_CASE(NotSupported) {
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( grid, &fp, keywords1 ); , std::invalid_argument );
}
static Opm::Deck createDefaultedRegions() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 3 3 2 /\n"
"GRID\n"
"DX\n"
"18*0.25 /\n"
"DY\n"
"18*0.25 /\n"
"DZ\n"
"18*0.25 /\n"
"TOPS\n"
"9*0.25 /\n"
"FLUXNUM\n"
"1 1 2\n"
"1 1 2\n"
"1 1 2\n"
"3 4 5\n"
"3 4 5\n"
"3 4 5\n"
"/\n"
"MULTREGT\n"
"3 4 1.25 XYZ ALL F /\n"
"2 -1 0 XYZ ALL F / -- Defaulted from region value \n"
"1 -1 0 XYZ ALL F / -- Defaulted from region value \n"
"2 1 1 XYZ ALL F / Override default \n"
"/\n"
"MULTREGT\n"
"2 * 0.75 XYZ ALL F / -- Defaulted to region value \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
namespace {
Opm::Deck createDefaultedRegions()
{
return Opm::Parser{}.parseString(R"(RUNSPEC
DIMENS
3 3 2 /
GRID
DX
18*0.25 /
DY
18*0.25 /
DZ
18*0.25 /
TOPS
9*0.25 /
FLUXNUM
1 1 2
1 1 2
1 1 2
3 4 5
3 4 5
3 4 5
/
MULTREGT
3 4 1.25 XYZ ALL F /
2 -1 0 XYZ ALL F / -- Defaulted from region value
1 -1 0 XYZ ALL F / -- Defaulted from region value
2 1 1 XYZ ALL F / Override default
/
MULTREGT
2 * 0.75 XYZ ALL F / -- Defaulted to region value
/
EDIT
)");
}
} // Anonymous namespace
BOOST_AUTO_TEST_CASE(DefaultedRegions) {
Opm::Deck deck = createDefaultedRegions();
@@ -252,42 +247,37 @@ BOOST_AUTO_TEST_CASE(DefaultedRegions) {
BOOST_CHECK_EQUAL( scanner1.getRegionMultiplier(grid.getGlobalIndex(2,0,0), grid.getGlobalIndex(2,0,1), Opm::FaceDir::ZPlus), 0.75);
}
static Opm::Deck createCopyMULTNUMDeck() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
"2 2 2 /\n"
"GRID\n"
"DX\n"
"8*0.25 /\n"
"DY\n"
"8*0.25 /\n"
"DZ\n"
"8*0.25 /\n"
"TOPS\n"
"4*0.25 /\n"
"FLUXNUM\n"
"1 2\n"
"1 2\n"
"3 4\n"
"3 4\n"
"/\n"
"COPY\n"
" FLUXNUM MULTNUM /\n"
"/\n"
"MULTREGT\n"
"1 2 0.50/ \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
namespace {
Opm::Deck createCopyMULTNUMDeck()
{
return Opm::Parser{}.parseString(R"(RUNSPEC
DIMENS
2 2 2 /
GRID
DX
8*0.25 /
DY
8*0.25 /
DZ
8*0.25 /
TOPS
4*0.25 /
FLUXNUM
1 2
1 2
3 4
3 4
/
COPY
FLUXNUM MULTNUM /
/
MULTREGT
1 2 0.50/
/
EDIT
)");
}
} // Anonymous namespace
BOOST_AUTO_TEST_CASE(MULTREGT_COPY_MULTNUM) {
Opm::Deck deck = createCopyMULTNUMDeck();