#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(); RiaEclipseUnitTools::UnitSystem unitSystem = caseData->unitsType();
bool isMainBore = false; 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 = 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( 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.intersectionWithWellMeasuredDepth = location->endMD();
wellBorePart.lateralIndex = completion.index(); wellBorePart.lateralIndex = completion->index();
wellBorePart.setSourcePdmObject(location.sourcePdmObject()); 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); 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; 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; 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); 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; 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; 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; 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; 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); 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); m_wellSegmentLocations.push_back(location);
} }
@ -556,7 +564,12 @@ void RicMswExportInfo::addWellSegmentLocation(const RicMswSegment& location)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicMswExportInfo::sortLocations() 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; 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; return m_wellSegmentLocations;
} }

View File

@ -27,6 +27,8 @@
#include <QString> #include <QString>
#include <memory>
class RimWellPath; class RimWellPath;
class RimFishbonesMultipleSubs; class RimFishbonesMultipleSubs;
@ -72,10 +74,10 @@ public:
void setSegmentNumber(int segmentNumber); void setSegmentNumber(int segmentNumber);
void setAttachedSegmentNumber(int attachedSegmentNumber); void setAttachedSegmentNumber(int attachedSegmentNumber);
void addIntersection(const RicMswSubSegmentCellIntersection& intersection); void addIntersection(std::shared_ptr<RicMswSubSegmentCellIntersection> intersection);
const std::vector<RicMswSubSegmentCellIntersection>& intersections() const; const std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>>& intersections() const;
std::vector<RicMswSubSegmentCellIntersection>& intersections(); std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>>& intersections();
private: private:
@ -86,7 +88,7 @@ private:
int m_segmentNumber; int m_segmentNumber;
int m_attachedSegmentNumber; int m_attachedSegmentNumber;
std::vector<RicMswSubSegmentCellIntersection> m_intersections; std::vector<std::shared_ptr<RicMswSubSegmentCellIntersection>> m_intersections;
}; };
//================================================================================================== //==================================================================================================
@ -103,17 +105,20 @@ public:
int branchNumber() const; int branchNumber() const;
void setBranchNumber(int branchNumber); void setBranchNumber(int branchNumber);
void addSubSegment(const RicMswSubSegment& subSegment); void addSubSegment(std::shared_ptr<RicMswSubSegment> subSegment);
std::vector<RicMswSubSegment>& subSegments(); std::vector<std::shared_ptr<RicMswSubSegment>>& subSegments();
const std::vector<RicMswSubSegment>& subSegments() const; const std::vector<std::shared_ptr<RicMswSubSegment>>& subSegments() const;
void setLabel(const QString& label);
private: private:
RigCompletionData::CompletionType m_completionType; RigCompletionData::CompletionType m_completionType;
QString m_label; QString m_label;
size_t m_index; size_t m_index;
int m_branchNumber; 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; size_t subIndex() const;
int segmentNumber() const; int segmentNumber() const;
const std::vector<RicMswCompletion>& completions() const; const std::vector<std::shared_ptr<RicMswCompletion>>& completions() const;
std::vector<RicMswCompletion>& completions(); std::vector<std::shared_ptr<RicMswCompletion>>& completions();
void setLabel(const QString& label); void setLabel(const QString& label);
void setEffectiveDiameter(double effectiveDiameter); void setEffectiveDiameter(double effectiveDiameter);
@ -160,7 +165,7 @@ public:
void setIcdFlowCoefficient(double icdFlowCoefficient); void setIcdFlowCoefficient(double icdFlowCoefficient);
void setIcdArea(double icdArea); void setIcdArea(double icdArea);
void setSegmentNumber(int segmentNumber); void setSegmentNumber(int segmentNumber);
void addCompletion(const RicMswCompletion& completion); void addCompletion(std::shared_ptr<RicMswCompletion> completion);
void setSourcePdmObject(const caf::PdmObject* object); void setSourcePdmObject(const caf::PdmObject* object);
const caf::PdmObject* sourcePdmObject() const; const caf::PdmObject* sourcePdmObject() const;
@ -184,7 +189,7 @@ private:
size_t m_subIndex; size_t m_subIndex;
int m_segmentNumber; int m_segmentNumber;
std::vector<RicMswCompletion> m_completions; std::vector<std::shared_ptr<RicMswCompletion>> m_completions;
caf::PdmPointer<caf::PdmObject> m_sourcePdmObject; caf::PdmPointer<caf::PdmObject> m_sourcePdmObject;
}; };
@ -203,7 +208,7 @@ public:
void setRoughnessFactor(double roughnessFactor); void setRoughnessFactor(double roughnessFactor);
void setHasSubGridIntersections(bool subGridIntersections); void setHasSubGridIntersections(bool subGridIntersections);
void addWellSegmentLocation(const RicMswSegment& location); void addWellSegment(std::shared_ptr<RicMswSegment> location);
void sortLocations(); void sortLocations();
const RimWellPath* wellPath() const; const RimWellPath* wellPath() const;
@ -218,8 +223,8 @@ public:
bool hasSubGridIntersections() const; bool hasSubGridIntersections() const;
static double defaultDoubleValue(); static double defaultDoubleValue();
const std::vector<RicMswSegment>& wellSegmentLocations() const; const std::vector<std::shared_ptr<RicMswSegment>>& wellSegmentLocations() const;
std::vector<RicMswSegment>& wellSegmentLocations(); std::vector<std::shared_ptr<RicMswSegment>>& wellSegmentLocations();
private: private:
const RimWellPath* m_wellPath; const RimWellPath* m_wellPath;
@ -231,6 +236,7 @@ private:
QString m_lengthAndDepthText; QString m_lengthAndDepthText;
QString m_pressureDropText; QString m_pressureDropText;
bool m_hasSubGridIntersections; 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 "cvfPlane.h"
#include <QDir> #include <QDir>
#include <map>
#include <set>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Internal definitions /// Internal definitions
@ -643,44 +645,45 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipse
double prevMD = exportInfo.initialMD(); double prevMD = exportInfo.initialMD();
double prevTVD = exportInfo.initialTVD(); double prevTVD = exportInfo.initialTVD();
formatter.comment("Main Stem Segments"); formatter.comment("Main Stem Segments");
for (const RicMswSegment& location : exportInfo.wellSegmentLocations()) for (std::shared_ptr<RicMswSegment> location : exportInfo.wellSegmentLocations())
{ {
double depth = 0; double depth = 0;
double length = 0; double length = 0;
if (exportInfo.lengthAndDepthText() == QString("INC")) if (exportInfo.lengthAndDepthText() == QString("INC"))
{ {
depth = location.endTVD() - prevTVD; depth = location->endTVD() - prevTVD;
length = location.endMD() - prevMD; length = location->endMD() - prevMD;
} }
else else
{ {
depth = location.endTVD(); depth = location->endTVD();
length = location.endMD(); 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.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(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(length);
formatter.add(depth); formatter.add(depth);
formatter.add(exportInfo.linerDiameter()); formatter.add(exportInfo.linerDiameter());
formatter.add(exportInfo.roughnessFactor()); formatter.add(exportInfo.roughnessFactor());
formatter.rowCompleted(); formatter.rowCompleted();
prevMD = location.endMD(); prevMD = location->endMD();
prevTVD = location.endTVD(); prevTVD = location->endTVD();
} }
} }
{ {
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FISHBONES_ICD, RigCompletionData::FISHBONES}); generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FISHBONES_ICD, RigCompletionData::FISHBONES});
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FRACTURE}); generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FRACTURE});
generateWelsegsSegments(formatter, exportInfo, { RigCompletionData::PERFORATION_ICD });
} }
formatter.tableCompleted(); formatter.tableCompleted();
@ -695,69 +698,74 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsSegments(
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes) const std::set<RigCompletionData::CompletionType>& exportCompletionTypes)
{ {
bool generatedHeader = false; 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) if (!generatedHeader)
{ {
generateWelsegsCompletionCommentHeader(formatter, completion.completionType()); generateWelsegsCompletionCommentHeader(formatter, completion->completionType());
generatedHeader = true; 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()); if (!completion->subSegments().empty())
formatter.add(completion.subSegments().front().segmentNumber()); {
formatter.add(completion.subSegments().front().segmentNumber()); formatter.comment(completion->label());
formatter.add(completion.branchNumber());
formatter.add(segment.segmentNumber()); 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.1); // ICDs have 0.1 length
formatter.add(0); // Depth change formatter.add(0); // Depth change
formatter.add(exportInfo.linerDiameter()); formatter.add(exportInfo.linerDiameter());
formatter.add(exportInfo.roughnessFactor()); formatter.add(exportInfo.roughnessFactor());
formatter.rowCompleted(); formatter.rowCompleted();
} }
}
else else
{ {
if (completion.completionType() == RigCompletionData::FISHBONES) if (completion->completionType() == RigCompletionData::FISHBONES)
{ {
formatter.comment(QString("%1 : Sub index %2 - %3") formatter.comment(QString("%1 : Sub index %2 - %3")
.arg(segment.label()) .arg(segment->label())
.arg(segment.subIndex()) .arg(segment->subIndex())
.arg(completion.label())); .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 depth = 0;
double length = 0; double length = 0;
if (exportInfo.lengthAndDepthText() == QString("INC")) if (exportInfo.lengthAndDepthText() == QString("INC"))
{ {
depth = subSegment.deltaTVD(); depth = subSegment->deltaTVD();
length = subSegment.deltaMD(); length = subSegment->deltaMD();
} }
else else
{ {
depth = subSegment.startTVD() + subSegment.deltaTVD(); depth = subSegment->startTVD() + subSegment->deltaTVD();
length = subSegment.startMD() + subSegment.deltaMD(); length = subSegment->startMD() + subSegment->deltaMD();
} }
double diameter = segment.effectiveDiameter(); double diameter = segment->effectiveDiameter();
formatter.add(subSegment.segmentNumber()); formatter.add(subSegment->segmentNumber());
formatter.add(subSegment.segmentNumber()); formatter.add(subSegment->segmentNumber());
formatter.add(completion.branchNumber()); formatter.add(completion->branchNumber());
formatter.add(subSegment.attachedSegmentNumber()); formatter.add(subSegment->attachedSegmentNumber());
formatter.add(length); formatter.add(length);
formatter.add(depth); formatter.add(depth);
formatter.add(diameter); formatter.add(diameter);
formatter.add(segment.openHoleRoughnessFactor()); formatter.add(segment->openHoleRoughnessFactor());
formatter.rowCompleted(); formatter.rowCompleted();
} }
} }
@ -849,49 +857,48 @@ void RicWellPathExportCompletionDataFeatureImpl::generateCompsegTable(
{ {
bool generatedHeader = false; 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) if (!generatedHeader)
{ {
generateCompsegHeader(formatter, exportInfo, completion.completionType(), exportSubGridIntersections); generateCompsegHeader(formatter, exportInfo, completion->completionType(), exportSubGridIntersections);
generatedHeader = true; generatedHeader = true;
} }
for (const RicMswSubSegment& segment : completion.subSegments()) for (std::shared_ptr<RicMswSubSegment> segment : completion->subSegments())
{ {
if (completion.completionType() == RigCompletionData::FISHBONES_ICD || if (completion->completionType() == RigCompletionData::FISHBONES_ICD)
completion.completionType() == RigCompletionData::PERFORATION_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 (isSubGridIntersection == exportSubGridIntersections)
{ {
if (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.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") && if (exportInfo.lengthAndDepthText() == QString("INC") &&
completion.completionType() != RigCompletionData::PERFORATION) completion->completionType() != RigCompletionData::PERFORATION)
{ {
startLength -= startMD; startLength -= startMD;
} }
formatter.add(startLength); formatter.add(startLength);
formatter.add(startLength + segment.deltaMD()); formatter.add(startLength + segment->deltaMD());
formatter.rowCompleted(); formatter.rowCompleted();
} }
@ -927,10 +934,6 @@ void RicWellPathExportCompletionDataFeatureImpl::generateCompsegHeader(RifEclips
{ {
formatter.comment("Fishbones"); formatter.comment("Fishbones");
} }
else if (completionType == RigCompletionData::PERFORATION_ICD)
{
formatter.comment("Perforation valves");
}
else if (completionType == RigCompletionData::FRACTURE) else if (completionType == RigCompletionData::FRACTURE)
{ {
formatter.comment("Fractures"); formatter.comment("Fractures");
@ -972,12 +975,12 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclips
{ {
bool foundValve = false; 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 || if (completion->completionType() == RigCompletionData::FISHBONES_ICD ||
completion.completionType() == RigCompletionData::PERFORATION_ICD) completion->completionType() == RigCompletionData::PERFORATION_ICD)
{ {
if (!foundValve) if (!foundValve)
{ {
@ -992,30 +995,33 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclips
foundValve = true; 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(exportInfo.wellPath()->name());
formatter.add(completion.subSegments().front().segmentNumber()); formatter.add(completion->subSegments().front()->segmentNumber());
formatter.add(location.icdFlowCoefficient()); formatter.add(location->icdFlowCoefficient());
formatter.add(location.icdArea()); formatter.add(location->icdArea());
formatter.rowCompleted(); formatter.rowCompleted();
} }
} }
else else
{ {
formatter.comment(completion.label()); if (!completion->subSegments().empty())
{
formatter.comment(completion->label());
formatter.add(exportInfo.wellPath()->name()); formatter.add(exportInfo.wellPath()->name());
formatter.add(location.segmentNumber()); formatter.add(completion->subSegments().front()->segmentNumber());
formatter.add(location.icdFlowCoefficient()); formatter.add(location->icdFlowCoefficient());
formatter.add(QString("%1").arg(location.icdArea(), 8, 'f', 6)); formatter.add(QString("%1").arg(location->icdArea(), 8, 'f', 6));
formatter.rowCompleted(); formatter.rowCompleted();
} }
} }
} }
} }
}
if (foundValve) if (foundValve)
{ {
formatter.tableCompleted(); formatter.tableCompleted();
@ -1837,34 +1843,34 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMs
double endMd = startMd + subSegLen; double endMd = startMd + subSegLen;
double endTvd = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMd).z(); double endTvd = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMd).z();
RicMswSegment location = RicMswSegment(subs->generatedName(), startMd, endMd, startTvd, endTvd, sub.subIndex); std::shared_ptr<RicMswSegment> location (new RicMswSegment(subs->generatedName(), startMd, endMd, startTvd, endTvd, sub.subIndex));
location.setEffectiveDiameter(subs->effectiveDiameter(unitSystem)); location->setEffectiveDiameter(subs->effectiveDiameter(unitSystem));
location.setHoleDiameter(subs->holeDiameter(unitSystem)); location->setHoleDiameter(subs->holeDiameter(unitSystem));
location.setOpenHoleRoughnessFactor(subs->openHoleRoughnessFactor(unitSystem)); location->setOpenHoleRoughnessFactor(subs->openHoleRoughnessFactor(unitSystem));
location.setSkinFactor(subs->skinFactor()); location->setSkinFactor(subs->skinFactor());
location.setIcdFlowCoefficient(subs->icdFlowCoefficient()); location->setIcdFlowCoefficient(subs->icdFlowCoefficient());
double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2; double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2;
location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount()); location->setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount());
location.setSourcePdmObject(subs); location->setSourcePdmObject(subs);
if (ssi == 0) if (ssi == 0)
{ {
// Add completion for ICD // Add completion for ICD
RicMswCompletion icdCompletion(RigCompletionData::FISHBONES_ICD, QString("ICD")); std::shared_ptr<RicMswCompletion> icdCompletion(new RicMswCompletion(RigCompletionData::FISHBONES_ICD, QString("ICD")));
RicMswSubSegment icdSegment(subEndMD, 0.1, subEndTVD, 0.0); std::shared_ptr<RicMswSubSegment> icdSegment(new RicMswSubSegment(subEndMD, 0.1, subEndTVD, 0.0));
icdCompletion.addSubSegment(icdSegment); icdCompletion->addSubSegment(icdSegment);
location.addCompletion(icdCompletion); location->addCompletion(icdCompletion);
for (size_t lateralIndex : sub.lateralIndices) for (size_t lateralIndex : sub.lateralIndices)
{ {
QString label = QString("Lateral %1").arg(lateralIndex); 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( assignFishbonesLateralIntersections(
caseToApply, subs, &location, &foundSubGridIntersections, maxSegmentLength); caseToApply, subs, location, &foundSubGridIntersections, maxSegmentLength);
} }
exportInfo.addWellSegmentLocation(location); exportInfo.addWellSegment(location);
startMd = endMd; startMd = endMd;
startTvd = endTvd; startTvd = endTvd;
@ -1963,7 +1969,7 @@ RicMswExportInfo
size_t i = 0u, j = 0u, k = 0u; size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k); localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
QString label = QString("Main stem segment %1").arg(++mainBoreSegment); 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 // Check if fractures are to be assigned to current main bore segment
for (RimWellPathFracture* fracture : fractures) for (RimWellPathFracture* fracture : fractures)
@ -1985,11 +1991,11 @@ RicMswExportInfo
nullptr, nullptr,
nullptr); nullptr);
assignFractureIntersections(caseToApply, fracture, completionData, &location, &foundSubGridIntersections); assignFractureIntersections(caseToApply, fracture, completionData, location, &foundSubGridIntersections);
} }
} }
exportInfo.addWellSegmentLocation(location); exportInfo.addWellSegment(location);
} }
exportInfo.setHasSubGridIntersections(foundSubGridIntersections); exportInfo.setHasSubGridIntersections(foundSubGridIntersections);
exportInfo.sortLocations(); exportInfo.sortLocations();
@ -2007,7 +2013,6 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation
const std::vector<const RimPerforationInterval*>& perforationIntervals) const std::vector<const RimPerforationInterval*>& perforationIntervals)
{ {
const RimEclipseCase* caseToApply = exportSettings.caseToApply; const RimEclipseCase* caseToApply = exportSettings.caseToApply;
const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid();
const RigActiveCellInfo* activeCellInfo = caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); const RigActiveCellInfo* activeCellInfo = caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL);
RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType(); RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType();
@ -2044,113 +2049,15 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation
bool foundSubGridIntersections = false; bool foundSubGridIntersections = false;
// Main bore MainBoreSegments mainBoreSegments = createMainBoreSegments(subSegIntersections, perforationIntervals, wellPath, exportSettings, &foundSubGridIntersections);
int mainBoreSegment = 1; ValveCompletionMap primaryValveCompletions = assignPrimaryValveCompletions(mainBoreSegments, perforationIntervals);
for (const auto& cellIntInfo : subSegIntersections) assignSecondaryValveContributions(mainBoreSegments, perforationIntervals, primaryValveCompletions, unitSystem);
{
double startTVD = cellIntInfo.startTVD;
double endTVD = cellIntInfo.endTVD;
size_t localGridIdx = 0u; for (std::shared_ptr<RicMswSegment> segment : mainBoreSegments)
const RigGridBase* localGrid = grid->gridAndGridLocalIdxFromGlobalCellIdx(cellIntInfo.globCellIndex, &localGridIdx);
QString gridName;
if (localGrid != grid)
{ {
gridName = QString::fromStdString(localGrid->gridName()); exportInfo.addWellSegment(segment);
foundSubGridIntersections = true;
} }
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;
double totalIcdArea = 0.0;
RiaWeightedMeanCalculator<double> coeffMeanCalc;
for (const RimPerforationInterval* interval : perforationIntervals)
{
double intervalStartMD = interval->startMD();
double intervalEndMD = interval->endMD();
if (cellIntInfo.endMD > intervalStartMD && cellIntInfo.startMD < intervalEndMD)
{
std::vector<const RimWellPathValve*> perforationValves;
interval->descendantsIncludingThisOfType(perforationValves);
for (const RimWellPathValve* valve : perforationValves)
{
if (!valve->isChecked()) continue;
for (const std::pair<double, double>& segment : valve->segmentsBetweenValves())
{
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);
if (overlap > 0.0)
{
cvf::Vec3d segStartPoint = wellPathGeometry->interpolatedPointAlongWellPath(overlapStart);
cvf::Vec3d segEndPoint = wellPathGeometry->interpolatedPointAlongWellPath(overlapEnd);
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);
}
}
}
}
std::vector<RigCompletionData> completionData =
generatePerforationsCompdatValues(wellPath, {interval}, exportSettings);
if (std::fabs(location.endMD() - location.startMD()) > 1.0e-8)
{
assignPerforationIntervalIntersections(
caseToApply, interval, completionData, &location, &cellIntInfo, &foundSubGridIntersections);
}
}
}
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.setHasSubGridIntersections(foundSubGridIntersections);
exportInfo.sortLocations(); exportInfo.sortLocations();
assignBranchAndSegmentNumbers(caseToApply, &exportInfo); assignBranchAndSegmentNumbers(caseToApply, &exportInfo);
@ -2158,13 +2065,169 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation
return 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)
{
if (std::fabs(cellIntInfo.endMD - cellIntInfo.startMD) > 1.0e-8)
{
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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)
{
std::vector<const RimWellPathValve*> perforationValves;
interval->descendantsIncludingThisOfType(perforationValves);
for (const RimWellPathValve* valve : perforationValves)
{
for (size_t nSubValve = 0u; nSubValve < valve->valveSegments().size(); ++nSubValve)
{
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);
if (overlap > 0.0)
{
auto primaryValveLocIt = primaryValveLocations.find(std::make_pair(valve, nSubValve));
if (primaryValveLocIt == primaryValveLocations.end()) continue;
std::shared_ptr<RicMswCompletion> completion = primaryValveLocIt->second;
slaveValves[completion].insert(std::make_pair(valve, nSubValve));
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);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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)
{
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;
}
}
}
}
}
return primaryValveLocations;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersections( void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersections(
const RimEclipseCase* caseToApply, const RimEclipseCase* caseToApply,
const RimFishbonesMultipleSubs* fishbonesSubs, const RimFishbonesMultipleSubs* fishbonesSubs,
RicMswSegment* location, std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections, bool* foundSubGridIntersections,
double maxSegmentLength) double maxSegmentLength)
{ {
@ -2172,15 +2235,15 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid(); 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; continue;
} }
std::vector<std::pair<cvf::Vec3d, double>> lateralCoordMDPairs = std::vector<std::pair<cvf::Vec3d, double>> lateralCoordMDPairs =
fishbonesSubs->coordsAndMDForLateral(location->subIndex(), completion.index()); fishbonesSubs->coordsAndMDForLateral(location->subIndex(), completion->index());
if (lateralCoordMDPairs.empty()) if (lateralCoordMDPairs.empty())
{ {
@ -2225,13 +2288,13 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
size_t i = 0u, j = 0u, k = 0u; size_t i = 0u, j = 0u, k = 0u;
localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k); localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k);
RicMswSubSegment subSegment( std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(
previousExitMD, cellIntInfo.endMD - previousExitMD, previousExitTVD, cellIntInfo.endTVD - previousExitTVD); previousExitMD, cellIntInfo.endMD - previousExitMD, previousExitTVD, cellIntInfo.endTVD - previousExitTVD));
RicMswSubSegmentCellIntersection intersection( std::shared_ptr<RicMswSubSegmentCellIntersection> intersection(new RicMswSubSegmentCellIntersection(
gridName, cellIntInfo.globCellIndex, cvf::Vec3st(i, j, k), cellIntInfo.intersectionLengthsInCellCS); gridName, cellIntInfo.globCellIndex, cvf::Vec3st(i, j, k), cellIntInfo.intersectionLengthsInCellCS));
subSegment.addIntersection(intersection); subSegment->addIntersection(intersection);
completion.addSubSegment(subSegment); completion->addSubSegment(subSegment);
previousExitMD = cellIntInfo.endMD; previousExitMD = cellIntInfo.endMD;
previousExitTVD = cellIntInfo.endTVD; previousExitTVD = cellIntInfo.endTVD;
@ -2245,12 +2308,12 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersect
void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(const RimEclipseCase* caseToApply, void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(const RimEclipseCase* caseToApply,
const RimWellPathFracture* fracture, const RimWellPathFracture* fracture,
const std::vector<RigCompletionData>& completionData, const std::vector<RigCompletionData>& completionData,
RicMswSegment* location, std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections) bool* foundSubGridIntersections)
{ {
CVF_ASSERT(foundSubGridIntersections != nullptr); 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 position = fracture->fractureMD();
double width = fracture->fractureTemplate()->computeFractureWidth(fracture); double width = fracture->fractureTemplate()->computeFractureWidth(fracture);
@ -2261,16 +2324,16 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(con
width = perforationLength; 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) for (const RigCompletionData& compIntersection : completionData)
{ {
const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell();
cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK()); cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK());
RicMswSubSegmentCellIntersection intersection(cell.lgrName(), cell.globalCellIndex(), localIJK, cvf::Vec3d::ZERO); std::shared_ptr<RicMswSubSegmentCellIntersection> intersection(new RicMswSubSegmentCellIntersection(cell.lgrName(), cell.globalCellIndex(), localIJK, cvf::Vec3d::ZERO));
subSegment.addIntersection(intersection); subSegment->addIntersection(intersection);
} }
fractureCompletion.addSubSegment(subSegment); fractureCompletion->addSubSegment(subSegment);
location->addCompletion(fractureCompletion); location->addCompletion(fractureCompletion);
} }
@ -2278,57 +2341,52 @@ void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(con
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignPerforationIntervalIntersections( void RicWellPathExportCompletionDataFeatureImpl::assignPerforationIntervalIntersections(
const RimEclipseCase* caseToApply,
const RimPerforationInterval* interval,
const std::vector<RigCompletionData>& completionData, const std::vector<RigCompletionData>& completionData,
RicMswSegment* location, std::shared_ptr<RicMswCompletion> perforationCompletion,
const SubSegmentIntersectionInfo* cellIntInfo, const SubSegmentIntersectionInfo& cellIntInfo,
bool* foundSubGridIntersections) bool* foundSubGridIntersections)
{ {
CVF_ASSERT(foundSubGridIntersections != nullptr); size_t currCellId = cellIntInfo.globCellIndex;
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;
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(cellIntInfo.startMD, cellIntInfo.endMD, cellIntInfo.startTVD, cellIntInfo.endTVD));
for (const RigCompletionData& compIntersection : completionData) for (const RigCompletionData& compIntersection : completionData)
{ {
const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell();
if (!cell.isMainGridCell())
{
*foundSubGridIntersections = true;
}
if (cell.globalCellIndex() != currCellId) continue; if (cell.globalCellIndex() != currCellId) continue;
cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK()); cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK());
RicMswSubSegmentCellIntersection intersection( std::shared_ptr<RicMswSubSegmentCellIntersection> intersection(new RicMswSubSegmentCellIntersection(
cell.lgrName(), cell.globalCellIndex(), localIJK, cellIntInfo->intersectionLengthsInCellCS); cell.lgrName(), cell.globalCellIndex(), localIJK, cellIntInfo.intersectionLengthsInCellCS));
subSegment.addIntersection(intersection); subSegment->addIntersection(intersection);
} }
intervalCompletion.addSubSegment(subSegment); perforationCompletion->addSubSegment(subSegment);
location->addCompletion(intervalCompletion);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
RicMswSegment* location, std::shared_ptr<RicMswSegment> location,
int* branchNum, int* branchNum,
int* segmentNum) int* segmentNum)
{ {
int icdSegmentNumber = cvf::UNDEFINED_INT; 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); ++(*branchNum);
completion.setBranchNumber(*branchNum); completion->setBranchNumber(*branchNum);
} }
int attachedSegmentNumber = location->segmentNumber(); int attachedSegmentNumber = location->segmentNumber();
@ -2337,19 +2395,19 @@ void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(c
attachedSegmentNumber = icdSegmentNumber; 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); subSegment->setSegmentNumber(location->segmentNumber() + 1);
icdSegmentNumber = subSegment.segmentNumber(); icdSegmentNumber = subSegment->segmentNumber();
} }
else else if (completion->completionType() != RigCompletionData::PERFORATION)
{ {
++(*segmentNum); ++(*segmentNum);
subSegment.setSegmentNumber(*segmentNum); subSegment->setSegmentNumber(*segmentNum);
} }
subSegment.setAttachedSegmentNumber(attachedSegmentNumber); subSegment->setAttachedSegmentNumber(attachedSegmentNumber);
attachedSegmentNumber = *segmentNum; attachedSegmentNumber = *segmentNum;
} }
} }
@ -2365,26 +2423,26 @@ void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(c
int branchNumber = 1; int branchNumber = 1;
// First loop over the locations so that each segment on the main stem is an incremental number // 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); location->setSegmentNumber(++segmentNumber);
for (RicMswCompletion& completion : location.completions()) 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 ++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 // 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 <vector>
#include <memory> #include <memory>
class RicMswCompletion;
class RigCell; class RigCell;
class RigEclipseCaseData; class RigEclipseCaseData;
class RigMainGrid; class RigMainGrid;
@ -41,6 +42,7 @@ class RimFishbonesMultipleSubs;
class RimSimWellInView; class RimSimWellInView;
class RimPerforationInterval; class RimPerforationInterval;
class RimWellPath; class RimWellPath;
class RimWellPathValve;
class RimWellPathFracture; class RimWellPathFracture;
class RimNonDarcyPerforationParameters; class RimNonDarcyPerforationParameters;
class RifEclipseDataTableFormatter; class RifEclipseDataTableFormatter;
@ -186,6 +188,24 @@ public:
const RicMswExportInfo& exportInfo); const RicMswExportInfo& exportInfo);
private: 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, static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase,
double skinFactor, double skinFactor,
double wellRadius, double wellRadius,
@ -242,25 +262,23 @@ private:
static void assignFishbonesLateralIntersections(const RimEclipseCase* caseToApply, static void assignFishbonesLateralIntersections(const RimEclipseCase* caseToApply,
const RimFishbonesMultipleSubs* fishbonesSubs, const RimFishbonesMultipleSubs* fishbonesSubs,
RicMswSegment* location, std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections, bool* foundSubGridIntersections,
double maxSegmentLength); double maxSegmentLength);
static void assignFractureIntersections(const RimEclipseCase* caseToApply, static void assignFractureIntersections(const RimEclipseCase* caseToApply,
const RimWellPathFracture* fracture, const RimWellPathFracture* fracture,
const std::vector<RigCompletionData>& completionData, const std::vector<RigCompletionData>& completionData,
RicMswSegment* location, std::shared_ptr<RicMswSegment> location,
bool* foundSubGridIntersections); bool* foundSubGridIntersections);
static void assignPerforationIntervalIntersections(const RimEclipseCase* caseToApply, static void assignPerforationIntervalIntersections(const std::vector<RigCompletionData>& completionData,
const RimPerforationInterval* interval, std::shared_ptr<RicMswCompletion> perforationCompletion,
const std::vector<RigCompletionData>& completionData, const SubSegmentIntersectionInfo& cellIntInfo,
RicMswSegment* location,
const SubSegmentIntersectionInfo* cellIntInfo,
bool* foundSubGridIntersections); bool* foundSubGridIntersections);
static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
RicMswSegment* location, std::shared_ptr<RicMswSegment> location,
int* branchNum, int* branchNum,
int* segmentNum); int* segmentNum);
static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, 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; RimPerforationInterval* perforationInterval = nullptr;
this->firstAncestorOrThisOfType(perforationInterval); this->firstAncestorOrThisOfType(perforationInterval);

View File

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