Merge pull request #548 from bska/flow-flow-restart
Add Support for Restarting Flow from ECLIPSE Compatible Restart File
This commit is contained in:
@@ -528,7 +528,9 @@ if(ENABLE_ECL_OUTPUT)
|
||||
opm/output/data/Solution.hpp
|
||||
opm/output/data/Wells.hpp
|
||||
opm/output/eclipse/VectorItems/connection.hpp
|
||||
opm/output/eclipse/VectorItems/group.hpp
|
||||
opm/output/eclipse/VectorItems/intehead.hpp
|
||||
opm/output/eclipse/VectorItems/msw.hpp
|
||||
opm/output/eclipse/VectorItems/well.hpp
|
||||
opm/output/eclipse/AggregateGroupData.hpp
|
||||
opm/output/eclipse/AggregateConnectionData.hpp
|
||||
|
||||
@@ -89,12 +89,16 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
const std::vector<std::string> restart_group_keys = {"GOPP", "GWPP", "GOPR", "GWPR", "GGPR",
|
||||
"GVPR", "GWIR", "GGIR", "GWCT", "GGOR",
|
||||
"GOPT", "GWPT", "GGPT", "GVPT", "GWIT",
|
||||
"GGIT"};
|
||||
"GGIT",
|
||||
"GOPTH", "GWPTH", "GGPTH",
|
||||
"GWITH", "GGITH"};
|
||||
|
||||
const std::vector<std::string> restart_field_keys = {"FOPP", "FWPP", "FOPR", "FWPR", "FGPR",
|
||||
"FVPR", "FWIR", "FGIR", "FWCT", "FGOR",
|
||||
"FOPT", "FWPT", "FGPT", "FVPT", "FWIT",
|
||||
"FGIT"};
|
||||
"FGIT",
|
||||
"FOPTH", "FWPTH", "FGPTH",
|
||||
"FWITH", "FGITH"};
|
||||
|
||||
const std::map<std::string, size_t> groupKeyToIndex = {
|
||||
{"GOPR", 0},
|
||||
@@ -113,6 +117,11 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
{"GGIT", 16},
|
||||
{"GOPP", 22},
|
||||
{"GWPP", 23},
|
||||
{"GOPTH", 135},
|
||||
{"GWPTH", 139},
|
||||
{"GWITH", 140},
|
||||
{"GGPTH", 143},
|
||||
{"GGITH", 144},
|
||||
};
|
||||
|
||||
const std::map<std::string, size_t> fieldKeyToIndex = {
|
||||
@@ -132,6 +141,11 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
{"FGIT", 16},
|
||||
{"FOPP", 22},
|
||||
{"FWPP", 23},
|
||||
{"FOPTH", 135},
|
||||
{"FWPTH", 139},
|
||||
{"FWITH", 140},
|
||||
{"FGPTH", 143},
|
||||
{"FGITH", 144},
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace Opm { namespace RestartIO {
|
||||
const double cnvT);
|
||||
|
||||
DoubHEAD& timeStamp(const TimeStamp& ts);
|
||||
DoubHEAD& nextStep(const double nextTimeStep);
|
||||
|
||||
DoubHEAD& drsdt(const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
Copyright (c) 2016 Statoil ASA
|
||||
Copyright (c) 2013-2015 Andreas Lauser
|
||||
Copyright (c) 2013 SINTEF ICT, Applied Mathematics.
|
||||
@@ -23,9 +24,6 @@
|
||||
#ifndef RESTART_IO_HPP
|
||||
#define RESTART_IO_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||
@@ -35,24 +33,29 @@
|
||||
#include <opm/output/data/Wells.hpp>
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
#include <ert/ecl/EclKW.hpp>
|
||||
#include <ert/ecl/ecl_rsthead.h>
|
||||
#include <ert/ecl/ecl_rst_file.h>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Phases;
|
||||
class Schedule;
|
||||
class SummaryState;
|
||||
class EclipseGrid;
|
||||
class EclipseState;
|
||||
class Phases;
|
||||
class Schedule;
|
||||
|
||||
namespace RestartIO {
|
||||
} // namespace Opm
|
||||
|
||||
|
||||
/*
|
||||
The two loose functions RestartIO::save() and RestartIO::load() can
|
||||
The two free functions RestartIO::save() and RestartIO::load() can
|
||||
be used to save and load reservoir and well state from restart
|
||||
files. Observe that these functions 'just do it', i.e. the checking
|
||||
of which report step to load from, if output is enabled at all and
|
||||
@@ -69,39 +72,30 @@ namespace RestartIO {
|
||||
load("CASE.X0010" , 99 , ...)
|
||||
save("CASE.X0010" , 99 , ...)
|
||||
|
||||
will read and write to the file "CASE.X0010" - completely ignoring
|
||||
will read from and write to the file "CASE.X0010" - completely ignoring
|
||||
the report step argument '99'.
|
||||
*/
|
||||
namespace Opm { namespace RestartIO {
|
||||
|
||||
/*void save(const std::string& filename,
|
||||
int report_step,
|
||||
double seconds_elapsed,
|
||||
data::Solution cells,
|
||||
data::Wells wells,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
std::map<std::string, std::vector<double>> extra_data = {},
|
||||
bool write_double = false);
|
||||
*/
|
||||
void save(const std::string& filename,
|
||||
int report_step,
|
||||
double seconds_elapsed,
|
||||
RestartValue value,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const SummaryState& sumState,
|
||||
bool write_double = false);
|
||||
void save(const std::string& filename,
|
||||
int report_step,
|
||||
double seconds_elapsed,
|
||||
RestartValue value,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const SummaryState& sumState,
|
||||
bool write_double = false);
|
||||
|
||||
RestartValue load( const std::string& filename,
|
||||
int report_step,
|
||||
const std::vector<RestartKey>& solution_keys,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const std::vector<RestartKey>& extra_keys = {});
|
||||
std::pair<RestartValue, SummaryState>
|
||||
load(const std::string& filename,
|
||||
int report_step,
|
||||
const std::vector<RestartKey>& solution_keys,
|
||||
const EclipseState& es,
|
||||
const EclipseGrid& grid,
|
||||
const Schedule& schedule,
|
||||
const std::vector<RestartKey>& extra_keys = {});
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}} // namespace Opm::RestartIO
|
||||
|
||||
#endif // RESTART_IO_HPP
|
||||
|
||||
@@ -63,6 +63,8 @@ class Summary {
|
||||
|
||||
const SummaryState& get_restart_vectors() const;
|
||||
|
||||
void reset_cumulative_quantities(const SummaryState& rstrt);
|
||||
|
||||
private:
|
||||
class keyword_handlers;
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
WaterRate = 1, // Surface flow rate (water)
|
||||
GasRate = 2, // Surface Flow rate (gas)
|
||||
|
||||
Pressure = 34, // Connection pressure value
|
||||
|
||||
ResVRate = 49, // Reservoir voidage rate
|
||||
};
|
||||
} // XConn
|
||||
|
||||
37
opm/output/eclipse/VectorItems/doubhead.hpp
Normal file
37
opm/output/eclipse/VectorItems/doubhead.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (c) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_DOUBHEAD_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_DOUBHEAD_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
// This is a subset of the items in src/opm/output/eclipse/DoubHEAD.cpp .
|
||||
// Promote items from that list to this in order to make them public.
|
||||
enum doubhead : std::vector<double>::size_type {
|
||||
TsInit = 1, // Maximum Length of Next Timestep
|
||||
TsMaxz = 2, // Maximum Length of Timestep After Next
|
||||
TsMinz = 3, // Minumum Length of All Timesteps
|
||||
};
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_DOUBHEAD_HPP
|
||||
67
opm/output/eclipse/VectorItems/group.hpp
Normal file
67
opm/output/eclipse/VectorItems/group.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright (c) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_GROUP_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_GROUP_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
namespace XGroup {
|
||||
enum index : std::vector<double>::size_type {
|
||||
OilPrRate = 0, // Group's oil production rate
|
||||
WatPrRate = 1, // Group's water production rate
|
||||
GasPrRate = 2, // Group's gas production rate
|
||||
LiqPrRate = 3, // Group's liquid production rate
|
||||
|
||||
WatInjRate = 5, // Group's water injection rate
|
||||
GasInjRate = 6, // Group's gas injection rate
|
||||
|
||||
WatCut = 8, // Group's producing water cut
|
||||
GORatio = 9, // Group's producing gas/oil ratio
|
||||
|
||||
OilPrTotal = 10, // Group's total cumulative oil production
|
||||
WatPrTotal = 11, // Group's total cumulative water production
|
||||
GasPrTotal = 12, // Group's total cumulative gas production
|
||||
VoidPrTotal = 13, // Group's total cumulative reservoir
|
||||
// voidage production
|
||||
|
||||
WatInjTotal = 15, // Group's total cumulative water injection
|
||||
GasInjTotal = 16, // Group's total cumulative gas injection
|
||||
|
||||
OilPrPot = 22, // Group's oil production potential
|
||||
WatPrPot = 23, // Group's water production potential
|
||||
|
||||
HistOilPrTotal = 135, // Group's total cumulative oil
|
||||
// production (observed/historical rates)
|
||||
HistWatPrTotal = 139, // Group's total cumulative water
|
||||
// production (observed/historical rates)
|
||||
HistWatInjTotal = 140, // Group's total cumulative water
|
||||
// injection (observed/historical rates)
|
||||
HistGasPrTotal = 143, // Group's total cumulative gas
|
||||
// production (observed/historical rates)
|
||||
HistGasInjTotal = 144, // Group's total cumulative gas injection
|
||||
// (observed/historical rates)
|
||||
};
|
||||
} // XGroup
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_GROUP_HPP
|
||||
64
opm/output/eclipse/VectorItems/msw.hpp
Normal file
64
opm/output/eclipse/VectorItems/msw.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_MSW_HPP
|
||||
#define OPM_OUTPUT_ECLIPSE_VECTOR_MSW_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
|
||||
|
||||
namespace ISeg {
|
||||
enum index : std::vector<int>::size_type {
|
||||
SegNo = 0, // Segment number (one-based)
|
||||
OutSeg = 1, // Outlet segment (one-based)
|
||||
InSegCurBranch = 2, // Inflow segment current branch (one-based)
|
||||
BranchNo = 3, // Branch number (one-based)
|
||||
};
|
||||
} // ISeg
|
||||
|
||||
namespace RSeg {
|
||||
enum index : std::vector<double>::size_type {
|
||||
DistOutlet = 0, // Segment's distance to outlet
|
||||
OutletDepthDiff = 1, // Segment's depth differential to outlet
|
||||
SegDiam = 2, // Internal diameter of segment
|
||||
SegRough = 3, // Roughness parameter of segment
|
||||
SegArea = 4, // Cross-sectional area of segment
|
||||
SegVolume = 5, // Physical volume of segment
|
||||
DistBHPRef = 6, // Segment's distance to BHP reference node
|
||||
DepthBHPRef = 7, // Segment's depth differential to BHP ref. node
|
||||
|
||||
TotFlowRate = 8, // Normalised total segment flow rate
|
||||
WatFlowFract = 9, // Normalised Water flow rate fraction
|
||||
GasFlowFract = 10, // Normalised Gas flow rate fraction
|
||||
Pressure = 11, // Segment pressure
|
||||
|
||||
item40 = 39, // Unknown
|
||||
item106 = 105, // Unknown
|
||||
item107 = 106, // Unknown
|
||||
item108 = 107, // Unknown
|
||||
item109 = 108, // Unknown
|
||||
item110 = 109, // Unknown
|
||||
item111 = 110, // Unknown
|
||||
};
|
||||
} // RSeg
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_MSW_HPP
|
||||
@@ -26,26 +26,30 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
|
||||
namespace IWell {
|
||||
enum index : std::vector<int>::size_type {
|
||||
IHead = 0, // I-location (one-based) of well head
|
||||
JHead = 1, // J-location (one-based) of well head
|
||||
FirstK = 2, // Layer ID (one-based) of top/first connection
|
||||
LastK = 3, // Layer ID (one-based) of bottom/last connection
|
||||
NConn = 4, // Number of active cells connected to well
|
||||
Group = 5, // Index (one-based) of well's current group
|
||||
WType = 6, // Well type
|
||||
WCtrl = 7, // Well control
|
||||
IHead = 0, // I-location (one-based) of well head
|
||||
JHead = 1, // J-location (one-based) of well head
|
||||
FirstK = 2, // Layer ID (one-based) of top/first connection
|
||||
LastK = 3, // Layer ID (one-based) of bottom/last connection
|
||||
NConn = 4, // Number of active cells connected to well
|
||||
Group = 5, // Index (one-based) of well's current group
|
||||
WType = 6, // Well type (producer vs. injector)
|
||||
ActWCtrl = 7, // Well's active target control mode (constraint).
|
||||
|
||||
item9 = 8, // Unknown
|
||||
item11 = 10, // Unknown
|
||||
item9 = 8, // Unknown
|
||||
item11 = 10, // Unknown
|
||||
VFPTab = 11, // ID (one-based) of well's current VFP table.
|
||||
|
||||
VFPTab = 11, // ID (one-based) of well's current VFP table
|
||||
PredReqWCtrl = 15, // Well's requested control mode from
|
||||
// simulation deck (WCONINJE, WCONPROD).
|
||||
|
||||
item18 = 17, // Unknown
|
||||
XFlow = 22,
|
||||
item25 = 24, // Unknown
|
||||
item32 = 31, // Unknown
|
||||
item48 = 47, // Unknown
|
||||
item50 = 49, // Unknown
|
||||
|
||||
HistReqWCtrl = 49, // Well's requested control mode from
|
||||
// simulation deck (WCONHIST, WCONINJH)
|
||||
|
||||
MsWID = 70, // Multisegment well ID
|
||||
// Value 0 for regular wells
|
||||
@@ -116,10 +120,15 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
BHPTarget = 6, // Well's bottom hole pressure target
|
||||
|
||||
DatumDepth = 9, // Well's reference depth for BHP
|
||||
LiqRateTarget_2 = 33, //Well's liquid rate target/limit for a well on WCONINJH control or for a producer
|
||||
GasRateTarget_2 = 54, //Well's gas rate target/limit for a well on WCONINJH control or for producer
|
||||
BHPTarget_2 = 55, //Well's bottom hole pressure target/limit
|
||||
|
||||
|
||||
HistLiqRateTarget = 33, // Well's historical/observed liquid
|
||||
// rate target/limit
|
||||
|
||||
HistGasRateTarget = 54, // Well's historical/observed gas rate
|
||||
// target/limit
|
||||
|
||||
HistBHPTarget = 55, // Well's historical/observed bottom
|
||||
// hole pressure target/limit
|
||||
};
|
||||
} // SWell
|
||||
|
||||
@@ -146,13 +155,22 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
|
||||
GasFVF = 34, // Well's producing gas formation volume factor.
|
||||
|
||||
item37 = 36, // Unknown
|
||||
item38 = 37, // Unknown
|
||||
item37 = 36, // Unknown
|
||||
item38 = 37, // Unknown
|
||||
|
||||
BHPTarget = 41, // Well's current BHP Target/Limit
|
||||
BHPTarget = 41, // Well's current BHP Target/Limit
|
||||
|
||||
item82 = 81, // Unknown
|
||||
item83 = 82, // Unknown
|
||||
HistOilPrTotal = 75, // Well's total cumulative oil production
|
||||
// (observed/historical rates)
|
||||
HistWatPrTotal = 76, // Well's total cumulative water
|
||||
// production (observed/historical rates)
|
||||
HistGasPrTotal = 77, // Well's total cumulative gas production
|
||||
// (observed(historical rates)
|
||||
|
||||
HistWatInjTotal = 81, // Well's total cumulative water injection
|
||||
// (observed/historical rates)
|
||||
HistGasInjTotal = 82, // Well's total cumulative gas injection
|
||||
// (observed/historical rates)
|
||||
|
||||
WatVoidPrRate = 122, // Well's voidage production rate
|
||||
GasVoidPrRate = 123, // Well's voidage production rate
|
||||
|
||||
@@ -47,7 +47,8 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
createDoubHead(const EclipseState& es,
|
||||
const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const double simTime);
|
||||
const double simTime,
|
||||
const double nextTimeStep);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -246,6 +246,8 @@ namespace {
|
||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XConn::index;
|
||||
using R = ::Opm::data::Rates::opt;
|
||||
|
||||
xConn[Ix::Pressure] = units.from_si(M::pressure, x.pressure);
|
||||
|
||||
// Note flow rate sign. Treat production rates as positive.
|
||||
const auto& Q = x.rates;
|
||||
|
||||
|
||||
@@ -381,7 +381,8 @@ namespace {
|
||||
|
||||
for (const auto& key : keys) {
|
||||
if ((key[3] == 'T') && ((key[2] == 'I') || (key[2] == 'P'))) {
|
||||
// Don't write cumulative quantities in case of
|
||||
// Don't write cumulative quantities in case of OPM
|
||||
// extended restart files.
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -424,7 +425,7 @@ namespace {
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
} // XGrp
|
||||
|
||||
namespace ZGrp {
|
||||
std::size_t entriesPerGroup(const std::vector<int>& inteHead)
|
||||
@@ -447,7 +448,13 @@ namespace {
|
||||
WV::WindowSize{ entriesPerGroup(inteHead) }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
template <class ZGroupArray>
|
||||
void staticContrib(const Opm::Group& group, ZGroupArray& zGroup)
|
||||
{
|
||||
zGroup[0] = group.name();
|
||||
}
|
||||
} // ZGrp
|
||||
} // Anonymous
|
||||
|
||||
void
|
||||
@@ -520,19 +527,20 @@ captureDeclaredGroupData(const Opm::Schedule& sched,
|
||||
|
||||
auto it = indexGroupMap.begin();
|
||||
while (it != indexGroupMap.end())
|
||||
{
|
||||
curGroups[static_cast<int>(it->first)] = it->second;
|
||||
it++;
|
||||
}
|
||||
{
|
||||
groupLoop(curGroups, [sched, simStep, inteHead, this]
|
||||
(const Group& group, const std::size_t groupID) -> void
|
||||
{
|
||||
auto ig = this->iGroup_[groupID];
|
||||
IGrp::staticContrib(sched, group, this->nWGMax_, this->nGMaxz_, simStep, ig, inteHead);
|
||||
});
|
||||
curGroups[static_cast<int>(it->first)] = it->second;
|
||||
it++;
|
||||
}
|
||||
|
||||
groupLoop(curGroups, [&sched, simStep, &inteHead, this]
|
||||
(const Group& group, const std::size_t groupID) -> void
|
||||
{
|
||||
auto ig = this->iGroup_[groupID];
|
||||
|
||||
IGrp::staticContrib(sched, group, this->nWGMax_, this->nGMaxz_,
|
||||
simStep, ig, inteHead);
|
||||
});
|
||||
|
||||
// Define Static Contributions to SGrp Array.
|
||||
groupLoop(curGroups,
|
||||
[this](const Group& group, const std::size_t groupID) -> void
|
||||
@@ -541,23 +549,25 @@ captureDeclaredGroupData(const Opm::Schedule& sched,
|
||||
SGrp::staticContrib(sw);
|
||||
});
|
||||
|
||||
// Define DynamicContributions to XGrp Array.
|
||||
groupLoop(curGroups,
|
||||
[restart_group_keys, restart_field_keys, groupKeyToIndex, fieldKeyToIndex, ecl_compatible_rst, sumState, this]
|
||||
// Define Dynamic Contributions to XGrp Array.
|
||||
groupLoop(curGroups, [&restart_group_keys, &restart_field_keys,
|
||||
&groupKeyToIndex, &fieldKeyToIndex,
|
||||
ecl_compatible_rst, &sumState, this]
|
||||
(const Group& group, const std::size_t groupID) -> void
|
||||
{
|
||||
auto xg = this->xGroup_[groupID];
|
||||
XGrp::dynamicContrib( restart_group_keys, restart_field_keys, groupKeyToIndex, fieldKeyToIndex, group, sumState, ecl_compatible_rst, xg);
|
||||
|
||||
XGrp::dynamicContrib(restart_group_keys, restart_field_keys,
|
||||
groupKeyToIndex, fieldKeyToIndex, group,
|
||||
sumState, ecl_compatible_rst, xg);
|
||||
});
|
||||
|
||||
|
||||
// Define Static Contributions to ZGrp Array.
|
||||
groupLoop(curGroups,
|
||||
[this](const Group& group, const std::size_t groupID) -> void
|
||||
groupLoop(curGroups, [this, &nameIndexMap]
|
||||
(const Group& group, const std::size_t /* groupID */) -> void
|
||||
{
|
||||
auto zw = this->zGroup_[groupID];
|
||||
zw[0] = group.name();
|
||||
auto zg = this->zGroup_[ nameIndexMap.at(group.name()) ];
|
||||
|
||||
ZGrp::staticContrib(group, zg);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||
//#include <opm/output/data/Wells.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
@@ -118,47 +117,22 @@ namespace {
|
||||
groupIndexMap.insert(groupPair);
|
||||
}
|
||||
return groupIndexMap;
|
||||
}
|
||||
|
||||
int groupIndex(const std::string& grpName,
|
||||
const std::map <const std::string, size_t>& currentGroupMapNameIndex)
|
||||
{
|
||||
}
|
||||
|
||||
int groupIndex(const std::string& grpName,
|
||||
const std::map <const std::string, size_t>& currentGroupMapNameIndex)
|
||||
{
|
||||
int ind = 0;
|
||||
auto searchGTName = currentGroupMapNameIndex.find(grpName);
|
||||
if (searchGTName != currentGroupMapNameIndex.end())
|
||||
{
|
||||
ind = searchGTName->second + 1;
|
||||
auto searchGTName = currentGroupMapNameIndex.find(grpName);
|
||||
if (searchGTName != currentGroupMapNameIndex.end()) {
|
||||
ind = searchGTName->second + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
std::cout << "group Name: " << grpName << std::endl;
|
||||
throw std::invalid_argument( "Invalid group name" );
|
||||
}
|
||||
return ind;
|
||||
}
|
||||
/*int groupIndex(const std::string& grpName,
|
||||
const std::vector<std::string>& groupNames,
|
||||
const int maxGroups)
|
||||
{
|
||||
if (grpName == "FIELD") {
|
||||
// Not really supposed to happen since wells are
|
||||
// not supposed to be parented dirctly to FIELD.
|
||||
return maxGroups + 1;
|
||||
}
|
||||
|
||||
auto b = std::begin(groupNames);
|
||||
auto e = std::end (groupNames);
|
||||
auto i = std::find(b, e, grpName);
|
||||
|
||||
if (i == e) {
|
||||
// Not really supposed to happen since wells are
|
||||
// not supposed to be parented dirctly to FIELD.
|
||||
return maxGroups + 1;
|
||||
}
|
||||
|
||||
// One-based indexing.
|
||||
return std::distance(b, i) + 1;
|
||||
} */
|
||||
return ind;
|
||||
}
|
||||
|
||||
int wellType(const Opm::Well& well,
|
||||
const std::size_t sim_step)
|
||||
@@ -199,16 +173,6 @@ namespace {
|
||||
using WMCtrlVal = ::Opm::RestartIO::Helpers::
|
||||
VectorItems::IWell::Value::WellCtrlMode;
|
||||
|
||||
/*{
|
||||
const auto stat = well.getStatus(sim_step);
|
||||
|
||||
using WStat = ::Opm::WellCommon::StatusEnum;
|
||||
|
||||
if (stat == WStat::SHUT) {
|
||||
return WMCtrlVal::Shut;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (well.isInjector(sim_step)) {
|
||||
const auto& prop = well
|
||||
.getInjectionProperties(sim_step);
|
||||
@@ -236,16 +200,16 @@ namespace {
|
||||
case CMode::GRUP: return WMCtrlVal::Group;
|
||||
|
||||
default:
|
||||
{
|
||||
const auto stat = well.getStatus(sim_step);
|
||||
{
|
||||
const auto stat = well.getStatus(sim_step);
|
||||
|
||||
using WStat = ::Opm::WellCommon::StatusEnum;
|
||||
using WStat = ::Opm::WellCommon::StatusEnum;
|
||||
|
||||
if (stat == WStat::SHUT) {
|
||||
return WMCtrlVal::Shut;
|
||||
}
|
||||
}
|
||||
return WMCtrlVal::WMCtlUnk;
|
||||
if (stat == WStat::SHUT) {
|
||||
return WMCtrlVal::Shut;
|
||||
}
|
||||
}
|
||||
return WMCtrlVal::WMCtlUnk;
|
||||
}
|
||||
}
|
||||
else if (well.isProducer(sim_step)) {
|
||||
@@ -263,19 +227,19 @@ namespace {
|
||||
case CMode::THP: return WMCtrlVal::THP;
|
||||
case CMode::BHP: return WMCtrlVal::BHP;
|
||||
case CMode::CRAT: return WMCtrlVal::CombRate;
|
||||
case CMode::GRUP: return WMCtrlVal::Group;
|
||||
|
||||
default:
|
||||
{
|
||||
const auto stat = well.getStatus(sim_step);
|
||||
case CMode::GRUP: return WMCtrlVal::Group;
|
||||
|
||||
using WStat = ::Opm::WellCommon::StatusEnum;
|
||||
default:
|
||||
{
|
||||
const auto stat = well.getStatus(sim_step);
|
||||
|
||||
if (stat == WStat::SHUT) {
|
||||
return WMCtrlVal::Shut;
|
||||
}
|
||||
}
|
||||
return WMCtrlVal::WMCtlUnk;
|
||||
using WStat = ::Opm::WellCommon::StatusEnum;
|
||||
|
||||
if (stat == WStat::SHUT) {
|
||||
return WMCtrlVal::Shut;
|
||||
}
|
||||
}
|
||||
return WMCtrlVal::WMCtlUnk;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,31 +280,29 @@ namespace {
|
||||
const auto& conn = well.getConnections(sim_step);
|
||||
|
||||
iWell[Ix::NConn] = static_cast<int>(conn.size());
|
||||
|
||||
if (well.isMultiSegment(sim_step))
|
||||
{
|
||||
// Set top and bottom connections to zero for multi segment wells
|
||||
iWell[Ix::FirstK] = 0;
|
||||
iWell[Ix::LastK] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iWell[Ix::FirstK] = (iWell[Ix::NConn] == 0)
|
||||
? 0 : conn.get(0).getK() + 1;
|
||||
|
||||
iWell[Ix::LastK] = (iWell[Ix::NConn] == 0)
|
||||
? 0 : conn.get(conn.size() - 1).getK() + 1;
|
||||
}
|
||||
if (well.isMultiSegment(sim_step)) {
|
||||
// Set top and bottom connections to zero for multi
|
||||
// segment wells
|
||||
iWell[Ix::FirstK] = 0;
|
||||
iWell[Ix::LastK] = 0;
|
||||
}
|
||||
else {
|
||||
iWell[Ix::FirstK] = (iWell[Ix::NConn] == 0)
|
||||
? 0 : conn.get(0).getK() + 1;
|
||||
|
||||
iWell[Ix::LastK] = (iWell[Ix::NConn] == 0)
|
||||
? 0 : conn.get(conn.size() - 1).getK() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
iWell[Ix::Group] =
|
||||
groupIndex(trim(well.getGroupName(sim_step)),
|
||||
GroupMapNameInd);
|
||||
groupIndex(trim(well.getGroupName(sim_step)),
|
||||
GroupMapNameInd);
|
||||
|
||||
iWell[Ix::WType] = wellType (well, sim_step);
|
||||
iWell[Ix::WCtrl] = ctrlMode (well, sim_step);
|
||||
iWell[Ix::VFPTab] = wellVFPTab(well, sim_step);
|
||||
iWell[Ix::XFlow] = well.getAllowCrossFlow() ? 1 : 0;
|
||||
iWell[Ix::XFlow] = well.getAllowCrossFlow() ? 1 : 0;
|
||||
|
||||
// The following items aren't fully characterised yet, but
|
||||
// needed for restart of M2. Will need further refinement.
|
||||
@@ -349,7 +311,31 @@ namespace {
|
||||
iWell[Ix::item32] = 7;
|
||||
iWell[Ix::item48] = - 1;
|
||||
|
||||
iWell[Ix::item50] = iWell[Ix::WCtrl];
|
||||
// Deliberate misrepresentation. Function 'ctrlMode()' returns
|
||||
// the target control mode requested in the simulation deck.
|
||||
// This item is supposed to be the well's actual, active target
|
||||
// control mode in the simulator.
|
||||
iWell[Ix::ActWCtrl] = ctrlMode(well, sim_step);
|
||||
|
||||
const auto isPred =
|
||||
(well.isProducer(sim_step) &&
|
||||
well.getProductionProperties(sim_step).predictionMode)
|
||||
||
|
||||
(well.isInjector(sim_step) &&
|
||||
well.getInjectionProperties(sim_step).predictionMode);
|
||||
|
||||
if (isPred) {
|
||||
// Well in prediction mode (WCONPROD, WCONINJE). Assign
|
||||
// requested control mode for prediction.
|
||||
iWell[Ix::PredReqWCtrl] = iWell[Ix::ActWCtrl];
|
||||
iWell[Ix::HistReqWCtrl] = 0;
|
||||
}
|
||||
else {
|
||||
// Well controlled by observed rates/BHP (WCONHIST,
|
||||
// WCONINJH). Assign requested control mode for history.
|
||||
iWell[Ix::PredReqWCtrl] = 0; // Possibly =1 instead.
|
||||
iWell[Ix::HistReqWCtrl] = iWell[Ix::ActWCtrl];
|
||||
}
|
||||
|
||||
// Multi-segmented well information
|
||||
iWell[Ix::MsWID] = 0; // MS Well ID (0 or 1..#MS wells)
|
||||
@@ -387,7 +373,7 @@ namespace {
|
||||
});
|
||||
|
||||
iWell[Ix::item9] = any_flowing_conn
|
||||
? iWell[Ix::WCtrl] : -1;
|
||||
? iWell[Ix::ActWCtrl] : -1;
|
||||
|
||||
iWell[Ix::item11] = 1;
|
||||
}
|
||||
@@ -481,7 +467,7 @@ namespace {
|
||||
void staticContrib(const Opm::Well& well,
|
||||
const Opm::UnitSystem& units,
|
||||
const std::size_t sim_step,
|
||||
const ::Opm::SummaryState& smry,
|
||||
const ::Opm::SummaryState& smry,
|
||||
SWellArray& sWell)
|
||||
{
|
||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::SWell::index;
|
||||
@@ -491,17 +477,17 @@ namespace {
|
||||
{
|
||||
return static_cast<float>(units.from_si(u, x));
|
||||
};
|
||||
|
||||
|
||||
assignDefaultSWell(sWell);
|
||||
|
||||
if (well.isProducer(sim_step)) {
|
||||
const auto& pp = well.getProductionProperties(sim_step);
|
||||
const auto& predMode = pp.predictionMode;
|
||||
const auto& predMode = pp.predictionMode;
|
||||
|
||||
if ((pp.OilRate != 0.0) || (!predMode)) {
|
||||
sWell[Ix::OilRateTarget] =
|
||||
swprop(M::liquid_surface_rate, pp.OilRate);
|
||||
}
|
||||
}
|
||||
|
||||
if ((pp.WaterRate != 0.0) || (!predMode)) {
|
||||
sWell[Ix::WatRateTarget] =
|
||||
@@ -511,13 +497,13 @@ namespace {
|
||||
if ((pp.GasRate != 0.0) || (!predMode)) {
|
||||
sWell[Ix::GasRateTarget] =
|
||||
swprop(M::gas_surface_rate, pp.GasRate);
|
||||
sWell[Ix::GasRateTarget_2] = sWell[Ix::GasRateTarget];
|
||||
sWell[Ix::HistGasRateTarget] = sWell[Ix::GasRateTarget];
|
||||
}
|
||||
|
||||
if (pp.LiquidRate != 0.0 || (!predMode)) {
|
||||
sWell[Ix::LiqRateTarget] =
|
||||
swprop(M::liquid_surface_rate, pp.LiquidRate);
|
||||
sWell[Ix::LiqRateTarget_2] = sWell[Ix::LiqRateTarget];
|
||||
sWell[Ix::HistLiqRateTarget] = sWell[Ix::LiqRateTarget];
|
||||
}
|
||||
else {
|
||||
sWell[Ix::LiqRateTarget] =
|
||||
@@ -528,45 +514,51 @@ namespace {
|
||||
sWell[Ix::ResVRateTarget] =
|
||||
swprop(M::rate, pp.ResVRate);
|
||||
}
|
||||
else if ((smry.has("WVPR:" + well.name())) && (!predMode)) {
|
||||
else if ((smry.has("WVPR:" + well.name())) && (!predMode)) {
|
||||
// Write out summary voidage production rate if
|
||||
// target/limit is not set
|
||||
auto vr = static_cast<float>(smry.get("WVPR:" + well.name()));
|
||||
if (vr != 0.0) sWell[Ix::ResVRateTarget] = vr;
|
||||
auto vr = static_cast<float>(smry.get("WVPR:" + well.name()));
|
||||
if (vr != 0.0) {
|
||||
sWell[Ix::ResVRateTarget] = vr;
|
||||
}
|
||||
}
|
||||
|
||||
sWell[Ix::THPTarget] = pp.THPLimit != 0.0
|
||||
sWell[Ix::THPTarget] = pp.THPLimit != 0.0
|
||||
? swprop(M::pressure, pp.THPLimit)
|
||||
: 0.;
|
||||
|
||||
sWell[Ix::BHPTarget] = pp.BHPLimit != 0.0
|
||||
: 0.0;
|
||||
|
||||
sWell[Ix::BHPTarget] = pp.BHPLimit != 0.0
|
||||
? swprop(M::pressure, pp.BHPLimit)
|
||||
: swprop(M::pressure, 1.0*::Opm::unit::atm);
|
||||
sWell[Ix::BHPTarget_2] = sWell[Ix::BHPTarget];
|
||||
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
|
||||
}
|
||||
else if (well.isInjector(sim_step)) {
|
||||
const auto& ip = well.getInjectionProperties(sim_step);
|
||||
|
||||
using IP = ::Opm::WellInjector::ControlModeEnum;
|
||||
using IT = ::Opm::WellInjector::TypeEnum;
|
||||
using IT = ::Opm::WellInjector::TypeEnum;
|
||||
|
||||
if (ip.hasInjectionControl(IP::RATE)) {
|
||||
if (ip.injectorType == IT::OIL) {
|
||||
sWell[Ix::OilRateTarget] = swprop(M::liquid_surface_rate, ip.surfaceInjectionRate);
|
||||
}
|
||||
if (ip.injectorType == IT::WATER) {
|
||||
sWell[Ix::WatRateTarget] = swprop(M::liquid_surface_rate, ip.surfaceInjectionRate);
|
||||
sWell[Ix::LiqRateTarget_2] = sWell[Ix::WatRateTarget];
|
||||
}
|
||||
if (ip.injectorType == IT::GAS) {
|
||||
sWell[Ix::GasRateTarget] = swprop(M::gas_surface_rate, ip.surfaceInjectionRate);
|
||||
sWell[Ix::GasRateTarget_2] = sWell[Ix::GasRateTarget];
|
||||
}
|
||||
if (ip.hasInjectionControl(IP::RATE)) {
|
||||
if (ip.injectorType == IT::OIL) {
|
||||
sWell[Ix::OilRateTarget] =
|
||||
swprop(M::liquid_surface_rate, ip.surfaceInjectionRate);
|
||||
}
|
||||
if (ip.injectorType == IT::WATER) {
|
||||
sWell[Ix::WatRateTarget] =
|
||||
swprop(M::liquid_surface_rate, ip.surfaceInjectionRate);
|
||||
sWell[Ix::HistLiqRateTarget] = sWell[Ix::WatRateTarget];
|
||||
}
|
||||
if (ip.injectorType == IT::GAS) {
|
||||
sWell[Ix::GasRateTarget] =
|
||||
swprop(M::gas_surface_rate, ip.surfaceInjectionRate);
|
||||
sWell[Ix::HistGasRateTarget] = sWell[Ix::GasRateTarget];
|
||||
}
|
||||
}
|
||||
|
||||
if (ip.hasInjectionControl(IP::RESV)) {
|
||||
sWell[Ix::ResVRateTarget] = swprop(M::rate, ip.reservoirInjectionRate);
|
||||
}
|
||||
if (ip.hasInjectionControl(IP::RESV)) {
|
||||
sWell[Ix::ResVRateTarget] =
|
||||
swprop(M::rate, ip.reservoirInjectionRate);
|
||||
}
|
||||
|
||||
if (ip.hasInjectionControl(IP::THP)) {
|
||||
sWell[Ix::THPTarget] = swprop(M::pressure, ip.THPLimit);
|
||||
@@ -575,7 +567,7 @@ namespace {
|
||||
sWell[Ix::BHPTarget] = ip.hasInjectionControl(IP::BHP)
|
||||
? swprop(M::pressure, ip.BHPLimit)
|
||||
: swprop(M::pressure, 1.0E05*::Opm::unit::psia);
|
||||
sWell[Ix::BHPTarget_2] = sWell[Ix::BHPTarget];
|
||||
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
|
||||
}
|
||||
|
||||
sWell[Ix::DatumDepth] =
|
||||
@@ -647,15 +639,41 @@ namespace {
|
||||
xWell[Ix::WatCut] = get("WWCT");
|
||||
xWell[Ix::GORatio] = get("WGOR");
|
||||
|
||||
if (ecl_compatible_rst) {
|
||||
xWell[Ix::OilPrTotal] = get("WOPT");
|
||||
xWell[Ix::WatPrTotal] = get("WWPT");
|
||||
xWell[Ix::GasPrTotal] = get("WGPT");
|
||||
xWell[Ix::VoidPrTotal] = get("WVPT");
|
||||
}
|
||||
if (ecl_compatible_rst) {
|
||||
xWell[Ix::OilPrTotal] = get("WOPT");
|
||||
xWell[Ix::WatPrTotal] = get("WWPT");
|
||||
xWell[Ix::GasPrTotal] = get("WGPT");
|
||||
xWell[Ix::VoidPrTotal] = get("WVPT");
|
||||
}
|
||||
|
||||
// Not fully characterised.
|
||||
xWell[Ix::item37] = xWell[Ix::WatPrRate];
|
||||
xWell[Ix::item38] = xWell[Ix::GasPrRate];
|
||||
|
||||
if (ecl_compatible_rst) {
|
||||
xWell[Ix::HistOilPrTotal] = get("WOPTH");
|
||||
xWell[Ix::HistWatPrTotal] = get("WWPTH");
|
||||
xWell[Ix::HistGasPrTotal] = get("WGPTH");
|
||||
}
|
||||
}
|
||||
|
||||
template <class GetSummaryVector, class XWellArray>
|
||||
void assignCommonInjector(GetSummaryVector& get,
|
||||
const bool ecl_compatible_rst,
|
||||
XWellArray& xWell)
|
||||
{
|
||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
|
||||
|
||||
xWell[Ix::FlowBHP] = get("WBHP");
|
||||
|
||||
if (ecl_compatible_rst) {
|
||||
// Note: Assign both water and gas cumulatives to support
|
||||
// case of well alternating between injecting water and gas.
|
||||
xWell[Ix::WatInjTotal] = get("WWIT");
|
||||
xWell[Ix::GasInjTotal] = get("WGIT");
|
||||
xWell[Ix::HistWatInjTotal] = get("WWITH");
|
||||
xWell[Ix::HistGasInjTotal] = get("WGITH");
|
||||
}
|
||||
}
|
||||
|
||||
template <class XWellArray>
|
||||
@@ -673,19 +691,14 @@ namespace {
|
||||
return smry.has(key) ? smry.get(key) : 0.0;
|
||||
};
|
||||
|
||||
// Injection rates reported as negative, cumulative
|
||||
// totals as positive.
|
||||
assignCommonInjector(get, ecl_compatible_rst, xWell);
|
||||
|
||||
// Injection rates reported as negative.
|
||||
xWell[Ix::WatPrRate] = -get("WWIR");
|
||||
xWell[Ix::LiqPrRate] = xWell[Ix::WatPrRate];
|
||||
|
||||
xWell[Ix::FlowBHP] = get("WBHP");
|
||||
|
||||
if (ecl_compatible_rst) {
|
||||
xWell[Ix::WatInjTotal] = get("WWIT");
|
||||
}
|
||||
|
||||
// Not fully characterised.
|
||||
xWell[Ix::item37] = xWell[Ix::WatPrRate];
|
||||
xWell[Ix::item82] = xWell[Ix::WatInjTotal];
|
||||
|
||||
xWell[Ix::WatVoidPrRate] = -get("WWVIR");
|
||||
}
|
||||
@@ -705,26 +718,22 @@ namespace {
|
||||
return smry.has(key) ? smry.get(key) : 0.0;
|
||||
};
|
||||
|
||||
// Injection rates reported as negative production rates,
|
||||
// cumulative injection totals as positive.
|
||||
assignCommonInjector(get, ecl_compatible_rst, xWell);
|
||||
|
||||
// Injection rates reported as negative production rates.
|
||||
xWell[Ix::GasPrRate] = -get("WGIR");
|
||||
xWell[Ix::VoidPrRate] = -get("WGVIR");
|
||||
|
||||
xWell[Ix::FlowBHP] = get("WBHP");
|
||||
|
||||
if (ecl_compatible_rst) {
|
||||
xWell[Ix::GasInjTotal] = get("WGIT");
|
||||
}
|
||||
|
||||
xWell[Ix::GasFVF] = (std::abs(xWell[Ix::GasPrRate]) > 0.0)
|
||||
? xWell[Ix::VoidPrRate] / xWell[Ix::GasPrRate]
|
||||
: 0.0;
|
||||
|
||||
if (std::isnan(xWell[Ix::GasFVF])) xWell[Ix::GasFVF] = 0.;
|
||||
|
||||
|
||||
if (std::isnan(xWell[Ix::GasFVF])) {
|
||||
xWell[Ix::GasFVF] = 0.0;
|
||||
}
|
||||
|
||||
// Not fully characterised.
|
||||
xWell[Ix::item38] = xWell[Ix::GasPrRate];
|
||||
xWell[Ix::item83] = xWell[Ix::GasInjTotal];
|
||||
|
||||
xWell[Ix::GasVoidPrRate] = xWell[Ix::VoidPrRate];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
Copyright (c) 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
@@ -24,6 +25,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -76,15 +78,23 @@ Opm::RestartIO::Helpers::
|
||||
createDoubHead(const EclipseState& es,
|
||||
const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const double simTime)
|
||||
const double simTime,
|
||||
const double nextTimeStep)
|
||||
{
|
||||
const auto& usys = es.getDeckUnitSystem();
|
||||
const auto dh = DoubHEAD{}
|
||||
.tuningParameters(sched.getTuning(), lookup_step,
|
||||
getTimeConv(usys))
|
||||
const auto& usys = es.getDeckUnitSystem();
|
||||
const auto tconv = getTimeConv(usys);
|
||||
|
||||
auto dh = DoubHEAD{}
|
||||
.tuningParameters(sched.getTuning(), lookup_step, tconv)
|
||||
.timeStamp (computeTimeStamp(sched, simTime))
|
||||
.drsdt (sched, lookup_step, getTimeConv(usys))
|
||||
.drsdt (sched, lookup_step, tconv)
|
||||
;
|
||||
|
||||
if (nextTimeStep > 0.0) {
|
||||
using M = ::Opm::UnitSystem::measure;
|
||||
|
||||
dh.nextStep(usys.from_si(M::time, nextTimeStep));
|
||||
}
|
||||
|
||||
return dh.data();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <opm/output/eclipse/InteHEAD.hpp> // Opm::RestartIO::makeUTCTime()
|
||||
|
||||
#include <opm/output/eclipse/VectorItems/doubhead.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
@@ -38,12 +40,14 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace VI = Opm::RestartIO::Helpers::VectorItems;
|
||||
|
||||
enum Index : std::vector<double>::size_type {
|
||||
// 0..9
|
||||
SimTime = 0,
|
||||
TsInit = 1,
|
||||
TsMaxz = 2,
|
||||
TsMinz = 3,
|
||||
TsInit = VI::doubhead::TsInit,
|
||||
TsMaxz = VI::doubhead::TsMaxz,
|
||||
TsMinz = VI::doubhead::TsMinz,
|
||||
TsMchp = 4,
|
||||
TsFMax = 5,
|
||||
TsFMin = 6,
|
||||
@@ -303,7 +307,7 @@ enum Index : std::vector<double>::size_type {
|
||||
dh_218 = 218,
|
||||
dh_219 = 219,
|
||||
|
||||
// 220..227
|
||||
// 220..228
|
||||
dh_220 = 220,
|
||||
dh_221 = 221,
|
||||
dh_222 = 222,
|
||||
@@ -376,7 +380,6 @@ namespace {
|
||||
|
||||
Opm::RestartIO::DoubHEAD::DoubHEAD()
|
||||
: data_(Index::NUMBER_OF_ITEMS, 0.0)
|
||||
//: data_(Index::NUMBER_OF_ITEMS, -1.0e20)
|
||||
{
|
||||
// Numbers below have unknown usage, values have been determined by
|
||||
// experiments to be constant across a range of reference cases.
|
||||
@@ -588,6 +591,16 @@ Opm::RestartIO::DoubHEAD::timeStamp(const TimeStamp& ts)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Opm::RestartIO::DoubHEAD&
|
||||
Opm::RestartIO::DoubHEAD::nextStep(const double nextTimeStep)
|
||||
{
|
||||
if (nextTimeStep > 0.0) {
|
||||
this->data_[Index::TsInit] = nextTimeStep;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Opm::RestartIO::DoubHEAD&
|
||||
Opm::RestartIO::DoubHEAD::drsdt(const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
|
||||
@@ -500,7 +500,14 @@ RestartValue EclipseIO::loadRestart(const std::vector<RestartKey>& solution_keys
|
||||
report_step,
|
||||
false );
|
||||
|
||||
return RestartIO::load( filename , report_step , solution_keys , es, grid , schedule, extra_keys);
|
||||
auto rst = RestartIO::load(filename, report_step, solution_keys,
|
||||
es, grid, schedule, extra_keys);
|
||||
|
||||
// Technically a violation of 'const'. Allowed because 'impl' is
|
||||
// constant pointer to mutable Impl.
|
||||
this->impl->summary.reset_cumulative_quantities(rst.second);
|
||||
|
||||
return std::move(rst.first);
|
||||
}
|
||||
|
||||
EclipseIO::EclipseIO( const EclipseState& es,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
@@ -74,6 +75,13 @@ namespace {
|
||||
return extra_solution.count(vector) > 0;
|
||||
}
|
||||
|
||||
double nextStepSize(const Opm::RestartValue& rst_value)
|
||||
{
|
||||
return rst_value.hasExtra("OPMEXTRA")
|
||||
? rst_value.getExtra("OPMEXTRA")[0]
|
||||
: 0.0;
|
||||
}
|
||||
|
||||
std::vector<int>
|
||||
serialize_OPM_IWEL(const data::Wells& wells,
|
||||
const std::vector<const Well*>& sched_wells)
|
||||
@@ -262,9 +270,10 @@ namespace {
|
||||
|
||||
std::vector<int>
|
||||
writeHeader(::Opm::RestartIO::ecl_rst_file_type* rst_file,
|
||||
int sim_step,
|
||||
int report_step,
|
||||
double simTime,
|
||||
const int sim_step,
|
||||
const int report_step,
|
||||
const double next_step_size,
|
||||
const double simTime,
|
||||
const Schedule& schedule,
|
||||
const EclipseGrid& grid,
|
||||
const EclipseState& es)
|
||||
@@ -274,7 +283,8 @@ namespace {
|
||||
}
|
||||
|
||||
// write INTEHEAD to restart file
|
||||
const auto ih = Helpers::createInteHead(es, grid, schedule, simTime, sim_step, sim_step);
|
||||
const auto ih = Helpers::createInteHead(es, grid, schedule,
|
||||
simTime, sim_step, sim_step);
|
||||
write_kw(rst_file, "INTEHEAD", ih);
|
||||
|
||||
// write LOGIHEAD to restart file
|
||||
@@ -282,7 +292,8 @@ namespace {
|
||||
write_kw(rst_file, "LOGIHEAD", lh);
|
||||
|
||||
// write DOUBHEAD to restart file
|
||||
const auto dh = Helpers::createDoubHead(es, schedule, sim_step, simTime);
|
||||
const auto dh = Helpers::createDoubHead(es, schedule, sim_step,
|
||||
simTime, next_step_size);
|
||||
write_kw(rst_file, "DOUBHEAD", dh);
|
||||
|
||||
// return the inteHead vector
|
||||
@@ -291,7 +302,7 @@ namespace {
|
||||
|
||||
void writeGroup(::Opm::RestartIO::ecl_rst_file_type* rst_file,
|
||||
int sim_step,
|
||||
const bool ecl_compatible_rst,
|
||||
const bool ecl_compatible_rst,
|
||||
const Schedule& schedule,
|
||||
const Opm::SummaryState& sumState,
|
||||
const std::vector<int>& ih)
|
||||
@@ -301,15 +312,15 @@ namespace {
|
||||
|
||||
auto groupData = Helpers::AggregateGroupData(ih);
|
||||
|
||||
auto & rst_g_keys = groupData.restart_group_keys;
|
||||
auto & rst_f_keys = groupData.restart_field_keys;
|
||||
auto & grpKeyToInd = groupData.groupKeyToIndex;
|
||||
auto & fldKeyToInd = groupData.fieldKeyToIndex;
|
||||
const auto& rst_g_keys = groupData.restart_group_keys;
|
||||
const auto& rst_f_keys = groupData.restart_field_keys;
|
||||
const auto& grpKeyToInd = groupData.groupKeyToIndex;
|
||||
const auto& fldKeyToInd = groupData.fieldKeyToIndex;
|
||||
|
||||
groupData.captureDeclaredGroupData(schedule,
|
||||
rst_g_keys, rst_f_keys,
|
||||
grpKeyToInd, fldKeyToInd,
|
||||
ecl_compatible_rst,
|
||||
ecl_compatible_rst,
|
||||
simStep, sumState, ih);
|
||||
write_kw(rst_file, "IGRP", groupData.getIGroup());
|
||||
write_kw(rst_file, "SGRP", groupData.getSGroup());
|
||||
@@ -322,14 +333,16 @@ namespace {
|
||||
const UnitSystem& units,
|
||||
const Schedule& schedule,
|
||||
const EclipseGrid& grid,
|
||||
const Opm::SummaryState& sumState,
|
||||
const Opm::data::Wells& wells,
|
||||
const Opm::SummaryState& sumState,
|
||||
const Opm::data::Wells& wells,
|
||||
const std::vector<int>& ih)
|
||||
{
|
||||
// write ISEG, RSEG, ILBS and ILBR to restart file
|
||||
const size_t simStep = static_cast<size_t> (sim_step);
|
||||
const auto simStep = static_cast<std::size_t> (sim_step);
|
||||
|
||||
auto MSWData = Helpers::AggregateMSWData(ih);
|
||||
MSWData.captureDeclaredMSWData(schedule, simStep, units, ih, grid, sumState, wells);
|
||||
MSWData.captureDeclaredMSWData(schedule, simStep, units,
|
||||
ih, grid, sumState, wells);
|
||||
|
||||
write_kw(rst_file, "ISEG", MSWData.getISeg());
|
||||
write_kw(rst_file, "ILBS", MSWData.getILBs());
|
||||
@@ -339,7 +352,7 @@ namespace {
|
||||
|
||||
void writeWell(::Opm::RestartIO::ecl_rst_file_type* rst_file,
|
||||
int sim_step,
|
||||
const bool ecl_compatible_rst,
|
||||
const bool ecl_compatible_rst,
|
||||
const Phases& phases,
|
||||
const UnitSystem& units,
|
||||
const EclipseGrid& grid,
|
||||
@@ -350,7 +363,9 @@ namespace {
|
||||
{
|
||||
auto wellData = Helpers::AggregateWellData(ih);
|
||||
wellData.captureDeclaredWellData(schedule, units, sim_step, sumState, ih);
|
||||
wellData.captureDynamicWellData(schedule, sim_step, ecl_compatible_rst, wells, sumState);
|
||||
wellData.captureDynamicWellData(schedule, sim_step,
|
||||
ecl_compatible_rst,
|
||||
wells, sumState);
|
||||
|
||||
write_kw(rst_file, "IWEL", wellData.getIWell());
|
||||
write_kw(rst_file, "SWEL", wellData.getSWell());
|
||||
@@ -358,7 +373,7 @@ namespace {
|
||||
write_kw(rst_file, "ZWEL", serialize_ZWEL(wellData.getZWell()));
|
||||
|
||||
// Extended set of OPM well vectors
|
||||
if (!ecl_compatible_rst)
|
||||
if (!ecl_compatible_rst)
|
||||
{
|
||||
const auto sched_wells = schedule.getWells(sim_step);
|
||||
|
||||
@@ -372,17 +387,81 @@ namespace {
|
||||
}
|
||||
|
||||
auto connectionData = Helpers::AggregateConnectionData(ih);
|
||||
connectionData.captureDeclaredConnData(schedule, grid, units, wells, sim_step);
|
||||
connectionData.captureDeclaredConnData(schedule, grid, units,
|
||||
wells, sim_step);
|
||||
|
||||
write_kw(rst_file, "ICON", connectionData.getIConn());
|
||||
write_kw(rst_file, "SCON", connectionData.getSConn());
|
||||
write_kw(rst_file, "XCON", connectionData.getXConn());
|
||||
}
|
||||
|
||||
bool haveHysteresis(const RestartValue& value)
|
||||
{
|
||||
for (const auto* key : { "KRNSW_OW", "PCSWM_OW",
|
||||
"KRNSW_GO", "PCSWM_GO", })
|
||||
{
|
||||
if (value.solution.has(key)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
convertedHysteresisSat(const RestartValue& value,
|
||||
const std::string& primary,
|
||||
const std::string& fallback)
|
||||
{
|
||||
auto smax = std::vector<double>{};
|
||||
|
||||
if (value.solution.has(primary)) {
|
||||
smax = value.solution.data(primary);
|
||||
}
|
||||
else if (value.solution.has(fallback)) {
|
||||
smax = value.solution.data(fallback);
|
||||
}
|
||||
|
||||
if (! smax.empty()) {
|
||||
std::transform(std::begin(smax), std::end(smax), std::begin(smax),
|
||||
[](const double s) { return 1.0 - s; });
|
||||
}
|
||||
|
||||
return smax;
|
||||
}
|
||||
|
||||
template <class OutputVector>
|
||||
void writeEclipseCompatHysteresis(const RestartValue& value,
|
||||
const bool write_double,
|
||||
OutputVector&& writeVector)
|
||||
{
|
||||
// Convert Flow-specific vectors {KRNSW,PCSWM}_OW to ECLIPSE's
|
||||
// requisite SOMAX vector. Only partially characterised.
|
||||
// Sufficient for Norne.
|
||||
{
|
||||
const auto somax =
|
||||
convertedHysteresisSat(value, "KRNSW_OW", "PCSWM_OW");
|
||||
|
||||
if (! somax.empty()) {
|
||||
writeVector("SOMAX", somax, write_double);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert Flow-specific vectors {KRNSW,PCSWM}_GO to ECLIPSE's
|
||||
// requisite SGMAX vector. Only partially characterised.
|
||||
// Sufficient for Norne.
|
||||
{
|
||||
const auto sgmax =
|
||||
convertedHysteresisSat(value, "KRNSW_GO", "PCSWM_GO");
|
||||
|
||||
if (! sgmax.empty()) {
|
||||
writeVector("SGMAX", sgmax, write_double);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeSolution(ecl_rst_file_type* rst_file,
|
||||
const RestartValue& value,
|
||||
const bool ecl_compatible_rst,
|
||||
const bool write_double_arg)
|
||||
const bool ecl_compatible_rst,
|
||||
const bool write_double_arg)
|
||||
{
|
||||
ecl_rst_file_start_solution(rst_file);
|
||||
|
||||
@@ -396,8 +475,6 @@ namespace {
|
||||
};
|
||||
|
||||
for (const auto& elm : value.solution) {
|
||||
if (ecl_compatible_rst && (elm.first == "TEMP")) continue;
|
||||
|
||||
if (elm.second.target == data::TargetType::RESTART_SOLUTION)
|
||||
{
|
||||
write(elm.first, elm.second.data, write_double_arg);
|
||||
@@ -413,9 +490,15 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
if (ecl_compatible_rst && haveHysteresis(value)) {
|
||||
writeEclipseCompatHysteresis(value, write_double_arg, write);
|
||||
}
|
||||
|
||||
ecl_rst_file_end_solution(rst_file);
|
||||
|
||||
if (ecl_compatible_rst) return;
|
||||
if (ecl_compatible_rst) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& elm : value.solution) {
|
||||
if (elm.second.target == data::TargetType::RESTART_AUXILIARY) {
|
||||
@@ -452,25 +535,24 @@ void save(const std::string& filename,
|
||||
bool write_double)
|
||||
{
|
||||
::Opm::RestartIO::checkSaveArguments(es, value, grid);
|
||||
bool ecl_compatible_rst = es.getIOConfig().getEclCompatibleRST();
|
||||
|
||||
const auto ecl_compatible_rst = es.getIOConfig().getEclCompatibleRST();
|
||||
|
||||
const auto sim_step = std::max(report_step - 1, 0);
|
||||
const auto& units = es.getUnits();
|
||||
|
||||
auto rst_file = openRestartFile(filename, report_step);
|
||||
if (ecl_compatible_rst)
|
||||
write_double = false;
|
||||
|
||||
// Convert solution fields and extra values from SI to user units.
|
||||
value.solution.convertFromSI(units);
|
||||
for (auto& extra_value : value.extra) {
|
||||
const auto& restart_key = extra_value.first;
|
||||
auto& data = extra_value.second;
|
||||
|
||||
units.from_si(restart_key.dim, data);
|
||||
if (ecl_compatible_rst) {
|
||||
write_double = false;
|
||||
}
|
||||
|
||||
const auto inteHD = writeHeader(rst_file.get(), sim_step, report_step,
|
||||
seconds_elapsed, schedule, grid, es);
|
||||
// Convert solution fields and extra values from SI to user units.
|
||||
value.convertFromSI(units);
|
||||
|
||||
const auto inteHD =
|
||||
writeHeader(rst_file.get(), sim_step, report_step,
|
||||
nextStepSize(value), seconds_elapsed,
|
||||
schedule, grid, es);
|
||||
|
||||
writeGroup(rst_file.get(), sim_step, ecl_compatible_rst,
|
||||
schedule, sumState, inteHD);
|
||||
@@ -480,14 +562,14 @@ void save(const std::string& filename,
|
||||
const auto& wells = schedule.getWells(sim_step);
|
||||
|
||||
if (! wells.empty()) {
|
||||
const auto numMSW =
|
||||
std::count_if(std::begin(wells), std::end(wells),
|
||||
const auto haveMSW =
|
||||
std::any_of(std::begin(wells), std::end(wells),
|
||||
[sim_step](const Well* well)
|
||||
{
|
||||
return well->isMultiSegment(sim_step);
|
||||
});
|
||||
|
||||
if (numMSW > 0) {
|
||||
if (haveMSW) {
|
||||
writeMSWData(rst_file.get(), sim_step, units,
|
||||
schedule, grid, sumState, value.wells, inteHD);
|
||||
}
|
||||
@@ -500,8 +582,9 @@ void save(const std::string& filename,
|
||||
|
||||
writeSolution(rst_file.get(), value, ecl_compatible_rst, write_double);
|
||||
|
||||
if (!ecl_compatible_rst)
|
||||
::Opm::RestartIO::writeExtraData(rst_file.get(), value.extra);
|
||||
if (! ecl_compatible_rst) {
|
||||
writeExtraData(rst_file.get(), value.extra);
|
||||
}
|
||||
}
|
||||
|
||||
}} // Opm::RestartIO
|
||||
|
||||
@@ -65,6 +65,8 @@ namespace {
|
||||
"WIR", "GIR",
|
||||
"WIT", "GIT",
|
||||
"WCT", "GOR",
|
||||
"OPTH", "WPTH", "GPTH",
|
||||
"WITH", "GITH",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1527,4 +1529,23 @@ const SummaryState& Summary::get_restart_vectors() const
|
||||
return this->prev_state;
|
||||
}
|
||||
|
||||
void Summary::reset_cumulative_quantities(const SummaryState& rstrt)
|
||||
{
|
||||
for (const auto& f : this->handlers->handlers) {
|
||||
if (! smspec_node_is_total(f.first)) {
|
||||
// Ignore quantities that are not cumulative ("total").
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto* genkey = smspec_node_get_gen_key1(f.first);
|
||||
if (rstrt.has(genkey)) {
|
||||
// Assume 'rstrt' uses output units. This is satisfied if rstrt
|
||||
// is constructed from information in a restart file--i.e., from
|
||||
// the double precision restart vectors 'XGRP' and 'XWEL' during
|
||||
// RestartIO::load().
|
||||
this->prev_state.add(genkey, rstrt.get(genkey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace Opm::out
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 Equinor
|
||||
Copyright 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
@@ -232,6 +233,11 @@ TSTEP -- 8
|
||||
state.add("WWCT:OP_1" , 0.625);
|
||||
state.add("WGOR:OP_1" , 234.5);
|
||||
state.add("WBHP:OP_1" , 314.15);
|
||||
state.add("WOPTH:OP_1", 345.6);
|
||||
state.add("WWPTH:OP_1", 456.7);
|
||||
state.add("WGPTH:OP_1", 567.8);
|
||||
state.add("WWITH:OP_1", 0.0);
|
||||
state.add("WGITH:OP_1", 0.0);
|
||||
state.add("WGVIR:OP_1", 0.0);
|
||||
state.add("WWVIR:OP_1", 0.0);
|
||||
|
||||
@@ -250,6 +256,11 @@ TSTEP -- 8
|
||||
state.add("WWCT:OP_2" , 0.0);
|
||||
state.add("WGOR:OP_2" , 0.0);
|
||||
state.add("WBHP:OP_2" , 400.6);
|
||||
state.add("WOPTH:OP_2", 0.0);
|
||||
state.add("WWPTH:OP_2", 0.0);
|
||||
state.add("WGPTH:OP_2", 0.0);
|
||||
state.add("WWITH:OP_2", 1515.0);
|
||||
state.add("WGITH:OP_2", 3030.0);
|
||||
state.add("WGVIR:OP_2", 1234.0);
|
||||
state.add("WWVIR:OP_2", 4321.0);
|
||||
|
||||
@@ -268,6 +279,11 @@ TSTEP -- 8
|
||||
state.add("WWCT:OP_3" , 0.0625);
|
||||
state.add("WGOR:OP_3" , 1234.5);
|
||||
state.add("WBHP:OP_3" , 314.15);
|
||||
state.add("WOPTH:OP_3", 2345.6);
|
||||
state.add("WWPTH:OP_3", 3456.7);
|
||||
state.add("WGPTH:OP_3", 4567.8);
|
||||
state.add("WWITH:OP_3", 0.0);
|
||||
state.add("WGITH:OP_3", 0.0);
|
||||
state.add("WGVIR:OP_3", 0.0);
|
||||
state.add("WWVIR:OP_3", 43.21);
|
||||
|
||||
@@ -532,7 +548,7 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
|
||||
|
||||
const auto& iwell = awd.getIWell();
|
||||
|
||||
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item9 ], iwell[i0 + Ix::WCtrl]);
|
||||
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item9 ], iwell[i0 + Ix::ActWCtrl]);
|
||||
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item11], 1);
|
||||
}
|
||||
|
||||
@@ -561,17 +577,27 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::LiqPrRate], 1.0 + 2.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrRate], 4.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::FlowBHP], 314.15, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatCut] , 0.625, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GORatio], 234.5, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::FlowBHP], 314.15 , 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatCut] , 0.625, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GORatio], 234.5 , 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::OilPrTotal], 10.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrTotal], 20.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrTotal], 30.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrTotal], 40.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item37], xwell[i0 + Ix::WatPrRate], 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item38], xwell[i0 + Ix::GasPrRate], 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item37],
|
||||
xwell[i0 + Ix::WatPrRate], 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item38],
|
||||
xwell[i0 + Ix::GasPrRate], 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistOilPrTotal], 345.6, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistWatPrTotal], 456.7, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistGasPrTotal], 567.8, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistWatInjTotal], 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistGasInjTotal], 0.0, 1.0e-10);
|
||||
}
|
||||
|
||||
// XWEL (OP_2)
|
||||
@@ -585,6 +611,7 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::VoidPrRate], -1234.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::FlowBHP], 400.6, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatInjTotal], 1000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasInjTotal], 2000.0, 1.0e-10);
|
||||
|
||||
// Bg = VGIR / GIR = 1234.0 / 200.0
|
||||
@@ -593,11 +620,11 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item38],
|
||||
xwell[i1 + Ix::GasPrRate], 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item83],
|
||||
xwell[i1 + Ix::GasInjTotal], 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasVoidPrRate],
|
||||
xwell[i1 + Ix::VoidPrRate], 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistOilPrTotal] , 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistWatPrTotal] , 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistGasPrTotal] , 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistWatInjTotal], 1515.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistGasInjTotal], 3030.0, 1.0e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,7 +668,7 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
|
||||
const auto& iwell = awd.getIWell();
|
||||
|
||||
BOOST_CHECK_EQUAL(iwell[i1 + Ix::item9],
|
||||
iwell[i1 + Ix::WCtrl]);
|
||||
iwell[i1 + Ix::ActWCtrl]);
|
||||
BOOST_CHECK_EQUAL(iwell[i1 + Ix::item11], 1);
|
||||
}
|
||||
|
||||
@@ -672,6 +699,10 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item38],
|
||||
xwell[i0 + Ix::GasPrRate], 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistOilPrTotal], 345.6, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistWatPrTotal], 456.7, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistGasPrTotal], 567.8, 1.0e-10);
|
||||
}
|
||||
|
||||
// XWEL (OP_2) -- water injector
|
||||
@@ -690,14 +721,17 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::FlowBHP], 400.6, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatInjTotal], 1000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasInjTotal], 2000.0, 1.0e-10);
|
||||
|
||||
// Copy of WWIR
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item37],
|
||||
xwell[i1 + Ix::WatPrRate], 1.0e-10);
|
||||
|
||||
// Copy of WWIT
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item82],
|
||||
xwell[i1 + Ix::WatInjTotal], 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistOilPrTotal] , 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistWatPrTotal] , 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistGasPrTotal] , 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistWatInjTotal], 1515.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistGasInjTotal], 3030.0, 1.0e-10);
|
||||
|
||||
// WWVIR
|
||||
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatVoidPrRate],
|
||||
@@ -733,6 +767,10 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
|
||||
// Copy of WGPR
|
||||
BOOST_CHECK_CLOSE(xwell[i2 + Ix::item38],
|
||||
xwell[i2 + Ix::GasPrRate], 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(xwell[i2 + Ix::HistOilPrTotal], 2345.6, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i2 + Ix::HistWatPrTotal], 3456.7, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(xwell[i2 + Ix::HistGasPrTotal], 4567.8, 1.0e-10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -366,6 +366,11 @@ Opm::SummaryState sim_state()
|
||||
state.add("WWCT:OP_1" , 0.625);
|
||||
state.add("WGOR:OP_1" , 234.5);
|
||||
state.add("WBHP:OP_1" , 314.15);
|
||||
state.add("WOPTH:OP_1", 345.6);
|
||||
state.add("WWPTH:OP_1", 456.7);
|
||||
state.add("WGPTH:OP_1", 567.8);
|
||||
state.add("WWITH:OP_1", 0.0);
|
||||
state.add("WGITH:OP_1", 0.0);
|
||||
state.add("WGVIR:OP_1", 0.0);
|
||||
state.add("WWVIR:OP_1", 0.0);
|
||||
|
||||
@@ -384,6 +389,11 @@ Opm::SummaryState sim_state()
|
||||
state.add("WWCT:OP_2" , 0.0);
|
||||
state.add("WGOR:OP_2" , 0.0);
|
||||
state.add("WBHP:OP_2" , 400.6);
|
||||
state.add("WOPTH:OP_2", 0.0);
|
||||
state.add("WWPTH:OP_2", 0.0);
|
||||
state.add("WGPTH:OP_2", 0.0);
|
||||
state.add("WWITH:OP_2", 1515.0);
|
||||
state.add("WGITH:OP_2", 3030.0);
|
||||
state.add("WGVIR:OP_2", 1234.0);
|
||||
state.add("WWVIR:OP_2", 4321.0);
|
||||
|
||||
@@ -402,9 +412,58 @@ Opm::SummaryState sim_state()
|
||||
state.add("WWCT:OP_3" , 0.0625);
|
||||
state.add("WGOR:OP_3" , 1234.5);
|
||||
state.add("WBHP:OP_3" , 314.15);
|
||||
state.add("WOPTH:OP_3", 2345.6);
|
||||
state.add("WWPTH:OP_3", 3456.7);
|
||||
state.add("WGPTH:OP_3", 4567.8);
|
||||
state.add("WWITH:OP_3", 0.0);
|
||||
state.add("WGITH:OP_3", 0.0);
|
||||
state.add("WGVIR:OP_3", 0.0);
|
||||
state.add("WWVIR:OP_3", 43.21);
|
||||
|
||||
state.add("GOPR:OP" , 110.0);
|
||||
state.add("GWPR:OP" , 120.0);
|
||||
state.add("GGPR:OP" , 130.0);
|
||||
state.add("GVPR:OP" , 140.0);
|
||||
state.add("GOPT:OP" , 1100.0);
|
||||
state.add("GWPT:OP" , 1200.0);
|
||||
state.add("GGPT:OP" , 1300.0);
|
||||
state.add("GVPT:OP" , 1400.0);
|
||||
state.add("GWIR:OP" , - 256.0);
|
||||
state.add("GGIR:OP" , - 65536.0);
|
||||
state.add("GWIT:OP" , 31415.9);
|
||||
state.add("GGIT:OP" , 27182.8);
|
||||
state.add("GWCT:OP" , 0.625);
|
||||
state.add("GGOR:OP" , 1234.5);
|
||||
state.add("GGVIR:OP", 123.45);
|
||||
state.add("GWVIR:OP", 1234.56);
|
||||
state.add("GOPTH:OP", 5678.90);
|
||||
state.add("GWPTH:OP", 6789.01);
|
||||
state.add("GGPTH:OP", 7890.12);
|
||||
state.add("GWITH:OP", 8901.23);
|
||||
state.add("GGITH:OP", 9012.34);
|
||||
|
||||
state.add("FOPR" , 1100.0);
|
||||
state.add("FWPR" , 1200.0);
|
||||
state.add("FGPR" , 1300.0);
|
||||
state.add("FVPR" , 1400.0);
|
||||
state.add("FOPT" , 11000.0);
|
||||
state.add("FWPT" , 12000.0);
|
||||
state.add("FGPT" , 13000.0);
|
||||
state.add("FVPT" , 14000.0);
|
||||
state.add("FWIR" , - 2560.0);
|
||||
state.add("FGIR" , - 655360.0);
|
||||
state.add("FWIT" , 314159.2);
|
||||
state.add("FGIT" , 271828.1);
|
||||
state.add("FWCT" , 0.625);
|
||||
state.add("FGOR" , 1234.5);
|
||||
state.add("FOPTH", 56789.01);
|
||||
state.add("FWPTH", 67890.12);
|
||||
state.add("FGPTH", 78901.23);
|
||||
state.add("FWITH", 89012.34);
|
||||
state.add("FGITH", 90123.45);
|
||||
state.add("FGVIR", 1234.56);
|
||||
state.add("FWVIR", 12345.67);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -688,7 +747,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) {
|
||||
/* extra_keys = */ {
|
||||
{"EXTRA" , UnitSystem::measure::pressure, true} ,
|
||||
{"EXTRA2", UnitSystem::measure::identity, false}
|
||||
});
|
||||
}).first;
|
||||
|
||||
BOOST_CHECK(!rst_value.hasExtra("EXTRA2"));
|
||||
BOOST_CHECK( rst_value.hasExtra("EXTRA"));
|
||||
@@ -777,4 +836,136 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) {
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Restore_Cumulatives)
|
||||
{
|
||||
Setup setup("FIRST_SIM.DATA");
|
||||
|
||||
// Write fully ECLIPSE compatible output. This also saves cumulatives.
|
||||
setup.es.getIOConfig().setEclCompatibleRST(true);
|
||||
|
||||
const auto restart_value = RestartValue {
|
||||
mkSolution(setup.grid.getNumActive()),
|
||||
mkWells()
|
||||
};
|
||||
const auto sumState = sim_state();
|
||||
|
||||
RestartIO::save("FILE.UNRST", 1, 100, restart_value,
|
||||
setup.es, setup.grid, setup.schedule, sumState);
|
||||
|
||||
const auto rst_value = RestartIO::load("FILE.UNRST", 1,
|
||||
/* solution_keys = */ {
|
||||
RestartKey("SWAT", UnitSystem::measure::identity),
|
||||
},
|
||||
setup.es, setup.grid, setup.schedule,
|
||||
/* extra_keys = */ {});
|
||||
|
||||
const auto& rstSumState = rst_value.second;
|
||||
|
||||
// Verify that the restored summary state has all of its requisite
|
||||
// cumulative summary vectors.
|
||||
|
||||
// Producer => W*IT{,H} saved/restored as zero (0.0)
|
||||
BOOST_CHECK(rstSumState.has("WOPT:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WGPT:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WWPT:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WVPT:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WWIT:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WGIT:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WOPTH:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WGPTH:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WWPTH:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WWITH:OP_1"));
|
||||
BOOST_CHECK(rstSumState.has("WGITH:OP_1"));
|
||||
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WOPT:OP_1"), 10.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGPT:OP_1"), 30.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWPT:OP_1"), 20.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WVPT:OP_1"), 40.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWIT:OP_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGIT:OP_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WOPTH:OP_1"), 345.6, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWPTH:OP_1"), 456.7, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGPTH:OP_1"), 567.8, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWITH:OP_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGITH:OP_1"), 0.0, 1.0e-10);
|
||||
|
||||
// Gas injector => W*PT{,H} saved/restored as zero (0.0)
|
||||
BOOST_CHECK(rstSumState.has("WOPT:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WGPT:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WWPT:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WVPT:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WWIT:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WGIT:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WOPTH:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WGPTH:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WWPTH:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WWITH:OP_2"));
|
||||
BOOST_CHECK(rstSumState.has("WGITH:OP_2"));
|
||||
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WOPT:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGPT:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWPT:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WVPT:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWIT:OP_2"), 1000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGIT:OP_2"), 2000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WOPTH:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGPTH:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWPTH:OP_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WWITH:OP_2"), 1515.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("WGITH:OP_2"), 3030.0, 1.0e-10);
|
||||
|
||||
// Group cumulatives saved/restored for all phases
|
||||
BOOST_CHECK(rstSumState.has("GOPT:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GGPT:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GWPT:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GVPT:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GWIT:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GGIT:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GOPTH:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GGPTH:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GWPTH:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GWITH:OP"));
|
||||
BOOST_CHECK(rstSumState.has("GGITH:OP"));
|
||||
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GOPT:OP"), 1100.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GWPT:OP"), 1200.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GGPT:OP"), 1300.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GVPT:OP"), 1400.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GWIT:OP"), 31415.9, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GGIT:OP"), 27182.8, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GOPTH:OP"), 5678.90, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GGPTH:OP"), 7890.12, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GWPTH:OP"), 6789.01, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GWITH:OP"), 8901.23, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("GGITH:OP"), 9012.34, 1.0e-10);
|
||||
|
||||
// Field cumulatives saved/restored for all phases
|
||||
BOOST_CHECK(rstSumState.has("FOPT"));
|
||||
BOOST_CHECK(rstSumState.has("FGPT"));
|
||||
BOOST_CHECK(rstSumState.has("FWPT"));
|
||||
BOOST_CHECK(rstSumState.has("FVPT"));
|
||||
BOOST_CHECK(rstSumState.has("FWIT"));
|
||||
BOOST_CHECK(rstSumState.has("FGIT"));
|
||||
BOOST_CHECK(rstSumState.has("FOPTH"));
|
||||
BOOST_CHECK(rstSumState.has("FGPTH"));
|
||||
BOOST_CHECK(rstSumState.has("FWPTH"));
|
||||
BOOST_CHECK(rstSumState.has("FWITH"));
|
||||
BOOST_CHECK(rstSumState.has("FGITH"));
|
||||
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FOPT"), 11000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FWPT"), 12000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FGPT"), 13000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FVPT"), 14000.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FWIT"), 314159.2, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FGIT"), 271828.1, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FOPTH"), 56789.01, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FGPTH"), 78901.23, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FWPTH"), 67890.12, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FWITH"), 89012.34, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(rstSumState.get("FGITH"), 90123.45, 1.0e-10);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2899,3 +2899,176 @@ BOOST_AUTO_TEST_CASE(Write_Read)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
// =====================================================================
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Reset_Cumulative_Vectors)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Reset)
|
||||
{
|
||||
const auto config = setup { "test.Reset.Cumulative" };
|
||||
::Opm::out::Summary smry {
|
||||
config.es, config.config, config.grid,
|
||||
config.schedule, "Ignore.This"
|
||||
};
|
||||
|
||||
auto rstrt = ::Opm::SummaryState{};
|
||||
rstrt.add("WOPT:W_1", 1.0);
|
||||
rstrt.add("WWPT:W_1", 2.0);
|
||||
rstrt.add("WGPT:W_1", 3.0);
|
||||
rstrt.add("WVPT:W_1", 4.0);
|
||||
|
||||
rstrt.add("WWIT:W_1", 5.0);
|
||||
rstrt.add("WGIT:W_1", 6.0);
|
||||
|
||||
rstrt.add("WOPTH:W_1", 0.1);
|
||||
rstrt.add("WWPTH:W_1", 0.2);
|
||||
rstrt.add("WGPTH:W_1", 0.3);
|
||||
|
||||
rstrt.add("WWITH:W_1", 0.5);
|
||||
rstrt.add("WGITH:W_1", 0.6);
|
||||
|
||||
rstrt.add("GOPT:NoSuchGroup", 1.0);
|
||||
rstrt.add("GWPT:NoSuchGroup", 2.0);
|
||||
rstrt.add("GGPT:NoSuchGroup", 3.0);
|
||||
rstrt.add("GVPT:NoSuchGroup", 4.0);
|
||||
|
||||
rstrt.add("GWIT:NoSuchGroup", 5.0);
|
||||
rstrt.add("GGIT:NoSuchGroup", 6.0);
|
||||
|
||||
rstrt.add("FOPT", 10.0);
|
||||
rstrt.add("FWPT", 20.0);
|
||||
rstrt.add("FGPT", 30.0);
|
||||
rstrt.add("FVPT", 40.0);
|
||||
|
||||
rstrt.add("FWIT", 50.0);
|
||||
rstrt.add("FGIT", 60.0);
|
||||
|
||||
rstrt.add("FOPTH", 0.01);
|
||||
rstrt.add("FWPTH", 0.02);
|
||||
rstrt.add("FGPTH", 0.03);
|
||||
|
||||
rstrt.add("FWITH", 0.05);
|
||||
rstrt.add("FGITH", 0.06);
|
||||
|
||||
smry.reset_cumulative_quantities(rstrt);
|
||||
|
||||
const auto& sumstate = smry.get_restart_vectors();
|
||||
|
||||
// Cumulatives don't affect rates, BHP, WCT, or GOR.
|
||||
for (const auto* w : { "W_1", "W_2", "W_3" }) {
|
||||
auto get = [w, &sumstate](const std::string& vector) {
|
||||
return sumstate.get(vector + ':' + std::string(w));
|
||||
};
|
||||
|
||||
BOOST_CHECK_THROW(get("WWPR"), std::out_of_range);
|
||||
BOOST_CHECK_THROW(get("WOPR"), std::out_of_range);
|
||||
BOOST_CHECK_THROW(get("WGPR"), std::out_of_range);
|
||||
BOOST_CHECK_THROW(get("WVPR"), std::out_of_range);
|
||||
|
||||
BOOST_CHECK_THROW(get("WWIR"), std::out_of_range);
|
||||
BOOST_CHECK_THROW(get("WGIR"), std::out_of_range);
|
||||
|
||||
BOOST_CHECK_THROW(get("WBHP"), std::out_of_range);
|
||||
BOOST_CHECK_THROW(get("WWCT"), std::out_of_range);
|
||||
BOOST_CHECK_THROW(get("WGOR"), std::out_of_range);
|
||||
}
|
||||
|
||||
// Cumulatives reset for W_1.
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WOPT:W_1"), 1.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWPT:W_1"), 2.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGPT:W_1"), 3.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WVPT:W_1"), 4.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWIT:W_1"), 5.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGIT:W_1"), 6.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WOPTH:W_1"), 0.1, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWPTH:W_1"), 0.2, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGPTH:W_1"), 0.3, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWITH:W_1"), 0.5, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGITH:W_1"), 0.6, 1.0e-10);
|
||||
|
||||
// Cumulatives unset for W_2.
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WOPT:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWPT:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGPT:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WVPT:W_2"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWIT:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGIT:W_2"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WOPTH:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWPTH:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGPTH:W_2"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWITH:W_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGITH:W_2"), 0.0, 1.0e-10);
|
||||
|
||||
// Cumulatives unset for W_3.
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WOPT:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWPT:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGPT:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WVPT:W_3"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWIT:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGIT:W_3"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WOPTH:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWPTH:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGPTH:W_3"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WWITH:W_3"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("WGITH:W_3"), 0.0, 1.0e-10);
|
||||
|
||||
// Cumulatives unset for G_1.
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GOPT:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWPT:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGPT:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GVPT:G_1"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWIT:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGIT:G_1"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GOPTH:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWPTH:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGPTH:G_1"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWITH:G_1"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGITH:G_1"), 0.0, 1.0e-10);
|
||||
|
||||
// Cumulatives unset for G_2.
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GOPT:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWPT:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGPT:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GVPT:G_2"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWIT:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGIT:G_2"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GOPTH:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWPTH:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGPTH:G_2"), 0.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GWITH:G_2"), 0.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("GGITH:G_2"), 0.0, 1.0e-10);
|
||||
|
||||
// Cumulatives reset for FIELD.
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FOPT"), 10.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FWPT"), 20.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FGPT"), 30.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FVPT"), 40.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FWIT"), 50.0, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FGIT"), 60.0, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FOPTH"), 0.01, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FWPTH"), 0.02, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FGPTH"), 0.03, 1.0e-10);
|
||||
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FWITH"), 0.05, 1.0e-10);
|
||||
BOOST_CHECK_CLOSE(sumstate.get("FGITH"), 0.06, 1.0e-10);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Reference in New Issue
Block a user