#3233, #3234 Multi segment well fracture: make lengths relative and implement along the well fractures.

This commit is contained in:
Gaute Lindkvist
2018-08-20 14:46:05 +02:00
parent e1c3c830cf
commit 5c635fa42d
4 changed files with 231 additions and 151 deletions

View File

@@ -449,24 +449,22 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
{
formatter.comment("Main stem");
double depth = 0;
double length = 0;
double previousMD = startMD;
double previousTVD = startTVD;
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
for (const RicMswWellSegment& location : exportInfo.wellSegmentLocations())
{
double depth = 0;
double length = 0;
if (exportInfo.lengthAndDepthText() == QString("INC"))
{
depth = location.trueVerticalDepth() - previousTVD;
length = location.measuredDepth() - previousMD;
depth = location.deltaTVD();
length = location.deltaMD();
}
else
{
depth += location.trueVerticalDepth() - previousTVD;
length += location.measuredDepth() - previousMD;
depth = location.endTVD();
length = location.endMD();
}
QString comment = QString("Segment for %1").arg(location.label());
QString comment = location.label();
if (location.subIndex() != cvf::UNDEFINED_SIZE_T)
{
comment += QString(", sub %1").arg(location.subIndex());
@@ -480,9 +478,6 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
formatter.add(exportInfo.linerDiameter());
formatter.add(exportInfo.roughnessFactor());
formatter.rowCompleted();
previousMD = location.measuredDepth();
previousTVD = location.trueVerticalDepth();
}
}
@@ -490,7 +485,7 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
formatter.comment("Laterals");
formatter.comment("Diam: MSW - Tubing Radius");
formatter.comment("Rough: MSW - Open Hole Roughness Factor");
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
for (const RicMswWellSegment& location : exportInfo.wellSegmentLocations())
{
if (location.completions().empty())
{
@@ -501,7 +496,7 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
{
if (completion.completionType() == RigCompletionData::ICD) // Found ICD
{
formatter.comment("ICD");
formatter.comment(completion.label());
formatter.add(completion.subSegments().front().segmentNumber());
formatter.add(completion.subSegments().front().segmentNumber());
formatter.add(completion.branchNumber());
@@ -515,14 +510,14 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
else {
if (completion.completionType() == RigCompletionData::FISHBONES)
{
formatter.comment(QString("%1 : Sub index %2 - Lateral %3")
formatter.comment(QString("%1 : Sub index %2 - %3")
.arg(location.label())
.arg(location.subIndex())
.arg(completion.index()));
.arg(completion.label()));
}
else if (completion.completionType() == RigCompletionData::FRACTURE)
{
formatter.comment(QString("%1").arg(location.label()));
formatter.comment(QString("%1 connected to %2").arg(completion.label()).arg(location.label()));
}
for (const RicWellSubSegment& subSegment : completion.subSegments())
{
@@ -613,22 +608,25 @@ void RicWellPathExportCompletionDataFeatureImpl::generateCompsegTable(RifEclipse
formatter.header(allHeaders);
}
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
for (const RicMswWellSegment& location : exportInfo.wellSegmentLocations())
{
double startMD = location.startMD();
for (const RicWellSegmentCompletion& completion : location.completions())
{
double aggregatedLength = 0;
if (completion.completionType() == RigCompletionData::FRACTURE)
{
aggregatedLength = location.measuredDepth();
}
for (const RicWellSubSegment& segment : completion.subSegments())
{
if (completion.completionType() == RigCompletionData::ICD)
{
startMD = segment.startMD();
}
for (const RicWellSubSegmentCellIntersection& intersection : segment.intersections())
{
bool isSubGridIntersection = !intersection.gridName().isEmpty();
if (isSubGridIntersection == exportSubGridIntersections)
{
double relativeStartLength = segment.startMD() - startMD;
if (exportSubGridIntersections)
{
formatter.add(intersection.gridName());
@@ -636,14 +634,10 @@ void RicWellPathExportCompletionDataFeatureImpl::generateCompsegTable(RifEclipse
cvf::Vec3st ijk = intersection.gridLocalCellIJK();
formatter.addZeroBasedCellIndex(ijk.x()).addZeroBasedCellIndex(ijk.y()).addZeroBasedCellIndex(ijk.z());
formatter.add(completion.branchNumber());
formatter.add(aggregatedLength);
formatter.add(aggregatedLength + segment.deltaMD());
formatter.add(relativeStartLength);
formatter.add(relativeStartLength + segment.deltaMD());
formatter.rowCompleted();
}
if (completion.completionType() == RigCompletionData::FISHBONES)
{
aggregatedLength += segment.deltaMD();
}
}
}
}
@@ -668,7 +662,7 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclips
};
formatter.header(header);
}
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
for (const RicMswWellSegment& location : exportInfo.wellSegmentLocations())
{
for (const RicWellSegmentCompletion& completion : location.completions())
{
@@ -1259,15 +1253,19 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
exportInfo.setRoughnessFactor(wellPath->fishbonesCollection()->roughnessFactor(unitSystem));
bool foundSubGridIntersections = false;
double startMD = wellPath->fishbonesCollection()->startMD();
for (RimFishbonesMultipleSubs* subs : fishbonesSubs)
{
for (auto& sub : subs->installedLateralIndices())
{
double measuredDepth = subs->measuredDepth(sub.subIndex);
cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(measuredDepth);
double endMD = subs->measuredDepth(sub.subIndex);
cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(startMD);
cvf::Vec3d endPosition = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD);
double startTVD = -position.z();
double endTVD = -endPosition.z();
RicWellSegmentLocation location =
RicWellSegmentLocation(subs->generatedName(), measuredDepth, -position.z(), sub.subIndex);
RicMswWellSegment location =
RicMswWellSegment(subs->generatedName(), startMD, endMD, startTVD, endTVD, sub.subIndex);
location.setEffectiveDiameter(subs->effectiveDiameter(unitSystem));
location.setHoleDiameter(subs->holeDiameter(unitSystem));
location.setOpenHoleRoughnessFactor(subs->openHoleRoughnessFactor(unitSystem));
@@ -1277,18 +1275,21 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount());
// Add completion for ICD
RicWellSegmentCompletion icdCompletion(RigCompletionData::ICD);
RicWellSubSegment icdSegment(measuredDepth, 0.1, -position.z(), 0.0);
RicWellSegmentCompletion icdCompletion(RigCompletionData::ICD, QString("ICD"));
RicWellSubSegment icdSegment(endMD, 0.1, -endPosition.z(), 0.0);
icdCompletion.addSubSegment(icdSegment);
location.addCompletion(icdCompletion);
for (size_t lateralIndex : sub.lateralIndices)
{
location.addCompletion(RicWellSegmentCompletion(RigCompletionData::FISHBONES, lateralIndex));
QString label = QString("Lateral %1").arg(lateralIndex);
location.addCompletion(RicWellSegmentCompletion(RigCompletionData::FISHBONES, label, lateralIndex));
}
assignFishbonesLateralIntersections(caseToApply, subs, &location, &foundSubGridIntersections);
exportInfo.addWellSegmentLocation(location);
startMD = endMD;
}
}
exportInfo.setHasSubGridIntersections(foundSubGridIntersections);
@@ -1330,12 +1331,6 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType();
RicMultiSegmentWellExportInfo exportInfo(wellPath,
unitSystem,
0.0,
QString("INC"),
QString("HF-"));
const RigWellPath* wellPathGeometry = wellPath->wellPathGeometry();
const std::vector<cvf::Vec3d>& coords = wellPathGeometry->wellPathPoints();
const std::vector<double>& mds = wellPathGeometry->measureDepths();
@@ -1345,8 +1340,18 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(
caseToApply->eclipseCaseData(), coords, mds);
double previousExitMD = mds.front();
double previousExitTVD = -coords.front().z();
double initialMD = mds.front();
if (!intersections.empty())
{
initialMD = intersections.front().startMD;
}
RicMultiSegmentWellExportInfo exportInfo(wellPath,
unitSystem,
initialMD,
QString("INC"),
QString("HF-"));
bool foundSubGridIntersections = false;
@@ -1354,6 +1359,9 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
int mainBoreSegment = 0;
for (const auto& cellIntInfo : intersections)
{
double startTVD = -cellIntInfo.startPoint.z();
double endTVD = -cellIntInfo.endPoint.z();
size_t localGridIdx = 0u;
const RigGridBase* localGrid = grid->gridAndGridLocalIdxFromGlobalCellIdx(cellIntInfo.globCellIndex, &localGridIdx);
QString gridName;
@@ -1366,31 +1374,34 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
QString label = QString("Main stem segment %1").arg(++mainBoreSegment);
RicWellSegmentLocation location(label, cellIntInfo.endMD, -cellIntInfo.endPoint.z());
exportInfo.addWellSegmentLocation(location);
RicMswWellSegment location(label, cellIntInfo.startMD, cellIntInfo.endMD, startTVD, endTVD);
previousExitMD = cellIntInfo.endMD;
previousExitTVD = -cellIntInfo.endPoint.z();
}
// Check if fractures are to be assigned to current main bore segment
for (RimWellPathFracture* fracture : fractures)
{
double fractureStartMD = fracture->fractureMD();
if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
{
double perforationLength = fracture->fractureTemplate()->perforationLength();
fractureStartMD -= 0.5 * perforationLength;
}
if (cvf::Math::valueInRange(fractureStartMD, cellIntInfo.startMD, cellIntInfo.endMD))
{
cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(fractureStartMD);
// Fractures
for (RimWellPathFracture* fracture : fractures)
{
double measuredDepth = fracture->fractureMD();
cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(measuredDepth);
RicWellSegmentLocation location(fracture->name(), measuredDepth, -position.z(), 0);
std::vector<RimFracture*> fractureVector(1, fracture);
std::vector<RigCompletionData> completionData =
RicExportFractureCompletionsImpl::generateCompdatValues(caseToApply,
wellPath->completions()->wellNameForExport(),
wellPath->wellPathGeometry(),
fractureVector,
nullptr,
nullptr);
std::vector<RimFracture*> fractureVector(1, fracture);
std::vector<RigCompletionData> completionData =
RicExportFractureCompletionsImpl::generateCompdatValues(caseToApply,
wellPath->completions()->wellNameForExport(),
wellPath->wellPathGeometry(),
fractureVector,
nullptr,
nullptr);
assignFractureIntersections(caseToApply, fracture, completionData, &location, &foundSubGridIntersections);
assignFractureIntersections(caseToApply, fracture, completionData, &location, &foundSubGridIntersections);
}
}
exportInfo.addWellSegmentLocation(location);
}
@@ -1407,7 +1418,7 @@ RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::genera
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersections(const RimEclipseCase* caseToApply,
const RimFishbonesMultipleSubs* fishbonesSubs,
RicWellSegmentLocation* location,
RicMswWellSegment* location,
bool* foundSubGridIntersections)
{
CVF_ASSERT(foundSubGridIntersections != nullptr);
@@ -1461,14 +1472,14 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
RicWellSubSegment subSegment (previousExitMD,
cellIntInfo.endMD - previousExitMD,
previousExitTVD,
cellIntInfo.endPoint.z() - previousExitTVD);
cellIntInfo.endMD - previousExitMD,
previousExitTVD,
cellIntInfo.endPoint.z() - previousExitTVD);
RicWellSubSegmentCellIntersection intersection(gridName,
cellIntInfo.globCellIndex,
cvf::Vec3st(i, j, k),
cellIntInfo.intersectionLengthsInCellCS);
cellIntInfo.globCellIndex,
cvf::Vec3st(i, j, k),
cellIntInfo.intersectionLengthsInCellCS);
subSegment.addIntersection(intersection);
completion.addSubSegment(subSegment);
@@ -1484,18 +1495,28 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(const RimEclipseCase* caseToApply,
const RimWellPathFracture* fracture,
const std::vector<RigCompletionData>& completionData,
RicWellSegmentLocation* location,
RicMswWellSegment* location,
bool* foundSubGridIntersections)
{
CVF_ASSERT(foundSubGridIntersections != nullptr);
const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid();
double fractureMD = fracture->fractureMD();
RicWellSegmentCompletion fractureCompletion(RigCompletionData::FRACTURE);
RicWellSubSegment subSegment(fracture->fractureMD(),
fracture->fractureTemplate()->computeFractureWidth(fracture),
0.0,
0.0);
RicWellSegmentCompletion fractureCompletion(RigCompletionData::FRACTURE, fracture->name());
double position = fracture->fractureMD();
double width = fracture->fractureTemplate()->computeFractureWidth(fracture);
if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH)
{
double perforationLength = fracture->fractureTemplate()->perforationLength();
position -= 0.5 * perforationLength;
width = perforationLength;
}
RicWellSubSegment subSegment(position,
width,
0.0,
0.0);
for (const RigCompletionData& compIntersection : completionData)
{
@@ -1503,9 +1524,9 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(con
cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK());
RicWellSubSegmentCellIntersection intersection(cell.lgrName(),
cell.globalCellIndex(),
localIJK,
cvf::Vec3d::ZERO);
cell.globalCellIndex(),
localIJK,
cvf::Vec3d::ZERO);
subSegment.addIntersection(intersection);
}
fractureCompletion.addSubSegment(subSegment);
@@ -1516,7 +1537,7 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(con
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
RicWellSegmentLocation* location,
RicMswWellSegment* location,
int* branchNum,
int* segmentNum)
{
@@ -1563,7 +1584,7 @@ void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(c
int branchNumber = 1;
// First loop over the locations so that each segment on the main stem is an incremental number
for (RicWellSegmentLocation& location : exportInfo->wellSegmentLocations())
for (RicMswWellSegment& location : exportInfo->wellSegmentLocations())
{
location.setSegmentNumber(++segmentNumber);
for (RicWellSegmentCompletion& completion : location.completions())
@@ -1577,7 +1598,7 @@ void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(c
}
// Then assign branch and segment numbers to each completion sub segment
for (RicWellSegmentLocation& location : exportInfo->wellSegmentLocations())
for (RicMswWellSegment& location : exportInfo->wellSegmentLocations())
{
assignBranchAndSegmentNumbers(caseToApply, &location, &branchNumber, &segmentNumber);
}