Initial work to add Actionx data to Eclipse compatible restart file
further changes to Actionx - restart further changes for Actionx data to Restart file additional changes to output Actionx data to Restart file add test data for UDQ-ACTIONX changes to add unit tests for InteHead - Actionx Added changes to allow for output of IACT, SACT and ZACT to the E100 compatible restart file changes to add ZLACT to restart output Further changes - add ZACN - prelim further changes to add ZACN to restart file Additional changes to output IACN and SACN to restart further changes to add IACN and SACN to the restart file further changes to make unit tests for Actionx data / keywords further changes to actionx restart and unit tests therefore Added code for unit tests - not finished some changes to correct for changes in upstream/master changes correct errors in IACN and SACN Initial work to add Actionx data to Eclipse compatible restart file further changes to Actionx - restart further changes for Actionx data to Restart file additional changes to output Actionx data to Restart file add test data for UDQ-ACTIONX changes to add unit tests for InteHead - Actionx Added changes to allow for output of IACT, SACT and ZACT to the E100 compatible restart file changes to add ZLACT to restart output Further changes - add ZACN - prelim further changes to add ZACN to restart file Additional changes to output IACN and SACN to restart further changes to add IACN and SACN to the restart file further changes to make unit tests for Actionx data / keywords further changes to actionx restart and unit tests therefore Added code for unit tests - not finished some changes to correct for changes in upstream/master changes correct errors in IACN and SACN changes to avoid change in output data for restart file further changes to avoid change in RESTART data minor change to avoid data change in Restart file
This commit is contained in:
committed by
Joakim Hove
parent
1db06277ce
commit
7973585db0
587
src/opm/output/eclipse/AggregateActionxData.cpp
Normal file
587
src/opm/output/eclipse/AggregateActionxData.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
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/AggregateActionxData.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/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/Action/ActionX.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 {
|
||||
const std::map<std::string, int> lhsQuantityToIndex = {
|
||||
{"F", 1},
|
||||
{"W", 2},
|
||||
{"G", 3},
|
||||
{"D", 10},
|
||||
{"M", 11},
|
||||
{"Y", 12},
|
||||
};
|
||||
|
||||
const std::map<std::string, double> monthToNo = {
|
||||
{"JAN", 1.},
|
||||
{"FEB", 2.},
|
||||
{"MAR", 3.},
|
||||
{"APR", 4.},
|
||||
{"MAY", 5.},
|
||||
{"JUN", 6.},
|
||||
{"JUL", 7.},
|
||||
{"AUG", 8.},
|
||||
{"SEP", 9.},
|
||||
{"OCT", 10.},
|
||||
{"NOV", 11.},
|
||||
{"DEC", 12.},
|
||||
};
|
||||
|
||||
|
||||
const std::map<std::string, int> rhsQuantityToIndex = {
|
||||
{"F", 1},
|
||||
{"W", 2},
|
||||
{"G", 3},
|
||||
};
|
||||
|
||||
using logic_enum = Opm::Action::Condition::Logical;
|
||||
const std::map<logic_enum, int> logicalToIndex_13 = {
|
||||
{logic_enum::AND, 1},
|
||||
{logic_enum::OR, 2},
|
||||
{logic_enum::END, 0},
|
||||
};
|
||||
|
||||
const std::map<logic_enum, int> logicalToIndex_17 = {
|
||||
{logic_enum::AND, 1},
|
||||
{logic_enum::OR, 0},
|
||||
{logic_enum::END, 0},
|
||||
};
|
||||
|
||||
|
||||
using cmp_enum = Opm::Action::Condition::Comparator;
|
||||
const std::map<cmp_enum, int> cmpToIndex = {
|
||||
{cmp_enum::GREATER, 1},
|
||||
{cmp_enum::LESS, 2},
|
||||
{cmp_enum::GREATER_EQUAL, 3},
|
||||
{cmp_enum::LESS_EQUAL, 4},
|
||||
{cmp_enum::EQUAL, 5},
|
||||
{cmp_enum::INVALID, 0},
|
||||
};
|
||||
|
||||
|
||||
namespace iACT {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<int>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[1]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class IACTArray>
|
||||
void staticContrib(const Opm::Action::ActionX& actx, IACTArray& iAct)
|
||||
{
|
||||
//item [0]: is unknown, (=0)
|
||||
iAct[0] = 0;
|
||||
//item [1]: The number of lines of schedule data including ENDACTIO
|
||||
iAct[1] = actx.keyword_strings().size();
|
||||
//item [2]: is unknown, (=1)
|
||||
iAct[2] = 1;
|
||||
//item [3]: is unknown, (=7)
|
||||
iAct[3] = 7;
|
||||
//item [4]: is unknown, (=0)
|
||||
iAct[4] = 0;
|
||||
//item [5]: The number of times the action is triggered
|
||||
iAct[5] = actx.max_run();
|
||||
//item [6]: is unknown, (=0)
|
||||
iAct[6] = 0;
|
||||
//item [7]: is unknown, (=0)
|
||||
iAct[7] = 0;
|
||||
//item [8]: The number of times the action is triggered
|
||||
iAct[8] = actx.conditions().size();
|
||||
}
|
||||
|
||||
} // iAct
|
||||
|
||||
namespace sACT {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<float>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<float>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[2]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class SACTArray>
|
||||
void staticContrib(SACTArray& sAct)
|
||||
{
|
||||
//item [0 - 4]: is unknown, (=0)
|
||||
for (std::size_t ind = 0; ind < 5 ; ind++) {
|
||||
sAct[ind] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // sAct
|
||||
|
||||
namespace zACT {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>;
|
||||
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[3]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class ZACTArray>
|
||||
void staticContrib(const Opm::Action::ActionX& actx, ZACTArray& zAct)
|
||||
{
|
||||
// entry 1 is udq keyword
|
||||
zAct[0] = actx.name();
|
||||
}
|
||||
} // zAct
|
||||
|
||||
namespace zLACT {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>;
|
||||
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[4]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class ZLACTArray>
|
||||
void staticContrib(const Opm::Action::ActionX& actx, int noEPrZlact, ZLACTArray& zLact)
|
||||
{
|
||||
std::size_t ind = 0;
|
||||
int l_sstr = 8;
|
||||
int max_l_str = 128;
|
||||
// write out the schedule input lines
|
||||
const auto& schedule_data = actx.keyword_strings();
|
||||
for (auto z_data : schedule_data) {
|
||||
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("Actionx: " + actx.name());
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < n_sstr; i++) {
|
||||
zLact[ind + i] = z_data.substr(i*l_sstr, l_sstr);
|
||||
}
|
||||
//add remainder of last non-zero string
|
||||
if ((z_data.size() % l_sstr) > 0)
|
||||
zLact[ind + n_sstr] = z_data.substr(n_sstr*l_sstr);
|
||||
}
|
||||
ind += static_cast<std::size_t>(noEPrZlact);
|
||||
}
|
||||
}
|
||||
} // zLact
|
||||
|
||||
namespace zACN {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<
|
||||
Opm::EclIO::PaddedOutputString<8>
|
||||
>;
|
||||
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[5]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class ZACNArray>
|
||||
void staticContrib(const Opm::Action::ActionX& actx, ZACNArray& zAcn)
|
||||
{
|
||||
std::size_t ind = 0;
|
||||
int noEPZacn = 13;
|
||||
// write out the schedule Actionx conditions
|
||||
const auto& actx_cond = actx.conditions();
|
||||
for (auto z_data : actx_cond) {
|
||||
// left hand quantity
|
||||
if ((z_data.lhs.quantity.substr(0,1) != "D") &&
|
||||
(z_data.lhs.quantity.substr(0,1) != "M") &&
|
||||
(z_data.lhs.quantity.substr(0,1) != "Y"))
|
||||
zAcn[ind + 0] = z_data.lhs.quantity;
|
||||
// right hand quantity
|
||||
if ((z_data.rhs.quantity.substr(0,1) == "W") ||
|
||||
(z_data.rhs.quantity.substr(0,1) == "G"))
|
||||
zAcn[ind + 1] = z_data.rhs.quantity;
|
||||
// operator (comparator)
|
||||
zAcn[ind + 2] = z_data.cmp_string;
|
||||
// well-name if left hand quantity is a well quantity
|
||||
if (z_data.lhs.quantity.substr(0,1) == "W") {
|
||||
zAcn[ind + 3] = z_data.lhs.args[0];
|
||||
}
|
||||
// well-name if right hand quantity is a well quantity
|
||||
if (z_data.rhs.quantity.substr(0,1) == "W") {
|
||||
zAcn[ind + 4] = z_data.rhs.args[0];
|
||||
}
|
||||
|
||||
// group-name if left hand quantity is a group quantity
|
||||
if (z_data.lhs.quantity.substr(0,1) == "G") {
|
||||
zAcn[ind + 5] = z_data.lhs.args[0];
|
||||
}
|
||||
// group-name if right hand quantity is a group quantity
|
||||
if (z_data.rhs.quantity.substr(0,1) == "G") {
|
||||
zAcn[ind + 6] = z_data.rhs.args[0];
|
||||
}
|
||||
|
||||
//increment index according to no of items pr condition
|
||||
ind += static_cast<std::size_t>(noEPZacn);
|
||||
}
|
||||
}
|
||||
} // zAcn
|
||||
|
||||
}
|
||||
|
||||
namespace iACN {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<int>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[6]) }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class IACNArray>
|
||||
void staticContrib(const Opm::Action::ActionX& actx, IACNArray& iAcn)
|
||||
{
|
||||
//item [0 - 9]: are unknown, (=0)
|
||||
|
||||
/*item [10] type of quantity for condition
|
||||
1 for a field quantity (number of flowing producing wells)
|
||||
2 for a well quantity
|
||||
3 for a (node) group quantity
|
||||
//9 for a well group quantity
|
||||
10 for DAY
|
||||
11 for MNTH
|
||||
12 for YEAR
|
||||
*/
|
||||
std::size_t ind = 0;
|
||||
int noEPZacn = 26;
|
||||
// write out the schedule Actionx conditions
|
||||
const auto& actx_cond = actx.conditions();
|
||||
for (auto cond_it = actx_cond.begin(); cond_it < actx_cond.end(); cond_it++) {
|
||||
auto z_data = *cond_it;
|
||||
// left hand quantity
|
||||
std::string lhsQtype = z_data.lhs.quantity.substr(0,1);
|
||||
const auto it_lhsq = lhsQuantityToIndex.find(lhsQtype);
|
||||
if (it_lhsq != lhsQuantityToIndex.end()) {
|
||||
iAcn[ind + 10] = it_lhsq->second;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown condition type: " << z_data.lhs.quantity << std::endl;
|
||||
throw std::invalid_argument("Actionx: " + actx.name());
|
||||
}
|
||||
|
||||
/*item[11] - quantity type for rhs quantity
|
||||
1 - for field variables
|
||||
2 - for well variables?
|
||||
3 - for group variables
|
||||
8 - for constant values
|
||||
*/
|
||||
iAcn[ind + 11] = 8;
|
||||
std::string rhsQtype = z_data.rhs.quantity.substr(0,1);
|
||||
const auto it_rhsq = rhsQuantityToIndex.find(rhsQtype);
|
||||
if (it_rhsq != rhsQuantityToIndex.end()) {
|
||||
iAcn[ind + 11] = it_rhsq->second;
|
||||
}
|
||||
|
||||
/*item[12] - index for lhs type
|
||||
1 - for MNTH
|
||||
0 - for all other types
|
||||
*/
|
||||
std::string lhsQ = z_data.lhs.quantity;
|
||||
if ( lhsQ == "MNTH") {
|
||||
iAcn[ind + 12] = 1;
|
||||
}
|
||||
|
||||
/*item [13] - relates to operator
|
||||
OR is 2
|
||||
AND is 1
|
||||
*/
|
||||
const auto it_logic_13 = logicalToIndex_13.find(z_data.logic);
|
||||
if (it_logic_13 != logicalToIndex_13.end()) {
|
||||
iAcn[ind + 13] = it_logic_13->second;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown Boolean operator type for condition: " << z_data.lhs.quantity << std::endl;
|
||||
throw std::invalid_argument("Actionx: " + actx.name());
|
||||
}
|
||||
|
||||
/*item [16] - related to the operater used in ACTIONX for defined quantities
|
||||
> is 1
|
||||
< is 2
|
||||
>= is 3
|
||||
<= is 4
|
||||
= is 5
|
||||
*/
|
||||
const auto it_cmp = cmpToIndex.find(z_data.cmp);
|
||||
if (it_cmp != cmpToIndex.end()) {
|
||||
iAcn[ind + 16] = it_cmp->second;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown operator type for condition: " << z_data.lhs.quantity << std::endl;
|
||||
throw std::invalid_argument("Actionx: " + actx.name());
|
||||
}
|
||||
|
||||
/*item [17] - relates to operator and if the right hand condition is a constant or not
|
||||
* First condition => [17] = 0
|
||||
* Second+ conditions
|
||||
*If the previous condition has a constant rhs => [17] = 0
|
||||
*If rhs is {W,G, F} and
|
||||
*If previous condition is AND => [17] = 1
|
||||
*If previous condition is OR => [17] = 0
|
||||
*/
|
||||
if (cond_it > actx_cond.begin()) {
|
||||
const std::string prev_rhs_quant = (cond_it-1)->rhs.quantity.substr(0,1);
|
||||
const auto it_prev_rhs = rhsQuantityToIndex.find(prev_rhs_quant);
|
||||
if (it_prev_rhs != rhsQuantityToIndex.end()) {
|
||||
const auto it_logic_17 = logicalToIndex_17.find((cond_it-1)->logic);
|
||||
if (it_logic_17 != logicalToIndex_17.end()) {
|
||||
iAcn[ind + 17] = it_logic_17->second;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown Boolean operator type for condition: " << z_data.lhs.quantity << std::endl;
|
||||
throw std::invalid_argument("Actionx: " + actx.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
//increment index according to no of items pr condition
|
||||
ind += static_cast<std::size_t>(noEPZacn);
|
||||
}
|
||||
}
|
||||
} // iAcn
|
||||
|
||||
namespace sACN {
|
||||
|
||||
Opm::RestartIO::Helpers::WindowedArray<double>
|
||||
allocate(const std::vector<int>& actDims)
|
||||
{
|
||||
using WV = Opm::RestartIO::Helpers::WindowedArray<double>;
|
||||
return WV {
|
||||
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
|
||||
WV::WindowSize{ static_cast<std::size_t>(actDims[7]) }
|
||||
};
|
||||
}
|
||||
|
||||
template <class SACNArray>
|
||||
void staticContrib(const Opm::Action::ActionX& actx,
|
||||
const Opm::SummaryState& st,
|
||||
SACNArray& sAcn)
|
||||
{
|
||||
std::size_t ind = 0;
|
||||
int noEPZacn = 16;
|
||||
double undef_high_val = 1.0E+20;
|
||||
// write out the schedule Actionx conditions
|
||||
const auto& actx_cond = actx.conditions();
|
||||
for (const auto& z_data : actx_cond) {
|
||||
|
||||
// item [0 - 1] = 0 (unknown)
|
||||
sAcn[ind + 0] = 0.;
|
||||
sAcn[ind + 1] = 0.;
|
||||
|
||||
//item [2, 5, 7, 9]: value of condition 1 (zero if well, group or field variable
|
||||
const std::string& rhsQtype = z_data.rhs.quantity.substr(0,1);
|
||||
const auto& it_rhsq = rhsQuantityToIndex.find(rhsQtype);
|
||||
if (it_rhsq == rhsQuantityToIndex.end()) {
|
||||
//come here if constant value condition
|
||||
double t_val = 0.;
|
||||
if (rhsQtype == "M") {
|
||||
const auto& it_mnth = monthToNo.find(z_data.rhs.quantity);
|
||||
if (it_mnth != monthToNo.end()) {
|
||||
t_val = it_mnth->second;
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown Month: " << z_data.rhs.quantity << std::endl;
|
||||
throw std::invalid_argument("Actionx: " + actx.name() + " Condition: " + z_data.lhs.quantity );
|
||||
}
|
||||
}
|
||||
else {
|
||||
t_val = std::stod(z_data.rhs.quantity);
|
||||
}
|
||||
sAcn[ind + 2] = t_val;
|
||||
sAcn[ind + 5] = sAcn[ind + 2];
|
||||
sAcn[ind + 7] = sAcn[ind + 2];
|
||||
sAcn[ind + 9] = sAcn[ind + 2];
|
||||
}
|
||||
//Treat well, group and field right hand side conditions
|
||||
if (it_rhsq != rhsQuantityToIndex.end()) {
|
||||
//Well variable
|
||||
if (it_rhsq->first == "W") {
|
||||
sAcn[ind + 4] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 5] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 6] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 7] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 8] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 9] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
}
|
||||
//group variable
|
||||
if (it_rhsq->first == "G") {
|
||||
sAcn[ind + 4] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 5] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 6] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 7] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 8] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
sAcn[ind + 9] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
|
||||
}
|
||||
//field variable
|
||||
if (it_rhsq->first == "F") {
|
||||
sAcn[ind + 4] = st.get(z_data.rhs.quantity);
|
||||
sAcn[ind + 5] = st.get(z_data.rhs.quantity);
|
||||
sAcn[ind + 6] = st.get(z_data.rhs.quantity);
|
||||
sAcn[ind + 7] = st.get(z_data.rhs.quantity);
|
||||
sAcn[ind + 8] = st.get(z_data.rhs.quantity);
|
||||
sAcn[ind + 9] = st.get(z_data.rhs.quantity);
|
||||
}
|
||||
}
|
||||
|
||||
//treat cases with left hand side condition being: DAY, MNTH og YEAR variable
|
||||
const std::string& lhsQtype = z_data.lhs.quantity.substr(0,1);
|
||||
const auto& it_lhsq = lhsQuantityToIndex.find(lhsQtype);
|
||||
if ((it_lhsq->first == "D") || (it_lhsq->first == "M") || (it_lhsq->first == "Y")) {
|
||||
sAcn[ind + 4] = undef_high_val;
|
||||
sAcn[ind + 5] = undef_high_val;
|
||||
sAcn[ind + 6] = undef_high_val;
|
||||
sAcn[ind + 7] = undef_high_val;
|
||||
sAcn[ind + 8] = undef_high_val;
|
||||
sAcn[ind + 9] = undef_high_val;
|
||||
}
|
||||
|
||||
//increment index according to no of items pr condition
|
||||
ind += static_cast<std::size_t>(noEPZacn);
|
||||
}
|
||||
}
|
||||
|
||||
} // sAcn
|
||||
|
||||
|
||||
// =====================================================================
|
||||
|
||||
Opm::RestartIO::Helpers::AggregateActionxData::
|
||||
AggregateActionxData(const std::vector<int>& actDims)
|
||||
: iACT_ (iACT::allocate(actDims)),
|
||||
sACT_ (sACT::allocate(actDims)),
|
||||
zACT_ (zACT::allocate(actDims)),
|
||||
zLACT_(zLACT::allocate(actDims)),
|
||||
zACN_ (zACN::allocate(actDims)),
|
||||
iACN_ (iACN::allocate(actDims)),
|
||||
sACN_ (sACN::allocate(actDims))
|
||||
{}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void
|
||||
Opm::RestartIO::Helpers::AggregateActionxData::
|
||||
captureDeclaredActionxData( const Opm::Schedule& sched,
|
||||
const Opm::SummaryState& st,
|
||||
const std::vector<int>& actDims,
|
||||
const std::size_t simStep)
|
||||
{
|
||||
auto acts = sched.actions(simStep);
|
||||
std::size_t act_ind = 0;
|
||||
for (auto actx_it = acts.begin(); actx_it < acts.end(); actx_it++) {
|
||||
{
|
||||
auto i_act = this->iACT_[act_ind];
|
||||
iACT::staticContrib(*actx_it, i_act);
|
||||
}
|
||||
|
||||
{
|
||||
auto s_act = this->sACT_[act_ind];
|
||||
sACT::staticContrib(s_act);
|
||||
}
|
||||
|
||||
{
|
||||
auto z_act = this->zACT_[act_ind];
|
||||
zACT::staticContrib(*actx_it, z_act);
|
||||
}
|
||||
|
||||
{
|
||||
auto z_lact = this->zLACT_[act_ind];
|
||||
zLACT::staticContrib(*actx_it, actDims[8], z_lact);
|
||||
}
|
||||
|
||||
{
|
||||
auto z_acn = this->zACN_[act_ind];
|
||||
zACN::staticContrib(*actx_it, z_acn);
|
||||
}
|
||||
|
||||
{
|
||||
auto i_acn = this->iACN_[act_ind];
|
||||
iACN::staticContrib(*actx_it, i_acn);
|
||||
}
|
||||
|
||||
{
|
||||
auto s_acn = this->sACN_[act_ind];
|
||||
sACN::staticContrib(*actx_it, st, s_acn);
|
||||
}
|
||||
|
||||
act_ind +=1;
|
||||
}
|
||||
}
|
||||
|
||||
139
src/opm/output/eclipse/CreateActionxDims.cpp
Executable file
139
src/opm/output/eclipse/CreateActionxDims.cpp
Executable file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
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/Schedule/Action/ActionX.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 {
|
||||
|
||||
// The number of actions (no of Actionx)
|
||||
std::size_t noOfActions(const Opm::Action::Actions& acts)
|
||||
{
|
||||
std::size_t no_entries = acts.size();
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
|
||||
std::size_t entriesPerIACT()
|
||||
{
|
||||
std::size_t no_entries = 9;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerSACT()
|
||||
{
|
||||
std::size_t no_entries = 5;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerZACT()
|
||||
{
|
||||
std::size_t no_entries = 4;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
// (The max number of characters in an action statement / (8 - chars pr string)) * (max over actions of number of lines pr ACTIONX)
|
||||
std::size_t entriesPerZLACT(const Opm::Runspec& rspec, const Opm::Action::Actions& acts)
|
||||
{
|
||||
int max_char_pr_line = rspec.actdims().max_characters();
|
||||
std::size_t no_entries_pr_line = ((max_char_pr_line % 8) == 0) ? max_char_pr_line / 8 : (max_char_pr_line / 8) + 1;
|
||||
std::size_t no_entries = no_entries_pr_line * acts.max_input_lines();
|
||||
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
// The max number of characters in an action statement * (max over actions of number of lines pr ACTIONX) / (8 - chars pr string)
|
||||
std::size_t entriesPerLine(const Opm::Runspec& rspec)
|
||||
{
|
||||
int max_char_pr_line = rspec.actdims().max_characters();
|
||||
std::size_t no_entries_pr_line = ((max_char_pr_line % 8) == 0) ? max_char_pr_line / 8 : (max_char_pr_line / 8) + 1;
|
||||
|
||||
return no_entries_pr_line;
|
||||
}
|
||||
|
||||
|
||||
std::size_t entriesPerZACN(const Opm::Runspec& rspec)
|
||||
{
|
||||
//(Max number of conditions pr ACTIONX) * ((max no characters pr line = 104) / (8 - characters pr string)(104/8 = 13)
|
||||
std::size_t no_entries = rspec.actdims().max_conditions() * 13;
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerIACN(const Opm::Runspec& rspec)
|
||||
{
|
||||
//26*Max number of conditions pr ACTIONX
|
||||
std::size_t no_entries = 26 * rspec.actdims().max_conditions();
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
std::size_t entriesPerSACN(const Opm::Runspec& rspec)
|
||||
{
|
||||
//16
|
||||
std::size_t no_entries = 16 * rspec.actdims().max_conditions();
|
||||
return no_entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // Anonymous
|
||||
|
||||
// #####################################################################
|
||||
// Public Interface (createUdqDims()) Below Separator
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
std::vector<int>
|
||||
Opm::RestartIO::Helpers::
|
||||
createActionxDims( const Runspec& rspec,
|
||||
const Schedule& sched,
|
||||
const std::size_t simStep)
|
||||
{
|
||||
const auto& acts = sched.actions(simStep);
|
||||
std::vector<int> actDims(9);
|
||||
|
||||
//No of Actionx keywords
|
||||
actDims[0] = noOfActions(acts);
|
||||
actDims[1] = entriesPerIACT();
|
||||
actDims[2] = entriesPerSACT();
|
||||
actDims[3] = entriesPerZACT();
|
||||
actDims[4] = entriesPerZLACT(rspec, acts);
|
||||
actDims[5] = entriesPerZACN(rspec);
|
||||
actDims[6] = entriesPerIACN(rspec);
|
||||
actDims[7] = entriesPerSACN(rspec);
|
||||
actDims[8] = entriesPerLine(rspec);
|
||||
|
||||
return actDims;
|
||||
}
|
||||
@@ -27,6 +27,9 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/Regdims.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
@@ -186,14 +189,27 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
/*Opm::RestartIO::InteHEAD::UdqParam
|
||||
getRandSeedPar(const ::Opm::Runspec& rspec)
|
||||
|
||||
Opm::RestartIO::InteHEAD::UdqParam
|
||||
getUdqParam(const ::Opm::Runspec& rspec, const ::Opm::UDQConfig& udqcfg )
|
||||
{
|
||||
const auto& udq_par = rspec.udqParams();
|
||||
const auto r_seed = udq_par.rand_seed();
|
||||
const auto no_udq = udqcfg.size();
|
||||
|
||||
return { r_seed};
|
||||
}*/
|
||||
return { r_seed, static_cast<int>(no_udq)};
|
||||
}
|
||||
|
||||
Opm::RestartIO::InteHEAD::ActionParam
|
||||
getActionParam(const ::Opm::Runspec& rspec, const ::Opm::Action::Actions& acts )
|
||||
{
|
||||
const auto& no_act = acts.size();
|
||||
const auto max_lines_pr_action = acts.max_input_lines();
|
||||
const auto max_cond_per_action = rspec.actdims().max_conditions();
|
||||
const auto max_characters_per_line = rspec.actdims().max_characters();
|
||||
|
||||
return { static_cast<int>(no_act), max_lines_pr_action, static_cast<int>(max_cond_per_action), static_cast<int>(max_characters_per_line)};
|
||||
}
|
||||
|
||||
Opm::RestartIO::InteHEAD::WellSegDims
|
||||
getWellSegDims(const ::Opm::Runspec& rspec,
|
||||
@@ -264,6 +280,8 @@ createInteHead(const EclipseState& es,
|
||||
{
|
||||
const auto nwgmax = maxGroupSize(sched, lookup_step);
|
||||
const auto ngmax = numGroupsInField(sched, lookup_step);
|
||||
const auto& udqCfg = sched.getUDQConfig(lookup_step);
|
||||
const auto& acts = sched.actions(lookup_step);
|
||||
const auto& rspec = es.runspec();
|
||||
const auto& tdim = es.getTableManager();
|
||||
const auto& rdim = tdim.getRegdims();
|
||||
@@ -292,7 +310,8 @@ 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))
|
||||
//.udqParam_1 (getUdqParam(rspec, udqCfg))
|
||||
//.actionParam (getActionParam(rspec, acts))
|
||||
;
|
||||
|
||||
return ih.data();
|
||||
|
||||
@@ -175,9 +175,9 @@ enum index : std::vector<int>::size_type {
|
||||
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
|
||||
NO_ACT = VI::intehead::NOOFACTIONS, // 0 0
|
||||
MAX_LINES = VI::intehead::MAXNOLINES, // 0 0
|
||||
MAXSPRLINE = VI::intehead::MAXNOSTRPRLINE, // 0 0
|
||||
ih_159 = 159 , // 0 0
|
||||
ih_160 = 160 , // 0 0
|
||||
ih_161 = 161 , // 0 0
|
||||
@@ -264,7 +264,7 @@ enum index : std::vector<int>::size_type {
|
||||
ih_242 = 242 , // 0
|
||||
ih_243 = 243 , // 0
|
||||
ih_244 = 244 , // 0
|
||||
ih_245 = 245 , // 0
|
||||
MXACTC = VI::intehead::MAX_ACT_COND, // Max no of conditions pr action
|
||||
ih_246 = 246 , // 0
|
||||
ih_247 = 247 , // 0
|
||||
ih_248 = 248 , // 0
|
||||
@@ -285,8 +285,8 @@ enum index : std::vector<int>::size_type {
|
||||
ih_263 = 263 , // 0
|
||||
ih_264 = 264 , // 0
|
||||
ih_265 = 265 , // 0
|
||||
ih_266 = 266 , // 0
|
||||
UDQPAR_1 = VI::intehead::UDQPAR_1, // 0
|
||||
NOUDQS = VI::intehead::NO_UDQS, // 0
|
||||
UDQPAR_1 = VI::intehead::UDQPAR_1, // 0
|
||||
ih_268 = 268 , // 0
|
||||
ih_269 = 269 , // 0
|
||||
ih_270 = 270 , // 0
|
||||
@@ -315,7 +315,7 @@ enum index : std::vector<int>::size_type {
|
||||
ih_293 = 293 , // 0
|
||||
ih_294 = 294 , // 0
|
||||
ih_295 = 295 , // 0
|
||||
ih_296 = 296 , // 0
|
||||
R_SEED = VI::intehead::RSEED, // 0
|
||||
ih_297 = 297 , // 0
|
||||
ih_298 = 298 , // 0
|
||||
ih_299 = 299 , // 0
|
||||
@@ -683,6 +683,21 @@ Opm::RestartIO::InteHEAD::
|
||||
udqParam_1(const UdqParam& udq_par)
|
||||
{
|
||||
this -> data_[UDQPAR_1] = - udq_par.udqParam_1;
|
||||
this -> data_[R_SEED] = - udq_par.udqParam_1;
|
||||
this -> data_[NOUDQS] = udq_par.no_udqs;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Opm::RestartIO::InteHEAD&
|
||||
Opm::RestartIO::InteHEAD::
|
||||
actionParam(const ActionParam& act_par)
|
||||
{
|
||||
this -> data_[NO_ACT] = act_par.no_actions;
|
||||
this -> data_[MAX_LINES] = act_par.max_no_sched_lines_per_action;
|
||||
this -> data_[MXACTC] = act_par.max_no_conditions_per_action;
|
||||
this -> data_[MAXSPRLINE] = ((act_par.max_no_characters_per_line % 8) == 0) ? act_par.max_no_characters_per_line / 8 :
|
||||
(act_par.max_no_characters_per_line / 8) + 1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,14 @@ const ActionX& Actions::get(std::size_t index) const {
|
||||
return this->actions[index];
|
||||
}
|
||||
|
||||
int Actions::max_input_lines() const {
|
||||
std::size_t max_il = 0;
|
||||
for (const auto& act : this-> actions) {
|
||||
if (act.keyword_strings().size() > max_il) max_il = act.keyword_strings().size() ;
|
||||
}
|
||||
return static_cast<int>(max_il);
|
||||
}
|
||||
|
||||
|
||||
bool Actions::ready(std::time_t sim_time) const {
|
||||
for (const auto& action : this->actions) {
|
||||
|
||||
Reference in New Issue
Block a user