From 03a95857c8ea460a907fbe473fc6d468d727e860 Mon Sep 17 00:00:00 2001 From: astridkbjorke Date: Mon, 12 Jun 2017 13:40:49 +0200 Subject: [PATCH] Moving fishbones transmissibility calculation to a separate class --- .../CompletionCommands/CMakeLists_files.cmake | 2 + ...sTransmissibilityCalculationFeatureImp.cpp | 131 ++++++++++++++++++ ...nesTransmissibilityCalculationFeatureImp.h | 37 +++++ ...RicWellPathExportCompletionDataFeature.cpp | 103 +------------- .../RicWellPathExportCompletionDataFeature.h | 16 +-- 5 files changed, 181 insertions(+), 108 deletions(-) create mode 100644 ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp create mode 100644 ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h diff --git a/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake index 1cd56d0bbe..28424d8825 100644 --- a/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake @@ -18,6 +18,7 @@ ${CEE_CURRENT_LIST_DIR}RicNewPerforationIntervalAtMeasuredDepthFeature.h ${CEE_CURRENT_LIST_DIR}RicWellPathExportCompletionDataFeature.h ${CEE_CURRENT_LIST_DIR}RicWellPathImportCompletionsFileFeature.h ${CEE_CURRENT_LIST_DIR}RicWellPathImportPerforationIntervalsFeature.h +${CEE_CURRENT_LIST_DIR}RicFishbonesTransmissibilityCalculationFeatureImp.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -34,6 +35,7 @@ ${CEE_CURRENT_LIST_DIR}RicNewPerforationIntervalAtMeasuredDepthFeature.cpp ${CEE_CURRENT_LIST_DIR}RicWellPathExportCompletionDataFeature.cpp ${CEE_CURRENT_LIST_DIR}RicWellPathImportCompletionsFileFeature.cpp ${CEE_CURRENT_LIST_DIR}RicWellPathImportPerforationIntervalsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicFishbonesTransmissibilityCalculationFeatureImp.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp b/ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp new file mode 100644 index 0000000000..8a17332c65 --- /dev/null +++ b/ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp @@ -0,0 +1,131 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicFishbonesTransmissibilityCalculationFeatureImp.h" + +#include "RigEclipseCaseData.h" +#include "RicExportCompletionDataSettingsUi.h" +#include "RicWellPathExportCompletionDataFeature.h" +#include "RimWellPath.h" +#include "RigWellPath.h" +#include "RimFishboneWellPath.h" +#include "RimFishbonesCollection.h" +#include "RigMainGrid.h" +#include "RimFishbonesMultipleSubs.h" +#include "RimFishboneWellPathCollection.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings) +{ + // Generate data + const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData(); + std::vector locations = RicWellPathExportCompletionDataFeature::findWellSegmentLocations(settings.caseToApply, wellPath); + + // Filter out cells where main bore is present + if (settings.removeLateralsInMainBoreCells()) + { + std::vector wellPathCells = RicWellPathExportCompletionDataFeature::findIntersectingCells(caseData, wellPath->wellPathGeometry()->m_wellPathPoints); + RicWellPathExportCompletionDataFeature::markWellPathCells(wellPathCells, &locations); + } + + RigMainGrid* grid = settings.caseToApply->eclipseCaseData()->mainGrid(); + + std::vector completionData; + + for (const WellSegmentLocation& location : locations) + { + for (const WellSegmentLateral& lateral : location.laterals) + { + for (const WellSegmentLateralIntersection& intersection : lateral.intersections) + { + if (intersection.mainBoreCell && settings.removeLateralsInMainBoreCells()) continue; + + size_t i, j, k; + grid->ijkFromCellIndex(intersection.cellIndex, &i, &j, &k); + RigCompletionData completion(wellPath->name(), IJKCellIndex(i, j, k)); + completion.addMetadata(location.fishbonesSubs->name(), QString("Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex)); + double diameter = location.fishbonesSubs->holeDiameter() / 1000; + if (settings.computeTransmissibility()) + { + double transmissibility = RicWellPathExportCompletionDataFeature::calculateTransmissibility(settings.caseToApply, + wellPath, + intersection.lengthsInCell, + location.fishbonesSubs->skinFactor(), + diameter / 2, + intersection.cellIndex); + completion.setFromFishbone(transmissibility, location.fishbonesSubs->skinFactor()); + } + else { + CellDirection direction = RicWellPathExportCompletionDataFeature::calculateDirectionInCell(settings.caseToApply, intersection.cellIndex, intersection.lengthsInCell); + completion.setFromFishbone(diameter, direction); + } + completionData.push_back(completion); + } + } + } + + return completionData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicFishbonesTransmissibilityCalculationFeatureImp::generateFishbonesImportedLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings) +{ + std::vector completionData; + + std::vector wellPathCells = RicWellPathExportCompletionDataFeature::findIntersectingCells(settings.caseToApply()->eclipseCaseData(), wellPath->wellPathGeometry()->m_wellPathPoints); + + double diameter = wellPath->fishbonesCollection()->wellPathCollection()->holeDiameter() / 1000; + for (const RimFishboneWellPath* fishbonesPath : wellPath->fishbonesCollection()->wellPathCollection()->wellPaths()) + { + std::vector intersectedCells = RigWellPathIntersectionTools::findCellsIntersectedByPath(settings.caseToApply->eclipseCaseData(), fishbonesPath->coordinates()); + for (auto& cell : intersectedCells) + { + if (std::find(wellPathCells.begin(), wellPathCells.end(), cell.cellIndex) != wellPathCells.end()) continue; + + size_t i, j, k; + settings.caseToApply->eclipseCaseData()->mainGrid()->ijkFromCellIndex(cell.cellIndex, &i, &j, &k); + RigCompletionData completion(wellPath->name(), IJKCellIndex(i, j, k)); + completion.addMetadata(fishbonesPath->name(), ""); + if (settings.computeTransmissibility()) + { + double skinFactor = wellPath->fishbonesCollection()->wellPathCollection()->skinFactor(); + double transmissibility = RicWellPathExportCompletionDataFeature::calculateTransmissibility(settings.caseToApply(), + wellPath, + cell.internalCellLengths, + skinFactor, + diameter / 2, + cell.cellIndex); + completion.setFromFishbone(transmissibility, skinFactor); + } + else { + CellDirection direction = RicWellPathExportCompletionDataFeature::calculateDirectionInCell(settings.caseToApply, cell.cellIndex, cell.internalCellLengths); + completion.setFromFishbone(diameter, direction); + } + completionData.push_back(completion); + } + } + + return completionData; +} + + diff --git a/ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h b/ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h new file mode 100644 index 0000000000..7571cf1319 --- /dev/null +++ b/ApplicationCode/Commands/CompletionCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 + +class RigCompletionData; +class RimWellPath; +class RicExportCompletionDataSettingsUi; + +class RicFishbonesTransmissibilityCalculationFeatureImp +{ +public: + static std::vector generateFishboneLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings); + static std::vector generateFishbonesImportedLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings); + +private: + + +}; + diff --git a/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.cpp index 69381e19d6..b6fdd02332 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.cpp +++ b/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.cpp @@ -52,6 +52,7 @@ #include #include #include +#include "RicFishbonesTransmissibilityCalculationFeatureImp.h" CAF_CMD_SOURCE_INIT(RicWellPathExportCompletionDataFeature, "RicWellPathExportCompletionDataFeature"); @@ -190,9 +191,9 @@ void RicWellPathExportCompletionDataFeature::exportCompletions(const std::vector } if (exportSettings.includeFishbones) { - std::vector fishbonesCompletionData = generateFishboneLateralsCompdatValues(wellPath, exportSettings); + std::vector fishbonesCompletionData = RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneLateralsCompdatValues(wellPath, exportSettings); appendCompletionData(&completionData, fishbonesCompletionData); - std::vector fishbonesWellPathCompletionData = generateFishbonesImportedLateralsCompdatValues(wellPath, exportSettings); + std::vector fishbonesWellPathCompletionData = RicFishbonesTransmissibilityCalculationFeatureImp::generateFishbonesImportedLateralsCompdatValues(wellPath, exportSettings); appendCompletionData(&completionData, fishbonesWellPathCompletionData); } } @@ -322,104 +323,6 @@ void RicWellPathExportCompletionDataFeature::generateWpimultTable(RifEclipseData formatter.tableCompleted(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RicWellPathExportCompletionDataFeature::generateFishboneLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings) -{ - // Generate data - const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData(); - std::vector locations = findWellSegmentLocations(settings.caseToApply, wellPath); - - // Filter out cells where main bore is present - if (settings.removeLateralsInMainBoreCells()) - { - std::vector wellPathCells = findIntersectingCells(caseData, wellPath->wellPathGeometry()->m_wellPathPoints); - markWellPathCells(wellPathCells, &locations); - } - - RigMainGrid* grid = settings.caseToApply->eclipseCaseData()->mainGrid(); - - std::vector completionData; - - for (const WellSegmentLocation& location : locations) - { - for (const WellSegmentLateral& lateral : location.laterals) - { - for (const WellSegmentLateralIntersection& intersection : lateral.intersections) - { - if (intersection.mainBoreCell && settings.removeLateralsInMainBoreCells()) continue; - - size_t i, j, k; - grid->ijkFromCellIndex(intersection.cellIndex, &i, &j, &k); - RigCompletionData completion(wellPath->name(), IJKCellIndex(i, j, k)); - completion.addMetadata(location.fishbonesSubs->name(), QString("Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex)); - double diameter = location.fishbonesSubs->holeDiameter() / 1000; - if (settings.computeTransmissibility()) - { - double transmissibility = calculateTransmissibility(settings.caseToApply, - wellPath, - intersection.lengthsInCell, - location.fishbonesSubs->skinFactor(), - diameter / 2, - intersection.cellIndex); - completion.setFromFishbone(transmissibility, location.fishbonesSubs->skinFactor()); - } - else { - CellDirection direction = calculateDirectionInCell(settings.caseToApply, intersection.cellIndex, intersection.lengthsInCell); - completion.setFromFishbone(diameter, direction); - } - completionData.push_back(completion); - } - } - } - - return completionData; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RicWellPathExportCompletionDataFeature::generateFishbonesImportedLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings) -{ - std::vector completionData; - - std::vector wellPathCells = findIntersectingCells(settings.caseToApply()->eclipseCaseData(), wellPath->wellPathGeometry()->m_wellPathPoints); - - double diameter = wellPath->fishbonesCollection()->wellPathCollection()->holeDiameter() / 1000; - for (const RimFishboneWellPath* fishbonesPath : wellPath->fishbonesCollection()->wellPathCollection()->wellPaths()) - { - std::vector intersectedCells = RigWellPathIntersectionTools::findCellsIntersectedByPath(settings.caseToApply->eclipseCaseData(), fishbonesPath->coordinates()); - for (auto& cell : intersectedCells) - { - if (std::find(wellPathCells.begin(), wellPathCells.end(), cell.cellIndex) != wellPathCells.end()) continue; - - size_t i, j, k; - settings.caseToApply->eclipseCaseData()->mainGrid()->ijkFromCellIndex(cell.cellIndex, &i, &j, &k); - RigCompletionData completion(wellPath->name(), IJKCellIndex(i, j, k)); - completion.addMetadata(fishbonesPath->name(), ""); - if (settings.computeTransmissibility()) - { - double skinFactor = wellPath->fishbonesCollection()->wellPathCollection()->skinFactor(); - double transmissibility = calculateTransmissibility(settings.caseToApply(), - wellPath, - cell.internalCellLengths, - skinFactor, - diameter / 2, - cell.cellIndex); - completion.setFromFishbone(transmissibility, skinFactor); - } - else { - CellDirection direction = calculateDirectionInCell(settings.caseToApply, cell.cellIndex, cell.internalCellLengths); - completion.setFromFishbone(diameter, direction); - } - completionData.push_back(completion); - } - } - - return completionData; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.h b/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.h index b0d09da693..a27e1377f9 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicWellPathExportCompletionDataFeature.h @@ -131,19 +131,21 @@ public: static std::vector findWellSegmentLocations(const RimEclipseCase* caseToApply, const RimWellPath* wellPath); static std::vector findWellSegmentLocations(const RimEclipseCase* caseToApply, const RimWellPath* wellPath, const std::vector& fishbonesSubs); + //functions also used by RicFishbonesTransmissibilityCalculationFeatureImp + static std::vector findIntersectingCells(const RigEclipseCaseData* grid, const std::vector& coords); + static void markWellPathCells(const std::vector& wellPathCells, std::vector* locations); + static CellDirection calculateDirectionInCell(RimEclipseCase* eclipseCase, size_t cellIndex, const cvf::Vec3d& lengthsInCell); + static double calculateTransmissibility(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, const cvf::Vec3d& internalCellLengths, double skinFactor, double wellRadius, size_t cellIndex); + + private: static void exportCompletions(const std::vector& wellPaths, const RicExportCompletionDataSettingsUi& exportSettings); static void generateCompdatTable(RifEclipseDataTableFormatter& formatter, const std::vector& completionData); static void generateWpimultTable(RifEclipseDataTableFormatter& formatter, const std::vector& completionData); - static std::vector generateFishboneLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings); - static std::vector generateFishbonesImportedLateralsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings); - static std::vector generatePerforationsCompdatValues(const RimWellPath* wellPath, const RicExportCompletionDataSettingsUi& settings); - static std::vector findIntersectingCells(const RigEclipseCaseData* grid, const std::vector& coords); - static void markWellPathCells(const std::vector& wellPathCells, std::vector* locations); static bool wellSegmentLocationOrdering(const WellSegmentLocation& first, const WellSegmentLocation& second); static bool isPointBetween(const cvf::Vec3d& pointA, const cvf::Vec3d& pointB, const cvf::Vec3d& needle); static void calculateLateralIntersections(const RimEclipseCase* caseToApply, WellSegmentLocation* location, int* branchNum, int* segmentNum); @@ -151,7 +153,5 @@ private: static void appendCompletionData(std::map* completionData, const std::vector& data); - static CellDirection calculateDirectionInCell(RimEclipseCase* eclipseCase, size_t cellIndex, const cvf::Vec3d& lengthsInCell); - - static double calculateTransmissibility(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, const cvf::Vec3d& internalCellLengths, double skinFactor, double wellRadius, size_t cellIndex); }; +