diff --git a/opm/io/eclipse/rst/connection.hpp b/opm/io/eclipse/rst/connection.hpp index 490854c7c..ea889eb20 100644 --- a/opm/io/eclipse/rst/connection.hpp +++ b/opm/io/eclipse/rst/connection.hpp @@ -24,12 +24,14 @@ #include 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 ijk; diff --git a/opm/io/eclipse/rst/group.hpp b/opm/io/eclipse/rst/group.hpp index dc55e0b0f..eed45891f 100644 --- a/opm/io/eclipse/rst/group.hpp +++ b/opm/io/eclipse/rst/group.hpp @@ -24,12 +24,15 @@ #include 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); diff --git a/opm/io/eclipse/rst/segment.hpp b/opm/io/eclipse/rst/segment.hpp index 318e48c9d..5ddcfd3b9 100644 --- a/opm/io/eclipse/rst/segment.hpp +++ b/opm/io/eclipse/rst/segment.hpp @@ -25,10 +25,12 @@ #include 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; diff --git a/opm/io/eclipse/rst/state.hpp b/opm/io/eclipse/rst/state.hpp index 3e6b66c8b..c645aaed0 100644 --- a/opm/io/eclipse/rst/state.hpp +++ b/opm/io/eclipse/rst/state.hpp @@ -28,39 +28,44 @@ #include namespace Opm { + +class UnitSystem; + namespace RestartIO { struct RstState { - RstState(const std::vector& intehead, - const std::vector& logihead, - const std::vector& doubhead, - const std::vector& zgrp, - const std::vector& igrp, - const std::vector& sgrp, - const std::vector& xgrp, - const std::vector& zwel, - const std::vector& iwel, - const std::vector& swel, - const std::vector& xwel, - const std::vector& icon, - const std::vector& scon, - const std::vector& xcon); + RstState(const ::Opm::UnitSystem& unit_system, + const std::vector& intehead, + const std::vector& logihead, + const std::vector& doubhead, + const std::vector& zgrp, + const std::vector& igrp, + const std::vector& sgrp, + const std::vector& xgrp, + const std::vector& zwel, + const std::vector& iwel, + const std::vector& swel, + const std::vector& xwel, + const std::vector& icon, + const std::vector& scon, + const std::vector& xcon); - RstState(const std::vector& intehead, - const std::vector& logihead, - const std::vector& doubhead, - const std::vector& zgrp, - const std::vector& igrp, - const std::vector& sgrp, - const std::vector& xgrp, - const std::vector& zwel, - const std::vector& iwel, - const std::vector& swel, - const std::vector& xwel, - const std::vector& icon, - const std::vector& scon, - const std::vector& xcon, - const std::vector& iseg, - const std::vector& rseg); + RstState(const ::Opm::UnitSystem& unit_system, + const std::vector& intehead, + const std::vector& logihead, + const std::vector& doubhead, + const std::vector& zgrp, + const std::vector& igrp, + const std::vector& sgrp, + const std::vector& xgrp, + const std::vector& zwel, + const std::vector& iwel, + const std::vector& swel, + const std::vector& xwel, + const std::vector& icon, + const std::vector& scon, + const std::vector& xcon, + const std::vector& iseg, + const std::vector& rseg); static RstState load(EclIO::ERst& rst_file, int report_step); @@ -70,7 +75,8 @@ struct RstState { std::vector groups; RstHeader header; private: - void add_groups(const std::vector& zgrp, + void add_groups(const ::Opm::UnitSystem& unit_system, + const std::vector& zgrp, const std::vector& igrp, const std::vector& sgrp, const std::vector& xgrp); diff --git a/opm/io/eclipse/rst/well.hpp b/opm/io/eclipse/rst/well.hpp index 77dcdbfa7..69f389c46 100644 --- a/opm/io/eclipse/rst/well.hpp +++ b/opm/io/eclipse/rst/well.hpp @@ -29,12 +29,15 @@ #include 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 connections; std::vector segments; }; diff --git a/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp b/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp index cea2bb447..0604e81b0 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp @@ -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, std::shared_ptr valv); + Segment(const RestartIO::RstSegment& rst_segment); + int segmentNumber() const; int branchNumber() const; int outletSegment() const; diff --git a/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp b/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp index 719282b5e..b405d8c74 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp @@ -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; diff --git a/src/opm/io/eclipse/rst/connection.cpp b/src/opm/io/eclipse/rst/connection.cpp index 978b25e70..63f2cc5c6 100644 --- a/src/opm/io/eclipse/rst/connection.cpp +++ b/src/opm/io/eclipse/rst/connection.cpp @@ -19,6 +19,7 @@ #include #include #include +#include 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(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(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(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(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])) {} } diff --git a/src/opm/io/eclipse/rst/group.cpp b/src/opm/io/eclipse/rst/group.cpp index 2c9fa22be..27ee8e868 100644 --- a/src/opm/io/eclipse/rst/group.cpp +++ b/src/opm/io/eclipse/rst/group.cpp @@ -22,6 +22,7 @@ #include #include +#include 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])) { } diff --git a/src/opm/io/eclipse/rst/segment.cpp b/src/opm/io/eclipse/rst/segment.cpp index 1d3d8ed34..0f995319f 100644 --- a/src/opm/io/eclipse/rst/segment.cpp +++ b/src/opm/io/eclipse/rst/segment.cpp @@ -21,6 +21,7 @@ #include #include #include +#include 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(iseg[VI::ISeg::SegmentType])), - icd_scaling_mode(iseg[VI::ISeg::ICDScalingMode]), - icd_status(from_int(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(iseg[VI::ISeg::SegmentType])), + icd_scaling_mode( iseg[VI::ISeg::ICDScalingMode]), + icd_status( from_int(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]); diff --git a/src/opm/io/eclipse/rst/state.cpp b/src/opm/io/eclipse/rst/state.cpp index ccbcfd608..247d9c443 100644 --- a/src/opm/io/eclipse/rst/state.cpp +++ b/src/opm/io/eclipse/rst/state.cpp @@ -25,13 +25,17 @@ #include #include +#include + +#include namespace VI = ::Opm::RestartIO::Helpers::VectorItems; namespace Opm { namespace RestartIO { -RstState::RstState(const std::vector& intehead, +RstState::RstState(const ::Opm::UnitSystem& unit_system, + const std::vector& intehead, const std::vector& logihead, const std::vector& doubhead, const std::vector& zgrp, @@ -47,7 +51,7 @@ RstState::RstState(const std::vector& intehead, const std::vector& 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& 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& intehead, } } -RstState::RstState(const std::vector& intehead, - const std::vector& logihead, - const std::vector& doubhead, - const std::vector& zgrp, - const std::vector& igrp, - const std::vector& sgrp, - const std::vector& xgrp, - const std::vector& zwel, - const std::vector& iwel, - const std::vector& swel, - const std::vector& xwel, - const std::vector& icon, - const std::vector& scon, - const std::vector& xcon, - const std::vector& iseg, - const std::vector& rseg) : +RstState::RstState(const ::Opm::UnitSystem& unit_system, + const std::vector& intehead, + const std::vector& logihead, + const std::vector& doubhead, + const std::vector& zgrp, + const std::vector& igrp, + const std::vector& sgrp, + const std::vector& xgrp, + const std::vector& zwel, + const std::vector& iwel, + const std::vector& swel, + const std::vector& xwel, + const std::vector& icon, + const std::vector& scon, + const std::vector& xcon, + const std::vector& iseg, + const std::vector& 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& 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& intehead, } } -void RstState::add_groups(const std::vector& zgrp, +void RstState::add_groups(const ::Opm::UnitSystem& unit_system, + const std::vector& zgrp, const std::vector& igrp, const std::vector& sgrp, const std::vector& xgrp) @@ -131,7 +139,8 @@ void RstState::add_groups(const std::vector& 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("SCON", report_step, 0); const auto& xcon = rst_file.getRst("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("ISEG", report_step, 0); const auto& rseg = rst_file.getRst("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); } } } + diff --git a/src/opm/io/eclipse/rst/well.cpp b/src/opm/io/eclipse/rst/well.cpp index 1913a614f..a73473080 100644 --- a/src/opm/io/eclipse/rst/well.cpp +++ b/src/opm/io/eclipse/rst/well.cpp @@ -25,6 +25,7 @@ #include #include #include +#include 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& iseg, const std::vector& 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; +} + } } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp index f452641ba..16d562856 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp @@ -16,8 +16,9 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ -#include +#include +#include #include #include @@ -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) diff --git a/tests/parser/ScheduleRestartTests.cpp b/tests/parser/ScheduleRestartTests.cpp index 85d0df224..0ff52d30d 100644 --- a/tests/parser/ScheduleRestartTests.cpp +++ b/tests/parser/ScheduleRestartTests.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -49,9 +50,11 @@ void compare_connections(const RestartIO::RstConnection& rst_conn, const Connect BOOST_CHECK_EQUAL(rst_conn.insert_index, static_cast(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()); diff --git a/tests/rst_load.cpp b/tests/rst_load.cpp index f47e4fc84..ceae034f5 100644 --- a/tests/rst_load.cpp +++ b/tests/rst_load.cpp @@ -16,12 +16,14 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ +#include #include #include #include +#include @@ -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(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); + } + } } } } diff --git a/tests/test_AggregateMSWData.cpp b/tests/test_AggregateMSWData.cpp index 5bf34795b..fc9f47285 100644 --- a/tests/test_AggregateMSWData.cpp +++ b/tests/test_AggregateMSWData.cpp @@ -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()); } diff --git a/tests/test_AggregateWellData.cpp b/tests/test_AggregateWellData.cpp index 3f565961c..0d1e4744f 100644 --- a/tests/test_AggregateWellData.cpp +++ b/tests/test_AggregateWellData.cpp @@ -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, diff --git a/tests/test_rst.cpp b/tests/test_rst.cpp index 3a42b7a87..5b83d9534 100644 --- a/tests/test_rst.cpp +++ b/tests/test_rst.cpp @@ -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 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); }