Make Segment/Compsegs no longer use shared_ptr
This commit is contained in:
@@ -45,11 +45,11 @@ namespace Opm {
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<CompsegsPtr> Compsegs::compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword ) {
|
||||
std::vector< Compsegs > Compsegs::compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword ) {
|
||||
|
||||
// only handle the second record here
|
||||
// The first record here only contains the well name
|
||||
std::vector<CompsegsPtr> compsegs;
|
||||
std::vector< Compsegs > compsegs;
|
||||
|
||||
for (size_t recordIndex = 1; recordIndex < compsegsKeyword.size(); ++recordIndex) {
|
||||
const auto& record = compsegsKeyword.getRecord(recordIndex);
|
||||
@@ -120,9 +120,12 @@ namespace Opm {
|
||||
}
|
||||
|
||||
if (!record.getItem<ParserKeywords::COMPSEGS::END_IJK>().hasValue(0)) { // only one compsegs
|
||||
CompsegsPtr new_compsegs = std::make_shared<Compsegs>(I, J, K, branch, distance_start, distance_end,
|
||||
direction, center_depth, segment_number);
|
||||
compsegs.push_back(new_compsegs);
|
||||
compsegs.emplace_back( I, J, K,
|
||||
branch,
|
||||
distance_start, distance_end,
|
||||
direction,
|
||||
center_depth,
|
||||
segment_number );
|
||||
} else { // a range is defined. genrate a range of Compsegs
|
||||
throw std::runtime_error("entering COMPSEGS entries with a range is not supported yet!");
|
||||
}
|
||||
@@ -131,67 +134,71 @@ namespace Opm {
|
||||
return compsegs;
|
||||
}
|
||||
|
||||
void Compsegs::processCOMPSEGS(std::vector<CompsegsPtr>& compsegs, SegmentSetConstPtr segment_set) {
|
||||
void Compsegs::processCOMPSEGS(std::vector< Compsegs >& compsegs, const SegmentSet& segment_set) {
|
||||
// for the current cases we have at the moment, the distance information is specified explicitly,
|
||||
// while the depth information is defaulted though, which need to be obtained from the related segment
|
||||
for (size_t i_comp = 0; i_comp < compsegs.size(); ++i_comp) {
|
||||
if (compsegs[i_comp]->m_segment_number == 0) { // need to determine the related segment number first
|
||||
const double center_distance = (compsegs[i_comp]->m_distance_start + compsegs[i_comp]->m_distance_end) / 2.0;
|
||||
const int branch_number = compsegs[i_comp]->m_branch_number;
|
||||
for( auto& compseg : compsegs ) {
|
||||
|
||||
int segment_number = 0;
|
||||
double min_distance_difference = 1.e100; // begin with a big value
|
||||
for (int i_segment = 0; i_segment < segment_set->numberSegment(); ++i_segment) {
|
||||
SegmentConstPtr current_segment = (*segment_set)[i_segment];
|
||||
if (branch_number == current_segment->branchNumber()) {
|
||||
const double distance = current_segment->totalLength();
|
||||
const double distance_difference = std::abs(center_distance - distance);
|
||||
if (distance_difference < min_distance_difference) {
|
||||
min_distance_difference = distance_difference;
|
||||
segment_number = current_segment->segmentNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
// need to determine the related segment number first
|
||||
if (compseg.m_segment_number != 0) continue;
|
||||
|
||||
if (segment_number != 0) {
|
||||
compsegs[i_comp]->m_segment_number = segment_number;
|
||||
if (compsegs[i_comp]->m_center_depth == 0.) {
|
||||
// using the depth of the segment node as the depth of the completion
|
||||
// TODO: now only one completion for one segment is hanlded,
|
||||
// TODO: later we will try to handle more than one completion for each segment,
|
||||
// TODO: which will be a linear interpolation based on the segment node depth
|
||||
// TODO: in the same branch, while the actually way is not clear yet
|
||||
const int segment_location = segment_set->numberToLocation(segment_number);
|
||||
compsegs[i_comp]->m_center_depth = (*segment_set)[segment_location]->depth();
|
||||
} else if (compsegs[i_comp]->m_center_depth < 0.) {
|
||||
throw std::runtime_error(" obtaining perforation depth from COMPDAT data is not supported yet \n");
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error(" the perforation failed in finding a related segment \n");
|
||||
const double center_distance = (compseg.m_distance_start + compseg.m_distance_end) / 2.0;
|
||||
const int branch_number = compseg.m_branch_number;
|
||||
|
||||
int segment_number = 0;
|
||||
double min_distance_difference = 1.e100; // begin with a big value
|
||||
for (int i_segment = 0; i_segment < segment_set.numberSegment(); ++i_segment) {
|
||||
const Segment& current_segment = segment_set[i_segment];
|
||||
if( branch_number != current_segment.branchNumber() ) continue;
|
||||
|
||||
const double distance = current_segment.totalLength();
|
||||
const double distance_difference = std::abs(center_distance - distance);
|
||||
if (distance_difference < min_distance_difference) {
|
||||
min_distance_difference = distance_difference;
|
||||
segment_number = current_segment.segmentNumber();
|
||||
}
|
||||
}
|
||||
|
||||
if (segment_number == 0) {
|
||||
throw std::runtime_error("The perforation failed in finding a related segment \n");
|
||||
}
|
||||
|
||||
if (compseg.m_center_depth < 0.) {
|
||||
throw std::runtime_error("Obtaining perforation depth from COMPDAT data is not supported yet");
|
||||
}
|
||||
|
||||
compseg.m_segment_number = segment_number;
|
||||
if (compseg.m_center_depth == 0.) {
|
||||
// using the depth of the segment node as the depth of the completion
|
||||
// TODO: now only one completion for one segment is hanlded,
|
||||
// TODO: later we will try to handle more than one completion for each segment,
|
||||
// TODO: which will be a linear interpolation based on the segment node depth
|
||||
// TODO: in the same branch, while the actually way is not clear yet
|
||||
const int segment_location = segment_set.numberToLocation(segment_number);
|
||||
compseg.m_center_depth = segment_set[segment_location].depth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Compsegs::updateCompletionsWithSegment(const std::vector<CompsegsPtr>& compsegs,
|
||||
CompletionSetPtr completion_set) {
|
||||
void Compsegs::updateCompletionsWithSegment(const std::vector< Compsegs >& compsegs,
|
||||
CompletionSet& completion_set) {
|
||||
|
||||
for (size_t i_comp = 0; i_comp < compsegs.size(); ++i_comp) {
|
||||
const int i = compsegs[i_comp]->m_i;
|
||||
const int j = compsegs[i_comp]->m_j;
|
||||
const int k = compsegs[i_comp]->m_k;
|
||||
for( const auto& compseg : compsegs ) {
|
||||
const int i = compseg.m_i;
|
||||
const int j = compseg.m_j;
|
||||
const int k = compseg.m_k;
|
||||
|
||||
CompletionPtr new_completion = std::make_shared<Completion>(completion_set->getFromIJK(i, j, k));
|
||||
new_completion->attachSegment(compsegs[i_comp]->m_segment_number, compsegs[i_comp]->m_center_depth);
|
||||
completion_set->add(new_completion);
|
||||
CompletionPtr new_completion = std::make_shared<Completion>(completion_set.getFromIJK(i, j, k));
|
||||
new_completion->attachSegment(compseg.m_segment_number, compseg.m_center_depth);
|
||||
completion_set.add(new_completion);
|
||||
}
|
||||
|
||||
for (size_t ic = 0; ic < completion_set->size(); ++ic) {
|
||||
if ( !(completion_set->get(ic)->attachedToSegment()) ) {
|
||||
throw std::runtime_error(" not all the completions are attached with a segment,\n the information from COMPSEGS are not complete");
|
||||
for (size_t ic = 0; ic < completion_set.size(); ++ic) {
|
||||
if ( !(completion_set.get(ic)->attachedToSegment()) ) {
|
||||
throw std::runtime_error("Not all the completions are attached with a segment. "
|
||||
"The information from COMPSEGS is not complete");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,19 +52,16 @@ namespace Opm {
|
||||
Compsegs(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
|
||||
WellCompletion::DirectionEnum dir_in, double center_depth_in, int segment_number_in);
|
||||
|
||||
static std::vector<std::shared_ptr<Compsegs>> compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword );
|
||||
static std::vector< Compsegs > compsegsFromCOMPSEGSKeyword( const DeckKeyword& compsegsKeyword );
|
||||
|
||||
// get the segment number information and depth information based on the information from SegmentSet
|
||||
static void processCOMPSEGS(std::vector<std::shared_ptr<Compsegs>>& compsegs, std::shared_ptr< const SegmentSet > segment_set);
|
||||
static void processCOMPSEGS(std::vector< Compsegs >& compsegs, const SegmentSet& segment_set );
|
||||
|
||||
// update the segment related information for Completions
|
||||
static void updateCompletionsWithSegment(const std::vector<std::shared_ptr<Compsegs>>& compsegs,
|
||||
std::shared_ptr< CompletionSet > completion_set);
|
||||
static void updateCompletionsWithSegment(const std::vector< Compsegs >& compsegs,
|
||||
CompletionSet& completion_set);
|
||||
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Compsegs> CompsegsPtr;
|
||||
typedef std::shared_ptr<const Compsegs> CompsegsConstPtr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,21 +52,6 @@ namespace Opm {
|
||||
{
|
||||
}
|
||||
|
||||
Segment::Segment(std::shared_ptr<const Segment> segment_in)
|
||||
: m_segment_number(segment_in->segmentNumber()),
|
||||
m_branch(segment_in->branchNumber()),
|
||||
m_outlet_segment(segment_in->outletSegment()),
|
||||
m_total_length(segment_in->totalLength()),
|
||||
m_depth(segment_in->depth()),
|
||||
m_internal_diameter(segment_in->internalDiameter()),
|
||||
m_roughness(segment_in->roughness()),
|
||||
m_cross_area(segment_in->crossArea()),
|
||||
m_volume(segment_in->volume()),
|
||||
m_data_ready(segment_in->dataReady())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int Segment::segmentNumber() const {
|
||||
return m_segment_number;
|
||||
}
|
||||
@@ -128,4 +113,29 @@ namespace Opm {
|
||||
return invalid_value;
|
||||
}
|
||||
|
||||
bool Segment::operator==( const Segment& rhs ) const {
|
||||
return this->m_segment_number == rhs.m_segment_number
|
||||
&& this->m_branch == rhs.m_branch
|
||||
&& this->m_outlet_segment == rhs.m_outlet_segment
|
||||
&& this->m_total_length == rhs.m_total_length
|
||||
&& this->m_depth == rhs.m_depth
|
||||
&& this->m_internal_diameter == rhs.m_internal_diameter
|
||||
&& this->m_roughness == rhs.m_roughness
|
||||
&& this->m_cross_area == rhs.m_cross_area
|
||||
&& this->m_volume == rhs.m_volume
|
||||
&& this->m_data_ready == rhs.m_data_ready;
|
||||
}
|
||||
|
||||
bool Segment::operator!=( const Segment& rhs ) const {
|
||||
return this->m_segment_number == rhs.m_segment_number
|
||||
&& this->m_branch == rhs.m_branch
|
||||
&& this->m_outlet_segment == rhs.m_outlet_segment
|
||||
&& this->m_total_length == rhs.m_total_length
|
||||
&& this->m_depth == rhs.m_depth
|
||||
&& this->m_internal_diameter == rhs.m_internal_diameter
|
||||
&& this->m_roughness == rhs.m_roughness
|
||||
&& this->m_cross_area == rhs.m_cross_area
|
||||
&& this->m_volume == rhs.m_volume
|
||||
&& this->m_data_ready == rhs.m_data_ready;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace Opm {
|
||||
|
||||
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);
|
||||
Segment(std::shared_ptr<const Segment> segment_in);
|
||||
|
||||
int segmentNumber() const;
|
||||
int branchNumber() const;
|
||||
@@ -48,6 +47,9 @@ namespace Opm {
|
||||
|
||||
static double invalidValue();
|
||||
|
||||
bool operator==( const Segment& ) const;
|
||||
bool operator!=( const Segment& ) const;
|
||||
|
||||
|
||||
private:
|
||||
// segment number
|
||||
@@ -100,10 +102,6 @@ namespace Opm {
|
||||
// while they are not supported by the keyword at the moment.
|
||||
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Segment> SegmentPtr;
|
||||
typedef std::shared_ptr<const Segment> SegmentConstPtr;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,9 +35,6 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
SegmentSet::SegmentSet() {
|
||||
}
|
||||
|
||||
std::string SegmentSet::wellName() const {
|
||||
return m_well_name;
|
||||
}
|
||||
@@ -74,7 +71,7 @@ namespace Opm {
|
||||
return m_multiphase_model;
|
||||
}
|
||||
|
||||
SegmentConstPtr SegmentSet::operator[](size_t idx) const {
|
||||
const Segment& SegmentSet::operator[](size_t idx) const {
|
||||
return m_segments[idx];
|
||||
}
|
||||
|
||||
@@ -87,9 +84,9 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void SegmentSet::addSegment(SegmentConstPtr new_segment) {
|
||||
void SegmentSet::addSegment( Segment new_segment ) {
|
||||
// decide whether to push_back or insert
|
||||
int segment_number = new_segment->segmentNumber();
|
||||
int segment_number = new_segment.segmentNumber();
|
||||
|
||||
const int segment_location = numberToLocation(segment_number);
|
||||
|
||||
@@ -101,24 +98,6 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
SegmentSet* SegmentSet::shallowCopy() const {
|
||||
SegmentSet* copy = new SegmentSet();
|
||||
copy->m_well_name = m_well_name;
|
||||
copy->m_number_branch = m_number_branch;
|
||||
copy->m_depth_top = m_depth_top;
|
||||
copy->m_length_top = m_length_top;
|
||||
copy->m_volume_top = m_volume_top;
|
||||
copy->m_length_depth_type = m_length_depth_type;
|
||||
copy->m_comp_pressure_drop = m_comp_pressure_drop;
|
||||
copy->m_multiphase_model = m_multiphase_model;
|
||||
copy->m_number_to_location = m_number_to_location;
|
||||
copy->m_segments.resize(m_segments.size());
|
||||
for (int i = 0; i < int(m_segments.size()); ++i) {
|
||||
copy->m_segments[i] = m_segments[i];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
void SegmentSet::segmentsFromWELSEGSKeyword( const DeckKeyword& welsegsKeyword ) {
|
||||
|
||||
// for the first record, which provides the information for the top segment
|
||||
@@ -140,13 +119,14 @@ namespace Opm {
|
||||
// the main branch is 1 instead of 0
|
||||
// the segment number for top segment is also 1
|
||||
if (m_length_depth_type == WellSegment::INC) {
|
||||
SegmentConstPtr top_segment(new Segment(1, 1, 0, 0., 0., invalid_value, invalid_value, invalid_value,
|
||||
m_volume_top, false));
|
||||
m_segments.push_back(top_segment);
|
||||
m_segments.emplace_back( 1, 1, 0, 0., 0.,
|
||||
invalid_value, invalid_value, invalid_value,
|
||||
m_volume_top, false );
|
||||
|
||||
} else if (m_length_depth_type == WellSegment::ABS) {
|
||||
SegmentConstPtr top_segment(new Segment(1, 1, 0, m_length_top, m_depth_top, invalid_value, invalid_value,
|
||||
invalid_value, m_volume_top, true));
|
||||
m_segments.push_back(top_segment);
|
||||
m_segments.emplace_back( 1, 1, 0, m_length_top, m_depth_top,
|
||||
invalid_value, invalid_value, invalid_value,
|
||||
m_volume_top, true );
|
||||
}
|
||||
|
||||
// read all the information out from the DECK first then process to get all the required information
|
||||
@@ -205,20 +185,20 @@ namespace Opm {
|
||||
}
|
||||
|
||||
if (m_length_depth_type == WellSegment::INC) {
|
||||
m_segments.push_back(std::make_shared<const Segment>(i, branch, outlet_segment, segment_length, depth_change,
|
||||
diameter, roughness, area, volume, false));
|
||||
m_segments.emplace_back( i, branch, outlet_segment, segment_length, depth_change,
|
||||
diameter, roughness, area, volume, false );
|
||||
} else if (i == segment2) {
|
||||
m_segments.push_back(std::make_shared<const Segment>(i, branch, outlet_segment, segment_length, depth_change,
|
||||
diameter, roughness, area, volume, true));
|
||||
m_segments.emplace_back( i, branch, outlet_segment, segment_length, depth_change,
|
||||
diameter, roughness, area, volume, true );
|
||||
} else {
|
||||
m_segments.push_back(std::make_shared<const Segment>(i, branch, outlet_segment, invalid_value, invalid_value,
|
||||
diameter, roughness, area, volume, false));
|
||||
m_segments.emplace_back( i, branch, outlet_segment, invalid_value, invalid_value,
|
||||
diameter, roughness, area, volume, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i_segment = 0; i_segment < m_segments.size(); ++i_segment){
|
||||
const int segment_number = m_segments[i_segment]->segmentNumber();
|
||||
const int segment_number = m_segments[i_segment].segmentNumber();
|
||||
const int location = numberToLocation(segment_number);
|
||||
if (location >= 0) { // found in the existing m_segments already
|
||||
throw std::logic_error("Segments with same segment number are found!\n");
|
||||
@@ -235,20 +215,20 @@ namespace Opm {
|
||||
|
||||
int current_loc = 1;
|
||||
while (current_loc < numberSegment()) {
|
||||
if (m_segments[current_loc]->dataReady()) {
|
||||
if (m_segments[current_loc].dataReady()) {
|
||||
current_loc ++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const int range_begin = current_loc;
|
||||
const int outlet_segment = m_segments[range_begin]->outletSegment();
|
||||
const int outlet_segment = m_segments[range_begin].outletSegment();
|
||||
const int outlet_loc = numberToLocation(outlet_segment);
|
||||
|
||||
assert(m_segments[outlet_loc]->dataReady() == true);
|
||||
assert(m_segments[outlet_loc].dataReady() == true);
|
||||
|
||||
int range_end = range_begin + 1;
|
||||
for (; range_end < numberSegment(); ++range_end) {
|
||||
if (m_segments[range_end]->dataReady() == true) {
|
||||
if (m_segments[range_end].dataReady() == true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -261,27 +241,27 @@ namespace Opm {
|
||||
int number_segments = range_end - range_begin + 1;
|
||||
assert(number_segments > 1); //if only 1, the information should be complete
|
||||
|
||||
const double length_outlet = m_segments[outlet_loc]->totalLength();
|
||||
const double depth_outlet = m_segments[outlet_loc]->depth();
|
||||
const double length_outlet = m_segments[outlet_loc].totalLength();
|
||||
const double depth_outlet = m_segments[outlet_loc].depth();
|
||||
|
||||
const double length_last = m_segments[range_end]->totalLength();
|
||||
const double depth_last = m_segments[range_end]->depth();
|
||||
const double length_last = m_segments[range_end].totalLength();
|
||||
const double depth_last = m_segments[range_end].depth();
|
||||
|
||||
// incremental length and depth for the segments within the range
|
||||
const double length_inc = (length_last - length_outlet) / number_segments;
|
||||
const double depth_inc = (depth_last - depth_outlet) / number_segments;
|
||||
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) {
|
||||
SegmentPtr new_segment = std::make_shared<Segment>(m_segments[k]);
|
||||
Segment new_segment = m_segments[k];
|
||||
const double temp_length = length_outlet + (k - range_begin + 1) * length_inc;
|
||||
const double temp_depth = depth_outlet + (k - range_end + 1) * depth_inc;
|
||||
if (k != range_end) {
|
||||
new_segment->setDepthAndLength(temp_depth, temp_length);
|
||||
new_segment.setDepthAndLength(temp_depth, temp_length);
|
||||
}
|
||||
|
||||
if (new_segment->volume() < 0.5 * invalid_value) {
|
||||
new_segment->setVolume(volume_segment);
|
||||
if (new_segment.volume() < 0.5 * invalid_value) {
|
||||
new_segment.setVolume(volume_segment);
|
||||
}
|
||||
addSegment(new_segment);
|
||||
}
|
||||
@@ -291,14 +271,14 @@ namespace Opm {
|
||||
// then update the volume for all the segments except the top segment
|
||||
// this is for the segments specified individually while the volume is not specified.
|
||||
for (int i = 1; i < numberSegment(); ++i) {
|
||||
assert(m_segments[i]->dataReady());
|
||||
if (m_segments[i]->volume() == invalid_value) {
|
||||
SegmentPtr new_segment = std::make_shared<Segment>(m_segments[i]);
|
||||
const int outlet_segment = m_segments[i]->outletSegment();
|
||||
assert(m_segments[i].dataReady());
|
||||
if (m_segments[i].volume() == invalid_value) {
|
||||
Segment new_segment = m_segments[i];
|
||||
const int outlet_segment = m_segments[i].outletSegment();
|
||||
const int outlet_location = numberToLocation(outlet_segment);
|
||||
const double segment_length = m_segments[i]->totalLength() - m_segments[outlet_location]->totalLength();
|
||||
const double segment_volume = m_segments[i]->crossArea() * segment_length;
|
||||
new_segment->setVolume(segment_volume);
|
||||
const double segment_length = m_segments[i].totalLength() - m_segments[outlet_location].totalLength();
|
||||
const double segment_volume = m_segments[i].crossArea() * segment_length;
|
||||
new_segment.setVolume(segment_volume);
|
||||
addSegment(new_segment);
|
||||
}
|
||||
}
|
||||
@@ -308,8 +288,8 @@ namespace Opm {
|
||||
|
||||
// update the information inside the SegmentSet to be in ABS way
|
||||
if (first_time) {
|
||||
SegmentPtr new_top_segment = std::make_shared<Segment>((*this)[0]);
|
||||
new_top_segment->setDepthAndLength(depthTopSegment(), lengthTopSegment());
|
||||
Segment new_top_segment = (*this)[0];
|
||||
new_top_segment.setDepthAndLength(depthTopSegment(), lengthTopSegment());
|
||||
this->addSegment(new_top_segment);
|
||||
}
|
||||
|
||||
@@ -317,25 +297,25 @@ namespace Opm {
|
||||
|
||||
// begin with the second segment
|
||||
for (int i_loc = 1; i_loc < numberSegment(); ++i_loc) {
|
||||
if (m_segments[i_loc]->dataReady() == false) {
|
||||
// find its outlet segment
|
||||
const int outlet_segment = m_segments[i_loc]->outletSegment();
|
||||
const int outlet_loc = numberToLocation(outlet_segment);
|
||||
if( m_segments[i_loc].dataReady() ) continue;
|
||||
|
||||
// assert some information of the outlet_segment
|
||||
assert(outlet_loc >= 0);
|
||||
assert(m_segments[outlet_loc]->dataReady());
|
||||
// find its outlet segment
|
||||
const int outlet_segment = m_segments[i_loc].outletSegment();
|
||||
const int outlet_loc = numberToLocation(outlet_segment);
|
||||
|
||||
const double outlet_depth = m_segments[outlet_loc]->depth();
|
||||
const double outlet_length = m_segments[outlet_loc]->totalLength();
|
||||
const double temp_depth = outlet_depth + m_segments[i_loc]->depth();
|
||||
const double temp_length = outlet_length + m_segments[i_loc]->totalLength();
|
||||
// assert some information of the outlet_segment
|
||||
assert(outlet_loc >= 0);
|
||||
assert(m_segments[outlet_loc].dataReady());
|
||||
|
||||
// applying the calculated length and depth to the current segment
|
||||
SegmentPtr new_segment = std::make_shared<Segment>(m_segments[i_loc]);
|
||||
new_segment->setDepthAndLength(temp_depth, temp_length);
|
||||
addSegment(new_segment);
|
||||
}
|
||||
const double outlet_depth = m_segments[outlet_loc].depth();
|
||||
const double outlet_length = m_segments[outlet_loc].totalLength();
|
||||
const double temp_depth = outlet_depth + m_segments[i_loc].depth();
|
||||
const double temp_length = outlet_length + m_segments[i_loc].totalLength();
|
||||
|
||||
// applying the calculated length and depth to the current segment
|
||||
Segment new_segment = this->m_segments[i_loc];
|
||||
new_segment.setDepthAndLength(temp_depth, temp_length);
|
||||
addSegment(new_segment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,13 +336,13 @@ namespace Opm {
|
||||
|
||||
while (current_loc < numberSegment()) {
|
||||
// the branch number of the last segment that is done re-ordering
|
||||
const int last_branch_number = m_segments[current_loc-1]->branchNumber();
|
||||
const int last_branch_number = m_segments[current_loc-1].branchNumber();
|
||||
// the one need to be swapped to the current_loc.
|
||||
int target_segment_loc = -1;
|
||||
|
||||
// looking for target_segment_loc
|
||||
for (int i_loc = current_loc; i_loc < numberSegment(); ++i_loc) {
|
||||
const int outlet_segment_number = m_segments[i_loc]->outletSegment();
|
||||
const int outlet_segment_number = m_segments[i_loc].outletSegment();
|
||||
const int outlet_segment_location = numberToLocation(outlet_segment_number);
|
||||
if (outlet_segment_location < 0) { // not found the outlet_segment in the done re-ordering segments
|
||||
continue;
|
||||
@@ -370,8 +350,8 @@ namespace Opm {
|
||||
if (target_segment_loc < 0) { // first time found a candidate
|
||||
target_segment_loc = i_loc;
|
||||
} else { // there is already a candidate, chosing the one with the same branch number with last_branch_number
|
||||
const int old_target_segment_loc_branch = m_segments[target_segment_loc]->branchNumber();
|
||||
const int new_target_segment_loc_branch = m_segments[i_loc]->branchNumber();
|
||||
const int old_target_segment_loc_branch = m_segments[target_segment_loc].branchNumber();
|
||||
const int new_target_segment_loc_branch = m_segments[i_loc].branchNumber();
|
||||
if (new_target_segment_loc_branch == last_branch_number) {
|
||||
if (old_target_segment_loc_branch != last_branch_number) {
|
||||
target_segment_loc = i_loc;
|
||||
@@ -389,10 +369,32 @@ namespace Opm {
|
||||
if (target_segment_loc > current_loc) {
|
||||
std::swap(m_segments[current_loc], m_segments[target_segment_loc]);
|
||||
}
|
||||
const int segment_number = m_segments[current_loc]->segmentNumber();
|
||||
const int segment_number = m_segments[current_loc].segmentNumber();
|
||||
m_number_to_location[segment_number] = current_loc;
|
||||
current_loc++;
|
||||
}
|
||||
}
|
||||
|
||||
bool SegmentSet::operator==( const SegmentSet& rhs ) const {
|
||||
return this->m_well_name == rhs.m_well_name
|
||||
&& this->m_number_branch == rhs.m_number_branch
|
||||
&& this->m_depth_top == rhs.m_depth_top
|
||||
&& this->m_length_top == rhs.m_length_top
|
||||
&& this->m_volume_top == rhs.m_length_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_number_to_location.size() == rhs.m_number_to_location.size()
|
||||
&& std::equal( this->m_segments.begin(),
|
||||
this->m_segments.end(),
|
||||
rhs.m_segments.begin() )
|
||||
&& std::equal( this->m_number_to_location.begin(),
|
||||
this->m_number_to_location.end(),
|
||||
rhs.m_number_to_location.begin() );
|
||||
}
|
||||
|
||||
bool SegmentSet::operator!=( const SegmentSet& rhs ) const {
|
||||
return !( *this == rhs );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Opm {
|
||||
|
||||
class SegmentSet {
|
||||
public:
|
||||
SegmentSet();
|
||||
SegmentSet() = default;
|
||||
|
||||
std::string wellName() const;
|
||||
int numberBranch() const;
|
||||
@@ -46,17 +46,18 @@ namespace Opm {
|
||||
WellSegment::MultiPhaseModelEnum multiPhaseModel() const;
|
||||
|
||||
int numberToLocation(const int segment_number) const;
|
||||
void addSegment(std::shared_ptr< const Segment > new_segment);
|
||||
void addSegment(Segment new_segment);
|
||||
|
||||
void segmentsFromWELSEGSKeyword( const DeckKeyword& welsegsKeyword);
|
||||
|
||||
SegmentSet* shallowCopy() const;
|
||||
|
||||
std::shared_ptr< const Segment > operator[](size_t idx) const;
|
||||
const Segment& operator[](size_t idx) const;
|
||||
void orderSegments();
|
||||
void processABS();
|
||||
void processINC(const bool first_time);
|
||||
|
||||
bool operator==( const SegmentSet& ) const;
|
||||
bool operator!=( const SegmentSet& ) const;
|
||||
|
||||
private:
|
||||
|
||||
// name of the well
|
||||
@@ -83,14 +84,11 @@ namespace Opm {
|
||||
// There are other three properties for segment related to thermal conduction,
|
||||
// while they are not supported by the keyword at the moment.
|
||||
|
||||
std::vector<std::shared_ptr< const Segment >> m_segments;
|
||||
std::vector< Segment > m_segments;
|
||||
// the mapping from the segment number to the
|
||||
// storage location in the vector
|
||||
std::map<int, int> m_number_to_location;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<SegmentSet> SegmentSetPtr;
|
||||
typedef std::shared_ptr<const SegmentSet> SegmentSetConstPtr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1218,11 +1218,11 @@ namespace Opm {
|
||||
}
|
||||
|
||||
void Schedule::handleWELSEGS( const DeckKeyword& keyword, size_t currentStep) {
|
||||
SegmentSetPtr newSegmentset= std::make_shared<SegmentSet>();
|
||||
newSegmentset->segmentsFromWELSEGSKeyword(keyword);
|
||||
SegmentSet newSegmentset;
|
||||
newSegmentset.segmentsFromWELSEGSKeyword(keyword);
|
||||
|
||||
const std::string& well_name = newSegmentset->wellName();
|
||||
auto well = this->m_wells.get( well_name );
|
||||
const std::string& well_name = newSegmentset.wellName();
|
||||
auto& well = this->m_wells.get( well_name );
|
||||
|
||||
// update multi-segment related information for the well
|
||||
well->addSegmentSet(currentStep, newSegmentset);
|
||||
@@ -1233,15 +1233,15 @@ namespace Opm {
|
||||
const std::string& well_name = record1.getItem("WELL").getTrimmedString(0);
|
||||
auto& well = *this->m_wells.get( well_name );
|
||||
|
||||
std::vector<CompsegsPtr> compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword( keyword );
|
||||
auto compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword( keyword );
|
||||
|
||||
SegmentSetConstPtr current_segmentSet = well.getSegmentSet(currentStep);
|
||||
const auto& current_segmentSet = well.getSegmentSet(currentStep);
|
||||
Compsegs::processCOMPSEGS(compsegs_vector, current_segmentSet);
|
||||
|
||||
CompletionSetConstPtr current_completionSet = well.getCompletions(currentStep);
|
||||
// it is necessary to update the segment related information for some completions.
|
||||
CompletionSetPtr new_completionSet = CompletionSetPtr(current_completionSet->shallowCopy());
|
||||
Compsegs::updateCompletionsWithSegment(compsegs_vector, new_completionSet);
|
||||
Compsegs::updateCompletionsWithSegment(compsegs_vector, *new_completionSet);
|
||||
|
||||
well.addCompletionSet(currentStep, new_completionSet);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Opm {
|
||||
m_comporder(completionOrdering),
|
||||
m_allowCrossFlow(allowCrossFlow),
|
||||
m_automaticShutIn(automaticShutIn),
|
||||
m_segmentset(new DynamicState<SegmentSetConstPtr>(*timeMap, SegmentSetPtr(new SegmentSet())))
|
||||
m_segmentset(new DynamicState< SegmentSet >(*timeMap, SegmentSet{} ) )
|
||||
{
|
||||
m_name = name_;
|
||||
m_creationTimeStep = creationTimeStep;
|
||||
@@ -419,15 +419,15 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
SegmentSetConstPtr Well::getSegmentSet(size_t time_step) const {
|
||||
const SegmentSet& Well::getSegmentSet(size_t time_step) const {
|
||||
return m_segmentset->get(time_step);
|
||||
}
|
||||
|
||||
bool Well::isMultiSegment(size_t time_step) const {
|
||||
return (getSegmentSet(time_step)->numberSegment() > 0);
|
||||
return (getSegmentSet(time_step).numberSegment() > 0);
|
||||
}
|
||||
|
||||
void Well::addSegmentSet(size_t time_step, SegmentSetConstPtr new_segmentset_in) {
|
||||
void Well::addSegmentSet(size_t time_step, SegmentSet new_segmentset ) {
|
||||
// to see if it is the first time entering WELSEGS input to this well.
|
||||
// if the well is not multi-segment well, it will be the first time
|
||||
// not sure if a well can switch between mutli-segment well and other
|
||||
@@ -435,26 +435,22 @@ namespace Opm {
|
||||
// Here, we assume not
|
||||
const bool first_time = !isMultiSegment(time_step);
|
||||
|
||||
if (first_time) {
|
||||
// overwrite the BHP reference depth with the one from WELSEGS keyword
|
||||
const double ref_depth = new_segmentset_in->depthTopSegment();
|
||||
m_refDepth.setValue(ref_depth);
|
||||
SegmentSetPtr new_segmentset = SegmentSetPtr(new_segmentset_in->shallowCopy());
|
||||
if (new_segmentset->lengthDepthType() == WellSegment::ABS) {
|
||||
new_segmentset->processABS();
|
||||
} else if (new_segmentset->lengthDepthType() == WellSegment::INC) {
|
||||
new_segmentset->processINC(first_time);
|
||||
} else {
|
||||
throw std::logic_error(" unknown length_depth_type in the new_segmentset");
|
||||
}
|
||||
m_segmentset->update(time_step, new_segmentset);
|
||||
} else {
|
||||
if( !first_time ) {
|
||||
// checking the consistency of the input WELSEGS information
|
||||
throw std::logic_error("re-entering WELSEGS for a well is not supported yet!!.");
|
||||
}
|
||||
|
||||
// overwrite the BHP reference depth with the one from WELSEGS keyword
|
||||
const double ref_depth = new_segmentset.depthTopSegment();
|
||||
m_refDepth.setValue(ref_depth);
|
||||
|
||||
if (new_segmentset.lengthDepthType() == WellSegment::ABS) {
|
||||
new_segmentset.processABS();
|
||||
} else if (new_segmentset.lengthDepthType() == WellSegment::INC) {
|
||||
new_segmentset.processINC(first_time);
|
||||
} else {
|
||||
throw std::logic_error(" unknown length_depth_type in the new_segmentset");
|
||||
}
|
||||
m_segmentset->update(time_step, new_segmentset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -131,9 +131,9 @@ namespace Opm {
|
||||
|
||||
// for multi-segment wells
|
||||
bool isMultiSegment(size_t time_step) const;
|
||||
std::shared_ptr< const SegmentSet > getSegmentSet(size_t time_step) const;
|
||||
const SegmentSet& getSegmentSet(size_t time_step) const;
|
||||
|
||||
void addSegmentSet(size_t time_step, std::shared_ptr< const SegmentSet > new_segmentset);
|
||||
void addSegmentSet(size_t time_step, SegmentSet new_segmentset);
|
||||
|
||||
const MessageContainer& getMessageContainer() const;
|
||||
private:
|
||||
@@ -173,7 +173,7 @@ namespace Opm {
|
||||
MessageContainer m_messages;
|
||||
// WELSEGS DATA - for mutli-segment wells
|
||||
// flag indicating if the well is a multi-segment well
|
||||
std::shared_ptr<DynamicState<std::shared_ptr< const SegmentSet >>> m_segmentset;
|
||||
std::shared_ptr<DynamicState< SegmentSet >> m_segmentset;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user