diff --git a/opm/core/wells.h b/opm/core/wells.h index 32c4431f..57572550 100644 --- a/opm/core/wells.h +++ b/opm/core/wells.h @@ -91,6 +91,10 @@ struct Wells */ double *WI; + /** + * Saturation table number , same size and structure as well_cells. + */ + int *sat_table_id; /** * Well controls, one set of controls for each well. @@ -205,6 +209,7 @@ add_well(enum WellType type , const double *comp_frac, const int *cells , const double *WI , + const int *sat_table_id, const char *name , int allow_cf , struct Wells *W ); diff --git a/opm/core/wells/WellsManager.hpp b/opm/core/wells/WellsManager.hpp index adcbef84..aa791963 100644 --- a/opm/core/wells/WellsManager.hpp +++ b/opm/core/wells/WellsManager.hpp @@ -56,6 +56,7 @@ namespace Opm { int cell; double well_index; + int satnumid; }; /// This class manages a Wells struct in the sense that it /// encapsulates creation and destruction of the wells diff --git a/opm/core/wells/WellsManager_impl.hpp b/opm/core/wells/WellsManager_impl.hpp index cac0df18..743eb3c9 100644 --- a/opm/core/wells/WellsManager_impl.hpp +++ b/opm/core/wells/WellsManager_impl.hpp @@ -220,6 +220,7 @@ void WellsManager::createWellsFromSpecs(std::vector& wells, size_t completion.getDirection(), ntg[cell]); } + pd.satnumid = completion.getSatTableId(); pd.well_index *= wellPi; } wellperf_data[active_well_index].push_back(pd); @@ -272,10 +273,12 @@ void WellsManager::createWellsFromSpecs(std::vector& wells, size_t const int w_num_perf = wellperf_data[w].size(); std::vector perf_cells (w_num_perf); std::vector perf_prodind(w_num_perf); + std::vector perf_satnumid(w_num_perf); for (int perf = 0; perf < w_num_perf; ++perf) { perf_cells [perf] = wellperf_data[w][perf].cell; perf_prodind[perf] = wellperf_data[w][perf].well_index; + perf_satnumid[perf] = wellperf_data[w][perf].satnumid; } const double* comp_frac = NULL; @@ -289,6 +292,7 @@ void WellsManager::createWellsFromSpecs(std::vector& wells, size_t comp_frac, perf_cells.data(), perf_prodind.data(), + perf_satnumid.data(), well_names[w].c_str(), well_data[w].allowCrossFlow, w_); diff --git a/opm/core/wells/wells.c b/opm/core/wells/wells.c index 75827697..3689ba70 100644 --- a/opm/core/wells/wells.c +++ b/opm/core/wells/wells.c @@ -118,16 +118,18 @@ perfs_allocate(int nperf, struct Wells *W) /* ---------------------------------------------------------------------- */ { int ok; - void *well_cells, *WI; + void *well_cells, *WI, *sat_table_id; well_cells = realloc(W->well_cells, nperf * sizeof *W->well_cells); WI = realloc(W->WI , nperf * sizeof *W->WI ); + sat_table_id = realloc(W->sat_table_id , nperf * sizeof *W->sat_table_id ); ok = 0; if (well_cells != NULL) { W->well_cells = well_cells; ok++; } if (WI != NULL) { W->WI = WI ; ok++; } + if (sat_table_id != NULL) { W->sat_table_id = sat_table_id ; ok++; } - return ok == 2; + return ok == 3; } @@ -185,6 +187,7 @@ initialise_new_perfs(int nperf, struct Wells *W) for (k = m->perf_cpty; k < nperf; k++) { W->well_cells[k] = -1 ; W->WI [k] = 0.0; + W->sat_table_id[k] = -1; } } @@ -275,6 +278,7 @@ create_wells(int nphases, int nwells, int nperf) W->well_connpos = malloc(1 * sizeof *W->well_connpos); W->well_cells = NULL; W->WI = NULL; + W->sat_table_id = NULL; W->ctrls = NULL; W->name = NULL; @@ -326,6 +330,7 @@ destroy_wells(struct Wells *W) free(W->name); free(W->ctrls); free(W->WI); + free(W->sat_table_id); free(W->well_cells); free(W->well_connpos); free(W->comp_frac); @@ -363,6 +368,7 @@ add_well(enum WellType type , const double *comp_frac, /* Injection fraction or NULL */ const int *cells , const double *WI , /* Well index per perf (or NULL) */ + const int *sat_table_id, /*Saturation table id per perf (or NULL) */ const char *name , /* Well name (or NULL) */ int allow_cf , struct Wells *W ) @@ -400,6 +406,9 @@ add_well(enum WellType type , if (WI != NULL) { memcpy(W->WI + off, WI, nperf * sizeof *W->WI); } + if (sat_table_id != NULL) { + memcpy(W->sat_table_id + off, sat_table_id, nperf * sizeof *W->sat_table_id); + } } if (ok) { @@ -485,7 +494,7 @@ clone_wells(const struct Wells *W) /* ---------------------------------------------------------------------- */ { int np, nperf, ok, pos, w; - const int *cells; + const int *cells, *sat_table_id; const double *WI, *comp_frac; struct WellControls *ctrl; @@ -508,10 +517,11 @@ clone_wells(const struct Wells *W) cells = W->well_cells + pos; WI = W->WI != NULL ? W->WI + pos : NULL; + sat_table_id = W->sat_table_id != NULL ? W->sat_table_id + pos : NULL; 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 ], W->allow_cf[ w ], newWells); + comp_frac, cells, WI, sat_table_id, W->name[ w ], W->allow_cf[ w ], newWells); if (ok) { ok = (ctrl = well_controls_clone(W->ctrls[w])) != NULL; @@ -630,6 +640,7 @@ wells_equal(const struct Wells *W1, const struct Wells *W2 , bool verbose) are_equal = are_equal && (memcmp(W1->well_cells, W2->well_cells, number_of_perforations * sizeof *W1->well_cells ) == 0); are_equal = are_equal && (memcmp(W1->WI, W2->WI, number_of_perforations * sizeof *W1->WI ) == 0); + are_equal = are_equal && (memcmp(W1->sat_table_id, W2->sat_table_id, number_of_perforations * sizeof *W1->sat_table_id ) == 0); } return are_equal; diff --git a/tests/test_wells.cpp b/tests/test_wells.cpp index de1acb32..4c4f102b 100644 --- a/tests/test_wells.cpp +++ b/tests/test_wells.cpp @@ -53,14 +53,15 @@ BOOST_AUTO_TEST_CASE(Construction) if (W) { int cells[] = { 0, 9 }; double WI = 1.0; + int sat_table_id = -1; const double ifrac[] = { 1.0, 0.0 }; const bool ok0 = add_well(INJECTOR, 0.0, 1, &ifrac[0], &cells[0], - &WI, "INJECTOR", true, W.get()); + &WI, &sat_table_id,"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", true, W.get()); + &WI, &sat_table_id,"PRODUCER", true, W.get()); if (ok0 && ok1) { BOOST_CHECK_EQUAL(W->number_of_phases, nphases); @@ -97,9 +98,10 @@ BOOST_AUTO_TEST_CASE(Controls) int cells[] = { 0 , 9 }; double WI [] = { 1.0, 1.0 }; const double ifrac[] = { 1.0, 0.0 }; + int sat_table_id = -1; const bool ok = add_well(INJECTOR, 0.0, nperfs, &ifrac[0], &cells[0], - &WI[0], "INJECTOR", true, W.get()); + &WI[0], &sat_table_id, "INJECTOR", true, W.get()); if (ok) { const double distr[] = { 1.0, 0.0 }; @@ -149,13 +151,15 @@ BOOST_AUTO_TEST_CASE(Copy) int cells[] = { 0, 9 }; const double WI = 1.0; const double ifrac[] = { 1.0, 0.0 }; + int sat_table_id = -1; + const bool ok0 = add_well(INJECTOR, 0.0, 1, &ifrac[0], &cells[0], - &WI, "INJECTOR", true, W1.get()); + &WI, &sat_table_id, "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", true, W1.get()); + &WI, &sat_table_id, "PRODUCER", true, W1.get()); bool ok = ok0 && ok1; for (int w = 0; ok && (w < W1->number_of_wells); ++w) { diff --git a/tutorials/tutorial4.cpp b/tutorials/tutorial4.cpp index 5eee336a..e37e86f1 100644 --- a/tutorials/tutorial4.cpp +++ b/tutorials/tutorial4.cpp @@ -324,10 +324,11 @@ try for (int i = 0; i < num_wells; ++i) { const int well_cells = i*nx; const double well_index = 1; + const int sat_table_id = -1; std::stringstream well_name; well_name << "well" << i; bool allowCrossFlow = true; - add_well(PRODUCER, 0, 1, NULL, &well_cells, &well_index, + add_well(PRODUCER, 0, 1, NULL, &well_cells, &well_index, &sat_table_id, well_name.str().c_str(), allowCrossFlow, wells); } /// \internal[well cells]