From ffa1a8518714028776a99aa1ceb6608e18f76f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Jensen?= Date: Tue, 23 Oct 2018 11:13:12 +0200 Subject: [PATCH] #3515 LGR Export/Temp LGR. New split type: One LGR per Completion --- .../RicfExportLgrForCompletions.cpp | 20 +- .../RicfExportLgrForCompletions.h | 13 +- .../RicExportFractureCompletionsImpl.cpp | 1 + ...sTransmissibilityCalculationFeatureImp.cpp | 17 +- ...nesTransmissibilityCalculationFeatureImp.h | 4 +- .../RicMultiSegmentWellExportInfo.cpp | 16 ++ .../RicMultiSegmentWellExportInfo.h | 5 + ...ellPathExportCompletionDataFeatureImpl.cpp | 2 + .../ExportCommands/RicExportLgrFeature.cpp | 236 ++++++++++++++---- .../ExportCommands/RicExportLgrFeature.h | 73 +++++- .../ExportCommands/RicExportLgrUi.cpp | 11 +- .../Commands/ExportCommands/RicExportLgrUi.h | 6 +- .../Commands/RicCreateTemporaryLgrFeature.cpp | 56 +++-- .../Completions/RigCompletionData.cpp | 17 ++ .../Completions/RigCompletionData.h | 8 + 15 files changed, 358 insertions(+), 127 deletions(-) diff --git a/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp index db5bd16cba..894b0cde51 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp @@ -41,18 +41,6 @@ CAF_PDM_SOURCE_INIT(RicfExportLgrForCompletions, "exportLgrForCompletions"); -namespace caf -{ - template<> - void RicfExportLgrForCompletions::LgrSplitType::setUp() - { - addItem(ExportLgr::ONE_LGR_PER_GRID_CELL, "ONE_LGR_PER_GRID_CELL", "One LGR per Main Grid Cell"); - addItem(ExportLgr::SINGLE_LGR_ALL_GRID_CELLS, "SINGLE_LGR_ALL_GRID_CELLS", "One Single LGR for all Main Grid Cells"); - - setDefault(ExportLgr::NONE); - } -} // namespace caf - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -64,7 +52,7 @@ RicfExportLgrForCompletions::RicfExportLgrForCompletions() RICF_InitField(&m_refinementI, "refinementI", -1, "RefinementI", "", "", ""); RICF_InitField(&m_refinementJ, "refinementJ", -1, "RefinementJ", "", "", ""); RICF_InitField(&m_refinementK, "refinementK", -1, "RefinementK", "", "", ""); - RICF_InitField(&m_splitType, "splitType", LgrSplitType(ExportLgr::ONE_LGR_PER_GRID_CELL), "SplitType", "", "", ""); + RICF_InitField(&m_splitType, "splitType", LgrSplitType(), "SplitType", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -107,7 +95,11 @@ void RicfExportLgrForCompletions::execute() { if (wellPath) { - if (!feature->exportLgrsForWellPath(exportFolder, wellPath, eclipseCase, m_timeStep, lgrCellCounts, m_splitType == ExportLgr::SINGLE_LGR_ALL_GRID_CELLS)) + try + { + feature->exportLgrsForWellPath(exportFolder, wellPath, eclipseCase, m_timeStep, lgrCellCounts, m_splitType()); + } + catch(CreateLgrException e) { lgrIntersected = true; } diff --git a/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h index 73e4871668..5a2c3a4a82 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h +++ b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h @@ -20,20 +20,13 @@ #include "RicfCommandObject.h" +#include "ExportCommands/RicExportLgrUi.h" + #include "cafAppEnum.h" #include "cafPdmField.h" class RimWellPath; -namespace ExportLgr -{ - enum SplitType - { - NONE, - ONE_LGR_PER_GRID_CELL, - SINGLE_LGR_ALL_GRID_CELLS - }; -} //================================================================================================== // @@ -44,7 +37,7 @@ class RicfExportLgrForCompletions : public RicfCommandObject { CAF_PDM_HEADER_INIT; - typedef caf::AppEnum LgrSplitType; + typedef caf::AppEnum LgrSplitType; public: RicfExportLgrForCompletions(); diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp index a3ed19d129..a8cd2b5f78 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp @@ -743,6 +743,7 @@ std::vector RicExportFractureCompletionsImpl::generateCompdat double diameter = 2.0 * fracture->wellRadius(); compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter); compDat.addMetadata(fracture->name(), QString::number(trans)); + compDat.setSourcePdmObject(fracture); allCompletionsForOneFracture.push_back(compDat); } diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp index 92c9e1c90a..ead249d6a7 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp @@ -36,6 +36,9 @@ #include "RimWellPath.h" #include "RimWellPathCompletions.h" +#include +#include + //================================================================================================== /// //================================================================================================== @@ -60,6 +63,9 @@ struct WellBorePartForTransCalc double intersectionWithWellMeasuredDepth; size_t lateralIndex; + + void setSourcePdmObject(const caf::PdmObject* sourcePdmObj) { this->sourcePdmObject = const_cast(sourcePdmObj); } + caf::PdmPointer sourcePdmObject; }; //-------------------------------------------------------------------------------------------------- @@ -161,7 +167,7 @@ std::vector transmissibility, wellBorePart.skinFactor, wellBorePart.wellRadius * 2, direction, wellBorePart.isMainBore); completion.addMetadata(wellBorePart.metaData, QString::number(transmissibility)); - + completion.setSourcePdmObject(wellBorePart.sourcePdmObject); completionData.push_back(completion); } } @@ -203,6 +209,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell wellBorePart.intersectionWithWellMeasuredDepth = location.endMD(); wellBorePart.lateralIndex = completion.index(); + wellBorePart.setSourcePdmObject(location.sourcePdmObject()); wellBorePartsInCells[intersection.globalCellIndex()].push_back(wellBorePart); } @@ -231,7 +238,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell endMD += 0.5; } - appendMainWellBoreParts(wellBorePartsInCells, wellPath, settings, skinFactor, holeRadius, startMD, endMD); + appendMainWellBoreParts(wellBorePartsInCells, wellPath, settings, skinFactor, holeRadius, startMD, endMD, fishboneDefinition); } } } @@ -290,7 +297,8 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts( double skinFactor, double holeRadius, double startMeasuredDepth, - double endMeasuredDepth) + double endMeasuredDepth, + const RimFishbonesMultipleSubs* fishbonesDefintions) { if (!wellPath) return; if (!wellPath->wellPathGeometry()) return; @@ -299,7 +307,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts( bool isMainBore = true; std::pair, std::vector> fishbonePerfWellPathCoords = - wellPath->wellPathGeometry()->clippedPointSubset(startMeasuredDepth, endMeasuredDepth); + wellPath->wellPathGeometry()->clippedPointSubset(startMeasuredDepth, endMeasuredDepth); std::vector intersectedCellsIntersectionInfo = RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( @@ -313,6 +321,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts( wellBorePart.intersectionWithWellMeasuredDepth = cellIntersectionInfo.startMD; + wellBorePart.setSourcePdmObject(fishbonesDefintions); wellBorePartsInCells[cellIntersectionInfo.globCellIndex].push_back(wellBorePart); } } diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h index 91fa981080..6f1a60bab1 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h @@ -27,6 +27,7 @@ class RigCompletionData; class RimWellPath; +class RimFishbonesMultipleSubs; class RicExportCompletionDataSettingsUi; class RigEclipseCaseData; @@ -58,5 +59,6 @@ private: double skinFactor, double holeRadius, double startMeasuredDepth, - double endMeasuredDepth); + double endMeasuredDepth, + const RimFishbonesMultipleSubs* fishbonesDefintions); }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp index b0564849ab..6439d49e80 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp @@ -459,6 +459,22 @@ void RicMswSegment::addCompletion(const RicMswCompletion& completion) m_completions.push_back(completion); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setSourcePdmObject(const caf::PdmObject* object) +{ + m_sourcePdmObject = const_cast(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const caf::PdmObject* RicMswSegment::sourcePdmObject() const +{ + return m_sourcePdmObject; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h index dc6d53e8f4..aded04da13 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h @@ -161,6 +161,9 @@ public: void setSegmentNumber(int segmentNumber); void addCompletion(const RicMswCompletion& completion); + void setSourcePdmObject(const caf::PdmObject* object); + const caf::PdmObject* sourcePdmObject() const; + bool operator<(const RicMswSegment& rhs) const; private: @@ -181,6 +184,8 @@ private: int m_segmentNumber; std::vector m_completions; + + caf::PdmPointer m_sourcePdmObject; }; class RicMswExportInfo diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp index 02ecf4a1fa..25d8dc2e70 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp @@ -1708,6 +1708,7 @@ std::vector RicWellPathExportCompletionDataFeatureImpl::gener completion.addMetadata("Perforation Completion", QString("MD In: %1 - MD Out: %2").arg(cell.startMD).arg(cell.endMD) + QString(" Transmissibility: ") + QString::number(transmissibility)); + completion.setSourcePdmObject(interval); completionData.push_back(completion); } } @@ -1775,6 +1776,7 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMs location.setIcdFlowCoefficient(subs->icdFlowCoefficient()); double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2; location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount()); + location.setSourcePdmObject(subs); if (ssi == 0) { diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp index 4e70728e81..67411c718f 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp @@ -42,6 +42,10 @@ #include "RiuPlotMainWindow.h" +#include "RimPerforationInterval.h" +#include "RimFracture.h" +#include "RimFishbonesMultipleSubs.h" + #include #include #include @@ -57,6 +61,8 @@ #include +#include + CAF_CMD_SOURCE_INIT(RicExportLgrFeature, "RicExportLgrFeature"); //-------------------------------------------------------------------------------------------------- @@ -185,71 +191,140 @@ void RicExportLgrFeature::exportLgrs(QTextStream& stream, const std::vector lgrs; - if (oneSingleLgr) - lgrs = buildSingleLgr(eclipseCase, intersectingCells, lgrCellCounts); - else - lgrs = buildOneLgrPerMainCell(eclipseCase, intersectingCells, lgrCellCounts); + + try + { + lgrs = buildLgrsForWellPath(wellPath, + eclipseCase, + timeStep, + lgrCellCounts, + splitType); - // Export - QFile file; - QString fileName = caf::Utils::makeValidFileBasename(QString("LGR_%1").arg(wellPath->name())) + ".dat"; - openFileForExport(exportFolder, fileName, &file); - QTextStream stream(&file); - stream.setRealNumberNotation(QTextStream::FixedNotation); - stream.setRealNumberPrecision(2); - exportLgrs(stream, lgrs); - file.close(); - return true; + // Export + QFile file; + QString fileName = caf::Utils::makeValidFileBasename(QString("LGR_%1").arg(wellPath->name())) + ".dat"; + openFileForExport(exportFolder, fileName, &file); + QTextStream stream(&file); + stream.setRealNumberNotation(QTextStream::FixedNotation); + stream.setRealNumberPrecision(2); + exportLgrs(stream, lgrs); + file.close(); + } + catch (CreateLgrException e) + { + throw; + } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RicExportLgrFeature::buildOneLgrPerMainCell(RimEclipseCase* eclipseCase, - const std::vector& intersectingCells, - const caf::VecIjk& lgrSizes) +std::vector RicExportLgrFeature::buildLgrsForWellPath(RimWellPath* wellPath, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + RicExportLgrUi::SplitType splitType) { std::vector lgrs; - int firstLgrId = firstAvailableLgrId(eclipseCase->mainGrid()); + bool intersectsWithExistingLgr = false; - int lgrCount = 0; - for (const auto& intersectingCell : intersectingCells) + if (splitType == RicExportLgrUi::LGR_PER_CELL) { - caf::VecIjk mainGridFirstCell(intersectingCell.localCellIndexI(), - intersectingCell.localCellIndexJ(), - intersectingCell.localCellIndexK()); - caf::VecIjk mainGridEndCell(intersectingCell.localCellIndexI(), - intersectingCell.localCellIndexJ(), - intersectingCell.localCellIndexK()); + auto intersectingCells = cellsIntersectingCompletions(eclipseCase, wellPath, timeStep); - int currLgrId = firstLgrId + lgrCount++; - LgrInfo lgrInfo(currLgrId, QString("LGR_%1").arg(currLgrId), lgrSizes, mainGridFirstCell, mainGridEndCell); - lgrs.push_back(lgrInfo); + if (containsAnyNonMainGridCells(intersectingCells)) + { + intersectsWithExistingLgr = true; + } + else + { + lgrs = buildLgrsPerMainCell(eclipseCase, intersectingCells, lgrCellCounts); + } + } + else if (splitType == RicExportLgrUi::LGR_PER_COMPLETION) + { + auto intersectingCells = cellsIntersectingCompletions_PerCompletion(eclipseCase, wellPath, timeStep); + + if (containsAnyNonMainGridCells(intersectingCells)) + { + intersectsWithExistingLgr = true; + } + else + { + lgrs = buildLgrsPerCompletion(eclipseCase, intersectingCells, lgrCellCounts); + } + } + else if (splitType == RicExportLgrUi::LGR_PER_WELL) + { + auto intersectingCells = cellsIntersectingCompletions(eclipseCase, wellPath, timeStep); + + if (containsAnyNonMainGridCells(intersectingCells)) + { + intersectsWithExistingLgr = true; + } + else + { + int lgrId = firstAvailableLgrId(eclipseCase->mainGrid()); + lgrs.push_back(buildLgr(lgrId, eclipseCase, intersectingCells, lgrCellCounts)); + } } + if (intersectsWithExistingLgr) + { + throw CreateLgrException("At least one completion intersects with an existing LGR"); + } return lgrs; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipseCase, - const std::vector& intersectingCells, - const caf::VecIjk& lgrSizesPerMainGridCell) +std::vector RicExportLgrFeature::buildLgrsPerMainCell(RimEclipseCase* eclipseCase, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizes) +{ + std::vector lgrs; + + int lgrId = firstAvailableLgrId(eclipseCase->mainGrid()); + for (auto intersectionCell : intersectingCells) + { + lgrs.push_back(buildLgr(lgrId++, eclipseCase, { intersectionCell }, lgrSizes)); + } + return lgrs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportLgrFeature::buildLgrsPerCompletion(RimEclipseCase* eclipseCase, + const std::map>& intersectingCells, + const caf::VecIjk& lgrSizesPerMainGridCell) +{ + std::vector lgrs; + + int lgrId = firstAvailableLgrId(eclipseCase->mainGrid()); + for (auto intersectionInfo : intersectingCells) + { + lgrs.push_back(buildLgr(lgrId++, eclipseCase, intersectionInfo.second, lgrSizesPerMainGridCell)); + } + return lgrs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LgrInfo RicExportLgrFeature::buildLgr(int lgrId, + RimEclipseCase* eclipseCase, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizesPerMainGridCell) { std::vector lgrs; @@ -268,25 +343,22 @@ std::vector RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipse kRange.second = std::max(cell.localCellIndexK(), kRange.second); } - int lgrId = firstAvailableLgrId(eclipseCase->mainGrid()); caf::VecIjk lgrSizes((iRange.second - iRange.first + 1) * lgrSizesPerMainGridCell.i(), (jRange.second - jRange.first + 1) * lgrSizesPerMainGridCell.j(), (kRange.second - kRange.first + 1) * lgrSizesPerMainGridCell.k()); caf::VecIjk mainGridStartCell(iRange.first, jRange.first, kRange.first); caf::VecIjk mainGridEndCell(iRange.second, jRange.second, kRange.second); - LgrInfo lgrInfo(lgrId, QString("LGR_%1").arg(lgrId), lgrSizes, mainGridStartCell, mainGridEndCell); - lgrs.push_back(lgrInfo); - - return lgrs; + return LgrInfo(lgrId, QString("LGR_%1").arg(lgrId), lgrSizes, mainGridStartCell, mainGridEndCell); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - size_t timeStep) +std::vector +RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + size_t timeStep) { std::vector cells; @@ -303,6 +375,47 @@ std::vector RicExportLgrFeature::cellsIntersectingCom return cells; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> + RicExportLgrFeature::cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + size_t timeStep) +{ + std::map> completionToCells; + + auto completions = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); + if (completions) + { + auto intCells = completions->multipleCompletionsPerEclipseCell(wellPath, timeStep); + + for (auto intCell : intCells) + { + auto pdmSrcObj = intCell.second.front().sourcePdmObject(); + auto perf = dynamic_cast(pdmSrcObj); + auto frac = dynamic_cast(pdmSrcObj); + auto fish = dynamic_cast(pdmSrcObj); + + QString name; + if (perf) + name = perf->name(); + else if (frac) + name = frac->name(); + else if (fish) + name = fish->generatedName(); + + if (name.isEmpty()) continue; + + for (auto compl : intCell.second) + { + completionToCells[CompletionInfo(compl.completionType(), name)].push_back(intCell.first); + } + } + } + return completionToCells; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -339,16 +452,20 @@ void RicExportLgrFeature::onActionTriggered(bool isChecked) auto lgrCellCounts = dialogData->lgrCellCount(); size_t timeStep = dialogData->timeStep(); - bool lgrIntersected = false; + bool intersectsExistingLgr = false; for (const auto& wellPath : wellPaths) { - if (!exportLgrsForWellPath(dialogData->exportFolder(), wellPath, eclipseCase, timeStep, lgrCellCounts, dialogData->singleLgrSplit())) + try { - lgrIntersected = true; + exportLgrsForWellPath(dialogData->exportFolder(), wellPath, eclipseCase, timeStep, lgrCellCounts, dialogData->splitType()); + } + catch(CreateLgrException e) + { + intersectsExistingLgr = true; } } - if (lgrIntersected) + if (intersectsExistingLgr) { QMessageBox::warning(nullptr, "LGR cells intersected", "At least one completion intersects with an LGR. No output for those completions produced"); } @@ -381,6 +498,19 @@ std::vector RicExportLgrFeature::selectedWellPaths() return wellPaths; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportLgrFeature::containsAnyNonMainGridCells( + const std::map>& cellsPerCompletion) +{ + for (auto cells : cellsPerCompletion) + { + if (containsAnyNonMainGridCells(cells.second)) return true; + } + return false; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h index 82af45a922..52ecd7417a 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h @@ -19,6 +19,10 @@ #pragma once #include "RigCompletionDataGridCell.h" +#include "RigCompletionData.h" + +#include "RicExportLgrUi.h" + #include "cafCmdFeature.h" #include #include @@ -27,10 +31,21 @@ class RimEclipseCase; class RimSimWellInView; class RimWellPath; -class RicExportLgrUi; class QFile; class QTextStream; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class CreateLgrException +{ +public: + CreateLgrException(const QString& message) + : message(message) + { + } + QString message; +}; //================================================================================================== /// @@ -73,6 +88,24 @@ public: caf::VecIjk mainGridEndCell; }; +//================================================================================================== +/// +//================================================================================================== +class CompletionInfo +{ +public: + CompletionInfo(RigCompletionData::CompletionType type, QString name) + : type(type), name(name) {} + + RigCompletionData::CompletionType type; + QString name; + + bool operator<(const CompletionInfo& other) const + { + return type < other.type || name < other.name; + } +}; + //================================================================================================== /// //================================================================================================== @@ -85,23 +118,18 @@ class RicExportLgrFeature : public caf::CmdFeature static RicExportLgrUi* openDialog(const QString& dialogTitle, RimEclipseCase* defaultCase = nullptr, int defaultTimeStep = 0); static bool openFileForExport(const QString& folderName, const QString& fileName, QFile* exportFile); - static void exportLgrs(QTextStream& stream, const std::vector& lgrInfos); - static bool exportLgrsForWellPath(const QString& exportFolder, + static void exportLgrsForWellPath(const QString& exportFolder, RimWellPath* wellPath, RimEclipseCase* eclipseCase, size_t timeStep, caf::VecIjk lgrCellCounts, - bool oneSingleLgr); - static std::vector buildOneLgrPerMainCell(RimEclipseCase* eclipseCase, - const std::vector& intersectingCells, - const caf::VecIjk& lgrSizes); - static std::vector buildSingleLgr(RimEclipseCase* eclipseCase, - const std::vector& intersectingCells, - const caf::VecIjk& lgrSizesPerMainGridCell); + RicExportLgrUi::SplitType splitType); - static std::vector cellsIntersectingCompletions(RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - size_t timeStep); + static std::vector buildLgrsForWellPath(RimWellPath* wellPath, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + RicExportLgrUi::SplitType splitType); protected: bool isCommandEnabled() override; @@ -109,7 +137,26 @@ protected: void setupActionLook(QAction* actionToSetup) override; private: + static void exportLgrs(QTextStream& stream, const std::vector& lgrInfos); + + static std::vector buildLgrsPerMainCell(RimEclipseCase* eclipseCase, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizes); + static std::vector + buildLgrsPerCompletion(RimEclipseCase* eclipseCase, + const std::map>& intersectingCells, + const caf::VecIjk& lgrSizesPerMainGridCell); + static LgrInfo buildLgr(int lgrId, + RimEclipseCase* eclipseCase, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizesPerMainGridCell); + + static std::vector + cellsIntersectingCompletions(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, size_t timeStep); + static std::map> + cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, size_t timeStep); static std::vector selectedWellPaths(); + static bool containsAnyNonMainGridCells(const std::map>& cellsPerCompletion); static bool containsAnyNonMainGridCells(const std::vector& cells); static int firstAvailableLgrId(const RigMainGrid* mainGrid); }; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp index f3f2c36f48..08f9025953 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp @@ -37,10 +37,11 @@ namespace caf template<> void RicExportLgrUi::LgrSplitTypeEnum::setUp() { - addItem(RicExportLgrUi::PER_CELL_LGR, "PER_CELL_LGR", "LGR Per Cell"); - addItem(RicExportLgrUi::SINGLE_LGR, "SINGLE_LGR", "Single LGR"); + addItem(RicExportLgrUi::LGR_PER_CELL, "LGR_PER_CELL", "LGR Per Cell"); + addItem(RicExportLgrUi::LGR_PER_COMPLETION, "LGR_PER_COMPLETION", "LGR Per Completion"); + addItem(RicExportLgrUi::LGR_PER_WELL, "LGR_PER_WELL", "LGR Per Well"); - setDefault(RicExportLgrUi::PER_CELL_LGR); + setDefault(RicExportLgrUi::LGR_PER_COMPLETION); } } @@ -131,9 +132,9 @@ int RicExportLgrUi::timeStep() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicExportLgrUi::singleLgrSplit() const +RicExportLgrUi::SplitType RicExportLgrUi::splitType() const { - return m_splitType == SINGLE_LGR; + return m_splitType(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h index 1fbeaf0280..406f242901 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h @@ -38,8 +38,8 @@ class RicExportLgrUi : public caf::PdmObject CAF_PDM_HEADER_INIT; public: - enum LgrSplitType { PER_CELL_LGR, SINGLE_LGR}; - typedef caf::AppEnum LgrSplitTypeEnum; + enum SplitType { LGR_PER_CELL, LGR_PER_COMPLETION, LGR_PER_WELL}; + typedef caf::AppEnum LgrSplitTypeEnum; RicExportLgrUi(); @@ -50,7 +50,7 @@ public: QString exportFolder() const; RimEclipseCase* caseToApply() const; int timeStep() const; - bool singleLgrSplit() const; + SplitType splitType() const; void setExportFolder(const QString& folder); diff --git a/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp index f1f03f7ad5..897bbc221b 100644 --- a/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp +++ b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp @@ -101,49 +101,57 @@ void RicCreateTemporaryLgrFeature::onActionTriggered(bool isChecked) auto eclipseCase = dialogData->caseToApply(); auto lgrCellCounts = dialogData->lgrCellCount(); size_t timeStep = dialogData->timeStep(); + auto splitType = dialogData->splitType(); auto eclipseCaseData = eclipseCase->eclipseCaseData(); RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL); RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::FRACTURE_MODEL); - bool lgrIntersected = false; + bool intersectsExistingLgr = false; for (const auto& wellPath : wellPaths) { - auto intersectingCells = RicExportLgrFeature::cellsIntersectingCompletions(eclipseCase, wellPath, timeStep); - if (containsAnyNonMainGridCells(intersectingCells)) - { - lgrIntersected = true; - continue; - } - - eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->freeAllocatedResultsData(); - std::vector lgrs; - if (dialogData->singleLgrSplit()) - lgrs = RicExportLgrFeature::buildSingleLgr(eclipseCase, intersectingCells, lgrCellCounts); - else - lgrs = RicExportLgrFeature::buildOneLgrPerMainCell(eclipseCase, intersectingCells, lgrCellCounts); - auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid(); - - for (auto lgr : lgrs) + try { - int totalCellCountBeforLgr = (int)mainGrid->globalCellArray().size(); + lgrs = RicExportLgrFeature::buildLgrsForWellPath(wellPath, + eclipseCase, + timeStep, + lgrCellCounts, + splitType); - createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid()); + auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid(); - int lgrCellCount = lgr.cellCount(); + for (auto lgr : lgrs) + { + int totalCellCountBeforLgr = (int)mainGrid->globalCellArray().size(); - activeCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount); - fractureActiveCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount); + createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid()); + + int lgrCellCount = lgr.cellCount(); + + activeCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount); + fractureActiveCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount); + } + + mainGrid->calculateFaults(activeCellInfo, true); + } + catch (CreateLgrException e) + { + intersectsExistingLgr = true; } - - mainGrid->calculateFaults(activeCellInfo, true); } eclipseCase->eclipseCaseData()->clearWellCellsInGridCache(); eclipseCase->eclipseCaseData()->mainGrid()->computeCachedData(); activeView->loadDataAndUpdate(); + + if (intersectsExistingLgr) + { + QMessageBox::warning(nullptr, + "LGR cells intersected", + "At least one completion intersects with an LGR. No output for those completions produced"); + } } } diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp index cb0840fc7b..79014a9e4d 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp @@ -393,6 +393,22 @@ double RigCompletionData::secondOrderingValue() const return m_secondOrderingValue; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCompletionData::setSourcePdmObject(const caf::PdmObject* object) +{ + m_sourcePdmObject = const_cast(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const caf::PdmObject* RigCompletionData::sourcePdmObject() const +{ + return m_sourcePdmObject; +} + //================================================================================================== /// //================================================================================================== @@ -415,4 +431,5 @@ void RigCompletionData::copy(RigCompletionData& target, const RigCompletionData& target.m_completionType = from.m_completionType; target.m_firstOrderingValue = from.m_firstOrderingValue; target.m_secondOrderingValue = from.m_secondOrderingValue; + target.m_sourcePdmObject = from.m_sourcePdmObject; } diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h index c6e19a1382..c4ee7f9d3c 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h @@ -22,6 +22,9 @@ #include +#include +#include + #include //================================================================================================== @@ -132,6 +135,9 @@ public: double firstOrderingValue() const; double secondOrderingValue() const; + void setSourcePdmObject(const caf::PdmObject* object); + const caf::PdmObject* sourcePdmObject() const; + std::vector m_metadata; private: @@ -156,6 +162,8 @@ private: double m_firstOrderingValue; double m_secondOrderingValue; + caf::PdmPointer m_sourcePdmObject; + private: static void copy(RigCompletionData& target, const RigCompletionData& from); };