From c0ddb9707ed54bd752dad658c3cb6f284bd1f85b 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 39fbdbd3e..adf3fb244 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 db6a36d1fdbe9544b8d52d751805fedf7337c266 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 adf3fb244..313914587 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 a592a23153addb1db664c7e2d129028093d2ed0e 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 313914587..d46e12544 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 c0fd11710331e7faba9722eed6a341642939f974 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 d46e12544..c12e68bd4 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 a13f7b990f83e9c3545c8f34a3799e14730f4919 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 c12e68bd4..090676ee5 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]; } } }