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:
Joakim Hove 2020-06-03 08:26:29 +02:00
parent 5b0045d4a5
commit 6b468787c8
9 changed files with 208 additions and 253 deletions

View File

@ -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

View File

@ -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

View File

@ -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)));
}
}
}

View File

@ -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);
};
}
}

View File

@ -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);
}
}

View File

@ -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 ) );
}
}

View File

@ -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) );
}

View File

@ -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 {

View File

@ -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");