mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 15:10:22 -05:00
#14667 Completions: Move MSW settings to segments
This commit is contained in:
1 parent
cfb9e5765e
commit
63bcc22485
46 files changed
+1635
-1008
No files matched your search
@@ -14,10 +14,8 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanModelPlotFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFractureStatisticsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportValveTemplatesFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewDiameterRoughnessIntervalFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteDiameterRoughnessIntervalFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewCustomSegmentIntervalFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteCustomSegmentIntervalFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewSegmentIntervalFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteSegmentIntervalFeature.cpp
|
||||
)
|
||||
|
||||
list(APPEND COMMAND_CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicDeleteCustomSegmentIntervalFeature.h"
|
||||
|
||||
#include "RimCustomSegmentInterval.h"
|
||||
#include "RimCustomSegmentIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicDeleteCustomSegmentIntervalFeature, "RicDeleteCustomSegmentIntervalFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicDeleteCustomSegmentIntervalFeature::isCommandEnabled() const
|
||||
{
|
||||
if ( caf::SelectionManager::instance()->selectedItemOfType<RimCustomSegmentInterval>( caf::SelectionManager::FIRST_LEVEL ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( auto collection = caf::SelectionManager::instance()->selectedItemOfType<RimCustomSegmentIntervalCollection>() )
|
||||
{
|
||||
return collection && !collection->intervals().empty();
|
||||
}
|
||||
|
||||
if ( auto mswParams = caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() )
|
||||
{
|
||||
if ( mswParams->customSegmentIntervals() )
|
||||
{
|
||||
return !mswParams->customSegmentIntervals()->intervals().empty();
|
||||
}
|
||||
}
|
||||
|
||||
if ( auto completionSettings = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
if ( auto wellPath = completionSettings->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
auto mswParams = wellPath->mswCompletionParameters();
|
||||
if ( mswParams && mswParams->customSegmentIntervals() )
|
||||
{
|
||||
return !mswParams->customSegmentIntervals()->intervals().empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicDeleteCustomSegmentIntervalFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
const auto intervals = caf::SelectionManager::instance()->objectsByType<RimCustomSegmentInterval>( caf::SelectionManager::FIRST_LEVEL );
|
||||
RimCustomSegmentIntervalCollection* intervalCollection = nullptr;
|
||||
|
||||
if ( !intervals.empty() )
|
||||
{
|
||||
// Delete selected intervals
|
||||
intervalCollection = intervals[0]->firstAncestorOrThisOfTypeAsserted<RimCustomSegmentIntervalCollection>();
|
||||
for ( RimCustomSegmentInterval* intervalToDelete : intervals )
|
||||
{
|
||||
intervalCollection->removeInterval( intervalToDelete );
|
||||
}
|
||||
intervalCollection->updateConnectedEditors();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete all intervals in collection
|
||||
intervalCollection = caf::SelectionManager::instance()->selectedItemOfType<RimCustomSegmentIntervalCollection>();
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
// Handle selection of MSW completion parameters
|
||||
auto mswParams = caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>();
|
||||
if ( mswParams && mswParams->customSegmentIntervals() )
|
||||
{
|
||||
intervalCollection = mswParams->customSegmentIntervals();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle selection of well path completion settings
|
||||
if ( auto completionSettings = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
if ( auto wellPath = completionSettings->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
auto mswParams = wellPath->mswCompletionParameters();
|
||||
if ( mswParams && mswParams->customSegmentIntervals() )
|
||||
{
|
||||
intervalCollection = mswParams->customSegmentIntervals();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( intervalCollection )
|
||||
{
|
||||
intervalCollection->removeAllIntervals();
|
||||
intervalCollection->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
if ( intervalCollection )
|
||||
{
|
||||
if ( intervalCollection->intervals().empty() )
|
||||
{
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( intervalCollection );
|
||||
}
|
||||
|
||||
if ( RimProject* proj = RimProject::current() )
|
||||
{
|
||||
proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicDeleteCustomSegmentIntervalFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
const auto intervals = caf::SelectionManager::instance()->objectsByType<RimCustomSegmentInterval>( caf::SelectionManager::FIRST_LEVEL );
|
||||
if ( !intervals.empty() )
|
||||
{
|
||||
if ( intervals.size() == 1 )
|
||||
{
|
||||
actionToSetup->setText( "Delete Segment Interval" );
|
||||
}
|
||||
else
|
||||
{
|
||||
actionToSetup->setText( QString( "Delete %1 Segment Intervals" ).arg( intervals.size() ) );
|
||||
}
|
||||
actionToSetup->setIcon( QIcon( ":/Erase.svg" ) );
|
||||
applyShortcutWithHintToAction( actionToSetup, QKeySequence::Delete );
|
||||
}
|
||||
else if ( caf::SelectionManager::instance()->selectedItemOfType<RimCustomSegmentIntervalCollection>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
actionToSetup->setText( "Delete All Segment Intervals" );
|
||||
actionToSetup->setIcon( QIcon( ":/Erase.svg" ) );
|
||||
applyShortcutWithHintToAction( actionToSetup, QKeySequence::Delete );
|
||||
}
|
||||
}
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicDeleteDiameterRoughnessIntervalFeature.h"
|
||||
|
||||
#include "RimDiameterRoughnessInterval.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicDeleteDiameterRoughnessIntervalFeature, "RicDeleteDiameterRoughnessIntervalFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicDeleteDiameterRoughnessIntervalFeature::isCommandEnabled() const
|
||||
{
|
||||
if ( caf::SelectionManager::instance()->selectedItemOfType<RimDiameterRoughnessInterval>( caf::SelectionManager::FIRST_LEVEL ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( auto collection = caf::SelectionManager::instance()->selectedItemOfType<RimDiameterRoughnessIntervalCollection>() )
|
||||
{
|
||||
return collection && !collection->intervals().empty();
|
||||
}
|
||||
|
||||
if ( auto mswParams = caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() )
|
||||
{
|
||||
if ( mswParams->diameterRoughnessIntervals() )
|
||||
{
|
||||
return !mswParams->diameterRoughnessIntervals()->intervals().empty();
|
||||
}
|
||||
}
|
||||
|
||||
if ( auto completionSettings = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
if ( auto wellPath = completionSettings->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
auto mswParams = wellPath->mswCompletionParameters();
|
||||
if ( mswParams && mswParams->diameterRoughnessIntervals() )
|
||||
{
|
||||
return !mswParams->diameterRoughnessIntervals()->intervals().empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicDeleteDiameterRoughnessIntervalFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
const auto intervals = caf::SelectionManager::instance()->objectsByType<RimDiameterRoughnessInterval>( caf::SelectionManager::FIRST_LEVEL );
|
||||
RimDiameterRoughnessIntervalCollection* intervalCollection = nullptr;
|
||||
|
||||
if ( !intervals.empty() )
|
||||
{
|
||||
// Delete selected intervals
|
||||
intervalCollection = intervals[0]->firstAncestorOrThisOfTypeAsserted<RimDiameterRoughnessIntervalCollection>();
|
||||
for ( RimDiameterRoughnessInterval* intervalToDelete : intervals )
|
||||
{
|
||||
intervalCollection->removeInterval( intervalToDelete );
|
||||
}
|
||||
intervalCollection->updateConnectedEditors();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete all intervals in collection
|
||||
intervalCollection = caf::SelectionManager::instance()->selectedItemOfType<RimDiameterRoughnessIntervalCollection>();
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
// Handle selection of MSW completion parameters
|
||||
auto mswParams = caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>();
|
||||
if ( mswParams && mswParams->diameterRoughnessIntervals() )
|
||||
{
|
||||
intervalCollection = mswParams->diameterRoughnessIntervals();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle selection of well path completion settings
|
||||
if ( auto completionSettings = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
if ( auto wellPath = completionSettings->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
auto mswParams = wellPath->mswCompletionParameters();
|
||||
if ( mswParams && mswParams->diameterRoughnessIntervals() )
|
||||
{
|
||||
intervalCollection = mswParams->diameterRoughnessIntervals();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( intervalCollection )
|
||||
{
|
||||
intervalCollection->removeAllIntervals();
|
||||
intervalCollection->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
if ( intervalCollection )
|
||||
{
|
||||
if ( intervalCollection->intervals().empty() )
|
||||
{
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( intervalCollection );
|
||||
}
|
||||
|
||||
if ( RimProject* proj = RimProject::current() )
|
||||
{
|
||||
proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicDeleteDiameterRoughnessIntervalFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
const auto intervals = caf::SelectionManager::instance()->objectsByType<RimDiameterRoughnessInterval>( caf::SelectionManager::FIRST_LEVEL );
|
||||
if ( !intervals.empty() )
|
||||
{
|
||||
if ( intervals.size() == 1 )
|
||||
{
|
||||
actionToSetup->setText( "Delete Interval" );
|
||||
}
|
||||
else
|
||||
{
|
||||
actionToSetup->setText( QString( "Delete %1 Intervals" ).arg( intervals.size() ) );
|
||||
}
|
||||
actionToSetup->setIcon( QIcon( ":/Erase.svg" ) );
|
||||
applyShortcutWithHintToAction( actionToSetup, QKeySequence::Delete );
|
||||
}
|
||||
else if ( caf::SelectionManager::instance()->selectedItemOfType<RimDiameterRoughnessIntervalCollection>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
actionToSetup->setText( "Delete All Intervals" );
|
||||
actionToSetup->setIcon( QIcon( ":/Erase.svg" ) );
|
||||
applyShortcutWithHintToAction( actionToSetup, QKeySequence::Delete );
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicDeleteDiameterRoughnessIntervalFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() const override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicDeleteSegmentIntervalFeature.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicDeleteSegmentIntervalFeature, "RicDeleteSegmentIntervalFeature" );
|
||||
|
||||
bool RicDeleteSegmentIntervalFeature::isCommandEnabled() const
|
||||
{
|
||||
if ( caf::SelectionManager::instance()->selectedItemOfType<RimSegmentInterval>( caf::SelectionManager::FIRST_LEVEL ) ) return true;
|
||||
auto* collection = caf::SelectionManager::instance()->selectedItemOfType<RimSegmentCollection>();
|
||||
return collection && collection->hasIntervals();
|
||||
}
|
||||
|
||||
void RicDeleteSegmentIntervalFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
auto selectedIntervals = caf::SelectionManager::instance()->objectsByType<RimSegmentInterval>( caf::SelectionManager::FIRST_LEVEL );
|
||||
RimSegmentCollection* collection = nullptr;
|
||||
|
||||
for ( auto* interval : selectedIntervals )
|
||||
{
|
||||
collection = interval->firstAncestorOrThisOfTypeAsserted<RimSegmentCollection>();
|
||||
collection->removeInterval( interval );
|
||||
}
|
||||
|
||||
if ( selectedIntervals.empty() )
|
||||
{
|
||||
collection = caf::SelectionManager::instance()->selectedItemOfType<RimSegmentCollection>();
|
||||
if ( collection ) collection->removeAllIntervals();
|
||||
}
|
||||
|
||||
if ( !collection ) return;
|
||||
collection->updateConnectedEditors();
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( collection );
|
||||
if ( auto* project = RimProject::current() ) project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
|
||||
void RicDeleteSegmentIntervalFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
auto intervals = caf::SelectionManager::instance()->objectsByType<RimSegmentInterval>( caf::SelectionManager::FIRST_LEVEL );
|
||||
actionToSetup->setText( intervals.empty() ? "Delete All Segment Intervals" : "Delete Segment Interval" );
|
||||
actionToSetup->setIcon( QIcon( ":/Erase.svg" ) );
|
||||
applyShortcutWithHintToAction( actionToSetup, QKeySequence::Delete );
|
||||
}
|
||||
+2
-2
@@ -23,7 +23,7 @@
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicNewCustomSegmentIntervalFeature : public caf::CmdFeature
|
||||
class RicDeleteSegmentIntervalFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
@@ -31,4 +31,4 @@ protected:
|
||||
bool isCommandEnabled() const override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
||||
};
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicNewCustomSegmentIntervalFeature.h"
|
||||
|
||||
#include "RimCustomSegmentInterval.h"
|
||||
#include "RimCustomSegmentIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewCustomSegmentIntervalFeature, "RicNewCustomSegmentIntervalFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicNewCustomSegmentIntervalFeature::isCommandEnabled() const
|
||||
{
|
||||
return ( caf::SelectionManager::instance()->selectedItemOfType<RimCustomSegmentIntervalCollection>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewCustomSegmentIntervalFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
// Try to get collection directly
|
||||
RimCustomSegmentIntervalCollection* intervalCollection =
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimCustomSegmentIntervalCollection>();
|
||||
|
||||
// If not found, try to get it from MSW completion parameters
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
if ( auto mswParams = caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() )
|
||||
{
|
||||
intervalCollection = mswParams->customSegmentIntervals();
|
||||
}
|
||||
}
|
||||
|
||||
// If still not found, try to get it from well path completion settings
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
if ( auto completionSettings = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
if ( auto wellPath = completionSettings->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
if ( auto mswParams = wellPath->mswCompletionParameters() )
|
||||
{
|
||||
intervalCollection = mswParams->customSegmentIntervals();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( intervalCollection )
|
||||
{
|
||||
RimCustomSegmentInterval* newInterval = new RimCustomSegmentInterval;
|
||||
|
||||
// Set default MD values
|
||||
newInterval->setStartMD( 0 );
|
||||
newInterval->setEndMD( 100 );
|
||||
|
||||
intervalCollection->addInterval( newInterval );
|
||||
intervalCollection->updateConnectedEditors();
|
||||
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( newInterval );
|
||||
|
||||
if ( RimProject* project = RimProject::current() )
|
||||
{
|
||||
project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewCustomSegmentIntervalFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "New Segment Interval" );
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicNewDiameterRoughnessIntervalFeature.h"
|
||||
|
||||
#include "RimDiameterRoughnessInterval.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewDiameterRoughnessIntervalFeature, "RicNewDiameterRoughnessIntervalFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicNewDiameterRoughnessIntervalFeature::isCommandEnabled() const
|
||||
{
|
||||
return ( caf::SelectionManager::instance()->selectedItemOfType<RimDiameterRoughnessIntervalCollection>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() ||
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewDiameterRoughnessIntervalFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
// Try to get collection directly
|
||||
RimDiameterRoughnessIntervalCollection* intervalCollection =
|
||||
caf::SelectionManager::instance()->selectedItemOfType<RimDiameterRoughnessIntervalCollection>();
|
||||
|
||||
// If not found, try to get it from MSW completion parameters
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
if ( auto mswParams = caf::SelectionManager::instance()->selectedItemOfType<RimMswCompletionParameters>() )
|
||||
{
|
||||
intervalCollection = mswParams->diameterRoughnessIntervals();
|
||||
}
|
||||
}
|
||||
|
||||
// If still not found, try to get it from well path completion settings
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
if ( auto completionSettings = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCompletionSettings>() )
|
||||
{
|
||||
if ( auto wellPath = completionSettings->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
if ( auto mswParams = wellPath->mswCompletionParameters() )
|
||||
{
|
||||
intervalCollection = mswParams->diameterRoughnessIntervals();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( intervalCollection )
|
||||
{
|
||||
RimDiameterRoughnessInterval* newInterval = new RimDiameterRoughnessInterval;
|
||||
|
||||
// Set default values
|
||||
if ( auto wellPath = intervalCollection->firstAncestorOrThisOfType<RimWellPath>() )
|
||||
{
|
||||
if ( auto mswParams = wellPath->mswCompletionParameters() )
|
||||
{
|
||||
newInterval->setStartMD( 0 );
|
||||
newInterval->setEndMD( 2000 );
|
||||
newInterval->setDiameter( mswParams->linerDiameter() );
|
||||
newInterval->setRoughnessFactor( mswParams->roughnessFactor() );
|
||||
}
|
||||
}
|
||||
|
||||
intervalCollection->addInterval( newInterval );
|
||||
intervalCollection->updateConnectedEditors();
|
||||
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( newInterval );
|
||||
|
||||
if ( RimProject* project = RimProject::current() )
|
||||
{
|
||||
project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewDiameterRoughnessIntervalFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "New Interval" );
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicNewDiameterRoughnessIntervalFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
bool isCommandEnabled() const override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicNewSegmentIntervalFeature.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewSegmentIntervalFeature, "RicNewSegmentIntervalFeature" );
|
||||
|
||||
bool RicNewSegmentIntervalFeature::isCommandEnabled() const
|
||||
{
|
||||
return caf::SelectionManager::instance()->selectedItemOfType<RimSegmentCollection>() != nullptr;
|
||||
}
|
||||
|
||||
void RicNewSegmentIntervalFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
auto* collection = caf::SelectionManager::instance()->selectedItemOfType<RimSegmentCollection>();
|
||||
if ( !collection ) return;
|
||||
|
||||
collection->setDiameterRoughnessMode( RimSegmentCollection::DiameterRoughnessMode::INTERVALS );
|
||||
auto* interval = collection->createInterval( 0.0, 2000.0, collection->linerDiameter(), collection->roughnessFactor() );
|
||||
collection->updateConnectedEditors();
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( interval );
|
||||
|
||||
if ( auto* project = RimProject::current() ) project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
|
||||
void RicNewSegmentIntervalFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "New Segment Interval" );
|
||||
}
|
||||
+2
-2
@@ -23,7 +23,7 @@
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicDeleteCustomSegmentIntervalFeature : public caf::CmdFeature
|
||||
class RicNewSegmentIntervalFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
@@ -31,4 +31,4 @@ protected:
|
||||
bool isCommandEnabled() const override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
||||
};
|
||||
+7
-7
@@ -34,9 +34,9 @@
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
#include "RimWellPathFracture.h"
|
||||
@@ -413,13 +413,13 @@ RigMswBranch buildMainBoreBranch( const RimWellPath*
|
||||
double roughness = 0.0;
|
||||
if ( exportDate.has_value() )
|
||||
{
|
||||
diameter = wellPath->mswCompletionParameters()->getDiameterAtMD( midPointMD, unitSystem, *exportDate );
|
||||
roughness = wellPath->mswCompletionParameters()->getRoughnessAtMD( midPointMD, unitSystem, *exportDate );
|
||||
diameter = wellPath->segmentCollection()->getDiameterAtMD( midPointMD, unitSystem, *exportDate );
|
||||
roughness = wellPath->segmentCollection()->getRoughnessAtMD( midPointMD, unitSystem, *exportDate );
|
||||
}
|
||||
else
|
||||
{
|
||||
diameter = wellPath->mswCompletionParameters()->getDiameterAtMD( midPointMD, unitSystem );
|
||||
roughness = wellPath->mswCompletionParameters()->getRoughnessAtMD( midPointMD, unitSystem );
|
||||
diameter = wellPath->segmentCollection()->getDiameterAtMD( midPointMD, unitSystem );
|
||||
roughness = wellPath->segmentCollection()->getRoughnessAtMD( midPointMD, unitSystem );
|
||||
}
|
||||
|
||||
RigMswSegment seg;
|
||||
@@ -483,8 +483,8 @@ std::vector<RigMswBranch> buildValveBranches( const RimWellPath*
|
||||
{
|
||||
std::vector<RigMswBranch> result;
|
||||
|
||||
const auto linerDiameter = wellPath->mswCompletionParameters()->linerDiameter( unitSystem );
|
||||
const auto roughnessFactor = wellPath->mswCompletionParameters()->roughnessFactor( unitSystem );
|
||||
const auto linerDiameter = wellPath->segmentCollection()->linerDiameter( unitSystem );
|
||||
const auto roughnessFactor = wellPath->segmentCollection()->roughnessFactor( unitSystem );
|
||||
|
||||
for ( const auto* perf : perforationIntervals )
|
||||
{
|
||||
|
||||
+3
-3
@@ -29,9 +29,9 @@
|
||||
#include "Well/RigWellPath.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimValveCollection.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
@@ -80,7 +80,7 @@ std::vector<RigMswBranch> buildLateralBranches( RimEclipseCase*
|
||||
RicMswBranchBuilder::FishbonesExportContext& fishbonesContext )
|
||||
{
|
||||
std::vector<RigMswBranch> result;
|
||||
auto mswParameters = wellPath->mswCompletionParameters();
|
||||
auto mswParameters = wellPath->segmentCollection();
|
||||
if ( !mswParameters ) return result;
|
||||
|
||||
const std::string infoType = mswParameters->lengthAndDepth().text().toStdString();
|
||||
@@ -306,7 +306,7 @@ RigMswWellExportData buildMswWellExportData( RimEclipseCase*
|
||||
CompletionType completionType,
|
||||
const std::optional<QDateTime>& exportDate )
|
||||
{
|
||||
auto mswParameters = wellPath->mswCompletionParameters();
|
||||
auto mswParameters = wellPath->segmentCollection();
|
||||
CAF_ASSERT( mswParameters );
|
||||
|
||||
const RiaDefines::EclipseUnitSystem unitSystem = eclipseCase->eclipseCaseData()->unitsType();
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "RimFishbones.h"
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
|
||||
|
||||
@@ -522,8 +522,8 @@ void RicScheduleDataGenerator::generateMswForWell( RimEclipseCase&
|
||||
return;
|
||||
}
|
||||
|
||||
auto* mswParams = wellPath.mswCompletionParameters();
|
||||
if ( !mswParams )
|
||||
auto* segmentCollection = wellPath.segmentCollection();
|
||||
if ( !segmentCollection )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
+8
-8
@@ -33,8 +33,8 @@
|
||||
#include "Well/RigWellPathIntersectionTools.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
#include "RimWellPathTieIn.h"
|
||||
@@ -72,13 +72,13 @@ std::expected<RigMswTableData, std::string> RicWellPathExportMswTableData::extra
|
||||
if ( !eclipseCase || !wellPath || eclipseCase->eclipseCaseData() == nullptr )
|
||||
return std::unexpected( "Invalid eclipse case or well path provided" );
|
||||
|
||||
auto mswParameters = wellPath->mswCompletionParameters();
|
||||
if ( !mswParameters ) return std::unexpected( "Missing MSW completion parameters" );
|
||||
auto segmentCollection = wellPath->segmentCollection();
|
||||
if ( !segmentCollection ) return std::unexpected( "Missing MSW completion parameters" );
|
||||
|
||||
const std::vector<std::pair<double, double>> customSegmentIntervals = mswParameters->getSegmentIntervals();
|
||||
const std::vector<std::pair<double, double>> customSegmentIntervals = segmentCollection->getSegmentIntervals();
|
||||
auto wellExportData = RicWellPathExportMswGeometryPath::buildMswWellExportData( eclipseCase,
|
||||
wellPath,
|
||||
mswParameters->maxSegmentLength(),
|
||||
segmentCollection->maxSegmentLength(),
|
||||
customSegmentIntervals,
|
||||
completionType,
|
||||
exportDate );
|
||||
@@ -143,7 +143,7 @@ std::vector<WellPathCellIntersectionInfo> RicWellPathExportMswTableData::generat
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RicWellPathExportMswTableData::computeIntitialMeasuredDepth( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
const RimMswCompletionParameters* mswParameters,
|
||||
const RimSegmentCollection* segmentCollection,
|
||||
const std::vector<WellPathCellIntersectionInfo>& allIntersections )
|
||||
{
|
||||
if ( allIntersections.empty() ) return 0.0;
|
||||
@@ -151,9 +151,9 @@ double RicWellPathExportMswTableData::computeIntitialMeasuredDepth( const RimEcl
|
||||
const RigActiveCellInfo* activeCellInfo = eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
|
||||
double candidateMeasuredDepth = 0.0;
|
||||
if ( mswParameters->referenceMDType() == RimMswCompletionParameters::ReferenceMDType::MANUAL_REFERENCE_MD )
|
||||
if ( segmentCollection->referenceMDType() == RimSegmentCollection::ReferenceMDType::MANUAL_REFERENCE_MD )
|
||||
{
|
||||
candidateMeasuredDepth = mswParameters->manualReferenceMD();
|
||||
candidateMeasuredDepth = segmentCollection->manualReferenceMD();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ class RigActiveCellInfo;
|
||||
class RimEclipseCase;
|
||||
class RimWellPath;
|
||||
class RigMswTableData;
|
||||
class RimMswCompletionParameters;
|
||||
class RimSegmentCollection;
|
||||
class RigWellPath;
|
||||
|
||||
struct WellPathCellIntersectionInfo;
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
|
||||
static double computeIntitialMeasuredDepth( const RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
const RimMswCompletionParameters* mswParameters,
|
||||
const RimSegmentCollection* segmentCollection,
|
||||
const std::vector<WellPathCellIntersectionInfo>& allIntersections );
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDiameterRoughnessIntervalCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomSegmentInterval.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomSegmentIntervalCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSegmentCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSegmentInterval.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleFractureStatistics.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleFractureStatisticsCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimMswSegment.cpp
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "RimCustomSegmentIntervalCollection.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
@@ -175,7 +176,10 @@ double RimMswCompletionParameters::linerDiameter( RiaDefines::EclipseUnitSystem
|
||||
double diameter = m_linerDiameter();
|
||||
if ( !wellPath->isTopLevelWellPath() && !m_customValuesForLateral )
|
||||
{
|
||||
diameter = wellPath->topLevelWellPath()->mswCompletionParameters()->m_linerDiameter();
|
||||
if ( const auto* topLevelWell = wellPath->topLevelWellPath() )
|
||||
{
|
||||
diameter = topLevelWell->segmentCollection()->linerDiameter();
|
||||
}
|
||||
}
|
||||
|
||||
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD && unitSystem == RiaDefines::EclipseUnitSystem::UNITS_METRIC )
|
||||
@@ -220,7 +224,10 @@ double RimMswCompletionParameters::roughnessFactor( RiaDefines::EclipseUnitSyste
|
||||
double rFactor = m_roughnessFactor();
|
||||
if ( !wellPath->isTopLevelWellPath() && !m_customValuesForLateral )
|
||||
{
|
||||
rFactor = wellPath->topLevelWellPath()->mswCompletionParameters()->m_roughnessFactor();
|
||||
if ( const auto* topLevelWell = wellPath->topLevelWellPath() )
|
||||
{
|
||||
rFactor = topLevelWell->segmentCollection()->roughnessFactor();
|
||||
}
|
||||
}
|
||||
|
||||
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD && unitSystem == RiaDefines::EclipseUnitSystem::UNITS_METRIC )
|
||||
|
||||
@@ -0,0 +1,623 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimSegmentCollection.h"
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RimCustomSegmentInterval.h"
|
||||
#include "RimCustomSegmentIntervalCollection.h"
|
||||
#include "RimDiameterRoughnessInterval.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafPdmUiObjectEditorHandle.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <>
|
||||
void RimSegmentCollection::ReferenceMDEnum::setUp()
|
||||
{
|
||||
addItem( RimSegmentCollection::ReferenceMDType::AUTO_REFERENCE_MD, "GridEntryPoint", "Grid Entry Point", { "GridIntersectionRefMD" } );
|
||||
addItem( RimSegmentCollection::ReferenceMDType::MANUAL_REFERENCE_MD, "UserDefined", "User Defined", { "ManualRefMD" } );
|
||||
setDefault( RimSegmentCollection::ReferenceMDType::AUTO_REFERENCE_MD );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <>
|
||||
void RimSegmentCollection::PressureDropEnum::setUp()
|
||||
{
|
||||
addItem( RimSegmentCollection::PressureDropType::HYDROSTATIC, "H--", "Hydrostatic" );
|
||||
addItem( RimSegmentCollection::PressureDropType::HYDROSTATIC_FRICTION, "HF-", "Hydrostatic + Friction" );
|
||||
addItem( RimSegmentCollection::PressureDropType::HYDROSTATIC_FRICTION_ACCELERATION, "HFA", "Hydrostatic + Friction + Acceleration" );
|
||||
setDefault( RimSegmentCollection::PressureDropType::HYDROSTATIC_FRICTION );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <>
|
||||
void RimSegmentCollection::LengthAndDepthEnum::setUp()
|
||||
{
|
||||
addItem( RimSegmentCollection::LengthAndDepthType::INC, "INC", "Incremental" );
|
||||
addItem( RimSegmentCollection::LengthAndDepthType::ABS, "ABS", "Absolute" );
|
||||
setDefault( RimSegmentCollection::LengthAndDepthType::ABS );
|
||||
}
|
||||
|
||||
template <>
|
||||
void RimSegmentCollection::DiameterRoughnessModeEnum::setUp()
|
||||
{
|
||||
addItem( RimSegmentCollection::DiameterRoughnessMode::UNIFORM, "Uniform", "Uniform" );
|
||||
addItem( RimSegmentCollection::DiameterRoughnessMode::INTERVALS, "Intervals", "Intervals" );
|
||||
setDefault( RimSegmentCollection::DiameterRoughnessMode::UNIFORM );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimSegmentCollection, "SegmentCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentCollection::RimSegmentCollection()
|
||||
{
|
||||
CAF_PDM_InitScriptableObject( "Segments", ":/CompletionsSymbol16x16.png", "", "SegmentCollection" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &m_refMDType, "RefMDType", "ReferenceMdType", "Reference MD Type" );
|
||||
CAF_PDM_InitScriptableFieldWithScriptKeyword( &m_refMD, "RefMD", "UserDefinedReferenceMd", 0.0, "User Defined Reference MD" );
|
||||
CAF_PDM_InitScriptableField( &m_customValuesForLateral, "CustomValuesForLateral", false, "Custom Values for Lateral" );
|
||||
|
||||
const auto unitSystem = RiaDefines::EclipseUnitSystem::UNITS_METRIC;
|
||||
CAF_PDM_InitScriptableField( &m_linerDiameter, "LinerDiameter", defaultLinerDiameter( unitSystem ), "Liner Inner Diameter" );
|
||||
CAF_PDM_InitScriptableField( &m_roughnessFactor, "RoughnessFactor", defaultRoughnessFactor( unitSystem ), "Roughness Factor" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_diameterRoughnessMode, "DiameterRoughnessMode", "Diameter Roughness Mode" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_segmentIntervals, "Intervals", "Segment Intervals" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_pressureDrop, "PressureDrop", "Pressure Drop" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_lengthAndDepth, "LengthAndDepth", "Length and Depth" );
|
||||
CAF_PDM_InitScriptableField( &m_enforceMaxSegmentLength, "EnforceMaxSegmentLength", false, "Enforce Max Segment Length" );
|
||||
CAF_PDM_InitScriptableField( &m_maxSegmentLength, "MaxSegmentLength", 200.0, "Max Segment Length" );
|
||||
m_maxSegmentLength.uiCapability()->setUiHidden( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentCollection::ReferenceMDType RimSegmentCollection::referenceMDType() const
|
||||
{
|
||||
return m_refMDType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::manualReferenceMD() const
|
||||
{
|
||||
if ( m_refMDType == ReferenceMDType::AUTO_REFERENCE_MD ) return std::numeric_limits<double>::infinity();
|
||||
return m_refMD();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::linerDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
auto* wellPath = firstAncestorOrThisOfTypeAsserted<RimWellPath>();
|
||||
double diameter = m_linerDiameter();
|
||||
if ( !wellPath->isTopLevelWellPath() && !m_customValuesForLateral() )
|
||||
{
|
||||
if ( const auto* topLevelWell = wellPath->topLevelWellPath() )
|
||||
{
|
||||
diameter = topLevelWell->segmentCollection()->linerDiameter();
|
||||
}
|
||||
}
|
||||
|
||||
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD && unitSystem == RiaDefines::EclipseUnitSystem::UNITS_METRIC )
|
||||
return RiaEclipseUnitTools::feetToMeter( diameter );
|
||||
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_METRIC && unitSystem == RiaDefines::EclipseUnitSystem::UNITS_FIELD )
|
||||
return RiaEclipseUnitTools::meterToFeet( diameter );
|
||||
return diameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::linerDiameter() const
|
||||
{
|
||||
return m_linerDiameter();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::roughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
auto* wellPath = firstAncestorOrThisOfTypeAsserted<RimWellPath>();
|
||||
double roughness = m_roughnessFactor();
|
||||
if ( !wellPath->isTopLevelWellPath() && !m_customValuesForLateral() )
|
||||
{
|
||||
if ( const auto* topLevelWell = wellPath->topLevelWellPath() )
|
||||
{
|
||||
roughness = topLevelWell->segmentCollection()->roughnessFactor();
|
||||
}
|
||||
}
|
||||
|
||||
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD && unitSystem == RiaDefines::EclipseUnitSystem::UNITS_METRIC )
|
||||
return RiaEclipseUnitTools::feetToMeter( roughness );
|
||||
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_METRIC && unitSystem == RiaDefines::EclipseUnitSystem::UNITS_FIELD )
|
||||
return RiaEclipseUnitTools::meterToFeet( roughness );
|
||||
return roughness;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::roughnessFactor() const
|
||||
{
|
||||
return m_roughnessFactor();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentCollection::PressureDropEnum RimSegmentCollection::pressureDrop() const
|
||||
{
|
||||
return m_pressureDrop();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentCollection::LengthAndDepthEnum RimSegmentCollection::lengthAndDepth() const
|
||||
{
|
||||
return m_lengthAndDepth();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::maxSegmentLength() const
|
||||
{
|
||||
return m_enforceMaxSegmentLength() ? m_maxSegmentLength() : std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setReferenceMDType( ReferenceMDType refType )
|
||||
{
|
||||
m_refMDType = refType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setManualReferenceMD( double manualRefMD )
|
||||
{
|
||||
m_refMD = manualRefMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setLinerDiameter( double diameter )
|
||||
{
|
||||
m_linerDiameter = diameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setRoughnessFactor( double roughnessFactor )
|
||||
{
|
||||
m_roughnessFactor = roughnessFactor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setPressureDrop( PressureDropType pressureDropType )
|
||||
{
|
||||
m_pressureDrop = pressureDropType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setLengthAndDepth( LengthAndDepthType lengthAndDepthType )
|
||||
{
|
||||
m_lengthAndDepth = lengthAndDepthType;
|
||||
}
|
||||
|
||||
RimSegmentCollection::DiameterRoughnessMode RimSegmentCollection::diameterRoughnessMode() const
|
||||
{
|
||||
return m_diameterRoughnessMode();
|
||||
}
|
||||
|
||||
void RimSegmentCollection::setDiameterRoughnessMode( DiameterRoughnessMode mode )
|
||||
{
|
||||
m_diameterRoughnessMode = mode;
|
||||
}
|
||||
|
||||
bool RimSegmentCollection::isUsingIntervalSpecificValues() const
|
||||
{
|
||||
return m_diameterRoughnessMode() == DiameterRoughnessMode::INTERVALS;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentInterval* RimSegmentCollection::findIntervalAtMD( double md, const std::optional<QDateTime>& exportDate ) const
|
||||
{
|
||||
for ( auto* interval : intervals() )
|
||||
{
|
||||
if ( interval && interval->containsMD( md ) && ( !exportDate.has_value() || interval->isActiveOnDate( *exportDate ) ) )
|
||||
return interval;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::getDiameterAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
if ( isUsingIntervalSpecificValues() )
|
||||
{
|
||||
if ( auto* interval = findIntervalAtMD( md, std::nullopt ) ) return interval->diameter( unitSystem );
|
||||
return defaultLinerDiameter( unitSystem );
|
||||
}
|
||||
return linerDiameter( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::getRoughnessAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
if ( isUsingIntervalSpecificValues() )
|
||||
{
|
||||
if ( auto* interval = findIntervalAtMD( md, std::nullopt ) ) return interval->roughnessFactor( unitSystem );
|
||||
return defaultRoughnessFactor( unitSystem );
|
||||
}
|
||||
return roughnessFactor( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::getDiameterAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem, const QDateTime& exportDate ) const
|
||||
{
|
||||
if ( isUsingIntervalSpecificValues() )
|
||||
{
|
||||
if ( auto* interval = findIntervalAtMD( md, exportDate ) ) return interval->diameter( unitSystem );
|
||||
return defaultLinerDiameter( unitSystem );
|
||||
}
|
||||
return linerDiameter( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentCollection::getRoughnessAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem, const QDateTime& exportDate ) const
|
||||
{
|
||||
if ( isUsingIntervalSpecificValues() )
|
||||
{
|
||||
if ( auto* interval = findIntervalAtMD( md, exportDate ) ) return interval->roughnessFactor( unitSystem );
|
||||
return defaultRoughnessFactor( unitSystem );
|
||||
}
|
||||
return roughnessFactor( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSegmentInterval*> RimSegmentCollection::intervals() const
|
||||
{
|
||||
return m_segmentIntervals.childrenByType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmChildArrayField<RimSegmentInterval*>& RimSegmentCollection::intervalsField()
|
||||
{
|
||||
return m_segmentIntervals;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentInterval* RimSegmentCollection::createInterval( double startMD, double endMD, double diameter, double roughness )
|
||||
{
|
||||
auto* interval = new RimSegmentInterval;
|
||||
interval->setStartMD( startMD );
|
||||
interval->setEndMD( endMD );
|
||||
interval->setDiameter( diameter );
|
||||
interval->setRoughnessFactor( roughness );
|
||||
addInterval( interval );
|
||||
return interval;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::addInterval( RimSegmentInterval* interval )
|
||||
{
|
||||
m_segmentIntervals.push_back( interval );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::removeInterval( RimSegmentInterval* interval )
|
||||
{
|
||||
m_segmentIntervals.removeChild( interval );
|
||||
delete interval;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::removeAllIntervals()
|
||||
{
|
||||
m_segmentIntervals.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentCollection::hasIntervals() const
|
||||
{
|
||||
return !m_segmentIntervals.empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::updateOverlapVisualFeedback()
|
||||
{
|
||||
auto segmentIntervals = intervals();
|
||||
for ( auto* interval : segmentIntervals )
|
||||
{
|
||||
bool hasOverlap = std::ranges::any_of( segmentIntervals,
|
||||
[interval]( const RimSegmentInterval* other )
|
||||
{ return interval != other && interval->overlaps( other ); } );
|
||||
interval->updateOverlapVisualFeedback( hasOverlap );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<double, double>> RimSegmentCollection::getSegmentIntervals() const
|
||||
{
|
||||
std::vector<std::pair<double, double>> result;
|
||||
for ( auto* interval : intervals() )
|
||||
{
|
||||
if ( interval && interval->isValidInterval() ) result.emplace_back( interval->startMD(), interval->endMD() );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentCollection::hasCustomSegmentIntervals() const
|
||||
{
|
||||
return hasIntervals();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::setUnitSystemSpecificDefaults()
|
||||
{
|
||||
auto* wellPath = firstAncestorOrThisOfTypeAsserted<RimWellPath>();
|
||||
m_linerDiameter = defaultLinerDiameter( wellPath->unitSystem() );
|
||||
m_roughnessFactor = defaultRoughnessFactor( wellPath->unitSystem() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::updateFromTopLevelWell( const RimSegmentCollection* topLevelWellParameters )
|
||||
{
|
||||
m_refMDType = topLevelWellParameters->m_refMDType();
|
||||
m_refMD = topLevelWellParameters->m_refMD();
|
||||
m_pressureDrop = topLevelWellParameters->m_pressureDrop();
|
||||
m_lengthAndDepth = topLevelWellParameters->m_lengthAndDepth();
|
||||
m_enforceMaxSegmentLength = topLevelWellParameters->m_enforceMaxSegmentLength();
|
||||
m_maxSegmentLength = topLevelWellParameters->m_maxSegmentLength();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentCollection::importLegacyData( const RimMswCompletionParameters* legacyParameters )
|
||||
{
|
||||
if ( !legacyParameters ) return;
|
||||
|
||||
const bool hasLegacyData = legacyParameters->referenceMDType() != RimMswCompletionParameters::ReferenceMDType::AUTO_REFERENCE_MD ||
|
||||
legacyParameters->storedReferenceMD() != 0.0 || legacyParameters->customValuesForLateral() ||
|
||||
legacyParameters->linerDiameter() != defaultLinerDiameter( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) ||
|
||||
legacyParameters->roughnessFactor() != defaultRoughnessFactor( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) ||
|
||||
legacyParameters->diameterRoughnessMode() != RimMswCompletionParameters::DiameterRoughnessMode::UNIFORM ||
|
||||
legacyParameters->pressureDrop() != RimMswCompletionParameters::PressureDropType::HYDROSTATIC_FRICTION ||
|
||||
legacyParameters->lengthAndDepth() != RimMswCompletionParameters::LengthAndDepthType::ABS ||
|
||||
legacyParameters->enforceMaxSegmentLength() || legacyParameters->storedMaxSegmentLength() != 200.0 ||
|
||||
!legacyParameters->diameterRoughnessIntervals()->intervals().empty() ||
|
||||
!legacyParameters->customSegmentIntervals()->intervals().empty();
|
||||
if ( !hasLegacyData ) return;
|
||||
|
||||
m_refMDType = static_cast<ReferenceMDType>(
|
||||
static_cast<int>( static_cast<RimMswCompletionParameters::ReferenceMDType>( legacyParameters->m_refMDType() ) ) );
|
||||
m_refMD = legacyParameters->m_refMD();
|
||||
m_customValuesForLateral = legacyParameters->m_customValuesForLateral();
|
||||
m_linerDiameter = legacyParameters->m_linerDiameter();
|
||||
m_roughnessFactor = legacyParameters->m_roughnessFactor();
|
||||
m_diameterRoughnessMode = static_cast<DiameterRoughnessMode>(
|
||||
static_cast<int>( static_cast<RimMswCompletionParameters::DiameterRoughnessMode>( legacyParameters->m_diameterRoughnessMode() ) ) );
|
||||
m_pressureDrop = static_cast<PressureDropType>(
|
||||
static_cast<int>( static_cast<RimMswCompletionParameters::PressureDropType>( legacyParameters->m_pressureDrop() ) ) );
|
||||
static_cast<int>( static_cast<RimMswCompletionParameters::LengthAndDepthType>( legacyParameters->lengthAndDepth() ) ) );
|
||||
m_enforceMaxSegmentLength = legacyParameters->enforceMaxSegmentLength();
|
||||
m_maxSegmentLength = legacyParameters->storedMaxSegmentLength();
|
||||
m_maxSegmentLength = legacyParameters->m_maxSegmentLength();
|
||||
|
||||
removeAllIntervals();
|
||||
for ( auto* oldInterval : legacyParameters->m_diameterRoughnessIntervals->intervals() )
|
||||
{
|
||||
auto* interval =
|
||||
createInterval( oldInterval->startMD(), oldInterval->endMD(), oldInterval->diameter(), oldInterval->roughnessFactor() );
|
||||
interval->m_useCustomStartDate = oldInterval->m_useCustomStartDate();
|
||||
interval->m_startDate = oldInterval->m_startDate();
|
||||
}
|
||||
|
||||
for ( auto* oldInterval : legacyParameters->customSegmentIntervals()->intervals() )
|
||||
for ( auto* oldInterval : legacyParameters->m_customSegmentIntervals->intervals() )
|
||||
{
|
||||
const auto currentIntervals = intervals();
|
||||
const auto matchingInterval =
|
||||
std::ranges::find_if( currentIntervals,
|
||||
[oldInterval]( const RimSegmentInterval* interval )
|
||||
{
|
||||
return std::abs( interval->startMD() - oldInterval->startMD() ) <= boundTolerance &&
|
||||
std::abs( interval->endMD() - oldInterval->endMD() ) <= boundTolerance;
|
||||
} );
|
||||
if ( matchingInterval == currentIntervals.end() )
|
||||
createInterval( oldInterval->startMD(), oldInterval->endMD(), legacyParameters->linerDiameter(), legacyParameters->roughnessFactor() );
|
||||
legacyParameters->m_roughnessFactor() );
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
double RimSegmentCollection::defaultLinerDiameter( RiaDefines::EclipseUnitSystem unitSystem )
|
||||
{
|
||||
return unitSystem == RiaDefines::EclipseUnitSystem::UNITS_METRIC ? 0.152 : 0.5;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
double RimSegmentCollection::defaultRoughnessFactor( RiaDefines::EclipseUnitSystem unitSystem )
|
||||
{
|
||||
return unitSystem == RiaDefines::EclipseUnitSystem::UNITS_METRIC ? 1.0e-5 : 3.28e-5;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RimSegmentCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
||||
{
|
||||
if ( changedField == &m_refMDType || changedField == &m_diameterRoughnessMode ) updateAllRequiredEditors();
|
||||
if ( changedField == &m_enforceMaxSegmentLength )
|
||||
{
|
||||
m_maxSegmentLength.uiCapability()->setUiHidden( !m_enforceMaxSegmentLength() );
|
||||
caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors();
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RimSegmentCollection::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
||||
{
|
||||
menuBuilder << "RicNewSegmentIntervalFeature";
|
||||
if ( hasIntervals() ) menuBuilder << "RicDeleteSegmentIntervalFeature";
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RimSegmentCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
auto* wellPath = firstAncestorOrThisOfTypeAsserted<RimWellPath>();
|
||||
const bool isMetric = wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_METRIC;
|
||||
m_linerDiameter.uiCapability()->setUiName( isMetric ? "Liner Inner Diameter [m]" : "Liner Inner Diameter [ft]" );
|
||||
m_roughnessFactor.uiCapability()->setUiName( isMetric ? "Roughness Factor [m]" : "Roughness Factor [ft]" );
|
||||
|
||||
if ( wellPath->isTopLevelWellPath() )
|
||||
{
|
||||
uiOrdering.add( &m_refMDType );
|
||||
uiOrdering.add( &m_refMD );
|
||||
m_refMD.uiCapability()->setUiHidden( m_refMDType == ReferenceMDType::AUTO_REFERENCE_MD );
|
||||
}
|
||||
else
|
||||
{
|
||||
uiOrdering.add( &m_customValuesForLateral );
|
||||
}
|
||||
|
||||
auto* diameterGroup = uiOrdering.addNewGroup( "Diameter and Roughness" );
|
||||
diameterGroup->add( &m_diameterRoughnessMode );
|
||||
if ( m_diameterRoughnessMode() == DiameterRoughnessMode::UNIFORM )
|
||||
{
|
||||
diameterGroup->add( &m_linerDiameter );
|
||||
diameterGroup->add( &m_roughnessFactor );
|
||||
}
|
||||
|
||||
if ( wellPath->isTopLevelWellPath() )
|
||||
{
|
||||
uiOrdering.add( &m_pressureDrop );
|
||||
uiOrdering.add( &m_lengthAndDepth );
|
||||
uiOrdering.add( &m_enforceMaxSegmentLength );
|
||||
uiOrdering.add( &m_maxSegmentLength );
|
||||
}
|
||||
|
||||
const bool readOnly = !wellPath->isTopLevelWellPath() && !m_customValuesForLateral();
|
||||
m_linerDiameter.uiCapability()->setUiReadOnly( readOnly );
|
||||
m_roughnessFactor.uiCapability()->setUiReadOnly( readOnly );
|
||||
m_diameterRoughnessMode.uiCapability()->setUiReadOnly( readOnly );
|
||||
m_segmentIntervals.uiCapability()->setUiReadOnly( readOnly );
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RimSegmentCollection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName )
|
||||
{
|
||||
for ( auto* interval : intervals() )
|
||||
uiTreeOrdering.add( interval );
|
||||
uiTreeOrdering.skipRemainingChildren( true );
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RimSegmentCollection::initAfterRead()
|
||||
{
|
||||
if ( m_linerDiameter() == std::numeric_limits<double>::infinity() && m_roughnessFactor() == std::numeric_limits<double>::infinity() )
|
||||
setUnitSystemSpecificDefaults();
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#include <optional>
|
||||
|
||||
class RimMswCompletionParameters;
|
||||
class RimSegmentInterval;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class CmdFeatureMenuBuilder;
|
||||
class PdmUiTreeOrdering;
|
||||
} // namespace caf
|
||||
|
||||
class RimSegmentCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
enum class ReferenceMDType
|
||||
{
|
||||
AUTO_REFERENCE_MD = 0,
|
||||
MANUAL_REFERENCE_MD
|
||||
};
|
||||
|
||||
enum class PressureDropType
|
||||
{
|
||||
HYDROSTATIC,
|
||||
HYDROSTATIC_FRICTION,
|
||||
HYDROSTATIC_FRICTION_ACCELERATION
|
||||
};
|
||||
|
||||
enum class LengthAndDepthType
|
||||
{
|
||||
ABS,
|
||||
INC
|
||||
};
|
||||
|
||||
enum class DiameterRoughnessMode
|
||||
{
|
||||
UNIFORM,
|
||||
INTERVALS
|
||||
};
|
||||
|
||||
using ReferenceMDEnum = caf::AppEnum<ReferenceMDType>;
|
||||
using PressureDropEnum = caf::AppEnum<PressureDropType>;
|
||||
using LengthAndDepthEnum = caf::AppEnum<LengthAndDepthType>;
|
||||
using DiameterRoughnessModeEnum = caf::AppEnum<DiameterRoughnessMode>;
|
||||
|
||||
RimSegmentCollection();
|
||||
|
||||
ReferenceMDType referenceMDType() const;
|
||||
double manualReferenceMD() const;
|
||||
double linerDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double linerDiameter() const;
|
||||
double roughnessFactor() const;
|
||||
double roughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
PressureDropEnum pressureDrop() const;
|
||||
LengthAndDepthEnum lengthAndDepth() const;
|
||||
double maxSegmentLength() const;
|
||||
|
||||
void setReferenceMDType( ReferenceMDType refType );
|
||||
void setManualReferenceMD( double manualRefMD );
|
||||
void setLinerDiameter( double diameter );
|
||||
void setRoughnessFactor( double roughnessFactor );
|
||||
void setPressureDrop( PressureDropType pressureDropType );
|
||||
void setLengthAndDepth( LengthAndDepthType lengthAndDepthType );
|
||||
|
||||
DiameterRoughnessMode diameterRoughnessMode() const;
|
||||
void setDiameterRoughnessMode( DiameterRoughnessMode mode );
|
||||
bool isUsingIntervalSpecificValues() const;
|
||||
|
||||
double getDiameterAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double getRoughnessAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double getDiameterAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem, const QDateTime& exportDate ) const;
|
||||
double getRoughnessAtMD( double md, RiaDefines::EclipseUnitSystem unitSystem, const QDateTime& exportDate ) const;
|
||||
|
||||
std::vector<RimSegmentInterval*> intervals() const;
|
||||
caf::PdmChildArrayField<RimSegmentInterval*>& intervalsField();
|
||||
RimSegmentInterval* createInterval( double startMD, double endMD, double diameter, double roughness );
|
||||
void addInterval( RimSegmentInterval* interval );
|
||||
void removeInterval( RimSegmentInterval* interval );
|
||||
void removeAllIntervals();
|
||||
bool hasIntervals() const;
|
||||
void updateOverlapVisualFeedback();
|
||||
|
||||
std::vector<std::pair<double, double>> getSegmentIntervals() const;
|
||||
bool hasCustomSegmentIntervals() const;
|
||||
|
||||
void setUnitSystemSpecificDefaults();
|
||||
void updateFromTopLevelWell( const RimSegmentCollection* topLevelWellParameters );
|
||||
void importLegacyData( const RimMswCompletionParameters* legacyParameters );
|
||||
|
||||
static double defaultLinerDiameter( RiaDefines::EclipseUnitSystem unitSystem );
|
||||
static double defaultRoughnessFactor( RiaDefines::EclipseUnitSystem unitSystem );
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
|
||||
void initAfterRead() override;
|
||||
|
||||
private:
|
||||
RimSegmentInterval* findIntervalAtMD( double md, const std::optional<QDateTime>& exportDate ) const;
|
||||
|
||||
private:
|
||||
caf::PdmField<ReferenceMDEnum> m_refMDType;
|
||||
caf::PdmField<double> m_refMD;
|
||||
|
||||
caf::PdmField<bool> m_customValuesForLateral;
|
||||
caf::PdmField<double> m_linerDiameter;
|
||||
caf::PdmField<double> m_roughnessFactor;
|
||||
|
||||
caf::PdmField<DiameterRoughnessModeEnum> m_diameterRoughnessMode;
|
||||
caf::PdmChildArrayField<RimSegmentInterval*> m_segmentIntervals;
|
||||
|
||||
caf::PdmField<PressureDropEnum> m_pressureDrop;
|
||||
caf::PdmField<LengthAndDepthEnum> m_lengthAndDepth;
|
||||
caf::PdmField<bool> m_enforceMaxSegmentLength;
|
||||
caf::PdmField<double> m_maxSegmentLength;
|
||||
};
|
||||
@@ -0,0 +1,391 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimSegmentInterval.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiDoubleValueEditor.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimSegmentInterval, "SegmentInterval" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentInterval::RimSegmentInterval()
|
||||
{
|
||||
CAF_PDM_InitScriptableObject( "Segment Interval", ":/WellPathComponent16x16.png", "", "SegmentInterval" );
|
||||
CAF_PDM_InitScriptableField( &m_startMD, "StartMd", 0.0, "Start MD" );
|
||||
CAF_PDM_InitScriptableField( &m_endMD, "EndMd", 0.0, "End MD" );
|
||||
CAF_PDM_InitScriptableField( &m_diameter,
|
||||
"Diameter",
|
||||
RimSegmentCollection::defaultLinerDiameter( RiaDefines::EclipseUnitSystem::UNITS_METRIC ),
|
||||
"Diameter" );
|
||||
CAF_PDM_InitScriptableField( &m_roughnessFactor,
|
||||
"RoughnessFactor",
|
||||
RimSegmentCollection::defaultRoughnessFactor( RiaDefines::EclipseUnitSystem::UNITS_METRIC ),
|
||||
"Roughness Factor" );
|
||||
|
||||
CAF_PDM_InitField( &m_useCustomStartDate, "UseCustomStartDate", false, "Custom Start Date" );
|
||||
CAF_PDM_InitField( &m_startDate, "StartDate", QDateTime::currentDateTime(), "Start Date" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentInterval::~RimSegmentInterval()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::startMD() const
|
||||
{
|
||||
return m_startMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::endMD() const
|
||||
{
|
||||
return m_endMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::diameter() const
|
||||
{
|
||||
return m_diameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::diameter( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
if ( unitSystem == RiaDefines::EclipseUnitSystem::UNITS_FIELD )
|
||||
{
|
||||
return RiaEclipseUnitTools::meterToInch( m_diameter );
|
||||
}
|
||||
return m_diameter; // METRIC units - already in meters
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::roughnessFactor() const
|
||||
{
|
||||
return m_roughnessFactor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::roughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const
|
||||
{
|
||||
if ( unitSystem == RiaDefines::EclipseUnitSystem::UNITS_FIELD )
|
||||
{
|
||||
return RiaEclipseUnitTools::meterToFeet( m_roughnessFactor );
|
||||
}
|
||||
return m_roughnessFactor; // METRIC units - already in meters
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::setStartMD( double startMD )
|
||||
{
|
||||
m_startMD = startMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::setEndMD( double endMD )
|
||||
{
|
||||
m_endMD = endMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::setDiameter( double diameter )
|
||||
{
|
||||
m_diameter = diameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::setRoughnessFactor( double roughness )
|
||||
{
|
||||
m_roughnessFactor = roughness;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::enableCustomStartDate( bool enable )
|
||||
{
|
||||
m_useCustomStartDate = enable;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::setCustomStartDate( const QDate& date )
|
||||
{
|
||||
if ( date.isValid() )
|
||||
{
|
||||
m_startDate = RiaQDateTimeTools::createDateTime( date );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::setCustomStartDate( const QDateTime& date )
|
||||
{
|
||||
m_startDate = date;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentInterval::isActiveOnDate( const QDateTime& date ) const
|
||||
{
|
||||
return !( m_useCustomStartDate() && date < m_startDate() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentInterval::isValidInterval() const
|
||||
{
|
||||
return m_endMD > m_startMD && m_diameter > 0.0 && m_roughnessFactor >= 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentInterval::overlaps( const RimSegmentInterval* other ) const
|
||||
{
|
||||
if ( !other ) return false;
|
||||
|
||||
return m_endMD > other->startMD() && m_startMD < other->endMD();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentInterval::containsMD( double md ) const
|
||||
{
|
||||
return md >= m_startMD && md <= m_endMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSegmentInterval::diameterLabel() const
|
||||
{
|
||||
return QString( "%1 m" ).arg( m_diameter(), 0, 'f', 3 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSegmentInterval::roughnessLabel() const
|
||||
{
|
||||
return QString( "%1 m" ).arg( m_roughnessFactor(), 0, 'e', 2 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentInterval::operator<( const RimSegmentInterval& rhs ) const
|
||||
{
|
||||
return m_startMD < rhs.m_startMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSegmentInterval::isEnabled() const
|
||||
{
|
||||
return true; // Always enabled for now
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaDefines::WellPathComponentType RimSegmentInterval::componentType() const
|
||||
{
|
||||
return RiaDefines::WellPathComponentType::CASING;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSegmentInterval::componentLabel() const
|
||||
{
|
||||
return generateDisplayLabel();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSegmentInterval::componentTypeLabel() const
|
||||
{
|
||||
return "Segment";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RimSegmentInterval::defaultComponentColor() const
|
||||
{
|
||||
return cvf::Color3f( 0.6f, 0.4f, 0.2f ); // Brown color for segment intervals
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::applyOffset( double offsetMD )
|
||||
{
|
||||
m_startMD = m_startMD + offsetMD;
|
||||
m_endMD = m_endMD + offsetMD;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
||||
{
|
||||
menuBuilder << "RicDeleteSegmentIntervalFeature";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
||||
{
|
||||
if ( changedField == &m_startMD || changedField == &m_endMD )
|
||||
{
|
||||
// Validate interval
|
||||
if ( m_startMD >= m_endMD )
|
||||
{
|
||||
RiaLogging::warning( "Invalid interval: Start MD must be less than End MD" );
|
||||
}
|
||||
|
||||
// Update overlap visual feedback in parent collection
|
||||
auto* collection = firstAncestorOrThisOfType<RimSegmentCollection>();
|
||||
if ( collection )
|
||||
{
|
||||
collection->updateOverlapVisualFeedback();
|
||||
}
|
||||
}
|
||||
|
||||
updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_startMD );
|
||||
uiOrdering.add( &m_endMD );
|
||||
uiOrdering.add( &m_diameter );
|
||||
uiOrdering.add( &m_roughnessFactor );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::updateConnectedEditors()
|
||||
{
|
||||
// Update any connected UI editors
|
||||
m_startMD.uiCapability()->updateConnectedEditors();
|
||||
m_endMD.uiCapability()->updateConnectedEditors();
|
||||
m_diameter.uiCapability()->updateConnectedEditors();
|
||||
m_roughnessFactor.uiCapability()->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimSegmentInterval::generateDisplayLabel() const
|
||||
{
|
||||
return QString( "MD %.1f-%.1f: D=%.3fm, R=%1em" ).arg( m_startMD() ).arg( m_endMD() ).arg( m_diameter() ).arg( m_roughnessFactor() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::defaultDiameter( RiaDefines::EclipseUnitSystem unitSystem )
|
||||
{
|
||||
return RimSegmentCollection::defaultLinerDiameter( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimSegmentInterval::defaultRoughness( RiaDefines::EclipseUnitSystem unitSystem )
|
||||
{
|
||||
return RimSegmentCollection::defaultRoughnessFactor( unitSystem );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSegmentInterval::updateOverlapVisualFeedback( bool hasOverlap )
|
||||
{
|
||||
if ( hasOverlap )
|
||||
{
|
||||
// Set red color for overlapping fields
|
||||
m_startMD.uiCapability()->setUiContentTextColor( Qt::red );
|
||||
m_endMD.uiCapability()->setUiContentTextColor( Qt::red );
|
||||
|
||||
// Create tooltip with overlap information
|
||||
QString tooltip = "This interval overlaps with another interval!";
|
||||
|
||||
m_startMD.uiCapability()->setUiToolTip( tooltip );
|
||||
m_endMD.uiCapability()->setUiToolTip( tooltip );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset color and tooltip
|
||||
m_startMD.uiCapability()->setUiContentTextColor( QColor() );
|
||||
m_endMD.uiCapability()->setUiContentTextColor( QColor() );
|
||||
m_startMD.uiCapability()->setUiToolTip( "" );
|
||||
m_endMD.uiCapability()->setUiToolTip( "" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RimWellPathComponentInterface.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <QDate>
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
|
||||
class RimWellPath;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class CmdFeatureMenuBuilder;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// Represents a segment interval for a specific measured depth range
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimSegmentInterval : public caf::PdmObject, public RimWellPathComponentInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimSegmentInterval();
|
||||
~RimSegmentInterval() override;
|
||||
|
||||
// Getters
|
||||
double startMD() const override;
|
||||
double endMD() const override;
|
||||
double diameter() const;
|
||||
double diameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
double roughnessFactor() const;
|
||||
double roughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const;
|
||||
|
||||
// Setters
|
||||
void setStartMD( double startMD );
|
||||
void setEndMD( double endMD );
|
||||
void setDiameter( double diameter );
|
||||
void setRoughnessFactor( double roughness );
|
||||
|
||||
// Date tracking
|
||||
void enableCustomStartDate( bool enable );
|
||||
void setCustomStartDate( const QDate& date );
|
||||
void setCustomStartDate( const QDateTime& date );
|
||||
bool isActiveOnDate( const QDateTime& date ) const;
|
||||
|
||||
// Validation
|
||||
bool isValidInterval() const;
|
||||
bool overlaps( const RimSegmentInterval* other ) const;
|
||||
bool containsMD( double md ) const;
|
||||
|
||||
// Display
|
||||
QString diameterLabel() const;
|
||||
QString roughnessLabel() const;
|
||||
|
||||
// Comparison for sorting
|
||||
bool operator<( const RimSegmentInterval& rhs ) const;
|
||||
|
||||
// Overrides from RimWellPathComponentInterface
|
||||
bool isEnabled() const override;
|
||||
RiaDefines::WellPathComponentType componentType() const override;
|
||||
QString componentLabel() const override;
|
||||
QString componentTypeLabel() const override;
|
||||
cvf::Color3f defaultComponentColor() const override;
|
||||
void applyOffset( double offsetMD ) override;
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
||||
// Public static methods for default values
|
||||
static double defaultDiameter( RiaDefines::EclipseUnitSystem unitSystem );
|
||||
static double defaultRoughness( RiaDefines::EclipseUnitSystem unitSystem );
|
||||
|
||||
// Visual feedback for overlapping intervals
|
||||
void updateOverlapVisualFeedback( bool hasOverlap );
|
||||
|
||||
protected:
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
private:
|
||||
void updateConnectedEditors();
|
||||
QString generateDisplayLabel() const;
|
||||
|
||||
private:
|
||||
caf::PdmField<double> m_startMD;
|
||||
caf::PdmField<double> m_endMD;
|
||||
caf::PdmField<double> m_diameter;
|
||||
caf::PdmField<double> m_roughnessFactor;
|
||||
|
||||
caf::PdmField<bool> m_useCustomStartDate;
|
||||
caf::PdmField<QDateTime> m_startDate;
|
||||
};
|
||||
@@ -123,14 +123,7 @@ RimWellPathCompletionSettings::RimWellPathCompletionSettings()
|
||||
CAF_PDM_InitFieldNoDefault( &m_mswParameters, "MswParameters", "Multi Segment Well Parameters" );
|
||||
m_mswParameters = new RimMswCompletionParameters;
|
||||
m_mswParameters.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_mswLinerDiameter, "MswLinerDiameter", "MSW Liner Diameter" );
|
||||
m_mswLinerDiameter.registerGetMethod( this, &RimWellPathCompletionSettings::mswLinerDiameter );
|
||||
m_mswLinerDiameter.registerSetMethod( this, &RimWellPathCompletionSettings::setMswLinerDiameter );
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_mswRoughness, "MswRoughness", "MSW Roughness" );
|
||||
m_mswRoughness.registerGetMethod( this, &RimWellPathCompletionSettings::mswRoughness );
|
||||
m_mswRoughness.registerSetMethod( this, &RimWellPathCompletionSettings::setMswRoughness );
|
||||
m_mswParameters.xmlCapability()->setIOWritable( false );
|
||||
|
||||
CAF_PDM_InitField( &m_referenceDepth_OBSOLETE, "ReferenceDepthForExport", QString(), "Reference Depth for BHP" );
|
||||
CAF_PDM_InitField( &m_drainageRadiusForPI_OBSOLETE, "DrainageRadiusForPI", QString( "0.0" ), "Drainage Radius for PI" );
|
||||
@@ -473,20 +466,9 @@ void RimWellPathCompletionSettings::defineUiOrdering( QString uiConfigName, caf:
|
||||
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 )
|
||||
{
|
||||
m_mswParameters->fieldChangedByUi( changedField, oldValue, newValue );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -496,35 +478,3 @@ QString RimWellPathCompletionSettings::formatStringForExport( const QString& tex
|
||||
if ( text.contains( ' ' ) ) return QString( "'%1'" ).arg( text );
|
||||
return text;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathCompletionSettings::setMswRoughness( const double& roughness )
|
||||
{
|
||||
m_mswParameters->setRoughnessFactor( roughness );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPathCompletionSettings::mswRoughness() const
|
||||
{
|
||||
return m_mswParameters->roughnessFactor();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathCompletionSettings::setMswLinerDiameter( const double& diameter )
|
||||
{
|
||||
m_mswParameters->setLinerDiameter( diameter );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPathCompletionSettings::mswLinerDiameter() const
|
||||
{
|
||||
return m_mswParameters->linerDiameter();
|
||||
}
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
@@ -107,17 +106,11 @@ public:
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void initAfterRead() override;
|
||||
|
||||
private:
|
||||
QString formatStringForExport( const QString& text, const QString& defaultText = "" ) const;
|
||||
|
||||
void setMswRoughness( const double& roughness );
|
||||
double mswRoughness() const;
|
||||
void setMswLinerDiameter( const double& diameter );
|
||||
double mswLinerDiameter() const;
|
||||
|
||||
private:
|
||||
friend class RimWellPathCompletions;
|
||||
|
||||
@@ -136,11 +129,6 @@ private:
|
||||
|
||||
caf::PdmChildField<RimMswCompletionParameters*> m_mswParameters;
|
||||
|
||||
// Use proxy fields for selected parameters in RimMswCompletionParameters, so it is possible to modify these values from the same
|
||||
// scripting object
|
||||
caf::PdmProxyValueField<double> m_mswLinerDiameter;
|
||||
caf::PdmProxyValueField<double> m_mswRoughness;
|
||||
|
||||
// OBSOLETE fields - kept for backward compatibility when reading old files
|
||||
caf::PdmField<QString> m_referenceDepth_OBSOLETE;
|
||||
caf::PdmField<QString> m_drainageRadiusForPI_OBSOLETE;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
#include "RimStimPlanModel.h"
|
||||
#include "RimStimPlanModelCollection.h"
|
||||
#include "RimValveCollection.h"
|
||||
@@ -74,6 +76,9 @@ RimWellPathCompletions::RimWellPathCompletions()
|
||||
CAF_PDM_InitFieldNoDefault( &m_mswSegmentCollection, "MswSegments", "MSW Segments" );
|
||||
m_mswSegmentCollection = new RimMswSegmentCollection;
|
||||
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_segmentCollection, "Segments", "Segments" );
|
||||
m_segmentCollection = new RimSegmentCollection;
|
||||
|
||||
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" );
|
||||
@@ -156,6 +161,14 @@ RimMswSegmentCollection* RimWellPathCompletions::mswSegmentCollection() const
|
||||
return m_mswSegmentCollection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSegmentCollection* RimWellPathCompletions::segmentCollection() const
|
||||
{
|
||||
return m_segmentCollection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -221,6 +234,10 @@ std::vector<RimWellPathComponentInterface*> RimWellPathCompletions::allCompletio
|
||||
completions.push_back( const_cast<RimMswSegment*>( segment ) );
|
||||
}
|
||||
}
|
||||
for ( auto* interval : m_segmentCollection->intervals() )
|
||||
{
|
||||
completions.push_back( interval );
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
@@ -258,6 +275,10 @@ std::vector<const RimWellPathComponentInterface*> RimWellPathCompletions::allCom
|
||||
completions.push_back( segment );
|
||||
}
|
||||
}
|
||||
for ( const auto* interval : m_segmentCollection->intervals() )
|
||||
{
|
||||
completions.push_back( interval );
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
@@ -273,7 +294,7 @@ bool RimWellPathCompletions::hasCompletions() const
|
||||
}
|
||||
|
||||
return !m_fishbonesCollection->allFishbonesSubs().empty() || !m_perforationCollection->perforations().empty() ||
|
||||
m_valveCollection->hasValves();
|
||||
m_valveCollection->hasValves() || m_segmentCollection->hasIntervals();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
class RimFishbonesCollection;
|
||||
class RimMswSegmentCollection;
|
||||
class RimPerforationCollection;
|
||||
class RimSegmentCollection;
|
||||
class RimValveCollection;
|
||||
class RimStimPlanModelCollection;
|
||||
class RimWellPathComponentInterface;
|
||||
@@ -51,6 +52,7 @@ public:
|
||||
RimWellPathFractureCollection* fractureCollection() const;
|
||||
RimStimPlanModelCollection* stimPlanModelCollection() const;
|
||||
RimMswSegmentCollection* mswSegmentCollection() const;
|
||||
RimSegmentCollection* segmentCollection() const;
|
||||
|
||||
std::vector<RimWellPathComponentInterface*> allCompletionsNoConst() const;
|
||||
std::vector<const RimWellPathComponentInterface*> allCompletions() const;
|
||||
@@ -76,6 +78,7 @@ private:
|
||||
caf::PdmChildField<RimWellPathFractureCollection*> m_fractureCollection;
|
||||
caf::PdmChildField<RimStimPlanModelCollection*> m_stimPlanModelCollection;
|
||||
caf::PdmChildField<RimMswSegmentCollection*> m_mswSegmentCollection;
|
||||
caf::PdmChildField<RimSegmentCollection*> m_segmentCollection;
|
||||
|
||||
private:
|
||||
/////////////////////
|
||||
|
||||
@@ -30,12 +30,11 @@
|
||||
#include "RimWellEventValve.h"
|
||||
#include "RimWellEventWellSpec.h"
|
||||
|
||||
#include "RimDiameterRoughnessInterval.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimValveTemplate.h"
|
||||
#include "RimValveTemplateCollection.h"
|
||||
@@ -528,23 +527,29 @@ bool RimWellEventTimeline::applyWellSpecEvent( const RimWellEventWellSpec& event
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellEventTimeline::applyTubingEvent( const RimWellEventTubing& event, RimWellPath& wellPath )
|
||||
{
|
||||
auto* mswParams = wellPath.mswCompletionParameters();
|
||||
if ( !mswParams )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* intervalCollection = mswParams->diameterRoughnessIntervals();
|
||||
if ( !intervalCollection )
|
||||
auto* segmentCollection = wellPath.segmentCollection();
|
||||
if ( !segmentCollection )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the diameter roughness mode to intervals
|
||||
mswParams->setDiameterRoughnessMode( RimMswCompletionParameters::DiameterRoughnessMode::INTERVALS );
|
||||
mswParams->setDiameterRoughnessMode( RimSegmentCollection::DiameterRoughnessMode::INTERVALS );
|
||||
|
||||
// Create a new interval
|
||||
auto* interval = intervalCollection->createInterval( event.startMD(), event.endMD(), event.innerDiameter(), event.roughness() );
|
||||
RimSegmentInterval* interval = nullptr;
|
||||
for ( auto* existingInterval : segmentCollection->intervals() )
|
||||
{
|
||||
if ( std::abs( existingInterval->startMD() - event.startMD() ) <= 1.0e-6 &&
|
||||
std::abs( existingInterval->endMD() - event.endMD() ) <= 1.0e-6 )
|
||||
{
|
||||
interval = existingInterval;
|
||||
interval->setDiameter( event.innerDiameter() );
|
||||
interval->setRoughnessFactor( event.roughness() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !interval )
|
||||
interval = segmentCollection->createInterval( event.startMD(), event.endMD(), event.innerDiameter(), event.roughness() );
|
||||
|
||||
if ( interval )
|
||||
{
|
||||
@@ -552,7 +557,7 @@ bool RimWellEventTimeline::applyTubingEvent( const RimWellEventTubing& event, Ri
|
||||
interval->enableCustomStartDate( true );
|
||||
interval->setCustomStartDate( event.eventDate().date() );
|
||||
|
||||
mswParams->updateConnectedEditors();
|
||||
segmentCollection->updateConnectedEditors();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,10 @@
|
||||
#include "RimFishbonesCollection.h"
|
||||
#include "RimImportedWellLog.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimOsduWellLog.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimStimPlanModelCollection.h"
|
||||
#include "RimValveCollection.h"
|
||||
#include "RimWellEventTimeline.h"
|
||||
@@ -334,35 +334,27 @@ RimWellPathCompletionSettings* RimWellPath::completionSettings()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimMswCompletionParameters* RimWellPath::mswCompletionParameters()
|
||||
RimSegmentCollection* RimWellPath::segmentCollection()
|
||||
{
|
||||
auto params = m_completionSettings->mswCompletionParameters();
|
||||
if ( !isTopLevelWellPath() )
|
||||
auto* collection = m_completions->segmentCollection();
|
||||
if ( const auto* topLevelWell = topLevelWellPath(); topLevelWell && topLevelWell != this )
|
||||
{
|
||||
auto topMsw = topLevelWellPath()->mswCompletionParameters();
|
||||
|
||||
// Propagate most settings from top level well into lateral parameters
|
||||
params->updateFromTopLevelWell( topMsw );
|
||||
collection->updateFromTopLevelWell( topLevelWell->segmentCollection() );
|
||||
}
|
||||
|
||||
return params;
|
||||
return collection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimMswCompletionParameters* RimWellPath::mswCompletionParameters() const
|
||||
const RimSegmentCollection* RimWellPath::segmentCollection() const
|
||||
{
|
||||
auto params = m_completionSettings->mswCompletionParameters();
|
||||
if ( !isTopLevelWellPath() )
|
||||
auto* collection = m_completions->segmentCollection();
|
||||
if ( const auto* topLevelWell = topLevelWellPath(); topLevelWell && topLevelWell != this )
|
||||
{
|
||||
auto topMsw = topLevelWellPath()->mswCompletionParameters();
|
||||
|
||||
// Propagate most settings from top level well into lateral parameters
|
||||
params->updateFromTopLevelWell( topMsw );
|
||||
collection->updateFromTopLevelWell( topLevelWell->segmentCollection() );
|
||||
}
|
||||
|
||||
return params;
|
||||
return collection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -557,6 +549,8 @@ void RimWellPath::initAfterRead()
|
||||
m_completionSettings->setWellNameForExport( name() );
|
||||
}
|
||||
}
|
||||
|
||||
m_completions->segmentCollection()->importLegacyData( m_completionSettings->mswCompletionParameters() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -785,9 +779,10 @@ void RimWellPath::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering,
|
||||
uiTreeOrdering.add( m_wellIASettingsCollection() );
|
||||
}
|
||||
|
||||
if ( m_completionSettings() && !allCompletionsRecursively().empty() )
|
||||
if ( m_completionSettings() && ( !allCompletionsRecursively().empty() || m_completions->segmentCollection()->hasIntervals() ) )
|
||||
{
|
||||
uiTreeOrdering.add( m_completionSettings() );
|
||||
uiTreeOrdering.add( m_completions->segmentCollection() );
|
||||
}
|
||||
if ( m_completions->valveCollection()->hasValves() )
|
||||
{
|
||||
@@ -886,10 +881,10 @@ void RimWellPath::setUnitSystem( RiaDefines::EclipseUnitSystem unitSystem )
|
||||
|
||||
m_completions->setUnitSystemSpecificDefaults();
|
||||
|
||||
std::vector<RimMswCompletionParameters*> mswParameters = descendantsOfType<RimMswCompletionParameters>();
|
||||
for ( auto mswParams : mswParameters )
|
||||
std::vector<RimSegmentCollection*> segmentCollections = descendantsOfType<RimSegmentCollection>();
|
||||
for ( auto* segmentCollection : segmentCollections )
|
||||
{
|
||||
mswParams->setUnitSystemSpecificDefaults();
|
||||
segmentCollection->setUnitSystemSpecificDefaults();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class RimWellPathFractureCollection;
|
||||
class Rim3dWellLogCurve;
|
||||
class Rim3dWellLogCurveCollection;
|
||||
class RimWellPathTieIn;
|
||||
class RimMswCompletionParameters;
|
||||
class RimSegmentCollection;
|
||||
class RimWellIASettingsCollection;
|
||||
class RimWellLogFile;
|
||||
class RimWellLog;
|
||||
@@ -128,8 +128,8 @@ public:
|
||||
const RimWellPathCompletions* completions() const;
|
||||
const RimWellPathCompletionSettings* completionSettings() const;
|
||||
RimWellPathCompletionSettings* completionSettings();
|
||||
RimMswCompletionParameters* mswCompletionParameters();
|
||||
const RimMswCompletionParameters* mswCompletionParameters() const;
|
||||
RimSegmentCollection* segmentCollection();
|
||||
const RimSegmentCollection* segmentCollection() const;
|
||||
|
||||
RimFishbonesCollection* fishbonesCollection();
|
||||
const RimFishbonesCollection* fishbonesCollection() const;
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
#include "RimFishbonesDefines.h"
|
||||
#include "RimImportedWellLog.h"
|
||||
#include "RimImportedWellLogData.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimPerforationCollection.h"
|
||||
#include "RimPerforationInterval.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimStimPlanFractureTemplate.h"
|
||||
#include "RimStimPlanModel.h"
|
||||
#include "RimThermalFractureTemplate.h"
|
||||
@@ -222,44 +222,32 @@ QString RimcWellPath_appendPerforationInterval::classKeywordReturnedType() const
|
||||
return RimPerforationInterval::classKeywordStatic();
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPath, RimcWellPath_multiSegmentWellSettings, "MswSettings" );
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPath, RimcWellPath_segmentCollection, "SegmentCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimcWellPath_multiSegmentWellSettings::RimcWellPath_multiSegmentWellSettings( caf::PdmObjectHandle* self )
|
||||
RimcWellPath_segmentCollection::RimcWellPath_segmentCollection( caf::PdmObjectHandle* self )
|
||||
: PdmObjectMethod( self, PdmObjectMethod::NullPointerType::NULL_IS_VALID, PdmObjectMethod::ResultType::PERSISTENT_TRUE )
|
||||
{
|
||||
CAF_PDM_InitObject( "MSW Settings", "", "", "Multi Segment Well Settings" );
|
||||
CAF_PDM_InitObject( "Segment Collection", "", "", "Segment Collection" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimcWellPath_multiSegmentWellSettings::execute()
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimcWellPath_segmentCollection::execute()
|
||||
{
|
||||
auto wellPath = self<RimWellPath>();
|
||||
|
||||
// RimMswCompletionParameters is a child object of RimWellPathCompletionSettings. To simplify the Python API, we return
|
||||
// RimMswCompletionParameters directly from a well path object in Python. Two parameters are already exposed as part of the completion
|
||||
// settings object, see RimWellPathCompletionSettings and the proxy fields liner_diameter and roughness. These fields are kept to
|
||||
// ensure backward compatibility with existing scripts.
|
||||
//
|
||||
// https://github.com/OPM/ResInsight/issues/11901
|
||||
|
||||
if ( auto completionSettings = wellPath->completionSettings() )
|
||||
{
|
||||
return completionSettings->mswCompletionParameters();
|
||||
}
|
||||
return nullptr;
|
||||
auto* wellPath = self<RimWellPath>();
|
||||
return wellPath ? wellPath->segmentCollection() : nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimcWellPath_multiSegmentWellSettings::classKeywordReturnedType() const
|
||||
QString RimcWellPath_segmentCollection::classKeywordReturnedType() const
|
||||
{
|
||||
return RimMswCompletionParameters::classKeywordStatic();
|
||||
return RimSegmentCollection::classKeywordStatic();
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPath, RimcWellPath_appendFishbones, "AppendFishbones" );
|
||||
|
||||
@@ -95,12 +95,12 @@ private:
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimcWellPath_multiSegmentWellSettings : public caf::PdmObjectMethod
|
||||
class RimcWellPath_segmentCollection : public caf::PdmObjectMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimcWellPath_multiSegmentWellSettings( caf::PdmObjectHandle* self );
|
||||
RimcWellPath_segmentCollection( caf::PdmObjectHandle* self );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
QString classKeywordReturnedType() const override;
|
||||
|
||||
@@ -18,141 +18,36 @@
|
||||
|
||||
#include "RimcWellPathCompletionSettings.h"
|
||||
|
||||
#include "RimCustomSegmentInterval.h"
|
||||
#include "RimCustomSegmentIntervalCollection.h"
|
||||
#include "RimDiameterRoughnessInterval.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimWellPathCompletionSettings.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPathCompletionSettings,
|
||||
RimcWellPathCompletionSettings_addDiameterRoughnessInterval,
|
||||
"AddDiameterRoughnessInterval" );
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimSegmentCollection, RimcSegmentCollection_addSegmentInterval, "AddSegmentInterval" );
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPathCompletionSettings,
|
||||
RimcWellPathCompletionSettings_addCustomSegmentInterval,
|
||||
"AddCustomSegmentInterval" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimcWellPathCompletionSettings_addDiameterRoughnessInterval::RimcWellPathCompletionSettings_addDiameterRoughnessInterval( caf::PdmObjectHandle* self )
|
||||
RimcSegmentCollection_addSegmentInterval::RimcSegmentCollection_addSegmentInterval( caf::PdmObjectHandle* self )
|
||||
: caf::PdmObjectCreationMethod( self )
|
||||
{
|
||||
CAF_PDM_InitObject( "Add Diameter Roughness Interval" );
|
||||
CAF_PDM_InitObject( "Add Segment Interval" );
|
||||
CAF_PDM_InitScriptableField( &m_startMD, "StartMd", 0.0, "Start Measured Depth" );
|
||||
CAF_PDM_InitScriptableField( &m_endMD, "EndMd", 100.0, "End Measured Depth" );
|
||||
CAF_PDM_InitScriptableField( &m_diameter, "Diameter", 0.152, "Diameter" );
|
||||
CAF_PDM_InitScriptableField( &m_roughnessFactor, "RoughnessFactor", 1.0e-5, "Roughness Factor" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimcWellPathCompletionSettings_addDiameterRoughnessInterval::execute()
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimcSegmentCollection_addSegmentInterval::execute()
|
||||
{
|
||||
auto completionSettings = self<RimWellPathCompletionSettings>();
|
||||
if ( !completionSettings )
|
||||
{
|
||||
return std::unexpected( QString( "Completion settings is null. Cannot add diameter roughness interval." ) );
|
||||
}
|
||||
auto* segmentCollection = self<RimSegmentCollection>();
|
||||
if ( !segmentCollection ) return std::unexpected( "Segment collection is null. Cannot add segment interval." );
|
||||
if ( m_endMD() <= m_startMD() ) return std::unexpected( "End MD must be greater than Start MD." );
|
||||
|
||||
auto mswParams = completionSettings->mswCompletionParameters();
|
||||
if ( !mswParams )
|
||||
{
|
||||
return std::unexpected( QString( "MSW completion parameters is null. Cannot add diameter roughness interval." ) );
|
||||
}
|
||||
|
||||
auto intervalCollection = mswParams->diameterRoughnessIntervals();
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
return std::unexpected( QString( "Diameter roughness interval collection is null. Cannot add interval." ) );
|
||||
}
|
||||
|
||||
// Ensure we're in interval-specific mode
|
||||
mswParams->setDiameterRoughnessMode( RimMswCompletionParameters::DiameterRoughnessMode::INTERVALS );
|
||||
|
||||
// Create new interval
|
||||
auto* newInterval = intervalCollection->createInterval( m_startMD(), m_endMD(), m_diameter(), m_roughnessFactor() );
|
||||
|
||||
if ( !newInterval )
|
||||
{
|
||||
return std::unexpected( QString( "Failed to create diameter roughness interval." ) );
|
||||
}
|
||||
|
||||
completionSettings->updateAllRequiredEditors();
|
||||
|
||||
return newInterval;
|
||||
segmentCollection->setDiameterRoughnessMode( RimSegmentCollection::DiameterRoughnessMode::INTERVALS );
|
||||
auto* interval = segmentCollection->createInterval( m_startMD(), m_endMD(), m_diameter(), m_roughnessFactor() );
|
||||
segmentCollection->updateAllRequiredEditors();
|
||||
return interval;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimcWellPathCompletionSettings_addDiameterRoughnessInterval::classKeywordReturnedType() const
|
||||
QString RimcSegmentCollection_addSegmentInterval::classKeywordReturnedType() const
|
||||
{
|
||||
return RimDiameterRoughnessInterval::classKeywordStatic();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimcWellPathCompletionSettings_addCustomSegmentInterval::RimcWellPathCompletionSettings_addCustomSegmentInterval( caf::PdmObjectHandle* self )
|
||||
: caf::PdmObjectCreationMethod( self )
|
||||
{
|
||||
CAF_PDM_InitObject( "Add Custom Segment Interval" );
|
||||
CAF_PDM_InitScriptableField( &m_startMD, "StartMd", 0.0, "Start Measured Depth" );
|
||||
CAF_PDM_InitScriptableField( &m_endMD, "EndMd", 100.0, "End Measured Depth" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimcWellPathCompletionSettings_addCustomSegmentInterval::execute()
|
||||
{
|
||||
auto completionSettings = self<RimWellPathCompletionSettings>();
|
||||
if ( !completionSettings )
|
||||
{
|
||||
return std::unexpected( QString( "Completion settings is null. Cannot add custom segment interval." ) );
|
||||
}
|
||||
|
||||
auto mswParams = completionSettings->mswCompletionParameters();
|
||||
if ( !mswParams )
|
||||
{
|
||||
return std::unexpected( QString( "MSW completion parameters is null. Cannot add custom segment interval." ) );
|
||||
}
|
||||
|
||||
auto intervalCollection = mswParams->customSegmentIntervals();
|
||||
if ( !intervalCollection )
|
||||
{
|
||||
return std::unexpected( QString( "Custom segment interval collection is null. Cannot add interval." ) );
|
||||
}
|
||||
|
||||
// Validate that end MD is greater than start MD
|
||||
if ( m_endMD() <= m_startMD() )
|
||||
{
|
||||
return std::unexpected(
|
||||
QString( "End MD must be greater than Start MD. Start MD: %1, End MD: %2" ).arg( m_startMD() ).arg( m_endMD() ) );
|
||||
}
|
||||
|
||||
// Create new interval
|
||||
auto* newInterval = intervalCollection->createInterval( m_startMD(), m_endMD() );
|
||||
|
||||
if ( !newInterval )
|
||||
{
|
||||
return std::unexpected( QString( "Failed to create custom segment interval." ) );
|
||||
}
|
||||
|
||||
completionSettings->updateAllRequiredEditors();
|
||||
|
||||
return newInterval;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimcWellPathCompletionSettings_addCustomSegmentInterval::classKeywordReturnedType() const
|
||||
{
|
||||
return RimCustomSegmentInterval::classKeywordStatic();
|
||||
return RimSegmentInterval::classKeywordStatic();
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmField.h"
|
||||
@@ -24,15 +23,12 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimcWellPathCompletionSettings_addDiameterRoughnessInterval : public caf::PdmObjectCreationMethod
|
||||
class RimcSegmentCollection_addSegmentInterval : public caf::PdmObjectCreationMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimcWellPathCompletionSettings_addDiameterRoughnessInterval( caf::PdmObjectHandle* self );
|
||||
RimcSegmentCollection_addSegmentInterval( caf::PdmObjectHandle* self );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
QString classKeywordReturnedType() const override;
|
||||
@@ -43,21 +39,3 @@ private:
|
||||
caf::PdmField<double> m_diameter;
|
||||
caf::PdmField<double> m_roughnessFactor;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimcWellPathCompletionSettings_addCustomSegmentInterval : public caf::PdmObjectCreationMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimcWellPathCompletionSettings_addCustomSegmentInterval( caf::PdmObjectHandle* self );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
QString classKeywordReturnedType() const override;
|
||||
|
||||
private:
|
||||
caf::PdmField<double> m_startMD;
|
||||
caf::PdmField<double> m_endMD;
|
||||
};
|
||||
@@ -1,7 +1,50 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RimCustomSegmentIntervalCollection.h"
|
||||
#include "RimDiameterRoughnessInterval.h"
|
||||
#include "RimDiameterRoughnessIntervalCollection.h"
|
||||
#include "RimMswCompletionParameters.h"
|
||||
#include "RimSegmentCollection.h"
|
||||
#include "RimSegmentInterval.h"
|
||||
#include "RimWellPathCompletions.h"
|
||||
|
||||
TEST( RimWellPathCompletions, SegmentIntervalsDefineCustomSegmentation )
|
||||
{
|
||||
RimWellPathCompletions completions;
|
||||
auto* segments = completions.segmentCollection();
|
||||
|
||||
segments->setDiameterRoughnessMode( RimSegmentCollection::DiameterRoughnessMode::INTERVALS );
|
||||
auto* interval = segments->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
||||
|
||||
ASSERT_NE( nullptr, interval );
|
||||
EXPECT_TRUE( segments->hasCustomSegmentIntervals() );
|
||||
EXPECT_EQ( ( std::vector<std::pair<double, double>>{ { 100.0, 200.0 } } ), segments->getSegmentIntervals() );
|
||||
EXPECT_DOUBLE_EQ( 0.12, segments->getDiameterAtMD( 150.0, RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
||||
EXPECT_DOUBLE_EQ( 2.0e-5, segments->getRoughnessAtMD( 150.0, RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
||||
}
|
||||
|
||||
TEST( RimWellPathCompletions, LegacySegmentIntervalsAreMergedByBounds )
|
||||
{
|
||||
RimMswCompletionParameters legacyParameters;
|
||||
legacyParameters.setLinerDiameter( 0.2 );
|
||||
legacyParameters.setRoughnessFactor( 3.0e-5 );
|
||||
legacyParameters.diameterRoughnessIntervals()->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
||||
legacyParameters.customSegmentIntervals()->createInterval( 100.0 + 0.5e-6, 200.0 - 0.5e-6 );
|
||||
legacyParameters.customSegmentIntervals()->createInterval( 300.0, 400.0 );
|
||||
|
||||
RimSegmentCollection segments;
|
||||
segments.importLegacyData( &legacyParameters );
|
||||
|
||||
const auto intervals = segments.intervals();
|
||||
ASSERT_EQ( 2, intervals.size() );
|
||||
EXPECT_DOUBLE_EQ( 0.12, intervals[0]->diameter() );
|
||||
EXPECT_DOUBLE_EQ( 2.0e-5, intervals[0]->roughnessFactor() );
|
||||
EXPECT_DOUBLE_EQ( 300.0, intervals[1]->startMD() );
|
||||
EXPECT_DOUBLE_EQ( 400.0, intervals[1]->endMD() );
|
||||
EXPECT_DOUBLE_EQ( 0.2, intervals[1]->diameter() );
|
||||
EXPECT_DOUBLE_EQ( 3.0e-5, intervals[1]->roughnessFactor() );
|
||||
}
|
||||
|
||||
/*
|
||||
#include <QRegExpValidator>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -61,34 +61,25 @@ perforation.update()
|
||||
|
||||
# Optionally update the completion settings
|
||||
completions_settings = well_path.completion_settings()
|
||||
completions_settings.msw_roughness = 12.34
|
||||
completions_settings.msw_liner_diameter = 0.2222
|
||||
completions_settings.well_name_for_export = "file name"
|
||||
completions_settings.group_name_for_export = "msj"
|
||||
completions_settings.well_type_for_export = "GAS"
|
||||
completions_settings.update() # Commit updates back to ResInsight
|
||||
|
||||
# Add diameter roughness intervals for interval-specific configuration
|
||||
interval1 = completions_settings.add_diameter_roughness_interval(
|
||||
start_md=3200, end_md=3300, diameter=0.18, roughness_factor=1.5e-5
|
||||
# Add segment intervals. Each interval defines explicit MSW segment boundaries
|
||||
# and its diameter and roughness.
|
||||
segment1 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=3200, end_md=3250, diameter=0.18, roughness_factor=1.5e-5
|
||||
)
|
||||
interval2 = completions_settings.add_diameter_roughness_interval(
|
||||
start_md=3300, end_md=3400, diameter=0.16, roughness_factor=2.0e-5
|
||||
segment2 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=3250, end_md=3320, diameter=0.16, roughness_factor=2.0e-5
|
||||
)
|
||||
print(
|
||||
f"Added diameter roughness intervals: {interval1.start_md}-{interval1.end_md}m and {interval2.start_md}-{interval2.end_md}m"
|
||||
f"Added segment intervals: {segment1.start_md}-{segment1.end_md}m and {segment2.start_md}-{segment2.end_md}m"
|
||||
)
|
||||
|
||||
# Add custom segment intervals to define explicit segment boundaries for MSW export
|
||||
segment1 = completions_settings.add_custom_segment_interval(start_md=3200, end_md=3250)
|
||||
segment2 = completions_settings.add_custom_segment_interval(start_md=3250, end_md=3320)
|
||||
segment3 = completions_settings.add_custom_segment_interval(start_md=3320, end_md=3400)
|
||||
print(
|
||||
f"Added custom segment intervals: {segment1.start_md}-{segment1.end_md}m, {segment2.start_md}-{segment2.end_md}m, {segment3.start_md}-{segment3.end_md}m"
|
||||
)
|
||||
|
||||
# Optionally update the MSW settings
|
||||
msw_settings = well_path.msw_settings()
|
||||
# Optionally update the segment settings
|
||||
msw_settings = well_path.segment_collection()
|
||||
msw_settings.custom_values_for_lateral = False
|
||||
msw_settings.enforce_max_segment_length = False
|
||||
msw_settings.liner_diameter = 0.152
|
||||
|
||||
@@ -236,7 +236,7 @@ def main():
|
||||
print(f" Valves: {len(valves)}")
|
||||
|
||||
# Check MSW settings (tubing intervals)
|
||||
msw_settings = well_path.msw_settings()
|
||||
msw_settings = well_path.segment_collection()
|
||||
if msw_settings:
|
||||
print(f" MSW diameter/roughness mode: {msw_settings.diameter_roughness_mode}")
|
||||
|
||||
|
||||
@@ -2067,11 +2067,14 @@ def _apply_segment(
|
||||
return
|
||||
|
||||
timeline_event = timeline.add_tubing_event(**kwargs)
|
||||
well_path.completion_settings().add_custom_segment_interval(
|
||||
start_md=start_md, end_md=end_md
|
||||
well_path.segment_collection().add_segment_interval(
|
||||
start_md=start_md,
|
||||
end_md=end_md,
|
||||
diameter=kwargs.get("inner_diameter", 0.152),
|
||||
roughness_factor=kwargs.get("roughness", 1.0e-5),
|
||||
)
|
||||
if pressure_components is not None:
|
||||
msw_settings = well_path.msw_settings()
|
||||
msw_settings = well_path.segment_collection()
|
||||
msw_settings.pressure_drop = pressure_components
|
||||
msw_settings.update()
|
||||
_apply_event_comment(event, timeline_event)
|
||||
|
||||
@@ -15,7 +15,7 @@ def test_custom_segment_intervals(rips_instance, initialize_test):
|
||||
assert completions_settings is not None, "Completion settings should not be None"
|
||||
|
||||
# Test creating first interval
|
||||
interval1 = completions_settings.add_custom_segment_interval(
|
||||
interval1 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=100, end_md=200
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ def test_custom_segment_intervals(rips_instance, initialize_test):
|
||||
assert interval1.end_md == 200
|
||||
|
||||
# Test creating a second interval with different values
|
||||
interval2 = completions_settings.add_custom_segment_interval(
|
||||
interval2 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=250, end_md=350
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ def test_custom_segment_intervals(rips_instance, initialize_test):
|
||||
assert interval2.end_md == 350
|
||||
|
||||
# Test default values
|
||||
interval3 = completions_settings.add_custom_segment_interval()
|
||||
interval3 = well_path.segment_collection().add_segment_interval()
|
||||
|
||||
assert interval3 is not None, "Third interval with defaults should not be None"
|
||||
assert interval3.start_md == 0.0
|
||||
@@ -50,10 +50,8 @@ def test_custom_segment_interval_properties(rips_instance, initialize_test):
|
||||
well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
|
||||
well_path.name = "Test Well for Property Modification"
|
||||
|
||||
completions_settings = well_path.completion_settings()
|
||||
|
||||
# Create an interval
|
||||
interval1 = completions_settings.add_custom_segment_interval(
|
||||
interval1 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=100, end_md=200
|
||||
)
|
||||
|
||||
@@ -73,12 +71,10 @@ def test_custom_segment_interval_invalid_range(rips_instance, initialize_test):
|
||||
well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
|
||||
well_path.name = "Test Well for Invalid Range"
|
||||
|
||||
completions_settings = well_path.completion_settings()
|
||||
|
||||
# Attempt to create an interval with start_md > end_md. Should fail.
|
||||
with pytest.raises(rips.RipsError, match="End MD must be greater than Start MD"):
|
||||
completions_settings.add_custom_segment_interval(start_md=200, end_md=100)
|
||||
well_path.segment_collection().add_segment_interval(start_md=200, end_md=100)
|
||||
|
||||
# Also test equal values (start_md == end_md), which should also fail
|
||||
with pytest.raises(rips.RipsError, match="End MD must be greater than Start MD"):
|
||||
completions_settings.add_custom_segment_interval(start_md=150, end_md=150)
|
||||
well_path.segment_collection().add_segment_interval(start_md=150, end_md=150)
|
||||
@@ -13,7 +13,7 @@ def test_diameter_roughness_intervals(rips_instance, initialize_test):
|
||||
assert completions_settings is not None, "Completion settings should not be None"
|
||||
|
||||
# Test our new method - create first interval
|
||||
interval1 = completions_settings.add_diameter_roughness_interval(
|
||||
interval1 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=100, end_md=200, diameter=0.15, roughness_factor=1e-5
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ def test_diameter_roughness_intervals(rips_instance, initialize_test):
|
||||
assert interval1.roughness_factor == 1e-5
|
||||
|
||||
# Test creating a second interval with different values
|
||||
interval2 = completions_settings.add_diameter_roughness_interval(
|
||||
interval2 = well_path.segment_collection().add_segment_interval(
|
||||
start_md=200, end_md=300, diameter=0.12, roughness_factor=2e-5
|
||||
)
|
||||
|
||||
@@ -37,7 +37,7 @@ def test_diameter_roughness_intervals(rips_instance, initialize_test):
|
||||
assert interval2.roughness_factor == 2e-5
|
||||
|
||||
# Test default values
|
||||
interval3 = completions_settings.add_diameter_roughness_interval()
|
||||
interval3 = well_path.segment_collection().add_segment_interval()
|
||||
|
||||
assert interval3 is not None, "Third interval with defaults should not be None"
|
||||
assert interval3.start_md == 0.0
|
||||
|
||||
@@ -212,7 +212,7 @@ def test_msw_settings_read(rips_instance, initialize_test):
|
||||
assert well_y1 is not None, "Well-1 Y1 should exist in project"
|
||||
|
||||
# Get MSW settings
|
||||
msw_settings = well_y1.msw_settings()
|
||||
msw_settings = well_y1.segment_collection()
|
||||
|
||||
# Verify MSW settings values from the project file
|
||||
# According to the project analysis, the liner diameter is 0.152m
|
||||
|
||||
@@ -61,17 +61,17 @@ class FakeCompletionSettings:
|
||||
self.allow_well_cross_flow = True
|
||||
self.reference_depth_for_export = None
|
||||
self.well_type_for_export = "OIL"
|
||||
self.custom_segment_calls = []
|
||||
|
||||
def add_custom_segment_interval(self, **kwargs):
|
||||
self.custom_segment_calls.append(kwargs)
|
||||
|
||||
|
||||
class FakeMswSettings:
|
||||
class FakeSegmentCollection:
|
||||
def __init__(self):
|
||||
self.pressure_drop = "HF-"
|
||||
self.segment_interval_calls = []
|
||||
self.update_calls = 0
|
||||
|
||||
def add_segment_interval(self, **kwargs):
|
||||
self.segment_interval_calls.append(kwargs)
|
||||
|
||||
def update(self):
|
||||
self.update_calls += 1
|
||||
|
||||
@@ -80,13 +80,13 @@ class FakeWellPath:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self._completion_settings = FakeCompletionSettings()
|
||||
self._msw_settings = FakeMswSettings()
|
||||
self._segment_collection = FakeSegmentCollection()
|
||||
|
||||
def completion_settings(self):
|
||||
return self._completion_settings
|
||||
|
||||
def msw_settings(self):
|
||||
return self._msw_settings
|
||||
def segment_collection(self):
|
||||
return self._segment_collection
|
||||
|
||||
|
||||
class FakeProject:
|
||||
@@ -1545,11 +1545,16 @@ class TestApplying:
|
||||
assert call["roughness"] == pytest.approx(1.0e-5)
|
||||
|
||||
well = call["well_path"]
|
||||
assert well.completion_settings().custom_segment_calls == [
|
||||
{"start_md": 0.0, "end_md": 2500.0}
|
||||
assert well.segment_collection().segment_interval_calls == [
|
||||
{
|
||||
"start_md": 0.0,
|
||||
"end_md": 2500.0,
|
||||
"diameter": 0.15,
|
||||
"roughness_factor": pytest.approx(1.0e-5),
|
||||
}
|
||||
]
|
||||
assert well.msw_settings().pressure_drop == "HFA"
|
||||
assert well.msw_settings().update_calls == 1
|
||||
assert well.segment_collection().pressure_drop == "HFA"
|
||||
assert well.segment_collection().update_calls == 1
|
||||
|
||||
def test_segment_rejects_invalid_pressure_components(self):
|
||||
text = (
|
||||
@@ -2419,12 +2424,12 @@ class TestSimulatorEventsIntegration:
|
||||
assert report.warnings == []
|
||||
assert report.events_applied == 11
|
||||
|
||||
custom_segments = well.descendants(rips.CustomSegmentInterval)
|
||||
segment_intervals = well.descendants(rips.SegmentInterval)
|
||||
assert any(
|
||||
segment.start_md == 0.0 and segment.end_md == 2500.0
|
||||
for segment in custom_segments
|
||||
for segment in segment_intervals
|
||||
)
|
||||
assert well.msw_settings().pressure_drop == "HFA"
|
||||
assert well.segment_collection().pressure_drop == "HFA"
|
||||
|
||||
timeline.set_timestamp(timestamp="2024-12-24")
|
||||
schedule = timeline.generate_schedule_text(
|
||||
|
||||
@@ -192,7 +192,7 @@ class TestWellEventScheduleApplication:
|
||||
timeline.set_timestamp(timestamp="2024-01-15")
|
||||
|
||||
# Verify MSW settings were updated
|
||||
msw_settings = well_path_b.msw_settings()
|
||||
msw_settings = well_path_b.segment_collection()
|
||||
assert msw_settings is not None, "MSW settings should be available"
|
||||
# Check that diameter roughness mode was set to intervals
|
||||
assert msw_settings.diameter_roughness_mode == "Intervals", (
|
||||
|
||||
@@ -41,8 +41,6 @@ def test_add_well_path_completions(rips_instance, initialize_test):
|
||||
completions_settings.gas_inflow_eq = "R-G"
|
||||
completions_settings.group_name_for_export = "TestGroup"
|
||||
completions_settings.hydrostatic_density = "AVG"
|
||||
completions_settings.msw_liner_diameter = 0.12
|
||||
completions_settings.msw_roughness = 4.66
|
||||
completions_settings.reference_depth_for_export = 1234
|
||||
completions_settings.well_bore_fluid_pvt_table = 33
|
||||
completions_settings.well_name_for_export = "TestWellName"
|
||||
@@ -57,33 +55,31 @@ def test_add_well_path_completions(rips_instance, initialize_test):
|
||||
assert completions_settings_updated.gas_inflow_eq == "R-G"
|
||||
assert completions_settings_updated.group_name_for_export == "TestGroup"
|
||||
assert completions_settings_updated.hydrostatic_density == "AVG"
|
||||
assert completions_settings_updated.msw_liner_diameter == 0.12
|
||||
assert completions_settings_updated.msw_roughness == 4.66
|
||||
assert completions_settings_updated.reference_depth_for_export == 1234
|
||||
assert completions_settings_updated.well_bore_fluid_pvt_table == 33
|
||||
assert completions_settings_updated.well_name_for_export == "TestWellName"
|
||||
assert completions_settings_updated.well_type_for_export == "LIQUID"
|
||||
|
||||
msw_settings = well_path.msw_settings()
|
||||
msw_settings.custom_values_for_lateral = True
|
||||
msw_settings.enforce_max_segment_length = True
|
||||
msw_settings.liner_diameter = 20.0
|
||||
msw_settings.max_segment_length = 123.05
|
||||
msw_settings.pressure_drop = "HFA"
|
||||
msw_settings.reference_md_type = "UserDefined"
|
||||
msw_settings.roughness_factor = 1.3
|
||||
msw_settings.user_defined_reference_md = 1234.56
|
||||
msw_settings.update()
|
||||
segment_collection = well_path.segment_collection()
|
||||
segment_collection.custom_values_for_lateral = True
|
||||
segment_collection.enforce_max_segment_length = True
|
||||
segment_collection.liner_diameter = 20.0
|
||||
segment_collection.max_segment_length = 123.05
|
||||
segment_collection.pressure_drop = "HFA"
|
||||
segment_collection.reference_md_type = "UserDefined"
|
||||
segment_collection.roughness_factor = 1.3
|
||||
segment_collection.user_defined_reference_md = 1234.56
|
||||
segment_collection.update()
|
||||
|
||||
msw_settings_updated = well_path.msw_settings()
|
||||
assert msw_settings_updated.custom_values_for_lateral
|
||||
assert msw_settings_updated.enforce_max_segment_length
|
||||
assert msw_settings_updated.liner_diameter == 20.0
|
||||
assert msw_settings_updated.max_segment_length == 123.05
|
||||
assert msw_settings_updated.pressure_drop == "HFA"
|
||||
assert msw_settings_updated.reference_md_type == "UserDefined"
|
||||
assert msw_settings_updated.roughness_factor == 1.3
|
||||
assert msw_settings_updated.user_defined_reference_md == 1234.56
|
||||
segment_collection_updated = well_path.segment_collection()
|
||||
assert segment_collection_updated.custom_values_for_lateral
|
||||
assert segment_collection_updated.enforce_max_segment_length
|
||||
assert segment_collection_updated.liner_diameter == 20.0
|
||||
assert segment_collection_updated.max_segment_length == 123.05
|
||||
assert segment_collection_updated.pressure_drop == "HFA"
|
||||
assert segment_collection_updated.reference_md_type == "UserDefined"
|
||||
assert segment_collection_updated.roughness_factor == 1.3
|
||||
assert segment_collection_updated.user_defined_reference_md == 1234.56
|
||||
|
||||
|
||||
def test_add_well_path_fracture_template(rips_instance, initialize_test):
|
||||
|
||||
+5
-4
@@ -143,23 +143,24 @@ QString RimcClassName_method::classKeywordReturnedType() const
|
||||
}
|
||||
```
|
||||
|
||||
### Example: DiameterRoughnessInterval
|
||||
### Example: SegmentInterval
|
||||
|
||||
**Before (not scriptable):**
|
||||
```cpp
|
||||
CAF_PDM_InitObject("Diameter Roughness Interval", ":/Icon.png");
|
||||
CAF_PDM_InitObject("Segment Interval", ":/Icon.png");
|
||||
CAF_PDM_InitField(&m_startMD, "StartMD", 0.0, "Start MD");
|
||||
```
|
||||
|
||||
**After (scriptable):**
|
||||
```cpp
|
||||
CAF_PDM_InitScriptableObject("Diameter Roughness Interval", ":/Icon.png", "", "DiameterRoughnessInterval");
|
||||
CAF_PDM_InitScriptableObject("Segment Interval", ":/Icon.png", "", "SegmentInterval");
|
||||
CAF_PDM_InitScriptableField(&m_startMD, "StartMd", 0.0, "Start MD");
|
||||
```
|
||||
|
||||
This enables the class to be used from Python:
|
||||
```python
|
||||
interval = completions_settings.add_diameter_roughness_interval(start_md=100, end_md=200)
|
||||
segments = well_path.segment_collection()
|
||||
interval = segments.add_segment_interval(start_md=100, end_md=200)
|
||||
print(f"Start: {interval.start_md}, End: {interval.end_md}")
|
||||
```
|
||||
|
||||
|
||||
@@ -166,14 +166,14 @@ Event lines are `@<date_expr> <EVENT_TYPE> KEY=VALUE ...`. Inside a WELL block,
|
||||
| `COMPLETION_NUMBER` | no | `completion_number` (COMPLUMP grouping) |
|
||||
| `FILTER` | no | case-level combined data filter attached to the perforation: a declared `FILTER` variable (`FILTER=POROPERM`) or an inline quoted expression (`FILTER="PORO > 0.4"`) — see [Filter expressions](#filter-expressions) |
|
||||
|
||||
**SEGMENT** → `add_tubing_event` and `add_custom_segment_interval`
|
||||
**SEGMENT** → `add_tubing_event` and `add_segment_interval`
|
||||
|
||||
Each event adds the underlying tubing timeline event and a corresponding **Custom Segment Interval** with the same measured-depth range.
|
||||
Each event adds the underlying tubing timeline event and a corresponding **Segment Interval** with the same measured-depth range, diameter, and roughness.
|
||||
|
||||
| Attribute | Required | Maps to |
|
||||
|---|---|---|
|
||||
| `MDSTART` | yes | tubing `start_md` and custom interval `start_md` |
|
||||
| `MDEND` | yes | tubing `end_md` and custom interval `end_md` |
|
||||
| `MDSTART` | yes | tubing and segment interval `start_md` |
|
||||
| `MDEND` | yes | tubing and segment interval `end_md` |
|
||||
| `INNER_DIAMETER` | no | tubing `inner_diameter` [m] |
|
||||
| `ROUGHNESS` | no | tubing `roughness` [m] |
|
||||
| `PRESSURE_COMPONENTS` | no | MSW `pressure_drop`: `H--`, `HF-` or `HFA` |
|
||||
|
||||
Reference in new issue
Block a user