From 40ec39fa7199f0625b3cb4d1ee2e7cba715508ab Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Tue, 6 Oct 2015 15:54:20 +0200 Subject: [PATCH 1/3] Add boolean flag to determine whether crossflow is allowed in a well This PR adds allow_cf to the wells structure that determine whether crossflow is allowed or not. An extra argument is added to addWell(..) to specify the allow_cf flag. --- opm/core/wells.h | 7 +++++++ opm/core/wells/WellsManager.hpp | 1 + opm/core/wells/WellsManager_impl.hpp | 7 +++++++ opm/core/wells/wells.c | 17 +++++++++++++++-- tests/test_wells.cpp | 10 +++++----- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/opm/core/wells.h b/opm/core/wells.h index 4d749cda7..d6737b57d 100644 --- a/opm/core/wells.h +++ b/opm/core/wells.h @@ -106,6 +106,11 @@ struct Wells * Internal management structure. */ void *data; + + /** + * Array of booleans, if true crossflow is allowed in the well. + */ + bool *allow_cf; }; @@ -185,6 +190,7 @@ create_wells(int nphases, int nwells, int nperf); * ideally be track ordered. * \param[in] WI Well production index per perforation, or NULL. * \param[in] name Name of new well. NULL if no name. + * \param[in] allow_cf Boolean flag to determine whether crossflow is allowed or not. * \param[in,out] W Existing set of wells to which new well will * be added. * @@ -198,6 +204,7 @@ add_well(enum WellType type , const int *cells , const double *WI , const char *name , + bool allow_cf , struct Wells *W ); diff --git a/opm/core/wells/WellsManager.hpp b/opm/core/wells/WellsManager.hpp index e29a10169..02aacc1ba 100644 --- a/opm/core/wells/WellsManager.hpp +++ b/opm/core/wells/WellsManager.hpp @@ -38,6 +38,7 @@ namespace Opm struct WellData { WellType type; + bool allowCrossFlow; // WellControlType control; // double target; double reference_bhp_depth; diff --git a/opm/core/wells/WellsManager_impl.hpp b/opm/core/wells/WellsManager_impl.hpp index ac2fd9031..e1b7ed0e7 100644 --- a/opm/core/wells/WellsManager_impl.hpp +++ b/opm/core/wells/WellsManager_impl.hpp @@ -247,6 +247,12 @@ void WellsManager::createWellsFromSpecs(std::vector& wells, size_t wd.type = INJECTOR; else wd.type = PRODUCER; + + if (well->getAllowCrossFlow()) { + wd.allowCrossFlow = true; + } else { + wd.allowCrossFlow = false; + } well_data.push_back(wd); } } @@ -293,6 +299,7 @@ void WellsManager::createWellsFromSpecs(std::vector& wells, size_t perf_cells.data(), perf_prodind.data(), well_names[w].c_str(), + well_data[w].allowCrossFlow, w_); if (!ok) { diff --git a/opm/core/wells/wells.c b/opm/core/wells/wells.c index 53e8590c3..a30a8380e 100644 --- a/opm/core/wells/wells.c +++ b/opm/core/wells/wells.c @@ -85,6 +85,7 @@ wells_allocate(int nwells, struct Wells *W) void *type, *depth_ref, *comp_frac; void *well_connpos; void *ctrls, *name; + bool *allow_cf; np = W->number_of_phases; @@ -93,6 +94,7 @@ wells_allocate(int nwells, struct Wells *W) comp_frac = realloc(W->comp_frac, np * nwells * sizeof *W->comp_frac); ctrls = realloc(W->ctrls , 1 * nwells * sizeof *W->ctrls); name = realloc(W->name , 1 * nwells * sizeof *W->name); + allow_cf = realloc(W->allow_cf , 1 * nwells * sizeof *W->allow_cf); well_connpos = realloc(W->well_connpos, (nwells + 1) * sizeof *W->well_connpos); @@ -104,8 +106,9 @@ wells_allocate(int nwells, struct Wells *W) if (well_connpos != NULL) { W->well_connpos = well_connpos; ok++; } if (ctrls != NULL) { W->ctrls = ctrls ; ok++; } if (name != NULL) { W->name = name ; ok++; } + if (allow_cf != NULL) { W->allow_cf = allow_cf ; ok++; } - return ok == 6; + return ok == 7; } @@ -143,6 +146,7 @@ initialise_new_wells(int nwells, struct Wells *W) W->type [w] = PRODUCER; W->depth_ref[w] = -1.0; W->name [w] = NULL; + W->allow_cf [w] = false; for (p = 0; p < W->number_of_phases; ++p) { W->comp_frac[W->number_of_phases*w + p] = 0.0; @@ -274,6 +278,7 @@ create_wells(int nphases, int nwells, int nperf) W->ctrls = NULL; W->name = NULL; + W->allow_cf = false; W->data = create_well_mgmt(); @@ -326,6 +331,7 @@ destroy_wells(struct Wells *W) free(W->comp_frac); free(W->depth_ref); free(W->type); + free(W->allow_cf); } free(W); @@ -358,6 +364,7 @@ add_well(enum WellType type , const int *cells , const double *WI , /* Well index per perf (or NULL) */ const char *name , /* Well name (or NULL) */ + bool allow_cf , struct Wells *W ) /* ---------------------------------------------------------------------- */ { @@ -398,6 +405,7 @@ add_well(enum WellType type , if (ok) { W->type [nw] = type ; W->depth_ref[nw] = depth_ref; + W->allow_cf [nw] = allow_cf; if (name != NULL) { /* May return NULL, but that's fine for the current @@ -503,7 +511,7 @@ clone_wells(const struct Wells *W) comp_frac = W->comp_frac != NULL ? W->comp_frac + w*np : NULL; ok = add_well(W->type[ w ], W->depth_ref[ w ], nperf, - comp_frac, cells, WI, W->name[ w ], newWells); + comp_frac, cells, WI, W->name[ w ], W->allow_cf[ w ], newWells); if (ok) { ok = (ctrl = well_controls_clone(W->ctrls[w])) != NULL; @@ -580,6 +588,11 @@ wells_equal(const struct Wells *W1, const struct Wells *W2 , bool verbose) if (verbose) printf("Well controls are different for well[%d]:%s \n",i,W1->name[i]); } + if (W1->allow_cf[i] != W2->allow_cf[i]) { + are_equal = false; + if (verbose) + printf("Well->allow_cf[%d] different %d %d \n",i , W1->type[i] , W2->type[i] ); + } } diff --git a/tests/test_wells.cpp b/tests/test_wells.cpp index 366fb3912..de1acb323 100644 --- a/tests/test_wells.cpp +++ b/tests/test_wells.cpp @@ -56,11 +56,11 @@ BOOST_AUTO_TEST_CASE(Construction) const double ifrac[] = { 1.0, 0.0 }; const bool ok0 = add_well(INJECTOR, 0.0, 1, &ifrac[0], &cells[0], - &WI, "INJECTOR", W.get()); + &WI, "INJECTOR", true, W.get()); const double pfrac[] = { 0.0, 0.0 }; const bool ok1 = add_well(PRODUCER, 0.0, 1, &pfrac[0], &cells[1], - &WI, "PRODUCER", W.get()); + &WI, "PRODUCER", true, W.get()); if (ok0 && ok1) { BOOST_CHECK_EQUAL(W->number_of_phases, nphases); @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(Controls) const double ifrac[] = { 1.0, 0.0 }; const bool ok = add_well(INJECTOR, 0.0, nperfs, &ifrac[0], &cells[0], - &WI[0], "INJECTOR", W.get()); + &WI[0], "INJECTOR", true, W.get()); if (ok) { const double distr[] = { 1.0, 0.0 }; @@ -151,11 +151,11 @@ BOOST_AUTO_TEST_CASE(Copy) const double ifrac[] = { 1.0, 0.0 }; const bool ok0 = add_well(INJECTOR, 0.0, 1, &ifrac[0], &cells[0], - &WI, "INJECTOR", W1.get()); + &WI, "INJECTOR", true, W1.get()); const double pfrac[] = { 0.0, 0.0 }; const bool ok1 = add_well(PRODUCER, 0.0, 1, &pfrac[0], &cells[1], - &WI, "PRODUCER", W1.get()); + &WI, "PRODUCER", true, W1.get()); bool ok = ok0 && ok1; for (int w = 0; ok && (w < W1->number_of_wells); ++w) { From cf35ecbb059b794bc6bb20fdf83389eefdf1c561 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Wed, 7 Oct 2015 12:49:05 +0200 Subject: [PATCH 2/3] Avoid using bool in the c code --- opm/core/wells.h | 14 ++++++++------ opm/core/wells/wells.c | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/opm/core/wells.h b/opm/core/wells.h index d6737b57d..32c4431ff 100644 --- a/opm/core/wells.h +++ b/opm/core/wells.h @@ -102,15 +102,17 @@ struct Wells */ char **name; + /** + * Array of flags indicating whether crossflow is allowed or not + * if allow_cf[w] == 0 (false) then crossflow is not allowed in well w. + */ + int *allow_cf; + /** * Internal management structure. */ void *data; - /** - * Array of booleans, if true crossflow is allowed in the well. - */ - bool *allow_cf; }; @@ -190,7 +192,7 @@ create_wells(int nphases, int nwells, int nperf); * ideally be track ordered. * \param[in] WI Well production index per perforation, or NULL. * \param[in] name Name of new well. NULL if no name. - * \param[in] allow_cf Boolean flag to determine whether crossflow is allowed or not. + * \param[in] allow_cf Flag to determine whether crossflow is allowed or not. * \param[in,out] W Existing set of wells to which new well will * be added. * @@ -204,7 +206,7 @@ add_well(enum WellType type , const int *cells , const double *WI , const char *name , - bool allow_cf , + int allow_cf , struct Wells *W ); diff --git a/opm/core/wells/wells.c b/opm/core/wells/wells.c index a30a8380e..026b470e3 100644 --- a/opm/core/wells/wells.c +++ b/opm/core/wells/wells.c @@ -85,7 +85,7 @@ wells_allocate(int nwells, struct Wells *W) void *type, *depth_ref, *comp_frac; void *well_connpos; void *ctrls, *name; - bool *allow_cf; + void *allow_cf; np = W->number_of_phases; @@ -146,7 +146,7 @@ initialise_new_wells(int nwells, struct Wells *W) W->type [w] = PRODUCER; W->depth_ref[w] = -1.0; W->name [w] = NULL; - W->allow_cf [w] = false; + W->allow_cf [w] = 1; for (p = 0; p < W->number_of_phases; ++p) { W->comp_frac[W->number_of_phases*w + p] = 0.0; @@ -278,7 +278,7 @@ create_wells(int nphases, int nwells, int nperf) W->ctrls = NULL; W->name = NULL; - W->allow_cf = false; + W->allow_cf = NULL; W->data = create_well_mgmt(); @@ -364,7 +364,7 @@ add_well(enum WellType type , const int *cells , const double *WI , /* Well index per perf (or NULL) */ const char *name , /* Well name (or NULL) */ - bool allow_cf , + int allow_cf , struct Wells *W ) /* ---------------------------------------------------------------------- */ { From da44c2cfd6ad2a943acf81e2e9538d25f1414063 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Wed, 7 Oct 2015 12:50:00 +0200 Subject: [PATCH 3/3] Set wd.allowCrossFlow directly --- opm/core/wells/WellsManager_impl.hpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/opm/core/wells/WellsManager_impl.hpp b/opm/core/wells/WellsManager_impl.hpp index e1b7ed0e7..97e57d3cc 100644 --- a/opm/core/wells/WellsManager_impl.hpp +++ b/opm/core/wells/WellsManager_impl.hpp @@ -248,11 +248,7 @@ void WellsManager::createWellsFromSpecs(std::vector& wells, size_t else wd.type = PRODUCER; - if (well->getAllowCrossFlow()) { - wd.allowCrossFlow = true; - } else { - wd.allowCrossFlow = false; - } + wd.allowCrossFlow = well->getAllowCrossFlow(); well_data.push_back(wd); } }