mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Add support for COMPLUMP in WECON and WTEST
This commit is contained in:
@@ -191,7 +191,7 @@ namespace Opm {
|
|||||||
|
|
||||||
well_container.reserve(wellsForTesting.size());
|
well_container.reserve(wellsForTesting.size());
|
||||||
for (auto& testWell : wellsForTesting) {
|
for (auto& testWell : wellsForTesting) {
|
||||||
const std::string msg = std::string("well ") + testWell.first + std::string(" will be tested");
|
const std::string msg = std::string("well ") + testWell.first + std::string(" is tested");
|
||||||
OpmLog::info(msg);
|
OpmLog::info(msg);
|
||||||
|
|
||||||
// finding the location of the well in wells_ecl
|
// finding the location of the well in wells_ecl
|
||||||
@@ -225,8 +225,6 @@ namespace Opm {
|
|||||||
const int well_cell_top = wells()->well_cells[wells()->well_connpos[wellidx]];
|
const int well_cell_top = wells()->well_cells[wells()->well_connpos[wellidx]];
|
||||||
const int pvtreg = pvt_region_idx_[well_cell_top];
|
const int pvtreg = pvt_region_idx_[well_cell_top];
|
||||||
|
|
||||||
//WellInterface<TypeTag> well(well_ecl, timeStepIdx, wells(), param_, *rateConverter_, pvtreg, numComponents() );
|
|
||||||
|
|
||||||
if ( !well_ecl->isMultiSegment(timeStepIdx) || !param_.use_multisegment_well_) {
|
if ( !well_ecl->isMultiSegment(timeStepIdx) || !param_.use_multisegment_well_) {
|
||||||
well_container.emplace_back(new StandardWell<TypeTag>(well_ecl, timeStepIdx, wells(),
|
well_container.emplace_back(new StandardWell<TypeTag>(well_ecl, timeStepIdx, wells(),
|
||||||
param_, *rateConverter_, pvtreg, numComponents() ) );
|
param_, *rateConverter_, pvtreg, numComponents() ) );
|
||||||
@@ -238,25 +236,37 @@ namespace Opm {
|
|||||||
|
|
||||||
for (auto& well : well_container) {
|
for (auto& well : well_container) {
|
||||||
WellTestState wellTestStateForTheWellTest;
|
WellTestState wellTestStateForTheWellTest;
|
||||||
|
WellState wellStateCopy = well_state_;
|
||||||
well->init(&phase_usage_, depth_, gravity_, number_of_cells_);
|
well->init(&phase_usage_, depth_, gravity_, number_of_cells_);
|
||||||
const std::string well_name = well->name();
|
const std::string well_name = well->name();
|
||||||
const WellNode& well_node = wellCollection().findWellNode(well_name);
|
const WellNode& well_node = wellCollection().findWellNode(well_name);
|
||||||
const double well_efficiency_factor = well_node.getAccumulativeEfficiencyFactor();
|
const double well_efficiency_factor = well_node.getAccumulativeEfficiencyFactor();
|
||||||
well->setWellEfficiencyFactor(well_efficiency_factor);
|
well->setWellEfficiencyFactor(well_efficiency_factor);
|
||||||
well->setVFPProperties(vfp_properties_.get());
|
well->setVFPProperties(vfp_properties_.get());
|
||||||
well->updatePrimaryVariables(well_state_);
|
well->updatePrimaryVariables(wellStateCopy);
|
||||||
well->initPrimaryVariablesEvaluation();
|
well->initPrimaryVariablesEvaluation();
|
||||||
well->solveWellEq(ebosSimulator_, well_state_, /*dt (not relevant for well test) =*/ 1.0, B_avg, terminal_output_);
|
|
||||||
well->updateListEconLimited(well_state_, simulationTime, wellTestStateForTheWellTest);
|
bool testWell = true;
|
||||||
|
while (testWell) {
|
||||||
|
size_t numberOfClosedCompletions = wellTestStateForTheWellTest.sizeCompletions();
|
||||||
|
well->solveWellEq(ebosSimulator_, wellStateCopy, /*dt (not relevant for well test) =*/ 1.0, B_avg, terminal_output_);
|
||||||
|
well->updateListEconLimited(wellStateCopy, simulationTime, wellTestStateForTheWellTest, /*writeMessageToOPMLog=*/ false);
|
||||||
|
well->closeWellsAndCompletions(wellTestStateForTheWellTest);
|
||||||
|
|
||||||
|
// test completions individually.
|
||||||
|
if (numberOfClosedCompletions == wellTestStateForTheWellTest.sizeCompletions())
|
||||||
|
testWell = false;
|
||||||
|
}
|
||||||
|
|
||||||
// update wellTestState if the well test succeeds
|
// update wellTestState if the well test succeeds
|
||||||
if (!wellTestStateForTheWellTest.hasWell(well->name(), WellTestConfig::Reason::ECONOMIC)) {
|
if (!wellTestStateForTheWellTest.hasWell(well->name(), WellTestConfig::Reason::ECONOMIC)) {
|
||||||
wellTestState_.openWell(well->name());
|
wellTestState_.openWell(well->name());
|
||||||
const std::string msg = std::string("well ") + well->name() + std::string(" is re-opened");
|
const std::string msg = std::string("well ") + well->name() + std::string(" is re-opened");
|
||||||
OpmLog::info(msg);
|
OpmLog::info(msg);
|
||||||
// also reopen completions
|
// also reopen completions
|
||||||
for (int completionIdx = 0; completionIdx <well->numberOfCompletions(); ++completionIdx) {
|
for (auto& completion : well->wellEcl()->getCompletions(timeStepIdx)) {
|
||||||
if (!wellTestStateForTheWellTest.hasCompletion(well->name(), completionIdx))
|
if (!wellTestStateForTheWellTest.hasCompletion(well->name(), completion.first))
|
||||||
wellTestState_.dropCompletion(well->name(), completionIdx);
|
wellTestState_.dropCompletion(well->name(), completion.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -748,7 +758,7 @@ namespace Opm {
|
|||||||
updateListEconLimited(const double& simulationTime, WellTestState& wellTestState) const
|
updateListEconLimited(const double& simulationTime, WellTestState& wellTestState) const
|
||||||
{
|
{
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
well->updateListEconLimited(well_state_, simulationTime, wellTestState);
|
well->updateListEconLimited(well_state_, simulationTime, wellTestState, /*writeMessageToOPMLog=*/ true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1570,7 +1570,6 @@ namespace Opm
|
|||||||
for ( int compIdx = 0; compIdx < num_components_; ++compIdx )
|
for ( int compIdx = 0; compIdx < num_components_; ++compIdx )
|
||||||
{
|
{
|
||||||
report.converged = report.converged && (well_flux_residual[compIdx] < tol_wells) && control_eq_converged;
|
report.converged = report.converged && (well_flux_residual[compIdx] < tol_wells) && control_eq_converged;
|
||||||
//std::cout << name() << " " << well_flux_residual[compIdx] << std::endl;
|
|
||||||
}
|
}
|
||||||
} else { // abnormal values found and no need to check the convergence
|
} else { // abnormal values found and no need to check the convergence
|
||||||
report.converged = false;
|
report.converged = false;
|
||||||
|
|||||||
@@ -179,7 +179,8 @@ namespace Opm
|
|||||||
|
|
||||||
void updateListEconLimited(const WellState& well_state,
|
void updateListEconLimited(const WellState& well_state,
|
||||||
const double& simulationTime,
|
const double& simulationTime,
|
||||||
WellTestState& wellTestState) const;
|
WellTestState& wellTestState,
|
||||||
|
const bool& writeMessageToOPMLog) const;
|
||||||
|
|
||||||
void setWellEfficiencyFactor(const double efficiency_factor);
|
void setWellEfficiencyFactor(const double efficiency_factor);
|
||||||
|
|
||||||
@@ -228,8 +229,7 @@ namespace Opm
|
|||||||
|
|
||||||
void closeWellsAndCompletions(WellTestState& wellTestState);
|
void closeWellsAndCompletions(WellTestState& wellTestState);
|
||||||
|
|
||||||
#warning currently just return number of connections
|
const Well* wellEcl() const { return well_ecl_;}
|
||||||
int numberOfCompletions(){ return number_of_perforations_;}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -348,6 +348,7 @@ namespace Opm
|
|||||||
|
|
||||||
double scalingFactor(const int comp_idx) const;
|
double scalingFactor(const int comp_idx) const;
|
||||||
|
|
||||||
|
int numberOfCompletions() const { return well_ecl_->getCompletions(current_step_).size();}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ namespace Opm
|
|||||||
saturation_table_number_.begin() );
|
saturation_table_number_.begin() );
|
||||||
}
|
}
|
||||||
well_efficiency_factor_ = 1.0;
|
well_efficiency_factor_ = 1.0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -538,24 +537,34 @@ namespace Opm
|
|||||||
water_cut_perf[perf] = 0.;
|
water_cut_perf[perf] = 0.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const auto& completions = well_ecl_->getCompletions(current_step_);
|
||||||
|
const auto& connections = well_ecl_->getConnections(current_step_);
|
||||||
|
|
||||||
last_connection = (perf_number == 1);
|
int complnumIdx = 0;
|
||||||
if (last_connection) {
|
std::vector<double> water_cut_in_completions(numberOfCompletions(), 0.0);
|
||||||
worst_offending_connection = 0;
|
for (const auto& completion : completions) {
|
||||||
violation_extent = water_cut_perf[0] / max_water_cut_limit;
|
int complnum = completion.first;
|
||||||
return std::make_tuple(water_cut_limit_violated, last_connection, worst_offending_connection, violation_extent);
|
for (int perf = 0; perf < perf_number; ++perf) {
|
||||||
|
if (complnum == connections.get ( perf ).complnum) {
|
||||||
|
water_cut_in_completions[complnumIdx] += water_cut_perf[perf];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
complnumIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_connection = false;
|
||||||
|
|
||||||
double max_water_cut_perf = 0.;
|
double max_water_cut_perf = 0.;
|
||||||
for (int perf = 0; perf < perf_number; ++perf) {
|
complnumIdx = 0;
|
||||||
if (water_cut_perf[perf] > max_water_cut_perf) {
|
for (const auto& completion : completions) {
|
||||||
worst_offending_connection = perf;
|
if (water_cut_in_completions[complnumIdx] > max_water_cut_perf) {
|
||||||
max_water_cut_perf = water_cut_perf[perf];
|
worst_offending_connection = completion.first;
|
||||||
|
max_water_cut_perf = water_cut_in_completions[complnumIdx];
|
||||||
}
|
}
|
||||||
|
complnumIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(max_water_cut_perf != 0.);
|
assert(max_water_cut_limit != 0.);
|
||||||
assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number));
|
|
||||||
|
|
||||||
violation_extent = max_water_cut_perf / max_water_cut_limit;
|
violation_extent = max_water_cut_perf / max_water_cut_limit;
|
||||||
}
|
}
|
||||||
@@ -629,7 +638,8 @@ namespace Opm
|
|||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
updateListEconLimited(const WellState& well_state,
|
updateListEconLimited(const WellState& well_state,
|
||||||
const double& simulationTime,
|
const double& simulationTime,
|
||||||
WellTestState& wellTestState) const
|
WellTestState& wellTestState,
|
||||||
|
const bool& writeMessageToOPMLog) const
|
||||||
{
|
{
|
||||||
// economic limits only apply for production wells.
|
// economic limits only apply for production wells.
|
||||||
if (wellType() != PRODUCER) {
|
if (wellType() != PRODUCER) {
|
||||||
@@ -672,12 +682,14 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, simulationTime);
|
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, simulationTime);
|
||||||
if (well_ecl_->getAutomaticShutIn()) {
|
if (writeMessageToOPMLog) {
|
||||||
const std::string msg = std::string("well ") + well_name + std::string(" will be shut due to rate economic limit");
|
if (well_ecl_->getAutomaticShutIn()) {
|
||||||
OpmLog::info(msg);
|
const std::string msg = std::string("well ") + well_name + std::string(" will be shut due to rate economic limit");
|
||||||
} else {
|
OpmLog::info(msg);
|
||||||
const std::string msg = std::string("well ") + well_name + std::string(" will be stopped due to rate economic limit");
|
} else {
|
||||||
OpmLog::info(msg);
|
const std::string msg = std::string("well ") + well_name + std::string(" will be stopped due to rate economic limit");
|
||||||
|
OpmLog::info(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// the well is closed, not need to check other limits
|
// the well is closed, not need to check other limits
|
||||||
return;
|
return;
|
||||||
@@ -699,23 +711,30 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
const int worst_offending_connection = std::get<2>(ratio_check_return);
|
const int worst_offending_connection = std::get<2>(ratio_check_return);
|
||||||
|
|
||||||
assert((worst_offending_connection >= 0) && (worst_offending_connection < number_of_perforations_));
|
|
||||||
#warning map to completions
|
|
||||||
wellTestState.addClosedCompletion(well_name, worst_offending_connection, simulationTime);
|
wellTestState.addClosedCompletion(well_name, worst_offending_connection, simulationTime);
|
||||||
const std::string msg = std::string("Connection ") + std::to_string(worst_offending_connection) + std::string(" for well ")
|
if (writeMessageToOPMLog) {
|
||||||
+ well_name + std::string(" will be closed due to economic limit");
|
if (worst_offending_connection < 0) {
|
||||||
OpmLog::info(msg);
|
const std::string msg = std::string("Connection ") + std::to_string(- worst_offending_connection) + std::string(" for well ")
|
||||||
|
+ well_name + std::string(" will be closed due to economic limit");
|
||||||
|
OpmLog::info(msg);
|
||||||
|
} else {
|
||||||
|
const std::string msg = std::string("Completion ") + std::to_string(worst_offending_connection) + std::string(" for well ")
|
||||||
|
+ well_name + std::string(" will be closed due to economic limit");
|
||||||
|
OpmLog::info(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool allCompletionsClosed = true;
|
bool allCompletionsClosed = true;
|
||||||
for (int perf = 0; perf < number_of_perforations_ ; ++perf) {
|
const auto& connections = well_ecl_->getConnections(current_step_);
|
||||||
if (!wellTestState.hasCompletion(name(), perf)) {
|
for (const auto& connection : connections) {
|
||||||
|
if (!wellTestState.hasCompletion(name(), connection.complnum)) {
|
||||||
allCompletionsClosed = false;
|
allCompletionsClosed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allCompletionsClosed) {
|
if (allCompletionsClosed) {
|
||||||
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, simulationTime);
|
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, simulationTime);
|
||||||
|
if (writeMessageToOPMLog) {
|
||||||
if (well_ecl_->getAutomaticShutIn()) {
|
if (well_ecl_->getAutomaticShutIn()) {
|
||||||
const std::string msg = well_name + std::string(" will be shut due to last compleation closed");
|
const std::string msg = well_name + std::string(" will be shut due to last compleation closed");
|
||||||
OpmLog::info(msg);
|
OpmLog::info(msg);
|
||||||
@@ -723,12 +742,14 @@ namespace Opm
|
|||||||
const std::string msg = well_name + std::string(" will be stopped due to last compleation closed");
|
const std::string msg = well_name + std::string(" will be stopped due to last compleation closed");
|
||||||
OpmLog::info(msg);
|
OpmLog::info(msg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WellEcon::WELL:
|
case WellEcon::WELL:
|
||||||
{
|
{
|
||||||
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, 0);
|
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, 0);
|
||||||
|
if (writeMessageToOPMLog) {
|
||||||
if (well_ecl_->getAutomaticShutIn()) {
|
if (well_ecl_->getAutomaticShutIn()) {
|
||||||
// tell the controll that the well is closed
|
// tell the controll that the well is closed
|
||||||
const std::string msg = well_name + std::string(" will be shut due to ratio economic limit");
|
const std::string msg = well_name + std::string(" will be shut due to ratio economic limit");
|
||||||
@@ -737,6 +758,7 @@ namespace Opm
|
|||||||
const std::string msg = well_name + std::string(" will be stopped due to ratio economic limit");
|
const std::string msg = well_name + std::string(" will be stopped due to ratio economic limit");
|
||||||
OpmLog::info(msg);
|
OpmLog::info(msg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WellEcon::NONE:
|
case WellEcon::NONE:
|
||||||
@@ -895,10 +917,13 @@ namespace Opm
|
|||||||
well_controls_stop_well(wellControls());
|
well_controls_stop_well(wellControls());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int perf = 0; perf < number_of_perforations_ ; ++perf) {
|
const auto& connections = well_ecl_->getConnections(current_step_);
|
||||||
if (wellTestState.hasCompletion(name(), perf)) {
|
int perfIdx = 0;
|
||||||
well_index_[perf] = 0.0;
|
for (const auto& connection : connections) {
|
||||||
|
if (wellTestState.hasCompletion(name(), connection.complnum)) {
|
||||||
|
well_index_[perfIdx] = 0.0;
|
||||||
}
|
}
|
||||||
|
perfIdx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user