diff --git a/ApplicationLibCode/Application/Tools/RiaProjectFileVersionTools.cpp b/ApplicationLibCode/Application/Tools/RiaProjectFileVersionTools.cpp index 2e2286c156..c162191ab2 100644 --- a/ApplicationLibCode/Application/Tools/RiaProjectFileVersionTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaProjectFileVersionTools.cpp @@ -28,8 +28,8 @@ bool RiaProjectFileVersionTools::isCandidateVersionNewerThanOther( const QString { int candidateMajorVersion = 0; int candidateMinorVersion = 0; - int candidatePatchNumber = 0; - int candidateDevelopmentId = 0; + int candidatePatchNumber = -1; + int candidateDevelopmentId = -1; RiaProjectFileVersionTools::decodeVersionString( candidateProjectFileVersion, &candidateMajorVersion, @@ -39,8 +39,8 @@ bool RiaProjectFileVersionTools::isCandidateVersionNewerThanOther( const QString int majorVersion = 0; int minorVersion = 0; - int patchNumber = 0; - int developmentId = 0; + int patchNumber = -1; + int developmentId = -1; RiaProjectFileVersionTools::decodeVersionString( projectFileVersion, &majorVersion, @@ -120,11 +120,17 @@ bool RiaProjectFileVersionTools::isCandidateNewerThanOther( int candidateMajorVe return ( candidateMinorVersion > otherMinorVersion ); } + // Early exit if a patch number is undefined + if ( candidatePatchNumber == -1 || otherPatchNumber == -1 ) return false; + if ( candidatePatchNumber != otherPatchNumber ) { return ( candidatePatchNumber > otherPatchNumber ); } + // Early exit if a development number is undefined + if ( candidateDevelopmentId == -1 && otherDevelopmentId == -1 ) return false; + if ( candidateDevelopmentId != otherDevelopmentId ) { return ( candidateDevelopmentId > otherDevelopmentId ); diff --git a/ApplicationLibCode/Application/Tools/RiaTextStringTools.cpp b/ApplicationLibCode/Application/Tools/RiaTextStringTools.cpp index f9c2743266..ba790d1cd0 100644 --- a/ApplicationLibCode/Application/Tools/RiaTextStringTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaTextStringTools.cpp @@ -86,6 +86,37 @@ QString RiaTextStringTools::commonRoot( const QStringList& stringList ) return root; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaTextStringTools::commonSuffix( const QStringList& stringList ) +{ + QString suffix; + if ( !stringList.isEmpty() ) + { + suffix = stringList.back(); + for ( const auto& item : stringList ) + { + if ( suffix.length() > item.length() ) + { + suffix = suffix.right( item.length() ); + } + + for ( int i = 0; i < suffix.length(); i++ ) + { + int suffixIndex = suffix.length() - i - 1; + int itemIndex = item.length() - i - 1; + if ( suffix[suffixIndex] != item[itemIndex] ) + { + suffix = suffix.right( i ); + break; + } + } + } + } + return suffix; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/Tools/RiaTextStringTools.h b/ApplicationLibCode/Application/Tools/RiaTextStringTools.h index 28f5804bd8..8e4a5ca95d 100644 --- a/ApplicationLibCode/Application/Tools/RiaTextStringTools.h +++ b/ApplicationLibCode/Application/Tools/RiaTextStringTools.h @@ -29,5 +29,6 @@ namespace RiaTextStringTools bool compare( const QString& expected, const QString& actual ); QString trimAndRemoveDoubleSpaces( const QString& s ); QString commonRoot( const QStringList& stringList ); +QString commonSuffix( const QStringList& stringList ); QString trimNonAlphaNumericCharacters( const QString& s ); } // namespace RiaTextStringTools diff --git a/ApplicationLibCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp b/ApplicationLibCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp index a64f081820..81d1566951 100644 --- a/ApplicationLibCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp +++ b/ApplicationLibCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp @@ -81,7 +81,7 @@ void RiaPolyArcLineSampler::sampleSegment( cvf::Vec3d t1, cvf::Vec3d p1, cvf::Ve CVF_ASSERT( p1p2.lengthSquared() > 1e-20 ); - if ( cvf::GeometryTools::getAngle( t1, p1p2 ) < 1e-5 ) + if ( cvf::GeometryTools::getAngle( t1, p1p2 ) < 1e-5 || p1p2.length() < m_maxSamplingsInterval ) { sampleLine( p1, p2, endTangent ); } diff --git a/ApplicationLibCode/CommandFileInterface/RicfExportMsw.cpp b/ApplicationLibCode/CommandFileInterface/RicfExportMsw.cpp index 45b25a4cac..8b430a84e6 100644 --- a/ApplicationLibCode/CommandFileInterface/RicfExportMsw.cpp +++ b/ApplicationLibCode/CommandFileInterface/RicfExportMsw.cpp @@ -26,8 +26,8 @@ #include "RimEclipseCase.h" #include "RimEclipseCaseCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimOilField.h" #include "RimProject.h" #include "RimWellPath.h" diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp index 7789bed651..b9b5ae86ff 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp @@ -25,8 +25,8 @@ #include "RigWellPath.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimWellPath.h" #include "cafSelectionManager.h" @@ -67,38 +67,35 @@ void RicExportFishbonesLateralsFeature::onActionTriggered( bool isChecked ) auto exportFile = EXP::openFileForExport( folder, fileName ); auto stream = EXP::createOutputFileStream( *exportFile ); - for ( RimFishbonesMultipleSubs* fishbone : wellPath->fishbonesCollection()->activeFishbonesSubs() ) + for ( RimFishbones* fishbone : wellPath->fishbonesCollection()->activeFishbonesSubs() ) { const QString fishboneName = fishbone->generatedName(); - for ( auto& sub : fishbone->installedLateralIndices() ) + for ( const auto& [subIndex, lateralIndex] : fishbone->installedLateralIndices() ) { - for ( size_t lateralIndex : sub.lateralIndices ) + std::vector> coordsAndMD = + fishbone->coordsAndMDForLateral( subIndex, lateralIndex ); + + std::vector lateralCoords; + std::vector lateralMDs; + + lateralCoords.reserve( coordsAndMD.size() ); + lateralMDs.reserve( coordsAndMD.size() ); + + for ( auto& coordMD : coordsAndMD ) { - std::vector> coordsAndMD = - fishbone->coordsAndMDForLateral( sub.subIndex, lateralIndex ); - - std::vector lateralCoords; - std::vector lateralMDs; - - lateralCoords.reserve( coordsAndMD.size() ); - lateralMDs.reserve( coordsAndMD.size() ); - - for ( auto& coordMD : coordsAndMD ) - { - lateralCoords.push_back( coordMD.first ); - lateralMDs.push_back( coordMD.second ); - } - - RigWellPath geometry( lateralCoords, lateralMDs ); - - // Pad with "0" to get a total of two characters defining the sub index text - QString subIndexText = QString( "%1" ).arg( sub.subIndex, 2, 10, QChar( '0' ) ); - QString lateralName = - QString( "%1_%2_Sub%3_Lat%4" ).arg( wellPath->name() ).arg( fishboneName ).arg( subIndexText ).arg( lateralIndex ); - - EXP::writeWellPathGeometryToStream( *stream, geometry, lateralName, mdStepSize, false, 0.0, false ); + lateralCoords.push_back( coordMD.first ); + lateralMDs.push_back( coordMD.second ); } + + RigWellPath geometry( lateralCoords, lateralMDs ); + + // Pad with "0" to get a total of two characters defining the sub index text + QString subIndexText = QString( "%1" ).arg( subIndex, 2, 10, QChar( '0' ) ); + QString lateralName = + QString( "%1_%2_Sub%3_Lat%4" ).arg( wellPath->name() ).arg( fishboneName ).arg( subIndexText ).arg( lateralIndex ); + + EXP::writeWellPathGeometryToStream( *stream, geometry, lateralName, mdStepSize, false, 0.0, false ); } } diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp index 06179e0a12..8cbdf02751 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp @@ -21,8 +21,8 @@ #include "RicNewFishbonesSubsFeature.h" #include "WellPathCommands/RicWellPathsUnitSystemSettingsImpl.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimProject.h" #include "RimWellPath.h" @@ -48,7 +48,7 @@ void RicNewFishbonesSubsAtMeasuredDepthFeature::onActionTriggered( bool isChecke if ( !RicWellPathsUnitSystemSettingsImpl::ensureHasUnitSystem( wellPath ) ) return; - RimFishbonesMultipleSubs* obj = new RimFishbonesMultipleSubs; + RimFishbones* obj = new RimFishbones; wellPath->fishbonesCollection()->appendFishbonesSubs( obj ); obj->setMeasuredDepthAndCount( wellPathSelItem->m_measuredDepth, 12.5, 13 ); diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp index f5b0b01738..77255a5e80 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.cpp @@ -25,9 +25,9 @@ #include "RigWellPath.h" #include "Rim3dView.h" -#include "RimFishboneWellPathCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimProject.h" #include "RimWellPathCollection.h" #include "RimWellPathCompletions.h" @@ -55,10 +55,10 @@ void RicNewFishbonesSubsFeature::onActionTriggered( bool isChecked ) fishbonesCollection->firstAncestorOrThisOfTypeAsserted( wellPath ); if ( !RicWellPathsUnitSystemSettingsImpl::ensureHasUnitSystem( wellPath ) ) return; - RimFishbonesMultipleSubs* obj = new RimFishbonesMultipleSubs; + RimFishbones* obj = new RimFishbones; fishbonesCollection->appendFishbonesSubs( obj ); - double wellPathTipMd = wellPath->endMD(); + double wellPathTipMd = wellPath->uniqueEndMD(); if ( wellPathTipMd != HUGE_VAL ) { double startMd = wellPathTipMd - 150 - 100; diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.cpp index 95cc6791d0..309bd0e83d 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.cpp @@ -20,7 +20,7 @@ #include "WellPathCommands/RicWellPathsUnitSystemSettingsImpl.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" #include "RimProject.h" diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.cpp index 0ee216a836..d3ff26e325 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.cpp @@ -55,6 +55,7 @@ void RicNewPerforationIntervalFeature::onActionTriggered( bool isChecked ) if ( !RicWellPathsUnitSystemSettingsImpl::ensureHasUnitSystem( wellPath ) ) return; RimPerforationInterval* perforationInterval = new RimPerforationInterval; + perforationInterval->setStartAndEndMD( wellPath->uniqueStartMD(), wellPath->uniqueEndMD() ); perforationCollection->appendPerforation( perforationInterval ); diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicNewValveAtMeasuredDepthFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicNewValveAtMeasuredDepthFeature.cpp index 8a4b7f10c4..47cc1162a3 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicNewValveAtMeasuredDepthFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicNewValveAtMeasuredDepthFeature.cpp @@ -19,7 +19,7 @@ #include "WellPathCommands/RicWellPathsUnitSystemSettingsImpl.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" #include "RimProject.h" diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp b/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp index ba8efbce7c..adaea708b5 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp @@ -20,8 +20,8 @@ #include "RiaApplication.h" -#include "RimFishboneWellPathCollection.h" #include "RimFishbonesCollection.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimProject.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" @@ -55,7 +55,7 @@ bool RicWellPathImportCompletionsFileFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicWellPathImportCompletionsFileFeature::onActionTriggered( bool isChecked ) { - RimFishboneWellPathCollection* fishbonesWellPathCollection = + RimImportedFishboneLateralsCollection* fishbonesWellPathCollection = RicWellPathImportCompletionsFileFeature::selectedWellPathCollection(); CVF_ASSERT( fishbonesWellPathCollection ); @@ -100,7 +100,7 @@ void RicWellPathImportCompletionsFileFeature::setupActionLook( QAction* actionTo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishboneWellPathCollection* RicWellPathImportCompletionsFileFeature::selectedWellPathCollection() +RimImportedFishboneLateralsCollection* RicWellPathImportCompletionsFileFeature::selectedWellPathCollection() { RimFishbonesCollection* objToFind = nullptr; caf::PdmUiItem* pdmUiItem = caf::SelectionManager::instance()->selectedItem(); diff --git a/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h b/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h index 26ee1cf32e..f52a9870fe 100644 --- a/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h +++ b/ApplicationLibCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h @@ -20,7 +20,7 @@ #include "cafCmdFeature.h" -class RimFishboneWellPathCollection; +class RimImportedFishboneLateralsCollection; //================================================================================================== /// @@ -36,5 +36,5 @@ protected: void setupActionLook( QAction* actionToSetup ) override; private: - static RimFishboneWellPathCollection* selectedWellPathCollection(); + static RimImportedFishboneLateralsCollection* selectedWellPathCollection(); }; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/CompletionExportCommands/CMakeLists_files.cmake index 71c5466978..6d4e6f8844 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/CompletionExportCommands/CMakeLists_files.cmake @@ -11,10 +11,12 @@ ${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}/RicMswBranch.h ${CMAKE_CURRENT_LIST_DIR}/RicMswCompletions.h ${CMAKE_CURRENT_LIST_DIR}/RicMswExportInfo.h +${CMAKE_CURRENT_LIST_DIR}/RicMswItem.h ${CMAKE_CURRENT_LIST_DIR}/RicMswSegment.h -${CMAKE_CURRENT_LIST_DIR}/RicMswSubSegment.h +${CMAKE_CURRENT_LIST_DIR}/RicMswSegmentCellIntersection.h ${CMAKE_CURRENT_LIST_DIR}/RicMswValveAccumulators.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.h @@ -34,10 +36,12 @@ ${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}/RicMswBranch.cpp ${CMAKE_CURRENT_LIST_DIR}/RicMswCompletions.cpp ${CMAKE_CURRENT_LIST_DIR}/RicMswExportInfo.cpp +${CMAKE_CURRENT_LIST_DIR}/RicMswItem.cpp ${CMAKE_CURRENT_LIST_DIR}/RicMswSegment.cpp -${CMAKE_CURRENT_LIST_DIR}/RicMswSubSegment.cpp +${CMAKE_CURRENT_LIST_DIR}/RicMswSegmentCellIntersection.cpp ${CMAKE_CURRENT_LIST_DIR}/RicMswValveAccumulators.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.cpp diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp index f94b9b00ab..b52ddd20e2 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp @@ -406,7 +406,7 @@ std::map>> double currentWellPressure = 0.0; RicExportFractureCompletionsImpl:: getWellPressuresAndInitialProductionTimeStepFromSummaryData( caseToApply, - wellPath->completions()->wellNameForExport(), + wellPath->completionSettings()->wellNameForExport(), 0, &initialWellProductionTimeStep, &initialWellPressure, diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp index f02ffb7f66..2574941b08 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp @@ -155,5 +155,10 @@ std::vector RicExportCompletionsForVisibleWellPathsFeature::visibl std::set uniqueWellPaths( wellPaths.begin(), wellPaths.end() ); wellPaths.assign( uniqueWellPaths.begin(), uniqueWellPaths.end() ); + wellPaths.erase( std::remove_if( wellPaths.begin(), + wellPaths.end(), + []( auto wellPath ) { return !wellPath->isTopLevelWellPath(); } ), + wellPaths.end() ); + return wellPaths; } diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.cpp index 64ace77648..e2f6756851 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.cpp @@ -30,9 +30,9 @@ #include "RicWellPathExportMswCompletionsImpl.h" #include "RimEclipseCase.h" -#include "RimFishboneWellPathCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimPerforationCollection.h" #include "RimProject.h" #include "RimWellPath.h" diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.h index 1915adb221..1abc3eb013 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportCompletionsWellSegmentsFeature.h @@ -23,7 +23,7 @@ #include "cafCmdFeature.h" class RimFishbonesCollection; -class RimFishbonesMultipleSubs; +class RimFishbones; class RimWellPath; //================================================================================================== diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp index dc46ec2eb5..235c0b0d8a 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp @@ -84,7 +84,7 @@ std::vector RicExportFractureCompletionsImpl::generateCompdat } return generateCompdatValues( caseToApply, - wellPath->completions()->wellNameForExport(), + wellPath->completionSettings()->wellNameForExport(), wellPath->wellPathGeometry(), fracturesAlongWellPath, fractureDataForReport, diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp index ab47357a48..7392c6fa1a 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp @@ -19,7 +19,10 @@ #include "RicFishbonesTransmissibilityCalculationFeatureImp.h" #include "RicExportCompletionDataSettingsUi.h" +#include "RicMswBranch.h" +#include "RicMswCompletions.h" #include "RicMswExportInfo.h" +#include "RicMswSegment.h" #include "RicWellPathExportCompletionDataFeatureImpl.h" #include "RicWellPathExportMswCompletionsImpl.h" @@ -31,10 +34,10 @@ #include "RigWellPathIntersectionTools.h" #include "RigWellLogExtractor.h" -#include "RimFishboneWellPath.h" -#include "RimFishboneWellPathCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimImportedFishboneLaterals.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimWellPath.h" #include "RimWellPathCompletions.h" @@ -134,7 +137,7 @@ std::vector continue; } - RigCompletionData completion( wellPath->completions()->wellNameForExport(), + RigCompletionData completion( wellPath->completionSettings()->wellNameForExport(), RigCompletionDataGridCell( globalCellIndex, settings.caseToApply->mainGrid() ), wellBorePart.intersectionWithWellMeasuredDepth ); completion.setSecondOrderingValue( wellBorePart.lateralIndex ); @@ -206,34 +209,50 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell // Generate data const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData(); - RicMswExportInfo exportInfo = - RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( settings.caseToApply(), wellPath, false ); - RiaDefines::EclipseUnitSystem unitSystem = caseData->unitsType(); - bool isMainBore = false; + auto mswParameters = wellPath->completionSettings()->mswParameters(); + RiaDefines::EclipseUnitSystem unitSystem = caseData->unitsType(); - for ( std::shared_ptr location : exportInfo.segments() ) + RicMswExportInfo exportInfo( wellPath, + unitSystem, + wellPath->fishbonesCollection()->startMD(), + mswParameters->lengthAndDepth().text(), + mswParameters->pressureDrop().text() ); + exportInfo.setLinerDiameter( mswParameters->linerDiameter( unitSystem ) ); + exportInfo.setRoughnessFactor( mswParameters->roughnessFactor( unitSystem ) ); + + RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( settings.caseToApply(), + wellPath, + 0.0, + {}, + false, + &exportInfo, + exportInfo.mainBoreBranch() ); + + bool isMainBore = false; + + for ( auto segment : exportInfo.mainBoreBranch()->segments() ) { - for ( std::shared_ptr completion : location->completions() ) + for ( auto completion : segment->completions() ) { - for ( std::shared_ptr segment : completion->subSegments() ) + for ( auto completionSegment : completion->segments() ) { - for ( std::shared_ptr intersection : segment->intersections() ) + for ( std::shared_ptr intersection : completionSegment->intersections() ) { - double diameter = location->holeDiameter(); + double diameter = segment->holeDiameter(); QString completionMetaData = - ( location->label() + - QString( ": Sub: %1 Lateral: %2" ).arg( location->subIndex() ).arg( completion->index() ) ); + ( segment->label() + + QString( ": Sub: %1 Lateral: %2" ).arg( segment->subIndex() ).arg( completion->index() ) ); WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc( intersection->lengthsInCell(), diameter / 2.0, - location->skinFactor(), + segment->skinFactor(), isMainBore, completionMetaData ); - wellBorePart.intersectionWithWellMeasuredDepth = location->endMD(); + wellBorePart.intersectionWithWellMeasuredDepth = segment->endMD(); wellBorePart.lateralIndex = completion->index(); - wellBorePart.setSourcePdmObject( location->sourcePdmObject() ); + wellBorePart.setSourcePdmObject( segment->sourcePdmObject() ); wellBorePartsInCells[intersection->globalCellIndex()].push_back( wellBorePart ); } @@ -293,7 +312,8 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneImportedLate double holeRadius = wellPath->fishbonesCollection()->wellPathCollection()->holeDiameter( unitSystem ) / 2.0; double skinFactor = wellPath->fishbonesCollection()->wellPathCollection()->skinFactor(); - for ( const RimFishboneWellPath* fishbonesPath : wellPath->fishbonesCollection()->wellPathCollection()->wellPaths() ) + for ( const RimImportedFishboneLaterals* fishbonesPath : + wellPath->fishbonesCollection()->wellPathCollection()->wellPaths() ) { if ( !fishbonesPath->isChecked() ) { @@ -336,7 +356,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts( double holeRadius, double startMeasuredDepth, double endMeasuredDepth, - const RimFishbonesMultipleSubs* fishbonesDefinitions ) + const RimFishbones* fishbonesDefinitions ) { if ( !wellPath ) return; if ( !wellPath->wellPathGeometry() ) return; @@ -355,7 +375,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts( for ( const auto& cellIntersectionInfo : intersectedCellsIntersectionInfo ) { - QString completionMetaData = wellPath->completions()->wellNameForExport() + " main bore"; + QString completionMetaData = wellPath->completionSettings()->wellNameForExport() + " main bore"; WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc( cellIntersectionInfo.intersectionLengthsInCellCS, holeRadius, skinFactor, diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h index e1eb2542d4..05d55ec8ca 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h @@ -26,7 +26,7 @@ class RigCompletionData; class RimWellPath; -class RimFishbonesMultipleSubs; +class RimFishbones; class RicExportCompletionDataSettingsUi; class RigEclipseCaseData; @@ -60,5 +60,5 @@ private: double holeRadius, double startMeasuredDepth, double endMeasuredDepth, - const RimFishbonesMultipleSubs* fishbonesDefinitions ); + const RimFishbones* fishbonesDefinitions ); }; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSubSegment.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswBranch.cpp similarity index 54% rename from ApplicationLibCode/Commands/CompletionExportCommands/RicMswSubSegment.cpp rename to ApplicationLibCode/Commands/CompletionExportCommands/RicMswBranch.cpp index ecf45989f7..722261458c 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSubSegment.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswBranch.cpp @@ -1,164 +1,182 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// 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. -// -///////////////////////////////////////////////////////////////////////////////// +#include "RicMswBranch.h" -#include "RicMswSubSegment.h" +#include "RicMswCompletions.h" +#include "RicMswSegment.h" + +#include "RimWellPath.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswSubSegmentCellIntersection::RicMswSubSegmentCellIntersection( const QString& gridName, - size_t globalCellIndex, - const cvf::Vec3st& gridLocalCellIJK, - const cvf::Vec3d& lengthsInCell ) - : m_gridName( gridName ) - , m_globalCellIndex( globalCellIndex ) - , m_gridLocalCellIJK( gridLocalCellIJK ) - , m_lengthsInCell( lengthsInCell ) +RicMswBranch::RicMswBranch( const QString& label, const RimWellPath* wellPath, double initialMD, double initialTVD ) + : RicMswItem( label ) + , m_initialMD( initialMD ) + , m_initialTVD( initialTVD ) + , m_branchNumber( -1 ) + , m_wellPath( wellPath ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const QString& RicMswSubSegmentCellIntersection::gridName() const +void RicMswBranch::addSegment( std::unique_ptr segment ) { - return m_gridName; + m_segments.push_back( std::move( segment ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RicMswSubSegmentCellIntersection::globalCellIndex() const +void RicMswBranch::insertAfterSegment( const RicMswSegment* insertAfter, std::unique_ptr insertItem ) { - return m_globalCellIndex; + auto it = std::find_if( m_segments.begin(), m_segments.end(), [insertAfter]( auto& item ) { + return item.get() == insertAfter; + } ); + + m_segments.insert( it, std::move( insertItem ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3st RicMswSubSegmentCellIntersection::gridLocalCellIJK() const +void RicMswBranch::sortSegments() { - return m_gridLocalCellIJK; + std::stable_sort( m_segments.begin(), + m_segments.end(), + []( const std::unique_ptr& lhs, const std::unique_ptr& rhs ) { + return *lhs < *rhs; + } ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const cvf::Vec3d& RicMswSubSegmentCellIntersection::lengthsInCell() const +const RimWellPath* RicMswBranch::wellPath() const { - return m_lengthsInCell; + return m_wellPath; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswSubSegment::RicMswSubSegment( double startMD, double endMD, double startTVD, double endTVD ) - : m_startMD( startMD ) - , m_endMD( endMD ) - , m_startTVD( startTVD ) - , m_endTVD( endTVD ) - , m_segmentNumber( -1 ) +double RicMswBranch::startMD() const { + return m_initialMD; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicMswSubSegment::startMD() const +double RicMswBranch::startTVD() const { - return m_startMD; + return m_initialTVD; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicMswSubSegment::endMD() const +double RicMswBranch::endMD() const { - return m_endMD; + if ( !m_segments.empty() ) + { + return m_segments.back()->endMD(); + } + return m_initialMD; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicMswSubSegment::deltaMD() const +double RicMswBranch::endTVD() const { - return m_endMD - m_startMD; + if ( !m_segments.empty() ) + { + return m_segments.back()->endTVD(); + } + return m_initialTVD; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicMswSubSegment::startTVD() const +int RicMswBranch::branchNumber() const { - return m_startTVD; + return m_branchNumber; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicMswSubSegment::endTVD() const +void RicMswBranch::setBranchNumber( int branchNumber ) { - return m_endTVD; + m_branchNumber = branchNumber; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicMswSubSegment::deltaTVD() const +std::vector RicMswBranch::segments() const { - return m_endTVD - m_startTVD; + std::vector allSegments; + for ( const auto& segment : m_segments ) + { + allSegments.push_back( segment.get() ); + } + return allSegments; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int RicMswSubSegment::segmentNumber() const +std::vector RicMswBranch::segments() { - return m_segmentNumber; + std::vector allSegments; + for ( auto& segment : m_segments ) + { + allSegments.push_back( segment.get() ); + } + return allSegments; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicMswSubSegment::setSegmentNumber( int segmentNumber ) +size_t RicMswBranch::segmentCount() const { - m_segmentNumber = segmentNumber; -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswSubSegment::addIntersection( std::shared_ptr intersection ) -{ - m_intersections.push_back( intersection ); + return m_segments.size(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector>& RicMswSubSegment::intersections() const +std::vector RicMswBranch::branches() const { - return m_intersections; + std::vector branches; + for ( const auto& branch : m_branches ) + { + branches.push_back( branch.get() ); + } + return branches; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector>& RicMswSubSegment::intersections() +std::vector RicMswBranch::branches() { - return m_intersections; + std::vector branches; + for ( auto& branch : m_branches ) + { + branches.push_back( branch.get() ); + } + return branches; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswBranch::addChildBranch( std::unique_ptr branch ) +{ + m_branches.push_back( std::move( branch ) ); } diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswBranch.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswBranch.h new file mode 100644 index 0000000000..4fddc9e7e7 --- /dev/null +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswBranch.h @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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 "RicMswItem.h" +#include "RicMswSegment.h" + +#include "cafPdmPointer.h" + +#include +#include + +class RimWellPath; + +class RicMswCompletion; +class RicMswSegment; + +class RicMswBranch : public RicMswItem +{ +public: + RicMswBranch( const QString& label, const RimWellPath* wellPath, double initialMD = 0.0, double initialTVD = 0.0 ); + virtual ~RicMswBranch() = default; + + void addSegment( std::unique_ptr segment ); + void insertAfterSegment( const RicMswSegment* insertAfter, std::unique_ptr segment ); + void sortSegments(); + const RimWellPath* wellPath() const; + + double startMD() const override; + double startTVD() const override; + + double endMD() const override; + double endTVD() const override; + + int branchNumber() const; + void setBranchNumber( int branchNumber ); + + std::vector segments() const; + std::vector segments(); + + size_t segmentCount() const; + + std::vector branches() const; + std::vector branches(); + + void addChildBranch( std::unique_ptr branch ); + +private: + double m_initialMD; + double m_initialTVD; + + int m_branchNumber; + + std::vector> m_segments; + std::vector> m_branches; + + const RimWellPath* m_wellPath; +}; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.cpp index 59c0115fd0..9274d92593 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.cpp @@ -18,27 +18,22 @@ #include "RicMswCompletions.h" -#include "RicMswSubSegment.h" +#include "RicMswSegmentCellIntersection.h" #include "RimWellPathValve.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswCompletion::RicMswCompletion( const QString& label, size_t index /* = cvf::UNDEFINED_SIZE_T */, int branchNumber /*= 0*/ ) - : m_label( label ) +RicMswCompletion::RicMswCompletion( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index /* = cvf::UNDEFINED_SIZE_T */ ) + : RicMswBranch( label, wellPath, startMD, startTVD ) , m_index( index ) - , m_branchNumber( branchNumber ) { } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const QString& RicMswCompletion::label() const -{ - return m_label; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -50,58 +45,12 @@ size_t RicMswCompletion::index() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int RicMswCompletion::branchNumber() const -{ - return m_branchNumber; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswCompletion::setBranchNumber( int branchNumber ) -{ - m_branchNumber = branchNumber; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswCompletion::addSubSegment( std::shared_ptr subSegment ) -{ - m_subSegments.push_back( subSegment ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector>& RicMswCompletion::subSegments() -{ - return m_subSegments; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector>& RicMswCompletion::subSegments() const -{ - return m_subSegments; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswCompletion::setLabel( const QString& label ) -{ - m_label = label; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RicMswFracture::RicMswFracture( const QString& label, - size_t index /*= cvf::UNDEFINED_SIZE_T*/, - int branchNumber /*= cvf::UNDEFINED_INT*/ ) - : RicMswCompletion( label, index, branchNumber ) +RicMswFracture::RicMswFracture( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index /*= cvf::UNDEFINED_SIZE_T*/ ) + : RicMswCompletion( label, wellPath, startMD, startTVD, index ) { } @@ -116,10 +65,12 @@ RigCompletionData::CompletionType RicMswFracture::completionType() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswPerforation::RicMswPerforation( const QString& label, - size_t index /*= cvf::UNDEFINED_SIZE_T*/, - int branchNumber /*= cvf::UNDEFINED_INT*/ ) - : RicMswCompletion( label, index, branchNumber ) +RicMswPerforation::RicMswPerforation( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index /*= cvf::UNDEFINED_SIZE_T*/ ) + : RicMswCompletion( label, wellPath, startMD, startTVD, index ) { } @@ -134,8 +85,12 @@ RigCompletionData::CompletionType RicMswPerforation::completionType() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswValve::RicMswValve( const QString& label, const RimWellPathValve* wellPathValve ) - : RicMswCompletion( label ) +RicMswValve::RicMswValve( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) + : RicMswCompletion( label, wellPath, startMD, startTVD ) , m_wellPathValve( wellPathValve ) , m_valid( false ) { @@ -168,8 +123,41 @@ void RicMswValve::setIsValid( bool valid ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswWsegValve::RicMswWsegValve( const QString& label, const RimWellPathValve* wellPathValve ) - : RicMswValve( label, wellPathValve ) +std::unique_ptr RicMswValve::createExportValve( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) +{ + std::unique_ptr outletValve; + if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::ICD ) + { + outletValve = std::make_unique( label, wellPath, startMD, startTVD, wellPathValve ); + } + else if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::ICV ) + { + outletValve = std::make_unique( label, wellPath, startMD, startTVD, wellPathValve ); + } + else if ( wellPathValve->componentType() == RiaDefines::WellPathComponentType::AICD ) + { + outletValve = std::make_unique( label, wellPath, startMD, startTVD, wellPathValve ); + } + else + { + CAF_ASSERT( false && "Valve needs to be either an ICD, ICVF or AICD" ); + } + return outletValve; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswWsegValve::RicMswWsegValve( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) + : RicMswValve( label, wellPath, startMD, startTVD, wellPathValve ) , m_flowCoefficient( 0.0 ) , m_area( 0.0 ) { @@ -210,8 +198,12 @@ void RicMswWsegValve::setArea( double icdArea ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswFishbonesICD::RicMswFishbonesICD( const QString& label, const RimWellPathValve* wellPathValve ) - : RicMswWsegValve( label, wellPathValve ) +RicMswFishbonesICD::RicMswFishbonesICD( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) + : RicMswWsegValve( label, wellPath, startMD, startTVD, wellPathValve ) { setIsValid( true ); } @@ -227,8 +219,12 @@ RigCompletionData::CompletionType RicMswFishbonesICD::completionType() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswPerforationICD::RicMswPerforationICD( const QString& label, const RimWellPathValve* wellPathValve ) - : RicMswWsegValve( label, wellPathValve ) +RicMswPerforationICD::RicMswPerforationICD( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) + : RicMswWsegValve( label, wellPath, startMD, startTVD, wellPathValve ) { } @@ -243,8 +239,12 @@ RigCompletionData::CompletionType RicMswPerforationICD::completionType() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswPerforationICV::RicMswPerforationICV( const QString& label, const RimWellPathValve* wellPathValve ) - : RicMswWsegValve( label, wellPathValve ) +RicMswPerforationICV::RicMswPerforationICV( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) + : RicMswWsegValve( label, wellPath, startMD, startTVD, wellPathValve ) { setIsValid( true ); } @@ -260,8 +260,12 @@ RigCompletionData::CompletionType RicMswPerforationICV::completionType() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswPerforationAICD::RicMswPerforationAICD( const QString& label, const RimWellPathValve* wellPathValve ) - : RicMswValve( label, wellPathValve ) +RicMswPerforationAICD::RicMswPerforationAICD( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ) + : RicMswValve( label, wellPath, startMD, startTVD, wellPathValve ) , m_deviceOpen( false ) , m_length( 0.0 ) , m_flowScalingFactor( 0.0 ) diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.h index 2f92ce141d..5a5fc36e9c 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswCompletions.h @@ -17,7 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RicMswSubSegment.h" +#include "RicMswBranch.h" #include "RigCompletionData.h" @@ -33,38 +33,31 @@ class RimWellPathValve; //================================================================================================== /// //================================================================================================== -class RicMswCompletion +class RicMswCompletion : public RicMswBranch { public: - RicMswCompletion( const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT ); + RicMswCompletion( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index = cvf::UNDEFINED_SIZE_T ); virtual RigCompletionData::CompletionType completionType() const = 0; - - const QString& label() const; - size_t index() const; - int branchNumber() const; - void setBranchNumber( int branchNumber ); - - void addSubSegment( std::shared_ptr subSegment ); - - std::vector>& subSegments(); - const std::vector>& subSegments() const; - - void setLabel( const QString& label ); + size_t index() const; private: - QString m_label; - size_t m_index; - int m_branchNumber; - - std::vector> m_subSegments; + size_t m_index; }; class RicMswFishbones : public RicMswCompletion { public: - RicMswFishbones( const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT ) - : RicMswCompletion( label, index, branchNumber ) + RicMswFishbones( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index = cvf::UNDEFINED_SIZE_T ) + : RicMswCompletion( label, wellPath, startMD, startTVD, index ) { } @@ -77,7 +70,11 @@ public: class RicMswFracture : public RicMswCompletion { public: - RicMswFracture( const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT ); + RicMswFracture( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index = cvf::UNDEFINED_SIZE_T ); RigCompletionData::CompletionType completionType() const override; }; @@ -87,7 +84,11 @@ public: class RicMswPerforation : public RicMswCompletion { public: - RicMswPerforation( const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT ); + RicMswPerforation( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + size_t index = cvf::UNDEFINED_SIZE_T ); RigCompletionData::CompletionType completionType() const override; }; @@ -97,7 +98,11 @@ public: class RicMswValve : public RicMswCompletion { public: - RicMswValve( const QString& label, const RimWellPathValve* wellPathValve ); + RicMswValve( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); virtual ~RicMswValve() {} @@ -106,6 +111,12 @@ public: bool isValid() const; void setIsValid( bool valid ); + static std::unique_ptr createExportValve( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); + private: bool m_valid; const RimWellPathValve* m_wellPathValve; @@ -117,7 +128,11 @@ private: class RicMswWsegValve : public RicMswValve { public: - RicMswWsegValve( const QString& label, const RimWellPathValve* wellPathValve ); + RicMswWsegValve( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); double flowCoefficient() const; double area() const; @@ -135,7 +150,11 @@ private: class RicMswFishbonesICD : public RicMswWsegValve { public: - RicMswFishbonesICD( const QString& label, const RimWellPathValve* wellPathValve ); + RicMswFishbonesICD( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); RigCompletionData::CompletionType completionType() const override; }; @@ -145,7 +164,11 @@ public: class RicMswPerforationICD : public RicMswWsegValve { public: - RicMswPerforationICD( const QString& label, const RimWellPathValve* wellPathValve ); + RicMswPerforationICD( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); RigCompletionData::CompletionType completionType() const override; }; @@ -155,7 +178,11 @@ public: class RicMswPerforationICV : public RicMswWsegValve { public: - RicMswPerforationICV( const QString& label, const RimWellPathValve* wellPathValve ); + RicMswPerforationICV( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); RigCompletionData::CompletionType completionType() const override; }; @@ -165,7 +192,11 @@ public: class RicMswPerforationAICD : public RicMswValve { public: - RicMswPerforationAICD( const QString& label, const RimWellPathValve* wellPathValve ); + RicMswPerforationAICD( const QString& label, + const RimWellPath* wellPath, + double startMD, + double startTVD, + const RimWellPathValve* wellPathValve ); RigCompletionData::CompletionType completionType() const override; bool isOpen() const; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.cpp index 9bd21bdb42..32006f21a2 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.cpp @@ -36,15 +36,18 @@ RicMswExportInfo::RicMswExportInfo( const RimWellPath* wellPath, double initialMD, const QString& lengthAndDepthText, const QString& pressureDropText ) - : m_wellPath( wellPath ) - , m_initialMD( initialMD ) - , m_unitSystem( unitSystem ) + : m_unitSystem( unitSystem ) , m_topWellBoreVolume( RicMswExportInfo::defaultDoubleValue() ) , m_linerDiameter( RimMswCompletionParameters::defaultLinerDiameter( unitSystem ) ) , m_roughnessFactor( RimMswCompletionParameters::defaultRoughnessFactor( unitSystem ) ) , m_lengthAndDepthText( lengthAndDepthText ) , m_pressureDropText( pressureDropText ) , m_hasSubGridIntersections( false ) + , m_mainBoreBranch( + std::make_unique( "Main Stem", + wellPath, + initialMD, + -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath( initialMD ).z() ) ) { } @@ -72,48 +75,6 @@ void RicMswExportInfo::setHasSubGridIntersections( bool subGridIntersections ) m_hasSubGridIntersections = subGridIntersections; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswExportInfo::addSegment( std::shared_ptr location ) -{ - m_segments.push_back( location ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswExportInfo::sortSegments() -{ - std::sort( m_segments.begin(), - m_segments.end(), - []( std::shared_ptr lhs, std::shared_ptr rhs ) { return *lhs < *rhs; } ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RimWellPath* RicMswExportInfo::wellPath() const -{ - return m_wellPath; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicMswExportInfo::initialMD() const -{ - return m_initialMD; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicMswExportInfo::initialTVD() const -{ - return -m_wellPath->wellPathGeometry()->interpolatedPointAlongWellPath( m_initialMD ).z(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -181,15 +142,15 @@ double RicMswExportInfo::defaultDoubleValue() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector>& RicMswExportInfo::segments() const +const RicMswBranch* RicMswExportInfo::mainBoreBranch() const { - return m_segments; + return m_mainBoreBranch.get(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector>& RicMswExportInfo::segments() +RicMswBranch* RicMswExportInfo::mainBoreBranch() { - return m_segments; + return m_mainBoreBranch.get(); } diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.h index d1ae94315f..3064ffe32a 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswExportInfo.h @@ -20,6 +20,7 @@ #include "RiaDefines.h" +#include "RicMswBranch.h" #include "RicMswSegment.h" #include @@ -27,7 +28,7 @@ #include class RimWellPath; -class RimFishbonesMultipleSubs; +class RimFishbones; //================================================================================================== /// @@ -45,13 +46,7 @@ public: void setRoughnessFactor( double roughnessFactor ); void setHasSubGridIntersections( bool subGridIntersections ); - void addSegment( std::shared_ptr location ); - void sortSegments(); - - const RimWellPath* wellPath() const; RiaDefines::EclipseUnitSystem unitSystem() const; - double initialMD() const; - double initialTVD() const; double topWellBoreVolume() const; double linerDiameter() const; double roughnessFactor() const; @@ -60,13 +55,11 @@ public: bool hasSubGridIntersections() const; static double defaultDoubleValue(); - const std::vector>& segments() const; - std::vector>& segments(); + const RicMswBranch* mainBoreBranch() const; + RicMswBranch* mainBoreBranch(); private: - const RimWellPath* m_wellPath; RiaDefines::EclipseUnitSystem m_unitSystem; - double m_initialMD; double m_topWellBoreVolume; double m_linerDiameter; double m_roughnessFactor; @@ -74,5 +67,5 @@ private: QString m_pressureDropText; bool m_hasSubGridIntersections; - std::vector> m_segments; + std::unique_ptr m_mainBoreBranch; }; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswItem.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswItem.cpp new file mode 100644 index 0000000000..e7d5b03292 --- /dev/null +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswItem.cpp @@ -0,0 +1,49 @@ +#include "RicMswItem.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswItem::RicMswItem( const QString& label ) + : m_label( label ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicMswItem::label() const +{ + return m_label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswItem::setLabel( const QString& label ) +{ + m_label = label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswItem::deltaMD() const +{ + return endMD() - startMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswItem::deltaTVD() const +{ + return endTVD() - startTVD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicMswItem::operator<( const RicMswItem& rhs ) const +{ + return startMD() < rhs.startMD(); +} diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDefInterface.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswItem.h similarity index 56% rename from ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDefInterface.cpp rename to ApplicationLibCode/Commands/CompletionExportCommands/RicMswItem.h index ce2e98407f..b4a031d862 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDefInterface.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswItem.h @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2020- Equinor ASA +// Copyright (C) 2021- 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 @@ -15,7 +15,29 @@ // for more details. // ///////////////////////////////////////////////////////////////////////////////// +#pragma once -#include "RimWellPathGeometryDefInterface.h" +#include -CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimWellPathGeometryDefInterface, "WellPathGeometryDefInterface" ); +class RicMswItem +{ +public: + RicMswItem( const QString& label ); + virtual ~RicMswItem() = default; + + QString label() const; + void setLabel( const QString& label ); + + virtual double startMD() const = 0; + virtual double endMD() const = 0; + double deltaMD() const; + + virtual double startTVD() const = 0; + virtual double endTVD() const = 0; + double deltaTVD() const; + + bool operator<( const RicMswItem& rhs ) const; + +protected: + QString m_label; +}; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.cpp index 47ba450da5..c14dd7b9f0 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.cpp @@ -15,9 +15,9 @@ // for more details. // ///////////////////////////////////////////////////////////////////////////////// - #include "RicMswSegment.h" +#include "RicMswCompletions.h" #include "RicMswExportInfo.h" #include @@ -33,7 +33,7 @@ RicMswSegment::RicMswSegment( const QString& label, double endTVD, size_t subIndex, int segmentNumber /*= -1*/ ) - : m_label( label ) + : RicMswItem( label ) , m_startMD( startMD ) , m_endMD( endMD ) , m_startTVD( startTVD ) @@ -49,14 +49,6 @@ RicMswSegment::RicMswSegment( const QString& label, { } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicMswSegment::label() const -{ - return m_label; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -73,38 +65,6 @@ double RicMswSegment::endMD() const return m_endMD; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicMswSegment::setOutputMD( double outputMD ) -{ - m_outputMD = outputMD; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicMswSegment::outputMD() const -{ - return m_outputMD; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicMswSegment::length() const -{ - return m_endMD - m_startMD; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicMswSegment::deltaMD() const -{ - return m_endMD - m_startMD; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -121,6 +81,22 @@ double RicMswSegment::endTVD() const return m_endTVD; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setOutputMD( double outputMD ) +{ + m_outputMD = outputMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::outputMD() const +{ + return m_outputMD; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -137,14 +113,6 @@ double RicMswSegment::outputTVD() const return m_outputTVD; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicMswSegment::deltaTVD() const -{ - return m_endTVD - m_startTVD; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -196,17 +164,27 @@ int RicMswSegment::segmentNumber() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector>& RicMswSegment::completions() const +std::vector RicMswSegment::completions() const { - return m_completions; + std::vector allCompletions; + for ( const auto& completion : m_completions ) + { + allCompletions.push_back( completion.get() ); + } + return allCompletions; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector>& RicMswSegment::completions() +std::vector RicMswSegment::completions() { - return m_completions; + std::vector allCompletions; + for ( auto& completion : m_completions ) + { + allCompletions.push_back( completion.get() ); + } + return allCompletions; } //-------------------------------------------------------------------------------------------------- @@ -260,24 +238,51 @@ void RicMswSegment::setSegmentNumber( int segmentNumber ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicMswSegment::addCompletion( std::shared_ptr completion ) +void RicMswSegment::addCompletion( std::unique_ptr completion ) { - m_completions.push_back( completion ); + m_completions.push_back( std::move( completion ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicMswSegment::removeCompletion( std::shared_ptr completion ) +std::unique_ptr RicMswSegment::removeCompletion( RicMswCompletion* completion ) { + std::unique_ptr removedCompletion; for ( auto it = m_completions.begin(); it != m_completions.end(); ++it ) { - if ( ( *it ) == completion ) + if ( it->get() == completion ) { + removedCompletion = std::move( *it ); m_completions.erase( it ); break; } } + return removedCompletion; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::addIntersection( std::shared_ptr intersection ) +{ + m_intersections.push_back( intersection ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector>& RicMswSegment::intersections() const +{ + return m_intersections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector>& RicMswSegment::intersections() +{ + return m_intersections; } //-------------------------------------------------------------------------------------------------- @@ -295,11 +300,3 @@ const caf::PdmObject* RicMswSegment::sourcePdmObject() const { return m_sourcePdmObject; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RicMswSegment::operator<( const RicMswSegment& rhs ) const -{ - return startMD() < rhs.startMD(); -} diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.h index 7c0eb1cd3e..c666b2633d 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegment.h @@ -17,16 +17,21 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RicMswCompletions.h" +#include "RicMswItem.h" +#include "RicMswSegmentCellIntersection.h" -#include +#include "cafPdmObject.h" +#include "cafPdmPointer.h" +#include "cvfMath.h" #include +class RicMswCompletion; + //================================================================================================== /// //================================================================================================== -class RicMswSegment +class RicMswSegment : public RicMswItem { public: RicMswSegment( const QString& label, @@ -37,20 +42,16 @@ public: size_t subIndex = cvf::UNDEFINED_SIZE_T, int segmentNumber = -1 ); - QString label() const; + double startMD() const override; + double endMD() const override; + + double startTVD() const override; + double endTVD() const override; - double startMD() const; - double endMD() const; void setOutputMD( double outputMD ); double outputMD() const; - double length() const; - - double deltaMD() const; - double startTVD() const; - double endTVD() const; void setOutputTVD( double outputTVD ); double outputTVD() const; - double deltaTVD() const; double effectiveDiameter() const; double holeDiameter() const; @@ -60,8 +61,8 @@ public: size_t subIndex() const; int segmentNumber() const; - const std::vector>& completions() const; - std::vector>& completions(); + std::vector completions() const; + std::vector completions(); void setLabel( const QString& label ); void setEffectiveDiameter( double effectiveDiameter ); @@ -69,31 +70,38 @@ public: void setOpenHoleRoughnessFactor( double roughnessFactor ); void setSkinFactor( double skinFactor ); void setSegmentNumber( int segmentNumber ); - void addCompletion( std::shared_ptr completion ); - void removeCompletion( std::shared_ptr completion ); + + void addCompletion( std::unique_ptr completion ); + std::unique_ptr removeCompletion( RicMswCompletion* completion ); + + void addIntersection( std::shared_ptr intersection ); + + const std::vector>& intersections() const; + std::vector>& intersections(); void setSourcePdmObject( const caf::PdmObject* object ); const caf::PdmObject* sourcePdmObject() const; - bool operator<( const RicMswSegment& rhs ) const; - private: - QString m_label; - double m_startMD; - double m_endMD; - double m_startTVD; - double m_endTVD; + double m_startMD; + double m_endMD; + double m_startTVD; + double m_endTVD; + double m_outputMD; double m_outputTVD; - double m_effectiveDiameter; - double m_holeDiameter; - double m_openHoleRoughnessFactor; - double m_skinFactor; + + double m_effectiveDiameter; + double m_holeDiameter; + double m_openHoleRoughnessFactor; + double m_skinFactor; size_t m_subIndex; int m_segmentNumber; - std::vector> m_completions; + std::vector> m_completions; + + std::vector> m_intersections; caf::PdmPointer m_sourcePdmObject; }; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegmentCellIntersection.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegmentCellIntersection.cpp new file mode 100644 index 0000000000..8e062c0b59 --- /dev/null +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegmentCellIntersection.cpp @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicMswSegmentCellIntersection.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswSegmentCellIntersection::RicMswSegmentCellIntersection( const QString& gridName, + size_t globalCellIndex, + const cvf::Vec3st& gridLocalCellIJK, + const cvf::Vec3d& lengthsInCell ) + : m_gridName( gridName ) + , m_globalCellIndex( globalCellIndex ) + , m_gridLocalCellIJK( gridLocalCellIJK ) + , m_lengthsInCell( lengthsInCell ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString& RicMswSegmentCellIntersection::gridName() const +{ + return m_gridName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RicMswSegmentCellIntersection::globalCellIndex() const +{ + return m_globalCellIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3st RicMswSegmentCellIntersection::gridLocalCellIJK() const +{ + return m_gridLocalCellIJK; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const cvf::Vec3d& RicMswSegmentCellIntersection::lengthsInCell() const +{ + return m_lengthsInCell; +} diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSubSegment.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegmentCellIntersection.h similarity index 57% rename from ApplicationLibCode/Commands/CompletionExportCommands/RicMswSubSegment.h rename to ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegmentCellIntersection.h index a3f6cf8b04..b661873597 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSubSegment.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswSegmentCellIntersection.h @@ -26,10 +26,10 @@ //================================================================================================== /// //================================================================================================== -class RicMswSubSegmentCellIntersection +class RicMswSegmentCellIntersection { public: - RicMswSubSegmentCellIntersection( const QString& gridName, // Pass in empty string for main grid + RicMswSegmentCellIntersection( const QString& gridName, // Pass in empty string for main grid size_t globalCellIndex, const cvf::Vec3st& gridLocalCellIJK, const cvf::Vec3d& lengthsInCell ); @@ -44,35 +44,3 @@ private: cvf::Vec3st m_gridLocalCellIJK; cvf::Vec3d m_lengthsInCell; }; - -//================================================================================================== -/// -//================================================================================================== -class RicMswSubSegment -{ -public: - RicMswSubSegment( double startMD, double endMD, double startTVD, double endTVD ); - - double startMD() const; - double endMD() const; - double deltaMD() const; - double startTVD() const; - double endTVD() const; - double deltaTVD() const; - - int segmentNumber() const; - void setSegmentNumber( int segmentNumber ); - void addIntersection( std::shared_ptr intersection ); - - const std::vector>& intersections() const; - std::vector>& intersections(); - -private: - double m_startMD; - double m_endMD; - double m_startTVD; - double m_endTVD; - int m_segmentNumber; - - std::vector> m_intersections; -}; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp index f793cfd441..ea1b5532ea 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.cpp @@ -27,7 +27,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswICDAccumulator::RicMswICDAccumulator( std::shared_ptr valve, RiaDefines::EclipseUnitSystem unitSystem ) +RicMswICDAccumulator::RicMswICDAccumulator( RicMswValve* valve, RiaDefines::EclipseUnitSystem unitSystem ) : RicMswValveAccumulator( valve, unitSystem ) , m_areaSum( 0.0 ) { @@ -70,7 +70,7 @@ bool RicMswICDAccumulator::accumulateValveParameters( const RimWellPathValve* we //-------------------------------------------------------------------------------------------------- void RicMswICDAccumulator::applyToSuperValve() { - std::shared_ptr icd = std::dynamic_pointer_cast( m_valve ); + auto icd = dynamic_cast( m_valve ); CVF_ASSERT( icd ); if ( m_coefficientCalculator.validAggregatedWeight() && m_valid ) @@ -84,7 +84,7 @@ void RicMswICDAccumulator::applyToSuperValve() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswAICDAccumulator::RicMswAICDAccumulator( std::shared_ptr valve, RiaDefines::EclipseUnitSystem unitSystem ) +RicMswAICDAccumulator::RicMswAICDAccumulator( RicMswValve* valve, RiaDefines::EclipseUnitSystem unitSystem ) : RicMswValveAccumulator( valve, unitSystem ) , m_deviceOpen( false ) , m_accumulatedLength( 0.0 ) @@ -145,8 +145,8 @@ bool RicMswAICDAccumulator::accumulateValveParameters( const RimWellPathValve* w //-------------------------------------------------------------------------------------------------- void RicMswAICDAccumulator::applyToSuperValve() { - const double eps = 1.0e-8; - std::shared_ptr aicd = std::dynamic_pointer_cast( m_valve ); + const double eps = 1.0e-8; + auto aicd = dynamic_cast( m_valve ); if ( aicd && m_valid && m_accumulatedLength > eps ) { diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h index 4f2b9baedf..0884e1996c 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicMswValveAccumulators.h @@ -22,7 +22,6 @@ #include "RimWellPathAicdParameters.h" #include -#include class RimWellPathValve; class RicMswValve; @@ -33,7 +32,7 @@ class RicMswValve; class RicMswValveAccumulator { public: - RicMswValveAccumulator( std::shared_ptr valve, RiaDefines::EclipseUnitSystem unitSystem ) + RicMswValveAccumulator( RicMswValve* valve, RiaDefines::EclipseUnitSystem unitSystem ) : m_valve( valve ) , m_unitSystem( unitSystem ) , m_valid( false ) @@ -44,10 +43,10 @@ public: double perforationCompsegsLength ) = 0; virtual void applyToSuperValve() = 0; - std::shared_ptr superValve() const { return m_valve; } + RicMswValve* superValve() const { return m_valve; } protected: - std::shared_ptr m_valve; + RicMswValve* m_valve; RiaDefines::EclipseUnitSystem m_unitSystem; bool m_valid; }; @@ -58,7 +57,7 @@ protected: class RicMswICDAccumulator : public RicMswValveAccumulator { public: - RicMswICDAccumulator( std::shared_ptr valve, RiaDefines::EclipseUnitSystem unitSystem ); + RicMswICDAccumulator( RicMswValve* valve, RiaDefines::EclipseUnitSystem unitSystem ); bool accumulateValveParameters( const RimWellPathValve* wellPathValve, double overlapLength, double perforationCompsegsLength ) override; @@ -75,7 +74,7 @@ private: class RicMswAICDAccumulator : public RicMswValveAccumulator { public: - RicMswAICDAccumulator( std::shared_ptr valve, RiaDefines::EclipseUnitSystem unitSystem ); + RicMswAICDAccumulator( RicMswValve* valve, RiaDefines::EclipseUnitSystem unitSystem ); bool accumulateValveParameters( const RimWellPathValve* wellPathValve, double overlapLength, double perforationCompsegsLength ) override; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp index e9bc62933d..db31d719de 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp @@ -25,7 +25,7 @@ #include "RicExportFeatureImpl.h" #include "RimDialogData.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimPerforationInterval.h" #include "RimProject.h" #include "RimSimWellFracture.h" @@ -87,10 +87,10 @@ void RicWellPathExportCompletionDataFeature::prepareExportSettingsAndExportCompl if ( exportSettings->folder().isEmpty() ) exportSettings->folder = defaultDir; - std::vector simWellFractures; - std::vector wellPathFractures; - std::vector wellPathFishbones; - std::vector wellPathPerforations; + std::vector simWellFractures; + std::vector wellPathFractures; + std::vector wellPathFishbones; + std::vector wellPathPerforations; for ( auto s : simWells ) { @@ -222,5 +222,10 @@ std::vector RicWellPathExportCompletionDataFeature::selectedWellPa } } + wellPaths.erase( std::remove_if( wellPaths.begin(), + wellPaths.end(), + []( auto wellPath ) { return !wellPath->isTopLevelWellPath(); } ), + wellPaths.end() ); + return wellPaths; } diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp index c6e2102958..1121f3e224 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp @@ -51,8 +51,8 @@ #include "RigWellPathIntersectionTools.h" #include "RimFileWellPath.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimFractureTemplate.h" #include "RimNonDarcyPerforationParameters.h" #include "RimPerforationCollection.h" @@ -298,7 +298,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v std::vector reportItemsForWell; for ( const auto& fracItem : fractureDataReportItems ) { - if ( fracItem.wellPathNameForExport() == wellPath->completions()->wellNameForExport() ) + if ( fracItem.wellPathNameForExport() == wellPath->completionSettings()->wellNameForExport() ) { reportItemsForWell.push_back( fracItem ); } @@ -353,7 +353,8 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v std::vector reportItemsForWell; for ( const auto& fracItem : fractureDataReportItems ) { - if ( fracItem.wellPathNameForExport() == wellPath->completions()->wellNameForExport() ) + if ( fracItem.wellPathNameForExport() == + wellPath->completionSettings()->wellNameForExport() ) { reportItemsForWell.push_back( fracItem ); } @@ -688,7 +689,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportWellPathFractureReport( { for ( const auto& reportItem : sortedReportItems ) { - if ( reportItem.wellPathNameForExport() == wellPath->completions()->wellNameForExport() ) + if ( reportItem.wellPathNameForExport() == wellPath->completionSettings()->wellNameForExport() ) { wellPathsSet.insert( wellPath ); } @@ -749,22 +750,22 @@ void RicWellPathExportCompletionDataFeatureImpl::exportWelspecsToFile( RimEclips // Export for ( const auto wellPath : wellPathSet ) { - auto rimCompletions = wellPath->completions(); - auto ijIntersection = wellPathUpperGridIntersectionIJ( gridCase, wellPath ); + auto completionSettings = wellPath->completionSettings(); + auto ijIntersection = wellPathUpperGridIntersectionIJ( gridCase, wellPath ); - formatter.add( rimCompletions->wellNameForExport() ) - .add( rimCompletions->wellGroupNameForExport() ) + formatter.add( completionSettings->wellNameForExport() ) + .add( completionSettings->wellGroupNameForExport() ) .addOneBasedCellIndex( ijIntersection.second.x() ) .addOneBasedCellIndex( ijIntersection.second.y() ) - .add( rimCompletions->referenceDepthForExport() ) - .add( rimCompletions->wellTypeNameForExport() ) - .add( rimCompletions->drainageRadiusForExport() ) - .add( rimCompletions->gasInflowEquationForExport() ) - .add( rimCompletions->automaticWellShutInForExport() ) - .add( rimCompletions->allowWellCrossFlowForExport() ) - .add( rimCompletions->wellBoreFluidPVTForExport() ) - .add( rimCompletions->hydrostaticDensityForExport() ) - .add( rimCompletions->fluidInPlaceRegionForExport() ) + .add( completionSettings->referenceDepthForExport() ) + .add( completionSettings->wellTypeNameForExport() ) + .add( completionSettings->drainageRadiusForExport() ) + .add( completionSettings->gasInflowEquationForExport() ) + .add( completionSettings->automaticWellShutInForExport() ) + .add( completionSettings->allowWellCrossFlowForExport() ) + .add( completionSettings->wellBoreFluidPVTForExport() ) + .add( completionSettings->hydrostaticDensityForExport() ) + .add( completionSettings->fluidInPlaceRegionForExport() ) .rowCompleted(); } @@ -839,22 +840,22 @@ void RicWellPathExportCompletionDataFeatureImpl::exportWelspeclToFile( std::tie( measuredDepth, ijIntersection, lgrName ) = itemWithLowestMD; - auto rimCompletions = wellPath->completions(); + auto completionSettings = wellPath->completionSettings(); - formatter.add( rimCompletions->wellNameForExport() ) - .add( rimCompletions->wellGroupNameForExport() ) + formatter.add( completionSettings->wellNameForExport() ) + .add( completionSettings->wellGroupNameForExport() ) .add( lgrName ) .addOneBasedCellIndex( ijIntersection.x() ) .addOneBasedCellIndex( ijIntersection.y() ) - .add( rimCompletions->referenceDepthForExport() ) - .add( rimCompletions->wellTypeNameForExport() ) - .add( rimCompletions->drainageRadiusForExport() ) - .add( rimCompletions->gasInflowEquationForExport() ) - .add( rimCompletions->automaticWellShutInForExport() ) - .add( rimCompletions->allowWellCrossFlowForExport() ) - .add( rimCompletions->wellBoreFluidPVTForExport() ) - .add( rimCompletions->hydrostaticDensityForExport() ) - .add( rimCompletions->fluidInPlaceRegionForExport() ) + .add( completionSettings->referenceDepthForExport() ) + .add( completionSettings->wellTypeNameForExport() ) + .add( completionSettings->drainageRadiusForExport() ) + .add( completionSettings->gasInflowEquationForExport() ) + .add( completionSettings->automaticWellShutInForExport() ) + .add( completionSettings->allowWellCrossFlowForExport() ) + .add( completionSettings->wellBoreFluidPVTForExport() ) + .add( completionSettings->hydrostaticDensityForExport() ) + .add( completionSettings->fluidInPlaceRegionForExport() ) .rowCompleted(); } } @@ -1190,7 +1191,7 @@ std::vector RicWellPathExportCompletionDataFeatureImpl::gener bool cellIsActive = activeCellInfo->isActive( cell.globCellIndex ); if ( !cellIsActive ) continue; - RigCompletionData completion( wellPath->completions()->wellNameForExport(), + RigCompletionData completion( wellPath->completionSettings()->wellNameForExport(), RigCompletionDataGridCell( cell.globCellIndex, settings.caseToApply->mainGrid() ), cell.startMD ); diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h index dbb7fdc975..85787f8b41 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h @@ -38,7 +38,7 @@ class RigCell; class RigEclipseCaseData; class RigMainGrid; class RimEclipseCase; -class RimFishbonesMultipleSubs; +class RimFishbones; class RimSimWellInView; class RimPerforationInterval; class RimWellPath; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionsFileTools.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionsFileTools.cpp index 1b4a820d9e..f0e9565daf 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionsFileTools.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionsFileTools.cpp @@ -88,7 +88,7 @@ const RimWellPath* RicWellPathExportCompletionsFileTools::findWellPathFromExport for ( const auto wellPath : allWellPaths ) { - if ( wellPath->completions()->wellNameForExport() == wellNameForExport ) return wellPath; + if ( wellPath->completionSettings()->wellNameForExport() == wellNameForExport ) return wellPath; } return nullptr; } diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp index 0cde9a0e5d..c0d843bf1b 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.cpp @@ -38,8 +38,8 @@ #include "RigWellPathIntersectionTools.h" #include "RimEclipseCase.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimFractureTemplate.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" @@ -47,6 +47,7 @@ #include "RimWellPathCompletions.h" #include "RimWellPathFracture.h" #include "RimWellPathFractureCollection.h" +#include "RimWellPathGroup.h" #include "RimWellPathValve.h" #include @@ -73,12 +74,25 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForAllCompletions( { std::shared_ptr unifiedWellPathFile; + auto allCompletions = wellPath->allCompletionsRecursively(); bool exportFractures = exportSettings.includeFractures() && - !wellPath->fractureCollection()->activeFractures().empty(); + std::any_of( allCompletions.begin(), allCompletions.end(), []( auto completion ) { + return completion->isEnabled() && + completion->componentType() == RiaDefines::WellPathComponentType::FRACTURE; + } ); bool exportPerforations = exportSettings.includePerforations() && - !wellPath->perforationIntervalCollection()->activePerforations().empty(); + std::any_of( allCompletions.begin(), allCompletions.end(), []( auto completion ) { + return completion->isEnabled() && + completion->componentType() == + RiaDefines::WellPathComponentType::PERFORATION_INTERVAL; + } ); + bool exportFishbones = exportSettings.includeFishbones() && - !wellPath->fishbonesCollection()->activeFishbonesSubs().empty(); + std::any_of( allCompletions.begin(), allCompletions.end(), []( auto completion ) { + return completion->isEnabled() && + completion->componentType() == RiaDefines::WellPathComponentType::FISHBONES; + } ); + bool exportAnyCompletion = exportFractures || exportPerforations || exportFishbones; if ( exportAnyCompletion && exportSettings.fileSplit() == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL && !unifiedWellPathFile ) @@ -166,7 +180,7 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForFractures( RimEcl QTextStream stream( exportFile.get() ); RifTextDataTableFormatter formatter( stream ); - double maxSegmentLength = wellPath->fractureCollection()->mswParameters()->maxSegmentLength(); + double maxSegmentLength = wellPath->completionSettings()->mswParameters()->maxSegmentLength(); generateWelsegsTable( formatter, exportInfo, maxSegmentLength ); generateCompsegTables( formatter, exportInfo ); @@ -187,12 +201,39 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForFishbones( RimEcl return; } - RicMswExportInfo exportInfo = generateFishbonesMswExportInfo( eclipseCase, wellPath, fishbonesSubs, true ); + double initialMD = 0.0; // Start measured depth location to export MSW data for. Either based on first intersection + // with active grid, or user defined value. + + auto cellIntersections = generateCellSegments( eclipseCase, wellPath, &initialMD ); + + auto mswParameters = wellPath->completionSettings()->mswParameters(); + RiaDefines::EclipseUnitSystem unitSystem = eclipseCase->eclipseCaseData()->unitsType(); + + RicMswExportInfo exportInfo( wellPath, + unitSystem, + wellPath->fishbonesCollection()->startMD(), + mswParameters->lengthAndDepth().text(), + mswParameters->pressureDrop().text() ); + exportInfo.setLinerDiameter( mswParameters->linerDiameter( unitSystem ) ); + exportInfo.setRoughnessFactor( mswParameters->roughnessFactor( unitSystem ) ); + + generateFishbonesMswExportInfo( eclipseCase, + wellPath, + initialMD, + cellIntersections, + fishbonesSubs, + true, + &exportInfo, + exportInfo.mainBoreBranch() ); + + int branchNumber = 1; + + assignBranchNumbersToBranch( eclipseCase, &exportInfo, exportInfo.mainBoreBranch(), &branchNumber ); QTextStream stream( exportFile.get() ); RifTextDataTableFormatter formatter( stream ); - double maxSegmentLength = wellPath->fishbonesCollection()->mswParameters()->maxSegmentLength(); + double maxSegmentLength = wellPath->completionSettings()->mswParameters()->maxSegmentLength(); generateWelsegsTable( formatter, exportInfo, maxSegmentLength ); generateCompsegTables( formatter, exportInfo ); @@ -207,69 +248,55 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForPerforations( Rim const RimWellPath* wellPath, int timeStep ) { - auto perforationIntervals = wellPath->perforationIntervalCollection()->activePerforations(); + RiaDefines::EclipseUnitSystem unitSystem = eclipseCase->eclipseCaseData()->unitsType(); - if ( eclipseCase == nullptr ) + double initialMD = 0.0; // Start measured depth location to export MSW data for. Either based on first intersection + // with active grid, or user defined value. + + auto cellIntersections = generateCellSegments( eclipseCase, wellPath, &initialMD ); + + auto mswParameters = wellPath->completionSettings()->mswParameters(); + RicMswExportInfo exportInfo( wellPath, + unitSystem, + initialMD, + mswParameters->lengthAndDepth().text(), + mswParameters->pressureDrop().text() ); + + if ( generatePerforationsMswExportInfo( eclipseCase, + wellPath, + timeStep, + initialMD, + cellIntersections, + &exportInfo, + exportInfo.mainBoreBranch() ) ) { - RiaLogging::error( "Export Well Segments: Cannot export completions data without specified eclipse case" ); - return; + int branchNumber = 1; + + assignBranchNumbersToBranch( eclipseCase, &exportInfo, exportInfo.mainBoreBranch(), &branchNumber ); + + QTextStream stream( exportFile.get() ); + RifTextDataTableFormatter formatter( stream ); + + double maxSegmentLength = wellPath->completionSettings()->mswParameters()->maxSegmentLength(); + + generateWelsegsTable( formatter, exportInfo, maxSegmentLength ); + generateCompsegTables( formatter, exportInfo ); + generateWsegvalvTable( formatter, exportInfo ); + generateWsegAicdTable( formatter, exportInfo ); } - - // Check if there exist overlap between valves in a perforation interval - for ( const auto& perfInterval : perforationIntervals ) - { - for ( const auto& valve : perfInterval->valves() ) - { - for ( const auto& otherValve : perfInterval->valves() ) - { - if ( otherValve != valve ) - { - bool hasIntersection = - !( ( valve->endMD() < otherValve->startMD() ) || ( otherValve->endMD() < valve->startMD() ) ); - - if ( hasIntersection ) - { - RiaLogging::error( - QString( "Valve overlap detected for perforation interval : %1" ).arg( perfInterval->name() ) ); - - RiaLogging::error( "Name of valves" ); - RiaLogging::error( valve->name() ); - RiaLogging::error( otherValve->name() ); - - RiaLogging::error( "Failed to export well segments" ); - - return; - } - } - } - } - } - - RicMswExportInfo exportInfo = - generatePerforationsMswExportInfo( eclipseCase, wellPath, timeStep, perforationIntervals ); - - QTextStream stream( exportFile.get() ); - RifTextDataTableFormatter formatter( stream ); - - double maxSegmentLength = wellPath->perforationIntervalCollection()->mswParameters()->maxSegmentLength(); - - generateWelsegsTable( formatter, exportInfo, maxSegmentLength ); - generateCompsegTables( formatter, exportInfo ); - generateWsegvalvTable( formatter, exportInfo ); - generateWsegAicdTable( formatter, exportInfo ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::generateWelsegsTable( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, + RicMswExportInfo& exportInfo, double maxSegmentLength ) { formatter.keyword( "WELSEGS" ); - double startMD = exportInfo.initialMD(); - double startTVD = exportInfo.initialTVD(); + double startMD = exportInfo.mainBoreBranch()->startMD(); + double startTVD = exportInfo.mainBoreBranch()->startTVD(); { std::vector header = { @@ -282,7 +309,7 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsTable( RifTextDataTable }; formatter.header( header ); - formatter.add( exportInfo.wellPath()->completions()->wellNameForExport() ); + formatter.add( exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() ); formatter.add( startTVD ); formatter.add( startMD ); formatter.addValueOrDefaultMarker( exportInfo.topWellBoreVolume(), RicMswExportInfo::defaultDoubleValue() ); @@ -306,39 +333,8 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsTable( RifTextDataTable } int segmentNumber = 2; // There's an implicit segment number 1. - { - formatter.comment( "Main Stem Segments" ); - std::shared_ptr previousSegment; - for ( std::shared_ptr segment : exportInfo.segments() ) - { - segment->setSegmentNumber( segmentNumber ); - if ( segment->subIndex() != cvf::UNDEFINED_SIZE_T ) - { - QString comment = segment->label() + QString( ", sub %1" ).arg( segment->subIndex() ); - formatter.comment( comment ); - } - - writeMainBoreWelsegsSegment( segment, previousSegment, formatter, exportInfo, maxSegmentLength, &segmentNumber ); - previousSegment = segment; - } - } - - { - generateWelsegsSegments( formatter, - exportInfo, - { RigCompletionData::FISHBONES_ICD, RigCompletionData::FISHBONES }, - maxSegmentLength, - &segmentNumber ); - generateWelsegsSegments( formatter, exportInfo, { RigCompletionData::FRACTURE }, maxSegmentLength, &segmentNumber ); - generateWelsegsSegments( formatter, - exportInfo, - { RigCompletionData::PERFORATION_ICD, - RigCompletionData::PERFORATION_ICV, - RigCompletionData::PERFORATION_AICD }, - maxSegmentLength, - &segmentNumber ); - } + writeWelsegsSegmentsRecursively( formatter, exportInfo, exportInfo.mainBoreBranch(), &segmentNumber, maxSegmentLength ); formatter.tableCompleted(); } @@ -346,51 +342,75 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsTable( RifTextDataTable //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::generateWelsegsSegments( - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - const std::set& exportCompletionTypes, - double maxSegmentLength, - int* segmentNumber ) +void RicWellPathExportMswCompletionsImpl::writeWelsegsSegmentsRecursively( RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + gsl::not_null branch, + gsl::not_null segmentNumber, + double maxSegmentLength, + RicMswSegment* connectedToSegment ) { - bool generatedHeader = false; - for ( std::shared_ptr segment : exportInfo.segments() ) - { - int mainSegmentNumber = segment->segmentNumber(); - segment->setSegmentNumber( mainSegmentNumber ); - for ( std::shared_ptr completion : segment->completions() ) - { - if ( exportCompletionTypes.count( completion->completionType() ) ) - { - if ( !generatedHeader ) - { - generateWelsegsCompletionCommentHeader( formatter, completion->completionType() ); - generatedHeader = true; - } + auto outletSegment = connectedToSegment; - if ( RigCompletionData::isValve( completion->completionType() ) ) - { - writeValveWelsegsSegment( segment, - std::dynamic_pointer_cast( completion ), - formatter, - exportInfo, - maxSegmentLength, - segmentNumber ); - } - else - { - writeCompletionWelsegsSegment( segment, completion, formatter, exportInfo, maxSegmentLength, segmentNumber ); - } + RicMswValve* outletValve = nullptr; + + auto branchSegments = branch->segments(); + auto it = branchSegments.begin(); + if ( outletValve = dynamic_cast( branch.get() ); outletValve != nullptr ) + { + writeValveWelsegsSegment( outletSegment, outletValve, formatter, exportInfo, maxSegmentLength, segmentNumber ); + + auto valveSegments = outletValve->segments(); + outletSegment = valveSegments.front(); + *segmentNumber = outletSegment->segmentNumber() + 1; + ++it; // skip segment below + } + + formatter.comment( QString( "Segments on branch %1" ).arg( branch->label() ) ); + + for ( ; it != branchSegments.end(); ++it ) + { + auto segment = *it; + segment->setSegmentNumber( *segmentNumber ); + + if ( segment->subIndex() != cvf::UNDEFINED_SIZE_T ) + { + QString comment = segment->label() + QString( ", sub %1" ).arg( segment->subIndex() ); + formatter.comment( comment ); + } + + writeWelsegsSegment( segment, outletSegment, formatter, exportInfo, maxSegmentLength, branch, segmentNumber ); + outletSegment = segment; + + for ( auto& completion : segment->completions() ) + { + auto segmentValve = dynamic_cast( completion ); + if ( segmentValve != nullptr ) + { + writeValveWelsegsSegment( segment, segmentValve, formatter, exportInfo, maxSegmentLength, segmentNumber ); + outletValve = segmentValve; + outletSegment = segment; + } + else + { + // If we have a valve, the outlet segment is the valve's segment + RicMswSegment* outletSegment = + outletValve && outletValve->segmentCount() > 0 ? outletValve->segments().front() : segment; + writeCompletionWelsegsSegments( outletSegment, completion, formatter, exportInfo, maxSegmentLength, segmentNumber ); } } } + + for ( auto childBranch : branch->branches() ) + { + writeWelsegsSegmentsRecursively( formatter, exportInfo, childBranch, segmentNumber, maxSegmentLength, outletSegment ); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::generateWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter, - RigCompletionData::CompletionType completionType ) +void RicWellPathExportMswCompletionsImpl::writeWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter, + RigCompletionData::CompletionType completionType ) { if ( completionType == RigCompletionData::CT_UNDEFINED ) { @@ -420,125 +440,174 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsCompletionCommentHeader /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::generateCompsegTables( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo ) + RicMswExportInfo& exportInfo ) { /* * TODO: Creating the regular perforation COMPSEGS table should come in here, before the others * should take precedence by appearing later in the output. See #3230. */ - { - std::set fishbonesTypes = { RigCompletionData::FISHBONES_ICD, - RigCompletionData::FISHBONES }; - generateCompsegTable( formatter, exportInfo, false, fishbonesTypes ); - if ( exportInfo.hasSubGridIntersections() ) - { - generateCompsegTable( formatter, exportInfo, true, fishbonesTypes ); - } - } + bool headerGenerated = false; - { - std::set fractureTypes = { RigCompletionData::FRACTURE }; - generateCompsegTable( formatter, exportInfo, false, fractureTypes ); - if ( exportInfo.hasSubGridIntersections() ) - { - generateCompsegTable( formatter, exportInfo, true, fractureTypes ); - } - } + std::set intersectedCells; { std::set perforationTypes = { RigCompletionData::PERFORATION, RigCompletionData::PERFORATION_ICD, RigCompletionData::PERFORATION_ICV, RigCompletionData::PERFORATION_AICD }; - generateCompsegTable( formatter, exportInfo, false, perforationTypes ); + generateCompsegTable( formatter, + exportInfo, + exportInfo.mainBoreBranch(), + false, + perforationTypes, + &headerGenerated, + &intersectedCells ); if ( exportInfo.hasSubGridIntersections() ) { - generateCompsegTable( formatter, exportInfo, true, perforationTypes ); + generateCompsegTable( formatter, + exportInfo, + exportInfo.mainBoreBranch(), + true, + perforationTypes, + &headerGenerated, + &intersectedCells ); } } -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::generateCompsegTable( - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - bool exportSubGridIntersections, - const std::set& exportCompletionTypes ) -{ - bool generatedHeader = false; - - for ( std::shared_ptr segment : exportInfo.segments() ) { - double startMD = segment->startMD(); - double endMD = segment->endMD(); - - for ( std::shared_ptr completion : segment->completions() ) + std::set fishbonesTypes = { RigCompletionData::FISHBONES_ICD, + RigCompletionData::FISHBONES }; + generateCompsegTable( formatter, + exportInfo, + exportInfo.mainBoreBranch(), + false, + fishbonesTypes, + &headerGenerated, + &intersectedCells ); + if ( exportInfo.hasSubGridIntersections() ) { - if ( !completion->subSegments().empty() && exportCompletionTypes.count( completion->completionType() ) ) - { - if ( !generatedHeader ) - { - generateCompsegHeader( formatter, exportInfo, completion->completionType(), exportSubGridIntersections ); - generatedHeader = true; - } - - for ( const std::shared_ptr& subSegment : completion->subSegments() ) - { - if ( completion->completionType() == RigCompletionData::FISHBONES_ICD ) - { - startMD = subSegment->startMD(); - endMD = subSegment->endMD(); - } - - for ( const std::shared_ptr& intersection : - subSegment->intersections() ) - { - bool isSubGridIntersection = !intersection->gridName().isEmpty(); - if ( isSubGridIntersection == exportSubGridIntersections ) - { - double startLength = subSegment->startMD(); - double endLength = subSegment->endMD(); - if ( completion->completionType() == RigCompletionData::PERFORATION_ICD || - completion->completionType() == RigCompletionData::PERFORATION_AICD || - completion->completionType() == RigCompletionData::PERFORATION_ICV ) - { - startLength = startMD; - endLength = endMD; - } - - if ( exportSubGridIntersections ) - { - formatter.add( intersection->gridName() ); - } - cvf::Vec3st ijk = intersection->gridLocalCellIJK(); - formatter.addOneBasedCellIndex( ijk.x() ).addOneBasedCellIndex( ijk.y() ).addOneBasedCellIndex( - ijk.z() ); - formatter.add( completion->branchNumber() ); - - formatter.add( startLength ); - formatter.add( endLength ); - - formatter.rowCompleted(); - } - } - } - } + generateCompsegTable( formatter, + exportInfo, + exportInfo.mainBoreBranch(), + true, + fishbonesTypes, + &headerGenerated, + &intersectedCells ); } } - if ( generatedHeader ) + + { + std::set fractureTypes = { RigCompletionData::FRACTURE }; + generateCompsegTable( formatter, + exportInfo, + exportInfo.mainBoreBranch(), + false, + fractureTypes, + &headerGenerated, + &intersectedCells ); + if ( exportInfo.hasSubGridIntersections() ) + { + generateCompsegTable( formatter, + exportInfo, + exportInfo.mainBoreBranch(), + true, + fractureTypes, + &headerGenerated, + &intersectedCells ); + } + } + + if ( headerGenerated ) { formatter.tableCompleted(); } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportMswCompletionsImpl::generateCompsegTable( + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + gsl::not_null branch, + bool exportSubGridIntersections, + const std::set& exportCompletionTypes, + gsl::not_null headerGenerated, + gsl::not_null*> intersectedCells ) +{ + for ( auto segment : branch->segments() ) + { + for ( auto completion : segment->completions() ) + { + if ( completion->segments().empty() || !exportCompletionTypes.count( completion->completionType() ) ) + continue; + + if ( !*headerGenerated ) + { + generateCompsegHeader( formatter, exportInfo, completion->completionType(), exportSubGridIntersections ); + *headerGenerated = true; + } + + bool isPerforationValve = completion->completionType() == RigCompletionData::PERFORATION_ICD || + completion->completionType() == RigCompletionData::PERFORATION_AICD || + completion->completionType() == RigCompletionData::PERFORATION_ICV; + + for ( auto subSegment : completion->segments() ) + { + for ( auto intersection : subSegment->intersections() ) + { + bool isSubGridIntersection = !intersection->gridName().isEmpty(); + if ( isSubGridIntersection != exportSubGridIntersections ) continue; + + double startLength = subSegment->startMD(); + double endLength = subSegment->endMD(); + if ( isPerforationValve ) + { + startLength = segment->startMD(); + endLength = segment->endMD(); + } + + cvf::Vec3st ijk = intersection->gridLocalCellIJK(); + if ( !intersectedCells->count( ijk ) ) + { + if ( exportSubGridIntersections ) + { + formatter.add( intersection->gridName() ); + } + + formatter.addOneBasedCellIndex( ijk.x() ).addOneBasedCellIndex( ijk.y() ).addOneBasedCellIndex( + ijk.z() ); + formatter.add( completion->branchNumber() ); + + formatter.add( startLength ); + formatter.add( endLength ); + + formatter.rowCompleted(); + intersectedCells->insert( ijk ); + } + } + } + } + } + + for ( auto childBranch : branch->branches() ) + { + generateCompsegTable( formatter, + exportInfo, + childBranch, + exportSubGridIntersections, + exportCompletionTypes, + headerGenerated, + intersectedCells ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::generateCompsegHeader( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, + RicMswExportInfo& exportInfo, RigCompletionData::CompletionType completionType, bool exportSubGridIntersections ) { @@ -563,7 +632,7 @@ void RicWellPathExportMswCompletionsImpl::generateCompsegHeader( RifTextDataTabl { std::vector header = { RifTextDataTableColumn( "Name" ) }; formatter.header( header ); - formatter.add( exportInfo.wellPath()->completions()->wellNameForExport() ); + formatter.add( exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() ); formatter.rowCompleted(); } @@ -592,13 +661,13 @@ void RicWellPathExportMswCompletionsImpl::generateCompsegHeader( RifTextDataTabl /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::generateWsegvalvTable( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo ) + RicMswExportInfo& exportInfo ) { bool foundValve = false; - for ( std::shared_ptr segment : exportInfo.segments() ) + for ( auto segment : exportInfo.mainBoreBranch()->segments() ) { - for ( std::shared_ptr completion : segment->completions() ) + for ( auto completion : segment->completions() ) { if ( RigCompletionData::isWsegValveTypes( completion->completionType() ) ) { @@ -616,23 +685,23 @@ void RicWellPathExportMswCompletionsImpl::generateWsegvalvTable( RifTextDataTabl foundValve = true; } - std::shared_ptr icd = std::static_pointer_cast( completion ); - if ( !icd->subSegments().empty() ) + auto wsegValve = static_cast( completion ); + if ( !wsegValve->segments().empty() ) { - CVF_ASSERT( icd->subSegments().size() == 1u ); + CVF_ASSERT( wsegValve->segments().size() == 1u ); - auto firstSubSegment = icd->subSegments().front(); + auto firstSubSegment = wsegValve->segments().front(); if ( !firstSubSegment->intersections().empty() ) { - if ( icd->completionType() == RigCompletionData::PERFORATION_ICD || - icd->completionType() == RigCompletionData::PERFORATION_ICV ) + if ( wsegValve->completionType() == RigCompletionData::PERFORATION_ICD || + wsegValve->completionType() == RigCompletionData::PERFORATION_ICV ) { - formatter.comment( icd->label() ); + formatter.comment( wsegValve->label() ); } - formatter.add( exportInfo.wellPath()->completions()->wellNameForExport() ); + formatter.add( exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() ); formatter.add( firstSubSegment->segmentNumber() ); - formatter.add( icd->flowCoefficient() ); - formatter.add( QString( "%1" ).arg( icd->area(), 8, 'g', 4 ) ); + formatter.add( wsegValve->flowCoefficient() ); + formatter.add( QString( "%1" ).arg( wsegValve->area(), 8, 'g', 4 ) ); formatter.rowCompleted(); } } @@ -649,7 +718,7 @@ void RicWellPathExportMswCompletionsImpl::generateWsegvalvTable( RifTextDataTabl /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo ) + RicMswExportInfo& exportInfo ) { RifTextDataTableFormatter tighterFormatter( formatter ); tighterFormatter.setColumnSpacing( 1 ); @@ -657,13 +726,13 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl bool foundValve = false; - for ( std::shared_ptr segment : exportInfo.segments() ) + for ( auto segment : exportInfo.mainBoreBranch()->segments() ) { - for ( std::shared_ptr completion : segment->completions() ) + for ( auto completion : segment->completions() ) { if ( completion->completionType() == RigCompletionData::PERFORATION_AICD ) { - std::shared_ptr aicd = std::static_pointer_cast( completion ); + auto aicd = static_cast( completion ); if ( aicd->isValid() ) { if ( !foundValve ) @@ -680,7 +749,7 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl "Emulsion viscosity transition region", "Max ratio of emulsion viscosity to continuous phase viscosity", "Flow scaling factor method", - "Maximum flowrate for AICD device", + "Maximum flow rate for AICD device", "Volume flow rate exponent, x", "Viscosity function exponent, y", "Device OPEN/SHUT", @@ -713,19 +782,20 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl foundValve = true; } - if ( !aicd->subSegments().empty() ) + if ( !aicd->segments().empty() ) { - CVF_ASSERT( aicd->subSegments().size() == 1u ); + CVF_ASSERT( aicd->segments().size() == 1u ); tighterFormatter.comment( aicd->label() ); - tighterFormatter.add( exportInfo.wellPath()->completions()->wellNameForExport() ); // #1 - tighterFormatter.add( aicd->subSegments().front()->segmentNumber() ); - tighterFormatter.add( aicd->subSegments().front()->segmentNumber() ); + tighterFormatter.add( + exportInfo.mainBoreBranch()->wellPath()->completionSettings()->wellNameForExport() ); // #1 + tighterFormatter.add( aicd->segments().front()->segmentNumber() ); + tighterFormatter.add( aicd->segments().front()->segmentNumber() ); std::array values = aicd->values(); tighterFormatter.add( values[AICD_STRENGTH] ); - tighterFormatter.add( aicd->flowScalingFactor() ); // #5 Flow scaling factor used when item #11 - // is set to '1' + tighterFormatter.add( aicd->flowScalingFactor() ); // #5 Flow scaling factor used when item + // #11 is set to '1' tighterFormatter.add( values[AICD_DENSITY_CALIB_FLUID] ); tighterFormatter.add( values[AICD_VISCOSITY_CALIB_FLUID] ); @@ -736,8 +806,8 @@ void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable( RifTextDataTabl tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_RATIO_EMULSION_VISC], RicMswExportInfo::defaultDoubleValue() ); // #10 - tighterFormatter.add( 1 ); // #11 : Always use method "b. Scale factor". The value of the scale - // factor is given in item #5 + tighterFormatter.add( 1 ); // #11 : Always use method "b. Scale factor". The value of the + // scale factor is given in item #5 tighterFormatter.addValueOrDefaultMarker( values[AICD_MAX_FLOW_RATE], RicMswExportInfo::defaultDoubleValue() ); @@ -825,52 +895,81 @@ std::pair RicWellPathExportMswCompletionsImpl::calculateOverlapW //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswExportInfo RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - bool enableSegmentSplitting ) +void RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( + const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + double initialMD, + const std::vector& cellIntersections, + bool enableSegmentSplitting, + gsl::not_null exportInfo, + gsl::not_null branch ) { - std::vector fishbonesSubs = wellPath->fishbonesCollection()->activeFishbonesSubs(); + std::vector fishbonesSubs = wellPath->fishbonesCollection()->activeFishbonesSubs(); - return generateFishbonesMswExportInfo( caseToApply, wellPath, fishbonesSubs, enableSegmentSplitting ); + generateFishbonesMswExportInfo( caseToApply, + wellPath, + initialMD, + cellIntersections, + fishbonesSubs, + enableSegmentSplitting, + exportInfo, + branch ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswExportInfo RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( - const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - const std::vector& fishbonesSubs, - bool enableSegmentSplitting ) +void RicWellPathExportMswCompletionsImpl::generateFishbonesMswExportInfo( + const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + double initialMD, + const std::vector& cellIntersections, + const std::vector& fishbonesSubs, + bool enableSegmentSplitting, + gsl::not_null exportInfo, + gsl::not_null branch ) { - RiaDefines::EclipseUnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType(); + std::vector filteredIntersections = + filterIntersections( cellIntersections, initialMD, wellPath->wellPathGeometry(), caseToApply ); - RicMswExportInfo exportInfo( wellPath, - unitSystem, - wellPath->fishbonesCollection()->startMD(), - wellPath->fishbonesCollection()->mswParameters()->lengthAndDepth().text(), - wellPath->fishbonesCollection()->mswParameters()->pressureDrop().text() ); - exportInfo.setLinerDiameter( wellPath->fishbonesCollection()->mswParameters()->linerDiameter( unitSystem ) ); - exportInfo.setRoughnessFactor( wellPath->fishbonesCollection()->mswParameters()->roughnessFactor( unitSystem ) ); + auto mswParameters = wellPath->completionSettings()->mswParameters(); - double maxSegmentLength = enableSegmentSplitting - ? wellPath->fishbonesCollection()->mswParameters()->maxSegmentLength() - : std::numeric_limits::infinity(); bool foundSubGridIntersections = false; - double subStartMD = wellPath->fishbonesCollection()->startMD(); - double subStartTVD = RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, subStartMD ); + // Create a dummy perforation interval + RimPerforationInterval perfInterval; + perfInterval.setStartAndEndMD( wellPath->fishbonesCollection()->startMD(), wellPath->fishbonesCollection()->endMD() ); - for ( RimFishbonesMultipleSubs* subs : fishbonesSubs ) + createWellPathSegments( branch, filteredIntersections, { &perfInterval }, wellPath, -1, caseToApply, &foundSubGridIntersections ); + + double maxSegmentLength = enableSegmentSplitting ? mswParameters->maxSegmentLength() + : std::numeric_limits::infinity(); + + double subStartMD = wellPath->fishbonesCollection()->startMD(); + double subStartTVD = RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( branch->wellPath(), subStartMD ); + + auto unitSystem = exportInfo->unitSystem(); + + for ( RimFishbones* subs : fishbonesSubs ) { - for ( auto& sub : subs->installedLateralIndices() ) + std::map> subAndLateralIndices; + for ( const auto& [subIndex, lateralIndex] : subs->installedLateralIndices() ) { - double subEndMD = subs->measuredDepth( sub.subIndex ); - double subEndTVD = RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, subEndMD ); + subAndLateralIndices[subIndex].push_back( lateralIndex ); + } + + for ( const auto& sub : subAndLateralIndices ) + { + double subEndMD = subs->measuredDepth( sub.first ); + double subEndTVD = RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( branch->wellPath(), subEndMD ); { - std::shared_ptr segment( - new RicMswSegment( subs->generatedName(), subStartMD, subEndMD, subStartTVD, subEndTVD, sub.subIndex ) ); + auto segment = std::make_unique( subs->generatedName(), + subStartMD, + subEndMD, + subStartTVD, + subEndTVD, + sub.first ); segment->setEffectiveDiameter( subs->effectiveDiameter( unitSystem ) ); segment->setHoleDiameter( subs->holeDiameter( unitSystem ) ); segment->setOpenHoleRoughnessFactor( subs->openHoleRoughnessFactor( unitSystem ) ); @@ -878,41 +977,79 @@ RicMswExportInfo RicWellPathExportMswCompletionsImpl::generateFishbonesMswExport segment->setSourcePdmObject( subs ); // Add completion for ICD - std::shared_ptr icdCompletion( new RicMswFishbonesICD( QString( "ICD" ), nullptr ) ); - std::shared_ptr icdSegment( - new RicMswSubSegment( subEndMD, subEndMD + 0.1, subEndTVD, subEndTVD ) ); + auto icdCompletion = + std::make_unique( QString( "ICD" ), wellPath, subEndMD, subEndTVD, nullptr ); + auto icdSegment = + std::make_unique( "ICD segment", subEndMD, subEndMD + 0.1, subEndTVD, subEndTVD, sub.first ); icdCompletion->setFlowCoefficient( subs->icdFlowCoefficient() ); double icdOrificeRadius = subs->icdOrificeDiameter( unitSystem ) / 2; icdCompletion->setArea( icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount() ); - icdCompletion->addSubSegment( icdSegment ); - segment->addCompletion( icdCompletion ); + icdCompletion->addSegment( std::move( icdSegment ) ); + segment->addCompletion( std::move( icdCompletion ) ); - for ( size_t lateralIndex : sub.lateralIndices ) + for ( auto lateralIndex : sub.second ) { QString label = QString( "Lateral %1" ).arg( lateralIndex ); - segment->addCompletion( std::make_shared( label, lateralIndex ) ); + segment->addCompletion( + std::make_unique( label, wellPath, subEndMD, subEndTVD, lateralIndex ) ); } assignFishbonesLateralIntersections( caseToApply, - wellPath, + branch->wellPath(), subs, - segment, + segment.get(), &foundSubGridIntersections, maxSegmentLength ); - exportInfo.addSegment( segment ); + exportInfo->mainBoreBranch()->addSegment( std::move( segment ) ); } subStartMD = subEndMD; subStartTVD = subEndTVD; } } - exportInfo.setHasSubGridIntersections( foundSubGridIntersections ); - exportInfo.sortSegments(); + exportInfo->setHasSubGridIntersections( exportInfo->hasSubGridIntersections() || foundSubGridIntersections ); + exportInfo->mainBoreBranch()->sortSegments(); - assignBranchNumbers( caseToApply, &exportInfo ); + if ( auto wellPathGroup = dynamic_cast( wellPath ); wellPathGroup != nullptr ) + { + auto initialChildMD = wellPathGroup->uniqueEndMD(); + auto initialChildTVD = tvdFromMeasuredDepth( wellPathGroup, initialMD ); + for ( auto childWellPath : wellPathGroup->childWellPaths() ) + { + auto childCellIntersections = generateCellSegments( caseToApply, childWellPath, &initialChildMD ); + auto childBranch = + std::make_unique( childWellPath->name(), childWellPath, initialChildMD, initialChildTVD ); - return exportInfo; + if ( wellPathGroup->outletValve() ) + { + childBranch = RicMswValve::createExportValve( QString( "%1 valve for %2" ) + .arg( wellPathGroup->outletValve()->componentLabel() ) + .arg( childWellPath->name() ), + childWellPath, + initialChildMD, + initialChildTVD, + wellPathGroup->outletValve() ); + auto dummySegment = std::make_unique< + RicMswSegment>( QString( "%1 segment" ).arg( wellPathGroup->outletValve()->componentLabel() ), + initialChildMD, + initialChildMD + 0.1, + initialChildTVD, + RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, + initialChildMD + 0.1 ) ); + childBranch->addSegment( std::move( dummySegment ) ); + } + + generateFishbonesMswExportInfo( caseToApply, + childWellPath, + initialChildMD, + childCellIntersections, + enableSegmentSplitting, + exportInfo, + childBranch.get() ); + branch->addChildBranch( std::move( childBranch ) ); + } + } } //-------------------------------------------------------------------------------------------------- @@ -952,15 +1089,16 @@ RicMswExportInfo coords, mds ); + auto mswParameters = wellPath->completionSettings()->mswParameters(); + double initialMD = 0.0; - if ( wellPath->fractureCollection()->mswParameters()->referenceMDType() == - RimMswCompletionParameters::MANUAL_REFERENCE_MD ) + if ( mswParameters->referenceMDType() == RimMswCompletionParameters::MANUAL_REFERENCE_MD ) { - initialMD = wellPath->fractureCollection()->mswParameters()->manualReferenceMD(); + initialMD = mswParameters->manualReferenceMD(); } else { - for ( WellPathCellIntersectionInfo intersection : intersections ) + for ( const WellPathCellIntersectionInfo& intersection : intersections ) { if ( activeCellInfo->isActive( intersection.globCellIndex ) ) { @@ -988,11 +1126,11 @@ RicMswExportInfo RicMswExportInfo exportInfo( wellPath, unitSystem, initialMD, - wellPath->fractureCollection()->mswParameters()->lengthAndDepth().text(), - wellPath->fractureCollection()->mswParameters()->pressureDrop().text() ); + mswParameters->lengthAndDepth().text(), + mswParameters->pressureDrop().text() ); - exportInfo.setLinerDiameter( wellPath->fractureCollection()->mswParameters()->linerDiameter( unitSystem ) ); - exportInfo.setRoughnessFactor( wellPath->fractureCollection()->mswParameters()->roughnessFactor( unitSystem ) ); + exportInfo.setLinerDiameter( mswParameters->linerDiameter( unitSystem ) ); + exportInfo.setRoughnessFactor( mswParameters->roughnessFactor( unitSystem ) ); bool foundSubGridIntersections = false; @@ -1012,9 +1150,11 @@ RicMswExportInfo size_t i = 0u, j = 0u, k = 0u; localGrid->ijkFromCellIndex( localGridIdx, &i, &j, &k ); - QString label = QString( "Main stem segment %1" ).arg( ++mainBoreSegment ); - std::shared_ptr segment( - new RicMswSegment( label, cellIntInfo.startMD, cellIntInfo.endMD, cellIntInfo.startTVD(), cellIntInfo.endTVD() ) ); + auto segment = std::make_unique( "Main stem segment", + cellIntInfo.startMD, + cellIntInfo.endMD, + cellIntInfo.startTVD(), + cellIntInfo.endTVD() ); // Check if fractures are to be assigned to current main bore segment for ( RimWellPathFracture* fracture : fractures ) @@ -1030,21 +1170,28 @@ RicMswExportInfo { std::vector completionData = RicExportFractureCompletionsImpl::generateCompdatValues( caseToApply, - wellPath->completions()->wellNameForExport(), + wellPath->completionSettings()->wellNameForExport(), wellPath->wellPathGeometry(), { fracture }, nullptr, nullptr ); - assignFractureCompletionsToCellSegment( caseToApply, fracture, completionData, segment, &foundSubGridIntersections ); + assignFractureCompletionsToCellSegment( caseToApply, + wellPath, + fracture, + completionData, + segment.get(), + &foundSubGridIntersections ); } } - exportInfo.addSegment( segment ); + exportInfo.mainBoreBranch()->addSegment( std::move( segment ) ); } exportInfo.setHasSubGridIntersections( foundSubGridIntersections ); - exportInfo.sortSegments(); - assignBranchNumbers( caseToApply, &exportInfo ); + exportInfo.mainBoreBranch()->sortSegments(); + + int branchNumber = 1; + assignBranchNumbersToBranch( caseToApply, &exportInfo, exportInfo.mainBoreBranch(), &branchNumber ); return exportInfo; } @@ -1052,71 +1199,129 @@ RicMswExportInfo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicMswExportInfo RicWellPathExportMswCompletionsImpl::generatePerforationsMswExportInfo( - RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - int timeStep, - const std::vector& perforationIntervals ) +bool RicWellPathExportMswCompletionsImpl::generatePerforationsMswExportInfo( + RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + int timeStep, + double initialMD, + const std::vector& cellIntersections, + gsl::not_null exportInfo, + gsl::not_null branch ) { - RiaDefines::EclipseUnitSystem unitSystem = eclipseCase->eclipseCaseData()->unitsType(); + auto perforationIntervals = wellPath->perforationIntervalCollection()->activePerforations(); + + // Check if there exist overlap between valves in a perforation interval + for ( const auto& perfInterval : perforationIntervals ) + { + for ( const auto& valve : perfInterval->valves() ) + { + for ( const auto& otherValve : perfInterval->valves() ) + { + if ( otherValve != valve ) + { + bool hasIntersection = + !( ( valve->endMD() < otherValve->startMD() ) || ( otherValve->endMD() < valve->startMD() ) ); + + if ( hasIntersection ) + { + RiaLogging::error( + QString( "Valve overlap detected for perforation interval : %1" ).arg( perfInterval->name() ) ); + + RiaLogging::error( "Name of valves" ); + RiaLogging::error( valve->name() ); + RiaLogging::error( otherValve->name() ); + + RiaLogging::error( "Failed to export well segments" ); + + return false; + } + } + } + } + } + + std::vector filteredIntersections = + filterIntersections( cellIntersections, initialMD, wellPath->wellPathGeometry(), eclipseCase ); + + auto mswParameters = wellPath->completionSettings()->mswParameters(); + + bool foundSubGridIntersections = false; + + createWellPathSegments( branch, + filteredIntersections, + perforationIntervals, + wellPath, + timeStep, + eclipseCase, + &foundSubGridIntersections ); + + createValveCompletions( branch, perforationIntervals, wellPath, exportInfo->unitSystem() ); const RigActiveCellInfo* activeCellInfo = eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ); - double initialMD = 0.0; // Start measured depth location to export MSW data for. Either based on first intersection - // with active grid, or user defined value. - - std::vector intersections = generateCellSegments( eclipseCase, wellPath, initialMD ); - std::vector filteredIntersections = - filterIntersections( intersections, initialMD, wellPath->wellPathGeometry(), eclipseCase ); - - RicMswExportInfo exportInfo( wellPath, - unitSystem, - initialMD, - wellPath->perforationIntervalCollection()->mswParameters()->lengthAndDepth().text(), - wellPath->perforationIntervalCollection()->mswParameters()->pressureDrop().text() ); - - exportInfo.setLinerDiameter( wellPath->perforationIntervalCollection()->mswParameters()->linerDiameter( unitSystem ) ); - exportInfo.setRoughnessFactor( - wellPath->perforationIntervalCollection()->mswParameters()->roughnessFactor( unitSystem ) ); - - bool foundSubGridIntersections = false; - - MainBoreSegments mainBoreSegments = createMainBoreSegmentsForPerforations( filteredIntersections, - perforationIntervals, - wellPath, - timeStep, - eclipseCase, - &foundSubGridIntersections ); - - createValveCompletions( mainBoreSegments, perforationIntervals, wellPath, unitSystem ); - assignValveContributionsToSuperICDsOrAICDs( mainBoreSegments, + assignValveContributionsToSuperICDsOrAICDs( branch, perforationIntervals, filteredIntersections, activeCellInfo, - unitSystem ); - moveIntersectionsToICVs( mainBoreSegments, perforationIntervals, unitSystem ); - moveIntersectionsToSuperICDsOrAICDs( mainBoreSegments ); + exportInfo->unitSystem() ); + moveIntersectionsToICVs( branch, perforationIntervals, exportInfo->unitSystem() ); + moveIntersectionsToSuperICDsOrAICDs( branch ); - for ( std::shared_ptr segment : mainBoreSegments ) + exportInfo->setHasSubGridIntersections( exportInfo->hasSubGridIntersections() || foundSubGridIntersections ); + branch->sortSegments(); + + if ( auto wellPathGroup = dynamic_cast( wellPath ); wellPathGroup != nullptr ) { - exportInfo.addSegment( segment ); + auto initialChildMD = wellPathGroup->uniqueEndMD(); + auto initialChildTVD = -wellPathGroup->wellPathGeometry()->interpolatedPointAlongWellPath( initialMD ).z(); + for ( auto childWellPath : wellPathGroup->childWellPaths() ) + { + auto childCellIntersections = generateCellSegments( eclipseCase, childWellPath, &initialChildMD ); + auto childBranch = + std::make_unique( childWellPath->name(), childWellPath, initialChildMD, initialChildTVD ); + + if ( wellPathGroup->outletValve() ) + { + childBranch = RicMswValve::createExportValve( QString( "%1 valve for %2" ) + .arg( wellPathGroup->outletValve()->componentLabel() ) + .arg( childWellPath->name() ), + childWellPath, + initialChildMD, + initialChildTVD, + wellPathGroup->outletValve() ); + auto dummySegment = std::make_unique< + RicMswSegment>( QString( "%1 segment" ).arg( wellPathGroup->outletValve()->componentLabel() ), + initialChildMD, + initialChildMD + 0.1, + initialChildTVD, + RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, + initialChildMD + 0.1 ) ); + childBranch->addSegment( std::move( dummySegment ) ); + } + + if ( generatePerforationsMswExportInfo( eclipseCase, + childWellPath, + timeStep, + initialChildMD, + childCellIntersections, + exportInfo, + childBranch.get() ) ) + { + branch->addChildBranch( std::move( childBranch ) ); + } + } } - - exportInfo.setHasSubGridIntersections( foundSubGridIntersections ); - exportInfo.sortSegments(); - assignBranchNumbers( eclipseCase, &exportInfo ); - - return exportInfo; + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector - RicWellPathExportMswCompletionsImpl::generateCellSegments( const RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - double& initialMD ) + RicWellPathExportMswCompletionsImpl::generateCellSegments( const RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + gsl::not_null initialMD ) { const RigActiveCellInfo* activeCellInfo = eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL ); @@ -1124,8 +1329,8 @@ std::vector auto wellPathGeometry = wellPath->wellPathGeometry(); CVF_ASSERT( wellPathGeometry ); - const std::vector& coords = wellPathGeometry->wellPathPoints(); - const std::vector& mds = wellPathGeometry->measuredDepths(); + const std::vector& coords = wellPathGeometry->uniqueWellPathPoints(); + const std::vector& mds = wellPathGeometry->uniqueMeasuredDepths(); CVF_ASSERT( !coords.empty() && !mds.empty() ); const RigMainGrid* mainGrid = eclipseCase->mainGrid(); @@ -1138,10 +1343,10 @@ std::vector std::vector continuousIntersections = RigWellPathIntersectionTools::buildContinuousIntersections( allIntersections, mainGrid ); - if ( wellPath->perforationIntervalCollection()->mswParameters()->referenceMDType() == + if ( wellPath->completionSettings()->mswParameters()->referenceMDType() == RimMswCompletionParameters::MANUAL_REFERENCE_MD ) { - initialMD = wellPath->perforationIntervalCollection()->mswParameters()->manualReferenceMD(); + *initialMD = wellPath->completionSettings()->mswParameters()->manualReferenceMD(); } else { @@ -1149,7 +1354,7 @@ std::vector { if ( activeCellInfo->isActive( intersection.globCellIndex ) ) { - initialMD = intersection.startMD; + *initialMD = intersection.startMD; break; } } @@ -1169,7 +1374,7 @@ std::vector // Initial MD is the lowest MD based on grid intersection and start of fracture completions // https://github.com/OPM/ResInsight/issues/6071 - initialMD = std::min( initialMD, startOfFirstCompletion ); + *initialMD = std::min( *initialMD, startOfFirstCompletion ); } return continuousIntersections; @@ -1262,17 +1467,15 @@ std::vector //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicWellPathExportMswCompletionsImpl::MainBoreSegments - RicWellPathExportMswCompletionsImpl::createMainBoreSegmentsForPerforations( - const std::vector& cellSegmentIntersections, - const std::vector& perforationIntervals, - const RimWellPath* wellPath, - int timeStep, - RimEclipseCase* eclipseCase, - bool* foundSubGridIntersections ) +void RicWellPathExportMswCompletionsImpl::createWellPathSegments( + gsl::not_null branch, + const std::vector& cellSegmentIntersections, + const std::vector& perforationIntervals, + const RimWellPath* wellPath, + int timeStep, + const RimEclipseCase* eclipseCase, + bool* foundSubGridIntersections ) { - MainBoreSegments mainBoreSegments; - // Intersections along the well path with grid geometry is handled by well log extraction tools. // The threshold in RigWellLogExtractionTools::isEqualDepth is currently set to 0.1m, and this // is a pretty large threshold based on the indicated threshold of 0.001m for MSW segments @@ -1284,12 +1487,11 @@ RicWellPathExportMswCompletionsImpl::MainBoreSegments if ( segmentLength > segmentLengthThreshold ) { - QString label = QString( "Main stem segment %1" ).arg( mainBoreSegments.size() + 2 ); - std::shared_ptr segment( new RicMswSegment( label, - cellIntInfo.startMD, - cellIntInfo.endMD, - cellIntInfo.startTVD(), - cellIntInfo.endTVD() ) ); + auto segment = std::make_unique( QString( "%1 segment" ).arg( branch->label() ), + cellIntInfo.startMD, + cellIntInfo.endMD, + cellIntInfo.startTVD(), + cellIntInfo.endTVD() ); for ( const RimPerforationInterval* interval : perforationIntervals ) { @@ -1298,19 +1500,22 @@ RicWellPathExportMswCompletionsImpl::MainBoreSegments double overlap = std::max( 0.0, overlapEnd - overlapStart ); if ( overlap > 0.0 ) { - std::shared_ptr intervalCompletion( new RicMswPerforation( interval->name() ) ); - std::vector completionData = + double overlapStartTVD = + -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath( overlapStart ).z(); + auto intervalCompletion = + std::make_unique( interval->name(), wellPath, overlapStart, overlapStartTVD ); + std::vector completionData = generatePerforationIntersections( wellPath, interval, timeStep, eclipseCase ); assignPerforationIntersections( completionData, - intervalCompletion, + intervalCompletion.get(), cellIntInfo, overlapStart, overlapEnd, foundSubGridIntersections ); - segment->addCompletion( intervalCompletion ); + segment->addCompletion( std::move( intervalCompletion ) ); } } - mainBoreSegments.push_back( segment ); + branch->addSegment( std::move( segment ) ); } else { @@ -1319,25 +1524,24 @@ RicWellPathExportMswCompletionsImpl::MainBoreSegments RiaLogging::info( text ); } } - return mainBoreSegments; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::createValveCompletions( - std::vector>& mainBoreSegments, + gsl::not_null branch, const std::vector& perforationIntervals, const RimWellPath* wellPath, RiaDefines::EclipseUnitSystem unitSystem ) { - for ( size_t nMainSegment = 0u; nMainSegment < mainBoreSegments.size(); ++nMainSegment ) + int nMainSegment = 0; + auto segments = branch->segments(); + for ( auto segment : segments ) { - std::shared_ptr segment = mainBoreSegments[nMainSegment]; - - std::shared_ptr ICV; - std::shared_ptr superICD; - std::shared_ptr superAICD; + std::unique_ptr ICV; + std::unique_ptr superICD; + std::unique_ptr superAICD; double totalICDOverlap = 0.0; double totalAICDOverlap = 0.0; @@ -1362,15 +1566,13 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( double overlapEnd = std::min( valveSegment.second, segment->endMD() ); double overlap = std::max( 0.0, overlapEnd - overlapStart ); - // "Dummy" values for the new branch created for the valve. - // Will be added to the main segments start MD, - double exportStartMD = 0.0; - double exportEndMD = 0.1; + double exportStartMD = valveMD; + double exportEndMD = valveMD + 0.1; double exportStartTVD = - RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, valveMD + exportStartMD ); + RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, exportStartMD ); double exportEndTVD = - RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, valveMD + exportEndMD ); + RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, exportEndMD ); double overlapStartTVD = RicWellPathExportMswCompletionsImpl::tvdFromMeasuredDepth( wellPath, overlapStart ); @@ -1383,31 +1585,52 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( { QString valveLabel = QString( "%1 #%2" ).arg( "Combined Valve for segment" ).arg( nMainSegment + 2 ); - auto subSegment = - std::make_shared( exportStartMD, exportEndMD, exportStartTVD, exportEndTVD ); + auto subSegment = std::make_unique( "Valve segment", + exportStartMD, + exportEndMD, + exportStartTVD, + exportEndTVD ); - superAICD = std::make_shared( valveLabel, valve ); - superAICD->addSubSegment( subSegment ); + superAICD = std::make_unique( valveLabel, + wellPath, + exportStartMD, + exportStartTVD, + valve ); + superAICD->addSegment( std::move( subSegment ) ); } else if ( valve->componentType() == RiaDefines::WellPathComponentType::ICD ) { QString valveLabel = QString( "%1 #%2" ).arg( "Combined Valve for segment" ).arg( nMainSegment + 2 ); - auto subSegment = - std::make_shared( exportStartMD, exportEndMD, exportStartTVD, exportEndTVD ); + auto subSegment = std::make_unique( "Valve segment", + exportStartMD, + exportEndMD, + exportStartTVD, + exportEndTVD ); - superICD = std::make_shared( valveLabel, valve ); - superICD->addSubSegment( subSegment ); + superICD = std::make_unique( valveLabel, + wellPath, + exportStartMD, + exportStartTVD, + valve ); + superICD->addSegment( std::move( subSegment ) ); } else if ( valve->componentType() == RiaDefines::WellPathComponentType::ICV ) { QString valveLabel = QString( "ICV %1 at segment #%2" ).arg( valve->name() ).arg( nMainSegment + 2 ); - auto subSegment = - std::make_shared( exportStartMD, exportEndMD, exportStartTVD, exportEndTVD ); + auto subSegment = std::make_unique( "Valve segment", + exportStartMD, + exportEndMD, + exportStartTVD, + exportEndTVD ); - ICV = std::make_shared( valveLabel, valve ); - ICV->addSubSegment( subSegment ); + ICV = std::make_unique( valveLabel, + wellPath, + exportStartMD, + exportStartTVD, + valve ); + ICV->addSegment( std::move( subSegment ) ); ICV->setFlowCoefficient( valve->flowCoefficient() ); double orificeRadius = valve->orificeDiameter( unitSystem ) / 2; ICV->setArea( orificeRadius * orificeRadius * cvf::PI_D ); @@ -1419,10 +1642,14 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( QString valveLabel = QString( "%1 #%2" ).arg( "Combined Valve for segment" ).arg( nMainSegment + 2 ); - auto subSegment = - std::make_shared( exportStartMD, exportEndMD, exportStartTVD, exportEndTVD ); - superICD = std::make_shared( valveLabel, valve ); - superICD->addSubSegment( subSegment ); + auto subSegment = std::make_unique( "Valve segment", + exportStartMD, + exportEndMD, + exportStartTVD, + exportEndTVD ); + superICD = + std::make_unique( valveLabel, wellPath, exportStartMD, exportStartTVD, valve ); + superICD->addSegment( std::move( subSegment ) ); } else if ( overlap > 0.0 && ( valve->componentType() == RiaDefines::WellPathComponentType::AICD && !superAICD ) ) @@ -1430,10 +1657,17 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( QString valveLabel = QString( "%1 #%2" ).arg( "Combined Valve for segment" ).arg( nMainSegment + 2 ); - auto subSegment = - std::make_shared( exportStartMD, exportEndMD, exportStartTVD, exportEndTVD ); - superAICD = std::make_shared( valveLabel, valve ); - superAICD->addSubSegment( subSegment ); + auto subSegment = std::make_unique( "Valve segment", + exportStartMD, + exportEndMD, + exportStartTVD, + exportEndTVD ); + superAICD = std::make_unique( valveLabel, + wellPath, + exportStartMD, + exportStartTVD, + valve ); + superAICD->addSegment( std::move( subSegment ) ); } if ( valve->componentType() == RiaDefines::WellPathComponentType::AICD ) @@ -1450,7 +1684,7 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( if ( ICV ) { - segment->addCompletion( ICV ); + segment->addCompletion( std::move( ICV ) ); } else { @@ -1458,14 +1692,15 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( { if ( totalAICDOverlap > totalICDOverlap ) { - segment->addCompletion( superAICD ); + segment->addCompletion( std::move( superAICD ) ); } else { - segment->addCompletion( superICD ); + segment->addCompletion( std::move( superICD ) ); } } } + nMainSegment++; } } @@ -1473,35 +1708,37 @@ void RicWellPathExportMswCompletionsImpl::createValveCompletions( /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrAICDs( - const std::vector>& mainBoreSegments, - const std::vector& perforationIntervals, - const std::vector& wellPathIntersections, - const RigActiveCellInfo* activeCellInfo, - RiaDefines::EclipseUnitSystem unitSystem ) + gsl::not_null branch, + const std::vector& perforationIntervals, + const std::vector& wellPathIntersections, + const RigActiveCellInfo* activeCellInfo, + RiaDefines::EclipseUnitSystem unitSystem ) { + typedef std::map> ValveContributionMap; + ValveContributionMap assignedRegularValves; - std::map, std::shared_ptr> accumulators; + std::map> accumulators; - for ( std::shared_ptr segment : mainBoreSegments ) + for ( auto segment : branch->segments() ) { - std::shared_ptr superValve; + RicMswValve* superValve = nullptr; for ( auto completion : segment->completions() ) { - std::shared_ptr valve = std::dynamic_pointer_cast( completion ); + auto valve = dynamic_cast( completion ); if ( valve ) { superValve = valve; break; } } - if ( std::dynamic_pointer_cast( superValve ) ) + if ( dynamic_cast( superValve ) ) { - accumulators[segment] = std::make_shared( superValve, unitSystem ); + accumulators[segment] = std::make_unique( superValve, unitSystem ); } - else if ( std::dynamic_pointer_cast( superValve ) ) + else if ( dynamic_cast( superValve ) ) { - accumulators[segment] = std::make_shared( superValve, unitSystem ); + accumulators[segment] = std::make_unique( superValve, unitSystem ); } } @@ -1517,7 +1754,7 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA { if ( !valve->isChecked() ) continue; - for ( std::shared_ptr segment : mainBoreSegments ) + for ( auto segment : branch->segments() ) { double intervalOverlapStart = std::max( interval->startMD(), segment->startMD() ); double intervalOverlapEnd = std::min( interval->endMD(), segment->endMD() ); @@ -1534,7 +1771,7 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA { if ( !valve->isChecked() ) continue; - for ( std::shared_ptr segment : mainBoreSegments ) + for ( auto segment : branch->segments() ) { double intervalOverlapStart = std::max( interval->startMD(), segment->startMD() ); double intervalOverlapEnd = std::min( interval->endMD(), segment->endMD() ); @@ -1559,7 +1796,7 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA } } - for ( auto accumulator : accumulators ) + for ( const auto& accumulator : accumulators ) { accumulator.second->applyToSuperValve(); } @@ -1584,17 +1821,17 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperICDsOrA /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::moveIntersectionsToICVs( - const std::vector>& mainBoreSegments, - const std::vector& perforationIntervals, - RiaDefines::EclipseUnitSystem unitSystem ) + gsl::not_null branch, + const std::vector& perforationIntervals, + RiaDefines::EclipseUnitSystem unitSystem ) { - std::map> icvCompletionMap; + std::map icvCompletionMap; - for ( std::shared_ptr segment : mainBoreSegments ) + for ( auto segment : branch->segments() ) { for ( auto completion : segment->completions() ) { - std::shared_ptr icv = std::dynamic_pointer_cast( completion ); + auto icv = dynamic_cast( completion ); if ( icv ) { icvCompletionMap[icv->wellPathValve()] = icv; @@ -1602,14 +1839,14 @@ void RicWellPathExportMswCompletionsImpl::moveIntersectionsToICVs( } } - for ( std::shared_ptr segment : mainBoreSegments ) + for ( auto segment : branch->segments() ) { - std::vector> perforations; - for ( auto completionPtr : segment->completions() ) + std::vector perforations; + for ( auto completion : segment->completions() ) { - if ( completionPtr->completionType() == RigCompletionData::PERFORATION ) + if ( completion->completionType() == RigCompletionData::PERFORATION ) { - perforations.push_back( completionPtr ); + perforations.push_back( completion ); } } @@ -1628,7 +1865,7 @@ void RicWellPathExportMswCompletionsImpl::moveIntersectionsToICVs( auto icvIt = icvCompletionMap.find( valve ); if ( icvIt == icvCompletionMap.end() ) continue; - std::shared_ptr icvCompletion = icvIt->second; + auto icvCompletion = icvIt->second; CVF_ASSERT( icvCompletion ); std::pair valveSegment = valve->valveSegments().front(); @@ -1638,14 +1875,14 @@ void RicWellPathExportMswCompletionsImpl::moveIntersectionsToICVs( if ( overlap > 0.0 ) { - CVF_ASSERT( icvCompletion->subSegments().size() == 1u ); + CVF_ASSERT( icvCompletion->segments().size() == 1u ); for ( auto perforationPtr : perforations ) { - for ( auto subSegmentPtr : perforationPtr->subSegments() ) + for ( auto subSegmentPtr : perforationPtr->segments() ) { for ( auto intersectionPtr : subSegmentPtr->intersections() ) { - icvCompletion->subSegments()[0]->addIntersection( intersectionPtr ); + icvCompletion->segments()[0]->addIntersection( intersectionPtr ); } } segment->removeCompletion( perforationPtr ); @@ -1659,44 +1896,41 @@ void RicWellPathExportMswCompletionsImpl::moveIntersectionsToICVs( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::writeMainBoreWelsegsSegment( std::shared_ptr segment, - std::shared_ptr previousSegment, - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - double maxSegmentLength, - int* segmentNumber ) +void RicWellPathExportMswCompletionsImpl::writeWelsegsSegment( RicMswSegment* segment, + const RicMswSegment* previousSegment, + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + double maxSegmentLength, + gsl::not_null branch, + int* segmentNumber ) { CVF_ASSERT( segment && segmentNumber ); double startMD = segment->startMD(); double endMD = segment->endMD(); - std::vector> subSegments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength ); + std::vector> segments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength ); - CVF_ASSERT( exportInfo.wellPath() ); - auto wellPathGeometry = exportInfo.wellPath()->wellPathGeometry(); + CVF_ASSERT( branch->wellPath() ); + auto wellPathGeometry = branch->wellPath()->wellPathGeometry(); CVF_ASSERT( wellPathGeometry ); - double prevOutMD = exportInfo.initialMD(); - double prevOutTVD = exportInfo.initialTVD(); + double prevOutMD = branch->startMD(); + double prevOutTVD = branch->startTVD(); if ( previousSegment ) { prevOutMD = previousSegment->outputMD(); prevOutTVD = previousSegment->outputTVD(); } - for ( const auto& [subStartMD, subEndMD] : subSegments ) + + auto outletSegment = previousSegment; + for ( const auto& [subStartMD, subEndMD] : segments ) { - auto startPoint = wellPathGeometry->interpolatedPointAlongWellPath( subStartMD ); - auto endPoint = wellPathGeometry->interpolatedPointAlongWellPath( subEndMD ); - - double subStartTVD = -startPoint.z(); - double subEndTVD = -endPoint.z(); - double depth = 0; double length = 0; double midPointMD = 0.5 * ( subStartMD + subEndMD ); - double midPointTVD = 0.5 * ( subStartTVD + subEndTVD ); + double midPointTVD = tvdFromMeasuredDepth( branch->wellPath(), midPointMD ); if ( exportInfo.lengthAndDepthText() == QString( "INC" ) ) { @@ -1710,62 +1944,67 @@ void RicWellPathExportMswCompletionsImpl::writeMainBoreWelsegsSegment( std::shar } segment->setOutputMD( midPointMD ); segment->setOutputTVD( midPointTVD ); + segment->setSegmentNumber( *segmentNumber ); formatter.add( *segmentNumber ).add( *segmentNumber ); - formatter.add( 1 ); // All segments on main stem are branch 1 - formatter.add( *segmentNumber - 1 ); // All main stem segments are connected to the segment below - // them + formatter.add( branch->branchNumber() ); + if ( outletSegment ) + formatter.add( outletSegment->segmentNumber() ); + else + formatter.add( 1 ); formatter.add( length ); formatter.add( depth ); formatter.add( exportInfo.linerDiameter() ); formatter.add( exportInfo.roughnessFactor() ); formatter.rowCompleted(); ( *segmentNumber )++; + outletSegment = segment; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::writeValveWelsegsSegment( std::shared_ptr segment, - std::shared_ptr valve, - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - double maxSegmentLength, - int* segmentNumber ) +void RicWellPathExportMswCompletionsImpl::writeValveWelsegsSegment( const RicMswSegment* outletSegment, + RicMswValve* valve, + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + double maxSegmentLength, + int* segmentNumber ) { CVF_ASSERT( valve ); if ( !valve->isValid() ) return; + CVF_ASSERT( !valve->label().isEmpty() ); + CVF_ASSERT( valve->wellPath() ); + formatter.comment( valve->label() ); - auto subSegment = valve->subSegments().front(); + auto segments = valve->segments(); + + auto subSegment = segments.front(); subSegment->setSegmentNumber( *segmentNumber ); double startMD = subSegment->startMD(); double endMD = subSegment->endMD(); - if ( valve->completionType() != RigCompletionData::FISHBONES_ICD ) - { - startMD += segment->outputMD(); - endMD += segment->outputMD(); - } + double midPointMD = 0.5 * ( startMD + endMD ); + double midPointTVD = tvdFromMeasuredDepth( valve->wellPath(), midPointMD ); + + subSegment->setOutputMD( midPointMD ); + subSegment->setOutputTVD( midPointTVD ); std::vector> splitSegments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength ); - CVF_ASSERT( exportInfo.wellPath() ); - auto wellPathGeometry = exportInfo.wellPath()->wellPathGeometry(); + auto wellPathGeometry = valve->wellPath()->wellPathGeometry(); CVF_ASSERT( wellPathGeometry ); for ( const auto& [subStartMD, subEndMD] : splitSegments ) { int subSegmentNumber = ( *segmentNumber )++; - auto startPoint = wellPathGeometry->interpolatedPointAlongWellPath( subStartMD ); - auto endPoint = wellPathGeometry->interpolatedPointAlongWellPath( subEndMD ); - - double subStartTVD = -startPoint.z(); - double subEndTVD = -endPoint.z(); + double subStartTVD = tvdFromMeasuredDepth( valve->wellPath(), subStartMD ); + double subEndTVD = tvdFromMeasuredDepth( valve->wellPath(), subEndMD ); double depth = 0; double length = 0; @@ -1780,10 +2019,11 @@ void RicWellPathExportMswCompletionsImpl::writeValveWelsegsSegment( std::shared_ depth = subEndTVD; length = subEndMD; } + formatter.add( subSegmentNumber ); formatter.add( subSegmentNumber ); formatter.add( valve->branchNumber() ); - formatter.add( segment->segmentNumber() ); + formatter.add( outletSegment->segmentNumber() ); formatter.add( length ); formatter.add( depth ); @@ -1796,31 +2036,33 @@ void RicWellPathExportMswCompletionsImpl::writeValveWelsegsSegment( std::shared_ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::writeCompletionWelsegsSegment( std::shared_ptr segment, - std::shared_ptr completion, - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - double maxSegmentLength, - int* segmentNumber ) +void RicWellPathExportMswCompletionsImpl::writeCompletionWelsegsSegments( gsl::not_null outletSegment, + gsl::not_null completion, + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + double maxSegmentLength, + int* segmentNumber ) { + writeWelsegsCompletionCommentHeader( formatter, completion->completionType() ); + if ( completion->completionType() == RigCompletionData::FISHBONES ) { - formatter.comment( - QString( "%1 : Sub index %2 - %3" ).arg( segment->label() ).arg( segment->subIndex() ).arg( completion->label() ) ); + formatter.comment( QString( "Sub index %1 - %2" ).arg( outletSegment->subIndex() ).arg( completion->label() ) ); } else if ( completion->completionType() == RigCompletionData::FRACTURE ) { - formatter.comment( QString( "%1 connected to %2" ).arg( completion->label() ).arg( segment->label() ) ); + formatter.comment( + QString( "%1 connected to segment %2" ).arg( completion->label() ).arg( outletSegment->segmentNumber() ) ); } - CVF_ASSERT( exportInfo.wellPath() ); - auto wellPathGeometry = exportInfo.wellPath()->wellPathGeometry(); - CVF_ASSERT( wellPathGeometry ); + CVF_ASSERT( completion->wellPath() ); - for ( std::shared_ptr subSegment : completion->subSegments() ) + int outletSegmentNumber = outletSegment->segmentNumber(); + + for ( auto segment : completion->segments() ) { - double startMD = subSegment->startMD(); - double endMD = subSegment->endMD(); + double startMD = segment->startMD(); + double endMD = segment->endMD(); std::vector> splitSegments = createSubSegmentMDPairs( startMD, endMD, maxSegmentLength ); @@ -1828,11 +2070,8 @@ void RicWellPathExportMswCompletionsImpl::writeCompletionWelsegsSegment( std::sh { int subSegmentNumber = ( *segmentNumber )++; - auto startPoint = wellPathGeometry->interpolatedPointAlongWellPath( subStartMD ); - auto endPoint = wellPathGeometry->interpolatedPointAlongWellPath( subEndMD ); - - double subStartTVD = -startPoint.z(); - double subEndTVD = -endPoint.z(); + double subStartTVD = tvdFromMeasuredDepth( completion->wellPath(), subStartMD ); + double subEndTVD = tvdFromMeasuredDepth( completion->wellPath(), subEndMD ); double depth = 0; double length = 0; @@ -1847,16 +2086,16 @@ void RicWellPathExportMswCompletionsImpl::writeCompletionWelsegsSegment( std::sh depth = subEndTVD; length = subEndMD; } - double diameter = segment->effectiveDiameter(); formatter.add( subSegmentNumber ); formatter.add( subSegmentNumber ); formatter.add( completion->branchNumber() ); - formatter.add( segment->segmentNumber() ); + formatter.add( outletSegmentNumber ); formatter.add( length ); formatter.add( depth ); - formatter.add( diameter ); - formatter.add( segment->openHoleRoughnessFactor() ); + formatter.add( outletSegment->effectiveDiameter() ); + formatter.add( outletSegment->openHoleRoughnessFactor() ); formatter.rowCompleted(); + outletSegmentNumber = subSegmentNumber; } } } @@ -1864,40 +2103,43 @@ void RicWellPathExportMswCompletionsImpl::writeCompletionWelsegsSegment( std::sh //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::moveIntersectionsToSuperICDsOrAICDs( MainBoreSegments mainBoreSegments ) +void RicWellPathExportMswCompletionsImpl::moveIntersectionsToSuperICDsOrAICDs( gsl::not_null branch ) { - for ( auto segmentPtr : mainBoreSegments ) + for ( auto segment : branch->segments() ) { - std::shared_ptr superValve; - std::vector> perforations; - for ( auto completionPtr : segmentPtr->completions() ) + RicMswCompletion* superValve = nullptr; + std::vector perforations; + for ( auto completion : segment->completions() ) { - if ( RigCompletionData::isPerforationValve( completionPtr->completionType() ) ) + if ( RigCompletionData::isPerforationValve( completion->completionType() ) ) { - superValve = completionPtr; + superValve = completion; } else { - CVF_ASSERT( completionPtr->completionType() == RigCompletionData::PERFORATION ); - perforations.push_back( completionPtr ); + CVF_ASSERT( completion->completionType() == RigCompletionData::PERFORATION ); + perforations.push_back( completion ); } } if ( superValve == nullptr ) continue; - CVF_ASSERT( superValve->subSegments().size() == 1u ); - segmentPtr->completions().clear(); - segmentPtr->addCompletion( superValve ); - for ( auto perforationPtr : perforations ) + CVF_ASSERT( superValve->segments().size() == 1u ); + // Remove and take over ownership of the superValve completion + auto completionPtr = segment->removeCompletion( superValve ); + for ( auto perforation : perforations ) { - for ( auto subSegmentPtr : perforationPtr->subSegments() ) + for ( auto subSegment : perforation->segments() ) { - for ( auto intersectionPtr : subSegmentPtr->intersections() ) + for ( auto intersectionPtr : subSegment->intersections() ) { - superValve->subSegments()[0]->addIntersection( intersectionPtr ); + completionPtr->segments()[0]->addIntersection( intersectionPtr ); } } } + // Remove all completions and re-add the super valve + segment->completions().clear(); + segment->addCompletion( std::move( completionPtr ) ); } } @@ -1906,8 +2148,8 @@ void RicWellPathExportMswCompletionsImpl::moveIntersectionsToSuperICDsOrAICDs( M //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::assignFishbonesLateralIntersections( const RimEclipseCase* caseToApply, const RimWellPath* wellPath, - const RimFishbonesMultipleSubs* fishbonesSubs, - std::shared_ptr segment, + const RimFishbones* fishbonesSubs, + gsl::not_null segment, bool* foundSubGridIntersections, double maxSegmentLength ) { @@ -1915,7 +2157,7 @@ void RicWellPathExportMswCompletionsImpl::assignFishbonesLateralIntersections( c const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid(); - for ( std::shared_ptr completion : segment->completions() ) + for ( auto completion : segment->completions() ) { if ( completion->completionType() != RigCompletionData::FISHBONES ) { @@ -1967,16 +2209,18 @@ void RicWellPathExportMswCompletionsImpl::assignFishbonesLateralIntersections( c size_t i = 0u, j = 0u, k = 0u; localGrid->ijkFromCellIndex( localGridIdx, &i, &j, &k ); - std::shared_ptr subSegment( - new RicMswSubSegment( previousExitMD, cellIntInfo.endMD, previousExitTVD, cellIntInfo.endTVD() ) ); + auto subSegment = std::make_unique( "Sub segment", + previousExitMD, + cellIntInfo.endMD, + previousExitTVD, + cellIntInfo.endTVD() ); - std::shared_ptr intersection( - new RicMswSubSegmentCellIntersection( gridName, - cellIntInfo.globCellIndex, - cvf::Vec3st( i, j, k ), - cellIntInfo.intersectionLengthsInCellCS ) ); - subSegment->addIntersection( intersection ); - completion->addSubSegment( subSegment ); + auto intersection = std::make_shared( gridName, + cellIntInfo.globCellIndex, + cvf::Vec3st( i, j, k ), + cellIntInfo.intersectionLengthsInCellCS ); + subSegment->addIntersection( std::move( intersection ) ); + completion->addSegment( std::move( subSegment ) ); previousExitMD = cellIntInfo.endMD; previousExitTVD = cellIntInfo.endTVD(); @@ -1988,16 +2232,18 @@ void RicWellPathExportMswCompletionsImpl::assignFishbonesLateralIntersections( c /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::assignFractureCompletionsToCellSegment( const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, const RimWellPathFracture* fracture, const std::vector& completionData, - std::shared_ptr segment, + gsl::not_null segment, bool* foundSubGridIntersections ) { CVF_ASSERT( foundSubGridIntersections != nullptr ); - std::shared_ptr fractureCompletion( new RicMswFracture( fracture->name() ) ); - double position = fracture->fractureMD(); - double width = fracture->fractureTemplate()->computeFractureWidth( fracture ); + double position = fracture->fractureMD(); + double width = fracture->fractureTemplate()->computeFractureWidth( fracture ); + + auto fractureCompletion = std::make_unique( fracture->name(), wellPath, position, position + width ); if ( fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH ) { @@ -2006,18 +2252,20 @@ void RicWellPathExportMswCompletionsImpl::assignFractureCompletionsToCellSegment width = perforationLength; } - std::shared_ptr subSegment( new RicMswSubSegment( position, position + width, 0.0, 0.0 ) ); + auto subSegment = std::make_unique( "Fracture segment", position, position + width, 0.0, 0.0 ); for ( const RigCompletionData& compIntersection : completionData ) { const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); cvf::Vec3st localIJK( cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK() ); - std::shared_ptr intersection( - new RicMswSubSegmentCellIntersection( cell.lgrName(), cell.globalCellIndex(), localIJK, cvf::Vec3d::ZERO ) ); + auto intersection = std::make_shared( cell.lgrName(), + cell.globalCellIndex(), + localIJK, + cvf::Vec3d::ZERO ); subSegment->addIntersection( intersection ); } - fractureCompletion->addSubSegment( subSegment ); - segment->addCompletion( fractureCompletion ); + fractureCompletion->addSegment( std::move( subSegment ) ); + segment->addCompletion( std::move( fractureCompletion ) ); } //-------------------------------------------------------------------------------------------------- @@ -2027,7 +2275,7 @@ std::vector RicWellPathExportMswCompletionsImpl::generatePerf gsl::not_null wellPath, gsl::not_null perforationInterval, int timeStep, - gsl::not_null eclipseCase ) + gsl::not_null eclipseCase ) { std::vector completionData; const RigActiveCellInfo* activeCellInfo = @@ -2054,7 +2302,7 @@ std::vector RicWellPathExportMswCompletionsImpl::generatePerf bool cellIsActive = activeCellInfo->isActive( cell.globCellIndex ); if ( !cellIsActive ) continue; - RigCompletionData completion( wellPath->completions()->wellNameForExport(), + RigCompletionData completion( wellPath->completionSettings()->wellNameForExport(), RigCompletionDataGridCell( cell.globCellIndex, eclipseCase->mainGrid() ), cell.startMD ); @@ -2071,7 +2319,7 @@ std::vector RicWellPathExportMswCompletionsImpl::generatePerf //-------------------------------------------------------------------------------------------------- void RicWellPathExportMswCompletionsImpl::assignPerforationIntersections( const std::vector& completionData, - std::shared_ptr perforationCompletion, + gsl::not_null perforationCompletion, const WellPathCellIntersectionInfo& cellIntInfo, double overlapStart, double overlapEnd, @@ -2079,8 +2327,11 @@ void RicWellPathExportMswCompletionsImpl::assignPerforationIntersections( { size_t currCellId = cellIntInfo.globCellIndex; - std::shared_ptr subSegment( - new RicMswSubSegment( overlapStart, overlapEnd, cellIntInfo.startTVD(), cellIntInfo.endTVD() ) ); + auto subSegment = std::make_unique( "Perforation segment", + overlapStart, + overlapEnd, + cellIntInfo.startTVD(), + cellIntInfo.endTVD() ); for ( const RigCompletionData& compIntersection : completionData ) { const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); @@ -2093,33 +2344,27 @@ void RicWellPathExportMswCompletionsImpl::assignPerforationIntersections( cvf::Vec3st localIJK( cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK() ); - std::shared_ptr intersection( - new RicMswSubSegmentCellIntersection( cell.lgrName(), - cell.globalCellIndex(), - localIJK, - cellIntInfo.intersectionLengthsInCellCS ) ); + auto intersection = std::make_shared( cell.lgrName(), + cell.globalCellIndex(), + localIJK, + cellIntInfo.intersectionLengthsInCellCS ); subSegment->addIntersection( intersection ); } - perforationCompletion->addSubSegment( subSegment ); + perforationCompletion->addSegment( std::move( subSegment ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::assignBranchNumbers( const RimEclipseCase* caseToApply, - std::shared_ptr segment, - int* branchNum ) +void RicWellPathExportMswCompletionsImpl::assignBranchNumbersToPerforations( const RimEclipseCase* caseToApply, + gsl::not_null segment, + gsl::not_null branchNumber ) { - for ( std::shared_ptr completion : segment->completions() ) + for ( auto completion : segment->completions() ) { if ( completion->completionType() == RigCompletionData::PERFORATION ) { - completion->setBranchNumber( 1 ); - } - else if ( completion->completionType() != RigCompletionData::FISHBONES_ICD ) - { - ++( *branchNum ); - completion->setBranchNumber( *branchNum ); + completion->setBranchNumber( *branchNumber ); } } } @@ -2127,27 +2372,46 @@ void RicWellPathExportMswCompletionsImpl::assignBranchNumbers( const RimEclipseC //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportMswCompletionsImpl::assignBranchNumbers( const RimEclipseCase* caseToApply, - RicMswExportInfo* exportInfo ) +void RicWellPathExportMswCompletionsImpl::assignBranchNumbersToOtherCompletions( const RimEclipseCase* caseToApply, + gsl::not_null segment, + gsl::not_null branchNumber ) { - int branchNumber = 1; - - // First loop over the segments so that each segment on the main stem is an incremental number - for ( auto segment : exportInfo->segments() ) + for ( auto completion : segment->completions() ) { - for ( auto completion : segment->completions() ) + if ( completion->completionType() != RigCompletionData::PERFORATION ) { - if ( completion->completionType() == RigCompletionData::FISHBONES_ICD ) - { - completion->setBranchNumber( ++branchNumber ); - } + completion->setBranchNumber( ++( *branchNumber ) ); } } +} - // Then assign branch numbers to each completion sub segment - for ( auto segment : exportInfo->segments() ) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportMswCompletionsImpl::assignBranchNumbersToBranch( const RimEclipseCase* caseToApply, + RicMswExportInfo* exportInfo, + gsl::not_null branch, + gsl::not_null branchNumber ) +{ + branch->setBranchNumber( *branchNumber ); + + // Assign perforations first to ensure the same branch number as the segment + for ( auto segment : branch->segments() ) { - assignBranchNumbers( caseToApply, segment, &branchNumber ); + assignBranchNumbersToPerforations( caseToApply, segment, branchNumber ); + } + + // Assign other completions with an incremented branch number + for ( auto segment : branch->segments() ) + { + assignBranchNumbersToOtherCompletions( caseToApply, segment, branchNumber ); + } + + ( *branchNumber )++; + + for ( auto childBranch : branch->branches() ) + { + assignBranchNumbersToBranch( caseToApply, exportInfo, childBranch, branchNumber ); } } diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h index c0eaad9cd7..a5c5ea8218 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportMswCompletionsImpl.h @@ -17,16 +17,21 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "RicMswBranch.h" +#include "RicMswCompletions.h" #include "RicMswExportInfo.h" +#include "RicMswSegment.h" #include "RigCompletionData.h" #include +#include + class RicExportCompletionDataSettingsUi; class RifTextDataTableFormatter; class RigActiveCellInfo; class RimEclipseCase; -class RimFishbonesMultipleSubs; +class RimFishbones; class RimPerforationInterval; class RimWellPath; class RimWellPathValve; @@ -40,6 +45,24 @@ class QFile; class RicWellPathExportMswCompletionsImpl { +private: + class CvfVec3stComparator + { + public: + bool operator()( const cvf::Vec3st& lhs, const cvf::Vec3st& rhs ) const + { + if ( lhs.z() == rhs.z() ) + { + if ( lhs.y() == rhs.y() ) + { + return lhs.x() < rhs.x(); + } + return lhs.y() < rhs.y(); + } + return lhs.z() < rhs.z(); + } + }; + public: static void exportWellSegmentsForAllCompletions( const RicExportCompletionDataSettingsUi& exportSettings, const std::vector& wellPaths ); @@ -57,15 +80,23 @@ public: const RimWellPath* wellPath, int timeStep ); - static RicMswExportInfo generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - bool enableSegmentSplitting ); + static void generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + double initialMD, + const std::vector& cellIntersections, + bool enableSegmentSplitting, + gsl::not_null exportInfo, + gsl::not_null branch ); private: - static RicMswExportInfo generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - const std::vector& fishbonesSubs, - bool enableSegmentSplitting ); + static void generateFishbonesMswExportInfo( const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + double initialMD, + const std::vector& cellIntersections, + const std::vector& fishbonesSubs, + bool enableSegmentSplitting, + gsl::not_null exportInfo, + gsl::not_null branch ); static RicMswExportInfo generateFracturesMswExportInfo( RimEclipseCase* caseToApply, const RimWellPath* wellPath ); @@ -73,14 +104,17 @@ private: const RimWellPath* wellPath, const std::vector& fractures ); - static RicMswExportInfo - generatePerforationsMswExportInfo( RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - int timeStep, - const std::vector& perforationIntervals ); + static bool generatePerforationsMswExportInfo( RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + int timeStep, + double initialMD, + const std::vector& cellIntersections, + gsl::not_null exportInfo, + gsl::not_null branch ); - static std::vector - generateCellSegments( const RimEclipseCase* eclipseCase, const RimWellPath* wellPath, double& initialMD ); + static std::vector generateCellSegments( const RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + gsl::not_null initialMD ); static std::vector filterIntersections( const std::vector& intersections, @@ -89,46 +123,52 @@ private: gsl::not_null eclipseCase ); static void generateWelsegsTable( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, + RicMswExportInfo& exportInfo, double maxSegmentLength ); - static void writeMainBoreWelsegsSegment( std::shared_ptr segment, - std::shared_ptr previousSegment, - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - double maxSegmentLength, - int* segmentNumber ); - static void writeValveWelsegsSegment( std::shared_ptr segment, - std::shared_ptr valve, - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - double maxSegmentLength, - int* segmentNumber ); - static void writeCompletionWelsegsSegment( std::shared_ptr segment, - std::shared_ptr completion, - RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - double maxSegmentLength, - int* segmentNumber ); + static void writeWelsegsSegmentsRecursively( RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + gsl::not_null branch, + gsl::not_null segmentNumber, + double maxSegmentLength, + RicMswSegment* connectedToSegment = nullptr ); - static void generateWelsegsSegments( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, - const std::set& exportCompletionTypes, - double maxSegmentLength, - int* segmentNumber ); - static void generateWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter, - RigCompletionData::CompletionType completionType ); - static void generateCompsegTables( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo ); + static void writeWelsegsSegment( RicMswSegment* segment, + const RicMswSegment* previousSegment, + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + double maxSegmentLength, + gsl::not_null branch, + int* segmentNumber ); + static void writeValveWelsegsSegment( const RicMswSegment* outletSegment, + RicMswValve* valve, + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + double maxSegmentLength, + int* segmentNumber ); + static void writeCompletionWelsegsSegments( gsl::not_null outletSegment, + gsl::not_null completion, + RifTextDataTableFormatter& formatter, + RicMswExportInfo& exportInfo, + double maxSegmentLength, + int* segmentNumber ); + + static void writeWelsegsCompletionCommentHeader( RifTextDataTableFormatter& formatter, + RigCompletionData::CompletionType completionType ); + static void generateCompsegTables( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo ); static void generateCompsegTable( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, + RicMswExportInfo& exportInfo, + gsl::not_null branch, bool exportSubGridIntersections, - const std::set& exportCompletionTypes ); + const std::set& exportCompletionTypes, + gsl::not_null headerGenerated, + gsl::not_null*> intersectedCells ); static void generateCompsegHeader( RifTextDataTableFormatter& formatter, - const RicMswExportInfo& exportInfo, + RicMswExportInfo& exportInfo, RigCompletionData::CompletionType completionType, bool exportSubGridIntersections ); - static void generateWsegvalvTable( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo ); - static void generateWsegAicdTable( RifTextDataTableFormatter& formatter, const RicMswExportInfo& exportInfo ); + static void generateWsegvalvTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo ); + static void generateWsegAicdTable( RifTextDataTableFormatter& formatter, RicMswExportInfo& exportInfo ); static std::pair calculateOverlapWithActiveCells( double startMD, @@ -137,67 +177,73 @@ private: const RigActiveCellInfo* activeCellInfo ); private: - typedef std::vector> MainBoreSegments; - typedef std::map, std::vector> ValveContributionMap; - static std::vector> createSubSegmentMDPairs( double startMD, double endMD, double maxSegmentLength ); - static MainBoreSegments - createMainBoreSegmentsForPerforations( const std::vector& cellSegmentIntersections, - const std::vector& perforationIntervals, - const RimWellPath* wellPath, - int timeStep, - RimEclipseCase* eclipseCase, - bool* foundSubGridIntersections ); + static void createWellPathSegments( gsl::not_null branch, + const std::vector& cellSegmentIntersections, + const std::vector& perforationIntervals, + const RimWellPath* wellPath, + int timeStep, + const RimEclipseCase* eclipseCase, + bool* foundSubGridIntersections ); - static void createValveCompletions( std::vector>& mainBoreSegments, + static void createValveCompletions( gsl::not_null branch, const std::vector& perforationIntervals, const RimWellPath* wellPath, RiaDefines::EclipseUnitSystem unitSystem ); static void - assignValveContributionsToSuperICDsOrAICDs( const std::vector>& mainBoreSegments, + assignValveContributionsToSuperICDsOrAICDs( gsl::not_null branch, const std::vector& perforationIntervals, const std::vector& wellPathIntersections, const RigActiveCellInfo* activeCellInfo, RiaDefines::EclipseUnitSystem unitSystem ); - static void moveIntersectionsToICVs( const std::vector>& mainBoreSegments, - const std::vector& perforationIntervals, - RiaDefines::EclipseUnitSystem unitSystem ); + static void moveIntersectionsToICVs( gsl::not_null branch, + const std::vector& perforationIntervals, + RiaDefines::EclipseUnitSystem unitSystem ); - static void moveIntersectionsToSuperICDsOrAICDs( MainBoreSegments mainBoreSegments ); + static void moveIntersectionsToSuperICDsOrAICDs( gsl::not_null branch ); - static void assignFishbonesLateralIntersections( const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - const RimFishbonesMultipleSubs* fishbonesSubs, - std::shared_ptr segment, - bool* foundSubGridIntersections, - double maxSegmentLength ); + static void assignFishbonesLateralIntersections( const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + const RimFishbones* fishbonesSubs, + gsl::not_null segment, + bool* foundSubGridIntersections, + double maxSegmentLength ); static void assignFractureCompletionsToCellSegment( const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, const RimWellPathFracture* fracture, const std::vector& completionData, - std::shared_ptr segment, + gsl::not_null segment, bool* foundSubGridIntersections ); static std::vector generatePerforationIntersections( gsl::not_null wellPath, gsl::not_null perforationInterval, int timeStep, - gsl::not_null eclipseCase ); + gsl::not_null eclipseCase ); static void assignPerforationIntersections( const std::vector& completionData, - std::shared_ptr perforationCompletion, + gsl::not_null perforationCompletion, const WellPathCellIntersectionInfo& cellIntInfo, double overlapStart, double overlapEnd, bool* foundSubGridIntersections ); - static void - assignBranchNumbers( const RimEclipseCase* caseToApply, std::shared_ptr segment, int* branchNum ); - static void assignBranchNumbers( const RimEclipseCase* caseToApply, RicMswExportInfo* exportInfo ); + static void assignBranchNumbersToPerforations( const RimEclipseCase* caseToApply, + gsl::not_null segment, + gsl::not_null branchNumber ); + static void assignBranchNumbersToOtherCompletions( const RimEclipseCase* caseToApply, + gsl::not_null segment, + gsl::not_null branchNumber ); + + static void assignBranchNumbersToBranch( const RimEclipseCase* caseToApply, + RicMswExportInfo* exportInfo, + gsl::not_null branch, + gsl::not_null branchNumber ); static double tvdFromMeasuredDepth( gsl::not_null wellPath, double measuredDepth ); }; diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp index bb7487c86a..46148ff1b7 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp @@ -253,7 +253,7 @@ QString RicWellPathFractureTextReportFeatureImpl::createWellFileLocationText( co auto fileWellPath = dynamic_cast( wellPath ); if ( fileWellPath ) { - formatter.add( wellPath->completions()->wellNameForExport() ); + formatter.add( wellPath->completionSettings()->wellNameForExport() ); formatter.add( fileWellPath->filePath() ); formatter.rowCompleted(); } @@ -564,7 +564,7 @@ QString RicWellPathFractureTextReportFeatureImpl::createFractureInstancesText( fracture->firstAncestorOrThisOfType( wellPath ); if ( wellPath ) { - wellName = wellPath->completions()->wellNameForExport(); + wellName = wellPath->completionSettings()->wellNameForExport(); } formatter.add( wellName ); diff --git a/ApplicationLibCode/Commands/ExportCommands/RicExportLgrFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicExportLgrFeature.cpp index 43f76b32b2..df36daf86c 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicExportLgrFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicExportLgrFeature.cpp @@ -48,7 +48,7 @@ #include "RiuPlotMainWindow.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimPerforationInterval.h" #include "RimWellPathFracture.h" @@ -236,7 +236,7 @@ QString completionName( const caf::PdmObject* object ) { auto perf = dynamic_cast( object ); auto frac = dynamic_cast( object ); - auto fish = dynamic_cast( object ); + auto fish = dynamic_cast( object ); QString name; if ( perf ) diff --git a/ApplicationLibCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp b/ApplicationLibCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp index 7c78de27d8..ac51333d63 100644 --- a/ApplicationLibCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp +++ b/ApplicationLibCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp @@ -118,7 +118,7 @@ void RicNewWellPathFractureFeature::onActionTriggered( bool isChecked ) RimWellPath* wellPath = nullptr; fractureColl->firstAncestorOrThisOfTypeAsserted( wellPath ); - double defaultMeasuredDepth = 0.0f; + double defaultMeasuredDepth = wellPath->uniqueStartMD(); RicNewWellPathFractureFeature::addFracture( wellPath, defaultMeasuredDepth ); } diff --git a/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.cpp b/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.cpp index fab1ce90d4..eb45067411 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.cpp @@ -22,7 +22,6 @@ #include "RicWellTarget3dEditor.h" #include "RimWellPathGeometryDef.h" -#include "RimWellPathLateralGeometryDef.h" #include "RimWellPathTarget.h" #include "cafPickEventHandler.h" @@ -56,7 +55,7 @@ RicWellPathGeometry3dEditor::~RicWellPathGeometry3dEditor() //-------------------------------------------------------------------------------------------------- void RicWellPathGeometry3dEditor::configureAndUpdateUi( const QString& uiConfigName ) { - RimWellPathGeometryDefInterface* geomDef = dynamic_cast( this->pdmObject() ); + RimWellPathGeometryDef* geomDef = dynamic_cast( this->pdmObject() ); for ( auto targetEditor : m_targetEditors ) { diff --git a/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellTarget3dEditor.cpp b/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellTarget3dEditor.cpp index cf61245cda..c0d8b6b2e3 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellTarget3dEditor.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/PointTangentManipulator/RicWellTarget3dEditor.cpp @@ -24,7 +24,6 @@ #include "RimCase.h" #include "RimModeledWellPath.h" #include "RimWellPathGeometryDef.h" -#include "RimWellPathLateralGeometryDef.h" #include "RimWellPathTarget.h" #include "RiuViewer.h" @@ -86,7 +85,7 @@ void RicWellTarget3dEditor::configureAndUpdateUi( const QString& uiConfigName ) return; } - RimWellPathGeometryDefInterface* geomDef; + RimWellPathGeometryDef* geomDef; target->firstAncestorOrThisOfTypeAsserted( geomDef ); target->m_targetType.uiCapability()->addFieldEditor( this ); @@ -153,7 +152,7 @@ void RicWellTarget3dEditor::slotUpdated( const cvf::Vec3d& origin, const cvf::Ve cvf::ref dispXf = view->displayCoordTransform(); - RimWellPathGeometryDefInterface* geomDef; + RimWellPathGeometryDef* geomDef; target->firstAncestorOrThisOfTypeAsserted( geomDef ); cvf::Vec3d domainOrigin = dispXf->transformToDomainCoord( origin ) - geomDef->anchorPointXyz(); diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp index df3169870b..558eb41e23 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp @@ -34,7 +34,6 @@ #include "RimModeledWellPath.h" #include "RimWellPath.h" #include "RimWellPathGeometryDef.h" -#include "RimWellPathLateralGeometryDef.h" #include "RimWellPathTarget.h" #include "RiuViewerCommands.h" @@ -56,8 +55,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicCreateWellTargetsPickEventHandler::RicCreateWellTargetsPickEventHandler( - gsl::not_null wellGeometryDef ) +RicCreateWellTargetsPickEventHandler::RicCreateWellTargetsPickEventHandler( gsl::not_null wellGeometryDef ) : m_geometryToAddTargetsTo( wellGeometryDef ) { } @@ -97,55 +95,94 @@ bool RicCreateWellTargetsPickEventHandler::handle3dPickEvent( const Ric3dPickEve cvf::Vec3d targetPointInDomain = cvf::Vec3d::ZERO; // If clicked on an other well path, snap target point to well path center line - auto firstPickItem = eventObject.m_pickItemInfos.front(); + auto firstPickItem = eventObject.m_pickItemInfos.front(); + auto wellPathSourceInfo = dynamic_cast( firstPickItem.sourceInfo() ); auto intersectionPointInDomain = rimView->displayCoordTransform()->transformToDomainCoord( firstPickItem.globalPickedPoint() ); + bool doSetAzimuthAndInclination = false; + double azimuth = 0.0; + double inclination = 0.0; - double azimuth = std::numeric_limits::infinity(); - double inclination = std::numeric_limits::infinity(); - - auto wellPathSourceInfo = dynamic_cast( firstPickItem.sourceInfo() ); - - if ( isValidWellPathSourceObject( wellPathSourceInfo ) ) + if ( wellPathSourceInfo && wellPathSourceInfo->wellPath() && wellPathSourceInfo->wellPath()->wellPathGeometry() ) { - calculateWellPathGeometryAtPickPoint( firstPickItem, - wellPathSourceInfo, - intersectionPointInDomain, - &targetPointInDomain, - &azimuth, - &inclination ); + auto wellPathGeometry = wellPathSourceInfo->wellPath()->wellPathGeometry(); + + targetPointInDomain = + wellPathSourceInfo->closestPointOnCenterLine( firstPickItem.faceIdx(), intersectionPointInDomain ); + double md = wellPathSourceInfo->measuredDepth( firstPickItem.faceIdx(), intersectionPointInDomain ); + doSetAzimuthAndInclination = calculateAzimuthAndInclinationAtMd( md, wellPathGeometry, &azimuth, &inclination ); + double rkbDiff = wellPathGeometry->rkbDiff(); + if ( m_geometryToAddTargetsTo->airGap() == 0.0 && rkbDiff != std::numeric_limits::infinity() ) + { + m_geometryToAddTargetsTo->setAirGap( rkbDiff ); + } } else if ( isGridSourceObject( firstPickItem.sourceInfo() ) ) { - targetPointInDomain = calculateGridPickPoint( rimView, firstPickItem, intersectionPointInDomain ); + targetPointInDomain = intersectionPointInDomain; + doSetAzimuthAndInclination = false; + + cvf::Vec3d domainRayOrigin = + rimView->displayCoordTransform()->transformToDomainCoord( firstPickItem.globalRayOrigin() ); + cvf::Vec3d domainRayEnd = targetPointInDomain + ( targetPointInDomain - domainRayOrigin ); + + cvf::Vec3d hexElementIntersection = + findHexElementIntersection( rimView, firstPickItem, domainRayOrigin, domainRayEnd ); + CVF_TIGHT_ASSERT( !hexElementIntersection.isUndefined() ); + if ( !hexElementIntersection.isUndefined() ) + { + targetPointInDomain = hexElementIntersection; + } } else { - targetPointInDomain = intersectionPointInDomain; + targetPointInDomain = intersectionPointInDomain; + doSetAzimuthAndInclination = false; } - if ( auto wellPathGeometryDef = dynamic_cast( m_geometryToAddTargetsTo.p() ); - wellPathGeometryDef ) + if ( !m_geometryToAddTargetsTo->firstActiveTarget() ) { - addNewTargetToModeledWellPath( firstPickItem, - wellPathGeometryDef, - intersectionPointInDomain, - targetPointInDomain, - azimuth, - inclination ); + m_geometryToAddTargetsTo->setReferencePointXyz( targetPointInDomain ); + + if ( wellPathSourceInfo ) + { + double mdAtFirstTarget = + wellPathSourceInfo->measuredDepth( firstPickItem.faceIdx(), intersectionPointInDomain ); + + RimModeledWellPath* modeledWellPath = dynamic_cast( wellPathSourceInfo->wellPath() ); + if ( modeledWellPath ) + { + mdAtFirstTarget += modeledWellPath->geometryDefinition()->mdAtFirstTarget(); + } + + m_geometryToAddTargetsTo->setMdAtFirstTarget( mdAtFirstTarget ); + } } - else if ( auto wellPathLateralGeometryDef = - dynamic_cast( m_geometryToAddTargetsTo.p() ); - wellPathLateralGeometryDef ) + + cvf::Vec3d referencePoint = m_geometryToAddTargetsTo->anchorPointXyz(); + cvf::Vec3d relativeTagetPoint = targetPointInDomain - referencePoint; + + RimWellPathTarget* newTarget = new RimWellPathTarget; + + if ( doSetAzimuthAndInclination ) { - addNewTargetToModeledWellPathLateral( firstPickItem, - wellPathLateralGeometryDef, - intersectionPointInDomain, - targetPointInDomain, - azimuth, - inclination ); + newTarget->setAsPointXYZAndTangentTarget( cvf::Vec3d( relativeTagetPoint.x(), + relativeTagetPoint.y(), + relativeTagetPoint.z() ), + azimuth, + inclination ); } + else + { + newTarget->setAsPointTargetXYD( + cvf::Vec3d( relativeTagetPoint.x(), relativeTagetPoint.y(), -relativeTagetPoint.z() ) ); + } + + m_geometryToAddTargetsTo->insertTarget( nullptr, newTarget ); + + m_geometryToAddTargetsTo->updateConnectedEditors(); + m_geometryToAddTargetsTo->updateWellPathVisualization( true ); return true; // Todo: See if we really should eat the event instead } @@ -206,155 +243,6 @@ bool RicCreateWellTargetsPickEventHandler::calculateAzimuthAndInclinationAtMd( d return false; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RicCreateWellTargetsPickEventHandler::calculateWellPathGeometryAtPickPoint( - const RiuPickItemInfo& pickItem, - gsl::not_null wellPathSourceInfo, - const cvf::Vec3d& intersectionPointInDomain, - gsl::not_null targetPointInDomain, - gsl::not_null azimuth, - gsl::not_null inclination ) const -{ - *targetPointInDomain = wellPathSourceInfo->closestPointOnCenterLine( pickItem.faceIdx(), intersectionPointInDomain ); - - bool doSetAzimuthAndInclination = false; - - auto wellPathGeometry = wellPathSourceInfo->wellPath()->wellPathGeometry(); - if ( wellPathGeometry ) - { - double md = wellPathSourceInfo->measuredDepth( pickItem.faceIdx(), intersectionPointInDomain ); - - doSetAzimuthAndInclination = calculateAzimuthAndInclinationAtMd( md, wellPathGeometry, azimuth, inclination ); - double rkbDiff = wellPathGeometry->rkbDiff(); - auto wellPathGeometryDef = dynamic_cast( m_geometryToAddTargetsTo.p() ); - if ( wellPathGeometryDef && wellPathGeometryDef->airGap() == 0.0 && - rkbDiff != std::numeric_limits::infinity() ) - { - wellPathGeometryDef->setAirGap( rkbDiff ); - } - } - return doSetAzimuthAndInclination; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec3d RicCreateWellTargetsPickEventHandler::calculateGridPickPoint( gsl::not_null rimView, - const RiuPickItemInfo& pickItem, - const cvf::Vec3d& intersectionPointInDomain ) const -{ - auto targetPointInDomain = intersectionPointInDomain; - - cvf::Vec3d domainRayOrigin = rimView->displayCoordTransform()->transformToDomainCoord( pickItem.globalRayOrigin() ); - cvf::Vec3d domainRayEnd = targetPointInDomain + ( targetPointInDomain - domainRayOrigin ); - - cvf::Vec3d hexElementIntersection = findHexElementIntersection( rimView, pickItem, domainRayOrigin, domainRayEnd ); - CVF_TIGHT_ASSERT( !hexElementIntersection.isUndefined() ); - if ( !hexElementIntersection.isUndefined() ) - { - targetPointInDomain = hexElementIntersection; - } - return targetPointInDomain; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicCreateWellTargetsPickEventHandler::addNewTargetToModeledWellPath( const RiuPickItemInfo& pickItem, - gsl::not_null wellPathGeometryDef, - const cvf::Vec3d& intersectionPointInDomain, - const cvf::Vec3d& targetPointInDomain, - double azimuth, - double inclination ) -{ - if ( !m_geometryToAddTargetsTo->firstActiveTarget() ) - { - wellPathGeometryDef->setReferencePointXyz( targetPointInDomain ); - - auto wellPathSourceInfo = dynamic_cast( pickItem.sourceInfo() ); - if ( wellPathSourceInfo ) - { - double mdAtFirstTarget = wellPathSourceInfo->measuredDepth( pickItem.faceIdx(), intersectionPointInDomain ); - - RimModeledWellPath* modeledWellPath = dynamic_cast( wellPathSourceInfo->wellPath() ); - if ( modeledWellPath ) - { - mdAtFirstTarget += modeledWellPath->geometryDefinition()->mdAtFirstTarget(); - } - - wellPathGeometryDef->setMdAtFirstTarget( mdAtFirstTarget ); - } - } - - cvf::Vec3d referencePoint = wellPathGeometryDef->anchorPointXyz(); - cvf::Vec3d relativeTargetPoint = targetPointInDomain - referencePoint; - - RimWellPathTarget* newTarget = new RimWellPathTarget; - - bool doSetAzimuthAndInclination = azimuth != std::numeric_limits::infinity() && - inclination != std::numeric_limits::infinity(); - if ( doSetAzimuthAndInclination ) - { - newTarget->setAsPointXYZAndTangentTarget( relativeTargetPoint, azimuth, inclination ); - } - else - { - newTarget->setAsPointTargetXYD( - cvf::Vec3d( relativeTargetPoint.x(), relativeTargetPoint.y(), -relativeTargetPoint.z() ) ); - } - - m_geometryToAddTargetsTo->insertTarget( nullptr, newTarget ); - m_geometryToAddTargetsTo->updateConnectedEditors(); - m_geometryToAddTargetsTo->updateWellPathVisualization( false ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicCreateWellTargetsPickEventHandler::addNewTargetToModeledWellPathLateral( - const RiuPickItemInfo& pickItem, - gsl::not_null wellPathLateralGeometryDef, - const cvf::Vec3d& intersectionPointInDomain, - const cvf::Vec3d& targetPointInDomain, - double azimuth, - double inclination ) -{ - auto wellPathSourceInfo = dynamic_cast( pickItem.sourceInfo() ); - if ( wellPathSourceInfo ) - { - double mdAtConnection = wellPathSourceInfo->measuredDepth( pickItem.faceIdx(), intersectionPointInDomain ); - - wellPathLateralGeometryDef->setParentGeometry( wellPathSourceInfo->wellPath()->wellPathGeometry() ); - wellPathLateralGeometryDef->setMdAtConnection( mdAtConnection ); - } - cvf::Vec3d referencePoint = wellPathLateralGeometryDef->anchorPointXyz(); - cvf::Vec3d relativeTargetPoint = targetPointInDomain - referencePoint; - - RimWellPathTarget* newTarget = new RimWellPathTarget; - - bool doSetAzimuthAndInclination = azimuth != std::numeric_limits::infinity() && - inclination != std::numeric_limits::infinity(); - if ( doSetAzimuthAndInclination ) - { - newTarget->setAsPointXYZAndTangentTarget( cvf::Vec3d( relativeTargetPoint.x(), - relativeTargetPoint.y(), - relativeTargetPoint.z() ), - azimuth, - inclination ); - } - else - { - newTarget->setAsPointTargetXYD( - cvf::Vec3d( relativeTargetPoint.x(), relativeTargetPoint.y(), -relativeTargetPoint.z() ) ); - } - - m_geometryToAddTargetsTo->insertTarget( nullptr, newTarget ); - m_geometryToAddTargetsTo->updateConnectedEditors(); - m_geometryToAddTargetsTo->updateWellPathVisualization( false ); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -368,18 +256,10 @@ bool RicCreateWellTargetsPickEventHandler::isGridSourceObject( const cvf::Object //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicCreateWellTargetsPickEventHandler::isValidWellPathSourceObject( const RivWellPathSourceInfo* wellPathSourceInfo ) -{ - return wellPathSourceInfo && wellPathSourceInfo->wellPath() && wellPathSourceInfo->wellPath()->wellPathGeometry(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl::not_null view, - const RiuPickItemInfo& pickItem, - const cvf::Vec3d& domainRayOrigin, - const cvf::Vec3d& domainRayEnd ) +cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl::not_null view, + const RiuPickItemInfo& pickItem, + const cvf::Vec3d& domainRayOrigin, + const cvf::Vec3d& domainRayEnd ) { auto sourceInfo = dynamic_cast( pickItem.sourceInfo() ); auto femSourceInfo = dynamic_cast( pickItem.sourceInfo() ); @@ -393,7 +273,7 @@ cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl { cellIndex = sourceInfo->m_cellFaceFromTriangleMapper->cellIndex( pickItem.faceIdx() ); - const RimEclipseView* eclipseView = dynamic_cast( view.get() ); + RimEclipseView* eclipseView = dynamic_cast( view.get() ); if ( eclipseView && eclipseView->mainGrid() ) { RigGridBase* hitGrid = eclipseView->mainGrid()->gridByIndex( gridIndex ); @@ -408,11 +288,11 @@ cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl { size_t elementIndex = femSourceInfo->triangleToElmMapper()->elementIndex( pickItem.faceIdx() ); - const RimGeoMechView* geoMechView = dynamic_cast( view.get() ); + RimGeoMechView* geoMechView = dynamic_cast( view.get() ); if ( geoMechView && geoMechView->femParts() ) { - const RigFemPart* femPart = geoMechView->femParts()->part( femPartIndex ); - RigElementType elType = femPart->elementType( elementIndex ); + RigFemPart* femPart = geoMechView->femParts()->part( femPartIndex ); + RigElementType elType = femPart->elementType( elementIndex ); if ( elType == HEX8 || elType == HEX8P ) { diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h b/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h index ed36860a33..1f81abd7ce 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h +++ b/ApplicationLibCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h @@ -24,12 +24,8 @@ #include -class RimWellPathGeometryDefInterface; -class RigWellPath; -class RiuPickItemInfo; -class RivWellPathSourceInfo; class RimWellPathGeometryDef; -class RimWellPathLateralGeometryDef; +class RigWellPath; //================================================================================================== /// @@ -37,7 +33,7 @@ class RimWellPathLateralGeometryDef; class RicCreateWellTargetsPickEventHandler : public Ric3dViewPickEventHandler { public: - RicCreateWellTargetsPickEventHandler( gsl::not_null wellGeometryDef ); + RicCreateWellTargetsPickEventHandler( gsl::not_null wellGeometryDef ); ~RicCreateWellTargetsPickEventHandler(); void registerAsPickEventHandler() override; @@ -51,38 +47,13 @@ private: gsl::not_null wellPathGeometry, double* azimuth, double* inclination ) const; - bool calculateWellPathGeometryAtPickPoint( const RiuPickItemInfo& pickItem, - gsl::not_null sourceInfo, - const cvf::Vec3d& intersectionPointInDomain, - gsl::not_null targetPointInDomain, - gsl::not_null azimuth, - gsl::not_null inclination ) const; - - cvf::Vec3d calculateGridPickPoint( gsl::not_null rimView, - const RiuPickItemInfo& pickItem, - const cvf::Vec3d& intersectionPointInDomain ) const; - - void addNewTargetToModeledWellPath( const RiuPickItemInfo& pickItem, - gsl::not_null wellPathGeometryDef, - const cvf::Vec3d& intersectionPointInDomain, - const cvf::Vec3d& targetPointInDomain, - double azimuth, - double inclination ); - - void addNewTargetToModeledWellPathLateral( const RiuPickItemInfo& pickItem, - gsl::not_null wellPathLateralGeometryDef, - const cvf::Vec3d& intersectionPointInDomain, - const cvf::Vec3d& targetPointInDomain, - double azimuth, - double inclination ); static bool isGridSourceObject( const cvf::Object* object ); - static bool isValidWellPathSourceObject( const RivWellPathSourceInfo* sourceInfo ); - static cvf::Vec3d findHexElementIntersection( gsl::not_null view, - const RiuPickItemInfo& pickItem, - const cvf::Vec3d& domainRayOrigin, - const cvf::Vec3d& domainRayEnd ); + static cvf::Vec3d findHexElementIntersection( gsl::not_null view, + const RiuPickItemInfo& pickItem, + const cvf::Vec3d& domainRayOrigin, + const cvf::Vec3d& domainRayEnd ); private: - caf::PdmPointer m_geometryToAddTargetsTo; + caf::PdmPointer m_geometryToAddTargetsTo; }; diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp index cfd8a033b6..d2e1e00538 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp @@ -20,15 +20,16 @@ #include "WellPathCommands/RicWellPathsUnitSystemSettingsImpl.h" #include "RigWellPath.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" -#include "RimModeledWellPathLateral.h" +#include "RimModeledWellPath.h" #include "RimOilField.h" #include "RimProject.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" +#include "RimWellPathGeometryDef.h" #include "RimWellPathGroup.h" -#include "RimWellPathLateralGeometryDef.h" +#include "RimWellPathTarget.h" #include "Riu3DMainWindowTools.h" #include "Riu3dSelectionManager.h" @@ -74,18 +75,17 @@ void RicNewWellPathLateralAtDepthFeature::onActionTriggered( bool isChecked ) if ( wellPathCollection ) { - auto newModeledWellPath = new RimModeledWellPathLateral(); + auto newModeledWellPath = new RimModeledWellPath(); auto [pointVector, measuredDepths] = wellPath->wellPathGeometry()->clippedPointSubset( wellPath->wellPathGeometry()->measuredDepths().front(), wellPathSelItem->m_measuredDepth ); if ( pointVector.size() < 2u ) return; - - newModeledWellPath->geometryDefinition()->setParentGeometry( wellPath->wellPathGeometry() ); - newModeledWellPath->geometryDefinition()->setMdAtConnection( wellPathSelItem->m_measuredDepth ); - newModeledWellPath->geometryDefinition()->createTargetAtConnectionPoint( - pointVector[pointVector.size() - 1u] - pointVector[pointVector.size() - 2u] ); - + newModeledWellPath->geometryDefinition()->setMdAtFirstTarget( measuredDepths.back() ); + newModeledWellPath->geometryDefinition()->setUseAutoGeneratedTargetAtSeaLevel( false ); + newModeledWellPath->geometryDefinition()->setFixedWellPathPoints( pointVector ); + newModeledWellPath->geometryDefinition()->setFixedMeasuredDepths( measuredDepths ); + newModeledWellPath->setName( wellPath->name() + QString( " md=%1" ).arg( wellPathSelItem->m_measuredDepth ) ); newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true ); newModeledWellPath->createWellPathGeometry(); if ( wellPathGroup ) diff --git a/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.cpp index a560606288..18ebc2bb5c 100644 --- a/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.cpp @@ -20,7 +20,7 @@ #include "RigWellPath.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimWellPath.h" #include "RivObjectSourceInfo.h" @@ -37,7 +37,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RivFishbonesSubsPartMgr::RivFishbonesSubsPartMgr( RimFishbonesMultipleSubs* subs ) +RivFishbonesSubsPartMgr::RivFishbonesSubsPartMgr( RimFishbones* subs ) : m_rimFishbonesSubs( subs ) { } @@ -90,20 +90,16 @@ void RivFishbonesSubsPartMgr::buildParts( const caf::DisplayCoordTransform* disp RivPipeGeometryGenerator geoGenerator; - for ( auto& sub : m_rimFishbonesSubs->installedLateralIndices() ) + for ( const auto& [subIndex, lateralIndex] : m_rimFishbonesSubs->installedLateralIndices() ) { - for ( size_t lateralIndex : sub.lateralIndices ) - { - std::vector lateralDomainCoords = - m_rimFishbonesSubs->coordsForLateral( sub.subIndex, lateralIndex ); + std::vector lateralDomainCoords = m_rimFishbonesSubs->coordsForLateral( subIndex, lateralIndex ); - std::vector displayCoords = displayCoordTransform->transformToDisplayCoords( lateralDomainCoords ); + std::vector displayCoords = displayCoordTransform->transformToDisplayCoords( lateralDomainCoords ); - geoGenerator.cylinderWithCenterLineParts( &m_parts, - displayCoords, - m_rimFishbonesSubs->fishbonesColor(), - wellPath->combinedScaleFactor() * characteristicCellSize * 0.5 ); - } + geoGenerator.cylinderWithCenterLineParts( &m_parts, + displayCoords, + m_rimFishbonesSubs->fishbonesColor(), + wellPath->combinedScaleFactor() * characteristicCellSize * 0.5 ); } cvf::ref objectSourceInfo = new RivObjectSourceInfo( m_rimFishbonesSubs ); diff --git a/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.h b/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.h index 61a3fcc960..e9de7d9262 100644 --- a/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.h +++ b/ApplicationLibCode/ModelVisualization/RivFishbonesSubsPartMgr.h @@ -40,7 +40,7 @@ namespace caf class DisplayCoordTransform; } -class RimFishbonesMultipleSubs; +class RimFishbones; //-------------------------------------------------------------------------------------------------- /// @@ -48,7 +48,7 @@ class RimFishbonesMultipleSubs; class RivFishbonesSubsPartMgr : public cvf::Object { public: - RivFishbonesSubsPartMgr( RimFishbonesMultipleSubs* subs ); + RivFishbonesSubsPartMgr( RimFishbones* subs ); ~RivFishbonesSubsPartMgr() override; void appendGeometryPartsToModel( cvf::ModelBasicList* model, @@ -60,6 +60,6 @@ private: void buildParts( const caf::DisplayCoordTransform* displayCoordTransform, double characteristicCellSize ); private: - caf::PdmPointer m_rimFishbonesSubs; - cvf::Collection m_parts; + caf::PdmPointer m_rimFishbonesSubs; + cvf::Collection m_parts; }; diff --git a/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp index 428fd229fa..6a30522403 100644 --- a/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp @@ -30,10 +30,10 @@ #include "Rim3dWellLogCurveCollection.h" #include "RimEclipseCase.h" #include "RimEclipseView.h" -#include "RimFishboneWellPath.h" -#include "RimFishboneWellPathCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimImportedFishboneLaterals.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" #include "RimRegularLegendConfig.h" @@ -371,10 +371,10 @@ void RivWellPathPartMgr::appendImportedFishbonesToModel( cvf::ModelBasicList* { if ( !m_rimWellPath || !m_rimWellPath->fishbonesCollection()->wellPathCollection()->isChecked() ) return; - RivPipeGeometryGenerator geoGenerator; - std::vector fishbonesWellPaths; + RivPipeGeometryGenerator geoGenerator; + std::vector fishbonesWellPaths; m_rimWellPath->descendantsIncludingThisOfType( fishbonesWellPaths ); - for ( RimFishboneWellPath* fbWellPath : fishbonesWellPaths ) + for ( RimImportedFishboneLaterals* fbWellPath : fishbonesWellPaths ) { if ( !fbWellPath->isChecked() ) continue; @@ -745,10 +745,13 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d m_centerLinePart->setEffect( eff.p() ); } - // Generate label with well-path name - + // Generate label with well-path name at a position that is slightly offset towards the end of the well path + // This is to avoid overlap between well path laterals. cvf::Vec3d textPosition = cvfCoords->get( 0 ); + cvf::Vec3d tangent = ( cvfCoords->get( cvfCoords->size() - 1 ) - cvfCoords->get( 0 ) ).getNormalized(); + textPosition.z() += 2.2 * characteristicCellSize; + textPosition += tangent * 2.2 * characteristicCellSize; if ( wellPathCollection->showWellPathLabel() && m_rimWellPath->showWellPathLabel() && !m_rimWellPath->name().isEmpty() ) { diff --git a/ApplicationLibCode/ProjectDataModel/.clang-tidy b/ApplicationLibCode/ProjectDataModel/.clang-tidy new file mode 100644 index 0000000000..0cbcb5aef3 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/.clang-tidy @@ -0,0 +1 @@ +Checks: 'google-readability-braces-around-statements,google-readability-casting,google-readability-function-size,google-readability-namespace-comments,google-readability-todo,modernize-avoid-bind,modernize-avoid-c-arrays,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,modernize-use-using,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-const-return-type,readability-container-size-empty,readability-deleted-default,readability-delete-null-pointer,readability-else-after-return,readability-function-size,readability-identifier-naming,readability-implicit-bool-conversion,readability-inconsistent-declaration-parameter-name,readability-isolate-declaration,readability-magic-numbers,readability-misleading-indentation,readability-misplaced-array-index,readability-named-parameter,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-member-init,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-boolean-expr,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-uppercase-literal-suffix' \ No newline at end of file diff --git a/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake index 96c60b9ae5..79390bf165 100644 --- a/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake @@ -23,13 +23,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPath.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathGroup.h ${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.h ${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.h -${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPathLateral.h ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurement.h ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilePath.h -${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDefInterface.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDef.h -${CMAKE_CURRENT_LIST_DIR}/RimWellPathLateralGeometryDef.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttribute.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttributeCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.h @@ -193,13 +190,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPath.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathGroup.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.cpp ${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.cpp -${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPathLateral.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurement.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilePath.cpp -${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDefInterface.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDef.cpp -${CMAKE_CURRENT_LIST_DIR}/RimWellPathLateralGeometryDef.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttribute.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttributeCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.cpp diff --git a/ApplicationLibCode/ProjectDataModel/Completions/.clang-tidy b/ApplicationLibCode/ProjectDataModel/Completions/.clang-tidy new file mode 100644 index 0000000000..0cbcb5aef3 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/Completions/.clang-tidy @@ -0,0 +1 @@ +Checks: 'google-readability-braces-around-statements,google-readability-casting,google-readability-function-size,google-readability-namespace-comments,google-readability-todo,modernize-avoid-bind,modernize-avoid-c-arrays,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,modernize-use-using,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-const-return-type,readability-container-size-empty,readability-deleted-default,readability-delete-null-pointer,readability-else-after-return,readability-function-size,readability-identifier-naming,readability-implicit-bool-conversion,readability-inconsistent-declaration-parameter-name,readability-isolate-declaration,readability-magic-numbers,readability-misleading-indentation,readability-misplaced-array-index,readability-named-parameter,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-member-init,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-boolean-expr,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-uppercase-literal-suffix' \ No newline at end of file diff --git a/ApplicationLibCode/ProjectDataModel/Completions/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/Completions/CMakeLists_files.cmake index 461fb14803..c829686f68 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/Completions/CMakeLists_files.cmake @@ -2,13 +2,14 @@ set (SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimCompletionCellIntersectionCalc.h ${CMAKE_CURRENT_LIST_DIR}/RimFishbonesCollection.h -${CMAKE_CURRENT_LIST_DIR}/RimFishbonesMultipleSubs.h +${CMAKE_CURRENT_LIST_DIR}/RimFishbones.h ${CMAKE_CURRENT_LIST_DIR}/RimFishbonesPipeProperties.h ${CMAKE_CURRENT_LIST_DIR}/RimFishboneWellPath.h ${CMAKE_CURRENT_LIST_DIR}/RimFishboneWellPathCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimPerforationCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimPerforationInterval.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletionSettings.h ${CMAKE_CURRENT_LIST_DIR}/RimEllipseFractureTemplate.h ${CMAKE_CURRENT_LIST_DIR}/RimFracture.h ${CMAKE_CURRENT_LIST_DIR}/RimFractureContainment.h @@ -38,13 +39,14 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPathAicdParameters.h set (SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RimCompletionCellIntersectionCalc.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFishbonesCollection.cpp -${CMAKE_CURRENT_LIST_DIR}/RimFishbonesMultipleSubs.cpp +${CMAKE_CURRENT_LIST_DIR}/RimFishbones.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFishbonesPipeProperties.cpp -${CMAKE_CURRENT_LIST_DIR}/RimFishboneWellPath.cpp -${CMAKE_CURRENT_LIST_DIR}/RimFishboneWellPathCollection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimImportedFishboneLaterals.cpp +${CMAKE_CURRENT_LIST_DIR}/RimImportedFishboneLateralsCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimPerforationCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimPerforationInterval.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletionSettings.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEllipseFractureTemplate.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFracture.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFractureContainment.cpp diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbones.cpp similarity index 82% rename from ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp rename to ApplicationLibCode/ProjectDataModel/Completions/RimFishbones.cpp index b740aab4a6..071726fb54 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbones.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RiaColorTables.h" #include "RiaEclipseUnitTools.h" @@ -38,33 +38,34 @@ #include #include +#include -CAF_PDM_SOURCE_INIT( RimFishbonesMultipleSubs, "FishbonesMultipleSubs" ); +CAF_PDM_SOURCE_INIT( RimFishbones, "FishbonesMultipleSubs" ); namespace caf { template <> -void AppEnum::setUp() +void AppEnum::setUp() { - addItem( RimFishbonesMultipleSubs::FB_SUB_COUNT_END, "FB_SUB_COUNT", "Start/End/Number of Subs" ); - addItem( RimFishbonesMultipleSubs::FB_SUB_SPACING_END, "FB_SUB_SPACING", "Start/End/Spacing" ); - addItem( RimFishbonesMultipleSubs::FB_SUB_USER_DEFINED, "FB_SUB_CUSTOM", "User Specification" ); - setDefault( RimFishbonesMultipleSubs::FB_SUB_COUNT_END ); + addItem( RimFishbones::FB_SUB_COUNT_END, "FB_SUB_COUNT", "Start/End/Number of Subs" ); + addItem( RimFishbones::FB_SUB_SPACING_END, "FB_SUB_SPACING", "Start/End/Spacing" ); + addItem( RimFishbones::FB_SUB_USER_DEFINED, "FB_SUB_CUSTOM", "User Specification" ); + setDefault( RimFishbones::FB_SUB_COUNT_END ); } template <> -void AppEnum::setUp() +void AppEnum::setUp() { - addItem( RimFishbonesMultipleSubs::FB_LATERAL_ORIENTATION_FIXED, "FB_LATERAL_ORIENTATION_FIXED", "Fixed Angle" ); - addItem( RimFishbonesMultipleSubs::FB_LATERAL_ORIENTATION_RANDOM, "FB_LATERAL_ORIENTATION_RANDOM", "Random Angle" ); - setDefault( RimFishbonesMultipleSubs::FB_LATERAL_ORIENTATION_RANDOM ); + addItem( RimFishbones::FB_LATERAL_ORIENTATION_FIXED, "FB_LATERAL_ORIENTATION_FIXED", "Fixed Angle" ); + addItem( RimFishbones::FB_LATERAL_ORIENTATION_RANDOM, "FB_LATERAL_ORIENTATION_RANDOM", "Random Angle" ); + setDefault( RimFishbones::FB_LATERAL_ORIENTATION_RANDOM ); } } // namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishbonesMultipleSubs::RimFishbonesMultipleSubs() +RimFishbones::RimFishbones() { CAF_PDM_InitObject( "FishbonesMultipleSubs", ":/FishBoneGroup16x16.png", "", "" ); @@ -72,7 +73,7 @@ RimFishbonesMultipleSubs::RimFishbonesMultipleSubs() m_isActive.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_name, "Name", "Name", "", "", "" ); - m_name.registerGetMethod( this, &RimFishbonesMultipleSubs::generatedName ); + m_name.registerGetMethod( this, &RimFishbones::generatedName ); m_name.uiCapability()->setUiReadOnly( true ); m_name.xmlCapability()->setIOWritable( false ); @@ -163,14 +164,14 @@ RimFishbonesMultipleSubs::RimFishbonesMultipleSubs() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishbonesMultipleSubs::~RimFishbonesMultipleSubs() +RimFishbones::~RimFishbones() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimFishbonesMultipleSubs::isActive() const +bool RimFishbones::isActive() const { return m_isActive; } @@ -178,10 +179,10 @@ bool RimFishbonesMultipleSubs::isActive() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimFishbonesMultipleSubs::generatedName() const +QString RimFishbones::generatedName() const { - caf::PdmChildArrayField* container = - dynamic_cast*>( this->parentField() ); + caf::PdmChildArrayField* container = + dynamic_cast*>( this->parentField() ); CVF_ASSERT( container ); size_t index = container->index( this ); @@ -191,7 +192,7 @@ QString RimFishbonesMultipleSubs::generatedName() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::setMeasuredDepthAndCount( double startMD, double spacing, int subCount ) +void RimFishbones::setMeasuredDepthAndCount( double startMD, double spacing, int subCount ) { double endMD = startMD + spacing * subCount; m_valveLocations->initFields( RimMultipleValveLocations::VALVE_SPACING, startMD, endMD, spacing, subCount, {} ); @@ -203,7 +204,7 @@ void RimFishbonesMultipleSubs::setMeasuredDepthAndCount( double startMD, double //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::measuredDepth( size_t subIndex ) const +double RimFishbones::measuredDepth( size_t subIndex ) const { return m_valveLocations->measuredDepth( subIndex ); } @@ -211,7 +212,7 @@ double RimFishbonesMultipleSubs::measuredDepth( size_t subIndex ) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::rotationAngle( size_t index ) const +double RimFishbones::rotationAngle( size_t index ) const { if ( m_subsOrientationMode == FB_LATERAL_ORIENTATION_FIXED ) { @@ -228,7 +229,7 @@ double RimFishbonesMultipleSubs::rotationAngle( size_t index ) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::exitAngle() const +double RimFishbones::exitAngle() const { return m_lateralExitAngle; } @@ -236,7 +237,7 @@ double RimFishbonesMultipleSubs::exitAngle() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::buildAngle() const +double RimFishbones::buildAngle() const { return m_lateralBuildAngle; } @@ -244,7 +245,7 @@ double RimFishbonesMultipleSubs::buildAngle() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const +double RimFishbones::tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const { RimWellPath* wellPath; firstAncestorOrThisOfTypeAsserted( wellPath ); @@ -277,7 +278,7 @@ double RimFishbonesMultipleSubs::tubingDiameter( RiaDefines::EclipseUnitSystem u //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const +double RimFishbones::effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const { double innerRadius = tubingDiameter( unitSystem ) / 2; double outerRadius = holeDiameter( unitSystem ) / 2; @@ -294,7 +295,7 @@ double RimFishbonesMultipleSubs::effectiveDiameter( RiaDefines::EclipseUnitSyste //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::openHoleRoughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const +double RimFishbones::openHoleRoughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const { RimWellPath* wellPath; firstAncestorOrThisOfTypeAsserted( wellPath ); @@ -314,7 +315,7 @@ double RimFishbonesMultipleSubs::openHoleRoughnessFactor( RiaDefines::EclipseUni //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::icdOrificeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const +double RimFishbones::icdOrificeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const { RimWellPath* wellPath; firstAncestorOrThisOfTypeAsserted( wellPath ); @@ -324,7 +325,7 @@ double RimFishbonesMultipleSubs::icdOrificeDiameter( RiaDefines::EclipseUnitSyst //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::icdFlowCoefficient() const +double RimFishbones::icdFlowCoefficient() const { return m_icdFlowCoefficient(); } @@ -332,7 +333,7 @@ double RimFishbonesMultipleSubs::icdFlowCoefficient() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RimFishbonesMultipleSubs::icdCount() const +size_t RimFishbones::icdCount() const { return m_icdCount(); } @@ -340,7 +341,7 @@ size_t RimFishbonesMultipleSubs::icdCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimFishbonesMultipleSubs::lateralLengths() const +std::vector RimFishbones::lateralLengths() const { QStringList items = m_lateralLength().split( ' ' ); double currentLength = 0.0; @@ -367,7 +368,7 @@ std::vector RimFishbonesMultipleSubs::lateralLengths() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::geometryUpdated() +void RimFishbones::geometryUpdated() { computeRotationAngles(); computeSubLateralIndices(); @@ -384,7 +385,7 @@ void RimFishbonesMultipleSubs::geometryUpdated() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimFishbonesMultipleSubs::coordsForLateral( size_t subIndex, size_t lateralIndex ) const +std::vector RimFishbones::coordsForLateral( size_t subIndex, size_t lateralIndex ) const { std::vector> coordsAndMD = m_rigFishbonesGeometry->coordsForLateral( subIndex, lateralIndex ); @@ -401,8 +402,7 @@ std::vector RimFishbonesMultipleSubs::coordsForLateral( size_t subIn //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector> RimFishbonesMultipleSubs::coordsAndMDForLateral( size_t subIndex, - size_t lateralIndex ) const +std::vector> RimFishbones::coordsAndMDForLateral( size_t subIndex, size_t lateralIndex ) const { return m_rigFishbonesGeometry->coordsForLateral( subIndex, lateralIndex ); } @@ -410,7 +410,7 @@ std::vector> RimFishbonesMultipleSubs::coordsAndMD //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::recomputeLateralLocations() +void RimFishbones::recomputeLateralLocations() { computeRangesAndLocations(); computeRotationAngles(); @@ -419,7 +419,7 @@ void RimFishbonesMultipleSubs::recomputeLateralLocations() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::setUnitSystemSpecificDefaults() +void RimFishbones::setUnitSystemSpecificDefaults() { RimWellPath* wellPath; firstAncestorOrThisOfType( wellPath ); @@ -450,7 +450,7 @@ void RimFishbonesMultipleSubs::setUnitSystemSpecificDefaults() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RiaDefines::WellPathComponentType RimFishbonesMultipleSubs::componentType() const +RiaDefines::WellPathComponentType RimFishbones::componentType() const { return RiaDefines::WellPathComponentType::FISHBONES; } @@ -458,7 +458,7 @@ RiaDefines::WellPathComponentType RimFishbonesMultipleSubs::componentType() cons //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimFishbonesMultipleSubs::componentLabel() const +QString RimFishbones::componentLabel() const { return generatedName(); } @@ -466,7 +466,7 @@ QString RimFishbonesMultipleSubs::componentLabel() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimFishbonesMultipleSubs::componentTypeLabel() const +QString RimFishbones::componentTypeLabel() const { return "Fishbones"; } @@ -474,7 +474,7 @@ QString RimFishbonesMultipleSubs::componentTypeLabel() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Color3f RimFishbonesMultipleSubs::defaultComponentColor() const +cvf::Color3f RimFishbones::defaultComponentColor() const { return fishbonesColor(); } @@ -482,7 +482,7 @@ cvf::Color3f RimFishbonesMultipleSubs::defaultComponentColor() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::startMD() const +double RimFishbones::startMD() const { double measuredDepth = 0.0; if ( !m_valveLocations->valveLocations().empty() ) @@ -496,7 +496,7 @@ double RimFishbonesMultipleSubs::startMD() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimFishbonesMultipleSubs::endMD() const +double RimFishbones::endMD() const { double measuredDepth = 0.0; if ( !m_valveLocations->valveLocations().empty() ) @@ -510,9 +510,7 @@ double RimFishbonesMultipleSubs::endMD() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::fieldChangedByUi( const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue ) +void RimFishbones::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) { if ( changedField == &m_subsOrientationMode ) { @@ -530,7 +528,7 @@ void RimFishbonesMultipleSubs::fieldChangedByUi( const caf::PdmFieldHandle* chan //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmFieldHandle* RimFishbonesMultipleSubs::userDescriptionField() +caf::PdmFieldHandle* RimFishbones::userDescriptionField() { return &m_name; } @@ -538,7 +536,7 @@ caf::PdmFieldHandle* RimFishbonesMultipleSubs::userDescriptionField() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmFieldHandle* RimFishbonesMultipleSubs::objectToggleField() +caf::PdmFieldHandle* RimFishbones::objectToggleField() { return &m_isActive; } @@ -546,7 +544,7 @@ caf::PdmFieldHandle* RimFishbonesMultipleSubs::objectToggleField() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::computeRangesAndLocations() +void RimFishbones::computeRangesAndLocations() { m_valveLocations->computeRangesAndLocations(); geometryUpdated(); @@ -555,7 +553,7 @@ void RimFishbonesMultipleSubs::computeRangesAndLocations() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +void RimFishbones::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { { RimWellPath* wellPath; @@ -637,7 +635,7 @@ void RimFishbonesMultipleSubs::defineUiOrdering( QString uiConfigName, caf::PdmU //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::initAfterRead() +void RimFishbones::initAfterRead() { initValveLocationFromLegacyData(); @@ -651,20 +649,17 @@ void RimFishbonesMultipleSubs::initAfterRead() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::BoundingBox RimFishbonesMultipleSubs::boundingBoxInDomainCoords() const +cvf::BoundingBox RimFishbones::boundingBoxInDomainCoords() const { cvf::BoundingBox bb; - for ( auto& sub : installedLateralIndices() ) + for ( const auto& [subIndex, lateralIndex] : installedLateralIndices() ) { - for ( size_t lateralIndex : sub.lateralIndices ) - { - std::vector coords = coordsForLateral( sub.subIndex, lateralIndex ); + std::vector coords = coordsForLateral( subIndex, lateralIndex ); - for ( auto c : coords ) - { - bb.add( c ); - } + for ( const auto& c : coords ) + { + bb.add( c ); } } @@ -674,7 +669,7 @@ cvf::BoundingBox RimFishbonesMultipleSubs::boundingBoxInDomainCoords() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimFishbonesMultipleSubs::isEnabled() const +bool RimFishbones::isEnabled() const { RimFishbonesCollection* collection; this->firstAncestorOrThisOfTypeAsserted( collection ); @@ -685,13 +680,13 @@ bool RimFishbonesMultipleSubs::isEnabled() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::computeRotationAngles() +void RimFishbones::computeRotationAngles() { std::vector vals; for ( size_t i = 0; i < m_valveLocations->valveLocations().size(); i++ ) { - vals.push_back( RimFishbonesMultipleSubs::randomValueFromRange( 0, 360 ) ); + vals.push_back( RimFishbones::randomValueFromRange( 0, 360 ) ); } m_installationRotationAngles = vals; @@ -700,56 +695,39 @@ void RimFishbonesMultipleSubs::computeRotationAngles() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::computeSubLateralIndices() +void RimFishbones::computeSubLateralIndices() { - m_subLateralIndices.clear(); + std::vector subLateralCandidates; for ( size_t subIndex = 0; subIndex < m_valveLocations->valveLocations().size(); ++subIndex ) { - SubLateralIndex subLateralIndex; - subLateralIndex.subIndex = subIndex; - for ( int lateralIndex = 0; lateralIndex < m_lateralCountPerSub(); ++lateralIndex ) { - subLateralIndex.lateralIndices.push_back( lateralIndex ); + subLateralCandidates.push_back( std::make_pair( subIndex, lateralIndex ) ); } - m_subLateralIndices.push_back( subLateralIndex ); } + + std::mt19937 randomEngine( m_randomSeed() ); + std::shuffle( subLateralCandidates.begin(), subLateralCandidates.end(), randomEngine ); + double numLaterals = static_cast( m_valveLocations->valveLocations().size() * m_lateralCountPerSub ); - int numToRemove = static_cast( std::round( ( 1 - m_lateralInstallSuccessFraction ) * numLaterals ) ); - srand( m_randomSeed() ); - while ( numToRemove > 0 ) - { - int subIndexToRemove; - do - { - subIndexToRemove = rand() % m_subLateralIndices.size(); - } while ( m_subLateralIndices[subIndexToRemove].lateralIndices.empty() ); - int lateralIndexToRemove = rand() % m_subLateralIndices[subIndexToRemove].lateralIndices.size(); - m_subLateralIndices[subIndexToRemove].lateralIndices.erase( - m_subLateralIndices[subIndexToRemove].lateralIndices.begin() + lateralIndexToRemove ); - --numToRemove; - } + m_subLateralIndices = + std::vector( subLateralCandidates.begin(), subLateralCandidates.begin() + numLaterals ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int RimFishbonesMultipleSubs::randomValueFromRange( int min, int max ) +int RimFishbones::randomValueFromRange( int min, int max ) { - // See http://www.cplusplus.com/reference/cstdlib/rand/ - - int range = abs( max - min ); - int randomNumberInRange = rand() % range; - - int randomValue = min + randomNumberInRange; - - return randomValue; + std::default_random_engine generator; + std::uniform_int_distribution distribution( min, max ); + return distribution( generator ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::initialiseObsoleteFields() +void RimFishbones::initialiseObsoleteFields() { CAF_PDM_InitField( &m_subsLocationMode_OBSOLETE, "SubsLocationMode", @@ -785,7 +763,7 @@ void RimFishbonesMultipleSubs::initialiseObsoleteFields() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::initValveLocationFromLegacyData() +void RimFishbones::initValveLocationFromLegacyData() { RimMultipleValveLocations::LocationType locationType = RimMultipleValveLocations::VALVE_UNDEFINED; if ( m_subsLocationMode_OBSOLETE() == FB_SUB_COUNT_END ) diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbones.h similarity index 90% rename from ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h rename to ApplicationLibCode/ProjectDataModel/Completions/RimFishbones.h index bf9d66a3bb..c50591341a 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbones.h @@ -43,21 +43,13 @@ class RimMultipleValveLocations; /// /// //================================================================================================== -struct SubLateralIndex -{ - size_t subIndex; - std::vector lateralIndices; -}; - -//================================================================================================== -/// -/// -//================================================================================================== -class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesInterface, public RimWellPathComponentInterface +class RimFishbones : public caf::PdmObject, public Rim3dPropertiesInterface, public RimWellPathComponentInterface { CAF_PDM_HEADER_INIT; public: + using SubAndLateralIndex = std::pair; + enum LocationType { FB_SUB_COUNT_END, @@ -73,8 +65,8 @@ public: }; public: - RimFishbonesMultipleSubs(); - ~RimFishbonesMultipleSubs() override; + RimFishbones(); + ~RimFishbones() override; bool isActive() const; QString generatedName() const; @@ -102,7 +94,7 @@ public: void geometryUpdated(); - const std::vector& installedLateralIndices() const { return m_subLateralIndices; }; + const std::vector& installedLateralIndices() const { return m_subLateralIndices; }; std::vector coordsForLateral( size_t subIndex, size_t lateralIndex ) const; std::vector> coordsAndMDForLateral( size_t subIndex, size_t lateralIndex ) const; void recomputeLateralLocations(); @@ -173,7 +165,7 @@ private: caf::PdmField m_randomSeed; std::unique_ptr m_rigFishbonesGeometry; - std::vector m_subLateralIndices; + std::vector m_subLateralIndices; // Moved to RimMultipleValveLocations caf::PdmField> m_subsLocationMode_OBSOLETE; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp index 2a197fc149..7b62d6e2d2 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp @@ -24,8 +24,8 @@ #include "RigWellPath.h" -#include "RimFishboneWellPathCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimProject.h" #include "RimWellPath.h" @@ -46,21 +46,22 @@ RimFishbonesCollection::RimFishbonesCollection() nameField()->uiCapability()->setUiHidden( true ); this->setName( "Fishbones" ); - CAF_PDM_InitFieldNoDefault( &m_fishbonesSubs, "FishbonesSubs", "fishbonesSubs", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_fishbones, "FishbonesSubs", "fishbonesSubs", "", "", "" ); - m_fishbonesSubs.uiCapability()->setUiHidden( true ); + m_fishbones.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_wellPathCollection, "WellPathCollection", "Imported Laterals", "", "", "" ); - m_wellPathCollection = new RimFishboneWellPathCollection; + m_wellPathCollection = new RimImportedFishboneLateralsCollection; m_wellPathCollection.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &m_startMD, "StartMD", HUGE_VAL, "Start MD", "", "", "" ); CAF_PDM_InitField( &m_mainBoreDiameter, "MainBoreDiameter", 0.216, "Main Bore Diameter", "", "", "" ); CAF_PDM_InitField( &m_skinFactor, "MainBoreSkinFactor", 0., "Main Bore Skin Factor [0..1]", "", "", "" ); - CAF_PDM_InitFieldNoDefault( &m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); - m_mswParameters = new RimMswCompletionParameters( false ); - m_mswParameters.uiCapability()->setUiTreeHidden( true ); - m_mswParameters.uiCapability()->setUiTreeChildrenHidden( true ); + CAF_PDM_InitFieldNoDefault( &m_mswParameters_OBSOLETE, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); + m_mswParameters_OBSOLETE = new RimMswCompletionParameters( false ); + m_mswParameters_OBSOLETE.uiCapability()->setUiTreeHidden( true ); + m_mswParameters_OBSOLETE.uiCapability()->setUiTreeChildrenHidden( true ); + m_mswParameters_OBSOLETE.xmlCapability()->setIOWritable( false ); manuallyModifiedStartMD = false; // Moved to RimMswCompletionParameters and obsoleted @@ -77,7 +78,7 @@ RimFishbonesCollection::RimFishbonesCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishboneWellPathCollection* RimFishbonesCollection::wellPathCollection() const +RimImportedFishboneLateralsCollection* RimFishbonesCollection::wellPathCollection() const { CVF_ASSERT( m_wellPathCollection ); @@ -135,8 +136,6 @@ void RimFishbonesCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiO wellGroup->add( &m_startMD ); wellGroup->add( &m_mainBoreDiameter ); wellGroup->add( &m_skinFactor ); - caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Multi Segment Well Options" ); - m_mswParameters->uiOrdering( uiConfigName, *mswGroup ); uiOrdering.skipRemainingFields( true ); } @@ -147,29 +146,29 @@ void RimFishbonesCollection::initAfterRead() { if ( m_linerDiameter_OBSOLETE() != m_linerDiameter_OBSOLETE.defaultValue() ) { - m_mswParameters->setLinerDiameter( m_linerDiameter_OBSOLETE() ); + m_mswParameters_OBSOLETE->setLinerDiameter( m_linerDiameter_OBSOLETE() ); } if ( m_roughnessFactor_OBSOLETE() != m_roughnessFactor_OBSOLETE.defaultValue() ) { - m_mswParameters->setRoughnessFactor( m_roughnessFactor_OBSOLETE() ); + m_mswParameters_OBSOLETE->setRoughnessFactor( m_roughnessFactor_OBSOLETE() ); } if ( m_pressureDrop_OBSOLETE() != m_pressureDrop_OBSOLETE.defaultValue() ) { - m_mswParameters->setPressureDrop( m_pressureDrop_OBSOLETE() ); + m_mswParameters_OBSOLETE->setPressureDrop( m_pressureDrop_OBSOLETE() ); } if ( m_lengthAndDepth_OBSOLETE() != m_lengthAndDepth_OBSOLETE.defaultValue() ) { - m_mswParameters->setLengthAndDepth( m_lengthAndDepth_OBSOLETE() ); + m_mswParameters_OBSOLETE->setLengthAndDepth( m_lengthAndDepth_OBSOLETE() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesCollection::appendFishbonesSubs( RimFishbonesMultipleSubs* subs ) +void RimFishbonesCollection::appendFishbonesSubs( RimFishbones* subs ) { subs->fishbonesColor = nextFishbonesColor(); - m_fishbonesSubs.push_back( subs ); + m_fishbones.push_back( subs ); subs->setUnitSystemSpecificDefaults(); subs->recomputeLateralLocations(); @@ -178,17 +177,17 @@ void RimFishbonesCollection::appendFishbonesSubs( RimFishbonesMultipleSubs* subs //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RimMswCompletionParameters* RimFishbonesCollection::mswParameters() const +bool RimFishbonesCollection::hasFishbones() const { - return m_mswParameters; + return !m_fishbones.empty(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimFishbonesCollection::activeFishbonesSubs() const +std::vector RimFishbonesCollection::activeFishbonesSubs() const { - std::vector active; + std::vector active; if ( isChecked() ) { @@ -207,9 +206,9 @@ std::vector RimFishbonesCollection::activeFishbonesSu //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimFishbonesCollection::allFishbonesSubs() const +std::vector RimFishbonesCollection::allFishbonesSubs() const { - return m_fishbonesSubs.childObjects(); + return m_fishbones.childObjects(); } //-------------------------------------------------------------------------------------------------- @@ -231,7 +230,7 @@ cvf::Color3f RimFishbonesCollection::nextFishbonesColor() const QColor qFishbonesColor; - int newIndex = static_cast( m_fishbonesSubs.size() ); + int newIndex = static_cast( m_fishbones.size() ); if ( qWellPathColor.lightnessF() < 0.5 ) { @@ -252,15 +251,15 @@ void RimFishbonesCollection::recalculateStartMD() { double minStartMD = HUGE_VAL; - for ( const RimFishbonesMultipleSubs* sub : m_fishbonesSubs() ) + for ( const RimFishbones* sub : m_fishbones() ) { - for ( auto& index : sub->installedLateralIndices() ) + for ( const auto& subAndLateralIndex : sub->installedLateralIndices() ) { - minStartMD = std::min( minStartMD, sub->measuredDepth( index.subIndex ) - 13.0 ); + minStartMD = std::min( minStartMD, sub->measuredDepth( subAndLateralIndex.first ) - 13.0 ); } } - for ( const RimFishboneWellPath* wellPath : m_wellPathCollection->wellPaths() ) + for ( const RimImportedFishboneLaterals* wellPath : m_wellPathCollection->wellPaths() ) { if ( wellPath->measuredDepths().size() > 0 ) { @@ -282,6 +281,21 @@ double RimFishbonesCollection::startMD() const return m_startMD; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFishbonesCollection::endMD() const +{ + double endMD = m_startMD; + if ( !m_fishbones.empty() ) + { + auto lastFishbone = m_fishbones.childObjects().back(); + CVF_ASSERT( lastFishbone ); + endMD = lastFishbone->endMD(); + } + return endMD; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -322,5 +336,4 @@ void RimFishbonesCollection::setUnitSystemSpecificDefaults() m_wellPathCollection->setUnitSystemSpecificDefaults(); } - m_mswParameters->setUnitSystemSpecificDefaults(); } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.h b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.h index 6c99b45ff3..a4fde9c44b 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFishbonesCollection.h @@ -29,8 +29,8 @@ #include "cvfColor3.h" -class RimFishbonesMultipleSubs; -class RimFishboneWellPathCollection; +class RimFishbones; +class RimImportedFishboneLateralsCollection; //================================================================================================== // @@ -44,15 +44,16 @@ class RimFishbonesCollection : public RimCheckableNamedObject public: RimFishbonesCollection(); - RimFishboneWellPathCollection* wellPathCollection() const; - void appendFishbonesSubs( RimFishbonesMultipleSubs* subs ); - const RimMswCompletionParameters* mswParameters() const; + RimImportedFishboneLateralsCollection* wellPathCollection() const; + void appendFishbonesSubs( RimFishbones* subs ); - std::vector activeFishbonesSubs() const; - std::vector allFishbonesSubs() const; + bool hasFishbones() const; + std::vector activeFishbonesSubs() const; + std::vector allFishbonesSubs() const; void recalculateStartMD(); double startMD() const; + double endMD() const; double mainBoreSkinFactor() const { return m_skinFactor; } double mainBoreDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const; void setUnitSystemSpecificDefaults(); @@ -66,18 +67,18 @@ private: cvf::Color3f nextFishbonesColor() const; private: - caf::PdmChildArrayField m_fishbonesSubs; - caf::PdmChildField m_wellPathCollection; + caf::PdmChildArrayField m_fishbones; + caf::PdmChildField m_wellPathCollection; - caf::PdmField m_startMD; - caf::PdmField m_skinFactor; - caf::PdmField m_mainBoreDiameter; - caf::PdmChildField m_mswParameters; - bool manuallyModifiedStartMD; + caf::PdmField m_startMD; + caf::PdmField m_skinFactor; + caf::PdmField m_mainBoreDiameter; + bool manuallyModifiedStartMD; caf::PdmField m_linerDiameter_OBSOLETE; caf::PdmField m_roughnessFactor_OBSOLETE; caf::PdmField m_pressureDrop_OBSOLETE; caf::PdmField m_lengthAndDepth_OBSOLETE; + caf::PdmChildField m_mswParameters_OBSOLETE; }; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLaterals.cpp similarity index 81% rename from ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp rename to ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLaterals.cpp index 7867b05b3f..643ae2149b 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLaterals.cpp @@ -17,19 +17,19 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RimFishboneWellPath.h" +#include "RimImportedFishboneLaterals.h" #include "RimProject.h" #include "cafPdmUiListEditor.h" #include "cafPdmUiTextEditor.h" -CAF_PDM_SOURCE_INIT( RimFishboneWellPath, "WellPathCompletion" ); +CAF_PDM_SOURCE_INIT( RimImportedFishboneLaterals, "WellPathCompletion" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishboneWellPath::RimFishboneWellPath() +RimImportedFishboneLaterals::RimImportedFishboneLaterals() { CAF_PDM_InitObject( "WellPathCompletion", ":/FishBoneLateralFromFile16x16.png", "", "" ); CAF_PDM_InitFieldNoDefault( &m_coordinates, "Coordinates", "Coordinates", "", "", "" ); @@ -41,7 +41,7 @@ RimFishboneWellPath::RimFishboneWellPath() userDescriptionField()->uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_displayCoordinates, "DisplayCoordinates", "Coordinates", "", "", "" ); - m_displayCoordinates.registerGetMethod( this, &RimFishboneWellPath::displayCoordinates ); + m_displayCoordinates.registerGetMethod( this, &RimImportedFishboneLaterals::displayCoordinates ); m_displayCoordinates.uiCapability()->setUiReadOnly( true ); m_displayCoordinates.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() ); m_displayCoordinates.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosType::TOP ); @@ -52,14 +52,14 @@ RimFishboneWellPath::RimFishboneWellPath() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishboneWellPath::~RimFishboneWellPath() +RimImportedFishboneLaterals::~RimImportedFishboneLaterals() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPath::setCoordinates( std::vector coordinates ) +void RimImportedFishboneLaterals::setCoordinates( std::vector coordinates ) { m_coordinates = coordinates; } @@ -67,7 +67,7 @@ void RimFishboneWellPath::setCoordinates( std::vector coordinates ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPath::setMeasuredDepths( std::vector measuredDepths ) +void RimImportedFishboneLaterals::setMeasuredDepths( std::vector measuredDepths ) { m_measuredDepths = measuredDepths; } @@ -75,9 +75,9 @@ void RimFishboneWellPath::setMeasuredDepths( std::vector measuredDepths //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue ) +void RimImportedFishboneLaterals::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) { RimProject* proj; this->firstAncestorOrThisOfType( proj ); @@ -87,7 +87,7 @@ void RimFishboneWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedFi //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +void RimImportedFishboneLaterals::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { uiOrdering.add( &m_displayCoordinates ); } @@ -95,7 +95,7 @@ void RimFishboneWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrde //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimFishboneWellPath::displayCoordinates() const +QString RimImportedFishboneLaterals::displayCoordinates() const { CVF_ASSERT( m_coordinates().size() == m_measuredDepths().size() ); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPath.h b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLaterals.h similarity index 93% rename from ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPath.h rename to ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLaterals.h index 03727bf2f6..2eeb544941 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPath.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLaterals.h @@ -40,13 +40,13 @@ /// /// //================================================================================================== -class RimFishboneWellPath : public RimCheckableNamedObject +class RimImportedFishboneLaterals : public RimCheckableNamedObject { CAF_PDM_HEADER_INIT; public: - RimFishboneWellPath(); - ~RimFishboneWellPath() override; + RimImportedFishboneLaterals(); + ~RimImportedFishboneLaterals() override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLateralsCollection.cpp similarity index 75% rename from ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp rename to ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLateralsCollection.cpp index d1f8553457..0b4d2f7f02 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLateralsCollection.cpp @@ -17,11 +17,11 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RimFishboneWellPathCollection.h" +#include "RimImportedFishboneLateralsCollection.h" #include "Rim3dView.h" -#include "RimFishboneWellPath.h" #include "RimFishbonesCollection.h" +#include "RimImportedFishboneLaterals.h" #include "RimProject.h" #include "RigWellPath.h" @@ -30,12 +30,14 @@ #include "Riu3DMainWindowTools.h" -CAF_PDM_SOURCE_INIT( RimFishboneWellPathCollection, "WellPathCompletionCollection" ); +// The more general term WellPathCompletionCollection was unfortunately used in this more specific case of fishbones +// In order to preserve compatibility, the old keyword is kept as an alias, but could be removed in the future. +CAF_PDM_SOURCE_INIT( RimImportedFishboneLateralsCollection, "FishboneWellPathCollection", "WellPathCompletionCollection" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFishboneWellPathCollection::RimFishboneWellPathCollection() +RimImportedFishboneLateralsCollection::RimImportedFishboneLateralsCollection() { CAF_PDM_InitObject( "WellPathCompletions", ":/FishBoneGroupFromFile16x16.png", "", "" ); @@ -55,7 +57,7 @@ RimFishboneWellPathCollection::RimFishboneWellPathCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPathCollection::importCompletionsFromFile( const QStringList& filePaths ) +void RimImportedFishboneLateralsCollection::importCompletionsFromFile( const QStringList& filePaths ) { RifWellPathImporter wellPathImporter; @@ -66,7 +68,7 @@ void RimFishboneWellPathCollection::importCompletionsFromFile( const QStringList for ( size_t i = 0; i < wellDataCount; ++i ) { RifWellPathImporter::WellData wellData = wellPathImporter.readWellData( filePath, i ); - RimFishboneWellPath* wellCompletion = new RimFishboneWellPath(); + RimImportedFishboneLaterals* wellCompletion = new RimImportedFishboneLaterals(); wellCompletion->setName( wellData.m_name ); wellCompletion->setCoordinates( wellData.m_wellPathGeometry->uniqueWellPathPoints() ); wellCompletion->setMeasuredDepths( wellData.m_wellPathGeometry->uniqueMeasuredDepths() ); @@ -85,9 +87,9 @@ void RimFishboneWellPathCollection::importCompletionsFromFile( const QStringList //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPathCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue ) +void RimImportedFishboneLateralsCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) { RimProject* proj; this->firstAncestorOrThisOfTypeAsserted( proj ); @@ -97,11 +99,11 @@ void RimFishboneWellPathCollection::fieldChangedByUi( const caf::PdmFieldHandle* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimFishboneWellPathCollection::wellPaths() const +std::vector RimImportedFishboneLateralsCollection::wellPaths() const { - std::vector paths; + std::vector paths; - for ( const RimFishboneWellPath* path : m_wellPaths ) + for ( const RimImportedFishboneLaterals* path : m_wellPaths ) { paths.push_back( path ); } @@ -112,7 +114,7 @@ std::vector RimFishboneWellPathCollection::wellPaths //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPathCollection::setUnitSystemSpecificDefaults() +void RimImportedFishboneLateralsCollection::setUnitSystemSpecificDefaults() { m_pipeProperties->setUnitSystemSpecificDefaults(); } @@ -120,7 +122,7 @@ void RimFishboneWellPathCollection::setUnitSystemSpecificDefaults() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPathCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +void RimImportedFishboneLateralsCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { caf::PdmUiGroup* wellPropertiesGroup = uiOrdering.addNewGroup( "Well Properties" ); m_pipeProperties->uiOrdering( uiConfigName, *wellPropertiesGroup ); @@ -129,7 +131,7 @@ void RimFishboneWellPathCollection::defineUiOrdering( QString uiConfigName, caf: //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishboneWellPathCollection::appendCompletion( RimFishboneWellPath* completion ) +void RimImportedFishboneLateralsCollection::appendCompletion( RimImportedFishboneLaterals* completion ) { m_wellPaths.push_back( completion ); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLateralsCollection.h similarity index 76% rename from ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h rename to ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLateralsCollection.h index 0c3fd4147f..a4c086ebdc 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimImportedFishboneLateralsCollection.h @@ -20,8 +20,8 @@ #pragma once #include "RimCheckableNamedObject.h" -#include "RimFishboneWellPath.h" #include "RimFishbonesPipeProperties.h" +#include "RimImportedFishboneLaterals.h" #include "RiaDefines.h" @@ -35,19 +35,19 @@ // // //================================================================================================== -class RimFishboneWellPathCollection : public RimCheckableNamedObject +class RimImportedFishboneLateralsCollection : public RimCheckableNamedObject { CAF_PDM_HEADER_INIT; public: - RimFishboneWellPathCollection(); + RimImportedFishboneLateralsCollection(); void importCompletionsFromFile( const QStringList& filePaths ); void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - std::vector wellPaths() const; - double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const + std::vector wellPaths() const; + double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const { return m_pipeProperties->holeDiameter( unitSystem ); } @@ -59,9 +59,9 @@ protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; private: - void appendCompletion( RimFishboneWellPath* completion ); + void appendCompletion( RimImportedFishboneLaterals* completion ); private: - caf::PdmChildArrayField m_wellPaths; - caf::PdmChildField m_pipeProperties; + caf::PdmChildArrayField m_wellPaths; + caf::PdmChildField m_pipeProperties; }; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp index 3b2f70d8ca..41e365ea39 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp @@ -102,6 +102,33 @@ RimMswCompletionParameters::~RimMswCompletionParameters() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimMswCompletionParameters::isDefault() const +{ + return m_refMDType() == ReferenceMDEnum() && m_refMD() == m_refMD.defaultValue() && + m_linerDiameter() == m_linerDiameter.defaultValue() && + m_roughnessFactor() == m_roughnessFactor.defaultValue() && m_pressureDrop == PressureDropEnum() && + m_enforceMaxSegmentLength() == m_enforceMaxSegmentLength.defaultValue() && + m_maxSegmentLength() == m_maxSegmentLength.defaultValue(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswCompletionParameters& RimMswCompletionParameters::operator=( const RimMswCompletionParameters& rhs ) +{ + m_refMDType = rhs.m_refMDType(); + m_refMD = rhs.m_refMD(); + m_linerDiameter = rhs.m_linerDiameter(); + m_roughnessFactor = rhs.m_roughnessFactor(); + m_pressureDrop = rhs.m_pressureDrop(); + m_enforceMaxSegmentLength = rhs.m_enforceMaxSegmentLength(); + m_maxSegmentLength = rhs.m_maxSegmentLength(); + return *this; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.h b/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.h index 66b9a78417..f91c5f3899 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimMswCompletionParameters.h @@ -54,6 +54,9 @@ public: RimMswCompletionParameters( bool enableReferenceDepth = true ); ~RimMswCompletionParameters() override; + bool isDefault() const; + RimMswCompletionParameters& operator=( const RimMswCompletionParameters& rhs ); + ReferenceMDType referenceMDType() const; double manualReferenceMD() const; double linerDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp index 5d2f586d07..e7774cfd2d 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp @@ -22,7 +22,7 @@ #include "RiaEclipseUnitTools.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimPerforationInterval.h" #include "RimWellPath.h" #include "RimWellPathValve.h" @@ -356,8 +356,8 @@ void RimMultipleValveLocations::fieldChangedByUi( const caf::PdmFieldHandle* cha { if ( parentCompletion ) { - RimFishbonesMultipleSubs* fishbones = dynamic_cast( parentCompletion ); - RimWellPathValve* valve = dynamic_cast( parentCompletion ); + RimFishbones* fishbones = dynamic_cast( parentCompletion ); + RimWellPathValve* valve = dynamic_cast( parentCompletion ); if ( fishbones ) { fishbones->recomputeLateralLocations(); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.cpp index 269a10bda5..60b33d11a5 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.cpp @@ -60,10 +60,10 @@ RimPerforationCollection::RimPerforationCollection() CAF_PDM_InitFieldNoDefault( &m_perforations, "Perforations", "Perforations", "", "", "" ); m_perforations.uiCapability()->setUiHidden( true ); - CAF_PDM_InitFieldNoDefault( &m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); - m_mswParameters = new RimMswCompletionParameters; - m_mswParameters.uiCapability()->setUiTreeHidden( true ); - m_mswParameters.uiCapability()->setUiTreeChildrenHidden( true ); + CAF_PDM_InitFieldNoDefault( &m_mswParameters_OBSOLETE, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); + m_mswParameters_OBSOLETE = new RimMswCompletionParameters; + m_mswParameters_OBSOLETE.uiCapability()->setUiTreeHidden( true ); + m_mswParameters_OBSOLETE.uiCapability()->setUiTreeChildrenHidden( true ); CAF_PDM_InitFieldNoDefault( &m_nonDarcyParameters, "NonDarcyParameters", "Non-Darcy Parameters", "", "", "" ); m_nonDarcyParameters = new RimNonDarcyPerforationParameters(); @@ -82,9 +82,9 @@ RimPerforationCollection::~RimPerforationCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RimMswCompletionParameters* RimPerforationCollection::mswParameters() const +bool RimPerforationCollection::hasPerforations() const { - return m_mswParameters; + return !m_perforations.empty(); } //-------------------------------------------------------------------------------------------------- @@ -95,14 +95,6 @@ const RimNonDarcyPerforationParameters* RimPerforationCollection::nonDarcyParame return m_nonDarcyParameters; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimPerforationCollection::setUnitSystemSpecificDefaults() -{ - m_mswParameters->setUnitSystemSpecificDefaults(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -190,7 +182,7 @@ std::vector RimPerforationCollection::activePerfo void RimPerforationCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Multi Segment Well Options" ); - m_mswParameters->uiOrdering( uiConfigName, *mswGroup ); + m_mswParameters_OBSOLETE->uiOrdering( uiConfigName, *mswGroup ); m_nonDarcyParameters->uiOrdering( uiConfigName, uiOrdering ); uiOrdering.skipRemainingFields( true ); } @@ -212,4 +204,4 @@ void RimPerforationCollection::fieldChangedByUi( const caf::PdmFieldHandle* chan { proj->scheduleCreateDisplayModelAndRedrawAllViews(); } -} \ No newline at end of file +} diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.h b/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.h index 5184b776d9..4fb710fc6b 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimPerforationCollection.h @@ -50,9 +50,8 @@ public: RimPerforationCollection(); ~RimPerforationCollection() override; - const RimMswCompletionParameters* mswParameters() const; + bool hasPerforations() const; const RimNonDarcyPerforationParameters* nonDarcyParameters() const; - void setUnitSystemSpecificDefaults(); void appendPerforation( RimPerforationInterval* perforation ); std::vector perforations() const; std::vector activePerforations() const; @@ -65,6 +64,7 @@ private: private: caf::PdmChildArrayField m_perforations; - caf::PdmChildField m_mswParameters; caf::PdmChildField m_nonDarcyParameters; + + caf::PdmChildField m_mswParameters_OBSOLETE; }; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionInterface b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionInterface deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionSettings.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionSettings.cpp new file mode 100644 index 0000000000..61d391cdc3 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionSettings.cpp @@ -0,0 +1,377 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimWellPathCompletionSettings.h" + +#include "RiaStdStringTools.h" +#include "RimMswCompletionParameters.h" + +#include "cafPdmDoubleStringValidator.h" +#include "cafPdmUiLineEditor.h" +#include "cafPdmUiOrdering.h" +#include "cafPdmUiTreeOrdering.h" + +namespace caf +{ +template <> +void RimWellPathCompletionSettings::WellTypeEnum::setUp() +{ + addItem( RimWellPathCompletionSettings::OIL, "OIL", "Oil" ); + addItem( RimWellPathCompletionSettings::GAS, "GAS", "Gas" ); + addItem( RimWellPathCompletionSettings::WATER, "WATER", "Water" ); + addItem( RimWellPathCompletionSettings::LIQUID, "LIQUID", "Liquid" ); + + setDefault( RimWellPathCompletionSettings::OIL ); +} + +template <> +void RimWellPathCompletionSettings::GasInflowEnum::setUp() +{ + addItem( RimWellPathCompletionSettings::STANDARD_EQ, "STD", "Standard" ); + addItem( RimWellPathCompletionSettings::RUSSELL_GOODRICH, "R-G", "Russell-Goodrich" ); + addItem( RimWellPathCompletionSettings::DRY_GAS_PSEUDO_PRESSURE, "P-P", "Dry Gas Pseudo-Pressure" ); + addItem( RimWellPathCompletionSettings::GENERALIZED_PSEUDO_PRESSURE, "GPP", "Generalized Pseudo-Pressure" ); + + setDefault( RimWellPathCompletionSettings::STANDARD_EQ ); +} + +template <> +void RimWellPathCompletionSettings::AutomaticWellShutInEnum::setUp() +{ + addItem( RimWellPathCompletionSettings::ISOLATE_FROM_FORMATION, "SHUT", "Isolate from Formation" ); + addItem( RimWellPathCompletionSettings::STOP_ABOVE_FORMATION, "STOP", "Stop above Formation" ); + + setDefault( RimWellPathCompletionSettings::STOP_ABOVE_FORMATION ); +} + +template <> +void RimWellPathCompletionSettings::HydrostaticDensityEnum::setUp() +{ + addItem( RimWellPathCompletionSettings::SEGMENTED, "SEG", "Segmented" ); + addItem( RimWellPathCompletionSettings::AVERAGED, "AVG", "Averaged" ); + + setDefault( RimWellPathCompletionSettings::SEGMENTED ); +} + +} // namespace caf + +CAF_PDM_SOURCE_INIT( RimWellPathCompletionSettings, "WellPathCompletionSettings" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathCompletionSettings::RimWellPathCompletionSettings() +{ + CAF_PDM_InitObject( "Completion Settings", ":/CompletionsSymbol16x16.png", "", "" ); + CAF_PDM_InitField( &m_wellNameForExport, "WellNameForExport", QString(), "Well Name", "", "", "" ); + m_wellNameForExport.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() ); + + CAF_PDM_InitField( &m_wellGroupName, "WellGroupNameForExport", QString(), "Well Group Name", "", "", "" ); + CAF_PDM_InitField( &m_referenceDepth, "ReferenceDepthForExport", QString(), "Reference Depth for BHP", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_preferredFluidPhase, "WellTypeForExport", "Preferred Fluid Phase", "", "", "" ); + CAF_PDM_InitField( &m_drainageRadiusForPI, "DrainageRadiusForPI", QString( "0.0" ), "Drainage Radius for PI", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_gasInflowEquation, "GasInflowEq", "Gas Inflow Equation", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_automaticWellShutIn, "AutoWellShutIn", "Automatic well shut-in", "", "", "" ); + CAF_PDM_InitField( &m_allowWellCrossFlow, "AllowWellCrossFlow", true, "Allow Well Cross-Flow", "", "", "" ); + CAF_PDM_InitField( &m_wellBoreFluidPVTTable, "WellBoreFluidPVTTable", 0, "Wellbore Fluid PVT table", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_hydrostaticDensity, "HydrostaticDensity", "Hydrostatic Density", "", "", "" ); + CAF_PDM_InitField( &m_fluidInPlaceRegion, "FluidInPlaceRegion", 0, "Fluid In-Place Region", "", "", "" ); + + CAF_PDM_InitFieldNoDefault( &m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); + m_mswParameters = new RimMswCompletionParameters( false ); + m_mswParameters.uiCapability()->setUiTreeHidden( true ); + m_mswParameters.uiCapability()->setUiTreeChildrenHidden( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathCompletionSettings::RimWellPathCompletionSettings( const RimWellPathCompletionSettings& rhs ) + : RimWellPathCompletionSettings() +{ + *this = rhs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathCompletionSettings& RimWellPathCompletionSettings::operator=( const RimWellPathCompletionSettings& rhs ) +{ + m_wellNameForExport = rhs.m_wellNameForExport; + m_wellGroupName = rhs.m_wellGroupName; + m_referenceDepth = rhs.m_referenceDepth; + m_preferredFluidPhase = rhs.m_preferredFluidPhase; + m_drainageRadiusForPI = rhs.m_drainageRadiusForPI; + m_gasInflowEquation = rhs.m_gasInflowEquation; + m_automaticWellShutIn = rhs.m_automaticWellShutIn; + m_allowWellCrossFlow = rhs.m_allowWellCrossFlow; + m_wellBoreFluidPVTTable = rhs.m_wellBoreFluidPVTTable; + m_hydrostaticDensity = rhs.m_hydrostaticDensity; + m_fluidInPlaceRegion = rhs.m_fluidInPlaceRegion; + return *this; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletionSettings::setWellNameForExport( const QString& name ) +{ + auto n = name; + m_wellNameForExport = n.remove( ' ' ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletionSettings::updateWellPathNameHasChanged( const QString& newWellPathName, + const QString& previousWellPathName ) +{ + if ( m_wellNameForExport().isEmpty() || m_wellNameForExport == previousWellPathName ) + { + m_wellNameForExport = newWellPathName; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::wellNameForExport() const +{ + return formatStringForExport( m_wellNameForExport() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::wellGroupNameForExport() const +{ + return formatStringForExport( m_wellGroupName, "1*" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::referenceDepthForExport() const +{ + std::string refDepth = m_referenceDepth.v().toStdString(); + if ( RiaStdStringTools::isNumber( refDepth, '.' ) ) + { + return m_referenceDepth.v(); + } + return "1*"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::wellTypeNameForExport() const +{ + switch ( m_preferredFluidPhase.v() ) + { + case OIL: + return "OIL"; + case GAS: + return "GAS"; + case WATER: + return "WATER"; + case LIQUID: + return "LIQ"; + } + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::drainageRadiusForExport() const +{ + return m_drainageRadiusForPI(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::gasInflowEquationForExport() const +{ + return m_gasInflowEquation().text(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::automaticWellShutInForExport() const +{ + return m_automaticWellShutIn().text(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::allowWellCrossFlowForExport() const +{ + return m_allowWellCrossFlow() ? "YES" : "NO"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::wellBoreFluidPVTForExport() const +{ + return QString( "%1" ).arg( m_wellBoreFluidPVTTable() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::hydrostaticDensityForExport() const +{ + return m_hydrostaticDensity().text(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::fluidInPlaceRegionForExport() const +{ + return QString( "%1" ).arg( m_fluidInPlaceRegion() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletionSettings::setUnitSystemSpecificDefaults() +{ + m_mswParameters->setUnitSystemSpecificDefaults(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimMswCompletionParameters* RimWellPathCompletionSettings::mswParameters() const +{ + return m_mswParameters(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswCompletionParameters* RimWellPathCompletionSettings::mswParameters() +{ + return m_mswParameters(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QRegExp RimWellPathCompletionSettings::wellNameForExportRegExp() +{ + QRegExp rx( "[\\w\\-\\_]{1,8}" ); + return rx; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletionSettings::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + caf::PdmUiGroup* compExportGroup = uiOrdering.addNewGroup( "Completion Export Parameters" ); + compExportGroup->add( &m_wellNameForExport ); + compExportGroup->add( &m_wellGroupName ); + compExportGroup->add( &m_referenceDepth ); + compExportGroup->add( &m_preferredFluidPhase ); + compExportGroup->add( &m_drainageRadiusForPI ); + compExportGroup->add( &m_gasInflowEquation ); + compExportGroup->add( &m_automaticWellShutIn ); + compExportGroup->add( &m_allowWellCrossFlow ); + compExportGroup->add( &m_wellBoreFluidPVTTable ); + compExportGroup->add( &m_hydrostaticDensity ); + compExportGroup->add( &m_fluidInPlaceRegion ); + + caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Multi Segment Well Options" ); + m_mswParameters->uiOrdering( uiConfigName, *mswGroup ); + uiOrdering.skipRemainingFields( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletionSettings::fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) +{ + if ( changedField == &m_referenceDepth ) + { + if ( !RiaStdStringTools::isNumber( m_referenceDepth.v().toStdString(), '.' ) ) + { + if ( !RiaStdStringTools::isNumber( m_referenceDepth.v().toStdString(), ',' ) ) + { + // Remove invalid input text + m_referenceDepth = ""; + } + else + { + // Wrong decimal sign entered, replace , by . + auto text = m_referenceDepth.v(); + m_referenceDepth = text.replace( ',', '.' ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletionSettings::defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) +{ + caf::PdmUiLineEditorAttribute* lineEditorAttr = dynamic_cast( attribute ); + if ( field == &m_wellNameForExport && lineEditorAttr ) + { + QRegExpValidator* validator = new QRegExpValidator( nullptr ); + validator->setRegExp( wellNameForExportRegExp() ); + lineEditorAttr->validator = validator; + } + else if ( field == &m_drainageRadiusForPI && lineEditorAttr ) + { + caf::PdmDoubleStringValidator* validator = new caf::PdmDoubleStringValidator( "1*" ); + lineEditorAttr->validator = validator; + } + else if ( field == &m_wellBoreFluidPVTTable && lineEditorAttr ) + { + // Positive integer + QIntValidator* validator = new QIntValidator( 0, std::numeric_limits::max(), nullptr ); + lineEditorAttr->validator = validator; + } + else if ( field == &m_fluidInPlaceRegion && lineEditorAttr ) + { + // Any integer + QIntValidator* validator = + new QIntValidator( -std::numeric_limits::max(), std::numeric_limits::max(), nullptr ); + lineEditorAttr->validator = validator; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletionSettings::formatStringForExport( const QString& text, const QString& defaultValue ) const +{ + if ( text.isEmpty() ) return defaultValue; + if ( text.contains( ' ' ) ) return QString( "'%1'" ).arg( text ); + return text; +} diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionSettings.h b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionSettings.h new file mode 100644 index 0000000000..96cfaebe3c --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletionSettings.h @@ -0,0 +1,117 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021- 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 "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimMswCompletionParameters; +class RimWellPathCompletionsLegacy; + +class RimWellPathCompletionSettings : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + enum WellType + { + OIL, + GAS, + WATER, + LIQUID + }; + typedef caf::AppEnum WellTypeEnum; + + enum GasInflowEquation + { + STANDARD_EQ, + RUSSELL_GOODRICH, + DRY_GAS_PSEUDO_PRESSURE, + GENERALIZED_PSEUDO_PRESSURE + }; + typedef caf::AppEnum GasInflowEnum; + + enum AutomaticWellShutIn + { + ISOLATE_FROM_FORMATION, + STOP_ABOVE_FORMATION + }; + typedef caf::AppEnum AutomaticWellShutInEnum; + + enum HydrostaticDensity + { + SEGMENTED, + AVERAGED + }; + typedef caf::AppEnum HydrostaticDensityEnum; + +public: + RimWellPathCompletionSettings(); + RimWellPathCompletionSettings( const RimWellPathCompletionSettings& rhs ); + RimWellPathCompletionSettings& operator=( const RimWellPathCompletionSettings& rhs ); + + void setWellNameForExport( const QString& name ); + void updateWellPathNameHasChanged( const QString& newWellPathName, const QString& previousWellPathName ); + QString wellNameForExport() const; + QString wellGroupNameForExport() const; + QString referenceDepthForExport() const; + QString wellTypeNameForExport() const; + + QString drainageRadiusForExport() const; + QString gasInflowEquationForExport() const; + QString automaticWellShutInForExport() const; + QString allowWellCrossFlowForExport() const; + QString wellBoreFluidPVTForExport() const; + QString hydrostaticDensityForExport() const; + QString fluidInPlaceRegionForExport() const; + void setUnitSystemSpecificDefaults(); + + const RimMswCompletionParameters* mswParameters() const; + RimMswCompletionParameters* mswParameters(); + + static QRegExp wellNameForExportRegExp(); + +protected: + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) override; + +private: + QString formatStringForExport( const QString& text, const QString& defaultText = "" ) const; + +private: + friend class RimWellPathCompletions; + + caf::PdmField m_wellNameForExport; + caf::PdmField m_wellGroupName; + + caf::PdmField m_referenceDepth; + caf::PdmField m_preferredFluidPhase; + caf::PdmField m_drainageRadiusForPI; + caf::PdmField m_gasInflowEquation; + caf::PdmField m_automaticWellShutIn; + caf::PdmField m_allowWellCrossFlow; + caf::PdmField m_wellBoreFluidPVTTable; + caf::PdmField m_hydrostaticDensity; + caf::PdmField m_fluidInPlaceRegion; + + caf::PdmChildField m_mswParameters; +}; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp index 22596ef1be..fad009ea4f 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp @@ -20,13 +20,15 @@ #include "RiaStdStringTools.h" -#include "RimFishboneWellPathCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" +#include "RimProject.h" #include "RimStimPlanModel.h" #include "RimStimPlanModelCollection.h" +#include "RimWellPath.h" #include "RimWellPathComponentInterface.h" #include "RimWellPathFracture.h" #include "RimWellPathFractureCollection.h" @@ -39,58 +41,8 @@ #include "cafPdmUiLineEditor.h" #include "cafPdmUiTreeOrdering.h" -#include #include -//-------------------------------------------------------------------------------------------------- -/// Internal constants -//-------------------------------------------------------------------------------------------------- -#define DOUBLE_INF std::numeric_limits::infinity() - -namespace caf -{ -template <> -void RimWellPathCompletions::WellTypeEnum::setUp() -{ - addItem( RimWellPathCompletions::OIL, "OIL", "Oil" ); - addItem( RimWellPathCompletions::GAS, "GAS", "Gas" ); - addItem( RimWellPathCompletions::WATER, "WATER", "Water" ); - addItem( RimWellPathCompletions::LIQUID, "LIQUID", "Liquid" ); - - setDefault( RimWellPathCompletions::OIL ); -} - -template <> -void RimWellPathCompletions::GasInflowEnum::setUp() -{ - addItem( RimWellPathCompletions::STANDARD_EQ, "STD", "Standard" ); - addItem( RimWellPathCompletions::RUSSELL_GOODRICH, "R-G", "Russell-Goodrich" ); - addItem( RimWellPathCompletions::DRY_GAS_PSEUDO_PRESSURE, "P-P", "Dry Gas Pseudo-Pressure" ); - addItem( RimWellPathCompletions::GENERALIZED_PSEUDO_PRESSURE, "GPP", "Generalized Pseudo-Pressure" ); - - setDefault( RimWellPathCompletions::STANDARD_EQ ); -} - -template <> -void RimWellPathCompletions::AutomaticWellShutInEnum::setUp() -{ - addItem( RimWellPathCompletions::ISOLATE_FROM_FORMATION, "SHUT", "Isolate from Formation" ); - addItem( RimWellPathCompletions::STOP_ABOVE_FORMATION, "STOP", "Stop above Formation" ); - - setDefault( RimWellPathCompletions::STOP_ABOVE_FORMATION ); -} - -template <> -void RimWellPathCompletions::HydrostaticDensityEnum::setUp() -{ - addItem( RimWellPathCompletions::SEGMENTED, "SEG", "Segmented" ); - addItem( RimWellPathCompletions::AVERAGED, "AVG", "Averaged" ); - - setDefault( RimWellPathCompletions::SEGMENTED ); -} - -} // namespace caf - CAF_PDM_SOURCE_INIT( RimWellPathCompletions, "WellPathCompletions" ); //-------------------------------------------------------------------------------------------------- @@ -116,19 +68,34 @@ RimWellPathCompletions::RimWellPathCompletions() m_stimPlanModelCollection = new RimStimPlanModelCollection; m_stimPlanModelCollection.uiCapability()->setUiHidden( true ); - CAF_PDM_InitField( &m_wellNameForExport, "WellNameForExport", QString(), "Well Name", "", "", "" ); - m_wellNameForExport.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() ); - - CAF_PDM_InitField( &m_wellGroupName, "WellGroupNameForExport", QString(), "Well Group Name", "", "", "" ); - CAF_PDM_InitField( &m_referenceDepth, "ReferenceDepthForExport", QString(), "Reference Depth for BHP", "", "", "" ); - CAF_PDM_InitField( &m_preferredFluidPhase, "WellTypeForExport", WellTypeEnum(), "Preferred Fluid Phase", "", "", "" ); - CAF_PDM_InitField( &m_drainageRadiusForPI, "DrainageRadiusForPI", QString( "0.0" ), "Drainage Radius for PI", "", "", "" ); - CAF_PDM_InitFieldNoDefault( &m_gasInflowEquation, "GasInflowEq", "Gas Inflow Equation", "", "", "" ); - CAF_PDM_InitFieldNoDefault( &m_automaticWellShutIn, "AutoWellShutIn", "Automatic well shut-in", "", "", "" ); - CAF_PDM_InitField( &m_allowWellCrossFlow, "AllowWellCrossFlow", true, "Allow Well Cross-Flow", "", "", "" ); - CAF_PDM_InitField( &m_wellBoreFluidPVTTable, "WellBoreFluidPVTTable", 0, "Wellbore Fluid PVT table", "", "", "" ); - CAF_PDM_InitFieldNoDefault( &m_hydrostaticDensity, "HydrostaticDensity", "Hydrostatic Density", "", "", "" ); - CAF_PDM_InitField( &m_fluidInPlaceRegion, "FluidInPlaceRegion", 0, "Fluid In-Place Region", "", "", "" ); + CAF_PDM_InitField( &m_wellNameForExport_OBSOLETE, "WellNameForExport", QString(), "Well Name", "", "", "" ); + m_wellNameForExport_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitField( &m_wellGroupName_OBSOLETE, "WellGroupNameForExport", QString(), "Well Group Name", "", "", "" ); + m_wellGroupName_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitField( &m_referenceDepth_OBSOLETE, "ReferenceDepthForExport", QString(), "Reference Depth for BHP", "", "", "" ); + m_referenceDepth_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitFieldNoDefault( &m_preferredFluidPhase_OBSOLETE, "WellTypeForExport", "Preferred Fluid Phase", "", "", "" ); + m_preferredFluidPhase_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitField( &m_drainageRadiusForPI_OBSOLETE, + "DrainageRadiusForPI", + QString( "0.0" ), + "Drainage Radius for PI", + "", + "", + "" ); + m_drainageRadiusForPI_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitFieldNoDefault( &m_gasInflowEquation_OBSOLETE, "GasInflowEq", "Gas Inflow Equation", "", "", "" ); + m_gasInflowEquation_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitFieldNoDefault( &m_automaticWellShutIn_OBSOLETE, "AutoWellShutIn", "Automatic well shut-in", "", "", "" ); + m_automaticWellShutIn_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitField( &m_allowWellCrossFlow_OBSOLETE, "AllowWellCrossFlow", true, "Allow Well Cross-Flow", "", "", "" ); + m_allowWellCrossFlow_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitField( &m_wellBoreFluidPVTTable_OBSOLETE, "WellBoreFluidPVTTable", 0, "Wellbore Fluid PVT table", "", "", "" ); + m_wellBoreFluidPVTTable_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitFieldNoDefault( &m_hydrostaticDensity_OBSOLETE, "HydrostaticDensity", "Hydrostatic Density", "", "", "" ); + m_hydrostaticDensity_OBSOLETE.xmlCapability()->setIOWritable( false ); + CAF_PDM_InitField( &m_fluidInPlaceRegion_OBSOLETE, "FluidInPlaceRegion", 0, "Fluid In-Place Region", "", "", "" ); + m_fluidInPlaceRegion_OBSOLETE.xmlCapability()->setIOWritable( false ); } //-------------------------------------------------------------------------------------------------- @@ -151,75 +118,6 @@ RimPerforationCollection* RimWellPathCompletions::perforationCollection() const return m_perforationCollection; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathCompletions::setWellNameForExport( const QString& name ) -{ - auto n = name; - m_wellNameForExport = n.remove( ' ' ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathCompletions::updateWellPathNameHasChanged( const QString& newWellPathName, - const QString& previousWellPathName ) -{ - if ( m_wellNameForExport == previousWellPathName ) - { - m_wellNameForExport = newWellPathName; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::wellNameForExport() const -{ - return formatStringForExport( m_wellNameForExport() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::wellGroupNameForExport() const -{ - return formatStringForExport( m_wellGroupName, "1*" ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::referenceDepthForExport() const -{ - std::string refDepth = m_referenceDepth.v().toStdString(); - if ( RiaStdStringTools::isNumber( refDepth, '.' ) ) - { - return m_referenceDepth.v(); - } - return "1*"; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::wellTypeNameForExport() const -{ - switch ( m_preferredFluidPhase.v() ) - { - case OIL: - return "OIL"; - case GAS: - return "GAS"; - case WATER: - return "WATER"; - case LIQUID: - return "LIQ"; - } - return ""; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -250,6 +148,30 @@ std::vector RimWellPathCompletions::valves() const return allValves; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathCompletions::allFractures() const +{ + if ( m_fractureCollection->isChecked() ) + { + return m_fractureCollection->allFractures(); + } + return {}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathCompletions::activeFractures() const +{ + if ( m_fractureCollection->isChecked() ) + { + return m_fractureCollection->activeFractures(); + } + return {}; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -257,15 +179,15 @@ std::vector RimWellPathCompletions::allCom { std::vector completions; - for ( const RimWellPathFracture* fracture : fractureCollection()->allFractures() ) + for ( const RimWellPathFracture* fracture : m_fractureCollection->allFractures() ) { completions.push_back( fracture ); } - for ( const RimFishbonesMultipleSubs* fishbones : fishbonesCollection()->allFishbonesSubs() ) + for ( const RimFishbones* fishbones : m_fishbonesCollection->allFishbonesSubs() ) { completions.push_back( fishbones ); } - for ( const RimPerforationInterval* perforation : perforationCollection()->perforations() ) + for ( const RimPerforationInterval* perforation : m_perforationCollection->perforations() ) { completions.push_back( perforation ); } @@ -284,70 +206,14 @@ std::vector RimWellPathCompletions::allCom //-------------------------------------------------------------------------------------------------- bool RimWellPathCompletions::hasCompletions() const { - if ( !fractureCollection()->allFractures().empty() || !stimPlanModelCollection()->allStimPlanModels().empty() ) + if ( !m_fractureCollection->allFractures().empty() || !m_stimPlanModelCollection->allStimPlanModels().empty() ) { return true; } - return !fishbonesCollection()->allFishbonesSubs().empty() || - !fishbonesCollection()->wellPathCollection()->wellPaths().empty() || - !perforationCollection()->perforations().empty(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::drainageRadiusForExport() const -{ - return m_drainageRadiusForPI(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::gasInflowEquationForExport() const -{ - return m_gasInflowEquation().text(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::automaticWellShutInForExport() const -{ - return m_automaticWellShutIn().text(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::allowWellCrossFlowForExport() const -{ - return m_allowWellCrossFlow() ? "YES" : "NO"; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::wellBoreFluidPVTForExport() const -{ - return QString( "%1" ).arg( m_wellBoreFluidPVTTable() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::hydrostaticDensityForExport() const -{ - return m_hydrostaticDensity().text(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::fluidInPlaceRegionForExport() const -{ - return QString( "%1" ).arg( m_fluidInPlaceRegion() ); + return !m_fishbonesCollection->allFishbonesSubs().empty() || + !m_fishbonesCollection->wellPathCollection()->wellPaths().empty() || + !m_perforationCollection->perforations().empty(); } //-------------------------------------------------------------------------------------------------- @@ -356,17 +222,6 @@ QString RimWellPathCompletions::fluidInPlaceRegionForExport() const void RimWellPathCompletions::setUnitSystemSpecificDefaults() { m_fishbonesCollection->setUnitSystemSpecificDefaults(); - m_fractureCollection->setUnitSystemSpecificDefaults(); - m_perforationCollection->setUnitSystemSpecificDefaults(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QRegExp RimWellPathCompletions::wellNameForExportRegExp() -{ - QRegExp rx( "[\\w\\-\\_]{1,8}" ); - return rx; } //-------------------------------------------------------------------------------------------------- @@ -374,18 +229,7 @@ QRegExp RimWellPathCompletions::wellNameForExportRegExp() //-------------------------------------------------------------------------------------------------- void RimWellPathCompletions::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { - caf::PdmUiGroup* compExportGroup = uiOrdering.addNewGroup( "Completion Export Parameters" ); - compExportGroup->add( &m_wellNameForExport ); - compExportGroup->add( &m_wellGroupName ); - compExportGroup->add( &m_referenceDepth ); - compExportGroup->add( &m_preferredFluidPhase ); - compExportGroup->add( &m_drainageRadiusForPI ); - compExportGroup->add( &m_gasInflowEquation ); - compExportGroup->add( &m_automaticWellShutIn ); - compExportGroup->add( &m_allowWellCrossFlow ); - compExportGroup->add( &m_wellBoreFluidPVTTable ); - compExportGroup->add( &m_hydrostaticDensity ); - compExportGroup->add( &m_fluidInPlaceRegion ); + uiOrdering.skipRemainingFields( true ); } //-------------------------------------------------------------------------------------------------- @@ -395,23 +239,23 @@ void RimWellPathCompletions::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTre { uiTreeOrdering.skipRemainingChildren( true ); - if ( !perforationCollection()->perforations().empty() ) + if ( !m_perforationCollection->perforations().empty() ) { uiTreeOrdering.add( &m_perforationCollection ); } - if ( !fishbonesCollection()->allFishbonesSubs().empty() || - !fishbonesCollection()->wellPathCollection()->wellPaths().empty() ) + if ( !m_fishbonesCollection->allFishbonesSubs().empty() || + !m_fishbonesCollection->wellPathCollection()->wellPaths().empty() ) { uiTreeOrdering.add( &m_fishbonesCollection ); } - if ( !fractureCollection()->allFractures().empty() ) + if ( !m_fractureCollection->allFractures().empty() ) { uiTreeOrdering.add( &m_fractureCollection ); } - if ( !stimPlanModelCollection()->allStimPlanModels().empty() ) + if ( !m_stimPlanModelCollection->allStimPlanModels().empty() ) { uiTreeOrdering.add( &m_stimPlanModelCollection ); } @@ -420,69 +264,32 @@ void RimWellPathCompletions::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTre //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathCompletions::fieldChangedByUi( const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue ) +void RimWellPathCompletions::initAfterRead() { - if ( changedField == &m_referenceDepth ) + if ( RimProject::current()->isProjectFileVersionEqualOrOlderThan( "2020.10.1.2" ) ) { - if ( !RiaStdStringTools::isNumber( m_referenceDepth.v().toStdString(), '.' ) ) - { - if ( !RiaStdStringTools::isNumber( m_referenceDepth.v().toStdString(), ',' ) ) - { - // Remove invalid input text - m_referenceDepth = ""; - } - else - { - // Wrong decimal sign entered, replace , by . - auto text = m_referenceDepth.v(); - m_referenceDepth = text.replace( ',', '.' ); - } - } - } + std::vector wellPathHierarchy; + this->allAncestorsOrThisOfType( wellPathHierarchy ); + RimWellPath* topLevelWellPath = wellPathHierarchy.back(); + auto settings = topLevelWellPath->completionSettings(); + + applyToSettings( settings ); + }; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathCompletions::defineEditorAttribute( const caf::PdmFieldHandle* field, - QString uiConfigName, - caf::PdmUiEditorAttribute* attribute ) +void RimWellPathCompletions::applyToSettings( gsl::not_null settings ) { - caf::PdmUiLineEditorAttribute* lineEditorAttr = dynamic_cast( attribute ); - if ( field == &m_wellNameForExport && lineEditorAttr ) - { - QRegExpValidator* validator = new QRegExpValidator( nullptr ); - validator->setRegExp( wellNameForExportRegExp() ); - lineEditorAttr->validator = validator; - } - else if ( field == &m_drainageRadiusForPI && lineEditorAttr ) - { - caf::PdmDoubleStringValidator* validator = new caf::PdmDoubleStringValidator( "1*" ); - lineEditorAttr->validator = validator; - } - else if ( field == &m_wellBoreFluidPVTTable && lineEditorAttr ) - { - // Positive integer - QIntValidator* validator = new QIntValidator( 0, std::numeric_limits::max(), nullptr ); - lineEditorAttr->validator = validator; - } - else if ( field == &m_fluidInPlaceRegion && lineEditorAttr ) - { - // Any integer - QIntValidator* validator = - new QIntValidator( -std::numeric_limits::max(), std::numeric_limits::max(), nullptr ); - lineEditorAttr->validator = validator; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPathCompletions::formatStringForExport( const QString& text, const QString& defaultValue ) const -{ - if ( text.isEmpty() ) return defaultValue; - if ( text.contains( ' ' ) ) return QString( "'%1'" ).arg( text ); - return text; + settings->m_wellNameForExport = m_wellNameForExport_OBSOLETE; + settings->m_referenceDepth = m_referenceDepth_OBSOLETE; + settings->m_preferredFluidPhase = m_preferredFluidPhase_OBSOLETE; + settings->m_drainageRadiusForPI = m_drainageRadiusForPI_OBSOLETE; + settings->m_gasInflowEquation = m_gasInflowEquation_OBSOLETE; + settings->m_automaticWellShutIn = m_automaticWellShutIn_OBSOLETE; + settings->m_allowWellCrossFlow = m_allowWellCrossFlow_OBSOLETE; + settings->m_wellBoreFluidPVTTable = m_wellBoreFluidPVTTable_OBSOLETE; + settings->m_hydrostaticDensity = m_hydrostaticDensity_OBSOLETE; + settings->m_fluidInPlaceRegion = m_fluidInPlaceRegion_OBSOLETE; } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h index c6bb6ecf08..0c377d32d7 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h @@ -18,16 +18,21 @@ #pragma once +#include "RimWellPathCompletionSettings.h" + #include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include "gsl/gsl" + class RimFishbonesCollection; class RimPerforationCollection; -class RimWellPathFractureCollection; -class RimWellPathComponentInterface; -class RimWellPathValve; class RimStimPlanModelCollection; +class RimWellPathComponentInterface; +class RimWellPathFracture; +class RimWellPathFractureCollection; +class RimWellPathValve; //================================================================================================== /// @@ -37,38 +42,6 @@ class RimWellPathCompletions : public caf::PdmObject { CAF_PDM_HEADER_INIT; - enum WellType - { - OIL, - GAS, - WATER, - LIQUID - }; - typedef caf::AppEnum WellTypeEnum; - - enum GasInflowEquation - { - STANDARD_EQ, - RUSSELL_GOODRICH, - DRY_GAS_PSEUDO_PRESSURE, - GENERALIZED_PSEUDO_PRESSURE - }; - typedef caf::AppEnum GasInflowEnum; - - enum AutomaticWellShutIn - { - ISOLATE_FROM_FORMATION, - STOP_ABOVE_FORMATION - }; - typedef caf::AppEnum AutomaticWellShutInEnum; - - enum HydrostaticDensity - { - SEGMENTED, - AVERAGED - }; - typedef caf::AppEnum HydrostaticDensityEnum; - public: RimWellPathCompletions(); @@ -76,39 +49,22 @@ public: RimPerforationCollection* perforationCollection() const; RimWellPathFractureCollection* fractureCollection() const; RimStimPlanModelCollection* stimPlanModelCollection() const; - std::vector valves() const; std::vector allCompletions() const; + bool hasCompletions() const; + void setUnitSystemSpecificDefaults(); - void setWellNameForExport( const QString& name ); - void updateWellPathNameHasChanged( const QString& newWellPathName, const QString& previousWellPathName ); - QString wellNameForExport() const; - QString wellGroupNameForExport() const; - QString referenceDepthForExport() const; - QString wellTypeNameForExport() const; - bool hasCompletions() const; - - QString drainageRadiusForExport() const; - QString gasInflowEquationForExport() const; - QString automaticWellShutInForExport() const; - QString allowWellCrossFlowForExport() const; - QString wellBoreFluidPVTForExport() const; - QString hydrostaticDensityForExport() const; - QString fluidInPlaceRegionForExport() const; - - void setUnitSystemSpecificDefaults(); - static QRegExp wellNameForExportRegExp(); + std::vector valves() const; + std::vector allFractures() const; + std::vector activeFractures() const; protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; - void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - void defineEditorAttribute( const caf::PdmFieldHandle* field, - QString uiConfigName, - caf::PdmUiEditorAttribute* attribute ) override; + void initAfterRead() override; private: - QString formatStringForExport( const QString& text, const QString& defaultText = "" ) const; + void applyToSettings( gsl::not_null settings ); private: caf::PdmChildField m_fishbonesCollection; @@ -116,16 +72,20 @@ private: caf::PdmChildField m_fractureCollection; caf::PdmChildField m_stimPlanModelCollection; - caf::PdmField m_wellNameForExport; - caf::PdmField m_wellGroupName; +private: + ///////////////////// + // OBSOLETE FIELDS // + ///////////////////// + caf::PdmField m_wellNameForExport_OBSOLETE; + caf::PdmField m_wellGroupName_OBSOLETE; - caf::PdmField m_referenceDepth; - caf::PdmField m_preferredFluidPhase; - caf::PdmField m_drainageRadiusForPI; - caf::PdmField m_gasInflowEquation; - caf::PdmField m_automaticWellShutIn; - caf::PdmField m_allowWellCrossFlow; - caf::PdmField m_wellBoreFluidPVTTable; - caf::PdmField m_hydrostaticDensity; - caf::PdmField m_fluidInPlaceRegion; + caf::PdmField m_referenceDepth_OBSOLETE; + caf::PdmField m_preferredFluidPhase_OBSOLETE; + caf::PdmField m_drainageRadiusForPI_OBSOLETE; + caf::PdmField m_gasInflowEquation_OBSOLETE; + caf::PdmField m_automaticWellShutIn_OBSOLETE; + caf::PdmField m_allowWellCrossFlow_OBSOLETE; + caf::PdmField m_wellBoreFluidPVTTable_OBSOLETE; + caf::PdmField m_hydrostaticDensity_OBSOLETE; + caf::PdmField m_fluidInPlaceRegion_OBSOLETE; }; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp index 59d2332704..c66e644866 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp @@ -38,10 +38,10 @@ RimWellPathFractureCollection::RimWellPathFractureCollection( void ) setName( "Fractures" ); nameField()->uiCapability()->setUiHidden( true ); - CAF_PDM_InitFieldNoDefault( &m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); - m_mswParameters = new RimMswCompletionParameters; - m_mswParameters.uiCapability()->setUiTreeHidden( true ); - m_mswParameters.uiCapability()->setUiTreeChildrenHidden( true ); + CAF_PDM_InitFieldNoDefault( &m_mswParameters_OBSOLETE, "MswParameters", "Multi Segment Well Parameters", "", "", "" ); + m_mswParameters_OBSOLETE = new RimMswCompletionParameters; + m_mswParameters_OBSOLETE.uiCapability()->setUiTreeHidden( true ); + m_mswParameters_OBSOLETE.uiCapability()->setUiTreeChildrenHidden( true ); CAF_PDM_InitField( &m_refMDType_OBSOLETE, "RefMDType", std::numeric_limits::max(), "Reference MD", "", "", "" ); CAF_PDM_InitField( &m_refMD_OBSOLETE, "RefMD", std::numeric_limits::infinity(), "", "", "", "" ); @@ -59,9 +59,9 @@ RimWellPathFractureCollection::~RimWellPathFractureCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RimMswCompletionParameters* RimWellPathFractureCollection::mswParameters() const +bool RimWellPathFractureCollection::hasFractures() const { - return m_mswParameters; + return !m_fractures.empty(); } //-------------------------------------------------------------------------------------------------- @@ -80,14 +80,6 @@ void RimWellPathFractureCollection::deleteFractures() m_fractures.deleteAllChildObjects(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathFractureCollection::setUnitSystemSpecificDefaults() -{ - m_mswParameters->setUnitSystemSpecificDefaults(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -122,8 +114,6 @@ std::vector RimWellPathFractureCollection::activeFractures //-------------------------------------------------------------------------------------------------- void RimWellPathFractureCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { - caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Multi Segment Well Options" ); - m_mswParameters->uiOrdering( uiConfigName, *mswGroup ); uiOrdering.skipRemainingFields( true ); } @@ -151,12 +141,12 @@ void RimWellPathFractureCollection::initAfterRead() { if ( m_refMDType_OBSOLETE() != std::numeric_limits::max() ) { - m_mswParameters->setReferenceMDType( (RimMswCompletionParameters::ReferenceMDType)m_refMDType_OBSOLETE() ); + m_mswParameters_OBSOLETE->setReferenceMDType( (RimMswCompletionParameters::ReferenceMDType)m_refMDType_OBSOLETE() ); } if ( m_refMD_OBSOLETE() != std::numeric_limits::infinity() ) { - m_mswParameters->setManualReferenceMD( m_refMD_OBSOLETE() ); + m_mswParameters_OBSOLETE->setManualReferenceMD( m_refMD_OBSOLETE() ); } } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h index 35a0206f51..4786302ff9 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h @@ -42,10 +42,9 @@ public: RimWellPathFractureCollection( void ); ~RimWellPathFractureCollection( void ) override; - const RimMswCompletionParameters* mswParameters() const; - void addFracture( RimWellPathFracture* fracture ); - void deleteFractures(); - void setUnitSystemSpecificDefaults(); + bool hasFractures() const; + void addFracture( RimWellPathFracture* fracture ); + void deleteFractures(); std::vector allFractures() const; std::vector activeFractures() const; @@ -59,9 +58,10 @@ private: void initAfterRead() override; private: - caf::PdmChildArrayField m_fractures; - caf::PdmChildField m_mswParameters; + caf::PdmChildArrayField m_fractures; caf::PdmField m_refMDType_OBSOLETE; caf::PdmField m_refMD_OBSOLETE; + + caf::PdmChildField m_mswParameters_OBSOLETE; }; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp index 5ce5a00bb3..3875edf6ef 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathValve.cpp @@ -452,6 +452,7 @@ QList RimWellPathValve::calculateValueOptions( const caf RimProject* project = nullptr; this->firstAncestorOrThisOfTypeAsserted( project ); + std::vector allTemplates = project->allValveTemplates(); for ( RimValveTemplate* valveTemplate : allTemplates ) { @@ -484,8 +485,11 @@ void RimWellPathValve::fieldChangedByUi( const caf::PdmFieldHandle* changedField } RimPerforationInterval* perfInterval; - this->firstAncestorOrThisOfTypeAsserted( perfInterval ); - perfInterval->updateAllReferringTracks(); + this->firstAncestorOrThisOfType( perfInterval ); + if ( perfInterval ) + { + perfInterval->updateAllReferringTracks(); + } RimProject* proj; this->firstAncestorOrThisOfTypeAsserted( proj ); @@ -509,35 +513,37 @@ void RimWellPathValve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin uiOrdering.add( &m_createValveTemplate, false ); } - if ( componentType() == RiaDefines::WellPathComponentType::ICV || - componentType() == RiaDefines::WellPathComponentType::ICD ) + if ( uiConfigName != "TemplateOnly" ) { - if ( componentType() == RiaDefines::WellPathComponentType::ICV ) + if ( componentType() == RiaDefines::WellPathComponentType::ICV || + componentType() == RiaDefines::WellPathComponentType::ICD ) { - RimWellPath* wellPath; - firstAncestorOrThisOfType( wellPath ); - if ( wellPath ) + if ( componentType() == RiaDefines::WellPathComponentType::ICV ) { - if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_METRIC ) + RimWellPath* wellPath; + firstAncestorOrThisOfType( wellPath ); + if ( wellPath ) { - m_measuredDepth.uiCapability()->setUiName( "Measured Depth [m]" ); - } - else if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD ) - { - m_measuredDepth.uiCapability()->setUiName( "Measured Depth [ft]" ); + if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_METRIC ) + { + m_measuredDepth.uiCapability()->setUiName( "Measured Depth [m]" ); + } + else if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD ) + { + m_measuredDepth.uiCapability()->setUiName( "Measured Depth [ft]" ); + } } + uiOrdering.add( &m_measuredDepth, { true, 3, 1 } ); } - uiOrdering.add( &m_measuredDepth, { true, 3, 1 } ); + } + + if ( componentType() == RiaDefines::WellPathComponentType::ICD || + componentType() == RiaDefines::WellPathComponentType::AICD ) + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Multiple Valve Locations" ); + m_multipleValveLocations->uiOrdering( uiConfigName, *group ); } } - - if ( componentType() == RiaDefines::WellPathComponentType::ICD || - componentType() == RiaDefines::WellPathComponentType::AICD ) - { - caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Multiple Valve Locations" ); - m_multipleValveLocations->uiOrdering( uiConfigName, *group ); - } - if ( m_valveTemplate() != nullptr ) { caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Parameters from Template" ); diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index 99028834b2..dffdc6b320 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -65,9 +65,8 @@ #include "RimEnsembleCurveSetCollection.h" #include "RimExtrudedCurveIntersection.h" #include "RimFaultInView.h" -#include "RimFishboneWellPathCollection.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimFlowCharacteristicsPlot.h" #include "RimFlowDiagSolution.h" #include "RimFlowPlotCollection.h" @@ -88,6 +87,7 @@ #include "RimGridCrossPlotCollection.h" #include "RimGridCrossPlotDataSet.h" #include "RimIdenticalGridCaseGroup.h" +#include "RimImportedFishboneLateralsCollection.h" #include "RimIntersectionCollection.h" #include "RimIntersectionResultDefinition.h" #include "RimIntersectionResultsDefinitionCollection.h" @@ -391,6 +391,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicShowWellPlanFeature"; } } + else if ( dynamic_cast( firstUiItem ) ) + { + appendImportMenu( menuBuilder ); + } else if ( dynamic_cast( firstUiItem ) ) { menuBuilder.subMenuStart( "Create Completions", QIcon( ":/CompletionsSymbol16x16.png" ) ); @@ -413,9 +417,8 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder.addSeparator(); appendExportCompletions( menuBuilder ); } - else if ( dynamic_cast( firstUiItem ) || - dynamic_cast( firstUiItem ) || - dynamic_cast( firstUiItem ) ) + else if ( dynamic_cast( firstUiItem ) || dynamic_cast( firstUiItem ) || + dynamic_cast( firstUiItem ) ) { menuBuilder << "RicNewFishbonesSubsFeature"; appendExportCompletions( menuBuilder ); diff --git a/ApplicationLibCode/ProjectDataModel/RimModeledWellPathLateral.cpp b/ApplicationLibCode/ProjectDataModel/RimModeledWellPathLateral.cpp deleted file mode 100644 index affee50e06..0000000000 --- a/ApplicationLibCode/ProjectDataModel/RimModeledWellPathLateral.cpp +++ /dev/null @@ -1,233 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2020- 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. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RimModeledWellPathLateral.h" - -#include "RiaCompletionTypeCalculationScheduler.h" -#include "RicfCommandObject.h" -#include "RifTextDataTableFormatter.h" -#include "RigWellPath.h" - -#include "RimProject.h" -#include "RimWellPathGroup.h" -#include "RimWellPathLateralGeometryDef.h" - -#include "RimExtrudedCurveIntersection.h" -#include "RimPlotCurve.h" -#include "RimWellPath.h" -#include "RimWellPathFracture.h" -#include "RimWellPathFractureCollection.h" - -#include "cafPdmFieldScriptingCapability.h" -#include "cafPdmUiTreeOrdering.h" - -CAF_PDM_SOURCE_INIT( RimModeledWellPathLateral, "ModeledWellPathLateral" ); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimModeledWellPathLateral::RimModeledWellPathLateral() -{ - CAF_PDM_InitScriptableObject( "Modeled Well Path Lateral", - ":/EditableWell.png", - "", - "A Well Path Lateral created interactively" ); - - CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &m_geometryDefinition, - "WellPathLateralGeometryDef", - "WellPathLateralGeometry", - "Trajectory", - "", - "", - "" ); - - m_geometryDefinition = new RimWellPathLateralGeometryDef; - m_geometryDefinition->changed.connect( this, &RimModeledWellPathLateral::onGeometryDefinitionChanged ); - - CAF_PDM_InitFieldNoDefault( &m_lateralName, "LateralName", "Lateral Name", "", "", "" ); - m_lateralName.registerGetMethod( this, &RimModeledWellPathLateral::createName ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimModeledWellPathLateral::~RimModeledWellPathLateral() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimModeledWellPathLateral::createWellPathGeometry() -{ - this->setWellPathGeometry( m_geometryDefinition->createWellPathGeometry().p() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimModeledWellPathLateral::updateWellPathVisualization() -{ - this->setWellPathGeometry( m_geometryDefinition->createWellPathGeometry().p() ); - - std::vector refferingCurves; - this->objectsWithReferringPtrFieldsOfType( refferingCurves ); - - for ( auto curve : refferingCurves ) - { - curve->loadDataAndUpdate( false ); - } - - for ( auto fracture : this->fractureCollection()->activeFractures() ) - { - fracture->loadDataAndUpdate(); - } - - std::vector refferingIntersections; - this->objectsWithReferringPtrFieldsOfType( refferingIntersections ); - - for ( auto intersection : refferingIntersections ) - { - intersection->rebuildGeometryAndScheduleCreateDisplayModel(); - } - - RimProject* proj; - this->firstAncestorOrThisOfTypeAsserted( proj ); - proj->scheduleCreateDisplayModelAndRedrawAllViews(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimModeledWellPathLateral::scheduleUpdateOfDependentVisualization() -{ - RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPathLateralGeometryDef* RimModeledWellPathLateral::geometryDefinition() const -{ - return m_geometryDefinition; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimModeledWellPathLateral::wellPlanText() -{ - QString planText; - QTextStream qtxtStream( &planText ); - - RifTextDataTableFormatter formatter( qtxtStream ); - formatter.setUnlimitedDataRowWidth(); - formatter.setTableRowPrependText( "" ); - formatter.setTableRowLineAppendText( "" ); - - std::vector tableHeader; - std::vector columns = { "MDRKB", "CL", "Inc", "Azi", "TVDMSL", "NS", "EW", "Dogleg", "Build", "Turn" }; - for ( QString column : columns ) - { - tableHeader.push_back( - RifTextDataTableColumn( column, - RifTextDataTableDoubleFormatting( RifTextDataTableDoubleFormat::RIF_FLOAT, 2 ) ) ); - } - - formatter.header( tableHeader ); - - double mdrkbAtFirstTarget = m_geometryDefinition->mdAtConnection() + parentGroup()->airGap(); - if ( m_geometryDefinition ) - { - std::vector wellPlan = m_geometryDefinition->wellPlan(); - for ( const auto& segment : wellPlan ) - { - formatter.add( segment.MD + mdrkbAtFirstTarget ); - formatter.add( segment.CL ); - formatter.add( segment.inc ); - formatter.add( segment.azi ); - formatter.add( segment.TVD ); - formatter.add( segment.NS ); - formatter.add( segment.EW ); - formatter.add( segment.dogleg ); - formatter.add( segment.build ); - formatter.add( segment.turn ); - formatter.rowCompleted(); - } - } - formatter.tableCompleted(); - - return planText; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RimWellPathGroup* RimModeledWellPathLateral::parentGroup() const -{ - const RimWellPathGroup* group = nullptr; - this->firstAncestorOrThisOfTypeAsserted( group ); - return group; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimModeledWellPathLateral::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) -{ - uiTreeOrdering.add( m_geometryDefinition() ); - RimWellPath::defineUiTreeOrdering( uiTreeOrdering, uiConfigName ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimModeledWellPathLateral::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) -{ - uiOrdering.add( &m_name ); - RimWellPath::defineUiOrdering( uiConfigName, uiOrdering ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimModeledWellPathLateral::onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate ) -{ - updateWellPathVisualization(); - if ( fullUpdate ) - { - scheduleUpdateOfDependentVisualization(); - } - updateConnectedEditors(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -caf::PdmFieldHandle* RimModeledWellPathLateral::userDescriptionField() -{ - return &m_lateralName; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimModeledWellPathLateral::createName() const -{ - return QString( "%1 [branch md=%2]" ).arg( parentGroup()->createGroupName() ).arg( m_geometryDefinition->mdAtConnection() ); -} diff --git a/ApplicationLibCode/ProjectDataModel/RimModeledWellPathLateral.h b/ApplicationLibCode/ProjectDataModel/RimModeledWellPathLateral.h deleted file mode 100644 index 3723e0ecb7..0000000000 --- a/ApplicationLibCode/ProjectDataModel/RimModeledWellPathLateral.h +++ /dev/null @@ -1,55 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2020- 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 "RimWellPath.h" - -#include "cafPdmChildField.h" -#include "cafPdmProxyValueField.h" - -class RimWellPathTarget; -class RimWellPath; -class RimWellPathGroup; -class RimWellPathLateralGeometryDef; - -class RimModeledWellPathLateral : public RimWellPath -{ - CAF_PDM_HEADER_INIT; - -public: - RimModeledWellPathLateral(); - ~RimModeledWellPathLateral() override; - - void createWellPathGeometry(); - void updateWellPathVisualization(); - void scheduleUpdateOfDependentVisualization(); - RimWellPathLateralGeometryDef* geometryDefinition() const; - QString wellPlanText(); - -private: - const RimWellPathGroup* parentGroup() const; - - void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; - void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - void onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate ); - caf::PdmFieldHandle* userDescriptionField() override; - QString createName() const; - - caf::PdmChildField m_geometryDefinition; - caf::PdmProxyValueField m_lateralName; -}; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellLogTrack.cpp b/ApplicationLibCode/ProjectDataModel/RimWellLogTrack.cpp index 945082b634..00ef725419 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellLogTrack.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellLogTrack.cpp @@ -49,8 +49,8 @@ #include "RimColorLegendItem.h" #include "RimEclipseCase.h" #include "RimEclipseResultDefinition.h" +#include "RimFishbones.h" #include "RimFishbonesCollection.h" -#include "RimFishbonesMultipleSubs.h" #include "RimGeoMechCase.h" #include "RimMainPlotCollection.h" #include "RimPerforationCollection.h" diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPath.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPath.cpp index fc0bb135f8..4870c11571 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPath.cpp @@ -34,8 +34,10 @@ #include "Rim3dWellLogCurve.h" #include "Rim3dWellLogCurveCollection.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" +#include "RimFishbonesCollection.h" #include "RimMainPlotCollection.h" +#include "RimPerforationCollection.h" #include "RimProject.h" #include "RimStimPlanModelCollection.h" #include "RimTools.h" @@ -44,6 +46,7 @@ #include "RimWellLogPlotCollection.h" #include "RimWellPathAttributeCollection.h" #include "RimWellPathCollection.h" +#include "RimWellPathCompletionSettings.h" #include "RimWellPathCompletions.h" #include "RimWellPathFracture.h" #include "RimWellPathFractureCollection.h" @@ -108,6 +111,9 @@ RimWellPath::RimWellPath() m_completions = new RimWellPathCompletions; m_completions.uiCapability()->setUiTreeHidden( true ); + CAF_PDM_InitFieldNoDefault( &m_completionSettings, "CompletionSettings", "Completion Settings", "", "", "" ); + m_completionSettings = new RimWellPathCompletionSettings; + CAF_PDM_InitFieldNoDefault( &m_wellLogFiles, "WellLogFiles", "Well Log Files", "", "", "" ); m_wellLogFiles.uiCapability()->setUiTreeHidden( true ); @@ -274,6 +280,22 @@ const RimWellPathCompletions* RimWellPath::completions() const return m_completions(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimWellPathCompletionSettings* RimWellPath::completionSettings() const +{ + return m_completionSettings(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathCompletionSettings* RimWellPath::completionSettings() +{ + return m_completionSettings(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -395,7 +417,7 @@ void RimWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedField, con { QString previousName = oldValue.toString(); QString newName = newValue.toString(); - m_completions->updateWellPathNameHasChanged( newName, previousName ); + m_completionSettings->updateWellPathNameHasChanged( newName, previousName ); } else { @@ -454,6 +476,33 @@ QList RimWellPath::calculateValueOptions( const caf::Pdm //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- +void RimWellPath::initAfterRead() +{ + if ( RimProject::current()->isProjectFileVersionEqualOrOlderThan( "2020.10.1" ) ) + { + if ( isTopLevelWellPath() && m_completionSettings->mswParameters()->isDefault() ) + { + std::vector allExistingMswParameters; + descendantsOfType( allExistingMswParameters ); + for ( auto mswParameters : allExistingMswParameters ) + { + if ( !mswParameters->isDefault() ) + { + *( m_completionSettings->mswParameters() ) = *mswParameters; + break; + } + } + if ( m_completionSettings->wellNameForExport().isEmpty() ) + { + m_completionSettings->setWellNameForExport( name() ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//--------------------------------------------------------------------- ----------------------------- QString RimWellPath::name() const { return m_name(); @@ -461,12 +510,12 @@ QString RimWellPath::name() const //-------------------------------------------------------------------------------------------------- /// -//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------- ----------------------------- void RimWellPath::setName( const QString& name ) { setNameNoUpdateOfExportName( name ); - m_completions->setWellNameForExport( name ); + m_completionSettings->setWellNameForExport( name ); } //-------------------------------------------------------------------------------------------------- @@ -622,9 +671,29 @@ void RimWellPath::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, { uiTreeOrdering.add( &m_wellLogFiles ); - if ( m_completions->hasCompletions() ) + if ( isTopLevelWellPath() && !allCompletionsRecursively().empty() ) { - uiTreeOrdering.add( m_completions() ); + if ( completionSettings() ) + { + uiTreeOrdering.add( completionSettings() ); + } + } + + if ( m_completions->fishbonesCollection()->hasFishbones() ) + { + uiTreeOrdering.add( m_completions->fishbonesCollection() ); + } + if ( m_completions->fractureCollection()->hasFractures() ) + { + uiTreeOrdering.add( m_completions->fractureCollection() ); + } + if ( m_completions->perforationCollection()->hasPerforations() ) + { + uiTreeOrdering.add( m_completions->perforationCollection() ); + } + if ( m_completions->stimPlanModelCollection()->hasStimPlanModels() ) + { + uiTreeOrdering.add( m_completions->stimPlanModelCollection() ); } if ( m_3dWellLogCurves->has3dWellLogCurves() ) @@ -640,6 +709,23 @@ void RimWellPath::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, uiTreeOrdering.skipRemainingChildren( true ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPath::copyCompletionSettings( RimWellPath* from, RimWellPath* to ) +{ + if ( !from->m_completionSettings ) return; + + if ( !to->m_completionSettings ) + { + to->m_completionSettings = new RimWellPathCompletionSettings( *from->m_completionSettings() ); + } + else + { + *( to->m_completionSettings() ) = *( from->m_completionSettings() ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -692,6 +778,7 @@ void RimWellPath::setUnitSystem( RiaDefines::EclipseUnitSystem unitSystem ) m_unitSystem = unitSystem; m_completions->setUnitSystemSpecificDefaults(); + m_completionSettings->setUnitSystemSpecificDefaults(); } //-------------------------------------------------------------------------------------------------- @@ -877,6 +964,24 @@ Rim3dWellLogCurveCollection* RimWellPath::rim3dWellLogCurveCollection() const return m_3dWellLogCurves(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPath::allCompletionsRecursively() const +{ + std::vector allCompletions; + + std::vector completionCollections; + this->descendantsOfType( completionCollections ); + for ( auto collection : completionCollections ) + { + std::vector completions = collection->allCompletions(); + allCompletions.insert( allCompletions.end(), completions.begin(), completions.end() ); + } + + return allCompletions; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -926,3 +1031,29 @@ void RimWellPath::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray { updateConnectedEditors(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPath::isTopLevelWellPath() const +{ + return this == topLevelWellPath(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RimWellPath::topLevelWellPath() const +{ + std::vector wellPathHierarchy; + this->allAncestorsOrThisOfType( wellPathHierarchy ); + RimWellPath* wellPath = wellPathHierarchy.back(); + return wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPath::updateAfterAddingToWellPathGroup() +{ +} diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPath.h b/ApplicationLibCode/ProjectDataModel/RimWellPath.h index 5c707b4dd8..2f4e61b80f 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPath.h +++ b/ApplicationLibCode/ProjectDataModel/RimWellPath.h @@ -48,12 +48,12 @@ class RigWellPathFormations; class RimProject; class RimWellLogFile; class RimFractureTemplateCollection; -class RimFishboneWellPathCollection; class RimStimPlanModelCollection; class RimFishbonesCollection; class RimPerforationCollection; class RimWellPathAttributeCollection; class RimWellPathCompletions; +class RimWellPathCompletionSettings; class RimWellPathFractureCollection; class Rim3dWellLogCurve; @@ -76,9 +76,9 @@ public: RimWellPath(); ~RimWellPath() override; - QString name() const; - void setName( const QString& name ); - void setNameNoUpdateOfExportName( const QString& name ); + virtual QString name() const; + void setName( const QString& name ); + void setNameNoUpdateOfExportName( const QString& name ); const QString associatedSimulationWellName() const; int associatedSimulationWellBranch() const; @@ -118,7 +118,11 @@ public: void add3dWellLogCurve( Rim3dWellLogCurve* rim3dWellLogCurve ); Rim3dWellLogCurveCollection* rim3dWellLogCurveCollection() const; - const RimWellPathCompletions* completions() const; + std::vector allCompletionsRecursively() const; + const RimWellPathCompletions* completions() const; + const RimWellPathCompletionSettings* completionSettings() const; + RimWellPathCompletionSettings* completionSettings(); + RimFishbonesCollection* fishbonesCollection(); const RimFishbonesCollection* fishbonesCollection() const; RimPerforationCollection* perforationIntervalCollection(); @@ -150,6 +154,10 @@ public: void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector& referringObjects ) override; + bool isTopLevelWellPath() const; + RimWellPath* topLevelWellPath() const; + void updateAfterAddingToWellPathGroup(); + protected: // Override PdmObject @@ -159,9 +167,12 @@ protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly ) override; + void initAfterRead() override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; + static void copyCompletionSettings( RimWellPath* from, RimWellPath* to ); + // Fields protected: caf::PdmProxyValueField m_airGap; @@ -185,6 +196,7 @@ private: caf::PdmChildArrayField m_wellLogFiles; caf::PdmChildField m_3dWellLogCurves; + caf::PdmChildField m_completionSettings; caf::PdmChildField m_completions; caf::PdmChildField m_wellPathAttributes; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp index 22edebd610..be47d12a92 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathCollection.cpp @@ -28,6 +28,9 @@ #include "RiaTextStringTools.h" #include "RiaWellNameComparer.h" +#include "RifWellPathFormationsImporter.h" +#include "RifWellPathImporter.h" + #include "RigEclipseCaseData.h" #include "RigMainGrid.h" #include "RigWellPath.h" @@ -35,6 +38,8 @@ #include "RimEclipseCase.h" #include "RimEclipseCaseCollection.h" #include "RimEclipseView.h" +#include "RimFileWellPath.h" +#include "RimModeledWellPath.h" #include "RimOilField.h" #include "RimPerforationCollection.h" #include "RimProject.h" @@ -43,11 +48,10 @@ #include "RimWellLogFile.h" #include "RimWellMeasurementCollection.h" #include "RimWellPath.h" +#include "RimWellPathCompletionSettings.h" #include "RimWellPathGroup.h" -#include "Riu3DMainWindowTools.h" -#include "RifWellPathFormationsImporter.h" -#include "RifWellPathImporter.h" +#include "Riu3DMainWindowTools.h" #include "cafPdmUiEditorHandle.h" #include "cafPdmUiTreeOrdering.h" @@ -57,8 +61,6 @@ #include #include -#include "RimFileWellPath.h" -#include "RimModeledWellPath.h" #include #include @@ -260,10 +262,13 @@ void RimWellPathCollection::loadDataAndUpdate() } progress.incrementProgress(); } + for ( auto group : topLevelGroups() ) { group->createWellPathGeometry(); + group->completionSettings()->setWellNameForExport( group->createGroupName() ); } + this->sortWellsByName(); } @@ -655,12 +660,22 @@ void RimWellPathCollection::groupWellPaths( const std::vector& wel if ( automaticGrouping ) { - for ( auto wellPath : allWellPaths() ) + bool detachedGroup = true; + while ( detachedGroup ) { - if ( dynamic_cast( wellPath ) ) + detachedGroup = false; + + // Detach may end up removing multiple groups, which could interfere with iteration of this loop + // So do only one and break + for ( auto wellPath : allWellPaths() ) { - auto existingGroupPaths = detachWellPaths( { wellPath } ); - detachedWellPaths.insert( detachedWellPaths.end(), existingGroupPaths.begin(), existingGroupPaths.end() ); + if ( dynamic_cast( wellPath ) ) + { + auto newlyDetachedPaths = detachWellPaths( { wellPath } ); + detachedWellPaths.insert( detachedWellPaths.end(), newlyDetachedPaths.begin(), newlyDetachedPaths.end() ); + detachedGroup = true; + break; + } } } } @@ -854,7 +869,7 @@ RimWellPathGroup* RimWellPathCollection::findOrCreateWellPathGroup( gsl::not_nul auto wellPathGeometry = wellPath->wellPathGeometry(); if ( !wellPathGeometry ) return nullptr; - const double eps = 1.0e-3; + const double eps = 1.0e-2; std::map wellPathsWithCommonGeometry; for ( auto existingWellPath : wellPathsToGroup ) diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.cpp index 65decd7d9c..bab3cbab0c 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.cpp @@ -93,6 +93,9 @@ RimWellPathGeometryDef::RimWellPathGeometryDef() m_autoTargetAtSeaLevel = new RimWellPathTarget; m_autoTargetAtSeaLevel->setEnabled( false ); + CAF_PDM_InitFieldNoDefault( &m_fixedWellPathPoints, "FixedWellPathPoints", "", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_fixedMeasuredDepths, "FixedMeasuredDepths", "", "", "", "" ); + CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" ); caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled ); } @@ -156,6 +159,40 @@ void RimWellPathGeometryDef::setMdAtFirstTarget( double md ) m_mdAtFirstTarget = md; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::setFixedWellPathPoints( const std::vector& points ) +{ + m_fixedWellPathPoints = points; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::setFixedMeasuredDepths( const std::vector& mds ) +{ + m_fixedMeasuredDepths = mds; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathGeometryDef::createTargets( const std::vector& points ) +{ + CAF_ASSERT( points.size() >= 2u ); + + std::vector appendedTargets; + + for ( size_t i = 0; i < points.size(); ++i ) + { + auto target = appendTarget(); + target->setAsPointTargetXYZ( points[i] ); + appendedTargets.push_back( target ); + } + return appendedTargets; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -168,14 +205,22 @@ cvf::ref RimWellPathGeometryDef::createWellPathGeometry() updateTargetAtSeaLevel(); } + std::vector wellPathPoints = m_fixedWellPathPoints; + std::vector measuredDepths = m_fixedMeasuredDepths; + RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator(); - if ( wellPathCalculator.lineArcEndpoints().size() < 2 ) return wellPathGeometry; - - RiaPolyArcLineSampler arcLineSampler( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() ); - - auto [wellPathPoints, measuredDepths] = arcLineSampler.sampledPointsAndMDs( 30, false ); - + if ( wellPathCalculator.lineArcEndpoints().size() >= 2 ) + { + RiaPolyArcLineSampler arcLineSampler( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() ); + auto [sampledWellPathPoints, sampledMeasuredDepths] = arcLineSampler.sampledPointsAndMDs( 30, false ); + wellPathPoints.insert( wellPathPoints.end(), sampledWellPathPoints.begin(), sampledWellPathPoints.end() ); + double startMD = measuredDepths.empty() ? 0.0 : measuredDepths.back(); + for ( auto md : sampledMeasuredDepths ) + { + measuredDepths.push_back( md + startMD ); + } + } wellPathGeometry->setWellPathPoints( wellPathPoints ); wellPathGeometry->setMeasuredDepths( measuredDepths ); diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.h b/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.h index 6cb2e72c1e..f7242f987e 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.h +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDef.h @@ -17,8 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RimWellPathGeometryDefInterface.h" - #include "RiaLineArcWellPathCalculator.h" #include "RiaWellPlanCalculator.h" @@ -38,7 +36,7 @@ class RicCreateWellTargetsPickEventHandler; class RigWellPath; -class RimWellPathGeometryDef : public RimWellPathGeometryDefInterface +class RimWellPathGeometryDef : public caf::PdmObject { CAF_PDM_HEADER_INIT; @@ -49,7 +47,7 @@ public: RimWellPathGeometryDef(); ~RimWellPathGeometryDef() override; - cvf::Vec3d anchorPointXyz() const override; + cvf::Vec3d anchorPointXyz() const; void setReferencePointXyz( const cvf::Vec3d& refPointXyz ); double airGap() const; @@ -57,21 +55,26 @@ public: double mdAtFirstTarget() const; void setMdAtFirstTarget( double mdrkb ); + void setFixedWellPathPoints( const std::vector& points ); + void setFixedMeasuredDepths( const std::vector& mds ); + + std::vector createTargets( const std::vector& points); + std::pair findActiveTargetsAroundInsertionPoint( const RimWellPathTarget* targetToInsertBefore ); - cvf::ref createWellPathGeometry() override; - void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert ) override; - void deleteTarget( RimWellPathTarget* targetTodelete ) override; - void deleteAllTargets() override; - RimWellPathTarget* appendTarget() override; + cvf::ref createWellPathGeometry(); + void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert ); + void deleteTarget( RimWellPathTarget* targetTodelete ); + void deleteAllTargets(); + RimWellPathTarget* appendTarget(); - const RimWellPathTarget* firstActiveTarget() const override; - const RimWellPathTarget* lastActiveTarget() const override; - std::vector activeWellTargets() const override; + const RimWellPathTarget* firstActiveTarget() const; + const RimWellPathTarget* lastActiveTarget() const; + std::vector activeWellTargets() const; - void enableTargetPointPicking( bool isEnabling ) override; - void updateWellPathVisualization( bool fullUpdate ) override; + void enableTargetPointPicking( bool isEnabling ); + void updateWellPathVisualization( bool fullUpdate ); void setUseAutoGeneratedTargetAtSeaLevel( bool autoGenerate ); @@ -111,6 +114,8 @@ private: caf::PdmField m_useAutoGeneratedTargetAtSeaLevel; caf::PdmChildField m_autoTargetAtSeaLevel; caf::PdmField m_pickPointsEnabled; + caf::PdmField> m_fixedWellPathPoints; + caf::PdmField> m_fixedMeasuredDepths; std::shared_ptr m_pickTargetsEventHandler; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDefInterface.h b/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDefInterface.h deleted file mode 100644 index 59aee3b017..0000000000 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGeometryDefInterface.h +++ /dev/null @@ -1,53 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2020- 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 "cafPdmObject.h" - -#include "cvfObject.h" -#include "cvfVector3.h" - -class RimWellPath; -class RimWellPathTarget; -class RicCreateWellTargetsPickEventHandler; - -class RiaLineArcWellPathCalculator; -class RigWellPath; - -class RimWellPathGeometryDefInterface : public caf::PdmObject -{ - CAF_PDM_HEADER_INIT; - -public: - virtual cvf::ref createWellPathGeometry() = 0; - virtual cvf::Vec3d anchorPointXyz() const = 0; - virtual void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert ) = 0; - virtual void deleteTarget( RimWellPathTarget* targetTodelete ) = 0; - virtual void deleteAllTargets() = 0; - virtual RimWellPathTarget* appendTarget() = 0; - - virtual const RimWellPathTarget* firstActiveTarget() const = 0; - virtual const RimWellPathTarget* lastActiveTarget() const = 0; - - virtual void enableTargetPointPicking( bool isEnabling ) = 0; - virtual std::vector activeWellTargets() const = 0; - virtual void updateWellPathVisualization( bool fullUpdate ) = 0; - -private: - virtual RiaLineArcWellPathCalculator lineArcWellPathCalculator() const = 0; -}; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp index 4668e38de0..066207b87c 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.cpp @@ -19,7 +19,11 @@ #include "RiaTextStringTools.h" #include "RigWellPath.h" -#include "RimModeledWellPathLateral.h" + +#include "RimModeledWellPath.h" +#include "RimWellPathCompletionSettings.h" +#include "RimWellPathCompletions.h" +#include "RimWellPathValve.h" #include "cafPdmFieldScriptingCapability.h" #include "cafPdmObjectScriptingCapability.h" @@ -43,15 +47,41 @@ RimWellPathGroup::RimWellPathGroup() "A Group of Well Paths" ); CAF_PDM_InitScriptableFieldNoDefault( &m_childWellPaths, "ChildWellPaths", "Child Well Paths", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_groupName, "GroupName", "Group Name", "", "", "" ); + + CAF_PDM_InitScriptableField( &m_addValveAtConnection, + "AddValveAtConnection", + false, + "Add Outlet Valve for Branches", + "", + "Should an outlet valve be added to branches for MSW export?", + "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" ); + m_valve = new RimWellPathValve; + m_groupName.registerGetMethod( this, &RimWellPathGroup::createGroupName ); + m_groupName.uiCapability()->setUiReadOnly( true ); + setWellPathGeometry( new RigWellPath ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathGroup::name() const +{ + return m_groupName(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathGroup::addChildWellPath( RimWellPath* wellPath ) { + if ( m_childWellPaths.empty() && isTopLevelWellPath() && wellPath->completions()->hasCompletions() ) + { + RimWellPath::copyCompletionSettings( wellPath, this ); + } + if ( !this->wellPathGeometry()->wellPathPoints().empty() ) { m_childWellPaths.push_back( wellPath ); @@ -65,6 +95,7 @@ void RimWellPathGroup::addChildWellPath( RimWellPath* wellPath ) setWellPathGeometry( geometryCopy.p() ); m_childWellPaths.push_back( wellPath ); } + wellPath->nameChanged.connect( this, &RimWellPathGroup::onChildNameChanged ); updateAllRequiredEditors(); @@ -100,11 +131,19 @@ bool RimWellPathGroup::hasChildWellPath( RimWellPath* wellPath ) void RimWellPathGroup::removeChildWellPath( RimWellPath* wellPath ) { m_childWellPaths.removeChildObject( wellPath ); + RimWellPath::copyCompletionSettings( this, wellPath ); + if ( auto geometry = wellPath->wellPathGeometry(); geometry ) { - geometry->setUniqueStartIndex( 0u ); + geometry->setUniqueStartAndEndIndex( 0u, std::numeric_limits::max() ); } createWellPathGeometry(); + + if ( isTopLevelWellPath() ) + { + completionSettings()->setWellNameForExport( m_groupName() ); + } + updateAllRequiredEditors(); } @@ -136,15 +175,22 @@ void RimWellPathGroup::createWellPathGeometry() } if ( wellPathGeometries().empty() ) return; - auto commonGeometry = RigWellPath::commonGeometry( wellPathGeometries() ); + auto commonGeometry = RigWellPath::commonGeometry( wellPathGeometries() ); + size_t childStartIndex = 0u; + size_t commonSize = commonGeometry->wellPathPoints().size(); + if ( commonSize > 0u ) childStartIndex = commonSize - 1u; + + setWellPathGeometry( commonGeometry.p() ); + wellPathGeometry()->setUniqueStartAndEndIndex( wellPathGeometry()->uniqueStartIndex(), childStartIndex ); + for ( auto wellPath : m_childWellPaths ) { - size_t startIndex = 0u; - size_t commonSize = commonGeometry->wellPathPoints().size(); - if ( commonSize > 0u ) startIndex = commonSize - 1u; - wellPath->wellPathGeometry()->setUniqueStartIndex( startIndex ); + if ( auto lateral = dynamic_cast( wellPath.p() ); lateral ) + { + lateral->createWellPathGeometry(); + } + wellPath->wellPathGeometry()->setUniqueStartAndEndIndex( childStartIndex, std::numeric_limits::max() ); } - setWellPathGeometry( commonGeometry.p() ); } //-------------------------------------------------------------------------------------------------- @@ -152,6 +198,8 @@ void RimWellPathGroup::createWellPathGeometry() //-------------------------------------------------------------------------------------------------- void RimWellPathGroup::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) { + RimWellPath::defineUiTreeOrdering( uiTreeOrdering, uiConfigName ); + for ( auto child : m_childWellPaths() ) { if ( child ) @@ -159,6 +207,7 @@ void RimWellPathGroup::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrder uiTreeOrdering.add( child ); } } + uiTreeOrdering.skipRemainingChildren( true ); } @@ -170,6 +219,40 @@ caf::PdmFieldHandle* RimWellPathGroup::userDescriptionField() return &m_groupName; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGroup::initAfterRead() +{ + if ( isTopLevelWellPath() ) + { + completionSettings()->setWellNameForExport( createGroupName() ); + } + + for ( auto wellPath : m_childWellPaths ) + { + wellPath->nameChanged.connect( this, &RimWellPathGroup::onChildNameChanged ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGroup::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + uiOrdering.add( &m_groupName ); + if ( !isTopLevelWellPath() ) + { + auto valveGroup = uiOrdering.addNewGroup( "Valve Settings" ); + valveGroup->add( &m_addValveAtConnection ); + if ( m_addValveAtConnection ) + { + m_valve->uiOrdering( "TemplateOnly", *valveGroup ); + } + } + uiOrdering.skipRemainingFields( true ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -178,7 +261,10 @@ std::vector RimWellPathGroup::wellPathGeometries() const std::vector allGeometries; for ( const auto child : m_childWellPaths() ) { - allGeometries.push_back( child->wellPathGeometry() ); + if ( child->wellPathGeometry() ) + { + allGeometries.push_back( child->wellPathGeometry() ); + } } return allGeometries; } @@ -193,36 +279,72 @@ QString RimWellPathGroup::createGroupName() const this->descendantsOfType( descendantWellPaths ); for ( auto wellPath : descendantWellPaths ) { - if ( !dynamic_cast( wellPath ) && !dynamic_cast( wellPath ) ) + if ( wellPath ) { - allNames.push_back( wellPath->name() ); + bool groupOrLateral = dynamic_cast( wellPath ) || + dynamic_cast( wellPath ); + if ( !groupOrLateral ) + { + allNames.push_back( wellPath->name() ); + } } } - QString commonName = RiaTextStringTools::commonRoot( allNames ); - QString trimmedCommonName = RiaTextStringTools::trimNonAlphaNumericCharacters( commonName ); + QString commonRoot = RiaTextStringTools::commonRoot( allNames ); + QString trimmedCommonRoot = RiaTextStringTools::trimNonAlphaNumericCharacters( commonRoot ); + + for ( auto& name : allNames ) + { + name.remove( commonRoot ); + } + + QString commonSuffix = RiaTextStringTools::commonSuffix( allNames ); + QString trimmedCommonSuffix = RiaTextStringTools::trimNonAlphaNumericCharacters( commonSuffix ); + QStringList branchNames; for ( auto& name : allNames ) { - name.remove( commonName ); + name.remove( commonSuffix ); name = RiaTextStringTools::trimNonAlphaNumericCharacters( name ); name = name.simplified(); - if ( !name.isEmpty() ) branchNames.push_back( name ); + if ( !name.isEmpty() ) + { + branchNames.push_back( name ); + } } - QString fullName = trimmedCommonName; + QString fullName = trimmedCommonRoot; if ( !branchNames.isEmpty() ) { - fullName += QString( "(%1)" ).arg( branchNames.join( ", " ) ); + fullName += QString( "%1" ).arg( branchNames.join( "" ) ); } + fullName += trimmedCommonSuffix; + + QString nameWithoutSpaces = fullName; + nameWithoutSpaces.remove( ' ' ); + + if ( nameWithoutSpaces.length() > 8 ) fullName = trimmedCommonRoot + trimmedCommonSuffix; return fullName; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimWellPathValve* RimWellPathGroup::outletValve() const +{ + return m_addValveAtConnection() && m_valve() && m_valve->valveTemplate() ? m_valve() : nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathGroup::onChildNameChanged( const caf::SignalEmitter* emitter ) { updateConnectedEditors(); + + if ( isTopLevelWellPath() ) + { + completionSettings()->setWellNameForExport( createGroupName() ); + } } //-------------------------------------------------------------------------------------------------- @@ -275,9 +397,9 @@ void RimWellPathGroup::makeMoreLevelsIfNecessary() } if ( anyNonTrivialBranches ) { - size_t startIndex = 0u; - size_t commonSize = wellPathGeometry()->wellPathPoints().size(); - if ( commonSize > 0u ) startIndex = commonSize - 1u; + size_t childStartIndex = 0u; + size_t commonSize = wellPathGeometry()->wellPathPoints().size(); + if ( commonSize > 0u ) childStartIndex = commonSize - 1u; for ( const auto& firstDeviationAndWellPaths : branches ) { @@ -289,7 +411,8 @@ void RimWellPathGroup::makeMoreLevelsIfNecessary() { m_childWellPaths().removeChildObject( wellPath ); newGroup->addChildWellPath( wellPath ); - newGroup->wellPathGeometry()->setUniqueStartIndex( startIndex ); + newGroup->wellPathGeometry()->setUniqueStartAndEndIndex( childStartIndex, + std::numeric_limits::max() ); } m_childWellPaths().push_back( newGroup ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.h b/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.h index 48d712f9a0..197da2f573 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.h +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathGroup.h @@ -19,6 +19,10 @@ #include "RimWellPath.h" +#include "cafPdmChildField.h" + +class RimWellPathValve; + #include class RimWellPathGroup : public RimWellPath @@ -29,6 +33,8 @@ class RimWellPathGroup : public RimWellPath public: RimWellPathGroup(); + QString name() const override; + void addChildWellPath( RimWellPath* wellPath ); std::vector childWellPaths() const; size_t childWellpathCount() const; @@ -40,9 +46,14 @@ public: void makeMoreLevelsIfNecessary(); QString createGroupName() const; + const RimWellPathValve* outletValve() const; + protected: - void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ); + void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; caf::PdmFieldHandle* userDescriptionField() override; + void initAfterRead() override; + + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; private: std::vector wellPathGeometries() const; @@ -51,5 +62,7 @@ private: private: caf::PdmChildArrayField m_childWellPaths; + caf::PdmField m_addValveAtConnection; + caf::PdmChildField m_valve; caf::PdmProxyValueField m_groupName; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathLateralGeometryDef.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathLateralGeometryDef.cpp deleted file mode 100644 index 9ecc43dc22..0000000000 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathLateralGeometryDef.cpp +++ /dev/null @@ -1,542 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2020- 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. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RimWellPathLateralGeometryDef.h" - -#include "WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.h" -#include "WellPathCommands/RicCreateWellTargetsPickEventHandler.h" - -#include "RiaFieldHandleTools.h" -#include "RiaJCurveCalculator.h" -#include "RiaLogging.h" -#include "RiaOffshoreSphericalCoords.h" -#include "RiaPolyArcLineSampler.h" -#include "RiaSCurveCalculator.h" - -#include "RigWellPath.h" - -#include "RimModeledWellPath.h" -#include "RimProject.h" -#include "RimWellPathGroup.h" -#include "RimWellPathTarget.h" - -#include "RiuViewerCommands.h" - -#include "cafCmdFeatureMenuBuilder.h" -#include "cafPdmFieldScriptingCapabilityCvfVec3d.h" -#include "cafPdmObjectScriptingCapability.h" -#include "cafPdmUiDoubleSliderEditor.h" -#include "cafPdmUiDoubleValueEditor.h" -#include "cafPdmUiLineEditor.h" -#include "cafPdmUiPushButtonEditor.h" -#include "cafPdmUiTableViewEditor.h" -#include "cafPdmUiTreeOrdering.h" -#include "cvfGeometryTools.h" - -CAF_PDM_SOURCE_INIT( RimWellPathLateralGeometryDef, "WellPathLateralGeometryDef", "WellPathLateralGeometry" ); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector createTargetsFromPoints( const std::vector& points ) -{ - CAF_ASSERT( points.size() >= 2u ); - - std::vector targets; - - for ( size_t i = 0; i < points.size(); ++i ) - { - cvf::Vec3d tangent; - if ( i < points.size() - 1u ) - { - tangent = points[i + 1] - points[i]; - } - else if ( i > 0u ) - { - tangent = points[i] - points[i - 1]; - } - RiaOffshoreSphericalCoords sphericalCoords( tangent ); - - RiaLineArcWellPathCalculator::WellTarget target = - { points[i], true, sphericalCoords.azi(), sphericalCoords.inc(), 0.0, 0.0 }; - targets.push_back( target ); - } - return targets; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPathLateralGeometryDef::RimWellPathLateralGeometryDef() - : changed( this ) - , m_pickTargetsEventHandler( new RicCreateWellTargetsPickEventHandler( this ) ) -{ - CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Targets", - ":/WellTargets.png", - "", - "", - "WellPathLateralGeometry", - "Class containing the geometry of a modeled Well Path Lateral" ); - - this->setUi3dEditorTypeName( RicWellPathGeometry3dEditor::uiEditorTypeName() ); - - CAF_PDM_InitScriptableField( &m_connectionMdOnParentWellPath, "MdAtConnection", 0.0, "MD at Well Path Connection", "", "", "" ); - m_connectionMdOnParentWellPath.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); - - // Temporarily disable changing of MD. It doesn't work right without also altering angles. - m_connectionMdOnParentWellPath.uiCapability()->setUiReadOnly( true ); - - CAF_PDM_InitScriptableFieldNoDefault( &m_wellTargets, "WellPathTargets", "Well Targets", "", "", "" ); - m_wellTargets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() ); - m_wellTargets.uiCapability()->setUiTreeChildrenHidden( true ); - m_wellTargets.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); - m_wellTargets.uiCapability()->setCustomContextMenuEnabled( true ); - - CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" ); - caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPathLateralGeometryDef::~RimWellPathLateralGeometryDef() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimWellPathLateralGeometryDef::mdAtConnection() const -{ - return m_connectionMdOnParentWellPath; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::setMdAtConnection( double md ) -{ - m_connectionMdOnParentWellPath = md; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec3d RimWellPathLateralGeometryDef::anchorPointXyz() const -{ - CAF_ASSERT( m_parentGeometry.notNull() ); - return m_parentGeometry->interpolatedPointAlongWellPath( m_connectionMdOnParentWellPath ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::createTargetAtConnectionPoint( const cvf::Vec3d& tangent ) -{ - auto target = appendTarget(); - target->setAsPointXYZAndTangentTarget( cvf::Vec3d::ZERO, tangent ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::setParentGeometry( const RigWellPath* parentGeometry ) -{ - m_parentGeometry = parentGeometry; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RimWellPathLateralGeometryDef::createWellPathGeometry() -{ - CAF_ASSERT( m_parentGeometry.notNull() ); - - cvf::ref wellPathLateralGeometry = new RigWellPath; - - RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator(); - - auto [allWellPathPoints, allMeasuredDepths] = - m_parentGeometry->clippedPointSubset( m_parentGeometry->measuredDepths().front(), m_connectionMdOnParentWellPath ); - auto originalSize = allWellPathPoints.size(); - - if ( wellPathCalculator.lineArcEndpoints().size() >= 2 ) - { - RiaPolyArcLineSampler arcLineSampler( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() ); - auto [wellPathPoints, measuredDepths] = arcLineSampler.sampledPointsAndMDs( 30, false ); - allWellPathPoints.insert( allWellPathPoints.end(), wellPathPoints.begin(), wellPathPoints.end() ); - std::transform( measuredDepths.begin(), - measuredDepths.end(), - std::back_inserter( allMeasuredDepths ), - [this]( double md ) { return md + this->m_connectionMdOnParentWellPath; } ); - } - wellPathLateralGeometry->setWellPathPoints( allWellPathPoints ); - wellPathLateralGeometry->setMeasuredDepths( allMeasuredDepths ); - wellPathLateralGeometry->setUniqueStartIndex( originalSize ); - - return wellPathLateralGeometry; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimWellPathLateralGeometryDef::wellPlan() const -{ - RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator(); - - RiaWellPlanCalculator wpCalc( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() ); - - return wpCalc.wellPlan(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::updateWellPathVisualization( bool fullUpdate ) -{ - changed.send( fullUpdate ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::pair - RimWellPathLateralGeometryDef::findActiveTargetsAroundInsertionPoint( const RimWellPathTarget* targetToInsertBefore ) -{ - RimWellPathTarget* before = nullptr; - RimWellPathTarget* after = nullptr; - - bool foundTarget = false; - for ( const auto& wt : m_wellTargets ) - { - if ( wt == targetToInsertBefore ) - { - foundTarget = true; - } - - if ( wt->isEnabled() && !after && foundTarget ) after = wt; - - if ( wt->isEnabled() && !foundTarget ) before = wt; - } - - return { before, after }; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::insertTarget( const RimWellPathTarget* targetToInsertBefore, - RimWellPathTarget* targetToInsert ) -{ - size_t index = m_wellTargets.index( targetToInsertBefore ); - if ( index < m_wellTargets.size() ) - m_wellTargets.insert( index, targetToInsert ); - else - m_wellTargets.push_back( targetToInsert ); - - targetToInsert->moved.connect( this, &RimWellPathLateralGeometryDef::onTargetMoved ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::deleteTarget( RimWellPathTarget* targetTodelete ) -{ - m_wellTargets.removeChildObject( targetTodelete ); - delete targetTodelete; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::deleteAllTargets() -{ - m_wellTargets.deleteAllChildObjects(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPathTarget* RimWellPathLateralGeometryDef::appendTarget() -{ - RimWellPathTarget* wellPathTarget = nullptr; - - auto targets = m_wellTargets.childObjects(); - if ( targets.empty() ) - { - wellPathTarget = new RimWellPathTarget; - } - else - { - wellPathTarget = dynamic_cast( - targets.back()->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) ); - } - - if ( wellPathTarget ) - { - m_wellTargets.push_back( wellPathTarget ); - } - wellPathTarget->moved.connect( this, &RimWellPathLateralGeometryDef::onTargetMoved ); - return wellPathTarget; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RimWellPathTarget* RimWellPathLateralGeometryDef::firstActiveTarget() const -{ - for ( const RimWellPathTarget* target : m_wellTargets ) - { - if ( target->isEnabled() ) - { - return target; - } - } - return nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RimWellPathTarget* RimWellPathLateralGeometryDef::lastActiveTarget() const -{ - if ( !m_wellTargets.size() ) return nullptr; - - for ( int tIdx = static_cast( m_wellTargets.size() - 1 ); tIdx >= 0; --tIdx ) - { - if ( m_wellTargets[tIdx]->isEnabled() ) - { - return m_wellTargets[tIdx]; - } - } - return nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::enableTargetPointPicking( bool isEnabling ) -{ - m_pickPointsEnabled = isEnabling; - this->updateConnectedEditors(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::fieldChangedByUi( const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue ) -{ - if ( changedField == &m_pickPointsEnabled ) - { - this->updateConnectedEditors(); - } - - updateWellPathVisualization( false ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) -{ - uiOrdering.add( &m_connectionMdOnParentWellPath ); - uiOrdering.add( &m_wellTargets ); - uiOrdering.add( &m_pickPointsEnabled ); - - uiOrdering.skipRemainingFields( true ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) -{ - uiTreeOrdering.skipRemainingChildren( true ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::initAfterRead() -{ - RimWellPathGroup* group = nullptr; - this->firstAncestorOrThisOfTypeAsserted( group ); - this->setParentGeometry( group->wellPathGeometry() ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimWellPathLateralGeometryDef::activeWellTargets() const -{ - std::vector active; - - for ( const auto& wt : m_wellTargets ) - { - if ( wt->targetType() != RimWellPathTarget::LATERAL_ANCHOR_POINT_MD && wt->isEnabled() ) - { - active.push_back( wt ); - } - } - - return active; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiaLineArcWellPathCalculator RimWellPathLateralGeometryDef::lineArcWellPathCalculator() const -{ - std::vector targetDatas; - - auto [pointVector, measuredDepths] = m_parentGeometry->clippedPointSubset( 0.0, m_connectionMdOnParentWellPath ); - cvf::Vec3d connectionPoint = anchorPointXyz(); - - auto N = pointVector.size(); - if ( N >= 2u ) - { - targetDatas = - createTargetsFromPoints( { pointVector[N - 2] - connectionPoint, pointVector[N - 1] - connectionPoint } ); - } - - std::vector activeTargets = activeWellTargets(); - - for ( auto wellTarget : activeTargets ) - { - targetDatas.push_back( wellTarget->wellTargetData() ); - } - - RiaLineArcWellPathCalculator wellPathCalculator( connectionPoint, targetDatas ); - - const std::vector& targetStatuses = - wellPathCalculator.targetStatuses(); - - for ( size_t tIdx = 0; tIdx < activeTargets.size(); ++tIdx ) - { - activeTargets[tIdx]->flagRadius1AsIncorrect( targetStatuses[tIdx].isRadius1Editable, false, 0 ); - activeTargets[tIdx]->flagRadius2AsIncorrect( targetStatuses[tIdx].isRadius2Editable, false, 0 ); - - if ( targetStatuses[tIdx].hasDerivedTangent ) - { - activeTargets[tIdx]->setDerivedTangent( targetStatuses[tIdx].resultAzimuth, - targetStatuses[tIdx].resultInclination ); - } - - if ( targetStatuses[tIdx].hasOverriddenRadius1 ) - { - activeTargets[tIdx]->flagRadius1AsIncorrect( targetStatuses[tIdx].isRadius1Editable, - true, - targetStatuses[tIdx].resultRadius1 ); - } - - if ( targetStatuses[tIdx].hasOverriddenRadius2 ) - { - activeTargets[tIdx]->flagRadius2AsIncorrect( targetStatuses[tIdx].isRadius2Editable, - true, - targetStatuses[tIdx].resultRadius2 ); - } - } - - return wellPathCalculator; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::onTargetMoved( const caf::SignalEmitter* moved, bool fullUpdate ) -{ - changed.send( fullUpdate ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, - QMenu* menu, - QWidget* fieldEditorWidget ) -{ - caf::CmdFeatureMenuBuilder menuBuilder; - - menuBuilder << "RicNewWellPathListTargetFeature"; - menuBuilder << "Separator"; - menuBuilder << "RicDeleteWellPathTargetFeature"; - - menuBuilder.appendToMenu( menu ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::defineEditorAttribute( const caf::PdmFieldHandle* field, - QString uiConfigName, - caf::PdmUiEditorAttribute* attribute ) -{ - if ( field == &m_pickPointsEnabled ) - { - caf::PdmUiPushButtonEditorAttribute* pbAttribute = dynamic_cast( attribute ); - if ( pbAttribute ) - { - if ( !m_pickPointsEnabled ) - { - pbAttribute->m_buttonText = "Start Picking Targets"; - } - else - { - pbAttribute->m_buttonText = "Stop Picking Targets"; - } - } - } - else if ( field = &m_connectionMdOnParentWellPath ) - { - auto myAttr = dynamic_cast( attribute ); - if ( myAttr ) - { - myAttr->m_minimum = m_parentGeometry->uniqueMeasuredDepths().front(); - myAttr->m_maximum = m_parentGeometry->uniqueMeasuredDepths().back(); - } - } - else if ( field == &m_wellTargets ) - { - auto tvAttribute = dynamic_cast( attribute ); - if ( tvAttribute ) - { - tvAttribute->resizePolicy = caf::PdmUiTableViewEditorAttribute::RESIZE_TO_FIT_CONTENT; - - if ( m_pickPointsEnabled ) - { - tvAttribute->baseColor.setRgb( 255, 220, 255 ); - tvAttribute->alwaysEnforceResizePolicy = true; - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathLateralGeometryDef::defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) -{ - RicWellPathGeometry3dEditorAttribute* attrib = dynamic_cast( attribute ); - if ( attrib ) - { - attrib->pickEventHandler = m_pickTargetsEventHandler; - attrib->enablePicking = m_pickPointsEnabled; - } -} diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathLateralGeometryDef.h b/ApplicationLibCode/ProjectDataModel/RimWellPathLateralGeometryDef.h deleted file mode 100644 index 9789a5a030..0000000000 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathLateralGeometryDef.h +++ /dev/null @@ -1,107 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2020- 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 "RimWellPathGeometryDefInterface.h" - -#include "RiaLineArcWellPathCalculator.h" -#include "RiaWellPlanCalculator.h" - -#include "cafAppEnum.h" -#include "cafPdmChildArrayField.h" -#include "cafPdmChildField.h" -#include "cafPdmField.h" -#include "cafPdmFieldCvfVec3d.h" -#include "cafPdmObject.h" -#include "cafPdmPtrField.h" - -#include "cvfObject.h" - -class RimWellPath; -class RimWellPathTarget; -class RicCreateWellTargetsPickEventHandler; - -class RigWellPath; - -class RimWellPathLateralGeometryDef : public RimWellPathGeometryDefInterface -{ - CAF_PDM_HEADER_INIT; - -public: - caf::Signal changed; - -public: - RimWellPathLateralGeometryDef(); - ~RimWellPathLateralGeometryDef() override; - - double mdAtConnection() const; - void setMdAtConnection( double mdrkb ); - - cvf::Vec3d anchorPointXyz() const override; - - void createTargetAtConnectionPoint( const cvf::Vec3d& tangent ); - - void setParentGeometry( const RigWellPath* parentGeometry ); - cvf::ref createWellPathGeometry(); - - void updateWellPathVisualization( bool fullUpdate ); - std::pair - findActiveTargetsAroundInsertionPoint( const RimWellPathTarget* targetToInsertBefore ); - - void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert ); - void deleteTarget( RimWellPathTarget* targetTodelete ); - void deleteAllTargets(); - RimWellPathTarget* appendTarget(); - - const RimWellPathTarget* firstActiveTarget() const; - const RimWellPathTarget* lastActiveTarget() const; - - void enableTargetPointPicking( bool isEnabling ); - - std::vector wellPlan() const; - std::vector activeWellTargets() const; - -protected: - void defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget ) override; - - void defineEditorAttribute( const caf::PdmFieldHandle* field, - QString uiConfigName, - caf::PdmUiEditorAttribute* attribute ) override; - - void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; - -private: - void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; - - void initAfterRead() override; - - RiaLineArcWellPathCalculator lineArcWellPathCalculator() const; - - void onTargetMoved( const caf::SignalEmitter* moved, bool fullUpdate ); - -private: - caf::PdmField m_connectionMdOnParentWellPath; - caf::PdmChildArrayField m_wellTargets; - caf::PdmField m_pickPointsEnabled; - - std::shared_ptr m_pickTargetsEventHandler; - - cvf::cref m_parentGeometry; -}; diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp b/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp index 2892a4cbaa..363e18287c 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.cpp @@ -23,7 +23,6 @@ #include "RigWellPath.h" #include "RimModeledWellPath.h" -#include "RimModeledWellPathLateral.h" #include "RimWellPath.h" #include "RimWellPathGeometryDef.h" @@ -41,7 +40,6 @@ void caf::AppEnum::setUp() { addItem( RimWellPathTarget::POINT_AND_TANGENT, "POINT_AND_TANGENT", "Point and Tangent" ); addItem( RimWellPathTarget::POINT, "POINT", "Point" ); - addItem( RimWellPathTarget::LATERAL_ANCHOR_POINT_MD, "LATERAL_ANCHOR_POINT_MD", "Lateral Anchor Point MD" ); setDefault( RimWellPathTarget::POINT_AND_TANGENT ); } } // namespace caf @@ -57,6 +55,8 @@ RimWellPathTarget::RimWellPathTarget() , m_isFullUpdateEnabled( true ) { CAF_PDM_InitField( &m_isEnabled, "IsEnabled", true, "", "", "", "" ); + CAF_PDM_InitField( &m_isLocked, "IsLocked", false, "", "", "", "" ); + m_isLocked.uiCapability()->setUiHidden( true ); // m_targetType.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault( &m_targetPoint, "TargetPoint", "Point", "", "", "" ); CAF_PDM_InitField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" ); @@ -68,10 +68,8 @@ RimWellPathTarget::RimWellPathTarget() CAF_PDM_InitField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", "" ); CAF_PDM_InitField( &m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", "" ); - CAF_PDM_InitField( &m_lateralMDConnection, "LateralMD", 0.0, "Lateral Anchor Point MD", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_parentWellPath, "ParentWellPath", "Parent Well Path", "", "", "" ); - m_lateralMDConnection.uiCapability()->setUiHidden( true ); m_parentWellPath.uiCapability()->setUiHidden( true ); } @@ -109,6 +107,17 @@ void RimWellPathTarget::setAsPointTargetXYD( const cvf::Vec3d& point ) m_inclination = 0.0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::setAsPointTargetXYZ( const cvf::Vec3d& point ) +{ + m_targetType = POINT; + m_targetPoint = cvf::Vec3d( point.x(), point.y(), -point.z() ); + m_azimuth = 0.0; + m_inclination = 0.0; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -129,16 +138,6 @@ void RimWellPathTarget::setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, m_inclination = cvf::Math::toDegrees( inclination ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPathTarget::setAsLateralMDConnection( RimWellPath* wellPath, double md ) -{ - m_targetType = LATERAL_ANCHOR_POINT_MD; - m_parentWellPath.setValue( wellPath ); - m_lateralMDConnection = md; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -181,16 +180,9 @@ RimWellPathTarget::TargetTypeEnum RimWellPathTarget::targetType() const //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimWellPathTarget::targetPointXYZ() const { - if ( m_targetType != LATERAL_ANCHOR_POINT_MD ) - { - cvf::Vec3d xyzPoint( m_targetPoint() ); - xyzPoint.z() = -xyzPoint.z(); - return xyzPoint; - } - else - { - return m_parentWellPath->wellPathGeometry()->interpolatedPointAlongWellPath( m_lateralMDConnection ); - } + cvf::Vec3d xyzPoint( m_targetPoint() ); + xyzPoint.z() = -xyzPoint.z(); + return xyzPoint; } //-------------------------------------------------------------------------------------------------- @@ -202,12 +194,6 @@ double RimWellPathTarget::azimuth() const { return cvf::Math::toRadians( m_azimuth ); } - else if ( m_targetType() == LATERAL_ANCHOR_POINT_MD ) - { - auto tangent = m_parentWellPath->wellPathGeometry()->tangentAlongWellPath( m_lateralMDConnection ); - RiaOffshoreSphericalCoords sphericalCoords( tangent ); - return cvf::Math::toRadians( sphericalCoords.azi() ); - } else { return std::numeric_limits::infinity(); @@ -223,12 +209,6 @@ double RimWellPathTarget::inclination() const { return cvf::Math::toRadians( m_inclination ); } - else if ( m_targetType() == LATERAL_ANCHOR_POINT_MD ) - { - auto tangent = m_parentWellPath->wellPathGeometry()->tangentAlongWellPath( m_lateralMDConnection ); - RiaOffshoreSphericalCoords sphericalCoords( tangent ); - return cvf::Math::toRadians( sphericalCoords.inc() ); - } else { return std::numeric_limits::infinity(); @@ -240,11 +220,6 @@ double RimWellPathTarget::inclination() const //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimWellPathTarget::tangent() const { - if ( m_targetType() == LATERAL_ANCHOR_POINT_MD ) - { - return m_parentWellPath->wellPathGeometry()->tangentAlongWellPath( m_lateralMDConnection ); - } - double aziRad = cvf::Math::toRadians( m_azimuth ); double incRad = cvf::Math::toRadians( m_inclination ); @@ -426,7 +401,7 @@ void RimWellPathTarget::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi { m_hasTangentConstraintUiField = ( m_targetType == POINT_AND_TANGENT ); - if ( m_isEnabled() ) + if ( m_isEnabled() && !m_isLocked() ) { m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly( false ); m_targetType.uiCapability()->setUiReadOnly( false ); @@ -453,4 +428,9 @@ void RimWellPathTarget::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi m_dogleg2.uiCapability()->setUiReadOnly( true ); m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly( true ); } + + if ( m_isLocked ) + { + m_isEnabled.uiCapability()->setUiReadOnly( true ); + } } diff --git a/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.h b/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.h index f516394383..787266d601 100644 --- a/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.h +++ b/ApplicationLibCode/ProjectDataModel/RimWellPathTarget.h @@ -43,9 +43,9 @@ public: bool isEnabled() const; void setAsPointTargetXYD( const cvf::Vec3d& point ); + void setAsPointTargetXYZ( const cvf::Vec3d& point); void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, const cvf::Vec3d& tangent ); void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuth, double inclination ); - void setAsLateralMDConnection( RimWellPath* wellPath, double md ); void setDerivedTangent( double azimuth, double inclination ); RiaLineArcWellPathCalculator::WellTarget wellTargetData(); @@ -53,8 +53,7 @@ public: enum TargetTypeEnum { POINT_AND_TANGENT, - POINT, - LATERAL_ANCHOR_POINT_MD + POINT }; TargetTypeEnum targetType() const; cvf::Vec3d targetPointXYZ() const; @@ -82,6 +81,7 @@ private: void enableFullUpdate( bool enable ); bool m_isFullUpdateEnabled; caf::PdmField m_isEnabled; + caf::PdmField m_isLocked; caf::PdmField> m_targetType; caf::PdmField m_targetPoint; caf::PdmField m_azimuth; @@ -90,6 +90,5 @@ private: caf::PdmField m_dogleg2; caf::PdmField m_hasTangentConstraintUiField; - caf::PdmField m_lateralMDConnection; caf::PdmPtrField m_parentWellPath; }; diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.cpp b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.cpp index ad2de5ea68..34064f743b 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.cpp @@ -48,6 +48,14 @@ RimStimPlanModelCollection::~RimStimPlanModelCollection() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimStimPlanModelCollection::hasStimPlanModels() const +{ + return !m_stimPlanModels.empty(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.h b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.h index 78c8351236..c7c523df3f 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.h +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCollection.h @@ -38,6 +38,7 @@ public: RimStimPlanModelCollection( void ); ~RimStimPlanModelCollection( void ) override; + bool hasStimPlanModels() const; void addStimPlanModel( RimStimPlanModel* fracture ); void deleteStimPlanModels(); diff --git a/ApplicationLibCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp b/ApplicationLibCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp index fe10559a4d..19adef628f 100644 --- a/ApplicationLibCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp +++ b/ApplicationLibCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp @@ -171,7 +171,7 @@ double RigEclipseToStimPlanCalculator::areaWeightedMatrixPermeability() const } } - return calc.weightedMean(); + return calc.validAggregatedWeight() ? calc.weightedMean() : 0.0; } //-------------------------------------------------------------------------------------------------- @@ -230,7 +230,7 @@ double RigEclipseToStimPlanCalculator::areaWeightedConductivity() const calc.addValueAndWeight( singleCellCalc.second.fractureCell().getConductivityValue(), cellArea ); } - return calc.weightedMean(); + return calc.validAggregatedWeight() ? calc.weightedMean() : 0.0; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.cpp b/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.cpp index 81c77aef73..a56775345c 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.cpp @@ -18,7 +18,7 @@ #include "RigFishbonesGeometry.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RigWellPath.h" #include "RimWellPath.h" @@ -28,7 +28,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigFisbonesGeometry::RigFisbonesGeometry( RimFishbonesMultipleSubs* fishbonesSub ) +RigFisbonesGeometry::RigFisbonesGeometry( RimFishbones* fishbonesSub ) : m_fishbonesSub( fishbonesSub ) { } @@ -40,19 +40,12 @@ std::vector> RigFisbonesGeometry::coordsForLateral { CVF_ASSERT( lateralIndex < m_fishbonesSub->lateralLengths().size() ); - bool found = false; - for ( auto& sub : m_fishbonesSub->installedLateralIndices() ) - { - if ( sub.subIndex == subIndex ) - { - auto it = std::find( sub.lateralIndices.begin(), sub.lateralIndices.end(), lateralIndex ); - if ( it != sub.lateralIndices.end() ) - { - found = true; - break; - } - } - } + const auto& subAndLateralIndices = m_fishbonesSub->installedLateralIndices(); + + bool found = std::find( subAndLateralIndices.begin(), + subAndLateralIndices.end(), + std::make_pair( subIndex, lateralIndex ) ) != subAndLateralIndices.end(); + CVF_ASSERT( found ); cvf::Vec3d position; diff --git a/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.h b/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.h index 9c2a6e1e91..37d9f0f6a6 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.h +++ b/ApplicationLibCode/ReservoirDataModel/RigFishbonesGeometry.h @@ -25,7 +25,7 @@ #include -class RimFishbonesMultipleSubs; +class RimFishbones; //================================================================================================== /// @@ -34,7 +34,7 @@ class RimFishbonesMultipleSubs; class RigFisbonesGeometry { public: - explicit RigFisbonesGeometry( RimFishbonesMultipleSubs* fishbonesSub ); + explicit RigFisbonesGeometry( RimFishbones* fishbonesSub ); std::vector> coordsForLateral( size_t subIndex, size_t lateralIndex ) const; @@ -54,5 +54,5 @@ private: static cvf::Vec3d closestMainAxis( const cvf::Vec3d& vec ); private: - caf::PdmPointer m_fishbonesSub; + caf::PdmPointer m_fishbonesSub; }; diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellPath.cpp b/ApplicationLibCode/ReservoirDataModel/RigWellPath.cpp index 1c5562028e..7ab299e4fa 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellPath.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigWellPath.cpp @@ -31,7 +31,8 @@ RigWellPath::RigWellPath() : cvf::Object() , m_hasDatumElevation( false ) , m_datumElevation( 0.0 ) - , m_startIndex( 0u ) + , m_uniqueStartIndex( 0u ) + , m_uniqueEndIndex( std::numeric_limits::max() ) , objectBeingDeleted( this ) { } @@ -45,9 +46,11 @@ RigWellPath::RigWellPath( const RigWellPath& rhs ) , m_measuredDepths( rhs.m_measuredDepths ) , m_hasDatumElevation( rhs.m_hasDatumElevation ) , m_datumElevation( rhs.m_datumElevation ) - , m_startIndex( rhs.m_startIndex ) + , m_uniqueStartIndex( rhs.m_uniqueStartIndex ) + , m_uniqueEndIndex( rhs.m_uniqueEndIndex ) , objectBeingDeleted( this ) { + CVF_ASSERT( m_wellPathPoints.size() == m_measuredDepths.size() ); } //-------------------------------------------------------------------------------------------------- @@ -59,9 +62,11 @@ RigWellPath::RigWellPath( const std::vector& wellPathPoints, const s , m_measuredDepths( measuredDepths ) , m_hasDatumElevation( false ) , m_datumElevation( 0.0 ) - , m_startIndex( 0u ) + , m_uniqueStartIndex( 0u ) + , m_uniqueEndIndex( std::numeric_limits::max() ) , objectBeingDeleted( this ) { + CVF_ASSERT( m_wellPathPoints.size() == m_measuredDepths.size() ); } //-------------------------------------------------------------------------------------------------- @@ -69,14 +74,19 @@ RigWellPath::RigWellPath( const std::vector& wellPathPoints, const s //-------------------------------------------------------------------------------------------------- RigWellPath& RigWellPath::operator=( const RigWellPath& rhs ) { - m_wellPathPoints = rhs.m_wellPathPoints; - m_measuredDepths = rhs.m_measuredDepths; + m_wellPathPoints = rhs.m_wellPathPoints; + m_measuredDepths = rhs.m_measuredDepths; + CVF_ASSERT( m_wellPathPoints.size() == m_measuredDepths.size() ); m_hasDatumElevation = rhs.m_hasDatumElevation; m_datumElevation = rhs.m_datumElevation; - m_startIndex = rhs.m_startIndex; + m_uniqueStartIndex = rhs.m_uniqueStartIndex; + m_uniqueEndIndex = rhs.m_uniqueEndIndex; return *this; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- RigWellPath::~RigWellPath() { objectBeingDeleted.send(); @@ -179,7 +189,7 @@ double RigWellPath::rkbDiff() const } // If measured depth is zero, use the z-value of the well path points - if ( m_wellPathPoints.size() > 0 && m_measuredDepths.size() > 0 ) + if ( !m_wellPathPoints.empty() && !m_measuredDepths.empty() ) { double epsilon = 1e-3; @@ -189,7 +199,8 @@ double RigWellPath::rkbDiff() const return diff; } - else if ( cvf::Math::abs( m_wellPathPoints[0].z() ) < epsilon ) + + if ( cvf::Math::abs( m_wellPathPoints[0].z() ) < epsilon ) { return m_measuredDepths[0]; // Assume a vertical drop before the first md point. } @@ -254,6 +265,9 @@ cvf::Vec3d return interpolatedVector; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- cvf::Vec3d RigWellPath::interpolatedPointAlongWellPath( double measuredDepth, double* horizontalLengthAlongWellToStartClipPoint /*= nullptr*/ ) const @@ -272,7 +286,8 @@ cvf::Vec3d RigWellPath::tangentAlongWellPath( double measuredDepth ) const { return ( m_wellPathPoints[1] - m_wellPathPoints[0] ).getNormalized(); } - else if ( measuredDepth >= m_measuredDepths.back() ) + + if ( measuredDepth >= m_measuredDepths.back() ) { auto N = m_measuredDepths.size(); return ( m_wellPathPoints[N - 1] - m_wellPathPoints[N - 2] ).getNormalized(); @@ -421,10 +436,9 @@ cvf::ref RigWellPath::commonGeometry( const std::vector( new RigWellPath( *allGeometries.front() ) ); + if ( allGeometries.empty() ) return nullptr; + + if ( allGeometries.size() == 1u ) return cvf::ref( new RigWellPath( *allGeometries.front() ) ); const RigWellPath* firstGeometry = allGeometries.front(); @@ -459,9 +473,12 @@ cvf::ref RigWellPath::commonGeometry( const std::vector RigWellPath::uniqueWellPathPoints() const { - return std::vector( m_wellPathPoints.begin() + m_startIndex, m_wellPathPoints.end() ); + return std::vector( m_wellPathPoints.begin() + uniqueStartIndex(), + m_wellPathPoints.begin() + uniqueEndIndex() + 1u ); } //-------------------------------------------------------------------------------------------------- @@ -485,7 +511,8 @@ std::vector RigWellPath::uniqueWellPathPoints() const //-------------------------------------------------------------------------------------------------- std::vector RigWellPath::uniqueMeasuredDepths() const { - return std::vector( m_measuredDepths.begin() + m_startIndex, m_measuredDepths.end() ); + return std::vector( m_measuredDepths.begin() + m_uniqueStartIndex, + m_measuredDepths.begin() + uniqueEndIndex() + 1u ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigWellPath.h b/ApplicationLibCode/ReservoirDataModel/RigWellPath.h index 4b0ae38a5a..3954207b9d 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigWellPath.h +++ b/ApplicationLibCode/ReservoirDataModel/RigWellPath.h @@ -72,8 +72,9 @@ public: double identicalTubeLength( const RigWellPath& otherWellPathGeometry ) const; static cvf::ref commonGeometry( const std::vector& allGeometries ); - void setUniqueStartIndex( size_t uniqueStartIndex ); + void setUniqueStartAndEndIndex( size_t uniqueStartIndex, size_t uniqueEndIndex ); size_t uniqueStartIndex() const; + size_t uniqueEndIndex() const; std::vector uniqueWellPathPoints() const; std::vector uniqueMeasuredDepths() const; @@ -95,5 +96,6 @@ private: bool m_hasDatumElevation; double m_datumElevation; - size_t m_startIndex; + size_t m_uniqueStartIndex; + size_t m_uniqueEndIndex; }; diff --git a/ApplicationLibCode/UnitTests/RimWellPathCompletions-Test.cpp b/ApplicationLibCode/UnitTests/RimWellPathCompletions-Test.cpp index 9598b974c1..e40e12cd31 100644 --- a/ApplicationLibCode/UnitTests/RimWellPathCompletions-Test.cpp +++ b/ApplicationLibCode/UnitTests/RimWellPathCompletions-Test.cpp @@ -11,7 +11,7 @@ TEST( RimWellPathCompletions, WellNameRegExp ) std::vector validNames = { "RASASD", "gf0sdf", "sd-ASD12", "1-AA_b" }; std::vector invalidNames = { ".AdSD", "+gf0sdf", "sd ASD12", "ABCDEFGHIJKL" }; - QRegExp rx = RimWellPathCompletions::wellNameForExportRegExp(); + QRegExp rx = RimWellPathCompletionSettings::wellNameForExportRegExp(); EXPECT_TRUE( rx.isValid() ); for ( QString validName : validNames ) @@ -30,7 +30,7 @@ TEST( RimWellPathCompletions, WellNameRegExpValidator ) std::vector invalidNames = { ".AdSD", "+gf0sdf", "sd ASD12", "ABCDEFGHIJKL" }; QString emptyString = ""; - QRegExp rx = RimWellPathCompletions::wellNameForExportRegExp(); + QRegExp rx = RimWellPathCompletionSettings::wellNameForExportRegExp(); QRegExpValidator validator( nullptr ); validator.setRegExp( rx ); @@ -47,4 +47,4 @@ TEST( RimWellPathCompletions, WellNameRegExpValidator ) int dummyPos; EXPECT_EQ( QValidator::Intermediate, validator.validate( emptyString, dummyPos ) ); -} \ No newline at end of file +} diff --git a/ApplicationLibCode/UserInterface/RiuWellPathComponentPlotItem.cpp b/ApplicationLibCode/UserInterface/RiuWellPathComponentPlotItem.cpp index ffa2e1fc40..6075b4516d 100644 --- a/ApplicationLibCode/UserInterface/RiuWellPathComponentPlotItem.cpp +++ b/ApplicationLibCode/UserInterface/RiuWellPathComponentPlotItem.cpp @@ -21,7 +21,7 @@ #include "RiaColorTables.h" #include "RiaColorTools.h" -#include "RimFishbonesMultipleSubs.h" +#include "RimFishbones.h" #include "RimFracture.h" #include "RimFractureTemplate.h" #include "RimPerforationInterval.h" diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h index 69d317c50c..ed8b1fb789 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h @@ -70,7 +70,7 @@ class PdmUiPropertyView : public QWidget { Q_OBJECT public: - PdmUiPropertyView( QWidget* parent = nullptr, Qt::WindowFlags f = nullptr ); + PdmUiPropertyView( QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags() ); ~PdmUiPropertyView() override; void setUiConfigurationName( QString uiConfigName ); diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index a2a9f16acc..70036125a0 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,7 +1,7 @@ set(RESINSIGHT_MAJOR_VERSION 2020) set(RESINSIGHT_MINOR_VERSION 10) -set(RESINSIGHT_PATCH_VERSION 1) +set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions set(RESINSIGHT_VERSION_TEXT "-dev")