Files
ResInsight/ApplicationLibCode/ProjectDataModelCommands/RimcWellPathCompletionSettings.cpp
T
Kristian Bendiksen a71fb9ad19 #13398 Python: Add API for custom well path segments
Add Python GRPC interface support for creating and managing custom segment
intervals for multi-segment wells. This provides API parity with the existing
GUI functionality.

Changes:
- Add createInterval() method to RimCustomSegmentIntervalCollection
- Add GRPC method addCustomSegmentInterval to RimcWellPathCompletionSettings
- Add validation to prevent creating intervals with start_md >= end_md
- Add Python test test_custom_segment_intervals.py with validation test
- Add usage example to modeled_well_path.py

Follows the pattern established by diameter roughness intervals.

Fixes #13398.
2026-01-13 10:44:55 +01:00

159 lines
6.7 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimcWellPathCompletionSettings.h"
#include "RimCustomSegmentInterval.h"
#include "RimCustomSegmentIntervalCollection.h"
#include "RimDiameterRoughnessInterval.h"
#include "RimDiameterRoughnessIntervalCollection.h"
#include "RimMswCompletionParameters.h"
#include "RimWellPathCompletionSettings.h"
#include "cafPdmFieldScriptingCapability.h"
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPathCompletionSettings,
RimcWellPathCompletionSettings_addDiameterRoughnessInterval,
"AddDiameterRoughnessInterval" );
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPathCompletionSettings,
RimcWellPathCompletionSettings_addCustomSegmentInterval,
"AddCustomSegmentInterval" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimcWellPathCompletionSettings_addDiameterRoughnessInterval::RimcWellPathCompletionSettings_addDiameterRoughnessInterval( caf::PdmObjectHandle* self )
: caf::PdmObjectCreationMethod( self )
{
CAF_PDM_InitObject( "Add Diameter Roughness 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()
{
auto completionSettings = self<RimWellPathCompletionSettings>();
if ( !completionSettings )
{
return std::unexpected( QString( "Completion settings is null. Cannot add diameter roughness interval." ) );
}
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimcWellPathCompletionSettings_addDiameterRoughnessInterval::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();
}