From e510dde102541f5a8b5f6986534b510679de9f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 10 Mar 2014 13:30:43 +0100 Subject: [PATCH 1/5] Initialize well rates better. Instead of making well rates zero for wells that are not controlled by surface volume, we initialize them to a small value with the correct sign (positive for injectors, negative for producers). --- opm/core/simulator/WellState.hpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/opm/core/simulator/WellState.hpp b/opm/core/simulator/WellState.hpp index 39fbdbd3..adf3fb24 100644 --- a/opm/core/simulator/WellState.hpp +++ b/opm/core/simulator/WellState.hpp @@ -59,13 +59,20 @@ namespace Opm bhp_[w] = well_controls_get_current_target( ctrl ); } - // Initialize well rates to match controls if type is SURFACE_RATE + // Initialize well rates to match controls if type is SURFACE_RATE, + // otherwise set to a small rate with the correct sign. if (well_controls_well_is_open( ctrl ) || (well_controls_get_current_type(ctrl) == SURFACE_RATE)) { const double rate_target = well_controls_get_current_target(ctrl); const double * distr = well_controls_get_current_distr( ctrl ); for (int p = 0; p < np; ++p) { wellrates_[np*w + p] = rate_target * distr[p]; } + } else { + const double small_rate = 1e-14; + const double sign = (wells->type[w] == INJECTOR) ? 1.0 : -1.0; + for (int p = 0; p < np; ++p) { + wellrates_[np*w + p] = small_rate * sign; + } } } // The perforation rates and perforation pressures are From dbd0635fdadde1d6873d03102cbe1e1b30e637fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 11 Mar 2014 12:50:58 +0100 Subject: [PATCH 2/5] Commented choices in initialisation of well rates. --- opm/core/simulator/WellState.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opm/core/simulator/WellState.hpp b/opm/core/simulator/WellState.hpp index adf3fb24..31391458 100644 --- a/opm/core/simulator/WellState.hpp +++ b/opm/core/simulator/WellState.hpp @@ -59,8 +59,10 @@ namespace Opm bhp_[w] = well_controls_get_current_target( ctrl ); } - // Initialize well rates to match controls if type is SURFACE_RATE, - // otherwise set to a small rate with the correct sign. + // Initialize well rates to match controls if type is SURFACE_RATE. + // Otherwise, we cannot set the correct value here, so we assign + // a small rate with the correct sign so that any logic depending on + // that sign will work as expected. if (well_controls_well_is_open( ctrl ) || (well_controls_get_current_type(ctrl) == SURFACE_RATE)) { const double rate_target = well_controls_get_current_target(ctrl); const double * distr = well_controls_get_current_distr( ctrl ); From c46ad990c16c5fe2c57a9aab6c6c57bd1c43d969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 11 Mar 2014 12:51:49 +0100 Subject: [PATCH 3/5] Assert to avoid future surprises. Well types must be either INJECTOR or PRODUCER for now, if we change this in the future, we should check this part of the code as well. --- opm/core/simulator/WellState.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opm/core/simulator/WellState.hpp b/opm/core/simulator/WellState.hpp index 31391458..d46e1254 100644 --- a/opm/core/simulator/WellState.hpp +++ b/opm/core/simulator/WellState.hpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace Opm { @@ -45,6 +46,7 @@ namespace Opm bhp_.resize(nw); wellrates_.resize(nw * np, 0.0); for (int w = 0; w < nw; ++w) { + assert((wells->type[w] == INJECTOR) || (wells->type[w] == PRODUCER)); const WellControls* ctrl = wells->ctrls[w]; // Initialize bhp to be target pressure if // bhp-controlled well, otherwise set to a little From f1377d9729eecf7a8aecb0024a8e192fabb9e7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 11 Mar 2014 12:54:04 +0100 Subject: [PATCH 4/5] Bugfix: || -> && --- opm/core/simulator/WellState.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/simulator/WellState.hpp b/opm/core/simulator/WellState.hpp index d46e1254..c12e68bd 100644 --- a/opm/core/simulator/WellState.hpp +++ b/opm/core/simulator/WellState.hpp @@ -65,7 +65,7 @@ namespace Opm // Otherwise, we cannot set the correct value here, so we assign // a small rate with the correct sign so that any logic depending on // that sign will work as expected. - if (well_controls_well_is_open( ctrl ) || (well_controls_get_current_type(ctrl) == SURFACE_RATE)) { + if (well_controls_well_is_open( ctrl ) && (well_controls_get_current_type(ctrl) == SURFACE_RATE)) { const double rate_target = well_controls_get_current_target(ctrl); const double * distr = well_controls_get_current_distr( ctrl ); for (int p = 0; p < np; ++p) { From d2e6ccec33d829210afec5764a834e83c16f1e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 14 Mar 2014 11:27:20 +0100 Subject: [PATCH 5/5] Fix logic related to open/shut wells initialisation. --- opm/core/simulator/WellState.hpp | 69 ++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/opm/core/simulator/WellState.hpp b/opm/core/simulator/WellState.hpp index c12e68bd..090676ee 100644 --- a/opm/core/simulator/WellState.hpp +++ b/opm/core/simulator/WellState.hpp @@ -48,34 +48,53 @@ namespace Opm for (int w = 0; w < nw; ++w) { assert((wells->type[w] == INJECTOR) || (wells->type[w] == PRODUCER)); const WellControls* ctrl = wells->ctrls[w]; - // Initialize bhp to be target pressure if - // bhp-controlled well, otherwise set to a little - // above or below (depending on if the well is an - // injector or producer) pressure in first perforation - // cell. - if (well_controls_well_is_shut(ctrl) || (well_controls_get_current_type(ctrl) != BHP)) { - const int first_cell = wells->well_cells[wells->well_connpos[w]]; - const double safety_factor = (wells->type[w] == INJECTOR) ? 1.01 : 0.99; - bhp_[w] = safety_factor*state.pressure()[first_cell]; - } else { - bhp_[w] = well_controls_get_current_target( ctrl ); - } - - // Initialize well rates to match controls if type is SURFACE_RATE. - // Otherwise, we cannot set the correct value here, so we assign - // a small rate with the correct sign so that any logic depending on - // that sign will work as expected. - if (well_controls_well_is_open( ctrl ) && (well_controls_get_current_type(ctrl) == SURFACE_RATE)) { - const double rate_target = well_controls_get_current_target(ctrl); - const double * distr = well_controls_get_current_distr( ctrl ); + if (well_controls_well_is_shut(ctrl)) { + // Shut well: + // 1. Assign zero well rates. for (int p = 0; p < np; ++p) { - wellrates_[np*w + p] = rate_target * distr[p]; + wellrates_[np*w + p] = 0.0; + } + // 2. Assign bhp equal to bhp control, if + // applicable, otherwise assign equal to + // first perforation cell pressure. + if (well_controls_get_current_type(ctrl) == BHP) { + bhp_[w] = well_controls_get_current_target( ctrl ); + } else { + const int first_cell = wells->well_cells[wells->well_connpos[w]]; + bhp_[w] = state.pressure()[first_cell]; } } else { - const double small_rate = 1e-14; - const double sign = (wells->type[w] == INJECTOR) ? 1.0 : -1.0; - for (int p = 0; p < np; ++p) { - wellrates_[np*w + p] = small_rate * sign; + // Open well: + // 1. Initialize well rates to match controls + // if type is SURFACE_RATE. Otherwise, we + // cannot set the correct value here, so we + // assign a small rate with the correct + // sign so that any logic depending on that + // sign will work as expected. + if (well_controls_get_current_type(ctrl) == SURFACE_RATE) { + const double rate_target = well_controls_get_current_target(ctrl); + const double * distr = well_controls_get_current_distr( ctrl ); + for (int p = 0; p < np; ++p) { + wellrates_[np*w + p] = rate_target * distr[p]; + } + } else { + const double small_rate = 1e-14; + const double sign = (wells->type[w] == INJECTOR) ? 1.0 : -1.0; + for (int p = 0; p < np; ++p) { + wellrates_[np*w + p] = small_rate * sign; + } + } + // 2. Initialize bhp to be target pressure if + // bhp-controlled well, otherwise set to a + // little above or below (depending on if + // the well is an injector or producer) + // pressure in first perforation cell. + if (well_controls_get_current_type(ctrl) == BHP) { + bhp_[w] = well_controls_get_current_target( ctrl ); + } else { + const int first_cell = wells->well_cells[wells->well_connpos[w]]; + const double safety_factor = (wells->type[w] == INJECTOR) ? 1.01 : 0.99; + bhp_[w] = safety_factor*state.pressure()[first_cell]; } } }