Merge pull request #435 from joakim-hove/completion-support2
Completion support2
This commit is contained in:
commit
1f7a2d5459
@ -34,10 +34,6 @@ namespace Opm {
|
||||
|
||||
class DeckKeyword;
|
||||
class DeckRecord;
|
||||
class Well;
|
||||
class EclipseGrid;
|
||||
class Eclipse3DProperties;
|
||||
class Schedule;
|
||||
|
||||
class Connection {
|
||||
public:
|
||||
@ -49,62 +45,39 @@ namespace Opm {
|
||||
const Value<double>& diameter,
|
||||
const Value<double>& skinFactor,
|
||||
const int satTableId,
|
||||
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z);
|
||||
const WellCompletion::DirectionEnum direction);
|
||||
|
||||
Connection(const Connection&, WellCompletion::StateEnum newStatus);
|
||||
Connection(const Connection&, double wellPi);
|
||||
Connection(const Connection&, int complnum );
|
||||
Connection(const Connection& connection_initial, int segment_number, double center_depth);
|
||||
|
||||
bool sameCoordinate(const Connection& other) const;
|
||||
bool sameCoordinate(const int i, const int j, const int k) const;
|
||||
|
||||
int getI() const;
|
||||
int getJ() const;
|
||||
int getK() const;
|
||||
int complnum() const;
|
||||
WellCompletion::StateEnum getState() const;
|
||||
double getConnectionTransmissibilityFactor() const;
|
||||
double getWellPi() const;
|
||||
const Value<double>& getConnectionTransmissibilityFactorAsValueObject() const;
|
||||
double getDiameter() const;
|
||||
double getSkinFactor() const;
|
||||
int getSatTableId() const;
|
||||
void fixDefaultIJ(int wellHeadI , int wellHeadJ);
|
||||
void shift_complnum( int );
|
||||
int getSegmentNumber() const;
|
||||
double getCenterDepth() const;
|
||||
bool attachedToSegment() const;
|
||||
|
||||
WellCompletion::DirectionEnum getDirection() const;
|
||||
|
||||
static std::map< std::string, std::vector< Connection > >
|
||||
fromCOMPDAT( const EclipseGrid& grid,
|
||||
const Eclipse3DProperties& eclipseProperties,
|
||||
const DeckKeyword& compdatKeyword,
|
||||
const std::vector< const Well* >&,
|
||||
const ParseContext&,
|
||||
const Schedule&);
|
||||
const Value<double>& getConnectionTransmissibilityFactorAsValueObject() const;
|
||||
|
||||
bool operator==( const Connection& ) const;
|
||||
bool operator!=( const Connection& ) const;
|
||||
|
||||
WellCompletion::DirectionEnum dir;
|
||||
double center_depth;
|
||||
WellCompletion::StateEnum state;
|
||||
int sat_tableId;
|
||||
int complnum;
|
||||
|
||||
private:
|
||||
int m_i, m_j, m_k;
|
||||
int m_complnum;
|
||||
std::array<int,3> ijk;
|
||||
Value<double> m_diameter;
|
||||
Value<double> m_connectionTransmissibilityFactor;
|
||||
double m_wellPi;
|
||||
Value<double> m_skinFactor;
|
||||
int m_satTableId;
|
||||
WellCompletion::StateEnum m_state;
|
||||
WellCompletion::DirectionEnum m_direction;
|
||||
Value<double> getDiameterAsValueObject() const;
|
||||
Value<double> getSkinFactorAsValueObject() const;
|
||||
|
||||
public:
|
||||
// related segment number
|
||||
// -1 means the completion is not related to segment
|
||||
int m_segment_number = -1;
|
||||
double m_center_depth;
|
||||
int segment_number = -1;
|
||||
double wellPi = 1.0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace Opm {
|
||||
private:
|
||||
// segment number
|
||||
// it should work as a ID.
|
||||
int m_segment_number;
|
||||
int segment_number;
|
||||
// branch number
|
||||
// for top segment, it should always be 1
|
||||
int m_branch;
|
||||
|
@ -50,7 +50,7 @@ namespace Opm {
|
||||
|
||||
void addSegment(Segment new_segment);
|
||||
|
||||
void segmentsFromWELSEGSKeyword( const DeckKeyword& welsegsKeyword);
|
||||
void loadWELSEGS( const DeckKeyword& welsegsKeyword);
|
||||
|
||||
const Segment& getFromSegmentNumber(const int segment_number) const;
|
||||
|
||||
@ -91,7 +91,7 @@ namespace Opm {
|
||||
std::vector< Segment > m_segments;
|
||||
// the mapping from the segment number to the
|
||||
// storage index in the vector
|
||||
std::map<int, int> m_segment_number_to_index;
|
||||
std::map<int, int> segment_number_to_index;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
|
||||
|
||||
namespace Opm {
|
||||
WellConnections updatingConnectionsWithSegments(const DeckKeyword& compsegs, const WellConnections& input_connections, const WellSegments& segments);
|
||||
WellConnections * newConnectionsWithSegments(const DeckKeyword& compsegs, const WellConnections& input_connections, const WellSegments& segments);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -94,11 +94,29 @@ namespace Opm {
|
||||
bool isInjector(size_t timeStep) const;
|
||||
void addWELSPECS(const DeckRecord& deckRecord);
|
||||
|
||||
void addConnections(size_t time_step, const std::vector< Connection >& );
|
||||
void addWellConnections(size_t time_step, WellConnections );
|
||||
/*
|
||||
The getCompletions() function will return a map:
|
||||
|
||||
{
|
||||
1 : [Connection, Connection],
|
||||
2 : [Connection, Connection, Connecton],
|
||||
-3 : [Connection]
|
||||
-7 : [Connection]
|
||||
}
|
||||
|
||||
The integer ID's correspond to the COMPLETION id given by the COMPLUMP
|
||||
keyword. All positive id values come from COMPLUMP, whereas the
|
||||
negative values are arbitrary negative id values for connections which
|
||||
have not been lumped together in a completion. In the case of negative
|
||||
id values the list of connections always has exactly one element.
|
||||
*/
|
||||
|
||||
std::map<int, std::vector<Connection>> getCompletions(size_t time_step) const;
|
||||
const WellConnections& getConnections(size_t timeStep) const;
|
||||
const WellConnections& getConnections() const;
|
||||
WellConnections getActiveConnections(size_t timeStep, const EclipseGrid& grid) const;
|
||||
WellConnections * newWellConnections(size_t time_step);
|
||||
void updateWellConnections(size_t time_step, WellConnections * new_set );
|
||||
|
||||
/* The rate of a given phase under the following assumptions:
|
||||
* * Returns zero if production is requested for an injector (and vice
|
||||
@ -164,6 +182,13 @@ namespace Opm {
|
||||
const Events& getEvents() const;
|
||||
void addEvent(ScheduleEvents::Events event, size_t reportStep);
|
||||
bool hasEvent(uint64_t eventMask, size_t reportStep) const;
|
||||
void handleCOMPLUMP(const DeckRecord& record, size_t time_step);
|
||||
void handleCOMPDAT(size_t time_step, const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
|
||||
void handleCOMPSEGS(const DeckKeyword& keyword, size_t time_step);
|
||||
void handleWELOPEN(const DeckRecord& record, size_t time_step, WellCompletion::StateEnum status);
|
||||
void handleWPIMULT(const DeckRecord& record, size_t time_step);
|
||||
void handleWELSEGS(const DeckKeyword& keyword, size_t time_step);
|
||||
|
||||
|
||||
/*
|
||||
Will remove all completions which are attached to inactive cells. Will
|
||||
@ -183,7 +208,7 @@ namespace Opm {
|
||||
DynamicState< double > m_efficiencyFactors;
|
||||
|
||||
DynamicState< int > m_isProducer;
|
||||
DynamicState< WellConnections > m_completions;
|
||||
DynamicState< std::shared_ptr<WellConnections> > m_completions;
|
||||
DynamicState< WellProductionProperties > m_productionProperties;
|
||||
DynamicState< WellInjectionProperties > m_injectionProperties;
|
||||
DynamicState< WellPolymerProperties > m_polymerProperties;
|
||||
|
@ -25,13 +25,22 @@
|
||||
|
||||
namespace Opm {
|
||||
class EclipseGrid;
|
||||
|
||||
class Eclipse3DProperties;
|
||||
class WellConnections {
|
||||
public:
|
||||
WellConnections() = default;
|
||||
WellConnections(int headI, int headJ);
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
WellConnections( std::initializer_list< Connection > );
|
||||
WellConnections(const WellConnections& src, const EclipseGrid& grid);
|
||||
void addConnection(int i, int j , int k ,
|
||||
double depth,
|
||||
WellCompletion::StateEnum state ,
|
||||
const Value<double>& connectionTransmissibilityFactor,
|
||||
const Value<double>& diameter,
|
||||
const Value<double>& skinFactor,
|
||||
const int satTableId,
|
||||
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z);
|
||||
void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
|
||||
|
||||
using const_iterator = std::vector< Connection >::const_iterator;
|
||||
|
||||
@ -39,6 +48,7 @@ namespace Opm {
|
||||
size_t size() const;
|
||||
const Connection& get(size_t index) const;
|
||||
const Connection& getFromIJK(const int i, const int j, const int k) const;
|
||||
Connection& getFromIJK(const int i, const int j, const int k);
|
||||
|
||||
const_iterator begin() const { return this->m_connections.begin(); }
|
||||
const_iterator end() const { return this->m_connections.end(); }
|
||||
@ -62,8 +72,19 @@ namespace Opm {
|
||||
bool operator!=( const WellConnections& ) const;
|
||||
|
||||
private:
|
||||
void addConnection(int i, int j , int k ,
|
||||
int complnum,
|
||||
double depth,
|
||||
WellCompletion::StateEnum state ,
|
||||
const Value<double>& connectionTransmissibilityFactor,
|
||||
const Value<double>& diameter,
|
||||
const Value<double>& skinFactor,
|
||||
const int satTableId,
|
||||
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z);
|
||||
|
||||
std::vector< Connection > m_connections;
|
||||
size_t findClosestConnection(int oi, int oj, double oz, size_t start_pos);
|
||||
int headI, headJ;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,10 @@ public:
|
||||
int num_attempt;
|
||||
};
|
||||
|
||||
|
||||
struct ClosedCompletion {
|
||||
std::string wellName;
|
||||
size_t completion;
|
||||
int complnum;
|
||||
double last_test;
|
||||
int num_attempt;
|
||||
};
|
||||
@ -63,7 +64,7 @@ public:
|
||||
The simulator has decided to close a particular completion in a well; we then add it here
|
||||
as a closed completions
|
||||
*/
|
||||
void addClosedCompletion(const std::string& well_name, size_t completionIdx, double sim_time);
|
||||
void addClosedCompletion(const std::string& well_name, int complnum, double sim_time);
|
||||
|
||||
/*
|
||||
The update will consult the WellTestConfig object and return a list of
|
||||
@ -79,7 +80,7 @@ public:
|
||||
update method will update the internal state of the object by counting up
|
||||
the openiing attempts, and also set the time for the last attempt to open.
|
||||
*/
|
||||
std::vector<std::pair<std::string, size_t>> updateCompletion(const WellTestConfig& config, double sim_time);
|
||||
std::vector<std::pair<std::string, int>> updateCompletion(const WellTestConfig& config, double sim_time);
|
||||
|
||||
|
||||
/*
|
||||
@ -94,12 +95,12 @@ public:
|
||||
method should be called to indicate that this reason for keeping the well
|
||||
closed is no longer active.
|
||||
*/
|
||||
void dropCompletion(const std::string& well_name, size_t completionIdx);
|
||||
void dropCompletion(const std::string& well_name, int complnum);
|
||||
|
||||
bool hasWell(const std::string& well_name, WellTestConfig::Reason reason) const;
|
||||
void openWell(const std::string& well_name);
|
||||
|
||||
bool hasCompletion(const std::string& well_name, const size_t completionIdx) const;
|
||||
bool hasCompletion(const std::string& well_name, const int complnum) const;
|
||||
|
||||
size_t sizeWells() const;
|
||||
size_t sizeCompletions() const;
|
||||
|
@ -194,7 +194,7 @@ data::Wells restore_wells( const ecl_kw_type * opm_xwel,
|
||||
|
||||
for( const auto& sc : sched_well->getConnections( sim_step ) ) {
|
||||
const auto i = sc.getI(), j = sc.getJ(), k = sc.getK();
|
||||
if( !grid.cellActive( i, j, k ) || sc.getState() == WellCompletion::SHUT ) {
|
||||
if( !grid.cellActive( i, j, k ) || sc.state == WellCompletion::SHUT ) {
|
||||
opm_xwel_data += data::Connection::restart_size + phases.size();
|
||||
continue;
|
||||
}
|
||||
@ -298,10 +298,10 @@ std::vector<int> serialize_ICON( int sim_step,
|
||||
data[ offset + ICON_I_INDEX ] = connection.getI() + 1;
|
||||
data[ offset + ICON_J_INDEX ] = connection.getJ() + 1;
|
||||
data[ offset + ICON_K_INDEX ] = connection.getK() + 1;
|
||||
data[ offset + ICON_DIRECTION_INDEX ] = connection.getDirection();
|
||||
data[ offset + ICON_DIRECTION_INDEX ] = connection.dir;
|
||||
{
|
||||
const auto open = WellCompletion::StateEnum::OPEN;
|
||||
data[ offset + ICON_STATUS_INDEX ] = connection.getState() == open
|
||||
data[ offset + ICON_STATUS_INDEX ] = connection.state == open
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
@ -396,7 +396,7 @@ std::vector< double > serialize_OPM_XWEL( const data::Wells& wells,
|
||||
const auto i = sc.getI(), j = sc.getJ(), k = sc.getK();
|
||||
|
||||
const auto rs_size = phases.size() + data::Connection::restart_size;
|
||||
if( !grid.cellActive( i, j, k ) || sc.getState() == WellCompletion::SHUT ) {
|
||||
if( !grid.cellActive( i, j, k ) || sc.state == WellCompletion::SHUT ) {
|
||||
xwel.insert( xwel.end(), rs_size, 0.0 );
|
||||
continue;
|
||||
}
|
||||
|
@ -94,17 +94,17 @@ serialize_ICON(int lookup_step,
|
||||
for (const auto& connection : connections) {
|
||||
const size_t offset = well_offset + connection_offset;
|
||||
|
||||
data[ offset + ICON_IC_INDEX ] = connection.complnum();
|
||||
data[ offset + ICON_IC_INDEX ] = connection.complnum;
|
||||
data[ offset + ICON_I_INDEX ] = connection.getI() + 1;
|
||||
data[ offset + ICON_J_INDEX ] = connection.getJ() + 1;
|
||||
data[ offset + ICON_K_INDEX ] = connection.getK() + 1;
|
||||
data[ offset + ICON_DIRECTION_INDEX ] = connection.getDirection();
|
||||
data[ offset + ICON_DIRECTION_INDEX ] = connection.dir;
|
||||
data[ offset + ICON_STATUS_INDEX ] =
|
||||
(connection.getState() == WellCompletion::StateEnum::OPEN) ?
|
||||
(connection.state == WellCompletion::StateEnum::OPEN) ?
|
||||
1 : -1000;
|
||||
data[ offset + ICON_SEGMENT_INDEX ] =
|
||||
connection.attachedToSegment() ?
|
||||
connection.getSegmentNumber() : 0;
|
||||
connection.segment_number : 0;
|
||||
connection_offset += niconz;
|
||||
}
|
||||
|
||||
|
@ -45,59 +45,19 @@ namespace Opm {
|
||||
const Value<double>& skinFactor,
|
||||
const int satTableId,
|
||||
const WellCompletion::DirectionEnum direction)
|
||||
: m_i(i), m_j(j), m_k(k),
|
||||
m_complnum( compnum ),
|
||||
: dir(direction),
|
||||
center_depth(depth),
|
||||
state(state),
|
||||
sat_tableId(satTableId),
|
||||
complnum( compnum ),
|
||||
ijk({i,j,k}),
|
||||
m_diameter(diameter),
|
||||
m_connectionTransmissibilityFactor(connectionTransmissibilityFactor),
|
||||
m_wellPi(1.0),
|
||||
m_skinFactor(skinFactor),
|
||||
m_satTableId(satTableId),
|
||||
m_state(state),
|
||||
m_direction(direction),
|
||||
m_center_depth( depth )
|
||||
m_skinFactor(skinFactor)
|
||||
{}
|
||||
|
||||
Connection::Connection(const Connection& oldConnection, WellCompletion::StateEnum newStatus ) :
|
||||
Connection( oldConnection )
|
||||
{
|
||||
this->m_state = newStatus;
|
||||
}
|
||||
|
||||
Connection::Connection(const Connection& oldConnection, double wellPi) :
|
||||
Connection( oldConnection )
|
||||
{
|
||||
if( this->m_wellPi != 0 ) {
|
||||
this->m_wellPi *= wellPi;
|
||||
} else {
|
||||
this->m_wellPi = wellPi;
|
||||
}
|
||||
}
|
||||
|
||||
Connection::Connection( const Connection& c, int num ) :
|
||||
Connection( c )
|
||||
{
|
||||
this->m_complnum = num;
|
||||
}
|
||||
|
||||
Connection::Connection(const Connection& connection_initial, int segment_number, double center_depth)
|
||||
: Connection(connection_initial)
|
||||
{
|
||||
assert(segment_number > 0);
|
||||
this->m_segment_number = segment_number;
|
||||
this->m_center_depth = center_depth;
|
||||
}
|
||||
|
||||
bool Connection::sameCoordinate(const Connection& other) const {
|
||||
if ((m_i == other.m_i) &&
|
||||
(m_j == other.m_j) &&
|
||||
(m_k == other.m_k))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Connection::sameCoordinate(const int i, const int j, const int k) const {
|
||||
if ((m_i == i) && (m_j == j) && (m_k == k)) {
|
||||
if ((ijk[0] == i) && (ijk[1] == j) && (ijk[2] == k)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -105,165 +65,19 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This will break up one record and return a pair: <name ,
|
||||
[Connection1, Connection2, ... , ConnectionN]>. The reason it
|
||||
will return a list is that the 'K1 K2' structure is
|
||||
disentangled, and each completion is returned separately.
|
||||
*/
|
||||
|
||||
inline std::vector< Connection >
|
||||
fromCOMPDAT( const EclipseGrid& grid,
|
||||
const Eclipse3DProperties& eclipseProperties,
|
||||
const DeckRecord& compdatRecord,
|
||||
const Well& well,
|
||||
int prev_complnum ) {
|
||||
|
||||
std::vector< Connection > completions;
|
||||
|
||||
// We change from eclipse's 1 - n, to a 0 - n-1 solution
|
||||
// I and J can be defaulted with 0 or *, in which case they are fetched
|
||||
// from the well head
|
||||
const auto& itemI = compdatRecord.getItem( "I" );
|
||||
const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0;
|
||||
const int I = !defaulted_I ? itemI.get< int >( 0 ) - 1 : well.getHeadI();
|
||||
|
||||
const auto& itemJ = compdatRecord.getItem( "J" );
|
||||
const auto defaulted_J = itemJ.defaultApplied( 0 ) || itemJ.get< int >( 0 ) == 0;
|
||||
const int J = !defaulted_J ? itemJ.get< int >( 0 ) - 1 : well.getHeadJ();
|
||||
|
||||
int K1 = compdatRecord.getItem("K1").get< int >(0) - 1;
|
||||
int K2 = compdatRecord.getItem("K2").get< int >(0) - 1;
|
||||
WellCompletion::StateEnum state = WellCompletion::StateEnumFromString( compdatRecord.getItem("STATE").getTrimmedString(0) );
|
||||
Value<double> connectionTransmissibilityFactor("CompletionTransmissibilityFactor");
|
||||
Value<double> diameter("Diameter");
|
||||
Value<double> skinFactor("SkinFactor");
|
||||
int satTableId;
|
||||
const auto& satnum = eclipseProperties.getIntGridProperty("SATNUM");
|
||||
bool defaultSatTable = true;
|
||||
{
|
||||
const auto& connectionTransmissibilityFactorItem = compdatRecord.getItem("CONNECTION_TRANSMISSIBILITY_FACTOR");
|
||||
const auto& diameterItem = compdatRecord.getItem("DIAMETER");
|
||||
const auto& skinFactorItem = compdatRecord.getItem("SKIN");
|
||||
const auto& satTableIdItem = compdatRecord.getItem("SAT_TABLE");
|
||||
|
||||
if (connectionTransmissibilityFactorItem.hasValue(0) && connectionTransmissibilityFactorItem.getSIDouble(0) > 0)
|
||||
connectionTransmissibilityFactor.setValue(connectionTransmissibilityFactorItem.getSIDouble(0));
|
||||
|
||||
if (diameterItem.hasValue(0))
|
||||
diameter.setValue( diameterItem.getSIDouble(0));
|
||||
|
||||
if (skinFactorItem.hasValue(0))
|
||||
skinFactor.setValue( skinFactorItem.get< double >(0));
|
||||
|
||||
if (satTableIdItem.hasValue(0) && satTableIdItem.get < int > (0) > 0)
|
||||
{
|
||||
satTableId = satTableIdItem.get< int >(0);
|
||||
defaultSatTable = false;
|
||||
}
|
||||
}
|
||||
|
||||
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnumFromString(compdatRecord.getItem("DIR").getTrimmedString(0));
|
||||
|
||||
for (int k = K1; k <= K2; k++) {
|
||||
if (defaultSatTable)
|
||||
satTableId = satnum.iget(grid.getGlobalIndex(I,J,k));
|
||||
|
||||
completions.emplace_back( I, J, k,
|
||||
int( completions.size() + prev_complnum ) + 1,
|
||||
grid.getCellDepth( I,J,k ),
|
||||
state,
|
||||
connectionTransmissibilityFactor,
|
||||
diameter,
|
||||
skinFactor,
|
||||
satTableId,
|
||||
direction );
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
|
||||
/*
|
||||
Will return a map:
|
||||
|
||||
{
|
||||
"WELL1" : [ Connection1 , Connection2 , ... , ConnectionN ],
|
||||
"WELL2" : [ Connection1 , Connection2 , ... , ConnectionN ],
|
||||
...
|
||||
}
|
||||
*/
|
||||
|
||||
std::map< std::string, std::vector< Connection > >
|
||||
Connection::fromCOMPDAT( const EclipseGrid& grid ,
|
||||
const Eclipse3DProperties& eclipseProperties,
|
||||
const DeckKeyword& compdatKeyword,
|
||||
const std::vector< const Well* >& wells,
|
||||
const ParseContext& parseContext,
|
||||
const Schedule& schedule) {
|
||||
|
||||
std::map< std::string, std::vector< Connection > > res;
|
||||
std::vector< int > prev_compls( wells.size(), 0 );
|
||||
|
||||
for( const auto& record : compdatKeyword ) {
|
||||
|
||||
const auto wellNamePattern = record.getItem( "WELL" ).getTrimmedString( 0 );
|
||||
const auto& matched_wells = schedule.getWellsMatching(wellNamePattern);
|
||||
|
||||
if (matched_wells.empty())
|
||||
schedule.invalidNamePattern(wellNamePattern, parseContext, compdatKeyword);
|
||||
|
||||
for (const auto& well : matched_wells){
|
||||
const auto it_pos = std::find( wells.begin(), wells.end(), well);
|
||||
const auto index = std::distance( wells.begin(), it_pos );
|
||||
|
||||
auto completions = Opm::fromCOMPDAT( grid,
|
||||
eclipseProperties,
|
||||
record,
|
||||
*well,
|
||||
prev_compls[ index ] );
|
||||
|
||||
prev_compls[ index ] += completions.size();
|
||||
|
||||
res[ well->name() ].insert( res[ well->name() ].end(),
|
||||
std::make_move_iterator( completions.begin() ),
|
||||
std::make_move_iterator( completions.end() ) );
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Connection::fixDefaultIJ(int wellHeadI , int wellHeadJ) {
|
||||
if (m_i < 0)
|
||||
m_i = wellHeadI;
|
||||
|
||||
if (m_j < 0)
|
||||
m_j = wellHeadJ;
|
||||
}
|
||||
|
||||
void Connection::shift_complnum( int shift ) {
|
||||
this->m_complnum += shift;
|
||||
}
|
||||
|
||||
int Connection::getI() const {
|
||||
return m_i;
|
||||
return ijk[0];
|
||||
}
|
||||
|
||||
int Connection::getJ() const {
|
||||
return m_j;
|
||||
return ijk[1];
|
||||
}
|
||||
|
||||
int Connection::getK() const {
|
||||
return m_k;
|
||||
return ijk[2];
|
||||
}
|
||||
|
||||
int Connection::complnum() const {
|
||||
return this->m_complnum;
|
||||
}
|
||||
|
||||
WellCompletion::StateEnum Connection::getState() const {
|
||||
return m_state;
|
||||
}
|
||||
|
||||
double Connection::getConnectionTransmissibilityFactor() const {
|
||||
return m_connectionTransmissibilityFactor.getValue();
|
||||
@ -277,60 +91,26 @@ namespace Opm {
|
||||
return m_skinFactor.getValue();
|
||||
}
|
||||
|
||||
int Connection::getSatTableId() const {
|
||||
return m_satTableId;
|
||||
}
|
||||
|
||||
const Value<double>& Connection::getConnectionTransmissibilityFactorAsValueObject() const {
|
||||
return m_connectionTransmissibilityFactor;
|
||||
}
|
||||
|
||||
Value<double> Connection::getDiameterAsValueObject() const {
|
||||
return m_diameter;
|
||||
}
|
||||
|
||||
Value<double> Connection::getSkinFactorAsValueObject() const {
|
||||
return m_skinFactor;
|
||||
}
|
||||
|
||||
WellCompletion::DirectionEnum Connection::getDirection() const {
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
double Connection::getWellPi() const {
|
||||
return m_wellPi;
|
||||
}
|
||||
|
||||
int Connection::getSegmentNumber() const {
|
||||
if (!attachedToSegment()) {
|
||||
throw std::runtime_error(" the completion is not attached to a segment!\n ");
|
||||
}
|
||||
return m_segment_number;
|
||||
}
|
||||
|
||||
double Connection::getCenterDepth() const {
|
||||
return m_center_depth;
|
||||
}
|
||||
|
||||
bool Connection::attachedToSegment() const {
|
||||
return (m_segment_number > 0);
|
||||
return (segment_number > 0);
|
||||
}
|
||||
|
||||
bool Connection::operator==( const Connection& rhs ) const {
|
||||
return this->m_i == rhs.m_i
|
||||
&& this->m_j == rhs.m_j
|
||||
&& this->m_k == rhs.m_k
|
||||
&& this->m_complnum == rhs.m_complnum
|
||||
return this->ijk == rhs.ijk
|
||||
&& this->complnum == rhs.complnum
|
||||
&& this->m_diameter == rhs.m_diameter
|
||||
&& this->m_connectionTransmissibilityFactor
|
||||
== rhs.m_connectionTransmissibilityFactor
|
||||
&& this->m_wellPi == rhs.m_wellPi
|
||||
&& this->m_connectionTransmissibilityFactor == rhs.m_connectionTransmissibilityFactor
|
||||
&& this->wellPi == rhs.wellPi
|
||||
&& this->m_skinFactor == rhs.m_skinFactor
|
||||
&& this->m_satTableId == rhs.m_satTableId
|
||||
&& this->m_state == rhs.m_state
|
||||
&& this->m_direction == rhs.m_direction
|
||||
&& this->m_segment_number == rhs.m_segment_number
|
||||
&& this->m_center_depth == rhs.m_center_depth;
|
||||
&& this->sat_tableId == rhs.sat_tableId
|
||||
&& this->state == rhs.state
|
||||
&& this->dir == rhs.dir
|
||||
&& this->segment_number == rhs.segment_number
|
||||
&& this->center_depth == rhs.center_depth;
|
||||
}
|
||||
|
||||
bool Connection::operator!=( const Connection& rhs ) const {
|
||||
|
@ -41,8 +41,8 @@ namespace Opm {
|
||||
m_distance_start(distance_start_in),
|
||||
m_distance_end(distance_end_in),
|
||||
m_dir(dir_in),
|
||||
m_center_depth(center_depth_in),
|
||||
m_segment_number(segment_number_in)
|
||||
center_depth(center_depth_in),
|
||||
segment_number(segment_number_in)
|
||||
{
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ namespace Opm {
|
||||
for( auto& compseg : compsegs ) {
|
||||
|
||||
// need to determine the related segment number first
|
||||
if (compseg.m_segment_number != 0) continue;
|
||||
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;
|
||||
@ -164,15 +164,15 @@ namespace Opm {
|
||||
throw std::runtime_error("The perforation failed in finding a related segment \n");
|
||||
}
|
||||
|
||||
if (compseg.m_center_depth < 0.) {
|
||||
if (compseg.center_depth < 0.) {
|
||||
throw std::runtime_error("Obtaining perforation depth from COMPDAT data is not supported yet");
|
||||
}
|
||||
|
||||
compseg.m_segment_number = segment_number;
|
||||
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.m_center_depth == 0.) {
|
||||
if (compseg.center_depth == 0.) {
|
||||
compseg.calculateCenterDepthWithSegments(segment_set);
|
||||
}
|
||||
}
|
||||
@ -181,13 +181,13 @@ namespace Opm {
|
||||
void Compsegs::calculateCenterDepthWithSegments(const WellSegments& segment_set) {
|
||||
|
||||
// the depth and distance of the segment to the well head
|
||||
const Segment& segment = segment_set.getFromSegmentNumber(m_segment_number);
|
||||
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 (m_segment_number == 1) {
|
||||
m_center_depth = segment_depth;
|
||||
if (segment_number == 1) {
|
||||
center_depth = segment_depth;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ namespace Opm {
|
||||
|
||||
if (interpolation_segment_number == 0) {
|
||||
throw std::runtime_error("Failed in finding a segment to do the interpolation with segment "
|
||||
+ std::to_string(m_segment_number));
|
||||
+ std::to_string(segment_number));
|
||||
}
|
||||
|
||||
// performing the interpolation
|
||||
@ -224,10 +224,10 @@ namespace Opm {
|
||||
|
||||
if (segment_length == 0.) {
|
||||
throw std::runtime_error("Zero segment length is botained when doing interpolation between segment "
|
||||
+ std::to_string(m_segment_number) + " and segment " + std::to_string(interpolation_segment_number) );
|
||||
+ std::to_string(segment_number) + " and segment " + std::to_string(interpolation_segment_number) );
|
||||
}
|
||||
|
||||
m_center_depth = segment_depth + (center_distance - segment_distance) / segment_length * depth_change_segment;
|
||||
center_depth = segment_depth + (center_distance - segment_distance) / segment_length * depth_change_segment;
|
||||
}
|
||||
|
||||
void Compsegs::updateConnectionsWithSegment(const std::vector< Compsegs >& compsegs,
|
||||
@ -238,8 +238,9 @@ namespace Opm {
|
||||
const int j = compseg.m_j;
|
||||
const int k = compseg.m_k;
|
||||
|
||||
const Connection& connection = connection_set.getFromIJK( i, j, k );
|
||||
connection_set.add(Connection(connection, compseg.m_segment_number, compseg.m_center_depth) );
|
||||
Connection& connection = connection_set.getFromIJK( i, j, k );
|
||||
connection.segment_number = compseg.segment_number;
|
||||
connection.center_depth = compseg.center_depth;
|
||||
}
|
||||
|
||||
for (size_t ic = 0; ic < connection_set.size(); ++ic) {
|
||||
|
@ -44,10 +44,10 @@ namespace Opm {
|
||||
double m_distance_end;
|
||||
|
||||
WellCompletion::DirectionEnum m_dir;
|
||||
double m_center_depth;
|
||||
double center_depth;
|
||||
// we do not handle thermal length for the moment
|
||||
// double m_thermal_length;
|
||||
int m_segment_number;
|
||||
int segment_number;
|
||||
|
||||
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);
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace Opm {
|
||||
|
||||
Segment::Segment()
|
||||
: m_segment_number(-1),
|
||||
: segment_number(-1),
|
||||
m_branch(-1),
|
||||
m_outlet_segment(-1),
|
||||
m_total_length(invalid_value),
|
||||
@ -39,7 +39,7 @@ namespace Opm {
|
||||
Segment::Segment(int segment_number_in, int branch_in, int outlet_segment_in, double length_in, double depth_in,
|
||||
double internal_diameter_in, double roughness_in, double cross_area_in,
|
||||
double volume_in, bool data_ready_in)
|
||||
: m_segment_number(segment_number_in),
|
||||
: segment_number(segment_number_in),
|
||||
m_branch(branch_in),
|
||||
m_outlet_segment(outlet_segment_in),
|
||||
m_total_length(length_in),
|
||||
@ -53,7 +53,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
int Segment::segmentNumber() const {
|
||||
return m_segment_number;
|
||||
return segment_number;
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
bool Segment::operator==( const Segment& rhs ) const {
|
||||
return this->m_segment_number == rhs.m_segment_number
|
||||
return this->segment_number == rhs.segment_number
|
||||
&& this->m_branch == rhs.m_branch
|
||||
&& this->m_outlet_segment == rhs.m_outlet_segment
|
||||
&& this->m_total_length == rhs.m_total_length
|
||||
@ -135,7 +135,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
bool Segment::operator!=( const Segment& rhs ) const {
|
||||
return this->m_segment_number == rhs.m_segment_number
|
||||
return this->segment_number == rhs.segment_number
|
||||
&& this->m_branch == rhs.m_branch
|
||||
&& this->m_outlet_segment == rhs.m_outlet_segment
|
||||
&& this->m_total_length == rhs.m_total_length
|
||||
|
@ -76,8 +76,8 @@ namespace Opm {
|
||||
}
|
||||
|
||||
int WellSegments::segmentNumberToIndex(const int segment_number) const {
|
||||
const auto it = m_segment_number_to_index.find(segment_number);
|
||||
if (it != m_segment_number_to_index.end()) {
|
||||
const auto it = segment_number_to_index.find(segment_number);
|
||||
if (it != segment_number_to_index.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return -1;
|
||||
@ -91,14 +91,14 @@ namespace Opm {
|
||||
const int segment_index = segmentNumberToIndex(segment_number);
|
||||
|
||||
if (segment_index < 0) { // it is a new segment
|
||||
m_segment_number_to_index[segment_number] = size();
|
||||
segment_number_to_index[segment_number] = size();
|
||||
m_segments.push_back(new_segment);
|
||||
} else { // the segment already exists
|
||||
m_segments[segment_index] = new_segment;
|
||||
}
|
||||
}
|
||||
|
||||
void WellSegments::segmentsFromWELSEGSKeyword( const DeckKeyword& welsegsKeyword ) {
|
||||
void WellSegments::loadWELSEGS( const DeckKeyword& welsegsKeyword ) {
|
||||
|
||||
// for the first record, which provides the information for the top segment
|
||||
// and information for the whole segment set
|
||||
@ -203,7 +203,7 @@ namespace Opm {
|
||||
if (index >= 0) { // found in the existing m_segments already
|
||||
throw std::logic_error("Segments with same segment number are found!\n");
|
||||
}
|
||||
m_segment_number_to_index[segment_number] = i_segment;
|
||||
segment_number_to_index[segment_number] = i_segment;
|
||||
}
|
||||
|
||||
for (size_t i_segment = 0; i_segment < m_segments.size(); ++i_segment) {
|
||||
@ -212,7 +212,7 @@ namespace Opm {
|
||||
if (outlet_segment <= 0) { // no outlet segment
|
||||
continue;
|
||||
}
|
||||
const int outlet_segment_index = m_segment_number_to_index[outlet_segment];
|
||||
const int outlet_segment_index = segment_number_to_index[outlet_segment];
|
||||
m_segments[outlet_segment_index].addInletSegment(segment_number);
|
||||
}
|
||||
|
||||
@ -350,9 +350,9 @@ namespace Opm {
|
||||
int current_index= 1;
|
||||
|
||||
// clear the mapping from segment number to store index
|
||||
m_segment_number_to_index.clear();
|
||||
segment_number_to_index.clear();
|
||||
// for the top segment
|
||||
m_segment_number_to_index[1] = 0;
|
||||
segment_number_to_index[1] = 0;
|
||||
|
||||
while (current_index< size()) {
|
||||
// the branch number of the last segment that is done re-ordering
|
||||
@ -390,7 +390,7 @@ namespace Opm {
|
||||
std::swap(m_segments[current_index], m_segments[target_segment_index]);
|
||||
}
|
||||
const int segment_number = m_segments[current_index].segmentNumber();
|
||||
m_segment_number_to_index[segment_number] = current_index;
|
||||
segment_number_to_index[segment_number] = current_index;
|
||||
current_index++;
|
||||
}
|
||||
}
|
||||
@ -405,13 +405,13 @@ namespace Opm {
|
||||
&& 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_segment_number_to_index.size() == rhs.m_segment_number_to_index.size()
|
||||
&& this->segment_number_to_index.size() == rhs.segment_number_to_index.size()
|
||||
&& std::equal( this->m_segments.begin(),
|
||||
this->m_segments.end(),
|
||||
rhs.m_segments.begin() )
|
||||
&& std::equal( this->m_segment_number_to_index.begin(),
|
||||
this->m_segment_number_to_index.end(),
|
||||
rhs.m_segment_number_to_index.begin() );
|
||||
&& std::equal( this->segment_number_to_index.begin(),
|
||||
this->segment_number_to_index.end(),
|
||||
rhs.segment_number_to_index.begin() );
|
||||
}
|
||||
|
||||
bool WellSegments::operator!=( const WellSegments& rhs ) const {
|
||||
|
@ -22,16 +22,15 @@
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
WellConnections updatingConnectionsWithSegments(const DeckKeyword& compsegs,
|
||||
const WellConnections& input_connections,
|
||||
const WellSegments& segment_set)
|
||||
WellConnections * newConnectionsWithSegments(const DeckKeyword& compsegs,
|
||||
const WellConnections& input_connections,
|
||||
const WellSegments& segment_set)
|
||||
{
|
||||
WellConnections new_connection_set(input_connections);
|
||||
WellConnections * new_connection_set = new WellConnections(input_connections);
|
||||
|
||||
std::vector<Compsegs> compsegs_vector = Compsegs::compsegsFromCOMPSEGSKeyword( compsegs );
|
||||
Compsegs::processCOMPSEGS(compsegs_vector, segment_set);
|
||||
Compsegs::updateConnectionsWithSegment(compsegs_vector, new_connection_set);
|
||||
Compsegs::updateConnectionsWithSegment(compsegs_vector, *new_connection_set);
|
||||
return new_connection_set;
|
||||
}
|
||||
}
|
||||
|
@ -552,69 +552,18 @@ namespace Opm {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleWPIMULT( const DeckKeyword& keyword, size_t currentStep) {
|
||||
for( const auto& record : keyword ) {
|
||||
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
|
||||
double wellPi = record.getItem("WELLPI").get< double >(0);
|
||||
|
||||
for( auto* well : getWells( wellNamePattern ) ) {
|
||||
const auto& currentWellConnections = well->getConnections(currentStep);
|
||||
|
||||
WellConnections newWellConnections;
|
||||
|
||||
Opm::Value<int> I = getValueItem(record.getItem("I"));
|
||||
Opm::Value<int> J = getValueItem(record.getItem("J"));
|
||||
Opm::Value<int> K = getValueItem(record.getItem("K"));
|
||||
Opm::Value<int> FIRST = getValueItem(record.getItem("FIRST"));
|
||||
Opm::Value<int> LAST = getValueItem(record.getItem("LAST"));
|
||||
|
||||
size_t completionSize = currentWellConnections.size();
|
||||
|
||||
for(size_t i = 0; i < completionSize;i++) {
|
||||
const auto& currentConnection = currentWellConnections.get(i);
|
||||
|
||||
if (FIRST.hasValue()) {
|
||||
if (i < (size_t) FIRST.getValue()) {
|
||||
newWellConnections.add(currentConnection);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (LAST.hasValue()) {
|
||||
if (i > (size_t) LAST.getValue()) {
|
||||
newWellConnections.add(currentConnection);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int ci = currentConnection.getI();
|
||||
int cj = currentConnection.getJ();
|
||||
int ck = currentConnection.getK();
|
||||
|
||||
if (I.hasValue() && (!(I.getValue() == ci) )) {
|
||||
newWellConnections.add(currentConnection);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (J.hasValue() && (!(J.getValue() == cj) )) {
|
||||
newWellConnections.add(currentConnection);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (K.hasValue() && (!(K.getValue() == ck) )) {
|
||||
newWellConnections.add(currentConnection);
|
||||
continue;
|
||||
}
|
||||
|
||||
newWellConnections.add( Connection{ currentConnection, wellPi } );
|
||||
}
|
||||
|
||||
well->addWellConnections(currentStep, newWellConnections);
|
||||
}
|
||||
for( auto* well : getWells( wellNamePattern ) )
|
||||
well->handleWPIMULT(record, currentStep);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Schedule::handleWCONINJE( const SCHEDULESection& section, const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext) {
|
||||
for( const auto& record : keyword ) {
|
||||
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
|
||||
@ -920,37 +869,14 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleCOMPLUMP( const DeckKeyword& keyword,
|
||||
size_t timestep ) {
|
||||
|
||||
for( const auto& record : keyword ) {
|
||||
const int N = maybe( record, "N" ) + 1;
|
||||
if( N < 1 ) throw std::invalid_argument(
|
||||
"Completion number in COMPLUMP can not be defaulted."
|
||||
);
|
||||
|
||||
const auto& wellname = record.getItem( "WELL" ).getTrimmedString(0);
|
||||
const int I = maybe( record, "I" );
|
||||
const int J = maybe( record, "J" );
|
||||
const int K1 = maybe( record, "K1" );
|
||||
const int K2 = maybe( record, "K2" );
|
||||
|
||||
auto new_completion = [=]( const Connection& c ) -> Connection {
|
||||
if( !defaulted( I ) && c.getI() != I ) return c;
|
||||
if( !defaulted( J ) && c.getJ() != J ) return c;
|
||||
if( !defaulted( K1 ) && c.getK() < K1 ) return c;
|
||||
if( !defaulted( K2 ) && c.getK() > K2 ) return c;
|
||||
|
||||
return { c, N };
|
||||
};
|
||||
|
||||
for( auto& well : this->getWells( wellname ) ) {
|
||||
WellConnections new_completions;
|
||||
for( const auto& completion : well->getConnections( timestep ) )
|
||||
new_completions.add( new_completion( completion ) );
|
||||
|
||||
well->addWellConnections( timestep, new_completions );
|
||||
}
|
||||
const std::string& well_name = record.getItem("WELL").getTrimmedString(0);
|
||||
auto& well = this->m_wells.get(well_name);
|
||||
well.handleCOMPLUMP(record, timestep);
|
||||
}
|
||||
}
|
||||
|
||||
@ -979,10 +905,9 @@ namespace Opm {
|
||||
* well status is updated
|
||||
*/
|
||||
if( all_defaulted( record ) ) {
|
||||
const auto status = WellCommon::StatusFromString( status_str );
|
||||
|
||||
const auto well_status = WellCommon::StatusFromString( status_str );
|
||||
for( auto* well : wells ) {
|
||||
if( status == open && !well->canOpen(currentStep) ) {
|
||||
if( well_status == open && !well->canOpen(currentStep) ) {
|
||||
auto days = m_timeMap.getTimePassedUntil( currentStep ) / (60 * 60 * 24);
|
||||
std::string msg = "Well " + well->name()
|
||||
+ " where crossflow is banned has zero total rate."
|
||||
@ -990,53 +915,16 @@ namespace Opm {
|
||||
+ std::to_string( days ) + " days";
|
||||
OpmLog::note(msg);
|
||||
} else {
|
||||
this->updateWellStatus( *well, currentStep, status );
|
||||
this->updateWellStatus( *well, currentStep, well_status );
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const int I = maybe( record, "I" );
|
||||
const int J = maybe( record, "J" );
|
||||
const int K = maybe( record, "K" );
|
||||
const int C1 = maybe( record, "C1" );
|
||||
const int C2 = maybe( record, "C2" );
|
||||
|
||||
const auto status = WellCompletion::StateEnumFromString( status_str );
|
||||
|
||||
/*
|
||||
* Construct the updated completion with the possible status change
|
||||
* applied. Status is changed when a completion matches all the IJK
|
||||
* criteria *and* the completion number. A defaulted field always
|
||||
* matches the property in question.
|
||||
*/
|
||||
auto new_completion = [=]( const Connection& completion ) -> Connection {
|
||||
if( !defaulted( I ) && completion.getI() != I ) return completion;
|
||||
if( !defaulted( J ) && completion.getJ() != J ) return completion;
|
||||
if( !defaulted( K ) && completion.getK() != K ) return completion;
|
||||
|
||||
// assuming CM can be defaulted, even in the presence of
|
||||
// CN, e.g. it's a match for c >= C1 when C2 is defaulted
|
||||
// and vice versa.
|
||||
// complnum starts at 1, but we temp. adjust it for zero to
|
||||
// generalise the negative default value
|
||||
const auto complnum = completion.complnum() - 1;
|
||||
if( !defaulted( C1 ) && complnum < C1 ) return completion;
|
||||
if( !defaulted( C2 ) && complnum > C2 ) return completion;
|
||||
if( !defaulted( C1 ) && !defaulted( C2 )
|
||||
&& ( C1 > complnum || complnum > C2 ) ) return completion;
|
||||
|
||||
// completion matched - update it's status
|
||||
return { completion, status };
|
||||
};
|
||||
|
||||
for( auto* well : wells ) {
|
||||
WellConnections new_completions;
|
||||
for( const auto& c : well->getConnections( currentStep ) )
|
||||
new_completions.add( new_completion( c ) );
|
||||
|
||||
well->addWellConnections( currentStep, new_completions );
|
||||
const auto comp_status = WellCompletion::StateEnumFromString( status_str );
|
||||
well->handleWELOPEN(record, currentStep, comp_status);
|
||||
m_events.addEvent( ScheduleEvents::COMPLETION_CHANGE, currentStep );
|
||||
}
|
||||
}
|
||||
@ -1415,46 +1303,42 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Schedule::handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties, const ParseContext& parseContext) {
|
||||
const auto wells = this->getWells( currentStep );
|
||||
auto completions = Connection::fromCOMPDAT( grid, eclipseProperties, keyword, wells, parseContext, *this );
|
||||
for (const auto& record : keyword) {
|
||||
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
|
||||
auto wells = getWells(wellNamePattern);
|
||||
if (wells.empty())
|
||||
invalidNamePattern(wellNamePattern, parseContext, keyword);
|
||||
|
||||
for( const auto pair : completions ) {
|
||||
auto& well = this->m_wells.get( pair.first );
|
||||
well.addConnections( currentStep, pair.second );
|
||||
if (well.getConnections( currentStep ).allConnectionsShut()) {
|
||||
std::string msg =
|
||||
"All completions in well " + well.name() + " is shut at " + std::to_string ( m_timeMap.getTimePassedUntil(currentStep) / (60*60*24) ) + " days. \n" +
|
||||
for (auto* well : wells) {
|
||||
well->handleCOMPDAT(currentStep, record, grid, eclipseProperties);
|
||||
|
||||
if (well->getConnections( currentStep ).allConnectionsShut()) {
|
||||
std::string msg =
|
||||
"All completions in well " + well->name() + " is shut at " + std::to_string ( m_timeMap.getTimePassedUntil(currentStep) / (60*60*24) ) + " days. \n" +
|
||||
"The well is therefore also shut.";
|
||||
OpmLog::note(msg);
|
||||
updateWellStatus( well, currentStep, WellCommon::StatusEnum::SHUT);
|
||||
OpmLog::note(msg);
|
||||
updateWellStatus( *well, currentStep, WellCommon::StatusEnum::SHUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_events.addEvent(ScheduleEvents::COMPLETION_CHANGE, currentStep);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Schedule::handleWELSEGS( const DeckKeyword& keyword, size_t currentStep) {
|
||||
WellSegments newSegmentset;
|
||||
newSegmentset.segmentsFromWELSEGSKeyword(keyword);
|
||||
|
||||
const std::string& well_name = newSegmentset.wellName();
|
||||
auto& well = this->m_wells.get( well_name );
|
||||
|
||||
// update multi-segment related information for the well
|
||||
well.addWellSegments(currentStep, newSegmentset);
|
||||
const auto& record1 = keyword.getRecord(0);
|
||||
auto& well = this->m_wells.get(record1.getItem("WELL").getTrimmedString(0));
|
||||
well.handleWELSEGS(keyword, currentStep);WellSegments newSegmentset;
|
||||
}
|
||||
|
||||
void Schedule::handleCOMPSEGS( const DeckKeyword& keyword, size_t currentStep) {
|
||||
const auto& record1 = keyword.getRecord(0);
|
||||
const std::string& well_name = record1.getItem("WELL").getTrimmedString(0);
|
||||
auto& well = this->m_wells.get( well_name );
|
||||
|
||||
const auto& segment_set = well.getWellSegments(currentStep);
|
||||
const auto& completion_set = well.getConnections( currentStep );
|
||||
const WellConnections new_completion_set = updatingConnectionsWithSegments(keyword, completion_set, segment_set);
|
||||
|
||||
well.addWellConnections(currentStep, new_completion_set);
|
||||
well.handleCOMPSEGS(keyword, currentStep);
|
||||
}
|
||||
|
||||
void Schedule::handleWGRUPCON( const DeckKeyword& keyword, size_t currentStep) {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||
|
||||
@ -48,7 +49,7 @@ namespace Opm {
|
||||
m_guideRateScalingFactor( timeMap, 1.0 ),
|
||||
m_efficiencyFactors (timeMap, 1.0 ),
|
||||
m_isProducer( timeMap, true ) ,
|
||||
m_completions( timeMap, WellConnections{} ),
|
||||
m_completions( timeMap, std::make_shared<WellConnections>(headI, headJ) ),
|
||||
m_productionProperties( timeMap, WellProductionProperties() ),
|
||||
m_injectionProperties( timeMap, WellInjectionProperties() ),
|
||||
m_polymerProperties( timeMap, WellPolymerProperties() ),
|
||||
@ -336,7 +337,7 @@ namespace Opm {
|
||||
+ ". Can not infer reference depth" );
|
||||
}
|
||||
|
||||
return completions.get( 0 ).getCenterDepth();
|
||||
return completions.get( 0 ).center_depth;
|
||||
}
|
||||
|
||||
void Well::setRefDepth( size_t timestep, double depth ) {
|
||||
@ -348,53 +349,33 @@ namespace Opm {
|
||||
}
|
||||
|
||||
const WellConnections& Well::getConnections(size_t timeStep) const {
|
||||
return m_completions.get( timeStep );
|
||||
return *m_completions.get( timeStep );
|
||||
}
|
||||
|
||||
|
||||
std::map<int, std::vector<Connection>> Well::getCompletions(size_t time_step) const {
|
||||
std::map<int, std::vector<Connection>> completions;
|
||||
|
||||
const auto& connections = this->getConnections(time_step);
|
||||
for (const auto& conn : connections) {
|
||||
auto pair = completions.find( conn.complnum );
|
||||
if (pair == completions.end())
|
||||
completions[conn.complnum] = {};
|
||||
|
||||
pair = completions.find(conn.complnum);
|
||||
pair->second.push_back(conn);
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
|
||||
|
||||
WellConnections Well::getActiveConnections(size_t timeStep, const EclipseGrid& grid) const {
|
||||
return WellConnections(this->getConnections(timeStep), grid);
|
||||
}
|
||||
|
||||
const WellConnections& Well::getConnections() const {
|
||||
return m_completions.back();
|
||||
}
|
||||
|
||||
void Well::addConnections(size_t time_step, const std::vector< Connection >& newConnections ) {
|
||||
auto new_set = this->getConnections( time_step );
|
||||
int complnum_shift = new_set.size();
|
||||
|
||||
const auto headI = this->m_headI[ time_step ];
|
||||
const auto headJ = this->m_headJ[ time_step ];
|
||||
|
||||
auto prev_size = new_set.size();
|
||||
for( auto completion : newConnections ) {
|
||||
completion.fixDefaultIJ( headI , headJ );
|
||||
completion.shift_complnum( complnum_shift );
|
||||
|
||||
new_set.add( completion );
|
||||
const auto new_size = new_set.size();
|
||||
|
||||
/* Connections can be "re-added", i.e. same coordinates but with a
|
||||
* different set of properties. In this case they also inherit the
|
||||
* completion number (which must otherwise be shifted because
|
||||
* every COMPDAT keyword thinks it's the only one.
|
||||
*/
|
||||
if( new_size == prev_size ) --complnum_shift;
|
||||
else ++prev_size;
|
||||
}
|
||||
|
||||
this->addWellConnections( time_step, new_set );
|
||||
}
|
||||
|
||||
void Well::addWellConnections(size_t time_step, WellConnections new_set ){
|
||||
if( getWellConnectionOrdering() == WellCompletion::TRACK) {
|
||||
const auto headI = this->m_headI[ time_step ];
|
||||
const auto headJ = this->m_headJ[ time_step ];
|
||||
new_set.orderConnections( headI, headJ );
|
||||
}
|
||||
|
||||
m_completions.update( time_step, std::move( new_set ) );
|
||||
addEvent( ScheduleEvents::COMPLETION_CHANGE , time_step );
|
||||
return *m_completions.back();
|
||||
}
|
||||
|
||||
const std::string Well::getGroupName(size_t time_step) const {
|
||||
@ -567,7 +548,20 @@ namespace Opm {
|
||||
m_segmentset.update(time_step, new_segmentset);
|
||||
}
|
||||
|
||||
WellConnections * Well::newWellConnections(size_t time_step) {
|
||||
return new WellConnections( this->m_headI[time_step], this->m_headJ[time_step]);
|
||||
}
|
||||
|
||||
void Well::updateWellConnections(size_t time_step, WellConnections * new_set ){
|
||||
if( getWellConnectionOrdering() == WellCompletion::TRACK) {
|
||||
const auto headI = this->m_headI[ time_step ];
|
||||
const auto headJ = this->m_headJ[ time_step ];
|
||||
new_set->orderConnections( headI, headJ );
|
||||
}
|
||||
|
||||
m_completions.update( time_step, std::shared_ptr<WellConnections>( new_set ));
|
||||
addEvent( ScheduleEvents::COMPLETION_CHANGE , time_step );
|
||||
}
|
||||
|
||||
|
||||
void Well::addEvent(ScheduleEvents::Events event, size_t reportStep) {
|
||||
@ -586,6 +580,148 @@ namespace Opm {
|
||||
instance, hence this for loop is over all timesteps.
|
||||
*/
|
||||
for (auto& completions : m_completions)
|
||||
completions.filter(grid);
|
||||
completions->filter(grid);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool defaulted(const DeckRecord& rec, const std::string& s) {
|
||||
const auto& item = rec.getItem( s );
|
||||
if (item.defaultApplied(0))
|
||||
return true;
|
||||
|
||||
if (item.get<int>(0) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int limit(const DeckRecord& rec, const std::string&s , int shift) {
|
||||
const auto& item = rec.getItem( s );
|
||||
return shift + item.get<int>(0);
|
||||
}
|
||||
|
||||
bool match_le(int value, const DeckRecord& rec, const std::string& s, int shift = 0) {
|
||||
if (defaulted(rec,s))
|
||||
return true;
|
||||
|
||||
return (value <= limit(rec,s,shift));
|
||||
}
|
||||
|
||||
bool match_ge(int value, const DeckRecord& rec, const std::string& s, int shift = 0) {
|
||||
if (defaulted(rec,s))
|
||||
return true;
|
||||
|
||||
return (value >= limit(rec,s,shift));
|
||||
}
|
||||
|
||||
|
||||
bool match_eq(int value, const DeckRecord& rec, const std::string& s, int shift = 0) {
|
||||
if (defaulted(rec,s))
|
||||
return true;
|
||||
|
||||
return (limit(rec,s,shift) == value);
|
||||
}}
|
||||
|
||||
|
||||
void Well::handleCOMPLUMP(const DeckRecord& record, size_t time_step) {
|
||||
|
||||
auto match = [=]( const Connection& c ) -> bool {
|
||||
if (!match_eq(c.getI(), record, "I" , -1)) return false;
|
||||
if (!match_eq(c.getJ(), record, "J" , -1)) return false;
|
||||
if (!match_ge(c.getK(), record, "K1", -1)) return false;
|
||||
if (!match_le(c.getK(), record, "K2", -1)) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
WellConnections * new_connections = this->newWellConnections(time_step);
|
||||
const int complnum = record.getItem("N").get<int>(0);
|
||||
if (complnum <= 0)
|
||||
throw std::invalid_argument("Completion number must be >= 1. COMPLNUM=" + std::to_string(complnum) + "is invalid");
|
||||
|
||||
for (auto c : this->getConnections(time_step)) {
|
||||
if (match(c))
|
||||
c.complnum = complnum;
|
||||
|
||||
new_connections->add(c);
|
||||
}
|
||||
this->updateWellConnections(time_step, new_connections);
|
||||
}
|
||||
|
||||
void Well::handleWELOPEN(const DeckRecord& record, size_t time_step, WellCompletion::StateEnum status) {
|
||||
|
||||
auto match = [=]( const Connection &c) -> bool {
|
||||
if (!match_eq(c.getI(), record, "I" , -1)) return false;
|
||||
if (!match_eq(c.getJ(), record, "J" , -1)) return false;
|
||||
if (!match_eq(c.getK(), record, "K", -1)) return false;
|
||||
if (!match_ge(c.complnum, record, "C1")) return false;
|
||||
if (!match_le(c.complnum, record, "C2")) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
WellConnections * new_connections = this->newWellConnections(time_step);
|
||||
|
||||
for (auto c : this->getConnections(time_step)) {
|
||||
if (match(c))
|
||||
c.state = status;
|
||||
|
||||
new_connections->add(c);
|
||||
}
|
||||
|
||||
this->updateWellConnections(time_step, new_connections);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Well::handleCOMPDAT(size_t time_step, const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) {
|
||||
WellConnections * connections = new WellConnections(this->getConnections(time_step));
|
||||
connections->loadCOMPDAT(record, grid, eclipseProperties);
|
||||
this->updateWellConnections(time_step, connections);
|
||||
}
|
||||
|
||||
|
||||
void Well::handleCOMPSEGS(const DeckKeyword& keyword, size_t time_step) {
|
||||
const auto& segment_set = this->getWellSegments(time_step);
|
||||
const auto& completion_set = this->getConnections( time_step );
|
||||
WellConnections * new_connection_set = newConnectionsWithSegments(keyword, completion_set, segment_set);
|
||||
this->updateWellConnections(time_step, new_connection_set);
|
||||
}
|
||||
|
||||
|
||||
void Well::handleWPIMULT(const DeckRecord& record, size_t time_step) {
|
||||
|
||||
auto match = [=]( const Connection &c) -> bool {
|
||||
if (!match_ge(c.complnum, record, "FIRST")) return false;
|
||||
if (!match_le(c.complnum, record, "LAST")) return false;
|
||||
if (!match_eq(c.getI() , record, "I", -1)) return false;
|
||||
if (!match_eq(c.getJ() , record, "J", -1)) return false;
|
||||
if (!match_eq(c.getK() , record, "K", -1)) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
WellConnections * new_connections = this->newWellConnections(time_step);
|
||||
double wellPi = record.getItem("WELLPI").get< double >(0);
|
||||
|
||||
for (auto c : this->getConnections(time_step)) {
|
||||
if (match(c))
|
||||
c.wellPi *= wellPi;
|
||||
|
||||
new_connections->add(c);
|
||||
}
|
||||
|
||||
this->updateWellConnections(time_step, new_connections);
|
||||
}
|
||||
|
||||
void Well::handleWELSEGS(const DeckKeyword& keyword, size_t time_step) {
|
||||
WellSegments newSegmentset;
|
||||
newSegmentset.loadWELSEGS(keyword);
|
||||
// update multi-segment related information for the well
|
||||
this->addWellSegments(time_step, newSegmentset);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -22,17 +22,21 @@
|
||||
#include <limits>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Connection.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
WellConnections::WellConnections( std::initializer_list< Connection > cs ) {
|
||||
for( auto&& c : cs ) this->add( c );
|
||||
WellConnections::WellConnections(int headI, int headJ) :
|
||||
headI(headI),
|
||||
headJ(headJ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
WellConnections::WellConnections(const WellConnections& src, const EclipseGrid& grid) {
|
||||
for (const auto& c : src) {
|
||||
if (grid.cellActive(c.getI(), c.getJ(), c.getK()))
|
||||
@ -40,6 +44,130 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void WellConnections::addConnection(int i, int j , int k ,
|
||||
int complnum,
|
||||
double depth,
|
||||
WellCompletion::StateEnum state ,
|
||||
const Value<double>& connectionTransmissibilityFactor,
|
||||
const Value<double>& diameter,
|
||||
const Value<double>& skinFactor,
|
||||
const int satTableId,
|
||||
const WellCompletion::DirectionEnum direction)
|
||||
{
|
||||
int conn_i = (i < 0) ? this->headI : i;
|
||||
int conn_j = (j < 0) ? this->headJ : j;
|
||||
Connection conn(conn_i, conn_j, k, complnum, depth, state, connectionTransmissibilityFactor, diameter, skinFactor, satTableId, direction);
|
||||
this->add(conn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WellConnections::addConnection(int i, int j , int k ,
|
||||
double depth,
|
||||
WellCompletion::StateEnum state ,
|
||||
const Value<double>& connectionTransmissibilityFactor,
|
||||
const Value<double>& diameter,
|
||||
const Value<double>& skinFactor,
|
||||
const int satTableId,
|
||||
const WellCompletion::DirectionEnum direction)
|
||||
{
|
||||
int complnum = -(this->m_connections.size() + 1);
|
||||
this->addConnection(i,
|
||||
j,
|
||||
k,
|
||||
complnum,
|
||||
depth,
|
||||
state,
|
||||
connectionTransmissibilityFactor,
|
||||
diameter,
|
||||
skinFactor,
|
||||
satTableId,
|
||||
direction);
|
||||
}
|
||||
|
||||
void WellConnections::loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) {
|
||||
const auto& itemI = record.getItem( "I" );
|
||||
const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0;
|
||||
const int I = !defaulted_I ? itemI.get< int >( 0 ) - 1 : this->headI;
|
||||
|
||||
const auto& itemJ = record.getItem( "J" );
|
||||
const auto defaulted_J = itemJ.defaultApplied( 0 ) || itemJ.get< int >( 0 ) == 0;
|
||||
const int J = !defaulted_J ? itemJ.get< int >( 0 ) - 1 : this->headJ;
|
||||
|
||||
int K1 = record.getItem("K1").get< int >(0) - 1;
|
||||
int K2 = record.getItem("K2").get< int >(0) - 1;
|
||||
WellCompletion::StateEnum state = WellCompletion::StateEnumFromString( record.getItem("STATE").getTrimmedString(0) );
|
||||
Value<double> connectionTransmissibilityFactor("CompletionTransmissibilityFactor");
|
||||
Value<double> diameter("Diameter");
|
||||
Value<double> skinFactor("SkinFactor");
|
||||
const auto& satnum = eclipseProperties.getIntGridProperty("SATNUM");
|
||||
int satTableId = -1;
|
||||
bool defaultSatTable = true;
|
||||
{
|
||||
const auto& connectionTransmissibilityFactorItem = record.getItem("CONNECTION_TRANSMISSIBILITY_FACTOR");
|
||||
const auto& diameterItem = record.getItem("DIAMETER");
|
||||
const auto& skinFactorItem = record.getItem("SKIN");
|
||||
const auto& satTableIdItem = record.getItem("SAT_TABLE");
|
||||
|
||||
if (connectionTransmissibilityFactorItem.hasValue(0) && connectionTransmissibilityFactorItem.getSIDouble(0) > 0)
|
||||
connectionTransmissibilityFactor.setValue(connectionTransmissibilityFactorItem.getSIDouble(0));
|
||||
|
||||
if (diameterItem.hasValue(0))
|
||||
diameter.setValue( diameterItem.getSIDouble(0));
|
||||
|
||||
if (skinFactorItem.hasValue(0))
|
||||
skinFactor.setValue( skinFactorItem.get< double >(0));
|
||||
|
||||
if (satTableIdItem.hasValue(0) && satTableIdItem.get < int > (0) > 0)
|
||||
{
|
||||
satTableId = satTableIdItem.get< int >(0);
|
||||
defaultSatTable = false;
|
||||
}
|
||||
}
|
||||
|
||||
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnumFromString(record.getItem("DIR").getTrimmedString(0));
|
||||
|
||||
for (int k = K1; k <= K2; k++) {
|
||||
if (defaultSatTable)
|
||||
satTableId = satnum.iget(grid.getGlobalIndex(I,J,k));
|
||||
|
||||
auto same_ijk = [&]( const Connection& c ) {
|
||||
return c.sameCoordinate( I,J,k );
|
||||
};
|
||||
|
||||
auto prev = std::find_if( this->m_connections.begin(),
|
||||
this->m_connections.end(),
|
||||
same_ijk );
|
||||
|
||||
if (prev == this->m_connections.end()) {
|
||||
this->addConnection(I,J,k,
|
||||
grid.getCellDepth( I,J,k ),
|
||||
state,
|
||||
connectionTransmissibilityFactor,
|
||||
diameter,
|
||||
skinFactor,
|
||||
satTableId,
|
||||
direction );
|
||||
} else {
|
||||
// The complnum value carries over; the rest of the state is fully specified by
|
||||
// the current COMPDAT keyword.
|
||||
int complnum = prev->complnum;
|
||||
*prev = Connection(I,J,k,
|
||||
complnum,
|
||||
grid.getCellDepth(I,J,k),
|
||||
state,
|
||||
connectionTransmissibilityFactor,
|
||||
diameter,
|
||||
skinFactor,
|
||||
satTableId,
|
||||
direction );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
size_t WellConnections::size() const {
|
||||
return m_connections.size();
|
||||
}
|
||||
@ -58,27 +186,23 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void WellConnections::add( Connection connection ) {
|
||||
auto same = [&]( const Connection& c ) {
|
||||
return c.sameCoordinate( connection );
|
||||
};
|
||||
|
||||
auto prev = std::find_if( this->m_connections.begin(),
|
||||
this->m_connections.end(),
|
||||
same );
|
||||
|
||||
if( prev != this->m_connections.end() ) {
|
||||
// update the completion, but preserve it's number
|
||||
*prev = Connection( connection, prev->complnum() );
|
||||
return;
|
||||
Connection& WellConnections::getFromIJK(const int i, const int j, const int k) {
|
||||
for (size_t ic = 0; ic < size(); ++ic) {
|
||||
if (get(ic).sameCoordinate(i, j, k)) {
|
||||
return this->m_connections[ic];
|
||||
}
|
||||
}
|
||||
throw std::runtime_error(" the connection is not found! \n ");
|
||||
}
|
||||
|
||||
|
||||
void WellConnections::add( Connection connection ) {
|
||||
m_connections.emplace_back( connection );
|
||||
}
|
||||
|
||||
bool WellConnections::allConnectionsShut( ) const {
|
||||
auto shut = []( const Connection& c ) {
|
||||
return c.getState() == WellCompletion::StateEnum::SHUT;
|
||||
return c.state == WellCompletion::StateEnum::SHUT;
|
||||
};
|
||||
|
||||
return std::all_of( this->m_connections.begin(),
|
||||
@ -109,7 +233,7 @@ namespace Opm {
|
||||
|
||||
for (size_t pos = 1; pos < m_connections.size() - 1; ++pos) {
|
||||
const auto& prev = m_connections[pos - 1];
|
||||
const double prevz = prev.getCenterDepth();
|
||||
const double prevz = prev.center_depth;
|
||||
size_t next_index = findClosestConnection(prev.getI(), prev.getJ(), prevz, pos);
|
||||
std::swap(m_connections[next_index], m_connections[pos]);
|
||||
}
|
||||
@ -125,7 +249,7 @@ namespace Opm {
|
||||
for (size_t pos = start_pos; pos < m_connections.size(); ++pos) {
|
||||
const auto& connection = m_connections[ pos ];
|
||||
|
||||
const double depth = connection.getCenterDepth();
|
||||
const double depth = connection.center_depth;
|
||||
const int ci = connection.getI();
|
||||
const int cj = connection.getJ();
|
||||
// Using square of distance to avoid non-integer arithmetics.
|
||||
|
@ -85,29 +85,29 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void WellTestState::addClosedCompletion(const std::string& well_name, size_t completionIdx, double sim_time) {
|
||||
if (this->hasCompletion(well_name, completionIdx))
|
||||
void WellTestState::addClosedCompletion(const std::string& well_name, int complnum, double sim_time) {
|
||||
if (this->hasCompletion(well_name, complnum))
|
||||
return;
|
||||
|
||||
this->completions.push_back({well_name, completionIdx, sim_time, 0});
|
||||
this->completions.push_back( {well_name, complnum, sim_time, 0} );
|
||||
}
|
||||
|
||||
|
||||
void WellTestState::dropCompletion(const std::string& well_name, size_t completionIdx) {
|
||||
void WellTestState::dropCompletion(const std::string& well_name, int complnum) {
|
||||
completions.erase(std::remove_if(completions.begin(),
|
||||
completions.end(),
|
||||
[&well_name, completionIdx](const ClosedCompletion& completion) { return (completion.wellName == well_name && completion.completion == completionIdx); }),
|
||||
completions.end());
|
||||
completions.end(),
|
||||
[&well_name, complnum](const ClosedCompletion& completion) { return (completion.wellName == well_name && completion.complnum == complnum); }),
|
||||
completions.end());
|
||||
}
|
||||
|
||||
|
||||
bool WellTestState::hasCompletion(const std::string& well_name, const size_t completionIdx) const {
|
||||
bool WellTestState::hasCompletion(const std::string& well_name, const int complnum) const {
|
||||
const auto completion_iter = std::find_if(completions.begin(),
|
||||
completions.end(),
|
||||
[&well_name, &completionIdx](const ClosedCompletion& completion)
|
||||
{
|
||||
return (completionIdx == completion.completion && completion.wellName == well_name);
|
||||
});
|
||||
completions.end(),
|
||||
[&well_name, &complnum](const ClosedCompletion& completion)
|
||||
{
|
||||
return (complnum == completion.complnum && completion.wellName == well_name);
|
||||
});
|
||||
return (completion_iter != completions.end());
|
||||
}
|
||||
|
||||
@ -115,8 +115,8 @@ namespace Opm {
|
||||
return this->completions.size();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, size_t>> WellTestState::updateCompletion(const WellTestConfig& config, double sim_time) {
|
||||
std::vector<std::pair<std::string, size_t>> output;
|
||||
std::vector<std::pair<std::string, int>> WellTestState::updateCompletion(const WellTestConfig& config, double sim_time) {
|
||||
std::vector<std::pair<std::string, int>> output;
|
||||
for (auto& closed_completion : this->completions) {
|
||||
if (config.has(closed_completion.wellName, WellTestConfig::Reason::COMPLETION)) {
|
||||
const auto& well_config = config.get(closed_completion.wellName, WellTestConfig::Reason::COMPLETION);
|
||||
@ -126,7 +126,7 @@ namespace Opm {
|
||||
if (well_config.num_test == 0 || (closed_completion.num_attempt < well_config.num_test)) {
|
||||
closed_completion.last_test = sim_time;
|
||||
closed_completion.num_attempt += 1;
|
||||
output.push_back(std::make_pair(closed_completion.wellName, closed_completion.completion));
|
||||
output.push_back(std::make_pair(closed_completion.wellName, closed_completion.complnum));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,37 +53,22 @@ inline std::ostream& operator<<( std::ostream& stream, const WellConnections& cs
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CreateCompletionOK) {
|
||||
Opm::Connection completion(10,10,10, 1, 0.0,Opm::WellCompletion::OPEN,Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(testGetFunctions) {
|
||||
Opm::Connection completion(10,11,12, 1, 0.0, Opm::WellCompletion::OPEN,Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
|
||||
Opm::Connection completion(10,11,12, 1, 0.0, Opm::WellCompletion::OPEN,Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
BOOST_CHECK_EQUAL( 10 , completion.getI() );
|
||||
BOOST_CHECK_EQUAL( 11 , completion.getJ() );
|
||||
BOOST_CHECK_EQUAL( 12 , completion.getK() );
|
||||
|
||||
BOOST_CHECK_EQUAL( Opm::WellCompletion::OPEN , completion.getState());
|
||||
BOOST_CHECK_EQUAL( Opm::WellCompletion::OPEN , completion.state);
|
||||
BOOST_CHECK_EQUAL( 99.88 , completion.getConnectionTransmissibilityFactor());
|
||||
BOOST_CHECK_EQUAL( 22.33 , completion.getDiameter());
|
||||
BOOST_CHECK_EQUAL( 33.22 , completion.getSkinFactor());
|
||||
BOOST_CHECK_EQUAL( 0 , completion.getSatTableId());
|
||||
BOOST_CHECK_EQUAL( 0 , completion.sat_tableId);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CompletionTestssameCoordinate) {
|
||||
Opm::Connection completion1(10,10,10, 1, 0.0, Opm::WellCompletion::OPEN, Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion2(10,10,10, 1, 0.0, Opm::WellCompletion::OPEN, Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion3(11,10,10, 1, 0.0, Opm::WellCompletion::OPEN, Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion4(10,11,10, 1, 0.0, Opm::WellCompletion::OPEN, Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion5(10,10,11, 1, 0.0, Opm::WellCompletion::OPEN, Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
|
||||
BOOST_CHECK( completion1.sameCoordinate( completion2 ));
|
||||
BOOST_CHECK_EQUAL( false , completion1.sameCoordinate( completion3 ));
|
||||
BOOST_CHECK_EQUAL( false , completion1.sameCoordinate( completion4 ));
|
||||
BOOST_CHECK_EQUAL( false , completion1.sameCoordinate( completion5 ));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CreateWellConnectionsOK) {
|
||||
Opm::WellConnections completionSet;
|
||||
@ -93,9 +78,10 @@ BOOST_AUTO_TEST_CASE(CreateWellConnectionsOK) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AddCompletionSizeCorrect) {
|
||||
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
|
||||
Opm::WellConnections completionSet;
|
||||
Opm::Connection completion1( 10,10,10, 1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion2( 11,10,10, 1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion1( 10,10,10, 1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
Opm::Connection completion2( 11,10,10, 1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
completionSet.add( completion1 );
|
||||
BOOST_CHECK_EQUAL( 1U , completionSet.size() );
|
||||
|
||||
@ -107,9 +93,10 @@ BOOST_AUTO_TEST_CASE(AddCompletionSizeCorrect) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WellConnectionsGetOutOfRangeThrows) {
|
||||
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
|
||||
Opm::WellConnections completionSet;
|
||||
Opm::Connection completion1( 10,10,10,1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion2( 11,10,10,1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion1( 10,10,10,1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
Opm::Connection completion2( 11,10,10,1, 0.0,Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
completionSet.add( completion1 );
|
||||
BOOST_CHECK_EQUAL( 1U , completionSet.size() );
|
||||
|
||||
@ -122,27 +109,14 @@ BOOST_AUTO_TEST_CASE(WellConnectionsGetOutOfRangeThrows) {
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AddCompletionSameCellUpdates) {
|
||||
Opm::WellConnections completionSet;
|
||||
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion2( 10,10,10, 1, 0.0,Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
|
||||
|
||||
completionSet.add( completion1 );
|
||||
BOOST_CHECK_EQUAL( 1U , completionSet.size() );
|
||||
|
||||
completionSet.add( completion2 );
|
||||
BOOST_CHECK_EQUAL( 1U , completionSet.size() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AddCompletionCopy) {
|
||||
Opm::WellConnections completionSet;
|
||||
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
|
||||
|
||||
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion3( 10,10,12, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion1( 10,10,10, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
Opm::Connection completion2( 10,10,11, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
Opm::Connection completion3( 10,10,12, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
|
||||
completionSet.add( completion1 );
|
||||
completionSet.add( completion2 );
|
||||
@ -160,10 +134,11 @@ BOOST_AUTO_TEST_CASE(AddCompletionCopy) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ActiveCompletions) {
|
||||
Opm::EclipseGrid grid(10,10,10);
|
||||
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
|
||||
Opm::WellConnections completions;
|
||||
Opm::Connection completion1( 0,0,0, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion2( 0,0,1, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion3( 0,0,2, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection completion1( 0,0,0, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
Opm::Connection completion2( 0,0,1, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
Opm::Connection completion3( 0,0,2, 1, 0.0, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0, dir);
|
||||
|
||||
completions.add( completion1 );
|
||||
completions.add( completion2 );
|
||||
|
@ -42,10 +42,12 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/updatingConnectionsWithSegments.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
||||
Opm::WellConnections connection_set;
|
||||
connection_set.add(Opm::Connection( 19, 0, 0, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.5), Opm::Value<double>("SKIN", 0.), 0) );
|
||||
connection_set.add(Opm::Connection( 19, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.5), Opm::Value<double>("SKIN", 0.), 0) );
|
||||
connection_set.add(Opm::Connection( 19, 0, 2, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.4), Opm::Value<double>("SKIN", 0.), 0) );
|
||||
Opm::WellCompletion::DirectionEnum dir = Opm::WellCompletion::DirectionEnum::Z;
|
||||
Opm::WellConnections connection_set;
|
||||
connection_set.add(Opm::Connection( 19, 0, 0, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.5), Opm::Value<double>("SKIN", 0.), 0, dir) );
|
||||
connection_set.add(Opm::Connection( 19, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.5), Opm::Value<double>("SKIN", 0.), 0, dir) );
|
||||
connection_set.add(Opm::Connection( 19, 0, 2, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.4), Opm::Value<double>("SKIN", 0.), 0, dir) );
|
||||
|
||||
connection_set.add(Opm::Connection( 18, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.4), Opm::Value<double>("SKIN", 0.), 0, Opm::WellCompletion::DirectionEnum::X) );
|
||||
connection_set.add(Opm::Connection( 17, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.4), Opm::Value<double>("SKIN", 0.), 0, Opm::WellCompletion::DirectionEnum::X) );
|
||||
connection_set.add(Opm::Connection( 16, 0, 1, 1, 0.0, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor", 200.), Opm::Value<double>("D", 0.4), Opm::Value<double>("SKIN", 0.), 0, Opm::WellCompletion::DirectionEnum::X) );
|
||||
@ -82,41 +84,41 @@ BOOST_AUTO_TEST_CASE(MultisegmentWellTest) {
|
||||
|
||||
Opm::WellSegments segment_set;
|
||||
const Opm::DeckKeyword welsegs = deck.getKeyword("WELSEGS");
|
||||
segment_set.segmentsFromWELSEGSKeyword(welsegs);
|
||||
segment_set.loadWELSEGS(welsegs);
|
||||
|
||||
BOOST_CHECK_EQUAL(6U, segment_set.size());
|
||||
|
||||
const Opm::WellConnections new_connection_set = Opm::updatingConnectionsWithSegments(compsegs, connection_set, segment_set);
|
||||
const Opm::WellConnections * new_connection_set = Opm::newConnectionsWithSegments(compsegs, connection_set, segment_set);
|
||||
|
||||
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 int segment_number_connection1 = connection1.getSegmentNumber();
|
||||
const double center_depth_connection1 = connection1.getCenterDepth();
|
||||
const Opm::Connection& connection1 = new_connection_set->get(0);
|
||||
const int segment_number_connection1 = connection1.segment_number;
|
||||
const double center_depth_connection1 = connection1.center_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 int segment_number_connection3 = connection3.getSegmentNumber();
|
||||
const double center_depth_connection3 = connection3.getCenterDepth();
|
||||
const Opm::Connection& connection3 = new_connection_set->get(2);
|
||||
const int segment_number_connection3 = connection3.segment_number;
|
||||
const double center_depth_connection3 = connection3.center_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 int segment_number_connection5 = connection5.getSegmentNumber();
|
||||
const double center_depth_connection5 = connection5.getCenterDepth();
|
||||
const Opm::Connection& connection5 = new_connection_set->get(4);
|
||||
const int segment_number_connection5 = connection5.segment_number;
|
||||
const double center_depth_connection5 = connection5.center_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 int segment_number_connection6 = connection6.getSegmentNumber();
|
||||
const double center_depth_connection6 = connection6.getCenterDepth();
|
||||
const Opm::Connection& connection6 = new_connection_set->get(5);
|
||||
const int segment_number_connection6 = connection6.segment_number;
|
||||
const double center_depth_connection6 = connection6.center_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 int segment_number_connection7 = connection7.getSegmentNumber();
|
||||
const double center_depth_connection7 = connection7.getCenterDepth();
|
||||
const Opm::Connection& connection7 = new_connection_set->get(6);
|
||||
const int segment_number_connection7 = connection7.segment_number;
|
||||
const double center_depth_connection7 = connection7.center_depth;
|
||||
BOOST_CHECK_EQUAL(segment_number_connection7, 7);
|
||||
BOOST_CHECK_EQUAL(center_depth_connection7, 2534.5);
|
||||
}
|
||||
|
@ -605,16 +605,6 @@ static Deck createDeckWithWellsAndConnectionDataWithWELOPEN() {
|
||||
" 'OP_2' 8 7 3 6 'OPEN' 1* 6.242 0.311 576.458 1* 1* 'Y' 21.915 / \n"
|
||||
" 'OP_3' 7 7 1 1 'OPEN' 1* 27.412 0.311 2445.337 1* 1* 'Y' 18.521 / \n"
|
||||
" 'OP_3' 7 7 2 2 'OPEN' 1* 55.195 0.311 4923.842 1* 1* 'Y' 18.524 / \n"
|
||||
/*
|
||||
* Completions for OP_2:
|
||||
* 1 - 8 8 1
|
||||
* 2 - 8 8 2
|
||||
* 3 - 8 8 3
|
||||
* 4 - 8 7 3
|
||||
* 5 - 8 7 4
|
||||
* 6 - 8 7 5
|
||||
* 7 - 8 7 6
|
||||
*/
|
||||
"/\n"
|
||||
"DATES -- 2,3\n"
|
||||
" 10 JUL 2007 / \n"
|
||||
@ -664,25 +654,25 @@ BOOST_AUTO_TEST_CASE(CreateScheduleDeckWellsAndConnectionDataWithWELOPEN) {
|
||||
constexpr auto open = WellCompletion::StateEnum::OPEN;
|
||||
|
||||
BOOST_CHECK_EQUAL( 7U, cs.size() );
|
||||
BOOST_CHECK_EQUAL(shut, cs.getFromIJK( 7, 6, 2 ).getState());
|
||||
BOOST_CHECK_EQUAL(shut, cs.getFromIJK( 7, 6, 3 ).getState());
|
||||
BOOST_CHECK_EQUAL(shut, cs.getFromIJK( 7, 6, 4 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 7, 2 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 2 ).state);
|
||||
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 3 ).state);
|
||||
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 6, 4 ).state);
|
||||
BOOST_CHECK_EQUAL(open, cs.getFromIJK( 7, 7, 2 ).state);
|
||||
|
||||
const auto& cs2 = well->getConnections( 4 );
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 2 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 3 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 4 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 7, 2 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 2 ).state);
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 3 ).state);
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 6, 4 ).state);
|
||||
BOOST_CHECK_EQUAL(open, cs2.getFromIJK( 7, 7, 2 ).state);
|
||||
|
||||
well = schedule.getWell("OP_3");
|
||||
const auto& cs3 = well->getConnections( 3 );
|
||||
|
||||
BOOST_CHECK_EQUAL(shut, cs3.get( 0 ).getState());
|
||||
BOOST_CHECK_EQUAL(shut, cs3.get( 0 ).state);
|
||||
|
||||
const auto& cs4 = well->getConnections( 4 );
|
||||
|
||||
BOOST_CHECK_EQUAL(open, cs4.get( 0 ).getState());
|
||||
BOOST_CHECK_EQUAL(open, cs4.get( 0 ).state);
|
||||
|
||||
well = schedule.getWell("OP_1");
|
||||
BOOST_CHECK_EQUAL(WellCommon::StatusEnum::SHUT, well->getStatus( 3 ));
|
||||
@ -1082,17 +1072,17 @@ BOOST_AUTO_TEST_CASE(createDeckWithWPIMULT) {
|
||||
|
||||
const auto& cs2 = well->getConnections( 2 );
|
||||
for(size_t i = 0; i < cs2.size(); i++) {
|
||||
BOOST_CHECK_EQUAL(cs2.get( i ).getWellPi(), 1.3);
|
||||
BOOST_CHECK_EQUAL(cs2.get( i ).wellPi, 1.3);
|
||||
}
|
||||
|
||||
const auto& cs3 = well->getConnections( 3 );
|
||||
for(size_t i = 0; i < cs3.size(); i++ ) {
|
||||
BOOST_CHECK_EQUAL(cs3.get( i ).getWellPi(), (1.3*1.3));
|
||||
BOOST_CHECK_EQUAL(cs3.get( i ).wellPi, (1.3*1.3));
|
||||
}
|
||||
|
||||
const auto& cs4 = well->getConnections( 4 );
|
||||
for(size_t i = 0; i < cs4.size(); i++ ) {
|
||||
BOOST_CHECK_EQUAL(cs4.get( i ).getWellPi(), 1.0);
|
||||
BOOST_CHECK_EQUAL(cs4.get( i ).wellPi, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1683,16 +1673,16 @@ BOOST_AUTO_TEST_CASE( COMPDAT_sets_automatic_complnum ) {
|
||||
Schedule schedule( deck, grid, eclipseProperties, Phases( true, true, true ) ,ctx);
|
||||
|
||||
const auto& cs1 = schedule.getWell( "W1" )->getConnections( 1 );
|
||||
BOOST_CHECK_EQUAL( 1, cs1.get( 0 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 2, cs1.get( 1 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 3, cs1.get( 2 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 4, cs1.get( 3 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( -1, cs1.get( 0 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -2, cs1.get( 1 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -3, cs1.get( 2 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -4, cs1.get( 3 ).complnum );
|
||||
|
||||
const auto& cs2 = schedule.getWell( "W1" )->getConnections( 2 );
|
||||
BOOST_CHECK_EQUAL( 1, cs2.get( 0 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 2, cs2.get( 1 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 3, cs2.get( 2 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 4, cs2.get( 3 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( -1, cs2.get( 0 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -2, cs2.get( 1 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -3, cs2.get( 2 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -4, cs2.get( 3 ).complnum );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( COMPDAT_multiple_wells ) {
|
||||
@ -1727,20 +1717,20 @@ BOOST_AUTO_TEST_CASE( COMPDAT_multiple_wells ) {
|
||||
Schedule schedule( deck, grid, eclipseProperties, Phases( true, true, true ) ,ctx);
|
||||
|
||||
const auto& w1cs = schedule.getWell( "W1" )->getConnections();
|
||||
BOOST_CHECK_EQUAL( 1, w1cs.get( 0 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 2, w1cs.get( 1 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 3, w1cs.get( 2 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 4, w1cs.get( 3 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 5, w1cs.get( 4 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( -1, w1cs.get( 0 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -2, w1cs.get( 1 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -3, w1cs.get( 2 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -4, w1cs.get( 3 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -5, w1cs.get( 4 ).complnum );
|
||||
|
||||
const auto& w2cs = schedule.getWell( "W2" )->getConnections();
|
||||
BOOST_CHECK_EQUAL( 1, w2cs.getFromIJK( 4, 4, 2 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 2, w2cs.getFromIJK( 4, 4, 0 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 3, w2cs.getFromIJK( 4, 4, 1 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 4, w2cs.getFromIJK( 4, 4, 3 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 5, w2cs.getFromIJK( 4, 4, 4 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( -1, w2cs.getFromIJK( 4, 4, 2 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -2, w2cs.getFromIJK( 4, 4, 0 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -3, w2cs.getFromIJK( 4, 4, 1 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -4, w2cs.getFromIJK( 4, 4, 3 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -5, w2cs.getFromIJK( 4, 4, 4 ).complnum );
|
||||
|
||||
BOOST_CHECK_THROW( w2cs.get( 5 ).complnum(), std::out_of_range );
|
||||
BOOST_CHECK_THROW( w2cs.get( 5 ).complnum, std::out_of_range );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( COMPDAT_multiple_records_same_completion ) {
|
||||
@ -1772,9 +1762,9 @@ BOOST_AUTO_TEST_CASE( COMPDAT_multiple_records_same_completion ) {
|
||||
|
||||
const auto& cs = schedule.getWell( "W1" )->getConnections();
|
||||
BOOST_CHECK_EQUAL( 3U, cs.size() );
|
||||
BOOST_CHECK_EQUAL( 1, cs.get( 0 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 2, cs.get( 1 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 3, cs.get( 2 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( -1, cs.get( 0 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -2, cs.get( 1 ).complnum );
|
||||
BOOST_CHECK_EQUAL( -3, cs.get( 2 ).complnum );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( complump_less_than_1 ) {
|
||||
@ -1853,22 +1843,37 @@ BOOST_AUTO_TEST_CASE( complump ) {
|
||||
const auto& sc0 = well.getConnections( 0 );
|
||||
|
||||
/* complnum should be modified by COMPLNUM */
|
||||
BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 0 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 1 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 2 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 4, sc0.getFromIJK( 2, 2, 3 ).complnum() );
|
||||
BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 0 ).complnum );
|
||||
BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 1 ).complnum );
|
||||
BOOST_CHECK_EQUAL( 1, sc0.getFromIJK( 2, 2, 2 ).complnum );
|
||||
BOOST_CHECK( sc0.getFromIJK( 2, 2, 3 ).complnum < 0);
|
||||
|
||||
BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 1 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 2 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 0 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 1 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, sc0.getFromIJK( 2, 2, 2 ).state );
|
||||
|
||||
const auto& sc1 = well.getConnections( 1 );
|
||||
BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 1 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 2 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, sc1.getFromIJK( 2, 2, 3 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 0 ).state );
|
||||
BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 1 ).state );
|
||||
BOOST_CHECK_EQUAL( open, sc1.getFromIJK( 2, 2, 2 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, sc1.getFromIJK( 2, 2, 3 ).state );
|
||||
|
||||
const auto completions = well.getCompletions(1);
|
||||
BOOST_CHECK_EQUAL(completions.size(), 4);
|
||||
|
||||
const auto& c1 = completions.at(1);
|
||||
BOOST_CHECK_EQUAL(c1.size(), 3);
|
||||
|
||||
for (const auto& pair : completions) {
|
||||
if (pair.first > 0)
|
||||
BOOST_CHECK(pair.second.size() > 1);
|
||||
else
|
||||
BOOST_CHECK_EQUAL(pair.second.size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( COMPLUMP_specific_coordinates ) {
|
||||
std::string input = R"(
|
||||
START -- 0
|
||||
@ -1892,9 +1897,6 @@ BOOST_AUTO_TEST_CASE( COMPLUMP_specific_coordinates ) {
|
||||
10 OKT 2008 /
|
||||
/
|
||||
|
||||
WELOPEN -- open completion 1, rest are still shut
|
||||
'W1' OPEN 1 1 0 1 1 /
|
||||
/
|
||||
|
||||
DATES -- 2
|
||||
15 OKT 2008 /
|
||||
@ -1928,25 +1930,23 @@ BOOST_AUTO_TEST_CASE( COMPLUMP_specific_coordinates ) {
|
||||
const auto& cs2 = well.getConnections( 2 );
|
||||
|
||||
BOOST_CHECK_EQUAL( 9U, cs1.size() );
|
||||
BOOST_CHECK_EQUAL( open, cs1.getFromIJK( 0, 0, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 0, 0, 1 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 1 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 2 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 3 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 4 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 5 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 0, 0, 1 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 0 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 1 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 2, 2, 2 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 0 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 3 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 4 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs1.getFromIJK( 1, 1, 5 ).state );
|
||||
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 1 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 2, 2, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 1 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 2 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 0 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 3 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 4 ).getState() );
|
||||
BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 1, 1, 5 ).getState() );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 0, 0, 1 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 2, 2, 0 ).state );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 1 ).state );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 2, 2, 2 ).state );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 0 ).state );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 3 ).state );
|
||||
BOOST_CHECK_EQUAL( open, cs2.getFromIJK( 1, 1, 4 ).state );
|
||||
BOOST_CHECK_EQUAL( shut, cs2.getFromIJK( 1, 1, 5 ).state );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TestCompletionStateEnum2String) {
|
||||
|
@ -337,41 +337,6 @@ BOOST_AUTO_TEST_CASE(NewWellZeroCompletions) {
|
||||
BOOST_CHECK_EQUAL( 0U , well.getConnections( 0 ).size() );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UpdateCompletions) {
|
||||
auto timeMap = createXDaysTimeMap(10);
|
||||
|
||||
Opm::Well well("WELL1" , 0, 0, 0.0, Opm::Phase::OIL, timeMap , 0);
|
||||
const auto& completions = well.getConnections( 0 );
|
||||
BOOST_CHECK_EQUAL( 0U , completions.size());
|
||||
|
||||
Opm::Connection comp1( 10 , 10 , 10 , 1, 10, Opm::WellCompletion::AUTO , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection comp2( 10 , 10 , 11 , 1, 11, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection comp3( 10 , 10 , 12 , 1, 12, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection comp4( 10 , 10 , 12 , 1, 12, Opm::WellCompletion::SHUT , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
Opm::Connection comp5( 10 , 10 , 13 , 1, 13, Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
|
||||
//std::vector<Opm::CompletionConstPtr> newCompletions2{ comp4 , comp5}; Newer c++
|
||||
|
||||
std::vector< Opm::Connection > newCompletions, newCompletions2;
|
||||
newCompletions.push_back( comp1 );
|
||||
newCompletions.push_back( comp2 );
|
||||
newCompletions.push_back( comp3 );
|
||||
|
||||
newCompletions2.push_back( comp4 );
|
||||
newCompletions2.push_back( comp5 );
|
||||
|
||||
BOOST_CHECK_EQUAL( 3U , newCompletions.size());
|
||||
well.addConnections( 5 , newCompletions );
|
||||
BOOST_CHECK_EQUAL( 3U , well.getConnections( 5 ).size());
|
||||
BOOST_CHECK_EQUAL( comp3 , well.getConnections( 5 ).get(2));
|
||||
|
||||
well.addConnections( 6 , newCompletions2 );
|
||||
|
||||
BOOST_CHECK_EQUAL( 4U , well.getConnections( 6 ).size());
|
||||
BOOST_CHECK_EQUAL( comp4 , well.getConnections( 6 ).get(2));
|
||||
}
|
||||
|
||||
// Helper function for CompletionOrder test.
|
||||
inline Opm::Connection connection( int i, int j, int k, int complnum = 1 ) {
|
||||
return Opm::Connection { i, j, k,
|
||||
@ -386,71 +351,6 @@ inline Opm::Connection connection( int i, int j, int k, int complnum = 1 ) {
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CompletionOrder) {
|
||||
auto timeMap = createXDaysTimeMap(10);
|
||||
{
|
||||
// Vertical well.
|
||||
Opm::Well well("WELL1" , 5, 5, 0.0, Opm::Phase::OIL, timeMap , 0);
|
||||
auto c1 = connection(5, 5, 8);
|
||||
auto c2 = connection(5, 5, 9);
|
||||
auto c3 = connection(5, 5, 1);
|
||||
auto c4 = connection(5, 5, 0);
|
||||
Opm::WellConnections cv1 = { c1, c2 };
|
||||
well.addWellConnections(1, cv1);
|
||||
BOOST_CHECK_EQUAL(well.getConnections(1).get(0), c1);
|
||||
Opm::WellConnections cv2 = { c3, c4 };
|
||||
well.addWellConnections(2, cv2);
|
||||
BOOST_CHECK_EQUAL(well.getConnections(1).get(0), c1);
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(0), c4);
|
||||
}
|
||||
|
||||
{
|
||||
// Horizontal well.
|
||||
Opm::Well well("WELL1" , 5, 5, 0.0, Opm::Phase::OIL, timeMap , 0);
|
||||
auto c1 = connection(6, 5, 8, 1);
|
||||
auto c2 = connection(5, 6, 7, 2);
|
||||
auto c3 = connection(7, 5, 8, 1);
|
||||
auto c4 = connection(9, 5, 8, 2);
|
||||
auto c5 = connection(8, 5, 9, 3);
|
||||
auto c6 = connection(5, 5, 4, 1);
|
||||
|
||||
std::vector< Opm::Connection > cv1 = { c1, c2 };
|
||||
well.addConnections(1, cv1);
|
||||
BOOST_CHECK_EQUAL(well.getConnections(1).get(0), c2);
|
||||
|
||||
/*
|
||||
* adding completions in batches like this will under the hood modify
|
||||
* completion numbers to match expectations, so we ensure that we're
|
||||
* comparing to the right value by forcing the right-hand-side of the
|
||||
* comparison to use the expected completion number
|
||||
*/
|
||||
std::vector< Opm::Connection > cv2 = { c3, c4, c5 };
|
||||
well.addConnections(2, cv2);
|
||||
BOOST_CHECK_EQUAL(well.getConnections(1).get(0), Connection( c2, 2 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(0), Connection( c2, 2 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(1), Connection( c1, 1 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(2), Connection( c3, 3 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(3), Connection( c5, 5 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(4), Connection( c4, 4 ) );
|
||||
std::vector< Opm::Connection > cv3 = { c6 };
|
||||
|
||||
well.addConnections(3, cv3);
|
||||
BOOST_CHECK_EQUAL(well.getConnections(1).get(0), Connection( c2, 2 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(0), Connection( c2, 2 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(1), Connection( c1, 1 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(2), Connection( c3, 3 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(3), Connection( c5, 5 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(2).get(4), Connection( c4, 4 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(3).get(0), Connection( c6, 6 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(3).get(1), Connection( c2, 2 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(3).get(2), Connection( c1, 1 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(3).get(3), Connection( c3, 3 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(3).get(4), Connection( c5, 5 ) );
|
||||
BOOST_CHECK_EQUAL(well.getConnections(3).get(5), Connection( c4, 4 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(setGasRate_RateSetCorrect) {
|
||||
auto timeMap = createXDaysTimeMap(10);
|
||||
@ -632,23 +532,6 @@ BOOST_AUTO_TEST_CASE(InjectorType) {
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WellStatus) {
|
||||
auto timeMap = createXDaysTimeMap(10);
|
||||
|
||||
Opm::Well well("WELL1" , 0, 0, 0.0, Opm::Phase::OIL, timeMap , 0);
|
||||
|
||||
std::vector<Opm::Connection> newCompletions;
|
||||
Opm::Connection comp1(10 , 10 , 10 , 1, 0.25 , Opm::WellCompletion::OPEN , Opm::Value<double>("ConnectionTransmissibilityFactor",99.88), Opm::Value<double>("D",22.33), Opm::Value<double>("SKIN",33.22), 0);
|
||||
|
||||
newCompletions.push_back( comp1 );
|
||||
|
||||
well.addConnections( 2 , newCompletions );
|
||||
|
||||
well.setStatus( 3 , Opm::WellCommon::OPEN );
|
||||
BOOST_CHECK_EQUAL( Opm::WellCommon::OPEN , well.getStatus( 5 ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
|
@ -443,13 +443,8 @@ BOOST_AUTO_TEST_CASE( MULTREGT_ECLIPSE_STATE ) {
|
||||
BOOST_AUTO_TEST_CASE( MULTISEGMENT_ABS ) {
|
||||
const Parser parser;
|
||||
const std::string deckFile(pathprefix() + "SCHEDULE/SCHEDULE_MULTISEGMENT_WELL");
|
||||
const auto deck = parser.parseFile(deckFile, ParseContext());
|
||||
const ParseContext parseContext;
|
||||
const EclipseState state(deck, parseContext);
|
||||
const auto& grid = state.getInputGrid();
|
||||
const TableManager table ( deck );
|
||||
const Eclipse3DProperties eclipseProperties ( deck , table, grid);
|
||||
const Schedule sched(deck, grid, eclipseProperties, Phases(true, true, true), parseContext );
|
||||
const auto deck = parser.parseFile(deckFile, parseContext);
|
||||
|
||||
// for WELSEGS keyword
|
||||
const auto& kw = deck.getKeyword("WELSEGS");
|
||||
@ -568,6 +563,11 @@ BOOST_AUTO_TEST_CASE( MULTISEGMENT_ABS ) {
|
||||
BOOST_CHECK_EQUAL( 3237.5, distance_end );
|
||||
}
|
||||
|
||||
const EclipseState state(deck, parseContext);
|
||||
const auto& grid = state.getInputGrid();
|
||||
const TableManager table ( deck );
|
||||
const Eclipse3DProperties eclipseProperties ( deck , table, grid);
|
||||
const Schedule sched(deck, grid, eclipseProperties, Phases(true, true, true), parseContext );
|
||||
// checking the relation between segments and completions
|
||||
// and also the depth of completions
|
||||
{
|
||||
@ -577,26 +577,26 @@ BOOST_AUTO_TEST_CASE( MULTISEGMENT_ABS ) {
|
||||
BOOST_CHECK_EQUAL(7U, connections.size());
|
||||
|
||||
const Connection& connection5 = connections.get(4);
|
||||
const int seg_number_connection5 = connection5.getSegmentNumber();
|
||||
const double connection5_depth = connection5.getCenterDepth();
|
||||
const int seg_number_connection5 = connection5.segment_number;
|
||||
const double connection5_depth = connection5.center_depth;
|
||||
BOOST_CHECK_EQUAL(seg_number_connection5, 6);
|
||||
BOOST_CHECK_CLOSE(connection5_depth, 2538.83, 0.001);
|
||||
|
||||
const Connection& connection6 = connections.get(5);
|
||||
const int seg_number_connection6 = connection6.getSegmentNumber();
|
||||
const double connection6_depth = connection6.getCenterDepth();
|
||||
const int seg_number_connection6 = connection6.segment_number;
|
||||
const double connection6_depth = connection6.center_depth;
|
||||
BOOST_CHECK_EQUAL(seg_number_connection6, 6);
|
||||
BOOST_CHECK_CLOSE(connection6_depth, 2537.83, 0.001);
|
||||
|
||||
const Connection& connection1 = connections.get(0);
|
||||
const int seg_number_connection1 = connection1.getSegmentNumber();
|
||||
const double connection1_depth = connection1.getCenterDepth();
|
||||
const int seg_number_connection1 = connection1.segment_number;
|
||||
const double connection1_depth = connection1.center_depth;
|
||||
BOOST_CHECK_EQUAL(seg_number_connection1, 1);
|
||||
BOOST_CHECK_EQUAL(connection1_depth, 2512.5);
|
||||
|
||||
const Connection& connection3 = connections.get(2);
|
||||
const int seg_number_connection3 = connection3.getSegmentNumber();
|
||||
const double connection3_depth = connection3.getCenterDepth();
|
||||
const int seg_number_connection3 = connection3.segment_number;
|
||||
const double connection3_depth = connection3.center_depth;
|
||||
BOOST_CHECK_EQUAL(seg_number_connection3, 3);
|
||||
BOOST_CHECK_EQUAL(connection3_depth, 2562.5);
|
||||
}
|
||||
|
@ -349,13 +349,13 @@ BOOST_AUTO_TEST_CASE(WellTestCOMPDAT) {
|
||||
const auto& connections = well1->getConnections(3);
|
||||
BOOST_CHECK_EQUAL(4U, connections.size());
|
||||
|
||||
BOOST_CHECK_EQUAL(WellCompletion::OPEN, connections.get(3).getState());
|
||||
BOOST_CHECK_EQUAL(WellCompletion::OPEN, connections.get(3).state);
|
||||
BOOST_CHECK_EQUAL(2.2836805555555556e-12 , connections.get(3).getConnectionTransmissibilityFactor());
|
||||
BOOST_CHECK_EQUAL(0.311/Metric::Length, connections.get(3).getDiameter());
|
||||
BOOST_CHECK_EQUAL(3.3, connections.get(3).getSkinFactor());
|
||||
|
||||
BOOST_CHECK_EQUAL(4U, well1->getConnections( 7 ).size() );
|
||||
BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).getState() );
|
||||
BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).state );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test )
|
||||
const size_t offset = w_offset + c_offset;
|
||||
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_IC_INDEX],
|
||||
c.complnum());
|
||||
c.complnum);
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_I_INDEX],
|
||||
c.getI() + 1);
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_J_INDEX],
|
||||
@ -64,9 +64,9 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test )
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_K_INDEX],
|
||||
c.getK() + 1);
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_DIRECTION_INDEX],
|
||||
c.getDirection());
|
||||
c.dir);
|
||||
|
||||
if (c.getState() == Opm::WellCompletion::StateEnum::OPEN)
|
||||
if (c.state == Opm::WellCompletion::StateEnum::OPEN)
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_STATUS_INDEX],
|
||||
1);
|
||||
else
|
||||
@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test )
|
||||
|
||||
if (c.attachedToSegment())
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_SEGMENT_INDEX],
|
||||
c.getSegmentNumber());
|
||||
c.segment_number);
|
||||
else
|
||||
BOOST_CHECK_EQUAL(icondata[offset + ICON_SEGMENT_INDEX],
|
||||
0);
|
||||
|
Loading…
Reference in New Issue
Block a user