Merge pull request #1460 from joakim-hove/wellsegments-state
Wellsegments state
This commit is contained in:
commit
8ddf71a67f
@ -42,6 +42,9 @@ namespace Opm {
|
|||||||
|
|
||||||
Segment();
|
Segment();
|
||||||
|
|
||||||
|
Segment(const Segment& src, double new_depth, double new_length, double new_volume);
|
||||||
|
Segment(const Segment& src, double new_depth, double new_length);
|
||||||
|
Segment(const Segment& src, double new_volume);
|
||||||
Segment(int segment_number_in, int branch_in, int outlet_segment_in, double length_in, double depth_in,
|
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);
|
double internal_diameter_in, double roughness_in, double cross_area_in, double volume_in, bool data_ready_in, SegmentType segment_type_in);
|
||||||
|
|
||||||
@ -76,11 +79,7 @@ namespace Opm {
|
|||||||
int ecl_type_id() const;
|
int ecl_type_id() const;
|
||||||
|
|
||||||
|
|
||||||
void setVolume(const double volume_in);
|
|
||||||
void setDepthAndLength(const double depth_in, const double length_in);
|
|
||||||
|
|
||||||
const std::vector<int>& inletSegments() const;
|
const std::vector<int>& inletSegments() const;
|
||||||
void addInletSegment(const int segment_number);
|
|
||||||
|
|
||||||
static double invalidValue();
|
static double invalidValue();
|
||||||
static SegmentType type_from_int(int ecl_id);
|
static SegmentType type_from_int(int ecl_id);
|
||||||
@ -88,15 +87,13 @@ namespace Opm {
|
|||||||
bool operator==( const Segment& ) const;
|
bool operator==( const Segment& ) const;
|
||||||
bool operator!=( const Segment& ) const;
|
bool operator!=( const Segment& ) const;
|
||||||
|
|
||||||
void updateSpiralICD(const SpiralICD& spiral_icd);
|
|
||||||
|
|
||||||
const std::shared_ptr<SpiralICD>& spiralICD() const;
|
const std::shared_ptr<SpiralICD>& spiralICD() const;
|
||||||
const std::shared_ptr<Valve>& getValve() const;
|
const std::shared_ptr<Valve>& getValve() const;
|
||||||
|
|
||||||
void updateValve(const Valve& valve, const double segment_length);
|
|
||||||
|
|
||||||
const Valve* valve() const;
|
const Valve* valve() const;
|
||||||
|
|
||||||
|
void updateSpiralICD(const SpiralICD& spiral_icd);
|
||||||
|
void updateValve(const Valve& valve, const double segment_length);
|
||||||
|
void addInletSegment(const int segment_number);
|
||||||
private:
|
private:
|
||||||
// segment number
|
// segment number
|
||||||
// it should work as a ID.
|
// it should work as a ID.
|
||||||
|
@ -62,38 +62,27 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
WellSegments() = default;
|
WellSegments() = default;
|
||||||
WellSegments(const std::string& wname,
|
WellSegments(const DeckKeyword& keyword);
|
||||||
double depthTopSeg,
|
WellSegments(CompPressureDrop compDrop,
|
||||||
double lengthTopSeg,
|
|
||||||
double volumeTopSeg,
|
|
||||||
LengthDepth lenDepType,
|
|
||||||
CompPressureDrop compDrop,
|
|
||||||
MultiPhaseModel multiPhase,
|
|
||||||
const std::vector<Segment>& segments,
|
const std::vector<Segment>& segments,
|
||||||
const std::map<int,int>& segmentNumberIdx);
|
const std::map<int,int>& segmentNumberIdx);
|
||||||
|
|
||||||
const std::string& wellName() const;
|
|
||||||
int size() const;
|
int size() const;
|
||||||
double depthTopSegment() const;
|
double depthTopSegment() const;
|
||||||
double lengthTopSegment() const;
|
double lengthTopSegment() const;
|
||||||
double volumeTopSegment() const;
|
double volumeTopSegment() const;
|
||||||
|
|
||||||
CompPressureDrop compPressureDrop() const;
|
CompPressureDrop compPressureDrop() const;
|
||||||
LengthDepth lengthDepthType() const;
|
|
||||||
MultiPhaseModel multiPhaseModel() const;
|
|
||||||
|
|
||||||
// mapping the segment number to the index in the vector of segments
|
// mapping the segment number to the index in the vector of segments
|
||||||
int segmentNumberToIndex(const int segment_number) const;
|
int segmentNumberToIndex(const int segment_number) const;
|
||||||
|
|
||||||
void addSegment(Segment new_segment);
|
|
||||||
|
|
||||||
void loadWELSEGS( const DeckKeyword& welsegsKeyword);
|
|
||||||
|
|
||||||
const Segment& getFromSegmentNumber(const int segment_number) const;
|
const Segment& getFromSegmentNumber(const int segment_number) const;
|
||||||
|
|
||||||
const Segment& operator[](size_t idx) const;
|
const Segment& operator[](size_t idx) const;
|
||||||
void orderSegments();
|
void orderSegments();
|
||||||
void process(bool first_time);
|
|
||||||
|
|
||||||
bool operator==( const WellSegments& ) const;
|
bool operator==( const WellSegments& ) const;
|
||||||
bool operator!=( const WellSegments& ) const;
|
bool operator!=( const WellSegments& ) const;
|
||||||
@ -109,23 +98,13 @@ namespace Opm {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void processABS();
|
void processABS();
|
||||||
void processINC(const bool first_time);
|
void processINC(double depth_top, double length_top);
|
||||||
|
void process(LengthDepth length_depth, double depth_top, double length_top);
|
||||||
|
void addSegment(const Segment& new_segment);
|
||||||
|
void loadWELSEGS( const DeckKeyword& welsegsKeyword);
|
||||||
|
|
||||||
std::string m_well_name;
|
|
||||||
// depth of the nodal point of the top segment
|
|
||||||
// it is taken as the BHP reference depth of the well
|
|
||||||
// BHP reference depth data from elsewhere will be ignored for multi-segmented wells
|
|
||||||
double m_depth_top;
|
|
||||||
// length down the tubing to the nodal point of the top segment
|
|
||||||
double m_length_top;
|
|
||||||
// effective wellbore volume of the top segment
|
|
||||||
double m_volume_top;
|
|
||||||
// type of the tubing length and depth information
|
|
||||||
LengthDepth m_length_depth_type;
|
|
||||||
// components of the pressure drop to be included
|
// components of the pressure drop to be included
|
||||||
CompPressureDrop m_comp_pressure_drop;
|
CompPressureDrop m_comp_pressure_drop;
|
||||||
// multi-phase flow model
|
|
||||||
MultiPhaseModel m_multiphase_model;
|
|
||||||
// There are X and Y cooridnate of the nodal point of the top segment
|
// There are X and Y cooridnate of the nodal point of the top segment
|
||||||
// Since they are not used for simulations and we are not supporting plotting,
|
// Since they are not used for simulations and we are not supporting plotting,
|
||||||
// we are not handling them at the moment.
|
// we are not handling them at the moment.
|
||||||
|
@ -178,7 +178,7 @@ namespace {
|
|||||||
|
|
||||||
|
|
||||||
Opm::RestartIO::Helpers::SegmentSetSourceSinkTerms
|
Opm::RestartIO::Helpers::SegmentSetSourceSinkTerms
|
||||||
getSegmentSetSSTerms(const Opm::WellSegments& segSet, const std::vector<Opm::data::Connection>& rateConns,
|
getSegmentSetSSTerms(const std::string& wname, const Opm::WellSegments& segSet, const std::vector<Opm::data::Connection>& rateConns,
|
||||||
const Opm::WellConnections& welConns, const Opm::UnitSystem& units)
|
const Opm::WellConnections& welConns, const Opm::UnitSystem& units)
|
||||||
{
|
{
|
||||||
std::vector<double> qosc (segSet.size(), 0.);
|
std::vector<double> qosc (segSet.size(), 0.);
|
||||||
@ -194,7 +194,7 @@ namespace {
|
|||||||
throw std::invalid_argument {
|
throw std::invalid_argument {
|
||||||
"Inconsistent number of open connections I in Opm::WellConnections (" +
|
"Inconsistent number of open connections I in Opm::WellConnections (" +
|
||||||
std::to_string(welConns.size()) + ") and vector<Opm::data::Connection> (" +
|
std::to_string(welConns.size()) + ") and vector<Opm::data::Connection> (" +
|
||||||
std::to_string(rateConns.size()) + ") in Well " + segSet.wellName()
|
std::to_string(rateConns.size()) + ") in Well " + wname
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for (auto nConn = openConnections.size(), connID = 0*nConn; connID < nConn; connID++) {
|
for (auto nConn = openConnections.size(), connID = 0*nConn; connID < nConn; connID++) {
|
||||||
@ -222,7 +222,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Opm::RestartIO::Helpers::SegmentSetFlowRates
|
Opm::RestartIO::Helpers::SegmentSetFlowRates
|
||||||
getSegmentSetFlowRates(const Opm::WellSegments& segSet, const std::vector<Opm::data::Connection>& rateConns,
|
getSegmentSetFlowRates(const std::string& wname, const Opm::WellSegments& segSet, const std::vector<Opm::data::Connection>& rateConns,
|
||||||
const Opm::WellConnections& welConns, const Opm::UnitSystem& units)
|
const Opm::WellConnections& welConns, const Opm::UnitSystem& units)
|
||||||
{
|
{
|
||||||
std::vector<double> sofr (segSet.size(), 0.);
|
std::vector<double> sofr (segSet.size(), 0.);
|
||||||
@ -230,7 +230,7 @@ namespace {
|
|||||||
std::vector<double> sgfr (segSet.size(), 0.);
|
std::vector<double> sgfr (segSet.size(), 0.);
|
||||||
//
|
//
|
||||||
//call function to calculate the individual segment source/sink terms
|
//call function to calculate the individual segment source/sink terms
|
||||||
auto sSSST = getSegmentSetSSTerms(segSet, rateConns, welConns, units);
|
auto sSSST = getSegmentSetSSTerms(wname, segSet, rateConns, welConns, units);
|
||||||
|
|
||||||
// find an ordered list of segments
|
// find an ordered list of segments
|
||||||
std::size_t segmentInd = 0;
|
std::size_t segmentInd = 0;
|
||||||
@ -355,7 +355,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int inflowSegmentCurBranch(const Opm::WellSegments& segSet, std::size_t segIndex) {
|
int inflowSegmentCurBranch(const std::string& wname, const Opm::WellSegments& segSet, std::size_t segIndex) {
|
||||||
const auto& branch = segSet[segIndex].branchNumber();
|
const auto& branch = segSet[segIndex].branchNumber();
|
||||||
const auto& segNumber = segSet[segIndex].segmentNumber();
|
const auto& segNumber = segSet[segIndex].segmentNumber();
|
||||||
int inFlowSegInd = -1;
|
int inFlowSegInd = -1;
|
||||||
@ -368,12 +368,12 @@ namespace {
|
|||||||
inFlowSegInd = segSet.segmentNumberToIndex(i_segNum);
|
inFlowSegInd = segSet.segmentNumberToIndex(i_segNum);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << "Non-unique inflow segment in same branch, Well: " << segSet.wellName() << std::endl;
|
std::cout << "Non-unique inflow segment in same branch, Well: " << wname << std::endl;
|
||||||
std::cout << "Segment number: " << segNumber << std::endl;
|
std::cout << "Segment number: " << segNumber << std::endl;
|
||||||
std::cout << "Branch number: " << branch << std::endl;
|
std::cout << "Branch number: " << branch << std::endl;
|
||||||
std::cout << "Inflow segment number 1: " << segSet[inFlowSegInd].segmentNumber() << std::endl;
|
std::cout << "Inflow segment number 1: " << segSet[inFlowSegInd].segmentNumber() << std::endl;
|
||||||
std::cout << "Inflow segment number 2: " << segSet[ind].segmentNumber() << std::endl;
|
std::cout << "Inflow segment number 2: " << segSet[ind].segmentNumber() << std::endl;
|
||||||
throw std::invalid_argument("Non-unique inflow segment in same branch, Well " + segSet.wellName());
|
throw std::invalid_argument("Non-unique inflow segment in same branch, Well " + wname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,7 +464,7 @@ namespace {
|
|||||||
auto iS = (segNumber-1)*noElmSeg;
|
auto iS = (segNumber-1)*noElmSeg;
|
||||||
iSeg[iS + 0] = welSegSet[orderedSegmentNo[ind]].segmentNumber();
|
iSeg[iS + 0] = welSegSet[orderedSegmentNo[ind]].segmentNumber();
|
||||||
iSeg[iS + 1] = segment.outletSegment();
|
iSeg[iS + 1] = segment.outletSegment();
|
||||||
iSeg[iS + 2] = (inflowSegmentCurBranch(welSegSet, ind) == 0) ? 0 : welSegSet[inflowSegmentCurBranch(welSegSet, ind)].segmentNumber();
|
iSeg[iS + 2] = (inflowSegmentCurBranch(well.name(), welSegSet, ind) == 0) ? 0 : welSegSet[inflowSegmentCurBranch(well.name(), welSegSet, ind)].segmentNumber();
|
||||||
iSeg[iS + 3] = segment.branchNumber();
|
iSeg[iS + 3] = segment.branchNumber();
|
||||||
iSeg[iS + 4] = noInFlowBranches(welSegSet, ind);
|
iSeg[iS + 4] = noInFlowBranches(welSegSet, ind);
|
||||||
iSeg[iS + 5] = sumNoInFlowBranches(welSegSet, ind);
|
iSeg[iS + 5] = sumNoInFlowBranches(welSegSet, ind);
|
||||||
@ -652,7 +652,7 @@ namespace {
|
|||||||
// find well connections and calculate segment rates based on well connection production/injection terms
|
// find well connections and calculate segment rates based on well connection production/injection terms
|
||||||
auto sSFR = Opm::RestartIO::Helpers::SegmentSetFlowRates{};
|
auto sSFR = Opm::RestartIO::Helpers::SegmentSetFlowRates{};
|
||||||
if (haveWellRes) {
|
if (haveWellRes) {
|
||||||
sSFR = getSegmentSetFlowRates(welSegSet, wRatesIt->second.connections, welConns, units);
|
sSFR = getSegmentSetFlowRates(well.name(), welSegSet, wRatesIt->second.connections, welConns, units);
|
||||||
}
|
}
|
||||||
// 'stringSegNum' is one-based (1 .. #segments inclusive)
|
// 'stringSegNum' is one-based (1 .. #segments inclusive)
|
||||||
std::string stringSegNum = std::to_string(segNumber);
|
std::string stringSegNum = std::to_string(segNumber);
|
||||||
|
@ -88,6 +88,27 @@ static constexpr double invalid_value = -1.e100;
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Segment::Segment(const Segment& src, double new_depth, double new_length):
|
||||||
|
Segment(src)
|
||||||
|
{
|
||||||
|
this->m_depth = new_depth;
|
||||||
|
this->m_total_length = new_length;
|
||||||
|
this->m_data_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Segment::Segment(const Segment& src, double new_depth, double new_length, double new_volume):
|
||||||
|
Segment(src, new_depth, new_length)
|
||||||
|
{
|
||||||
|
this->m_volume = new_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Segment::Segment(const Segment& src, double new_volume):
|
||||||
|
Segment(src)
|
||||||
|
{
|
||||||
|
this->m_volume = new_volume;
|
||||||
|
}
|
||||||
|
|
||||||
int Segment::segmentNumber() const {
|
int Segment::segmentNumber() const {
|
||||||
return m_segment_number;
|
return m_segment_number;
|
||||||
@ -140,16 +161,6 @@ static constexpr double invalid_value = -1.e100;
|
|||||||
return m_segment_type;
|
return m_segment_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::setDepthAndLength(const double depth_in, const double length_in) {
|
|
||||||
m_total_length = length_in;
|
|
||||||
m_depth = depth_in;
|
|
||||||
m_data_ready = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Segment::setVolume(const double volume_in) {
|
|
||||||
m_volume = volume_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<int>& Segment::inletSegments() const {
|
const std::vector<int>& Segment::inletSegments() const {
|
||||||
return m_inlet_segments;
|
return m_inlet_segments;
|
||||||
}
|
}
|
||||||
|
@ -36,46 +36,35 @@
|
|||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
WellSegments::WellSegments(const std::string& wname,
|
WellSegments::WellSegments(CompPressureDrop compDrop,
|
||||||
double depthTopSeg,
|
|
||||||
double lengthTopSeg,
|
|
||||||
double volumeTopSeg,
|
|
||||||
LengthDepth lenDepType,
|
|
||||||
CompPressureDrop compDrop,
|
|
||||||
MultiPhaseModel multiPhase,
|
|
||||||
const std::vector<Segment>& segments,
|
const std::vector<Segment>& segments,
|
||||||
const std::map<int,int>& segmentNumberIdx)
|
const std::map<int,int>& segmentNumberIdx)
|
||||||
: m_well_name(wname)
|
: m_comp_pressure_drop(compDrop)
|
||||||
, m_depth_top(depthTopSeg)
|
|
||||||
, m_length_top(lengthTopSeg)
|
|
||||||
, m_volume_top(volumeTopSeg)
|
|
||||||
, m_length_depth_type(lenDepType)
|
|
||||||
, m_comp_pressure_drop(compDrop)
|
|
||||||
, m_multiphase_model(multiPhase)
|
|
||||||
, m_segments(segments)
|
, m_segments(segments)
|
||||||
, segment_number_to_index(segmentNumberIdx)
|
, segment_number_to_index(segmentNumberIdx)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& WellSegments::wellName() const {
|
|
||||||
return m_well_name;
|
WellSegments::WellSegments(const DeckKeyword& keyword) {
|
||||||
|
this->loadWELSEGS(keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WellSegments::size() const {
|
int WellSegments::size() const {
|
||||||
return m_segments.size();
|
return m_segments.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
double WellSegments::depthTopSegment() const {
|
double WellSegments::depthTopSegment() const {
|
||||||
return m_depth_top;
|
return this->m_segments[0].depth();
|
||||||
}
|
}
|
||||||
|
|
||||||
double WellSegments::lengthTopSegment() const {
|
double WellSegments::lengthTopSegment() const {
|
||||||
return m_length_top;
|
return this->m_segments[0].totalLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
double WellSegments::volumeTopSegment() const {
|
double WellSegments::volumeTopSegment() const {
|
||||||
return m_volume_top;
|
return this->m_segments[0].volume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,10 +72,6 @@ namespace Opm {
|
|||||||
return m_comp_pressure_drop;
|
return m_comp_pressure_drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
WellSegments::MultiPhaseModel WellSegments::multiPhaseModel() const {
|
|
||||||
return m_multiphase_model;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Segment& WellSegments::operator[](size_t idx) const {
|
const Segment& WellSegments::operator[](size_t idx) const {
|
||||||
return m_segments[idx];
|
return m_segments[idx];
|
||||||
}
|
}
|
||||||
@ -100,7 +85,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellSegments::addSegment( Segment new_segment ) {
|
void WellSegments::addSegment( const Segment& new_segment ) {
|
||||||
// decide whether to push_back or insert
|
// decide whether to push_back or insert
|
||||||
const int segment_number = new_segment.segmentNumber();
|
const int segment_number = new_segment.segmentNumber();
|
||||||
|
|
||||||
@ -119,30 +104,25 @@ namespace Opm {
|
|||||||
// for the first record, which provides the information for the top segment
|
// for the first record, which provides the information for the top segment
|
||||||
// and information for the whole segment set
|
// and information for the whole segment set
|
||||||
const auto& record1 = welsegsKeyword.getRecord(0);
|
const auto& record1 = welsegsKeyword.getRecord(0);
|
||||||
m_well_name = record1.getItem("WELL").getTrimmedString(0);
|
|
||||||
|
|
||||||
m_segments.clear();
|
|
||||||
|
|
||||||
const double invalid_value = Segment::invalidValue(); // meaningless value to indicate unspecified values
|
const double invalid_value = Segment::invalidValue(); // meaningless value to indicate unspecified values
|
||||||
|
|
||||||
m_depth_top = record1.getItem("DEPTH").getSIDouble(0);
|
const double depth_top = record1.getItem("DEPTH").getSIDouble(0);
|
||||||
m_length_top = record1.getItem("LENGTH").getSIDouble(0);
|
const double length_top = record1.getItem("LENGTH").getSIDouble(0);
|
||||||
m_length_depth_type = LengthDepthFromString(record1.getItem("INFO_TYPE").getTrimmedString(0));
|
const double volume_top = record1.getItem("WELLBORE_VOLUME").getSIDouble(0);
|
||||||
m_volume_top = record1.getItem("WELLBORE_VOLUME").getSIDouble(0);
|
const LengthDepth length_depth_type = LengthDepthFromString(record1.getItem("INFO_TYPE").getTrimmedString(0));
|
||||||
m_comp_pressure_drop = CompPressureDropFromString(record1.getItem("PRESSURE_COMPONENTS").getTrimmedString(0));
|
m_comp_pressure_drop = CompPressureDropFromString(record1.getItem("PRESSURE_COMPONENTS").getTrimmedString(0));
|
||||||
m_multiphase_model = MultiPhaseModelFromString(record1.getItem("FLOW_MODEL").getTrimmedString(0));
|
|
||||||
|
|
||||||
// the main branch is 1 instead of 0
|
// the main branch is 1 instead of 0
|
||||||
// the segment number for top segment is also 1
|
// the segment number for top segment is also 1
|
||||||
if (m_length_depth_type == LengthDepth::INC) {
|
if (length_depth_type == LengthDepth::INC) {
|
||||||
m_segments.emplace_back( 1, 1, 0, 0., 0.,
|
m_segments.emplace_back( 1, 1, 0, 0., 0.,
|
||||||
invalid_value, invalid_value, invalid_value,
|
invalid_value, invalid_value, invalid_value,
|
||||||
m_volume_top, false , Segment::SegmentType::REGULAR);
|
volume_top, false , Segment::SegmentType::REGULAR);
|
||||||
|
|
||||||
} else if (m_length_depth_type == LengthDepth::ABS) {
|
} else if (length_depth_type == LengthDepth::ABS) {
|
||||||
m_segments.emplace_back( 1, 1, 0, m_length_top, m_depth_top,
|
m_segments.emplace_back( 1, 1, 0, length_top, depth_top,
|
||||||
invalid_value, invalid_value, invalid_value,
|
invalid_value, invalid_value, invalid_value,
|
||||||
m_volume_top, true , Segment::SegmentType::REGULAR);
|
volume_top, true , Segment::SegmentType::REGULAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read all the information out from the DECK first then process to get all the required information
|
// read all the information out from the DECK first then process to get all the required information
|
||||||
@ -182,7 +162,7 @@ namespace Opm {
|
|||||||
double volume;
|
double volume;
|
||||||
if (itemVolume.hasValue(0)) {
|
if (itemVolume.hasValue(0)) {
|
||||||
volume = itemVolume.getSIDouble(0);
|
volume = itemVolume.getSIDouble(0);
|
||||||
} else if (m_length_depth_type == LengthDepth::INC) {
|
} else if (length_depth_type == LengthDepth::INC) {
|
||||||
volume = area * segment_length;
|
volume = area * segment_length;
|
||||||
} else {
|
} else {
|
||||||
volume = invalid_value; // A * L, while L is not determined yet
|
volume = invalid_value; // A * L, while L is not determined yet
|
||||||
@ -200,7 +180,7 @@ namespace Opm {
|
|||||||
outlet_segment = i - 1;
|
outlet_segment = i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_length_depth_type == LengthDepth::INC) {
|
if (length_depth_type == LengthDepth::INC) {
|
||||||
m_segments.emplace_back( i, branch, outlet_segment, segment_length, depth_change,
|
m_segments.emplace_back( i, branch, outlet_segment, segment_length, depth_change,
|
||||||
diameter, roughness, area, volume, false , Segment::SegmentType::REGULAR);
|
diameter, roughness, area, volume, false , Segment::SegmentType::REGULAR);
|
||||||
} else if (i == segment2) {
|
} else if (i == segment2) {
|
||||||
@ -232,6 +212,9 @@ namespace Opm {
|
|||||||
m_segments[outlet_segment_index].addInletSegment(segment_number);
|
m_segments[outlet_segment_index].addInletSegment(segment_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this->process(length_depth_type, depth_top, length_top);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Segment& WellSegments::getFromSegmentNumber(const int segment_number) const {
|
const Segment& WellSegments::getFromSegmentNumber(const int segment_number) const {
|
||||||
@ -244,11 +227,11 @@ namespace Opm {
|
|||||||
return m_segments[segment_index];
|
return m_segments[segment_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellSegments::process(bool first_time) {
|
void WellSegments::process(LengthDepth length_depth, double depth_top, double length_top) {
|
||||||
if (this->m_length_depth_type == LengthDepth::ABS)
|
if (length_depth == LengthDepth::ABS)
|
||||||
this->processABS();
|
this->processABS();
|
||||||
else if (this->m_length_depth_type == LengthDepth::INC)
|
else if (length_depth == LengthDepth::INC)
|
||||||
this->processINC(first_time);
|
this->processINC(depth_top, length_top);
|
||||||
else
|
else
|
||||||
throw std::logic_error("Invalid llength/depth/type in segment data structure");
|
throw std::logic_error("Invalid llength/depth/type in segment data structure");
|
||||||
}
|
}
|
||||||
@ -299,16 +282,22 @@ namespace Opm {
|
|||||||
const double volume_segment = m_segments[range_end].crossArea() * length_inc;
|
const double volume_segment = m_segments[range_end].crossArea() * length_inc;
|
||||||
|
|
||||||
for (int k = range_begin; k <= range_end; ++k) {
|
for (int k = range_begin; k <= range_end; ++k) {
|
||||||
Segment new_segment = m_segments[k];
|
const auto& old_segment = this->m_segments[k];
|
||||||
const double temp_length = length_outlet + (k - range_begin + 1) * length_inc;
|
double new_volume, new_length, new_depth;
|
||||||
const double temp_depth = depth_outlet + (k - range_end + 1) * depth_inc;
|
if (k == range_end) {
|
||||||
if (k != range_end) {
|
new_length = old_segment.totalLength();
|
||||||
new_segment.setDepthAndLength(temp_depth, temp_length);
|
new_depth = old_segment.depth();
|
||||||
|
} else {
|
||||||
|
new_length = length_outlet + (k - range_begin + 1) * length_inc;
|
||||||
|
new_depth = depth_outlet + (k - range_end + 1) * depth_inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_segment.volume() < 0.5 * invalid_value) {
|
if (old_segment.volume() < 0.5 * invalid_value)
|
||||||
new_segment.setVolume(volume_segment);
|
new_volume = volume_segment;
|
||||||
}
|
else
|
||||||
|
new_volume = old_segment.volume();
|
||||||
|
|
||||||
|
Segment new_segment(old_segment, new_length, new_depth, new_volume);
|
||||||
addSegment(new_segment);
|
addSegment(new_segment);
|
||||||
}
|
}
|
||||||
current_index= range_end + 1;
|
current_index= range_end + 1;
|
||||||
@ -319,26 +308,23 @@ namespace Opm {
|
|||||||
for (int i = 1; i < size(); ++i) {
|
for (int i = 1; i < size(); ++i) {
|
||||||
assert(m_segments[i].dataReady());
|
assert(m_segments[i].dataReady());
|
||||||
if (m_segments[i].volume() == invalid_value) {
|
if (m_segments[i].volume() == invalid_value) {
|
||||||
Segment new_segment = m_segments[i];
|
const auto& old_segment = this->m_segments[i];
|
||||||
const int outlet_segment = m_segments[i].outletSegment();
|
const int outlet_segment = m_segments[i].outletSegment();
|
||||||
const int outlet_index = segmentNumberToIndex(outlet_segment);
|
const int outlet_index = segmentNumberToIndex(outlet_segment);
|
||||||
const double segment_length = m_segments[i].totalLength() - m_segments[outlet_index].totalLength();
|
const double segment_length = m_segments[i].totalLength() - m_segments[outlet_index].totalLength();
|
||||||
const double segment_volume = m_segments[i].crossArea() * segment_length;
|
const double segment_volume = m_segments[i].crossArea() * segment_length;
|
||||||
new_segment.setVolume(segment_volume);
|
|
||||||
|
Segment new_segment(old_segment, segment_volume);
|
||||||
addSegment(new_segment);
|
addSegment(new_segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellSegments::processINC(const bool first_time) {
|
void WellSegments::processINC(double depth_top, double length_top) {
|
||||||
|
|
||||||
// update the information inside the WellSegments to be in ABS way
|
// update the information inside the WellSegments to be in ABS way
|
||||||
if (first_time) {
|
Segment new_top_segment(this->m_segments[0], depth_top, length_top);
|
||||||
Segment new_top_segment = (*this)[0];
|
this->addSegment(new_top_segment);
|
||||||
new_top_segment.setDepthAndLength(depthTopSegment(), lengthTopSegment());
|
|
||||||
this->addSegment(new_top_segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
orderSegments();
|
orderSegments();
|
||||||
|
|
||||||
// begin with the second segment
|
// begin with the second segment
|
||||||
@ -359,8 +345,7 @@ namespace Opm {
|
|||||||
const double temp_length = outlet_length + m_segments[i_index].totalLength();
|
const double temp_length = outlet_length + m_segments[i_index].totalLength();
|
||||||
|
|
||||||
// applying the calculated length and depth to the current segment
|
// applying the calculated length and depth to the current segment
|
||||||
Segment new_segment = this->m_segments[i_index];
|
Segment new_segment(this->m_segments[i_index], temp_depth, temp_length);
|
||||||
new_segment.setDepthAndLength(temp_depth, temp_length);
|
|
||||||
addSegment(new_segment);
|
addSegment(new_segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,13 +407,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool WellSegments::operator==( const WellSegments& rhs ) const {
|
bool WellSegments::operator==( const WellSegments& rhs ) const {
|
||||||
return this->m_well_name == rhs.m_well_name
|
return this->m_comp_pressure_drop == rhs.m_comp_pressure_drop
|
||||||
&& this->m_depth_top == rhs.m_depth_top
|
|
||||||
&& this->m_length_top == rhs.m_length_top
|
|
||||||
&& this->m_volume_top == rhs.m_volume_top
|
|
||||||
&& this->m_length_depth_type == rhs.m_length_depth_type
|
|
||||||
&& this->m_comp_pressure_drop == rhs.m_comp_pressure_drop
|
|
||||||
&& this->m_multiphase_model == rhs.m_multiphase_model
|
|
||||||
&& this->m_segments.size() == rhs.m_segments.size()
|
&& this->m_segments.size() == rhs.m_segments.size()
|
||||||
&& this->segment_number_to_index.size() == rhs.segment_number_to_index.size()
|
&& this->segment_number_to_index.size() == rhs.segment_number_to_index.size()
|
||||||
&& std::equal( this->m_segments.begin(),
|
&& std::equal( this->m_segments.begin(),
|
||||||
@ -462,8 +441,7 @@ namespace Opm {
|
|||||||
|
|
||||||
bool WellSegments::updateWSEGSICD(const std::vector<std::pair<int, SpiralICD> >& sicd_pairs) {
|
bool WellSegments::updateWSEGSICD(const std::vector<std::pair<int, SpiralICD> >& sicd_pairs) {
|
||||||
if (m_comp_pressure_drop == CompPressureDrop::H__) {
|
if (m_comp_pressure_drop == CompPressureDrop::H__) {
|
||||||
const std::string msg = "to use spiral ICD segment for well " + m_well_name
|
const std::string msg = "to use spiral ICD segment you have to activate the frictional pressure drop calculation";
|
||||||
+ " , you have to activate the frictional pressure drop calculation";
|
|
||||||
throw std::runtime_error(msg);
|
throw std::runtime_error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,8 +459,7 @@ namespace Opm {
|
|||||||
bool WellSegments::updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs) {
|
bool WellSegments::updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs) {
|
||||||
|
|
||||||
if (m_comp_pressure_drop == CompPressureDrop::H__) {
|
if (m_comp_pressure_drop == CompPressureDrop::H__) {
|
||||||
const std::string msg = "to use WSEGVALV segment for well " + m_well_name
|
const std::string msg = "to use WSEGVALV segment you have to activate the frictional pressure drop calculation";
|
||||||
+ " , you have to activate the frictional pressure drop calculation";
|
|
||||||
throw std::runtime_error(msg);
|
throw std::runtime_error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,10 +553,6 @@ WellSegments::MultiPhaseModel WellSegments::MultiPhaseModelFromString(const std:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WellSegments::LengthDepth WellSegments::lengthDepthType() const {
|
|
||||||
return m_length_depth_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<Segment>& WellSegments::segments() const {
|
const std::vector<Segment>& WellSegments::segments() const {
|
||||||
return m_segments;
|
return m_segments;
|
||||||
}
|
}
|
||||||
|
@ -758,16 +758,9 @@ bool Well::handleWELSEGS(const DeckKeyword& keyword) {
|
|||||||
if( this->segments )
|
if( this->segments )
|
||||||
throw std::logic_error("re-entering WELSEGS for a well is not supported yet!!.");
|
throw std::logic_error("re-entering WELSEGS for a well is not supported yet!!.");
|
||||||
|
|
||||||
auto new_segmentset = std::make_shared<WellSegments>();
|
this->segments = std::make_shared<WellSegments>(keyword);
|
||||||
new_segmentset->loadWELSEGS(keyword);
|
this->ref_depth = this->segments->depthTopSegment();
|
||||||
|
return true;
|
||||||
new_segmentset->process(true);
|
|
||||||
if (new_segmentset != this->segments) {
|
|
||||||
this->segments = new_segmentset;
|
|
||||||
this->ref_depth = new_segmentset->depthTopSegment();
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,10 +90,8 @@ BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
|||||||
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
||||||
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
||||||
|
|
||||||
Opm::WellSegments segment_set;
|
|
||||||
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
||||||
|
Opm::WellSegments segment_set(welsegs);
|
||||||
segment_set.loadWELSEGS(welsegs);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(7U, segment_set.size());
|
BOOST_CHECK_EQUAL(7U, segment_set.size());
|
||||||
|
|
||||||
@ -237,9 +235,8 @@ BOOST_AUTO_TEST_CASE(WrongDistanceCOMPSEGS) {
|
|||||||
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
||||||
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
||||||
|
|
||||||
Opm::WellSegments segment_set;
|
|
||||||
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
||||||
segment_set.loadWELSEGS(welsegs);
|
Opm::WellSegments segment_set(welsegs);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(6U, segment_set.size());
|
BOOST_CHECK_EQUAL(6U, segment_set.size());
|
||||||
|
|
||||||
@ -295,9 +292,8 @@ BOOST_AUTO_TEST_CASE(NegativeDepthCOMPSEGS) {
|
|||||||
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
||||||
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
||||||
|
|
||||||
Opm::WellSegments segment_set;
|
|
||||||
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
||||||
segment_set.loadWELSEGS(welsegs);
|
Opm::WellSegments segment_set(welsegs);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(6U, segment_set.size());
|
BOOST_CHECK_EQUAL(6U, segment_set.size());
|
||||||
|
|
||||||
@ -360,10 +356,8 @@ BOOST_AUTO_TEST_CASE(testwsegvalv) {
|
|||||||
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
const Opm::DeckKeyword compsegs = deck.getKeyword("COMPSEGS");
|
||||||
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
BOOST_CHECK_EQUAL( 8U, compsegs.size() );
|
||||||
|
|
||||||
Opm::WellSegments segment_set;
|
|
||||||
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
||||||
|
Opm::WellSegments segment_set(welsegs);
|
||||||
segment_set.loadWELSEGS(welsegs);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(8U, segment_set.size());
|
BOOST_CHECK_EQUAL(8U, segment_set.size());
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <opm/io/eclipse/rst/state.hpp>
|
#include <opm/io/eclipse/rst/state.hpp>
|
||||||
#include <opm/io/eclipse/ERst.hpp>
|
#include <opm/io/eclipse/ERst.hpp>
|
||||||
|
|
||||||
@ -28,6 +31,7 @@ int main(int argc, char ** argv) {
|
|||||||
Opm::EclIO::ERst rst_file(argv[iarg]);
|
Opm::EclIO::ERst rst_file(argv[iarg]);
|
||||||
for (int report_step : rst_file.listOfReportStepNumbers()) {
|
for (int report_step : rst_file.listOfReportStepNumbers()) {
|
||||||
if (report_step > 0) {
|
if (report_step > 0) {
|
||||||
|
std::cout << "Loading restart step: " << report_step << std::endl;
|
||||||
const auto& state = Opm::RestartIO::RstState::load(rst_file, report_step);
|
const auto& state = Opm::RestartIO::RstState::load(rst_file, report_step);
|
||||||
static_cast<void>(state); // Suppress unused variable warning.
|
static_cast<void>(state); // Suppress unused variable warning.
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user