Refactor COMPSEGS handling
When handling the COMPSEGS keyword the connections are updated with segment number and the segments are updated with total perforated length. The new Compsegs::processCOMPSEGS() function will create new updated copies of both WellSegments and WellConnections.
This commit is contained in:
parent
5b0045d4a5
commit
6b468787c8
@ -112,7 +112,6 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/SICD.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Network/Branch.cpp
|
||||
@ -716,7 +715,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/SICD.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/BCConfig.hpp
|
||||
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UPDATING_CONNECTIONS_WITH_SEGMENTS
|
||||
#define UPDATING_CONNECTIONS_WITH_SEGMENTS
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
|
||||
|
||||
namespace Opm {
|
||||
WellConnections * newConnectionsWithSegments(const DeckKeyword& compsegs, const WellConnections& input_connections,
|
||||
const WellSegments& segments, const EclipseGrid& grid,
|
||||
const ParseContext& parseContext, ErrorGuard& errors);
|
||||
}
|
||||
|
||||
#endif
|
@ -29,13 +29,41 @@
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
||||
|
||||
#include "Compsegs.hpp"
|
||||
|
||||
namespace Opm {
|
||||
namespace Compsegs {
|
||||
|
||||
struct Record {
|
||||
int m_i;
|
||||
int m_j;
|
||||
int m_k;
|
||||
// the branch number on the main stem is always 1.
|
||||
// lateral branches should be numbered bigger than 1.
|
||||
// a suboridnate branch must have a higher branch number than parent branch.
|
||||
int m_branch_number;
|
||||
double m_distance_start;
|
||||
double m_distance_end;
|
||||
Connection::Direction m_dir;
|
||||
|
||||
double center_depth;
|
||||
// we do not handle thermal length for the moment
|
||||
// double m_thermal_length;
|
||||
int segment_number;
|
||||
std::size_t m_seqIndex;
|
||||
|
||||
Record(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
|
||||
Connection::Direction dir_in, double center_depth_in, int segment_number_in, std::size_t seqIndex_in);
|
||||
|
||||
void calculateCenterDepthWithSegments(const WellSegments& segment_set);
|
||||
|
||||
|
||||
Compsegs::Compsegs(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
|
||||
};
|
||||
|
||||
Record::Record(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
|
||||
Connection::Direction dir_in, double center_depth_in, int segment_number_in, size_t seqIndex_in)
|
||||
: m_i(i_in),
|
||||
m_j(j_in),
|
||||
@ -50,10 +78,112 @@ namespace Opm {
|
||||
{
|
||||
}
|
||||
|
||||
std::vector< Compsegs > Compsegs::compsegsFromCOMPSEGSKeyword(const DeckKeyword& compsegsKeyword, const EclipseGrid& grid,
|
||||
const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
|
||||
std::vector< Compsegs > compsegs;
|
||||
void Record::calculateCenterDepthWithSegments(const WellSegments& segment_set) {
|
||||
|
||||
// the depth and distance of the segment to the well head
|
||||
const Segment& segment = segment_set.getFromSegmentNumber(segment_number);
|
||||
const double segment_depth = segment.depth();
|
||||
const double segment_distance = segment.totalLength();
|
||||
|
||||
// for top segment, no interpolation is needed
|
||||
if (segment_number == 1) {
|
||||
center_depth = segment_depth;
|
||||
return;
|
||||
}
|
||||
|
||||
// for other cases, interpolation between two segments is needed.
|
||||
// looking for the other segment needed for interpolation
|
||||
// by default, it uses the outlet segment to do the interpolation
|
||||
int interpolation_segment_number = segment.outletSegment();
|
||||
|
||||
const double center_distance = (m_distance_start + m_distance_end) / 2.0;
|
||||
// if the perforation is further than the segment and the segment has inlet segments in the same branch
|
||||
// we use the inlet segment to do the interpolation
|
||||
if (center_distance > segment_distance) {
|
||||
for (const int inlet : segment.inletSegments()) {
|
||||
const int inlet_index = segment_set.segmentNumberToIndex(inlet);
|
||||
if (segment_set[inlet_index].branchNumber() == m_branch_number) {
|
||||
interpolation_segment_number = inlet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interpolation_segment_number == 0) {
|
||||
throw std::runtime_error("Failed in finding a segment to do the interpolation with segment "
|
||||
+ std::to_string(segment_number));
|
||||
}
|
||||
|
||||
// performing the interpolation
|
||||
const Segment& interpolation_segment = segment_set.getFromSegmentNumber(interpolation_segment_number);
|
||||
const double interpolation_detph = interpolation_segment.depth();
|
||||
const double interpolation_distance = interpolation_segment.totalLength();
|
||||
|
||||
const double depth_change_segment = segment_depth - interpolation_detph;
|
||||
const double segment_length = segment_distance - interpolation_distance;
|
||||
|
||||
if (segment_length == 0.) {
|
||||
throw std::runtime_error("Zero segment length is botained when doing interpolation between segment "
|
||||
+ std::to_string(segment_number) + " and segment " + std::to_string(interpolation_segment_number) );
|
||||
}
|
||||
|
||||
center_depth = segment_depth + (center_distance - segment_distance) / segment_length * depth_change_segment;
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void processCOMPSEGS__(std::vector< Record >& compsegs, const WellSegments& 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( auto& compseg : compsegs ) {
|
||||
|
||||
// need to determine the related segment number first
|
||||
if (compseg.segment_number != 0) continue;
|
||||
|
||||
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 (std::size_t i_segment = 0; i_segment < segment_set.size(); ++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) {
|
||||
std::ostringstream sstr;
|
||||
sstr << "The connection specified in COMPSEGS with index of " << compseg.m_i + 1 << " "
|
||||
<< compseg.m_j + 1 << " " << compseg.m_k + 1 << " failed in finding a related segment";
|
||||
throw std::runtime_error(sstr.str());
|
||||
}
|
||||
|
||||
compseg.segment_number = segment_number;
|
||||
|
||||
// when depth is default or zero, we obtain the depth of the connection based on the information
|
||||
// of the related segments
|
||||
if (compseg.center_depth == 0.) {
|
||||
compseg.calculateCenterDepthWithSegments(segment_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< Record > compsegsFromCOMPSEGSKeyword(const DeckKeyword& compsegsKeyword,
|
||||
const WellSegments& segments,
|
||||
const EclipseGrid& grid,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors) {
|
||||
|
||||
std::vector< Record > compsegs;
|
||||
|
||||
// The first record in the keyword only contains the well name
|
||||
// looping from the second record in the keyword
|
||||
@ -155,7 +285,7 @@ namespace Opm {
|
||||
segment_number,
|
||||
seqIndex);
|
||||
}
|
||||
} else { // a range is defined. genrate a range of Compsegs
|
||||
} else { // a range is defined. genrate a range of Record
|
||||
std::ostringstream sstr;
|
||||
sstr << "COMPSEGS entries can only be input for single connection, not supporting COMPSEGS entries specified with a range yet.\n"
|
||||
<< " well " << well_name << " " << I + 1 << " " << J + 1 << " " << K + 1 << " in keyword COMPSEGS\n";
|
||||
@ -163,127 +293,46 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
processCOMPSEGS__(compsegs, segments);
|
||||
return compsegs;
|
||||
}
|
||||
}
|
||||
|
||||
void Compsegs::processCOMPSEGS(std::vector< Compsegs >& compsegs, const WellSegments& 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( auto& compseg : compsegs ) {
|
||||
|
||||
// need to determine the related segment number first
|
||||
if (compseg.segment_number != 0) continue;
|
||||
std::pair<WellConnections, WellSegments>
|
||||
processCOMPSEGS(const DeckKeyword& compsegs,
|
||||
const WellConnections& input_connections,
|
||||
const WellSegments& input_segments,
|
||||
const EclipseGrid& grid,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors)
|
||||
{
|
||||
const auto& compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword( compsegs, input_segments, grid, parseContext, errors);
|
||||
WellSegments new_segment_set = input_segments;
|
||||
WellConnections new_connection_set = input_connections;
|
||||
|
||||
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 (std::size_t i_segment = 0; i_segment < segment_set.size(); ++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();
|
||||
for (const auto& compseg : compsegs_vector) {
|
||||
const int i = compseg.m_i;
|
||||
const int j = compseg.m_j;
|
||||
const int k = compseg.m_k;
|
||||
if (grid.cellActive(i, j, k)) {
|
||||
Connection& connection = new_connection_set.getFromIJK(i, j, k);
|
||||
connection.updateSegment(compseg.segment_number,
|
||||
compseg.center_depth,
|
||||
compseg.m_seqIndex,
|
||||
{ compseg.m_distance_start, compseg.m_distance_end });
|
||||
}
|
||||
}
|
||||
|
||||
if (segment_number == 0) {
|
||||
std::ostringstream sstr;
|
||||
sstr << "The connection specified in COMPSEGS with index of " << compseg.m_i + 1 << " "
|
||||
<< compseg.m_j + 1 << " " << compseg.m_k + 1 << " failed in finding a related segment";
|
||||
throw std::runtime_error(sstr.str());
|
||||
for (const auto& connection : new_connection_set) {
|
||||
if (!connection.attachedToSegment())
|
||||
throw std::runtime_error("Not all the connections are attached with a segment. "
|
||||
"The information from COMPSEGS is not complete");
|
||||
}
|
||||
new_segment_set.updatePerfLength( new_connection_set );
|
||||
|
||||
compseg.segment_number = segment_number;
|
||||
|
||||
// when depth is default or zero, we obtain the depth of the connection based on the information
|
||||
// of the related segments
|
||||
if (compseg.center_depth == 0.) {
|
||||
compseg.calculateCenterDepthWithSegments(segment_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compsegs::calculateCenterDepthWithSegments(const WellSegments& segment_set) {
|
||||
|
||||
// the depth and distance of the segment to the well head
|
||||
const Segment& segment = segment_set.getFromSegmentNumber(segment_number);
|
||||
const double segment_depth = segment.depth();
|
||||
const double segment_distance = segment.totalLength();
|
||||
|
||||
// for top segment, no interpolation is needed
|
||||
if (segment_number == 1) {
|
||||
center_depth = segment_depth;
|
||||
return;
|
||||
}
|
||||
|
||||
// for other cases, interpolation between two segments is needed.
|
||||
// looking for the other segment needed for interpolation
|
||||
// by default, it uses the outlet segment to do the interpolation
|
||||
int interpolation_segment_number = segment.outletSegment();
|
||||
|
||||
const double center_distance = (m_distance_start + m_distance_end) / 2.0;
|
||||
// if the perforation is further than the segment and the segment has inlet segments in the same branch
|
||||
// we use the inlet segment to do the interpolation
|
||||
if (center_distance > segment_distance) {
|
||||
for (const int inlet : segment.inletSegments()) {
|
||||
const int inlet_index = segment_set.segmentNumberToIndex(inlet);
|
||||
if (segment_set[inlet_index].branchNumber() == m_branch_number) {
|
||||
interpolation_segment_number = inlet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interpolation_segment_number == 0) {
|
||||
throw std::runtime_error("Failed in finding a segment to do the interpolation with segment "
|
||||
+ std::to_string(segment_number));
|
||||
}
|
||||
|
||||
// performing the interpolation
|
||||
const Segment& interpolation_segment = segment_set.getFromSegmentNumber(interpolation_segment_number);
|
||||
const double interpolation_detph = interpolation_segment.depth();
|
||||
const double interpolation_distance = interpolation_segment.totalLength();
|
||||
|
||||
const double depth_change_segment = segment_depth - interpolation_detph;
|
||||
const double segment_length = segment_distance - interpolation_distance;
|
||||
|
||||
if (segment_length == 0.) {
|
||||
throw std::runtime_error("Zero segment length is botained when doing interpolation between segment "
|
||||
+ std::to_string(segment_number) + " and segment " + std::to_string(interpolation_segment_number) );
|
||||
}
|
||||
|
||||
center_depth = segment_depth + (center_distance - segment_distance) / segment_length * depth_change_segment;
|
||||
}
|
||||
|
||||
void
|
||||
Compsegs::updateConnectionsWithSegment(const std::vector<Compsegs>& compsegs,
|
||||
const EclipseGrid& grid,
|
||||
WellConnections& connection_set)
|
||||
{
|
||||
|
||||
for (const auto& compseg : compsegs) {
|
||||
const int i = compseg.m_i;
|
||||
const int j = compseg.m_j;
|
||||
const int k = compseg.m_k;
|
||||
if (grid.cellActive(i, j, k)) {
|
||||
Connection& connection = connection_set.getFromIJK(i, j, k);
|
||||
connection.updateSegment(compseg.segment_number,
|
||||
compseg.center_depth,
|
||||
compseg.m_seqIndex,
|
||||
{ compseg.m_distance_start, compseg.m_distance_end });
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t ic = 0; ic < connection_set.size(); ++ic) {
|
||||
if (!(connection_set.get(ic).attachedToSegment())) {
|
||||
throw std::runtime_error("Not all the connections are attached with a segment. "
|
||||
"The information from COMPSEGS is not complete");
|
||||
}
|
||||
return std::make_pair( WellConnections( std::move( new_connection_set ) ),
|
||||
WellSegments( std::move(new_segment_set)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,12 +21,6 @@
|
||||
#ifndef COMPSEGS_HPP_
|
||||
#define COMPSEGS_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -34,42 +28,29 @@ namespace Opm {
|
||||
class DeckKeyword;
|
||||
class WellSegments;
|
||||
class EclipseGrid;
|
||||
class ParseContext;
|
||||
class ErrorGuard;
|
||||
|
||||
struct Compsegs {
|
||||
int m_i;
|
||||
int m_j;
|
||||
int m_k;
|
||||
// the branch number on the main stem is always 1.
|
||||
// lateral branches should be numbered bigger than 1.
|
||||
// a suboridnate branch must have a higher branch number than parent branch.
|
||||
int m_branch_number;
|
||||
double m_distance_start;
|
||||
double m_distance_end;
|
||||
Connection::Direction m_dir;
|
||||
namespace Compsegs {
|
||||
|
||||
double center_depth;
|
||||
// we do not handle thermal length for the moment
|
||||
// double m_thermal_length;
|
||||
int segment_number;
|
||||
std::size_t m_seqIndex;
|
||||
|
||||
Compsegs(int i_in, int j_in, int k_in, int branch_number_in, double distance_start_in, double distance_end_in,
|
||||
Connection::Direction dir_in, double center_depth_in, int segment_number_in, std::size_t seqIndex_in);
|
||||
/*
|
||||
The COMPSEGS keyword defines a link between connections and segments. This
|
||||
linking is circular because information about the segments is embedded in the
|
||||
connections, and visa versa. The function creates new WellSegments and
|
||||
WellConnections instances where the segment <--> connection linking has been
|
||||
established.
|
||||
*/
|
||||
|
||||
void calculateCenterDepthWithSegments(const WellSegments& segment_set);
|
||||
std::pair<WellConnections, WellSegments>
|
||||
processCOMPSEGS(const DeckKeyword& compsegs,
|
||||
const WellConnections& input_connections,
|
||||
const WellSegments& input_segments,
|
||||
const EclipseGrid& grid,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors);
|
||||
|
||||
static std::vector< Compsegs > compsegsFromCOMPSEGSKeyword(const DeckKeyword& compsegsKeyword, const EclipseGrid& grid,
|
||||
const ParseContext& parseContext, ErrorGuard& errors);
|
||||
|
||||
// get the segment number information and depth information based on the information from WellSegments
|
||||
static void processCOMPSEGS(std::vector< Compsegs >& compsegs, const WellSegments& segment_set);
|
||||
|
||||
// update the segment related information for Connections
|
||||
static void updateConnectionsWithSegment(const std::vector< Compsegs >& compsegs,
|
||||
const EclipseGrid& grid,
|
||||
WellConnections& connection_set);
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -626,8 +626,6 @@ WellSegments::MultiPhaseModel WellSegments::MultiPhaseModelFromString(const std:
|
||||
void WellSegments::updatePerfLength(const WellConnections& connections) {
|
||||
for (auto& segment : this->m_segments) {
|
||||
auto perf_length = connections.segment_perf_length( segment.segmentNumber() );
|
||||
if (perf_length == 0)
|
||||
throw std::logic_error("This seems suspicious - segment is not connected to any connection");
|
||||
segment.updatePerfLength(perf_length);
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
#include "Compsegs.hpp"
|
||||
|
||||
namespace Opm {
|
||||
WellConnections * newConnectionsWithSegments(const DeckKeyword& compsegs,
|
||||
const WellConnections& input_connections,
|
||||
const WellSegments& segment_set,
|
||||
const EclipseGrid& grid,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors)
|
||||
{
|
||||
WellConnections new_connection_set = input_connections;
|
||||
std::vector<Compsegs> compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword( compsegs, grid, parseContext, errors);
|
||||
Compsegs::processCOMPSEGS(compsegs_vector, segment_set);
|
||||
Compsegs::updateConnectionsWithSegment(compsegs_vector, grid, new_connection_set);
|
||||
return new WellConnections( std::move( new_connection_set ) );
|
||||
}
|
||||
}
|
@ -52,7 +52,6 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/SICD.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
|
||||
|
||||
@ -3106,6 +3105,7 @@ void Schedule::load_rst(const RestartIO::RstState& rst_state, const EclipseGrid&
|
||||
std::sort( segments_list.begin(), segments_list.end(),[](const Segment& seg1, const Segment& seg2) { return seg1.segmentNumber() < seg2.segmentNumber(); } );
|
||||
auto comp_pressure_drop = WellSegments::CompPressureDrop::HFA;
|
||||
std::shared_ptr<Opm::WellSegments> well_segments = std::make_shared<Opm::WellSegments>(comp_pressure_drop, segments_list);
|
||||
well_segments->updatePerfLength( well.getConnections() );
|
||||
well.updateSegments( std::move(well_segments) );
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,13 @@
|
||||
#include <opm/io/eclipse/rst/well.hpp>
|
||||
#include <opm/output/eclipse/VectorItems/well.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
#include "../MSW/Compsegs.hpp"
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <cmath>
|
||||
@ -646,9 +648,12 @@ bool Well::updateSolventFraction(double solvent_fraction_arg) {
|
||||
|
||||
bool Well::handleCOMPSEGS(const DeckKeyword& keyword, const EclipseGrid& grid,
|
||||
const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
std::shared_ptr<WellConnections> new_connection_set( newConnectionsWithSegments(keyword, *this->connections, *this->segments , grid,
|
||||
parseContext, errors) );
|
||||
return this->updateConnections(std::move(new_connection_set));
|
||||
auto [new_connections, new_segments] = Compsegs::processCOMPSEGS(keyword, *this->connections, *this->segments , grid,
|
||||
parseContext, errors);
|
||||
|
||||
this->updateConnections( std::make_shared<WellConnections>(std::move(new_connections)) );
|
||||
this->updateSegments( std::make_shared<WellSegments>( std::move(new_segments)) );
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string& Well::groupName() const {
|
||||
|
@ -39,12 +39,13 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
||||
#include "src/opm/parser/eclipse/EclipseState/Schedule/MSW/Compsegs.hpp"
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
||||
|
||||
@ -103,8 +104,7 @@ BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
||||
Opm::ParseContext parseContext;
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_INVALID, Opm::InputError::THROW_EXCEPTION);
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_NOT_SUPPORTED, Opm::InputError::THROW_EXCEPTION);
|
||||
std::unique_ptr<Opm::WellConnections> new_connection_set{nullptr};
|
||||
BOOST_CHECK_NO_THROW(new_connection_set.reset(Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set, grid, parseContext, errorGuard)));
|
||||
const auto& [new_connection_set, new_segment_set] = Opm::Compsegs::processCOMPSEGS(compsegs, connection_set, segment_set, grid, parseContext, errorGuard);
|
||||
|
||||
// checking the ICD segment
|
||||
const Opm::DeckKeyword wsegsicd = deck.getKeyword("WSEGSICD");
|
||||
@ -154,7 +154,7 @@ BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
||||
const int outlet_segment_number = segment.outletSegment();
|
||||
const double outlet_segment_length = segment_set.segmentLength(outlet_segment_number);
|
||||
// only one connection attached to the outlet segment in this case
|
||||
const Opm::Connection& connection = new_connection_set->getFromIJK(15, 0, 1);
|
||||
const Opm::Connection& connection = new_connection_set.getFromIJK(15, 0, 1);
|
||||
const auto& perf_range = connection.perf_range();
|
||||
const auto connection_length = perf_range->second - perf_range->first;
|
||||
sicd_ptr->updateScalingFactor(outlet_segment_length, connection_length);
|
||||
@ -163,33 +163,33 @@ BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
||||
BOOST_CHECK_NO_THROW(sicd_ptr->scalingFactor());
|
||||
BOOST_CHECK_EQUAL(0.7, sicd_ptr->scalingFactor());
|
||||
|
||||
BOOST_CHECK_EQUAL(7U, new_connection_set->size());
|
||||
BOOST_CHECK_EQUAL(7U, new_connection_set.size());
|
||||
|
||||
const Opm::Connection& connection1 = new_connection_set->get(0);
|
||||
const Opm::Connection& connection1 = new_connection_set.get(0);
|
||||
const int segment_number_connection1 = connection1.segment();
|
||||
const double center_depth_connection1 = connection1.depth();
|
||||
BOOST_CHECK_EQUAL(segment_number_connection1, 1);
|
||||
BOOST_CHECK_EQUAL(center_depth_connection1, 2512.5);
|
||||
|
||||
const Opm::Connection& connection3 = new_connection_set->get(2);
|
||||
const Opm::Connection& connection3 = new_connection_set.get(2);
|
||||
const int segment_number_connection3 = connection3.segment();
|
||||
const double center_depth_connection3 = connection3.depth();
|
||||
BOOST_CHECK_EQUAL(segment_number_connection3, 3);
|
||||
BOOST_CHECK_EQUAL(center_depth_connection3, 2562.5);
|
||||
|
||||
const Opm::Connection& connection5 = new_connection_set->get(4);
|
||||
const Opm::Connection& connection5 = new_connection_set.get(4);
|
||||
const int segment_number_connection5 = connection5.segment();
|
||||
const double center_depth_connection5 = connection5.depth();
|
||||
BOOST_CHECK_EQUAL(segment_number_connection5, 6);
|
||||
BOOST_CHECK_CLOSE(center_depth_connection5, 2538.83, 0.001);
|
||||
|
||||
const Opm::Connection& connection6 = new_connection_set->get(5);
|
||||
const Opm::Connection& connection6 = new_connection_set.get(5);
|
||||
const int segment_number_connection6 = connection6.segment();
|
||||
const double center_depth_connection6 = connection6.depth();
|
||||
BOOST_CHECK_EQUAL(segment_number_connection6, 6);
|
||||
BOOST_CHECK_CLOSE(center_depth_connection6, 2537.83, 0.001);
|
||||
|
||||
const Opm::Connection& connection7 = new_connection_set->get(6);
|
||||
const Opm::Connection& connection7 = new_connection_set.get(6);
|
||||
const int segment_number_connection7 = connection7.segment();
|
||||
const double center_depth_connection7 = connection7.depth();
|
||||
BOOST_CHECK_EQUAL(segment_number_connection7, 8);
|
||||
@ -248,10 +248,10 @@ BOOST_AUTO_TEST_CASE(WrongDistanceCOMPSEGS) {
|
||||
Opm::ErrorGuard errorGuard;
|
||||
Opm::ParseContext parseContext;
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_INVALID, Opm::InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(std::unique_ptr<Opm::WellConnections>(Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set, grid, parseContext, errorGuard)), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(Opm::Compsegs::processCOMPSEGS(compsegs, connection_set, segment_set, grid, parseContext, errorGuard), std::invalid_argument);
|
||||
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_INVALID, Opm::InputError::IGNORE);
|
||||
BOOST_CHECK_NO_THROW(std::unique_ptr<Opm::WellConnections>(Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set, grid, parseContext, errorGuard)));
|
||||
BOOST_CHECK_NO_THROW(Opm::Compsegs::processCOMPSEGS(compsegs, connection_set, segment_set, grid, parseContext, errorGuard));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(NegativeDepthCOMPSEGS) {
|
||||
@ -304,12 +304,11 @@ BOOST_AUTO_TEST_CASE(NegativeDepthCOMPSEGS) {
|
||||
|
||||
Opm::ErrorGuard errorGuard;
|
||||
Opm::ParseContext parseContext;
|
||||
std::unique_ptr<Opm::WellConnections> wconns{nullptr};
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_NOT_SUPPORTED, Opm::InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(wconns.reset(Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set, grid, parseContext, errorGuard)), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(Opm::Compsegs::processCOMPSEGS(compsegs, connection_set, segment_set, grid, parseContext, errorGuard), std::invalid_argument);
|
||||
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_NOT_SUPPORTED, Opm::InputError::IGNORE);
|
||||
BOOST_CHECK_NO_THROW(wconns.reset(Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set, grid, parseContext, errorGuard)));
|
||||
BOOST_CHECK_NO_THROW( Opm::Compsegs::processCOMPSEGS(compsegs, connection_set, segment_set, grid, parseContext, errorGuard) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(testwsegvalv) {
|
||||
@ -370,8 +369,7 @@ BOOST_AUTO_TEST_CASE(testwsegvalv) {
|
||||
Opm::ParseContext parseContext;
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_INVALID, Opm::InputError::THROW_EXCEPTION);
|
||||
parseContext.update(Opm::ParseContext::SCHEDULE_COMPSEGS_NOT_SUPPORTED, Opm::InputError::THROW_EXCEPTION);
|
||||
std::unique_ptr<Opm::WellConnections> new_connection_set{nullptr};
|
||||
BOOST_CHECK_NO_THROW(new_connection_set.reset(Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set, grid, parseContext, errorGuard)));
|
||||
BOOST_CHECK_NO_THROW( Opm::Compsegs::processCOMPSEGS(compsegs, connection_set, segment_set, grid, parseContext, errorGuard));
|
||||
|
||||
// checking the WSEGVALV segment
|
||||
const Opm::DeckKeyword wsegvalv = deck.getKeyword("WSEGVALV");
|
||||
|
Loading…
Reference in New Issue
Block a user