Merge pull request #928 from jalvestad/udqrst-pull909
Output of UDQ properties to Eclipse compatible restart file
This commit is contained in:
@@ -136,13 +136,15 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParser.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp
|
||||
src/opm/parser/eclipse/Parser/ErrorGuard.cpp
|
||||
@@ -178,10 +180,12 @@ if(ENABLE_ECL_OUTPUT)
|
||||
src/opm/output/eclipse/AggregateConnectionData.cpp
|
||||
src/opm/output/eclipse/AggregateGroupData.cpp
|
||||
src/opm/output/eclipse/AggregateMSWData.cpp
|
||||
src/opm/output/eclipse/AggregateUDQData.cpp
|
||||
src/opm/output/eclipse/AggregateWellData.cpp
|
||||
src/opm/output/eclipse/CreateDoubHead.cpp
|
||||
src/opm/output/eclipse/CreateInteHead.cpp
|
||||
src/opm/output/eclipse/CreateLogiHead.cpp
|
||||
src/opm/output/eclipse/CreateUdqDims.cpp
|
||||
src/opm/output/eclipse/DoubHEAD.cpp
|
||||
src/opm/output/eclipse/EclipseGridInspector.cpp
|
||||
src/opm/output/eclipse/EclipseIO.cpp
|
||||
@@ -284,6 +288,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/test_AggregateGroupData.cpp
|
||||
tests/test_AggregateMSWData.cpp
|
||||
tests/test_AggregateConnectionData.cpp
|
||||
#tests/test_AggregateUDQData.cpp
|
||||
tests/test_ArrayDimChecker.cpp
|
||||
tests/test_EclipseIO.cpp
|
||||
tests/test_DoubHEAD.cpp
|
||||
@@ -324,6 +329,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
tests/SPE1CASE1A.SMSPEC
|
||||
tests/SPE9_CP_PACKED.DATA
|
||||
tests/SOFR_TEST.DATA
|
||||
tests/UDQ_TEST_WCONPROD_IUAD-2.DATA
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -564,10 +570,11 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp
|
||||
@@ -608,6 +615,7 @@ if(ENABLE_ECL_OUTPUT)
|
||||
opm/output/eclipse/AggregateGroupData.hpp
|
||||
opm/output/eclipse/AggregateConnectionData.hpp
|
||||
opm/output/eclipse/AggregateMSWData.hpp
|
||||
opm/output/eclipse/AggregateUDQData.hpp
|
||||
opm/output/eclipse/AggregateWellData.hpp
|
||||
opm/output/eclipse/DoubHEAD.hpp
|
||||
opm/output/eclipse/EclipseGridInspector.hpp
|
||||
|
||||
137
opm/output/eclipse/AggregateUDQData.hpp
Normal file
137
opm/output/eclipse/AggregateUDQData.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright (c) 2018 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_AGGREGATE_UDQ_DATA_HPP
|
||||
#define OPM_AGGREGATE_UDQ_DATA_HPP
|
||||
|
||||
#include <opm/output/eclipse/WindowedArray.hpp>
|
||||
#include <opm/io/eclipse/PaddedOutputString.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Opm {
|
||||
class Schedule;
|
||||
class UDQInput;
|
||||
class UDQActive;
|
||||
} // Opm
|
||||
|
||||
namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
|
||||
class igphData {
|
||||
public:
|
||||
const std::vector<int> ig_phase(const Opm::Schedule& sched, const std::size_t simStep, const std::vector<int>& inteHead);
|
||||
};
|
||||
|
||||
|
||||
class AggregateUDQData
|
||||
{
|
||||
public:
|
||||
explicit AggregateUDQData(const std::vector<int>& udqDims);
|
||||
|
||||
void captureDeclaredUDQData(const Opm::Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const std::vector<int>& ih);
|
||||
|
||||
const std::vector<int>& getIUDQ() const
|
||||
{
|
||||
return this->iUDQ_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIUAD() const
|
||||
{
|
||||
return this->iUAD_.data();
|
||||
}
|
||||
|
||||
const std::vector<EclIO::PaddedOutputString<8>>& getZUDN() const
|
||||
{
|
||||
return this->zUDN_.data();
|
||||
}
|
||||
|
||||
const std::vector<EclIO::PaddedOutputString<8>>& getZUDL() const
|
||||
{
|
||||
return this->zUDL_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIGPH() const
|
||||
{
|
||||
return this->iGPH_.data();
|
||||
}
|
||||
|
||||
const std::vector<int>& getIUAP() const
|
||||
{
|
||||
return this->iUAP_.data();
|
||||
}
|
||||
#if 0
|
||||
const std::vector<double>& getDUDW() const
|
||||
{
|
||||
return this->dUDW_.data();
|
||||
}
|
||||
|
||||
const std::vector<double>& getDUDF() const
|
||||
{
|
||||
return this->dUDF_.data();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
/// Aggregate 'IUDQ' array (Integer) for all UDQ data (3 integers pr UDQ)
|
||||
WindowedArray<int> iUDQ_;
|
||||
|
||||
/// Aggregate 'IUAD' array (Integer) for all UDQ data (5 integers pr UDQ that is used for various well and group controls)
|
||||
WindowedArray<int> iUAD_;
|
||||
|
||||
|
||||
/// Aggregate 'ZUDN' array (Character) for all UDQ data. (2 * 8 chars pr UDQ -> UNIT keyword)
|
||||
WindowedArray<EclIO::PaddedOutputString<8>> zUDN_;
|
||||
|
||||
/// Aggregate 'ZUDL' array (Character) for all UDQ data. (16 * 8 chars pr UDQ DEFINE "Data for operation - Msth Expression)
|
||||
WindowedArray<EclIO::PaddedOutputString<8>> zUDL_;
|
||||
|
||||
/// Aggregate 'IGPH' array (Integer) for all UDQ data (3 - zeroes - as of current understanding)
|
||||
WindowedArray<int> iGPH_;
|
||||
|
||||
/// Aggregate 'IUAP' array (ICharArrayNullTermnteger) for all UDQ data (1 integer pr UDQ constraint used)
|
||||
WindowedArray<int> iUAP_;
|
||||
#if 0
|
||||
/// Aggregate 'DUDW' array (Double Precision) for all UDQ data. (Dimension = max no wells * noOfUDQ's)
|
||||
WindowedArray<double> dUDW_;
|
||||
|
||||
/// Aggregate 'DUDF' array (Double Precision) for all UDQ data. (Dimension = Number of FU - UDQ's, with value equal to the actual constraint)
|
||||
WindowedArray<double> dUDF_;
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
#endif //OPM_AGGREGATE_WELL_DATA_HPP
|
||||
@@ -27,6 +27,7 @@
|
||||
namespace Opm {
|
||||
class Tuning;
|
||||
class Schedule;
|
||||
class UDQParams;
|
||||
}
|
||||
|
||||
namespace Opm { namespace RestartIO {
|
||||
@@ -38,7 +39,7 @@ namespace Opm { namespace RestartIO {
|
||||
std::chrono::time_point<std::chrono::system_clock> start;
|
||||
std::chrono::duration<double, std::chrono::seconds::period> elapsed;
|
||||
};
|
||||
|
||||
|
||||
DoubHEAD();
|
||||
|
||||
~DoubHEAD() = default;
|
||||
@@ -58,6 +59,8 @@ namespace Opm { namespace RestartIO {
|
||||
DoubHEAD& drsdt(const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const double cnvT);
|
||||
|
||||
DoubHEAD& udq_param(const UDQParams& udqPar);
|
||||
|
||||
const std::vector<double>& data() const
|
||||
{
|
||||
|
||||
@@ -89,6 +89,10 @@ namespace Opm { namespace RestartIO {
|
||||
struct Group {
|
||||
int ngroups;
|
||||
};
|
||||
|
||||
struct UdqParam {
|
||||
int udqParam_1;
|
||||
};
|
||||
|
||||
InteHEAD();
|
||||
~InteHEAD() = default;
|
||||
@@ -117,6 +121,7 @@ namespace Opm { namespace RestartIO {
|
||||
InteHEAD& wellSegDimensions(const WellSegDims& wsdim);
|
||||
InteHEAD& regionDimensions(const RegDims& rdim);
|
||||
InteHEAD& ngroups(const Group& gr);
|
||||
InteHEAD& udqParam_1(const UdqParam& udqpar);
|
||||
|
||||
const std::vector<int>& data() const
|
||||
{
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
TsInit = 1, // Maximum Length of Next Timestep
|
||||
TsMaxz = 2, // Maximum Length of Timestep After Next
|
||||
TsMinz = 3, // Minumum Length of All Timesteps
|
||||
UdqPar_2 = 212, // UDQPARAM item number 2 (Permitted range (+/-) of user-defined quantities)
|
||||
UdqPar_3 = 213, // UDQPARAM item number 3 (Value given to undefined elements when outputting data)
|
||||
UdqPar_4 = 214, // UDQPARAM item number 4 (fractional equality tolerance used in ==, <= etc. functions)
|
||||
};
|
||||
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
@@ -84,6 +84,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
NISEGZ = 178, // Number of entries per segment in ISEG array
|
||||
NRSEGZ = 179, // Number of entries per segment in RSEG array
|
||||
NILBRZ = 180, // Number of entries per segment in ILBR array
|
||||
|
||||
UDQPAR_1 = 267, // Integer seed value for the RAND /
|
||||
};
|
||||
}}}} // Opm::RestartIO::Helpers::VectorItems
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Opm {
|
||||
class Schedule;
|
||||
class Well;
|
||||
class UnitSystem;
|
||||
class UDQActive;
|
||||
|
||||
} // Opm
|
||||
|
||||
@@ -63,6 +64,11 @@ namespace Opm { namespace RestartIO { namespace Helpers {
|
||||
std::vector<bool>
|
||||
createLogiHead(const EclipseState& es);
|
||||
|
||||
std::vector<int>
|
||||
createUdqDims(const Schedule& sched,
|
||||
const std::size_t lookup_step,
|
||||
const std::vector<int>& inteHead);
|
||||
|
||||
|
||||
}}} // Opm::RestartIO::Helpers
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ namespace Opm
|
||||
class UnitSystem;
|
||||
class ErrorGuard;
|
||||
class WListManager;
|
||||
class UDQInput;
|
||||
class UDQConfig;
|
||||
class UDQActive;
|
||||
|
||||
class Schedule {
|
||||
public:
|
||||
@@ -177,9 +178,10 @@ namespace Opm
|
||||
std::vector<Well2> getChildWells2(const std::string& group_name, size_t timeStep, GroupWellQueryMode query_mode) const;
|
||||
const OilVaporizationProperties& getOilVaporizationProperties(size_t timestep) const;
|
||||
|
||||
const UDQActive& udqActive(size_t timeStep) const;
|
||||
const WellTestConfig& wtestConfig(size_t timestep) const;
|
||||
const WListManager& getWListManager(size_t timeStep) const;
|
||||
const UDQInput& getUDQConfig(size_t timeStep) const;
|
||||
const UDQConfig& getUDQConfig(size_t timeStep) const;
|
||||
const Action::Actions& actions() const;
|
||||
void evalAction(const SummaryState& summary_state, size_t timeStep);
|
||||
|
||||
@@ -226,7 +228,8 @@ namespace Opm
|
||||
std::map<int, DynamicState<std::shared_ptr<VFPInjTable>>> vfpinj_tables;
|
||||
DynamicState<std::shared_ptr<WellTestConfig>> wtest_config;
|
||||
DynamicState<std::shared_ptr<WListManager>> wlist_manager;
|
||||
DynamicState<std::shared_ptr<UDQInput>> udq_config;
|
||||
DynamicState<std::shared_ptr<UDQConfig>> udq_config;
|
||||
DynamicState<std::shared_ptr<UDQActive>> udq_active;
|
||||
DynamicState<WellProducer::ControlModeEnum> global_whistctl_mode;
|
||||
RFTConfig rft_config;
|
||||
|
||||
@@ -236,6 +239,8 @@ namespace Opm
|
||||
|
||||
GTNode groupTree(const std::string& root_node, std::size_t report_step, const GTNode * parent) const;
|
||||
void updateGroup(std::shared_ptr<Group2> group, size_t reportStep);
|
||||
bool checkGroups(const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void updateUDQActive( std::size_t timeStep, std::shared_ptr<UDQActive> udq );
|
||||
bool updateWellStatus( const std::string& well, size_t reportStep , WellCommon::StatusEnum status);
|
||||
void addWellToGroup( const std::string& group_name, const std::string& well_name , size_t timeStep);
|
||||
void iterateScheduleSection(const ParseContext& parseContext , ErrorGuard& errors, const SCHEDULESection& , const EclipseGrid& grid,
|
||||
|
||||
113
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp
Normal file
113
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UDQ_USAGE_HPP
|
||||
#define UDQ_USAGE_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class UDAValue;
|
||||
class UDQConfig;
|
||||
class UDQActive {
|
||||
public:
|
||||
|
||||
class Record{
|
||||
public:
|
||||
Record(const std::string& udq_arg, std::size_t input_index_arg, std::size_t use_index_arg, const std::string& wgname_arg, UDAControl control_arg) :
|
||||
udq(udq_arg),
|
||||
input_index(input_index_arg),
|
||||
use_index(use_index_arg),
|
||||
wgname(wgname_arg),
|
||||
control(control_arg),
|
||||
uad_code(UDQ::uadCode(control_arg)),
|
||||
use_count(1)
|
||||
{}
|
||||
|
||||
bool operator==(const Record& other) const {
|
||||
if ((this->udq == other.udq) &&
|
||||
(this->input_index == other.input_index) &&
|
||||
(this->use_index == other.use_index) &&
|
||||
(this->wgname == other.wgname) &&
|
||||
(this->control == other.control) &&
|
||||
(this->uad_code == other.uad_code) &&
|
||||
(this->use_count == other.use_count))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const Record& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::string udq;
|
||||
std::size_t input_index;
|
||||
std::size_t use_index = 0;
|
||||
std::string wgname;
|
||||
UDAControl control;
|
||||
int uad_code;
|
||||
std::size_t use_count;
|
||||
};
|
||||
|
||||
class InputRecord {
|
||||
public:
|
||||
InputRecord(std::size_t input_index_arg, const std::string& udq_arg, const std::string& wgname_arg, UDAControl control_arg) :
|
||||
input_index(input_index_arg),
|
||||
udq(udq_arg),
|
||||
wgname(wgname_arg),
|
||||
control(control_arg)
|
||||
{}
|
||||
|
||||
std::size_t input_index;
|
||||
std::string udq;
|
||||
std::string wgname;
|
||||
UDAControl control;
|
||||
int uad_code;
|
||||
};
|
||||
|
||||
int update(const UDQConfig& udq_config, const UDAValue& uda, const std::string& wgname, UDAControl control);
|
||||
std::size_t IUAD_size() const;
|
||||
std::size_t IUAP_size() const;
|
||||
explicit operator bool() const;
|
||||
Record operator[](std::size_t index) const;
|
||||
const std::vector<Record>& get_iuad() const;
|
||||
std::vector<InputRecord> get_iuap() const;
|
||||
private:
|
||||
std::string udq_hash(const std::string& udq, UDAControl control);
|
||||
std::string wg_hash(const std::string& wgname, UDAControl control);
|
||||
int add(const UDQConfig& udq_config, const std::string& udq, const std::string& wgname, UDAControl control);
|
||||
int update_input(const UDQConfig& udq_config, const UDAValue& uda, const std::string& wgname, UDAControl control);
|
||||
int drop(const std::string& wgname, UDAControl control);
|
||||
|
||||
std::vector<InputRecord> input_data;
|
||||
std::vector<Record> mutable output_data;
|
||||
std::unordered_map<std::string, std::size_t> udq_keys;
|
||||
std::unordered_map<std::string, std::size_t> wg_keys;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
97
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp
Normal file
97
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2018 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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UDQINPUT_HPP_
|
||||
#define UDQINPUT_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class Deck;
|
||||
class UDQConfig {
|
||||
public:
|
||||
explicit UDQConfig(const Deck& deck);
|
||||
explicit UDQConfig(const UDQParams& params);
|
||||
const std::string& unit(const std::string& key) const;
|
||||
bool has_unit(const std::string& keyword) const;
|
||||
bool has_keyword(const std::string& keyword) const;
|
||||
void add_record(const DeckRecord& record);
|
||||
|
||||
void add_unit(const std::string& keyword, const std::string& unit);
|
||||
void add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value);
|
||||
void add_define(const std::string& quantity, const std::vector<std::string>& expression);
|
||||
|
||||
std::vector<UDQDefine> definitions() const;
|
||||
std::vector<UDQDefine> definitions(UDQVarType var_type) const;
|
||||
std::vector<UDQInput> input() const;
|
||||
|
||||
// The size() method will return the number of active DEFINE and ASSIGN
|
||||
// statements; this will correspond to the length of the vector returned
|
||||
// from input().
|
||||
size_t size() const;
|
||||
|
||||
const UDQInput operator[](const std::string& keyword) const;
|
||||
|
||||
std::vector<UDQAssign> assignments() const;
|
||||
std::vector<UDQAssign> assignments(UDQVarType var_type) const;
|
||||
const UDQParams& params() const;
|
||||
const UDQFunctionTable& function_table() const;
|
||||
private:
|
||||
void add_node(const std::string& quantity, UDQAction action);
|
||||
|
||||
UDQParams udq_params;
|
||||
UDQFunctionTable udqft;
|
||||
|
||||
|
||||
/*
|
||||
The choices of datastructures are strongly motivated by the
|
||||
constraints imposed by the Eclipse formatted restart files; for
|
||||
writing restart files it is essential to keep meticolous control over
|
||||
the ordering of the keywords. In this class the ordering is mainly
|
||||
maintained by the input_index map which keeps track of the insert
|
||||
order of each keyword, and whether the keyword is currently DEFINE'ed
|
||||
or ASSIGN'ed.
|
||||
*/
|
||||
std::unordered_map<std::string, UDQDefine> m_definitions;
|
||||
std::unordered_map<std::string, UDQAssign> m_assignments;
|
||||
std::unordered_map<std::string, std::string> units;
|
||||
|
||||
OrderedMap<std::string, UDQIndex> input_index;
|
||||
std::map<UDQVarType, std::size_t> type_count;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -100,7 +100,6 @@ enum class UDQAction {
|
||||
UPDATE
|
||||
};
|
||||
|
||||
|
||||
enum class UDAControl {
|
||||
WCONPROD_ORAT,
|
||||
WCONPROD_GRAT,
|
||||
@@ -122,6 +121,15 @@ enum class UDAControl {
|
||||
};
|
||||
|
||||
|
||||
enum class UDAKeyword {
|
||||
WCONPROD,
|
||||
WCONINJE,
|
||||
GCONINJE,
|
||||
GCONPROD
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace UDQ {
|
||||
|
||||
bool compatibleTypes(UDQVarType lhs, UDQVarType rhs);
|
||||
@@ -135,6 +143,9 @@ namespace UDQ {
|
||||
bool cmpFunc(UDQTokenType token_type);
|
||||
|
||||
std::string typeName(UDQVarType var_type);
|
||||
UDAKeyword keyword(UDAControl control);
|
||||
int uadCode(UDAControl control);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
@@ -18,90 +18,58 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UDQINPUT_HPP_
|
||||
#define UDQINPUT_HPP_
|
||||
#ifndef UDQINPUT__HPP_
|
||||
#define UDQINPUT__HPP_
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <memory>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class Deck;
|
||||
class UDQAssign;
|
||||
class UDQDefine;
|
||||
|
||||
class UDQInput {
|
||||
public:
|
||||
explicit UDQInput(const Deck& deck);
|
||||
const std::string& unit(const std::string& key) const;
|
||||
bool has_unit(const std::string& keyword) const;
|
||||
bool has_keyword(const std::string& keyword) const;
|
||||
void add_record(const DeckRecord& record);
|
||||
void assign_unit(const std::string& keyword, const std::string& unit);
|
||||
class UDQIndex {
|
||||
public:
|
||||
UDQIndex() = default;
|
||||
|
||||
std::vector<UDQDefine> definitions() const;
|
||||
std::vector<UDQDefine> definitions(UDQVarType var_type) const;
|
||||
|
||||
/*
|
||||
The input_definitions() function is written to supply the information
|
||||
needed when writing the restart file. The return value is a list of
|
||||
pairs, where the first element in the pair is the index in the deck
|
||||
for a particular UDQ keyword, and then the corresponding keyword.
|
||||
Assume a deck keyword which looks like this:
|
||||
|
||||
UDQ
|
||||
ASSIGN WUX 10 /
|
||||
UNITS WUX 'BARSA' /
|
||||
DEFINE WUPR SUM(WOPR) * 0.75 /
|
||||
DEFINE FUCK MAX(WOPR) * 1.25 /
|
||||
ASSIGN FUX 100 /
|
||||
DEFINE BUPR ?? /
|
||||
/
|
||||
|
||||
Then the return value from input_definitions() will be:
|
||||
|
||||
{{1, UDQDefine("WUPR")},
|
||||
{2, UDQDefine("FUCK")},
|
||||
{4, UDQDefine("BUPR")}
|
||||
UDQIndex(std::size_t insert_index_arg, std::size_t typed_insert_index_arg, UDQAction action_arg) :
|
||||
insert_index(insert_index_arg),
|
||||
typed_insert_index(typed_insert_index_arg),
|
||||
action(action_arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Where the the numerical index is the index in a fictious vector
|
||||
consisting of only the ASSIGN and DEFINE keywords, in input order.
|
||||
*/
|
||||
std::vector<std::pair<size_t, UDQDefine>> input_definitions() const;
|
||||
|
||||
std::vector<UDQAssign> assignments() const;
|
||||
std::vector<UDQAssign> assignments(UDQVarType var_type) const;
|
||||
const UDQParams& params() const;
|
||||
const UDQFunctionTable& function_table() const;
|
||||
private:
|
||||
UDQParams udq_params;
|
||||
UDQFunctionTable udqft;
|
||||
std::size_t insert_index;
|
||||
std::size_t typed_insert_index;
|
||||
UDQAction action;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
The choices of datastructures are strongly motivated by the
|
||||
constraints imposed by the Eclipse formatted restart files; for
|
||||
writing restart files it is essential to keep meticolous control over
|
||||
the ordering of the keywords. In this class the ordering is mainly
|
||||
maintained by the input_index map which keeps track of the insert
|
||||
order of each keyword, and whether the keyword is currently DEFINE'ed
|
||||
or ASSIGN'ed.
|
||||
*/
|
||||
std::unordered_map<std::string, UDQDefine> m_definitions;
|
||||
std::unordered_map<std::string, UDQAssign> m_assignments;
|
||||
std::unordered_map<std::string, std::string> units;
|
||||
class UDQInput{
|
||||
public:
|
||||
UDQInput(const UDQIndex& index, const UDQDefine& udq_define, const std::string& unit);
|
||||
UDQInput(const UDQIndex& index, const UDQAssign& udq_assign, const std::string& unit);
|
||||
|
||||
OrderedMap<std::string, std::pair<size_t, UDQAction>> input_index;
|
||||
};
|
||||
template<typename T>
|
||||
const T& get() const;
|
||||
|
||||
template<typename T>
|
||||
bool is() const;
|
||||
|
||||
const std::string& keyword() const;
|
||||
UDQVarType var_type() const;
|
||||
const std::string& unit() const;
|
||||
const UDQIndex index;
|
||||
private:
|
||||
const UDQDefine * define;
|
||||
const UDQAssign * assign;
|
||||
const std::string m_keyword;
|
||||
UDQVarType m_var_type;
|
||||
const std::string m_unit;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Opm {
|
||||
public:
|
||||
explicit UDQParams(const Deck& deck);
|
||||
UDQParams();
|
||||
|
||||
int rand_seed() const noexcept;
|
||||
void reseedRNG(int seed);
|
||||
double range() const noexcept;
|
||||
double undefinedValue() const noexcept;
|
||||
|
||||
@@ -44,6 +44,7 @@ class EclipseGrid;
|
||||
class DeckKeyword;
|
||||
struct WellInjectionProperties;
|
||||
class WellProductionProperties;
|
||||
class UDQActive;
|
||||
|
||||
struct WellGuideRate {
|
||||
bool available;
|
||||
@@ -162,7 +163,6 @@ public:
|
||||
void switchToProducer();
|
||||
ProductionControls productionControls(const SummaryState& st) const;
|
||||
InjectionControls injectionControls(const SummaryState& st) const;
|
||||
|
||||
int vfp_table_number() const;
|
||||
double alq_value() const;
|
||||
double temperature() const;
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace Opm {
|
||||
class DeckRecord;
|
||||
class UnitSystem;
|
||||
class SummaryState;
|
||||
class UDQActive;
|
||||
class UDQConfig;
|
||||
|
||||
struct WellInjectionProperties {
|
||||
std::string name;
|
||||
@@ -75,6 +77,7 @@ namespace Opm {
|
||||
|
||||
void setBHPLimit(const double limit);
|
||||
InjectionControls controls(const UnitSystem& unit_system, const SummaryState& st, double udq_default) const;
|
||||
bool updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const;
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream&, const WellInjectionProperties& );
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class SummaryState;
|
||||
class UDQActive;
|
||||
|
||||
class WellProductionProperties {
|
||||
public:
|
||||
@@ -75,13 +76,13 @@ namespace Opm {
|
||||
|
||||
// this is used to check whether the specified control mode is an effective history matching production mode
|
||||
static bool effectiveHistoryProductionControl(const WellProducer::ControlModeEnum cmode);
|
||||
void handleWCONPROD( const DeckRecord& record);
|
||||
void handleWCONPROD( const std::string& well, const DeckRecord& record);
|
||||
void handleWCONHIST( const DeckRecord& record);
|
||||
void handleWELTARG(WellTarget::ControlModeEnum cmode, double newValue, double siFactorG, double siFactorL, double siFactorP);
|
||||
void resetDefaultBHPLimit();
|
||||
void clearControls();
|
||||
|
||||
ProductionControls controls(const SummaryState& st, double udq_default) const;
|
||||
bool updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const;
|
||||
private:
|
||||
int m_productionControls = 0;
|
||||
void init_rates( const DeckRecord& record );
|
||||
|
||||
360
src/opm/output/eclipse/AggregateUDQData.cpp
Normal file
360
src/opm/output/eclipse/AggregateUDQData.cpp
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
Copyright 2018 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/output/eclipse/AggregateUDQData.hpp>
|
||||
#include <opm/output/eclipse/AggregateGroupData.hpp>
|
||||
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
//#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
// #####################################################################
|
||||
// Class Opm::RestartIO::Helpers::AggregateGroupData
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// maximum number of groups
|
||||
std::size_t ngmaxz(const std::vector<int>& inteHead)
|
||||
{
|
||||
return inteHead[20];
|
||||
}
|
||||
|
||||
|
||||
namespace iUdq {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<int>
|
||||
allocate(const std::vector<int>& udqDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(udqDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(udqDims[1]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class IUDQArray>
|
||||
void staticContrib(const Opm::UDQInput& udq_input, IUDQArray& iUdq)
|
||||
{
|
||||
if (udq_input.is<Opm::UDQDefine>()) {
|
||||
iUdq[0] = 2;
|
||||
iUdq[1] = -4;
|
||||
} else {
|
||||
iUdq[0] = 0;
|
||||
iUdq[1] = -4;
|
||||
}
|
||||
iUdq[2] = udq_input.index.typed_insert_index;
|
||||
}
|
||||
|
||||
} // iUdq
|
||||
|
||||
namespace iUad {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<int>
|
||||
allocate(const std::vector<int>& udqDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(udqDims[2]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(udqDims[3]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class IUADArray>
|
||||
void staticContrib(const Opm::UDQActive::Record& udq_record, IUADArray& iUad)
|
||||
{
|
||||
iUad[0] = udq_record.uad_code;
|
||||
iUad[1] = udq_record.input_index + 1;
|
||||
|
||||
// entry 3 - unknown meaning - value = 1
|
||||
iUad[2] = 1;
|
||||
|
||||
iUad[3] = udq_record.use_count;
|
||||
iUad[4] = udq_record.use_index + 1;
|
||||
}
|
||||
} // iUad
|
||||
|
||||
|
||||
namespace zUdn {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>
|
||||
allocate(const std::vector<int>& udqDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>;
|
||||
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(udqDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(udqDims[4]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class zUdnArray>
|
||||
void staticContrib(const Opm::UDQInput& udq_input, zUdnArray& zUdn)
|
||||
{
|
||||
// entry 1 is udq keyword
|
||||
zUdn[0] = udq_input.keyword();
|
||||
zUdn[1] = udq_input.unit();
|
||||
}
|
||||
} // zUdn
|
||||
|
||||
namespace zUdl {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>
|
||||
allocate(const std::vector<int>& udqDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>;
|
||||
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(udqDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(udqDims[5]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class zUdlArray>
|
||||
void staticContrib(const Opm::UDQInput& input, zUdlArray& zUdl)
|
||||
{
|
||||
int l_sstr = 8;
|
||||
int max_l_str = 128;
|
||||
// write out the input formula if key is a DEFINE udq
|
||||
if (input.is<Opm::UDQDefine>()) {
|
||||
const auto& udq_define = input.get<Opm::UDQDefine>();
|
||||
const std::string& z_data = udq_define.input_string();
|
||||
int n_sstr = z_data.size()/l_sstr;
|
||||
if (static_cast<int>(z_data.size()) > max_l_str) {
|
||||
std::cout << "Too long input data string (max 128 characters): " << z_data << std::endl;
|
||||
throw std::invalid_argument("UDQ - variable: " + udq_define.keyword());
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < n_sstr; i++) {
|
||||
zUdl[i] = z_data.substr(i*l_sstr, l_sstr);
|
||||
}
|
||||
//add remainder of last non-zero string
|
||||
if ((z_data.size() % l_sstr) > 0)
|
||||
zUdl[n_sstr] = z_data.substr(n_sstr*l_sstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // zUdl
|
||||
|
||||
namespace iGph {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<int>
|
||||
allocate(const std::vector<int>& udqDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(udqDims[6]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(1) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class IGPHArray>
|
||||
void staticContrib(const int inj_phase,
|
||||
IGPHArray& iGph)
|
||||
{
|
||||
iGph[0] = inj_phase;
|
||||
}
|
||||
} // iGph
|
||||
|
||||
namespace iUap {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<int>
|
||||
allocate(const std::vector<int>& udqDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(udqDims[7]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(1) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class IUAPArray>
|
||||
void staticContrib(const int wg_no,
|
||||
IUAPArray& iUap)
|
||||
{
|
||||
iUap[0] = wg_no+1;
|
||||
}
|
||||
} // iUap
|
||||
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
|
||||
|
||||
template < typename T>
|
||||
std::pair<bool, int > findInVector(const std::vector<T> & vecOfElements, const T & element)
|
||||
{
|
||||
std::pair<bool, int > result;
|
||||
|
||||
// Find given element in vector
|
||||
auto it = std::find(vecOfElements.begin(), vecOfElements.end(), element);
|
||||
|
||||
if (it != vecOfElements.end())
|
||||
{
|
||||
result.second = std::distance(vecOfElements.begin(), it);
|
||||
result.first = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.first = false;
|
||||
result.second = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<int> Opm::RestartIO::Helpers::igphData::ig_phase(const Opm::Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const std::vector<int>& inteHead
|
||||
)
|
||||
{
|
||||
std::vector<int> inj_phase(ngmaxz(inteHead), 0);
|
||||
|
||||
for (const auto& gname : sched.groupNames(simStep)) {
|
||||
const auto& group = sched.getGroup2(gname, simStep);
|
||||
if (group.isInjectionGroup()) {
|
||||
//auto phase = group.getInjectionPhase();
|
||||
auto phase = Opm::Phase::OIL;
|
||||
if ( phase == Opm::Phase::OIL ) inj_phase[group.insert_index()] = 1;
|
||||
if ( phase == Opm::Phase::WATER ) inj_phase[group.insert_index()] = 2;
|
||||
if ( phase == Opm::Phase::GAS ) inj_phase[group.insert_index()] = 3;
|
||||
}
|
||||
|
||||
}
|
||||
return inj_phase;
|
||||
}
|
||||
|
||||
const std::vector<int> iuap_data(const Opm::Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const std::vector<Opm::UDQActive::InputRecord>& iuap)
|
||||
{
|
||||
//construct the current list of well or group sequence numbers to output the IUAP array
|
||||
std::vector<int> wg_no;
|
||||
Opm::UDAKeyword wg_key;
|
||||
|
||||
for (std::size_t ind = 0; ind < iuap.size(); ind++) {
|
||||
auto& ctrl = iuap[ind].control;
|
||||
wg_key = Opm::UDQ::keyword(ctrl);
|
||||
if ((wg_key == Opm::UDAKeyword::WCONPROD) || (wg_key == Opm::UDAKeyword::WCONINJE)) {
|
||||
const auto& well = sched.getWell2(iuap[ind].wgname, simStep);
|
||||
wg_no.push_back(well.seqIndex());
|
||||
}
|
||||
else if ((wg_key == Opm::UDAKeyword::GCONPROD) || (wg_key == Opm::UDAKeyword::GCONINJE)) {
|
||||
const auto& group = sched.getGroup2(iuap[ind].wgname, simStep);
|
||||
wg_no.push_back(group.insert_index());
|
||||
}
|
||||
else {
|
||||
std::cout << "Invalid Control keyword: " << static_cast<int>(ctrl) << std::endl;
|
||||
throw std::invalid_argument("UDQ - variable: " + iuap[ind].udq );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return wg_no;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Opm::RestartIO::Helpers::AggregateUDQData::
|
||||
AggregateUDQData(const std::vector<int>& udqDims)
|
||||
: iUDQ_ (iUdq::allocate(udqDims)),
|
||||
iUAD_ (iUad::allocate(udqDims)),
|
||||
zUDN_ (zUdn::allocate(udqDims)),
|
||||
zUDL_ (zUdl::allocate(udqDims)),
|
||||
iGPH_ (iGph::allocate(udqDims)),
|
||||
iUAP_ (iUap::allocate(udqDims))
|
||||
{}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void
|
||||
Opm::RestartIO::Helpers::AggregateUDQData::
|
||||
captureDeclaredUDQData(const Opm::Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const std::vector<int>& inteHead)
|
||||
{
|
||||
auto udqCfg = sched.getUDQConfig(simStep);
|
||||
for (const auto& udq_input : udqCfg.input()) {
|
||||
auto udq_index = udq_input.index.insert_index;
|
||||
{
|
||||
auto i_udq = this->iUDQ_[udq_index];
|
||||
iUdq::staticContrib(udq_input, i_udq);
|
||||
}
|
||||
{
|
||||
auto z_udn = this->zUDN_[udq_index];
|
||||
zUdn::staticContrib(udq_input, z_udn);
|
||||
}
|
||||
{
|
||||
auto z_udl = this->zUDL_[udq_index];
|
||||
zUdl::staticContrib(udq_input, z_udl);
|
||||
}
|
||||
}
|
||||
|
||||
auto udq_active = sched.udqActive(simStep);
|
||||
if (udq_active) {
|
||||
const auto& udq_records = udq_active.get_iuad();
|
||||
for (std::size_t index = 0; index < udq_records.size(); index++) {
|
||||
const auto& record = udq_records[index];
|
||||
auto i_uad = this->iUAD_[index];
|
||||
iUad::staticContrib(record, i_uad);
|
||||
}
|
||||
|
||||
const auto& iuap_records = udq_active.get_iuap();
|
||||
const auto iuap_vect = iuap_data(sched, simStep,iuap_records);
|
||||
for (std::size_t index = 0; index < iuap_vect.size(); index++) {
|
||||
const auto& wg_no = iuap_vect[index];
|
||||
auto i_uap = this->iUAP_[index];
|
||||
iUap::staticContrib(wg_no, i_uap);
|
||||
}
|
||||
|
||||
}
|
||||
Opm::RestartIO::Helpers::igphData igph_dat;
|
||||
auto igph = igph_dat.ig_phase(sched, simStep, inteHead);
|
||||
for (std::size_t index = 0; index < igph.size(); index++) {
|
||||
auto i_igph = this->iGPH_[index];
|
||||
iGph::staticContrib(igph[index], i_igph);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,12 +82,14 @@ createDoubHead(const EclipseState& es,
|
||||
const double nextTimeStep)
|
||||
{
|
||||
const auto& usys = es.getDeckUnitSystem();
|
||||
//const auto& rspec = es.runspec();
|
||||
const auto tconv = getTimeConv(usys);
|
||||
|
||||
auto dh = DoubHEAD{}
|
||||
.tuningParameters(sched.getTuning(), lookup_step, tconv)
|
||||
.timeStamp (computeTimeStamp(sched, simTime))
|
||||
.drsdt (sched, lookup_step, tconv)
|
||||
//.udq_param(getUDQParam(rspec))
|
||||
;
|
||||
|
||||
if (nextTimeStep > 0.0) {
|
||||
|
||||
@@ -182,7 +182,18 @@ namespace {
|
||||
mxwpit,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Opm::RestartIO::InteHEAD::UdqParam
|
||||
getRandSeedPar(const ::Opm::Runspec& rspec)
|
||||
{
|
||||
const auto& udq_par = rspec.udqParams();
|
||||
const auto r_seed = udq_par.rand_seed();
|
||||
|
||||
return { r_seed};
|
||||
}
|
||||
*/
|
||||
|
||||
Opm::RestartIO::InteHEAD::WellSegDims
|
||||
getWellSegDims(const ::Opm::Runspec& rspec,
|
||||
const ::Opm::Schedule& sched,
|
||||
@@ -280,6 +291,7 @@ createInteHead(const EclipseState& es,
|
||||
.regionDimensions (getRegDims(tdim, rdim))
|
||||
.ngroups ({ ngmax })
|
||||
.variousParam (201702, 100) // Output should be compatible with Eclipse 100, 2017.02 version.
|
||||
//.udqParam_1 (getRandSeedPar(rspec))
|
||||
;
|
||||
|
||||
return ih.data();
|
||||
|
||||
98
src/opm/output/eclipse/CreateUdqDims.cpp
Executable file
98
src/opm/output/eclipse/CreateUdqDims.cpp
Executable file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright (c) 2018 Equinor ASA
|
||||
Copyright (c) 2018 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/output/eclipse/AggregateUDQData.hpp>
|
||||
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
|
||||
|
||||
#include <opm/output/eclipse/InteHEAD.hpp>
|
||||
#include <opm/output/eclipse/DoubHEAD.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
|
||||
#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>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
std::size_t entriesPerIUDQ()
|
||||
{
|
||||
std::size_t no_entries = 3;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerIUAD()
|
||||
{
|
||||
std::size_t no_entries = 5;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerZUDN()
|
||||
{
|
||||
std::size_t no_entries = 2;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerZUDL()
|
||||
{
|
||||
std::size_t no_entries = 16;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerIGph(const std::vector<int>& inteHead)
|
||||
{
|
||||
std::size_t no_entries = inteHead[20];
|
||||
return no_entries;
|
||||
}
|
||||
} // Anonymous
|
||||
|
||||
// #####################################################################
|
||||
// Public Interface (createUdqDims()) Below Separator
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
std::vector<int>
|
||||
Opm::RestartIO::Helpers::
|
||||
createUdqDims(const Schedule& sched,
|
||||
const std::size_t simStep,
|
||||
const std::vector<int>& inteHead)
|
||||
{
|
||||
const auto& udqCfg = sched.getUDQConfig(simStep);
|
||||
const auto& udqActive = sched.udqActive(simStep);
|
||||
std::vector<int> udqDims(8);
|
||||
|
||||
udqDims[0] = udqCfg.size();
|
||||
udqDims[1] = entriesPerIUDQ();
|
||||
udqDims[2] = udqActive.IUAD_size();
|
||||
udqDims[3] = entriesPerIUAD();
|
||||
udqDims[4] = entriesPerZUDN();
|
||||
udqDims[5] = entriesPerZUDL();
|
||||
udqDims[6] = entriesPerIGph(inteHead);
|
||||
udqDims[7] = udqActive.IUAP_size();
|
||||
|
||||
return udqDims;
|
||||
}
|
||||
@@ -298,9 +298,9 @@ enum Index : std::vector<double>::size_type {
|
||||
// 210..219
|
||||
dh_210 = 210,
|
||||
dh_211 = 211,
|
||||
dh_212 = 212,
|
||||
dh_213 = 213,
|
||||
dh_214 = 214,
|
||||
UdqPar_2= VI::doubhead::UdqPar_2,
|
||||
UdqPar_3= VI::doubhead::UdqPar_3,
|
||||
UdqPar_4= VI::doubhead::UdqPar_4,
|
||||
dh_215 = 215,
|
||||
dh_216 = 216,
|
||||
dh_217 = 217,
|
||||
@@ -487,7 +487,14 @@ Opm::RestartIO::DoubHEAD::DoubHEAD()
|
||||
|
||||
this->data_[Index::dh_210] = 0.0;
|
||||
this->data_[Index::dh_211] = 0.0;
|
||||
this->data_[Index::dh_214] = 1.0e-4;
|
||||
/*
|
||||
UdqPar_2 and UdqPar_3 correspond to indices 212 og 213 respectively, they
|
||||
were not set at all in the original code, therefor temporarily commented
|
||||
out here to avoid effect of UDQ.
|
||||
*/
|
||||
//this->data_[UdqPar_2] = 1.0E+20;
|
||||
//this->data_[UdqPar_3] = 0.0;
|
||||
this->data_[UdqPar_4] = 1.0e-4;
|
||||
this->data_[Index::dh_215] = -2.0e+20;
|
||||
this->data_[Index::dh_217] = 0.0;
|
||||
this->data_[Index::dh_218] = 0.0;
|
||||
@@ -616,3 +623,13 @@ Opm::RestartIO::DoubHEAD::drsdt(const Schedule& sched,
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Opm::RestartIO::DoubHEAD&
|
||||
Opm::RestartIO::DoubHEAD::udq_param(const UDQParams& udqPar)
|
||||
{
|
||||
this->data_[UdqPar_2] = udqPar.range();
|
||||
this->data_[UdqPar_3] = udqPar.undefinedValue();
|
||||
this->data_[UdqPar_4] = udqPar.cmpEpsilon();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -19,420 +19,419 @@
|
||||
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
|
||||
|
||||
enum index : std::vector<int>::size_type {
|
||||
ISNUM = VI::intehead::ISNUM , // 0 0 An encoded integer corresponding to the time the file was created. For files not originating from ECLIPSE, this value may be set to zero.
|
||||
VERSION = VI::intehead::VERSION , // 0 0
|
||||
UNIT = VI::intehead::UNIT , // (1,2,3) 1 units type: 1 - METRIC, 2 - FIELD, 3 - LAB
|
||||
ih_003 = 3 , // 0 0
|
||||
ih_004 = 4 , // 0 0
|
||||
ih_005 = 5 , // 0 0
|
||||
ih_006 = 6 , // 0 0
|
||||
ih_007 = 7 , // 0 0
|
||||
NX = VI::intehead::NX , // NX 137 Grid x-direction dimension, NX
|
||||
NY = VI::intehead::NY , // NY 236 Grid x-direction dimension, NY
|
||||
NZ = VI::intehead::NZ , // NZ 58 Grid x-direction dimension, NZ
|
||||
NACTIV = VI::intehead::NACTIV , // NACTIV? 89022 NACTIV = number of active cells
|
||||
ih_012 = 12 , // 0 0
|
||||
ih_013 = 13 , // 0 0
|
||||
PHASE = VI::intehead::PHASE , // IPHS 7 IPHS = phase indicator: 1 - oil, 2 - water, 3 - oil/water, 4 - gas, 5 – oil/gas, 6 - gas/water, 7 - oil/water/gas (ECLIPSE output only)
|
||||
ih_015 = 15 , // 0 0
|
||||
NWELLS = VI::intehead::NWELLS , // NWELLS 39 NWELL = number of wells
|
||||
NCWMAX = VI::intehead::NCWMAX , // NCWMAX 108 Weldims item2 NCWMAX = maximum number of completions per well
|
||||
NGRP = 18 , // NGRP? 0 Number of actual groups
|
||||
NWGMAX = VI::intehead::NWGMAX , // NWGMAX 0 maximum of weldims item3 or item4 NWGMAX = maximum number of wells in any well group
|
||||
NGMAXZ = VI::intehead::NGMAXZ , // NGMAXZ 0 weldims item3 + 1 NGMAXZ = maximum number of groups in field
|
||||
ih_021 = 21 , // 0 0
|
||||
ih_022 = 22 , // 0 0
|
||||
ih_023 = 23 , // 0 0
|
||||
NIWELZ = VI::intehead::NIWELZ , // NIWELZ 155 155 NIWELZ = no of data elements per well in IWEL array (default 97 for ECLIPSE, 94 for ECLIPSE 300)
|
||||
NSWELZ = VI::intehead::NSWELZ , // NSWELZ 122 122 NSWELZ = number of daelements per well in SWEL array
|
||||
NXWELZ = VI::intehead::NXWELZ , // NXWELZ 130 130 NXWELZ = number of delements per well in XWEL array
|
||||
NZWELZ = VI::intehead::NZWELZ , // NZWEL 3 3 NZWEL = no of 8-character words per well in ZWEL array (= 3)
|
||||
ih_028 = 28 , // 0 0
|
||||
ih_029 = 29 , // 0 0
|
||||
ih_030 = 30 , // 0 0
|
||||
ih_031 = 31 , // 0 0
|
||||
NICONZ = VI::intehead::NICONZ , // 25 15 25 NICON = no of data elements per completion in ICON array (default 19)
|
||||
NSCONZ = VI::intehead::NSCONZ , // 40 0 NSCONZ = number of data elements per completion in SCON array
|
||||
NXCONZ = VI::intehead::NXCONZ , // 58 0 58 NXCONZ = number of data elements per completion in XCON array
|
||||
ih_035 = 35 , // 0 0
|
||||
NIGRPZ = VI::intehead::NIGRPZ , // 97+intehead_array[19] 0 97 + intehead[19] NIGRPZ = no of data elements per group in IGRP array
|
||||
NSGRPZ = VI::intehead::NSGRPZ , // 112 0 112 NSGRPZ = number of data elements per group in SGRP array
|
||||
NXGRPZ = VI::intehead::NXGRPZ , // 180 0 180 NXGRPZ = number of data elements per group in XGRP array
|
||||
NZGRPZ = VI::intehead::NZGRPZ , // 5 0 NZGRPZ = number of data elements per group in ZGRP array
|
||||
ih_040 = 40 , // 0 0
|
||||
NCAMAX = VI::intehead::NCAMAX , // 1 0 NCAMAX = maximum number of analytic aquifer connections
|
||||
NIAAQZ = VI::intehead::NIAAQZ , // 18 0 NIAAQZ = number of data elements per aquifer in IAAQ array
|
||||
NSAAQZ = VI::intehead::NSAAQZ , // 24 0 NSAAQZ = number of data elements per aquifer in SAAQ array
|
||||
NXAAQZ = VI::intehead::NXAAQZ , // 10 0 NXAAQZ = number of data elements per aquifer in XAAQ array
|
||||
NICAQZ = VI::intehead::NICAQZ , // 7 0 NSCAQZ= number of data elements per aquifer connection in SCAQ array
|
||||
NSCAQZ = VI::intehead::NSCAQZ , // 2 0
|
||||
NACAQZ = VI::intehead::NACAQZ , // 4 0
|
||||
ih_048 = 48 , // 0 0
|
||||
ih_049 = 49 , // 1 // has been determined by testing
|
||||
ih_050 = 50 , // 1 // has been determined by testing
|
||||
ih_051 = 51 , // 0 0
|
||||
ih_052 = 52 , // 0 0
|
||||
ih_053 = 53 , // 0 0
|
||||
ih_054 = 54 , // 0 0
|
||||
ih_055 = 55 , // 0 0
|
||||
ih_056 = 56 , // 0 0
|
||||
ih_057 = 57 , // 0 0
|
||||
ih_058 = 58 , // 0 0
|
||||
ih_059 = 59 , // 0 0
|
||||
ih_060 = 60 , // 0 0
|
||||
ih_061 = 61 , // 0 0
|
||||
ih_062 = 62 , // 0 0
|
||||
ih_063 = 63 , // 0 0
|
||||
DAY = 64 , // IDAY 2 IDAY = calendar day at this report time
|
||||
MONTH = 65 , // IMON 6 IMON = calendar month at this report time
|
||||
YEAR = 66 , // IYEAR 2016 IYEAR = calendar year at this report time
|
||||
NUM_SOLVER_STEPS = 67 , // The number of solver steps the simulator has performed so far.
|
||||
REPORT_STEP = 68 , // The sequence/report number for for this restart file.
|
||||
ih_069 = 69 , // 0 0
|
||||
ih_070 = 70 , // 0 0
|
||||
ih_071 = 71 , // 0 0
|
||||
ih_072 = 72 , // 0 0
|
||||
ih_073 = 73 , // 0 0
|
||||
ih_074 = 74 , // 0 0
|
||||
ih_075 = 75 , // 0 0
|
||||
ih_076 = 76 , // 0 0 2
|
||||
ih_077 = 77 , // 0 0
|
||||
ih_078 = 78 , // 0 0
|
||||
ih_079 = 79 , // 0 0
|
||||
NEWTMX = 80 , // 0 0 Tuning,Record3,Item1
|
||||
NEWTMN = 81 , // 0 0 Tuning,Record3,Item2
|
||||
LITMAX = 82 , // 0 0 Tuning,Record3,Item3
|
||||
LITMIN = 83 , // 0 0 Tuning,Record3,Item4
|
||||
ih_084 = 84 , // 0 0 Tuning,Record3,Item5
|
||||
ih_085 = 85 , // 0 0 Tuning,Record3,Item6
|
||||
MXWSIT = 86 , // 0 0
|
||||
MXWPIT = 87 , // 0 0
|
||||
ih_088 = 88 , // 0 0
|
||||
NTFIP = 89 , // 0 0 REGDIMS item1, or TABDIMS item 5
|
||||
ih_090 = 90 , // 0 0
|
||||
ih_091 = 91 , // 0 0
|
||||
ih_092 = 92 , // 0 0
|
||||
ih_093 = 93 , // 0 0
|
||||
IPROG = 94 , // 0 100 IPROG = simulation program identifier: 100 - ECLIPSE 100, 300 - ECLIPSE 300, 500 - ECLIPSE 300 (thermal option), negative - Other simulator
|
||||
INITSIZE = 95 , // 0 0
|
||||
ih_096 = 96 , // 0 0
|
||||
ih_097 = 97 , // 0 0
|
||||
ih_098 = 98 , // 0 0
|
||||
NMFIPR = 99 , // 0 0 REGDIMS item2
|
||||
ih_100 = 100 , // 0 0
|
||||
ih_101 = 101 , // 0 0 1
|
||||
ih_102 = 102 , // 0 0
|
||||
ih_103 = 103 , // 0 0 1
|
||||
ih_104 = 104 , // 0 0
|
||||
ih_105 = 105 , // 0 0
|
||||
ih_106 = 106 , // 0 0
|
||||
ih_107 = 107 , // 0 0
|
||||
ih_108 = 108 , // 0 0
|
||||
ih_109 = 109 , // 0 0
|
||||
ih_110 = 110 , // 0 0
|
||||
ih_111 = 111 , // 0 0
|
||||
ih_112 = 112 , // 0 0
|
||||
ih_113 = 113 , // 0 0
|
||||
ih_114 = 114 , // 0 0
|
||||
ih_115 = 115 , // 0 0
|
||||
ih_116 = 116 , // 0 0
|
||||
ih_117 = 117 , // 0 0
|
||||
ih_118 = 118 , // 0 0
|
||||
ih_119 = 119 , // 0 0
|
||||
ih_120 = 120 , // 0 0
|
||||
ih_121 = 121 , // 0 0
|
||||
ih_122 = 122 , // 0 0
|
||||
ih_123 = 123 , // 0 0
|
||||
ih_124 = 124 , // 0 0
|
||||
ih_125 = 125 , // 0 0
|
||||
ih_126 = 126 , // 0 0
|
||||
ih_127 = 127 , // 0 0
|
||||
ih_128 = 128 , // 0 0
|
||||
ih_129 = 129 , // 0 0
|
||||
ih_130 = 130 , // 0 0
|
||||
NODMAX = 131 , // 0 0 NODMAX = maximum number of nodes in extended network option
|
||||
NBRMAX = 132 , // 0 0 NBRMAX = maximum number of branches in extended network option
|
||||
NIBRAN = 133 , // 0 0 NIBRAN = number of entries per branch in the IBRAN array
|
||||
NRBRAN = 134 , // 0 0 NRBRAN = number of tries per branch in the RBRAN array
|
||||
NINODE = 135 , // 0 0 NINODE = number of entries per node in the INODE array
|
||||
NRNODE = 136 , // 0 0 NRNODE = number of entries per node in the RNODE array
|
||||
NZNODE = 137 , // 0 0 NZNODE = number of entries per node in the ZNODE array
|
||||
NINOBR = 138 , // 0 0 NINOBR = size of the INOBR array
|
||||
ih_139 = 139 , // 0 0
|
||||
ih_140 = 140 , // 0 0
|
||||
ih_141 = 141 , // 0 0
|
||||
ih_142 = 142 , // 0 0
|
||||
ih_143 = 143 , // 0 0
|
||||
ih_144 = 144 , // 0 0
|
||||
ih_145 = 145 , // 0 0
|
||||
ih_146 = 146 , // 0 0
|
||||
ih_147 = 147 , // 0 0
|
||||
ih_148 = 148 , // 0 0
|
||||
ih_149 = 149 , // 0 0
|
||||
ih_150 = 150 , // 0 0
|
||||
ih_151 = 151 , // 0 0
|
||||
ih_152 = 152 , // 0 0
|
||||
ih_153 = 153 , // 0 0
|
||||
ih_154 = 154 , // 0 0
|
||||
ih_155 = 155 , // 0 0
|
||||
ih_156 = 156 , // 0 0
|
||||
ih_157 = 157 , // 0 0
|
||||
ih_158 = 158 , // 0 0
|
||||
ih_159 = 159 , // 0 0
|
||||
ih_160 = 160 , // 0 0
|
||||
ih_161 = 161 , // 0 0
|
||||
NGCAUS = 162 , // 0 0 NGCAUS = maximum number of aquifer connections actually used.
|
||||
ih_163 = 163 , // 0 0
|
||||
ih_164 = 164 , // 0 0
|
||||
ih_165 = 165 , // 0 0
|
||||
ih_166 = 166 , // 0 0
|
||||
ih_167 = 167 , // 0 0
|
||||
ih_168 = 168 , // 0 0
|
||||
ih_169 = 169 , // 0 0
|
||||
ih_170 = 170 , // 0 0
|
||||
ih_171 = 171 , // 0 0
|
||||
ih_172 = 172 , // 0 0
|
||||
ih_173 = 173 , // 0 0
|
||||
NSEGWL = VI::intehead::NSEGWL , // 0 0 number of mswm wells defined with WELSEG
|
||||
NSWLMX = VI::intehead::NSWLMX , // NSWLMX 0 Item 1 in WSEGDIMS keyword (runspec section) NSWLMX = maximum number of segmented wells
|
||||
NSEGMX = VI::intehead::NSEGMX , // NSEGMX 0 Item 2 in WSEGDIMS keyword (runspec section) NSEGMX = maximum number of segments per well
|
||||
NLBRMX = VI::intehead::NLBRMX , // NLBRMX 0 Item 3 in WSEGDIMS keyword (runspec section) NLBRMX = maximum number of lateral branches per well
|
||||
NISEGZ = VI::intehead::NISEGZ , // 22 0 22 NISEGZ = number of entries per segment in ISEG array
|
||||
NRSEGZ = VI::intehead::NRSEGZ , // 146 0 140 NRSEGZ = number of entries per segment in RSEG array
|
||||
NILBRZ = VI::intehead::NILBRZ , // 10 10 NILBRZ = number of entries per segment in ILBR array
|
||||
RSTSIZE = 181 , // 0
|
||||
ih_182 = 182 , // 0
|
||||
ih_183 = 183 , // 0
|
||||
ih_184 = 184 , // 0
|
||||
ih_185 = 185 , // 0
|
||||
ih_186 = 186 , // 0
|
||||
ih_187 = 187 , // 0
|
||||
ih_188 = 188 , // 0
|
||||
ih_189 = 189 , // 0
|
||||
ih_190 = 190 , // 0
|
||||
ih_191 = 191 , // 0
|
||||
ih_192 = 192 , // 0
|
||||
ih_193 = 193 , // 0
|
||||
ih_194 = 194 , // 0
|
||||
ih_195 = 195 , // 0
|
||||
ih_196 = 196 , // 0
|
||||
ih_197 = 197 , // 0
|
||||
ih_198 = 198 , // 0
|
||||
ih_199 = 199 , // 0
|
||||
ih_200 = 200 , // 0
|
||||
ih_201 = 201 , // 0
|
||||
ih_202 = 202 , // 0
|
||||
ih_203 = 203 , // 0
|
||||
ih_204 = 204 , // 0
|
||||
ih_205 = 205 , // 0
|
||||
IHOURZ = 206 , // IHOURZ IHOURZ = current simulation time HH:MM:SS – number of hours (HH) (0-23).
|
||||
IMINTS = 207 , // IMINTS IMINTS = current simulation time HH:MM:SS - number of minutes (MM) (0-59).
|
||||
ih_208 = 208 , // 0
|
||||
ih_209 = 209 , // 0
|
||||
ih_210 = 210 , // 0
|
||||
ih_211 = 211 , // 0
|
||||
ih_212 = 212 , // 0
|
||||
ih_213 = 213 , // 0
|
||||
ih_214 = 214 , // 0
|
||||
ih_215 = 215 , // 0
|
||||
ih_216 = 216 , // 0
|
||||
ih_217 = 217 , // 0
|
||||
ih_218 = 218 , // 0
|
||||
ih_219 = 219 , // 0
|
||||
ih_220 = 220 , // 0
|
||||
ih_221 = 221 , // 0
|
||||
ih_222 = 222 , // 0
|
||||
NIIAQN = 223 , // 0 NIIAQN = number of lines of integer AQUNUM data.
|
||||
NIRAQN = 224 , // 0 NIRAQN = number of lines of real AQUNUM data.
|
||||
ih_225 = 225 , // 0
|
||||
NUMAQN = 226 , // 0 NUMAQN = number of lines of AQUNUM data entered.
|
||||
ih_227 = 227 , // 0
|
||||
ih_228 = 228 , // 0
|
||||
ih_229 = 229 , // 0
|
||||
ih_230 = 230 , // 0
|
||||
ih_231 = 231 , // 0
|
||||
ih_232 = 232 , // 0
|
||||
ih_233 = 233 , // 0
|
||||
NICOTZ = 234 , // 0 NICOTZ = number of entries in the ICOT array
|
||||
NXCOTZ = 235 , // 0 NXCOTZ = number of entries in the XCOT array
|
||||
NIWETZ = 236 , // 0 NIWETZ = number of entries in the IWET array
|
||||
NXWETZ = 237 , // 0 NXWETZ = number of entries in the XWET array
|
||||
NIGRTZ = 238 , // 0 NIGRTZ = number of entries in the IGRT array
|
||||
NXGRTZ = 239 , // 0 NXGRTZ = number of entries in the XGRT array
|
||||
NSTRA2 = 240 , // 0 NSTRA2 = number of tracers + 2
|
||||
ih_241 = 241 , // 0
|
||||
ih_242 = 242 , // 0
|
||||
ih_243 = 243 , // 0
|
||||
ih_244 = 244 , // 0
|
||||
ih_245 = 245 , // 0
|
||||
ih_246 = 246 , // 0
|
||||
ih_247 = 247 , // 0
|
||||
ih_248 = 248 , // 0
|
||||
ih_249 = 249 , // 0
|
||||
ih_250 = 250 , // 0
|
||||
ih_251 = 251 , // 0
|
||||
MAAQID = 252 , // 0 MAAQID = maximum number of analytic aquifers
|
||||
ih_253 = 253 , // 0
|
||||
ih_254 = 254 , // 0
|
||||
ih_255 = 255 , // 0
|
||||
ih_256 = 256 , // 0
|
||||
ih_257 = 257 , // 0
|
||||
ih_258 = 258 , // 0
|
||||
ih_259 = 259 , // 0
|
||||
ih_260 = 260 , // 0
|
||||
ih_261 = 261 , // 0
|
||||
ih_262 = 262 , // 0
|
||||
ih_263 = 263 , // 0
|
||||
ih_264 = 264 , // 0
|
||||
ih_265 = 265 , // 0
|
||||
ih_266 = 266 , // 0
|
||||
ih_267 = 267 , // 0
|
||||
ih_268 = 268 , // 0
|
||||
ih_269 = 269 , // 0
|
||||
ih_270 = 270 , // 0
|
||||
NCRDMX = 271 , // 0 NCRDMX = maximum number of chord segment links per well
|
||||
ih_272 = 272 , // 0
|
||||
ih_273 = 273 , // 0
|
||||
ih_274 = 274 , // 0
|
||||
ih_275 = 275 , // 0
|
||||
ih_276 = 276 , // 0
|
||||
ih_277 = 277 , // 0
|
||||
ih_278 = 278 , // 0
|
||||
ih_279 = 279 , // 0
|
||||
ih_280 = 280 , // 0
|
||||
ih_281 = 281 , // 0
|
||||
ih_282 = 282 , // 0
|
||||
ih_283 = 283 , // 0
|
||||
ih_284 = 284 , // 0
|
||||
ih_285 = 285 , // 0
|
||||
ih_286 = 286 , // 0
|
||||
ih_287 = 287 , // 0
|
||||
ih_288 = 288 , // 0
|
||||
ih_289 = 289 , // 0
|
||||
ih_290 = 290 , // 0
|
||||
ih_291 = 291 , // 0
|
||||
ih_292 = 292 , // 0
|
||||
ih_293 = 293 , // 0
|
||||
ih_294 = 294 , // 0
|
||||
ih_295 = 295 , // 0
|
||||
ih_296 = 296 , // 0
|
||||
ih_297 = 297 , // 0
|
||||
ih_298 = 298 , // 0
|
||||
ih_299 = 299 , // 0
|
||||
ih_300 = 300 , // 0
|
||||
ih_301 = 301 , // 0
|
||||
ih_302 = 302 , // 0
|
||||
ih_303 = 303 , // 0
|
||||
ih_304 = 304 , // 0
|
||||
ih_305 = 305 , // 0
|
||||
ih_306 = 306 , // 0
|
||||
ih_307 = 307 , // 0
|
||||
ih_308 = 308 , // 0
|
||||
ih_309 = 309 , // 0
|
||||
ih_310 = 310 , // 0
|
||||
ih_311 = 311 , // 0
|
||||
ih_312 = 312 , // 0
|
||||
ih_313 = 313 , // 0
|
||||
ih_314 = 314 , // 0
|
||||
ih_315 = 315 , // 0
|
||||
ih_316 = 316 , // 0
|
||||
ih_317 = 317 , // 0
|
||||
ih_318 = 318 , // 0
|
||||
ih_319 = 319 , // 0
|
||||
ih_320 = 320 , // 0
|
||||
ih_321 = 321 , // 0
|
||||
ih_322 = 322 , // 0
|
||||
ih_323 = 323 , // 0
|
||||
ih_324 = 324 , // 0
|
||||
ih_325 = 325 , // 0
|
||||
ih_326 = 326 , // 0
|
||||
ih_327 = 327 , // 0
|
||||
ih_328 = 328 , // 0
|
||||
ih_329 = 329 , // 0
|
||||
ih_330 = 330 , // 0
|
||||
ih_331 = 331 , // 0
|
||||
ih_332 = 332 , // 0
|
||||
ih_333 = 333 , // 0
|
||||
ih_334 = 334 , // 0
|
||||
ih_335 = 335 , // 0
|
||||
ih_336 = 336 , // 0
|
||||
ih_337 = 337 , // 0
|
||||
ih_338 = 338 , // 0
|
||||
ih_339 = 339 , // 0
|
||||
ih_340 = 340 , // 0
|
||||
ih_341 = 341 , // 0
|
||||
ih_342 = 342 , // 0
|
||||
ih_343 = 343 , // 0
|
||||
ih_344 = 344 , // 0
|
||||
ih_345 = 345 , // 0
|
||||
ih_346 = 346 , // 0
|
||||
ih_347 = 347 , // 0
|
||||
ih_348 = 348 , // 0
|
||||
ih_349 = 349 , // 0
|
||||
ih_350 = 350 , // 0
|
||||
ih_351 = 351 , // 0
|
||||
ih_352 = 352 , // 0
|
||||
ih_353 = 353 , // 0
|
||||
ih_354 = 354 , // 0
|
||||
ih_355 = 355 , // 0
|
||||
ih_356 = 356 , // 0
|
||||
ih_357 = 357 , // 0
|
||||
ih_358 = 358 , // 0
|
||||
ih_359 = 359 , // 0
|
||||
ih_360 = 360 , // 0
|
||||
ih_361 = 361 , // 0
|
||||
ih_362 = 362 , // 0
|
||||
ih_363 = 363 , // 0
|
||||
ih_364 = 364 , // 0
|
||||
ih_365 = 365 , // 0
|
||||
ih_366 = 366 , // 0
|
||||
ih_367 = 367 , // 0
|
||||
ih_368 = 368 , // 0
|
||||
ih_369 = 369 , // 0
|
||||
ih_370 = 370 , // 0
|
||||
ih_371 = 371 , // 0
|
||||
ih_372 = 372 , // 0
|
||||
ih_373 = 373 , // 0
|
||||
ih_374 = 374 , // 0
|
||||
ih_375 = 375 , // 0
|
||||
ih_376 = 376 , // 0
|
||||
ih_377 = 377 , // 0
|
||||
ih_378 = 378 , // 0
|
||||
ih_379 = 379 , // 0
|
||||
ih_380 = 380 , // 0
|
||||
ih_381 = 381 , // 0
|
||||
ih_382 = 382 , // 0
|
||||
ih_383 = 383 , // 0
|
||||
ih_384 = 384 , // 0
|
||||
ih_385 = 385 , // 0
|
||||
ih_386 = 386 , // 0
|
||||
ih_387 = 387 , // 0
|
||||
ih_388 = 388 , // 0
|
||||
ih_389 = 389 , // 0
|
||||
ih_390 = 390 , // 0
|
||||
ih_391 = 391 , // 0
|
||||
ih_392 = 392 , // 0
|
||||
ih_393 = 393 , // 0
|
||||
ih_394 = 394 , // 0
|
||||
ih_395 = 395 , // 0
|
||||
ih_396 = 396 , // 0
|
||||
ih_397 = 397 , // 0
|
||||
ih_398 = 398 , // 0
|
||||
ih_399 = 399 , // 0
|
||||
ih_400 = 400 , // 0
|
||||
ih_401 = 401 , // 0
|
||||
ih_402 = 402 , // 0
|
||||
ih_403 = 403 , // 0
|
||||
ih_404 = 404 , // 0
|
||||
ih_405 = 405 , // 0
|
||||
ih_406 = 406 , // 0
|
||||
ih_407 = 407 , // 0
|
||||
ih_408 = 408 , // 0
|
||||
ih_409 = 409 , // 0
|
||||
ISECND = 410 , // 0 ISECND = current simulation time HH:MM:SS - number of seconds (SS), reported in microseconds (0-59,999,999)
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
ISNUM = VI::intehead::ISNUM, // 0 0 An encoded integer corresponding to the time the file was created. For files not originating from ECLIPSE, this value may be set to zero.
|
||||
VERSION = VI::intehead::VERSION, // 0 0
|
||||
UNIT = VI::intehead::UNIT, // (1,2,3) 1 units type: 1 - METRIC, 2 - FIELD, 3 - LAB
|
||||
ih_003 = 3 , // 0 0
|
||||
ih_004 = 4 , // 0 0
|
||||
ih_005 = 5 , // 0 0
|
||||
ih_006 = 6 , // 0 0
|
||||
ih_007 = 7 , // 0 0
|
||||
NX = VI::intehead::NX, // NX 137 Grid x-direction dimension, NX
|
||||
NY = VI::intehead::NY, // NY 236 Grid x-direction dimension, NY
|
||||
NZ = VI::intehead::NZ, // NZ 58 Grid x-direction dimension, NZ
|
||||
NACTIV = VI::intehead::NACTIV, // NACTIV? 89022 NACTIV = number of active cells
|
||||
ih_012 = 12 , // 0 0
|
||||
ih_013 = 13 , // 0 0
|
||||
PHASE = VI::intehead::PHASE, // IPHS 7 IPHS = phase indicator: 1 - oil, 2 - water, 3 - oil/water, 4 - gas, 5 – oil/gas, 6 - gas/water, 7 - oil/water/gas (ECLIPSE output only)
|
||||
ih_015 = 15 , // 0 0
|
||||
NWELLS = VI::intehead::NWELLS, // NWELLS 39 NWELL = number of wells
|
||||
NCWMAX = VI::intehead::NCWMAX, // NCWMAX 108 Weldims item2 NCWMAX = maximum number of completions per well
|
||||
NGRP = 18 , // NGRP? 0 Number of actual groups
|
||||
NWGMAX = VI::intehead::NWGMAX, // NWGMAX 0 maximum of weldims item3 or item4 NWGMAX = maximum number of wells in any well group
|
||||
NGMAXZ = VI::intehead::NGMAXZ, // NGMAXZ 0 weldims item3 + 1 NGMAXZ = maximum number of groups in field
|
||||
ih_021 = 21 , // 0 0
|
||||
ih_022 = 22 , // 0 0
|
||||
ih_023 = 23 , // 0 0
|
||||
NIWELZ = VI::intehead::NIWELZ, // NIWELZ 155 155 NIWELZ = no of data elements per well in IWEL array (default 97 for ECLIPSE, 94 for ECLIPSE 300)
|
||||
NSWELZ = VI::intehead::NSWELZ, // NSWELZ 122 122 NSWELZ = number of daelements per well in SWEL array
|
||||
NXWELZ = VI::intehead::NXWELZ, // NXWELZ 130 130 NXWELZ = number of delements per well in XWEL array
|
||||
NZWELZ = VI::intehead::NZWELZ, // NZWEL 3 3 NZWEL = no of 8-character words per well in ZWEL array (= 3)
|
||||
ih_028 = 28 , // 0 0
|
||||
ih_029 = 29 , // 0 0
|
||||
ih_030 = 30 , // 0 0
|
||||
ih_031 = 31 , // 0 0
|
||||
NICONZ = VI::intehead::NICONZ, // 25 15 25 NICON = no of data elements per completion in ICON array (default 19)
|
||||
NSCONZ = VI::intehead::NSCONZ, // 40 0 NSCONZ = number of data elements per completion in SCON array
|
||||
NXCONZ = VI::intehead::NXCONZ, // 58 0 58 NXCONZ = number of data elements per completion in XCON array
|
||||
ih_035 = 35 , // 0 0
|
||||
NIGRPZ = VI::intehead::NIGRPZ, // 97+intehead_array[19] 0 97 + intehead[19] NIGRPZ = no of data elements per group in IGRP array
|
||||
NSGRPZ = VI::intehead::NSGRPZ, // 112 0 112 NSGRPZ = number of data elements per group in SGRP array
|
||||
NXGRPZ = VI::intehead::NXGRPZ, // 180 0 180 NXGRPZ = number of data elements per group in XGRP array
|
||||
NZGRPZ = VI::intehead::NZGRPZ, // 5 0 NZGRPZ = number of data elements per group in ZGRP array
|
||||
ih_040 = 40 , // 0 0
|
||||
NCAMAX = VI::intehead::NCAMAX, // 1 0 NCAMAX = maximum number of analytic aquifer connections
|
||||
NIAAQZ = VI::intehead::NIAAQZ, // 18 0 NIAAQZ = number of data elements per aquifer in IAAQ array
|
||||
NSAAQZ = VI::intehead::NSAAQZ, // 24 0 NSAAQZ = number of data elements per aquifer in SAAQ array
|
||||
NXAAQZ = VI::intehead::NXAAQZ, // 10 0 NXAAQZ = number of data elements per aquifer in XAAQ array
|
||||
NICAQZ = VI::intehead::NICAQZ, // 7 0 NSCAQZ= number of data elements per aquifer connection in SCAQ array
|
||||
NSCAQZ = VI::intehead::NSCAQZ, // 2 0
|
||||
NACAQZ = VI::intehead::NACAQZ, // 4 0
|
||||
ih_048 = 48 , // 0 0
|
||||
ih_049 = 49 , // 1 // has been determined by testing
|
||||
ih_050 = 50 , // 1 // has been determined by testing
|
||||
ih_051 = 51 , // 0 0
|
||||
ih_052 = 52 , // 0 0
|
||||
ih_053 = 53 , // 0 0
|
||||
ih_054 = 54 , // 0 0
|
||||
ih_055 = 55 , // 0 0
|
||||
ih_056 = 56 , // 0 0
|
||||
ih_057 = 57 , // 0 0
|
||||
ih_058 = 58 , // 0 0
|
||||
ih_059 = 59 , // 0 0
|
||||
ih_060 = 60 , // 0 0
|
||||
ih_061 = 61 , // 0 0
|
||||
ih_062 = 62 , // 0 0
|
||||
ih_063 = 63 , // 0 0
|
||||
DAY = 64 , // IDAY 2 IDAY = calendar day at this report time
|
||||
MONTH = 65 , // IMON 6 IMON = calendar month at this report time
|
||||
YEAR = 66 , // IYEAR 2016 IYEAR = calendar year at this report time
|
||||
NUM_SOLVER_STEPS = 67 , // The number of solver steps the simulator has performed so far.
|
||||
REPORT_STEP = 68 , // The sequence/report number for for this restart file.
|
||||
ih_069 = 69 , // 0 0
|
||||
ih_070 = 70 , // 0 0
|
||||
ih_071 = 71 , // 0 0
|
||||
ih_072 = 72 , // 0 0
|
||||
ih_073 = 73 , // 0 0
|
||||
ih_074 = 74 , // 0 0
|
||||
ih_075 = 75 , // 0 0
|
||||
ih_076 = 76 , // 0 0 2
|
||||
ih_077 = 77 , // 0 0
|
||||
ih_078 = 78 , // 0 0
|
||||
ih_079 = 79 , // 0 0
|
||||
NEWTMX = 80 , // 0 0 Tuning,Record3,Item1
|
||||
NEWTMN = 81 , // 0 0 Tuning,Record3,Item2
|
||||
LITMAX = 82 , // 0 0 Tuning,Record3,Item3
|
||||
LITMIN = 83 , // 0 0 Tuning,Record3,Item4
|
||||
ih_084 = 84 , // 0 0 Tuning,Record3,Item5
|
||||
ih_085 = 85 , // 0 0 Tuning,Record3,Item6
|
||||
MXWSIT = 86 , // 0 0
|
||||
MXWPIT = 87 , // 0 0
|
||||
ih_088 = 88 , // 0 0
|
||||
NTFIP = 89 , // 0 0 REGDIMS item1, or TABDIMS item 5
|
||||
ih_090 = 90 , // 0 0
|
||||
ih_091 = 91 , // 0 0
|
||||
ih_092 = 92 , // 0 0
|
||||
ih_093 = 93 , // 0 0
|
||||
IPROG = 94 , // 0 100 IPROG = simulation program identifier: 100 - ECLIPSE 100, 300 - ECLIPSE 300, 500 - ECLIPSE 300 (thermal option), negative - Other simulator
|
||||
INITSIZE = 95 , // 0 0
|
||||
ih_096 = 96 , // 0 0
|
||||
ih_097 = 97 , // 0 0
|
||||
ih_098 = 98 , // 0 0
|
||||
NMFIPR = 99 , // 0 0 REGDIMS item2
|
||||
ih_100 = 100 , // 0 0
|
||||
ih_101 = 101 , // 0 0 1
|
||||
ih_102 = 102 , // 0 0
|
||||
ih_103 = 103 , // 0 0 1
|
||||
ih_104 = 104 , // 0 0
|
||||
ih_105 = 105 , // 0 0
|
||||
ih_106 = 106 , // 0 0
|
||||
ih_107 = 107 , // 0 0
|
||||
ih_108 = 108 , // 0 0
|
||||
ih_109 = 109 , // 0 0
|
||||
ih_110 = 110 , // 0 0
|
||||
ih_111 = 111 , // 0 0
|
||||
ih_112 = 112 , // 0 0
|
||||
ih_113 = 113 , // 0 0
|
||||
ih_114 = 114 , // 0 0
|
||||
ih_115 = 115 , // 0 0
|
||||
ih_116 = 116 , // 0 0
|
||||
ih_117 = 117 , // 0 0
|
||||
ih_118 = 118 , // 0 0
|
||||
ih_119 = 119 , // 0 0
|
||||
ih_120 = 120 , // 0 0
|
||||
ih_121 = 121 , // 0 0
|
||||
ih_122 = 122 , // 0 0
|
||||
ih_123 = 123 , // 0 0
|
||||
ih_124 = 124 , // 0 0
|
||||
ih_125 = 125 , // 0 0
|
||||
ih_126 = 126 , // 0 0
|
||||
ih_127 = 127 , // 0 0
|
||||
ih_128 = 128 , // 0 0
|
||||
ih_129 = 129 , // 0 0
|
||||
ih_130 = 130 , // 0 0
|
||||
NODMAX = 131 , // 0 0 NODMAX = maximum number of nodes in extended network option
|
||||
NBRMAX = 132 , // 0 0 NBRMAX = maximum number of branches in extended network option
|
||||
NIBRAN = 133 , // 0 0 NIBRAN = number of entries per branch in the IBRAN array
|
||||
NRBRAN = 134 , // 0 0 NRBRAN = number of tries per branch in the RBRAN array
|
||||
NINODE = 135 , // 0 0 NINODE = number of entries per node in the INODE array
|
||||
NRNODE = 136 , // 0 0 NRNODE = number of entries per node in the RNODE array
|
||||
NZNODE = 137 , // 0 0 NZNODE = number of entries per node in the ZNODE array
|
||||
NINOBR = 138 , // 0 0 NINOBR = size of the INOBR array
|
||||
ih_139 = 139 , // 0 0
|
||||
ih_140 = 140 , // 0 0
|
||||
ih_141 = 141 , // 0 0
|
||||
ih_142 = 142 , // 0 0
|
||||
ih_143 = 143 , // 0 0
|
||||
ih_144 = 144 , // 0 0
|
||||
ih_145 = 145 , // 0 0
|
||||
ih_146 = 146 , // 0 0
|
||||
ih_147 = 147 , // 0 0
|
||||
ih_148 = 148 , // 0 0
|
||||
ih_149 = 149 , // 0 0
|
||||
ih_150 = 150 , // 0 0
|
||||
ih_151 = 151 , // 0 0
|
||||
ih_152 = 152 , // 0 0
|
||||
ih_153 = 153 , // 0 0
|
||||
ih_154 = 154 , // 0 0
|
||||
ih_155 = 155 , // 0 0
|
||||
ih_156 = 156 , // 0 0
|
||||
ih_157 = 157 , // 0 0
|
||||
ih_158 = 158 , // 0 0
|
||||
ih_159 = 159 , // 0 0
|
||||
ih_160 = 160 , // 0 0
|
||||
ih_161 = 161 , // 0 0
|
||||
NGCAUS = 162 , // 0 0 NGCAUS = maximum number of aquifer connections actually used.
|
||||
ih_163 = 163 , // 0 0
|
||||
ih_164 = 164 , // 0 0
|
||||
ih_165 = 165 , // 0 0
|
||||
ih_166 = 166 , // 0 0
|
||||
ih_167 = 167 , // 0 0
|
||||
ih_168 = 168 , // 0 0
|
||||
ih_169 = 169 , // 0 0
|
||||
ih_170 = 170 , // 0 0
|
||||
ih_171 = 171 , // 0 0
|
||||
ih_172 = 172 , // 0 0
|
||||
ih_173 = 173 , // 0 0
|
||||
NSEGWL = VI::intehead::NSEGWL, // 0 0 number of mswm wells defined with WELSEG
|
||||
NSWLMX = VI::intehead::NSWLMX, // NSWLMX 0 Item 1 in WSEGDIMS keyword (runspec section) NSWLMX = maximum number of segmented wells
|
||||
NSEGMX = VI::intehead::NSEGMX, // NSEGMX 0 Item 2 in WSEGDIMS keyword (runspec section) NSEGMX = maximum number of segments per well
|
||||
NLBRMX = VI::intehead::NLBRMX, // NLBRMX 0 Item 3 in WSEGDIMS keyword (runspec section) NLBRMX = maximum number of lateral branches per well
|
||||
NISEGZ = VI::intehead::NISEGZ, // 22 0 22 NISEGZ = number of entries per segment in ISEG array
|
||||
NRSEGZ = VI::intehead::NRSEGZ, // 146 0 140 NRSEGZ = number of entries per segment in RSEG array
|
||||
NILBRZ = VI::intehead::NILBRZ, // 10 10 NILBRZ = number of entries per segment in ILBR array
|
||||
RSTSIZE = 181 , // 0
|
||||
ih_182 = 182 , // 0
|
||||
ih_183 = 183 , // 0
|
||||
ih_184 = 184 , // 0
|
||||
ih_185 = 185 , // 0
|
||||
ih_186 = 186 , // 0
|
||||
ih_187 = 187 , // 0
|
||||
ih_188 = 188 , // 0
|
||||
ih_189 = 189 , // 0
|
||||
ih_190 = 190 , // 0
|
||||
ih_191 = 191 , // 0
|
||||
ih_192 = 192 , // 0
|
||||
ih_193 = 193 , // 0
|
||||
ih_194 = 194 , // 0
|
||||
ih_195 = 195 , // 0
|
||||
ih_196 = 196 , // 0
|
||||
ih_197 = 197 , // 0
|
||||
ih_198 = 198 , // 0
|
||||
ih_199 = 199 , // 0
|
||||
ih_200 = 200 , // 0
|
||||
ih_201 = 201 , // 0
|
||||
ih_202 = 202 , // 0
|
||||
ih_203 = 203 , // 0
|
||||
ih_204 = 204 , // 0
|
||||
ih_205 = 205 , // 0
|
||||
IHOURZ = 206 , // IHOURZ IHOURZ = current simulation time HH:MM:SS – number of hours (HH) (0-23).
|
||||
IMINTS = 207 , // IMINTS IMINTS = current simulation time HH:MM:SS - number of minutes (MM) (0-59).
|
||||
ih_208 = 208 , // 0
|
||||
ih_209 = 209 , // 0
|
||||
ih_210 = 210 , // 0
|
||||
ih_211 = 211 , // 0
|
||||
ih_212 = 212 , // 0
|
||||
ih_213 = 213 , // 0
|
||||
ih_214 = 214 , // 0
|
||||
ih_215 = 215 , // 0
|
||||
ih_216 = 216 , // 0
|
||||
ih_217 = 217 , // 0
|
||||
ih_218 = 218 , // 0
|
||||
ih_219 = 219 , // 0
|
||||
ih_220 = 220 , // 0
|
||||
ih_221 = 221 , // 0
|
||||
ih_222 = 222 , // 0
|
||||
NIIAQN = 223 , // 0 NIIAQN = number of lines of integer AQUNUM data.
|
||||
NIRAQN = 224 , // 0 NIRAQN = number of lines of real AQUNUM data.
|
||||
ih_225 = 225 , // 0
|
||||
NUMAQN = 226 , // 0 NUMAQN = number of lines of AQUNUM data entered.
|
||||
ih_227 = 227 , // 0
|
||||
ih_228 = 228 , // 0
|
||||
ih_229 = 229 , // 0
|
||||
ih_230 = 230 , // 0
|
||||
ih_231 = 231 , // 0
|
||||
ih_232 = 232 , // 0
|
||||
ih_233 = 233 , // 0
|
||||
NICOTZ = 234 , // 0 NICOTZ = number of entries in the ICOT array
|
||||
NXCOTZ = 235 , // 0 NXCOTZ = number of entries in the XCOT array
|
||||
NIWETZ = 236 , // 0 NIWETZ = number of entries in the IWET array
|
||||
NXWETZ = 237 , // 0 NXWETZ = number of entries in the XWET array
|
||||
NIGRTZ = 238 , // 0 NIGRTZ = number of entries in the IGRT array
|
||||
NXGRTZ = 239 , // 0 NXGRTZ = number of entries in the XGRT array
|
||||
NSTRA2 = 240 , // 0 NSTRA2 = number of tracers + 2
|
||||
ih_241 = 241 , // 0
|
||||
ih_242 = 242 , // 0
|
||||
ih_243 = 243 , // 0
|
||||
ih_244 = 244 , // 0
|
||||
ih_245 = 245 , // 0
|
||||
ih_246 = 246 , // 0
|
||||
ih_247 = 247 , // 0
|
||||
ih_248 = 248 , // 0
|
||||
ih_249 = 249 , // 0
|
||||
ih_250 = 250 , // 0
|
||||
ih_251 = 251 , // 0
|
||||
MAAQID = 252 , // 0 MAAQID = maximum number of analytic aquifers
|
||||
ih_253 = 253 , // 0
|
||||
ih_254 = 254 , // 0
|
||||
ih_255 = 255 , // 0
|
||||
ih_256 = 256 , // 0
|
||||
ih_257 = 257 , // 0
|
||||
ih_258 = 258 , // 0
|
||||
ih_259 = 259 , // 0
|
||||
ih_260 = 260 , // 0
|
||||
ih_261 = 261 , // 0
|
||||
ih_262 = 262 , // 0
|
||||
ih_263 = 263 , // 0
|
||||
ih_264 = 264 , // 0
|
||||
ih_265 = 265 , // 0
|
||||
ih_266 = 266 , // 0
|
||||
UDQPAR_1 = VI::intehead::UDQPAR_1, // 0
|
||||
ih_268 = 268 , // 0
|
||||
ih_269 = 269 , // 0
|
||||
ih_270 = 270 , // 0
|
||||
NCRDMX = 271 , // 0 NCRDMX = maximum number of chord segment links per well
|
||||
ih_272 = 272 , // 0
|
||||
ih_273 = 273 , // 0
|
||||
ih_274 = 274 , // 0
|
||||
ih_275 = 275 , // 0
|
||||
ih_276 = 276 , // 0
|
||||
ih_277 = 277 , // 0
|
||||
ih_278 = 278 , // 0
|
||||
ih_279 = 279 , // 0
|
||||
ih_280 = 280 , // 0
|
||||
ih_281 = 281 , // 0
|
||||
ih_282 = 282 , // 0
|
||||
ih_283 = 283 , // 0
|
||||
ih_284 = 284 , // 0
|
||||
ih_285 = 285 , // 0
|
||||
ih_286 = 286 , // 0
|
||||
ih_287 = 287 , // 0
|
||||
ih_288 = 288 , // 0
|
||||
ih_289 = 289 , // 0
|
||||
ih_290 = 290 , // 0
|
||||
ih_291 = 291 , // 0
|
||||
ih_292 = 292 , // 0
|
||||
ih_293 = 293 , // 0
|
||||
ih_294 = 294 , // 0
|
||||
ih_295 = 295 , // 0
|
||||
ih_296 = 296 , // 0
|
||||
ih_297 = 297 , // 0
|
||||
ih_298 = 298 , // 0
|
||||
ih_299 = 299 , // 0
|
||||
ih_300 = 300 , // 0
|
||||
ih_301 = 301 , // 0
|
||||
ih_302 = 302 , // 0
|
||||
ih_303 = 303 , // 0
|
||||
ih_304 = 304 , // 0
|
||||
ih_305 = 305 , // 0
|
||||
ih_306 = 306 , // 0
|
||||
ih_307 = 307 , // 0
|
||||
ih_308 = 308 , // 0
|
||||
ih_309 = 309 , // 0
|
||||
ih_310 = 310 , // 0
|
||||
ih_311 = 311 , // 0
|
||||
ih_312 = 312 , // 0
|
||||
ih_313 = 313 , // 0
|
||||
ih_314 = 314 , // 0
|
||||
ih_315 = 315 , // 0
|
||||
ih_316 = 316 , // 0
|
||||
ih_317 = 317 , // 0
|
||||
ih_318 = 318 , // 0
|
||||
ih_319 = 319 , // 0
|
||||
ih_320 = 320 , // 0
|
||||
ih_321 = 321 , // 0
|
||||
ih_322 = 322 , // 0
|
||||
ih_323 = 323 , // 0
|
||||
ih_324 = 324 , // 0
|
||||
ih_325 = 325 , // 0
|
||||
ih_326 = 326 , // 0
|
||||
ih_327 = 327 , // 0
|
||||
ih_328 = 328 , // 0
|
||||
ih_329 = 329 , // 0
|
||||
ih_330 = 330 , // 0
|
||||
ih_331 = 331 , // 0
|
||||
ih_332 = 332 , // 0
|
||||
ih_333 = 333 , // 0
|
||||
ih_334 = 334 , // 0
|
||||
ih_335 = 335 , // 0
|
||||
ih_336 = 336 , // 0
|
||||
ih_337 = 337 , // 0
|
||||
ih_338 = 338 , // 0
|
||||
ih_339 = 339 , // 0
|
||||
ih_340 = 340 , // 0
|
||||
ih_341 = 341 , // 0
|
||||
ih_342 = 342 , // 0
|
||||
ih_343 = 343 , // 0
|
||||
ih_344 = 344 , // 0
|
||||
ih_345 = 345 , // 0
|
||||
ih_346 = 346 , // 0
|
||||
ih_347 = 347 , // 0
|
||||
ih_348 = 348 , // 0
|
||||
ih_349 = 349 , // 0
|
||||
ih_350 = 350 , // 0
|
||||
ih_351 = 351 , // 0
|
||||
ih_352 = 352 , // 0
|
||||
ih_353 = 353 , // 0
|
||||
ih_354 = 354 , // 0
|
||||
ih_355 = 355 , // 0
|
||||
ih_356 = 356 , // 0
|
||||
ih_357 = 357 , // 0
|
||||
ih_358 = 358 , // 0
|
||||
ih_359 = 359 , // 0
|
||||
ih_360 = 360 , // 0
|
||||
ih_361 = 361 , // 0
|
||||
ih_362 = 362 , // 0
|
||||
ih_363 = 363 , // 0
|
||||
ih_364 = 364 , // 0
|
||||
ih_365 = 365 , // 0
|
||||
ih_366 = 366 , // 0
|
||||
ih_367 = 367 , // 0
|
||||
ih_368 = 368 , // 0
|
||||
ih_369 = 369 , // 0
|
||||
ih_370 = 370 , // 0
|
||||
ih_371 = 371 , // 0
|
||||
ih_372 = 372 , // 0
|
||||
ih_373 = 373 , // 0
|
||||
ih_374 = 374 , // 0
|
||||
ih_375 = 375 , // 0
|
||||
ih_376 = 376 , // 0
|
||||
ih_377 = 377 , // 0
|
||||
ih_378 = 378 , // 0
|
||||
ih_379 = 379 , // 0
|
||||
ih_380 = 380 , // 0
|
||||
ih_381 = 381 , // 0
|
||||
ih_382 = 382 , // 0
|
||||
ih_383 = 383 , // 0
|
||||
ih_384 = 384 , // 0
|
||||
ih_385 = 385 , // 0
|
||||
ih_386 = 386 , // 0
|
||||
ih_387 = 387 , // 0
|
||||
ih_388 = 388 , // 0
|
||||
ih_389 = 389 , // 0
|
||||
ih_390 = 390 , // 0
|
||||
ih_391 = 391 , // 0
|
||||
ih_392 = 392 , // 0
|
||||
ih_393 = 393 , // 0
|
||||
ih_394 = 394 , // 0
|
||||
ih_395 = 395 , // 0
|
||||
ih_396 = 396 , // 0
|
||||
ih_397 = 397 , // 0
|
||||
ih_398 = 398 , // 0
|
||||
ih_399 = 399 , // 0
|
||||
ih_400 = 400 , // 0
|
||||
ih_401 = 401 , // 0
|
||||
ih_402 = 402 , // 0
|
||||
ih_403 = 403 , // 0
|
||||
ih_404 = 404 , // 0
|
||||
ih_405 = 405 , // 0
|
||||
ih_406 = 406 , // 0
|
||||
ih_407 = 407 , // 0
|
||||
ih_408 = 408 , // 0
|
||||
ih_409 = 409 , // 0
|
||||
ISECND = 410 , // 0 ISECND = current simulation time HH:MM:SS - number of seconds (SS), reported in microseconds (0-59,999,999)
|
||||
// ---------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
INTEHEAD_NUMBER_OF_ITEMS // MUST be last element of enum.
|
||||
};
|
||||
@@ -677,6 +676,14 @@ ngroups(const Group& gr)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Opm::RestartIO::InteHEAD&
|
||||
Opm::RestartIO::InteHEAD::
|
||||
udqParam_1(const UdqParam& udq_par)
|
||||
{
|
||||
this -> data_[UDQPAR_1] = - udq_par.udqParam_1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Free functions (calendar/time utilities)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <opm/output/eclipse/AggregateWellData.hpp>
|
||||
#include <opm/output/eclipse/AggregateConnectionData.hpp>
|
||||
#include <opm/output/eclipse/AggregateMSWData.hpp>
|
||||
#include <opm/output/eclipse/AggregateUDQData.hpp>
|
||||
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
|
||||
|
||||
#include <opm/io/eclipse/OutputStream.hpp>
|
||||
@@ -259,6 +260,28 @@ namespace {
|
||||
rstFile.write("RSEG", MSWData.getRSeg());
|
||||
}
|
||||
|
||||
void writeUDQ(int sim_step,
|
||||
const Schedule& schedule,
|
||||
const std::vector<int>& ih,
|
||||
EclIO::OutputStream::Restart& rstFile)
|
||||
{
|
||||
return;
|
||||
//need to add test if UDQ-data exist and UDQ - active exist etc.
|
||||
// do not write unless data exists and copy E100 logic.
|
||||
|
||||
// write UDQ - data to restart file
|
||||
const std::size_t simStep = static_cast<size_t> (sim_step);
|
||||
|
||||
const auto udqDims = Helpers::createUdqDims(schedule, simStep, ih);
|
||||
auto udqData = Helpers::AggregateUDQData(udqDims);
|
||||
udqData.captureDeclaredUDQData(schedule, simStep, ih);
|
||||
|
||||
rstFile.write("IUDQ", udqData.getIUDQ());
|
||||
rstFile.write("IUAD", udqData.getIUAD());
|
||||
rstFile.write("ZUDN", udqData.getZUDN());
|
||||
rstFile.write("ZUDL", udqData.getZUDL());
|
||||
}
|
||||
|
||||
void writeWell(int sim_step,
|
||||
const bool ecl_compatible_rst,
|
||||
const Phases& phases,
|
||||
@@ -368,8 +391,11 @@ namespace {
|
||||
}
|
||||
|
||||
void writeSolution(const RestartValue& value,
|
||||
const Schedule& schedule,
|
||||
int report_step,
|
||||
const bool ecl_compatible_rst,
|
||||
const bool write_double_arg,
|
||||
const std::vector<int>& inteHD,
|
||||
EclIO::OutputStream::Restart& rstFile)
|
||||
{
|
||||
rstFile.message("STARTSOL");
|
||||
@@ -396,6 +422,8 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
writeUDQ(report_step, schedule, inteHD, rstFile);
|
||||
|
||||
for (const auto& elm : value.extra) {
|
||||
const std::string& key = elm.first.key;
|
||||
if (extraInSolution(key)) {
|
||||
@@ -489,8 +517,8 @@ void save(EclIO::OutputStream::Restart& rstFile,
|
||||
value.wells, sumState, inteHD, rstFile);
|
||||
}
|
||||
}
|
||||
|
||||
writeSolution(value, ecl_compatible_rst, write_double, rstFile);
|
||||
|
||||
writeSolution(value, schedule, sim_step, ecl_compatible_rst, write_double, inteHD, rstFile);
|
||||
|
||||
if (! ecl_compatible_rst) {
|
||||
writeExtraData(value.extra, rstFile);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
@@ -1168,7 +1168,7 @@ bool is_udq(const std::string& keyword) {
|
||||
|
||||
void eval_udq(const Schedule& schedule, std::size_t sim_step, SummaryState& st)
|
||||
{
|
||||
const UDQInput& udq = schedule.getUDQConfig(sim_step);
|
||||
const UDQConfig& udq = schedule.getUDQConfig(sim_step);
|
||||
const auto& func_table = udq.function_table();
|
||||
UDQContext context(udq.params(), func_table, st);
|
||||
std::vector<std::string> wells;
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
|
||||
@@ -117,7 +118,8 @@ namespace {
|
||||
m_runspec( runspec ),
|
||||
wtest_config(this->m_timeMap, std::make_shared<WellTestConfig>() ),
|
||||
wlist_manager( this->m_timeMap, std::make_shared<WListManager>()),
|
||||
udq_config(this->m_timeMap, std::make_shared<UDQInput>(deck)),
|
||||
udq_config(this->m_timeMap, std::make_shared<UDQConfig>(deck)),
|
||||
udq_active(this->m_timeMap, std::make_shared<UDQActive>()),
|
||||
global_whistctl_mode(this->m_timeMap, WellProducer::CMODE_UNDEFINED),
|
||||
rft_config(this->m_timeMap)
|
||||
{
|
||||
@@ -772,12 +774,11 @@ namespace {
|
||||
bool switching_from_injector = !well2->isProducer();
|
||||
auto properties = std::make_shared<WellProductionProperties>(well2->getProductionProperties());
|
||||
bool update_well = switching_from_injector;
|
||||
|
||||
properties->clearControls();
|
||||
if (well2->isAvailableForGroupControl())
|
||||
properties->addProductionControl(WellProducer::GRUP);
|
||||
|
||||
properties->handleWCONPROD(record);
|
||||
properties->handleWCONPROD(well_name, record);
|
||||
|
||||
if (switching_from_injector)
|
||||
properties->resetDefaultBHPLimit();
|
||||
@@ -796,6 +797,10 @@ namespace {
|
||||
this->addWellEvent( well2->name(), ScheduleEvents::PRODUCTION_UPDATE, currentStep);
|
||||
this->updateWell(well2, currentStep);
|
||||
}
|
||||
|
||||
auto udq = std::make_shared<UDQActive>(this->udqActive(currentStep));
|
||||
if (properties->updateUDQActive(this->getUDQConfig(currentStep), *udq))
|
||||
this->updateUDQActive(currentStep, udq);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -900,6 +905,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto udq = std::make_shared<UDQActive>(this->udqActive(currentStep));
|
||||
if (injection->updateUDQActive(this->getUDQConfig(currentStep), *udq))
|
||||
this->updateUDQActive(currentStep, udq);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1126,7 +1135,7 @@ namespace {
|
||||
|
||||
void Schedule::handleUDQ(const DeckKeyword& keyword, size_t currentStep) {
|
||||
const auto& current = *this->udq_config.get(currentStep);
|
||||
std::shared_ptr<UDQInput> new_udq = std::make_shared<UDQInput>(current);
|
||||
std::shared_ptr<UDQConfig> new_udq = std::make_shared<UDQConfig>(current);
|
||||
for (const auto& record : keyword)
|
||||
new_udq->add_record(record);
|
||||
|
||||
@@ -1478,7 +1487,6 @@ namespace {
|
||||
auto water_target = record.getItem("WATER_TARGET").get<UDAValue>(0);
|
||||
auto liquid_target = record.getItem("LIQUID_TARGET").get<UDAValue>(0);
|
||||
auto resv_target = record.getItem("RESERVOIR_FLUID_TARGET").getSIDouble(0);
|
||||
|
||||
{
|
||||
auto group_ptr = std::make_shared<Group2>(this->getGroup2(group_name, currentStep));
|
||||
Group2::GroupProductionProperties production;
|
||||
@@ -2444,6 +2452,13 @@ void Schedule::handleGRUPTREE( const DeckKeyword& keyword, size_t currentStep, c
|
||||
return tables;
|
||||
}
|
||||
|
||||
const UDQActive& Schedule::udqActive(size_t timeStep) const {
|
||||
return *this->udq_active[timeStep];
|
||||
}
|
||||
|
||||
void Schedule::updateUDQActive( size_t timeStep, std::shared_ptr<UDQActive> udq ) {
|
||||
this->udq_active.update(timeStep, udq);
|
||||
}
|
||||
|
||||
const WellTestConfig& Schedule::wtestConfig(size_t timeStep) const {
|
||||
const auto& ptr = this->wtest_config.get(timeStep);
|
||||
@@ -2455,7 +2470,7 @@ void Schedule::handleGRUPTREE( const DeckKeyword& keyword, size_t currentStep, c
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
const UDQInput& Schedule::getUDQConfig(size_t timeStep) const {
|
||||
const UDQConfig& Schedule::getUDQConfig(size_t timeStep) const {
|
||||
const auto& ptr = this->udq_config.get(timeStep);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
178
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.cpp
Normal file
178
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
std::size_t UDQActive::IUAD_size() const {
|
||||
const auto& output = this->get_iuad();
|
||||
return output.size();
|
||||
}
|
||||
|
||||
std::size_t UDQActive::IUAP_size() const {
|
||||
const auto& output = this->get_iuap();
|
||||
return output.size();
|
||||
}
|
||||
|
||||
UDQActive::operator bool() const {
|
||||
return this->input_data.size() > 0;
|
||||
}
|
||||
|
||||
std::string UDQActive::udq_hash(const std::string& udq, UDAControl control) {
|
||||
return udq + std::to_string(static_cast<int64_t>(control));
|
||||
}
|
||||
|
||||
std::string UDQActive::wg_hash(const std::string& wgname, UDAControl control) {
|
||||
return wgname + std::to_string(static_cast<int64_t>(control));
|
||||
}
|
||||
|
||||
/*
|
||||
We go through the current list of input records and compare with the supplied
|
||||
arguments (uda, wgnamem, control). There are six possible outcomes:
|
||||
|
||||
1. The uda variable is a double and no uda usage has been registered so far:
|
||||
fast return.
|
||||
|
||||
2. The uda variable is a double, and the (wgname,control) combination is
|
||||
found in the input data; this implies that uda has been used previously
|
||||
for this particular (wgname, control) combination: We remove that record
|
||||
from the input_data.
|
||||
|
||||
3. The uda variable is a string and we find that particular (udq, wgname,
|
||||
control) combination in the input data: No changes
|
||||
|
||||
4. The uda variable is a string; but another udq was used for this (wgname,
|
||||
control) combination: We erase the previous entry and add a new entry.
|
||||
|
||||
5. The uda ariable is a string and we do not find this (wgname, control)
|
||||
combination in the previous records: We add a new record.
|
||||
|
||||
6. The uda variable is a double, and the (wgname, control) combination has
|
||||
not been encountered before: return 0
|
||||
|
||||
*/
|
||||
int UDQActive::update(const UDQConfig& udq_config, const UDAValue& uda, const std::string& wgname, UDAControl control) {
|
||||
// Alternative 1
|
||||
if (uda.is<double>() && this->input_data.empty())
|
||||
return 0;
|
||||
|
||||
for (auto iter = this->input_data.begin(); iter != this->input_data.end(); ++iter) {
|
||||
auto& record = *iter;
|
||||
if ((record.wgname == wgname) && (record.control == control)) {
|
||||
if (uda.is<double>()) {
|
||||
// Alternative 2
|
||||
iter = this->input_data.erase(iter);
|
||||
this->output_data.clear();
|
||||
return 1;
|
||||
} else {
|
||||
const std::string& udq = uda.get<std::string>();
|
||||
if (record.udq == udq)
|
||||
// Alternative 3
|
||||
return 0;
|
||||
else {
|
||||
// Alternative 4
|
||||
iter = this->input_data.erase(iter);
|
||||
this->output_data.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative 4 & 5
|
||||
if (uda.is<std::string>()) {
|
||||
const std::string& udq = uda.get<std::string>();
|
||||
const auto& udq_input = udq_config[udq];
|
||||
auto udq_index = udq_input.index.insert_index;
|
||||
this->input_data.emplace_back( udq_index, udq, wgname, control );
|
||||
this->output_data.clear();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Alternative 6
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<UDQActive::Record>& UDQActive::get_iuad() const {
|
||||
if (this->output_data.empty()) {
|
||||
for (const auto& input_record : this->input_data) {
|
||||
const auto& udq = input_record.udq;
|
||||
const auto& control = input_record.control;
|
||||
bool found = false;
|
||||
for (auto& output_record : this->output_data) {
|
||||
if ((output_record.udq == udq) && (output_record.control == control)) {
|
||||
output_record.use_count += 1;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
this->output_data.emplace_back(input_record.udq, input_record.input_index, 0, input_record.wgname, input_record.control);
|
||||
}
|
||||
|
||||
if (!output_data.empty()) {
|
||||
for (std::size_t index = 1; index < output_data.size(); index++) {
|
||||
const auto& prev_record = this->output_data[index - 1];
|
||||
this->output_data[index].use_index = prev_record.use_index + prev_record.use_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this->output_data;
|
||||
}
|
||||
|
||||
std::vector<UDQActive::InputRecord> UDQActive::get_iuap() const {
|
||||
std::vector<UDQActive::InputRecord> iuap_data;
|
||||
auto input_rcpy = this->input_data;
|
||||
while (!input_rcpy.empty()) {
|
||||
//store next active control (new control)
|
||||
auto inp_rec = input_rcpy.begin();
|
||||
auto cur_rec = *inp_rec;
|
||||
iuap_data.push_back(*inp_rec);
|
||||
auto it = input_rcpy.erase(input_rcpy.begin());
|
||||
//find and store active controls with same control and udq
|
||||
//auto it = input_rcpy.begin();
|
||||
while (it != input_rcpy.end()) {
|
||||
if ((it->control == cur_rec.control) && (it->udq == cur_rec.udq)) {
|
||||
iuap_data.push_back(*it);
|
||||
it = input_rcpy.erase(it);
|
||||
}
|
||||
else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return iuap_data;
|
||||
}
|
||||
|
||||
UDQActive::Record UDQActive::operator[](std::size_t index) const {
|
||||
const auto& output_record = this->get_iuad()[index];
|
||||
return output_record;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
260
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp
Normal file
260
src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
Copyright 2018 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 <algorithm>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace {
|
||||
std::string strip_quotes(const std::string& s) {
|
||||
if (s[0] == '\'')
|
||||
return s.substr(1, s.size() - 2);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UDQConfig::UDQConfig(const UDQParams& params) :
|
||||
udq_params(params),
|
||||
udqft(this->udq_params)
|
||||
{}
|
||||
|
||||
|
||||
UDQConfig::UDQConfig(const Deck& deck) :
|
||||
udq_params(deck),
|
||||
udqft(this->udq_params)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
const UDQParams& UDQConfig::params() const {
|
||||
return this->udq_params;
|
||||
}
|
||||
|
||||
void UDQConfig::add_node( const std::string& quantity, UDQAction action) {
|
||||
auto index_iter = this->input_index.find(quantity);
|
||||
if (this->input_index.find(quantity) == this->input_index.end()) {
|
||||
auto var_type = UDQ::varType(quantity);
|
||||
auto insert_index = this->input_index.size();
|
||||
this->type_count[var_type] += 1;
|
||||
this->input_index[quantity] = UDQIndex(insert_index, this->type_count[var_type], action);
|
||||
} else
|
||||
index_iter->second.action = action;
|
||||
}
|
||||
|
||||
void UDQConfig::add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value) {
|
||||
this->add_node(quantity, UDQAction::ASSIGN);
|
||||
auto assignment = this->m_assignments.find(quantity);
|
||||
if (assignment == this->m_assignments.end())
|
||||
this->m_assignments.insert( std::make_pair(quantity, UDQAssign(quantity, selector, value )));
|
||||
else
|
||||
assignment->second.add_record(selector, value);
|
||||
}
|
||||
|
||||
|
||||
void UDQConfig::add_define(const std::string& quantity, const std::vector<std::string>& expression) {
|
||||
this->add_node(quantity, UDQAction::DEFINE);
|
||||
auto defined_iter = this->m_definitions.find( quantity );
|
||||
if (defined_iter != this->m_definitions.end())
|
||||
this->m_definitions.erase( defined_iter );
|
||||
|
||||
this->m_definitions.insert( std::make_pair(quantity, UDQDefine(this->udq_params, quantity, expression)));
|
||||
}
|
||||
|
||||
|
||||
void UDQConfig::add_unit(const std::string& keyword, const std::string& quoted_unit) {
|
||||
const std::string unit = strip_quotes(quoted_unit);
|
||||
const auto pair_ptr = this->units.find(keyword);
|
||||
if (pair_ptr != this->units.end()) {
|
||||
if (pair_ptr->second != unit)
|
||||
throw std::invalid_argument("Illegal to change unit of UDQ keyword runtime");
|
||||
|
||||
return;
|
||||
}
|
||||
this->units[keyword] = unit;
|
||||
}
|
||||
|
||||
|
||||
void UDQConfig::add_record(const DeckRecord& record) {
|
||||
auto action = UDQ::actionType(record.getItem("ACTION").get<std::string>(0));
|
||||
const auto& quantity = record.getItem("QUANTITY").get<std::string>(0);
|
||||
const auto& data = record.getItem("DATA").getData<std::string>();
|
||||
|
||||
if (action == UDQAction::UPDATE)
|
||||
throw std::invalid_argument("The UDQ action UPDATE is not yet implemented in opm/flow");
|
||||
|
||||
if (action == UDQAction::UNITS)
|
||||
this->add_unit( quantity, data[0] );
|
||||
else {
|
||||
if (action == UDQAction::ASSIGN) {
|
||||
std::vector<std::string> selector(data.begin(), data.end() - 1);
|
||||
double value = std::stod(data.back());
|
||||
this->add_assign(quantity, selector, value);
|
||||
} else if (action == UDQAction::DEFINE)
|
||||
this->add_define(quantity, data);
|
||||
else
|
||||
throw std::runtime_error("Internal error - should not be here");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQDefine> UDQConfig::definitions() const {
|
||||
std::vector<UDQDefine> ret;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.action == UDQAction::DEFINE) {
|
||||
const std::string& key = index_pair.first;
|
||||
ret.push_back(this->m_definitions.at(key));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQDefine> UDQConfig::definitions(UDQVarType var_type) const {
|
||||
std::vector<UDQDefine> filtered_defines;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.action == UDQAction::DEFINE) {
|
||||
const std::string& key = index_pair.first;
|
||||
const auto& udq_define = this->m_definitions.at(key);
|
||||
if (udq_define.var_type() == var_type)
|
||||
filtered_defines.push_back(udq_define);
|
||||
}
|
||||
}
|
||||
return filtered_defines;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQInput> UDQConfig::input() const {
|
||||
std::vector<UDQInput> res;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
const UDQIndex& index = index_pair.second;
|
||||
std::string u;
|
||||
if (this->has_unit(index_pair.first))
|
||||
u = this->unit(index_pair.first);
|
||||
|
||||
if (index.action == UDQAction::DEFINE) {
|
||||
const std::string& key = index_pair.first;
|
||||
res.push_back(UDQInput(index, this->m_definitions.at(key), u));
|
||||
} else if (index_pair.second.action == UDQAction::ASSIGN) {
|
||||
const std::string& key = index_pair.first;
|
||||
res.push_back(UDQInput(index, this->m_assignments.at(key), u));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::size_t UDQConfig::size() const {
|
||||
std::size_t s = 0;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.action == UDQAction::DEFINE)
|
||||
s += 1;
|
||||
else if (index_pair.second.action == UDQAction::ASSIGN)
|
||||
s += 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQAssign> UDQConfig::assignments() const {
|
||||
std::vector<UDQAssign> ret;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.action == UDQAction::ASSIGN) {
|
||||
const std::string& key = index_pair.first;
|
||||
ret.push_back(this->m_assignments.at(key));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQAssign> UDQConfig::assignments(UDQVarType var_type) const {
|
||||
std::vector<UDQAssign> filtered_defines;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.action == UDQAction::ASSIGN) {
|
||||
const std::string& key = index_pair.first;
|
||||
const auto& udq_define = this->m_assignments.at(key);
|
||||
if (udq_define.var_type() == var_type)
|
||||
filtered_defines.push_back(udq_define);
|
||||
}
|
||||
}
|
||||
return filtered_defines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string& UDQConfig::unit(const std::string& key) const {
|
||||
const auto pair_ptr = this->units.find(key);
|
||||
if (pair_ptr == this->units.end())
|
||||
throw std::invalid_argument("No such UDQ quantity: " + key);
|
||||
|
||||
return pair_ptr->second;
|
||||
}
|
||||
|
||||
bool UDQConfig::has_unit(const std::string& keyword) const {
|
||||
return (this->units.count(keyword) > 0);
|
||||
}
|
||||
|
||||
|
||||
bool UDQConfig::has_keyword(const std::string& keyword) const {
|
||||
if (this->m_assignments.count(keyword) > 0)
|
||||
return true;
|
||||
|
||||
if (this->m_definitions.count(keyword) > 0)
|
||||
return true;
|
||||
|
||||
/*
|
||||
That a keyword is mentioned with UNITS is enough to consider it
|
||||
as a keyword which is present.
|
||||
*/
|
||||
if (this->units.count(keyword) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const UDQInput UDQConfig::operator[](const std::string& keyword) const {
|
||||
const auto index_iter = this->input_index.find(keyword);
|
||||
if (index_iter == this->input_index.end())
|
||||
throw std::invalid_argument("Keyword: " + keyword + " not recognized as ASSIGN/DEFINE UDQ");
|
||||
|
||||
std::string u;
|
||||
if (this->has_unit(keyword))
|
||||
u = this->unit(keyword);
|
||||
|
||||
if (index_iter->second.action == UDQAction::ASSIGN)
|
||||
return UDQInput(this->input_index.at(keyword), this->m_assignments.at(keyword), u);
|
||||
|
||||
if (index_iter->second.action == UDQAction::DEFINE)
|
||||
return UDQInput(this->input_index.at(keyword), this->m_definitions.at(keyword), u);
|
||||
|
||||
throw std::logic_error("Internal error - should not be here");
|
||||
}
|
||||
|
||||
|
||||
const UDQFunctionTable& UDQConfig::function_table() const {
|
||||
return this->udqft;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -268,6 +268,53 @@ std::string typeName(UDQVarType var_type) {
|
||||
}
|
||||
}
|
||||
|
||||
UDAKeyword keyword(UDAControl control) {
|
||||
const std::map<UDAControl, UDAKeyword> c2k = {{UDAControl::WCONPROD_ORAT, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONPROD_GRAT, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONPROD_WRAT, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONPROD_LRAT, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONPROD_RESV, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONPROD_BHP, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONPROD_THP, UDAKeyword::WCONPROD},
|
||||
{UDAControl::WCONINJE_RATE, UDAKeyword::WCONINJE},
|
||||
{UDAControl::WCONINJE_RESV, UDAKeyword::WCONINJE},
|
||||
{UDAControl::WCONINJE_BHP, UDAKeyword::WCONINJE},
|
||||
{UDAControl::WCONINJE_THP, UDAKeyword::WCONINJE},
|
||||
{UDAControl::GCONPROD_OIL_TARGET, UDAKeyword::GCONPROD},
|
||||
{UDAControl::GCONPROD_WATER_TARGET, UDAKeyword::GCONPROD},
|
||||
{UDAControl::GCONPROD_GAS_TARGET, UDAKeyword::GCONPROD},
|
||||
{UDAControl::GCONPROD_LIQUID_TARGET, UDAKeyword::GCONPROD}};
|
||||
|
||||
auto it = c2k.find(control);
|
||||
if (it != c2k.end())
|
||||
return it->second;
|
||||
|
||||
throw std::logic_error("Unrecognized enum type - internal error");
|
||||
}
|
||||
|
||||
|
||||
int uadCode(UDAControl control) {
|
||||
const std::map<UDAControl, int> c2uad = {{UDAControl::WCONPROD_ORAT, 300004},
|
||||
{UDAControl::WCONPROD_GRAT, 500004},
|
||||
{UDAControl::WCONPROD_WRAT, 400004},
|
||||
{UDAControl::WCONPROD_LRAT, 600004},
|
||||
{UDAControl::WCONPROD_RESV, 999999},
|
||||
{UDAControl::WCONPROD_BHP, 999999},
|
||||
{UDAControl::WCONPROD_THP, 999999},
|
||||
{UDAControl::WCONINJE_RATE, 400003},
|
||||
{UDAControl::WCONINJE_RESV, 500003},
|
||||
{UDAControl::WCONINJE_BHP, 999999},
|
||||
{UDAControl::WCONINJE_THP, 999999},
|
||||
{UDAControl::GCONPROD_OIL_TARGET, 200019},
|
||||
{UDAControl::GCONPROD_WATER_TARGET, 300019},
|
||||
{UDAControl::GCONPROD_GAS_TARGET, 400019},
|
||||
{UDAControl::GCONPROD_LIQUID_TARGET, 500019}};
|
||||
|
||||
auto it = c2uad.find(control);
|
||||
if (it != c2uad.end())
|
||||
return it->second;
|
||||
|
||||
throw std::logic_error("Unrecognized enum type - internal error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
Copyright 2019 Equinor ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
@@ -15,180 +15,78 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace {
|
||||
std::string strip_quotes(const std::string& s) {
|
||||
if (s[0] == '\'')
|
||||
return s.substr(1, s.size() - 2);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UDQInput::UDQInput(const Deck& deck) :
|
||||
udq_params(deck),
|
||||
udqft(this->udq_params)
|
||||
{
|
||||
}
|
||||
|
||||
const UDQParams& UDQInput::params() const {
|
||||
return this->udq_params;
|
||||
}
|
||||
|
||||
void UDQInput::add_record(const DeckRecord& record) {
|
||||
auto action = UDQ::actionType(record.getItem("ACTION").get<std::string>(0));
|
||||
const auto& quantity = record.getItem("QUANTITY").get<std::string>(0);
|
||||
const auto& data = record.getItem("DATA").getData<std::string>();
|
||||
|
||||
if (action == UDQAction::UPDATE)
|
||||
throw std::invalid_argument("The UDQ action UPDATE is not yet implemented in opm/flow");
|
||||
|
||||
if (action == UDQAction::UNITS)
|
||||
this->assign_unit( quantity, data[0] );
|
||||
else {
|
||||
auto index_iter = this->input_index.find(quantity);
|
||||
if (this->input_index.find(quantity) == this->input_index.end())
|
||||
this->input_index[quantity] = std::make_pair(this->input_index.size(), action);
|
||||
else
|
||||
index_iter->second.second = action;
|
||||
UDQInput::UDQInput(const UDQIndex& index_arg, const UDQDefine& udq_define, const std::string& unit_arg) :
|
||||
index(index_arg),
|
||||
define(std::addressof(udq_define)),
|
||||
assign(nullptr),
|
||||
m_keyword(udq_define.keyword()),
|
||||
m_var_type(udq_define.var_type()),
|
||||
m_unit(unit_arg)
|
||||
{}
|
||||
|
||||
|
||||
if (action == UDQAction::ASSIGN) {
|
||||
std::vector<std::string> selector(data.begin(), data.end() - 1);
|
||||
double value = std::stod(data.back());
|
||||
auto assignment = this->m_assignments.find(quantity);
|
||||
if (assignment == this->m_assignments.end())
|
||||
this->m_assignments.insert( std::make_pair(quantity, UDQAssign(quantity, selector, value )));
|
||||
else
|
||||
assignment->second.add_record(selector, value);
|
||||
} else if (action == UDQAction::DEFINE)
|
||||
this->m_definitions.insert( std::make_pair(quantity, UDQDefine(this->udq_params, quantity, data)));
|
||||
else
|
||||
throw std::runtime_error("Internal error - should not be here");
|
||||
}
|
||||
}
|
||||
UDQInput::UDQInput(const UDQIndex& index_arg, const UDQAssign& udq_assign, const std::string& unit_arg):
|
||||
index(index_arg),
|
||||
define(nullptr),
|
||||
assign(std::addressof(udq_assign)),
|
||||
m_keyword(udq_assign.keyword()),
|
||||
m_var_type(udq_assign.var_type()),
|
||||
m_unit(unit_arg)
|
||||
{}
|
||||
|
||||
|
||||
std::vector<UDQDefine> UDQInput::definitions() const {
|
||||
std::vector<UDQDefine> ret;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.second == UDQAction::DEFINE) {
|
||||
const std::string& key = index_pair.first;
|
||||
ret.push_back(this->m_definitions.at(key));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQDefine> UDQInput::definitions(UDQVarType var_type) const {
|
||||
std::vector<UDQDefine> filtered_defines;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.second == UDQAction::DEFINE) {
|
||||
const std::string& key = index_pair.first;
|
||||
const auto& udq_define = this->m_definitions.at(key);
|
||||
if (udq_define.var_type() == var_type)
|
||||
filtered_defines.push_back(udq_define);
|
||||
}
|
||||
}
|
||||
return filtered_defines;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::pair<size_t, UDQDefine>> UDQInput::input_definitions() const {
|
||||
std::vector<std::pair<size_t, UDQDefine>> res;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.second == UDQAction::DEFINE) {
|
||||
const std::string& key = index_pair.first;
|
||||
res.emplace_back(index_pair.second.first, this->m_definitions.at(key));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQAssign> UDQInput::assignments() const {
|
||||
std::vector<UDQAssign> ret;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.second == UDQAction::ASSIGN) {
|
||||
const std::string& key = index_pair.first;
|
||||
ret.push_back(this->m_assignments.at(key));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::vector<UDQAssign> UDQInput::assignments(UDQVarType var_type) const {
|
||||
std::vector<UDQAssign> filtered_defines;
|
||||
for (const auto& index_pair : this->input_index) {
|
||||
if (index_pair.second.second == UDQAction::ASSIGN) {
|
||||
const std::string& key = index_pair.first;
|
||||
const auto& udq_define = this->m_assignments.at(key);
|
||||
if (udq_define.var_type() == var_type)
|
||||
filtered_defines.push_back(udq_define);
|
||||
}
|
||||
}
|
||||
return filtered_defines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string& UDQInput::unit(const std::string& key) const {
|
||||
const auto pair_ptr = this->units.find(key);
|
||||
if (pair_ptr == this->units.end())
|
||||
throw std::invalid_argument("No such UDQ quantity: " + key);
|
||||
|
||||
return pair_ptr->second;
|
||||
}
|
||||
|
||||
|
||||
void UDQInput::assign_unit(const std::string& keyword, const std::string& quoted_unit) {
|
||||
const std::string unit = strip_quotes(quoted_unit);
|
||||
const auto pair_ptr = this->units.find(keyword);
|
||||
if (pair_ptr != this->units.end()) {
|
||||
if (pair_ptr->second != unit)
|
||||
throw std::invalid_argument("Illegal to change unit of UDQ keyword runtime");
|
||||
|
||||
return;
|
||||
}
|
||||
this->units[keyword] = unit;
|
||||
}
|
||||
|
||||
bool UDQInput::has_unit(const std::string& keyword) const {
|
||||
return (this->units.count(keyword) > 0);
|
||||
}
|
||||
|
||||
|
||||
bool UDQInput::has_keyword(const std::string& keyword) const {
|
||||
if (this->m_assignments.count(keyword) > 0)
|
||||
return true;
|
||||
|
||||
if (this->m_definitions.count(keyword) > 0)
|
||||
return true;
|
||||
|
||||
/*
|
||||
That a keyword is mentioned with UNITS is enough to consider it
|
||||
as a keyword which is present.
|
||||
*/
|
||||
if (this->units.count(keyword) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const UDQFunctionTable& UDQInput::function_table() const {
|
||||
return this->udqft;
|
||||
}
|
||||
const std::string& UDQInput::unit() const {
|
||||
return this->m_unit;
|
||||
}
|
||||
|
||||
const std::string& UDQInput::keyword() const {
|
||||
return this->m_keyword;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool UDQInput::is<UDQAssign>() const {
|
||||
if (this->assign)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool UDQInput::is<UDQDefine>() const {
|
||||
if (this->define)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<>
|
||||
const UDQAssign& UDQInput::get<UDQAssign>() const {
|
||||
if (this->assign)
|
||||
return *this->assign;
|
||||
|
||||
throw std::runtime_error("Invalid get");
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const UDQDefine& UDQInput::get<UDQDefine>() const {
|
||||
if (this->define)
|
||||
return *this->define;
|
||||
|
||||
throw std::runtime_error("Invalid get");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,6 +88,9 @@ namespace Opm {
|
||||
this->m_true_rng.seed( seed );
|
||||
}
|
||||
|
||||
int UDQParams::rand_seed() const noexcept {
|
||||
return this->random_seed;
|
||||
}
|
||||
|
||||
double UDQParams::range() const noexcept {
|
||||
return this->value_range;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
|
||||
@@ -780,6 +781,4 @@ double Well2::temperature() const {
|
||||
throw std::runtime_error("Can not ask for temperature in a producer");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
|
||||
|
||||
#include "injection.hpp"
|
||||
@@ -261,4 +262,16 @@ namespace Opm {
|
||||
|
||||
return controls;
|
||||
}
|
||||
|
||||
bool WellInjectionProperties::updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const {
|
||||
int update_count = 0;
|
||||
|
||||
update_count += active.update(udq_config, this->surfaceInjectionRate, this->name, UDAControl::WCONINJE_RATE);
|
||||
update_count += active.update(udq_config, this->reservoirInjectionRate, this->name, UDAControl::WCONINJE_RESV);
|
||||
update_count += active.update(udq_config, this->BHPLimit, this->name, UDAControl::WCONINJE_BHP);
|
||||
update_count += active.update(udq_config, this->THPLimit, this->name, UDAControl::WCONINJE_THP);
|
||||
|
||||
return (update_count > 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
@@ -102,7 +103,7 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void WellProductionProperties::handleWCONPROD( const DeckRecord& record )
|
||||
void WellProductionProperties::handleWCONPROD( const std::string& /* well */, const DeckRecord& record)
|
||||
{
|
||||
this->predictionMode = true;
|
||||
|
||||
@@ -297,5 +298,19 @@ namespace Opm {
|
||||
return controls;
|
||||
}
|
||||
|
||||
bool WellProductionProperties::updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const {
|
||||
int update_count = 0;
|
||||
|
||||
update_count += active.update(udq_config, this->OilRate, this->name, UDAControl::WCONPROD_ORAT);
|
||||
update_count += active.update(udq_config, this->WaterRate, this->name, UDAControl::WCONPROD_WRAT);
|
||||
update_count += active.update(udq_config, this->GasRate, this->name, UDAControl::WCONPROD_GRAT);
|
||||
update_count += active.update(udq_config, this->LiquidRate, this->name, UDAControl::WCONPROD_LRAT);
|
||||
update_count += active.update(udq_config, this->ResVRate, this->name, UDAControl::WCONPROD_RESV);
|
||||
update_count += active.update(udq_config, this->BHPLimit, this->name, UDAControl::WCONPROD_BHP);
|
||||
update_count += active.update(udq_config, this->THPLimit, this->name, UDAControl::WCONPROD_THP);
|
||||
|
||||
return (update_count > 0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
||||
|
||||
383
tests/UDQ_TEST_WCONPROD_IUAD-2.DATA
Normal file
383
tests/UDQ_TEST_WCONPROD_IUAD-2.DATA
Normal file
@@ -0,0 +1,383 @@
|
||||
RUNSPEC
|
||||
|
||||
TITLE
|
||||
2 PRODUCERS AND INJECTORS, 2 WELL GROUPS AND ONE INTERMEDIATE GROUP LEVEL BELOW THE FIELD LEVEL
|
||||
|
||||
DIMENS
|
||||
10 5 10 /
|
||||
|
||||
|
||||
OIL
|
||||
|
||||
WATER
|
||||
|
||||
GAS
|
||||
|
||||
DISGAS
|
||||
|
||||
FIELD
|
||||
|
||||
TABDIMS
|
||||
1 1 15 15 2 15 /
|
||||
|
||||
EQLDIMS
|
||||
2 /
|
||||
|
||||
WELLDIMS
|
||||
4 20 4 2 /
|
||||
|
||||
UNIFIN
|
||||
UNIFOUT
|
||||
|
||||
FMTIN
|
||||
FMTOUT
|
||||
-- Dimensions for used defined quantity facility
|
||||
-- max functions permitted in a quantity definition
|
||||
-- max arguments permitted in a quantity definition
|
||||
-- max user defined connection quantities
|
||||
-- max user defined field quantities
|
||||
-- max user defined group quantities
|
||||
-- max user defined region quantities
|
||||
-- max user defined segment quantities
|
||||
-- max user defined well quantities
|
||||
-- max user defined aquifer quantities
|
||||
-- max user defined block quantities
|
||||
-- whether new randon number generator seed computed for restart runs
|
||||
UDQDIMS
|
||||
50 25 0 50 50 0 0 50 0 20 /
|
||||
|
||||
-- Dimensions for the user defined arguments facility
|
||||
-- number of keyword arguments in which UDQs replace numerical values
|
||||
-- ratained for back-compatibility
|
||||
-- total number of unique instances in which a UDQ is used in a keyword argument
|
||||
UDADIMS
|
||||
10 1* 10 /
|
||||
|
||||
START
|
||||
1 'JAN' 2015 /
|
||||
|
||||
-- RPTRUNSP
|
||||
|
||||
GRID =========================================================
|
||||
|
||||
--NOGGF
|
||||
BOX
|
||||
1 10 1 5 1 1 /
|
||||
|
||||
TOPS
|
||||
50*7000 /
|
||||
|
||||
BOX
|
||||
1 10 1 5 1 10 /
|
||||
|
||||
DXV
|
||||
10*100 /
|
||||
DYV
|
||||
5*100 /
|
||||
DZV
|
||||
2*20 100 7*20 /
|
||||
|
||||
EQUALS
|
||||
-- 'DX' 100 /
|
||||
-- 'DY' 100 /
|
||||
'PERMX' 50 /
|
||||
'PERMZ' 5 /
|
||||
-- 'DZ' 20 /
|
||||
'PORO' 0.2 /
|
||||
-- 'TOPS' 7000 1 10 1 5 1 1 /
|
||||
--'DZ' 100 1 10 1 5 3 3 /
|
||||
'PORO' 0.0 1 10 1 5 3 3 /
|
||||
/
|
||||
|
||||
COPY
|
||||
PERMX PERMY /
|
||||
/
|
||||
|
||||
RPTGRID
|
||||
-- Report Levels for Grid Section Data
|
||||
--
|
||||
/
|
||||
|
||||
PROPS ==========================================================
|
||||
|
||||
-- WATER RELATIVE PERMEABILITY AND CAPILLARY PRESSURE ARE TABULATED AS
|
||||
-- A FUNCTION OF WATER SATURATION.
|
||||
--
|
||||
-- SWAT KRW PCOW
|
||||
SWFN
|
||||
|
||||
0.12 0 0
|
||||
1.0 0.00001 0 /
|
||||
|
||||
-- SIMILARLY FOR GAS
|
||||
--
|
||||
-- SGAS KRG PCOG
|
||||
SGFN
|
||||
|
||||
0 0 0
|
||||
0.02 0 0
|
||||
0.05 0.005 0
|
||||
0.12 0.025 0
|
||||
0.2 0.075 0
|
||||
0.25 0.125 0
|
||||
0.3 0.19 0
|
||||
0.4 0.41 0
|
||||
0.45 0.6 0
|
||||
0.5 0.72 0
|
||||
0.6 0.87 0
|
||||
0.7 0.94 0
|
||||
0.85 0.98 0
|
||||
1.0 1.0 0
|
||||
/
|
||||
|
||||
-- OIL RELATIVE PERMEABILITY IS TABULATED AGAINST OIL SATURATION
|
||||
-- FOR OIL-WATER AND OIL-GAS-CONNATE WATER CASES
|
||||
--
|
||||
-- SOIL KROW KROG
|
||||
SOF3
|
||||
|
||||
0 0 0
|
||||
0.18 0 0
|
||||
0.28 0.0001 0.0001
|
||||
0.38 0.001 0.001
|
||||
0.43 0.01 0.01
|
||||
0.48 0.021 0.021
|
||||
0.58 0.09 0.09
|
||||
0.63 0.2 0.2
|
||||
0.68 0.35 0.35
|
||||
0.76 0.7 0.7
|
||||
0.83 0.98 0.98
|
||||
0.86 0.997 0.997
|
||||
0.879 1 1
|
||||
0.88 1 1 /
|
||||
|
||||
|
||||
-- PVT PROPERTIES OF WATER
|
||||
--
|
||||
-- REF. PRES. REF. FVF COMPRESSIBILITY REF VISCOSITY VISCOSIBILITY
|
||||
PVTW
|
||||
4014.7 1.029 3.13D-6 0.31 0 /
|
||||
|
||||
-- ROCK COMPRESSIBILITY
|
||||
--
|
||||
-- REF. PRES COMPRESSIBILITY
|
||||
ROCK
|
||||
14.7 3.0D-6 /
|
||||
|
||||
-- SURFACE DENSITIES OF RESERVOIR FLUIDS
|
||||
--
|
||||
-- OIL WATER GAS
|
||||
DENSITY
|
||||
49.1 64.79 0.06054 /
|
||||
|
||||
-- PVT PROPERTIES OF DRY GAS (NO VAPOURISED OIL)
|
||||
-- WE WOULD USE PVTG TO SPECIFY THE PROPERTIES OF WET GAS
|
||||
--
|
||||
-- PGAS BGAS VISGAS
|
||||
PVDG
|
||||
14.7 166.666 0.008
|
||||
264.7 12.093 0.0096
|
||||
514.7 6.274 0.0112
|
||||
1014.7 3.197 0.014
|
||||
2014.7 1.614 0.0189
|
||||
2514.7 1.294 0.0208
|
||||
3014.7 1.080 0.0228
|
||||
4014.7 0.811 0.0268
|
||||
5014.7 0.649 0.0309
|
||||
9014.7 0.386 0.047 /
|
||||
|
||||
-- PVT PROPERTIES OF LIVE OIL (WITH DISSOLVED GAS)
|
||||
-- WE WOULD USE PVDO TO SPECIFY THE PROPERTIES OF DEAD OIL
|
||||
--
|
||||
-- FOR EACH VALUE OF RS THE SATURATION PRESSURE, FVF AND VISCOSITY
|
||||
-- ARE SPECIFIED. FOR RS=1.27 AND 1.618, THE FVF AND VISCOSITY OF
|
||||
-- UNDERSATURATED OIL ARE DEFINED AS A FUNCTION OF PRESSURE. DATA
|
||||
-- FOR UNDERSATURATED OIL MAY BE SUPPLIED FOR ANY RS, BUT MUST BE
|
||||
-- SUPPLIED FOR THE HIGHEST RS (1.618).
|
||||
--
|
||||
-- RS POIL FVFO VISO
|
||||
PVTO
|
||||
0.001 14.7 1.062 1.04 /
|
||||
0.0905 264.7 1.15 0.975 /
|
||||
0.18 514.7 1.207 0.91 /
|
||||
0.371 1014.7 1.295 0.83 /
|
||||
0.636 2014.7 1.435 0.695 /
|
||||
0.775 2514.7 1.5 0.641 /
|
||||
0.93 3014.7 1.565 0.594 /
|
||||
1.270 4014.7 1.695 0.51
|
||||
5014.7 1.671 0.549
|
||||
9014.7 1.579 0.74 /
|
||||
1.618 5014.7 1.827 0.449
|
||||
9014.7 1.726 0.605 /
|
||||
/
|
||||
|
||||
|
||||
RPTPROPS
|
||||
-- PROPS Reporting Options
|
||||
--
|
||||
/
|
||||
|
||||
REGIONS ===========================================================
|
||||
|
||||
|
||||
FIPNUM
|
||||
|
||||
100*1
|
||||
400*2
|
||||
/
|
||||
|
||||
EQLNUM
|
||||
|
||||
100*1
|
||||
400*2
|
||||
/
|
||||
|
||||
RPTREGS
|
||||
|
||||
/
|
||||
|
||||
SOLUTION ============================================================
|
||||
|
||||
EQUIL
|
||||
7020.00 2700.00 7990.00 .00000 7020.00 .00000 0 0 5 /
|
||||
7200.00 3700.00 7300.00 .00000 7000.00 .00000 1 0 5 /
|
||||
|
||||
RSVD 2 TABLES 3 NODES IN EACH FIELD 12:00 17 AUG 83
|
||||
7000.0 1.0000
|
||||
7990.0 1.0000
|
||||
/
|
||||
7000.0 1.0000
|
||||
7400.0 1.0000
|
||||
/
|
||||
|
||||
RPTRST
|
||||
-- Restart File Output Control
|
||||
--
|
||||
'BASIC=2' 'FLOWS' 'POT' 'PRES' /
|
||||
|
||||
|
||||
SUMMARY ===========================================================
|
||||
|
||||
FOPR
|
||||
|
||||
WOPR
|
||||
/
|
||||
|
||||
FGPR
|
||||
|
||||
FWPR
|
||||
|
||||
FWIR
|
||||
|
||||
FWCT
|
||||
|
||||
FGOR
|
||||
|
||||
--RUNSUM
|
||||
|
||||
ALL
|
||||
|
||||
MSUMLINS
|
||||
|
||||
MSUMNEWT
|
||||
|
||||
SEPARATE
|
||||
|
||||
SCHEDULE ===========================================================
|
||||
|
||||
DEBUG
|
||||
1 3 /
|
||||
|
||||
DRSDT
|
||||
1.0E20 /
|
||||
|
||||
RPTSCHED
|
||||
'PRES' 'SWAT' 'SGAS' 'RESTART=1' 'RS' 'WELLS=2' 'SUMMARY=2'
|
||||
'CPU=2' 'WELSPECS' 'NEWTON=2' /
|
||||
|
||||
NOECHO
|
||||
|
||||
|
||||
ECHO
|
||||
|
||||
GRUPTREE
|
||||
'GRP1' 'FIELD' /
|
||||
'WGRP1' 'GRP1' /
|
||||
'WGRP2' 'GRP1' /
|
||||
/
|
||||
|
||||
WELSPECS
|
||||
'PROD1' 'WGRP1' 1 5 7030 'OIL' 0.0 'STD' 'STOP' /
|
||||
'PROD2' 'WGRP2' 1 5 7030 'OIL' 0.0 'STD' 'STOP' /
|
||||
'WINJ1' 'WGRP1' 10 1 7030 'WAT' 0.0 'STD' 'STOP' /
|
||||
'WINJ2' 'WGRP2' 10 1 7030 'WAT' 0.0 'STD' 'STOP' /
|
||||
/
|
||||
|
||||
COMPDAT
|
||||
|
||||
'PROD1' 1 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD1' 2 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD1' 3 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD2' 4 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD2' 5 5 2 2 3* 0.2 3* 'X' /
|
||||
|
||||
'WINJ1' 10 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ1' 9 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ1' 8 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ2' 7 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ2' 6 1 9 9 3* 0.2 3* 'X' /
|
||||
/
|
||||
|
||||
|
||||
|
||||
UDQ
|
||||
-- test
|
||||
--oil & liquid capacities at GEFAC = 0.8995
|
||||
DEFINE WUOPRL (WOPR PROD1 - 150) * 0.90 /
|
||||
DEFINE WULPRL (WLPR PROD1 - 200) * 0.90 /
|
||||
DEFINE WUOPRU (WOPR PROD2 - 250) * 0.80 /
|
||||
DEFINE GUOPRU (GOPR WGRP2 - 449) * 0.77 /
|
||||
DEFINE WULPRU (WLPR PROD2 - 300) * 0.80 /
|
||||
ASSIGN WULPRL 400. /
|
||||
DEFINE FULPR (FLPR - 543) * 0.65 /
|
||||
DEFINE WUOPRL (WOPR PROD1 - 170) * 0.60 /
|
||||
-- units
|
||||
UNITS WUOPRL SM3/DAY /
|
||||
UNITS WULPRL SM3/DAY /
|
||||
UNITS GUOPRU SM3/DAY /
|
||||
UNITS WUOPRU SM3/DAY /
|
||||
UNITS WULPRU SM3/DAY /
|
||||
UNITS FULPR SM3/DAY /
|
||||
--
|
||||
/
|
||||
|
||||
-- Well production rate targets/limits:
|
||||
-- testing UDQs as production constrains
|
||||
WCONPROD
|
||||
-- name status ctrl qo qw qg ql qr bhp thp vfp alq
|
||||
'PROD1' 'OPEN' 'GRUP' WUOPRU 1* 1* WULPRU 1* 60.0 / single wells
|
||||
/
|
||||
|
||||
|
||||
WCONPROD
|
||||
-- name status ctrl qo qw qg ql qr bhp thp vfp alq
|
||||
'PROD2' 'OPEN' 'GRUP' WUOPRU 1* 1* WULPRU 1* 60.0 / single wells
|
||||
/
|
||||
|
||||
WCONINJE
|
||||
'WINJ1' 'WAT' 'OPEN' 'BHP' 1* 1200 3500 1* /
|
||||
'WINJ2' 'WAT' 'OPEN' 'BHP' 1* 800 3500 1* /
|
||||
/
|
||||
|
||||
|
||||
TUNING
|
||||
/
|
||||
/
|
||||
/
|
||||
|
||||
TSTEP
|
||||
4
|
||||
/
|
||||
|
||||
|
||||
END
|
||||
@@ -26,12 +26,13 @@ Copyright 2018 Statoil ASA.
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
@@ -1173,22 +1174,32 @@ UDQ
|
||||
const auto& udq = schedule.getUDQConfig(0);
|
||||
|
||||
|
||||
const auto& def_input = udq.input_definitions();
|
||||
const auto& input = udq.input();
|
||||
const auto& def = udq.definitions();
|
||||
BOOST_CHECK_EQUAL(def_input.size(), 3);
|
||||
for (std::size_t i = 0; i < def_input.size(); i++)
|
||||
BOOST_CHECK_EQUAL(def[i].input_string(), def_input[i].second.input_string());
|
||||
BOOST_CHECK_EQUAL(input.size(), 7);
|
||||
BOOST_CHECK_EQUAL(udq.size(), 7);
|
||||
|
||||
BOOST_CHECK_EQUAL(def_input[0].first, 3);
|
||||
BOOST_CHECK_EQUAL(def_input[1].first, 4);
|
||||
BOOST_CHECK_EQUAL(def_input[2].first, 6);
|
||||
BOOST_CHECK( input[0].is<UDQAssign>() );
|
||||
BOOST_CHECK( input[1].is<UDQAssign>() );
|
||||
BOOST_CHECK( input[2].is<UDQAssign>() );
|
||||
BOOST_CHECK( input[3].is<UDQDefine>() );
|
||||
BOOST_CHECK( input[4].is<UDQDefine>() );
|
||||
BOOST_CHECK( input[5].is<UDQAssign>() );
|
||||
BOOST_CHECK( input[6].is<UDQDefine>() );
|
||||
|
||||
BOOST_CHECK_EQUAL( input[4].unit(), "SM3/DAY" );
|
||||
|
||||
BOOST_CHECK_EQUAL(def[0].keyword(), "WUWCT");
|
||||
BOOST_CHECK_EQUAL(def[1].keyword(), "FUOPR");
|
||||
BOOST_CHECK_EQUAL(def[2].keyword(), "FUOPRX");
|
||||
|
||||
BOOST_CHECK_EQUAL( input[3].get<UDQDefine>().keyword(), "WUWCT");
|
||||
BOOST_CHECK_EQUAL( input[4].get<UDQDefine>().keyword(), "FUOPR");
|
||||
BOOST_CHECK_EQUAL( input[6].get<UDQDefine>().keyword(), "FUOPRX");
|
||||
|
||||
BOOST_CHECK( udq.has_keyword("FUXXX") );
|
||||
const auto wubhp1 = udq["WUBHP1"];
|
||||
BOOST_CHECK( wubhp1.is<UDQAssign>() );
|
||||
}
|
||||
|
||||
|
||||
@@ -1210,6 +1221,7 @@ UDQ
|
||||
|
||||
UDQ
|
||||
DEFINE WUBHP1 SUM(WOPR) /
|
||||
DEFINE FUOPR MAX(WOPR) /
|
||||
/
|
||||
|
||||
)";
|
||||
@@ -1217,14 +1229,221 @@ UDQ
|
||||
const auto& udq = schedule.getUDQConfig(0);
|
||||
|
||||
|
||||
const auto& def_input = udq.input_definitions();
|
||||
const auto& input = udq.input();
|
||||
const auto& def = udq.definitions();
|
||||
BOOST_CHECK_EQUAL(def_input.size(), 3);
|
||||
for (std::size_t i = 0; i < def_input.size(); i++)
|
||||
BOOST_CHECK_EQUAL(def[i].input_string(), def_input[i].second.input_string());
|
||||
BOOST_CHECK_EQUAL(input.size(), 5);
|
||||
BOOST_CHECK_EQUAL(udq.size(), 5);
|
||||
|
||||
BOOST_CHECK_EQUAL(def_input[0].first, 0);
|
||||
BOOST_CHECK_EQUAL(def_input[1].first, 3);
|
||||
BOOST_CHECK_EQUAL(def_input[2].first, 4);
|
||||
BOOST_CHECK( input[0].is<UDQDefine>());
|
||||
BOOST_CHECK_EQUAL( input[0].keyword(), "WUBHP1");
|
||||
|
||||
const auto fuopr = udq["FUOPR"];
|
||||
BOOST_CHECK( fuopr.is<UDQDefine>() );
|
||||
const auto& def2 = fuopr.get<UDQDefine>();
|
||||
BOOST_CHECK_EQUAL(def2.input_string(), "MAX(WOPR)");
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_USAGE) {
|
||||
UDQActive usage;
|
||||
UDQParams params;
|
||||
UDQConfig conf(params);
|
||||
BOOST_CHECK_EQUAL( usage.IUAD_size(), 0 );
|
||||
|
||||
UDAValue uda1("WUX");
|
||||
conf.add_assign(uda1.get<std::string>(), {}, 100);
|
||||
|
||||
usage.update(conf, uda1, "W1", UDAControl::WCONPROD_ORAT);
|
||||
BOOST_CHECK_EQUAL( usage.IUAD_size(), 1 );
|
||||
BOOST_CHECK_EQUAL( usage[0].use_count, 1);
|
||||
|
||||
usage.update(conf, uda1, "W1", UDAControl::WCONPROD_GRAT);
|
||||
BOOST_CHECK_EQUAL( usage.IUAD_size(), 2 );
|
||||
BOOST_CHECK_EQUAL( usage[1].use_count, 1);
|
||||
|
||||
const auto& rec = usage[0];
|
||||
BOOST_CHECK_EQUAL(rec.wgname, "W1");
|
||||
BOOST_CHECK_EQUAL(rec.udq, "WUX");
|
||||
BOOST_CHECK(rec.control == UDAControl::WCONPROD_ORAT);
|
||||
|
||||
|
||||
for (std::size_t index = 0; index < usage.IUAD_size(); index++) {
|
||||
const auto& record = usage[index];
|
||||
BOOST_CHECK_EQUAL(record.input_index, 0);
|
||||
BOOST_CHECK_EQUAL(record.wgname, "W1");
|
||||
|
||||
if (index == 0)
|
||||
BOOST_CHECK(record.control == UDAControl::WCONPROD_ORAT);
|
||||
else
|
||||
BOOST_CHECK(record.control == UDAControl::WCONPROD_GRAT);
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(IntegrationTest) {
|
||||
#include "data/integration_tests/udq.data"
|
||||
auto schedule = make_schedule(deck_string);
|
||||
{
|
||||
const auto& active = schedule.udqActive(1);
|
||||
BOOST_CHECK_EQUAL(active.IUAD_size(), 4);
|
||||
|
||||
BOOST_CHECK(active[0].control == UDAControl::WCONPROD_ORAT);
|
||||
BOOST_CHECK(active[1].control == UDAControl::WCONPROD_LRAT);
|
||||
BOOST_CHECK(active[2].control == UDAControl::WCONPROD_ORAT);
|
||||
BOOST_CHECK(active[3].control == UDAControl::WCONPROD_LRAT);
|
||||
|
||||
BOOST_CHECK(active[0].wgname == "OPL02");
|
||||
BOOST_CHECK(active[1].wgname == "OPL02");
|
||||
BOOST_CHECK(active[2].wgname == "OPU02");
|
||||
BOOST_CHECK(active[3].wgname == "OPU02");
|
||||
|
||||
BOOST_CHECK(active[0].udq == "WUOPRL");
|
||||
BOOST_CHECK(active[1].udq == "WULPRL");
|
||||
BOOST_CHECK(active[2].udq == "WUOPRU");
|
||||
BOOST_CHECK(active[3].udq == "WULPRU");
|
||||
|
||||
BOOST_CHECK(active[0].input_index == 0);
|
||||
BOOST_CHECK(active[1].input_index == 1);
|
||||
BOOST_CHECK(active[2].input_index == 2);
|
||||
BOOST_CHECK(active[3].input_index == 3);
|
||||
|
||||
BOOST_CHECK(active[0].use_count == 1);
|
||||
BOOST_CHECK(active[1].use_count == 1);
|
||||
BOOST_CHECK(active[2].use_count == 1);
|
||||
BOOST_CHECK(active[3].use_count == 1);
|
||||
}
|
||||
}
|
||||
|
||||
Schedule make_udq_schedule(const std::string& schedule_string) {
|
||||
#include "data/integration_tests/udq2.data"
|
||||
deck_string += schedule_string;
|
||||
return make_schedule(deck_string);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(IntegrationTest2) {
|
||||
const std::string udq_string = R"(
|
||||
UDQ
|
||||
DEFINE WUOPRL (WOPR PROD1 - 150) * 0.90 /
|
||||
DEFINE WULPRL (WLPR PROD1 - 200) * 0.90 /
|
||||
DEFINE WUOPRU (WOPR PROD2 - 250) * 0.80 /
|
||||
DEFINE WULPRU (WLPR PROD2 - 300) * 0.80 /
|
||||
DEFINE WUOPRL (WOPR PROD1 - 170) * 0.60 /
|
||||
DEFINE WUXO (WOPR PROD1 - 170) * 0.60 /
|
||||
DEFINE WUXL (WOPR PROD1 - 170) * 0.60 /
|
||||
-- units
|
||||
UNITS WUOPRL SM3/DAY /
|
||||
UNITS WULPRL SM3/DAY /
|
||||
UNITS WUOPRU SM3/DAY /
|
||||
UNITS WULPRU SM3/DAY /
|
||||
/
|
||||
|
||||
WCONPROD
|
||||
'PROD1' 'OPEN' 'GRUP' WUOPRU 1* 1* WULPRU 1* 60.0 / single wells
|
||||
/
|
||||
|
||||
|
||||
WCONPROD
|
||||
'PROD2' 'OPEN' 'GRUP' WUOPRU 1* 1* WULPRU 1* 60.0 / single wells
|
||||
/
|
||||
|
||||
WCONINJE
|
||||
'WINJ1' 'WAT' 'OPEN' 'BHP' 1* 1200 3500 1* /
|
||||
'WINJ2' 'WAT' 'OPEN' 'BHP' 1* 800 3500 1* /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
5 /
|
||||
|
||||
WCONPROD
|
||||
'PROD2' 'OPEN' 'GRUP' WUXO 1* 1* WUXL 1* 60.0 / single wells
|
||||
/
|
||||
|
||||
TSTEP
|
||||
5 /
|
||||
|
||||
WCONPROD
|
||||
'PROD1' 'OPEN' 'GRUP' 100 1* 1* 100 1* 60.0 / single wells
|
||||
/
|
||||
|
||||
|
||||
|
||||
|
||||
)";
|
||||
auto schedule = make_udq_schedule(udq_string);
|
||||
|
||||
// First timestep
|
||||
{
|
||||
const auto& udq_active = schedule.udqActive(0);
|
||||
BOOST_CHECK(udq_active);
|
||||
BOOST_CHECK_EQUAL(udq_active.IUAD_size(), 2);
|
||||
|
||||
const auto& record0 = udq_active[0];
|
||||
BOOST_CHECK_EQUAL( record0.uad_code, 300004);
|
||||
BOOST_CHECK_EQUAL( record0.input_index, 2);
|
||||
BOOST_CHECK_EQUAL( record0.use_count, 2);
|
||||
BOOST_CHECK_EQUAL( record0.use_index, 0);
|
||||
|
||||
const auto& record1 = udq_active[1];
|
||||
BOOST_CHECK_EQUAL( record1.uad_code, 600004);
|
||||
BOOST_CHECK_EQUAL( record1.input_index, 3);
|
||||
BOOST_CHECK_EQUAL( record1.use_count, 2);
|
||||
BOOST_CHECK_EQUAL( record1.use_index, 2);
|
||||
}
|
||||
|
||||
{
|
||||
// Second timestep
|
||||
// - The WUOPRU and WULPRU udq are still used in the same manner for the PROD1 well.
|
||||
// - The new UDQs WUXO and WUXL are now used for the PROD2 well.
|
||||
const auto& udq_active = schedule.udqActive(1);
|
||||
BOOST_CHECK(udq_active);
|
||||
BOOST_CHECK_EQUAL(udq_active.IUAD_size(), 4);
|
||||
|
||||
const auto& record0 = udq_active[0];
|
||||
BOOST_CHECK_EQUAL( record0.uad_code, 300004);
|
||||
BOOST_CHECK_EQUAL( record0.input_index, 2);
|
||||
BOOST_CHECK_EQUAL( record0.use_count, 1);
|
||||
BOOST_CHECK_EQUAL( record0.use_index, 0);
|
||||
|
||||
const auto& record1 = udq_active[1];
|
||||
BOOST_CHECK_EQUAL( record1.uad_code, 600004);
|
||||
BOOST_CHECK_EQUAL( record1.input_index, 3);
|
||||
BOOST_CHECK_EQUAL( record1.use_count, 1);
|
||||
BOOST_CHECK_EQUAL( record1.use_index, 1);
|
||||
|
||||
const auto& record2 = udq_active[2];
|
||||
BOOST_CHECK_EQUAL( record2.uad_code, 300004);
|
||||
BOOST_CHECK_EQUAL( record2.input_index, 4);
|
||||
BOOST_CHECK_EQUAL( record2.use_count, 1);
|
||||
BOOST_CHECK_EQUAL( record2.use_index, 2);
|
||||
|
||||
const auto& record3 = udq_active[3];
|
||||
BOOST_CHECK_EQUAL( record3.uad_code, 600004);
|
||||
BOOST_CHECK_EQUAL( record3.input_index, 5);
|
||||
BOOST_CHECK_EQUAL( record3.use_count, 1);
|
||||
BOOST_CHECK_EQUAL( record3.use_index, 3);
|
||||
}
|
||||
|
||||
{
|
||||
// Third timestep
|
||||
// - The new UDQs WUXO and WUXL are now used for the PROD2 well.
|
||||
// - The PROD1 well does not use UDQ
|
||||
const auto& udq_active = schedule.udqActive(2);
|
||||
BOOST_CHECK(udq_active);
|
||||
BOOST_CHECK_EQUAL(udq_active.IUAD_size(), 2);
|
||||
|
||||
const auto& record0 = udq_active[0];
|
||||
BOOST_CHECK_EQUAL( record0.uad_code, 300004);
|
||||
BOOST_CHECK_EQUAL( record0.input_index, 4);
|
||||
BOOST_CHECK_EQUAL( record0.use_count, 1);
|
||||
BOOST_CHECK_EQUAL( record0.use_index, 0);
|
||||
|
||||
const auto& record1 = udq_active[1];
|
||||
BOOST_CHECK_EQUAL( record1.uad_code, 600004);
|
||||
BOOST_CHECK_EQUAL( record1.input_index, 5);
|
||||
BOOST_CHECK_EQUAL( record1.use_count, 1);
|
||||
BOOST_CHECK_EQUAL( record1.use_index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
||||
@@ -545,7 +546,7 @@ namespace {
|
||||
const auto& kwd = deck.getKeyword("WCONPROD");
|
||||
const auto& record = kwd.getRecord(0);
|
||||
Opm::WellProductionProperties pred("W");
|
||||
pred.handleWCONPROD(record);
|
||||
pred.handleWCONPROD("WELL", record);
|
||||
|
||||
return pred;
|
||||
}
|
||||
|
||||
718
tests/parser/data/integration_tests/udq.data
Normal file
718
tests/parser/data/integration_tests/udq.data
Normal file
@@ -0,0 +1,718 @@
|
||||
const std::string deck_string = R"(
|
||||
RUNSPEC
|
||||
|
||||
|
||||
TITLE
|
||||
'Generic' 'Reservoir'
|
||||
|
||||
NOECHO
|
||||
|
||||
|
||||
DIMENS
|
||||
3 5 4 /
|
||||
|
||||
|
||||
START
|
||||
22 'AUG' 2018 /
|
||||
|
||||
|
||||
OIL
|
||||
|
||||
|
||||
GAS
|
||||
|
||||
|
||||
WATER
|
||||
|
||||
|
||||
DISGAS
|
||||
|
||||
|
||||
METRIC
|
||||
|
||||
|
||||
TABDIMS
|
||||
1 1 130 24 1 20 /
|
||||
|
||||
|
||||
EQLDIMS
|
||||
2 100 20 /
|
||||
|
||||
|
||||
WELLDIMS
|
||||
230 120 50 80 /
|
||||
|
||||
|
||||
UNIFIN
|
||||
|
||||
|
||||
UNIFOUT
|
||||
|
||||
|
||||
UDQDIMS
|
||||
50 25 0 50 50 0 0 50 0 20 /
|
||||
|
||||
|
||||
UDADIMS
|
||||
10 1* 10 /
|
||||
|
||||
|
||||
GRID
|
||||
|
||||
|
||||
NOECHO
|
||||
|
||||
|
||||
INIT
|
||||
|
||||
|
||||
GRIDFILE
|
||||
0 1 /
|
||||
|
||||
|
||||
MAPAXES
|
||||
0 100 0 0 100 0 /
|
||||
|
||||
|
||||
NOECHO
|
||||
|
||||
|
||||
SPECGRID
|
||||
3 5 4 1 'F' /
|
||||
|
||||
|
||||
COORD
|
||||
2000 2000 2000 1999.5638 2000 2039.9619 2199.8096 2000 2008.7239 2199.3735 2000 2048.6858 2399.6193 2000 2017.4478 2399.1831
|
||||
2000 2057.4097 2599.4289 2000 2026.1716 2598.9927 2000 2066.1336 2000 2200 2000 1999.5638 2200 2039.9619 2199.8096 2200
|
||||
2008.7239 2199.3735 2200 2048.6858 2399.6193 2200 2017.4478 2399.1831 2200 2057.4097 2599.4289 2200 2026.1716 2598.9927 2200 2066.1336
|
||||
2000 2400 2000 1999.5638 2400 2039.9619 2199.8096 2400 2008.7239 2199.3735 2400 2048.6858 2399.6193 2400 2017.4478 2399.1831
|
||||
2400 2057.4097 2599.4289 2400 2026.1716 2598.9927 2400 2066.1336 2000 2600 2000 1999.5638 2600 2039.9619 2199.8096 2600
|
||||
2008.7239 2199.3735 2600 2048.6858 2399.6193 2600 2017.4478 2399.1831 2600 2057.4097 2599.4289 2600 2026.1716 2598.9927 2600 2066.1336
|
||||
2000 2800 2000 1999.5638 2800 2039.9619 2199.8096 2800 2008.7239 2199.3735 2800 2048.6858 2399.6193 2800 2017.4478 2399.1831
|
||||
2800 2057.4097 2599.4289 2800 2026.1716 2598.9927 2800 2066.1336 2000 3000 2000 1999.5638 3000 2039.9619 2199.8096 3000
|
||||
2008.7239 2199.3735 3000 2048.6858 2399.6193 3000 2017.4478 2399.1831 3000 2057.4097 2599.4289 3000 2026.1716 2598.9927 3000 2066.1336 /
|
||||
|
||||
|
||||
ZCORN
|
||||
2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478
|
||||
2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239
|
||||
2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716
|
||||
2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2000 2008.7239 2008.7239 2017.4478 2017.4478 2026.1716 2009.9905 2018.7144 2018.7144 2027.4382
|
||||
2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144
|
||||
2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621
|
||||
2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382
|
||||
2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144
|
||||
2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621
|
||||
2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382
|
||||
2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144 2018.7144 2027.4382 2027.4382 2036.1621 2009.9905 2018.7144
|
||||
2018.7144 2027.4382 2027.4382 2036.1621 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526
|
||||
2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287
|
||||
2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048
|
||||
2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526
|
||||
2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287
|
||||
2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048
|
||||
2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526
|
||||
2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2019.981 2028.7048 2028.7048 2037.4287 2037.4287 2046.1526 2029.9714 2038.6953 2038.6953 2047.4192
|
||||
2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953
|
||||
2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431
|
||||
2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192
|
||||
2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953
|
||||
2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431
|
||||
2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192
|
||||
2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953 2038.6953 2047.4192 2047.4192 2056.1431 2029.9714 2038.6953
|
||||
2038.6953 2047.4192 2047.4192 2056.1431 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336
|
||||
2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097
|
||||
2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858
|
||||
2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 2039.9619 2048.6858 2048.6858 2057.4097 2057.4097 2066.1336 /
|
||||
|
||||
|
||||
PORO
|
||||
0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.2
|
||||
0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.23 0.23
|
||||
0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.23 0.18 0.18 0.18
|
||||
0.18 0.18 0.18 0.18 0.18 0.18 0.18 0.18 0.18 0.18 0.18 0.18 /
|
||||
|
||||
|
||||
PERMX
|
||||
500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 100
|
||||
100 100 100 100 100 100 100 100 100 100 100 100 100 100 1000 1000
|
||||
1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 250 250 250
|
||||
250 250 250 250 250 250 250 250 250 250 250 250 /
|
||||
|
||||
|
||||
COPY
|
||||
'PERMX' 'PERMY' /
|
||||
'PERMX' 'PERMZ' /
|
||||
/
|
||||
|
||||
|
||||
MULTIPLY
|
||||
'PERMZ' 0.1 /
|
||||
/
|
||||
|
||||
|
||||
MULTZ
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 /
|
||||
|
||||
|
||||
EDIT
|
||||
|
||||
|
||||
PROPS
|
||||
|
||||
|
||||
SGOF
|
||||
0 0 1 0 0.0183 0.001480314 0.8127534 0 0.0366 0.004696335 0.675857 0 0.0549 0.009371694 0.5622753 0
|
||||
0.0732 0.01546379 0.4663578 0 0.0915 0.02298664 0.385133 0 0.1098 0.03197913 0.3164995 0 0.1281 0.04249268 0.2587408 0
|
||||
0.1464 0.05458466 0.2103665 0 0.1647 0.06831379 0.1700565 0 0.183 0.08373629 0.1366388 0 0.2013 0.1009022 0.1090792 0
|
||||
0.2196 0.1198516 0.08647139 0 0.2379 0.1406109 0.06802822 0 0.2562 0.1631885 0.05307051 0 0.2745 0.1875705 0.04101619 0
|
||||
0.2928 0.2137163 0.03136912 0 0.3111 0.2415547 0.02370834 0 0.3294 0.2709792 0.01767817 0 0.3477 0.3018447 0.01297907 0
|
||||
0.366 0.3339653 0.009359652 0 0.3843 0.3671116 0.006609586 0 0.4026 0.401011 0.00455345 0 0.4209 0.4353486 0.003045475 0
|
||||
0.4392 0.4697695 0.001965044 0 0.4575 0.5038828 0.001212868 0 0.4758 0.5372664 0.0007077659 0 0.4941 0.5694721 0.000383946 0
|
||||
0.5124 0.6000285 0.0001887263 0 0.5307 0.6284408 8.062741e-05 0 0.549 0.6541796 2.778023e-05 0 0.5673 0.676644 6.602397e-06 0
|
||||
0.5856 0.6950468 7.048731e-07 0 0.61 0.71 0 0 0.6275 0.7825 0 0 0.645 0.855 0 0
|
||||
0.6625 0.9275 0 0 0.68 1 0 0 /
|
||||
|
||||
|
||||
SWOF
|
||||
0.32 0 1 0 0.3365 3.00925e-08 0.9804566 0 0.353 7.541952e-07 0.9391194 0 0.3695 5.01876e-06 0.8832853 0
|
||||
0.386 1.941502e-05 0.8178788 0 0.4025 5.581854e-05 0.7471578 0 0.419 0.0001330574 0.674704 0 0.4355 0.0002787865 0.60333 0
|
||||
0.452 0.0005316304 0.535068 0 0.4685 0.0009436502 0.4712431 0 0.485 0.001583182 0.412597 0 0.5015 0.002538082 0.3594268 0
|
||||
0.518 0.00391938 0.3117147 0 0.5345 0.005865308 0.2692366 0 0.551 0.008545575 0.2316458 0 0.5675 0.01216566 0.1985336 0
|
||||
0.584 0.01697073 0.169471 0 0.6005 0.0232485 0.1440352 0 0.617 0.03133019 0.1218258 0 0.6335 0.04158825 0.1024735 0
|
||||
0.65 0.05442925 0.08564409 0 0.6665 0.07028023 0.0710386 0 0.683 0.08956673 0.05839253 0 0.6995 0.1126816 0.0474734 0
|
||||
0.716 0.1399451 0.03807806 0 0.7325 0.1715593 0.03002991 0 0.749 0.2075632 0.02317622 0 0.7655 0.2478002 0.01738581 0
|
||||
0.782 0.2919105 0.01254709 0 0.7985 0.3393688 0.008566921 0 0.815 0.3895919 0.005370427 0 0.8315 0.4421811 0.002903191 0
|
||||
0.848 0.4975608 0.001139647 0 0.87 0.59168 0 0 0.8885714 0.6500114 0 0 0.9071429 0.7083429 0 0
|
||||
0.9257143 0.7666743 0 0 0.9442857 0.8250057 0 0 0.9628571 0.8833371 0 0 0.9814286 0.9416686 0 0
|
||||
1 1 0 0 /
|
||||
|
||||
|
||||
PVDG
|
||||
20 0.061895 0.01299 40 0.030252 0.01383 60 0.019844 0.0145 80 0.014686 0.0152 100 0.011627 0.01596 120
|
||||
0.009619 0.01682 140 0.008213 0.0178 160 0.007184 0.0189 197.66 0.00582 0.0216 231.13 0.005042 0.02477 261.31 0.004561
|
||||
0.02844 288.87 0.004255 0.03272 314.34 0.004062 0.03783 338.2 0.003953 0.0441 360.83 0.003947 0.0521 382.58 0.003915 0.06273
|
||||
403.6 0.003912 0.07723 423.77 0.003907 0.09631 /
|
||||
|
||||
|
||||
PVTO
|
||||
19.6 20 1.12324 0.96519 55 1.11698 1.03237 90 1.11127 1.10051 125 1.10602 1.16942 160 1.10119 1.2389
|
||||
195 1.09672 1.30876 230 1.09256 1.37884 265 1.08868 1.44899 300 1.08504 1.51908 335 1.08164 1.58903 370
|
||||
1.07843 1.65876 /
|
||||
31.5 40 1.15981 0.85738 75 1.15288 0.91402 110 1.14657 0.97137 145 1.14079 1.02927 180 1.13546 1.08759
|
||||
215 1.13053 1.14617 250 1.12595 1.20488 285 1.12168 1.2636 320 1.11768 1.32224 355 1.11394 1.38073 390
|
||||
1.11042 1.43898 /
|
||||
42.4 60 1.191 0.7868 95 1.184 0.8364 130 1.177 0.8866 165 1.171 0.9371 200 1.165 0.988
|
||||
235 1.16 1.039 270 1.155 1.0902 305 1.15 1.1413 340 1.146 1.1922 375 1.142 1.2431 410
|
||||
1.138 1.2936 /
|
||||
53.4 80 1.222 0.7175 115 1.214 0.7608 150 1.206 0.8045 185 1.2 0.8485 220 1.194 0.8928
|
||||
255 1.188 0.9371 290 1.183 0.9815 325 1.178 1.0258 360 1.173 1.07 395 1.169 1.1141 430
|
||||
1.165 1.1579 /
|
||||
64.6 100 1.252 0.6544 135 1.244 0.6923 170 1.236 0.7305 205 1.229 0.7689 240 1.222 0.8075
|
||||
275 1.216 0.8461 310 1.211 0.8847 345 1.205 0.9233 380 1.2 0.9618 415 1.196 1 450
|
||||
1.191 1.0381 /
|
||||
76.3 120 1.284 0.5978 155 1.275 0.6312 190 1.266 0.6648 225 1.259 0.6985 260 1.252 0.7323
|
||||
295 1.245 0.7661 330 1.239 0.7999 365 1.234 0.8337 400 1.229 0.8673 435 1.224 0.9007 470
|
||||
1.219 0.934 /
|
||||
88.5 140 1.316 0.5477 175 1.307 0.5749 210 1.298 0.602 245 1.29 0.629 280 1.282 0.6559
|
||||
315 1.276 0.6827 350 1.269 0.7095 385 1.263 0.7362 420 1.258 0.7629 455 1.253 0.7895 490
|
||||
1.248 0.8161 /
|
||||
101.3 160 1.35 0.502 195 1.34 0.5227 230 1.331 0.5432 265 1.322 0.5635 300 1.314 0.5835
|
||||
335 1.307 0.6034 370 1.3 0.6231 405 1.294 0.6426 440 1.288 0.662 475 1.283 0.6813 /
|
||||
114.7 180 1.385 0.4636 215 1.375 0.482 250 1.365 0.5003 285 1.356 0.5183 320 1.347 0.5362
|
||||
355 1.34 0.5538 390 1.333 0.5712 425 1.326 0.5885 460 1.32 0.6055 495 1.314 0.6222 /
|
||||
128.9 200 1.422 0.429 235 1.411 0.4455 270 1.401 0.4618 305 1.391 0.4779 340 1.382 0.4938
|
||||
375 1.374 0.5096 410 1.367 0.5252 445 1.36 0.5406 480 1.353 0.5558 /
|
||||
143.8 220 1.461 0.3977 255 1.449 0.4125 290 1.438 0.4271 325 1.428 0.4415 360 1.419 0.4558
|
||||
395 1.41 0.4699 430 1.402 0.4839 465 1.395 0.4977 /
|
||||
159.5 240 1.502 0.3692 275 1.489 0.3825 310 1.478 0.3956 345 1.467 0.4086 380 1.458 0.4214
|
||||
415 1.449 0.4341 450 1.44 0.4466 485 1.432 0.459 /
|
||||
184 268.79 1.565 0.3324 303.79 1.551 0.3438 338.79 1.539 0.3551 373.79 1.528 0.3663 408.79 1.517 0.3774
|
||||
443.79 1.508 0.3883 478.79 1.499 0.3991 /
|
||||
226.3 306.18 1.679 0.2855 341.18 1.664 0.2949 376.18 1.65 0.3041 411.18 1.637 0.3132 446.18 1.625 0.3222
|
||||
481.18 1.614 0.3311 /
|
||||
268.6 339.93 1.792 0.2517 374.93 1.775 0.2597 409.93 1.76 0.2675 444.93 1.746 0.2751 479.93 1.732 0.2827 /
|
||||
310.9 371.44 1.903 0.2265 406.44 1.885 0.2333 441.44 1.868 0.2401 476.44 1.853 0.2468 /
|
||||
353.3 401.66 2.013 0.2071 436.66 1.993 0.2132 471.66 1.975 0.2192 /
|
||||
/
|
||||
|
||||
|
||||
PVTW
|
||||
344.83 1.0292 4.002e-05 0.36 0 /
|
||||
|
||||
|
||||
ROCK
|
||||
383 4.12e-05 /
|
||||
|
||||
|
||||
DENSITY
|
||||
842.3 1001.1 0.9 /
|
||||
|
||||
|
||||
REGIONS
|
||||
|
||||
|
||||
EQLNUM
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
|
||||
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
|
||||
2 2 2 2 2 2 2 2 2 2 2 2 /
|
||||
|
||||
|
||||
SOLUTION
|
||||
|
||||
|
||||
EQUIL
|
||||
2030 382.4 2030 0 500 0 1 1 0 /
|
||||
2050 382.4 2050 0 500 0 1 1 0 /
|
||||
|
||||
|
||||
RSVD
|
||||
1500 180 4000 180 /
|
||||
1500 180 4000 180 /
|
||||
|
||||
|
||||
RPTRST
|
||||
'BASIC=2' 'PBPD' /
|
||||
|
||||
|
||||
SUMMARY
|
||||
|
||||
|
||||
FOPR
|
||||
|
||||
|
||||
FOPRH
|
||||
|
||||
|
||||
FGPR
|
||||
|
||||
|
||||
FGPRH
|
||||
|
||||
|
||||
FWPR
|
||||
|
||||
|
||||
FWPRH
|
||||
|
||||
|
||||
FWIR
|
||||
|
||||
|
||||
FWIP
|
||||
|
||||
|
||||
FOIP
|
||||
|
||||
|
||||
FGIP
|
||||
|
||||
|
||||
FWCT
|
||||
|
||||
|
||||
FWCTH
|
||||
|
||||
|
||||
FGOR
|
||||
|
||||
|
||||
FGORH
|
||||
|
||||
|
||||
FPR
|
||||
|
||||
|
||||
RPR
|
||||
/
|
||||
|
||||
|
||||
ROIP
|
||||
/
|
||||
|
||||
|
||||
ROIPL
|
||||
/
|
||||
|
||||
|
||||
ROIPG
|
||||
/
|
||||
|
||||
|
||||
RGIP
|
||||
/
|
||||
|
||||
|
||||
RGIPL
|
||||
/
|
||||
|
||||
|
||||
RGIPG
|
||||
/
|
||||
|
||||
|
||||
RGPR
|
||||
/
|
||||
|
||||
|
||||
RGPT
|
||||
/
|
||||
|
||||
|
||||
GWIR
|
||||
/
|
||||
|
||||
|
||||
GVIR
|
||||
/
|
||||
|
||||
|
||||
GOPR
|
||||
/
|
||||
|
||||
|
||||
GWPR
|
||||
/
|
||||
|
||||
|
||||
GLPR
|
||||
/
|
||||
|
||||
|
||||
GLPR
|
||||
/
|
||||
|
||||
|
||||
GVPR
|
||||
/
|
||||
|
||||
|
||||
WOPR
|
||||
/
|
||||
|
||||
|
||||
WOPRH
|
||||
/
|
||||
|
||||
|
||||
WGPR
|
||||
/
|
||||
|
||||
|
||||
WGPRH
|
||||
/
|
||||
|
||||
|
||||
WWPR
|
||||
/
|
||||
|
||||
|
||||
WWPRH
|
||||
/
|
||||
|
||||
|
||||
WOPT
|
||||
/
|
||||
|
||||
|
||||
WWPT
|
||||
/
|
||||
|
||||
|
||||
WGPT
|
||||
/
|
||||
|
||||
|
||||
WOPTH
|
||||
/
|
||||
|
||||
|
||||
WWPTH
|
||||
/
|
||||
|
||||
|
||||
WGPTH
|
||||
/
|
||||
|
||||
|
||||
WWCT
|
||||
/
|
||||
|
||||
|
||||
WWCTH
|
||||
/
|
||||
|
||||
|
||||
WGOR
|
||||
/
|
||||
|
||||
|
||||
WGORH
|
||||
/
|
||||
|
||||
|
||||
WWIR
|
||||
/
|
||||
|
||||
|
||||
WWIRH
|
||||
/
|
||||
|
||||
|
||||
WGIR
|
||||
/
|
||||
|
||||
|
||||
WGIRH
|
||||
/
|
||||
|
||||
|
||||
WWIT
|
||||
/
|
||||
|
||||
|
||||
WWITH
|
||||
/
|
||||
|
||||
|
||||
WGIT
|
||||
/
|
||||
|
||||
|
||||
WGITH
|
||||
/
|
||||
|
||||
|
||||
WBHP
|
||||
/
|
||||
|
||||
|
||||
WTHP
|
||||
/
|
||||
|
||||
|
||||
WPI
|
||||
/
|
||||
|
||||
|
||||
WVPR
|
||||
/
|
||||
|
||||
|
||||
WBP
|
||||
/
|
||||
|
||||
|
||||
WBP4
|
||||
/
|
||||
|
||||
|
||||
WBP9
|
||||
/
|
||||
|
||||
|
||||
WMCTL
|
||||
/
|
||||
|
||||
|
||||
WLPR
|
||||
/
|
||||
|
||||
|
||||
TCPU
|
||||
|
||||
|
||||
TCPUDAY
|
||||
|
||||
|
||||
FMWIN
|
||||
|
||||
|
||||
FMWPR
|
||||
|
||||
|
||||
GMWPR
|
||||
'UPPER' 'LOWER' /
|
||||
|
||||
|
||||
GMWIN
|
||||
'UPPER' 'LOWER' /
|
||||
|
||||
|
||||
WUOPRL
|
||||
'OPL01' 'OPL02' 'OPU01' 'OPU02' /
|
||||
|
||||
|
||||
WULPRL
|
||||
'OPL01' 'OPL02' 'OPU01' 'OPU02' /
|
||||
|
||||
|
||||
WUOPRU
|
||||
'OPL01' 'OPL02' 'OPU01' 'OPU02' /
|
||||
|
||||
|
||||
WULPRU
|
||||
'OPL01' 'OPL02' 'OPU01' 'OPU02' /
|
||||
|
||||
|
||||
SCHEDULE
|
||||
|
||||
|
||||
GRUPTREE
|
||||
'UPPER' 'TEST' /
|
||||
'LOWER' 'TEST' /
|
||||
/
|
||||
|
||||
|
||||
WELSPECS
|
||||
'OPU01' 'UPPER' 1 2 2002 'OIL' 0 'STD' 'SHUT' 'YES' 0 'SEG' /
|
||||
'OPU02' 'UPPER' 1 4 2002 'OIL' 0 'STD' 'SHUT' 'YES' 0 'SEG' /
|
||||
'OPL01' 'LOWER' 1 2 2025 'OIL' 0 'STD' 'SHUT' 'YES' 0 'SEG' /
|
||||
'OPL02' 'LOWER' 1 4 2025 'OIL' 0 'STD' 'SHUT' 'YES' 0 'SEG' /
|
||||
/
|
||||
|
||||
|
||||
WELSPECS
|
||||
'WIU01' 'UPPER' 3 3 2030 'WATER' 0 'STD' 'SHUT' 'YES' 0 'SEG' /
|
||||
'WIL01' 'LOWER' 3 3 2050 'WATER' 0 'STD' 'SHUT' 'YES' 0 'SEG' /
|
||||
/
|
||||
|
||||
|
||||
COMPDAT
|
||||
'OPU01' 1 2 1 1 'OPEN' 0 1* 0.241 1* 2.5 0 'Z' /
|
||||
'OPU02' 1 4 1 1 'OPEN' 0 1* 0.241 1* 2.5 0 'Z' /
|
||||
'OPL01' 1 2 3 3 'OPEN' 0 1* 0.241 1* 2.5 0 'Z' /
|
||||
'OPL02' 1 4 3 3 'OPEN' 0 1* 0.241 1* 2.5 0 'Z' /
|
||||
'WIU01' 3 3 2 2 'OPEN' 0 1* 0.241 1* 2.5 0 'Z' /
|
||||
'WIL01' 3 3 4 4 'OPEN' 0 1* 0.241 1* 2.5 0 'Z' /
|
||||
/
|
||||
|
||||
|
||||
WCONPROD
|
||||
'OPU*' 'SHUT' 'GRUP' 1500 2* 2500 1* 60 /
|
||||
'OPL*' 'SHUT' 'GRUP' 1500 2* 2500 1* 60 /
|
||||
/
|
||||
|
||||
|
||||
WCONINJE
|
||||
'WIU*' 'WATER' 'SHUT' 'GRUP' 10500 1* 400 /
|
||||
'WIL*' 'WATER' 'SHUT' 'GRUP' 10500 1* 400 /
|
||||
/
|
||||
|
||||
UDQ
|
||||
-- test
|
||||
--oil & liquid capacities at GEFAC = 0.8995
|
||||
DEFINE WUOPRL (WOPR OPL01 - 150) * 0.90 /
|
||||
DEFINE WULPRL (WLPR OPL01 - 200) * 0.90 /
|
||||
DEFINE WUOPRU (WOPR OPU01 - 250) * 0.80 /
|
||||
DEFINE WULPRU (WLPR OPU01 - 300) * 0.80 /
|
||||
-- units
|
||||
UNITS WUOPRL SM3/DAY /
|
||||
UNITS WULPRL SM3/DAY /
|
||||
UNITS WUOPRU SM3/DAY /
|
||||
UNITS WULPRU SM3/DAY /
|
||||
--
|
||||
/
|
||||
|
||||
|
||||
GCONPROD
|
||||
'TEST' 'LRAT' 6000 2* 6000 'RATE' 'NO' /
|
||||
'LOWER' 'FLD' 6000 2* 6000 'RATE' 'YES' 1* 'FORM' /
|
||||
'UPPER' 'FLD' 3000 2* 6000 'RATE' 'YES' 1* 'FORM' /
|
||||
/
|
||||
|
||||
|
||||
GCONINJE
|
||||
'LOWER' 'WATER' 'VREP' 3* 1.2 /
|
||||
'UPPER' 'WATER' 'VREP' 3* 1.2 /
|
||||
/
|
||||
|
||||
|
||||
GUIDERAT
|
||||
0 'OIL' 1 0.5 1 1 0 0 'YES' 0.5 /
|
||||
|
||||
|
||||
WCONPROD
|
||||
'OPL02' 'OPEN' 'GRUP' 'WUOPRL' 2* 'WULPRL' 1* 60 /
|
||||
/
|
||||
|
||||
|
||||
WCONPROD
|
||||
'OPU02' 'OPEN' 'GRUP' 'WUOPRU' 2* 'WULPRU' 1* 60 /
|
||||
/
|
||||
|
||||
|
||||
DATES
|
||||
1 'SEP' 2018 /
|
||||
/
|
||||
|
||||
|
||||
WELOPEN
|
||||
'OPL01' 'OPEN' /
|
||||
/
|
||||
|
||||
|
||||
DATES
|
||||
1 'OCT' 2018 /
|
||||
/
|
||||
|
||||
|
||||
WELOPEN
|
||||
'WIL01' 'OPEN' /
|
||||
/
|
||||
|
||||
|
||||
DATES
|
||||
1 'NOV' 2018 /
|
||||
/
|
||||
|
||||
WCONPROD
|
||||
'OPL02' 'OPEN' 'GRUP' 100 2* 200 1* 60 /
|
||||
/
|
||||
|
||||
WELOPEN
|
||||
'OPL02' 'OPEN' /
|
||||
/
|
||||
|
||||
|
||||
DATES
|
||||
1 'DEC' 2018 /
|
||||
/
|
||||
|
||||
|
||||
WELOPEN
|
||||
'OPU01' 'OPEN' /
|
||||
/
|
||||
|
||||
|
||||
DATES
|
||||
1 'JAN' 2019 /
|
||||
/
|
||||
|
||||
|
||||
WELOPEN
|
||||
'OPU02' 'OPEN' /
|
||||
/
|
||||
|
||||
|
||||
DATES
|
||||
1 'FEB' 2019 /
|
||||
/
|
||||
|
||||
|
||||
WELOPEN
|
||||
'WIU01' 'OPEN' /
|
||||
/
|
||||
DATES
|
||||
1 'MAR' 2019 /
|
||||
1 'APR' 2019 /
|
||||
1 'MAY' 2019 /
|
||||
1 'JUN' 2019 /
|
||||
1 'JUL' 2019 /
|
||||
1 'JAN' 2020 /
|
||||
/
|
||||
)";
|
||||
318
tests/parser/data/integration_tests/udq2.data
Normal file
318
tests/parser/data/integration_tests/udq2.data
Normal file
@@ -0,0 +1,318 @@
|
||||
std::string deck_string = R"(
|
||||
RUNSPEC
|
||||
|
||||
TITLE
|
||||
2 PRODUCERS AND INJECTORS, 2 WELL GROUPS AND ONE INTERMEDIATE GROUP LEVEL BELOW THE FIELD LEVEL
|
||||
|
||||
DIMENS
|
||||
10 5 10 /
|
||||
|
||||
|
||||
OIL
|
||||
|
||||
WATER
|
||||
|
||||
GAS
|
||||
|
||||
DISGAS
|
||||
|
||||
FIELD
|
||||
|
||||
TABDIMS
|
||||
1 1 15 15 2 15 /
|
||||
|
||||
EQLDIMS
|
||||
2 /
|
||||
|
||||
WELLDIMS
|
||||
4 20 4 2 /
|
||||
|
||||
UNIFIN
|
||||
UNIFOUT
|
||||
|
||||
FMTIN
|
||||
FMTOUT
|
||||
-- Dimensions for used defined quantity facility
|
||||
-- max functions permitted in a quantity definition
|
||||
-- max arguments permitted in a quantity definition
|
||||
-- max user defined connection quantities
|
||||
-- max user defined field quantities
|
||||
-- max user defined group quantities
|
||||
-- max user defined region quantities
|
||||
-- max user defined segment quantities
|
||||
-- max user defined well quantities
|
||||
-- max user defined aquifer quantities
|
||||
-- max user defined block quantities
|
||||
-- whether new randon number generator seed computed for restart runs
|
||||
UDQDIMS
|
||||
50 25 0 50 50 0 0 50 0 20 /
|
||||
|
||||
-- Dimensions for the user defined arguments facility
|
||||
-- number of keyword arguments in which UDQs replace numerical values
|
||||
-- ratained for back-compatibility
|
||||
-- total number of unique instances in which a UDQ is used in a keyword argument
|
||||
UDADIMS
|
||||
10 1* 10 /
|
||||
|
||||
START
|
||||
1 'JAN' 2015 /
|
||||
|
||||
-- RPTRUNSP
|
||||
|
||||
GRID =========================================================
|
||||
|
||||
--NOGGF
|
||||
BOX
|
||||
1 10 1 5 1 1 /
|
||||
|
||||
TOPS
|
||||
50*7000 /
|
||||
|
||||
BOX
|
||||
1 10 1 5 1 10 /
|
||||
|
||||
DXV
|
||||
10*100 /
|
||||
DYV
|
||||
5*100 /
|
||||
DZV
|
||||
2*20 100 7*20 /
|
||||
|
||||
EQUALS
|
||||
-- 'DX' 100 /
|
||||
-- 'DY' 100 /
|
||||
'PERMX' 50 /
|
||||
'PERMZ' 5 /
|
||||
-- 'DZ' 20 /
|
||||
'PORO' 0.2 /
|
||||
-- 'TOPS' 7000 1 10 1 5 1 1 /
|
||||
--'DZ' 100 1 10 1 5 3 3 /
|
||||
'PORO' 0.0 1 10 1 5 3 3 /
|
||||
/
|
||||
|
||||
COPY
|
||||
PERMX PERMY /
|
||||
/
|
||||
|
||||
RPTGRID
|
||||
-- Report Levels for Grid Section Data
|
||||
--
|
||||
/
|
||||
|
||||
PROPS ==========================================================
|
||||
|
||||
-- WATER RELATIVE PERMEABILITY AND CAPILLARY PRESSURE ARE TABULATED AS
|
||||
-- A FUNCTION OF WATER SATURATION.
|
||||
--
|
||||
-- SWAT KRW PCOW
|
||||
SWFN
|
||||
|
||||
0.12 0 0
|
||||
1.0 0.00001 0 /
|
||||
|
||||
-- SIMILARLY FOR GAS
|
||||
--
|
||||
-- SGAS KRG PCOG
|
||||
SGFN
|
||||
|
||||
0 0 0
|
||||
0.02 0 0
|
||||
0.05 0.005 0
|
||||
0.12 0.025 0
|
||||
0.2 0.075 0
|
||||
0.25 0.125 0
|
||||
0.3 0.19 0
|
||||
0.4 0.41 0
|
||||
0.45 0.6 0
|
||||
0.5 0.72 0
|
||||
0.6 0.87 0
|
||||
0.7 0.94 0
|
||||
0.85 0.98 0
|
||||
1.0 1.0 0
|
||||
/
|
||||
|
||||
-- OIL RELATIVE PERMEABILITY IS TABULATED AGAINST OIL SATURATION
|
||||
-- FOR OIL-WATER AND OIL-GAS-CONNATE WATER CASES
|
||||
--
|
||||
-- SOIL KROW KROG
|
||||
SOF3
|
||||
|
||||
0 0 0
|
||||
0.18 0 0
|
||||
0.28 0.0001 0.0001
|
||||
0.38 0.001 0.001
|
||||
0.43 0.01 0.01
|
||||
0.48 0.021 0.021
|
||||
0.58 0.09 0.09
|
||||
0.63 0.2 0.2
|
||||
0.68 0.35 0.35
|
||||
0.76 0.7 0.7
|
||||
0.83 0.98 0.98
|
||||
0.86 0.997 0.997
|
||||
0.879 1 1
|
||||
0.88 1 1 /
|
||||
|
||||
|
||||
-- PVT PROPERTIES OF WATER
|
||||
--
|
||||
-- REF. PRES. REF. FVF COMPRESSIBILITY REF VISCOSITY VISCOSIBILITY
|
||||
PVTW
|
||||
4014.7 1.029 3.13D-6 0.31 0 /
|
||||
|
||||
-- ROCK COMPRESSIBILITY
|
||||
--
|
||||
-- REF. PRES COMPRESSIBILITY
|
||||
ROCK
|
||||
14.7 3.0D-6 /
|
||||
|
||||
-- SURFACE DENSITIES OF RESERVOIR FLUIDS
|
||||
--
|
||||
-- OIL WATER GAS
|
||||
DENSITY
|
||||
49.1 64.79 0.06054 /
|
||||
|
||||
-- PVT PROPERTIES OF DRY GAS (NO VAPOURISED OIL)
|
||||
-- WE WOULD USE PVTG TO SPECIFY THE PROPERTIES OF WET GAS
|
||||
--
|
||||
-- PGAS BGAS VISGAS
|
||||
PVDG
|
||||
14.7 166.666 0.008
|
||||
264.7 12.093 0.0096
|
||||
514.7 6.274 0.0112
|
||||
1014.7 3.197 0.014
|
||||
2014.7 1.614 0.0189
|
||||
2514.7 1.294 0.0208
|
||||
3014.7 1.080 0.0228
|
||||
4014.7 0.811 0.0268
|
||||
5014.7 0.649 0.0309
|
||||
9014.7 0.386 0.047 /
|
||||
|
||||
-- PVT PROPERTIES OF LIVE OIL (WITH DISSOLVED GAS)
|
||||
-- WE WOULD USE PVDO TO SPECIFY THE PROPERTIES OF DEAD OIL
|
||||
--
|
||||
-- FOR EACH VALUE OF RS THE SATURATION PRESSURE, FVF AND VISCOSITY
|
||||
-- ARE SPECIFIED. FOR RS=1.27 AND 1.618, THE FVF AND VISCOSITY OF
|
||||
-- UNDERSATURATED OIL ARE DEFINED AS A FUNCTION OF PRESSURE. DATA
|
||||
-- FOR UNDERSATURATED OIL MAY BE SUPPLIED FOR ANY RS, BUT MUST BE
|
||||
-- SUPPLIED FOR THE HIGHEST RS (1.618).
|
||||
--
|
||||
-- RS POIL FVFO VISO
|
||||
PVTO
|
||||
0.001 14.7 1.062 1.04 /
|
||||
0.0905 264.7 1.15 0.975 /
|
||||
0.18 514.7 1.207 0.91 /
|
||||
0.371 1014.7 1.295 0.83 /
|
||||
0.636 2014.7 1.435 0.695 /
|
||||
0.775 2514.7 1.5 0.641 /
|
||||
0.93 3014.7 1.565 0.594 /
|
||||
1.270 4014.7 1.695 0.51
|
||||
5014.7 1.671 0.549
|
||||
9014.7 1.579 0.74 /
|
||||
1.618 5014.7 1.827 0.449
|
||||
9014.7 1.726 0.605 /
|
||||
/
|
||||
|
||||
|
||||
RPTPROPS
|
||||
-- PROPS Reporting Options
|
||||
--
|
||||
/
|
||||
|
||||
REGIONS ===========================================================
|
||||
|
||||
|
||||
FIPNUM
|
||||
|
||||
100*1
|
||||
400*2
|
||||
/
|
||||
|
||||
EQLNUM
|
||||
|
||||
100*1
|
||||
400*2
|
||||
/
|
||||
|
||||
RPTREGS
|
||||
|
||||
/
|
||||
|
||||
SOLUTION ============================================================
|
||||
|
||||
EQUIL
|
||||
7020.00 2700.00 7990.00 .00000 7020.00 .00000 0 0 5 /
|
||||
7200.00 3700.00 7300.00 .00000 7000.00 .00000 1 0 5 /
|
||||
|
||||
RSVD 2 TABLES 3 NODES IN EACH FIELD 12:00 17 AUG 83
|
||||
7000.0 1.0000
|
||||
7990.0 1.0000
|
||||
/
|
||||
7000.0 1.0000
|
||||
7400.0 1.0000
|
||||
/
|
||||
|
||||
RPTRST
|
||||
-- Restart File Output Control
|
||||
--
|
||||
'BASIC=2' 'FLOWS' 'POT' 'PRES' /
|
||||
|
||||
|
||||
SUMMARY ===========================================================
|
||||
|
||||
FOPR
|
||||
|
||||
WOPR
|
||||
/
|
||||
|
||||
FGPR
|
||||
|
||||
FWPR
|
||||
|
||||
FWIR
|
||||
|
||||
FWCT
|
||||
|
||||
FGOR
|
||||
|
||||
--RUNSUM
|
||||
|
||||
ALL
|
||||
|
||||
MSUMLINS
|
||||
|
||||
MSUMNEWT
|
||||
|
||||
SEPARATE
|
||||
SCHEDULE ===========================================================
|
||||
|
||||
GRUPTREE
|
||||
'GRP1' 'FIELD' /
|
||||
'WGRP1' 'GRP1' /
|
||||
'WGRP2' 'GRP1' /
|
||||
/
|
||||
|
||||
WELSPECS
|
||||
'PROD1' 'WGRP1' 1 5 7030 'OIL' 0.0 'STD' 'STOP' /
|
||||
'PROD2' 'WGRP2' 1 5 7030 'OIL' 0.0 'STD' 'STOP' /
|
||||
'WINJ1' 'WGRP1' 10 1 7030 'WAT' 0.0 'STD' 'STOP' /
|
||||
'WINJ2' 'WGRP2' 10 1 7030 'WAT' 0.0 'STD' 'STOP' /
|
||||
/
|
||||
|
||||
COMPDAT
|
||||
|
||||
'PROD1' 1 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD1' 2 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD1' 3 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD2' 4 5 2 2 3* 0.2 3* 'X' /
|
||||
'PROD2' 5 5 2 2 3* 0.2 3* 'X' /
|
||||
|
||||
'WINJ1' 10 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ1' 9 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ1' 8 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ2' 7 1 9 9 3* 0.2 3* 'X' /
|
||||
'WINJ2' 6 1 9 9 3* 0.2 3* 'X' /
|
||||
/
|
||||
|
||||
|
||||
|
||||
)";
|
||||
354
tests/test_AggregateUDQData.cpp
Normal file
354
tests/test_AggregateUDQData.cpp
Normal file
@@ -0,0 +1,354 @@
|
||||
#define BOOST_TEST_MODULE UDQ_Data
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
|
||||
#include <opm/output/eclipse/AggregateUDQData.hpp>
|
||||
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
|
||||
|
||||
#include <opm/output/eclipse/InteHEAD.hpp>
|
||||
#include <opm/output/eclipse/VectorItems/intehead.hpp>
|
||||
#include <opm/output/eclipse/DoubHEAD.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
|
||||
//#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 <opm/io/eclipse/OutputStream.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
Opm::Deck first_sim(std::string fname) {
|
||||
return Opm::Parser{}.parseFile(fname);
|
||||
}
|
||||
|
||||
Opm::UDQActive udq_active() {
|
||||
int update_count = 0;
|
||||
// construct record data for udq_active
|
||||
Opm::UDQParams params;
|
||||
Opm::UDQConfig conf(params);
|
||||
Opm::UDQActive udq_act;
|
||||
Opm::UDAValue uda1("WUOPRL");
|
||||
update_count += udq_act.update(conf, uda1, "PROD1", Opm::UDAControl::WCONPROD_ORAT);
|
||||
|
||||
Opm::UDAValue uda2("WULPRL");
|
||||
update_count += udq_act.update(conf, uda2, "PROD1", Opm::UDAControl::WCONPROD_LRAT);
|
||||
Opm::UDAValue uda3("WUOPRU");
|
||||
update_count += udq_act.update(conf, uda3, "PROD2", Opm::UDAControl::WCONPROD_ORAT);
|
||||
Opm::UDAValue uda4("WULPRU");
|
||||
update_count += udq_act.update(conf, uda4, "PROD2", Opm::UDAControl::WCONPROD_LRAT);
|
||||
|
||||
for (std::size_t index=0; index < udq_act.IUAD_size(); index++)
|
||||
{
|
||||
const auto & record = udq_act[index];
|
||||
auto ind = record.input_index;
|
||||
auto udq_key = record.udq;
|
||||
auto name = record.wgname;
|
||||
auto ctrl_type = record.control;
|
||||
}
|
||||
return udq_act;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int main(int argc, char* argv[])
|
||||
struct SimulationCase
|
||||
{
|
||||
explicit SimulationCase(const Opm::Deck& deck)
|
||||
: es { deck }
|
||||
, grid { deck }
|
||||
, sched{ deck, es }
|
||||
{}
|
||||
|
||||
// Order requirement: 'es' must be declared/initialised before 'sched'.
|
||||
Opm::EclipseState es;
|
||||
Opm::EclipseGrid grid;
|
||||
Opm::Schedule sched;
|
||||
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Aggregate_UDQ)
|
||||
|
||||
|
||||
|
||||
// test constructed UDQ restart data
|
||||
BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
|
||||
{
|
||||
const auto simCase = SimulationCase{first_sim("UDQ_TEST_WCONPROD_IUAD-2.DATA")};
|
||||
|
||||
Opm::EclipseState es = simCase.es;
|
||||
Opm::Schedule sched = simCase.sched;
|
||||
Opm::EclipseGrid grid = simCase.grid;
|
||||
const auto& ioConfig = es.getIOConfig();
|
||||
const auto& restart = es.cfg().restart();
|
||||
//Opm::UDQActive udq_act = udq_active();
|
||||
|
||||
// Report Step 1: 2008-10-10 --> 2011-01-20
|
||||
const auto rptStep = std::size_t{1};
|
||||
|
||||
std::string outputDir = "./";
|
||||
std::string baseName = "TEST_UDQRST";
|
||||
Opm::EclIO::OutputStream::Restart rstFile {
|
||||
Opm::EclIO::OutputStream::ResultSet { outputDir, baseName },
|
||||
rptStep,
|
||||
Opm::EclIO::OutputStream::Formatted { ioConfig.getFMTOUT() },
|
||||
Opm::EclIO::OutputStream::Unified { ioConfig.getUNIFOUT() }
|
||||
};
|
||||
|
||||
double secs_elapsed = 3.1536E07;
|
||||
const auto ih = Opm::RestartIO::Helpers::createInteHead(es, grid, sched,
|
||||
secs_elapsed, rptStep, rptStep);
|
||||
//set dummy value for next_step_size
|
||||
const double next_step_size= 0.1;
|
||||
const auto dh = Opm::RestartIO::Helpers::createDoubHead(es, sched, rptStep,
|
||||
secs_elapsed, next_step_size);
|
||||
|
||||
const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih);
|
||||
auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims);
|
||||
udqData.captureDeclaredUDQData(sched, rptStep, ih);
|
||||
|
||||
rstFile.write("IUDQ", udqData.getIUDQ());
|
||||
rstFile.write("IUAD", udqData.getIUAD());
|
||||
rstFile.write("IGPH", udqData.getIGPH());
|
||||
rstFile.write("IUAP", udqData.getIUAP());
|
||||
rstFile.write("ZUDN", udqData.getZUDN());
|
||||
rstFile.write("ZUDL", udqData.getZUDL());
|
||||
|
||||
{
|
||||
/*
|
||||
Check of InteHEAD and DoubHEAD data for UDQ variables
|
||||
|
||||
INTEHEAD
|
||||
|
||||
UDQPARAM (1) = - InteHead [267 ]
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
DOUBHEAD
|
||||
|
||||
UDQPARAM (2) = Doubhead [212]
|
||||
UDQPARAM (3) = Doubhead [213]
|
||||
UDQPARAM (4) = Doubhead [214]
|
||||
|
||||
*/
|
||||
|
||||
BOOST_CHECK_EQUAL(ih[267] , -1);
|
||||
BOOST_CHECK_EQUAL(dh[212] , 1.0E+20);
|
||||
BOOST_CHECK_EQUAL(dh[213] , 0.0);
|
||||
BOOST_CHECK_EQUAL(dh[214] , 1.0E-4);
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
/*
|
||||
IUDQ
|
||||
3- integers pr UDQ (line/quantity)
|
||||
|
||||
Integer no 1 = type of UDQ ( 0 - ASSIGN, UPDATE-OFF
|
||||
1-update+NEXT,
|
||||
2 - DEFINE, 2- UPDATE-ON
|
||||
3 - units)
|
||||
|
||||
Integer no 2 = -4 : used for ASSIGN - numerical value
|
||||
-4 : used for DEFINE
|
||||
-1 : used for DEFINE MIN() function, SUM() function, AVEA() function
|
||||
-4 : used for DEFINE MAX() - function - also used for SUM() function - must check on (-1 - value)
|
||||
1 : used for UPDATE quantity
|
||||
|
||||
Integer no 3 = sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
(1 - based)
|
||||
|
||||
NOTE: UPDATE - does not define a new quantity, only updates an alredy defined quantity!
|
||||
*/
|
||||
|
||||
|
||||
const auto& iUdq = udqData.getIUDQ();
|
||||
|
||||
auto start = 0*udqDims[1];
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 0] , 2); // udq NO. 1 - ( 0 - ASSIGN, 2 - DEFINE)
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 1] , -4); // udq NO. 1 - (-4 - DEFINE / ASSIGN
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 2] , 1); // udq NO. 1 - (sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
|
||||
start = 1*udqDims[1];
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 0] , 0); // udq NO. 2 - ( 0 - ASSIGN, 2 - DEFINE)
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 1] , -4); // udq NO. 2 - (-4 - DEFINE / ASSIGN
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 2] , 2); // udq NO. 2 - (sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
|
||||
start = 2*udqDims[1];
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 0] , 2); // udq NO. 2 - ( 0 - ASSIGN, 2 - DEFINE)
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 1] , -4); // udq NO. 2 - (-4 - DEFINE / ASSIGN
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 2] , 3); // udq NO. 2 - (sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
|
||||
start = 3*udqDims[1];
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 0] , 2); // udq NO. 2 - ( 0 - ASSIGN, 2 - DEFINE)
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 1] , -4); // udq NO. 2 - (-4 - DEFINE / ASSIGN
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 2] , 1); // udq NO. 2 - (sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
|
||||
start = 4*udqDims[1];
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 0] , 2); // udq NO. 2 - ( 0 - ASSIGN, 2 - DEFINE)
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 1] , -4); // udq NO. 2 - (-4 - DEFINE / ASSIGN
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 2] , 4); // udq NO. 2 - (sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
|
||||
start = 5*udqDims[1];
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 0] , 2); // udq NO. 2 - ( 0 - ASSIGN, 2 - DEFINE)
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 1] , -4); // udq NO. 2 - (-4 - DEFINE / ASSIGN
|
||||
BOOST_CHECK_EQUAL(iUdq[start + 2] , 1); // udq NO. 2 - (sequence number of UDQ pr type (CU, FU, GU, RU, , SU, WU, AU or BU etc.)
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
IUAD:
|
||||
Sequences of 5 items pr UDQ that is used for various well and group controls,
|
||||
i.e. sorted on the various active controls, see list for item (1).This means that
|
||||
one udq can occur several times, one for each control it is used for
|
||||
Only the active controls are output - and the sequence is according to when
|
||||
they are defined
|
||||
|
||||
dimension 5*no_of_udq-constraint-used in well and group controls
|
||||
|
||||
item (1) : = 200000 + 19 for GCONPROD and ORAT
|
||||
300000 + 19 for GCONPROD and WRAT
|
||||
400000 + 19 for GCONPROD and GRAT
|
||||
500000 + 19 for GCONPROD and LRAT
|
||||
300000 + 4 for WCONPROD + oil rate target or upper limit
|
||||
400000 + 4 for WCONPROD + water rate target or upper limit
|
||||
500000 + 4 for WCONPROD + gas rate target or upper limit
|
||||
600000 + 4 for WCONPROD + liquid rate target or upper limit
|
||||
? 300000 + 3 for WCONINJE + oil rate target or upper limit
|
||||
400000 + 3 for WCONINJE + surface rate target or upper limit
|
||||
500000 + 3 for WCONINJE + reservoir volume rate target or upper limit
|
||||
1000000 + 27 for CECON + minimum oil rate
|
||||
|
||||
item (2) - sequence number of UDQ used (from input sequence) for the actual constraint/target
|
||||
|
||||
item (3) - do not know yet (value: 1)
|
||||
item (4) - number of times the UDQ variable is used (e.g. for several different wells)
|
||||
item (5) - the sequence number for the first use of the actual UDQ (index i+1) = 1+sum over <the first i udq's in use >(no_use_udq(i))
|
||||
*/
|
||||
|
||||
const auto& iUad = udqData.getIUAD();
|
||||
|
||||
auto start = 0*udqDims[3];
|
||||
BOOST_CHECK_EQUAL(iUad[start + 0] , 300004); // iuad NO. 1
|
||||
BOOST_CHECK_EQUAL(iUad[start + 1] , 3); // iuad NO. 1
|
||||
BOOST_CHECK_EQUAL(iUad[start + 2] , 1); // iuad NO. 1
|
||||
BOOST_CHECK_EQUAL(iUad[start + 3] , 2); // iuad NO. 1
|
||||
BOOST_CHECK_EQUAL(iUad[start + 4] , 1); // iuad NO. 1
|
||||
|
||||
start = 1*udqDims[3];
|
||||
BOOST_CHECK_EQUAL(iUad[start + 0] , 600004); // iuad NO. 2
|
||||
BOOST_CHECK_EQUAL(iUad[start + 1] , 5); // iuad NO. 2
|
||||
BOOST_CHECK_EQUAL(iUad[start + 2] , 1); // iuad NO. 2
|
||||
BOOST_CHECK_EQUAL(iUad[start + 3] , 2); // iuad NO. 2
|
||||
BOOST_CHECK_EQUAL(iUad[start + 4] , 3); // iuad NO. 2
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
ZUDN:
|
||||
contains UDQ keyword data:
|
||||
Pairs of:
|
||||
quantity name (item2): e.g. 'WUOPRL ' and
|
||||
units: e.g.: 'SM3/DAY '
|
||||
|
||||
Length is dependent on number of UDQ quantities = 2*no of UDQ's
|
||||
*/
|
||||
|
||||
const auto& zUdn = udqData.getZUDN();
|
||||
|
||||
auto start = 0*udqDims[4];
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 0].c_str() , "WUOPRL "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 1].c_str() , "SM3/DAY "); // udq NO. 1
|
||||
|
||||
start = 1*udqDims[4];
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 0].c_str() , "WULPRL "); // udq NO. 2
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 1].c_str() , "SM3/DAY "); // udq NO. 2
|
||||
|
||||
start = 2*udqDims[4];
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 0].c_str() , "WUOPRU "); // udq NO. 3
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 1].c_str() , "SM3/DAY "); // udq NO. 3
|
||||
|
||||
start = 3*udqDims[4];
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 0].c_str() , "GUOPRU "); // udq NO. 4
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 1].c_str() , "SM3/DAY "); // udq NO. 4
|
||||
|
||||
start = 4*udqDims[4];
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 0].c_str() , "WULPRU "); // udq NO. 5
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 1].c_str() , "SM3/DAY "); // udq NO. 5
|
||||
|
||||
start = 5*udqDims[4];
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 0].c_str() , "FULPR "); // udq NO. 6
|
||||
BOOST_CHECK_EQUAL(zUdn[start + 1].c_str() , "SM3/DAY "); // udq NO. 6
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
/*
|
||||
ZUDL:
|
||||
contains string that define the "Data for operation" for the defined quantity
|
||||
|
||||
e.g.
|
||||
'(WOPR OP' 'L01 - 15' '0) * 0.9' '0 ' ' ' ' ' ' '
|
||||
|
||||
The appropriate data are split into strings of 8 characters each.
|
||||
|
||||
Length: No of UDQ's * 16
|
||||
*/
|
||||
|
||||
const auto& zUdl = udqData.getZUDL();
|
||||
|
||||
auto start = 0*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WOPR PR"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "OD1 - 17"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.6"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
|
||||
|
||||
/*start = 1*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WLPR PR"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "OD1 - 20"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.9"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
|
||||
*/
|
||||
|
||||
start = 3*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(GOPR WG"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "RP2 - 44"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "9) * 0.7"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "7 "); // udq NO. 1
|
||||
|
||||
start = 5*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(FLPR - "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "543) * 0"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , ".65 "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , " "); // udq NO. 1
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Reference in New Issue
Block a user