From 18fa44272148fa388a4fa64d30d1e5a89ece88ec Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 27 Jun 2016 13:39:25 +0200 Subject: [PATCH 01/21] adapted to the interface change of WellsManager At the moment, for the ParallelDebugOutput, we put a dummy dyanmic_list_econ_limited, not sure how it will the parallel running. The basic problem is that when initialzing the globalWellState_, what will happen if they can not find state information for a well in the Wells*. If some defaulted values are used, then no big problem here. --- opm/autodiff/ParallelDebugOutput.hpp | 6 ++++++ opm/autodiff/SimulatorBase_impl.hpp | 3 +++ .../SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp | 2 ++ opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp | 6 +++++- tests/test_multisegmentwells.cpp | 5 +++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/opm/autodiff/ParallelDebugOutput.hpp b/opm/autodiff/ParallelDebugOutput.hpp index 9d29a76c3..bd81cfdc6 100644 --- a/opm/autodiff/ParallelDebugOutput.hpp +++ b/opm/autodiff/ParallelDebugOutput.hpp @@ -28,6 +28,7 @@ #include #include +#include #if HAVE_OPM_GRID #include @@ -523,6 +524,10 @@ namespace Opm if( isIORank() ) { Dune::CpGrid& globalGrid = *grid_; + // TODO: make a dummy DynamicListEconLimited here for NOW for compilation and development + // TODO: NOT SURE whether it will cause problem for parallel running + // TODO: TO BE TESTED AND IMPROVED + const DynamicListEconLimited dynamic_list_econ_limited; // Create wells and well state. WellsManager wells_manager(eclipseState_, reportStep, @@ -533,6 +538,7 @@ namespace Opm Opm::UgGridHelpers::cell2Faces( globalGrid ), Opm::UgGridHelpers::beginFaceCentroids( globalGrid ), permeability_, + dynamic_list_econ_limited, false); const Wells* wells = wells_manager.c_wells(); diff --git a/opm/autodiff/SimulatorBase_impl.hpp b/opm/autodiff/SimulatorBase_impl.hpp index 404bc2967..7f26ed3d3 100644 --- a/opm/autodiff/SimulatorBase_impl.hpp +++ b/opm/autodiff/SimulatorBase_impl.hpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace Opm { @@ -131,6 +132,7 @@ namespace Opm unsigned int totalLinearIterations = 0; bool is_well_potentials_computed = param_.getDefault("compute_well_potentials", false ); std::vector well_potentials; + DynamicListEconLimited dynamic_list_econ_limited; // Main simulation loop. while (!timer.done()) { @@ -153,6 +155,7 @@ namespace Opm Opm::UgGridHelpers::cell2Faces(grid_), Opm::UgGridHelpers::beginFaceCentroids(grid_), props_.permeability(), + dynamic_list_econ_limited, is_parallel_run_, well_potentials); const Wells* wells = wells_manager.c_wells(); diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp index ec9821b48..d98bca55b 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp @@ -89,6 +89,7 @@ namespace Opm unsigned int totalNonlinearIterations = 0; unsigned int totalLinearIterations = 0; + DynamicListEconLimited dynamic_list_econ_limited; // Main simulation loop. while (!timer.done()) { @@ -109,6 +110,7 @@ namespace Opm Opm::UgGridHelpers::cell2Faces(grid_), Opm::UgGridHelpers::beginFaceCentroids(grid_), props_.permeability(), + dynamic_list_econ_limited, is_parallel_run_); const Wells* wells = wells_manager.c_wells(); WellState well_state; diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp index 784d3f115..c1361468c 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -352,6 +353,8 @@ namespace Opm SimulationDataContainer& simulatorstate, WellStateFullyImplicitBlackoil& wellstate) { + // gives a dummy dynamic_list_econ_limited + DynamicListEconLimited dummy_list_econ_limited; WellsManager wellsmanager(eclipseState_, eclipseState_->getInitConfig()->getRestartStep(), Opm::UgGridHelpers::numCells(grid), @@ -360,7 +363,8 @@ namespace Opm Opm::UgGridHelpers::dimensions(grid), Opm::UgGridHelpers::cell2Faces(grid), Opm::UgGridHelpers::beginFaceCentroids(grid), - permeability); + permeability, + dummy_list_econ_limited); const Wells* wells = wellsmanager.c_wells(); wellstate.resize(wells, simulatorstate); //Resize for restart step diff --git a/tests/test_multisegmentwells.cpp b/tests/test_multisegmentwells.cpp index 1e6998256..fa43b58ca 100644 --- a/tests/test_multisegmentwells.cpp +++ b/tests/test_multisegmentwells.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,9 @@ struct SetupMSW { const size_t current_timestep = 0; + // dummy_dynamic_list_econ_lmited + const Opm::DynamicListEconLimited dummy_dynamic_list; + // Create wells. Opm::WellsManager wells_manager(ecl_state, current_timestep, @@ -101,6 +105,7 @@ struct SetupMSW { Opm::UgGridHelpers::cell2Faces(grid), Opm::UgGridHelpers::beginFaceCentroids(grid), fluidprops->permeability(), + dummy_dynamic_list, false); const Wells* wells = wells_manager.c_wells(); From 53490270e18f2ffbf46af5dcabc6eaa8afcf1641 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 27 Jun 2016 16:14:28 +0200 Subject: [PATCH 02/21] adding updateListEconLimited to StandardWells --- opm/autodiff/BlackoilModelBase.hpp | 8 ++-- opm/autodiff/SimulatorBase_impl.hpp | 2 + opm/autodiff/StandardWells.hpp | 12 +++++ opm/autodiff/StandardWells_impl.hpp | 73 +++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/opm/autodiff/BlackoilModelBase.hpp b/opm/autodiff/BlackoilModelBase.hpp index 181d5d8e1..c25bac544 100644 --- a/opm/autodiff/BlackoilModelBase.hpp +++ b/opm/autodiff/BlackoilModelBase.hpp @@ -255,6 +255,10 @@ namespace Opm { /// Update the scaling factors for mass balance equations void updateEquationsScaling(); + /// return the WellModel object + WellModel& wellModel() { return well_model_; } + const WellModel& wellModel() const { return well_model_; } + protected: // --------- Types and enums --------- @@ -333,10 +337,6 @@ namespace Opm { return static_cast(*this); } - /// return the WellModel object - WellModel& wellModel() { return well_model_; } - const WellModel& wellModel() const { return well_model_; } - /// return the Well struct in the WellModel const Wells& wells() const { return well_model_.wells(); } diff --git a/opm/autodiff/SimulatorBase_impl.hpp b/opm/autodiff/SimulatorBase_impl.hpp index 7f26ed3d3..51dc361e1 100644 --- a/opm/autodiff/SimulatorBase_impl.hpp +++ b/opm/autodiff/SimulatorBase_impl.hpp @@ -272,6 +272,8 @@ namespace Opm asImpl().computeWellPotentials(wells, well_state, well_potentials); } + solver->model().wellModel().updateListEconLimited(eclipse_state_->getSchedule(), timer.currentStepNum(), wells, + well_state, dynamic_list_econ_limited); } // Write final simulation state. output_writer_.writeTimeStep( timer, state, prev_well_state ); diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index 7b367f43a..2f3054f25 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -29,7 +29,10 @@ #include +#include + #include +#include #include #include #include @@ -170,6 +173,15 @@ namespace Opm { /// called. const Vector& getStoredWellPerforationFluxes() const; + /// upate the dynamic lists related to economic limits + template + void + updateListEconLimited(ScheduleConstPtr schedule, + const int current_step, + const Wells* wells, + const WellState& well_state, + DynamicListEconLimited& list_econ_limited) const; + protected: bool wells_active_; const Wells* wells_; diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index ccbea3c42..6079c0cab 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1248,4 +1248,77 @@ namespace Opm } + + + + + template + void + StandardWells:: + updateListEconLimited(ScheduleConstPtr schedule, + const int current_step, + const Wells* wells_struct, + const WellState& well_state, + DynamicListEconLimited& list_econ_limited) const + { + const int nw = wells_struct->number_of_wells; + const int np = wells_struct->number_of_phases; + + for (int w = 0; w < nw; ++w) { + // flag to check if the mim oil/gas rate limit is violated + bool rate_limit_violated = false; + const std::string& well_name = wells_struct->name[w]; + const Well* well_ecl = schedule->getWell(well_name); + const WellEconProductionLimits& econ_production_limits = well_ecl->getEconProductionLimits(current_step); + + // if no limit is effective here, then continue to the next well + if ( !econ_production_limits.onAnyEffectiveLimit() ) { + continue; + } + // for the moment, we only handle rate limits, not handling potential limits + // the potential limits should not be difficult to add + const WellEcon::QuantityLimitEnum quantity_limit = econ_production_limits.quantityLimit(); + if (quantity_limit == WellEcon::POTN) { + OPM_THROW(std::logic_error, "Only RATE limit is supported for the moment"); + } + + using MapEntryType = typename WellState::mapentry_t; + using WellMapType = typename WellState::WellMapType; + + const WellMapType& well_map = well_state.wellMap(); + typename WellMapType::const_iterator i = well_map.find(well_name); + + assert(i != well_map.end()); // should always be found? + + const int well_number = (i->second)[0]; + + const Opm::PhaseUsage& pu = fluid_->phaseUsage(); + + // oil rate limit + // TODO: SHOULD we give a message when closing a well due to economic limit reason? + if (econ_production_limits.onMinOilRate()) { + assert((*active_)[Oil]); + const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; + const double min_oil_rate = econ_production_limits.minOilRate(); + if (std::abs(oil_rate) < min_oil_rate) { + rate_limit_violated = true; + } + } + // gas rate limit + if (econ_production_limits.onMinGasRate()) { + assert((*active_)[Gas]); + const double gas_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Gas ] ]; + const double min_gas_rate = econ_production_limits.minGasRate(); + if (std::abs(gas_rate) < min_gas_rate) { + rate_limit_violated = true; + } + } + + if (rate_limit_violated) { + list_econ_limited.addShuttedWell(well_name); + } + } + } + + } // namespace Opm From e903690107d4cde915911631ad2705fdca87cea4 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 10:44:56 +0200 Subject: [PATCH 03/21] giving a warning if the WECON request ending running It is not supported yet to stop the whole program after a well is closed due to economic limits. --- opm/autodiff/StandardWells_impl.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 6079c0cab..0a45a5bce 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1315,6 +1315,11 @@ namespace Opm } if (rate_limit_violated) { + if (econ_production_limits.endRun()) { + std::cerr << "WARNING: ending run after well closed due to economic limits is not supported yet" + << std::endl + << "the program will keep running after " << well_name << " is closed " << std::endl; + } list_econ_limited.addShuttedWell(well_name); } } From a0194602688261bf8e0c0dbf1547a4aca5da6e72 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 10:52:05 +0200 Subject: [PATCH 04/21] warning if requesting opening a new well after closing a well it is not supported yet. --- opm/autodiff/StandardWells_impl.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 0a45a5bce..8ce60db64 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1320,6 +1320,11 @@ namespace Opm << std::endl << "the program will keep running after " << well_name << " is closed " << std::endl; } + + if (econ_production_limits.validFollowonWell()) { + std::cerr << "WARNING: opening following on well after well closed is not supported yet" << std::endl; + } + list_econ_limited.addShuttedWell(well_name); } } From d48399ac3a90aac9088c92a8cbdef979d2b7743d Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 15:14:10 +0200 Subject: [PATCH 05/21] WIP for handling the water cut ecnomic limit --- opm/autodiff/StandardWells_impl.hpp | 66 +++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 8ce60db64..9a525edf9 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1326,7 +1326,73 @@ namespace Opm } list_econ_limited.addShuttedWell(well_name); + // the well is closed, not need to check other limits + continue; } + + // checking for other limits, mostly all kinds of ratio. + // TODO: not sure when more than one ratio limit is violated, what is the definition of the + // worst-offending connection + // Should not be more than one connection be closed each time + // Maybe we can compare the extent of the different violations to give a worst one. + bool water_cut_limit_violated = false; + if (econ_production_limits.onMaxWaterCut()) { + assert((*active_)[Oil]); + assert((*active_)[Water]); + const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; + const double water_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Water ] ]; + const double liquid_rate = oil_rate + water_rate; + if (std::abs(liquid_rate) == 0.) { + continue; + } + const double water_cut = water_rate / liquid_rate; + const double max_water_cut = econ_production_limits.maxWaterCut(); + if (water_cut > max_water_cut) { + water_cut_limit_violated = true; + } + } + + if (econ_production_limits.workover() != WellEcon::CON) { + std::cerr << "WARNING: only CON workover over exceeding limit is supported for the moment." << std::endl; + } + + const int perf_start = (i->second)[1]; + const int perf_number = (i->second)[2]; + + std::vector oil_perf_rate(perf_number); + std::vector gas_perf_rate(perf_number); + std::vector water_perf_rate(perf_number); + + for (int perf = 0; perf < perf_number; ++perf) { + const int i_perf = perf_start + perf; + oil_perf_rate[perf] = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Oil ] ]; + water_perf_rate[perf] = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Water ] ]; + gas_perf_rate[perf] = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Gas ] ]; + } + + std::vector water_cut_perf(perf_number); + double max_water_cut_perf = 0.0; + int worst_offending_perf = -1; + for (int perf = 0; perf < perf_number; ++perf) { + const double liquid_rate = water_perf_rate[perf] + oil_perf_rate[perf]; + if (std::abs(liquid_rate) == 0.0) { + water_cut_perf[perf] = 0.0; + } else { + water_cut_perf[perf] = water_perf_rate[perf] / liquid_rate; + } + + if (water_cut_perf[perf] > max_water_cut_perf) { + worst_offending_perf = perf; + max_water_cut_perf = water_cut_perf[perf]; + } + } + + assert((worst_offending_perf >= 0) && (worst_offending_perf <= perf_number)); + + const int cell_worst_offending_perf = wells_struct->well_cells[perf_start + worst_offending_perf]; + + list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_perf); + } } From c77aa5af095f31988bc3e24e37f4b7e22be66109 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 16:13:08 +0200 Subject: [PATCH 06/21] adding checkRateEconLimited to StandardWells to check rate related to economic limits. --- opm/autodiff/StandardWells.hpp | 6 ++++ opm/autodiff/StandardWells_impl.hpp | 53 ++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index 2f3054f25..835d9f36d 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -220,6 +220,12 @@ namespace Opm { const std::vector& depth_perf, const double grav); + + template + bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const int well_number) const; + }; diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 9a525edf9..451d25038 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1277,7 +1277,7 @@ namespace Opm } // for the moment, we only handle rate limits, not handling potential limits // the potential limits should not be difficult to add - const WellEcon::QuantityLimitEnum quantity_limit = econ_production_limits.quantityLimit(); + const WellEcon::QuantityLimitEnum& quantity_limit = econ_production_limits.quantityLimit(); if (quantity_limit == WellEcon::POTN) { OPM_THROW(std::logic_error, "Only RATE limit is supported for the moment"); } @@ -1397,4 +1397,55 @@ namespace Opm } + + + + template + bool + StandardWells:: + checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const int well_number) const + { + const Opm::PhaseUsage& pu = fluid_->phaseUsage(); + const int np = well_state.numPhases(); + + if (econ_production_limits.onMinOilRate()) { + assert((*active_)[Oil]); + const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; + const double min_oil_rate = econ_production_limits.minOilRate(); + if (std::abs(oil_rate) < min_oil_rate) { + return true; + } + } + + if (econ_production_limits.onMinGasRate() ) { + assert((*active_)[Gas]); + const double gas_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Gas ] ]; + const double min_gas_rate = econ_production_limits.minGasRate(); + if (std::abs(gas_rate) < min_gas_rate) { + return true; + } + } + + if (econ_production_limits.onMinLiquidRate() ) { + assert((*active_)[Oil]); + assert((*active_)[Water]); + const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; + const double water_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Water ] ]; + const double liquid_rate = oil_rate + water_rate; + const double min_liquid_rate = econ_production_limits.minLiquidRate(); + if (std::abs(liquid_rate) < min_liquid_rate) { + return true; + } + } + + if (econ_production_limits.onMinReservoirFluidRate()) { + std::cerr << "WARNING: Minimum reservoir fluid production rate limit is not supported yet" << std::endl; + } + + return false; + } + + } // namespace Opm From dd59762c0bfdaec2754c4ce5226204a1262b471d Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 17:27:25 +0200 Subject: [PATCH 07/21] adding checkMaxWaterCutLimit to StandardWells. --- opm/autodiff/StandardWells.hpp | 11 ++++ opm/autodiff/StandardWells_impl.hpp | 87 ++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index 835d9f36d..224e66ff0 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -226,6 +226,17 @@ namespace Opm { const WellState& well_state, const int well_number) const; + using WellMapType = typename WellState::WellMapType; + + + template + bool checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const typename WellMapType::const_iterator& i_well, + int& worst_offending_connection, + double& violation_extent, + bool& last_connection) const; + }; diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 451d25038..fc8ee8b81 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1282,9 +1282,6 @@ namespace Opm OPM_THROW(std::logic_error, "Only RATE limit is supported for the moment"); } - using MapEntryType = typename WellState::mapentry_t; - using WellMapType = typename WellState::WellMapType; - const WellMapType& well_map = well_state.wellMap(); typename WellMapType::const_iterator i = well_map.find(well_name); @@ -1448,4 +1445,88 @@ namespace Opm } + + + + + + template + bool + StandardWells:: + checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const typename WellMapType::const_iterator& i_well, + int& worst_offending_connection, + double& violation_extent, + bool& last_connection) const + { + bool water_cut_limit_violated = false; + worst_offending_connection = -1; + violation_extent = -1.0; + last_connection = false; + + const int np = well_state.numPhases(); + const Opm::PhaseUsage& pu = fluid_->phaseUsage(); + const int well_number = (i_well->second)[0]; + + assert((*active_)[Oil]); + assert((*active_)[Water]); + + const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; + const double water_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Water ] ]; + const double liquid_rate = oil_rate + water_rate; + double water_cut; + if (std::abs(liquid_rate) != 0.) { + water_cut = water_rate / liquid_rate; + } else { + water_cut = 0.0; + } + + const double max_water_cut_limit = econ_production_limits.maxWaterCut(); + if (water_cut > max_water_cut_limit) { + water_cut_limit_violated = true; + } + + if (water_cut_limit_violated) { + // need to handle the worst_offending_connection + const int perf_start = (i_well->second)[1]; + const int perf_number = (i_well->second)[2]; + + std::vector water_cut_perf(perf_number); + for (int perf = 0; perf < perf_number; ++perf) { + const int i_perf = perf_start + perf; + const double oil_perf_rate = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Oil ] ]; + const double water_perf_rate = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Water ] ]; + const double liquid_perf_rate = oil_perf_rate + water_perf_rate; + if (std::abs(liquid_perf_rate) != 0.) { + water_cut_perf[perf] = water_perf_rate / liquid_perf_rate; + } else { + water_cut_perf[perf] = 0.; + } + } + + if (perf_number == 1) { + last_connection = true; + worst_offending_connection = 0; + violation_extent = water_cut_perf[0] / max_water_cut_limit; + return water_cut_limit_violated; + } + + 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]; + } + } + + assert(max_water_cut_perf != 0.); + assert(worst_offending_connection >= 0); + + violation_extent = max_water_cut_perf / max_water_cut_limit; + } + + return water_cut_limit_violated; + } + } // namespace Opm From 9220a2bbaf99358aa7779944bf21ff43950394a8 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 17:58:41 +0200 Subject: [PATCH 08/21] refactoring updateListEconLimited based on new functions. --- opm/autodiff/StandardWells_impl.hpp | 105 ++++++---------------------- 1 file changed, 20 insertions(+), 85 deletions(-) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index fc8ee8b81..38b671bc1 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1262,7 +1262,6 @@ namespace Opm DynamicListEconLimited& list_econ_limited) const { const int nw = wells_struct->number_of_wells; - const int np = wells_struct->number_of_phases; for (int w = 0; w < nw; ++w) { // flag to check if the mim oil/gas rate limit is violated @@ -1283,32 +1282,12 @@ namespace Opm } const WellMapType& well_map = well_state.wellMap(); - typename WellMapType::const_iterator i = well_map.find(well_name); + typename WellMapType::const_iterator i_well = well_map.find(well_name); + assert(i_well != well_map.end()); // should always be found? + const int well_number = (i_well->second)[0]; - assert(i != well_map.end()); // should always be found? - - const int well_number = (i->second)[0]; - - const Opm::PhaseUsage& pu = fluid_->phaseUsage(); - - // oil rate limit - // TODO: SHOULD we give a message when closing a well due to economic limit reason? - if (econ_production_limits.onMinOilRate()) { - assert((*active_)[Oil]); - const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; - const double min_oil_rate = econ_production_limits.minOilRate(); - if (std::abs(oil_rate) < min_oil_rate) { - rate_limit_violated = true; - } - } - // gas rate limit - if (econ_production_limits.onMinGasRate()) { - assert((*active_)[Gas]); - const double gas_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Gas ] ]; - const double min_gas_rate = econ_production_limits.minGasRate(); - if (std::abs(gas_rate) < min_gas_rate) { - rate_limit_violated = true; - } + if (econ_production_limits.onAnyRateLimit()) { + rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state, well_number); } if (rate_limit_violated) { @@ -1327,69 +1306,24 @@ namespace Opm continue; } - // checking for other limits, mostly all kinds of ratio. - // TODO: not sure when more than one ratio limit is violated, what is the definition of the - // worst-offending connection - // Should not be more than one connection be closed each time - // Maybe we can compare the extent of the different violations to give a worst one. - bool water_cut_limit_violated = false; - if (econ_production_limits.onMaxWaterCut()) { - assert((*active_)[Oil]); - assert((*active_)[Water]); - const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; - const double water_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Water ] ]; - const double liquid_rate = oil_rate + water_rate; - if (std::abs(liquid_rate) == 0.) { - continue; - } - const double water_cut = water_rate / liquid_rate; - const double max_water_cut = econ_production_limits.maxWaterCut(); - if (water_cut > max_water_cut) { - water_cut_limit_violated = true; - } + // checking for ratio related limits, mostly all kinds of ratio. + int worst_offending_connection = -1e4; + bool ratio_limits_violated = false; + + if (econ_production_limits.onAnyRateLimit()) { + ratio_limits_violated = checkRatioEconLimits(econ_production_limits, well_state, i_well, worst_offending_connection); } - if (econ_production_limits.workover() != WellEcon::CON) { - std::cerr << "WARNING: only CON workover over exceeding limit is supported for the moment." << std::endl; + // TODO: not decided to use local perf index or global perf index. + // UPDATE LATER. + if (ratio_limits_violated) { + const int perf_start = (i_well->second)[1]; + const int perf_number = (i_well->second)[2]; + assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number)); + const int cell_worst_offending_connection = wells_struct->well_cells[perf_start + worst_offending_connection]; + list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_connection); } - const int perf_start = (i->second)[1]; - const int perf_number = (i->second)[2]; - - std::vector oil_perf_rate(perf_number); - std::vector gas_perf_rate(perf_number); - std::vector water_perf_rate(perf_number); - - for (int perf = 0; perf < perf_number; ++perf) { - const int i_perf = perf_start + perf; - oil_perf_rate[perf] = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Oil ] ]; - water_perf_rate[perf] = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Water ] ]; - gas_perf_rate[perf] = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Gas ] ]; - } - - std::vector water_cut_perf(perf_number); - double max_water_cut_perf = 0.0; - int worst_offending_perf = -1; - for (int perf = 0; perf < perf_number; ++perf) { - const double liquid_rate = water_perf_rate[perf] + oil_perf_rate[perf]; - if (std::abs(liquid_rate) == 0.0) { - water_cut_perf[perf] = 0.0; - } else { - water_cut_perf[perf] = water_perf_rate[perf] / liquid_rate; - } - - if (water_cut_perf[perf] > max_water_cut_perf) { - worst_offending_perf = perf; - max_water_cut_perf = water_cut_perf[perf]; - } - } - - assert((worst_offending_perf >= 0) && (worst_offending_perf <= perf_number)); - - const int cell_worst_offending_perf = wells_struct->well_cells[perf_start + worst_offending_perf]; - - list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_perf); - } } @@ -1529,4 +1463,5 @@ namespace Opm return water_cut_limit_violated; } + } // namespace Opm From 41b9fca4344d57c1473e978485271f89e09e170e Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 28 Jun 2016 17:59:50 +0200 Subject: [PATCH 09/21] implementing checkRatioEconLimits --- opm/autodiff/StandardWells.hpp | 6 +++ opm/autodiff/StandardWells_impl.hpp | 61 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index 224e66ff0..ff2c9f6c6 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -229,6 +229,12 @@ namespace Opm { using WellMapType = typename WellState::WellMapType; + template + bool checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const typename WellMapType::const_iterator& i_well, + int& worst_offending_connection) const; + template bool checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 38b671bc1..45de5f3ff 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1382,6 +1382,67 @@ namespace Opm + template + bool + StandardWells:: + checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const typename WellMapType::const_iterator& i_well, + int& worst_offending_connection) const + { + // TODO: not sure how to define the worst-offending connection when more than one + // ratio related limit is violated. + // The defintion used here is that we define the violation extent based on the + // ratio between the value and the corresopoding limit. + // For each violated limit, we decide the worst-offending connection separately. + // Among the worst-offending connections, we use the one has the biggest violation + // extent. + + + bool any_limit_violated = false; + // should handle last_connection here instead of in any following check Function. + bool last_connection = false; + double violation_extent = 0.0; + worst_offending_connection = -1; + + if (econ_production_limits.onMaxWaterCut()) { + int worst_offending_connection_water_cut = -1; + double violation_extent_water_cut = 0.0; + const bool water_cut_violated = checkMaxWaterCutLimit(econ_production_limits, well_state, i_well, + worst_offending_connection_water_cut, + violation_extent_water_cut, + last_connection); + if (water_cut_violated) { + any_limit_violated = true; + if (violation_extent_water_cut > violation_extent) { + violation_extent = violation_extent_water_cut; + worst_offending_connection = worst_offending_connection_water_cut; + } + } + } + + if (econ_production_limits.onMaxGasOilRatio()) { + OPM_MESSAGE("WARNING: the support for max Gas-Oil ratio is not implemented yet!"); + } + + if (econ_production_limits.onMaxWaterGasRatio()) { + OPM_MESSAGE("WARNING: the support for max Water-Gas ratio is not implemented yet!"); + } + + if (econ_production_limits.onMaxGasLiquidRatio()) { + OPM_MESSAGE("WARNING: the support for max Gas-Liquid ratio is not implemented yet!"); + } + + if (any_limit_violated) { + assert(worst_offending_connection >=0); + assert(violation_extent > 1.); + } + + return any_limit_violated; + } + + + template From 109b55f61c61f8f66d1841216df224734e644d2b Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 29 Jun 2016 11:43:11 +0200 Subject: [PATCH 10/21] using OpmLog to give warning. --- opm/autodiff/StandardWells.hpp | 2 ++ opm/autodiff/StandardWells_impl.hpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index ff2c9f6c6..dd3d1e1c2 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -22,6 +22,8 @@ #ifndef OPM_STANDARDWELLS_HEADER_INCLUDED #define OPM_STANDARDWELLS_HEADER_INCLUDED +#include + #include #include #include diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 45de5f3ff..910c28137 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1292,13 +1292,13 @@ namespace Opm if (rate_limit_violated) { if (econ_production_limits.endRun()) { - std::cerr << "WARNING: ending run after well closed due to economic limits is not supported yet" - << std::endl - << "the program will keep running after " << well_name << " is closed " << std::endl; + const std::string warning_message = std::string("WARNING: ending run after well closed due to economic limits is not supported yet \n") + + std::string("the program will keep running after ") + well_name + std::string(" is closed"); + OpmLog::warning(warning_message); } if (econ_production_limits.validFollowonWell()) { - std::cerr << "WARNING: opening following on well after well closed is not supported yet" << std::endl; + OpmLog::warning("WARNING: opening following on well after well closed is not supported yet"); } list_econ_limited.addShuttedWell(well_name); @@ -1372,7 +1372,7 @@ namespace Opm } if (econ_production_limits.onMinReservoirFluidRate()) { - std::cerr << "WARNING: Minimum reservoir fluid production rate limit is not supported yet" << std::endl; + OpmLog::warning("WARNING: Minimum reservoir fluid production rate limit is not supported yet"); } return false; @@ -1422,15 +1422,15 @@ namespace Opm } if (econ_production_limits.onMaxGasOilRatio()) { - OPM_MESSAGE("WARNING: the support for max Gas-Oil ratio is not implemented yet!"); + OpmLog::warning("WARNING: the support for max Gas-Oil ratio is not implemented yet!"); } if (econ_production_limits.onMaxWaterGasRatio()) { - OPM_MESSAGE("WARNING: the support for max Water-Gas ratio is not implemented yet!"); + OpmLog::warning("WARNING: the support for max Water-Gas ratio is not implemented yet!"); } if (econ_production_limits.onMaxGasLiquidRatio()) { - OPM_MESSAGE("WARNING: the support for max Gas-Liquid ratio is not implemented yet!"); + OpmLog::warning("WARNING: the support for max Gas-Liquid ratio is not implemented yet!"); } if (any_limit_violated) { From e817719d4811e4d0ae4a4aa2b352b427c24465a0 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 29 Jun 2016 12:37:11 +0200 Subject: [PATCH 11/21] When last connection is closed, the well is shut done. --- opm/autodiff/StandardWells.hpp | 3 ++- opm/autodiff/StandardWells_impl.hpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index dd3d1e1c2..12fd2653e 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -235,7 +235,8 @@ namespace Opm { bool checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, const typename WellMapType::const_iterator& i_well, - int& worst_offending_connection) const; + int& worst_offending_connection, + bool& last_connection) const; template bool checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 910c28137..13c3541f2 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1309,9 +1309,11 @@ namespace Opm // checking for ratio related limits, mostly all kinds of ratio. int worst_offending_connection = -1e4; bool ratio_limits_violated = false; + bool last_connection = false; if (econ_production_limits.onAnyRateLimit()) { - ratio_limits_violated = checkRatioEconLimits(econ_production_limits, well_state, i_well, worst_offending_connection); + ratio_limits_violated = checkRatioEconLimits(econ_production_limits, well_state, i_well, + worst_offending_connection, last_connection); } // TODO: not decided to use local perf index or global perf index. @@ -1322,6 +1324,9 @@ namespace Opm assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number)); const int cell_worst_offending_connection = wells_struct->well_cells[perf_start + worst_offending_connection]; list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_connection); + if (last_connection) { + list_econ_limited.addShuttedWell(well_name); + } } } @@ -1388,7 +1393,8 @@ namespace Opm checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, const typename WellMapType::const_iterator& i_well, - int& worst_offending_connection) const + int& worst_offending_connection, + bool& last_connection) const { // TODO: not sure how to define the worst-offending connection when more than one // ratio related limit is violated. @@ -1400,10 +1406,9 @@ namespace Opm bool any_limit_violated = false; - // should handle last_connection here instead of in any following check Function. - bool last_connection = false; double violation_extent = 0.0; worst_offending_connection = -1; + last_connection = false; if (econ_production_limits.onMaxWaterCut()) { int worst_offending_connection_water_cut = -1; @@ -1458,7 +1463,6 @@ namespace Opm bool water_cut_limit_violated = false; worst_offending_connection = -1; violation_extent = -1.0; - last_connection = false; const int np = well_state.numPhases(); const Opm::PhaseUsage& pu = fluid_->phaseUsage(); From cc957a77fede79d7ac0922f226760d92db353f7a Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 29 Jun 2016 15:04:05 +0200 Subject: [PATCH 12/21] some well will go to stopped list and infomation output. --- opm/autodiff/StandardWells_impl.hpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 13c3541f2..5fec032b3 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1270,6 +1270,11 @@ namespace Opm const Well* well_ecl = schedule->getWell(well_name); const WellEconProductionLimits& econ_production_limits = well_ecl->getEconProductionLimits(current_step); + // economic limits only apply for production wells. + if (wells_struct->type[w] != PRODUCER) { + continue; + } + // if no limit is effective here, then continue to the next well if ( !econ_production_limits.onAnyEffectiveLimit() ) { continue; @@ -1301,7 +1306,15 @@ namespace Opm OpmLog::warning("WARNING: opening following on well after well closed is not supported yet"); } - list_econ_limited.addShuttedWell(well_name); + if (well_ecl->getAutomaticShutIn()) { + list_econ_limited.addShuttedWell(well_name); + const std::string msg = std::string("well ") + well_name + std::string(" will be shutted in due to economic limit"); + OpmLog::info(msg); + } else { + list_econ_limited.addStoppedWell(well_name); + const std::string msg = std::string("well ") + well_name + std::string(" will be stopped due to economic limit"); + OpmLog::info(msg); + } // the well is closed, not need to check other limits continue; } @@ -1311,21 +1324,26 @@ namespace Opm bool ratio_limits_violated = false; bool last_connection = false; - if (econ_production_limits.onAnyRateLimit()) { + if (econ_production_limits.onAnyRatioLimit()) { ratio_limits_violated = checkRatioEconLimits(econ_production_limits, well_state, i_well, worst_offending_connection, last_connection); } - // TODO: not decided to use local perf index or global perf index. - // UPDATE LATER. if (ratio_limits_violated) { const int perf_start = (i_well->second)[1]; const int perf_number = (i_well->second)[2]; assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number)); + const int cell_worst_offending_connection = wells_struct->well_cells[perf_start + worst_offending_connection]; list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_connection); + 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 econic limit"); + OpmLog::info(msg); + if (last_connection) { list_econ_limited.addShuttedWell(well_name); + const std::string msg2 = well_name + std::string(" will be shutted due to the last connection closed"); + OpmLog::info(msg2); } } @@ -1404,7 +1422,6 @@ namespace Opm // Among the worst-offending connections, we use the one has the biggest violation // extent. - bool any_limit_violated = false; double violation_extent = 0.0; worst_offending_connection = -1; @@ -1520,7 +1537,7 @@ namespace Opm } assert(max_water_cut_perf != 0.); - assert(worst_offending_connection >= 0); + assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number)); violation_extent = max_water_cut_perf / max_water_cut_limit; } From 98a6495abc9945bea73e38cab027a3f9786d62dd Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 29 Jun 2016 17:08:45 +0200 Subject: [PATCH 13/21] makeing wellModel public for flow_polymer and flow_solvent. --- opm/autodiff/BlackoilSolventModel.hpp | 3 ++- opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/opm/autodiff/BlackoilSolventModel.hpp b/opm/autodiff/BlackoilSolventModel.hpp index 589aeaced..14391daf0 100644 --- a/opm/autodiff/BlackoilSolventModel.hpp +++ b/opm/autodiff/BlackoilSolventModel.hpp @@ -88,6 +88,8 @@ namespace Opm { ReservoirState& reservoir_state, WellState& well_state); + using Base::wellModel; + protected: @@ -129,7 +131,6 @@ namespace Opm { // --------- Protected methods --------- // Need to declare Base members we want to use here. - using Base::wellModel; using Base::wells; using Base::variableState; using Base::computeGasPressure; diff --git a/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp b/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp index cfe157a17..c3ef5cefd 100644 --- a/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp +++ b/opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp @@ -125,6 +125,7 @@ namespace Opm { WellState& well_state, const bool initial_assembly); + using Base::wellModel; protected: @@ -180,7 +181,6 @@ namespace Opm { // --------- Protected methods --------- // Need to declare Base members we want to use here. - using Base::wellModel; using Base::wells; using Base::wellsActive; using Base::variableState; From b2524a7dc3d925dd0306aa1a2d931ba8ace1fda2 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Thu, 30 Jun 2016 11:36:09 +0200 Subject: [PATCH 14/21] making a forwarded updateListEconLimited in SimulatorBase. and some changes to make the code compile for all the simulators. --- opm/autodiff/BlackoilPressureModel.hpp | 1 + opm/autodiff/BlackoilSequentialModel.hpp | 7 ++++++ opm/autodiff/SimulatorBase.hpp | 7 ++++++ opm/autodiff/SimulatorBase_impl.hpp | 24 +++++++++++++++++-- ...ulatorFullyImplicitCompressiblePolymer.hpp | 8 +++++++ ...rFullyImplicitCompressiblePolymer_impl.hpp | 17 +++++++++++++ 6 files changed, 62 insertions(+), 2 deletions(-) diff --git a/opm/autodiff/BlackoilPressureModel.hpp b/opm/autodiff/BlackoilPressureModel.hpp index b38c626d7..67e057b21 100644 --- a/opm/autodiff/BlackoilPressureModel.hpp +++ b/opm/autodiff/BlackoilPressureModel.hpp @@ -129,6 +129,7 @@ namespace Opm { using Base::numPhases; using Base::numMaterials; + using Base::wellModel; protected: using Base::asImpl; diff --git a/opm/autodiff/BlackoilSequentialModel.hpp b/opm/autodiff/BlackoilSequentialModel.hpp index 613fcb3ca..91025565b 100644 --- a/opm/autodiff/BlackoilSequentialModel.hpp +++ b/opm/autodiff/BlackoilSequentialModel.hpp @@ -239,6 +239,13 @@ namespace Opm { transport_solver_.model().relativeChange(previous, current)); } + /// Return the well model + const WellModel& wellModel() const + { + return pressure_model_->wellModel(); + } + + diff --git a/opm/autodiff/SimulatorBase.hpp b/opm/autodiff/SimulatorBase.hpp index 780868644..39f223e82 100644 --- a/opm/autodiff/SimulatorBase.hpp +++ b/opm/autodiff/SimulatorBase.hpp @@ -162,6 +162,13 @@ namespace Opm const WellState& xw, std::vector& well_potentials); + void updateListEconLimited(const std::unique_ptr& solver, + ScheduleConstPtr schedule, + const int current_step, + const Wells* wells, + const WellState& well_state, + DynamicListEconLimited& list_econ_limited) const; + // Data. typedef RateConverter:: diff --git a/opm/autodiff/SimulatorBase_impl.hpp b/opm/autodiff/SimulatorBase_impl.hpp index 51dc361e1..34dfbdda6 100644 --- a/opm/autodiff/SimulatorBase_impl.hpp +++ b/opm/autodiff/SimulatorBase_impl.hpp @@ -272,8 +272,8 @@ namespace Opm asImpl().computeWellPotentials(wells, well_state, well_potentials); } - solver->model().wellModel().updateListEconLimited(eclipse_state_->getSchedule(), timer.currentStepNum(), wells, - well_state, dynamic_list_econ_limited); + asImpl().updateListEconLimited(solver, eclipse_state_->getSchedule(), timer.currentStepNum(), wells, + well_state, dynamic_list_econ_limited); } // Write final simulation state. output_writer_.writeTimeStep( timer, state, prev_well_state ); @@ -618,4 +618,24 @@ namespace Opm } } } + + + + + + template + void + SimulatorBase:: + updateListEconLimited(const std::unique_ptr& solver, + ScheduleConstPtr schedule, + const int current_step, + const Wells* wells, + const WellState& well_state, + DynamicListEconLimited& list_econ_limited) const + { + + solver->model().wellModel().updateListEconLimited(schedule, current_step, wells, + well_state, list_econ_limited); + } + } // namespace Opm diff --git a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp index 1043d678f..011c1c4e1 100644 --- a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp +++ b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp @@ -119,9 +119,17 @@ namespace Opm WellsManager& wells_manager, typename BaseType::WellState& well_state, const Wells* wells); + + void updateListEconLimited(const std::unique_ptr& solver, + ScheduleConstPtr schedule, + const int current_step, + const Wells* wells, + const WellState& well_state, + DynamicListEconLimited& list_econ_limited) const; private: Opm::DeckConstPtr deck_; const PolymerPropsAd& polymer_props_; + }; } // namespace Opm diff --git a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp index 5ba9928f4..522403ef1 100644 --- a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp +++ b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp @@ -98,6 +98,23 @@ handleAdditionalWellInflow(SimulatorTimer& timer, } + + + +template +void +SimulatorFullyImplicitCompressiblePolymer:: +updateListEconLimited(const std::unique_ptr& /*solver*/, + ScheduleConstPtr /*schedule*/, + const int /*current_step*/, + const Wells* /*wells*/, + const WellState& /*well_state*/, + DynamicListEconLimited& /*list_econ_limited*/) const +{ + +} + + } // namespace Opm #endif // OPM_SIMULATORFULLYIMPLICITCOMPRESSIBLEPOLYMER_HEADER_INCLUDED From 8e52e7199328822ca39c5c34487b869397fcf49c Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Thu, 30 Jun 2016 16:25:58 +0200 Subject: [PATCH 15/21] changing shutted to shut. --- opm/autodiff/StandardWells_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 5fec032b3..5f0a3ac25 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1307,8 +1307,8 @@ namespace Opm } if (well_ecl->getAutomaticShutIn()) { - list_econ_limited.addShuttedWell(well_name); - const std::string msg = std::string("well ") + well_name + std::string(" will be shutted in due to economic limit"); + list_econ_limited.addShutWell(well_name); + const std::string msg = std::string("well ") + well_name + std::string(" will be shut in due to economic limit"); OpmLog::info(msg); } else { list_econ_limited.addStoppedWell(well_name); @@ -1341,8 +1341,8 @@ namespace Opm OpmLog::info(msg); if (last_connection) { - list_econ_limited.addShuttedWell(well_name); - const std::string msg2 = well_name + std::string(" will be shutted due to the last connection closed"); + list_econ_limited.addShutWell(well_name); + const std::string msg2 = well_name + std::string(" will be shut due to the last connection closed"); OpmLog::info(msg2); } } From 6a70450422799c0fe3df4071ef7c3371fbbe70c4 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 4 Jul 2016 11:39:56 +0200 Subject: [PATCH 16/21] wrtiting state to report at the end of each time step insead of writing in the begining of each time step. --- opm/autodiff/SimulatorBase_impl.hpp | 13 ++++++++----- ...ulatorFullyImplicitBlackoilMultiSegment_impl.hpp | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/opm/autodiff/SimulatorBase_impl.hpp b/opm/autodiff/SimulatorBase_impl.hpp index 34dfbdda6..62074387b 100644 --- a/opm/autodiff/SimulatorBase_impl.hpp +++ b/opm/autodiff/SimulatorBase_impl.hpp @@ -165,9 +165,10 @@ namespace Opm // give the polymer and surfactant simulators the chance to do their stuff asImpl().handleAdditionalWellInflow(timer, wells_manager, well_state, wells); - // write simulation state at the report stage - output_writer_.writeTimeStep( timer, state, well_state ); - + // write the inital state at the report stage + if (timer.initialStep()) { + output_writer_.writeTimeStep( timer, state, well_state ); + } // Max oil saturation (for VPPARS), hysteresis update. props_.updateSatOilMax(state.saturation()); @@ -265,6 +266,10 @@ namespace Opm // Increment timer, remember well state. ++timer; + + // write simulation state at the report stage + output_writer_.writeTimeStep( timer, state, well_state ); + prev_well_state = well_state; // The well potentials are only computed if they are needed // For now thay are only used to determine default guide rates for group controlled wells @@ -275,8 +280,6 @@ namespace Opm asImpl().updateListEconLimited(solver, eclipse_state_->getSchedule(), timer.currentStepNum(), wells, well_state, dynamic_list_econ_limited); } - // Write final simulation state. - output_writer_.writeTimeStep( timer, state, prev_well_state ); // Stop timer and create timing report total_timer.stop(); diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp index d98bca55b..84e040539 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp @@ -126,8 +126,10 @@ namespace Opm // give the polymer and surfactant simulators the chance to do their stuff Base::asImpl().handleAdditionalWellInflow(timer, wells_manager, well_state, wells); - // write simulation state at the report stage - output_writer_.writeTimeStep( timer, state, well_state ); + // write the inital state at the report stage + if (timer.initialStep()) { + output_writer_.writeTimeStep( timer, state, well_state ); + } // Max oil saturation (for VPPARS), hysteresis update. props_.updateSatOilMax(state.saturation()); @@ -179,12 +181,13 @@ namespace Opm // Increment timer, remember well state. ++timer; + + // write simulation state at the report stage + output_writer_.writeTimeStep( timer, state, well_state ); + prev_well_state = well_state; } - // Write final simulation state. - output_writer_.writeTimeStep( timer, state, prev_well_state ); - // Stop timer and create timing report total_timer.stop(); SimulatorReport report; From ddec62288a55d4c794569265f6ae249dd44c654a Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 4 Jul 2016 12:34:01 +0200 Subject: [PATCH 17/21] fixing the warning messages. --- opm/autodiff/StandardWells_impl.hpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 5f0a3ac25..b6afe8281 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1283,7 +1283,9 @@ namespace Opm // the potential limits should not be difficult to add const WellEcon::QuantityLimitEnum& quantity_limit = econ_production_limits.quantityLimit(); if (quantity_limit == WellEcon::POTN) { - OPM_THROW(std::logic_error, "Only RATE limit is supported for the moment"); + const std::string msg = std::string("POTN limit for well ") + well_name + std::string(" is not supported for the moment. \n") + + std::string("All the limits will be evaluated based on RATE. "); + OpmLog::warning(msg); } const WellMapType& well_map = well_state.wellMap(); @@ -1297,13 +1299,13 @@ namespace Opm if (rate_limit_violated) { if (econ_production_limits.endRun()) { - const std::string warning_message = std::string("WARNING: ending run after well closed due to economic limits is not supported yet \n") + const std::string warning_message = std::string("ending run after well closed due to economic limits is not supported yet \n") + std::string("the program will keep running after ") + well_name + std::string(" is closed"); OpmLog::warning(warning_message); } if (econ_production_limits.validFollowonWell()) { - OpmLog::warning("WARNING: opening following on well after well closed is not supported yet"); + OpmLog::warning("opening following on well after well closed is not supported yet"); } if (well_ecl->getAutomaticShutIn()) { @@ -1395,7 +1397,7 @@ namespace Opm } if (econ_production_limits.onMinReservoirFluidRate()) { - OpmLog::warning("WARNING: Minimum reservoir fluid production rate limit is not supported yet"); + OpmLog::warning("Minimum reservoir fluid production rate limit is not supported yet"); } return false; @@ -1444,15 +1446,15 @@ namespace Opm } if (econ_production_limits.onMaxGasOilRatio()) { - OpmLog::warning("WARNING: the support for max Gas-Oil ratio is not implemented yet!"); + OpmLog::warning("the support for max Gas-Oil ratio is not implemented yet!"); } if (econ_production_limits.onMaxWaterGasRatio()) { - OpmLog::warning("WARNING: the support for max Water-Gas ratio is not implemented yet!"); + OpmLog::warning("the support for max Water-Gas ratio is not implemented yet!"); } if (econ_production_limits.onMaxGasLiquidRatio()) { - OpmLog::warning("WARNING: the support for max Gas-Liquid ratio is not implemented yet!"); + OpmLog::warning("the support for max Gas-Liquid ratio is not implemented yet!"); } if (any_limit_violated) { From aed2760b31b3227b469d285b9dde37dc8fb18f75 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 4 Jul 2016 13:31:37 +0200 Subject: [PATCH 18/21] updating the path for the multi-segment wells test. due to the renaming of the folder name in opm-data. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 338925301..1c67dd0df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ if (HAVE_OPM_DATA) add_test( NAME flow_SPE1CASE2 COMMAND flow ${OPM_DATA_ROOT}/spe1/SPE1CASE2.DATA ) add_test( NAME flow_SPE1CASE2_restart COMMAND flow ${OPM_DATA_ROOT}/spe1/SPE1CASE2_RESTART.DATA ) - add_test( NAME flow_MSW2DH__ COMMAND flow_multisegment ${OPM_DATA_ROOT}/multisegment_wells_test_suite/2D_H__/2D_H__.DATA) + add_test( NAME flow_MSW2DH__ COMMAND flow_multisegment ${OPM_DATA_ROOT}/wells_test_suite/MSW/2D_H__/2D_H__.DATA) set_tests_properties(flow_SPE1CASE2_restart PROPERTIES DEPENDS flow_SPE1CASE2) # Dependes on the restart file from test flow_SPE1CASE2 From 4dad47f90d3e9b8d196c6c5a2572cb46ae6aed1c Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 5 Jul 2016 10:55:34 +0200 Subject: [PATCH 19/21] adding warning tags to all the WECON related warnings. --- opm/autodiff/StandardWells_impl.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index b6afe8281..4af8f51c2 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1285,7 +1285,7 @@ namespace Opm if (quantity_limit == WellEcon::POTN) { const std::string msg = std::string("POTN limit for well ") + well_name + std::string(" is not supported for the moment. \n") + std::string("All the limits will be evaluated based on RATE. "); - OpmLog::warning(msg); + OpmLog::warning("NOT_SUPPORTING_POTN", msg); } const WellMapType& well_map = well_state.wellMap(); @@ -1301,11 +1301,11 @@ namespace Opm if (econ_production_limits.endRun()) { const std::string warning_message = std::string("ending run after well closed due to economic limits is not supported yet \n") + std::string("the program will keep running after ") + well_name + std::string(" is closed"); - OpmLog::warning(warning_message); + OpmLog::warning("NOT_SUPPORTING_ENDRUN", warning_message); } if (econ_production_limits.validFollowonWell()) { - OpmLog::warning("opening following on well after well closed is not supported yet"); + OpmLog::warning("NOT_SUPPORTING_FOLLOWONWELL", "opening following on well after well closed is not supported yet"); } if (well_ecl->getAutomaticShutIn()) { @@ -1397,7 +1397,7 @@ namespace Opm } if (econ_production_limits.onMinReservoirFluidRate()) { - OpmLog::warning("Minimum reservoir fluid production rate limit is not supported yet"); + OpmLog::warning("NOT_SUPPORTING_MIN_RESERVOIR_FLUID_RATE", "Minimum reservoir fluid production rate limit is not supported yet"); } return false; @@ -1446,15 +1446,15 @@ namespace Opm } if (econ_production_limits.onMaxGasOilRatio()) { - OpmLog::warning("the support for max Gas-Oil ratio is not implemented yet!"); + OpmLog::warning("NOT_SUPPORTING_MAX_GOR", "the support for max Gas-Oil ratio is not implemented yet!"); } if (econ_production_limits.onMaxWaterGasRatio()) { - OpmLog::warning("the support for max Water-Gas ratio is not implemented yet!"); + OpmLog::warning("NOT_SUPPORTING_MAX_WGR", "the support for max Water-Gas ratio is not implemented yet!"); } if (econ_production_limits.onMaxGasLiquidRatio()) { - OpmLog::warning("the support for max Gas-Liquid ratio is not implemented yet!"); + OpmLog::warning("NOT_SUPPORTING_MAX_GLR", "the support for max Gas-Liquid ratio is not implemented yet!"); } if (any_limit_violated) { From a8c2626e5ab4f7fac89ef2bcaff07e9628036a1d Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 5 Jul 2016 13:02:06 +0200 Subject: [PATCH 20/21] fixing comments. no functional change. --- opm/autodiff/StandardWells.hpp | 31 +++++++++----- opm/autodiff/StandardWells_impl.hpp | 64 ++++++++++++++--------------- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index 12fd2653e..249078e26 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -30,6 +30,7 @@ #include #include +#include #include @@ -230,21 +231,29 @@ namespace Opm { using WellMapType = typename WellState::WellMapType; + // a tuple type for ratio limit check. + // first value indicates whether ratio limit is violated, when the ratio limit is not violated, the following three + // values should not be used. + // second value indicates whehter there is only one connection left. + // third value indicates the indx of the worst-offending connection. + // the last value indicates the extent of the violation for the worst-offending connection, which is defined by + // the ratio of the actual value to the value of the violated limit. + using RatioCheckTuple = std::tuple; + + enum ConnectionIndex { + INVALIDCONNECTION = -10000 + }; + template - bool checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, - const WellState& well_state, - const typename WellMapType::const_iterator& i_well, - int& worst_offending_connection, - bool& last_connection) const; + RatioCheckTuple checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const typename WellMapType::const_iterator& i_well) const; template - bool checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, - const WellState& well_state, - const typename WellMapType::const_iterator& i_well, - int& worst_offending_connection, - double& violation_extent, - bool& last_connection) const; + RatioCheckTuple checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, + const WellState& well_state, + const typename WellMapType::const_iterator& i_well) const; }; diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 4af8f51c2..4b93644d0 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1322,24 +1322,26 @@ namespace Opm } // checking for ratio related limits, mostly all kinds of ratio. - int worst_offending_connection = -1e4; bool ratio_limits_violated = false; - bool last_connection = false; + RatioCheckTuple ratio_check_return; if (econ_production_limits.onAnyRatioLimit()) { - ratio_limits_violated = checkRatioEconLimits(econ_production_limits, well_state, i_well, - worst_offending_connection, last_connection); + ratio_check_return = checkRatioEconLimits(econ_production_limits, well_state, i_well); + ratio_limits_violated = std::get<0>(ratio_check_return); } if (ratio_limits_violated) { + const bool last_connection = std::get<1>(ratio_check_return); + const int worst_offending_connection = std::get<2>(ratio_check_return); + const int perf_start = (i_well->second)[1]; - const int perf_number = (i_well->second)[2]; - assert((worst_offending_connection >= 0) && (worst_offending_connection < perf_number)); + + assert((worst_offending_connection >= 0) && (worst_offending_connection < (i_well->second)[2])); const int cell_worst_offending_connection = wells_struct->well_cells[perf_start + worst_offending_connection]; list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_connection); 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 econic limit"); + + well_name + std::string(" will be closed due to economic limit"); OpmLog::info(msg); if (last_connection) { @@ -1408,39 +1410,35 @@ namespace Opm template - bool + StandardWells::RatioCheckTuple StandardWells:: checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, - const typename WellMapType::const_iterator& i_well, - int& worst_offending_connection, - bool& last_connection) const + const typename WellMapType::const_iterator& i_well) const { // TODO: not sure how to define the worst-offending connection when more than one // ratio related limit is violated. // The defintion used here is that we define the violation extent based on the - // ratio between the value and the corresopoding limit. + // ratio between the value and the corresponding limit. // For each violated limit, we decide the worst-offending connection separately. // Among the worst-offending connections, we use the one has the biggest violation // extent. bool any_limit_violated = false; - double violation_extent = 0.0; - worst_offending_connection = -1; - last_connection = false; + bool last_connection = false; + int worst_offending_connection = INVALIDCONNECTION; + double violation_extent = -1.0; if (econ_production_limits.onMaxWaterCut()) { - int worst_offending_connection_water_cut = -1; - double violation_extent_water_cut = 0.0; - const bool water_cut_violated = checkMaxWaterCutLimit(econ_production_limits, well_state, i_well, - worst_offending_connection_water_cut, - violation_extent_water_cut, - last_connection); + const RatioCheckTuple water_cut_return = checkMaxWaterCutLimit(econ_production_limits, well_state, i_well); + bool water_cut_violated = std::get<0>(water_cut_return); if (water_cut_violated) { any_limit_violated = true; + const double violation_extent_water_cut = std::get<3>(water_cut_return); if (violation_extent_water_cut > violation_extent) { violation_extent = violation_extent_water_cut; - worst_offending_connection = worst_offending_connection_water_cut; + worst_offending_connection = std::get<2>(water_cut_return); + last_connection = std::get<1>(water_cut_return); } } } @@ -1462,7 +1460,7 @@ namespace Opm assert(violation_extent > 1.); } - return any_limit_violated; + return std::make_tuple(any_limit_violated, last_connection, worst_offending_connection, violation_extent); } @@ -1470,18 +1468,16 @@ namespace Opm template - bool + StandardWells::RatioCheckTuple StandardWells:: checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, - const typename WellMapType::const_iterator& i_well, - int& worst_offending_connection, - double& violation_extent, - bool& last_connection) const + const typename WellMapType::const_iterator& i_well) const { bool water_cut_limit_violated = false; - worst_offending_connection = -1; - violation_extent = -1.0; + int worst_offending_connection = INVALIDCONNECTION; + bool last_connection = false; + double violation_extent = -1.0; const int np = well_state.numPhases(); const Opm::PhaseUsage& pu = fluid_->phaseUsage(); @@ -1523,11 +1519,11 @@ namespace Opm } } - if (perf_number == 1) { - last_connection = true; + last_connection = (perf_number == 1); + if (last_connection) { worst_offending_connection = 0; violation_extent = water_cut_perf[0] / max_water_cut_limit; - return water_cut_limit_violated; + return std::make_tuple(water_cut_limit_violated, last_connection, worst_offending_connection, violation_extent); } double max_water_cut_perf = 0.; @@ -1544,7 +1540,7 @@ namespace Opm violation_extent = max_water_cut_perf / max_water_cut_limit; } - return water_cut_limit_violated; + return std::make_tuple(water_cut_limit_violated, last_connection, worst_offending_connection, violation_extent); } From 399298be2113008e41a529213d5947f1182a5db7 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Tue, 5 Jul 2016 15:28:02 +0200 Subject: [PATCH 21/21] using mapentry_t instead of iterator. --- opm/autodiff/StandardWells.hpp | 5 +++-- opm/autodiff/StandardWells_impl.hpp | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/opm/autodiff/StandardWells.hpp b/opm/autodiff/StandardWells.hpp index 249078e26..c106c2e0b 100644 --- a/opm/autodiff/StandardWells.hpp +++ b/opm/autodiff/StandardWells.hpp @@ -230,6 +230,7 @@ namespace Opm { const int well_number) const; using WellMapType = typename WellState::WellMapType; + using WellMapEntryType = typename WellState::mapentry_t; // a tuple type for ratio limit check. // first value indicates whether ratio limit is violated, when the ratio limit is not violated, the following three @@ -248,12 +249,12 @@ namespace Opm { template RatioCheckTuple checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, - const typename WellMapType::const_iterator& i_well) const; + const WellMapEntryType& map_entry) const; template RatioCheckTuple checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, - const typename WellMapType::const_iterator& i_well) const; + const WellMapEntryType& map_entry) const; }; diff --git a/opm/autodiff/StandardWells_impl.hpp b/opm/autodiff/StandardWells_impl.hpp index 4b93644d0..d47fa4617 100644 --- a/opm/autodiff/StandardWells_impl.hpp +++ b/opm/autodiff/StandardWells_impl.hpp @@ -1289,9 +1289,10 @@ namespace Opm } const WellMapType& well_map = well_state.wellMap(); - typename WellMapType::const_iterator i_well = well_map.find(well_name); + const typename WellMapType::const_iterator i_well = well_map.find(well_name); assert(i_well != well_map.end()); // should always be found? - const int well_number = (i_well->second)[0]; + const WellMapEntryType& map_entry = i_well->second; + const int well_number = map_entry[0]; if (econ_production_limits.onAnyRateLimit()) { rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state, well_number); @@ -1326,7 +1327,7 @@ namespace Opm RatioCheckTuple ratio_check_return; if (econ_production_limits.onAnyRatioLimit()) { - ratio_check_return = checkRatioEconLimits(econ_production_limits, well_state, i_well); + ratio_check_return = checkRatioEconLimits(econ_production_limits, well_state, map_entry); ratio_limits_violated = std::get<0>(ratio_check_return); } @@ -1334,9 +1335,9 @@ namespace Opm const bool last_connection = std::get<1>(ratio_check_return); const int worst_offending_connection = std::get<2>(ratio_check_return); - const int perf_start = (i_well->second)[1]; + const int perf_start = map_entry[1]; - assert((worst_offending_connection >= 0) && (worst_offending_connection < (i_well->second)[2])); + assert((worst_offending_connection >= 0) && (worst_offending_connection < map_entry[2])); const int cell_worst_offending_connection = wells_struct->well_cells[perf_start + worst_offending_connection]; list_econ_limited.addClosedConnectionsForWell(well_name, cell_worst_offending_connection); @@ -1414,7 +1415,7 @@ namespace Opm StandardWells:: checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, - const typename WellMapType::const_iterator& i_well) const + const WellMapEntryType& map_entry) const { // TODO: not sure how to define the worst-offending connection when more than one // ratio related limit is violated. @@ -1430,7 +1431,7 @@ namespace Opm double violation_extent = -1.0; if (econ_production_limits.onMaxWaterCut()) { - const RatioCheckTuple water_cut_return = checkMaxWaterCutLimit(econ_production_limits, well_state, i_well); + const RatioCheckTuple water_cut_return = checkMaxWaterCutLimit(econ_production_limits, well_state, map_entry); bool water_cut_violated = std::get<0>(water_cut_return); if (water_cut_violated) { any_limit_violated = true; @@ -1472,7 +1473,7 @@ namespace Opm StandardWells:: checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, const WellState& well_state, - const typename WellMapType::const_iterator& i_well) const + const WellMapEntryType& map_entry) const { bool water_cut_limit_violated = false; int worst_offending_connection = INVALIDCONNECTION; @@ -1481,7 +1482,7 @@ namespace Opm const int np = well_state.numPhases(); const Opm::PhaseUsage& pu = fluid_->phaseUsage(); - const int well_number = (i_well->second)[0]; + const int well_number = map_entry[0]; assert((*active_)[Oil]); assert((*active_)[Water]); @@ -1503,8 +1504,8 @@ namespace Opm if (water_cut_limit_violated) { // need to handle the worst_offending_connection - const int perf_start = (i_well->second)[1]; - const int perf_number = (i_well->second)[2]; + const int perf_start = map_entry[1]; + const int perf_number = map_entry[2]; std::vector water_cut_perf(perf_number); for (int perf = 0; perf < perf_number; ++perf) {