Merge pull request #2879 from joakim-hove/rst-load-tracer-rate

Rst load tracer rate
This commit is contained in:
Joakim Hove 2021-11-30 14:09:15 +01:00 committed by GitHub
commit 0f48afd01d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 77 additions and 22 deletions

View File

@ -23,14 +23,17 @@
#include <ctime>
#include <cstddef>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
namespace Opm {
class UnitSystem;
namespace RestartIO {
struct RstHeader {
RstHeader(const UnitSystem& unit_system, const std::vector<int>& intehead, const std::vector<bool>& logihead, const std::vector<double>& doubhead);
RstHeader(const Runspec& runspec, const UnitSystem& unit_system, const std::vector<int>& intehead, const std::vector<bool>& logihead, const std::vector<double>& doubhead);
Runspec runspec;
int nx;
int ny;
int nz;

View File

@ -50,6 +50,7 @@ namespace Opm { namespace RestartIO {
struct RstState {
RstState(std::shared_ptr<EclIO::RestartFileView> rstView,
const Runspec& runspec,
const ::Opm::EclipseGrid* grid);
static RstState load(std::shared_ptr<EclIO::RestartFileView> rstView,

View File

@ -102,6 +102,7 @@ struct RstWell {
float glift_min_rate;
float glift_weight_factor;
float glift_inc_weight_factor;
std::vector<float> tracer_concentration_injection;
double oil_rate;
double water_rate;

View File

@ -149,7 +149,8 @@ namespace Opm
ErrorGuard& errors,
std::shared_ptr<const Python> python,
const std::optional<int>& output_interval = {},
const RestartIO::RstState* rst = nullptr);
const RestartIO::RstState* rst = nullptr,
const TracerConfig* tracer_config = nullptr);
template<typename T>
Schedule(const Deck& deck,
@ -160,7 +161,8 @@ namespace Opm
T&& errors,
std::shared_ptr<const Python> python,
const std::optional<int>& output_interval = {},
const RestartIO::RstState* rst = nullptr);
const RestartIO::RstState* rst = nullptr,
const TracerConfig* tracer_config = nullptr);
Schedule(const Deck& deck,
const EclipseGrid& grid,
@ -168,7 +170,8 @@ namespace Opm
const Runspec &runspec,
std::shared_ptr<const Python> python,
const std::optional<int>& output_interval = {},
const RestartIO::RstState* rst = nullptr);
const RestartIO::RstState* rst = nullptr,
const TracerConfig* tracer_config = nullptr);
Schedule(const Deck& deck,
const EclipseState& es,
@ -480,6 +483,7 @@ namespace Opm
CompletedCells completed_cells;
void load_rst(const RestartIO::RstState& rst,
const TracerConfig& tracer_config,
const ScheduleGrid& grid,
const FieldPropsManager& fp);
void addWell(Well well);

View File

@ -67,6 +67,7 @@ class SICD;
class SummaryState;
class UDQActive;
class UDQConfig;
class TracerConfig;
namespace RestartIO {
struct RstWell;
@ -495,6 +496,7 @@ public:
Well(const RestartIO::RstWell& rst_well,
int report_step,
const TracerConfig& tracer_config,
const UnitSystem& unit_system,
double udq_undefined);

View File

@ -24,6 +24,7 @@
#include <opm/output/eclipse/VectorItems/doubhead.hpp>
#include <opm/common/utility/TimeService.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
using M = ::Opm::UnitSystem::measure;
@ -31,7 +32,8 @@ using M = ::Opm::UnitSystem::measure;
namespace Opm {
namespace RestartIO {
RstHeader::RstHeader(const Opm::UnitSystem& unit_system, const std::vector<int>& intehead, const std::vector<bool>& logihead, const std::vector<double>& doubhead) :
RstHeader::RstHeader(const Runspec& runspec_, const Opm::UnitSystem& unit_system, const std::vector<int>& intehead, const std::vector<bool>& logihead, const std::vector<double>& doubhead) :
runspec(runspec_),
nx(intehead[VI::intehead::NX]),
ny(intehead[VI::intehead::NY]),
nz(intehead[VI::intehead::NZ]),

View File

@ -82,9 +82,10 @@ namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace Opm { namespace RestartIO {
RstState::RstState(std::shared_ptr<EclIO::RestartFileView> rstView,
const Runspec& runspec,
const ::Opm::EclipseGrid* grid)
: unit_system(rstView->intehead()[VI::intehead::UNIT])
, header(unit_system, rstView->intehead(), rstView->logihead(), rstView->doubhead())
, header(runspec, unit_system, rstView->intehead(), rstView->logihead(), rstView->doubhead())
, aquifers(rstView, grid, unit_system)
, network(rstView, unit_system)
{
@ -407,7 +408,7 @@ RstState RstState::load(std::shared_ptr<EclIO::RestartFileView> rstView,
const Parser& parser,
const ::Opm::EclipseGrid* grid)
{
RstState state(rstView, grid);
RstState state(rstView, runspec, grid);
// At minimum we need any applicable constraint data for FIELD. Load
// groups unconditionally.

View File

@ -126,6 +126,11 @@ RstWell::RstWell(const ::Opm::UnitSystem& unit_system,
water_void_rate( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::WatVoidPrRate])),
gas_void_rate( unit_system.to_si(M::gas_surface_volume, xwel[VI::XWell::GasVoidPrRate]))
{
for (std::size_t tracer_index = 0; tracer_index < static_cast<std::size_t>(header.runspec.tracers().water_tracers()); tracer_index++)
this->tracer_concentration_injection.push_back( swel[VI::SWell::TracerOffset + tracer_index] );
for (int ic = 0; ic < iwel[VI::IWell::NConn]; ic++) {
std::size_t icon_offset = ic * header.niconz;
std::size_t scon_offset = ic * header.nsconz;

View File

@ -44,6 +44,7 @@
#include <opm/output/eclipse/RestartValue.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/TracerConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleTypes.hpp>
@ -70,6 +71,7 @@
#include <unordered_set>
#include <utility>
#include <vector>
#include <fmt/format.h>
#include <boost/range.hpp>
@ -1434,6 +1436,8 @@ namespace {
void assign_well_cumulatives(const std::string& well,
const std::size_t wellID,
const Opm::Tracers& tracer_dims,
const Opm::TracerConfig& tracer_config,
const WellVectors& wellData,
Opm::SummaryState& smry)
{
@ -1466,6 +1470,15 @@ namespace {
smry.update_well_var(well, "WWITH", xwel[VI::XWell::index::HistWatInjTotal]);
smry.update_well_var(well, "WGITH", xwel[VI::XWell::index::HistGasInjTotal]);
for (std::size_t tracer_index = 0; tracer_index < tracer_config.size(); tracer_index++) {
const auto& tracer_name = tracer_config[tracer_index].name;
auto wtpt_offset = VI::XWell::index::TracerOffset + tracer_dims.water_tracers();
auto wtit_offset = VI::XWell::index::TracerOffset + 2*tracer_dims.water_tracers();
smry.update_well_var(well, fmt::format("WTPT{}", tracer_name), xwel[wtpt_offset + tracer_index]);
smry.update_well_var(well, fmt::format("WTIT{}", tracer_name), xwel[wtit_offset + tracer_index]);
}
}
void assign_group_cumulatives(const std::string& group,
@ -1558,6 +1571,7 @@ namespace {
void restore_cumulative(::Opm::SummaryState& smry,
const ::Opm::Schedule& schedule,
const Opm::TracerConfig& tracer_config,
std::shared_ptr<Opm::EclIO::RestartFileView> rst_view)
{
const auto sim_step = rst_view->simStep();
@ -1573,7 +1587,7 @@ namespace {
for (auto nWells = wells.size(), wellID = 0*nWells;
wellID < nWells; ++wellID)
{
assign_well_cumulatives(wells[wellID], wellID, wellData, smry);
assign_well_cumulatives(wells[wellID], wellID, schedule.runspec().tracers(), tracer_config, wellData, smry);
}
}
@ -1645,7 +1659,7 @@ namespace Opm { namespace RestartIO {
}
restore_udq(summary_state, schedule, rst_view);
restore_cumulative(summary_state, schedule, std::move(rst_view));
restore_cumulative(summary_state, schedule, es.tracer(), std::move(rst_view));
return rst_value;
}

View File

@ -56,6 +56,7 @@
#include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
#include <opm/parser/eclipse/EclipseState/TracerConfig.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp>
@ -155,7 +156,8 @@ namespace Opm {
ErrorGuard& errors,
std::shared_ptr<const Python> python,
const std::optional<int>& output_interval,
const RestartIO::RstState * rst)
const RestartIO::RstState * rst,
const TracerConfig * tracer_config)
try :
m_static( python, ScheduleRestartInfo(rst, deck), deck, runspec, output_interval, parseContext, errors ),
m_sched_deck(TimeService::from_time_t(runspec.start_time()), deck, m_static.rst_info ),
@ -168,9 +170,12 @@ namespace Opm {
ScheduleGrid grid(ecl_grid, fp, this->completed_cells);
if (rst) {
if (!tracer_config)
throw std::logic_error("Bug: when loading from restart a valid TracerConfig object must be supplied");
auto restart_step = this->m_static.rst_info.report_step;
this->iterateScheduleSection( 0, restart_step, parseContext, errors, grid, nullptr, "");
this->load_rst(*rst, grid, fp);
this->load_rst(*rst, *tracer_config, grid, fp);
if (! this->restart_output.writeRestartFile(restart_step))
this->restart_output.addRestartOutput(restart_step);
this->iterateScheduleSection( restart_step, this->m_sched_deck.size(), parseContext, errors, grid, nullptr, "");
@ -202,8 +207,9 @@ namespace Opm {
T&& errors,
std::shared_ptr<const Python> python,
const std::optional<int>& output_interval,
const RestartIO::RstState * rst) :
Schedule(deck, grid, fp, runspec, parseContext, errors, python, output_interval, rst)
const RestartIO::RstState * rst,
const TracerConfig* tracer_config) :
Schedule(deck, grid, fp, runspec, parseContext, errors, python, output_interval, rst, tracer_config)
{}
@ -213,8 +219,9 @@ namespace Opm {
const Runspec &runspec,
std::shared_ptr<const Python> python,
const std::optional<int>& output_interval,
const RestartIO::RstState * rst) :
Schedule(deck, grid, fp, runspec, ParseContext(), ErrorGuard(), python, output_interval, rst)
const RestartIO::RstState * rst,
const TracerConfig* tracer_config) :
Schedule(deck, grid, fp, runspec, ParseContext(), ErrorGuard(), python, output_interval, rst, tracer_config)
{}
@ -227,7 +234,8 @@ namespace Opm {
errors,
python,
output_interval,
rst)
rst,
&es.tracer())
{}
@ -241,7 +249,8 @@ namespace Opm {
errors,
python,
output_interval,
rst)
rst,
&es.tracer())
{}
@ -1469,7 +1478,7 @@ namespace {
}
}
void Schedule::load_rst(const RestartIO::RstState& rst_state, const ScheduleGrid& grid, const FieldPropsManager& fp)
void Schedule::load_rst(const RestartIO::RstState& rst_state, const TracerConfig& tracer_config, const ScheduleGrid& grid, const FieldPropsManager& fp)
{
const auto report_step = rst_state.header.report_step - 1;
double udq_undefined = 0;
@ -1514,7 +1523,7 @@ namespace {
}
for (const auto& rst_well : rst_state.wells) {
Opm::Well well(rst_well, report_step, this->m_static.m_unit_system, udq_undefined);
Opm::Well well(rst_well, report_step, tracer_config, this->m_static.m_unit_system, udq_undefined);
std::vector<Opm::Connection> rst_connections;
for (const auto& rst_conn : rst_well.connections)

View File

@ -31,6 +31,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleGrid.hpp>
#include <opm/parser/eclipse/EclipseState/TracerConfig.hpp>
#include "../MSW/Compsegs.hpp"
@ -168,6 +169,7 @@ constexpr double def_solvent_fraction = 0;
Well::Well(const RestartIO::RstWell& rst_well,
int report_step,
const TracerConfig& tracer_config,
const UnitSystem& unit_system_arg,
double udq_undefined_arg) :
wname(rst_well.name),
@ -313,6 +315,16 @@ Well::Well(const RestartIO::RstWell& rst_well,
i->addInjectionControl(Well::InjectorCMode::GRUP);
this->updateInjection(std::move(i));
if (!rst_well.tracer_concentration_injection.empty()) {
auto tracer = std::make_shared<WellTracerProperties>(this->getTracerProperties());
for (std::size_t tracer_index = 0; tracer_index < tracer_config.size(); tracer_index++) {
const auto& name = tracer_config[tracer_index].name;
const auto concentration = rst_well.tracer_concentration_injection[tracer_index];
tracer->setConcentration(name, concentration);
}
this->updateTracer(tracer);
}
}
}

View File

@ -1293,7 +1293,7 @@ BOOST_AUTO_TEST_CASE(WELL_POD) {
const auto& scon = connectionData.getSConn();
const auto& xcon = connectionData.getXConn();
Opm::RestartIO::RstHeader header(units, ih, std::vector<bool>(100), std::vector<double>(1000));
Opm::RestartIO::RstHeader header(simCase.es.runspec(), units, ih, std::vector<bool>(100), std::vector<double>(1000));
std::vector<Opm::RestartIO::RstWell> wells;
std::vector<std::string> zwel;
for (const auto& s8: zwel8)

View File

@ -666,7 +666,8 @@ BOOST_AUTO_TEST_CASE(TestHeader) {
.regionDimensions({ntfip, nmfipr, 0,0,0})
.ngroups({ngroup});
Opm::RestartIO::RstHeader header(unit_system, ih.data(), std::vector<bool>(100), std::vector<double>(1000));
Opm::Runspec runspec;
Opm::RestartIO::RstHeader header(runspec, unit_system, ih.data(), std::vector<bool>(100), std::vector<double>(1000));
BOOST_CHECK_EQUAL(header.nx, nx);
BOOST_CHECK_EQUAL(header.ny, ny);
BOOST_CHECK_EQUAL(header.nactive, nactive);

View File

@ -254,7 +254,7 @@ BOOST_AUTO_TEST_CASE(group_test) {
for (const auto& s8: zgrp8)
zgrp.push_back(s8.c_str());
Opm::RestartIO::RstHeader header(unit_system,ih,lh,dh);
Opm::RestartIO::RstHeader header(simCase.es.runspec(), unit_system,ih,lh,dh);
for (int ig=0; ig < header.ngroup; ig++) {
std::size_t zgrp_offset = ig * header.nzgrpz;
std::size_t igrp_offset = ig * header.nigrpz;