#3442 Improve ICD/ICV export to add a small 0.1 length segment for each segment containing valves.

This commit is contained in:
Gaute Lindkvist 2018-12-03 15:37:50 +01:00
parent 2ed41d3158
commit 420944e910
7 changed files with 390 additions and 295 deletions

View File

@ -192,26 +192,26 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
RiaEclipseUnitTools::UnitSystem unitSystem = caseData->unitsType();
bool isMainBore = false;
for (const RicMswSegment& location : exportInfo.wellSegmentLocations())
for (std::shared_ptr<RicMswSegment> location : exportInfo.wellSegmentLocations())
{
for (const RicMswCompletion& completion : location.completions())
for (std::shared_ptr<RicMswCompletion> completion : location->completions())
{
for (const RicMswSubSegment& segment : completion.subSegments())
for (std::shared_ptr<RicMswSubSegment> segment : completion->subSegments())
{
for (const RicMswSubSegmentCellIntersection& intersection : segment.intersections())
for (std::shared_ptr<RicMswSubSegmentCellIntersection> intersection : segment->intersections())
{
double diameter = location.holeDiameter();
double diameter = location->holeDiameter();
QString completionMetaData =
(location.label() + QString(": Sub: %1 Lateral: %2").arg(location.subIndex()).arg(completion.index()));
(location->label() + QString(": Sub: %1 Lateral: %2").arg(location->subIndex()).arg(completion->index()));
WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc(
intersection.lengthsInCell(), diameter / 2.0, location.skinFactor(), isMainBore, completionMetaData);
intersection->lengthsInCell(), diameter / 2.0, location->skinFactor(), isMainBore, completionMetaData);
wellBorePart.intersectionWithWellMeasuredDepth = location.endMD();
wellBorePart.lateralIndex = completion.index();
wellBorePart.setSourcePdmObject(location.sourcePdmObject());
wellBorePart.intersectionWithWellMeasuredDepth = location->endMD();
wellBorePart.lateralIndex = completion->index();
wellBorePart.setSourcePdmObject(location->sourcePdmObject());
wellBorePartsInCells[intersection.globalCellIndex()].push_back(wellBorePart);
wellBorePartsInCells[intersection->globalCellIndex()].push_back(wellBorePart);
}
}
}

View File

@ -134,7 +134,7 @@ void RicMswSubSegment::setAttachedSegmentNumber(int attachedSegmentNumber)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswSubSegment::addIntersection(const RicMswSubSegmentCellIntersection& intersection)
void RicMswSubSegment::addIntersection(std::shared_ptr<RicMswSubSegmentCellIntersection> intersection)
{
m_intersections.push_back(intersection);
}
@ -142,7 +142,7 @@ void RicMswSubSegment::addIntersection(const RicMswSubSegmentCellIntersection& i
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RicMswSubSegmentCellIntersection>& RicMswSubSegment::intersections() const
const std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>>& RicMswSubSegment::intersections() const
{
return m_intersections;
}
@ -150,7 +150,7 @@ const std::vector<RicMswSubSegmentCellIntersection>& RicMswSubSegment::intersect
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RicMswSubSegmentCellIntersection>& RicMswSubSegment::intersections()
std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>>& RicMswSubSegment::intersections()
{
return m_intersections;
}
@ -212,7 +212,7 @@ void RicMswCompletion::setBranchNumber(int branchNumber)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswCompletion::addSubSegment(const RicMswSubSegment& subSegment)
void RicMswCompletion::addSubSegment(std::shared_ptr<RicMswSubSegment> subSegment)
{
m_subSegments.push_back(subSegment);
}
@ -220,7 +220,7 @@ void RicMswCompletion::addSubSegment(const RicMswSubSegment& subSegment)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RicMswSubSegment>& RicMswCompletion::subSegments()
std::vector<std::shared_ptr<RicMswSubSegment>>& RicMswCompletion::subSegments()
{
return m_subSegments;
}
@ -228,11 +228,19 @@ std::vector<RicMswSubSegment>& RicMswCompletion::subSegments()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RicMswSubSegment>& RicMswCompletion::subSegments() const
const std::vector<std::shared_ptr<RicMswSubSegment>>& RicMswCompletion::subSegments() const
{
return m_subSegments;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswCompletion::setLabel(const QString& label)
{
m_label = label;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -382,7 +390,7 @@ int RicMswSegment::segmentNumber() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RicMswCompletion>& RicMswSegment::completions() const
const std::vector<std::shared_ptr<RicMswCompletion>>& RicMswSegment::completions() const
{
return m_completions;
}
@ -390,7 +398,7 @@ const std::vector<RicMswCompletion>& RicMswSegment::completions() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RicMswCompletion>& RicMswSegment::completions()
std::vector<std::shared_ptr<RicMswCompletion>>& RicMswSegment::completions()
{
return m_completions;
}
@ -462,7 +470,7 @@ void RicMswSegment::setSegmentNumber(int segmentNumber)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswSegment::addCompletion(const RicMswCompletion& completion)
void RicMswSegment::addCompletion(std::shared_ptr<RicMswCompletion> completion)
{
m_completions.push_back(completion);
}
@ -546,7 +554,7 @@ void RicMswExportInfo::setHasSubGridIntersections(bool subGridIntersections)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswExportInfo::addWellSegmentLocation(const RicMswSegment& location)
void RicMswExportInfo::addWellSegment(std::shared_ptr<RicMswSegment> location)
{
m_wellSegmentLocations.push_back(location);
}
@ -556,7 +564,12 @@ void RicMswExportInfo::addWellSegmentLocation(const RicMswSegment& location)
//--------------------------------------------------------------------------------------------------
void RicMswExportInfo::sortLocations()
{
std::sort(m_wellSegmentLocations.begin(), m_wellSegmentLocations.end());
std::sort(m_wellSegmentLocations.begin(),
m_wellSegmentLocations.end(),
[](std::shared_ptr<RicMswSegment> lhs, std::shared_ptr<RicMswSegment> rhs)
{
return *lhs < *rhs;
});
}
//--------------------------------------------------------------------------------------------------
@ -650,7 +663,7 @@ double RicMswExportInfo::defaultDoubleValue()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RicMswSegment>& RicMswExportInfo::wellSegmentLocations() const
const std::vector<std::shared_ptr<RicMswSegment>>& RicMswExportInfo::wellSegmentLocations() const
{
return m_wellSegmentLocations;
}
@ -658,7 +671,7 @@ const std::vector<RicMswSegment>& RicMswExportInfo::wellSegmentLocations() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RicMswSegment>& RicMswExportInfo::wellSegmentLocations()
std::vector<std::shared_ptr<RicMswSegment>>& RicMswExportInfo::wellSegmentLocations()
{
return m_wellSegmentLocations;
}

View File

@ -27,6 +27,8 @@
#include <QString>
#include <memory>
class RimWellPath;
class RimFishbonesMultipleSubs;
@ -72,10 +74,10 @@ public:
void setSegmentNumber(int segmentNumber);
void setAttachedSegmentNumber(int attachedSegmentNumber);
void addIntersection(const RicMswSubSegmentCellIntersection& intersection);
void addIntersection(std::shared_ptr<RicMswSubSegmentCellIntersection> intersection);
const std::vector<RicMswSubSegmentCellIntersection>& intersections() const;
std::vector<RicMswSubSegmentCellIntersection>& intersections();
const std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>>& intersections() const;
std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>>& intersections();
private:
@ -86,7 +88,7 @@ private:
int m_segmentNumber;
int m_attachedSegmentNumber;
std::vector<RicMswSubSegmentCellIntersection> m_intersections;
std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>> m_intersections;
};
//==================================================================================================
@ -103,17 +105,20 @@ public:
int branchNumber() const;
void setBranchNumber(int branchNumber);
void addSubSegment(const RicMswSubSegment& subSegment);
void addSubSegment(std::shared_ptr<RicMswSubSegment> subSegment);
std::vector<std::shared_ptr<RicMswSubSegment>>& subSegments();
const std::vector<std::shared_ptr<RicMswSubSegment>>& subSegments() const;
void setLabel(const QString& label);
std::vector<RicMswSubSegment>& subSegments();
const std::vector<RicMswSubSegment>& subSegments() const;
private:
RigCompletionData::CompletionType m_completionType;
QString m_label;
size_t m_index;
int m_branchNumber;
std::vector<RicMswSubSegment> m_subSegments;
std::vector<std::shared_ptr<RicMswSubSegment>> m_subSegments;
};
//==================================================================================================
@ -149,8 +154,8 @@ public:
size_t subIndex() const;
int segmentNumber() const;
const std::vector<RicMswCompletion>& completions() const;
std::vector<RicMswCompletion>& completions();
const std::vector<std::shared_ptr<RicMswCompletion>>& completions() const;
std::vector<std::shared_ptr<RicMswCompletion>>& completions();
void setLabel(const QString& label);
void setEffectiveDiameter(double effectiveDiameter);
@ -160,7 +165,7 @@ public:
void setIcdFlowCoefficient(double icdFlowCoefficient);
void setIcdArea(double icdArea);
void setSegmentNumber(int segmentNumber);
void addCompletion(const RicMswCompletion& completion);
void addCompletion(std::shared_ptr<RicMswCompletion> completion);
void setSourcePdmObject(const caf::PdmObject* object);
const caf::PdmObject* sourcePdmObject() const;
@ -184,7 +189,7 @@ private:
size_t m_subIndex;
int m_segmentNumber;
std::vector<RicMswCompletion> m_completions;
std::vector<std::shared_ptr<RicMswCompletion>> m_completions;
caf::PdmPointer<caf::PdmObject> m_sourcePdmObject;
};
@ -203,7 +208,7 @@ public:
void setRoughnessFactor(double roughnessFactor);
void setHasSubGridIntersections(bool subGridIntersections);
void addWellSegmentLocation(const RicMswSegment& location);
void addWellSegment(std::shared_ptr<RicMswSegment> location);
void sortLocations();
const RimWellPath* wellPath() const;
@ -218,8 +223,8 @@ public:
bool hasSubGridIntersections() const;
static double defaultDoubleValue();
const std::vector<RicMswSegment>& wellSegmentLocations() const;
std::vector<RicMswSegment>& wellSegmentLocations();
const std::vector<std::shared_ptr<RicMswSegment>>& wellSegmentLocations() const;
std::vector<std::shared_ptr<RicMswSegment>>& wellSegmentLocations();
private:
const RimWellPath* m_wellPath;
@ -231,6 +236,7 @@ private:
QString m_lengthAndDepthText;
QString m_pressureDropText;
bool m_hasSubGridIntersections;
std::vector<RicMswSegment> m_wellSegmentLocations;
std::vector<std::shared_ptr<RicMswSegment>> m_wellSegmentLocations;
};

View File

@ -74,6 +74,8 @@
#include "cvfPlane.h"
#include <QDir>
#include <map>
#include <set>
//--------------------------------------------------------------------------------------------------
/// Internal definitions
@ -643,44 +645,45 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
double prevMD = exportInfo.initialMD();
double prevTVD = exportInfo.initialTVD();
formatter.comment("Main Stem Segments");
for (const RicMswSegment& location : exportInfo.wellSegmentLocations())
for (std::shared_ptr<RicMswSegment> location : exportInfo.wellSegmentLocations())
{
double depth = 0;
double length = 0;
if (exportInfo.lengthAndDepthText() == QString("INC"))
{
depth = location.endTVD() - prevTVD;
length = location.endMD() - prevMD;
depth = location->endTVD() - prevTVD;
length = location->endMD() - prevMD;
}
else
{
depth = location.endTVD();
length = location.endMD();
depth = location->endTVD();
length = location->endMD();
}
if (location.subIndex() != cvf::UNDEFINED_SIZE_T)
if (location->subIndex() != cvf::UNDEFINED_SIZE_T)
{
QString comment = location.label() + QString(", sub %1").arg(location.subIndex());
QString comment = location->label() + QString(", sub %1").arg(location->subIndex());
formatter.comment(comment);
}
formatter.add(location.segmentNumber()).add(location.segmentNumber());
formatter.add(location->segmentNumber()).add(location->segmentNumber());
formatter.add(1); // All segments on main stem are branch 1
formatter.add(location.segmentNumber() - 1); // All main stem segments are connected to the segment below them
formatter.add(location->segmentNumber() - 1); // All main stem segments are connected to the segment below them
formatter.add(length);
formatter.add(depth);
formatter.add(exportInfo.linerDiameter());
formatter.add(exportInfo.roughnessFactor());
formatter.rowCompleted();
prevMD = location.endMD();
prevTVD = location.endTVD();
prevMD = location->endMD();
prevTVD = location->endTVD();
}
}
{
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FISHBONES_ICD, RigCompletionData::FISHBONES});
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FRACTURE});
generateWelsegsSegments(formatter, exportInfo, { RigCompletionData::PERFORATION_ICD });
}
formatter.tableCompleted();
@ -695,69 +698,74 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsSegments(
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes)
{
bool generatedHeader = false;
for (const RicMswSegment& segment : exportInfo.wellSegmentLocations())
for (std::shared_ptr<RicMswSegment> segment : exportInfo.wellSegmentLocations())
{
for (const RicMswCompletion& completion : segment.completions())
for (std::shared_ptr<RicMswCompletion> completion : segment->completions())
{
if (exportCompletionTypes.count(completion.completionType()))
if (exportCompletionTypes.count(completion->completionType()))
{
if (!generatedHeader)
{
generateWelsegsCompletionCommentHeader(formatter, completion.completionType());
generateWelsegsCompletionCommentHeader(formatter, completion->completionType());
generatedHeader = true;
}
if (completion.completionType() == RigCompletionData::FISHBONES_ICD) // Found ICD
if (completion->completionType() == RigCompletionData::FISHBONES_ICD ||
completion->completionType() == RigCompletionData::PERFORATION_ICD) // Found ICD
{
formatter.comment(completion.label());
formatter.add(completion.subSegments().front().segmentNumber());
formatter.add(completion.subSegments().front().segmentNumber());
formatter.add(completion.branchNumber());
formatter.add(segment.segmentNumber());
formatter.add(0.1); // ICDs have 0.1 length
formatter.add(0); // Depth change
formatter.add(exportInfo.linerDiameter());
formatter.add(exportInfo.roughnessFactor());
formatter.rowCompleted();
if (!completion->subSegments().empty())
{
formatter.comment(completion->label());
formatter.add(completion->subSegments().front()->segmentNumber());
formatter.add(completion->subSegments().front()->segmentNumber());
formatter.add(completion->branchNumber());
formatter.add(segment->segmentNumber());
formatter.add(0.1); // ICDs have 0.1 length
formatter.add(0); // Depth change
formatter.add(exportInfo.linerDiameter());
formatter.add(exportInfo.roughnessFactor());
formatter.rowCompleted();
}
}
else
{
if (completion.completionType() == RigCompletionData::FISHBONES)
if (completion->completionType() == RigCompletionData::FISHBONES)
{
formatter.comment(QString("%1 : Sub index %2 - %3")
.arg(segment.label())
.arg(segment.subIndex())
.arg(completion.label()));
.arg(segment->label())
.arg(segment->subIndex())
.arg(completion->label()));
}
else if (completion.completionType() == RigCompletionData::FRACTURE)
else if (completion->completionType() == RigCompletionData::FRACTURE)
{
formatter.comment(QString("%1 connected to %2").arg(completion.label()).arg(segment.label()));
formatter.comment(QString("%1 connected to %2").arg(completion->label()).arg(segment->label()));
}
for (const RicMswSubSegment& subSegment : completion.subSegments())
for (std::shared_ptr<RicMswSubSegment> subSegment : completion->subSegments())
{
double depth = 0;
double length = 0;
if (exportInfo.lengthAndDepthText() == QString("INC"))
{
depth = subSegment.deltaTVD();
length = subSegment.deltaMD();
depth = subSegment->deltaTVD();
length = subSegment->deltaMD();
}
else
{
depth = subSegment.startTVD() + subSegment.deltaTVD();
length = subSegment.startMD() + subSegment.deltaMD();
depth = subSegment->startTVD() + subSegment->deltaTVD();
length = subSegment->startMD() + subSegment->deltaMD();
}
double diameter = segment.effectiveDiameter();
formatter.add(subSegment.segmentNumber());
formatter.add(subSegment.segmentNumber());
formatter.add(completion.branchNumber());
formatter.add(subSegment.attachedSegmentNumber());
double diameter = segment->effectiveDiameter();
formatter.add(subSegment->segmentNumber());
formatter.add(subSegment->segmentNumber());
formatter.add(completion->branchNumber());
formatter.add(subSegment->attachedSegmentNumber());
formatter.add(length);
formatter.add(depth);
formatter.add(diameter);
formatter.add(segment.openHoleRoughnessFactor());
formatter.add(segment->openHoleRoughnessFactor());
formatter.rowCompleted();
}
}
@ -849,49 +857,48 @@ void RicWellPathExportCompletionDataFeatureImpl::generateCompsegTable(
{
bool generatedHeader = false;
for (const RicMswSegment& location : exportInfo.wellSegmentLocations())
for (std::shared_ptr<RicMswSegment> location : exportInfo.wellSegmentLocations())
{
double startMD = location.startMD();
double startMD = location->startMD();
for (const RicMswCompletion& completion : location.completions())
for (std::shared_ptr<RicMswCompletion> completion : location->completions())
{
if (!completion.subSegments().empty() && exportCompletionTypes.count(completion.completionType()))
if (!completion->subSegments().empty() && exportCompletionTypes.count(completion->completionType()))
{
if (!generatedHeader)
{
generateCompsegHeader(formatter, exportInfo, completion.completionType(), exportSubGridIntersections);
generateCompsegHeader(formatter, exportInfo, completion->completionType(), exportSubGridIntersections);
generatedHeader = true;
}
for (const RicMswSubSegment& segment : completion.subSegments())
for (std::shared_ptr<RicMswSubSegment> segment : completion->subSegments())
{
if (completion.completionType() == RigCompletionData::FISHBONES_ICD ||
completion.completionType() == RigCompletionData::PERFORATION_ICD)
if (completion->completionType() == RigCompletionData::FISHBONES_ICD)
{
startMD = segment.startMD();
startMD = segment->startMD();
}
for (const RicMswSubSegmentCellIntersection& intersection : segment.intersections())
for (std::shared_ptr<RicMswSubSegmentCellIntersection> intersection : segment->intersections())
{
bool isSubGridIntersection = !intersection.gridName().isEmpty();
bool isSubGridIntersection = !intersection->gridName().isEmpty();
if (isSubGridIntersection == exportSubGridIntersections)
{
if (exportSubGridIntersections)
{
formatter.add(intersection.gridName());
formatter.add(intersection->gridName());
}
cvf::Vec3st ijk = intersection.gridLocalCellIJK();
cvf::Vec3st ijk = intersection->gridLocalCellIJK();
formatter.addOneBasedCellIndex(ijk.x()).addOneBasedCellIndex(ijk.y()).addOneBasedCellIndex(ijk.z());
formatter.add(completion.branchNumber());
formatter.add(completion->branchNumber());
double startLength = segment.startMD();
double startLength = segment->startMD();
if (exportInfo.lengthAndDepthText() == QString("INC") &&
completion.completionType() != RigCompletionData::PERFORATION)
completion->completionType() != RigCompletionData::PERFORATION)
{
startLength -= startMD;
}
formatter.add(startLength);
formatter.add(startLength + segment.deltaMD());
formatter.add(startLength + segment->deltaMD());
formatter.rowCompleted();
}
@ -927,10 +934,6 @@ void RicWellPathExportCompletionDataFeatureImpl::generateCompsegHeader(RifEclips
{
formatter.comment("Fishbones");
}
else if (completionType == RigCompletionData::PERFORATION_ICD)
{
formatter.comment("Perforation valves");
}
else if (completionType == RigCompletionData::FRACTURE)
{
formatter.comment("Fractures");
@ -972,12 +975,12 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclips
{
bool foundValve = false;
for (const RicMswSegment& location : exportInfo.wellSegmentLocations())
for (std::shared_ptr<RicMswSegment> location : exportInfo.wellSegmentLocations())
{
for (const RicMswCompletion& completion : location.completions())
for (std::shared_ptr<RicMswCompletion> completion : location->completions())
{
if (completion.completionType() == RigCompletionData::FISHBONES_ICD ||
completion.completionType() == RigCompletionData::PERFORATION_ICD)
if (completion->completionType() == RigCompletionData::FISHBONES_ICD ||
completion->completionType() == RigCompletionData::PERFORATION_ICD)
{
if (!foundValve)
{
@ -992,26 +995,29 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclips
foundValve = true;
}
if (completion.completionType() == RigCompletionData::FISHBONES_ICD)
if (completion->completionType() == RigCompletionData::FISHBONES_ICD)
{
if (!completion.subSegments().empty())
if (!completion->subSegments().empty())
{
CVF_ASSERT(completion.subSegments().size() == 1u);
CVF_ASSERT(completion->subSegments().size() == 1u);
formatter.add(exportInfo.wellPath()->name());
formatter.add(completion.subSegments().front().segmentNumber());
formatter.add(location.icdFlowCoefficient());
formatter.add(location.icdArea());
formatter.add(completion->subSegments().front()->segmentNumber());
formatter.add(location->icdFlowCoefficient());
formatter.add(location->icdArea());
formatter.rowCompleted();
}
}
else
{
formatter.comment(completion.label());
formatter.add(exportInfo.wellPath()->name());
formatter.add(location.segmentNumber());
formatter.add(location.icdFlowCoefficient());
formatter.add(QString("%1").arg(location.icdArea(), 8, 'f', 6));
formatter.rowCompleted();
if (!completion->subSegments().empty())
{
formatter.comment(completion->label());
formatter.add(exportInfo.wellPath()->name());
formatter.add(completion->subSegments().front()->segmentNumber());
formatter.add(location->icdFlowCoefficient());
formatter.add(QString("%1").arg(location->icdArea(), 8, 'f', 6));
formatter.rowCompleted();
}
}
}
}
@ -1837,34 +1843,34 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMs
double endMd = startMd + subSegLen;
double endTvd = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMd).z();
RicMswSegment location = RicMswSegment(subs->generatedName(), startMd, endMd, startTvd, endTvd, sub.subIndex);
location.setEffectiveDiameter(subs->effectiveDiameter(unitSystem));
location.setHoleDiameter(subs->holeDiameter(unitSystem));
location.setOpenHoleRoughnessFactor(subs->openHoleRoughnessFactor(unitSystem));
location.setSkinFactor(subs->skinFactor());
location.setIcdFlowCoefficient(subs->icdFlowCoefficient());
std::shared_ptr<RicMswSegment> location (new RicMswSegment(subs->generatedName(), startMd, endMd, startTvd, endTvd, sub.subIndex));
location->setEffectiveDiameter(subs->effectiveDiameter(unitSystem));
location->setHoleDiameter(subs->holeDiameter(unitSystem));
location->setOpenHoleRoughnessFactor(subs->openHoleRoughnessFactor(unitSystem));
location->setSkinFactor(subs->skinFactor());
location->setIcdFlowCoefficient(subs->icdFlowCoefficient());
double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2;
location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount());
location.setSourcePdmObject(subs);
location->setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount());
location->setSourcePdmObject(subs);
if (ssi == 0)
{
// Add completion for ICD
RicMswCompletion icdCompletion(RigCompletionData::FISHBONES_ICD, QString("ICD"));
RicMswSubSegment icdSegment(subEndMD, 0.1, subEndTVD, 0.0);
icdCompletion.addSubSegment(icdSegment);
location.addCompletion(icdCompletion);
std::shared_ptr<RicMswCompletion> icdCompletion(new RicMswCompletion(RigCompletionData::FISHBONES_ICD, QString("ICD")));
std::shared_ptr<RicMswSubSegment> icdSegment(new RicMswSubSegment(subEndMD, 0.1, subEndTVD, 0.0));
icdCompletion->addSubSegment(icdSegment);
location->addCompletion(icdCompletion);
for (size_t lateralIndex : sub.lateralIndices)
{
QString label = QString("Lateral %1").arg(lateralIndex);
location.addCompletion(RicMswCompletion(RigCompletionData::FISHBONES, label, lateralIndex));
location->addCompletion(std::make_shared<RicMswCompletion>(RigCompletionData::FISHBONES, label, lateralIndex));
}
assignFishbonesLateralIntersections(
caseToApply, subs, &location, &foundSubGridIntersections, maxSegmentLength);
caseToApply, subs, location, &foundSubGridIntersections, maxSegmentLength);
}
exportInfo.addWellSegmentLocation(location);
exportInfo.addWellSegment(location);
startMd = endMd;
startTvd = endTvd;
@ -1963,7 +1969,7 @@ RicMswExportInfo
size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
QString label = QString("Main stem segment %1").arg(++mainBoreSegment);
RicMswSegment location(label, cellIntInfo.startMD, cellIntInfo.endMD, startTVD, endTVD);
std::shared_ptr<RicMswSegment> location(new RicMswSegment(label, cellIntInfo.startMD, cellIntInfo.endMD, startTVD, endTVD));
// Check if fractures are to be assigned to current main bore segment
for (RimWellPathFracture* fracture : fractures)
@ -1985,11 +1991,11 @@ RicMswExportInfo
nullptr,
nullptr);
assignFractureIntersections(caseToApply, fracture, completionData, &location, &foundSubGridIntersections);
assignFractureIntersections(caseToApply, fracture, completionData, location, &foundSubGridIntersections);
}
}
exportInfo.addWellSegmentLocation(location);
exportInfo.addWellSegment(location);
}
exportInfo.setHasSubGridIntersections(foundSubGridIntersections);
exportInfo.sortLocations();
@ -2007,7 +2013,6 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation
const std::vector<const RimPerforationInterval*>& perforationIntervals)
{
const RimEclipseCase* caseToApply = exportSettings.caseToApply;
const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid();
const RigActiveCellInfo* activeCellInfo = caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL);
RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType();
@ -2044,118 +2049,176 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation
bool foundSubGridIntersections = false;
// Main bore
int mainBoreSegment = 1;
MainBoreSegments mainBoreSegments = createMainBoreSegments(subSegIntersections, perforationIntervals, wellPath, exportSettings, &foundSubGridIntersections);
ValveCompletionMap primaryValveCompletions = assignPrimaryValveCompletions(mainBoreSegments, perforationIntervals);
assignSecondaryValveContributions(mainBoreSegments, perforationIntervals, primaryValveCompletions, unitSystem);
for (std::shared_ptr<RicMswSegment> segment : mainBoreSegments)
{
exportInfo.addWellSegment(segment);
}
exportInfo.setHasSubGridIntersections(foundSubGridIntersections);
exportInfo.sortLocations();
assignBranchAndSegmentNumbers(caseToApply, &exportInfo);
return exportInfo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicWellPathExportCompletionDataFeatureImpl::MainBoreSegments
RicWellPathExportCompletionDataFeatureImpl::createMainBoreSegments(
const std::vector<SubSegmentIntersectionInfo>& subSegIntersections,
const std::vector<const RimPerforationInterval*>& perforationIntervals,
const RimWellPath* wellPath,
const RicExportCompletionDataSettingsUi& exportSettings,
bool* foundSubGridIntersections)
{
MainBoreSegments mainBoreSegments;
for (const auto& cellIntInfo : subSegIntersections)
{
double startTVD = cellIntInfo.startTVD;
double endTVD = cellIntInfo.endTVD;
size_t localGridIdx = 0u;
const RigGridBase* localGrid = grid->gridAndGridLocalIdxFromGlobalCellIdx(cellIntInfo.globCellIndex, &localGridIdx);
QString gridName;
if (localGrid != grid)
if (std::fabs(cellIntInfo.endMD - cellIntInfo.startMD) > 1.0e-8)
{
gridName = QString::fromStdString(localGrid->gridName());
foundSubGridIntersections = true;
QString label = QString("Main stem segment %1").arg(mainBoreSegments.size() + 2);
std::shared_ptr<RicMswSegment> segment(
new RicMswSegment(label, cellIntInfo.startMD, cellIntInfo.endMD, cellIntInfo.startTVD, cellIntInfo.endTVD));
for (const RimPerforationInterval* interval : perforationIntervals)
{
double overlapStart = std::max(interval->startMD(), segment->startMD());
double overlapEnd = std::min(interval->endMD(), segment->endMD());
double overlap = std::max(0.0, overlapEnd - overlapStart);
if (overlap > 0.0)
{
std::shared_ptr<RicMswCompletion> intervalCompletion(
new RicMswCompletion(RigCompletionData::PERFORATION, interval->name()));
std::vector<RigCompletionData> completionData =
generatePerforationsCompdatValues(wellPath, {interval}, exportSettings);
assignPerforationIntervalIntersections(
completionData, intervalCompletion, cellIntInfo, foundSubGridIntersections);
segment->addCompletion(intervalCompletion);
}
}
mainBoreSegments.push_back(segment);
}
}
return mainBoreSegments;
}
size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
QString label = QString("Main stem segment %1").arg(++mainBoreSegment);
RicMswSegment location(label, cellIntInfo.startMD, cellIntInfo.endMD, startTVD, endTVD);
int nICDs = 0, nICVs = 0;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignSecondaryValveContributions(
std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals,
const ValveCompletionMap& primaryValveLocations,
RiaEclipseUnitTools::UnitSystem unitSystem)
{
ValveContributionMap slaveValves;
for (std::shared_ptr<RicMswSegment> segment : mainBoreSegments)
{
double totalIcdArea = 0.0;
RiaWeightedMeanCalculator<double> coeffMeanCalc;
for (const RimPerforationInterval* interval : perforationIntervals)
{
double intervalStartMD = interval->startMD();
double intervalEndMD = interval->endMD();
std::vector<const RimWellPathValve*> perforationValves;
interval->descendantsIncludingThisOfType(perforationValves);
if (cellIntInfo.endMD > intervalStartMD && cellIntInfo.startMD < intervalEndMD)
for (const RimWellPathValve* valve : perforationValves)
{
std::vector<const RimWellPathValve*> perforationValves;
interval->descendantsIncludingThisOfType(perforationValves);
for (const RimWellPathValve* valve : perforationValves)
for (size_t nSubValve = 0u; nSubValve < valve->valveSegments().size(); ++nSubValve)
{
if (!valve->isChecked()) continue;
std::pair<double, double> valveSegment = valve->valveSegments()[nSubValve];
double valveSegmentLength = valveSegment.second - valveSegment.first;
double overlapStart = std::max(valveSegment.first, segment->startMD());
double overlapEnd = std::min(valveSegment.second, segment->endMD());
double overlap = std::max(0.0, overlapEnd - overlapStart);
for (const std::pair<double, double>& segment : valve->segmentsBetweenValves())
if (overlap > 0.0)
{
double segmentLength = segment.second - segment.first;
double overlapStart = std::max(segment.first, cellIntInfo.startMD);
double overlapEnd = std::min(segment.second, cellIntInfo.endMD);
double overlap = std::max(0.0, overlapEnd - overlapStart);
auto primaryValveLocIt = primaryValveLocations.find(std::make_pair(valve, nSubValve));
if (primaryValveLocIt == primaryValveLocations.end()) continue;
if (overlap > 0.0)
{
cvf::Vec3d segStartPoint = wellPathGeometry->interpolatedPointAlongWellPath(overlapStart);
cvf::Vec3d segEndPoint = wellPathGeometry->interpolatedPointAlongWellPath(overlapEnd);
std::shared_ptr<RicMswCompletion> completion = primaryValveLocIt->second;
slaveValves[completion].insert(std::make_pair(valve, nSubValve));
if (valve->componentType() == RiaDefines::ICV || valve->componentType() == RiaDefines::ICD)
{
if (valve->componentType() == RiaDefines::ICV)
nICVs++;
else
nICDs++;
double icdOrificeRadius = valve->orificeDiameter(unitSystem) / 2;
double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D * overlap / segmentLength;
totalIcdArea += icdArea;
coeffMeanCalc.addValueAndWeight(valve->flowCoefficient(), icdArea);
}
}
double icdOrificeRadius = valve->orificeDiameter(unitSystem) / 2;
double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D * overlap / valveSegmentLength;
totalIcdArea += icdArea;
coeffMeanCalc.addValueAndWeight(valve->flowCoefficient(), icdArea);
}
}
}
}
segment->setIcdArea(totalIcdArea);
if (coeffMeanCalc.validAggregatedWeight())
{
segment->setIcdFlowCoefficient(coeffMeanCalc.weightedMean());
}
}
for (auto slaveValvePair : slaveValves)
{
if (slaveValvePair.second.size())
{
QStringList valveLabels;
for (std::pair<const RimWellPathValve*, size_t> slaveValve : slaveValvePair.second)
{
QString valveLabel = QString("%1 #%2").arg(slaveValve.first->name()).arg(slaveValve.second + 1);
valveLabels.push_back(valveLabel);
}
QString valveContribLabel = QString(" with contribution from: %1").arg(valveLabels.join(", "));
slaveValvePair.first->setLabel(slaveValvePair.first->label() + valveContribLabel);
}
}
}
std::vector<RigCompletionData> completionData =
generatePerforationsCompdatValues(wellPath, {interval}, exportSettings);
if (std::fabs(location.endMD() - location.startMD()) > 1.0e-8)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicWellPathExportCompletionDataFeatureImpl::ValveCompletionMap
RicWellPathExportCompletionDataFeatureImpl::assignPrimaryValveCompletions(
std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals)
{
ValveCompletionMap primaryValveLocations;
for (size_t nMainSegment = 0u; nMainSegment < mainBoreSegments.size(); ++nMainSegment)
{
std::shared_ptr<RicMswSegment> segment = mainBoreSegments[nMainSegment];
std::shared_ptr<RicMswCompletion> valveCompletion;
for (const RimPerforationInterval* interval : perforationIntervals)
{
std::vector<const RimWellPathValve*> perforationValves;
interval->descendantsIncludingThisOfType(perforationValves);
for (const RimWellPathValve* valve : perforationValves)
{
for (size_t nSubValve = 0u; nSubValve < valve->valveLocations().size(); ++nSubValve)
{
assignPerforationIntervalIntersections(
caseToApply, interval, completionData, &location, &cellIntInfo, &foundSubGridIntersections);
double valveMD = valve->valveLocations()[nSubValve];
if (segment->startMD() <= valveMD && valveMD < segment->endMD())
{
QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2);
if (!valveCompletion)
{
valveCompletion.reset(new RicMswCompletion(RigCompletionData::PERFORATION_ICD, valveLabel));
std::shared_ptr<RicMswSubSegment> valveSegment(new RicMswSubSegment(valveMD, 0.1, 0.0, 0.0));
valveCompletion->addSubSegment(valveSegment);
segment->addCompletion(valveCompletion);
}
primaryValveLocations[std::make_pair(valve, nSubValve)] = valveCompletion;
}
}
}
}
if (totalIcdArea > 0.0)
{
location.setIcdArea(totalIcdArea);
if (coeffMeanCalc.validAggregatedWeight())
{
location.setIcdFlowCoefficient(coeffMeanCalc.weightedMean());
}
QStringList valveLabelComponents;
if (nICDs)
{
valveLabelComponents += QString("%1 ICDs").arg(nICDs);
}
if (nICVs)
{
valveLabelComponents += QString("%1 ICVs").arg(nICVs);
}
QString valveLabel;
if (!valveLabelComponents.isEmpty())
{
valveLabel += QString("Contribution from %1").arg(valveLabelComponents.join(" and "));
}
RicMswCompletion valveCompletion(RigCompletionData::PERFORATION_ICD, valveLabel);
location.addCompletion(valveCompletion);
}
if (std::fabs(location.endMD() - location.startMD()) > 1.0e-8)
{
exportInfo.addWellSegmentLocation(location);
}
}
exportInfo.setHasSubGridIntersections(foundSubGridIntersections);
exportInfo.sortLocations();
assignBranchAndSegmentNumbers(caseToApply, &exportInfo);
return exportInfo;
return primaryValveLocations;
}
//--------------------------------------------------------------------------------------------------
@ -2164,7 +2227,7 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation
void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersections(
const RimEclipseCase* caseToApply,
const RimFishbonesMultipleSubs* fishbonesSubs,
RicMswSegment* location,
std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections,
double maxSegmentLength)
{
@ -2172,15 +2235,15 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid();
for (RicMswCompletion& completion : location->completions())
for (std::shared_ptr<RicMswCompletion> completion : location->completions())
{
if (completion.completionType() != RigCompletionData::FISHBONES)
if (completion->completionType() != RigCompletionData::FISHBONES)
{
continue;
}
std::vector<std::pair<cvf::Vec3d, double>> lateralCoordMDPairs =
fishbonesSubs->coordsAndMDForLateral(location->subIndex(), completion.index());
fishbonesSubs->coordsAndMDForLateral(location->subIndex(), completion->index());
if (lateralCoordMDPairs.empty())
{
@ -2225,13 +2288,13 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
RicMswSubSegment subSegment(
previousExitMD, cellIntInfo.endMD - previousExitMD, previousExitTVD, cellIntInfo.endTVD - previousExitTVD);
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(
previousExitMD, cellIntInfo.endMD - previousExitMD, previousExitTVD, cellIntInfo.endTVD - previousExitTVD));
RicMswSubSegmentCellIntersection intersection(
gridName, cellIntInfo.globCellIndex, cvf::Vec3st(i, j, k), cellIntInfo.intersectionLengthsInCellCS);
subSegment.addIntersection(intersection);
completion.addSubSegment(subSegment);
std::shared_ptr<RicMswSubSegmentCellIntersection> intersection(new RicMswSubSegmentCellIntersection(
gridName, cellIntInfo.globCellIndex, cvf::Vec3st(i, j, k), cellIntInfo.intersectionLengthsInCellCS));
subSegment->addIntersection(intersection);
completion->addSubSegment(subSegment);
previousExitMD = cellIntInfo.endMD;
previousExitTVD = cellIntInfo.endTVD;
@ -2245,12 +2308,12 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(const RimEclipseCase* caseToApply,
const RimWellPathFracture* fracture,
const std::vector<RigCompletionData>& completionData,
RicMswSegment* location,
std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections)
{
CVF_ASSERT(foundSubGridIntersections != nullptr);
RicMswCompletion fractureCompletion(RigCompletionData::FRACTURE, fracture->name());
std::shared_ptr<RicMswCompletion> fractureCompletion(new RicMswCompletion(RigCompletionData::FRACTURE, fracture->name()));
double position = fracture->fractureMD();
double width = fracture->fractureTemplate()->computeFractureWidth(fracture);
@ -2261,16 +2324,16 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(con
width = perforationLength;
}
RicMswSubSegment subSegment(position, width, 0.0, 0.0);
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(position, width, 0.0, 0.0));
for (const RigCompletionData& compIntersection : completionData)
{
const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell();
cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK());
RicMswSubSegmentCellIntersection intersection(cell.lgrName(), cell.globalCellIndex(), localIJK, cvf::Vec3d::ZERO);
subSegment.addIntersection(intersection);
std::shared_ptr<RicMswSubSegmentCellIntersection> intersection(new RicMswSubSegmentCellIntersection(cell.lgrName(), cell.globalCellIndex(), localIJK, cvf::Vec3d::ZERO));
subSegment->addIntersection(intersection);
}
fractureCompletion.addSubSegment(subSegment);
fractureCompletion->addSubSegment(subSegment);
location->addCompletion(fractureCompletion);
}
@ -2278,57 +2341,52 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(con
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignPerforationIntervalIntersections(
const RimEclipseCase* caseToApply,
const RimPerforationInterval* interval,
const std::vector<RigCompletionData>& completionData,
RicMswSegment* location,
const SubSegmentIntersectionInfo* cellIntInfo,
std::shared_ptr<RicMswCompletion> perforationCompletion,
const SubSegmentIntersectionInfo& cellIntInfo,
bool* foundSubGridIntersections)
{
CVF_ASSERT(foundSubGridIntersections != nullptr);
RicMswCompletion intervalCompletion(RigCompletionData::PERFORATION, interval->name());
double startMd = std::max(location->startMD(), interval->startMD());
double endMd = std::min(location->endMD(), interval->endMD());
RicMswSubSegment subSegment(startMd, endMd - startMd, 0.0, 0.0);
size_t currCellId = cellIntInfo->globCellIndex;
size_t currCellId = cellIntInfo.globCellIndex;
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(cellIntInfo.startMD, cellIntInfo.endMD, cellIntInfo.startTVD, cellIntInfo.endTVD));
for (const RigCompletionData& compIntersection : completionData)
{
const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell();
if (!cell.isMainGridCell())
{
*foundSubGridIntersections = true;
}
if (cell.globalCellIndex() != currCellId) continue;
cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK());
RicMswSubSegmentCellIntersection intersection(
cell.lgrName(), cell.globalCellIndex(), localIJK, cellIntInfo->intersectionLengthsInCellCS);
subSegment.addIntersection(intersection);
std::shared_ptr<RicMswSubSegmentCellIntersection> intersection(new RicMswSubSegmentCellIntersection(
cell.lgrName(), cell.globalCellIndex(), localIJK, cellIntInfo.intersectionLengthsInCellCS));
subSegment->addIntersection(intersection);
}
intervalCompletion.addSubSegment(subSegment);
location->addCompletion(intervalCompletion);
perforationCompletion->addSubSegment(subSegment);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
RicMswSegment* location,
int* branchNum,
int* segmentNum)
void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
std::shared_ptr<RicMswSegment> location,
int* branchNum,
int* segmentNum)
{
int icdSegmentNumber = cvf::UNDEFINED_INT;
for (RicMswCompletion& completion : location->completions())
for (std::shared_ptr<RicMswCompletion> completion : location->completions())
{
if (completion.completionType() == RigCompletionData::PERFORATION)
if (completion->completionType() == RigCompletionData::PERFORATION)
{
completion.setBranchNumber(1);
completion->setBranchNumber(1);
}
else if (completion.completionType() != RigCompletionData::FISHBONES_ICD)
else if (completion->completionType() != RigCompletionData::FISHBONES_ICD)
{
++(*branchNum);
completion.setBranchNumber(*branchNum);
completion->setBranchNumber(*branchNum);
}
int attachedSegmentNumber = location->segmentNumber();
@ -2337,19 +2395,19 @@ void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(c
attachedSegmentNumber = icdSegmentNumber;
}
for (auto& subSegment : completion.subSegments())
for (auto subSegment : completion->subSegments())
{
if (completion.completionType() == RigCompletionData::FISHBONES_ICD)
if (completion->completionType() == RigCompletionData::FISHBONES_ICD)
{
subSegment.setSegmentNumber(location->segmentNumber() + 1);
icdSegmentNumber = subSegment.segmentNumber();
subSegment->setSegmentNumber(location->segmentNumber() + 1);
icdSegmentNumber = subSegment->segmentNumber();
}
else
else if (completion->completionType() != RigCompletionData::PERFORATION)
{
++(*segmentNum);
subSegment.setSegmentNumber(*segmentNum);
subSegment->setSegmentNumber(*segmentNum);
}
subSegment.setAttachedSegmentNumber(attachedSegmentNumber);
subSegment->setAttachedSegmentNumber(attachedSegmentNumber);
attachedSegmentNumber = *segmentNum;
}
}
@ -2365,26 +2423,26 @@ 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 (RicMswSegment& location : exportInfo->wellSegmentLocations())
for (auto location : exportInfo->wellSegmentLocations())
{
location.setSegmentNumber(++segmentNumber);
for (RicMswCompletion& completion : location.completions())
location->setSegmentNumber(++segmentNumber);
for (auto completion : location->completions())
{
if (completion.completionType() == RigCompletionData::FISHBONES_ICD)
if (completion->completionType() == RigCompletionData::FISHBONES_ICD)
{
++segmentNumber; // Skip a segment number because we need one for the ICD
if (completion.completionType() == RigCompletionData::FISHBONES_ICD)
if (completion->completionType() == RigCompletionData::FISHBONES_ICD)
{
completion.setBranchNumber(++branchNumber);
completion->setBranchNumber(++branchNumber);
}
}
}
}
// Then assign branch and segment numbers to each completion sub segment
for (RicMswSegment& location : exportInfo->wellSegmentLocations())
for (auto location : exportInfo->wellSegmentLocations())
{
assignBranchAndSegmentNumbers(caseToApply, &location, &branchNumber, &segmentNumber);
assignBranchAndSegmentNumbers(caseToApply, location, &branchNumber, &segmentNumber);
}
}

View File

@ -33,6 +33,7 @@
#include <vector>
#include <memory>
class RicMswCompletion;
class RigCell;
class RigEclipseCaseData;
class RigMainGrid;
@ -41,6 +42,7 @@ class RimFishbonesMultipleSubs;
class RimSimWellInView;
class RimPerforationInterval;
class RimWellPath;
class RimWellPathValve;
class RimWellPathFracture;
class RimNonDarcyPerforationParameters;
class RifEclipseDataTableFormatter;
@ -186,6 +188,24 @@ public:
const RicMswExportInfo& exportInfo);
private:
typedef std::vector<std::shared_ptr<RicMswSegment>> MainBoreSegments;
typedef std::map<std::pair<const RimWellPathValve*, size_t>, std::shared_ptr<RicMswCompletion>> ValveCompletionMap;
typedef std::map <std::shared_ptr<RicMswCompletion>, std::set<std::pair<const RimWellPathValve*, size_t>>> ValveContributionMap;
static MainBoreSegments createMainBoreSegments(const std::vector<SubSegmentIntersectionInfo>& subSegIntersections,
const std::vector<const RimPerforationInterval*>& perforationIntervals,
const RimWellPath* wellPath,
const RicExportCompletionDataSettingsUi& exportSettings,
bool* foundSubGridIntersections);
static ValveCompletionMap assignPrimaryValveCompletions(std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals);
static void assignSecondaryValveContributions(std::vector<std::shared_ptr<RicMswSegment>>& mainBoreSegments,
const std::vector<const RimPerforationInterval*>& perforationIntervals,
const ValveCompletionMap& primaryValveLocations,
RiaEclipseUnitTools::UnitSystem unitSystem);
static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase,
double skinFactor,
double wellRadius,
@ -242,25 +262,23 @@ private:
static void assignFishbonesLateralIntersections(const RimEclipseCase* caseToApply,
const RimFishbonesMultipleSubs* fishbonesSubs,
RicMswSegment* location,
std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections,
double maxSegmentLength);
static void assignFractureIntersections(const RimEclipseCase* caseToApply,
const RimWellPathFracture* fracture,
const std::vector<RigCompletionData>& completionData,
RicMswSegment* location,
std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections);
static void assignPerforationIntervalIntersections(const RimEclipseCase* caseToApply,
const RimPerforationInterval* interval,
const std::vector<RigCompletionData>& completionData,
RicMswSegment* location,
const SubSegmentIntersectionInfo* cellIntInfo,
bool* foundSubGridIntersections);
static void assignPerforationIntervalIntersections(const std::vector<RigCompletionData>& completionData,
std::shared_ptr<RicMswCompletion> perforationCompletion,
const SubSegmentIntersectionInfo& cellIntInfo,
bool* foundSubGridIntersections);
static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
RicMswSegment* location,
std::shared_ptr<RicMswSegment> location,
int* branchNum,
int* segmentNum);
static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,

View File

@ -179,7 +179,7 @@ double RimWellPathValve::convertOrificeDiameter(double
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<double, double>> RimWellPathValve::segmentsBetweenValves() const
std::vector<std::pair<double, double>> RimWellPathValve::valveSegments() const
{
RimPerforationInterval* perforationInterval = nullptr;
this->firstAncestorOrThisOfType(perforationInterval);

View File

@ -54,7 +54,7 @@ public:
RiaEclipseUnitTools::UnitSystem wellPathUnitSystem,
RiaEclipseUnitTools::UnitSystem wantedUnitSystem);
std::vector<std::pair<double, double>> segmentsBetweenValves() const;
std::vector<std::pair<double, double>> valveSegments() const;
// Overrides from RimWellPathCompletionInterface