Add support for COMPLUMP in WECON and WTEST

This commit is contained in:
Tor Harald Sandve 2018-06-28 13:28:30 +02:00
parent 0f4038342d
commit 834f680587
4 changed files with 80 additions and 45 deletions

View File

@ -191,7 +191,7 @@ namespace Opm {
well_container.reserve(wellsForTesting.size());
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);
// 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 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_) {
well_container.emplace_back(new StandardWell<TypeTag>(well_ecl, timeStepIdx, wells(),
param_, *rateConverter_, pvtreg, numComponents() ) );
@ -238,25 +236,37 @@ namespace Opm {
for (auto& well : well_container) {
WellTestState wellTestStateForTheWellTest;
WellState wellStateCopy = well_state_;
well->init(&phase_usage_, depth_, gravity_, number_of_cells_);
const std::string well_name = well->name();
const WellNode& well_node = wellCollection().findWellNode(well_name);
const double well_efficiency_factor = well_node.getAccumulativeEfficiencyFactor();
well->setWellEfficiencyFactor(well_efficiency_factor);
well->setVFPProperties(vfp_properties_.get());
well->updatePrimaryVariables(well_state_);
well->updatePrimaryVariables(wellStateCopy);
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
if (!wellTestStateForTheWellTest.hasWell(well->name(), WellTestConfig::Reason::ECONOMIC)) {
wellTestState_.openWell(well->name());
const std::string msg = std::string("well ") + well->name() + std::string(" is re-opened");
OpmLog::info(msg);
// also reopen completions
for (int completionIdx = 0; completionIdx <well->numberOfCompletions(); ++completionIdx) {
if (!wellTestStateForTheWellTest.hasCompletion(well->name(), completionIdx))
wellTestState_.dropCompletion(well->name(), completionIdx);
for (auto& completion : well->wellEcl()->getCompletions(timeStepIdx)) {
if (!wellTestStateForTheWellTest.hasCompletion(well->name(), completion.first))
wellTestState_.dropCompletion(well->name(), completion.first);
}
}
}
@ -748,7 +758,7 @@ namespace Opm {
updateListEconLimited(const double& simulationTime, WellTestState& wellTestState) const
{
for (const auto& well : well_container_) {
well->updateListEconLimited(well_state_, simulationTime, wellTestState);
well->updateListEconLimited(well_state_, simulationTime, wellTestState, /*writeMessageToOPMLog=*/ true);
}
}

View File

@ -1570,7 +1570,6 @@ namespace Opm
for ( int compIdx = 0; compIdx < num_components_; ++compIdx )
{
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
report.converged = false;

View File

@ -179,7 +179,8 @@ namespace Opm
void updateListEconLimited(const WellState& well_state,
const double& simulationTime,
WellTestState& wellTestState) const;
WellTestState& wellTestState,
const bool& writeMessageToOPMLog) const;
void setWellEfficiencyFactor(const double efficiency_factor);
@ -228,8 +229,7 @@ namespace Opm
void closeWellsAndCompletions(WellTestState& wellTestState);
#warning currently just return number of connections
int numberOfCompletions(){ return number_of_perforations_;}
const Well* wellEcl() const { return well_ecl_;}
protected:
@ -348,6 +348,7 @@ namespace Opm
double scalingFactor(const int comp_idx) const;
int numberOfCompletions() const { return well_ecl_->getCompletions(current_step_).size();}
};

View File

@ -103,7 +103,6 @@ namespace Opm
saturation_table_number_.begin() );
}
well_efficiency_factor_ = 1.0;
}
@ -538,24 +537,34 @@ namespace Opm
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);
if (last_connection) {
worst_offending_connection = 0;
violation_extent = water_cut_perf[0] / max_water_cut_limit;
return std::make_tuple(water_cut_limit_violated, last_connection, worst_offending_connection, violation_extent);
int complnumIdx = 0;
std::vector<double> water_cut_in_completions(numberOfCompletions(), 0.0);
for (const auto& completion : completions) {
int complnum = completion.first;
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.;
for (int perf = 0; perf < perf_number; ++perf) {
if (water_cut_perf[perf] > max_water_cut_perf) {
worst_offending_connection = perf;
max_water_cut_perf = water_cut_perf[perf];
complnumIdx = 0;
for (const auto& completion : completions) {
if (water_cut_in_completions[complnumIdx] > max_water_cut_perf) {
worst_offending_connection = completion.first;
max_water_cut_perf = water_cut_in_completions[complnumIdx];
}
complnumIdx++;
}
assert(max_water_cut_perf != 0.);
assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number));
assert(max_water_cut_limit != 0.);
violation_extent = max_water_cut_perf / max_water_cut_limit;
}
@ -629,7 +638,8 @@ namespace Opm
WellInterface<TypeTag>::
updateListEconLimited(const WellState& well_state,
const double& simulationTime,
WellTestState& wellTestState) const
WellTestState& wellTestState,
const bool& writeMessageToOPMLog) const
{
// economic limits only apply for production wells.
if (wellType() != PRODUCER) {
@ -672,12 +682,14 @@ namespace Opm
}
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, simulationTime);
if (well_ecl_->getAutomaticShutIn()) {
const std::string msg = std::string("well ") + well_name + std::string(" will be shut due to rate economic limit");
OpmLog::info(msg);
} else {
const std::string msg = std::string("well ") + well_name + std::string(" will be stopped due to rate economic limit");
OpmLog::info(msg);
if (writeMessageToOPMLog) {
if (well_ecl_->getAutomaticShutIn()) {
const std::string msg = std::string("well ") + well_name + std::string(" will be shut due to rate economic limit");
OpmLog::info(msg);
} else {
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
return;
@ -699,23 +711,30 @@ namespace Opm
{
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);
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);
if (writeMessageToOPMLog) {
if (worst_offending_connection < 0) {
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;
for (int perf = 0; perf < number_of_perforations_ ; ++perf) {
if (!wellTestState.hasCompletion(name(), perf)) {
const auto& connections = well_ecl_->getConnections(current_step_);
for (const auto& connection : connections) {
if (!wellTestState.hasCompletion(name(), connection.complnum)) {
allCompletionsClosed = false;
}
}
if (allCompletionsClosed) {
wellTestState.addClosedWell(well_name, WellTestConfig::Reason::ECONOMIC, simulationTime);
if (writeMessageToOPMLog) {
if (well_ecl_->getAutomaticShutIn()) {
const std::string msg = well_name + std::string(" will be shut due to last compleation closed");
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");
OpmLog::info(msg);
}
}
}
break;
}
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()) {
// tell the controll that the well is closed
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");
OpmLog::info(msg);
}
}
break;
}
case WellEcon::NONE:
@ -895,10 +917,13 @@ namespace Opm
well_controls_stop_well(wellControls());
}
for (int perf = 0; perf < number_of_perforations_ ; ++perf) {
if (wellTestState.hasCompletion(name(), perf)) {
well_index_[perf] = 0.0;
const auto& connections = well_ecl_->getConnections(current_step_);
int perfIdx = 0;
for (const auto& connection : connections) {
if (wellTestState.hasCompletion(name(), connection.complnum)) {
well_index_[perfIdx] = 0.0;
}
perfIdx++;
}
}