#12674: Assign well path unit system from loaded cases

Move unit system assignment for new well paths into RimWellPathCollection::assignUnitSystem, used by addWellPath and onChildAdded so Python-created well paths get the case unit system. Ignore unloaded and unknown-unit cases in RimProject::commonUnitSystemForAllCases.

Pasted and multiple-lateral well paths are copies that already carry unit specific settings, so skip unit assignment for them. Note: RimProject::commonUnitSystemForAllCases now ignores unloaded and unknown-unit cases and returns UNKNOWN only for mixed units, which affects its other callers.
This commit is contained in:
Magne Sjaastad authored and GitHub committed 2026-10-23 12:01:59 +02:00
1 parent 915e951a64
commit 7dfa813c06
8 files changed
+60 -20

No files matched your search

@@ -110,7 +110,6 @@ void RicCreateWellPathFromSimulationWellFeature::onActionTriggered( bool isCheck
auto newModeledWellPath = new RimModeledWellPath();
newModeledWellPath->geometryDefinition()->createAndInsertTargets( filteredWellPathPoints );
newModeledWellPath->createWellPathGeometry();
newModeledWellPath->setUnitSystem( project->commonUnitSystemForAllCases() );
newModeledWellPath->setWellPathColor(
RiaColorTables::editableWellPathsPaletteColors().cycledColor3f( modelledWellpathCount + numAddedWells ) );
@@ -149,7 +149,7 @@ void RicCreateMultipleWellPathLaterals::slotAppendFractures()
newModeledWellPath->wellPathTieIn()->setTieInMeasuredDepth( measuredDepth );
wellPathCollection->addWellPath( newModeledWellPath );
wellPathCollection->addWellPath( newModeledWellPath, false );
newModeledWellPath->resolveReferencesRecursively();
newModeledWellPath->updateReferencePoint();
@@ -78,8 +78,6 @@ void RicNewEditableWellPathFeature::onActionTriggered( bool isChecked )
auto newModeledWellPath = new RimModeledWellPath();
newWellPaths.push_back( newModeledWellPath );
newModeledWellPath->setUnitSystem( project->commonUnitSystemForAllCases() );
RimFileWellPath* sourceWellPath = caf::SelectionManager::instance()->selectedItemOfType<RimFileWellPath>();
bool enableTargetPointPicking = !copyWellPathGeometry( sourceWellPath, newModeledWellPath );
@@ -111,7 +111,6 @@ RimModeledWellPath* RicNewWellPathLateralAtDepthFeature::createLateralAtMeasured
newModeledWellPath->connectWellPaths( parentWellPath, parentWellMD );
newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true );
newModeledWellPath->setUnitSystem( parentWellPath->unitSystem() );
newModeledWellPath->createWellPathGeometry();
@@ -148,7 +148,7 @@ RimModeledWellPath* RicPasteModeledWellPathFeature::duplicateAndInitializeWellPa
QString name = sourceWellPath->name() + "(copy)";
destinationWellPath->setName( name );
wpc->addWellPath( destinationWellPath );
wpc->addWellPath( destinationWellPath, false );
// Resolve references, will connect to the fracture template
destinationWellPath->resolveReferencesRecursively();
@@ -1338,22 +1338,27 @@ std::vector<RimValveTemplate*> RimProject::allValveTemplates() const
//--------------------------------------------------------------------------------------------------
caf::AppEnum<RiaDefines::EclipseUnitSystem> RimProject::commonUnitSystemForAllCases() const
{
RiaDefines::EclipseUnitSystem commonUnitSystem = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
using Unit = RiaDefines::EclipseUnitSystem;
Unit commonUnitSystem = Unit::UNITS_UNKNOWN;
for ( const auto& c : allGridCases() )
{
// Cases that are not loaded, or have no unit information, do not take part in the comparison
auto eclipseCase = dynamic_cast<RimEclipseCase*>( c );
if ( eclipseCase && eclipseCase->eclipseCaseData() )
if ( !eclipseCase || !eclipseCase->eclipseCaseData() ) continue;
const Unit caseUnit = eclipseCase->eclipseCaseData()->unitsType();
if ( caseUnit == Unit::UNITS_UNKNOWN ) continue;
if ( commonUnitSystem == Unit::UNITS_UNKNOWN )
{
if ( commonUnitSystem == RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN )
{
commonUnitSystem = eclipseCase->eclipseCaseData()->unitsType();
}
else if ( commonUnitSystem != eclipseCase->eclipseCaseData()->unitsType() )
{
commonUnitSystem = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
break;
}
commonUnitSystem = caseUnit;
}
else if ( commonUnitSystem != caseUnit )
{
// Mixed unit systems: there is no common unit system
return Unit::UNITS_UNKNOWN;
}
}
@@ -387,13 +387,45 @@ std::expected<std::vector<RimFileWellPath*>, QString> RimWellPathCollection::add
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::addWellPath( RimWellPath* wellPath )
void RimWellPathCollection::addWellPath( RimWellPath* wellPath, bool assignUnit )
{
if ( assignUnit ) assignUnitSystem( wellPath );
m_wellPaths.push_back( wellPath );
rebuildWellPathNodes();
}
//--------------------------------------------------------------------------------------------------
/// Single place where the unit system of a new well path is decided
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::assignUnitSystem( RimWellPath* wellPath )
{
if ( !wellPath ) return;
using Unit = RiaDefines::EclipseUnitSystem;
if ( dynamic_cast<RimFileWellPath*>( wellPath ) )
{
// Files have no unit information, so use the case the well path overlaps. This is unknown if there is no overlap.
wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) );
return;
}
Unit unitSystem = Unit::UNITS_UNKNOWN;
if ( wellPath->wellPathTieIn() && wellPath->wellPathTieIn()->parentWell() )
{
// Laterals use the same unit system as their parent
unitSystem = wellPath->wellPathTieIn()->parentWell()->unitSystem();
}
else if ( auto* project = firstAncestorOrThisOfType<RimProject>() )
{
unitSystem = project->commonUnitSystemForAllCases();
}
// Keep the current unit system if it can not be determined
if ( unitSystem != Unit::UNITS_UNKNOWN ) wellPath->setUnitSystem( unitSystem );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -440,7 +472,6 @@ std::vector<RimWellPath*> RimWellPathCollection::readAndAddWellPaths( std::vecto
progress.setProgressDescription( QString( "Reading file %1" ).arg( wellPath->name() ) );
wellPath->setWellPathColor( RiaColorTables::wellPathsPaletteColors().cycledColor3f( m_wellPaths.size() ) );
wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) );
addWellPath( wellPath );
addedWellPaths.push_back( wellPath );
@@ -1309,6 +1340,12 @@ void RimWellPathCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* child
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::onChildAdded( caf::PdmFieldHandle* containerForNewObject )
{
// Well paths created from Python are added directly to the child field
if ( containerForNewObject == &m_wellPaths && !m_wellPaths.empty() )
{
assignUnitSystem( m_wellPaths[m_wellPaths.size() - 1] );
}
rebuildWellPathNodes();
scheduleRedrawAffectedViews();
@@ -129,7 +129,8 @@ public:
RimWellPath* wellPathByName( const QString& wellPathName ) const;
RimWellPath* tryFindMatchingWellPath( const QString& wellName ) const;
void addWellPaths( const std::vector<RimWellPath*> incomingWellPaths );
void addWellPath( RimWellPath* wellPath );
// Set assignUnit to false for copies of existing well paths, as they already carry unit specific settings
void addWellPath( RimWellPath* wellPath, bool assignUnit = true );
std::vector<RimWellLogLasFile*> addWellLogs( const QStringList& filePaths, QStringList* errorMessages );
void addWellPathFormations( const QStringList& filePaths );
@@ -174,6 +175,7 @@ private:
std::expected<std::vector<RimFileWellPath*>, QString> addWellPathsForFile( const QString& filePath );
caf::AppEnum<RiaDefines::EclipseUnitSystem> findUnitSystemForWellPath( const RimWellPath* wellPath );
void assignUnitSystem( RimWellPath* wellPath );
std::vector<RimWellPath*> wellPathsWithNoParent( const std::vector<RimWellPath*>& sourceWellPaths ) const;
std::map<QString, std::vector<RimWellPath*>> wellPathsForWellNameStem( const std::vector<RimWellPath*>& sourceWellPaths ) const;