Skip to content

Commit

Permalink
Load active UDA's from restart file
Browse files Browse the repository at this point in the history
  • Loading branch information
joakim-hove committed Aug 31, 2021
1 parent fd010c1 commit d8d6749
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 6 deletions.
1 change: 1 addition & 0 deletions opm/io/eclipse/rst/state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct RstState {
std::vector<RstWell> wells;
std::vector<RstGroup> groups;
std::vector<RstUDQ> udqs;
RstUDQActive udq_active;
Tuning tuning;

private:
Expand Down
24 changes: 23 additions & 1 deletion opm/io/eclipse/rst/udq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <vector>

#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>

namespace Opm {

Expand Down Expand Up @@ -81,10 +82,31 @@ class RstUDQ {
};



class RstUDQActive {

struct RstRecord {
RstRecord(UDAControl c, std::size_t i, std::size_t u1, std::size_t u2);


UDAControl control;
std::size_t input_index;
std::size_t use_count;
std::size_t wg_offset;
};


public:
RstUDQActive() = default;
RstUDQActive(const std::vector<int>& iuad, const std::vector<int>& iuap, const std::vector<int>& igph);

std::vector<RstRecord> iuad;
std::vector<int> wg_index;
std::vector<Phase> ig_phase;
};
}
}




#endif
38 changes: 37 additions & 1 deletion opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,49 @@
#define UDQ_USAGE_HPP

#include <cstdlib>
#include <optional>
#include <string>
#include <vector>

#include <opm/parser/eclipse/Deck/UDAValue.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>

namespace Opm {

class UDAValue;
class UDQConfig;
class UnitSystem;

namespace RestartIO {
struct RstState;
}

class UDQActive {
public:

struct RstRecord {

RstRecord(UDAControl control_arg, UDAValue value_arg, std::string wgname_arg)
: control(control_arg)
, value(value_arg)
, wgname(wgname_arg)
{};

RstRecord(UDAControl control_arg, UDAValue value_arg, std::string wgname_arg, Phase phase)
: RstRecord(control_arg, value_arg, wgname_arg)
{
this->ig_phase = phase;
};

UDAControl control;
UDAValue value;
std::string wgname;
std::optional<Phase> ig_phase;
};



class OutputRecord{
public:
OutputRecord() :
Expand Down Expand Up @@ -131,7 +162,12 @@ class UDQActive {
};

static UDQActive serializeObject();

UDQActive() = default;
static std::vector<RstRecord> load_rst(const UnitSystem& units,
const UDQConfig& udq_config,
const RestartIO::RstState& rst_state,
const std::vector<std::string>& well_names,
const std::vector<std::string>& group_names);
int update(const UDQConfig& udq_config, const UDAValue& uda, const std::string& wgname, UDAControl control);
explicit operator bool() const;
const std::vector<OutputRecord>& iuad() const;
Expand Down
3 changes: 3 additions & 0 deletions opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,14 @@ namespace UDQ {
bool setFunc(UDQTokenType token_type);
bool trailingSpace(UDQTokenType token_type);
bool leadingSpace(UDQTokenType token_type);
bool group_control(UDAControl control);
bool well_control(UDAControl control);


std::string typeName(UDQVarType var_type);
UDAKeyword keyword(UDAControl control);
int udaCode(UDAControl control);
UDAControl udaControl(int uda_code);

constexpr double restart_default = -0.3E+21;
} // UDQ
Expand Down
4 changes: 3 additions & 1 deletion opm/parser/eclipse/Units/UnitSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <memory>

#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>


namespace Opm {

Expand Down Expand Up @@ -97,7 +99,7 @@ namespace Opm {
const Dimension& getNewDimension(const std::string& dimension);
const Dimension& getDimension(const std::string& dimension) const;
Dimension getDimension(measure m) const;

Dimension uda_dim(UDAControl control) const;

bool hasDimension(const std::string& dimension) const;
bool equal(const UnitSystem& other) const;
Expand Down
7 changes: 7 additions & 0 deletions src/opm/io/eclipse/rst/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,13 @@ RstState RstState::load(std::shared_ptr<EclIO::RestartFileView> rstView,
const auto& dudf = state.header.nfield_udq > 0 ? rstView->getKeyword<double>("DUDF") : std::vector<double>{};

state.add_udqs(iudq, zudn, zudl, dudw, dudg, dudf);

if (rstView->hasKeyword<int>("IUAD")) {
const auto& iuad = rstView->getKeyword<int>("IUAD");
const auto& iuap = rstView->getKeyword<int>("IUAP");
const auto& igph = rstView->getKeyword<int>("IGPH");
state.udq_active = RstUDQActive(iuad, iuap, igph);
}
}

return state;
Expand Down
37 changes: 37 additions & 0 deletions src/opm/io/eclipse/rst/udq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <fmt/format.h>

#include <opm/io/eclipse/rst/udq.hpp>
#include <opm/output/eclipse/UDQDims.hpp>

namespace Opm {
namespace RestartIO {
Expand Down Expand Up @@ -106,5 +107,41 @@ std::optional<double> RstUDQ::field_value() const {
return define.field_value;
}

RstUDQActive::RstRecord::RstRecord(UDAControl c, std::size_t i, std::size_t u1, std::size_t u2)
: control(c)
, input_index(i)
, use_count(u1)
, wg_offset(u2)
{}

RstUDQActive::RstUDQActive(const std::vector<int>& iuad_arg, const std::vector<int>& iuap, const std::vector<int>& igph)
{
auto uda_size = UDQDims::entriesPerIUAD();
for (std::size_t iuad_index = 0; iuad_index < iuad_arg.size() / uda_size; iuad_index++) {
auto offset = iuad_index * uda_size;
this->iuad.emplace_back( UDQ::udaControl(iuad_arg[offset + 0]),
iuad_arg[offset + 1] - 1,
iuad_arg[offset + 3],
iuad_arg[offset + 4] - 1);
}

std::transform(iuap.begin(), iuap.end(), std::back_inserter(this->wg_index), [](const int& value) { return value - 1;});

for (const auto& int_phase : igph) {
Phase phase{Phase::OIL};

if (int_phase == 1)
phase = Phase::OIL;

if (int_phase == 2)
phase = Phase::WATER;

if (int_phase == 3)
phase = Phase::GAS;

this->ig_phase.push_back(phase);
};
}

}
}
7 changes: 7 additions & 0 deletions src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,13 @@ namespace {
}
}
this->snapshots.back().udq.update( UDQConfig(this->m_static.m_runspec.udqParams(), rst_state) );
for (const auto& [control, value, wgname] : UDQActive::load_rst( this->m_static.m_unit_system, this->snapshots.back().udq(), rst_state, this->wellNames(report_step), this->groupNames(report_step))) {
if (UDQ::well_control(control)) {
auto& well = this->getWell(wgname, report_step);
} else {
auto& group = this->getGroup(wgname, report_step);
}
}
}

std::shared_ptr<const Python> Schedule::python() const
Expand Down
33 changes: 31 additions & 2 deletions src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,44 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>

#include <opm/parser/eclipse/Deck/UDAValue.hpp>
#include <opm/io/eclipse/rst/state.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>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>

namespace Opm {

std::vector<UDQActive::RstRecord> UDQActive::load_rst(const UnitSystem& units,
const UDQConfig& udq_config,
const RestartIO::RstState& rst_state,
const std::vector<std::string>& well_names,
const std::vector<std::string>& group_names)
{
std::vector<RstRecord> records;
const auto& rst_active = rst_state.udq_active;

for (const auto& record : rst_active.iuad) {
const auto& udq_input = udq_config[record.input_index];
UDAValue uda(udq_input.keyword(), units.uda_dim(record.control));
for (std::size_t use_index = 0; use_index < record.use_count; use_index++) {
std::size_t wg_index = rst_active.wg_index[record.wg_offset + use_index];

if (UDQ::well_control(record.control))
records.emplace_back(record.control, uda, well_names[wg_index]);
else {
if (UDQ::production_control)
records.emplace_back(record.control, uda, group_names[wg_index]);
else
records.emplace_back(record.control, uda, group_names[wg_index], rst_active.ig_phase[wg_index]);
}
}
}
return records;
}

UDQActive UDQActive::serializeObject()
{
UDQActive result;
Expand Down
32 changes: 32 additions & 0 deletions src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,38 @@ int udaCode(UDAControl control)
return lookup_control_map_value(c2uda, control);
}

bool group_control(UDAControl control) {
if (control == UDAControl::GCONPROD_OIL_TARGET)
return true;

if (control == UDAControl::GCONPROD_WATER_TARGET)
return true;

if (control == UDAControl::GCONPROD_GAS_TARGET)
return true;

if (control == UDAControl::GCONPROD_LIQUID_TARGET)
return true;

if (control == UDAControl::GCONINJE_SURFACE_MAX_RATE)
return true;

if (control == UDAControl::GCONINJE_RESV_MAX_RATE)
return true;

if (control == UDAControl::GCONINJE_TARGET_REINJ_FRACTION)
return true;

if (control == UDAControl::GCONINJE_TARGET_VOID_FRACTION)
return true;

return false;
}

bool well_control(UDAControl control) {
return !group_control(control);
}

UDAControl udaControl(int uda_code) {
switch (uda_code) {
case 300004:
Expand Down
36 changes: 36 additions & 0 deletions src/opm/parser/eclipse/Units/UnitSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,42 @@ namespace {
}


Dimension UnitSystem::uda_dim(UDAControl control) const {
switch (control) {
case UDAControl::WCONPROD_ORAT:
case UDAControl::WCONPROD_WRAT:
case UDAControl::WCONPROD_LRAT:
case UDAControl::GCONPROD_OIL_TARGET:
case UDAControl::GCONPROD_WATER_TARGET:
case UDAControl::GCONPROD_LIQUID_TARGET:
return this->getDimension(UnitSystem::measure::liquid_surface_rate);

case UDAControl::WCONINJE_RESV:
case UDAControl::WCONPROD_RESV:
case UDAControl::GCONINJE_RESV_MAX_RATE:
return this->getDimension(UnitSystem::measure::geometric_volume_rate);

case UDAControl::WCONPROD_GRAT:
return this->getDimension(UnitSystem::measure::gas_surface_rate);

case UDAControl::WCONPROD_BHP:
case UDAControl::WCONPROD_THP:
case UDAControl::WCONINJE_THP:
case UDAControl::WCONINJE_BHP:
return this->getDimension(UnitSystem::measure::pressure);

case UDAControl::GCONINJE_TARGET_REINJ_FRACTION:
case UDAControl::GCONINJE_TARGET_VOID_FRACTION:
case UDAControl::GCONINJE_SURFACE_MAX_RATE:
case UDAControl::WCONINJE_RATE:
return this->getDimension(UnitSystem::measure::identity);

default:
throw std::logic_error("No dimension");
}
}


std::size_t UnitSystem::use_count() const {
return this->m_use_count;
}
Expand Down
Loading

0 comments on commit d8d6749

Please sign in to comment.