Merge pull request #521 from joakim-hove/input-sim
Add skeleton for input simulator
This commit is contained in:
@@ -7,6 +7,7 @@ set(OPM_MACROS_ROOT ${PROJECT_SOURCE_DIR})
|
||||
|
||||
option(ENABLE_ECL_INPUT "Enable eclipse input support?" ON)
|
||||
option(ENABLE_ECL_OUTPUT "Enable eclipse output support?" ON)
|
||||
option(ENABLE_MOCKSIM "Build the mock simulator for io testing" OFF)
|
||||
|
||||
# Output implies input
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
@@ -18,6 +19,7 @@ if(NOT ENABLE_ECL_INPUT)
|
||||
set(ENABLE_ECL_OUTPUT OFF)
|
||||
endif()
|
||||
|
||||
|
||||
# not the same location as most of the other projects; this hook overrides
|
||||
macro (dir_hook)
|
||||
endmacro (dir_hook)
|
||||
@@ -130,6 +132,30 @@ endmacro (install_hook)
|
||||
# all setup common to the OPM library modules is done here
|
||||
include (OpmLibMain)
|
||||
|
||||
if (ENABLE_MOCKSIM)
|
||||
add_library(mocksim
|
||||
msim/src/msim.cpp)
|
||||
target_link_libraries(mocksim opmcommon)
|
||||
target_include_directories(mocksim PUBLIC msim/include)
|
||||
add_executable(msim examples/msim.cpp)
|
||||
target_link_libraries(msim mocksim)
|
||||
|
||||
set(_libs mocksim opmcommon
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
||||
|
||||
foreach( test test_msim)
|
||||
add_executable(${test} "tests/msim/${test}")
|
||||
target_link_libraries(${test} ${_libs})
|
||||
add_test(NAME ${test} COMMAND ${test})
|
||||
set_tests_properties(${test} PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests)
|
||||
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties(${test} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Build the compare utilities
|
||||
if(ENABLE_ECL_INPUT)
|
||||
add_library(testutil STATIC
|
||||
|
||||
28
examples/msim.cpp
Normal file
28
examples/msim.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2013 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/>.
|
||||
*/
|
||||
|
||||
#include <opm/msim/msim.hpp>
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Opm::msim msim(argv[1]);
|
||||
msim.run();
|
||||
}
|
||||
|
||||
38
msim/include/opm/msim/msim.hpp
Normal file
38
msim/include/opm/msim/msim.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef ISIM_MAIN_HPP
|
||||
#define ISIM_MAIN_HPP
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseIO;
|
||||
|
||||
class msim {
|
||||
public:
|
||||
msim(const std::string& deck_file);
|
||||
msim(const std::string& deck_file, const Parser& parser, const ParseContext& parse_context);
|
||||
|
||||
void run();
|
||||
private:
|
||||
|
||||
void run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const;
|
||||
void run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, double dt, EclipseIO& io) const;
|
||||
void output(size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, EclipseIO& io) const;
|
||||
|
||||
Deck deck;
|
||||
EclipseState state;
|
||||
Schedule schedule;
|
||||
SummaryConfig summary_config;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
101
msim/src/msim.cpp
Normal file
101
msim/src/msim.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright 2018 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 <iostream>
|
||||
|
||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
#include <opm/output/data/Solution.hpp>
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/msim/msim.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
msim::msim(const std::string& deck_file, const Parser& parser, const ParseContext& parse_context) :
|
||||
deck(parser.parseFile(deck_file, parse_context)),
|
||||
state(deck, parse_context),
|
||||
schedule(deck, state.getInputGrid(), state.get3DProperties(), state.runspec().phases(), parse_context),
|
||||
summary_config(deck, schedule, state.getTableManager(), parse_context)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
msim::msim(const std::string& deck_file) :
|
||||
msim(deck_file, Parser(), ParseContext())
|
||||
{}
|
||||
|
||||
|
||||
void msim::run() {
|
||||
const double week = 7 * 86400;
|
||||
EclipseIO io(this->state, this->state.getInputGrid(), this->schedule, this->summary_config);
|
||||
data::Solution sol;
|
||||
data::Wells well_data;
|
||||
|
||||
io.writeInitial();
|
||||
for (size_t report_step = 1; report_step < this->schedule.size(); report_step++) {
|
||||
double time_step = std::min(week, 0.5*this->schedule.stepLength(report_step - 1));
|
||||
run_step(sol, well_data, report_step, time_step, io);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, EclipseIO& io) const {
|
||||
this->run_step(sol, well_data, report_step, this->schedule.stepLength(report_step - 1), io);
|
||||
}
|
||||
|
||||
|
||||
void msim::run_step(data::Solution& sol, data::Wells& well_data, size_t report_step, double dt, EclipseIO& io) const {
|
||||
double start_time = this->schedule.seconds(report_step - 1);
|
||||
double end_time = this->schedule.seconds(report_step);
|
||||
double seconds_elapsed = start_time;
|
||||
|
||||
while (seconds_elapsed < end_time) {
|
||||
double time_step = dt;
|
||||
if ((seconds_elapsed + time_step) > end_time)
|
||||
time_step = end_time - seconds_elapsed;
|
||||
|
||||
// Simulate
|
||||
|
||||
seconds_elapsed += time_step;
|
||||
this->output(report_step,
|
||||
(seconds_elapsed < end_time),
|
||||
seconds_elapsed,
|
||||
sol,
|
||||
well_data,
|
||||
io);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void msim::output(size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, EclipseIO& io) const {
|
||||
RestartValue value(sol, well_data);
|
||||
io.writeTimeStep(report_step,
|
||||
false,
|
||||
seconds_elapsed,
|
||||
value,
|
||||
{},
|
||||
{},
|
||||
{});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,7 +73,8 @@ namespace Opm
|
||||
time_t getStartTime() const;
|
||||
time_t posixStartTime() const;
|
||||
time_t posixEndTime() const;
|
||||
|
||||
double seconds(size_t timeStep) const;
|
||||
double stepLength(size_t timeStep) const;
|
||||
|
||||
const TimeMap& getTimeMap() const;
|
||||
|
||||
@@ -127,7 +128,7 @@ namespace Opm
|
||||
active. Will scan through all wells and all timesteps.
|
||||
*/
|
||||
void filterConnections(const EclipseGrid& grid);
|
||||
|
||||
size_t size() const;
|
||||
private:
|
||||
TimeMap m_timeMap;
|
||||
OrderedMap< Well > m_wells;
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace Opm {
|
||||
size_t last() const;
|
||||
size_t numTimesteps() const;
|
||||
double getTotalTime() const;
|
||||
double seconds(size_t timeStep) const;
|
||||
|
||||
std::time_t operator[] (size_t index) const;
|
||||
/// Return the date and time where a given time step starts.
|
||||
|
||||
@@ -1883,5 +1883,20 @@ namespace Opm {
|
||||
const auto& ptr = this->wtest_config.get(timeStep);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
|
||||
size_t Schedule::size() const {
|
||||
return this->m_timeMap.size();
|
||||
}
|
||||
|
||||
|
||||
double Schedule::seconds(size_t timeStep) const {
|
||||
return this->m_timeMap.seconds(timeStep);
|
||||
}
|
||||
|
||||
|
||||
double Schedule::stepLength(size_t timeStep) const {
|
||||
return this->m_timeMap.getTimeStepLength(timeStep);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,11 @@ namespace Opm {
|
||||
return this->operator[]( this->size( ) - 1);
|
||||
}
|
||||
|
||||
|
||||
double TimeMap::seconds(size_t timeStep) const {
|
||||
return std::difftime( this->operator[](timeStep), this->operator[](0));
|
||||
}
|
||||
|
||||
double TimeMap::getTotalTime() const
|
||||
{
|
||||
if (m_timeList.size() < 2)
|
||||
|
||||
46
tests/msim/test_msim.cpp
Normal file
46
tests/msim/test_msim.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2018 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 <stdexcept>
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#define BOOST_TEST_MODULE WTEST
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <ert/util/test_work_area.h>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <opm/msim/msim.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RUN) {
|
||||
msim msim("SPE1CASE1.DATA");
|
||||
{
|
||||
test_work_area_type * work_area = test_work_area_alloc("test_msim");
|
||||
msim.run();
|
||||
|
||||
for (const auto& fname : {"SPE1CASE1.INIT", "SPE1CASE1.UNRST", "SPE1CASE1.EGRID", "SPE1CASE1.SMSPEC"})
|
||||
BOOST_CHECK( util_is_file( fname ));
|
||||
|
||||
test_work_area_free( work_area );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user