Compdat extraction from new CompletionXXX classes

This commit is contained in:
Kristian Flikka 2014-01-28 21:02:47 +01:00
parent 74c3040c43
commit 7ce9cb9055
3 changed files with 145 additions and 104 deletions

View File

@ -253,6 +253,24 @@ namespace Opm
return; return;
} }
// global_cell is a map from compressed cells to Cartesian grid cells.
// We must make the inverse lookup.
const int* global_cell = grid.global_cell;
const int* cpgdim = grid.cartdims;
std::map<int,int> cartesian_to_compressed;
if (global_cell) {
for (int i = 0; i < grid.number_of_cells; ++i) {
cartesian_to_compressed.insert(std::make_pair(global_cell[i], i));
}
}
else {
for (int i = 0; i < grid.number_of_cells; ++i) {
cartesian_to_compressed.insert(std::make_pair(i, i));
}
}
// Obtain phase usage data. // Obtain phase usage data.
PhaseUsage pu = phaseUsageFromDeck(eclipseState); PhaseUsage pu = phaseUsageFromDeck(eclipseState);
@ -273,123 +291,146 @@ namespace Opm
std::vector<WellConstPtr> wells = schedule->getWells(timeStep); std::vector<WellConstPtr> wells = schedule->getWells(timeStep);
well_names.reserve(wells.size()); well_names.reserve(wells.size());
well_data.reserve(wells.size()); well_data.reserve(wells.size());
wellperf_data.resize(wells.size());
int well_index = 0; int well_index = 0;
for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) { for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) {
WellConstPtr well = (*wellIter); WellConstPtr well = (*wellIter);
well_names_to_index[well->name()] = well_index; { // WELSPECS handling
well_names.push_back(well->name()); well_names_to_index[well->name()] = well_index;
{ well_names.push_back(well->name());
WellData wd; {
// If negative (defaulted), set refdepth to a marker WellData wd;
// value, will be changed after getting perforation // If negative (defaulted), set refdepth to a marker
// data to the centroid of the cell of the top well // value, will be changed after getting perforation
// perforation. // data to the centroid of the cell of the top well
wd.reference_bhp_depth = (well->getRefDepth() < 0.0) ? -1e100 : well->getRefDepth(); // perforation.
wd.welspecsline = -1; wd.reference_bhp_depth = (well->getRefDepth() < 0.0) ? -1e100 : well->getRefDepth();
well_data.push_back(wd); wd.welspecsline = -1;
well_data.push_back(wd);
}
}
{ // COMPDAT handling
CompletionSetConstPtr completionSet = well->getCompletions(timeStep);
for (size_t c=0; c<completionSet->size(); c++) {
CompletionConstPtr completion = completionSet->get(c);
int i = completion->getI() - 1;
int j = completion->getJ() - 1;
int k = completion->getK() - 1;
int cart_grid_indx = i + cpgdim[0]*(j + cpgdim[1]*k);
std::map<int, int>::const_iterator cgit = cartesian_to_compressed.find(cart_grid_indx);
if (cgit == cartesian_to_compressed.end()) {
OPM_THROW(std::runtime_error, "Cell with i,j,k indices " << i << ' ' << j << ' '
<< k << " not found in grid (well = " << well->name() << ')');
}
int cell = cgit->second;
PerfData pd;
pd.cell = cell;
if (completion->getCF() > 0.0) {
pd.well_index = completion->getCF();
} else {
double radius = 0.5*completion->getDiameter();
if (radius <= 0.0) {
radius = 0.5*unit::feet;
OPM_MESSAGE("**** Warning: Well bore internal radius set to " << radius);
}
std::array<double, 3> cubical = getCubeDim(grid, cell);
const double* cell_perm = &permeability[grid.dimensions*grid.dimensions*cell];
pd.well_index = computeWellIndex(radius, cubical, cell_perm,
completion->getDiameter());
}
wellperf_data[well_index].push_back(pd);
}
} }
well_index++; well_index++;
} }
const int num_wells = well_data.size();
wellperf_data.resize(num_wells);
// global_cell is a map from compressed cells to Cartesian grid cells.
// We must make the inverse lookup.
const int* global_cell = grid.global_cell;
const int* cpgdim = grid.cartdims;
std::map<int,int> cartesian_to_compressed;
if (global_cell) {
for (int i = 0; i < grid.number_of_cells; ++i) {
cartesian_to_compressed.insert(std::make_pair(global_cell[i], i));
}
}
else {
for (int i = 0; i < grid.number_of_cells; ++i) {
cartesian_to_compressed.insert(std::make_pair(i, i));
}
}
// Get COMPDAT data
// It is *not* allowed to have multiple lines corresponding to
// the same perforation!
const COMPDAT& compdat = deck.getCOMPDAT();
const int num_compdat = compdat.compdat.size();
for (int kw = 0; kw < num_compdat; ++kw) {
// Extract well name, or the part of the well name that
// comes before the '*'.
std::string name = compdat.compdat[kw].well_;
std::string::size_type len = name.find('*');
if (len != std::string::npos) {
name = name.substr(0, len);
}
// Look for well with matching name.
bool found = false;
for (int wix = 0; wix < num_wells; ++wix) {
if (well_names[wix].compare(0,len, name) == 0) { // equal
// We have a matching name.
int ix = compdat.compdat[kw].grid_ind_[0] - 1;
int jy = compdat.compdat[kw].grid_ind_[1] - 1;
int kz1 = compdat.compdat[kw].grid_ind_[2] - 1;
int kz2 = compdat.compdat[kw].grid_ind_[3] - 1;
WellConstPtr well = schedule->getWell(well_names[wix]); // // Get COMPDAT data
if (ix < 0) { // // It is *not* allowed to have multiple lines corresponding to
// Defaulted I location. Extract from WELSPECS. // // the same perforation!
ix = well->getHeadI() - 1; // const COMPDAT& compdat = deck.getCOMPDAT();
} // const int num_compdat = compdat.compdat.size();
if (jy < 0) { // for (int kw = 0; kw < num_compdat; ++kw) {
// Defaulted J location. Extract from WELSPECS. // // Extract well name, or the part of the well name that
jy = well->getHeadJ() - 1; // // comes before the '*'.
} // std::string name = compdat.compdat[kw].well_;
if (kz1 < 0) { // std::string::size_type len = name.find('*');
// Defaulted KZ1. Use top layer. // if (len != std::string::npos) {
kz1 = 0; // name = name.substr(0, len);
} // }
if (kz2 < 0) { // // Look for well with matching name.
// Defaulted KZ2. Use bottom layer. // bool found = false;
kz2 = cpgdim[2] - 1; // for (int wix = 0; wix < num_wells; ++wix) {
} // if (well_names[wix].compare(0,len, name) == 0) { // equal
// // We have a matching name.
// int ix = compdat.compdat[kw].grid_ind_[0] - 1;
// int jy = compdat.compdat[kw].grid_ind_[1] - 1;
// int kz1 = compdat.compdat[kw].grid_ind_[2] - 1;
// int kz2 = compdat.compdat[kw].grid_ind_[3] - 1;
for (int kz = kz1; kz <= kz2; ++kz) { // WellConstPtr well = schedule->getWell(well_names[wix]);
int cart_grid_indx = ix + cpgdim[0]*(jy + cpgdim[1]*kz); // if (ix < 0) {
std::map<int, int>::const_iterator cgit = // // Defaulted I location. Extract from WELSPECS.
cartesian_to_compressed.find(cart_grid_indx); // ix = well->getHeadI() - 1;
if (cgit == cartesian_to_compressed.end()) { // }
OPM_THROW(std::runtime_error, "Cell with i,j,k indices " << ix << ' ' << jy << ' ' // if (jy < 0) {
<< kz << " not found in grid (well = " << name << ')'); // // Defaulted J location. Extract from WELSPECS.
} // jy = well->getHeadJ() - 1;
int cell = cgit->second; // }
PerfData pd; // if (kz1 < 0) {
pd.cell = cell; // // Defaulted KZ1. Use top layer.
if (compdat.compdat[kw].connect_trans_fac_ > 0.0) { // kz1 = 0;
pd.well_index = compdat.compdat[kw].connect_trans_fac_; // }
} else { // if (kz2 < 0) {
double radius = 0.5*compdat.compdat[kw].diameter_; // // Defaulted KZ2. Use bottom layer.
if (radius <= 0.0) { // kz2 = cpgdim[2] - 1;
radius = 0.5*unit::feet; // }
OPM_MESSAGE("**** Warning: Well bore internal radius set to " << radius);
} // for (int kz = kz1; kz <= kz2; ++kz) {
std::array<double, 3> cubical = getCubeDim(grid, cell); // int cart_grid_indx = ix + cpgdim[0]*(jy + cpgdim[1]*kz);
const double* cell_perm = &permeability[grid.dimensions*grid.dimensions*cell]; // std::map<int, int>::const_iterator cgit =
pd.well_index = computeWellIndex(radius, cubical, cell_perm, // cartesian_to_compressed.find(cart_grid_indx);
compdat.compdat[kw].skin_factor_); // if (cgit == cartesian_to_compressed.end()) {
} // OPM_THROW(std::runtime_error, "Cell with i,j,k indices " << ix << ' ' << jy << ' '
wellperf_data[wix].push_back(pd); // << kz << " not found in grid (well = " << name << ')');
} // }
found = true; // int cell = cgit->second;
break; // PerfData pd;
} // pd.cell = cell;
} // if (compdat.compdat[kw].connect_trans_fac_ > 0.0) {
if (!found) { // pd.well_index = compdat.compdat[kw].connect_trans_fac_;
OPM_THROW(std::runtime_error, "Undefined well name: " << compdat.compdat[kw].well_ // } else {
<< " in COMPDAT"); // double radius = 0.5*compdat.compdat[kw].diameter_;
} // if (radius <= 0.0) {
} // radius = 0.5*unit::feet;
// OPM_MESSAGE("**** Warning: Well bore internal radius set to " << radius);
// }
// std::array<double, 3> cubical = getCubeDim(grid, cell);
// const double* cell_perm = &permeability[grid.dimensions*grid.dimensions*cell];
// pd.well_index = computeWellIndex(radius, cubical, cell_perm,
// compdat.compdat[kw].skin_factor_);
// }
// wellperf_data[wix].push_back(pd);
// }
// found = true;
// break;
// }
// }
// if (!found) {
// OPM_THROW(std::runtime_error, "Undefined well name: " << compdat.compdat[kw].well_
// << " in COMPDAT");
// }
// }
// Set up reference depths that were defaulted. Count perfs. // Set up reference depths that were defaulted. Count perfs.
const int num_wells = well_data.size();
int num_perfs = 0; int num_perfs = 0;
assert(grid.dimensions == 3); assert(grid.dimensions == 3);
for (int w = 0; w < num_wells; ++w) { for (int w = 0; w < num_wells; ++w) {

View File

@ -124,7 +124,7 @@ namespace Opm
// Data // Data
Wells* w_; Wells* w_;
WellCollection well_collection_; WellCollection well_collection_;

View File

@ -26,7 +26,7 @@ WELSPECS
COMPDAT COMPDAT
'INJ1' 1 1 1 2 'OPEN' 1 10.6092 0.5 / 'INJ1' 1 1 1 2 'OPEN' 1 10.6092 0.5 /
'INJ1' 1 1 3 5 'OPEN' 1 12.6092 0.5 / 'INJ1' 1 1 3 5 'OPEN' 1 12.6092 0.5 /
'INJ1' 1 1 2* 'OPEN' 1 14.6092 0.5 / 'INJ1' 1 1 1 1 'OPEN' 1 14.6092 0.5 /
'PROD1' 10 3 3 3 'OPEN' 0 10.6092 0.5 / 'PROD1' 10 3 3 3 'OPEN' 0 10.6092 0.5 /
/ /