Merge pull request #2115 from joakim-hove/all-connections-inactive
Automatically shut wells with no connections
This commit is contained in:
commit
b8179b943d
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
|
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
|
||||||
@ -400,7 +401,7 @@ namespace Opm
|
|||||||
void updateGroup(std::shared_ptr<Group> group, std::size_t reportStep);
|
void updateGroup(std::shared_ptr<Group> group, std::size_t reportStep);
|
||||||
bool checkGroups(const ParseContext& parseContext, ErrorGuard& errors);
|
bool checkGroups(const ParseContext& parseContext, ErrorGuard& errors);
|
||||||
void updateUDQActive( std::size_t timeStep, std::shared_ptr<UDQActive> udq );
|
void updateUDQActive( std::size_t timeStep, std::shared_ptr<UDQActive> udq );
|
||||||
bool updateWellStatus( const std::string& well, std::size_t reportStep , Well::Status status, bool update_connections);
|
bool updateWellStatus( const std::string& well, std::size_t reportStep , Well::Status status, bool update_connections, std::optional<KeywordLocation> = {});
|
||||||
void addWellToGroup( const std::string& group_name, const std::string& well_name , std::size_t timeStep);
|
void addWellToGroup( const std::string& group_name, const std::string& well_name , std::size_t timeStep);
|
||||||
void iterateScheduleSection(std::shared_ptr<const Python> python, const std::string& input_path, const ParseContext& parseContext , ErrorGuard& errors, const SCHEDULESection& , const EclipseGrid& grid,
|
void iterateScheduleSection(std::shared_ptr<const Python> python, const std::string& input_path, const ParseContext& parseContext , ErrorGuard& errors, const SCHEDULESection& , const EclipseGrid& grid,
|
||||||
const FieldPropsManager& fp);
|
const FieldPropsManager& fp);
|
||||||
|
@ -541,7 +541,7 @@ public:
|
|||||||
bool updateRefDepth(const std::optional<double>& ref_dpeth);
|
bool updateRefDepth(const std::optional<double>& ref_dpeth);
|
||||||
bool updateDrainageRadius(double drainage_radius);
|
bool updateDrainageRadius(double drainage_radius);
|
||||||
void updateSegments(std::shared_ptr<WellSegments> segments_arg);
|
void updateSegments(std::shared_ptr<WellSegments> segments_arg);
|
||||||
bool updateConnections(std::shared_ptr<WellConnections> connections);
|
bool updateConnections(std::shared_ptr<WellConnections> connections, bool force = false);
|
||||||
bool updateConnections(std::shared_ptr<WellConnections> connections, const EclipseGrid& grid, const std::vector<int>& pvtnum);
|
bool updateConnections(std::shared_ptr<WellConnections> connections, const EclipseGrid& grid, const std::vector<int>& pvtnum);
|
||||||
bool updateStatus(Status status, bool update_connections);
|
bool updateStatus(Status status, bool update_connections);
|
||||||
bool updateGroup(const std::string& group);
|
bool updateGroup(const std::string& group);
|
||||||
@ -567,8 +567,6 @@ public:
|
|||||||
bool handleCOMPLUMP(const DeckRecord& record);
|
bool handleCOMPLUMP(const DeckRecord& record);
|
||||||
bool handleWPIMULT(const DeckRecord& record);
|
bool handleWPIMULT(const DeckRecord& record);
|
||||||
|
|
||||||
void forceUpdateConnections(std::shared_ptr<WellConnections> connections_arg);
|
|
||||||
|
|
||||||
void filterConnections(const ActiveGridCells& grid);
|
void filterConnections(const ActiveGridCells& grid);
|
||||||
ProductionControls productionControls(const SummaryState& st) const;
|
ProductionControls productionControls(const SummaryState& st) const;
|
||||||
InjectionControls injectionControls(const SummaryState& st) const;
|
InjectionControls injectionControls(const SummaryState& st) const;
|
||||||
|
@ -35,6 +35,7 @@ namespace Opm {
|
|||||||
class DeckRecord;
|
class DeckRecord;
|
||||||
class EclipseGrid;
|
class EclipseGrid;
|
||||||
class FieldPropsManager;
|
class FieldPropsManager;
|
||||||
|
class KeywordLocation;
|
||||||
class WellConnections {
|
class WellConnections {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ namespace Opm {
|
|||||||
const Connection::CTFKind ctf_kind = Connection::CTFKind::DeckValue,
|
const Connection::CTFKind ctf_kind = Connection::CTFKind::DeckValue,
|
||||||
const std::size_t seqIndex = 0,
|
const std::size_t seqIndex = 0,
|
||||||
const bool defaultSatTabId = true);
|
const bool defaultSatTabId = true);
|
||||||
void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const FieldPropsManager& field_properties);
|
void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const FieldPropsManager& field_properties, const KeywordLocation& location);
|
||||||
|
|
||||||
using const_iterator = std::vector< Connection >::const_iterator;
|
using const_iterator = std::vector< Connection >::const_iterator;
|
||||||
|
|
||||||
@ -154,7 +155,8 @@ namespace Opm {
|
|||||||
const std::vector<double>* permx,
|
const std::vector<double>* permx,
|
||||||
const std::vector<double>* permy,
|
const std::vector<double>* permy,
|
||||||
const std::vector<double>* permz,
|
const std::vector<double>* permz,
|
||||||
const std::vector<double>& ntg);
|
const std::vector<double>& ntg,
|
||||||
|
const KeywordLocation& location);
|
||||||
|
|
||||||
size_t findClosestConnection(int oi, int oj, double oz, size_t start_pos);
|
size_t findClosestConnection(int oi, int oj, double oz, size_t start_pos);
|
||||||
void orderTRACK();
|
void orderTRACK();
|
||||||
|
@ -153,11 +153,19 @@ namespace {
|
|||||||
for (const auto& name : wellnames) {
|
for (const auto& name : wellnames) {
|
||||||
auto well2 = std::shared_ptr<Well>(new Well( this->getWell(name, handlerContext.currentStep)));
|
auto well2 = std::shared_ptr<Well>(new Well( this->getWell(name, handlerContext.currentStep)));
|
||||||
auto connections = std::shared_ptr<WellConnections>( new WellConnections( well2->getConnections()));
|
auto connections = std::shared_ptr<WellConnections>( new WellConnections( well2->getConnections()));
|
||||||
connections->loadCOMPDAT(record, handlerContext.grid, handlerContext.fieldPropsManager);
|
connections->loadCOMPDAT(record, handlerContext.grid, handlerContext.fieldPropsManager, handlerContext.keyword.location());
|
||||||
if (well2->updateConnections(connections, handlerContext.grid, handlerContext.fieldPropsManager.get_int("PVTNUM"))) {
|
if (well2->updateConnections(connections, handlerContext.grid, handlerContext.fieldPropsManager.get_int("PVTNUM"))) {
|
||||||
this->updateWell(std::move(well2), handlerContext.currentStep);
|
this->updateWell(std::move(well2), handlerContext.currentStep);
|
||||||
wells.insert( name );
|
wells.insert( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connections->empty() && well2->getConnections().empty()) {
|
||||||
|
const auto& location = handlerContext.keyword.location();
|
||||||
|
auto msg = fmt::format("Problem with COMPDAT/{}\n"
|
||||||
|
"In {} line {}\n"
|
||||||
|
"Well {} is not connected to grid - will remain SHUT", name, location.filename, location.lineno, name);
|
||||||
|
OpmLog::warning(msg);
|
||||||
|
}
|
||||||
this->addWellGroupEvent(name, ScheduleEvents::COMPLETION_CHANGE, handlerContext.currentStep);
|
this->addWellGroupEvent(name, ScheduleEvents::COMPLETION_CHANGE, handlerContext.currentStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,6 +218,16 @@ namespace {
|
|||||||
|
|
||||||
auto& dynamic_state = this->wells_static.at(well_name);
|
auto& dynamic_state = this->wells_static.at(well_name);
|
||||||
auto well_ptr = std::make_shared<Well>( *dynamic_state[handlerContext.currentStep] );
|
auto well_ptr = std::make_shared<Well>( *dynamic_state[handlerContext.currentStep] );
|
||||||
|
|
||||||
|
if (well_ptr->getConnections().empty()) {
|
||||||
|
const auto& location = handlerContext.keyword.location();
|
||||||
|
auto msg = fmt::format("Problem with COMPSEGS/{0}\n"
|
||||||
|
"In {1} line {2}\n"
|
||||||
|
"Well {0} is not connected to grid - COMPSEGS will be ignored", well_name, location.filename, location.lineno);
|
||||||
|
OpmLog::warning(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (well_ptr->handleCOMPSEGS(handlerContext.keyword, handlerContext.grid, parseContext, errors))
|
if (well_ptr->handleCOMPSEGS(handlerContext.keyword, handlerContext.grid, parseContext, errors))
|
||||||
this->updateWell(std::move(well_ptr), handlerContext.currentStep);
|
this->updateWell(std::move(well_ptr), handlerContext.currentStep);
|
||||||
}
|
}
|
||||||
@ -852,7 +870,7 @@ namespace {
|
|||||||
const Well::Status status = Well::StatusFromString(record.getItem("STATUS").getTrimmedString(0));
|
const Well::Status status = Well::StatusFromString(record.getItem("STATUS").getTrimmedString(0));
|
||||||
|
|
||||||
for (const auto& well_name : well_names) {
|
for (const auto& well_name : well_names) {
|
||||||
updateWellStatus( well_name , handlerContext.currentStep , status, false );
|
this->updateWellStatus( well_name , handlerContext.currentStep , status, false, handlerContext.keyword.location() );
|
||||||
|
|
||||||
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
||||||
std::optional<VFPProdTable::ALQ_TYPE> alq_type;
|
std::optional<VFPProdTable::ALQ_TYPE> alq_type;
|
||||||
@ -901,7 +919,7 @@ namespace {
|
|||||||
"Well " + well2->name() + " is a history matched well with zero rate where crossflow is banned. " +
|
"Well " + well2->name() + " is a history matched well with zero rate where crossflow is banned. " +
|
||||||
"This well will be closed at " + std::to_string(m_timeMap.getTimePassedUntil(handlerContext.currentStep) / (60*60*24)) + " days";
|
"This well will be closed at " + std::to_string(m_timeMap.getTimePassedUntil(handlerContext.currentStep) / (60*60*24)) + " days";
|
||||||
OpmLog::note(msg);
|
OpmLog::note(msg);
|
||||||
updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
this->updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -918,7 +936,7 @@ namespace {
|
|||||||
const Well::Status status = Well::StatusFromString(record.getItem("STATUS").getTrimmedString(0));
|
const Well::Status status = Well::StatusFromString(record.getItem("STATUS").getTrimmedString(0));
|
||||||
|
|
||||||
for (const auto& well_name : well_names) {
|
for (const auto& well_name : well_names) {
|
||||||
updateWellStatus(well_name, handlerContext.currentStep, status, false);
|
this->updateWellStatus(well_name, handlerContext.currentStep, status, false, handlerContext.keyword.location());
|
||||||
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
||||||
std::optional<VFPProdTable::ALQ_TYPE> alq_type;
|
std::optional<VFPProdTable::ALQ_TYPE> alq_type;
|
||||||
auto& dynamic_state = this->wells_static.at(well_name);
|
auto& dynamic_state = this->wells_static.at(well_name);
|
||||||
@ -969,7 +987,7 @@ namespace {
|
|||||||
const Well::Status status = Well::StatusFromString(record.getItem("STATUS").getTrimmedString(0));
|
const Well::Status status = Well::StatusFromString(record.getItem("STATUS").getTrimmedString(0));
|
||||||
|
|
||||||
for (const auto& well_name : well_names) {
|
for (const auto& well_name : well_names) {
|
||||||
updateWellStatus(well_name, handlerContext.currentStep, status, false);
|
this->updateWellStatus(well_name, handlerContext.currentStep, status, false, handlerContext.keyword.location());
|
||||||
|
|
||||||
bool update_well = false;
|
bool update_well = false;
|
||||||
auto& dynamic_state = this->wells_static.at(well_name);
|
auto& dynamic_state = this->wells_static.at(well_name);
|
||||||
@ -1002,14 +1020,14 @@ namespace {
|
|||||||
if (injection->surfaceInjectionRate.is<double>()) {
|
if (injection->surfaceInjectionRate.is<double>()) {
|
||||||
if (injection->hasInjectionControl(Well::InjectorCMode::RATE) && injection->surfaceInjectionRate.zero()) {
|
if (injection->hasInjectionControl(Well::InjectorCMode::RATE) && injection->surfaceInjectionRate.zero()) {
|
||||||
OpmLog::note(msg);
|
OpmLog::note(msg);
|
||||||
updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
this->updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (injection->reservoirInjectionRate.is<double>()) {
|
if (injection->reservoirInjectionRate.is<double>()) {
|
||||||
if (injection->hasInjectionControl(Well::InjectorCMode::RESV) && injection->reservoirInjectionRate.zero()) {
|
if (injection->hasInjectionControl(Well::InjectorCMode::RESV) && injection->reservoirInjectionRate.zero()) {
|
||||||
OpmLog::note(msg);
|
OpmLog::note(msg);
|
||||||
updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
this->updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1031,7 +1049,7 @@ namespace {
|
|||||||
const Well::Status status = Well::StatusFromString( record.getItem("STATUS").getTrimmedString(0));
|
const Well::Status status = Well::StatusFromString( record.getItem("STATUS").getTrimmedString(0));
|
||||||
|
|
||||||
for (const auto& well_name : well_names) {
|
for (const auto& well_name : well_names) {
|
||||||
updateWellStatus(well_name, handlerContext.currentStep, status, false);
|
this->updateWellStatus(well_name, handlerContext.currentStep, status, false, handlerContext.keyword.location());
|
||||||
|
|
||||||
bool update_well = false;
|
bool update_well = false;
|
||||||
auto& dynamic_state = this->wells_static.at(well_name);
|
auto& dynamic_state = this->wells_static.at(well_name);
|
||||||
@ -1059,7 +1077,7 @@ namespace {
|
|||||||
"Well " + well_name + " is an injector with zero rate where crossflow is banned. " +
|
"Well " + well_name + " is an injector with zero rate where crossflow is banned. " +
|
||||||
"This well will be closed at " + std::to_string ( m_timeMap.getTimePassedUntil(handlerContext.currentStep) / (60*60*24) ) + " days";
|
"This well will be closed at " + std::to_string ( m_timeMap.getTimePassedUntil(handlerContext.currentStep) / (60*60*24) ) + " days";
|
||||||
OpmLog::note(msg);
|
OpmLog::note(msg);
|
||||||
updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
this->updateWellStatus( well_name, handlerContext.currentStep, Well::Status::SHUT, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1140,7 +1158,7 @@ namespace {
|
|||||||
// Well::updateWellProductivityIndex() implicitly mutates
|
// Well::updateWellProductivityIndex() implicitly mutates
|
||||||
// internal state in the WellConnections class.
|
// internal state in the WellConnections class.
|
||||||
auto connections = std::make_shared<WellConnections>(well2->getConnections());
|
auto connections = std::make_shared<WellConnections>(well2->getConnections());
|
||||||
well2->forceUpdateConnections(std::move(connections));
|
well2->updateConnections(std::move(connections), true);
|
||||||
if (well2->updateWellProductivityIndex(rawProdIndex))
|
if (well2->updateWellProductivityIndex(rawProdIndex))
|
||||||
this->updateWell(std::move(well2), report_step);
|
this->updateWell(std::move(well2), report_step);
|
||||||
|
|
||||||
|
@ -594,10 +594,21 @@ private:
|
|||||||
Function is quite dangerous - because if this is called while holding a
|
Function is quite dangerous - because if this is called while holding a
|
||||||
Well pointer that will go stale and needs to be refreshed.
|
Well pointer that will go stale and needs to be refreshed.
|
||||||
*/
|
*/
|
||||||
bool Schedule::updateWellStatus( const std::string& well_name, std::size_t reportStep , Well::Status status, bool update_connections) {
|
bool Schedule::updateWellStatus( const std::string& well_name, std::size_t reportStep , Well::Status status, bool update_connections, std::optional<KeywordLocation> location) {
|
||||||
bool update = false;
|
|
||||||
auto& dynamic_state = this->wells_static.at(well_name);
|
auto& dynamic_state = this->wells_static.at(well_name);
|
||||||
auto well2 = std::make_shared<Well>(*dynamic_state[reportStep]);
|
auto well2 = std::make_shared<Well>(*dynamic_state[reportStep]);
|
||||||
|
if (well2->getConnections().empty() && status == Well::Status::OPEN) {
|
||||||
|
if (location) {
|
||||||
|
auto msg = fmt::format("Problem with{}\n",
|
||||||
|
"In {} line{}\n"
|
||||||
|
"Well {} has no connections to grid and will remain SHUT", location->keyword, location->filename, location->lineno, well_name);
|
||||||
|
OpmLog::warning(msg);
|
||||||
|
} else
|
||||||
|
OpmLog::warning(fmt::format("Well {} has no connections to grid and will remain SHUT", well_name));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update = false;
|
||||||
if (well2->updateStatus(status, update_connections)) {
|
if (well2->updateStatus(status, update_connections)) {
|
||||||
m_events.addEvent( ScheduleEvents::WELL_STATUS_CHANGE, reportStep );
|
m_events.addEvent( ScheduleEvents::WELL_STATUS_CHANGE, reportStep );
|
||||||
this->addWellGroupEvent( well2->name(), ScheduleEvents::WELL_STATUS_CHANGE, reportStep);
|
this->addWellGroupEvent( well2->name(), ScheduleEvents::WELL_STATUS_CHANGE, reportStep);
|
||||||
|
@ -688,13 +688,15 @@ bool Well::updateAutoShutin(bool auto_shutin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Well::updateConnections(std::shared_ptr<WellConnections> connections_arg) {
|
bool Well::updateConnections(std::shared_ptr<WellConnections> connections_arg, bool force) {
|
||||||
connections_arg->order( );
|
connections_arg->order( );
|
||||||
if (*this->connections != *connections_arg) {
|
if (force || *this->connections != *connections_arg) {
|
||||||
this->connections = connections_arg;
|
this->connections = connections_arg;
|
||||||
|
if (this->connections->empty())
|
||||||
|
this->status = Status::SHUT;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,7 +722,7 @@ bool Well::updateSolventFraction(double solvent_fraction_arg) {
|
|||||||
|
|
||||||
|
|
||||||
bool Well::handleCOMPSEGS(const DeckKeyword& keyword, const EclipseGrid& grid,
|
bool Well::handleCOMPSEGS(const DeckKeyword& keyword, const EclipseGrid& grid,
|
||||||
const ParseContext& parseContext, ErrorGuard& errors) {
|
const ParseContext& parseContext, ErrorGuard& errors) {
|
||||||
auto [new_connections, new_segments] = Compsegs::processCOMPSEGS(keyword, *this->connections, *this->segments , grid,
|
auto [new_connections, new_segments] = Compsegs::processCOMPSEGS(keyword, *this->connections, *this->segments , grid,
|
||||||
parseContext, errors);
|
parseContext, errors);
|
||||||
|
|
||||||
@ -1145,10 +1147,6 @@ bool Well::updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Well::forceUpdateConnections(std::shared_ptr<WellConnections> connections_arg) {
|
|
||||||
connections_arg->order();
|
|
||||||
this->connections = std::move(connections_arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Well::filterConnections(const ActiveGridCells& grid) {
|
void Well::filterConnections(const ActiveGridCells& grid) {
|
||||||
this->connections->filter(grid);
|
this->connections->filter(grid);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||||
#include <opm/io/eclipse/rst/connection.hpp>
|
#include <opm/io/eclipse/rst/connection.hpp>
|
||||||
|
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
|
||||||
@ -270,14 +271,14 @@ inline std::array< size_t, 3> directionIndices(const Opm::Connection::Direction
|
|||||||
defaultSatTabId);
|
defaultSatTabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellConnections::loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const FieldPropsManager& field_properties) {
|
void WellConnections::loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const FieldPropsManager& field_properties, const KeywordLocation& location) {
|
||||||
const auto permx = field_properties.try_get<double>("PERMX");
|
const auto permx = field_properties.try_get<double>("PERMX");
|
||||||
const auto permy = field_properties.try_get<double>("PERMY");
|
const auto permy = field_properties.try_get<double>("PERMY");
|
||||||
const auto permz = field_properties.try_get<double>("PERMZ");
|
const auto permz = field_properties.try_get<double>("PERMZ");
|
||||||
const auto& ntg = field_properties.get_double("NTG");
|
const auto& ntg = field_properties.get_double("NTG");
|
||||||
const auto& satnum_data = field_properties.get_int("SATNUM");
|
const auto& satnum_data = field_properties.get_int("SATNUM");
|
||||||
|
|
||||||
this->loadCOMPDAT(record, grid, satnum_data, permx, permy, permz, ntg);
|
this->loadCOMPDAT(record, grid, satnum_data, permx, permy, permz, ntg, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellConnections::loadCOMPDAT(const DeckRecord& record,
|
void WellConnections::loadCOMPDAT(const DeckRecord& record,
|
||||||
@ -286,7 +287,8 @@ inline std::array< size_t, 3> directionIndices(const Opm::Connection::Direction
|
|||||||
const std::vector<double>* permx,
|
const std::vector<double>* permx,
|
||||||
const std::vector<double>* permy,
|
const std::vector<double>* permy,
|
||||||
const std::vector<double>* permz,
|
const std::vector<double>* permz,
|
||||||
const std::vector<double>& ntg) {
|
const std::vector<double>& ntg,
|
||||||
|
const KeywordLocation& location) {
|
||||||
|
|
||||||
const auto& itemI = record.getItem( "I" );
|
const auto& itemI = record.getItem( "I" );
|
||||||
const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0;
|
const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0;
|
||||||
@ -326,8 +328,13 @@ inline std::array< size_t, 3> directionIndices(const Opm::Connection::Direction
|
|||||||
rw = 0.5*unit::feet;
|
rw = 0.5*unit::feet;
|
||||||
|
|
||||||
for (int k = K1; k <= K2; k++) {
|
for (int k = K1; k <= K2; k++) {
|
||||||
if (!grid.cellActive(I, J, k))
|
if (!grid.cellActive(I, J, k)) {
|
||||||
|
auto msg = fmt::format("Problem with COMPDAT keyword\n"
|
||||||
|
"In {} line {}\n"
|
||||||
|
"The cell ({},{},{}) is not active and the connection will be ignored", location.filename, location.lineno, I,J,k);
|
||||||
|
OpmLog::warning(msg);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
size_t active_index = grid.activeIndex(I,J,k);
|
size_t active_index = grid.activeIndex(I,J,k);
|
||||||
double CF = -1;
|
double CF = -1;
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
|
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
||||||
|
|
||||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ Opm::WellConnections loadCOMPDAT(const std::string& compdat_keyword) {
|
|||||||
const auto& keyword = deck.getKeyword("COMPDAT", 0);
|
const auto& keyword = deck.getKeyword("COMPDAT", 0);
|
||||||
Opm::WellConnections connections(Opm::Connection::Order::TRACK, 10,10);
|
Opm::WellConnections connections(Opm::Connection::Order::TRACK, 10,10);
|
||||||
for (const auto& rec : keyword)
|
for (const auto& rec : keyword)
|
||||||
connections.loadCOMPDAT(rec, grid, field_props);
|
connections.loadCOMPDAT(rec, grid, field_props, {});
|
||||||
|
|
||||||
return connections;
|
return connections;
|
||||||
}
|
}
|
||||||
|
@ -1343,7 +1343,7 @@ END
|
|||||||
"P and Q must have the same internal connections pointers");
|
"P and Q must have the same internal connections pointers");
|
||||||
|
|
||||||
auto connQ = std::make_shared<WellConnections>(wellP.getConnections());
|
auto connQ = std::make_shared<WellConnections>(wellP.getConnections());
|
||||||
wellQ.forceUpdateConnections(std::move(connQ));
|
wellQ.updateConnections(std::move(connQ), true);
|
||||||
BOOST_CHECK_MESSAGE(! wellP.hasSameConnectionsPointers(wellQ),
|
BOOST_CHECK_MESSAGE(! wellP.hasSameConnectionsPointers(wellQ),
|
||||||
"P and Q must NOT have the same internal connections pointers "
|
"P and Q must NOT have the same internal connections pointers "
|
||||||
"after forcibly updating the connections structure");
|
"after forcibly updating the connections structure");
|
||||||
|
Loading…
Reference in New Issue
Block a user