Files
opm-common/tests/parser/InitConfigTest.cpp
Bård Skaflestad ffecc035c0 InitConfig: Internalize FILLEPS Keyword
This commit extends the InitConfig class to support querying whether
or not the FILLEPS keyword is present in the PROPS section.  Note
that we only look for the keyword in PROPS (not the whole input
deck), since the keyword is only permitted in PROPS.

Add unit tests to exercise the new ability.
2019-06-24 14:15:55 +02:00

539 lines
9.7 KiB
C++

/*
Copyright 2015 Statoil 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 InitConfigTests
#include <sys/stat.h>
#include <sys/types.h>
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <ert/util/test_work_area.hpp>
using namespace Opm;
const std::string& deckStr =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5\n"
"/\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n";
const std::string& deckStr2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n";
const std::string& deckStr3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5 SAVE UNFORMATTED /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n";
const std::string& deckStr4 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n";
const std::string& deckStr5 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"'/abs/path/BASE' 5 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n";
const std::string& deckWithEquil =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"EQLDIMS\n"
"1 100 20 1 1 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5\n"
"/\n"
"EQUIL\n"
"2469 382.4 1705.0 0.0 500 0.0 1 1 20 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n";
static Deck createDeck(const std::string& input) {
Opm::Parser parser;
return parser.parseString(input);
}
BOOST_AUTO_TEST_CASE(InitConfigTest) {
Deck deck = createDeck(deckStr);
InitConfig cfg( deck );
BOOST_CHECK_EQUAL(cfg.restartRequested(), true);
BOOST_CHECK_EQUAL(cfg.getRestartStep(), 5);
BOOST_CHECK_EQUAL(cfg.getRestartRootName(), "BASE");
Deck deck2 = createDeck(deckStr2);
InitConfig cfg2( deck2 );
BOOST_CHECK_EQUAL(cfg2.restartRequested(), false);
BOOST_CHECK_EQUAL(cfg2.getRestartStep(), 0);
BOOST_CHECK_EQUAL(cfg2.getRestartRootName(), "");
cfg2.setRestart( "CASE" , 100);
BOOST_CHECK_EQUAL(cfg2.restartRequested(), true);
BOOST_CHECK_EQUAL(cfg2.getRestartStep(), 100);
BOOST_CHECK_EQUAL(cfg2.getRestartRootName(), "CASE");
Deck deck3 = createDeck(deckStr3);
BOOST_CHECK_THROW( InitConfig{ deck3 }, std::runtime_error );
Deck deck4 = createDeck(deckStr4);
BOOST_CHECK_NO_THROW( InitConfig{ deck4 } );
}
BOOST_AUTO_TEST_CASE( InitConfigWithoutEquil ) {
auto deck = createDeck( deckStr );
InitConfig config( deck );
BOOST_CHECK( !config.hasEquil() );
BOOST_CHECK_THROW( config.getEquil(), std::runtime_error );
}
BOOST_AUTO_TEST_CASE( InitConfigWithEquil ) {
auto deck = createDeck( deckWithEquil );
InitConfig config( deck );
BOOST_CHECK( config.hasEquil() );
BOOST_CHECK_NO_THROW( config.getEquil() );
}
BOOST_AUTO_TEST_CASE( EquilOperations ) {
auto deck = createDeck( deckWithEquil );
InitConfig config( deck );
const auto& equil = config.getEquil();
BOOST_CHECK( !equil.empty() );
BOOST_CHECK_EQUAL( 1U, equil.size() );
BOOST_CHECK_NO_THROW( equil.getRecord( 0 ) );
BOOST_CHECK_THROW( equil.getRecord( 1 ), std::out_of_range );
const auto& record = equil.getRecord( 0 );
BOOST_CHECK_CLOSE( 2469, record.datumDepth(), 1e-12 );
BOOST_CHECK_CLOSE( 382.4 * unit::barsa, record.datumDepthPressure(), 1e-12 );
BOOST_CHECK_CLOSE( 1705.0, record.waterOilContactDepth(), 1e-12 );
BOOST_CHECK_CLOSE( 0.0, record.waterOilContactCapillaryPressure(), 1e-12 );
BOOST_CHECK_CLOSE( 500, record.gasOilContactDepth(), 1e-12 );
BOOST_CHECK_CLOSE( 0.0, record.gasOilContactCapillaryPressure(), 1e-12 );
BOOST_CHECK( !record.liveOilInitConstantRs() );
BOOST_CHECK( !record.wetGasInitConstantRv() );
BOOST_CHECK_EQUAL( 20, record.initializationTargetAccuracy() );
}
BOOST_AUTO_TEST_CASE(RestartCWD) {
test_work_area_type * work_area = test_work_area_alloc("restart_cwd");
mkdir("simulation", 0777);
{
std::fstream fs;
fs.open ("simulation/CASE.DATA", std::fstream::out);
fs << deckStr4;
fs.close();
fs.open("simulation/CASE5.DATA", std::fstream::out);
fs << deckStr5;
fs.close();
fs.open("CASE5.DATA", std::fstream::out);
fs << deckStr5;
fs.close();
fs.open("CWD_CASE.DATA", std::fstream::out);
fs << deckStr4;
fs.close();
}
Opm::Parser parser;
{
Opm::Deck deck = parser.parseFile("simulation/CASE.DATA");
Opm::InitConfig init_config(deck);
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "simulation/BASE");
}
{
Opm::Deck deck = parser.parseFile("simulation/CASE5.DATA");
Opm::InitConfig init_config(deck);
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE");
}
{
Opm::Deck deck = parser.parseFile("CWD_CASE.DATA");
Opm::InitConfig init_config(deck);
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "BASE");
}
{
Opm::Deck deck = parser.parseFile("CASE5.DATA");
Opm::InitConfig init_config(deck);
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE");
}
test_work_area_free(work_area);
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_SUITE (FILLEPS)
BOOST_AUTO_TEST_CASE(WrongSection)
{
// FILLEPS in GRID section (should ideally be caught at load time)
auto input = std::string { R"(
RUNSPEC
DIMENS
5 5 3 /
TITLE
Break FILLEPS Keyword
START
24 'JUN' 2019 /
GAS
OIL
WATER
DISGAS
METRIC
TABDIMS
/
GRID
INIT
DXV
5*100 /
DYV
5*100 /
DZV
3*10 /
TOPS
25*2000 /
EQUALS
PERMX 100 /
/
COPY
PERMX PERMY /
PERMX PERMZ /
/
MULTIPLY
PERMZ 0.1 /
/
PORO
75*0.3 /
-- Wrong section (should be in PROPS)
FILLEPS
PROPS
SWOF
0 0 1 0
1 1 0 0 /
SGOF
0 0 1 0
1 1 0 0 /
DENSITY
900 1000 1 /
PVTW
400 1 1.0E-06 1 0 /
PVDG
30 0.04234 0.01344
530 0.003868 0.02935
/
PVTO
0.000 1.0 1.07033 0.645
500.0 1.02339 1.029 /
17.345 25.0 1.14075 0.484
500.0 1.07726 0.834 /
31.462 50.0 1.18430 0.439
500.0 1.11592 0.757 /
45.089 75.0 1.22415 0.402
500.0 1.15223 0.689 /
/
END
)" };
const auto es = ::Opm::EclipseState {
::Opm::Parser{}.parseString(input)
};
// Keyword present but placed in wrong section => treat as absent
BOOST_CHECK(! es.cfg().init().filleps());
}
BOOST_AUTO_TEST_CASE(Present)
{
auto input = std::string { R"(
RUNSPEC
DIMENS
5 5 3 /
TITLE
Break FILLEPS Keyword
START
24 'JUN' 2019 /
GAS
OIL
WATER
DISGAS
METRIC
TABDIMS
/
GRID
INIT
DXV
5*100 /
DYV
5*100 /
DZV
3*10 /
TOPS
25*2000 /
EQUALS
PERMX 100 /
/
COPY
PERMX PERMY /
PERMX PERMZ /
/
MULTIPLY
PERMZ 0.1 /
/
PORO
75*0.3 /
PROPS
SWOF
0 0 1 0
1 1 0 0 /
SGOF
0 0 1 0
1 1 0 0 /
DENSITY
900 1000 1 /
PVTW
400 1 1.0E-06 1 0 /
PVDG
30 0.04234 0.01344
530 0.003868 0.02935
/
PVTO
0.000 1.0 1.07033 0.645
500.0 1.02339 1.029 /
17.345 25.0 1.14075 0.484
500.0 1.07726 0.834 /
31.462 50.0 1.18430 0.439
500.0 1.11592 0.757 /
45.089 75.0 1.22415 0.402
500.0 1.15223 0.689 /
/
FILLEPS
END
)" };
const auto es = ::Opm::EclipseState {
::Opm::Parser{}.parseString(input)
};
BOOST_CHECK(es.cfg().init().filleps());
}
BOOST_AUTO_TEST_CASE(Absent)
{
auto input = std::string { R"(
RUNSPEC
DIMENS
5 5 3 /
TITLE
Break FILLEPS Keyword
START
24 'JUN' 2019 /
GAS
OIL
WATER
DISGAS
METRIC
TABDIMS
/
GRID
INIT
DXV
5*100 /
DYV
5*100 /
DZV
3*10 /
TOPS
25*2000 /
EQUALS
PERMX 100 /
/
COPY
PERMX PERMY /
PERMX PERMZ /
/
MULTIPLY
PERMZ 0.1 /
/
PORO
75*0.3 /
PROPS
SWOF
0 0 1 0
1 1 0 0 /
SGOF
0 0 1 0
1 1 0 0 /
DENSITY
900 1000 1 /
PVTW
400 1 1.0E-06 1 0 /
PVDG
30 0.04234 0.01344
530 0.003868 0.02935
/
PVTO
0.000 1.0 1.07033 0.645
500.0 1.02339 1.029 /
17.345 25.0 1.14075 0.484
500.0 1.07726 0.834 /
31.462 50.0 1.18430 0.439
500.0 1.11592 0.757 /
45.089 75.0 1.22415 0.402
500.0 1.15223 0.689 /
/
-- No FILLEPS here
-- FILLEPS
END
)" };
const auto es = ::Opm::EclipseState {
::Opm::Parser{}.parseString(input)
};
BOOST_CHECK(! es.cfg().init().filleps());
}
BOOST_AUTO_TEST_SUITE_END()