Improve how wells are connected during import

When importing new wells, consider all wells when connecting multi segment wells
Make sure that import of individual well paths will give the same ordering as importing all wells in a single operation.
This commit is contained in:
Magne Sjaastad 2023-03-07 12:51:14 +01:00
parent daf30b4ee1
commit eb273aeb5e
13 changed files with 98 additions and 88 deletions

View File

@ -913,8 +913,7 @@ bool RiaApplication::openOdbCaseFromFile( const QString& fileName, bool applyTim
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Add a list of well path file paths (JSON files) to the well path collection /// Add a list of well path file paths (JSON files) to the well path collection
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimWellPath*> std::vector<RimWellPath*> RiaApplication::addWellPathsToModel( QList<QString> wellPathFilePaths, gsl::not_null<QStringList*> errorMessages )
RiaApplication::addWellPathsToModel( QList<QString> wellPathFilePaths, bool importGrouped, gsl::not_null<QStringList*> errorMessages )
{ {
if ( m_project == nullptr || m_project->oilFields.size() < 1 ) return {}; if ( m_project == nullptr || m_project->oilFields.size() < 1 ) return {};
@ -932,7 +931,7 @@ std::vector<RimWellPath*>
std::vector<RimWellPath*> wellPaths; std::vector<RimWellPath*> wellPaths;
if ( oilField->wellPathCollection ) if ( oilField->wellPathCollection )
{ {
wellPaths = oilField->wellPathCollection->addWellPaths( wellPathFilePaths, importGrouped, errorMessages ); wellPaths = oilField->wellPathCollection->addWellPaths( wellPathFilePaths, errorMessages );
} }
oilField->wellPathCollection->updateConnectedEditors(); oilField->wellPathCollection->updateConnectedEditors();

View File

@ -147,8 +147,7 @@ public:
bool openOdbCaseFromFile( const QString& fileName, bool applyTimeStepFilter = false ); bool openOdbCaseFromFile( const QString& fileName, bool applyTimeStepFilter = false );
std::vector<RimWellPath*> std::vector<RimWellPath*> addWellPathsToModel( QList<QString> wellPathFilePaths, gsl::not_null<QStringList*> errorMessages );
addWellPathsToModel( QList<QString> wellPathFilePaths, bool importGrouped, gsl::not_null<QStringList*> errorMessages );
void addWellPathFormationsToModel( QList<QString> wellPathFilePaths ); void addWellPathFormationsToModel( QList<QString> wellPathFilePaths );
std::vector<RimWellLogFile*> addWellLogsToModel( const QList<QString>& wellLogFilePaths, gsl::not_null<QStringList*> errorMessages ); std::vector<RimWellLogFile*> addWellLogsToModel( const QList<QString>& wellLogFilePaths, gsl::not_null<QStringList*> errorMessages );

View File

@ -81,7 +81,7 @@ RimStimPlanModel* RicNewStimPlanModelFeature::addStimPlanModel( RimWellPath*
stimPlanModel->setThicknessDirectionWellPath( thicknessDirectionWellPath ); stimPlanModel->setThicknessDirectionWellPath( thicknessDirectionWellPath );
std::vector<RimWellPath*> wellPaths = { thicknessDirectionWellPath }; std::vector<RimWellPath*> wellPaths = { thicknessDirectionWellPath };
wellPathCollection->addWellPaths( wellPaths, false ); wellPathCollection->addWellPaths( wellPaths );
if ( project ) if ( project )
{ {

View File

@ -127,9 +127,8 @@ void RicCreateEnsembleWellLogFeature::executeCommand( const RicCreateEnsembleWel
// Load well path from file // Load well path from file
QStringList wellPathFilePaths; QStringList wellPathFilePaths;
wellPathFilePaths << ui.wellPathFilePath(); wellPathFilePaths << ui.wellPathFilePath();
bool importGrouped = false;
QStringList errorMessages; QStringList errorMessages;
std::vector<RimWellPath*> wellPaths = RicImportWellPaths::importWellPaths( wellPathFilePaths, importGrouped, &errorMessages ); std::vector<RimWellPath*> wellPaths = RicImportWellPaths::importWellPaths( wellPathFilePaths, &errorMessages );
if ( wellPaths.empty() ) return; if ( wellPaths.empty() ) return;
wellPath = wellPaths[0]; wellPath = wellPaths[0];

View File

@ -118,7 +118,7 @@ void RicWellPathsImportSsihubFeature::onActionTriggered( bool isChecked )
if ( wellPaths.size() > 0 ) if ( wellPaths.size() > 0 )
{ {
QStringList errorMessages; QStringList errorMessages;
app->addWellPathsToModel( wellPaths, false, &errorMessages ); app->addWellPathsToModel( wellPaths, &errorMessages );
app->project()->scheduleCreateDisplayModelAndRedrawAllViews(); app->project()->scheduleCreateDisplayModelAndRedrawAllViews();
} }

View File

@ -163,7 +163,7 @@ void RicCreateMultipleWellPathLaterals::slotAppendFractures()
newModeledWellPath->wellPathTieIn()->setTieInMeasuredDepth( measuredDepth ); newModeledWellPath->wellPathTieIn()->setTieInMeasuredDepth( measuredDepth );
wellPathCollection->addWellPath( newModeledWellPath, false ); wellPathCollection->addWellPath( newModeledWellPath );
newModeledWellPath->resolveReferencesRecursively(); newModeledWellPath->resolveReferencesRecursively();
newModeledWellPath->updateReferencePoint(); newModeledWellPath->updateReferencePoint();

View File

@ -66,7 +66,6 @@ RicImportWellPaths::RicImportWellPaths()
{ {
CAF_PDM_InitScriptableFieldNoDefault( &m_wellPathFolder, "wellPathFolder", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_wellPathFolder, "wellPathFolder", "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_wellPathFiles, "wellPathFiles", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_wellPathFiles, "wellPathFiles", "" );
CAF_PDM_InitScriptableField( &m_importGrouped, "importGrouped", false, "" );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -124,7 +123,7 @@ caf::PdmScriptResponse RicImportWellPaths::execute()
caf::PdmScriptResponse response; caf::PdmScriptResponse response;
if ( !wellPathFiles.empty() ) if ( !wellPathFiles.empty() )
{ {
std::vector<RimWellPath*> importedWellPaths = importWellPaths( wellPathFiles, m_importGrouped(), &warningMessages ); std::vector<RimWellPath*> importedWellPaths = importWellPaths( wellPathFiles, &warningMessages );
if ( !importedWellPaths.empty() ) if ( !importedWellPaths.empty() )
{ {
RicImportWellPathsResult* wellPathsResult = new RicImportWellPathsResult; RicImportWellPathsResult* wellPathsResult = new RicImportWellPathsResult;
@ -157,15 +156,14 @@ caf::PdmScriptResponse RicImportWellPaths::execute()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimWellPath*> std::vector<RimWellPath*> RicImportWellPaths::importWellPaths( const QStringList& wellPathFilePaths, QStringList* errorMessages )
RicImportWellPaths::importWellPaths( const QStringList& wellPathFilePaths, bool importGrouped, QStringList* errorMessages )
{ {
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
// Remember the path to next time // Remember the path to next time
app->setLastUsedDialogDirectory( "WELLPATH_DIR", QFileInfo( wellPathFilePaths.last() ).absolutePath() ); app->setLastUsedDialogDirectory( "WELLPATH_DIR", QFileInfo( wellPathFilePaths.last() ).absolutePath() );
std::vector<RimWellPath*> wellPaths = app->addWellPathsToModel( wellPathFilePaths, importGrouped, errorMessages ); std::vector<RimWellPath*> wellPaths = app->addWellPathsToModel( wellPathFilePaths, errorMessages );
RimProject* project = app->project(); RimProject* project = app->project();

View File

@ -42,7 +42,7 @@ public:
RicImportWellPaths(); RicImportWellPaths();
caf::PdmScriptResponse execute() override; caf::PdmScriptResponse execute() override;
static std::vector<RimWellPath*> importWellPaths( const QStringList& wellPathFilePaths, bool importGrouped, QStringList* errorMessages ); static std::vector<RimWellPath*> importWellPaths( const QStringList& wellPathFilePaths, QStringList* errorMessages );
protected: protected:
static QStringList wellPathNameFilters(); static QStringList wellPathNameFilters();
@ -54,5 +54,4 @@ protected:
protected: protected:
caf::PdmField<QString> m_wellPathFolder; caf::PdmField<QString> m_wellPathFolder;
caf::PdmField<std::vector<QString>> m_wellPathFiles; caf::PdmField<std::vector<QString>> m_wellPathFiles;
caf::PdmField<bool> m_importGrouped;
}; };

View File

@ -80,7 +80,7 @@ void RicNewEditableWellPathFeature::onActionTriggered( bool isChecked )
newWellPaths.back()->setName( "Well-" + QString::number( modelledWellpathCount + 1 ) ); newWellPaths.back()->setName( "Well-" + QString::number( modelledWellpathCount + 1 ) );
newModeledWellPath->setWellPathColor( RiaColorTables::editableWellPathsPaletteColors().cycledColor3f( modelledWellpathCount ) ); newModeledWellPath->setWellPathColor( RiaColorTables::editableWellPathsPaletteColors().cycledColor3f( modelledWellpathCount ) );
wellPathCollection->addWellPaths( newWellPaths, false ); wellPathCollection->addWellPaths( newWellPaths );
wellPathCollection->uiCapability()->updateConnectedEditors(); wellPathCollection->uiCapability()->updateConnectedEditors();
newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true ); newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true );

View File

@ -116,8 +116,7 @@ RimModeledWellPath* RicNewWellPathLateralAtDepthFeature::createLateralAtMeasured
newModeledWellPath->createWellPathGeometry(); newModeledWellPath->createWellPathGeometry();
bool importGrouped = false; wellPathColl->addWellPath( newModeledWellPath );
wellPathColl->addWellPath( newModeledWellPath, importGrouped );
wellPathColl->updateAllRequiredEditors(); wellPathColl->updateAllRequiredEditors();
project->scheduleCreateDisplayModelAndRedrawAllViews(); project->scheduleCreateDisplayModelAndRedrawAllViews();

View File

@ -155,7 +155,7 @@ RimModeledWellPath* RicPasteModeledWellPathFeature::duplicateAndInitializeWellPa
QString name = sourceWellPath->name() + "(copy)"; QString name = sourceWellPath->name() + "(copy)";
destinationWellPath->setName( name ); destinationWellPath->setName( name );
wpc->addWellPath( destinationWellPath, false ); wpc->addWellPath( destinationWellPath );
// Resolve references, will connect to the fracture template // Resolve references, will connect to the fracture template
destinationWellPath->resolveReferencesRecursively(); destinationWellPath->resolveReferencesRecursively();

View File

@ -149,8 +149,8 @@ void RimWellPathCollection::loadDataAndUpdate()
{ {
progress.setProgressDescription( QString( "Reading file %1" ).arg( wellPath->name() ) ); progress.setProgressDescription( QString( "Reading file %1" ).arg( wellPath->name() ) );
RimFileWellPath* fWPath = dynamic_cast<RimFileWellPath*>( wellPath ); auto* fWPath = dynamic_cast<RimFileWellPath*>( wellPath );
RimModeledWellPath* mWPath = dynamic_cast<RimModeledWellPath*>( wellPath ); auto* mWPath = dynamic_cast<RimModeledWellPath*>( wellPath );
if ( fWPath ) if ( fWPath )
{ {
if ( !fWPath->filePath().isEmpty() ) if ( !fWPath->filePath().isEmpty() )
@ -201,19 +201,19 @@ void RimWellPathCollection::loadDataAndUpdate()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimWellPath*> RimWellPathCollection::addWellPaths( QStringList filePaths, bool importGrouped, QStringList* errorMessages ) std::vector<RimWellPath*> RimWellPathCollection::addWellPaths( QStringList filePaths, QStringList* errorMessages )
{ {
CAF_ASSERT( errorMessages ); CAF_ASSERT( errorMessages );
std::vector<RimFileWellPath*> wellPathArray; std::vector<RimFileWellPath*> wellPathArray;
for ( QString filePath : filePaths ) for ( const QString& filePath : filePaths )
{ {
// Check if this file is already open // Check if this file is already open
bool alreadyOpen = false; bool alreadyOpen = false;
for ( auto wellPath : m_wellPaths ) for ( const auto& wellPath : m_wellPaths )
{ {
RimFileWellPath* fWPath = dynamic_cast<RimFileWellPath*>( wellPath.p() ); auto* fWPath = dynamic_cast<RimFileWellPath*>( wellPath.p() );
if ( !fWPath ) continue; if ( !fWPath ) continue;
QFile f1; QFile f1;
@ -238,7 +238,7 @@ std::vector<RimWellPath*> RimWellPathCollection::addWellPaths( QStringList fileP
if ( fi.suffix().compare( "json" ) == 0 ) if ( fi.suffix().compare( "json" ) == 0 )
{ {
RimFileWellPath* wellPath = new RimFileWellPath(); auto* wellPath = new RimFileWellPath();
wellPath->setFilepath( filePath ); wellPath->setFilepath( filePath );
wellPathArray.push_back( wellPath ); wellPathArray.push_back( wellPath );
} }
@ -248,7 +248,7 @@ std::vector<RimWellPath*> RimWellPathCollection::addWellPaths( QStringList fileP
size_t wellPathCount = m_wellPathImporter->wellDataCount( filePath ); size_t wellPathCount = m_wellPathImporter->wellDataCount( filePath );
for ( size_t i = 0; i < wellPathCount; ++i ) for ( size_t i = 0; i < wellPathCount; ++i )
{ {
RimFileWellPath* wellPath = new RimFileWellPath(); auto* wellPath = new RimFileWellPath();
wellPath->setFilepath( filePath ); wellPath->setFilepath( filePath );
wellPath->setWellPathIndexInFile( static_cast<int>( i ) ); wellPath->setWellPathIndexInFile( static_cast<int>( i ) );
wellPathArray.push_back( wellPath ); wellPathArray.push_back( wellPath );
@ -257,7 +257,7 @@ std::vector<RimWellPath*> RimWellPathCollection::addWellPaths( QStringList fileP
} }
} }
readAndAddWellPaths( wellPathArray, importGrouped ); readAndAddWellPaths( wellPathArray );
CAF_ASSERT( wellPathArray.empty() ); CAF_ASSERT( wellPathArray.empty() );
scheduleRedrawAffectedViews(); scheduleRedrawAffectedViews();
@ -269,7 +269,7 @@ std::vector<RimWellPath*> RimWellPathCollection::addWellPaths( QStringList fileP
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellPathCollection::addWellPath( gsl::not_null<RimWellPath*> wellPath, bool importGrouped ) void RimWellPathCollection::addWellPath( gsl::not_null<RimWellPath*> wellPath )
{ {
m_wellPaths.push_back( wellPath ); m_wellPaths.push_back( wellPath );
@ -289,11 +289,10 @@ std::vector<RimWellPath*> RimWellPathCollection::allWellPaths() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellPathCollection::readAndAddWellPaths( std::vector<RimFileWellPath*>& wellPathArray, bool importGrouped ) void RimWellPathCollection::readAndAddWellPaths( std::vector<RimFileWellPath*>& wellPathArray )
{ {
caf::ProgressInfo progress( wellPathArray.size(), "Reading well paths from file" ); caf::ProgressInfo progress( wellPathArray.size(), "Reading well paths from file" );
std::vector<RimWellPath*> wellPathsToGroup;
for ( RimFileWellPath* wellPath : wellPathArray ) for ( RimFileWellPath* wellPath : wellPathArray )
{ {
wellPath->readWellPathFile( nullptr, m_wellPathImporter.get(), true ); wellPath->readWellPathFile( nullptr, m_wellPathImporter.get(), true );
@ -321,16 +320,14 @@ void RimWellPathCollection::readAndAddWellPaths( std::vector<RimFileWellPath*>&
{ {
wellPath->setWellPathColor( RiaColorTables::wellPathsPaletteColors().cycledColor3f( m_wellPaths.size() ) ); wellPath->setWellPathColor( RiaColorTables::wellPathsPaletteColors().cycledColor3f( m_wellPaths.size() ) );
wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) ); wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) );
addWellPath( wellPath, false ); addWellPath( wellPath );
wellPathsToGroup.push_back( wellPath );
} }
progress.incrementProgress(); progress.incrementProgress();
} }
wellPathArray.clear(); // This should not be used again. We may have deleted items wellPathArray.clear(); // This should not be used again. We may have deleted items
groupWellPaths( wellPathsToGroup ); groupWellPaths( allWellPaths() );
sortWellsByName(); sortWellsByName();
rebuildWellPathNodes(); rebuildWellPathNodes();
} }
@ -338,14 +335,14 @@ void RimWellPathCollection::readAndAddWellPaths( std::vector<RimFileWellPath*>&
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellPathCollection::addWellPaths( const std::vector<RimWellPath*> incomingWellPaths, bool importGrouped ) void RimWellPathCollection::addWellPaths( const std::vector<RimWellPath*> incomingWellPaths )
{ {
for ( const auto& wellPath : incomingWellPaths ) for ( const auto& wellPath : incomingWellPaths )
{ {
addWellPath( wellPath, importGrouped ); addWellPath( wellPath );
} }
groupWellPaths( incomingWellPaths ); groupWellPaths( allWellPaths() );
sortWellsByName(); sortWellsByName();
rebuildWellPathNodes(); rebuildWellPathNodes();
@ -375,7 +372,7 @@ std::vector<RimWellLogFile*> RimWellPathCollection::addWellLogs( const QStringLi
if ( !wellPath ) if ( !wellPath )
{ {
wellPath = new RimWellPath(); wellPath = new RimWellPath();
addWellPath( wellPath, false ); addWellPath( wellPath );
} }
wellPath->addWellLogFile( logFileInfo ); wellPath->addWellLogFile( logFileInfo );
@ -400,30 +397,30 @@ void RimWellPathCollection::addWellPathFormations( const QStringList& filePaths
bool fileReadSuccess = false; bool fileReadSuccess = false;
for ( QString filePath : filePaths ) for ( const QString& filePath : filePaths )
{ {
std::map<QString, cvf::ref<RigWellPathFormations>> newFormations = std::map<QString, cvf::ref<RigWellPathFormations>> newFormations =
m_wellPathFormationsImporter->readWellPathFormationsFromPath( filePath ); m_wellPathFormationsImporter->readWellPathFormationsFromPath( filePath );
for ( auto it = newFormations.begin(); it != newFormations.end(); it++ ) for ( const auto& newFormation : newFormations )
{ {
fileReadSuccess = true; fileReadSuccess = true;
RimWellPath* wellPath = tryFindMatchingWellPath( it->first ); RimWellPath* wellPath = tryFindMatchingWellPath( newFormation.first );
if ( !wellPath ) if ( !wellPath )
{ {
wellPath = new RimWellPath(); wellPath = new RimWellPath();
wellPath->setName( it->first ); wellPath->setName( newFormation.first );
addWellPath( wellPath, false ); addWellPath( wellPath );
RiaLogging::info( QString( "Created new well: %1" ).arg( wellPath->name() ) ); RiaLogging::info( QString( "Created new well: %1" ).arg( wellPath->name() ) );
} }
wellPath->setFormationsGeometry( it->second ); wellPath->setFormationsGeometry( newFormation.second );
QString wellFormationsCount = QString( "%1" ).arg( it->second->formationNamesCount() ); QString wellFormationsCount = QString( "%1" ).arg( newFormation.second->formationNamesCount() );
m_mostRecentlyUpdatedWellPath = wellPath; m_mostRecentlyUpdatedWellPath = wellPath;
outputMessage += it->first + "\t\t"; outputMessage += newFormation.first + "\t\t";
outputMessage += wellPath->name() + " \t\t\t"; outputMessage += wellPath->name() + " \t\t\t";
outputMessage += wellFormationsCount + "\n"; outputMessage += wellFormationsCount + "\n";
} }
@ -498,7 +495,7 @@ void RimWellPathCollection::scheduleRedrawAffectedViews()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RimWellPathCollection::anyWellsContainingPerforationIntervals() const bool RimWellPathCollection::anyWellsContainingPerforationIntervals() const
{ {
for ( auto wellPath : m_wellPaths ) for ( const auto& wellPath : m_wellPaths )
{ {
if ( !wellPath->perforationIntervalCollection()->perforations().empty() ) return true; if ( !wellPath->perforationIntervalCollection()->perforations().empty() ) return true;
} }
@ -511,7 +508,7 @@ bool RimWellPathCollection::anyWellsContainingPerforationIntervals() const
size_t RimWellPathCollection::modelledWellPathCount() const size_t RimWellPathCollection::modelledWellPathCount() const
{ {
size_t count = 0; size_t count = 0;
for ( auto wellPath : m_wellPaths ) for ( const auto& wellPath : m_wellPaths )
{ {
if ( dynamic_cast<const RimModeledWellPath*>( wellPath.p() ) ) if ( dynamic_cast<const RimModeledWellPath*>( wellPath.p() ) )
{ {
@ -526,7 +523,7 @@ size_t RimWellPathCollection::modelledWellPathCount() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPathCollection::wellPathByName( const QString& wellPathName ) const RimWellPath* RimWellPathCollection::wellPathByName( const QString& wellPathName ) const
{ {
for ( auto wellPath : m_wellPaths ) for ( const auto& wellPath : m_wellPaths )
{ {
if ( wellPath->name() == wellPathName ) if ( wellPath->name() == wellPathName )
{ {
@ -574,56 +571,77 @@ void RimWellPathCollection::deleteWell( RimWellPath* wellPath )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellPathCollection::groupWellPaths( const std::vector<RimWellPath*>& wellPaths ) void RimWellPathCollection::groupWellPaths( const std::vector<RimWellPath*>& wellPaths )
{ {
auto rootWells = wellPathsForWellNameStem( wellPaths ); const auto& rootWells = wellPathsForWellNameStem( wellPaths );
for ( auto [groupName, wellPathCommonName] : rootWells ) for ( const auto& [groupName, wellPathsInGroup] : rootWells )
{ {
if ( groupName == unGroupedText() ) continue; if ( groupName == unGroupedText() ) continue;
for ( auto wellPath : wellPathCommonName ) for ( const auto& wellPathToConnect : wellPathsInGroup )
{ {
// Assign the group names as well name for export // Assign the group names as well name for export
wellPath->completionSettings()->setWellNameForExport( groupName ); wellPathToConnect->completionSettings()->setWellNameForExport( groupName );
auto wellPathGeometry = wellPath->wellPathGeometry(); const auto wellPathGeometry = wellPathToConnect->wellPathGeometry();
if ( wellPathGeometry ) if ( wellPathGeometry )
{ {
const double eps = 1.0e-2; std::map<RimWellPath*, double> sharedWellPathLengths;
std::map<RimWellPath*, double> wellPathsWithCommonGeometry;
for ( auto existingWellPath : wellPathCommonName ) for ( const auto& otherWellPath : wellPathsInGroup )
{ {
if ( existingWellPath == wellPath ) continue; if ( otherWellPath == wellPathToConnect ) continue;
if ( wellPath->name() < existingWellPath->name() ) continue; if ( otherWellPath && otherWellPath->wellPathGeometry() )
double identicalTubeLength = existingWellPath->wellPathGeometry()->identicalTubeLength( *wellPathGeometry );
if ( identicalTubeLength > eps )
{ {
wellPathsWithCommonGeometry[existingWellPath] = identicalTubeLength; const double sharedWellPathLength = otherWellPath->wellPathGeometry()->identicalTubeLength( *wellPathGeometry );
const double eps = 1.0e-2;
if ( sharedWellPathLength > eps )
{
sharedWellPathLengths[otherWellPath] = sharedWellPathLength;
}
} }
} }
RimWellPath* mostSimilarWellPath = nullptr; RimWellPath* longestSharedWellPath = nullptr;
double longestIdenticalTubeLength = 0.0; double longestSharedWellPathLength = 0.0;
for ( auto [existingWellPath, identicalTubeLength] : wellPathsWithCommonGeometry ) for ( const auto& [wellPathCandidate, sharedWellPathLength] : sharedWellPathLengths )
{ {
if ( existingWellPath && ( existingWellPath != wellPath ) && identicalTubeLength > longestIdenticalTubeLength ) if ( wellPathCandidate )
{ {
mostSimilarWellPath = existingWellPath; const double distanceDifference = fabs( sharedWellPathLength - longestSharedWellPathLength );
longestIdenticalTubeLength = identicalTubeLength;
const double differenceThreshold = 1.0;
if ( longestSharedWellPath && ( distanceDifference < differenceThreshold ) )
{
// If the main well is named WELL_A, each side steps of a MSW can be given the following names
// WELL_A_Y1
// WELL_A_Y2
// WELL_A_Y3
//
// If Y3 has equal shared geometry with both Y2 and Y1, make sure that Y3 is connected to Y1.
if ( wellPathCandidate->name() < longestSharedWellPath->name() )
{
longestSharedWellPath = wellPathCandidate;
longestSharedWellPathLength = sharedWellPathLength;
}
}
else if ( sharedWellPathLength > longestSharedWellPathLength )
{
longestSharedWellPath = wellPathCandidate;
longestSharedWellPathLength = sharedWellPathLength;
}
} }
} }
if ( mostSimilarWellPath ) if ( longestSharedWellPath )
{ {
if ( wellPath->name() > mostSimilarWellPath->name() ) if ( wellPathToConnect->name() > longestSharedWellPath->name() )
{ {
wellPath->connectWellPaths( mostSimilarWellPath, longestIdenticalTubeLength ); wellPathToConnect->connectWellPaths( longestSharedWellPath, longestSharedWellPathLength );
} }
else else
{ {
mostSimilarWellPath->connectWellPaths( wellPath, longestIdenticalTubeLength ); longestSharedWellPath->connectWellPaths( wellPathToConnect, longestSharedWellPathLength );
} }
} }
} }
@ -666,7 +684,7 @@ void RimWellPathCollection::reloadAllWellPathFormations()
{ {
caf::ProgressInfo progress( m_wellPaths.size(), "Reloading well picks from file" ); caf::ProgressInfo progress( m_wellPaths.size(), "Reloading well picks from file" );
for ( auto wellPath : m_wellPaths ) for ( const auto& wellPath : m_wellPaths )
{ {
QString errorMessage; QString errorMessage;
if ( !wellPath->reloadWellPathFormationsFile( &errorMessage, m_wellPathFormationsImporter.get() ) ) if ( !wellPath->reloadWellPathFormationsFile( &errorMessage, m_wellPathFormationsImporter.get() ) )
@ -723,10 +741,10 @@ bool lessWellPath( const caf::PdmPointer<RimWellPath>& w1, const caf::PdmPointer
collator.setNumericMode( true ); collator.setNumericMode( true );
return collator.compare( w1->name(), w2->name() ) < 0; return collator.compare( w1->name(), w2->name() ) < 0;
} }
else if ( w1.notNull() )
return true; if ( w1.notNull() ) return true;
else
return false; return false;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -93,7 +93,7 @@ public:
caf::PdmField<int> wellPathClipZDistance; caf::PdmField<int> wellPathClipZDistance;
void loadDataAndUpdate(); void loadDataAndUpdate();
std::vector<RimWellPath*> addWellPaths( QStringList filePaths, bool importGrouped, QStringList* errorMessages ); std::vector<RimWellPath*> addWellPaths( QStringList filePaths, QStringList* errorMessages );
std::vector<RimWellPath*> allWellPaths() const; std::vector<RimWellPath*> allWellPaths() const;
void removeWellPath( gsl::not_null<RimWellPath*> wellPath ); void removeWellPath( gsl::not_null<RimWellPath*> wellPath );
@ -107,13 +107,12 @@ public:
RimWellPath* mostRecentlyUpdatedWellPath(); RimWellPath* mostRecentlyUpdatedWellPath();
void readWellPathFormationFiles(); void readWellPathFormationFiles();
void reloadAllWellPathFormations(); void reloadAllWellPathFormations();
RimWellPath* wellPathByName( const QString& wellPathName ) const; RimWellPath* wellPathByName( const QString& wellPathName ) const;
RimWellPath* tryFindMatchingWellPath( const QString& wellName ) const; RimWellPath* tryFindMatchingWellPath( const QString& wellName ) const;
void addWellPaths( const std::vector<RimWellPath*> incomingWellPaths, bool importGrouped ); void addWellPaths( const std::vector<RimWellPath*> incomingWellPaths );
void addWellPath( gsl::not_null<RimWellPath*> wellPath, bool importGrouped ); void addWellPath( gsl::not_null<RimWellPath*> wellPath );
std::vector<RimWellLogFile*> addWellLogs( const QStringList& filePaths, QStringList* errorMessages ); std::vector<RimWellLogFile*> addWellLogs( const QStringList& filePaths, QStringList* errorMessages );
void addWellPathFormations( const QStringList& filePaths ); void addWellPathFormations( const QStringList& filePaths );
@ -139,7 +138,7 @@ private:
caf::PdmFieldHandle* objectToggleField() override; caf::PdmFieldHandle* objectToggleField() override;
void readAndAddWellPaths( std::vector<RimFileWellPath*>& wellPathArray, bool importGrouped ); void readAndAddWellPaths( std::vector<RimFileWellPath*>& wellPathArray );
void sortWellsByName(); void sortWellsByName();
caf::AppEnum<RiaDefines::EclipseUnitSystem> findUnitSystemForWellPath( const RimWellPath* wellPath ); caf::AppEnum<RiaDefines::EclipseUnitSystem> findUnitSystemForWellPath( const RimWellPath* wellPath );