@@ -54,6 +54,15 @@ namespace Opm {
|
||||
AutoICD::serializeOp(serializer);
|
||||
}
|
||||
|
||||
double flowRateExponent() const;
|
||||
double viscExponent() const;
|
||||
double oilDensityExponent() const;
|
||||
double waterDensityExponent() const;
|
||||
double gasDensityExponent() const;
|
||||
double oilViscExponent() const;
|
||||
double waterViscExponent() const;
|
||||
double gasViscExponent() const;
|
||||
|
||||
private:
|
||||
double m_flow_rate_exponent;
|
||||
double m_visc_exponent;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
namespace Opm {
|
||||
class SICD;
|
||||
class AutoICD;
|
||||
class Valve;
|
||||
class WellConnections;
|
||||
}
|
||||
@@ -100,6 +101,7 @@ namespace Opm {
|
||||
bool updateWSEGSICD(const std::vector<std::pair<int, SICD> >& sicd_pairs);
|
||||
|
||||
bool updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs);
|
||||
bool updateWSEGAICD(const std::vector<std::pair<int, AutoICD> >& aicd_pairs, const KeywordLocation& location);
|
||||
const std::vector<Segment>::const_iterator begin() const;
|
||||
const std::vector<Segment>::const_iterator end() const;
|
||||
|
||||
|
||||
@@ -568,6 +568,7 @@ namespace Opm
|
||||
void handleWSALT (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
void handleWSEGITER (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
void handleWSEGSICD (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
void handleWSEGAICD (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
void handleWSEGVALV (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
void handleWSKPTAB (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
void handleWSOLVENT (const HandlerContext&, const ParseContext&, ErrorGuard&);
|
||||
|
||||
@@ -59,6 +59,7 @@ class DeckKeyword;
|
||||
class UDQActive;
|
||||
class UDQConfig;
|
||||
class SICD;
|
||||
class AutoICD;
|
||||
|
||||
namespace RestartIO {
|
||||
struct RstWell;
|
||||
@@ -560,6 +561,7 @@ public:
|
||||
bool updateWellProductivityIndex(const double prodIndex);
|
||||
bool updateWSEGSICD(const std::vector<std::pair<int, SICD> >& sicd_pairs);
|
||||
bool updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs);
|
||||
bool updateWSEGAICD(const std::vector<std::pair<int, AutoICD> >& aicd_pairs, const KeywordLocation& location);
|
||||
bool updateWPAVE(const PAvg& pavg);
|
||||
|
||||
bool handleWELSEGS(const DeckKeyword& keyword);
|
||||
|
||||
@@ -1652,6 +1652,29 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWSEGAICD(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
|
||||
std::map<std::string, std::vector<std::pair<int, AutoICD> > > auto_icds = AutoICD::fromWSEGAICD(handlerContext.keyword);
|
||||
|
||||
for (auto& [well_name_pattern, aicd_pairs] : auto_icds) {
|
||||
const auto well_names = this->wellNames(well_name_pattern, handlerContext.currentStep);
|
||||
|
||||
for (const auto& well_name : well_names) {
|
||||
auto& dynamic_state = this->wells_static.at(well_name);
|
||||
auto well_ptr = std::make_shared<Well>( *dynamic_state[handlerContext.currentStep] );
|
||||
|
||||
const auto& connections = well_ptr->getConnections();
|
||||
const auto& segments = well_ptr->getSegments();
|
||||
for (auto& [segment_nr, aicd] : aicd_pairs) {
|
||||
const auto& outlet_segment_length = segments.segmentLength( segments.getFromSegmentNumber(segment_nr).outletSegment() );
|
||||
aicd.updateScalingFactor(outlet_segment_length, connections.segment_perf_length(segment_nr));
|
||||
}
|
||||
|
||||
if (well_ptr->updateWSEGAICD(aicd_pairs, handlerContext.keyword.location()) )
|
||||
this->updateWell(std::move(well_ptr), handlerContext.currentStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWSEGVALV(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
|
||||
const std::map<std::string, std::vector<std::pair<int, Valve> > > valves = Valve::fromWSEGVALV(handlerContext.keyword);
|
||||
|
||||
@@ -1885,6 +1908,7 @@ namespace {
|
||||
{ "WSALT" , &Schedule::handleWSALT },
|
||||
{ "WSEGITER", &Schedule::handleWSEGITER },
|
||||
{ "WSEGSICD", &Schedule::handleWSEGSICD },
|
||||
{ "WSEGAICD", &Schedule::handleWSEGAICD },
|
||||
{ "WSEGVALV", &Schedule::handleWSEGVALV },
|
||||
{ "WSKPTAB" , &Schedule::handleWSKPTAB },
|
||||
{ "WSOLVENT", &Schedule::handleWSOLVENT },
|
||||
|
||||
@@ -66,4 +66,37 @@ bool AutoICD::operator==(const AutoICD& other) const {
|
||||
this->m_gas_viscosity_exponent == other.m_gas_viscosity_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::flowRateExponent() const {
|
||||
return this->m_flow_rate_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::viscExponent() const {
|
||||
return this->m_visc_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::oilDensityExponent() const {
|
||||
return this->m_oil_density_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::waterDensityExponent() const {
|
||||
return this->m_water_density_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::gasDensityExponent() const {
|
||||
return this->m_gas_density_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::oilViscExponent() const {
|
||||
return this->m_oil_viscosity_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::waterViscExponent() const {
|
||||
return this->m_water_viscosity_exponent;
|
||||
}
|
||||
|
||||
double AutoICD::gasViscExponent() const {
|
||||
return this->m_gas_viscosity_exponent;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
|
||||
@@ -545,6 +547,26 @@ namespace Opm {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WellSegments::updateWSEGAICD(const std::vector<std::pair<int, AutoICD> >& aicd_pairs, const KeywordLocation& location) {
|
||||
if (m_comp_pressure_drop == CompPressureDrop::H__) {
|
||||
const std::string msg = fmt::format("to use Autonomous ICD segment with keyword {} "
|
||||
"at line {} in file {},\n"
|
||||
"you have to activate frictional pressure drop calculation in WELSEGS",
|
||||
location.keyword, location.lineno, location.filename);
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
for (const auto& pair_elem : aicd_pairs) {
|
||||
const int segment_number = pair_elem.first;
|
||||
const AutoICD& auto_icd = pair_elem.second;
|
||||
Segment segment = this->getFromSegmentNumber(segment_number);
|
||||
segment.updateAutoICD(auto_icd);
|
||||
this->addSegment(segment);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WellSegments::operator!=( const WellSegments& rhs ) const {
|
||||
return !( *this == rhs );
|
||||
|
||||
@@ -1138,6 +1138,16 @@ bool Well::updateWSEGSICD(const std::vector<std::pair<int, SICD> >& sicd_pairs)
|
||||
}
|
||||
|
||||
|
||||
bool Well::updateWSEGAICD(const std::vector<std::pair<int, AutoICD> >& aicd_pairs, const KeywordLocation& location) {
|
||||
auto new_segments = std::make_shared<WellSegments>(*this->segments);
|
||||
if (new_segments->updateWSEGAICD(aicd_pairs, location)) {
|
||||
this->segments = new_segments;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Well::updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs) {
|
||||
auto new_segments = std::make_shared<WellSegments>(*this->segments);
|
||||
if (new_segments->updateWSEGVALV(valve_pairs)) {
|
||||
|
||||
Reference in New Issue
Block a user