diff --git a/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake index 587e2d6b32..540be00e4a 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake @@ -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 ) diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp index 6d6df0b84d..b2482fe12d 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp @@ -184,260 +184,11 @@ void RicExportFishbonesWellSegmentsFeature::exportWellSegments(const RimWellPath return; } - std::vector 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& 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 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 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& locations) -{ - RigMainGrid* grid = settings.caseToApply->eclipseCaseData()->mainGrid(); - formatter.keyword("COMPSEGS"); - { - std::vector header = { - RifEclipseOutputTableColumn("Name") - }; - formatter.header(header); - formatter.add(wellPath->name()); - formatter.rowCompleted(); - } - - { - std::vector 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& locations) -{ - RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType(); - - { - formatter.keyword("WSEGVALV"); - std::vector 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(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); } diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h index fe125abb2c..35d714ab43 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h @@ -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& locations); - static void generateCompsegsTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector& locations); - static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector& locations); - - static double computeEffectiveDiameter(double innerDiameter, double outerDiameter); + }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp index e4775e46c6..c54474c701 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp @@ -69,22 +69,22 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell // Generate data const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData(); - std::vector 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); diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp new file mode 100644 index 0000000000..7d913e3642 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp @@ -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& RicMultiSegmentWellExportInfo::wellSegmentLocations() const +{ + return m_wellSegmentLocations; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RicMultiSegmentWellExportInfo::wellSegmentLocations() +{ + return m_wellSegmentLocations; +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h new file mode 100644 index 0000000000..abced0c406 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaEclipseUnitTools.h" + +#include "cvfBase.h" +#include "cvfVector3.h" + +#include + +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::infinity()) + , attachedSegmentNumber(std::numeric_limits::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 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::infinity()) + , openHoleRoughnessFactor(5.0e-5) + , skinFactor(std::numeric_limits::infinity()) + , icdFlowCoefficient(std::numeric_limits::infinity()) + , icdArea(std::numeric_limits::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 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::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& wellSegmentLocations() const; + std::vector& 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 m_wellSegmentLocations; +}; + diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp index 4540deac08..86fa40d8a5 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp @@ -173,10 +173,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions(const std::ve std::vector 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 return completionsPerEclipseCell; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipseDataTableFormatter& formatter, + const RicMultiSegmentWellExportInfo& exportInfo) +{ + formatter.keyword("WELSEGS"); + + double startMD = exportInfo.initialMD(); + double startTVD = exportInfo.initialTVD(); + + { + std::vector 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 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 header = {RifEclipseOutputTableColumn("Name")}; + formatter.header(header); + formatter.add(exportInfo.wellPath()->name()); + formatter.rowCompleted(); + } + + { + std::vector 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 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 RicWellPathExportCompletionDataFeatureImpl::gener //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicWellPathExportCompletionDataFeatureImpl::wellSegmentLocationOrdering(const WellSegmentLocation& first, - const WellSegmentLocation& second) -{ - return first.measuredDepth < second.measuredDepth; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector - RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(const RimEclipseCase* caseToApply, - const RimWellPath* wellPath) +RicMultiSegmentWellExportInfo + RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMSWExportInfo(const RimEclipseCase* caseToApply, + const RimWellPath* wellPath) { std::vector fishbonesSubs; @@ -979,55 +1181,72 @@ std::vector } } - return findWellSegmentLocations(caseToApply, wellPath, fishbonesSubs); + return generateFishbonesMSWExportInfo(caseToApply, wellPath, fishbonesSubs); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations( +RicMultiSegmentWellExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMSWExportInfo( const RimEclipseCase* caseToApply, const RimWellPath* wellPath, const std::vector& fishbonesSubs) { - std::vector 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> 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* 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); } } diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h index 20a00a7785..3af48dd30a 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h @@ -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 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 laterals; -}; - //================================================================================================== /// //================================================================================================== @@ -121,12 +46,12 @@ class RicWellPathExportCompletionDataFeatureImpl { public: - static std::vector findWellSegmentLocations(const RimEclipseCase* caseToApply, - const RimWellPath* wellPath); + static RicMultiSegmentWellExportInfo generateFishbonesMSWExportInfo(const RimEclipseCase* caseToApply, + const RimWellPath* wellPath); - static std::vector findWellSegmentLocations(const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - const std::vector& fishbonesSubs); + static RicMultiSegmentWellExportInfo generateFishbonesMSWExportInfo(const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + const std::vector& 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 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* 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>* completionData, const std::vector& data); diff --git a/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp b/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp index 4bcbe5ce2a..4bdfdf9149 100644 --- a/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp +++ b/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp @@ -343,6 +343,11 @@ int RifEclipseDataTableFormatter::tableWidth() const //-------------------------------------------------------------------------------------------------- QString RifEclipseDataTableFormatter::format(double num, RifEclipseOutputTableDoubleFormatting doubleFormat) { + if (num == std::numeric_limits::infinity()) + { + return QString("1*"); // Eclipse default column value + } + switch (doubleFormat.format) { case RifEclipseOutputTableDoubleFormat::RIF_FLOAT: diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp index a5e4f57172..c7b8785d02 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp @@ -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; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h index 4b4166d250..404a6b2758 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h @@ -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;