Remove old well implementation

This commit is contained in:
Joakim Hove 2019-05-04 12:00:32 +02:00
parent 1d31de03c7
commit 94b160258e
48 changed files with 1988 additions and 4093 deletions

View File

@ -101,7 +101,6 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Schedule/TimeMap.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Tuning.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/Connection.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp
@ -505,7 +504,6 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp

View File

@ -26,7 +26,6 @@
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/output/data/Cells.hpp>
#include <opm/output/data/Solution.hpp>

View File

@ -49,7 +49,6 @@
//jal - comment on the following include to avoid duplication
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/output/data/Cells.hpp>
#include <opm/output/data/Solution.hpp>

View File

@ -90,17 +90,17 @@ class DynamicState {
}
std::vector<std::pair<std::size_t, T>> unique() {
std::vector<std::pair<std::size_t, T>> unique() const {
if (this->m_data.empty())
return {};
auto& current_value = this->m_data[0];
const auto * current_value = std::addressof(this->m_data[0]);
std::size_t current_index = 0;
std::vector<std::pair<std::size_t, T>> result{{current_index, current_value}};
std::vector<std::pair<std::size_t, T>> result{{current_index, *current_value}};
while (true) {
if (this->m_data[current_index] != current_value) {
current_value = this->m_data[current_index];
result.emplace_back(current_index, current_value);
if (this->m_data[current_index] != *current_value) {
current_value = std::addressof(this->m_data[current_index]);
result.emplace_back(current_index, *current_value);
}
current_index++;

View File

@ -39,7 +39,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/RFTConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
@ -115,6 +114,7 @@ namespace Opm
size_t numWells() const;
size_t numWells(size_t timestep) const;
bool hasWell(const std::string& wellName) const;
bool hasWell(const std::string& wellName, std::size_t timeStep) const;
std::vector<std::string> wellNames(const std::string& pattern, size_t timeStep, const std::vector<std::string>& matching_wells = {}) const;
std::vector<std::string> wellNames(const std::string& pattern) const;
@ -123,12 +123,11 @@ namespace Opm
void updateWell(std::shared_ptr<Well2> well, size_t reportStep);
const Well2& getWell2(const std::string& wellName, size_t timeStep) const;
std::vector< const Well2* > getChildWells2(const std::string& group_name, size_t timeStep, GroupWellQueryMode query_mode) const;
const Well* getWell(const std::string& wellName) const;
std::vector< const Well* > getOpenWells(size_t timeStep) const;
std::vector< const Well* > getWells() const;
std::vector< const Well* > getWells(size_t timeStep) const;
std::vector< const Well* > getChildWells(const std::string& group_name, size_t timeStep, GroupWellQueryMode query_mode) const;
const Well2& getWell2atEnd(const std::string& well_name) const;
std::vector<Well2> getWells2(size_t timeStep) const;
std::vector<Well2> getWells2atEnd() const;
std::vector<Well2> getChildWells2(const std::string& group_name, size_t timeStep, GroupWellQueryMode query_mode) const;
const OilVaporizationProperties& getOilVaporizationProperties(size_t timestep) const;
const WellTestConfig& wtestConfig(size_t timestep) const;
@ -169,7 +168,6 @@ namespace Opm
void applyAction(size_t reportStep, const ActionX& action, const std::vector<std::string>& matching_wells);
private:
TimeMap m_timeMap;
OrderedMap< std::string, Well > m_wells;
OrderedMap< std::string, Group > m_groups;
OrderedMap< std::string, DynamicState<std::shared_ptr<Well2>>> wells_static;
DynamicState< GroupTree > m_rootGroupTree;
@ -189,7 +187,6 @@ namespace Opm
Actions m_actions;
std::vector< Well* > getWells(const std::string& wellNamePattern, const std::vector<std::string>& matching_wells = {});
std::vector< Group* > getGroups(const std::string& groupNamePattern);
std::map<std::string,Events> well_events;

View File

@ -1,239 +0,0 @@
/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WELL_HPP_
#define WELL_HPP_
#include <memory>
#include <string>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
namespace Opm {
template< typename > class DynamicState;
class COnnection;
class WellConnections;
class Segment;
class WellSegments;
class TimeMap;
class EclipseGrid;
class Well {
public:
Well(const std::string& name, const size_t& seqIndex, int headI,
int headJ, double refDepth, double drainageRadius, Phase preferredPhase,
WellProducer::ControlModeEnum whist_ctl,
const TimeMap& timeMap, size_t creationTimeStep,
WellCompletion::CompletionOrderEnum completionOrdering = WellCompletion::TRACK,
bool allowCrossFlow = true, bool automaticShutIn = true);
const std::string& name() const;
const size_t& seqIndex() const;
std::size_t getTotNoConn() const;
bool hasBeenDefined(size_t timeStep) const;
const std::string getGroupName(size_t timeStep) const;
void setGroupName(size_t timeStep , const std::string& groupName);
WellCommon::StatusEnum getStatus(size_t timeStep) const;
bool setStatus(size_t timeStep, WellCommon::StatusEnum Status);
int getHeadI() const;
int getHeadJ() const;
int getHeadI( size_t timestep ) const;
int getHeadJ( size_t timestep ) const;
void setHeadI( size_t timestep, int I );
void setHeadJ( size_t timestep, int J );
double getRefDepth() const;
double getRefDepth( size_t timestep ) const;
void setRefDepth( size_t timestep, double );
double getDrainageRadius( size_t timestep ) const;
void setDrainageRadius( size_t timestep, double );
Phase getPreferredPhase() const;
bool isAvailableForGroupControl(size_t timeStep) const;
void setAvailableForGroupControl(size_t timeStep, bool isAvailableForGroupControl);
double getGuideRate(size_t timeStep) const;
void setGuideRate(size_t timeStep, double guideRate);
GuideRate::GuideRatePhaseEnum getGuideRatePhase(size_t timeStep) const;
void setGuideRatePhase(size_t timeStep, GuideRate::GuideRatePhaseEnum phase);
double getGuideRateScalingFactor(size_t timeStep) const;
void setGuideRateScalingFactor(size_t timeStep, double scalingFactor);
void setEfficiencyFactor (size_t timestep, double efficiencyFactor);
double getEfficiencyFactor (size_t timestep) const;
void switchToInjector( size_t timeStep);
void switchToProducer( size_t timeStep);
bool setProducer(size_t timeStep, bool producer);
bool isProducer(size_t timeStep) const;
bool isInjector(size_t timeStep) const;
void addWELSPECS(const DeckRecord& deckRecord);
/*
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
* versa)
* * If this is an injector and something else than the
* requested phase is injected, returns 0, i.e.
* water_injector.injection_rate( gas ) == 0
* * Mixed injection is not supported and always returns 0.
*/
double production_rate( Phase phase, size_t timestep ) const;
double injection_rate( Phase phase, size_t timestep ) const;
bool operator==(const Well&) const;
bool operator!=(const Well&) const;
bool setProductionProperties(size_t timeStep , const WellProductionProperties& properties);
WellProductionProperties getProductionPropertiesCopy(size_t timeStep) const;
const WellProductionProperties& getProductionProperties(size_t timeStep) const;
bool setInjectionProperties(size_t timeStep , const WellInjectionProperties& properties);
WellInjectionProperties getInjectionPropertiesCopy(size_t timeStep) const;
const WellInjectionProperties& getInjectionProperties(size_t timeStep) const;
bool setPolymerProperties(size_t timeStep , const WellPolymerProperties& properties);
WellPolymerProperties getPolymerPropertiesCopy(size_t timeStep) const;
const WellPolymerProperties& getPolymerProperties(size_t timeStep) const;
bool setTracerProperties(size_t timeStep , const WellTracerProperties& properties);
const WellTracerProperties& getTracerProperties(size_t timeStep) const;
bool setSolventFraction(size_t timeStep , const double fraction);
const double& getSolventFraction(size_t timeStep) const;
bool setEconProductionLimits(const size_t timeStep, const WellEconProductionLimits& productionlimits);
const WellEconProductionLimits& getEconProductionLimits(const size_t timeStep) const;
int findWellFirstOpen(int startTimeStep) const;
/*
Will return the report step when the well is created with
WELSPECS, actually opening the well might be later.
*/
size_t firstTimeStep( ) const;
static bool wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern);
WellCompletion::CompletionOrderEnum getWellConnectionOrdering() const;
bool getAllowCrossFlow() const;
bool getAutomaticShutIn() const;
bool canOpen(size_t time_step) const;
// for multi-segment wells
bool isMultiSegment(size_t time_step) const;
const WellSegments& getWellSegments(size_t time_step) const;
void addWellSegments(size_t time_step, WellSegments new_segmentset);
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, const EclipseGrid& grid, 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
scan through all timesteps.
*/
void filterConnections(const EclipseGrid& grid);
private:
size_t m_creationTimeStep;
std::string m_name;
std::size_t m_seqIndex;
DynamicState< WellCommon::StatusEnum > m_status;
DynamicState< int > m_isAvailableForGroupControl;
DynamicState< double > m_guideRate;
DynamicState< GuideRate::GuideRatePhaseEnum > m_guideRatePhase;
DynamicState< double > m_guideRateScalingFactor;
DynamicState< double > m_efficiencyFactors;
DynamicState< int > m_isProducer;
DynamicState< std::shared_ptr<WellConnections> > m_completions;
DynamicState< WellProductionProperties > m_productionProperties;
DynamicState< WellInjectionProperties > m_injectionProperties;
DynamicState< WellPolymerProperties > m_polymerProperties;
DynamicState< WellEconProductionLimits > m_econproductionlimits;
DynamicState< double > m_solventFraction;
DynamicState< WellTracerProperties > m_tracerProperties;
DynamicState< std::string > m_groupName;
DynamicState< int > m_headI;
DynamicState< int > m_headJ;
DynamicState< double > m_refDepth;
DynamicState< double > m_drainageRadius;
Phase m_preferredPhase;
WellCompletion::CompletionOrderEnum m_comporder;
bool m_allowCrossFlow;
bool m_automaticShutIn;
// WELSEGS DATA - for mutli-segment wells
// flag indicating if the well is a multi-segment well
DynamicState< WellSegments > m_segmentset;
size_t timesteps;
};
}
#endif /* WELL_HPP_ */

View File

@ -67,10 +67,12 @@ public:
GuideRate::GuideRatePhaseEnum getGuideRatePhase() const;
double getGuideRateScalingFactor() const;
bool hasBeenDefined(size_t timeStep) const;
std::size_t firstTimeStep() const;
bool predictionMode() const;
bool canOpen() const;
bool isProducer() const;
bool isInjector() const;
size_t seqIndex() const;
bool getAutomaticShutIn() const;
bool getAllowCrossFlow() const;
@ -92,6 +94,18 @@ public:
WellCommon::StatusEnum getStatus() const;
const std::string& groupName() const;
Phase getPreferredPhase() const;
/* The rate of a given phase under the following assumptions:
* * Returns zero if production is requested for an injector (and vice
* versa)
* * If this is an injector and something else than the
* requested phase is injected, returns 0, i.e.
* water_injector.injection_rate( gas ) == 0
* * Mixed injection is not supported and always returns 0.
*/
double production_rate( Phase phase) const;
double injection_rate( Phase phase) const;
static bool wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern);
/*
The getCompletions() function will return a map:
@ -126,8 +140,6 @@ public:
bool updateEconLimits(std::shared_ptr<WellEconProductionLimits> econ_limits);
bool updateProduction(std::shared_ptr<WellProductionProperties> production);
bool updateInjection(std::shared_ptr<WellInjectionProperties> injection);
void switchToProducer();
void switchToInjector();
bool handleWELSEGS(const DeckKeyword& keyword);
bool handleCOMPSEGS(const DeckKeyword& keyword, const EclipseGrid& grid);
@ -136,6 +148,8 @@ public:
bool handleWPIMULT(const DeckRecord& record);
void filterConnections(const EclipseGrid& grid);
void switchToInjector();
void switchToProducer();
private:
std::string wname;
std::string group_name;

View File

@ -27,7 +27,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
@ -55,66 +54,65 @@ namespace {
std::map <std::size_t, const Opm::Connection*> mapSeqIndexToConnection(const Opm::WellConnections& conns)
{
// make seqIndex to Connection map
std::map <std::size_t, const Opm::Connection*> seqIndConnMap;
for (const auto & conn : conns) {
std::size_t sI = conn.getSeqIndex();
seqIndConnMap.insert(std::make_pair(sI, &conn));
}
return seqIndConnMap;
// make seqIndex to Connection map
std::map <std::size_t, const Opm::Connection*> seqIndConnMap;
for (const auto & conn : conns) {
std::size_t sI = conn.getSeqIndex();
seqIndConnMap.insert(std::make_pair(sI, &conn));
}
return seqIndConnMap;
}
std::map <std::size_t, const Opm::Connection*> mapCompSegSeqIndexToConnection(const Opm::WellConnections& conns)
{
// make CompSegSeqIndex to Connection map
std::map <std::size_t, const Opm::Connection*> cs_seqIndConnMap;
for (const auto & conn : conns) {
std::size_t sI = conn.getCompSegSeqIndex();
cs_seqIndConnMap.insert(std::make_pair(sI, &conn));
}
return cs_seqIndConnMap;
// make CompSegSeqIndex to Connection map
std::map <std::size_t, const Opm::Connection*> cs_seqIndConnMap;
for (const auto & conn : conns) {
std::size_t sI = conn.getCompSegSeqIndex();
cs_seqIndConnMap.insert(std::make_pair(sI, &conn));
}
return cs_seqIndConnMap;
}
template <class ConnOp>
void connectionLoop(const std::vector<const Opm::Well*>& wells,
const Opm::EclipseGrid& grid,
const std::size_t sim_step,
ConnOp&& connOp)
void connectionLoop(const std::vector<Opm::Well2>& wells,
const Opm::EclipseGrid& grid,
const std::size_t sim_step,
ConnOp&& connOp)
{
for (auto nWell = wells.size(), wellID = 0*nWell;
wellID < nWell; ++wellID)
{
const auto* well = wells[wellID];
if (well == nullptr) { continue; }
const auto& conns = well->getActiveConnections(sim_step, grid);
const int niSI = static_cast<int>(well->getTotNoConn());
std::map <std::size_t, const Opm::Connection*> sIToConn;
//Branch according to MSW well or not and
//sort active connections according to appropriate seqIndex
if (well->isMultiSegment(sim_step)) {
//sort connections according to input sequence in COMPSEGS
sIToConn = mapCompSegSeqIndexToConnection(conns);
} else
{
//sort connections according to input sequence in COMPDAT
sIToConn = mapSeqIndexToConnection(conns);
}
std::vector<const Opm::Connection*> connSI;
for (int iSI = 0; iSI < niSI; iSI++) {
const auto searchSI = sIToConn.find(static_cast<std::size_t>(iSI));
if (searchSI != sIToConn.end()) {
connSI.push_back(searchSI->second);
}
}
for (auto nConn = connSI.size(), connID = 0*nConn;
connID < nConn; ++connID)
{
connOp(*well, wellID, *(connSI[connID]), connID);
const auto& well = wells[wellID];
const auto& conn0 = well.getConnections();
const auto& conns = Opm::WellConnections( conn0, grid );
const int niSI = static_cast<int>(conn0.size());
std::map <std::size_t, const Opm::Connection*> sIToConn;
//Branch according to MSW well or not and
//sort active connections according to appropriate seqIndex
if (well.isMultiSegment()) {
//sort connections according to input sequence in COMPSEGS
sIToConn = mapCompSegSeqIndexToConnection(conns);
} else {
//sort connections according to input sequence in COMPDAT
sIToConn = mapSeqIndexToConnection(conns);
}
std::vector<const Opm::Connection*> connSI;
for (int iSI = 0; iSI < niSI; iSI++) {
const auto searchSI = sIToConn.find(static_cast<std::size_t>(iSI));
if (searchSI != sIToConn.end()) {
connSI.push_back(searchSI->second);
}
}
for (auto nConn = connSI.size(), connID = 0*nConn;
connID < nConn; ++connID)
{
connOp(well, wellID, *(connSI[connID]), connID);
}
}
}
}
namespace IConn {
@ -130,8 +128,8 @@ namespace {
return WM {
WM::NumRows { numWells(inteHead) },
WM::NumCols { maxNumConn(inteHead) },
WM::WindowSize{ entriesPerConn(inteHead) }
WM::NumCols { maxNumConn(inteHead) },
WM::WindowSize{ entriesPerConn(inteHead) }
};
}
@ -159,7 +157,7 @@ namespace {
// draining and imbibition curves at connections.
iConn[Ix::Imbibition] = iConn[Ix::Drainage];
//complnum is(1 too large): 1 - based while icon is 0 - based?
//complnum is(1 too large): 1 - based while icon is 0 - based?
iConn[Ix::ComplNum] = std::abs(conn.complnum());
//iConn[Ix::ComplNum] = iConn[Ix::SeqIndex];
@ -182,8 +180,8 @@ namespace {
return WM {
WM::NumRows { numWells(inteHead) },
WM::NumCols { maxNumConn(inteHead) },
WM::WindowSize{ entriesPerConn(inteHead) }
WM::NumCols { maxNumConn(inteHead) },
WM::WindowSize{ entriesPerConn(inteHead) }
};
}
@ -196,18 +194,18 @@ namespace {
using Ix = ::Opm::RestartIO::Helpers::VectorItems::SConn::index;
auto scprop = [&units](const M u, const double x) -> float
{
return static_cast<float>(units.from_si(u, x));
};
{
return static_cast<float>(units.from_si(u, x));
};
sConn[Ix::ConnTrans] =
scprop(M::transmissibility, conn.CF());
sConn[Ix::ConnTrans] =
scprop(M::transmissibility, conn.CF());
sConn[Ix::Depth] = scprop(M::length, conn.depth());
sConn[Ix::Diameter] = scprop(M::length, 2*conn.rw());
sConn[Ix::EffectiveKH] =
scprop(M::effective_Kh, conn.Kh());
sConn[Ix::EffectiveKH] =
scprop(M::effective_Kh, conn.Kh());
sConn[Ix::item12] = sConn[Ix::ConnTrans];
@ -232,8 +230,8 @@ namespace {
return WM {
WM::NumRows { numWells(inteHead) },
WM::NumCols { maxNumConn(inteHead) },
WM::WindowSize{ entriesPerConn(inteHead) }
WM::NumCols { maxNumConn(inteHead) },
WM::WindowSize{ entriesPerConn(inteHead) }
};
}
@ -303,57 +301,60 @@ captureDeclaredConnData(const Schedule& sched,
const data::WellRates& xw,
const std::size_t sim_step)
{
const auto& wells = sched.getWells(sim_step);
const auto& wells = sched.getWells2(sim_step);
//
// construct a composite vector of connection objects holding
// rates for all open connectons
//
std::map<std::string, std::vector<const Opm::data::Connection*> > allWellConnections;
for (const auto wl : wells) {
const auto& conns = wl->getActiveConnections(sim_step, grid);
std::vector<const Opm::data::Connection*> initConn (conns.size(), nullptr);
allWellConnections.insert(std::make_pair(wl->name(), initConn));
const auto it = allWellConnections.find(wl->name());
const auto xr = xw.find(wl->name());
size_t rCInd = 0;
if ((it != allWellConnections.end()) && (xr != xw.end())) {
for (auto nConn = conns.size(), connID = 0*nConn; connID < nConn; connID++) {
//
// WellRates connections are only defined for OPEN connections
if ((conns[connID].state() == Opm::WellCompletion::StateEnum::OPEN) &&
(rCInd < xr->second.connections.size())) {
it->second[connID] = &(xr->second.connections[rCInd]);
rCInd+= 1;
}
else if ((conns[connID].state() == Opm::WellCompletion::StateEnum::OPEN) && (rCInd >= xr->second.connections.size())) {
throw std::invalid_argument {
"Inconsistent number of open connections I in vector<Opm::data::Connection*> (" +
std::to_string(xr->second.connections.size()) + ") in Well " + wl->name()
};
for (const auto& wl : wells) {
const auto& conn0 = wl.getConnections();
const auto conns = WellConnections(conn0, grid);
std::vector<const Opm::data::Connection*> initConn (conns.size(), nullptr);
}
}
}
}
connectionLoop(wells, grid, sim_step, [&units, &allWellConnections, this]
(const Well& well, const std::size_t wellID,
const Connection& conn, const std::size_t connID) -> void
{
auto ic = this->iConn_(wellID, connID);
auto sc = this->sConn_(wellID, connID);
allWellConnections.insert(std::make_pair(wl.name(), initConn));
const auto it = allWellConnections.find(wl.name());
const auto xr = xw.find(wl.name());
size_t rCInd = 0;
if ((it != allWellConnections.end()) && (xr != xw.end())) {
for (auto nConn = conns.size(), connID = 0*nConn; connID < nConn; connID++) {
//
// WellRates connections are only defined for OPEN connections
if ((conns[connID].state() == Opm::WellCompletion::StateEnum::OPEN) &&
(rCInd < xr->second.connections.size())) {
it->second[connID] = &(xr->second.connections[rCInd]);
rCInd+= 1;
}
else if ((conns[connID].state() == Opm::WellCompletion::StateEnum::OPEN) && (rCInd >= xr->second.connections.size())) {
throw std::invalid_argument {
"Inconsistent number of open connections I in vector<Opm::data::Connection*> (" +
std::to_string(xr->second.connections.size()) + ") in Well " + wl.name()
};
IConn::staticContrib(conn, connID, ic);
SConn::staticContrib(conn, units, sc);
auto xi = allWellConnections.find(well.name());
if ((xi != allWellConnections.end()) &&
(connID < xi->second.size()))
//(connID < xi->second.connections.size()))
{
auto xc = this->xConn_(wellID, connID);
//XConn::dynamicContrib(xi->second.connections[connID],
if (xi->second[connID]) XConn::dynamicContrib(*(xi->second[connID]), units, xc);
}
}
}
});
}
connectionLoop(wells, grid, sim_step, [&units, &allWellConnections, this]
(const Well2& well, const std::size_t wellID,
const Connection& conn, const std::size_t connID) -> void
{
auto ic = this->iConn_(wellID, connID);
auto sc = this->sConn_(wellID, connID);
IConn::staticContrib(conn, connID, ic);
SConn::staticContrib(conn, units, sc);
auto xi = allWellConnections.find(well.name());
if ((xi != allWellConnections.end()) &&
(connID < xi->second.size()))
//(connID < xi->second.connections.size()))
{
auto xc = this->xConn_(wellID, connID);
//XConn::dynamicContrib(xi->second.connections[connID],
if (xi->second[connID]) XConn::dynamicContrib(*(xi->second[connID]), units, xc);
}
});
}

View File

@ -26,7 +26,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <algorithm>
#include <cstddef>
@ -174,65 +173,65 @@ namespace {
IGrpArray& iGrp,
const std::vector<int>& inteHead)
{
// find the number of wells or child groups belonging to a group and store in
// location nwgmax +1 in the iGrp array
// find the number of wells or child groups belonging to a group and store in
// location nwgmax +1 in the iGrp array
const auto childGroups = sched.getChildGroups(group.name(), simStep);
const auto childWells = sched.getChildWells(group.name(), simStep, Opm::GroupWellQueryMode::Immediate);
const auto groupMapNameIndex = currentGroupMapNameIndex(sched, simStep, inteHead);
const auto mapIndexGroup = currentGroupMapIndexGroup(sched, simStep, inteHead);
if ((childGroups.size() != 0) && (childWells.size()!=0))
throw std::invalid_argument("group has both wells and child groups" + group.name());
const auto childGroups = sched.getChildGroups(group.name(), simStep);
const auto childWells = sched.getChildWells2(group.name(), simStep, Opm::GroupWellQueryMode::Immediate);
const auto groupMapNameIndex = currentGroupMapNameIndex(sched, simStep, inteHead);
const auto mapIndexGroup = currentGroupMapIndexGroup(sched, simStep, inteHead);
if ((childGroups.size() != 0) && (childWells.size()!=0))
throw std::invalid_argument("group has both wells and child groups" + group.name());
int igrpCount = 0;
if (childWells.size() != 0) {
//group has child wells
//store the well number (sequence index) in iGrp according to the sequence they are defined
for ( auto it = childWells.begin() ; it != childWells.end(); it++) {
iGrp[igrpCount] = (*it)->seqIndex()+1;
igrpCount+=1;
}
}
else if (childGroups.size() != 0) {
//group has child groups
//The field group always has seqIndex = 0 because it is always defined first
//Hence the all groups except the Field group uses the seqIndex assigned
//iGrp contains the child groups in ascending group sequence index
std::vector<size_t> childGroupIndex;
Opm::RestartIO::Helpers::groupMaps groupMap;
groupMap.currentGrpTreeNameSeqIndMap(sched, simStep, groupMapNameIndex,mapIndexGroup);
const auto indGroupMap = groupMap.indexGroupMap();
const auto gNameIndMap = groupMap.groupNameIndexMap();
for (auto* grp : childGroups) {
auto groupName = grp->name();
auto searchGTName = gNameIndMap.find(groupName);
if (searchGTName != gNameIndMap.end()) {
childGroupIndex.push_back(searchGTName->second);
}
else {
throw std::invalid_argument( "Invalid group name" );
}
}
std::sort(childGroupIndex.begin(), childGroupIndex.end());
for (auto groupTreeIndex : childGroupIndex) {
auto searchGTIterator = indGroupMap.find(groupTreeIndex);
if (searchGTIterator != indGroupMap.end()) {
auto gname = (searchGTIterator->second)->name();
auto gSeqNoItr = groupMapNameIndex.find(gname);
if (gSeqNoItr != groupMapNameIndex.end()) {
iGrp[igrpCount] = (gSeqNoItr->second) + 1;
igrpCount+=1;
}
else {
std::cout << "AggregateGroupData, ChildGroups - Group name: groupMapNameIndex: " << gSeqNoItr->first << std::endl;
throw std::invalid_argument( "Invalid group name" );
}
}
else {
std::cout << "AggregateGroupData, ChildGroups - GroupTreeIndex: " << groupTreeIndex << std::endl;
throw std::invalid_argument( "Invalid GroupTree index" );
}
}
}
if (childWells.size() != 0) {
//group has child wells
//store the well number (sequence index) in iGrp according to the sequence they are defined
for ( const auto& well : childWells) {
iGrp[igrpCount] = well.seqIndex()+1;
igrpCount+=1;
}
}
else if (childGroups.size() != 0) {
//group has child groups
//The field group always has seqIndex = 0 because it is always defined first
//Hence the all groups except the Field group uses the seqIndex assigned
//iGrp contains the child groups in ascending group sequence index
std::vector<size_t> childGroupIndex;
Opm::RestartIO::Helpers::groupMaps groupMap;
groupMap.currentGrpTreeNameSeqIndMap(sched, simStep, groupMapNameIndex,mapIndexGroup);
const auto indGroupMap = groupMap.indexGroupMap();
const auto gNameIndMap = groupMap.groupNameIndexMap();
for (auto* grp : childGroups) {
auto groupName = grp->name();
auto searchGTName = gNameIndMap.find(groupName);
if (searchGTName != gNameIndMap.end()) {
childGroupIndex.push_back(searchGTName->second);
}
else {
throw std::invalid_argument( "Invalid group name" );
}
}
std::sort(childGroupIndex.begin(), childGroupIndex.end());
for (auto groupTreeIndex : childGroupIndex) {
auto searchGTIterator = indGroupMap.find(groupTreeIndex);
if (searchGTIterator != indGroupMap.end()) {
auto gname = (searchGTIterator->second)->name();
auto gSeqNoItr = groupMapNameIndex.find(gname);
if (gSeqNoItr != groupMapNameIndex.end()) {
iGrp[igrpCount] = (gSeqNoItr->second) + 1;
igrpCount+=1;
}
else {
std::cout << "AggregateGroupData, ChildGroups - Group name: groupMapNameIndex: " << gSeqNoItr->first << std::endl;
throw std::invalid_argument( "Invalid group name" );
}
}
else {
std::cout << "AggregateGroupData, ChildGroups - GroupTreeIndex: " << groupTreeIndex << std::endl;
throw std::invalid_argument( "Invalid GroupTree index" );
}
}
}
//assign the number of child wells or child groups to
// location nwgmax

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
@ -73,17 +72,15 @@ namespace {
}
template <typename WellOp>
void wellLoop(const std::vector<const Opm::Well*>& wells,
WellOp&& wellOp)
void wellLoop(const std::vector<Opm::Well2>& wells,
WellOp&& wellOp)
{
for (auto nWell = wells.size(), wellID = 0*nWell;
wellID < nWell; ++wellID)
{
const auto* well = wells[wellID];
const auto& well = wells[wellID];
if (well == nullptr) { continue; }
wellOp(*well, wellID);
wellOp(well, wellID);
}
}
@ -133,20 +130,20 @@ namespace {
return ind;
}
int wellType(const Opm::Well& well,
int wellType(const Opm::Well2& well,
const std::size_t sim_step)
{
using WTypeVal = ::Opm::RestartIO::Helpers::
VectorItems::IWell::Value::WellType;
if (well.isProducer(sim_step)) {
if (well.isProducer()) {
return WTypeVal::Producer;
}
using IType = ::Opm::WellInjector::TypeEnum;
const auto itype = well
.getInjectionProperties(sim_step).injectorType;
.getInjectionProperties().injectorType;
switch (itype) {
case IType::OIL: return WTypeVal::OilInj;
@ -156,25 +153,25 @@ namespace {
}
}
int wellVFPTab(const Opm::Well& well,
int wellVFPTab(const Opm::Well2& well,
const std::size_t sim_step)
{
if (well.isInjector(sim_step)) {
return well.getInjectionProperties(sim_step).VFPTableNumber;
if (well.isInjector()) {
return well.getInjectionProperties().VFPTableNumber;
}
return well.getProductionProperties(sim_step).VFPTableNumber;
return well.getProductionProperties().VFPTableNumber;
}
int ctrlMode(const Opm::Well& well,
int ctrlMode(const Opm::Well2& well,
const std::size_t sim_step)
{
using WMCtrlVal = ::Opm::RestartIO::Helpers::
VectorItems::IWell::Value::WellCtrlMode;
if (well.isInjector(sim_step)) {
if (well.isInjector()) {
const auto& prop = well
.getInjectionProperties(sim_step);
.getInjectionProperties();
const auto wmctl = prop.controlMode;
const auto wtype = prop.injectorType;
@ -200,7 +197,7 @@ namespace {
default:
{
const auto stat = well.getStatus(sim_step);
const auto stat = well.getStatus();
using WStat = ::Opm::WellCommon::StatusEnum;
@ -211,9 +208,9 @@ namespace {
return WMCtrlVal::WMCtlUnk;
}
}
else if (well.isProducer(sim_step)) {
else if (well.isProducer()) {
const auto& prop = well
.getProductionProperties(sim_step);
.getProductionProperties();
using CMode = ::Opm::WellProducer::ControlModeEnum;
@ -230,7 +227,7 @@ namespace {
default:
{
const auto stat = well.getStatus(sim_step);
const auto stat = well.getStatus();
using WStat = ::Opm::WellCommon::StatusEnum;
@ -245,7 +242,7 @@ namespace {
return WMCtrlVal::WMCtlUnk;
}
int compOrder(const Opm::Well& well)
int compOrder(const Opm::Well2& well)
{
using WCO = ::Opm::WellCompletion::CompletionOrderEnum;
using COVal = ::Opm::RestartIO::Helpers::
@ -261,26 +258,26 @@ namespace {
}
template <class IWellArray>
void staticContrib(const Opm::Well& well,
void staticContrib(const Opm::Well2& well,
const std::size_t msWellID,
const std::map <const std::string, size_t>& GroupMapNameInd,
/*const std::vector<std::string>& groupNames,*/
/*const std::vector<std::string>& groupNames,*/
const int /* maxGroups */,
const std::size_t sim_step,
IWellArray& iWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
iWell[Ix::IHead] = well.getHeadI(sim_step) + 1;
iWell[Ix::JHead] = well.getHeadJ(sim_step) + 1;
iWell[Ix::IHead] = well.getHeadI() + 1;
iWell[Ix::JHead] = well.getHeadJ() + 1;
// Connections
{
const auto& conn = well.getConnections(sim_step);
const auto& conn = well.getConnections();
iWell[Ix::NConn] = static_cast<int>(conn.size());
if (well.isMultiSegment(sim_step)) {
if (well.isMultiSegment()) {
// Set top and bottom connections to zero for multi
// segment wells
iWell[Ix::FirstK] = 0;
@ -296,8 +293,7 @@ namespace {
}
iWell[Ix::Group] =
groupIndex(trim(well.getGroupName(sim_step)),
GroupMapNameInd);
groupIndex(trim(well.groupName()), GroupMapNameInd);
iWell[Ix::WType] = wellType (well, sim_step);
iWell[Ix::VFPTab] = wellVFPTab(well, sim_step);
@ -317,11 +313,11 @@ namespace {
iWell[Ix::ActWCtrl] = ctrlMode(well, sim_step);
const auto isPred =
(well.isProducer(sim_step) &&
well.getProductionProperties(sim_step).predictionMode)
(well.isProducer() &&
well.getProductionProperties().predictionMode)
||
(well.isInjector(sim_step) &&
well.getInjectionProperties(sim_step).predictionMode);
(well.isInjector() &&
well.getInjectionProperties().predictionMode);
if (isPred) {
// Well in prediction mode (WCONPROD, WCONINJE). Assign
@ -339,44 +335,44 @@ namespace {
// Multi-segmented well information
iWell[Ix::MsWID] = 0; // MS Well ID (0 or 1..#MS wells)
iWell[Ix::NWseg] = 0; // Number of well segments
if (well.isMultiSegment(sim_step)) {
if (well.isMultiSegment()) {
iWell[Ix::MsWID] = static_cast<int>(msWellID);
iWell[Ix::NWseg] =
well.getWellSegments(sim_step).size();
well.getSegments().size();
}
iWell[Ix::CompOrd] = compOrder(well);
}
template <class IWellArray>
void dynamicContribShut(IWellArray& iWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
iWell[Ix::item9 ] = -1000;
iWell[Ix::item11] = -1000;
}
template <class IWellArray>
void dynamicContribOpen(const Opm::data::Well& xw,
IWellArray& iWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto any_flowing_conn =
std::any_of(std::begin(xw.connections),
std::end (xw.connections),
[](const Opm::data::Connection& c)
template <class IWellArray>
void dynamicContribShut(IWellArray& iWell)
{
return c.rates.any();
});
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
iWell[Ix::item9] = any_flowing_conn
? iWell[Ix::ActWCtrl] : -1;
iWell[Ix::item9 ] = -1000;
iWell[Ix::item11] = -1000;
}
iWell[Ix::item11] = 1;
}
} // IWell
template <class IWellArray>
void dynamicContribOpen(const Opm::data::Well& xw,
IWellArray& iWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto any_flowing_conn =
std::any_of(std::begin(xw.connections),
std::end (xw.connections),
[](const Opm::data::Connection& c)
{
return c.rates.any();
});
iWell[Ix::item9] = any_flowing_conn
? iWell[Ix::ActWCtrl] : -1;
iWell[Ix::item11] = 1;
}
} // IWell
namespace SWell {
std::size_t entriesPerWell(const std::vector<int>& inteHead)
@ -387,19 +383,17 @@ namespace {
return inteHead[VI::intehead::NSWELZ];
}
float datumDepth(const Opm::Well& well,
const std::size_t sim_step)
float datumDepth(const Opm::Well2& well)
{
if (well.isMultiSegment(sim_step)) {
if (well.isMultiSegment()) {
// Datum depth for multi-segment wells is
// depth of top-most segment.
return well.getWellSegments(sim_step)
.depthTopSegment();
return well.getSegments().depthTopSegment();
}
// Not a multi-segment well--i.e., this is a regular
// well. Use well's reference depth.
return well.getRefDepth(sim_step);
return well.getRefDepth();
}
Opm::RestartIO::Helpers::WindowedArray<float>
@ -463,7 +457,7 @@ namespace {
}
template <class SWellArray>
void staticContrib(const Opm::Well& well,
void staticContrib(const Opm::Well2& well,
const Opm::UnitSystem& units,
const std::size_t sim_step,
const ::Opm::SummaryState& smry,
@ -479,8 +473,8 @@ namespace {
assignDefaultSWell(sWell);
if (well.isProducer(sim_step)) {
const auto& pp = well.getProductionProperties(sim_step);
if (well.isProducer()) {
const auto& pp = well.getProductionProperties();
const auto& predMode = pp.predictionMode;
if ((pp.OilRate != 0.0) || (!predMode)) {
@ -531,8 +525,8 @@ namespace {
: swprop(M::pressure, 1.0*::Opm::unit::atm);
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
}
else if (well.isInjector(sim_step)) {
const auto& ip = well.getInjectionProperties(sim_step);
else if (well.isInjector()) {
const auto& ip = well.getInjectionProperties();
using IP = ::Opm::WellInjector::ControlModeEnum;
using IT = ::Opm::WellInjector::TypeEnum;
@ -569,8 +563,7 @@ namespace {
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
}
sWell[Ix::DatumDepth] =
swprop(M::length, datumDepth(well, sim_step));
sWell[Ix::DatumDepth] = swprop(M::length, datumDepth(well));
}
} // SWell
@ -595,7 +588,7 @@ namespace {
}
template <class XWellArray>
void staticContrib(const ::Opm::Well& well,
void staticContrib(const ::Opm::Well2& well,
const Opm::UnitSystem& units,
const std::size_t sim_step,
XWellArray& xWell)
@ -603,9 +596,9 @@ namespace {
using M = ::Opm::UnitSystem::measure;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto bhpTarget = well.isInjector(sim_step)
? well.getInjectionProperties (sim_step).BHPLimit
: well.getProductionProperties(sim_step).BHPLimit;
const auto bhpTarget = well.isInjector()
? well.getInjectionProperties ().BHPLimit
: well.getProductionProperties().BHPLimit;
xWell[Ix::BHPTarget] = units.from_si(M::pressure, bhpTarget);
}
@ -728,19 +721,19 @@ namespace {
}
template <class XWellArray>
void dynamicContrib(const ::Opm::Well& well,
void dynamicContrib(const ::Opm::Well2& well,
const ::Opm::SummaryState& smry,
const std::size_t sim_step,
XWellArray& xWell)
{
if (well.isProducer(sim_step)) {
if (well.isProducer()) {
assignProducer(well.name(), smry, xWell);
}
else if (well.isInjector(sim_step)) {
else if (well.isInjector()) {
using IType = ::Opm::WellInjector::TypeEnum;
const auto itype = well
.getInjectionProperties(sim_step).injectorType;
.getInjectionProperties().injectorType;
switch (itype) {
case IType::OIL:
@ -789,7 +782,7 @@ namespace {
}
template <class ZWellArray>
void staticContrib(const Opm::Well& well, ZWellArray& zWell)
void staticContrib(const Opm::Well2& well, ZWellArray& zWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index;
@ -816,54 +809,54 @@ Opm::RestartIO::Helpers::AggregateWellData::
captureDeclaredWellData(const Schedule& sched,
const UnitSystem& units,
const std::size_t sim_step,
const ::Opm::SummaryState& smry,
const std::vector<int>& inteHead)
const ::Opm::SummaryState& smry,
const std::vector<int>& inteHead)
{
const auto& wells = sched.getWells(sim_step);
const auto& wells = sched.getWells2(sim_step);
// Static contributions to IWEL array.
{
//const auto grpNames = groupNames(sched.getGroups());
const auto groupMapNameIndex = IWell::currentGroupMapNameIndex(sched, sim_step, inteHead);
const auto groupMapNameIndex = IWell::currentGroupMapNameIndex(sched, sim_step, inteHead);
auto msWellID = std::size_t{0};
wellLoop(wells, [&groupMapNameIndex, &msWellID, sim_step, this]
(const Well& well, const std::size_t wellID) -> void
{
msWellID += well.isMultiSegment(sim_step); // 1-based index.
auto iw = this->iWell_[wellID];
(const Well2& well, const std::size_t wellID) -> void
{
msWellID += well.isMultiSegment(); // 1-based index.
auto iw = this->iWell_[wellID];
IWell::staticContrib(well, msWellID, groupMapNameIndex,
this->nWGMax_, sim_step, iw);
});
IWell::staticContrib(well, msWellID, groupMapNameIndex,
this->nWGMax_, sim_step, iw);
});
}
// Static contributions to SWEL array.
wellLoop(wells, [&units, sim_step, &smry, this]
(const Well& well, const std::size_t wellID) -> void
{
auto sw = this->sWell_[wellID];
(const Well2& well, const std::size_t wellID) -> void
{
auto sw = this->sWell_[wellID];
SWell::staticContrib(well, units, sim_step, smry, sw);
});
SWell::staticContrib(well, units, sim_step, smry, sw);
});
// Static contributions to XWEL array.
wellLoop(wells, [&units, sim_step, this]
(const Well& well, const std::size_t wellID) -> void
{
auto xw = this->xWell_[wellID];
(const Well2& well, const std::size_t wellID) -> void
{
auto xw = this->xWell_[wellID];
XWell::staticContrib(well, units, sim_step, xw);
});
XWell::staticContrib(well, units, sim_step, xw);
});
// Static contributions to ZWEL array.
wellLoop(wells,
[this](const Well& well, const std::size_t wellID) -> void
{
auto zw = this->zWell_[wellID];
[this](const Well2& well, const std::size_t wellID) -> void
{
auto zw = this->zWell_[wellID];
ZWell::staticContrib(well, zw);
});
ZWell::staticContrib(well, zw);
});
}
// ---------------------------------------------------------------------
@ -875,26 +868,26 @@ captureDynamicWellData(const Schedule& sched,
const Opm::data::WellRates& xw,
const ::Opm::SummaryState& smry)
{
const auto& wells = sched.getWells(sim_step);
const auto& wells = sched.getWells2(sim_step);
// Dynamic contributions to IWEL array.
wellLoop(wells, [this, &xw]
(const Well& well, const std::size_t wellID) -> void
{
auto iWell = this->iWell_[wellID];
(const Well2& well, const std::size_t wellID) -> void
{
auto iWell = this->iWell_[wellID];
auto i = xw.find(well.name());
if ((i == std::end(xw)) || !i->second.flowing()) {
IWell::dynamicContribShut(iWell);
}
else {
IWell::dynamicContribOpen(i->second, iWell);
}
});
auto i = xw.find(well.name());
if ((i == std::end(xw)) || !i->second.flowing()) {
IWell::dynamicContribShut(iWell);
}
else {
IWell::dynamicContribOpen(i->second, iWell);
}
});
// Dynamic contributions to XWEL array.
wellLoop(wells, [this, sim_step, &smry]
(const Well& well, const std::size_t wellID) -> void
(const Well2& well, const std::size_t wellID) -> void
{
auto xw = this->xWell_[wellID];

View File

@ -45,8 +45,8 @@ namespace {
{
auto ncwmax = 0;
for (const auto* well : sched.getWells(lookup_step)) {
const auto ncw = well->getConnections().size();
for (const auto& well : sched.getWells2(lookup_step)) {
const auto ncw = well.getConnections().size();
ncwmax = std::max(ncwmax, static_cast<int>(ncw));
}
@ -188,13 +188,13 @@ namespace {
{
const auto& wsd = rspec.wellSegmentDimensions();
const auto& sched_wells = sched.getWells(lookup_step);
const auto& sched_wells = sched.getWells2(lookup_step);
const auto nsegwl =
std::count_if(std::begin(sched_wells), std::end(sched_wells),
[lookup_step](const Opm::Well* wellPtr)
[lookup_step](const Opm::Well2& well)
{
return wellPtr->isMultiSegment(lookup_step);
return well.isMultiSegment();
});
const auto nswlmx = wsd.maxSegmentedWells();

View File

@ -34,7 +34,6 @@
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/Utility/Functional.hpp>
@ -239,14 +238,14 @@ void RFT::writeTimeStep( const Schedule& schedule,
if (!(rft_config.rft(well_name, report_step) || rft_config.plt(well_name, report_step)))
continue;
auto* well = schedule.getWell(well_name);
rft rft_node(ecl_rft_node_alloc_new( well_name.c_str(), "RFT", current_time, days ));
const auto& wellData = wellDatas.at(well_name);
if (wellData.connections.empty())
continue;
for( const auto& connection : well->getConnections( report_step ) ) {
const auto& well = schedule.getWell2(well_name, report_step);
for( const auto& connection : well.getConnections() ) {
const size_t i = size_t( connection.getI() );
const size_t j = size_t( connection.getJ() );

View File

@ -54,7 +54,6 @@
#include <utility>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
class RestartFileView
@ -671,17 +670,17 @@ namespace {
const ::Opm::RestartIO::ecl_kw_type* opm_iwel,
const int sim_step,
const std::vector<Opm::data::Rates::opt>& phases,
const std::vector<const Opm::Well*>& sched_wells)
const std::vector<Opm::Well2>& sched_wells)
{
const auto expected_xwel_size =
std::accumulate(sched_wells.begin(), sched_wells.end(),
std::size_t(0),
[&phases, sim_step](const std::size_t acc, const Opm::Well* w)
[&phases, sim_step](const std::size_t acc, const Opm::Well2& w)
-> std::size_t
{
return acc
+ 2 + phases.size()
+ (w->getConnections(sim_step).size()
+ (w.getConnections().size()
* (phases.size() + Opm::data::Connection::restart_size));
});
@ -720,7 +719,7 @@ namespace {
using rt = Opm::data::Rates::opt;
const auto& sched_wells = schedule.getWells(rst_view.simStep());
const auto& sched_wells = schedule.getWells2(rst_view.simStep());
std::vector<rt> phases;
{
const auto& phase = es.runspec().phases();
@ -738,8 +737,8 @@ namespace {
const auto* opm_xwel_data = Load::ecl_kw_get_type_ptr<double>(opm_xwel, Load::ECL_DOUBLE_TYPE);
const auto* opm_iwel_data = Load::ecl_kw_get_type_ptr<int>(opm_iwel, Load::ECL_INT_TYPE);
for (const auto* sched_well : sched_wells) {
auto& well = wells[ sched_well->name() ];
for (const auto& sched_well : sched_wells) {
auto& well = wells[ sched_well.name() ];
well.bhp = *opm_xwel_data++;
well.temperature = *opm_xwel_data++;
@ -749,7 +748,7 @@ namespace {
well.rates.set(phase, *opm_xwel_data++);
}
for (const auto& sc : sched_well->getConnections(rst_view.simStep())) {
for (const auto& sc : sched_well.getConnections()) {
const auto i = sc.getI(), j = sc.getJ(), k = sc.getK();
if (!grid.cellActive(i, j, k) || sc.state() == Opm::WellCompletion::SHUT) {
@ -835,7 +834,7 @@ namespace {
if (gas) { xc.rates.set(Opm::data::Rates::opt::gas, 0.0); }
}
void restoreConnResults(const Opm::Well& well,
void restoreConnResults(const Opm::Well2& well,
const std::size_t wellID,
const std::size_t sim_step,
const Opm::EclipseGrid& grid,
@ -868,7 +867,8 @@ namespace {
return;
}
const auto conns = well.getActiveConnections(sim_step, grid);
const auto& conn0 = well.getConnections();
const auto conns = Opm::WellConnections(conn0, grid);
const auto ijk_to_res = ijk_to_resID(wellID, nConn, wellData);
auto linConnID = std::size_t{0};
@ -956,7 +956,7 @@ namespace {
}
Opm::data::Well
restore_well(const Opm::Well& well,
restore_well(const Opm::Well2& well,
const std::size_t wellID,
const std::size_t sim_step,
const Opm::EclipseGrid& grid,
@ -1010,14 +1010,14 @@ namespace {
grid, usys, phases, wellData, xw);
// 4) Restore segment quantities if applicable.
if (well.isMultiSegment(sim_step) &&
if (well.isMultiSegment() &&
segData.hasDefinedValues())
{
const auto iwel = wellData.iwel(wellID);
const auto mswID = iwel[VI::IWell::index::MsWID]; // One-based
const auto numSeg = iwel[VI::IWell::index::NWseg];
const auto& segSet = well.getWellSegments(sim_step);
const auto& segSet = well.getSegments();
if ((mswID > 0) && (numSeg > 0) &&
(segSet.size() == numSeg))
@ -1053,14 +1053,13 @@ namespace {
const auto& phases = es.runspec().phases();
const auto sim_step = rst_view.simStep();
const auto& wells = schedule.getWells(sim_step);
for (auto nWells = wells.size(), wellID = 0*nWells;
wellID < nWells; ++wellID)
const auto& wells = schedule.getWells2(sim_step);
for (auto nWells = wells.size(), wellID = 0*nWells; wellID < nWells; ++wellID)
{
const auto* well = wells[wellID];
const auto& well = wells[wellID];
soln[well->name()] =
restore_well(*well, wellID, sim_step, grid,
soln[well.name()] =
restore_well(well, wellID, sim_step, grid,
units, phases, wellData, segData);
}
@ -1152,12 +1151,12 @@ namespace {
// Well cumulatives
{
const auto wellData = WellVectors { rst_view, intehead };
const auto& wells = schedule.getWells(sim_step);
const auto& wells = schedule.getWells2(sim_step);
for (auto nWells = wells.size(), wellID = 0*nWells;
wellID < nWells; ++wellID)
{
assign_well_cumulatives(wells[wellID]->name(),
assign_well_cumulatives(wells[wellID].name(),
wellID, wellData, smry);
}
}

View File

@ -15,12 +15,12 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
@ -33,16 +33,16 @@ namespace out {
RegionCache::RegionCache(const Eclipse3DProperties& properties, const EclipseGrid& grid, const Schedule& schedule) {
const auto& fipnum = properties.getIntGridProperty("FIPNUM");
const auto& wells = schedule.getWells();
const auto& wells = schedule.getWells2atEnd();
for (const auto& well : wells) {
const auto& connections = well->getConnections( );
const auto& connections = well.getConnections( );
for (const auto& c : connections) {
size_t global_index = grid.getGlobalIndex( c.getI() , c.getJ() , c.getK());
if (grid.cellActive( global_index )) {
size_t active_index = grid.activeIndex( global_index );
int region_id =fipnum.iget( global_index );
auto& well_index_list = this->connection_map[ region_id ];
well_index_list.push_back( { well->name() , active_index } );
well_index_list.push_back( { well.name() , active_index } );
}
}
}
@ -59,3 +59,4 @@ RegionCache::RegionCache(const Eclipse3DProperties& properties, const EclipseGri
}
}

View File

@ -51,7 +51,6 @@
#include <ert/ecl/EclFilename.hpp>
#include <ert/ecl/fortio.h>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
namespace Opm { namespace RestartIO {
namespace {
@ -98,11 +97,11 @@ namespace {
}
std::vector<double>
serialize_OPM_XWEL(const data::Wells& wells,
int sim_step,
const std::vector<const Well*>& sched_wells,
const Phases& phase_spec,
const EclipseGrid& grid)
serialize_OPM_XWEL(const data::Wells& wells,
int sim_step,
const std::vector<Opm::Well2>& sched_wells,
const Phases& phase_spec,
const EclipseGrid& grid)
{
using rt = data::Rates::opt;
@ -112,13 +111,12 @@ namespace {
if (phase_spec.active(Phase::GAS)) phases.push_back(rt::gas);
std::vector< double > xwel;
for (const auto* sched_well : sched_wells) {
if (wells.count(sched_well->name()) == 0 ||
sched_well->getStatus(sim_step) == Opm::WellCommon::SHUT)
for (const auto& sched_well : sched_wells) {
if (wells.count(sched_well.name()) == 0 ||
sched_well.getStatus() == Opm::WellCommon::SHUT)
{
const auto elems = (sched_well->getConnections( sim_step ).size()
* (phases.size() + data::Connection::restart_size))
const auto elems = (sched_well.getConnections().size()
* (phases.size() + data::Connection::restart_size))
+ 2 /* bhp, temperature */
+ phases.size();
@ -127,7 +125,7 @@ namespace {
continue;
}
const auto& well = wells.at( sched_well->name() );
const auto& well = wells.at( sched_well.name() );
xwel.push_back( well.bhp );
xwel.push_back( well.temperature );
@ -135,7 +133,7 @@ namespace {
for (auto phase : phases)
xwel.push_back(well.rates.get(phase));
for (const auto& sc : sched_well->getConnections(sim_step)) {
for (const auto& sc : sched_well.getConnections()) {
const auto i = sc.getI(), j = sc.getJ(), k = sc.getK();
const auto rs_size = phases.size() + data::Connection::restart_size;
@ -373,7 +371,7 @@ namespace {
// Extended set of OPM well vectors
if (!ecl_compatible_rst)
{
const auto sched_wells = schedule.getWells(sim_step);
const auto sched_wells = schedule.getWells2(sim_step);
const auto sched_well_names = schedule.wellNames(sim_step);
const auto opm_xwel =
@ -557,14 +555,14 @@ void save(const std::string& filename,
// Write well and MSW data only when applicable (i.e., when present)
{
const auto& wells = schedule.getWells(sim_step);
const auto& wells = schedule.getWells2(sim_step);
if (! wells.empty()) {
const auto haveMSW =
std::any_of(std::begin(wells), std::end(wells),
[sim_step](const Well* well)
[sim_step](const Well2& well)
{
return well->isMultiSegment(sim_step);
return well.isMultiSegment();
});
if (haveMSW) {

View File

@ -40,7 +40,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
@ -122,17 +121,15 @@ namespace {
ret.push_back(SRD{"SPR" , well, segNumber});
};
const auto last_timestep = sched.getTimeMap().last();
for (const auto* well : sched.getWells()) {
if (! well->isMultiSegment(last_timestep)) {
for (const auto& well : sched.getWells2atEnd()) {
if (! well.isMultiSegment()) {
// Don't allocate MS summary vectors for non-MS wells.
continue;
}
const auto& wname = well->name();
const auto& wname = well.name();
const auto nSeg =
well->getWellSegments(last_timestep).size();
well.getSegments().size();
for (auto segID = 0*nSeg; segID < nSeg; ++segID) {
makeVectors(wname, segID + 1); // One-based
@ -289,7 +286,7 @@ struct quantity {
* is the index of the block in question. wells is simulation data.
*/
struct fn_args {
const std::vector< const Well* >& schedule_wells;
const std::vector<Well2>& schedule_wells;
double duration;
const int sim_step;
int num;
@ -357,14 +354,14 @@ template< rt phase, bool injection = true, bool polymer = false >
inline quantity rate( const fn_args& args ) {
double sum = 0.0;
for( const auto* sched_well : args.schedule_wells ) {
const auto& name = sched_well->name();
for( const auto& sched_well : args.schedule_wells ) {
const auto& name = sched_well.name();
if( args.wells.count( name ) == 0 ) continue;
double eff_fac = efac( args.eff_factors, name );
double concentration = polymer
? sched_well->getPolymerProperties( args.sim_step ).m_polymerConcentration
? sched_well.getPolymerProperties().m_polymerConcentration
: 1;
const auto v = args.wells.at(name).rates.get(phase, 0.0) * eff_fac * concentration;
@ -383,9 +380,9 @@ template< bool injection >
inline quantity flowing( const fn_args& args ) {
const auto& wells = args.wells;
const auto ts = args.sim_step;
auto pred = [&wells,ts]( const Well* w ) {
const auto& name = w->name();
return w->isInjector( ts ) == injection
auto pred = [&wells,ts]( const Well2& w ) {
const auto& name = w.name();
return w.isInjector( ) == injection
&& wells.count( name ) > 0
&& wells.at( name ).flowing();
};
@ -407,7 +404,7 @@ inline quantity crate( const fn_args& args ) {
if( args.schedule_wells.empty() ) return zero;
const auto& well = args.schedule_wells.front();
const auto& name = well->name();
const auto& name = well.name();
if( args.wells.count( name ) == 0 ) return zero;
const auto& well_data = args.wells.at( name );
@ -421,7 +418,7 @@ inline quantity crate( const fn_args& args ) {
double eff_fac = efac( args.eff_factors, name );
double concentration = polymer
? well->getPolymerProperties( args.sim_step ).m_polymerConcentration
? well.getPolymerProperties().m_polymerConcentration
: 1;
auto v = completion->rates.get( phase, 0.0 ) * eff_fac * concentration;
@ -443,7 +440,7 @@ inline quantity srate( const fn_args& args ) {
if( args.schedule_wells.empty() ) return zero;
const auto& well = args.schedule_wells.front();
const auto& name = well->name();
const auto& name = well.name();
if( args.wells.count( name ) == 0 ) return zero;
const auto& well_data = args.wells.at( name );
@ -454,7 +451,7 @@ inline quantity srate( const fn_args& args ) {
double eff_fac = efac( args.eff_factors, name );
double concentration = polymer
? well->getPolymerProperties( args.sim_step ).m_polymerConcentration
? well.getPolymerProperties().m_polymerConcentration
: 1;
auto v = segment->second.rates.get( phase, 0.0 ) * eff_fac * concentration;
@ -474,11 +471,11 @@ inline quantity trans_factors ( const fn_args& args ) {
const size_t global_index = args.num - 1;
const auto& well = args.schedule_wells.front();
const auto& name = well->name();
const auto& name = well.name();
if( args.wells.count( name ) == 0 ) return zero;
const auto& grid = args.grid;
const auto& connections = well->getConnections(args.sim_step);
const auto& connections = well.getConnections();
const auto& connection = std::find_if(
connections.begin(),
@ -503,7 +500,7 @@ inline quantity spr ( const fn_args& args ) {
if( args.schedule_wells.empty() ) return zero;
const auto& well = args.schedule_wells.front();
const auto& name = well->name();
const auto& name = well.name();
if( args.wells.count( name ) == 0 ) return zero;
const auto& well_data = args.wells.at( name );
@ -522,7 +519,7 @@ inline quantity bhp( const fn_args& args ) {
const quantity zero = { 0, measure::pressure };
if( args.schedule_wells.empty() ) return zero;
const auto p = args.wells.find( args.schedule_wells.front()->name() );
const auto p = args.wells.find( args.schedule_wells.front().name() );
if( p == args.wells.end() ) return zero;
return { p->second.bhp, measure::pressure };
@ -532,7 +529,7 @@ inline quantity thp( const fn_args& args ) {
const quantity zero = { 0, measure::pressure };
if( args.schedule_wells.empty() ) return zero;
const auto p = args.wells.find( args.schedule_wells.front()->name() );
const auto p = args.wells.find( args.schedule_wells.front().name() );
if( p == args.wells.end() ) return zero;
return { p->second.thp, measure::pressure };
@ -541,13 +538,13 @@ inline quantity thp( const fn_args& args ) {
inline quantity bhp_history( const fn_args& args ) {
if( args.schedule_wells.empty() ) return { 0.0, measure::pressure };
const Well* sched_well = args.schedule_wells.front();
const Well2& sched_well = args.schedule_wells.front();
double bhp_hist;
if ( sched_well->isProducer( args.sim_step ) )
bhp_hist = sched_well->getProductionProperties( args.sim_step ).BHPH;
if ( sched_well.isProducer( ) )
bhp_hist = sched_well.getProductionProperties().BHPH;
else
bhp_hist = sched_well->getInjectionProperties( args.sim_step ).BHPH;
bhp_hist = sched_well.getInjectionProperties().BHPH;
return { bhp_hist, measure::pressure };
}
@ -555,13 +552,13 @@ inline quantity bhp_history( const fn_args& args ) {
inline quantity thp_history( const fn_args& args ) {
if( args.schedule_wells.empty() ) return { 0.0, measure::pressure };
const Well* sched_well = args.schedule_wells.front();
const Well2& sched_well = args.schedule_wells.front();
double thp_hist;
if ( sched_well->isProducer( args.sim_step ) )
thp_hist = sched_well->getProductionProperties( args.sim_step ).THPH;
if ( sched_well.isProducer() )
thp_hist = sched_well.getProductionProperties().THPH;
else
thp_hist = sched_well->getInjectionProperties( args.sim_step ).THPH;
thp_hist = sched_well.getInjectionProperties().THPH;
return { thp_hist, measure::pressure };
}
@ -576,10 +573,10 @@ inline quantity production_history( const fn_args& args ) {
*/
double sum = 0.0;
for( const Well* sched_well : args.schedule_wells ){
for( const auto& sched_well : args.schedule_wells ){
double eff_fac = efac( args.eff_factors, sched_well->name() );
sum += sched_well->production_rate( phase, args.sim_step ) * eff_fac;
double eff_fac = efac( args.eff_factors, sched_well.name() );
sum += sched_well.production_rate( phase ) * eff_fac;
}
@ -590,10 +587,9 @@ template< Phase phase >
inline quantity injection_history( const fn_args& args ) {
double sum = 0.0;
for( const Well* sched_well : args.schedule_wells ){
double eff_fac = efac( args.eff_factors, sched_well->name() );
sum += sched_well->injection_rate( phase, args.sim_step ) * eff_fac;
for( const auto& sched_well : args.schedule_wells ){
double eff_fac = efac( args.eff_factors, sched_well.name() );
sum += sched_well.injection_rate( phase ) * eff_fac;
}
@ -603,9 +599,9 @@ inline quantity injection_history( const fn_args& args ) {
inline quantity res_vol_production_target( const fn_args& args ) {
double sum = 0.0;
for( const Well* sched_well : args.schedule_wells )
if (sched_well->getProductionProperties(args.sim_step).predictionMode)
sum += sched_well->getProductionProperties( args.sim_step ).ResVRate;
for( const Well2& sched_well : args.schedule_wells )
if (sched_well.getProductionProperties().predictionMode)
sum += sched_well.getProductionProperties().ResVRate;
return { sum, measure::rate };
}
@ -661,15 +657,15 @@ template < rt phase, bool outputProducer = true, bool outputInjector = true>
inline quantity potential_rate( const fn_args& args ) {
double sum = 0.0;
for( const auto* sched_well : args.schedule_wells ) {
const auto& name = sched_well->name();
for( const auto& sched_well : args.schedule_wells ) {
const auto& name = sched_well.name();
if( args.wells.count( name ) == 0 ) continue;
if (sched_well->isInjector(args.sim_step) && outputInjector) {
if (sched_well.isInjector() && outputInjector) {
const auto v = args.wells.at(name).rates.get(phase, 0.0);
sum += v;
}
else if (sched_well->isProducer(args.sim_step) && outputProducer) {
else if (sched_well.isProducer() && outputProducer) {
const auto v = args.wells.at(name).rates.get(phase, 0.0);
sum += v;
}
@ -1079,10 +1075,10 @@ static const std::unordered_map< std::string, UnitSystem::measure> block_units =
{"BOVIS" , UnitSystem::measure::viscosity},
};
inline std::vector< const Well* > find_wells( const Schedule& schedule,
const ecl::smspec_node* node,
const int sim_step,
const out::RegionCache& regionCache ) {
inline std::vector<Well2> find_wells( const Schedule& schedule,
const ecl::smspec_node* node,
const int sim_step,
const out::RegionCache& regionCache ) {
const auto* name = smspec_node_get_wgname( node );
const auto type = smspec_node_get_var_type( node );
@ -1091,34 +1087,38 @@ inline std::vector< const Well* > find_wells( const Schedule& schedule,
(type == ECL_SMSPEC_COMPLETION_VAR) ||
(type == ECL_SMSPEC_SEGMENT_VAR))
{
const auto* well = schedule.getWell( name );
if( !well ) return {};
return { well };
if (schedule.hasWell(name, sim_step)) {
const auto& well = schedule.getWell2( name, sim_step );
return { well };
} else
return {};
}
if( type == ECL_SMSPEC_GROUP_VAR ) {
if( !schedule.hasGroup( name ) ) return {};
return schedule.getChildWells( name, sim_step, GroupWellQueryMode::Recursive);
return schedule.getChildWells2( name, sim_step, GroupWellQueryMode::Recursive);
}
if( type == ECL_SMSPEC_FIELD_VAR )
return schedule.getWells();
return schedule.getWells2(sim_step);
if( type == ECL_SMSPEC_REGION_VAR ) {
std::vector< const Well* > wells;
std::vector<Well2> wells;
const auto region = smspec_node_get_num( node );
for ( const auto& connection : regionCache.connections( region ) ){
const auto& w_name = connection.first;
const auto& well = schedule.getWell( w_name );
if (schedule.hasWell(w_name, sim_step)) {
const auto& well = schedule.getWell2( w_name, sim_step );
const auto& it = std::find_if( wells.begin(), wells.end(),
[&] ( const Well* elem )
{ return *elem == *well; });
if ( it == wells.end() )
wells.push_back( schedule.getWell( w_name ) );
const auto& it = std::find_if( wells.begin(), wells.end(),
[&] ( const Well2& elem )
{ return elem.name() == well.name(); });
if ( it == wells.end() )
wells.push_back( schedule.getWell2( w_name, sim_step ));
}
}
return wells;
@ -1312,7 +1312,7 @@ Summary::Summary( const EclipseState& st,
/* get unit strings by calling each function with dummy input */
const auto handle = funs_pair->second;
const std::vector< const Well* > dummy_wells;
const std::vector< Well2 > dummy_wells;
const fn_args no_args { dummy_wells, // Wells from Schedule object
0, // Duration of time step
@ -1419,7 +1419,7 @@ Summary::Summary( const EclipseState& st,
std::vector< std::pair< std::string, double > >
well_efficiency_factors( const ecl::smspec_node* node,
const Schedule& schedule,
const std::vector< const Well* >& schedule_wells,
const std::vector<Well2>& schedule_wells,
const int sim_step ) {
std::vector< std::pair< std::string, double > > efac;
@ -1435,13 +1435,12 @@ well_efficiency_factors( const ecl::smspec_node* node,
const bool is_rate = !node->is_total();
const auto &groupTree = schedule.getGroupTree(sim_step);
for( const auto* well : schedule_wells ) {
double eff_factor = well->getEfficiencyFactor(sim_step);
if ( !well->hasBeenDefined( sim_step ) )
for( const auto& well : schedule_wells ) {
if (!well.hasBeenDefined(sim_step))
continue;
const auto* group_node = &schedule.getGroup(well->getGroupName(sim_step));
double eff_factor = well.getEfficiencyFactor();
const auto* group_node = &schedule.getGroup(well.groupName());
while(true){
if(( is_group
@ -1455,7 +1454,7 @@ well_efficiency_factors( const ecl::smspec_node* node,
break;
group_node = &schedule.getGroup( parent );
}
efac.emplace_back( well->name(), eff_factor );
efac.emplace_back( well.name(), eff_factor );
}
return efac;

View File

@ -31,7 +31,6 @@
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <ert/ecl/EclFilename.hpp>

View File

@ -38,7 +38,6 @@
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>

View File

@ -29,7 +29,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp>
@ -61,8 +60,9 @@ namespace {
Opm::ErrorGuard& guard)
{
auto nconn = std::size_t{0};
for (const auto* well : sched.getWells()) {
nconn = std::max(nconn, well->getConnections().size());
for (const auto& well_name : sched.wellNames()) {
const auto& well = sched.getWell2atEnd(well_name);
nconn = std::max(nconn, well.getConnections().size());
}
if (nconn > static_cast<decltype(nconn)>(wdims.maxConnPerWell()))

View File

@ -21,7 +21,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#define INVALID_GROUP_RATE -999e100
#define INVALID_EFFICIENCY_FACTOR 0.0

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>

View File

@ -1,643 +0,0 @@
/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.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/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
namespace Opm {
Well::Well(const std::string& name_, const size_t& seqIndex_, int headI,
int headJ, double refDepth , double drainageRadius, Phase preferredPhase,
WellProducer::ControlModeEnum whist_ctl,
const TimeMap& timeMap, size_t creationTimeStep,
WellCompletion::CompletionOrderEnum completionOrdering,
bool allowCrossFlow, bool automaticShutIn)
: m_creationTimeStep( creationTimeStep ),
m_name( name_ ),
m_seqIndex( seqIndex_),
m_status( timeMap, WellCommon::SHUT ),
m_isAvailableForGroupControl( timeMap, true ),
m_guideRate( timeMap, -1.0 ),
m_guideRatePhase( timeMap, GuideRate::UNDEFINED ),
m_guideRateScalingFactor( timeMap, 1.0 ),
m_efficiencyFactors (timeMap, 1.0 ),
m_isProducer( timeMap, true ) ,
m_completions( timeMap, std::make_shared<WellConnections>(headI, headJ) ),
m_productionProperties( timeMap, WellProductionProperties() ),
m_injectionProperties( timeMap, WellInjectionProperties() ),
m_polymerProperties( timeMap, WellPolymerProperties() ),
m_econproductionlimits( timeMap, WellEconProductionLimits() ),
m_solventFraction( timeMap, 0.0 ),
m_tracerProperties( timeMap, WellTracerProperties() ),
m_groupName( timeMap, "" ),
m_headI( timeMap, headI ),
m_headJ( timeMap, headJ ),
m_refDepth( timeMap, refDepth ),
m_drainageRadius (timeMap, drainageRadius),
m_preferredPhase(preferredPhase),
m_comporder(completionOrdering),
m_allowCrossFlow(allowCrossFlow),
m_automaticShutIn(automaticShutIn),
m_segmentset( timeMap, WellSegments{} ),
timesteps( timeMap.numTimesteps() )
{
WellProductionProperties p;
p.whistctl_cmode = whist_ctl;
this->m_productionProperties = DynamicState<WellProductionProperties>(timeMap, p);
}
const std::string& Well::name() const {
return m_name;
}
const size_t& Well::seqIndex() const {
return m_seqIndex;
}
void Well::switchToProducer( size_t timeStep) {
WellInjectionProperties p = getInjectionPropertiesCopy(timeStep);
p.BHPLimit = 0;
p.dropInjectionControl( Opm::WellInjector::BHP );
setInjectionProperties( timeStep , p );
}
void Well::switchToInjector( size_t timeStep) {
WellProductionProperties p = getProductionPropertiesCopy(timeStep);
p.BHPLimit = 0;
p.dropProductionControl( Opm::WellProducer::BHP );
setProductionProperties( timeStep , p );
}
bool Well::operator==(const Well& other) const {
return this->m_creationTimeStep == other.m_creationTimeStep
&& this->m_name == other.m_name
&& this->m_preferredPhase == other.m_preferredPhase
&& this->timesteps == other.timesteps;
}
bool Well::operator!=(const Well& other) const {
return !(*this == other);
}
double Well::production_rate( Phase phase, size_t timestep ) const {
if( !this->isProducer( timestep ) ) return 0.0;
const auto& p = this->getProductionProperties( timestep );
switch( phase ) {
case Phase::WATER: return p.WaterRate;
case Phase::OIL: return p.OilRate;
case Phase::GAS: return p.GasRate;
case Phase::SOLVENT:
throw std::invalid_argument( "Production of 'SOLVENT' requested." );
case Phase::POLYMER:
throw std::invalid_argument( "Production of 'POLYMER' requested." );
case Phase::ENERGY:
throw std::invalid_argument( "Production of 'ENERGY' requested." );
case Phase::POLYMW:
throw std::invalid_argument( "Production of 'POLYMW' requested.");
}
throw std::logic_error( "Unreachable state. Invalid Phase value. "
"This is likely a programming error." );
}
double Well::injection_rate( Phase phase, size_t timestep ) const {
if( !this->isInjector( timestep ) ) return 0.0;
const auto& i = this->getInjectionProperties( timestep );
const auto type = i.injectorType;
if( phase == Phase::WATER && type != WellInjector::WATER ) return 0.0;
if( phase == Phase::OIL && type != WellInjector::OIL ) return 0.0;
if( phase == Phase::GAS && type != WellInjector::GAS ) return 0.0;
return i.surfaceInjectionRate;
}
bool Well::setProductionProperties(size_t timeStep , const WellProductionProperties& newProperties) {
if (isInjector(timeStep))
switchToProducer( timeStep );
this->setProducer(timeStep, true);
return m_productionProperties.update(timeStep, newProperties);
}
WellProductionProperties Well::getProductionPropertiesCopy(size_t timeStep) const {
return m_productionProperties.get(timeStep);
}
const WellProductionProperties& Well::getProductionProperties(size_t timeStep) const {
return m_productionProperties.at(timeStep);
}
bool Well::setInjectionProperties(size_t timeStep , const WellInjectionProperties& newProperties) {
if (isProducer(timeStep))
switchToInjector( timeStep );
this->setProducer(timeStep, false);
return m_injectionProperties.update(timeStep, newProperties);
}
WellInjectionProperties Well::getInjectionPropertiesCopy(size_t timeStep) const {
return m_injectionProperties.get(timeStep);
}
const WellInjectionProperties& Well::getInjectionProperties(size_t timeStep) const {
return m_injectionProperties.at(timeStep);
}
bool Well::setPolymerProperties(size_t timeStep , const WellPolymerProperties& newProperties) {
bool update = m_polymerProperties.update(timeStep, newProperties);
this->setProducer(timeStep, false);
return update;
}
WellPolymerProperties Well::getPolymerPropertiesCopy(size_t timeStep) const {
return m_polymerProperties.get(timeStep);
}
const WellPolymerProperties& Well::getPolymerProperties(size_t timeStep) const {
return m_polymerProperties.at(timeStep);
}
bool Well::setSolventFraction(size_t timeStep , const double fraction) {
m_isProducer.update(timeStep , false);
return m_solventFraction.update(timeStep, fraction);
}
bool Well::setTracerProperties(size_t timeStep , const WellTracerProperties& newProperties) {
if (isProducer(timeStep))
throw std::invalid_argument("WTRACER keyword can only be applied to injectors");
return m_tracerProperties.update(timeStep, newProperties);
}
bool Well::setEconProductionLimits(const size_t timeStep, const WellEconProductionLimits& productionlimits) {
// not sure if this keyword turning a well to be producer.
// not sure what will happen if we use this keyword to a injector.
return m_econproductionlimits.update(timeStep, productionlimits);
}
const WellEconProductionLimits& Well::getEconProductionLimits(const size_t timeStep) const {
return m_econproductionlimits.at(timeStep);
}
const double& Well::getSolventFraction(size_t timeStep) const {
return m_solventFraction.at(timeStep);
}
const WellTracerProperties& Well::getTracerProperties(size_t timeStep) const {
return m_tracerProperties.at(timeStep);
}
bool Well::hasBeenDefined(size_t timeStep) const {
if (timeStep < m_creationTimeStep)
return false;
else
return true;
}
WellCommon::StatusEnum Well::getStatus(size_t timeStep) const {
return m_status.get( timeStep );
}
bool Well::setStatus(size_t timeStep, WellCommon::StatusEnum status) {
if ((WellCommon::StatusEnum::OPEN == status) && getConnections(timeStep).allConnectionsShut()) {
OpmLog::note("When handling keyword for well " + name() + ": Cannot open a well where all completions are shut" );
return false;
} else
return m_status.update( timeStep , status );
}
bool Well::setProducer(size_t timeStep, bool producer) {
return this->m_isProducer.update(timeStep, producer);
}
bool Well::isProducer(size_t timeStep) const {
return bool( m_isProducer.get(timeStep) );
}
bool Well::isInjector(size_t timeStep) const {
return !bool( isProducer(timeStep) );
}
bool Well::isAvailableForGroupControl(size_t timeStep) const {
return m_isAvailableForGroupControl.get(timeStep);
}
void Well::setAvailableForGroupControl(size_t timeStep, bool isAvailableForGroupControl_) {
m_isAvailableForGroupControl.update(timeStep, isAvailableForGroupControl_);
}
double Well::getGuideRate(size_t timeStep) const {
return m_guideRate.get(timeStep);
}
void Well::setGuideRate(size_t timeStep, double guideRate) {
m_guideRate.update(timeStep, guideRate);
}
GuideRate::GuideRatePhaseEnum Well::getGuideRatePhase(size_t timeStep) const {
return m_guideRatePhase.get(timeStep);
}
void Well::setGuideRatePhase(size_t timeStep, GuideRate::GuideRatePhaseEnum phase) {
m_guideRatePhase.update(timeStep, phase);
}
double Well::getGuideRateScalingFactor(size_t timeStep) const {
return m_guideRateScalingFactor.get(timeStep);
}
void Well::setGuideRateScalingFactor(size_t timeStep, double scalingFactor) {
m_guideRateScalingFactor.update(timeStep, scalingFactor);
}
double Well::getEfficiencyFactor (size_t timeStep) const {
return m_efficiencyFactors.get(timeStep);
}
void Well::setEfficiencyFactor(size_t timeStep, double scalingFactor) {
m_efficiencyFactors.update(timeStep, scalingFactor);
}
/*****************************************************************/
// WELSPECS
int Well::getHeadI() const {
return m_headI.back();
}
int Well::getHeadJ() const {
return m_headJ.back();
}
int Well::getHeadI( size_t timestep ) const {
return this->m_headI.get( timestep );
}
int Well::getHeadJ( size_t timestep ) const {
return this->m_headJ.get( timestep );
}
void Well::setHeadI( size_t timestep, int I ) {
this->m_headI.update( timestep, I );
}
void Well::setHeadJ( size_t timestep, int J ) {
this->m_headJ.update( timestep, J );
}
double Well::getRefDepth() const {
return this->getRefDepth( this->timesteps );
}
double Well::getRefDepth( size_t timestep ) const {
auto depth = this->m_refDepth.get( timestep );
if( depth >= 0.0 ) return depth;
// ref depth was defaulted and we get the depth of the first completion
const auto& completions = this->getConnections( timestep );
if( completions.size() == 0 ) {
throw std::invalid_argument( "No completions defined for well: "
+ name()
+ ". Can not infer reference depth" );
}
return completions.get( 0 ).depth();
}
void Well::setRefDepth( size_t timestep, double depth ) {
this->m_refDepth.update( timestep, depth );
}
void Well::setDrainageRadius( size_t timestep, double radius ) {
this->m_drainageRadius.update( timestep, radius );
}
double Well::getDrainageRadius(size_t timestep) const {
return m_drainageRadius.get( timestep );
}
Phase Well::getPreferredPhase() const {
return m_preferredPhase;
}
const WellConnections& Well::getConnections(size_t timeStep) const {
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();
}
std::size_t Well::getTotNoConn() const {
std::size_t time_step = this->timesteps;
const auto& connections = this->getConnections(time_step);
return connections.inputSize();
}
const std::string Well::getGroupName(size_t time_step) const {
return m_groupName.get(time_step);
}
void Well::setGroupName(size_t time_step, const std::string& groupName ) {
m_groupName.update(time_step , groupName);
}
size_t Well::firstTimeStep( ) const {
return m_creationTimeStep;
}
WellCompletion::CompletionOrderEnum Well::getWellConnectionOrdering() const {
return m_comporder;
}
bool Well::wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern) {
bool wellNameInPattern = false;
if (util_fnmatch( wellNamePattern.c_str() , wellName.c_str()) == 0) {
wellNameInPattern = true;
}
return wellNameInPattern;
}
bool Well::getAllowCrossFlow() const {
return m_allowCrossFlow;
}
bool Well::getAutomaticShutIn() const {
return m_automaticShutIn;
}
bool Well::canOpen(size_t currentStep) const {
if( getAllowCrossFlow() ) return true;
if( isInjector( currentStep ) )
return getInjectionProperties( currentStep ).surfaceInjectionRate != 0;
const auto& prod = getProductionProperties( currentStep );
return (prod.WaterRate + prod.OilRate + prod.GasRate) != 0;
}
const WellSegments& Well::getWellSegments(size_t time_step) const {
return m_segmentset.get(time_step);
}
bool Well::isMultiSegment(size_t time_step) const {
return (getWellSegments(time_step).size() > 0);
}
void Well::addWellSegments(size_t time_step, WellSegments new_segmentset ) {
// to see if it is the first time entering WELSEGS input to this well.
// if the well is not multi-segment well, it will be the first time
// not sure if a well can switch between mutli-segment well and other
// type of well
// Here, we assume not
const bool first_time = !isMultiSegment(time_step);
if( !first_time ) {
// checking the consistency of the input WELSEGS information
throw std::logic_error("re-entering WELSEGS for a well is not supported yet!!.");
}
// overwrite the BHP reference depth with the one from WELSEGS keyword
const double ref_depth = new_segmentset.depthTopSegment();
m_refDepth.update( time_step, ref_depth );
new_segmentset.process(first_time);
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 );
}
//This breaks test at line 824 in ScheduleTests
/*if (new_set->allConnectionsShut())
this->setStatus(time_step, WellCommon::SHUT );
*/
m_completions.update( time_step, std::shared_ptr<WellConnections>( new_set ));
}
void Well::filterConnections(const EclipseGrid& grid) {
/*
The m_completions member variable is DynamicState<WellConnections>
instance, hence this for loop is over all timesteps.
*/
for (auto& completions : m_completions)
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.setComplnum( 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.setState( 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, const EclipseGrid& grid, 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, grid);
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.scaleWellPi( 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);
}
}

View File

@ -104,9 +104,9 @@ Well2::Well2(const std::string& wname,
production(std::make_shared<WellProductionProperties>()),
injection(std::make_shared<WellInjectionProperties>())
{
WellProductionProperties * p = new WellProductionProperties(*this->production);
auto p = std::make_shared<WellProductionProperties>();
p->whistctl_cmode = whistctl_cmode;
this->production.reset( p );
this->updateProduction(p);
}
bool Well2::updateEfficiencyFactor(double efficiency_factor) {
@ -148,7 +148,6 @@ bool Well2::updateEconLimits(std::shared_ptr<WellEconProductionLimits> econ_limi
return false;
}
void Well2::switchToProducer() {
auto p = std::make_shared<WellInjectionProperties>(this->getInjectionProperties());
@ -355,6 +354,11 @@ bool Well2::isProducer() const {
return this->producer;
}
bool Well2::isInjector() const {
return !this->producer;
}
bool Well2::isAvailableForGroupControl() const {
return this->guide_rate.available;
}
@ -584,6 +588,13 @@ std::size_t Well2::firstTimeStep() const {
return this->init_step;
}
bool Well2::hasBeenDefined(size_t timeStep) const {
if (timeStep < this->init_step)
return false;
else
return true;
}
bool Well2::canOpen() const {
@ -619,6 +630,50 @@ WellCompletion::CompletionOrderEnum Well2::getWellConnectionOrdering() const {
return this->ordering;
}
double Well2::production_rate( Phase phase) const {
if( !this->isProducer() ) return 0.0;
const auto& p = this->getProductionProperties();
switch( phase ) {
case Phase::WATER: return p.WaterRate;
case Phase::OIL: return p.OilRate;
case Phase::GAS: return p.GasRate;
case Phase::SOLVENT:
throw std::invalid_argument( "Production of 'SOLVENT' requested." );
case Phase::POLYMER:
throw std::invalid_argument( "Production of 'POLYMER' requested." );
case Phase::ENERGY:
throw std::invalid_argument( "Production of 'ENERGY' requested." );
case Phase::POLYMW:
throw std::invalid_argument( "Production of 'POLYMW' requested.");
}
throw std::logic_error( "Unreachable state. Invalid Phase value. "
"This is likely a programming error." );
}
double Well2::injection_rate( Phase phase) const {
if( !this->isInjector() ) return 0.0;
const auto& i = this->getInjectionProperties();
const auto type = i.injectorType;
if( phase == Phase::WATER && type != WellInjector::WATER ) return 0.0;
if( phase == Phase::OIL && type != WellInjector::OIL ) return 0.0;
if( phase == Phase::GAS && type != WellInjector::GAS ) return 0.0;
return i.surfaceInjectionRate;
}
bool Well2::wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern) {
bool wellNameInPattern = false;
if (util_fnmatch( wellNamePattern.c_str() , wellName.c_str()) == 0) {
wellNameInPattern = true;
}
return wellNameInPattern;
}
}

View File

@ -39,7 +39,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
@ -294,8 +293,6 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
const GridDims& dims) {
const auto& keywordstring = keyword.name();
const auto last_timestep = schedule.getTimeMap().last();
for( const auto& record : keyword ) {
const auto& wellitem = record.getItem( 0 );
@ -308,13 +305,13 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
handleMissingWell( parseContext, errors, keyword.name(), wellitem.getTrimmedString( 0 ) );
for(const auto& name : well_names) {
const auto* well = schedule.getWell(name);
const auto& well = schedule.getWell2atEnd(name);
/*
* we don't want to add completions that don't exist, so we iterate
* over a well's completions regardless of the desired block is
* defaulted or not
*/
for( const auto& connection : well->getConnections( last_timestep ) ) {
for( const auto& connection : well.getConnections() ) {
/* block coordinates defaulted */
auto cijk = getijk( connection );
@ -354,34 +351,20 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
});
}
bool isMultiSegmentWell(const std::size_t last_timestep,
const Well* well)
{
for (auto step = 0*last_timestep;
step <= last_timestep; ++step)
{
if (well->isMultiSegment(step)) {
return true;
}
}
return false;
}
int maxNumWellSegments(const std::size_t last_timestep,
const Well* well)
const Well2& well)
{
auto numSeg = 0;
for (auto step = 0*last_timestep;
step <= last_timestep; ++step)
{
if (! well->isMultiSegment(step)) {
if (! well.isMultiSegment())
continue;
}
const auto nseg =
well->getWellSegments(last_timestep).size();
well.getSegments().size();
if (nseg > numSeg) {
numSeg = nseg;
@ -394,7 +377,7 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
void makeSegmentNodes(const std::size_t last_timestep,
const int segID,
const DeckKeyword& keyword,
const Well* well,
const Well2& well,
SummaryConfig::keyword_list& list)
{
// Modifies 'list' in place.
@ -404,11 +387,11 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
list.push_back(SummaryConfig::keyword_type( keyword.name(), well, segNumber ));
};
if (! isMultiSegmentWell(last_timestep, well))
if (!well.isMultiSegment())
// Not an MSW. Don't create summary vectors for segments.
return;
const auto& wname = well->name();
const auto& wname = well.name();
if (segID < 1) {
// Segment number defaulted. Allocate a summary
// vector for each segment.
@ -443,7 +426,7 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
const auto segID = -1;
for (const auto& well : schedule.getWells())
for (const auto& well : schedule.getWells2atEnd())
makeSegmentNodes(last_timestep, segID, keyword,
well, list);
}
@ -487,7 +470,7 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
? -1 : record.getItem(1).get<int>(0);
for (const auto& well_name : well_names)
makeSegmentNodes(last_timestep, segID, keyword, schedule.getWell(well_name), list);
makeSegmentNodes(last_timestep, segID, keyword, schedule.getWell2atEnd(well_name), list);
}
}

View File

@ -130,14 +130,16 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) {
sim.run(td.schedule, io);
{
const auto& w1 = td.schedule.getWell("P1");
const auto& w4 = td.schedule.getWell("P4");
std::size_t last_step = td.schedule.size() - 1;
BOOST_CHECK_EQUAL(w1->getStatus(1), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4->getStatus(1), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w1->getStatus(last_step), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4->getStatus(last_step), WellCommon::StatusEnum::SHUT );
const auto& w1 = td.schedule.getWell2("P1", 1);
const auto& w4 = td.schedule.getWell2("P4", 1);
BOOST_CHECK_EQUAL(w1.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4.getStatus(), WellCommon::StatusEnum::OPEN );
}
{
const auto& w1 = td.schedule.getWell2atEnd("P1");
const auto& w4 = td.schedule.getWell2atEnd("P4");
BOOST_CHECK_EQUAL(w1.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4.getStatus(), WellCommon::StatusEnum::SHUT );
}
test_work_area_free(work_area);
@ -165,36 +167,37 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) {
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
{
const auto& w1 = td.schedule.getWell("P1");
const auto& w2 = td.schedule.getWell("P2");
const auto& w3 = td.schedule.getWell("P3");
const auto& w4 = td.schedule.getWell("P4");
const auto& w1 = td.schedule.getWell2("P1", 15);
const auto& w2 = td.schedule.getWell2("P2", 15);
const auto& w3 = td.schedule.getWell2("P3", 15);
const auto& w4 = td.schedule.getWell2("P4", 15);
BOOST_CHECK_EQUAL(w1->getStatus(15), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w2->getStatus(15), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w3->getStatus(15), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4->getStatus(15), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w1.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w2.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w3.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4.getStatus(), WellCommon::StatusEnum::OPEN );
}
sim.run(td.schedule, io);
{
const auto& w1 = td.schedule.getWell("P1");
const auto& w2 = td.schedule.getWell("P2");
const auto& w3 = td.schedule.getWell("P3");
const auto& w4 = td.schedule.getWell("P4");
BOOST_CHECK_EQUAL(w1->getStatus(15), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w3->getStatus(15), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w2->getStatus(5), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w2->getStatus(6), WellCommon::StatusEnum::SHUT );
BOOST_CHECK_EQUAL(w4->getStatus(10), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4->getStatus(11), WellCommon::StatusEnum::SHUT );
const auto& w1 = td.schedule.getWell2("P1", 15);
const auto& w3 = td.schedule.getWell2("P3", 15);
BOOST_CHECK_EQUAL(w1.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w3.getStatus(), WellCommon::StatusEnum::OPEN );
}
{
const auto& w2_5 = td.schedule.getWell2("P2", 5);
const auto& w2_6 = td.schedule.getWell2("P2", 6);
BOOST_CHECK_EQUAL(w2_5.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w2_6.getStatus(), WellCommon::StatusEnum::SHUT );
}
{
const auto& w4_10 = td.schedule.getWell2("P4", 10);
const auto& w4_11 = td.schedule.getWell2("P4", 11);
BOOST_CHECK_EQUAL(w4_10.getStatus(), WellCommon::StatusEnum::OPEN );
BOOST_CHECK_EQUAL(w4_11.getStatus(), WellCommon::StatusEnum::SHUT );
}
test_work_area_free(work_area);
}

View File

@ -203,8 +203,8 @@ BOOST_AUTO_TEST_CASE(loadCOMPDATTESTSPE1) {
Opm::Schedule sched(deck, state);
const auto& units = deck.getActiveUnitSystem();
const auto& prod = sched.getWell("PROD");
const auto& connections = prod->getConnections(0);
const auto& prod = sched.getWell2("PROD", 0);
const auto& connections = prod.getConnections();
const auto& conn0 = connections[0];
/* Expected values come from Eclipse simulation. */
BOOST_CHECK_CLOSE(conn0.CF(), units.to_si(Opm::UnitSystem::measure::transmissibility, 10.609), 2e-2);
@ -316,8 +316,8 @@ BOOST_AUTO_TEST_CASE(loadCOMPDATTESTSPE9) {
{"PRODU26" ,3 , 0.176, 118.6}};
for (const auto& ec : expected) {
const auto& well = sched.getWell(ec.well);
const auto& connections = well->getConnections(0);
const auto& well = sched.getWell2(ec.well, 0);
const auto& connections = well.getConnections();
const auto& conn = connections[ec.ci - 1];
BOOST_CHECK_CLOSE( conn.CF(), units.to_si(Opm::UnitSystem::measure::transmissibility, ec.CF), 2e-1);

View File

@ -26,8 +26,6 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>

View File

@ -23,8 +23,6 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp>

View File

@ -31,7 +31,6 @@
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
@ -156,8 +155,8 @@ BOOST_AUTO_TEST_CASE(GroupAddWell) {
auto timeMap = createXDaysTimeMap( 10 );
Opm::Group group("G1" , 1, timeMap , 0);
auto well1 = std::make_shared< Well >("WELL1", 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
auto well2 = std::make_shared< Well >("WELL2", 2, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
auto well1 = std::make_shared< Well2 >("WELL1", "G1", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
auto well2 = std::make_shared< Well2 >("WELL2", "G1", 0, 2, 0, 0, 0.0, Opm::Phase::OIL, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK_EQUAL(0U , group.numWells(2));
group.addWell( 3 , well1->name() );
@ -193,8 +192,8 @@ BOOST_AUTO_TEST_CASE(GroupAddAndDelWell) {
auto timeMap = createXDaysTimeMap( 10 );
Opm::Group group("G1" , 1, timeMap , 0);
auto well1 = std::make_shared< Well >("WELL1", 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
auto well2 = std::make_shared< Well >("WELL2", 2, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
auto well1 = std::make_shared< Well2 >("WELL1", "G1", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
auto well2 = std::make_shared< Well2 >("WELL2", "G1", 0, 2, 0, 0, 0.0, Opm::Phase::OIL, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK_EQUAL(0U , group.numWells(2));
group.addWell( 3 , well1->name() );
@ -226,8 +225,8 @@ BOOST_AUTO_TEST_CASE(GroupAddAndDelWell) {
BOOST_AUTO_TEST_CASE(getWells) {
auto timeMap = createXDaysTimeMap( 10 );
Opm::Group group("G1" , 1, timeMap , 0);
auto well1 = std::make_shared< Well >("WELL1", 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
auto well2 = std::make_shared< Well >("WELL2", 2, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
auto well1 = std::make_shared< Well2 >("WELL1", "G1", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
auto well2 = std::make_shared< Well2 >("WELL2", "G1", 0, 2, 0, 0, 0.0, Opm::Phase::OIL, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
group.addWell( 2 , well1->name() );
group.addWell( 3 , well1->name() );
@ -333,14 +332,14 @@ BOOST_AUTO_TEST_CASE(createDeckWithWGRUPCONandWCONPROD) {
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Runspec runspec (deck );
Opm::Schedule schedule(deck, grid, eclipseProperties, runspec);
const auto* currentWell = schedule.getWell("B-37T2");
const Opm::WellProductionProperties& wellProductionProperties = currentWell->getProductionProperties(0);
const auto& currentWell = schedule.getWell2("B-37T2", 0);
const Opm::WellProductionProperties& wellProductionProperties = currentWell.getProductionProperties();
BOOST_CHECK_EQUAL(wellProductionProperties.controlMode, Opm::WellProducer::ControlModeEnum::GRUP);
BOOST_CHECK_EQUAL(currentWell->isAvailableForGroupControl(0), true);
BOOST_CHECK_EQUAL(currentWell->getGuideRate(0), 30);
BOOST_CHECK_EQUAL(currentWell->getGuideRatePhase(0), Opm::GuideRate::OIL);
BOOST_CHECK_EQUAL(currentWell->getGuideRateScalingFactor(0), 1.0);
BOOST_CHECK_EQUAL(currentWell.isAvailableForGroupControl(), true);
BOOST_CHECK_EQUAL(currentWell.getGuideRate(), 30);
BOOST_CHECK_EQUAL(currentWell.getGuideRatePhase(), Opm::GuideRate::OIL);
BOOST_CHECK_EQUAL(currentWell.getGuideRateScalingFactor(), 1.0);
}

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>

View File

@ -24,7 +24,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@ -206,11 +205,10 @@ BOOST_AUTO_TEST_CASE(TestDynamicWSOLVENT) {
const auto& record = keyword.getRecord(0);
const std::string& well_name = record.getItem("WELL").getTrimmedString(0);
BOOST_CHECK_EQUAL(well_name, "W_1");
const auto* well = schedule.getWell(well_name);
BOOST_CHECK_EQUAL(well->getSolventFraction(0),0); //default 0
BOOST_CHECK_EQUAL(well->getSolventFraction(1),1);
BOOST_CHECK_EQUAL(well->getSolventFraction(2),1);
BOOST_CHECK_EQUAL(well->getSolventFraction(3),0);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 0).getSolventFraction(),0); //default 0
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 1).getSolventFraction(),1);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 2).getSolventFraction(),1);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 3).getSolventFraction(),0);
}
BOOST_AUTO_TEST_CASE(TestOilInjector) {

View File

@ -36,7 +36,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@ -44,143 +43,16 @@
using namespace Opm;
static Opm::TimeMap createXDaysTimeMap(size_t numDays) {
const std::time_t startDate = Opm::TimeMap::mkdate(2010, 1, 1);
Opm::TimeMap timeMap{ startDate };
for (size_t i = 0; i < numDays; i++)
timeMap.addTStep((i+1) * 24 * 60 * 60);
return timeMap;
}
namespace Opm {
inline std::ostream& operator<<( std::ostream& stream, const Connection& c ) {
return stream << "(" << c.getI() << "," << c.getJ() << "," << c.getK() << ")";
}
inline std::ostream& operator<<( std::ostream& stream, const Well& well ) {
inline std::ostream& operator<<( std::ostream& stream, const Well2& well ) {
return stream << "(" << well.name() << ")";
}
}
BOOST_AUTO_TEST_CASE(CreateWell_CorrectNameAndDefaultValues) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL( "WELL1" , well.name() );
BOOST_CHECK_EQUAL(0.0 , well.getProductionPropertiesCopy(5).OilRate);
}
BOOST_AUTO_TEST_CASE(CreateWell_GetProductionPropertiesShouldReturnSameObject) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(&(well.getProductionProperties(5)), &(well.getProductionProperties(5)));
BOOST_CHECK_EQUAL(&(well.getProductionProperties(8)), &(well.getProductionProperties(8)));
BOOST_CHECK_EQUAL(well.getProductionProperties(5), well.getProductionProperties(8));
}
BOOST_AUTO_TEST_CASE(CreateWell_GetInjectionPropertiesShouldReturnSameObject) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(&(well.getInjectionProperties(5)), &(well.getInjectionProperties(5)));
BOOST_CHECK_EQUAL(&(well.getInjectionProperties(8)), &(well.getInjectionProperties(8)));
BOOST_CHECK_EQUAL(well.getInjectionProperties(5), well.getInjectionProperties(8));
}
BOOST_AUTO_TEST_CASE(CreateWellCreateTimeStepOK) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 5);
BOOST_CHECK_EQUAL( false , well.hasBeenDefined(0) );
BOOST_CHECK_EQUAL( false , well.hasBeenDefined(4) );
BOOST_CHECK_EQUAL( true , well.hasBeenDefined(5) );
BOOST_CHECK_EQUAL( true , well.hasBeenDefined(7) );
}
BOOST_AUTO_TEST_CASE(setWellProductionProperties_PropertiesSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getProductionPropertiesCopy( 5 ).OilRate);
Opm::WellProductionProperties props;
props.OilRate = 99;
props.GasRate = 98;
props.WaterRate = 97;
props.LiquidRate = 96;
props.ResVRate = 95;
well.setProductionProperties( 5 , props);
BOOST_CHECK_EQUAL(99 , well.getProductionPropertiesCopy( 5 ).OilRate);
BOOST_CHECK_EQUAL(98 , well.getProductionPropertiesCopy( 5 ).GasRate);
BOOST_CHECK_EQUAL(97 , well.getProductionPropertiesCopy( 5 ).WaterRate);
BOOST_CHECK_EQUAL(96 , well.getProductionPropertiesCopy( 5 ).LiquidRate);
BOOST_CHECK_EQUAL(95 , well.getProductionPropertiesCopy( 5 ).ResVRate);
BOOST_CHECK_EQUAL(99 , well.getProductionPropertiesCopy( 8 ).OilRate);
BOOST_CHECK_EQUAL(98 , well.getProductionPropertiesCopy( 8 ).GasRate);
BOOST_CHECK_EQUAL(97 , well.getProductionPropertiesCopy( 8 ).WaterRate);
BOOST_CHECK_EQUAL(96 , well.getProductionPropertiesCopy( 8 ).LiquidRate);
BOOST_CHECK_EQUAL(95 , well.getProductionPropertiesCopy( 8 ).ResVRate);
BOOST_CHECK_EQUAL(99, well.production_rate( Opm::Phase::OIL, 5 ) );
BOOST_CHECK_EQUAL(99, well.production_rate( Opm::Phase::OIL, 8 ) );
BOOST_CHECK_EQUAL(98, well.production_rate( Opm::Phase::GAS, 5 ) );
BOOST_CHECK_EQUAL(98, well.production_rate( Opm::Phase::GAS, 8 ) );
BOOST_CHECK_EQUAL(0.0, well.injection_rate( Opm::Phase::GAS, 8 ) );
BOOST_CHECK_THROW( well.production_rate( Opm::Phase::SOLVENT, 5 ), std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(setOilRate_RateSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getProductionPropertiesCopy(5).OilRate);
Opm::WellProductionProperties props;
props.OilRate = 99;
well.setProductionProperties( 5 , props);
BOOST_CHECK_EQUAL(99 , well.getProductionPropertiesCopy(5).OilRate);
BOOST_CHECK_EQUAL(99 , well.getProductionPropertiesCopy(8).OilRate);
}
BOOST_AUTO_TEST_CASE(seLiquidRate_RateSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getProductionPropertiesCopy(5).LiquidRate);
Opm::WellProductionProperties props;
props.LiquidRate = 99;
well.setProductionProperties( 5 , props);
BOOST_CHECK_EQUAL(99 , well.getProductionPropertiesCopy(5).LiquidRate);
BOOST_CHECK_EQUAL(99 , well.getProductionPropertiesCopy(8).LiquidRate);
}
BOOST_AUTO_TEST_CASE(setPredictionModeProduction_ModeSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL( true, well.getProductionPropertiesCopy(5).predictionMode);
Opm::WellProductionProperties props;
props.predictionMode = false;
well.setProductionProperties( 5 , props);
BOOST_CHECK( !well.getProductionPropertiesCopy(5).predictionMode );
BOOST_CHECK( !well.getProductionPropertiesCopy(8).predictionMode );
}
BOOST_AUTO_TEST_CASE(setpredictionModeInjection_ModeSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL( true, well.getInjectionPropertiesCopy(5).predictionMode);
Opm::WellInjectionProperties props;
props.predictionMode = false;
well.setInjectionProperties( 5 , props);
BOOST_CHECK_EQUAL(false , well.getInjectionPropertiesCopy(5).predictionMode);
BOOST_CHECK_EQUAL(false , well.getInjectionPropertiesCopy(8).predictionMode);
}
BOOST_AUTO_TEST_CASE(WellCOMPDATtestTRACK) {
Opm::Parser parser;
@ -213,10 +85,9 @@ BOOST_AUTO_TEST_CASE(WellCOMPDATtestTRACK) {
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Opm::Runspec runspec (deck);
Opm::Schedule schedule(deck, grid , eclipseProperties, runspec);
auto* op_1 = schedule.getWell("OP_1");
const auto& op_1 = schedule.getWell2("OP_1", 2);
size_t timestep = 2;
const auto& completions = op_1->getConnections( timestep );
const auto& completions = op_1.getConnections();
BOOST_CHECK_EQUAL(9U, completions.size());
//Verify TRACK completion ordering
@ -254,10 +125,9 @@ BOOST_AUTO_TEST_CASE(WellCOMPDATtestDefaultTRACK) {
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Opm::Runspec runspec (deck);
Opm::Schedule schedule(deck, grid , eclipseProperties, runspec);
auto* op_1 = schedule.getWell("OP_1");
const auto& op_1 = schedule.getWell2("OP_1", 2);
size_t timestep = 2;
const auto& completions = op_1->getConnections( timestep );
const auto& completions = op_1.getConnections();
BOOST_CHECK_EQUAL(9U, completions.size());
//Verify TRACK completion ordering
@ -298,10 +168,9 @@ BOOST_AUTO_TEST_CASE(WellCOMPDATtestINPUT) {
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Opm::Runspec runspec (deck);
Opm::Schedule schedule(deck, grid , eclipseProperties, runspec, Opm::ParseContext(), errors);
auto* op_1 = schedule.getWell("OP_1");
const auto& op_1 = schedule.getWell2("OP_1", 2);
size_t timestep = 2;
const auto& completions = op_1->getConnections( timestep );
const auto& completions = op_1.getConnections();
BOOST_CHECK_EQUAL(9U, completions.size());
//Verify INPUT completion ordering
@ -317,148 +186,75 @@ BOOST_AUTO_TEST_CASE(WellCOMPDATtestINPUT) {
}
BOOST_AUTO_TEST_CASE(NewWellZeroCompletions) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL( 0U , well.getConnections( 0 ).size() );
}
BOOST_AUTO_TEST_CASE(setGasRate_RateSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::GAS, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getProductionPropertiesCopy(5).GasRate);
Opm::WellProductionProperties properties;
properties.GasRate = 108;
well.setProductionProperties(5, properties);
BOOST_CHECK_EQUAL(108 , well.getProductionPropertiesCopy(5).GasRate);
BOOST_CHECK_EQUAL(108 , well.getProductionPropertiesCopy(8).GasRate);
}
BOOST_AUTO_TEST_CASE(setWaterRate_RateSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getProductionPropertiesCopy(5).WaterRate);
Opm::WellProductionProperties properties;
properties.WaterRate = 108;
well.setProductionProperties(5, properties);
BOOST_CHECK_EQUAL(108 , well.getProductionPropertiesCopy(5).WaterRate);
BOOST_CHECK_EQUAL(108 , well.getProductionPropertiesCopy(8).WaterRate);
}
BOOST_AUTO_TEST_CASE(setSurfaceInjectionRate_RateSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getInjectionPropertiesCopy(5).surfaceInjectionRate);
Opm::WellInjectionProperties props(well.getInjectionPropertiesCopy(5));
props.surfaceInjectionRate = 108;
well.setInjectionProperties(5, props);
BOOST_CHECK_EQUAL(108 , well.getInjectionPropertiesCopy(5).surfaceInjectionRate);
BOOST_CHECK_EQUAL(108 , well.getInjectionPropertiesCopy(8).surfaceInjectionRate);
BOOST_CHECK_EQUAL( 108, well.injection_rate(Opm::Phase::WATER, 5) );
BOOST_CHECK_EQUAL( 108, well.injection_rate(Opm::Phase::WATER, 8) );
BOOST_CHECK_EQUAL( 0.0, well.injection_rate(Opm::Phase::GAS, 5) );
BOOST_CHECK_EQUAL( 0.0, well.injection_rate(Opm::Phase::GAS, 8) );
}
BOOST_AUTO_TEST_CASE(setReservoirInjectionRate_RateSetCorrect) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap , 0);
BOOST_CHECK_EQUAL(0.0 , well.getInjectionPropertiesCopy(5).reservoirInjectionRate);
Opm::WellInjectionProperties properties(well.getInjectionPropertiesCopy(5));
properties.reservoirInjectionRate = 108;
well.setInjectionProperties(5, properties);
BOOST_CHECK_EQUAL(108 , well.getInjectionPropertiesCopy(5).reservoirInjectionRate);
BOOST_CHECK_EQUAL(108 , well.getInjectionPropertiesCopy(8).reservoirInjectionRate);
Opm::Well2 well("WELL1", "GROUP", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK_EQUAL( 0U , well.getConnections( ).size() );
}
BOOST_AUTO_TEST_CASE(isProducerCorrectlySet) {
// HACK: This test checks correctly setting of isProducer/isInjector. This property depends on which of
// WellProductionProperties/WellInjectionProperties is set last, independent of actual values.
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap ,0);
Opm::Well2 well("WELL1" , "GROUP", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
/* 1: Well is created as producer */
BOOST_CHECK_EQUAL( false , well.isInjector(0));
BOOST_CHECK_EQUAL( true , well.isProducer(0));
BOOST_CHECK_EQUAL( false , well.isInjector());
BOOST_CHECK_EQUAL( true , well.isProducer());
/* Set a surface injection rate => Well becomes an Injector */
Opm::WellInjectionProperties injectionProps1(well.getInjectionPropertiesCopy(3));
injectionProps1.surfaceInjectionRate = 100;
well.setInjectionProperties(3, injectionProps1);
BOOST_CHECK_EQUAL( true , well.isInjector(3));
BOOST_CHECK_EQUAL( false , well.isProducer(3));
BOOST_CHECK_EQUAL( 100 , well.getInjectionPropertiesCopy(3).surfaceInjectionRate);
auto injectionProps1 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injectionProps1->surfaceInjectionRate = 100;
well.updateInjection(injectionProps1);
BOOST_CHECK_EQUAL( true , well.isInjector());
BOOST_CHECK_EQUAL( false , well.isProducer());
BOOST_CHECK_EQUAL( 100 , well.getInjectionProperties().surfaceInjectionRate);
/* Set a reservoir injection rate => Well becomes an Injector */
Opm::WellInjectionProperties injectionProps2(well.getInjectionPropertiesCopy(4));
injectionProps2.reservoirInjectionRate = 200;
well.setInjectionProperties(4, injectionProps2);
BOOST_CHECK_EQUAL( true , well.isInjector(4));
BOOST_CHECK_EQUAL( false , well.isProducer(4));
BOOST_CHECK_EQUAL( 200 , well.getInjectionPropertiesCopy(4).reservoirInjectionRate);
{
Opm::Well2 well("WELL1" , "GROUP", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
/* Set a reservoir injection rate => Well becomes an Injector */
auto injectionProps2 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injectionProps2->reservoirInjectionRate = 200;
well.updateInjection(injectionProps2);
BOOST_CHECK_EQUAL( true , well.isInjector());
BOOST_CHECK_EQUAL( false , well.isProducer());
BOOST_CHECK_EQUAL( 200 , well.getInjectionProperties().reservoirInjectionRate);
}
/* Set rates => Well becomes a producer; injection rate should be set to 0. */
Opm::WellInjectionProperties injectionProps3;
well.setInjectionProperties(4, injectionProps3);
Opm::WellProductionProperties properties(well.getProductionPropertiesCopy(4));
properties.OilRate = 100;
properties.GasRate = 200;
properties.WaterRate = 300;
well.setProductionProperties(4, properties);
BOOST_CHECK_EQUAL( false , well.isInjector(4));
BOOST_CHECK_EQUAL( true , well.isProducer(4));
BOOST_CHECK_EQUAL( 0 , well.getInjectionPropertiesCopy(4).surfaceInjectionRate);
BOOST_CHECK_EQUAL( 0 , well.getInjectionPropertiesCopy(4).reservoirInjectionRate);
BOOST_CHECK_EQUAL( 100 , well.getProductionPropertiesCopy(4).OilRate);
BOOST_CHECK_EQUAL( 200 , well.getProductionPropertiesCopy(4).GasRate);
BOOST_CHECK_EQUAL( 300 , well.getProductionPropertiesCopy(4).WaterRate);
{
Opm::Well2 well("WELL1" , "GROUP", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
/* Set injection rate => Well becomes injector - all produced rates -> 0 */
Opm::WellProductionProperties prodProps2;
well.setProductionProperties(6, prodProps2);
Opm::WellInjectionProperties injectionProps4(well.getInjectionPropertiesCopy(6));
injectionProps4.reservoirInjectionRate = 50;
well.setInjectionProperties(6, injectionProps4);
BOOST_CHECK_EQUAL( true , well.isInjector(6));
BOOST_CHECK_EQUAL( false , well.isProducer(6));
BOOST_CHECK_EQUAL( 50 , well.getInjectionPropertiesCopy(6).reservoirInjectionRate);
BOOST_CHECK_EQUAL( 0 , well.getProductionPropertiesCopy(6).OilRate);
BOOST_CHECK_EQUAL( 0 , well.getProductionPropertiesCopy(6).GasRate);
BOOST_CHECK_EQUAL( 0 , well.getProductionPropertiesCopy(6).WaterRate);
/* Set rates => Well becomes a producer; injection rate should be set to 0. */
auto injectionProps3 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
well.updateInjection(injectionProps3);
auto properties = std::make_shared<Opm::WellProductionProperties>( well.getProductionProperties() );
properties->OilRate = 100;
properties->GasRate = 200;
properties->WaterRate = 300;
well.updateProduction(properties);
BOOST_CHECK_EQUAL( false , well.isInjector());
BOOST_CHECK_EQUAL( true , well.isProducer());
BOOST_CHECK_EQUAL( 0 , well.getInjectionProperties().surfaceInjectionRate);
BOOST_CHECK_EQUAL( 0 , well.getInjectionProperties().reservoirInjectionRate);
BOOST_CHECK_EQUAL( 100 , well.getProductionProperties().OilRate);
BOOST_CHECK_EQUAL( 200 , well.getProductionProperties().GasRate);
BOOST_CHECK_EQUAL( 300 , well.getProductionProperties().WaterRate);
}
}
BOOST_AUTO_TEST_CASE(GroupnameCorretlySet) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1" , 1, 0, 0, 0.0, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap ,0);
Opm::Well2 well("WELL1" , "G1", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK_EQUAL("" , well.getGroupName(2));
well.setGroupName(3 , "GROUP2");
BOOST_CHECK_EQUAL("GROUP2" , well.getGroupName(3));
BOOST_CHECK_EQUAL("GROUP2" , well.getGroupName(6));
well.setGroupName(7 , "NEWGROUP");
BOOST_CHECK_EQUAL("NEWGROUP" , well.getGroupName(7));
BOOST_CHECK_EQUAL("G1" , well.groupName());
well.updateGroup( "GROUP2");
BOOST_CHECK_EQUAL("GROUP2" , well.groupName());
}
BOOST_AUTO_TEST_CASE(addWELSPECS_setData_dataSet) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1", 1, 23, 42, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 3);
Opm::Well2 well("WELL1", "GROUP", 0, 1, 23, 42, 2334.32, Opm::Phase::WATER, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK(!well.hasBeenDefined(2));
BOOST_CHECK(well.hasBeenDefined(3));
BOOST_CHECK_EQUAL(23, well.getHeadI());
BOOST_CHECK_EQUAL(42, well.getHeadJ());
BOOST_CHECK_EQUAL(2334.32, well.getRefDepth());
@ -467,36 +263,34 @@ BOOST_AUTO_TEST_CASE(addWELSPECS_setData_dataSet) {
BOOST_AUTO_TEST_CASE(XHPLimitDefault) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
Opm::Well2 well("WELL1", "GROUP", 0, 1, 23, 42, 2334.32, Opm::Phase::WATER, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
Opm::WellProductionProperties productionProps(well.getProductionPropertiesCopy(1));
productionProps.BHPLimit = 100;
productionProps.addProductionControl(Opm::WellProducer::BHP);
well.setProductionProperties(1, productionProps);
BOOST_CHECK_EQUAL( 100 , well.getProductionPropertiesCopy(5).BHPLimit);
BOOST_CHECK( well.getProductionPropertiesCopy(5).hasProductionControl( Opm::WellProducer::BHP ));
auto productionProps = std::make_shared<Opm::WellProductionProperties>(well.getProductionProperties());
productionProps->BHPLimit = 100;
productionProps->addProductionControl(Opm::WellProducer::BHP);
well.updateProduction(productionProps);
BOOST_CHECK_EQUAL( 100 , well.getProductionProperties().BHPLimit);
BOOST_CHECK_EQUAL( true, well.getProductionProperties().hasProductionControl( Opm::WellProducer::BHP ));
Opm::WellInjectionProperties injProps(well.getInjectionPropertiesCopy(1));
injProps.THPLimit = 200;
well.setInjectionProperties(1, injProps);
BOOST_CHECK_EQUAL( 200 , well.getInjectionPropertiesCopy(5).THPLimit);
BOOST_CHECK( !well.getInjectionPropertiesCopy(5).hasInjectionControl( Opm::WellInjector::THP ));
auto injProps = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injProps->THPLimit = 200;
well.updateInjection(injProps);
BOOST_CHECK_EQUAL( 200 , well.getInjectionProperties().THPLimit);
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::THP ));
}
BOOST_AUTO_TEST_CASE(InjectorType) {
auto timeMap = createXDaysTimeMap(10);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
Opm::Well2 well("WELL1", "GROUP", 0, 1, 23, 42, 2334.32, Opm::Phase::WATER, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
Opm::WellInjectionProperties injectionProps(well.getInjectionPropertiesCopy(1));
injectionProps.injectorType = Opm::WellInjector::WATER;
well.setInjectionProperties(1, injectionProps);
auto injectionProps = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injectionProps->injectorType = Opm::WellInjector::WATER;
well.updateInjection(injectionProps);
// TODO: Should we test for something other than water here, as long as
// the default value for InjectorType is WellInjector::WATER?
BOOST_CHECK_EQUAL( Opm::WellInjector::WATER , well.getInjectionPropertiesCopy(5).injectorType);
BOOST_CHECK_EQUAL( Opm::WellInjector::WATER , well.getInjectionProperties().injectorType);
}
@ -505,158 +299,113 @@ BOOST_AUTO_TEST_CASE(InjectorType) {
BOOST_AUTO_TEST_CASE(WellHaveProductionControlLimit) {
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
Opm::Well2 well("WELL1", "GROUP", 0, 1, 23, 42, 2334.32, Opm::Phase::WATER, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK( !well.getProductionPropertiesCopy(1).hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( !well.getProductionPropertiesCopy(1).hasProductionControl( Opm::WellProducer::RESV ));
BOOST_CHECK( !well.getProductionProperties().hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( !well.getProductionProperties().hasProductionControl( Opm::WellProducer::RESV ));
Opm::WellProductionProperties properties(well.getProductionPropertiesCopy(1));
properties.OilRate = 100;
properties.addProductionControl(Opm::WellProducer::ORAT);
well.setProductionProperties(2, properties);
BOOST_CHECK( well.getProductionPropertiesCopy(2).hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( !well.getProductionPropertiesCopy(2).hasProductionControl( Opm::WellProducer::RESV ));
auto properties1 = std::make_shared<Opm::WellProductionProperties>(well.getProductionProperties());
properties1->OilRate = 100;
properties1->addProductionControl(Opm::WellProducer::ORAT);
well.updateProduction(properties1);
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( !well.getProductionProperties().hasProductionControl( Opm::WellProducer::RESV ));
Opm::WellProductionProperties properties2(well.getProductionPropertiesCopy(2));
properties2.ResVRate = 100;
properties2.addProductionControl(Opm::WellProducer::RESV);
well.setProductionProperties(2, properties2);
BOOST_CHECK( well.getProductionPropertiesCopy(2).hasProductionControl( Opm::WellProducer::RESV ));
auto properties2 = std::make_shared<Opm::WellProductionProperties>(well.getProductionProperties());
properties2->ResVRate = 100;
properties2->addProductionControl(Opm::WellProducer::RESV);
well.updateProduction(properties2);
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::RESV ));
Opm::WellProductionProperties properties3(well.getProductionPropertiesCopy(2));
properties3.OilRate = 100;
properties3.WaterRate = 100;
properties3.GasRate = 100;
properties3.LiquidRate = 100;
properties3.ResVRate = 100;
properties3.BHPLimit = 100;
properties3.THPLimit = 100;
properties3.addProductionControl(Opm::WellProducer::ORAT);
properties3.addProductionControl(Opm::WellProducer::LRAT);
properties3.addProductionControl(Opm::WellProducer::BHP);
well.setProductionProperties(10, properties3);
auto properties3 = std::make_shared<Opm::WellProductionProperties>(well.getProductionProperties());
properties3->OilRate = 100;
properties3->WaterRate = 100;
properties3->GasRate = 100;
properties3->LiquidRate = 100;
properties3->ResVRate = 100;
properties3->BHPLimit = 100;
properties3->THPLimit = 100;
properties3->addProductionControl(Opm::WellProducer::ORAT);
properties3->addProductionControl(Opm::WellProducer::LRAT);
properties3->addProductionControl(Opm::WellProducer::BHP);
well.updateProduction(properties3);
BOOST_CHECK( well.getProductionPropertiesCopy(10).hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( well.getProductionPropertiesCopy(10).hasProductionControl( Opm::WellProducer::LRAT ));
BOOST_CHECK( well.getProductionPropertiesCopy(10).hasProductionControl( Opm::WellProducer::BHP ));
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::LRAT ));
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::BHP ));
Opm::WellProductionProperties properties4(well.getProductionPropertiesCopy(10));
properties4.dropProductionControl( Opm::WellProducer::LRAT );
well.setProductionProperties(10, properties4);
auto properties4 = std::make_shared<Opm::WellProductionProperties>(well.getProductionProperties());
properties4->dropProductionControl( Opm::WellProducer::LRAT );
well.updateProduction(properties4);
BOOST_CHECK( well.getProductionPropertiesCopy(11).hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK( !well.getProductionPropertiesCopy(11).hasProductionControl( Opm::WellProducer::LRAT ));
BOOST_CHECK( well.getProductionPropertiesCopy(11).hasProductionControl( Opm::WellProducer::BHP ));
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::ORAT ));
BOOST_CHECK(!well.getProductionProperties().hasProductionControl( Opm::WellProducer::LRAT ));
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::WellProducer::BHP ));
}
BOOST_AUTO_TEST_CASE(WellHaveInjectionControlLimit) {
Opm::Well2 well("WELL1", "GROUP", 0, 1, 23, 42, 2334.32, Opm::Phase::WATER, WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RESV ));
BOOST_CHECK( !well.getInjectionPropertiesCopy(1).hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( !well.getInjectionPropertiesCopy(1).hasInjectionControl( Opm::WellInjector::RESV ));
auto injProps1 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injProps1->surfaceInjectionRate = 100;
injProps1->addInjectionControl(Opm::WellInjector::RATE);
well.updateInjection(injProps1);
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RESV ));
Opm::WellInjectionProperties injProps1(well.getInjectionPropertiesCopy(2));
injProps1.surfaceInjectionRate = 100;
injProps1.addInjectionControl(Opm::WellInjector::RATE);
well.setInjectionProperties(2, injProps1);
BOOST_CHECK( well.getInjectionPropertiesCopy(2).hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( !well.getInjectionPropertiesCopy(2).hasInjectionControl( Opm::WellInjector::RESV ));
auto injProps2 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injProps2->reservoirInjectionRate = 100;
injProps2->addInjectionControl(Opm::WellInjector::RESV);
well.updateInjection(injProps2);
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RESV ));
Opm::WellInjectionProperties injProps2(well.getInjectionPropertiesCopy(2));
injProps2.reservoirInjectionRate = 100;
injProps2.addInjectionControl(Opm::WellInjector::RESV);
well.setInjectionProperties(2, injProps2);
BOOST_CHECK( well.getInjectionPropertiesCopy(2).hasInjectionControl( Opm::WellInjector::RESV ));
auto injProps3 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injProps3->BHPLimit = 100;
injProps3->addInjectionControl(Opm::WellInjector::BHP);
injProps3->THPLimit = 100;
injProps3->addInjectionControl(Opm::WellInjector::THP);
well.updateInjection(injProps3);
Opm::WellInjectionProperties injProps3(well.getInjectionPropertiesCopy(10));
injProps3.BHPLimit = 100;
injProps3.addInjectionControl(Opm::WellInjector::BHP);
injProps3.THPLimit = 100;
injProps3.addInjectionControl(Opm::WellInjector::THP);
well.setInjectionProperties(10, injProps3);
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RESV ));
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::THP ));
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::BHP ));
BOOST_CHECK( well.getInjectionPropertiesCopy(10).hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( well.getInjectionPropertiesCopy(10).hasInjectionControl( Opm::WellInjector::RESV ));
BOOST_CHECK( well.getInjectionPropertiesCopy(10).hasInjectionControl( Opm::WellInjector::THP ));
BOOST_CHECK( well.getInjectionPropertiesCopy(10).hasInjectionControl( Opm::WellInjector::BHP ));
Opm::WellInjectionProperties injProps4(well.getInjectionPropertiesCopy(11));
injProps4.dropInjectionControl( Opm::WellInjector::RESV );
well.setInjectionProperties(11, injProps4);
BOOST_CHECK( well.getInjectionPropertiesCopy(11).hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( !well.getInjectionPropertiesCopy(11).hasInjectionControl( Opm::WellInjector::RESV ));
BOOST_CHECK( well.getInjectionPropertiesCopy(11).hasInjectionControl( Opm::WellInjector::THP ));
BOOST_CHECK( well.getInjectionPropertiesCopy(11).hasInjectionControl( Opm::WellInjector::BHP ));
auto injProps4 = std::make_shared<Opm::WellInjectionProperties>(well.getInjectionProperties());
injProps4->dropInjectionControl( Opm::WellInjector::RESV );
well.updateInjection(injProps4);
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RATE ));
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::RESV ));
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::THP ));
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::WellInjector::BHP ));
}
/*********************************************************************/
BOOST_AUTO_TEST_CASE(WellSetAvailableForGroupControl_ControlSet) {
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
BOOST_CHECK(well.isAvailableForGroupControl(10));
well.setAvailableForGroupControl(12, false);
BOOST_CHECK(!well.isAvailableForGroupControl(13));
well.setAvailableForGroupControl(15, true);
BOOST_CHECK(well.isAvailableForGroupControl(15));
}
BOOST_AUTO_TEST_CASE(WellSetGuideRate_GuideRateSet) {
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
BOOST_CHECK_LT(well.getGuideRate(0), 0);
well.setGuideRate(1, 32.2);
BOOST_CHECK_LT(well.getGuideRate(0), 0);
BOOST_CHECK_EQUAL(32.2, well.getGuideRate(1));
}
BOOST_AUTO_TEST_CASE(WellGuideRatePhase_GuideRatePhaseSet) {
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
BOOST_CHECK_EQUAL(Opm::GuideRate::UNDEFINED, well.getGuideRatePhase(0));
well.setGuideRatePhase(3, Opm::GuideRate::RAT);
BOOST_CHECK_EQUAL(Opm::GuideRate::UNDEFINED, well.getGuideRatePhase(2));
BOOST_CHECK_EQUAL(Opm::GuideRate::RAT, well.getGuideRatePhase(3));
Opm::Well2 well("WELL1" , "GROUP", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK_EQUAL(Opm::GuideRate::UNDEFINED, well.getGuideRatePhase());
BOOST_CHECK(well.updateWellGuideRate(true, 100, Opm::GuideRate::RAT, 66.0));
BOOST_CHECK_EQUAL(Opm::GuideRate::RAT, well.getGuideRatePhase());
BOOST_CHECK_EQUAL(100, well.getGuideRate());
BOOST_CHECK_EQUAL(66.0, well.getGuideRateScalingFactor());
}
BOOST_AUTO_TEST_CASE(WellEfficiencyFactorSet) {
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
BOOST_CHECK_EQUAL(1.0, well.getEfficiencyFactor(0));
well.setEfficiencyFactor(3, 0.9);
BOOST_CHECK_EQUAL(1.0, well.getEfficiencyFactor(0));
BOOST_CHECK_EQUAL(0.9, well.getEfficiencyFactor(3));
Opm::Well2 well("WELL1" , "GROUP", 0, 1, 0, 0, 0.0, Opm::Phase::OIL, Opm::WellProducer::CMODE_UNDEFINED, WellCompletion::DEPTH);
BOOST_CHECK_EQUAL(1.0, well.getEfficiencyFactor());
BOOST_CHECK( well.updateEfficiencyFactor(0.9));
BOOST_CHECK_EQUAL(0.9, well.getEfficiencyFactor());
}
BOOST_AUTO_TEST_CASE(WellSetScalingFactor_ScalingFactorSetSet) {
auto timeMap = createXDaysTimeMap(20);
Opm::Well well("WELL1", 1, 1, 2, 2334.32, 0.0, Opm::Phase::WATER, Opm::WellProducer::CMODE_UNDEFINED, timeMap, 0);
BOOST_CHECK_EQUAL(1.0, well.getGuideRateScalingFactor(0));
well.setGuideRateScalingFactor(4, 0.6);
BOOST_CHECK_EQUAL(1.0, well.getGuideRateScalingFactor(3));
BOOST_CHECK_EQUAL(0.6, well.getGuideRateScalingFactor(4));
}
BOOST_AUTO_TEST_CASE(testWellNameInWellNamePattern) {
const std::string& wellnamePattern1 = "OP_*";
const std::string& wellname1 = "OP_1";
BOOST_CHECK_EQUAL(Opm::Well::wellNameInWellNamePattern(wellname1, wellnamePattern1), true);
const std::string& wellnamePattern2 = "NONE";
BOOST_CHECK_EQUAL(Opm::Well::wellNameInWellNamePattern(wellname1, wellnamePattern2), false);
}
namespace {
namespace WCONHIST {

View File

@ -24,7 +24,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@ -153,13 +152,12 @@ BOOST_AUTO_TEST_CASE(TestDynamicWTRACER) {
const auto& record = keyword.getRecord(0);
const std::string& well_name = record.getItem("WELL").getTrimmedString(0);
BOOST_CHECK_EQUAL(well_name, "W_1");
const auto* well = schedule.getWell(well_name);
BOOST_CHECK_EQUAL(well->getTracerProperties(0).getConcentration("I1"),0); //default 0
BOOST_CHECK_EQUAL(well->getTracerProperties(0).getConcentration("I2"),0); //default 0
BOOST_CHECK_EQUAL(well->getTracerProperties(1).getConcentration("I1"),1);
BOOST_CHECK_EQUAL(well->getTracerProperties(2).getConcentration("I1"),1);
BOOST_CHECK_EQUAL(well->getTracerProperties(4).getConcentration("I1"),0);
BOOST_CHECK_EQUAL(well->getTracerProperties(4).getConcentration("I2"),1);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 0).getTracerProperties().getConcentration("I1"),0); //default 0
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 0).getTracerProperties().getConcentration("I2"),0); //default 0
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 1).getTracerProperties().getConcentration("I1"),1);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 2).getTracerProperties().getConcentration("I1"),1);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 4).getTracerProperties().getConcentration("I1"),0);
BOOST_CHECK_EQUAL(schedule.getWell2("W_1", 4).getTracerProperties().getConcentration("I2"),1);
}

View File

@ -575,36 +575,34 @@ BOOST_AUTO_TEST_CASE( MULTISEGMENT_ABS ) {
// checking the relation between segments and completions
// and also the depth of completions
{
BOOST_CHECK(sched.hasWell("PROD01"));
const auto* well = sched.getWell("PROD01");
const auto& connections = well->getConnections(0);
BOOST_CHECK_EQUAL(7U, connections.size());
BOOST_CHECK(sched.hasWell("PROD01"));
const auto& well = sched.getWell2("PROD01", 0);
const auto& connections = well.getConnections();
BOOST_CHECK_EQUAL(7U, connections.size());
const Connection& connection5 = connections.get(4);
const int seg_number_connection5 = connection5.segment();
const double connection5_depth = connection5.depth();
BOOST_CHECK_EQUAL(seg_number_connection5, 6);
BOOST_CHECK_CLOSE(connection5_depth, 2538.83, 0.001);
const Connection& connection5 = connections.get(4);
const int seg_number_connection5 = connection5.segment();
const double connection5_depth = connection5.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.segment();
const double connection6_depth = connection6.depth();
BOOST_CHECK_EQUAL(seg_number_connection6, 6);
BOOST_CHECK_CLOSE(connection6_depth, 2537.83, 0.001);
const Connection& connection6 = connections.get(5);
const int seg_number_connection6 = connection6.segment();
const double connection6_depth = connection6.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.segment();
const double connection1_depth = connection1.depth();
BOOST_CHECK_EQUAL(seg_number_connection1, 1);
BOOST_CHECK_EQUAL(connection1_depth, 2512.5);
const Connection& connection1 = connections.get(0);
const int seg_number_connection1 = connection1.segment();
const double connection1_depth = connection1.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.segment();
const double connection3_depth = connection3.depth();
BOOST_CHECK_EQUAL(seg_number_connection3, 3);
BOOST_CHECK_EQUAL(connection3_depth, 2562.5);
}
const Connection& connection3 = connections.get(2);
const int seg_number_connection3 = connection3.segment();
const double connection3_depth = connection3.depth();
BOOST_CHECK_EQUAL(seg_number_connection3, 3);
BOOST_CHECK_EQUAL(connection3_depth, 2562.5);
}
BOOST_AUTO_TEST_CASE( PLYADS ) {
@ -1364,21 +1362,24 @@ BOOST_AUTO_TEST_CASE( WCONPROD ) {
BOOST_CHECK(sched.hasWell("PROX5"));
{
auto* well = sched.getWell("PROD2");
BOOST_CHECK_CLOSE(1000/Metric::Time, well->getProductionProperties(0).OilRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well->getProductionProperties(1).OilRate, 0.001);
const auto& well0 = sched.getWell2("PROD2", 0 );
const auto& well1 = sched.getWell2("PROD2", 1 );
BOOST_CHECK_CLOSE(1000/Metric::Time, well0.getProductionProperties().OilRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well1.getProductionProperties().OilRate, 0.001);
}
{
auto* well = sched.getWell("PROD3");
BOOST_CHECK_CLOSE(0/Metric::Time, well->getProductionProperties(0).OilRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well->getProductionProperties(1).OilRate, 0.001);
const auto& well0 = sched.getWell2("PROD3", 0 );
const auto& well1 = sched.getWell2("PROD3", 1 );
BOOST_CHECK_CLOSE(0/Metric::Time, well0.getProductionProperties().OilRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well1.getProductionProperties().OilRate, 0.001);
}
{
auto* well = sched.getWell("PROX5");
BOOST_CHECK_CLOSE(2000/Metric::Time, well->getProductionProperties(0).OilRate, 0.001);
BOOST_CHECK_CLOSE(2000/Metric::Time, well->getProductionProperties(1).OilRate, 0.001);
const auto& well0 = sched.getWell2("PROX5", 0);
const auto& well1 = sched.getWell2("PROX5", 1);
BOOST_CHECK_CLOSE(2000/Metric::Time, well0.getProductionProperties().OilRate, 0.001);
BOOST_CHECK_CLOSE(2000/Metric::Time, well1.getProductionProperties().OilRate, 0.001);
}
}
@ -1401,21 +1402,24 @@ BOOST_AUTO_TEST_CASE( WCONINJE ) {
BOOST_CHECK(sched.hasWell("INJX5"));
{
auto* well = sched.getWell("INJE2");
BOOST_CHECK_CLOSE(1000/Metric::Time, well->getInjectionProperties(0).surfaceInjectionRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well->getInjectionProperties(1).surfaceInjectionRate, 0.001);
const auto& well0 = sched.getWell2("INJE2", 0);
const auto& well1 = sched.getWell2("INJE2", 1);
BOOST_CHECK_CLOSE(1000/Metric::Time, well0.getInjectionProperties().surfaceInjectionRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well1.getInjectionProperties().surfaceInjectionRate, 0.001);
}
{
auto* well = sched.getWell("INJE3");
BOOST_CHECK_CLOSE(0/Metric::Time, well->getInjectionProperties(0).surfaceInjectionRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well->getInjectionProperties(1).surfaceInjectionRate, 0.001);
const auto& well0 = sched.getWell2("INJE3", 0);
const auto& well1 = sched.getWell2("INJE3", 1);
BOOST_CHECK_CLOSE(0000/Metric::Time, well0.getInjectionProperties().surfaceInjectionRate, 0.001);
BOOST_CHECK_CLOSE(1500/Metric::Time, well1.getInjectionProperties().surfaceInjectionRate, 0.001);
}
{
auto* well = sched.getWell("INJX5");
BOOST_CHECK_CLOSE(2000/Metric::Time, well->getInjectionProperties(0).surfaceInjectionRate, 0.001);
BOOST_CHECK_CLOSE(2000/Metric::Time, well->getInjectionProperties(1).surfaceInjectionRate, 0.001);
const auto& well0 = sched.getWell2("INJX5", 0);
const auto& well1 = sched.getWell2("INJX5", 1);
BOOST_CHECK_CLOSE(2000/Metric::Time, well0.getInjectionProperties().surfaceInjectionRate, 0.001);
BOOST_CHECK_CLOSE(2000/Metric::Time, well1.getInjectionProperties().surfaceInjectionRate, 0.001);
}
}

View File

@ -32,7 +32,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
@ -116,72 +115,12 @@ BOOST_AUTO_TEST_CASE(WellTestRefDepth) {
Schedule sched(deck , grid , eclipseProperties, runspec);
BOOST_CHECK_EQUAL(4, 4);
auto* well1 = sched.getWell("W_1");
auto* well2 = sched.getWell("W_2");
auto* well4 = sched.getWell("W_4");
BOOST_CHECK_EQUAL( well1->getRefDepth() , grid.getCellDepth( 29 , 36 , 0 ));
BOOST_CHECK_EQUAL( well2->getRefDepth() , 100 );
BOOST_CHECK_THROW( well4->getRefDepth() , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(WellTestOpen) {
Parser parser;
std::string scheduleFile(pathprefix() + "SCHEDULE/SCHEDULE_WELLS2");
auto deck = parser.parseFile(scheduleFile);
EclipseGrid grid(40,60,30);
TableManager table ( deck );
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Runspec runspec (deck);
Schedule sched(deck, grid , eclipseProperties, runspec);
auto well1 = sched.getWell( "W_1" );
auto well2 = sched.getWell( "W_2" );
auto well3 = sched.getWell( "W_3" );
{
auto wells = sched.getOpenWells( 0 );
BOOST_CHECK_EQUAL( 0U , wells.size() );
}
{
auto wells = sched.getOpenWells( 3 );
BOOST_CHECK_EQUAL( 1U , wells.size() );
BOOST_CHECK_EQUAL( well1 , wells[0] );
}
{
auto wells = sched.getOpenWells(6);
BOOST_CHECK_EQUAL( 3U , wells.size() );
BOOST_CHECK_EQUAL( well1 , wells[0] );
BOOST_CHECK_EQUAL( well2 , wells[1] );
BOOST_CHECK_EQUAL( well3 , wells[2] );
}
{
auto wells = sched.getOpenWells(12);
BOOST_CHECK_EQUAL( 3U , wells.size() );
BOOST_CHECK_EQUAL( well2 , wells[1] );
BOOST_CHECK_EQUAL( well3 , wells[2] );
}
{
auto wells = sched.getOpenWells(13);
BOOST_CHECK_EQUAL( 2U , wells.size() );
BOOST_CHECK_EQUAL( well2 , wells[0] );
BOOST_CHECK_EQUAL( well3 , wells[1] );
}
{
auto wells = sched.getOpenWells(14);
BOOST_CHECK_EQUAL( 3U , wells.size() );
BOOST_CHECK_EQUAL( well2 , wells[1] );
BOOST_CHECK_EQUAL( well3 , wells[2] );
}
const auto& well1 = sched.getWell2atEnd("W_1");
const auto& well2 = sched.getWell2atEnd("W_2");
const auto& well4 = sched.getWell2atEnd("W_4");
BOOST_CHECK_EQUAL( well1.getRefDepth() , grid.getCellDepth( 29 , 36 , 0 ));
BOOST_CHECK_EQUAL( well2.getRefDepth() , 100 );
BOOST_CHECK_THROW( well4.getRefDepth() , std::invalid_argument );
}
@ -203,95 +142,78 @@ BOOST_AUTO_TEST_CASE(WellTesting) {
BOOST_CHECK(sched.hasWell("W_2"));
BOOST_CHECK(sched.hasWell("W_3"));
BOOST_CHECK_CLOSE( 777/Metric::Time , sched.getWell2("W_2", 7).getProductionProperties().ResVRate , 0.0001);
BOOST_CHECK_EQUAL( 0 , sched.getWell2("W_2", 8).getProductionProperties().ResVRate);
BOOST_CHECK_EQUAL( WellCommon::SHUT , sched.getWell2("W_2", 3).getStatus());
{
auto* well2 = sched.getWell("W_2");
const auto& rft_config = sched.rftConfig();
BOOST_CHECK_EQUAL( 0 , well2->getProductionPropertiesCopy(2).ResVRate);
BOOST_CHECK_CLOSE( 777/Metric::Time , well2->getProductionPropertiesCopy(7).ResVRate , 0.0001);
BOOST_CHECK_EQUAL( 0 , well2->getProductionPropertiesCopy(8).ResVRate);
BOOST_CHECK_EQUAL( WellCommon::SHUT , well2->getStatus(3));
BOOST_CHECK( !rft_config.rft("W_2", 2));
BOOST_CHECK( rft_config.rft("W_2", 3));
BOOST_CHECK( rft_config.rft("W_2", 4));
BOOST_CHECK( !rft_config.rft("W_2", 5));
{
const WellProductionProperties& prop3 = well2->getProductionProperties(3);
BOOST_CHECK_EQUAL( WellProducer::ORAT , prop3.controlMode);
BOOST_CHECK( prop3.hasProductionControl(WellProducer::ORAT));
BOOST_CHECK( !prop3.hasProductionControl(WellProducer::GRAT));
BOOST_CHECK( !prop3.hasProductionControl(WellProducer::WRAT));
}
// BOOST_CHECK( !well2->getProductionProperties(8).hasProductionControl(WellProducer::GRAT));
BOOST_CHECK( rft_config.rft("W_1", 3));
}
{
const WellProductionProperties& prop3 = sched.getWell2("W_2", 3).getProductionProperties();
BOOST_CHECK_EQUAL( WellProducer::ORAT , prop3.controlMode);
BOOST_CHECK( prop3.hasProductionControl(WellProducer::ORAT));
BOOST_CHECK( !prop3.hasProductionControl(WellProducer::GRAT));
BOOST_CHECK( !prop3.hasProductionControl(WellProducer::WRAT));
}
BOOST_CHECK_EQUAL( WellCommon::AUTO, sched.getWell2("W_3", 3).getStatus());
{
auto* well3 = sched.getWell("W_3");
BOOST_CHECK_EQUAL( WellCommon::AUTO , well3->getStatus(3));
BOOST_CHECK_EQUAL( 0 , well3->getProductionPropertiesCopy(2).LiquidRate);
{
const WellProductionProperties& prop7 = well3->getProductionProperties(7);
BOOST_CHECK_CLOSE( 999/Metric::Time , prop7.LiquidRate , 0.001);
BOOST_CHECK_EQUAL( WellProducer::RESV, prop7.controlMode);
}
BOOST_CHECK_CLOSE( 8000./Metric::Time, well3->getProductionPropertiesCopy(3).LiquidRate, 1.e-12);
BOOST_CHECK_CLOSE( 18000./Metric::Time, well3->getProductionPropertiesCopy(8).LiquidRate, 1.e-12);
const WellProductionProperties& prop7 = sched.getWell2("W_3", 7).getProductionProperties();
BOOST_CHECK_CLOSE( 999/Metric::Time , prop7.LiquidRate , 0.001);
BOOST_CHECK_EQUAL( WellProducer::RESV, prop7.controlMode);
}
BOOST_CHECK_CLOSE( 8000./Metric::Time , sched.getWell2("W_3", 3).getProductionProperties().LiquidRate, 1.e-12);
BOOST_CHECK_CLOSE( 18000./Metric::Time, sched.getWell2("W_3", 8).getProductionProperties().LiquidRate, 1.e-12);
{
auto* well1 = sched.getWell("W_1");
const auto& rft_config = sched.rftConfig();
BOOST_CHECK_EQUAL(sched.getWell2("W_1", 3).getProductionProperties().predictionMode, false);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 3).getProductionProperties().WaterRate , 4/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 3).getProductionProperties().GasRate , 12345/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 3).getProductionProperties().OilRate , 4000/Metric::Time, 0.001);
BOOST_CHECK(rft_config.rft("W_1", 3));
BOOST_CHECK(well1->getProductionPropertiesCopy(0).predictionMode);
BOOST_CHECK_EQUAL(0, well1->getProductionPropertiesCopy(0).OilRate);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 4).getProductionProperties().OilRate , 4000/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 4).getProductionProperties().WaterRate , 4/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 4).getProductionProperties().GasRate , 12345/Metric::Time,0.001);
BOOST_CHECK_EQUAL(0, well1->getProductionPropertiesCopy(1).OilRate);
BOOST_CHECK_EQUAL(0, well1->getProductionPropertiesCopy(2).OilRate);
BOOST_CHECK(!well1->getProductionPropertiesCopy(3).predictionMode);
BOOST_CHECK_CLOSE(4000/Metric::Time , well1->getProductionPropertiesCopy(3).OilRate , 0.001);
BOOST_CHECK_CLOSE(4000/Metric::Time , well1->getProductionPropertiesCopy(4).OilRate , 0.001);
BOOST_CHECK_CLOSE(4000/Metric::Time , well1->getProductionPropertiesCopy(5).OilRate , 0.001);
BOOST_CHECK_CLOSE(4/Metric::Time , well1->getProductionPropertiesCopy(3).WaterRate , 0.001);
BOOST_CHECK_CLOSE(12345/Metric::Time , well1->getProductionPropertiesCopy(3).GasRate , 0.001);
BOOST_CHECK_CLOSE(4/Metric::Time , well1->getProductionPropertiesCopy(4).WaterRate , 0.001);
BOOST_CHECK_CLOSE(12345/Metric::Time , well1->getProductionPropertiesCopy(4).GasRate , 0.001);
BOOST_CHECK_CLOSE(4/Metric::Time , well1->getProductionPropertiesCopy(5).WaterRate , 0.001);
BOOST_CHECK_CLOSE(12345/Metric::Time , well1->getProductionPropertiesCopy(5).GasRate , 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 5).getProductionProperties().WaterRate, 4/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 5).getProductionProperties().GasRate , 12345/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 5).getProductionProperties().OilRate , 4000/Metric::Time, 0.001);
BOOST_CHECK(!well1->getProductionPropertiesCopy(6).predictionMode);
BOOST_CHECK_CLOSE(14000/Metric::Time , well1->getProductionPropertiesCopy(6).OilRate , 0.001);
BOOST_CHECK_EQUAL(sched.getWell2("W_1", 6).getProductionProperties().predictionMode, false);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 6).getProductionProperties().OilRate , 14000/Metric::Time, 0.001);
BOOST_CHECK(well1->getProductionPropertiesCopy(7).predictionMode);
BOOST_CHECK_CLOSE(11000/Metric::Time , well1->getProductionPropertiesCopy(7).OilRate , 0.001);
BOOST_CHECK_CLOSE(44/Metric::Time , well1->getProductionPropertiesCopy(7).WaterRate , 0.001);
BOOST_CHECK_CLOSE(188/Metric::Time , well1->getProductionPropertiesCopy(7).GasRate , 0.001);
BOOST_CHECK_EQUAL(sched.getWell2("W_1", 7).getProductionProperties().predictionMode, true);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 7).getProductionProperties().OilRate , 11000/Metric::Time, 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 7).getProductionProperties().WaterRate , 44/Metric::Time, 0.001);
BOOST_CHECK(!well1->getProductionPropertiesCopy(8).predictionMode);
BOOST_CHECK_CLOSE(13000/Metric::Time , well1->getProductionPropertiesCopy(8).OilRate , 0.001);
BOOST_CHECK_CLOSE(123.00 * Metric::Pressure , well1->getInjectionPropertiesCopy(10).BHPLimit, 0.001);
BOOST_CHECK_CLOSE(678.00 * Metric::Pressure , well1->getInjectionPropertiesCopy(10).THPLimit, 0.001);
BOOST_CHECK_EQUAL(sched.getWell2("W_1", 8).getProductionProperties().predictionMode, false);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 8).getProductionProperties().OilRate , 13000/Metric::Time , 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 10).getInjectionProperties().BHPLimit, 123.00 * Metric::Pressure , 0.001);
BOOST_CHECK_CLOSE(sched.getWell2("W_1", 10).getInjectionProperties().THPLimit, 678.00 * Metric::Pressure , 0.001);
{
const WellInjectionProperties& prop11 = well1->getInjectionProperties(11);
const WellInjectionProperties& prop11 = sched.getWell2("W_1", 11).getInjectionProperties();
BOOST_CHECK_CLOSE(5000/Metric::Time , prop11.surfaceInjectionRate, 0.001);
BOOST_CHECK_EQUAL( WellInjector::RATE , prop11.controlMode);
BOOST_CHECK_EQUAL( WellCommon::OPEN , well1->getStatus( 11 ));
}
BOOST_CHECK( well1->isInjector(9));
BOOST_CHECK( sched.getWell2("W_1", 9).isInjector());
{
const WellInjectionProperties& prop9 = well1->getInjectionProperties(9);
const WellInjectionProperties& prop9 = sched.getWell2("W_1", 9).getInjectionProperties();
BOOST_CHECK_CLOSE(20000/Metric::Time , prop9.surfaceInjectionRate , 0.001);
BOOST_CHECK_CLOSE(200000/Metric::Time , prop9.reservoirInjectionRate, 0.001);
BOOST_CHECK_CLOSE(6895 * Metric::Pressure , prop9.BHPLimit, 0.001);
@ -304,14 +226,16 @@ BOOST_AUTO_TEST_CASE(WellTesting) {
}
BOOST_CHECK_EQUAL( WellCommon::OPEN , well1->getStatus( 12 ));
BOOST_CHECK( well1->getInjectionPropertiesCopy(12).hasInjectionControl(WellInjector::RATE ));
BOOST_CHECK( !well1->getInjectionPropertiesCopy(12).hasInjectionControl(WellInjector::RESV));
BOOST_CHECK( well1->getInjectionPropertiesCopy(12).hasInjectionControl(WellInjector::THP ));
BOOST_CHECK( well1->getInjectionPropertiesCopy(12).hasInjectionControl(WellInjector::BHP ));
BOOST_CHECK_EQUAL( WellCommon::SHUT , well1->getStatus( 13 ));
BOOST_CHECK_EQUAL( WellCommon::OPEN , well1->getStatus( 14 ));
BOOST_CHECK_EQUAL( WellCommon::OPEN, sched.getWell2("W_1", 11).getStatus( ));
BOOST_CHECK_EQUAL( WellCommon::OPEN, sched.getWell2("W_1", 12).getStatus( ));
BOOST_CHECK_EQUAL( WellCommon::SHUT, sched.getWell2("W_1", 13).getStatus( ));
BOOST_CHECK_EQUAL( WellCommon::OPEN, sched.getWell2("W_1", 14).getStatus( ));
{
BOOST_CHECK( sched.getWell2("W_1", 12).getInjectionProperties().hasInjectionControl(WellInjector::RATE ));
BOOST_CHECK( !sched.getWell2("W_1", 12).getInjectionProperties().hasInjectionControl(WellInjector::RESV));
BOOST_CHECK( sched.getWell2("W_1", 12).getInjectionProperties().hasInjectionControl(WellInjector::THP ));
BOOST_CHECK( sched.getWell2("W_1", 12).getInjectionProperties().hasInjectionControl(WellInjector::BHP ));
}
}
}
@ -343,18 +267,19 @@ BOOST_AUTO_TEST_CASE(WellTestCOMPDAT) {
BOOST_CHECK(sched.hasWell("W_2"));
BOOST_CHECK(sched.hasWell("W_3"));
{
auto* well1 = sched.getWell("W_1");
BOOST_CHECK_CLOSE(13000/Metric::Time , well1->getProductionPropertiesCopy(8).OilRate , 0.0001);
BOOST_CHECK_EQUAL(0U, well1->getConnections( 0 ).size() );
BOOST_CHECK_CLOSE(13000/Metric::Time , sched.getWell2("W_1", 8).getProductionProperties().OilRate , 0.0001);
{
const auto& connections = sched.getWell2("W_1", 3).getConnections();
BOOST_CHECK_EQUAL(4U, connections.size());
const auto& connections = well1->getConnections(3);
BOOST_CHECK_EQUAL(4U, connections.size());
BOOST_CHECK_EQUAL(WellCompletion::OPEN, connections.get(3).state());
BOOST_CHECK_EQUAL(2.2836805555555556e-12 , connections.get(3).CF());
BOOST_CHECK_EQUAL(4U, well1->getConnections( 7 ).size() );
BOOST_CHECK_EQUAL(WellCompletion::SHUT, well1->getConnections( 7 ).get( 3 ).state() );
BOOST_CHECK_EQUAL(WellCompletion::OPEN, connections.get(3).state());
BOOST_CHECK_EQUAL(2.2836805555555556e-12 , connections.get(3).CF());
}
{
const auto& connections = sched.getWell2("W_1", 7).getConnections();
BOOST_CHECK_EQUAL(4U, connections.size() );
BOOST_CHECK_EQUAL(WellCompletion::SHUT, connections.get( 3 ).state() );
}
}
}
@ -549,41 +474,6 @@ BOOST_AUTO_TEST_CASE( WellTestGroupAndWellRelation ) {
}
BOOST_AUTO_TEST_CASE(WellTestWELSPECSDataLoaded) {
Parser parser;
std::string scheduleFile(pathprefix() + "SCHEDULE/SCHEDULE_WELLS2");
auto deck = parser.parseFile(scheduleFile);
EclipseGrid grid(40,60,30);
TableManager table ( deck );
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Runspec runspec (deck);
Schedule sched(deck, grid , eclipseProperties, runspec);
BOOST_CHECK_EQUAL(4U, sched.numWells());
BOOST_CHECK(sched.hasWell("W_1"));
BOOST_CHECK(sched.hasWell("W_2"));
BOOST_CHECK(sched.hasWell("W_3"));
{
const auto* well1 = sched.getWell("W_1");
BOOST_CHECK(!well1->hasBeenDefined(2));
BOOST_CHECK(well1->hasBeenDefined(3));
BOOST_CHECK_EQUAL(29, well1->getHeadI());
BOOST_CHECK_EQUAL(36, well1->getHeadJ());
const auto* well2 = sched.getWell("W_2");
BOOST_CHECK(!well2->hasBeenDefined(2));
BOOST_CHECK(well2->hasBeenDefined(3));
BOOST_CHECK_EQUAL(19, well2->getHeadI());
BOOST_CHECK_EQUAL(50, well2->getHeadJ());
const auto* well3 = sched.getWell("W_3");
BOOST_CHECK(!well3->hasBeenDefined(2));
BOOST_CHECK(well3->hasBeenDefined(3));
BOOST_CHECK_EQUAL(30, well3->getHeadI());
BOOST_CHECK_EQUAL(17, well3->getHeadJ());
}
}
/*
BOOST_AUTO_TEST_CASE(WellTestWELOPEN_ConfigWithIndexes_Throws) {
Parser parser;
@ -623,23 +513,23 @@ BOOST_AUTO_TEST_CASE(WellTestWGRUPCONWellPropertiesSet) {
Runspec runspec (deck);
Schedule sched(deck, grid , eclipseProperties, runspec);
const auto* well1 = sched.getWell("W_1");
BOOST_CHECK(well1->isAvailableForGroupControl(0));
BOOST_CHECK_EQUAL(-1, well1->getGuideRate(0));
BOOST_CHECK_EQUAL(GuideRate::OIL, well1->getGuideRatePhase(0));
BOOST_CHECK_EQUAL(1.0, well1->getGuideRateScalingFactor(0));
const auto& well1 = sched.getWell2("W_1", 0);
BOOST_CHECK(well1.isAvailableForGroupControl( ));
BOOST_CHECK_EQUAL(-1, well1.getGuideRate( ));
BOOST_CHECK_EQUAL(GuideRate::OIL, well1.getGuideRatePhase( ));
BOOST_CHECK_EQUAL(1.0, well1.getGuideRateScalingFactor( ));
const auto* well2 = sched.getWell("W_2");
BOOST_CHECK(!well2->isAvailableForGroupControl(0));
BOOST_CHECK_EQUAL(-1, well2->getGuideRate(0));
BOOST_CHECK_EQUAL(GuideRate::UNDEFINED, well2->getGuideRatePhase(0));
BOOST_CHECK_EQUAL(1.0, well2->getGuideRateScalingFactor(0));
const auto& well2 = sched.getWell2("W_2", 0);
BOOST_CHECK(!well2.isAvailableForGroupControl( ));
BOOST_CHECK_EQUAL(-1, well2.getGuideRate( ));
BOOST_CHECK_EQUAL(GuideRate::UNDEFINED, well2.getGuideRatePhase( ));
BOOST_CHECK_EQUAL(1.0, well2.getGuideRateScalingFactor( ));
const auto* well3 = sched.getWell("W_3");
BOOST_CHECK(well3->isAvailableForGroupControl(0));
BOOST_CHECK_EQUAL(100, well3->getGuideRate(0));
BOOST_CHECK_EQUAL(GuideRate::RAT, well3->getGuideRatePhase(0));
BOOST_CHECK_EQUAL(0.5, well3->getGuideRateScalingFactor(0));
const auto& well3 = sched.getWell2("W_3", 0);
BOOST_CHECK(well3.isAvailableForGroupControl( ));
BOOST_CHECK_EQUAL(100, well3.getGuideRate( ));
BOOST_CHECK_EQUAL(GuideRate::RAT, well3.getGuideRatePhase( ));
BOOST_CHECK_EQUAL(0.5, well3.getGuideRateScalingFactor( ));
}
@ -670,8 +560,7 @@ COMPDAT \n\
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Runspec runspec (deck);
Schedule sched(deck, grid , eclipseProperties, runspec);
const auto* well = sched.getWell("W1");
const auto& connections = well->getConnections(0);
const auto& connections = sched.getWell2("W1", 0).getConnections();
BOOST_CHECK_EQUAL( 10 , connections.get(0).getI() );
BOOST_CHECK_EQUAL( 20 , connections.get(0).getJ() );
}
@ -705,18 +594,22 @@ BOOST_AUTO_TEST_CASE(WELLS_SHUT) {
Schedule sched(deck, grid , eclipseProperties, runspec);
const auto* well1 = sched.getWell("W1");
const auto* well2 = sched.getWell("W2");
const auto* well3 = sched.getWell("W3");
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well1->getStatus(1));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well2->getStatus(1));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well3->getStatus(1));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well1->getStatus(2));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well2->getStatus(2));
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well3->getStatus(2));
{
const auto& well1 = sched.getWell2("W1", 1);
const auto& well2 = sched.getWell2("W2", 1);
const auto& well3 = sched.getWell2("W3", 1);
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well1.getStatus());
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well2.getStatus());
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::OPEN , well3.getStatus());
}
{
const auto& well1 = sched.getWell2("W1", 2);
const auto& well2 = sched.getWell2("W2", 2);
const auto& well3 = sched.getWell2("W3", 2);
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well1.getStatus());
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well2.getStatus());
BOOST_CHECK_EQUAL( WellCommon::StatusEnum::SHUT , well3.getStatus());
}
}
@ -735,36 +628,53 @@ BOOST_AUTO_TEST_CASE(WellTestWPOLYMER) {
BOOST_CHECK(sched.hasWell("INJE01"));
BOOST_CHECK(sched.hasWell("PROD01"));
const auto* well1 = sched.getWell("INJE01");
BOOST_CHECK( well1->isInjector(0));
{
const WellPolymerProperties& props_well10 = well1->getPolymerProperties(0);
const auto& well1 = sched.getWell2("INJE01", 0);
BOOST_CHECK( well1.isInjector());
const WellPolymerProperties& props_well10 = well1.getPolymerProperties();
BOOST_CHECK_CLOSE(1.5*Metric::PolymerDensity, props_well10.m_polymerConcentration, 0.0001);
const WellPolymerProperties& props_well11 = well1->getPolymerProperties(1);
}
{
const auto& well1 = sched.getWell2("INJE01", 1);
const WellPolymerProperties& props_well11 = well1.getPolymerProperties();
BOOST_CHECK_CLOSE(1.0*Metric::PolymerDensity, props_well11.m_polymerConcentration, 0.0001);
const WellPolymerProperties& props_well12 = well1->getPolymerProperties(2);
}
{
const auto& well1 = sched.getWell2("INJE01", 2);
const WellPolymerProperties& props_well12 = well1.getPolymerProperties();
BOOST_CHECK_CLOSE(0.1*Metric::PolymerDensity, props_well12.m_polymerConcentration, 0.0001);
}
const auto* well2 = sched.getWell("INJE02");
BOOST_CHECK( well2->isInjector(0));
{
const WellPolymerProperties& props_well20 = well2->getPolymerProperties(0);
const auto& well2 = sched.getWell2("INJE02", 0);
BOOST_CHECK( well2.isInjector());
const WellPolymerProperties& props_well20 = well2.getPolymerProperties();
BOOST_CHECK_CLOSE(2.0*Metric::PolymerDensity, props_well20.m_polymerConcentration, 0.0001);
const WellPolymerProperties& props_well21 = well2->getPolymerProperties(1);
}
{
const auto& well2 = sched.getWell2("INJE02", 1);
const WellPolymerProperties& props_well21 = well2.getPolymerProperties();
BOOST_CHECK_CLOSE(1.5*Metric::PolymerDensity, props_well21.m_polymerConcentration, 0.0001);
const WellPolymerProperties& props_well22 = well2->getPolymerProperties(2);
}
{
const auto& well2 = sched.getWell2("INJE02", 2);
const WellPolymerProperties& props_well22 = well2.getPolymerProperties();
BOOST_CHECK_CLOSE(0.2*Metric::PolymerDensity, props_well22.m_polymerConcentration, 0.0001);
}
const auto* well3 = sched.getWell("INJE03");
BOOST_CHECK( well3->isInjector(0));
{
const WellPolymerProperties& props_well30 = well3->getPolymerProperties(0);
const auto& well3 = sched.getWell2("INJE03", 0);
BOOST_CHECK( well3.isInjector());
const WellPolymerProperties& props_well30 = well3.getPolymerProperties();
BOOST_CHECK_CLOSE(2.5*Metric::PolymerDensity, props_well30.m_polymerConcentration, 0.0001);
const WellPolymerProperties& props_well31 = well3->getPolymerProperties(1);
}
{
const auto& well3 = sched.getWell2("INJE03", 1);
const WellPolymerProperties& props_well31 = well3.getPolymerProperties();
BOOST_CHECK_CLOSE(2.0*Metric::PolymerDensity, props_well31.m_polymerConcentration, 0.0001);
const WellPolymerProperties& props_well32 = well3->getPolymerProperties(2);
}
{
const auto& well3 = sched.getWell2("INJE03", 2);
const WellPolymerProperties& props_well32 = well3.getPolymerProperties();
BOOST_CHECK_CLOSE(0.3*Metric::PolymerDensity, props_well32.m_polymerConcentration, 0.0001);
}
}
@ -785,9 +695,8 @@ BOOST_AUTO_TEST_CASE(WellTestWECON) {
BOOST_CHECK(sched.hasWell("PROD01"));
BOOST_CHECK(sched.hasWell("PROD02"));
const auto* prod1 = sched.getWell("PROD01");
{
const WellEconProductionLimits& econ_limit1 = prod1->getEconProductionLimits(0);
const WellEconProductionLimits& econ_limit1 = sched.getWell2("PROD01", 0).getEconLimits();
BOOST_CHECK(econ_limit1.onMinOilRate());
BOOST_CHECK(econ_limit1.onMaxWaterCut());
BOOST_CHECK(!(econ_limit1.onMinGasRate()));
@ -809,7 +718,7 @@ BOOST_AUTO_TEST_CASE(WellTestWECON) {
BOOST_CHECK(econ_limit1.onAnyRateLimit());
BOOST_CHECK(econ_limit1.onAnyEffectiveLimit());
const WellEconProductionLimits& econ_limit2 = prod1->getEconProductionLimits(1);
const WellEconProductionLimits& econ_limit2 = sched.getWell2("PROD01", 1).getEconLimits();
BOOST_CHECK(!(econ_limit2.onMinOilRate()));
BOOST_CHECK(econ_limit2.onMaxWaterCut());
BOOST_CHECK(econ_limit2.onMinGasRate());
@ -832,9 +741,8 @@ BOOST_AUTO_TEST_CASE(WellTestWECON) {
BOOST_CHECK(econ_limit2.onAnyEffectiveLimit());
}
const auto* prod2 = sched.getWell("PROD02");
{
const WellEconProductionLimits& econ_limit1 = prod2->getEconProductionLimits(0);
const WellEconProductionLimits& econ_limit1 = sched.getWell2("PROD02", 0).getEconLimits();
BOOST_CHECK(!(econ_limit1.onMinOilRate()));
BOOST_CHECK(!(econ_limit1.onMaxWaterCut()));
BOOST_CHECK(!(econ_limit1.onMinGasRate()));
@ -856,7 +764,7 @@ BOOST_AUTO_TEST_CASE(WellTestWECON) {
BOOST_CHECK(!(econ_limit1.onAnyRateLimit()));
BOOST_CHECK(!(econ_limit1.onAnyEffectiveLimit()));
const WellEconProductionLimits& econ_limit2 = prod2->getEconProductionLimits(1);
const WellEconProductionLimits& econ_limit2 = sched.getWell2("PROD02", 1).getEconLimits();
BOOST_CHECK(!(econ_limit2.onMinOilRate()));
BOOST_CHECK(econ_limit2.onMaxWaterCut());
BOOST_CHECK(econ_limit2.onMinGasRate());
@ -925,14 +833,11 @@ BOOST_AUTO_TEST_CASE(TestWellEvents) {
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Runspec runspec(deck);
Schedule sched(deck , grid , eclipseProperties, runspec);
const auto& w1 = sched.getWell( "W_1");
const auto& w2 = sched.getWell( "W_2");
BOOST_CHECK( sched.hasWellEvent( "W_1", ScheduleEvents::NEW_WELL , 0 ));
BOOST_CHECK( sched.hasWellEvent( "W_2", ScheduleEvents::NEW_WELL , 2 ));
BOOST_CHECK( sched.hasWellEvent( "W_1", ScheduleEvents::NEW_WELL , 0 ));
BOOST_CHECK( sched.hasWellEvent( "W_2", ScheduleEvents::NEW_WELL , 2 ));
BOOST_CHECK( !sched.hasWellEvent( "W_2", ScheduleEvents::NEW_WELL , 3 ));
BOOST_CHECK( sched.hasWellEvent( "W_2", ScheduleEvents::WELL_WELSPECS_UPDATE , 3 ));
BOOST_CHECK( sched.hasWellEvent( "W_2", ScheduleEvents::WELL_WELSPECS_UPDATE , 3 ));
BOOST_CHECK( sched.hasWellEvent( "W_1", ScheduleEvents::WELL_STATUS_CHANGE , 0 ));
BOOST_CHECK( sched.hasWellEvent( "W_1", ScheduleEvents::WELL_STATUS_CHANGE , 1 ));
@ -942,7 +847,4 @@ BOOST_AUTO_TEST_CASE(TestWellEvents) {
BOOST_CHECK( sched.hasWellEvent( "W_1", ScheduleEvents::COMPLETION_CHANGE , 0 ));
BOOST_CHECK( sched.hasWellEvent( "W_1", ScheduleEvents::COMPLETION_CHANGE , 5 ));
BOOST_CHECK_EQUAL( w1->firstTimeStep( ) , 0 );
BOOST_CHECK_EQUAL( w2->firstTimeStep( ) , 2 );
}

View File

@ -553,7 +553,7 @@ BOOST_AUTO_TEST_CASE (Declared_Connection_Data)
const auto rptStep = std::size_t{1};
const auto ih = MockIH {
static_cast<int>(simCase.sched.getWells(rptStep).size())
static_cast<int>(simCase.sched.getWells2(rptStep).size())
};
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{2});

View File

@ -492,7 +492,7 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data)
const auto rptStep = std::size_t{1};
const auto ih = MockIH {
static_cast<int>(simCase.sched.getWells(rptStep).size())
static_cast<int>(simCase.sched.getWells2(rptStep).size())
};
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{4});

View File

@ -619,7 +619,7 @@ BOOST_AUTO_TEST_CASE (Declared_MSW_Data)
const auto rptStep = std::size_t{1};
const auto ih = MockIH {
static_cast<int>(simCase.sched.getWells(rptStep).size())
static_cast<int>(simCase.sched.getWells2(rptStep).size())
};
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{2});

View File

@ -380,7 +380,7 @@ BOOST_AUTO_TEST_CASE (Declared_Well_Data)
const auto rptStep = std::size_t{1};
const auto ih = MockIH {
static_cast<int>(simCase.sched.getWells(rptStep).size())
static_cast<int>(simCase.sched.getWells2(rptStep).size())
};
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{2});
@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
const auto rptStep = std::size_t{1};
const auto ih = MockIH {
static_cast<int>(simCase.sched.getWells(rptStep).size())
static_cast<int>(simCase.sched.getWells2(rptStep).size())
};
const auto xw = well_rates_1();
@ -638,7 +638,7 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
const auto rptStep = std::size_t{2};
const auto ih = MockIH {
static_cast<int>(simCase.sched.getWells(rptStep).size())
static_cast<int>(simCase.sched.getWells2(rptStep).size())
};
const auto xw = well_rates_2();

View File

@ -30,7 +30,6 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>

View File

@ -34,7 +34,6 @@
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Utility/Functional.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>

View File

@ -299,7 +299,6 @@ void compare(const SummaryState& st, const ecl_sum_type * ecl_sum, int tstep) {
BOOST_AUTO_TEST_SUITE(Summary)
/*
* Tests works by reading the Deck, write the summary output, then immediately
* read it again (with ERT), and compare the read values with the input.

View File

@ -29,7 +29,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
@ -54,32 +53,39 @@ void verifyWellState(const std::string& rst_filename,
int numwells = well_info_get_num_wells(well_info);
BOOST_CHECK_EQUAL( numwells, schedule.numWells() );
auto wells = schedule.getWells();
auto wells = schedule.getWells2atEnd();
for (int i = 0; i < numwells; ++i) {
//Verify wellnames
const char * wellname = well_info_iget_well_name(well_info, i);
auto* well = wells.at(i);
BOOST_CHECK_EQUAL( wellname, well->name() );
// Verify well-head position data
well_ts_type* well_ts = well_info_get_ts(well_info , wellname);
well_state_type* well_state = well_ts_iget_state(well_ts, 0);
const well_conn_type* well_head = well_state_get_wellhead(well_state, ECL_GRID_GLOBAL_GRID);
BOOST_CHECK_EQUAL(well_conn_get_i(well_head), well->getHeadI());
BOOST_CHECK_EQUAL(well_conn_get_j(well_head), well->getHeadJ());
{
const auto& sched_well = wells.at(i);
BOOST_CHECK_EQUAL( wellname, sched_well.name() );
// Verify well-head position data
const well_conn_type* well_head = well_state_get_wellhead(well_state, ECL_GRID_GLOBAL_GRID);
BOOST_CHECK_EQUAL(well_conn_get_i(well_head), sched_well.getHeadI());
BOOST_CHECK_EQUAL(well_conn_get_j(well_head), sched_well.getHeadJ());
}
for (int j = 0; j < well_ts_get_size(well_ts); ++j) {
const auto& well_at_end = schedule.getWell2atEnd(wellname);
if (!well_at_end.hasBeenDefined(j))
continue;
const auto& well = schedule.getWell2(wellname, j);
well_state = well_ts_iget_state(well_ts, j);
//Verify welltype
int well_type = ERT_UNDOCUMENTED_ZERO;
if( well->isProducer( j ) ) {
if( well.isProducer( ) ) {
well_type = ERT_PRODUCER;
}
else {
switch( well->getInjectionProperties( j ).injectorType ) {
switch( well.getInjectionProperties( ).injectorType ) {
case WellInjector::WATER:
well_type = ERT_WATER_INJECTOR;
break;
@ -99,7 +105,7 @@ void verifyWellState(const std::string& rst_filename,
//Verify wellstatus
int ert_well_status = well_state_is_open(well_state) ? 1 : 0;
int wellstatus = well->getStatus( j ) == WellCommon::OPEN ? 1 : 0;
int wellstatus = well.getStatus( ) == WellCommon::OPEN ? 1 : 0;
BOOST_CHECK_EQUAL(ert_well_status, wellstatus);
@ -107,8 +113,7 @@ void verifyWellState(const std::string& rst_filename,
const well_conn_collection_type * well_connections = well_state_get_global_connections( well_state );
size_t num_wellconnections = well_conn_collection_get_size(well_connections);
int report_nr = well_state_get_report_nr(well_state);
const auto& connections_set = well->getConnections((size_t)report_nr);
const auto& connections_set = well.getConnections();
BOOST_CHECK_EQUAL(num_wellconnections, connections_set.size());