Add Tool for Checking Array Dimensions
This commit introduces a new function, Opm::checkConsistentArrayDimensions() that inspects various dynamic array/table sizes and compares those to the maximum dimensions requested in the relevant *DIMS keywords of the RUNSPEC section. At present we check only items one through four of WELLDIMS since those are directly relevant for the ECLIPSE-compatible output code. We leverage the ErrorGuard to integrate into the existing mechanism for terminating a simulation run if there's a parse failure.
This commit is contained in:
parent
7bf635ef59
commit
6cc65ada59
@ -82,6 +82,7 @@ if(ENABLE_ECL_INPUT)
|
|||||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionParser.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionParser.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/Action/ASTNode.cpp
|
||||||
|
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp
|
||||||
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
||||||
@ -256,6 +257,7 @@ if(ENABLE_ECL_OUTPUT)
|
|||||||
tests/test_AggregateWellData.cpp
|
tests/test_AggregateWellData.cpp
|
||||||
#The unit tests are not finished yet, will be added in a separate pullrequest soon
|
#The unit tests are not finished yet, will be added in a separate pullrequest soon
|
||||||
#tests/test_AggregateMSWData.cpp
|
#tests/test_AggregateMSWData.cpp
|
||||||
|
tests/test_ArrayDimChecker.cpp
|
||||||
tests/test_CharArrayNullTerm.cpp
|
tests/test_CharArrayNullTerm.cpp
|
||||||
tests/test_EclipseIO.cpp
|
tests/test_EclipseIO.cpp
|
||||||
tests/test_DoubHEAD.cpp
|
tests/test_DoubHEAD.cpp
|
||||||
@ -281,6 +283,7 @@ list (APPEND TEST_DATA_FILES
|
|||||||
)
|
)
|
||||||
if(ENABLE_ECL_OUTPUT)
|
if(ENABLE_ECL_OUTPUT)
|
||||||
list (APPEND TEST_DATA_FILES
|
list (APPEND TEST_DATA_FILES
|
||||||
|
tests/expect-wdims.err.out
|
||||||
tests/FIRST_SIM.DATA
|
tests/FIRST_SIM.DATA
|
||||||
tests/FIRST_SIM_THPRES.DATA
|
tests/FIRST_SIM_THPRES.DATA
|
||||||
tests/summary_deck.DATA
|
tests/summary_deck.DATA
|
||||||
@ -465,6 +468,7 @@ if(ENABLE_ECL_INPUT)
|
|||||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp
|
opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp
|
opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp
|
opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp
|
||||||
|
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp
|
opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
|
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
|
||||||
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
|
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
|
||||||
|
42
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
Normal file
42
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 Equinor ASA
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPM_ARRAYDIM_CHECKER_HPP
|
||||||
|
#define OPM_ARRAYDIM_CHECKER_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
class ErrorGuard;
|
||||||
|
class EclipseState;
|
||||||
|
class ParseContext;
|
||||||
|
class Schedule;
|
||||||
|
} // Opm
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
int maxGroupSize(const Schedule& sched,
|
||||||
|
const std::size_t step);
|
||||||
|
|
||||||
|
void checkConsistentArrayDimensions(const EclipseState& es,
|
||||||
|
const Schedule& sched,
|
||||||
|
const ParseContext& ctxt,
|
||||||
|
ErrorGuard& guard);
|
||||||
|
} // Opm
|
||||||
|
|
||||||
|
#endif // OPM_ARRAYDIM_CHECKER_HPP
|
189
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
Normal file
189
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 Equinor ASA
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||||
|
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
namespace WellDims {
|
||||||
|
void checkNumWells(const Opm::Welldims& wdims,
|
||||||
|
const Opm::Schedule& sched,
|
||||||
|
const Opm::ParseContext& ctxt,
|
||||||
|
Opm::ErrorGuard& guard)
|
||||||
|
{
|
||||||
|
const auto nWells = sched.numWells();
|
||||||
|
|
||||||
|
if (nWells > static_cast<decltype(nWells)>(wdims.maxWellsInField()))
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Run uses " << nWells << " wells, but allocates at "
|
||||||
|
<< "most " << wdims.maxWellsInField() << " in RUNSPEC "
|
||||||
|
<< "section. Increase item 1 of WELLDIMS accordingly.";
|
||||||
|
|
||||||
|
ctxt.handleError(Opm::ParseContext::RUNSPEC_NUMWELLS_TOO_LARGE,
|
||||||
|
os.str(), guard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkConnPerWell(const Opm::Welldims& wdims,
|
||||||
|
const Opm::Schedule& sched,
|
||||||
|
const Opm::ParseContext& ctxt,
|
||||||
|
Opm::ErrorGuard& guard)
|
||||||
|
{
|
||||||
|
auto nconn = std::size_t{0};
|
||||||
|
for (const auto* well : sched.getWells()) {
|
||||||
|
nconn = std::max(nconn, well->getConnections().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nconn > static_cast<decltype(nconn)>(wdims.maxConnPerWell()))
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Run has well with " << nconn << " reservoir connections, "
|
||||||
|
<< "but allocates at most " << wdims.maxConnPerWell()
|
||||||
|
<< " connections per well in RUNSPEC section. Increase item "
|
||||||
|
<< "2 of WELLDIMS accordingly.";
|
||||||
|
|
||||||
|
ctxt.handleError(Opm::ParseContext::RUNSPEC_CONNS_PER_WELL_TOO_LARGE,
|
||||||
|
os.str(), guard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkNumGroups(const Opm::Welldims& wdims,
|
||||||
|
const Opm::Schedule& sched,
|
||||||
|
const Opm::ParseContext& ctxt,
|
||||||
|
Opm::ErrorGuard& guard)
|
||||||
|
{
|
||||||
|
const auto nGroups = sched.numGroups();
|
||||||
|
|
||||||
|
// Note: "1 +" to account for FIELD group being in 'sched.numGroups()'
|
||||||
|
// but excluded from WELLDIMS(3).
|
||||||
|
if (nGroups > 1 + static_cast<decltype(nGroups)>(wdims.maxGroupsInField()))
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Run uses " << (nGroups - 1) << " non-FIELD groups, but "
|
||||||
|
<< "allocates at most " << wdims.maxGroupsInField()
|
||||||
|
<< " in RUNSPEC section. Increase item 3 of WELLDIMS "
|
||||||
|
<< "accordingly.";
|
||||||
|
|
||||||
|
ctxt.handleError(Opm::ParseContext::RUNSPEC_NUMGROUPS_TOO_LARGE,
|
||||||
|
os.str(), guard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkGroupSize(const Opm::Welldims& wdims,
|
||||||
|
const Opm::Schedule& sched,
|
||||||
|
const Opm::ParseContext& ctxt,
|
||||||
|
Opm::ErrorGuard& guard)
|
||||||
|
{
|
||||||
|
const auto numSteps = sched.getTimeMap().numTimesteps();
|
||||||
|
|
||||||
|
auto size = std::size_t{0};
|
||||||
|
for (auto step = 0*numSteps; step < numSteps; ++step) {
|
||||||
|
const auto nwgmax = maxGroupSize(sched, step);
|
||||||
|
|
||||||
|
size = std::max(size, static_cast<std::size_t>(nwgmax));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size >= static_cast<decltype(size)>(wdims.maxWellsPerGroup()))
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Run uses maximum group size of " << size << ", but "
|
||||||
|
<< "allocates at most " << wdims.maxWellsPerGroup()
|
||||||
|
<< " in RUNSPEC section. Increase item 4 of WELLDIMS "
|
||||||
|
<< "accordingly.";
|
||||||
|
|
||||||
|
ctxt.handleError(Opm::ParseContext::RUNSPEC_GROUPSIZE_TOO_LARGE,
|
||||||
|
os.str(), guard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // WellDims
|
||||||
|
|
||||||
|
void consistentWellDims(const Opm::Welldims& wdims,
|
||||||
|
const Opm::Schedule& sched,
|
||||||
|
const Opm::ParseContext& ctxt,
|
||||||
|
Opm::ErrorGuard& guard)
|
||||||
|
{
|
||||||
|
WellDims::checkNumWells (wdims, sched, ctxt, guard);
|
||||||
|
WellDims::checkConnPerWell(wdims, sched, ctxt, guard);
|
||||||
|
WellDims::checkNumGroups (wdims, sched, ctxt, guard);
|
||||||
|
WellDims::checkGroupSize (wdims, sched, ctxt, guard);
|
||||||
|
}
|
||||||
|
} // Anonymous
|
||||||
|
|
||||||
|
void
|
||||||
|
Opm::checkConsistentArrayDimensions(const EclipseState& es,
|
||||||
|
const Schedule& sched,
|
||||||
|
const ParseContext& ctxt,
|
||||||
|
ErrorGuard& guard)
|
||||||
|
{
|
||||||
|
consistentWellDims(es.runspec().wellDimensions(), sched, ctxt, guard);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Opm::maxGroupSize(const Opm::Schedule& sched,
|
||||||
|
const std::size_t step)
|
||||||
|
{
|
||||||
|
const auto& gt = sched.getGroupTree(step);
|
||||||
|
|
||||||
|
auto groups = std::vector<std::string>{"FIELD"};
|
||||||
|
auto nwgmax = std::size_t{0};
|
||||||
|
|
||||||
|
auto update_size = [&nwgmax](const std::size_t n) {
|
||||||
|
nwgmax = std::max(nwgmax, n);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note: We update 'groups' in the body of the loop, so
|
||||||
|
// groups.size() is potentially increasing as we
|
||||||
|
// traverse down the group tree to its leaf nodes.
|
||||||
|
for (auto i = 0*groups.size(); i < groups.size(); ++i) {
|
||||||
|
const auto& grp = groups[i];
|
||||||
|
auto children = gt.children(grp);
|
||||||
|
|
||||||
|
if (children.empty()) {
|
||||||
|
// Well group. Size is number of wells.
|
||||||
|
update_size(sched.getGroup(grp).numWells(step));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Node group. Size is number of child nodes.
|
||||||
|
update_size(children.size());
|
||||||
|
|
||||||
|
// Enqueue those children to get their sizes.
|
||||||
|
groups.insert(groups.end(),
|
||||||
|
std::make_move_iterator(children.begin()),
|
||||||
|
std::make_move_iterator(children.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nwgmax;
|
||||||
|
}
|
8
tests/expect-wdims.err.out
Normal file
8
tests/expect-wdims.err.out
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Errors:
|
||||||
|
RUNSPEC_NUMWELLS_TOO_LARGE : Run uses 12 wells, but allocates at most 0 in RUNSPEC section. Increase item 1 of WELLDIMS accordingly.
|
||||||
|
RUNSPEC_CONNS_PER_WELL_TOO_LARGE: Run has well with 15 reservoir connections, but allocates at most 0 connections per well in RUNSPEC section. Increase item 2 of WELLDIMS accordingly.
|
||||||
|
RUNSPEC_NUMGROUPS_TOO_LARGE : Run uses 11 non-FIELD groups, but allocates at most 0 in RUNSPEC section. Increase item 3 of WELLDIMS accordingly.
|
||||||
|
RUNSPEC_GROUPSIZE_TOO_LARGE : Run uses maximum group size of 10, but allocates at most 0 in RUNSPEC section. Increase item 4 of WELLDIMS accordingly.
|
||||||
|
|
280
tests/test_ArrayDimChecker.cpp
Normal file
280
tests/test_ArrayDimChecker.cpp
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 Equinor ASA
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BOOST_TEST_MODULE Array_Dimension_Checker
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <boost/test/output_test_stream.hpp>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||||
|
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||||
|
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
Opm::Deck simCaseWellDims()
|
||||||
|
{
|
||||||
|
const auto input = std::string{ R"(RUNSPEC
|
||||||
|
TITLE
|
||||||
|
'Check Well Dimensions' /
|
||||||
|
|
||||||
|
DIMENS
|
||||||
|
20 20 15 /
|
||||||
|
|
||||||
|
OIL
|
||||||
|
WATER
|
||||||
|
|
||||||
|
METRIC
|
||||||
|
|
||||||
|
EQLDIMS
|
||||||
|
-- Defaulted
|
||||||
|
/
|
||||||
|
|
||||||
|
TABDIMS
|
||||||
|
-- Defaulted
|
||||||
|
/
|
||||||
|
|
||||||
|
WELLDIMS
|
||||||
|
-- Defaulted
|
||||||
|
/
|
||||||
|
|
||||||
|
-- ====================================================================
|
||||||
|
GRID
|
||||||
|
|
||||||
|
SPECGRID
|
||||||
|
20 20 15 1 F /
|
||||||
|
|
||||||
|
DXV
|
||||||
|
20*100.0 /
|
||||||
|
|
||||||
|
DYV
|
||||||
|
20*100.0 /
|
||||||
|
|
||||||
|
DZV
|
||||||
|
15*0.1 /
|
||||||
|
|
||||||
|
DEPTHZ
|
||||||
|
441*2000 /
|
||||||
|
|
||||||
|
PORO
|
||||||
|
6000*0.3 /
|
||||||
|
|
||||||
|
PERMX
|
||||||
|
6000*100.0 /
|
||||||
|
|
||||||
|
COPY
|
||||||
|
'PERMX' 'PERMY' /
|
||||||
|
'PERMX' 'PERMZ' /
|
||||||
|
/
|
||||||
|
|
||||||
|
MULTIPLY
|
||||||
|
'PERMZ' 0.1 /
|
||||||
|
/
|
||||||
|
|
||||||
|
-- ====================================================================
|
||||||
|
PROPS
|
||||||
|
|
||||||
|
SWOF
|
||||||
|
0 0 1 0
|
||||||
|
1 1 0 0 /
|
||||||
|
|
||||||
|
PVDO
|
||||||
|
1 1.0 0.5
|
||||||
|
800 0.99 0.51 /
|
||||||
|
|
||||||
|
PVTW
|
||||||
|
300 0.99 1.0e-6 0.25 0 /
|
||||||
|
|
||||||
|
DENSITY
|
||||||
|
850.0 1014.0 1.05 /
|
||||||
|
|
||||||
|
-- ====================================================================
|
||||||
|
SOLUTION
|
||||||
|
|
||||||
|
EQUIL
|
||||||
|
2000 300 2010 0.0 2000 10 /
|
||||||
|
|
||||||
|
-- ====================================================================
|
||||||
|
SUMMARY
|
||||||
|
ALL
|
||||||
|
|
||||||
|
-- ====================================================================
|
||||||
|
SCHEDULE
|
||||||
|
|
||||||
|
RPTRST
|
||||||
|
BASIC=5 FREQ=6 /
|
||||||
|
|
||||||
|
GRUPTREE
|
||||||
|
'G1' 'FIELD' /
|
||||||
|
'PLAT1' 'G1' /
|
||||||
|
'PLAT2' 'G1' /
|
||||||
|
'I-NORTH' 'PLAT1' /
|
||||||
|
'P-NORTH' 'PLAT1' /
|
||||||
|
'O-WEST' 'PLAT2' /
|
||||||
|
'I-SOUTH' 'PLAT2' /
|
||||||
|
'P-EAST' 'PLAT2' /
|
||||||
|
'G2' 'FIELD' /
|
||||||
|
'PLAT3' 'G2' /
|
||||||
|
'I-2' 'PLAT3' /
|
||||||
|
/
|
||||||
|
|
||||||
|
WELSPECS
|
||||||
|
'I-N-1' 'I-NORTH' 1 1 2000.15 'WATER' /
|
||||||
|
'I-N-2' 'I-NORTH' 5 1 2001.05 'WATER' /
|
||||||
|
'P-N-0' 'P-NORTH' 1 10 2000.15 'OIL' /
|
||||||
|
'P-N-1' 'P-NORTH' 10 15 2000.15 'OIL' /
|
||||||
|
'P-N-2' 'P-NORTH' 1 20 2000.15 'OIL' /
|
||||||
|
'P-N-3' 'P-NORTH' 19 20 2000.15 'OIL' /
|
||||||
|
'P-N-4' 'P-NORTH' 15 10 2000.15 'OIL' /
|
||||||
|
'P-N-5' 'P-NORTH' 10 10 2000.15 'OIL' /
|
||||||
|
'P-N-6' 'P-NORTH' 10 20 2000.15 'OIL' /
|
||||||
|
'P-N-7' 'P-NORTH' 7 15 2000.15 'OIL' /
|
||||||
|
'P-N-8' 'P-NORTH' 2 20 2000.15 'OIL' /
|
||||||
|
'P-N-9' 'P-NORTH' 20 1 2000.05 'OIL' /
|
||||||
|
/
|
||||||
|
|
||||||
|
COMPDAT
|
||||||
|
'I-N-1' 0 0 2 10 'OPEN' 1* 1* 1.0 /
|
||||||
|
'I-N-2' 0 0 10 15 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-0' 0 0 2 3 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-1' 0 0 2 4 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-2' 0 0 2 5 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-3' 0 0 2 6 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-4' 0 0 2 7 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-5' 0 0 2 8 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-6' 0 0 2 9 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-7' 0 0 2 10 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-8' 0 0 2 5 'OPEN' 1* 1* 1.0 /
|
||||||
|
'P-N-9' 0 0 1 15 'OPEN' 1* 1* 1.0 /
|
||||||
|
/
|
||||||
|
|
||||||
|
WCONPROD
|
||||||
|
-- Well O/S Mode ORAT WRAT GRAT LRAT RESV BHP
|
||||||
|
'P-N-*' 'OPEN' 'LRAT' 1* 1* 1* 5E3 1* 100 /
|
||||||
|
/
|
||||||
|
|
||||||
|
WCONINJE
|
||||||
|
-- Well Type O/S Mode RATE RESV BHP
|
||||||
|
'I-N-*' 'WATER' 'OPEN' 'RATE' 25E3 1* 500 /
|
||||||
|
/
|
||||||
|
|
||||||
|
TSTEP
|
||||||
|
100*30 /
|
||||||
|
|
||||||
|
END
|
||||||
|
)" };
|
||||||
|
|
||||||
|
return Opm::Parser{}.parseString(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CaseObjects
|
||||||
|
{
|
||||||
|
explicit CaseObjects(const Opm::Deck& deck);
|
||||||
|
~CaseObjects();
|
||||||
|
|
||||||
|
CaseObjects(const CaseObjects& rhs) = default;
|
||||||
|
CaseObjects(CaseObjects&& rhs) = default;
|
||||||
|
|
||||||
|
CaseObjects& operator=(const CaseObjects& rhs) = default;
|
||||||
|
CaseObjects& operator=(CaseObjects&& rhs) = default;
|
||||||
|
|
||||||
|
Opm::ErrorGuard guard;
|
||||||
|
Opm::ParseContext ctxt;
|
||||||
|
Opm::EclipseState es;
|
||||||
|
Opm::Schedule sched;
|
||||||
|
};
|
||||||
|
|
||||||
|
CaseObjects::CaseObjects(const Opm::Deck& deck)
|
||||||
|
: guard{}
|
||||||
|
, ctxt {}
|
||||||
|
, es (deck, ctxt, guard)
|
||||||
|
, sched(deck, es, ctxt, guard)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CaseObjects::~CaseObjects()
|
||||||
|
{
|
||||||
|
this->guard.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
class RedirectCERR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit RedirectCERR(std::streambuf* buf);
|
||||||
|
~RedirectCERR();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::streambuf* orig_;
|
||||||
|
};
|
||||||
|
|
||||||
|
RedirectCERR::RedirectCERR(std::streambuf* buf)
|
||||||
|
: orig_{ std::cerr.rdbuf(buf) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RedirectCERR::~RedirectCERR()
|
||||||
|
{
|
||||||
|
std::cerr.rdbuf(this->orig_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================================================================
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(WellDimensions)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(MaxGroupSize)
|
||||||
|
{
|
||||||
|
auto cse = CaseObjects{ simCaseWellDims() };
|
||||||
|
|
||||||
|
// Verify at most ten wells in a single group.
|
||||||
|
BOOST_CHECK_EQUAL(Opm::maxGroupSize(cse.sched, 1), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(WellDims)
|
||||||
|
{
|
||||||
|
auto cse = CaseObjects{ simCaseWellDims() };
|
||||||
|
|
||||||
|
// There should be no failures in basic input layer
|
||||||
|
BOOST_CHECK(!cse.guard);
|
||||||
|
|
||||||
|
Opm::checkConsistentArrayDimensions(cse.es , cse.sched,
|
||||||
|
cse.ctxt, cse.guard);
|
||||||
|
|
||||||
|
// There *should* be errors from dimension checking
|
||||||
|
BOOST_CHECK(cse.guard);
|
||||||
|
|
||||||
|
// Verify that we get expected output from ErrorGuard::dump()
|
||||||
|
boost::test_tools::output_test_stream output{"expect-wdims.err.out", true};
|
||||||
|
{
|
||||||
|
RedirectCERR stream(output.rdbuf());
|
||||||
|
|
||||||
|
cse.guard.dump();
|
||||||
|
|
||||||
|
BOOST_CHECK(output.match_pattern());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue
Block a user