#1561 Replacing old combine function for RigCompletionData with new combineEclipseCellCompletions which can calculate WPImult. Assumes completions to always have calculated transmissibility.

This commit is contained in:
astridkbjorke
2017-06-20 08:26:53 +02:00
parent 42dc881cec
commit a6a1ad0f95
5 changed files with 242 additions and 24 deletions

View File

@@ -115,7 +115,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
if (intersection.mainBoreCell && settings.removeLateralsInMainBoreCells()) continue;
double diameter = location.fishbonesSubs->holeDiameter() / 1000;
QString completionMetaData = (location.fishbonesSubs->name(), QString("Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex));
QString completionMetaData = (location.fishbonesSubs->name() + QString(" Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex));
WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc(intersection.lengthsInCell,
diameter / 2,
location.fishbonesSubs->skinFactor(),
@@ -155,8 +155,11 @@ std::vector<RigCompletionData> RicFishbonesTransmissibilityCalculationFeatureImp
bool cellIsActive = activeCellInfo->isActive(cellIndex);
if (!cellIsActive) continue;
//TODO: Only laterals should contribute to reduction!
size_t NumberOfCellContributions = wellBoreParts.size();
//Simplest implementation possible, this can be improved later
//TODO: Find main bore direction and use this as direction in which to split cell
QString directionToSplitCellVolume = "DX";
for (WellBorePartForTransCalc wellBorePart : wellBoreParts)
@@ -165,6 +168,8 @@ std::vector<RigCompletionData> RicFishbonesTransmissibilityCalculationFeatureImp
completion.addMetadata(wellBorePart.metaData, "");
if (settings.computeTransmissibility())
{
double transmissibility = RicWellPathExportCompletionDataFeature::calculateTransmissibility(settings.caseToApply,
wellPath,
wellBorePart.lengthsInCell,

View File

@@ -138,7 +138,8 @@ std::vector<RimWellPath*> RicWellPathExportCompletionDataFeature::selectedWellPa
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeature::exportCompletions(const std::vector<RimWellPath*>& wellPaths, const RicExportCompletionDataSettingsUi& exportSettings)
void RicWellPathExportCompletionDataFeature::exportCompletions(const std::vector<RimWellPath*>& wellPaths,
const RicExportCompletionDataSettingsUi& exportSettings)
{
if (exportSettings.caseToApply() == nullptr)
@@ -184,9 +185,8 @@ void RicWellPathExportCompletionDataFeature::exportCompletions(const std::vector
return;
}
}
std::map<IJKCellIndex, std::vector<RigCompletionData> > completionData;
std::map<IJKCellIndex, std::vector<RigCompletionData> > completionsPerEclipseCell;
for (auto wellPath : usedWellPaths)
{
@@ -195,26 +195,24 @@ void RicWellPathExportCompletionDataFeature::exportCompletions(const std::vector
if (exportSettings.includePerforations)
{
std::vector<RigCompletionData> perforationCompletionData = generatePerforationsCompdatValues(wellPath, exportSettings);
appendCompletionData(&completionData, perforationCompletionData);
appendCompletionData(&completionsPerEclipseCell, perforationCompletionData);
}
if (exportSettings.includeFishbones)
{
// std::vector<RigCompletionData> fishbonesCompletionData = RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneLateralsCompdatValues(wellPath, exportSettings);
// appendCompletionData(&completionData, fishbonesCompletionData);
// std::vector<RigCompletionData> fishbonesWellPathCompletionData = RicFishbonesTransmissibilityCalculationFeatureImp::generateFishbonesImportedLateralsCompdatValues(wellPath, exportSettings);
// appendCompletionData(&completionData, fishbonesWellPathCompletionData);
std::vector<RigCompletionData> fishbonesCompletionData = RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume(wellPath, exportSettings);
appendCompletionData(&completionData, fishbonesCompletionData);
appendCompletionData(&completionsPerEclipseCell, fishbonesCompletionData);
}
}
// Merge map into a vector of values
std::vector<RigCompletionData> completions;
for (auto& data : completionData)
//std::map < IJKCellIndex, std::map<QString, RigCompletionData >> combinedCompletionDataPerEclipseCell;
//Should be moved to map instead of vector
for (auto& data : completionsPerEclipseCell)
{
completions.push_back(RigCompletionData::combine(data.second));
//completions.push_back(RigCompletionData::combine(data.second));
completions.push_back(combineEclipseCellCompletions(data.second, exportSettings));
}
const QString eclipseCaseName = exportSettings.caseToApply->caseUserDescription();
@@ -259,11 +257,97 @@ void RicWellPathExportCompletionDataFeature::exportCompletions(const std::vector
}
}
//==================================================================================================
///
//==================================================================================================
RigCompletionData RicWellPathExportCompletionDataFeature::combineEclipseCellCompletions(const std::vector<RigCompletionData>& completions,
const RicExportCompletionDataSettingsUi& settings)
{
CVF_ASSERT(!completions.empty());
QString wellName = completions[0].wellName();
IJKCellIndex cellIndexIJK = completions[0].cellIndex();
RigMainGrid* grid = settings.caseToApply->eclipseCaseData()->mainGrid();
size_t cellIndex = grid->cellIndexFromIJK(cellIndexIJK.i, cellIndexIJK.j, cellIndexIJK.k);
RigCompletionData::CompletionType completionType = completions[0].completionType();
//completion type, skin factor, well bore diameter and cell direction are taken from (first) main bore,
//if no main bore they are taken from first completion
double skinfactor = completions[0].skinFactor();
double wellBoreDiameter = completions[0].diameter();
CellDirection cellDirection = completions[0].direction();
for (const RigCompletionData& completion : completions)
{
if (completion.isMainBore())
{
skinfactor = completion.skinFactor();
wellBoreDiameter = completion.diameter();
cellDirection = completion.direction();
break;
}
}
RigCompletionData resultCompletion(wellName, cellIndexIJK);
double totalTrans = 0.0;
for (const RigCompletionData& completion : completions)
{
if (completion.completionType() != completions[0].completionType())
{
RiaLogging::error(QString("Cannot combine completions of different types in same cell [%1, %2, %3]").arg(cellIndexIJK.i).arg(cellIndexIJK.j).arg(cellIndexIJK.k));
return resultCompletion; //Returning empty completion, should not be exported
}
if (completion.wellName() != completions[0].wellName())
{
RiaLogging::error(QString("Cannot combine completions from different wells in same cell [%1, %2, %3]").arg(cellIndexIJK.i).arg(cellIndexIJK.j).arg(cellIndexIJK.k));
return resultCompletion; //Returning empty completion, should not be exported
}
if (completion.transmissibility() == HUGE_VAL)
{
RiaLogging::error(QString("Transmissibility calculation has failed for cell [%1, %2, %3]").arg(cellIndexIJK.i).arg(cellIndexIJK.j).arg(cellIndexIJK.k));
return resultCompletion; //Returning empty completion, should not be exported
}
totalTrans = totalTrans + completion.transmissibility();
}
if (settings.computeTransmissibility() && !settings.includeWpimult) //TODO: replace with explicitTransmissibilityExport setting
{
resultCompletion.setCombinedValuesExplicitTrans(totalTrans, completionType);
}
if (settings.includeWpimult) //TODO: replace with implicitTransmissibilityExportByWPImult
{
//calculate trans for main bore - but as Eclipse will do it!
double transmissibilityEclipseCalculation = RicWellPathExportCompletionDataFeature::calculateTransmissibilityAsEclipseDoes(settings.caseToApply(),
skinfactor,
wellBoreDiameter / 2,
cellIndex,
cellDirection);
double wpimult = totalTrans / transmissibilityEclipseCalculation;
resultCompletion.setCombinedValuesImplicitTransWPImult(wpimult, cellDirection, skinfactor, wellBoreDiameter, completionType);
}
return resultCompletion;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeature::printCompletionsToFile(const QString& exportFolder, const QString& fileName, std::vector<RigCompletionData>& completions, bool includeWpimult)
{
//TODO: Check that completion is ready for export
//TODO: Use wpimult instead of count for export!
QString filePath = QDir(exportFolder).filePath(fileName);
QFile exportFile(filePath);
if (!exportFile.open(QIODevice::WriteOnly))
@@ -280,6 +364,8 @@ void RicWellPathExportCompletionDataFeature::printCompletionsToFile(const QStrin
// Print completion data
generateCompdatTable(formatter, completions);
if (includeWpimult)
{
generateWpimultTable(formatter, completions);
@@ -708,3 +794,67 @@ double RicWellPathExportCompletionDataFeature::calculateTransmissibility(RimEcli
return RigTransmissibilityEquations::totalConnectionFactor(transx, transy, transz);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RicWellPathExportCompletionDataFeature::calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase,
double skinFactor,
double wellRadius,
size_t cellIndex,
CellDirection direction)
{
RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData();
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DX");
cvf::ref<RigResultAccessor> dxAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RifReaderInterface::MATRIX_RESULTS, 0, "DX");
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DY");
cvf::ref<RigResultAccessor> dyAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RifReaderInterface::MATRIX_RESULTS, 0, "DY");
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DZ");
cvf::ref<RigResultAccessor> dzAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RifReaderInterface::MATRIX_RESULTS, 0, "DZ");
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PERMX");
cvf::ref<RigResultAccessor> permxAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RifReaderInterface::MATRIX_RESULTS, 0, "PERMX");
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PERMY");
cvf::ref<RigResultAccessor> permyAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RifReaderInterface::MATRIX_RESULTS, 0, "PERMY");
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PERMZ");
cvf::ref<RigResultAccessor> permzAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RifReaderInterface::MATRIX_RESULTS, 0, "PERMZ");
double dx = dxAccessObject->cellScalarGlobIdx(cellIndex);
double dy = dyAccessObject->cellScalarGlobIdx(cellIndex);
double dz = dzAccessObject->cellScalarGlobIdx(cellIndex);
double permx = permxAccessObject->cellScalarGlobIdx(cellIndex);
double permy = permxAccessObject->cellScalarGlobIdx(cellIndex);
double permz = permxAccessObject->cellScalarGlobIdx(cellIndex);
//TODO: EclipseCaseData should use RiaEclipseUnitTools to simplify this!!!
RiaEclipseUnitTools::UnitSystem units = RiaEclipseUnitTools::UNITS_UNKNOWN;
if (eclipseCase->eclipseCaseData()->unitsType() == RigEclipseCaseData::UNITS_FIELD)
{
units = RiaEclipseUnitTools::UNITS_FIELD;
}
else if (eclipseCase->eclipseCaseData()->unitsType() == RigEclipseCaseData::UNITS_METRIC)
{
units = RiaEclipseUnitTools::UNITS_METRIC;
}
double darcy = RiaEclipseUnitTools::darcysConstant(units);
double trans = cvf::UNDEFINED_DOUBLE;
if (direction == CellDirection::DIR_I)
{
trans = RigTransmissibilityEquations::wellBoreTransmissibilityComponent(dx, permy, permz, dy, dz, wellRadius, skinFactor, darcy);
}
else if (direction == CellDirection::DIR_J)
{
trans = RigTransmissibilityEquations::wellBoreTransmissibilityComponent(dy, permx, permz, dx, dz, wellRadius, skinFactor, darcy);
}
else if (direction == CellDirection::DIR_K)
{
trans = RigTransmissibilityEquations::wellBoreTransmissibilityComponent(dz, permy, permx, dy, dx, wellRadius, skinFactor, darcy);
}
return trans;
}

View File

@@ -136,8 +136,23 @@ public:
static void markWellPathCells(const std::vector<size_t>& wellPathCells, std::vector<WellSegmentLocation>* locations);
static CellDirection calculateDirectionInCell(RimEclipseCase* eclipseCase, size_t cellIndex, const cvf::Vec3d& lengthsInCell);
static double calculateTransmissibility(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, const cvf::Vec3d& internalCellLengths, double skinFactor, double wellRadius, size_t cellIndex, size_t volumeScaleConstant = 1, QString directionForVolumeScaling = "DX");
static double calculateTransmissibility(RimEclipseCase* eclipseCase,
const RimWellPath* wellPath,
const cvf::Vec3d& internalCellLengths,
double skinFactor,
double wellRadius,
size_t cellIndex,
size_t volumeScaleConstant = 1,
QString directionForVolumeScaling = "DX");
static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase,
double skinFactor,
double wellRadius,
size_t cellIndex,
CellDirection direction);
private:
static RigCompletionData combineEclipseCellCompletions(const std::vector<RigCompletionData>& completions,
const RicExportCompletionDataSettingsUi& settings);
static void exportCompletions(const std::vector<RimWellPath*>& wellPaths, const RicExportCompletionDataSettingsUi& exportSettings);
static void printCompletionsToFile(const QString& exportFolder, const QString& fileName, std::vector<RigCompletionData>& completions, bool includeWpimult);
static std::vector<RigCompletionData> getCompletionsForWellAndCompletionType(const std::vector<RigCompletionData>& completions, const QString& wellName, RigCompletionData::CompletionType completionType);