mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-11 07:56:08 -06:00
#3183 Refactor MSW export code so fishbones structures are not needed at the time of formatting/writing
* Instead fill up the RicMultiSegmentWellExportInfo structures beforehand
This commit is contained in:
parent
5081f12bb5
commit
ffd545c75c
@ -9,6 +9,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicCaseAndFileExportSettingsUi.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportFractureCompletionsImpl.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleWellPathsFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleSimWellsFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicMultiSegmentWellExportInfo.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.h
|
||||
)
|
||||
@ -24,6 +25,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicCaseAndFileExportSettingsUi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportFractureCompletionsImpl.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleWellPathsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleSimWellsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicMultiSegmentWellExportInfo.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.cpp
|
||||
)
|
||||
|
@ -184,260 +184,11 @@ void RicExportFishbonesWellSegmentsFeature::exportWellSegments(const RimWellPath
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<WellSegmentLocation> locations = RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(settings.caseToApply, wellPath, fishbonesSubs);
|
||||
RicMultiSegmentWellExportInfo exportInfo = RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMSWExportInfo(settings.caseToApply, wellPath, fishbonesSubs);
|
||||
|
||||
QTextStream stream(&exportFile);
|
||||
RifEclipseDataTableFormatter formatter(stream);
|
||||
generateWelsegsTable(formatter, wellPath, settings, locations);
|
||||
generateCompsegsTable(formatter, wellPath, settings, locations);
|
||||
generateWsegvalvTable(formatter, wellPath, settings, locations);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicExportFishbonesWellSegmentsFeature::generateWelsegsTable(RifEclipseDataTableFormatter& formatter,
|
||||
const RimWellPath* wellPath,
|
||||
const RicCaseAndFileExportSettingsUi& settings,
|
||||
const std::vector<WellSegmentLocation>& locations)
|
||||
{
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType();
|
||||
|
||||
formatter.keyword("WELSEGS");
|
||||
|
||||
double startMD = wellPath->fishbonesCollection()->startMD();
|
||||
double startTVD = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(startMD).z();
|
||||
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("Name"),
|
||||
RifEclipseOutputTableColumn("Dep 1"),
|
||||
RifEclipseOutputTableColumn("Tlen 1"),
|
||||
RifEclipseOutputTableColumn("Vol 1"),
|
||||
RifEclipseOutputTableColumn("Len&Dep"),
|
||||
RifEclipseOutputTableColumn("PresDrop"),
|
||||
};
|
||||
formatter.header(header);
|
||||
|
||||
formatter.add(wellPath->name());
|
||||
formatter.add(startTVD);
|
||||
formatter.add(startMD);
|
||||
formatter.add("1*");
|
||||
formatter.add(wellPath->fishbonesCollection()->lengthAndDepth().text());
|
||||
formatter.add(wellPath->fishbonesCollection()->pressureDrop().text());
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("First Seg"),
|
||||
RifEclipseOutputTableColumn("Last Seg"),
|
||||
RifEclipseOutputTableColumn("Branch Num"),
|
||||
RifEclipseOutputTableColumn("Outlet Seg"),
|
||||
RifEclipseOutputTableColumn("Length"),
|
||||
RifEclipseOutputTableColumn("Depth Change"),
|
||||
RifEclipseOutputTableColumn("Diam"),
|
||||
RifEclipseOutputTableColumn("Rough"),
|
||||
};
|
||||
formatter.header(header);
|
||||
}
|
||||
|
||||
{
|
||||
formatter.comment("Main stem");
|
||||
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
double previousMD = startMD;
|
||||
double previousTVD = startTVD;
|
||||
|
||||
for (const WellSegmentLocation& location : locations)
|
||||
{
|
||||
if (wellPath->fishbonesCollection()->lengthAndDepth() == RimFishbonesCollection::INC)
|
||||
{
|
||||
depth = location.trueVerticalDepth - previousTVD;
|
||||
length = location.fishbonesSubs->measuredDepth(location.subIndex) - previousMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth += location.trueVerticalDepth - previousTVD;
|
||||
length += location.fishbonesSubs->measuredDepth(location.subIndex) - previousMD;
|
||||
}
|
||||
|
||||
formatter.comment(QString("Segment for sub %1").arg(location.subIndex));
|
||||
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(length);
|
||||
formatter.add(depth);
|
||||
formatter.add(wellPath->fishbonesCollection()->linerDiameter(unitSystem));
|
||||
formatter.add(wellPath->fishbonesCollection()->roughnessFactor(unitSystem));
|
||||
formatter.rowCompleted();
|
||||
|
||||
previousMD = location.measuredDepth;
|
||||
previousTVD = location.trueVerticalDepth;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
formatter.comment("Laterals");
|
||||
formatter.comment("Diam: MSW - Tubing Radius");
|
||||
formatter.comment("Rough: MSW - Open Hole Roughness Factor");
|
||||
for (const WellSegmentLocation& location : locations)
|
||||
{
|
||||
formatter.comment("ICD");
|
||||
formatter.add(location.icdSegmentNumber).add(location.icdSegmentNumber);
|
||||
formatter.add(location.icdBranchNumber);
|
||||
formatter.add(location.segmentNumber);
|
||||
formatter.add(0.1); // ICDs have 0.1 length
|
||||
formatter.add(0); // Depth change
|
||||
formatter.add(wellPath->fishbonesCollection()->linerDiameter(unitSystem));
|
||||
formatter.add(wellPath->fishbonesCollection()->roughnessFactor(unitSystem));
|
||||
formatter.rowCompleted();
|
||||
|
||||
for (const WellSegmentLateral& lateral : location.laterals)
|
||||
{
|
||||
formatter.comment(QString("%1 : Sub index %2 - Lateral %3").arg(location.fishbonesSubs->generatedName()).arg(location.subIndex).arg(lateral.lateralIndex));
|
||||
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
|
||||
for (const WellSegmentLateralIntersection& intersection : lateral.intersections)
|
||||
{
|
||||
if (wellPath->fishbonesCollection()->lengthAndDepth() == RimFishbonesCollection::INC)
|
||||
{
|
||||
depth = intersection.tvdChangeFromPreviousIntersection;
|
||||
length = intersection.mdFromPreviousIntersection;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth += intersection.tvdChangeFromPreviousIntersection;
|
||||
length += intersection.mdFromPreviousIntersection;
|
||||
}
|
||||
double diameter = computeEffectiveDiameter(location.fishbonesSubs->tubingDiameter(unitSystem), location.fishbonesSubs->holeDiameter(unitSystem));
|
||||
formatter.add(intersection.segmentNumber);
|
||||
formatter.add(intersection.segmentNumber);
|
||||
formatter.add(lateral.branchNumber);
|
||||
formatter.add(intersection.attachedSegmentNumber);
|
||||
formatter.add(length);
|
||||
formatter.add(depth);
|
||||
formatter.add(diameter);
|
||||
formatter.add(location.fishbonesSubs->openHoleRoughnessFactor(unitSystem));
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicExportFishbonesWellSegmentsFeature::generateCompsegsTable(RifEclipseDataTableFormatter& formatter,
|
||||
const RimWellPath* wellPath,
|
||||
const RicCaseAndFileExportSettingsUi& settings,
|
||||
const std::vector<WellSegmentLocation>& locations)
|
||||
{
|
||||
RigMainGrid* grid = settings.caseToApply->eclipseCaseData()->mainGrid();
|
||||
formatter.keyword("COMPSEGS");
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("Name")
|
||||
};
|
||||
formatter.header(header);
|
||||
formatter.add(wellPath->name());
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("I"),
|
||||
RifEclipseOutputTableColumn("J"),
|
||||
RifEclipseOutputTableColumn("K"),
|
||||
RifEclipseOutputTableColumn("Branch no"),
|
||||
RifEclipseOutputTableColumn("Start Length"),
|
||||
RifEclipseOutputTableColumn("End Length"),
|
||||
RifEclipseOutputTableColumn("Dir Pen"),
|
||||
RifEclipseOutputTableColumn("End Range"),
|
||||
RifEclipseOutputTableColumn("Connection Depth")
|
||||
};
|
||||
formatter.header(header);
|
||||
}
|
||||
|
||||
for (const WellSegmentLocation& location : locations)
|
||||
{
|
||||
for (const WellSegmentLateral& lateral : location.laterals)
|
||||
{
|
||||
double aggregatedLength = 0;
|
||||
for (const WellSegmentLateralIntersection& intersection : lateral.intersections)
|
||||
{
|
||||
size_t i, j, k;
|
||||
grid->ijkFromCellIndex(intersection.globalCellIndex, &i, &j, &k);
|
||||
|
||||
formatter.addZeroBasedCellIndex(i).addZeroBasedCellIndex(j).addZeroBasedCellIndex(k);
|
||||
formatter.add(lateral.branchNumber);
|
||||
formatter.add(aggregatedLength);
|
||||
formatter.add(aggregatedLength + intersection.mdFromPreviousIntersection);
|
||||
formatter.rowCompleted();
|
||||
|
||||
aggregatedLength += intersection.mdFromPreviousIntersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicExportFishbonesWellSegmentsFeature::generateWsegvalvTable(RifEclipseDataTableFormatter& formatter,
|
||||
const RimWellPath* wellPath,
|
||||
const RicCaseAndFileExportSettingsUi& settings,
|
||||
const std::vector<WellSegmentLocation>& locations)
|
||||
{
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType();
|
||||
|
||||
{
|
||||
formatter.keyword("WSEGVALV");
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("Well Name"),
|
||||
RifEclipseOutputTableColumn("Seg No"),
|
||||
RifEclipseOutputTableColumn("Cv"),
|
||||
RifEclipseOutputTableColumn("Ac"),
|
||||
};
|
||||
formatter.header(header);
|
||||
}
|
||||
for (const WellSegmentLocation& location : locations)
|
||||
{
|
||||
formatter.add(wellPath->name());
|
||||
formatter.add(location.icdSegmentNumber);
|
||||
formatter.add(location.fishbonesSubs->icdFlowCoefficient());
|
||||
|
||||
double icdOrificeRadius = location.fishbonesSubs->icdOrificeDiameter(unitSystem) / 2;
|
||||
double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D;
|
||||
formatter.add(icdArea * static_cast<double>(location.fishbonesSubs->icdCount()));
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicExportFishbonesWellSegmentsFeature::computeEffectiveDiameter(double innerDiameter, double outerDiameter)
|
||||
{
|
||||
double innerRadius = innerDiameter / 2;
|
||||
double innerArea = cvf::PI_D * innerRadius * innerRadius;
|
||||
|
||||
double outerRadius = outerDiameter / 2;
|
||||
double outerArea = cvf::PI_D * outerRadius * outerRadius;
|
||||
|
||||
double effectiveArea = outerArea - innerArea;
|
||||
|
||||
double effectiveRadius = cvf::Math::sqrt(effectiveArea / cvf::PI_D);
|
||||
|
||||
return effectiveRadius * 2;
|
||||
RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(formatter, exportInfo);
|
||||
RicWellPathExportCompletionDataFeatureImpl::generateCompsegsTable(formatter, exportInfo);
|
||||
RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(formatter, exportInfo);
|
||||
}
|
||||
|
@ -21,15 +21,17 @@
|
||||
#include "RifEclipseDataTableFormatter.h"
|
||||
|
||||
#include "RicCaseAndFileExportSettingsUi.h"
|
||||
#include "RicMultiSegmentWellExportInfo.h"
|
||||
#include "RicWellPathExportCompletionDataFeatureImpl.h"
|
||||
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
class RimFishbonesCollection;
|
||||
class RimFishbonesMultipleSubs;
|
||||
class RimWellPath;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -48,10 +50,5 @@ public:
|
||||
private:
|
||||
static RimFishbonesCollection* selectedFishbonesCollection();
|
||||
static RimWellPath* selectedWellPath();
|
||||
|
||||
static void generateWelsegsTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector<WellSegmentLocation>& locations);
|
||||
static void generateCompsegsTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector<WellSegmentLocation>& locations);
|
||||
static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector<WellSegmentLocation>& locations);
|
||||
|
||||
static double computeEffectiveDiameter(double innerDiameter, double outerDiameter);
|
||||
|
||||
};
|
||||
|
@ -69,22 +69,22 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
|
||||
|
||||
// Generate data
|
||||
const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData();
|
||||
std::vector<WellSegmentLocation> locations = RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(settings.caseToApply, wellPath);
|
||||
RicMultiSegmentWellExportInfo exportInfo = RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMSWExportInfo(settings.caseToApply(), wellPath);
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = caseData->unitsType();
|
||||
bool isMainBore = false;
|
||||
|
||||
for (const WellSegmentLocation& location : locations)
|
||||
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
|
||||
{
|
||||
for (const WellSegmentLateral& lateral : location.laterals)
|
||||
for (const RicWellSegmentLateral& lateral : location.laterals)
|
||||
{
|
||||
for (const WellSegmentLateralIntersection& intersection : lateral.intersections)
|
||||
for (const RicWellSegmentLateralIntersection& intersection : lateral.intersections)
|
||||
{
|
||||
double diameter = location.fishbonesSubs->holeDiameter(unitSystem);
|
||||
QString completionMetaData = (location.fishbonesSubs->generatedName() + QString(": Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex));
|
||||
double diameter = location.holeDiameter;
|
||||
QString completionMetaData = (location.label + QString(": Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex));
|
||||
WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc(intersection.lengthsInCell,
|
||||
diameter / 2,
|
||||
location.fishbonesSubs->skinFactor(),
|
||||
location.skinFactor,
|
||||
isMainBore,
|
||||
completionMetaData);
|
||||
|
||||
|
@ -0,0 +1,141 @@
|
||||
#include "RicMultiSegmentWellExportInfo.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicWellSegmentLocation::operator<(const RicWellSegmentLocation& rhs) const
|
||||
{
|
||||
return measuredDepth < rhs.measuredDepth;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMultiSegmentWellExportInfo::setTopWellBoreVolume(double topWellBoreVolume)
|
||||
{
|
||||
m_topWellBoreVolume = topWellBoreVolume;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMultiSegmentWellExportInfo::setLinerDiameter(double linerDiameter)
|
||||
{
|
||||
m_linerDiameter = linerDiameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMultiSegmentWellExportInfo::setRoughnessFactor(double roughnessFactor)
|
||||
{
|
||||
m_roughnessFactor = roughnessFactor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMultiSegmentWellExportInfo::addWellSegmentLocation(const RicWellSegmentLocation& location)
|
||||
{
|
||||
m_wellSegmentLocations.push_back(location);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicMultiSegmentWellExportInfo::sortLocations()
|
||||
{
|
||||
std::sort(m_wellSegmentLocations.begin(), m_wellSegmentLocations.end());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPath* RicMultiSegmentWellExportInfo::wellPath() const
|
||||
{
|
||||
return m_wellPath;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMultiSegmentWellExportInfo::initialMD() const
|
||||
{
|
||||
return m_initialMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMultiSegmentWellExportInfo::initialTVD() const
|
||||
{
|
||||
return -m_wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(m_initialMD).z();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RicMultiSegmentWellExportInfo::unitSystem() const
|
||||
{
|
||||
return m_unitSystem;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMultiSegmentWellExportInfo::topWellBoreVolume() const
|
||||
{
|
||||
return m_topWellBoreVolume;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMultiSegmentWellExportInfo::linerDiameter() const
|
||||
{
|
||||
return m_linerDiameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicMultiSegmentWellExportInfo::roughnessFactor() const
|
||||
{
|
||||
return m_roughnessFactor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RicMultiSegmentWellExportInfo::lengthAndDepthText() const
|
||||
{
|
||||
return m_lengthAndDepthText;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RicMultiSegmentWellExportInfo::pressureDropText() const
|
||||
{
|
||||
return m_pressureDropText;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<RicWellSegmentLocation>& RicMultiSegmentWellExportInfo::wellSegmentLocations() const
|
||||
{
|
||||
return m_wellSegmentLocations;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RicWellSegmentLocation>& RicMultiSegmentWellExportInfo::wellSegmentLocations()
|
||||
{
|
||||
return m_wellSegmentLocations;
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2018 Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class RimWellPath;
|
||||
class RimFishbonesMultipleSubs;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
struct RicWellSegmentLateralIntersection
|
||||
{
|
||||
RicWellSegmentLateralIntersection(size_t globalCellIndex,
|
||||
const cvf::Vec3st& cellIJK,
|
||||
double length,
|
||||
double depth,
|
||||
const cvf::Vec3d& lengthsInCell)
|
||||
: segmentNumber(std::numeric_limits<int>::infinity())
|
||||
, attachedSegmentNumber(std::numeric_limits<int>::infinity())
|
||||
, globalCellIndex(globalCellIndex)
|
||||
, cellIJK(cellIJK)
|
||||
, mdFromPreviousIntersection(length)
|
||||
, tvdChangeFromPreviousIntersection(depth)
|
||||
, lengthsInCell(lengthsInCell)
|
||||
, mainBoreCell(false)
|
||||
{
|
||||
}
|
||||
int segmentNumber;
|
||||
int attachedSegmentNumber;
|
||||
size_t globalCellIndex;
|
||||
cvf::Vec3st cellIJK;
|
||||
bool mainBoreCell;
|
||||
double mdFromPreviousIntersection;
|
||||
double tvdChangeFromPreviousIntersection;
|
||||
cvf::Vec3d lengthsInCell;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
struct RicWellSegmentLateral
|
||||
{
|
||||
RicWellSegmentLateral(size_t lateralIndex)
|
||||
: lateralIndex(lateralIndex)
|
||||
, branchNumber(0)
|
||||
{
|
||||
}
|
||||
|
||||
size_t lateralIndex;
|
||||
int branchNumber;
|
||||
std::vector<RicWellSegmentLateralIntersection> intersections;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
struct RicWellSegmentLocation
|
||||
{
|
||||
RicWellSegmentLocation(const QString& label,
|
||||
double measuredDepth,
|
||||
double trueVerticalDepth,
|
||||
size_t subIndex,
|
||||
int segmentNumber = -1)
|
||||
: label(label)
|
||||
, measuredDepth(measuredDepth)
|
||||
, trueVerticalDepth(trueVerticalDepth)
|
||||
, effectiveDiameter(0.15)
|
||||
, holeDiameter(std::numeric_limits<double>::infinity())
|
||||
, openHoleRoughnessFactor(5.0e-5)
|
||||
, skinFactor(std::numeric_limits<double>::infinity())
|
||||
, icdFlowCoefficient(std::numeric_limits<double>::infinity())
|
||||
, icdArea(std::numeric_limits<double>::infinity())
|
||||
, subIndex(subIndex)
|
||||
, segmentNumber(segmentNumber)
|
||||
, icdBranchNumber(-1)
|
||||
, icdSegmentNumber(-1)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const RicWellSegmentLocation& rhs) const;
|
||||
|
||||
QString label;
|
||||
double measuredDepth;
|
||||
double trueVerticalDepth;
|
||||
double effectiveDiameter;
|
||||
double holeDiameter;
|
||||
double linerDiameter;
|
||||
double openHoleRoughnessFactor;
|
||||
double skinFactor;
|
||||
double icdFlowCoefficient;
|
||||
double icdArea;
|
||||
|
||||
size_t subIndex;
|
||||
int segmentNumber;
|
||||
int icdBranchNumber;
|
||||
int icdSegmentNumber;
|
||||
|
||||
std::vector<RicWellSegmentLateral> laterals;
|
||||
};
|
||||
|
||||
class RicMultiSegmentWellExportInfo
|
||||
{
|
||||
public:
|
||||
RicMultiSegmentWellExportInfo(const RimWellPath* wellPath,
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem,
|
||||
double initialMD,
|
||||
const QString& lengthAndDepthText,
|
||||
const QString& pressureDropText)
|
||||
: m_wellPath(wellPath)
|
||||
, m_initialMD(initialMD)
|
||||
, m_unitSystem(unitSystem)
|
||||
, m_topWellBoreVolume(std::numeric_limits<double>::infinity())
|
||||
, m_linerDiameter(0.15)
|
||||
, m_roughnessFactor(5.0e-5)
|
||||
, m_lengthAndDepthText(lengthAndDepthText)
|
||||
, m_pressureDropText(pressureDropText)
|
||||
{}
|
||||
|
||||
void setTopWellBoreVolume(double topWellBoreVolume);
|
||||
void setLinerDiameter(double linerDiameter);
|
||||
void setRoughnessFactor(double roughnessFactor);
|
||||
void addWellSegmentLocation(const RicWellSegmentLocation& location);
|
||||
void sortLocations();
|
||||
|
||||
const RimWellPath* wellPath() const;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const;
|
||||
double initialMD() const;
|
||||
double initialTVD() const;
|
||||
double topWellBoreVolume() const;
|
||||
double linerDiameter() const;
|
||||
double roughnessFactor() const;
|
||||
QString lengthAndDepthText() const;
|
||||
QString pressureDropText() const;
|
||||
|
||||
const std::vector<RicWellSegmentLocation>& wellSegmentLocations() const;
|
||||
std::vector<RicWellSegmentLocation>& wellSegmentLocations();
|
||||
|
||||
protected:
|
||||
const RimWellPath* m_wellPath;
|
||||
RiaEclipseUnitTools::UnitSystem m_unitSystem;
|
||||
double m_initialMD;
|
||||
double m_topWellBoreVolume;
|
||||
double m_linerDiameter;
|
||||
double m_roughnessFactor;
|
||||
QString m_lengthAndDepthText;
|
||||
QString m_pressureDropText;
|
||||
|
||||
std::vector<RicWellSegmentLocation> m_wellSegmentLocations;
|
||||
};
|
||||
|
@ -173,10 +173,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions(const std::ve
|
||||
|
||||
std::vector<RigCompletionData> fractureCompletionData =
|
||||
RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath(
|
||||
wellPath,
|
||||
exportSettings.caseToApply(),
|
||||
reportItems,
|
||||
fractureTransmissibilityExportInformationStream.get());
|
||||
wellPath, exportSettings.caseToApply(), reportItems, fractureTransmissibilityExportInformationStream.get());
|
||||
|
||||
appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, fractureCompletionData);
|
||||
appendCompletionData(&completionsPerEclipseCellFracture, fractureCompletionData);
|
||||
@ -400,6 +397,220 @@ std::vector<RigCompletionData>
|
||||
return completionsPerEclipseCell;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipseDataTableFormatter& formatter,
|
||||
const RicMultiSegmentWellExportInfo& exportInfo)
|
||||
{
|
||||
formatter.keyword("WELSEGS");
|
||||
|
||||
double startMD = exportInfo.initialMD();
|
||||
double startTVD = exportInfo.initialTVD();
|
||||
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("Name"),
|
||||
RifEclipseOutputTableColumn("Dep 1"),
|
||||
RifEclipseOutputTableColumn("Tlen 1"),
|
||||
RifEclipseOutputTableColumn("Vol 1"),
|
||||
RifEclipseOutputTableColumn("Len&Dep"),
|
||||
RifEclipseOutputTableColumn("PresDrop"),
|
||||
};
|
||||
formatter.header(header);
|
||||
|
||||
formatter.add(exportInfo.wellPath()->name());
|
||||
formatter.add(startTVD);
|
||||
formatter.add(startMD);
|
||||
formatter.add(exportInfo.topWellBoreVolume());
|
||||
formatter.add(exportInfo.lengthAndDepthText());
|
||||
formatter.add(exportInfo.pressureDropText());
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("First Seg"),
|
||||
RifEclipseOutputTableColumn("Last Seg"),
|
||||
RifEclipseOutputTableColumn("Branch Num"),
|
||||
RifEclipseOutputTableColumn("Outlet Seg"),
|
||||
RifEclipseOutputTableColumn("Length"),
|
||||
RifEclipseOutputTableColumn("Depth Change"),
|
||||
RifEclipseOutputTableColumn("Diam"),
|
||||
RifEclipseOutputTableColumn("Rough"),
|
||||
};
|
||||
formatter.header(header);
|
||||
}
|
||||
|
||||
{
|
||||
formatter.comment("Main stem");
|
||||
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
double previousMD = startMD;
|
||||
double previousTVD = startTVD;
|
||||
|
||||
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
|
||||
{
|
||||
if (exportInfo.lengthAndDepthText() == QString("INC"))
|
||||
{
|
||||
depth = location.trueVerticalDepth - previousTVD;
|
||||
length = location.measuredDepth - previousMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth += location.trueVerticalDepth - previousTVD;
|
||||
length += location.measuredDepth - previousMD;
|
||||
}
|
||||
|
||||
formatter.comment(QString("Segment for sub %1").arg(location.subIndex));
|
||||
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(length);
|
||||
formatter.add(depth);
|
||||
formatter.add(exportInfo.linerDiameter());
|
||||
formatter.add(exportInfo.roughnessFactor());
|
||||
formatter.rowCompleted();
|
||||
|
||||
previousMD = location.measuredDepth;
|
||||
previousTVD = location.trueVerticalDepth;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
formatter.comment("Laterals");
|
||||
formatter.comment("Diam: MSW - Tubing Radius");
|
||||
formatter.comment("Rough: MSW - Open Hole Roughness Factor");
|
||||
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
|
||||
{
|
||||
formatter.comment("ICD");
|
||||
formatter.add(location.icdSegmentNumber).add(location.icdSegmentNumber);
|
||||
formatter.add(location.icdBranchNumber);
|
||||
formatter.add(location.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();
|
||||
|
||||
for (const RicWellSegmentLateral& lateral : location.laterals)
|
||||
{
|
||||
formatter.comment(QString("%1 : Sub index %2 - Lateral %3")
|
||||
.arg(location.label)
|
||||
.arg(location.subIndex)
|
||||
.arg(lateral.lateralIndex));
|
||||
|
||||
double depth = 0;
|
||||
double length = 0;
|
||||
|
||||
for (const RicWellSegmentLateralIntersection& intersection : lateral.intersections)
|
||||
{
|
||||
if (exportInfo.lengthAndDepthText() == QString("INC"))
|
||||
{
|
||||
depth = intersection.tvdChangeFromPreviousIntersection;
|
||||
length = intersection.mdFromPreviousIntersection;
|
||||
}
|
||||
else
|
||||
{
|
||||
depth += intersection.tvdChangeFromPreviousIntersection;
|
||||
length += intersection.mdFromPreviousIntersection;
|
||||
}
|
||||
double diameter = location.effectiveDiameter;
|
||||
formatter.add(intersection.segmentNumber);
|
||||
formatter.add(intersection.segmentNumber);
|
||||
formatter.add(lateral.branchNumber);
|
||||
formatter.add(intersection.attachedSegmentNumber);
|
||||
formatter.add(length);
|
||||
formatter.add(depth);
|
||||
formatter.add(diameter);
|
||||
formatter.add(location.openHoleRoughnessFactor);
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::generateCompsegsTable(RifEclipseDataTableFormatter& formatter,
|
||||
const RicMultiSegmentWellExportInfo& exportInfo)
|
||||
{
|
||||
formatter.keyword("COMPSEGS");
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {RifEclipseOutputTableColumn("Name")};
|
||||
formatter.header(header);
|
||||
formatter.add(exportInfo.wellPath()->name());
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<RifEclipseOutputTableColumn> header = {RifEclipseOutputTableColumn("I"),
|
||||
RifEclipseOutputTableColumn("J"),
|
||||
RifEclipseOutputTableColumn("K"),
|
||||
RifEclipseOutputTableColumn("Branch no"),
|
||||
RifEclipseOutputTableColumn("Start Length"),
|
||||
RifEclipseOutputTableColumn("End Length"),
|
||||
RifEclipseOutputTableColumn("Dir Pen"),
|
||||
RifEclipseOutputTableColumn("End Range"),
|
||||
RifEclipseOutputTableColumn("Connection Depth")};
|
||||
formatter.header(header);
|
||||
}
|
||||
|
||||
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
|
||||
{
|
||||
for (const RicWellSegmentLateral& lateral : location.laterals)
|
||||
{
|
||||
double aggregatedLength = 0;
|
||||
for (const RicWellSegmentLateralIntersection& intersection : lateral.intersections)
|
||||
{
|
||||
cvf::Vec3st ijk = intersection.cellIJK;
|
||||
formatter.addZeroBasedCellIndex(ijk.x()).addZeroBasedCellIndex(ijk.y()).addZeroBasedCellIndex(ijk.z());
|
||||
formatter.add(lateral.branchNumber);
|
||||
formatter.add(aggregatedLength);
|
||||
formatter.add(aggregatedLength + intersection.mdFromPreviousIntersection);
|
||||
formatter.rowCompleted();
|
||||
|
||||
aggregatedLength += intersection.mdFromPreviousIntersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclipseDataTableFormatter& formatter,
|
||||
const RicMultiSegmentWellExportInfo& exportInfo)
|
||||
{
|
||||
{
|
||||
formatter.keyword("WSEGVALV");
|
||||
std::vector<RifEclipseOutputTableColumn> header = {
|
||||
RifEclipseOutputTableColumn("Well Name"),
|
||||
RifEclipseOutputTableColumn("Seg No"),
|
||||
RifEclipseOutputTableColumn("Cv"),
|
||||
RifEclipseOutputTableColumn("Ac"),
|
||||
};
|
||||
formatter.header(header);
|
||||
}
|
||||
for (const RicWellSegmentLocation& location : exportInfo.wellSegmentLocations())
|
||||
{
|
||||
formatter.add(exportInfo.wellPath()->name());
|
||||
formatter.add(location.icdSegmentNumber);
|
||||
formatter.add(location.icdFlowCoefficient);
|
||||
formatter.add(location.icdArea);
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -953,18 +1164,9 @@ std::vector<RigCompletionData> RicWellPathExportCompletionDataFeatureImpl::gener
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicWellPathExportCompletionDataFeatureImpl::wellSegmentLocationOrdering(const WellSegmentLocation& first,
|
||||
const WellSegmentLocation& second)
|
||||
{
|
||||
return first.measuredDepth < second.measuredDepth;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<WellSegmentLocation>
|
||||
RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath)
|
||||
RicMultiSegmentWellExportInfo
|
||||
RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMSWExportInfo(const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath)
|
||||
{
|
||||
std::vector<RimFishbonesMultipleSubs*> fishbonesSubs;
|
||||
|
||||
@ -979,55 +1181,72 @@ std::vector<WellSegmentLocation>
|
||||
}
|
||||
}
|
||||
|
||||
return findWellSegmentLocations(caseToApply, wellPath, fishbonesSubs);
|
||||
return generateFishbonesMSWExportInfo(caseToApply, wellPath, fishbonesSubs);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<WellSegmentLocation> RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(
|
||||
RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMSWExportInfo(
|
||||
const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath,
|
||||
const std::vector<RimFishbonesMultipleSubs*>& fishbonesSubs)
|
||||
{
|
||||
std::vector<WellSegmentLocation> wellSegmentLocations;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType();
|
||||
|
||||
RicMultiSegmentWellExportInfo exportInfo(wellPath,
|
||||
unitSystem,
|
||||
wellPath->fishbonesCollection()->startMD(),
|
||||
wellPath->fishbonesCollection()->lengthAndDepth().text(),
|
||||
wellPath->fishbonesCollection()->pressureDrop().text());
|
||||
exportInfo.setLinerDiameter(wellPath->fishbonesCollection()->linerDiameter(unitSystem));
|
||||
exportInfo.setRoughnessFactor(wellPath->fishbonesCollection()->roughnessFactor(unitSystem));
|
||||
for (RimFishbonesMultipleSubs* subs : fishbonesSubs)
|
||||
{
|
||||
for (auto& sub : subs->installedLateralIndices())
|
||||
{
|
||||
double measuredDepth = subs->measuredDepth(sub.subIndex);
|
||||
cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(measuredDepth);
|
||||
WellSegmentLocation location = WellSegmentLocation(subs, measuredDepth, -position.z(), sub.subIndex);
|
||||
double measuredDepth = subs->measuredDepth(sub.subIndex);
|
||||
cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(measuredDepth);
|
||||
|
||||
RicWellSegmentLocation location =
|
||||
RicWellSegmentLocation(subs->generatedName(), measuredDepth, -position.z(), sub.subIndex);
|
||||
location.effectiveDiameter = subs->effectiveDiameter(unitSystem);
|
||||
location.holeDiameter = subs->holeDiameter(unitSystem);
|
||||
location.openHoleRoughnessFactor = subs->openHoleRoughnessFactor(unitSystem);
|
||||
location.skinFactor = subs->skinFactor();
|
||||
location.icdFlowCoefficient = subs->icdFlowCoefficient();
|
||||
double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2;
|
||||
location.icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount();
|
||||
|
||||
for (size_t lateralIndex : sub.lateralIndices)
|
||||
{
|
||||
location.laterals.push_back(WellSegmentLateral(lateralIndex));
|
||||
location.laterals.push_back(RicWellSegmentLateral(lateralIndex));
|
||||
}
|
||||
wellSegmentLocations.push_back(location);
|
||||
assignLateralIntersections(caseToApply, subs, &location);
|
||||
|
||||
exportInfo.addWellSegmentLocation(location);
|
||||
}
|
||||
}
|
||||
std::sort(wellSegmentLocations.begin(), wellSegmentLocations.end(), wellSegmentLocationOrdering);
|
||||
exportInfo.sortLocations();
|
||||
|
||||
assignLateralIntersectionsAndBranchAndSegmentNumbers(caseToApply, &wellSegmentLocations);
|
||||
assignBranchAndSegmentNumbers(caseToApply, &exportInfo);
|
||||
|
||||
return wellSegmentLocations;
|
||||
return exportInfo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(const RimEclipseCase* caseToApply,
|
||||
WellSegmentLocation* location,
|
||||
int* branchNum,
|
||||
int* segmentNum)
|
||||
void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(const RimEclipseCase* caseToApply,
|
||||
const RimFishbonesMultipleSubs* fishbonesSubs,
|
||||
RicWellSegmentLocation* location)
|
||||
{
|
||||
for (WellSegmentLateral& lateral : location->laterals)
|
||||
{
|
||||
++(*branchNum);
|
||||
lateral.branchNumber = (*branchNum);
|
||||
const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid();
|
||||
|
||||
for (RicWellSegmentLateral& lateral : location->laterals)
|
||||
{
|
||||
std::vector<std::pair<cvf::Vec3d, double>> lateralCoordMDPairs =
|
||||
location->fishbonesSubs->coordsAndMDForLateral(location->subIndex, lateral.lateralIndex);
|
||||
fishbonesSubs->coordsAndMDForLateral(location->subIndex, lateral.lateralIndex);
|
||||
|
||||
if (lateralCoordMDPairs.empty())
|
||||
{
|
||||
@ -1052,22 +1271,20 @@ void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(cons
|
||||
double previousExitMD = lateralMDs.front();
|
||||
double previousExitTVD = lateralCoords.front().z();
|
||||
|
||||
int attachedSegmentNumber = location->icdSegmentNumber;
|
||||
for (const auto& cellIntInfo : intersections)
|
||||
{
|
||||
++(*segmentNum);
|
||||
WellSegmentLateralIntersection lateralIntersection((*segmentNum),
|
||||
attachedSegmentNumber,
|
||||
cellIntInfo.globCellIndex,
|
||||
cellIntInfo.endMD - previousExitMD,
|
||||
cellIntInfo.endPoint.z() - previousExitTVD,
|
||||
cellIntInfo.intersectionLengthsInCellCS);
|
||||
size_t i = 0u, j = 0u, k = 0u;
|
||||
grid->ijkFromCellIndex(cellIntInfo.globCellIndex, &i, &j, &k);
|
||||
RicWellSegmentLateralIntersection lateralIntersection(cellIntInfo.globCellIndex,
|
||||
cvf::Vec3st(i, j, k),
|
||||
cellIntInfo.endMD - previousExitMD,
|
||||
cellIntInfo.endPoint.z() - previousExitTVD,
|
||||
cellIntInfo.intersectionLengthsInCellCS);
|
||||
|
||||
lateral.intersections.push_back(lateralIntersection);
|
||||
|
||||
attachedSegmentNumber = (*segmentNum);
|
||||
previousExitMD = cellIntInfo.endMD;
|
||||
previousExitTVD = cellIntInfo.endPoint.z();
|
||||
previousExitMD = cellIntInfo.endMD;
|
||||
previousExitTVD = cellIntInfo.endPoint.z();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1075,15 +1292,38 @@ void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(cons
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersectionsAndBranchAndSegmentNumbers(
|
||||
const RimEclipseCase* caseToApply,
|
||||
std::vector<WellSegmentLocation>* locations)
|
||||
void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
|
||||
RicWellSegmentLocation* location,
|
||||
int* branchNum,
|
||||
int* segmentNum)
|
||||
{
|
||||
for (RicWellSegmentLateral& lateral : location->laterals)
|
||||
{
|
||||
++(*branchNum);
|
||||
lateral.branchNumber = (*branchNum);
|
||||
|
||||
int attachedSegmentNumber = location->icdSegmentNumber;
|
||||
for (auto& intersection : lateral.intersections)
|
||||
{
|
||||
++(*segmentNum);
|
||||
intersection.segmentNumber = *segmentNum;
|
||||
intersection.attachedSegmentNumber = attachedSegmentNumber;
|
||||
attachedSegmentNumber = *segmentNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
|
||||
RicMultiSegmentWellExportInfo* exportInfo)
|
||||
{
|
||||
int segmentNumber = 1;
|
||||
int branchNumber = 1;
|
||||
|
||||
// First loop over the locations so that each segment on the main stem is an incremental number
|
||||
for (WellSegmentLocation& location : *locations)
|
||||
for (RicWellSegmentLocation& location : exportInfo->wellSegmentLocations())
|
||||
{
|
||||
location.segmentNumber = ++segmentNumber;
|
||||
location.icdBranchNumber = ++branchNumber;
|
||||
@ -1091,9 +1331,9 @@ void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersectionsAndBr
|
||||
}
|
||||
|
||||
// Then assign branch and segment numbers to each lateral parts
|
||||
for (WellSegmentLocation& location : *locations)
|
||||
for (RicWellSegmentLocation& location : exportInfo->wellSegmentLocations())
|
||||
{
|
||||
assignLateralIntersections(caseToApply, &location, &branchNumber, &segmentNumber);
|
||||
assignBranchAndSegmentNumbers(caseToApply, &location, &branchNumber, &segmentNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "RigCompletionData.h"
|
||||
|
||||
#include "RicExportCompletionDataSettingsUi.h"
|
||||
#include "RicMultiSegmentWellExportInfo.h"
|
||||
#include "RicWellPathFractureReportItem.h"
|
||||
|
||||
#include "cvfBase.h"
|
||||
@ -38,82 +39,6 @@ class RimWellPath;
|
||||
class RifEclipseDataTableFormatter;
|
||||
class RigVirtualPerforationTransmissibilities;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
struct WellSegmentLateralIntersection
|
||||
{
|
||||
WellSegmentLateralIntersection(int segmentNumber,
|
||||
int attachedSegmentNumber,
|
||||
size_t globalCellIndex,
|
||||
double length,
|
||||
double depth,
|
||||
const cvf::Vec3d& lengthsInCell)
|
||||
: segmentNumber(segmentNumber)
|
||||
, attachedSegmentNumber(attachedSegmentNumber)
|
||||
, globalCellIndex(globalCellIndex)
|
||||
, mdFromPreviousIntersection(length)
|
||||
, tvdChangeFromPreviousIntersection(depth)
|
||||
, lengthsInCell(lengthsInCell)
|
||||
, mainBoreCell(false)
|
||||
{
|
||||
}
|
||||
|
||||
int segmentNumber;
|
||||
int attachedSegmentNumber;
|
||||
size_t globalCellIndex;
|
||||
bool mainBoreCell;
|
||||
double mdFromPreviousIntersection;
|
||||
double tvdChangeFromPreviousIntersection;
|
||||
cvf::Vec3d lengthsInCell;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
struct WellSegmentLateral
|
||||
{
|
||||
WellSegmentLateral(size_t lateralIndex)
|
||||
: lateralIndex(lateralIndex)
|
||||
, branchNumber(0)
|
||||
{
|
||||
}
|
||||
|
||||
size_t lateralIndex;
|
||||
int branchNumber;
|
||||
std::vector<WellSegmentLateralIntersection> intersections;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
struct WellSegmentLocation
|
||||
{
|
||||
WellSegmentLocation(const RimFishbonesMultipleSubs* subs,
|
||||
double measuredDepth,
|
||||
double trueVerticalDepth,
|
||||
size_t subIndex,
|
||||
int segmentNumber = -1)
|
||||
: fishbonesSubs(subs)
|
||||
, measuredDepth(measuredDepth)
|
||||
, trueVerticalDepth(trueVerticalDepth)
|
||||
, subIndex(subIndex)
|
||||
, segmentNumber(segmentNumber)
|
||||
, icdBranchNumber(-1)
|
||||
, icdSegmentNumber(-1)
|
||||
{
|
||||
}
|
||||
|
||||
const RimFishbonesMultipleSubs* fishbonesSubs;
|
||||
double measuredDepth;
|
||||
double trueVerticalDepth;
|
||||
size_t subIndex;
|
||||
int segmentNumber;
|
||||
int icdBranchNumber;
|
||||
int icdSegmentNumber;
|
||||
std::vector<WellSegmentLateral> laterals;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -121,12 +46,12 @@ class RicWellPathExportCompletionDataFeatureImpl
|
||||
{
|
||||
|
||||
public:
|
||||
static std::vector<WellSegmentLocation> findWellSegmentLocations(const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath);
|
||||
static RicMultiSegmentWellExportInfo generateFishbonesMSWExportInfo(const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath);
|
||||
|
||||
static std::vector<WellSegmentLocation> findWellSegmentLocations(const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath,
|
||||
const std::vector<RimFishbonesMultipleSubs*>& fishbonesSubs);
|
||||
static RicMultiSegmentWellExportInfo generateFishbonesMSWExportInfo(const RimEclipseCase* caseToApply,
|
||||
const RimWellPath* wellPath,
|
||||
const std::vector<RimFishbonesMultipleSubs*>& fishbonesSubs);
|
||||
|
||||
static CellDirection calculateDirectionInCell(RimEclipseCase* eclipseCase,
|
||||
size_t globalCellIndex,
|
||||
@ -154,6 +79,10 @@ public:
|
||||
RimEclipseCase* eclipseCase,
|
||||
size_t timeStepIndex);
|
||||
|
||||
static void generateWelsegsTable(RifEclipseDataTableFormatter& formatter, const RicMultiSegmentWellExportInfo& exportInfo);
|
||||
static void generateCompsegsTable(RifEclipseDataTableFormatter& formatter, const RicMultiSegmentWellExportInfo& exportInfo);
|
||||
static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, const RicMultiSegmentWellExportInfo& exportInfo);
|
||||
|
||||
private:
|
||||
static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase,
|
||||
double skinFactor,
|
||||
@ -189,16 +118,15 @@ private:
|
||||
static std::vector<RigCompletionData> generatePerforationsCompdatValues(const RimWellPath* wellPath,
|
||||
const RicExportCompletionDataSettingsUi& settings);
|
||||
|
||||
static bool wellSegmentLocationOrdering(const WellSegmentLocation& first,
|
||||
const WellSegmentLocation& second);
|
||||
|
||||
static void assignLateralIntersections(const RimEclipseCase* caseToApply,
|
||||
WellSegmentLocation* location,
|
||||
int* branchNum,
|
||||
int* segmentNum);
|
||||
|
||||
static void assignLateralIntersectionsAndBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
|
||||
std::vector<WellSegmentLocation>* locations);
|
||||
const RimFishbonesMultipleSubs* fishbonesSubs,
|
||||
RicWellSegmentLocation* location);
|
||||
static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
|
||||
RicWellSegmentLocation* location,
|
||||
int* branchNum,
|
||||
int* segmentNum);
|
||||
static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply,
|
||||
RicMultiSegmentWellExportInfo* exportInfo);
|
||||
|
||||
static void appendCompletionData(std::map<RigCompletionDataGridCell, std::vector<RigCompletionData>>* completionData,
|
||||
const std::vector<RigCompletionData>& data);
|
||||
|
@ -343,6 +343,11 @@ int RifEclipseDataTableFormatter::tableWidth() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseDataTableFormatter::format(double num, RifEclipseOutputTableDoubleFormatting doubleFormat)
|
||||
{
|
||||
if (num == std::numeric_limits<double>::infinity())
|
||||
{
|
||||
return QString("1*"); // Eclipse default column value
|
||||
}
|
||||
|
||||
switch (doubleFormat.format)
|
||||
{
|
||||
case RifEclipseOutputTableDoubleFormat::RIF_FLOAT:
|
||||
|
@ -240,6 +240,23 @@ double RimFishbonesMultipleSubs::tubingDiameter(RiaEclipseUnitTools::UnitSystem
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFishbonesMultipleSubs::effectiveDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const
|
||||
{
|
||||
double innerRadius = tubingDiameter(unitSystem) / 2;
|
||||
double outerRadius = holeDiameter(unitSystem) / 2;
|
||||
|
||||
double innerArea = cvf::PI_D * innerRadius * innerRadius;
|
||||
double outerArea = cvf::PI_D * outerRadius * outerRadius;
|
||||
|
||||
double effectiveArea = outerArea - innerArea;
|
||||
|
||||
double effectiveRadius = cvf::Math::sqrt(effectiveArea / cvf::PI_D);
|
||||
return effectiveRadius * 2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -86,6 +86,7 @@ public:
|
||||
|
||||
double tubingDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const;
|
||||
double holeDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const { return m_pipeProperties()->holeDiameter(unitSystem); }
|
||||
double effectiveDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const;
|
||||
double skinFactor() const { return m_pipeProperties()->skinFactor(); }
|
||||
double openHoleRoughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) const;
|
||||
double icdOrificeDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const;
|
||||
|
Loading…
Reference in New Issue
Block a user