Convert rst quantities to SI units

This commit is contained in:
Joakim Hove 2020-02-05 07:19:21 +01:00
parent 50d1108e61
commit 7da79ae532
18 changed files with 368 additions and 212 deletions

View File

@ -24,12 +24,14 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
namespace Opm {
class UnitSystem;
namespace RestartIO {
class Header;
struct RstConnection {
RstConnection(const int* icon, const float* scon, const double *xcon);
RstConnection(const ::Opm::UnitSystem& unit_system, const int* icon, const float* scon, const double *xcon);
int insert_index;
std::array<int,3> ijk;

View File

@ -24,12 +24,15 @@
#include <string>
namespace Opm {
class UnitSystem;
namespace RestartIO {
struct RstHeader;
struct RstGroup {
RstGroup(const std::string* zwel,
RstGroup(const UnitSystem& unit_system,
const std::string* zwel,
const int * igrp,
const float * sgrp,
const double * xgrp);

View File

@ -25,10 +25,12 @@
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/icd.hpp>
namespace Opm {
class UnitSystem;
namespace RestartIO {
struct RstSegment {
RstSegment(const int* iseg, const double * rseg);
RstSegment(const ::Opm::UnitSystem& unit_system, const int* iseg, const double * rseg);
int segment;
int outlet_segment;

View File

@ -28,39 +28,44 @@
#include <opm/io/eclipse/rst/well.hpp>
namespace Opm {
class UnitSystem;
namespace RestartIO {
struct RstState {
RstState(const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp,
const std::vector<std::string>& zwel,
const std::vector<int>& iwel,
const std::vector<float>& swel,
const std::vector<double>& xwel,
const std::vector<int>& icon,
const std::vector<float>& scon,
const std::vector<double>& xcon);
RstState(const ::Opm::UnitSystem& unit_system,
const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp,
const std::vector<std::string>& zwel,
const std::vector<int>& iwel,
const std::vector<float>& swel,
const std::vector<double>& xwel,
const std::vector<int>& icon,
const std::vector<float>& scon,
const std::vector<double>& xcon);
RstState(const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp,
const std::vector<std::string>& zwel,
const std::vector<int>& iwel,
const std::vector<float>& swel,
const std::vector<double>& xwel,
const std::vector<int>& icon,
const std::vector<float>& scon,
const std::vector<double>& xcon,
const std::vector<int>& iseg,
const std::vector<double>& rseg);
RstState(const ::Opm::UnitSystem& unit_system,
const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp,
const std::vector<std::string>& zwel,
const std::vector<int>& iwel,
const std::vector<float>& swel,
const std::vector<double>& xwel,
const std::vector<int>& icon,
const std::vector<float>& scon,
const std::vector<double>& xcon,
const std::vector<int>& iseg,
const std::vector<double>& rseg);
static RstState load(EclIO::ERst& rst_file, int report_step);
@ -70,7 +75,8 @@ struct RstState {
std::vector<RstGroup> groups;
RstHeader header;
private:
void add_groups(const std::vector<std::string>& zgrp,
void add_groups(const ::Opm::UnitSystem& unit_system,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp);

View File

@ -29,12 +29,15 @@
#include <opm/io/eclipse/rst/segment.hpp>
namespace Opm {
class UnitSystem;
namespace RestartIO {
struct RstHeader;
struct RstWell {
RstWell(const RstHeader& header,
RstWell(const ::Opm::UnitSystem& unit_system,
const RstHeader& header,
const std::string& group_arg,
const std::string* zwel,
const int * iwel,
@ -44,7 +47,8 @@ struct RstWell {
const float * scon,
const double * xcon);
RstWell(const RstHeader& header,
RstWell(const ::Opm::UnitSystem& unit_system,
const RstHeader& header,
const std::string& group_arg,
const std::string* zwel,
const int * iwel,
@ -104,6 +108,7 @@ struct RstWell {
double water_void_rate;
double gas_void_rate;
const RstSegment segment(int segment_number) const;
std::vector<RstConnection> connections;
std::vector<RstSegment> segments;
};

View File

@ -26,6 +26,10 @@
namespace Opm {
class SpiralICD;
class Valve;
namespace RestartIO {
class RstSegment;
}
}
namespace Opm {
@ -64,6 +68,8 @@ namespace Opm {
std::shared_ptr<SpiralICD> spiralICD,
std::shared_ptr<Valve> valv);
Segment(const RestartIO::RstSegment& rst_segment);
int segmentNumber() const;
int branchNumber() const;
int outletSegment() const;

View File

@ -57,13 +57,13 @@ namespace Opm {
double conFlowCoefficient() const;
double conCrossArea() const;
double conMaxCrossArea() const;
// parameters for pressure loss along the pipe
double pipeAdditionalLength() const;
double pipeDiameter() const;
double pipeRoughness() const;
double pipeCrossArea() const;
// parameters for pressure loss along the pipe
double pipeAdditionalLength() const;
// Status: OPEN or SHUT
ICDStatus status() const;

View File

@ -19,6 +19,7 @@
#include <opm/io/eclipse/rst/header.hpp>
#include <opm/io/eclipse/rst/connection.hpp>
#include <opm/output/eclipse/VectorItems/connection.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
@ -55,27 +56,28 @@ Connection::Direction from_int(int int_dir) {
}
using M = ::Opm::UnitSystem::measure;
RstConnection::RstConnection(const int* icon, const float* scon, const double* xcon) :
insert_index(icon[VI::IConn::SeqIndex] - 1),
ijk({icon[VI::IConn::CellI] - 1, icon[VI::IConn::CellJ] - 1, icon[VI::IConn::CellK] - 1}),
state(from_int<Connection::State>(icon[VI::IConn::ConnStat])),
drain_sat_table(icon[VI::IConn::Drainage]),
imb_sat_table(icon[VI::IConn::Imbibition]),
completion(icon[VI::IConn::ComplNum] - 1),
dir(from_int<Connection::Direction>(icon[VI::IConn::ConnDir])),
segment(icon[VI::IConn::Segment] - 1),
tran(scon[VI::SConn::ConnTrans]),
depth(scon[VI::SConn::Depth]),
diameter(scon[VI::SConn::Diameter]),
kh(scon[VI::SConn::EffectiveKH]),
segdist_end(scon[VI::SConn::SegDistEnd]),
segdist_start(scon[VI::SConn::SegDistStart]),
oil_rate(xcon[VI::XConn::OilRate]),
water_rate(xcon[VI::XConn::WaterRate]),
gas_rate(xcon[VI::XConn::GasRate]),
pressure(xcon[VI::XConn::Pressure]),
resv_rate(xcon[VI::XConn::ResVRate])
RstConnection::RstConnection(const ::Opm::UnitSystem& unit_system, const int* icon, const float* scon, const double* xcon) :
insert_index( icon[VI::IConn::SeqIndex] - 1),
ijk( {icon[VI::IConn::CellI] - 1, icon[VI::IConn::CellJ] - 1, icon[VI::IConn::CellK] - 1}),
state( from_int<Connection::State>(icon[VI::IConn::ConnStat])),
drain_sat_table( icon[VI::IConn::Drainage]),
imb_sat_table( icon[VI::IConn::Imbibition]),
completion( icon[VI::IConn::ComplNum] - 1),
dir( from_int<Connection::Direction>(icon[VI::IConn::ConnDir])),
segment( icon[VI::IConn::Segment] - 1),
tran( unit_system.to_si(M::transmissibility, scon[VI::SConn::ConnTrans])),
depth( unit_system.to_si(M::length, scon[VI::SConn::Depth])),
diameter( unit_system.to_si(M::length, scon[VI::SConn::Diameter])),
kh( unit_system.to_si(M::effective_Kh, scon[VI::SConn::EffectiveKH])),
segdist_end( unit_system.to_si(M::length, scon[VI::SConn::SegDistEnd])),
segdist_start( unit_system.to_si(M::length, scon[VI::SConn::SegDistStart])),
oil_rate( unit_system.to_si(M::liquid_surface_rate, xcon[VI::XConn::OilRate])),
water_rate( unit_system.to_si(M::liquid_surface_rate, xcon[VI::XConn::WaterRate])),
gas_rate( unit_system.to_si(M::gas_surface_rate, xcon[VI::XConn::GasRate])),
pressure( unit_system.to_si(M::pressure, xcon[VI::XConn::Pressure])),
resv_rate( unit_system.to_si(M::rate, xcon[VI::XConn::ResVRate]))
{}
}

View File

@ -22,6 +22,7 @@
#include <opm/io/eclipse/rst/group.hpp>
#include <opm/output/eclipse/VectorItems/group.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
@ -29,44 +30,47 @@ namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace Opm {
namespace RestartIO {
RstGroup::RstGroup(const std::string* zwel,
using M = ::Opm::UnitSystem::measure;
RstGroup::RstGroup(const ::Opm::UnitSystem& unit_system,
const std::string* zwel,
const int *,
const float * sgrp,
const double * xgrp) :
name(rtrim_copy(zwel[0])),
oil_rate_limit(sgrp[VI::SGroup::OilRateLimit]),
water_rate_limit(sgrp[VI::SGroup::WatRateLimit]),
gas_rate_limit(sgrp[VI::SGroup::GasRateLimit]),
liquid_rate_limit(sgrp[VI::SGroup::LiqRateLimit]),
water_surface_limit(sgrp[VI::SGroup::waterSurfRateLimit]),
water_reservoir_limit(sgrp[VI::SGroup::waterResRateLimit]),
water_reinject_limit(sgrp[VI::SGroup::waterReinjectionLimit]),
water_voidage_limit(sgrp[VI::SGroup::waterVoidageLimit]),
gas_surface_limit(sgrp[VI::SGroup::gasSurfRateLimit]),
gas_reservoir_limit(sgrp[VI::SGroup::gasResRateLimit]),
gas_reinject_limit(sgrp[VI::SGroup::gasReinjectionLimit]),
gas_voidage_limit(sgrp[VI::SGroup::gasVoidageLimit]),
oil_production_rate(xgrp[VI::XGroup::OilPrRate]),
water_production_rate(xgrp[VI::XGroup::WatPrRate]),
gas_production_rate(xgrp[VI::XGroup::GasPrRate]),
liquid_production_rate(xgrp[VI::XGroup::LiqPrRate]),
water_injection_rate(xgrp[VI::XGroup::WatInjRate]),
gas_injection_rate(xgrp[VI::XGroup::GasInjRate]),
wct(xgrp[VI::XGroup::WatCut]),
gor(xgrp[VI::XGroup::GORatio]),
oil_production_total(xgrp[VI::XGroup::OilPrTotal]),
water_production_total(xgrp[VI::XGroup::WatPrTotal]),
gas_production_total(xgrp[VI::XGroup::GasPrTotal]),
voidage_production_total(xgrp[VI::XGroup::VoidPrTotal]),
water_injection_total(xgrp[VI::XGroup::WatInjTotal]),
gas_injection_total(xgrp[VI::XGroup::GasInjTotal]),
oil_production_potential(xgrp[VI::XGroup::OilPrPot]),
water_production_potential(xgrp[VI::XGroup::WatPrPot]),
history_total_oil_production(xgrp[VI::XGroup::HistOilPrTotal]),
history_total_water_production(xgrp[VI::XGroup::HistWatPrTotal]),
history_total_water_injection(xgrp[VI::XGroup::HistWatInjTotal]),
history_total_gas_production(xgrp[VI::XGroup::HistGasPrTotal]),
history_total_gas_injection(xgrp[VI::XGroup::HistGasInjTotal])
name(trim_copy(zwel[0])),
oil_rate_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::OilRateLimit])),
water_rate_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::WatRateLimit])),
gas_rate_limit( unit_system.to_si(M::gas_surface_rate, sgrp[VI::SGroup::GasRateLimit])),
liquid_rate_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::LiqRateLimit])),
water_surface_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::waterSurfRateLimit])),
water_reservoir_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::waterResRateLimit])),
water_reinject_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::waterReinjectionLimit])),
water_voidage_limit( unit_system.to_si(M::liquid_surface_rate, sgrp[VI::SGroup::waterVoidageLimit])),
gas_surface_limit( unit_system.to_si(M::gas_surface_rate, sgrp[VI::SGroup::gasSurfRateLimit])),
gas_reservoir_limit( unit_system.to_si(M::geometric_volume_rate, sgrp[VI::SGroup::gasResRateLimit])),
gas_reinject_limit( unit_system.to_si(M::gas_surface_rate, sgrp[VI::SGroup::gasReinjectionLimit])),
gas_voidage_limit( unit_system.to_si(M::geometric_volume_rate, sgrp[VI::SGroup::gasVoidageLimit])),
oil_production_rate( unit_system.to_si(M::liquid_surface_rate, xgrp[VI::XGroup::OilPrRate])),
water_production_rate( unit_system.to_si(M::liquid_surface_rate, xgrp[VI::XGroup::WatPrRate])),
gas_production_rate( unit_system.to_si(M::gas_surface_rate, xgrp[VI::XGroup::GasPrRate])),
liquid_production_rate( unit_system.to_si(M::liquid_surface_rate, xgrp[VI::XGroup::LiqPrRate])),
water_injection_rate( unit_system.to_si(M::liquid_surface_rate, xgrp[VI::XGroup::WatInjRate])),
gas_injection_rate( unit_system.to_si(M::gas_surface_rate, xgrp[VI::XGroup::GasInjRate])),
wct( unit_system.to_si(M::water_cut, xgrp[VI::XGroup::WatCut])),
gor( unit_system.to_si(M::gas_oil_ratio, xgrp[VI::XGroup::GORatio])),
oil_production_total( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::OilPrTotal])),
water_production_total( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::WatPrTotal])),
gas_production_total( unit_system.to_si(M::gas_surface_volume, xgrp[VI::XGroup::GasPrTotal])),
voidage_production_total( unit_system.to_si(M::geometric_volume, xgrp[VI::XGroup::VoidPrTotal])),
water_injection_total( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::WatInjTotal])),
gas_injection_total( unit_system.to_si(M::gas_surface_volume, xgrp[VI::XGroup::GasInjTotal])),
oil_production_potential( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::OilPrPot])),
water_production_potential( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::WatPrPot])),
history_total_oil_production( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::HistOilPrTotal])),
history_total_water_production(unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::HistWatPrTotal])),
history_total_water_injection( unit_system.to_si(M::liquid_surface_volume, xgrp[VI::XGroup::HistWatInjTotal])),
history_total_gas_production( unit_system.to_si(M::gas_surface_volume, xgrp[VI::XGroup::HistGasPrTotal])),
history_total_gas_injection( unit_system.to_si(M::gas_surface_volume, xgrp[VI::XGroup::HistGasInjTotal]))
{
}

View File

@ -21,6 +21,7 @@
#include <opm/output/eclipse/VectorItems/msw.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/icd.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
@ -40,38 +41,47 @@ Segment::SegmentType from_ecl(int int_type) {
namespace RestartIO {
RstSegment::RstSegment(const int * iseg, const double * rseg) :
segment(iseg[VI::ISeg::SegNo]),
outlet_segment(iseg[VI::ISeg::OutSeg]),
branch(iseg[VI::ISeg::BranchNo]),
segment_type(from_ecl<Segment::SegmentType>(iseg[VI::ISeg::SegmentType])),
icd_scaling_mode(iseg[VI::ISeg::ICDScalingMode]),
icd_status(from_int<ICDStatus>(iseg[VI::ISeg::ICDOpenShutFlag])),
dist_outlet(rseg[VI::RSeg::DistOutlet]),
outlet_dz(rseg[VI::RSeg::OutletDepthDiff]),
diameter(rseg[VI::RSeg::SegDiam]),
roughness(rseg[VI::RSeg::SegRough]),
area(rseg[VI::RSeg::SegArea]),
volume(rseg[VI::RSeg::SegVolume]),
dist_bhp_ref(rseg[VI::RSeg::DistBHPRef]),
bhp_ref_dz(rseg[VI::RSeg::DepthBHPRef]),
total_flow(rseg[VI::RSeg::TotFlowRate]),
water_flow_fraction(rseg[VI::RSeg::WatFlowFract]),
gas_flow_fraction(rseg[VI::RSeg::GasFlowFract]),
pressure(rseg[VI::RSeg::Pressure]),
valve_length(rseg[VI::RSeg::ValveLength]),
valve_area(rseg[VI::RSeg::ValveArea]),
valve_flow_coeff(rseg[VI::RSeg::ValveFlowCoeff]),
valve_max_area(rseg[VI::RSeg::ValveMaxArea]),
base_strength(rseg[VI::RSeg::DeviceBaseStrength]),
fluid_density(rseg[VI::RSeg::CalibrFluidDensity]),
fluid_viscosity(rseg[VI::RSeg::CalibrFluidViscosity]),
critical_water_fraction(rseg[VI::RSeg::CriticalWaterFraction]),
transition_region_width(rseg[VI::RSeg::TransitionRegWidth]),
max_emulsion_ratio(rseg[VI::RSeg::MaxEmulsionRatio]),
max_valid_flow_rate(rseg[VI::RSeg::MaxValidFlowRate]),
icd_length(rseg[VI::RSeg::ICDLength]),
valve_area_fraction(rseg[VI::RSeg::ValveAreaFraction])
using M = ::Opm::UnitSystem::measure;
namespace {
double area_to_si(const UnitSystem& unit_system, double raw_value) {
return unit_system.to_si( M::length, unit_system.to_si( M::length, raw_value));
}
}
RstSegment::RstSegment(const ::Opm::UnitSystem& unit_system, const int * iseg, const double * rseg) :
segment( iseg[VI::ISeg::SegNo]),
outlet_segment( iseg[VI::ISeg::OutSeg]),
branch( iseg[VI::ISeg::BranchNo]),
segment_type( from_ecl<Segment::SegmentType>(iseg[VI::ISeg::SegmentType])),
icd_scaling_mode( iseg[VI::ISeg::ICDScalingMode]),
icd_status( from_int<ICDStatus>(iseg[VI::ISeg::ICDOpenShutFlag])),
dist_outlet( unit_system.to_si(M::length, rseg[VI::RSeg::DistOutlet])),
outlet_dz( unit_system.to_si(M::length, rseg[VI::RSeg::OutletDepthDiff])),
diameter( unit_system.to_si(M::length, rseg[VI::RSeg::SegDiam])),
roughness( unit_system.to_si(M::length, rseg[VI::RSeg::SegRough])),
area( area_to_si(unit_system, rseg[VI::RSeg::SegArea])),
volume( unit_system.to_si(M::volume, rseg[VI::RSeg::SegVolume])),
dist_bhp_ref( unit_system.to_si(M::length, rseg[VI::RSeg::DistBHPRef])),
bhp_ref_dz( unit_system.to_si(M::length, rseg[VI::RSeg::DepthBHPRef])),
total_flow( unit_system.to_si(M::rate, rseg[VI::RSeg::TotFlowRate])),
water_flow_fraction( rseg[VI::RSeg::WatFlowFract]),
gas_flow_fraction( rseg[VI::RSeg::GasFlowFract]),
pressure( unit_system.to_si(M::pressure, rseg[VI::RSeg::Pressure])),
valve_length( unit_system.to_si(M::length, rseg[VI::RSeg::ValveLength])),
valve_area( area_to_si( unit_system, rseg[VI::RSeg::ValveArea])),
valve_flow_coeff( rseg[VI::RSeg::ValveFlowCoeff]),
valve_max_area( area_to_si(unit_system, rseg[VI::RSeg::ValveMaxArea])),
base_strength( unit_system.to_si( M::icd_strength, rseg[VI::RSeg::DeviceBaseStrength])),
fluid_density( unit_system.to_si(M::density, rseg[VI::RSeg::CalibrFluidDensity])),
fluid_viscosity( unit_system.to_si(M::viscosity, rseg[VI::RSeg::CalibrFluidViscosity])),
critical_water_fraction( rseg[VI::RSeg::CriticalWaterFraction]),
transition_region_width(unit_system.to_si(M::length, rseg[VI::RSeg::TransitionRegWidth])),
max_emulsion_ratio( rseg[VI::RSeg::MaxEmulsionRatio]),
max_valid_flow_rate( unit_system.to_si(M::rate, rseg[VI::RSeg::MaxValidFlowRate])),
icd_length( unit_system.to_si(M::rate, rseg[VI::RSeg::ICDLength])),
valve_area_fraction( rseg[VI::RSeg::ValveAreaFraction])
{
if (iseg[VI::ISeg::InSegCurBranch] != 0)
this->inflow_segments.push_back(iseg[VI::ISeg::InSegCurBranch]);

View File

@ -25,13 +25,17 @@
#include <opm/output/eclipse/VectorItems/connection.hpp>
#include <opm/output/eclipse/VectorItems/well.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace Opm {
namespace RestartIO {
RstState::RstState(const std::vector<int>& intehead,
RstState::RstState(const ::Opm::UnitSystem& unit_system,
const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
@ -47,7 +51,7 @@ RstState::RstState(const std::vector<int>& intehead,
const std::vector<double>& xcon):
header(intehead, logihead, doubhead)
{
this->add_groups(zgrp, igrp, sgrp, xgrp);
this->add_groups(unit_system, zgrp, igrp, sgrp, xgrp);
for (int iw = 0; iw < this->header.num_wells; iw++) {
std::size_t zwel_offset = iw * this->header.nzwelz;
@ -60,7 +64,8 @@ RstState::RstState(const std::vector<int>& intehead,
int group_index = iwel[ iwel_offset + VI::IWell::Group ] - 1;
const std::string group = this->groups[group_index].name;
this->wells.emplace_back(this->header,
this->wells.emplace_back(unit_system,
this->header,
group,
zwel.data() + zwel_offset,
iwel.data() + iwel_offset,
@ -75,25 +80,26 @@ RstState::RstState(const std::vector<int>& intehead,
}
}
RstState::RstState(const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp,
const std::vector<std::string>& zwel,
const std::vector<int>& iwel,
const std::vector<float>& swel,
const std::vector<double>& xwel,
const std::vector<int>& icon,
const std::vector<float>& scon,
const std::vector<double>& xcon,
const std::vector<int>& iseg,
const std::vector<double>& rseg) :
RstState::RstState(const ::Opm::UnitSystem& unit_system,
const std::vector<int>& intehead,
const std::vector<bool>& logihead,
const std::vector<double>& doubhead,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp,
const std::vector<std::string>& zwel,
const std::vector<int>& iwel,
const std::vector<float>& swel,
const std::vector<double>& xwel,
const std::vector<int>& icon,
const std::vector<float>& scon,
const std::vector<double>& xcon,
const std::vector<int>& iseg,
const std::vector<double>& rseg) :
header(intehead, logihead, doubhead)
{
this->add_groups(zgrp, igrp, sgrp, xgrp);
this->add_groups(unit_system, zgrp, igrp, sgrp, xgrp);
for (int iw = 0; iw < this->header.num_wells; iw++) {
std::size_t zwel_offset = iw * this->header.nzwelz;
@ -106,7 +112,8 @@ RstState::RstState(const std::vector<int>& intehead,
int group_index = iwel[ iwel_offset + VI::IWell::Group ] - 1;
const std::string group = this->groups[group_index].name;
this->wells.emplace_back(this->header,
this->wells.emplace_back(unit_system,
this->header,
group,
zwel.data() + zwel_offset,
iwel.data() + iwel_offset,
@ -120,7 +127,8 @@ RstState::RstState(const std::vector<int>& intehead,
}
}
void RstState::add_groups(const std::vector<std::string>& zgrp,
void RstState::add_groups(const ::Opm::UnitSystem& unit_system,
const std::vector<std::string>& zgrp,
const std::vector<int>& igrp,
const std::vector<float>& sgrp,
const std::vector<double>& xgrp)
@ -131,7 +139,8 @@ void RstState::add_groups(const std::vector<std::string>& zgrp,
std::size_t sgrp_offset = ig * this->header.nsgrpz;
std::size_t xgrp_offset = ig * this->header.nxgrpz;
this->groups.emplace_back(zgrp.data() + zgrp_offset,
this->groups.emplace_back(unit_system,
zgrp.data() + zgrp_offset,
igrp.data() + igrp_offset,
sgrp.data() + sgrp_offset,
xgrp.data() + xgrp_offset);
@ -170,22 +179,28 @@ RstState RstState::load(EclIO::ERst& rst_file, int report_step) {
const auto& scon = rst_file.getRst<float>("SCON", report_step, 0);
const auto& xcon = rst_file.getRst<double>("XCON", report_step, 0);
auto unit_id = intehead[VI::intehead::UNIT];
::Opm::UnitSystem unit_system(unit_id);
if (rst_file.hasKey("ISEG")) {
const auto& iseg = rst_file.getRst<int>("ISEG", report_step, 0);
const auto& rseg = rst_file.getRst<double>("RSEG", report_step, 0);
return RstState(intehead, logihead, doubhead,
zgrp, igrp, sgrp, xgrp,
zwel, iwel, swel, xwel,
icon, scon, xcon,
iseg, rseg);
return RstState(unit_system,
intehead, logihead, doubhead,
zgrp, igrp, sgrp, xgrp,
zwel, iwel, swel, xwel,
icon, scon, xcon,
iseg, rseg);
} else
return RstState(intehead, logihead, doubhead,
zgrp, igrp, sgrp, xgrp,
zwel, iwel, swel, xwel,
icon, scon, xcon);
return RstState(unit_system,
intehead, logihead, doubhead,
zgrp, igrp, sgrp, xgrp,
zwel, iwel, swel, xwel,
icon, scon, xcon);
}
}
}

View File

@ -25,6 +25,7 @@
#include <opm/output/eclipse/VectorItems/connection.hpp>
#include <opm/output/eclipse/VectorItems/msw.hpp>
#include <opm/output/eclipse/VectorItems/well.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
@ -32,7 +33,10 @@ namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace Opm {
namespace RestartIO {
RstWell::RstWell(const RstHeader& header,
using M = ::Opm::UnitSystem::measure;
RstWell::RstWell(const ::Opm::UnitSystem& unit_system,
const RstHeader& header,
const std::string& group_arg,
const std::string* zwel,
const int * iwel,
@ -43,61 +47,62 @@ RstWell::RstWell(const RstHeader& header,
const double * xcon) :
name(rtrim_copy(zwel[0])),
group(group_arg),
ij({iwel[VI::IWell::IHead] - 1, iwel[VI::IWell::JHead] - 1}),
k1k2(std::make_pair(iwel[VI::IWell::FirstK] - 1, iwel[VI::IWell::LastK] - 1)),
wtype(iwel[VI::IWell::WType]),
active_control(iwel[VI::IWell::ActWCtrl]),
vfp_table(iwel[VI::IWell::VFPTab]),
pred_requested_control(iwel[VI::IWell::PredReqWCtrl]),
xflow(iwel[VI::IWell::XFlow]),
hist_requested_control(iwel[VI::IWell::HistReqWCtrl]),
msw_index(iwel[VI::IWell::MsWID]),
completion_ordering(iwel[VI::IWell::CompOrd]),
orat_target(swel[VI::SWell::OilRateTarget]),
wrat_target(swel[VI::SWell::WatRateTarget]),
grat_target(swel[VI::SWell::GasRateTarget]),
lrat_target(swel[VI::SWell::LiqRateTarget]),
resv_target(swel[VI::SWell::ResVRateTarget]),
thp_target(swel[VI::SWell::THPTarget]),
bhp_target_float(swel[VI::SWell::BHPTarget]),
hist_lrat_target(swel[VI::SWell::HistLiqRateTarget]),
hist_grat_target(swel[VI::SWell::HistGasRateTarget]),
hist_bhp_target(swel[VI::SWell::HistBHPTarget]),
oil_rate(xwel[VI::XWell::OilPrRate]),
water_rate(xwel[VI::XWell::WatPrRate]),
gas_rate(xwel[VI::XWell::GasPrRate]),
liquid_rate(xwel[VI::XWell::LiqPrRate]),
void_rate(xwel[VI::XWell::VoidPrRate]),
flow_bhp(xwel[VI::XWell::FlowBHP]),
wct(xwel[VI::XWell::WatCut]),
gor(xwel[VI::XWell::GORatio]),
oil_total(xwel[VI::XWell::OilPrTotal]),
water_total(xwel[VI::XWell::WatPrTotal]),
gas_total(xwel[VI::XWell::GasPrTotal]),
void_total(xwel[VI::XWell::VoidPrTotal]),
water_inj_total(xwel[VI::XWell::WatInjTotal]),
gas_inj_total(xwel[VI::XWell::GasInjTotal]),
gas_fvf(xwel[VI::XWell::GasFVF]),
bhp_target_double(xwel[VI::XWell::BHPTarget]),
hist_oil_total(xwel[VI::XWell::HistOilPrTotal]),
hist_wat_total(xwel[VI::XWell::HistWatPrTotal]),
hist_gas_total(xwel[VI::XWell::HistGasPrTotal]),
hist_water_inj_total(xwel[VI::XWell::HistWatInjTotal]),
hist_gas_inj_total(xwel[VI::XWell::HistGasInjTotal]),
water_void_rate(xwel[VI::XWell::WatVoidPrRate]),
gas_void_rate(xwel[VI::XWell::GasVoidPrRate])
ij( {iwel[VI::IWell::IHead] - 1, iwel[VI::IWell::JHead] - 1}),
k1k2( std::make_pair(iwel[VI::IWell::FirstK] - 1, iwel[VI::IWell::LastK] - 1)),
wtype( iwel[VI::IWell::WType]),
active_control( iwel[VI::IWell::ActWCtrl]),
vfp_table( iwel[VI::IWell::VFPTab]),
pred_requested_control( iwel[VI::IWell::PredReqWCtrl]),
xflow( iwel[VI::IWell::XFlow]),
hist_requested_control( iwel[VI::IWell::HistReqWCtrl]),
msw_index( iwel[VI::IWell::MsWID]),
completion_ordering( iwel[VI::IWell::CompOrd]),
orat_target( unit_system.to_si(M::liquid_surface_rate, swel[VI::SWell::OilRateTarget])),
wrat_target( unit_system.to_si(M::liquid_surface_rate, swel[VI::SWell::WatRateTarget])),
grat_target( unit_system.to_si(M::gas_surface_rate, swel[VI::SWell::GasRateTarget])),
lrat_target( unit_system.to_si(M::liquid_surface_rate, swel[VI::SWell::LiqRateTarget])),
resv_target( unit_system.to_si(M::rate, swel[VI::SWell::ResVRateTarget])),
thp_target( unit_system.to_si(M::pressure, swel[VI::SWell::THPTarget])),
bhp_target_float( unit_system.to_si(M::pressure, swel[VI::SWell::BHPTarget])),
hist_lrat_target( unit_system.to_si(M::liquid_surface_rate, swel[VI::SWell::HistLiqRateTarget])),
hist_grat_target( unit_system.to_si(M::gas_surface_rate, swel[VI::SWell::HistGasRateTarget])),
hist_bhp_target( unit_system.to_si(M::pressure, swel[VI::SWell::HistBHPTarget])),
oil_rate( unit_system.to_si(M::liquid_surface_rate, xwel[VI::XWell::OilPrRate])),
water_rate( unit_system.to_si(M::liquid_surface_rate, xwel[VI::XWell::WatPrRate])),
gas_rate( unit_system.to_si(M::gas_surface_rate, xwel[VI::XWell::GasPrRate])),
liquid_rate( unit_system.to_si(M::rate, xwel[VI::XWell::LiqPrRate])),
void_rate( unit_system.to_si(M::rate, xwel[VI::XWell::VoidPrRate])),
flow_bhp( unit_system.to_si(M::pressure, xwel[VI::XWell::FlowBHP])),
wct( unit_system.to_si(M::water_cut, xwel[VI::XWell::WatCut])),
gor( unit_system.to_si(M::gas_oil_ratio, xwel[VI::XWell::GORatio])),
oil_total( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::OilPrTotal])),
water_total( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::WatPrTotal])),
gas_total( unit_system.to_si(M::gas_surface_volume, xwel[VI::XWell::GasPrTotal])),
void_total( unit_system.to_si(M::volume, xwel[VI::XWell::VoidPrTotal])),
water_inj_total( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::WatInjTotal])),
gas_inj_total( unit_system.to_si(M::gas_surface_volume, xwel[VI::XWell::GasInjTotal])),
gas_fvf( xwel[VI::XWell::GasFVF]),
bhp_target_double( unit_system.to_si(M::pressure, xwel[VI::XWell::BHPTarget])),
hist_oil_total( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::HistOilPrTotal])),
hist_wat_total( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::HistWatPrTotal])),
hist_gas_total( unit_system.to_si(M::gas_surface_volume, xwel[VI::XWell::HistGasPrTotal])),
hist_water_inj_total(unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::HistWatInjTotal])),
hist_gas_inj_total( unit_system.to_si(M::gas_surface_volume, xwel[VI::XWell::HistGasInjTotal])),
water_void_rate( unit_system.to_si(M::liquid_surface_volume, xwel[VI::XWell::WatVoidPrRate])),
gas_void_rate( unit_system.to_si(M::gas_surface_volume, xwel[VI::XWell::GasVoidPrRate]))
{
for (int ic = 0; ic < iwel[VI::IWell::NConn]; ic++) {
std::size_t icon_offset = ic * header.niconz;
std::size_t scon_offset = ic * header.nsconz;
std::size_t xcon_offset = ic * header.nxconz;
this->connections.emplace_back( icon + icon_offset, scon + scon_offset, xcon + xcon_offset);
this->connections.emplace_back( unit_system, icon + icon_offset, scon + scon_offset, xcon + xcon_offset);
}
}
RstWell::RstWell(const RstHeader& header,
RstWell::RstWell(const ::Opm::UnitSystem& unit_system,
const RstHeader& header,
const std::string& group_arg,
const std::string* zwel,
const int * iwel,
@ -108,7 +113,7 @@ RstWell::RstWell(const RstHeader& header,
const double * xcon,
const std::vector<int>& iseg,
const std::vector<double>& rseg) :
RstWell(header, group_arg, zwel, iwel, swel, xwel, icon, scon, xcon)
RstWell(unit_system, header, group_arg, zwel, iwel, swel, xwel, icon, scon, xcon)
{
if (this->msw_index) {
@ -119,7 +124,7 @@ RstWell::RstWell(const RstHeader& header,
auto segment_number = iseg[iseg_offset + VI::ISeg::SegNo];
if (segment_number != 0) {
segment_map.insert({segment_number, this->segments.size()});
this->segments.emplace_back( iseg.data() + iseg_offset, rseg.data() + rseg_offset);
this->segments.emplace_back( unit_system, iseg.data() + iseg_offset, rseg.data() + rseg_offset);
}
}
@ -132,5 +137,13 @@ RstWell::RstWell(const RstHeader& header,
}
}
const RstSegment RstWell::segment(int segment_number) const {
const auto& iter = std::find_if(this->segments.begin(), this->segments.end(), [segment_number](const RstSegment& segment) { return segment.segment == segment_number; });
if (iter == this->segments.end())
throw std::invalid_argument("No such segment");
return *iter;
}
}
}

View File

@ -16,8 +16,9 @@
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/EclipseState/Schedule/MSW/Segment.hpp>
#include <opm/io/eclipse/rst/segment.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/SpiralICD.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp>
@ -47,6 +48,71 @@ static constexpr double invalid_value = -1.e100;
}
Segment::Segment(const RestartIO::RstSegment& rst_segment):
m_segment_number(rst_segment.segment),
m_branch(rst_segment.branch),
m_outlet_segment(rst_segment.outlet_segment),
m_total_length( rst_segment.dist_bhp_ref ),
m_depth(rst_segment.bhp_ref_dz),
m_internal_diameter(rst_segment.diameter),
m_roughness(rst_segment.roughness),
m_cross_area(rst_segment.area),
m_volume(rst_segment.volume),
m_data_ready(true),
m_segment_type(rst_segment.segment_type)
{
if (this->m_segment_type == SegmentType::SICD) {
double scalingFactor = -1; // The scaling factor will be and updated from the simulator.
SpiralICD icd(rst_segment.base_strength,
rst_segment.icd_length,
rst_segment.fluid_density,
rst_segment.fluid_viscosity,
rst_segment.critical_water_fraction,
rst_segment.transition_region_width,
rst_segment.max_emulsion_ratio,
rst_segment.icd_scaling_mode,
rst_segment.max_valid_flow_rate,
rst_segment.icd_status,
scalingFactor);
this->updateSpiralICD(icd);
}
if (this->m_segment_type == SegmentType::VALVE) {
/*
These three variables are currently not stored in the restart
file; here we initialize with the default values, but if they have
originally been assigned in the deck with non-default values, that
will *not* be picked in a restarted run.
*/
double pipeDiam = this->m_internal_diameter;
double pipeRough = this->m_roughness;
double pipeCrossA = this->m_cross_area;
Valve valve(rst_segment.valve_flow_coeff,
rst_segment.valve_area,
rst_segment.valve_max_area,
rst_segment.valve_length,
pipeDiam,
pipeRough,
pipeCrossA,
rst_segment.icd_status);
/*
The segment length argument should be the length of this
particular segment; in the input phase that is calculated from the
WellSegments::segmentLength() function which also uses the outlet
segment.
*/
double segment_length = -1;
this->updateValve(valve, segment_length);
}
}
Segment::Segment(int segment_number_in, int branch_in, int outlet_segment_in, double length_in, double depth_in,
double internal_diameter_in, double roughness_in, double cross_area_in,
double volume_in, bool data_ready_in, SegmentType segment_type_in)

View File

@ -31,6 +31,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
@ -49,9 +50,11 @@ void compare_connections(const RestartIO::RstConnection& rst_conn, const Connect
BOOST_CHECK_EQUAL(rst_conn.insert_index, static_cast<int>(sched_conn.getSeqIndex()));
BOOST_CHECK(rst_conn.state == sched_conn.state());
BOOST_CHECK(rst_conn.dir == sched_conn.dir());
BOOST_CHECK_CLOSE( rst_conn.tran, sched_conn.CF() , 1e-6);
}
void compare_wells(const RestartIO::RstWell& rst_well, const Well& sched_well) {
BOOST_CHECK_EQUAL(rst_well.name, sched_well.name());
BOOST_CHECK_EQUAL(rst_well.group, sched_well.groupName());

View File

@ -16,12 +16,14 @@
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 <iostream>
#include <opm/io/eclipse/rst/state.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
@ -34,6 +36,16 @@ int main(int argc, char ** argv) {
std::cout << "Loading restart step: " << report_step << std::endl;
const auto& state = Opm::RestartIO::RstState::load(rst_file, report_step);
static_cast<void>(state); // Suppress unused variable warning.
for (const auto& rst_well : state.wells) {
std::cout << "Loading well " << rst_well.name << std::endl;
for (const auto& rst_segment : rst_well.segments) {
std::cout << " Segment: " << rst_segment.segment << std::endl;
Opm::Segment segment(rst_segment);
}
}
}
}
}

View File

@ -843,7 +843,7 @@ BOOST_AUTO_TEST_CASE(MSW_RST) {
);
const auto& iseg = amswd.getISeg();
const auto& rseg = amswd.getRSeg();
auto segment = Opm::RestartIO::RstSegment(iseg.data(), rseg.data());
auto segment = Opm::RestartIO::RstSegment(simCase.es.getUnits(), iseg.data(), rseg.data());
}

View File

@ -827,7 +827,8 @@ BOOST_AUTO_TEST_CASE(WELL_POD) {
std::size_t scon_offset = header.nsconz * header.ncwmax * iw;
std::size_t xcon_offset = header.nxconz * header.ncwmax * iw;
wells.emplace_back(header,
wells.emplace_back(units,
header,
"GROUP",
zwel.data() + zwel_offset,
iwel.data() + iwel_offset,

View File

@ -232,6 +232,7 @@ BOOST_AUTO_TEST_CASE(group_test) {
const auto& xgrp = groupData.getXGroup();
const auto& zgrp8 = groupData.getZGroup();
Opm::UnitSystem unit_system(Opm::UnitSystem::UnitType::UNIT_TYPE_METRIC);
std::vector<std::string> zgrp;
for (const auto& s8: zgrp8)
zgrp.push_back(s8.c_str());
@ -243,7 +244,8 @@ BOOST_AUTO_TEST_CASE(group_test) {
std::size_t sgrp_offset = ig * header.nsgrpz;
std::size_t xgrp_offset = ig * header.nxgrpz;
Opm::RestartIO::RstGroup group(zgrp.data() + zgrp_offset,
Opm::RestartIO::RstGroup group(unit_system,
zgrp.data() + zgrp_offset,
igrp.data() + igrp_offset,
sgrp.data() + sgrp_offset,
xgrp.data() + xgrp_offset);
@ -254,7 +256,7 @@ BOOST_AUTO_TEST_CASE(State_test) {
const auto simCase = SimulationCase{first_sim()};
const auto& units = simCase.es.getUnits();
// Report Step 2: 2011-01-20 --> 2013-06-15
const auto rptStep = std::size_t{2};
const auto rptStep = std::size_t{4};
const auto sim_step = rptStep - 1;
Opm::SummaryState sumState(std::chrono::system_clock::now());
@ -304,8 +306,12 @@ BOOST_AUTO_TEST_CASE(State_test) {
for (const auto& s8: zgrp8)
zgrp.push_back(s8.c_str());
Opm::RestartIO::RstState state(ih, lh, dh,
Opm::RestartIO::RstState state(units,
ih, lh, dh,
zgrp, igrp, sgrp, xgrp,
zwel, iwel, swel, xwel,
icon, scon, xcon);
const auto& well = state.get_well("OP_3");
BOOST_CHECK_THROW(well.segment(10), std::invalid_argument);
}