Major rewrite of MSW export model

This commit is contained in:
Magne Sjaastad
2021-04-13 07:22:56 +02:00
parent 9ecfefe094
commit 63690d5196
65 changed files with 2766 additions and 2225 deletions

View File

@@ -152,6 +152,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionWeight.h
${CMAKE_CURRENT_LIST_DIR}/RimEquilibriumAxisAnnotation.h
${CMAKE_CURRENT_LIST_DIR}/RimTimeAxisAnnotation.h
${CMAKE_CURRENT_LIST_DIR}/RimPolylinesDataInterface.h
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTieIn.h
)
@@ -304,6 +305,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunction.cpp
${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionWeight.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEquilibriumAxisAnnotation.cpp
${CMAKE_CURRENT_LIST_DIR}/RimTimeAxisAnnotation.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTieIn.cpp
)
if(Qt5Charts_FOUND)

View File

@@ -42,8 +42,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCompletionCellIntersectionCalc.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFishbonesCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFishbones.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFishbonesPipeProperties.cpp
${CMAKE_CURRENT_LIST_DIR}/RimImportedFishboneLaterals.cpp
${CMAKE_CURRENT_LIST_DIR}/RimImportedFishboneLateralsCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPerforationCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPerforationInterval.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions.cpp

View File

@@ -24,6 +24,7 @@
#include "RigFishbonesGeometry.h"
#include "RigWellPath.h"
#include "RimFishbonesCollection.h"
#include "RimFishbonesPipeProperties.h"
#include "RimMultipleValveLocations.h"
#include "RimProject.h"
#include "RimWellPath.h"
@@ -185,7 +186,7 @@ QString RimFishbones::generatedName() const
dynamic_cast<caf::PdmChildArrayField<RimFishbones*>*>( this->parentField() );
CVF_ASSERT( container );
size_t index = container->index( this );
size_t index = container->index( this ) + 1;
return QString( "Fishbone %1" ).arg( index );
}
@@ -278,7 +279,17 @@ double RimFishbones::tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFishbones::effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
double RimFishbones::holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
{
return m_pipeProperties()->holeDiameter( unitSystem );
}
//--------------------------------------------------------------------------------------------------
/// Compute the equivalent diameter based on the area between two cylinders
//
// http://www.fekete.com/san/webhelp/feketeharmony/harmony_webhelp/content/html_files/reference_material/calculations_and_correlations/annular_diameters.htm
//--------------------------------------------------------------------------------------------------
double RimFishbones::equivalentDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
{
double innerRadius = tubingDiameter( unitSystem ) / 2;
double outerRadius = holeDiameter( unitSystem ) / 2;
@@ -286,12 +297,20 @@ double RimFishbones::effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem
double innerArea = cvf::PI_D * innerRadius * innerRadius;
double outerArea = cvf::PI_D * outerRadius * outerRadius;
double effectiveArea = outerArea - innerArea;
double equivalentArea = outerArea - innerArea;
double effectiveRadius = cvf::Math::sqrt( effectiveArea / cvf::PI_D );
double effectiveRadius = cvf::Math::sqrt( equivalentArea / cvf::PI_D );
return effectiveRadius * 2;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFishbones::skinFactor() const
{
return m_pipeProperties()->skinFactor();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -382,6 +401,14 @@ void RimFishbones::geometryUpdated()
proj->reloadCompletionTypeResultsInAllViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RimFishbones::SubAndLateralIndex>& RimFishbones::installedLateralIndices() const
{
return m_subLateralIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -613,13 +640,13 @@ void RimFishbones::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& u
}
{
caf::PdmUiGroup* wellGroup = uiOrdering.addNewGroup( "Well Properties" );
caf::PdmUiGroup* wellGroup = uiOrdering.addNewGroup( "Lateral Properties" );
m_pipeProperties->uiOrdering( uiConfigName, *wellGroup );
}
{
caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Multi Segment Wells" );
caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup( "Lateral Multi Segment Wells" );
mswGroup->setCollapsedByDefault( true );
mswGroup->add( &m_lateralTubingDiameter );
mswGroup->add( &m_lateralOpenHoleRoghnessFactor );

View File

@@ -22,7 +22,6 @@
#include "Rim3dPropertiesInterface.h"
#include "RimCheckableNamedObject.h"
#include "RimFishbonesPipeProperties.h"
#include "RimWellPathComponentInterface.h"
#include "cvfColor3.h"
@@ -37,6 +36,7 @@
#include <memory>
class RigFisbonesGeometry;
class RimFishbonesPipeProperties;
class RimMultipleValveLocations;
//==================================================================================================
@@ -79,13 +79,10 @@ public:
double exitAngle() const;
double buildAngle() const;
double tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
{
return m_pipeProperties()->holeDiameter( unitSystem );
}
double effectiveDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
double skinFactor() const { return m_pipeProperties()->skinFactor(); }
double tubingDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
double equivalentDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
double skinFactor() const;
double openHoleRoughnessFactor( RiaDefines::EclipseUnitSystem unitSystem ) const;
double icdOrificeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const;
double icdFlowCoefficient() const;
@@ -94,7 +91,7 @@ public:
void geometryUpdated();
const std::vector<SubAndLateralIndex>& installedLateralIndices() const { return m_subLateralIndices; };
const std::vector<SubAndLateralIndex>& installedLateralIndices() const;
std::vector<cvf::Vec3d> coordsForLateral( size_t subIndex, size_t lateralIndex ) const;
std::vector<std::pair<cvf::Vec3d, double>> coordsAndMDForLateral( size_t subIndex, size_t lateralIndex ) const;
void recomputeLateralLocations();

View File

@@ -25,7 +25,6 @@
#include "RigWellPath.h"
#include "RimFishbones.h"
#include "RimImportedFishboneLateralsCollection.h"
#include "RimProject.h"
#include "RimWellPath.h"
@@ -50,10 +49,6 @@ RimFishbonesCollection::RimFishbonesCollection()
m_fishbones.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_wellPathCollection, "WellPathCollection", "Imported Laterals", "", "", "" );
m_wellPathCollection = new RimImportedFishboneLateralsCollection;
m_wellPathCollection.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_startMD, "StartMD", HUGE_VAL, "Start MD", "", "", "" );
CAF_PDM_InitField( &m_mainBoreDiameter, "MainBoreDiameter", 0.216, "Main Bore Diameter", "", "", "" );
CAF_PDM_InitField( &m_skinFactor, "MainBoreSkinFactor", 0., "Main Bore Skin Factor [0..1]", "", "", "" );
@@ -74,16 +69,6 @@ RimFishbonesCollection::RimFishbonesCollection()
m_lengthAndDepth_OBSOLETE.xmlCapability()->setIOWritable( false );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimImportedFishboneLateralsCollection* RimFishbonesCollection::wellPathCollection() const
{
CVF_ASSERT( m_wellPathCollection );
return m_wellPathCollection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -268,14 +253,6 @@ void RimFishbonesCollection::recalculateStartMD()
}
}
for ( const RimImportedFishboneLaterals* wellPath : m_wellPathCollection->wellPaths() )
{
if ( wellPath->measuredDepths().size() > 0 )
{
minStartMD = std::min( minStartMD, wellPath->measuredDepths()[0] - 13.0 );
}
}
if ( !manuallyModifiedStartMD || minStartMD < m_startMD() )
{
m_startMD = minStartMD;
@@ -342,7 +319,5 @@ void RimFishbonesCollection::setUnitSystemSpecificDefaults()
{
m_mainBoreDiameter = 0.708;
}
m_wellPathCollection->setUnitSystemSpecificDefaults();
}
}

View File

@@ -30,7 +30,6 @@
#include "cvfColor3.h"
class RimFishbones;
class RimImportedFishboneLateralsCollection;
//==================================================================================================
//
@@ -44,9 +43,8 @@ class RimFishbonesCollection : public RimCheckableNamedObject
public:
RimFishbonesCollection();
RimImportedFishboneLateralsCollection* wellPathCollection() const;
void appendFishbonesSubs( RimFishbones* subs );
const RimMswCompletionParameters* mswParameters() const;
void appendFishbonesSubs( RimFishbones* subs );
const RimMswCompletionParameters* mswParameters() const;
bool hasFishbones() const;
std::vector<RimFishbones*> activeFishbonesSubs() const;
@@ -68,9 +66,8 @@ private:
cvf::Color3f nextFishbonesColor() const;
private:
caf::PdmChildArrayField<RimFishbones*> m_fishbones;
caf::PdmChildField<RimImportedFishboneLateralsCollection*> m_wellPathCollection;
caf::PdmChildField<RimMswCompletionParameters*> m_mswParameters;
caf::PdmChildArrayField<RimFishbones*> m_fishbones;
caf::PdmChildField<RimMswCompletionParameters*> m_mswParameters;
caf::PdmField<double> m_startMD;
caf::PdmField<double> m_skinFactor;

View File

@@ -1,117 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
//
// 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 "RimImportedFishboneLaterals.h"
#include "RimProject.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiTextEditor.h"
CAF_PDM_SOURCE_INIT( RimImportedFishboneLaterals, "WellPathCompletion" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimImportedFishboneLaterals::RimImportedFishboneLaterals()
{
CAF_PDM_InitObject( "WellPathCompletion", ":/FishBoneLateralFromFile16x16.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_coordinates, "Coordinates", "Coordinates", "", "", "" );
m_coordinates.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_measuredDepths, "MeasuredDepth", "MeasuredDepth", "", "", "" );
m_measuredDepths.uiCapability()->setUiHidden( true );
userDescriptionField()->uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_displayCoordinates, "DisplayCoordinates", "Coordinates", "", "", "" );
m_displayCoordinates.registerGetMethod( this, &RimImportedFishboneLaterals::displayCoordinates );
m_displayCoordinates.uiCapability()->setUiReadOnly( true );
m_displayCoordinates.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
m_displayCoordinates.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosType::TOP );
setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimImportedFishboneLaterals::~RimImportedFishboneLaterals()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLaterals::setCoordinates( std::vector<cvf::Vec3d> coordinates )
{
m_coordinates = coordinates;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLaterals::setMeasuredDepths( std::vector<double> measuredDepths )
{
m_measuredDepths = measuredDepths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLaterals::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimProject* proj;
this->firstAncestorOrThisOfType( proj );
if ( proj ) proj->scheduleCreateDisplayModelAndRedrawAllViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLaterals::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_displayCoordinates );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimImportedFishboneLaterals::displayCoordinates() const
{
CVF_ASSERT( m_coordinates().size() == m_measuredDepths().size() );
QStringList displayValues;
displayValues.push_back( QString( "X\tY\tZ\tMD" ) );
for ( size_t i = 0; i < m_coordinates().size(); i++ )
{
const cvf::Vec3d& coords = m_coordinates()[i];
const double& measuredDepth = m_measuredDepths()[i];
displayValues.push_back( QString( "%1\t%2\t%3\t%4" )
.arg( coords.x(), 0, 'f', 2 )
.arg( coords.y(), 0, 'f', 2 )
.arg( coords.z(), 0, 'f', 2 )
.arg( measuredDepth, 0, 'f', 2 ) );
}
return displayValues.join( "\n" );
}

View File

@@ -1,66 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
//
// 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 "RimCheckableNamedObject.h"
#include "cafAppEnum.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
// Include to make Pdm work for cvf::Color
#include "cafPdmChildArrayField.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfVec3d.h"
#include "cafPdmProxyValueField.h"
#include "cvfObject.h"
#include "cvfVector3.h"
//==================================================================================================
///
///
//==================================================================================================
class RimImportedFishboneLaterals : public RimCheckableNamedObject
{
CAF_PDM_HEADER_INIT;
public:
RimImportedFishboneLaterals();
~RimImportedFishboneLaterals() override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void setCoordinates( std::vector<cvf::Vec3d> coordinates );
void setMeasuredDepths( std::vector<double> measuredDepths );
std::vector<cvf::Vec3d> coordinates() const { return m_coordinates(); }
std::vector<double> measuredDepths() const { return m_measuredDepths(); }
private:
QString displayCoordinates() const;
caf::PdmField<std::vector<cvf::Vec3d>> m_coordinates;
caf::PdmField<std::vector<double>> m_measuredDepths;
caf::PdmProxyValueField<QString> m_displayCoordinates;
};

View File

@@ -1,149 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimImportedFishboneLateralsCollection.h"
#include "Rim3dView.h"
#include "RimFishbonesCollection.h"
#include "RimImportedFishboneLaterals.h"
#include "RimProject.h"
#include "RigWellPath.h"
#include "RifWellPathImporter.h"
#include "Riu3DMainWindowTools.h"
// The more general term WellPathCompletionCollection was unfortunately used in this more specific case of fishbones
// In order to preserve compatibility, the old keyword is kept as an alias, but could be removed in the future.
CAF_PDM_SOURCE_INIT( RimImportedFishboneLateralsCollection, "FishboneWellPathCollection", "WellPathCompletionCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimImportedFishboneLateralsCollection::RimImportedFishboneLateralsCollection()
{
CAF_PDM_InitObject( "WellPathCompletions", ":/FishBoneGroupFromFile16x16.png", "", "" );
nameField()->uiCapability()->setUiHidden( true );
this->setName( "Imported Laterals" );
CAF_PDM_InitFieldNoDefault( &m_wellPaths, "WellPaths", "Imported Laterals", "", "", "" );
m_wellPaths.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_pipeProperties, "PipeProperties", "Pipe Properties", "", "", "" );
m_pipeProperties.uiCapability()->setUiHidden( true );
m_pipeProperties.uiCapability()->setUiTreeHidden( true );
m_pipeProperties.uiCapability()->setUiTreeChildrenHidden( true );
m_pipeProperties = new RimFishbonesPipeProperties;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLateralsCollection::importCompletionsFromFile( const QStringList& filePaths )
{
RifWellPathImporter wellPathImporter;
for ( const QString& filePath : filePaths )
{
size_t wellDataCount = wellPathImporter.wellDataCount( filePath );
for ( size_t i = 0; i < wellDataCount; ++i )
{
RifWellPathImporter::WellData wellData = wellPathImporter.readWellData( filePath, i );
RimImportedFishboneLaterals* wellCompletion = new RimImportedFishboneLaterals();
wellCompletion->setName( wellData.m_name );
wellCompletion->setCoordinates( wellData.m_wellPathGeometry->uniqueWellPathPoints() );
wellCompletion->setMeasuredDepths( wellData.m_wellPathGeometry->uniqueMeasuredDepths() );
appendCompletion( wellCompletion );
}
}
RimFishbonesCollection* fishbonesCollection;
firstAncestorOrThisOfType( fishbonesCollection );
if ( fishbonesCollection != nullptr )
{
fishbonesCollection->recalculateStartMD();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLateralsCollection::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimProject* proj;
this->firstAncestorOrThisOfTypeAsserted( proj );
proj->scheduleCreateDisplayModelAndRedrawAllViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<const RimImportedFishboneLaterals*> RimImportedFishboneLateralsCollection::wellPaths() const
{
std::vector<const RimImportedFishboneLaterals*> paths;
for ( const RimImportedFishboneLaterals* path : m_wellPaths )
{
paths.push_back( path );
}
return paths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLateralsCollection::setUnitSystemSpecificDefaults()
{
m_pipeProperties->setUnitSystemSpecificDefaults();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLateralsCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
caf::PdmUiGroup* wellPropertiesGroup = uiOrdering.addNewGroup( "Well Properties" );
m_pipeProperties->uiOrdering( uiConfigName, *wellPropertiesGroup );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimImportedFishboneLateralsCollection::appendCompletion( RimImportedFishboneLaterals* completion )
{
m_wellPaths.push_back( completion );
updateConnectedEditors();
Riu3DMainWindowTools::selectAsCurrentItem( completion );
uiCapability()->setUiHidden( !m_wellPaths.empty() );
RimProject* project = nullptr;
firstAncestorOrThisOfTypeAsserted( project );
if ( project )
{
project->reloadCompletionTypeResultsInAllViews();
}
}

View File

@@ -1,67 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimCheckableNamedObject.h"
#include "RimFishbonesPipeProperties.h"
#include "RimImportedFishboneLaterals.h"
#include "RiaDefines.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
//==================================================================================================
//
//
//
//==================================================================================================
class RimImportedFishboneLateralsCollection : public RimCheckableNamedObject
{
CAF_PDM_HEADER_INIT;
public:
RimImportedFishboneLateralsCollection();
void importCompletionsFromFile( const QStringList& filePaths );
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
std::vector<const RimImportedFishboneLaterals*> wellPaths() const;
double holeDiameter( RiaDefines::EclipseUnitSystem unitSystem ) const
{
return m_pipeProperties->holeDiameter( unitSystem );
}
double skinFactor() const { return m_pipeProperties->skinFactor(); }
void setUnitSystemSpecificDefaults();
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
private:
void appendCompletion( RimImportedFishboneLaterals* completion );
private:
caf::PdmChildArrayField<RimImportedFishboneLaterals*> m_wellPaths;
caf::PdmChildField<RimFishbonesPipeProperties*> m_pipeProperties;
};

View File

@@ -49,7 +49,7 @@ void RimMswCompletionParameters::LengthAndDepthEnum::setUp()
{
addItem( RimMswCompletionParameters::INC, "INC", "Incremental" );
addItem( RimMswCompletionParameters::ABS, "ABS", "Absolute" );
setDefault( RimMswCompletionParameters::INC );
setDefault( RimMswCompletionParameters::ABS );
}
} // namespace caf

View File

@@ -309,13 +309,7 @@ void RimWellPathCompletionSettings::defineEditorAttribute( const caf::PdmFieldHa
caf::PdmUiEditorAttribute* attribute )
{
caf::PdmUiLineEditorAttribute* lineEditorAttr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute );
if ( field == &m_wellNameForExport && lineEditorAttr )
{
QRegExpValidator* validator = new QRegExpValidator( nullptr );
validator->setRegExp( wellNameForExportRegExp() );
lineEditorAttr->validator = validator;
}
else if ( field == &m_drainageRadiusForPI && lineEditorAttr )
if ( field == &m_drainageRadiusForPI && lineEditorAttr )
{
caf::PdmDoubleStringValidator* validator = new caf::PdmDoubleStringValidator( "1*" );
lineEditorAttr->validator = validator;

View File

@@ -22,7 +22,6 @@
#include "RimFishbones.h"
#include "RimFishbonesCollection.h"
#include "RimImportedFishboneLateralsCollection.h"
#include "RimPerforationCollection.h"
#include "RimPerforationInterval.h"
#include "RimProject.h"
@@ -211,9 +210,7 @@ bool RimWellPathCompletions::hasCompletions() const
return true;
}
return !m_fishbonesCollection->allFishbonesSubs().empty() ||
!m_fishbonesCollection->wellPathCollection()->wellPaths().empty() ||
!m_perforationCollection->perforations().empty();
return !m_fishbonesCollection->allFishbonesSubs().empty() || !m_perforationCollection->perforations().empty();
}
//--------------------------------------------------------------------------------------------------
@@ -244,8 +241,7 @@ void RimWellPathCompletions::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTre
uiTreeOrdering.add( &m_perforationCollection );
}
if ( !m_fishbonesCollection->allFishbonesSubs().empty() ||
!m_fishbonesCollection->wellPathCollection()->wellPaths().empty() )
if ( !m_fishbonesCollection->allFishbonesSubs().empty() )
{
uiTreeOrdering.add( &m_fishbonesCollection );
}

View File

@@ -304,6 +304,14 @@ std::vector<std::pair<double, double>> RimWellPathValve::valveSegments() const
return segments;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathValve::setComponentTypeFilter( const std::set<RiaDefines::WellPathComponentType>& filter )
{
m_componentTypeFilter = filter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -456,6 +464,11 @@ QList<caf::PdmOptionItemInfo> RimWellPathValve::calculateValueOptions( const caf
std::vector<RimValveTemplate*> allTemplates = project->allValveTemplates();
for ( RimValveTemplate* valveTemplate : allTemplates )
{
if ( !m_componentTypeFilter.empty() )
{
if ( m_componentTypeFilter.count( valveTemplate->type() ) == 0 ) continue;
}
options.push_back( caf::PdmOptionItemInfo( valveTemplate->name(), valveTemplate ) );
}

View File

@@ -65,6 +65,8 @@ public:
std::vector<std::pair<double, double>> valveSegments() const;
void setComponentTypeFilter( const std::set<RiaDefines::WellPathComponentType>& filter );
// Overrides from RimWellPathCompletionInterface
bool isEnabled() const override;
RiaDefines::WellPathComponentType componentType() const override;
@@ -92,4 +94,6 @@ private:
caf::PdmChildField<RimMultipleValveLocations*> m_multipleValveLocations;
caf::PdmField<bool> m_editValveTemplate;
caf::PdmField<bool> m_createValveTemplate;
std::set<RiaDefines::WellPathComponentType> m_componentTypeFilter;
};

View File

@@ -88,7 +88,6 @@
#include "RimGridCrossPlotCollection.h"
#include "RimGridCrossPlotDataSet.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimImportedFishboneLateralsCollection.h"
#include "RimIntersectionCollection.h"
#include "RimIntersectionResultDefinition.h"
#include "RimIntersectionResultsDefinitionCollection.h"
@@ -336,7 +335,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder << "RicReloadWellPathFormationNamesFeature";
menuBuilder.addSeparator();
menuBuilder << "RicWellPathImportPerforationIntervalsFeature";
menuBuilder << "RicWellPathImportCompletionsFileFeature";
menuBuilder << "RicImportWellMeasurementsFeature";
menuBuilder.subMenuEnd();
menuBuilder.addSeparator();
@@ -392,10 +390,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder << "RicShowWellPlanFeature";
}
}
else if ( dynamic_cast<RimImportedFishboneLateralsCollection*>( firstUiItem ) )
{
appendImportMenu( menuBuilder );
}
else if ( dynamic_cast<RimWellPathCompletions*>( firstUiItem ) )
{
menuBuilder.subMenuStart( "Create Completions", QIcon( ":/CompletionsSymbol16x16.png" ) );
@@ -418,8 +412,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder.addSeparator();
appendExportCompletions( menuBuilder );
}
else if ( dynamic_cast<RimFishbonesCollection*>( firstUiItem ) || dynamic_cast<RimFishbones*>( firstUiItem ) ||
dynamic_cast<RimImportedFishboneLateralsCollection*>( firstUiItem ) )
else if ( dynamic_cast<RimFishbonesCollection*>( firstUiItem ) || dynamic_cast<RimFishbones*>( firstUiItem ) )
{
menuBuilder << "RicNewFishbonesSubsFeature";
appendExportCompletions( menuBuilder );
@@ -1335,8 +1328,6 @@ int RimContextCommandBuilder::appendImportMenu( caf::CmdFeatureMenuBuilder& menu
candidates << "RicWellPathFormationsImportFileFeature";
candidates << "RicWellLogsImportFileFeature";
candidates << "RicReloadWellPathFormationNamesFeature";
candidates << "Separator";
candidates << "RicWellPathImportCompletionsFileFeature";
return appendSubMenuWithCommands( menuBuilder, candidates, "Import", QIcon(), addSeparatorBeforeMenu );
}

View File

@@ -18,21 +18,24 @@
#include "RimModeledWellPath.h"
#include "RiaCompletionTypeCalculationScheduler.h"
#include "RicfCommandObject.h"
#include "RimProject.h"
#include "RimWellPathGeometryDef.h"
#include "RifTextDataTableFormatter.h"
#include "RigWellPath.h"
#include "RiaCompletionTypeCalculationScheduler.h"
#include "RifTextDataTableFormatter.h"
#include "RimExtrudedCurveIntersection.h"
#include "RimPlotCurve.h"
#include "RimProject.h"
#include "RimTools.h"
#include "RimWellPath.h"
#include "RimWellPathFracture.h"
#include "RimWellPathFractureCollection.h"
#include "RimWellPathGeometryDef.h"
#include "RimWellPathTarget.h"
#include "RimWellPathTieIn.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmUiDoubleValueEditor.h"
#include "cafPdmUiTreeOrdering.h"
CAF_PDM_SOURCE_INIT( RimModeledWellPath, "ModeledWellPath" );
@@ -191,6 +194,7 @@ void RimModeledWellPath::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrd
void RimModeledWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_name );
RimWellPath::defineUiOrdering( uiConfigName, uiOrdering );
}
@@ -198,10 +202,95 @@ void RimModeledWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
///
//--------------------------------------------------------------------------------------------------
void RimModeledWellPath::onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate )
{
updateGeometry( fullUpdate );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimModeledWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
// TODO remove if nothing happens here
RimWellPath::fieldChangedByUi( changedField, oldValue, newValue );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimModeledWellPath::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimModeledWellPath::updateGeometry( bool fullUpdate )
{
updateWellPathVisualization();
std::vector<RimWellPathTieIn*> tieInObjects;
objectsWithReferringPtrFieldsOfType( tieInObjects );
for ( auto tieIn : tieInObjects )
{
if ( tieIn->parentWell() == this )
{
tieIn->updateChildWellGeometry();
}
}
if ( fullUpdate )
{
scheduleUpdateOfDependentVisualization();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimModeledWellPath::updateTieInLocationFromParentWell()
{
RimWellPath* parentWellPath = nullptr;
RimWellPathTieIn* tieIn = wellPathTieIn();
if ( tieIn )
{
parentWellPath = tieIn->parentWell();
auto targets = m_geometryDefinition->activeWellTargets();
if ( parentWellPath && !targets.empty() )
{
auto [pointVector, measuredDepths] =
parentWellPath->wellPathGeometry()
->clippedPointSubset( parentWellPath->wellPathGeometry()->measuredDepths().front(),
tieIn->tieInMeasuredDepth() );
if ( pointVector.size() > 2u )
{
auto firstTarget = targets.front();
firstTarget->setPointXYZ( pointVector.back() );
m_geometryDefinition->setIsAttachedToParentWell( true );
m_geometryDefinition->setMdAtFirstTarget( measuredDepths.back() );
m_geometryDefinition->setFixedWellPathPoints( pointVector );
m_geometryDefinition->setFixedMeasuredDepths( measuredDepths );
updateGeometry( true );
}
}
}
if ( !parentWellPath )
{
m_geometryDefinition->setIsAttachedToParentWell( false );
m_geometryDefinition->setFixedWellPathPoints( {} );
m_geometryDefinition->setFixedMeasuredDepths( {} );
}
}

View File

@@ -20,6 +20,7 @@
#include "RimWellPath.h"
#include "cafPdmChildField.h"
#include "cafPdmPtrField.h"
class RimWellPathTarget;
class RimWellPath;
@@ -38,11 +39,20 @@ public:
void scheduleUpdateOfDependentVisualization();
RimWellPathGeometryDef* geometryDefinition() const;
QString wellPlanText();
void updateTieInLocationFromParentWell();
private:
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate );
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void updateGeometry( bool fullUpdate );
private:
caf::PdmChildField<RimWellPathGeometryDef*> m_geometryDefinition;
};

View File

@@ -234,19 +234,43 @@ QString RimTools::relocateFile( const QString& originalFileName,
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options )
void RimTools::wellPathOptionItemsSubset( const std::vector<RimWellPath*>& wellPathsToExclude,
QList<caf::PdmOptionItemInfo>* options )
{
CVF_ASSERT( options );
if ( !options ) return;
auto wellPathColl = RimTools::wellPathCollection();
if ( wellPathColl )
{
caf::IconProvider wellIcon( ":/Well.svg" );
for ( auto wellPath : wellPathColl->allWellPaths() )
std::vector<RimWellPath*> wellPathsToInclude;
auto all = wellPathColl->allWellPaths();
for ( auto w : all )
{
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
bool include = true;
for ( auto exclude : wellPathsToExclude )
{
if ( w == exclude ) include = false;
}
if ( include ) wellPathsToInclude.push_back( w );
}
optionItemsForSpecifiedWellPaths( wellPathsToInclude, options );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options )
{
if ( !options ) return;
auto wellPathColl = RimTools::wellPathCollection();
if ( wellPathColl )
{
optionItemsForSpecifiedWellPaths( wellPathColl->allWellPaths(), options );
}
}
@@ -255,17 +279,12 @@ void RimTools::wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options )
//--------------------------------------------------------------------------------------------------
void RimTools::wellPathWithFormationsOptionItems( QList<caf::PdmOptionItemInfo>* options )
{
CVF_ASSERT( options );
if ( !options ) return;
std::vector<RimWellPath*> wellPaths;
RimTools::wellPathWithFormations( &wellPaths );
caf::IconProvider wellIcon( ":/Well.svg" );
for ( auto wellPath : wellPaths )
{
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
}
optionItemsForSpecifiedWellPaths( wellPaths, options );
}
//--------------------------------------------------------------------------------------------------
@@ -291,7 +310,6 @@ void RimTools::wellPathWithFormations( std::vector<RimWellPath*>* wellPaths )
//--------------------------------------------------------------------------------------------------
void RimTools::caseOptionItems( QList<caf::PdmOptionItemInfo>* options )
{
CVF_ASSERT( options );
if ( !options ) return;
RimProject* proj = RimProject::current();
@@ -312,7 +330,6 @@ void RimTools::caseOptionItems( QList<caf::PdmOptionItemInfo>* options )
//--------------------------------------------------------------------------------------------------
void RimTools::eclipseCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
{
CVF_ASSERT( options );
if ( !options ) return;
RimProject* proj = RimProject::current();
@@ -337,7 +354,6 @@ void RimTools::eclipseCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
//--------------------------------------------------------------------------------------------------
void RimTools::geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
{
CVF_ASSERT( options );
if ( !options ) return;
RimProject* proj = RimProject::current();
@@ -362,7 +378,6 @@ void RimTools::geoMechCaseOptionItems( QList<caf::PdmOptionItemInfo>* options )
//--------------------------------------------------------------------------------------------------
void RimTools::colorLegendOptionItems( QList<caf::PdmOptionItemInfo>* options )
{
CVF_ASSERT( options );
if ( !options ) return;
RimProject* project = RimProject::current();
@@ -407,3 +422,18 @@ void RimTools::timeStepsForCase( RimCase* gridCase, QList<caf::PdmOptionItemInfo
options->push_back( caf::PdmOptionItemInfo( timeStepNames[i], i ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::optionItemsForSpecifiedWellPaths( const std::vector<RimWellPath*>& wellPaths,
QList<caf::PdmOptionItemInfo>* options )
{
if ( !options ) return;
caf::IconProvider wellIcon( ":/Well.svg" );
for ( auto wellPath : wellPaths )
{
options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) );
}
}

View File

@@ -51,6 +51,8 @@ public:
bool* foundFile,
std::vector<QString>* searchedPaths );
static void wellPathOptionItemsSubset( const std::vector<RimWellPath*>& wellPathsToExclude,
QList<caf::PdmOptionItemInfo>* options );
static void wellPathOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void wellPathWithFormationsOptionItems( QList<caf::PdmOptionItemInfo>* options );
static void wellPathWithFormations( std::vector<RimWellPath*>* wellPaths );
@@ -61,4 +63,8 @@ public:
static RimWellPathCollection* wellPathCollection();
static void timeStepsForCase( RimCase* gridCase, QList<caf::PdmOptionItemInfo>* options );
private:
static void optionItemsForSpecifiedWellPaths( const std::vector<RimWellPath*>& wellPaths,
QList<caf::PdmOptionItemInfo>* options );
};

View File

@@ -50,6 +50,7 @@
#include "RimWellPathCompletions.h"
#include "RimWellPathFracture.h"
#include "RimWellPathFractureCollection.h"
#include "RimWellPathTieIn.h"
#include "RiuMainWindow.h"
@@ -131,6 +132,8 @@ RimWellPath::RimWellPath()
m_wellPathAttributes = new RimWellPathAttributeCollection;
m_wellPathAttributes->uiCapability()->setUiTreeHidden( true );
CAF_PDM_InitFieldNoDefault( &m_wellPathTieIn, "WellPathTieIn", "well Path Tie-In", "", "", "" );
this->setDeletable( true );
}
@@ -285,7 +288,9 @@ const RimWellPathCompletions* RimWellPath::completions() const
//--------------------------------------------------------------------------------------------------
const RimWellPathCompletionSettings* RimWellPath::completionSettings() const
{
return m_completionSettings();
if ( isTopLevelWellPath() ) return m_completionSettings();
return topLevelWellPath()->completionSettings();
}
//--------------------------------------------------------------------------------------------------
@@ -293,7 +298,9 @@ const RimWellPathCompletionSettings* RimWellPath::completionSettings() const
//--------------------------------------------------------------------------------------------------
RimWellPathCompletionSettings* RimWellPath::completionSettings()
{
return m_completionSettings();
if ( isTopLevelWellPath() ) return m_completionSettings();
return topLevelWellPath()->completionSettings();
}
//--------------------------------------------------------------------------------------------------
@@ -612,6 +619,11 @@ void RimWellPath::setWellPathGeometry( RigWellPath* wellPathModel )
//--------------------------------------------------------------------------------------------------
void RimWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
if ( m_wellPathTieIn() )
{
m_wellPathTieIn->uiOrdering( uiConfigName, uiOrdering );
}
if ( m_simWellName().isEmpty() )
{
// Try to set default simulation well name
@@ -961,12 +973,18 @@ std::vector<const RimWellPathComponentInterface*> RimWellPath::allCompletionsRec
{
std::vector<const RimWellPathComponentInterface*> allCompletions;
std::vector<const RimWellPathCompletions*> completionCollections;
this->descendantsOfType( completionCollections );
for ( auto collection : completionCollections )
auto tieInWells = wellPathLateralsRecursively();
tieInWells.push_back( const_cast<RimWellPath*>( this ) );
for ( auto w : tieInWells )
{
std::vector<const RimWellPathComponentInterface*> completions = collection->allCompletions();
allCompletions.insert( allCompletions.end(), completions.begin(), completions.end() );
std::vector<const RimWellPathCompletions*> completionCollections;
w->descendantsOfType( completionCollections );
for ( auto collection : completionCollections )
{
std::vector<const RimWellPathComponentInterface*> completions = collection->allCompletions();
allCompletions.insert( allCompletions.end(), completions.begin(), completions.end() );
}
}
return allCompletions;
@@ -1048,12 +1066,27 @@ bool RimWellPath::isMultiLateralWellPath() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPath::topLevelWellPath() const
RimWellPath* RimWellPath::topLevelWellPath()
{
std::vector<RimWellPath*> wellPathHierarchy;
this->allAncestorsOrThisOfType( wellPathHierarchy );
RimWellPath* wellPath = wellPathHierarchy.back();
return wellPath;
if ( m_wellPathTieIn() && m_wellPathTieIn->parentWell() )
{
return m_wellPathTieIn()->parentWell()->topLevelWellPath();
}
return this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimWellPath* RimWellPath::topLevelWellPath() const
{
if ( m_wellPathTieIn() && m_wellPathTieIn->parentWell() )
{
return m_wellPathTieIn()->parentWell()->topLevelWellPath();
}
return this;
}
//--------------------------------------------------------------------------------------------------
@@ -1062,3 +1095,46 @@ RimWellPath* RimWellPath::topLevelWellPath() const
void RimWellPath::updateAfterAddingToWellPathGroup()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellPath*> RimWellPath::wellPathLateralsRecursively() const
{
std::vector<RimWellPath*> tieInWells;
auto wellPathColl = RimTools::wellPathCollection();
if ( wellPathColl )
{
wellPathColl->allWellPaths();
for ( auto w : wellPathColl->allWellPaths() )
{
if ( w->topLevelWellPath() == this )
{
tieInWells.push_back( w );
}
}
}
return tieInWells;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathTieIn* RimWellPath::wellPathTieIn() const
{
return m_wellPathTieIn();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPath::connectWellPaths( RimWellPath* parentWell, double parentTieInMeasuredDepth )
{
if ( !m_wellPathTieIn() ) m_wellPathTieIn = new RimWellPathTieIn;
m_wellPathTieIn->connectWellPaths( parentWell, this, parentTieInMeasuredDepth );
m_wellPathTieIn->updateFirstTargetFromParentWell();
}

View File

@@ -54,10 +54,10 @@ class RimPerforationCollection;
class RimWellPathAttributeCollection;
class RimWellPathCompletions;
class RimWellPathCompletionSettings;
class RimWellPathFractureCollection;
class Rim3dWellLogCurve;
class Rim3dWellLogCurveCollection;
class RimWellPathTieIn;
//==================================================================================================
///
@@ -154,10 +154,15 @@ public:
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
bool isTopLevelWellPath() const;
bool isMultiLateralWellPath() const;
RimWellPath* topLevelWellPath() const;
void updateAfterAddingToWellPathGroup();
bool isTopLevelWellPath() const;
bool isMultiLateralWellPath() const;
RimWellPath* topLevelWellPath();
const RimWellPath* topLevelWellPath() const;
void updateAfterAddingToWellPathGroup();
std::vector<RimWellPath*> wellPathLateralsRecursively() const;
RimWellPathTieIn* wellPathTieIn() const;
void connectWellPaths( RimWellPath* childWell, double tieInMeasuredDepth );
protected:
// Override PdmObject
@@ -201,6 +206,8 @@ private:
caf::PdmChildField<RimWellPathCompletions*> m_completions;
caf::PdmChildField<RimWellPathAttributeCollection*> m_wellPathAttributes;
caf::PdmChildField<RimWellPathTieIn*> m_wellPathTieIn;
private:
static size_t simulationWellBranchCount( const QString& simWellName );

View File

@@ -74,7 +74,10 @@ RimWellPathGeometryDef::RimWellPathGeometryDef()
CAF_PDM_InitScriptableField( &m_airGap, "AirGap", 0.0, "Air Gap", "", "", "" );
m_airGap.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitScriptableField( &m_mdAtFirstTarget, "MdAtFirstTarget", 0.0, "MD at First Target", "", "", "" );
m_mdAtFirstTarget.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitScriptableFieldNoDefault( &m_wellTargets, "WellPathTargets", "Well Targets", "", "", "" );
m_wellTargets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
m_wellTargets.uiCapability()->setUiTreeChildrenHidden( true );
@@ -93,11 +96,16 @@ RimWellPathGeometryDef::RimWellPathGeometryDef()
m_autoTargetAtSeaLevel = new RimWellPathTarget;
m_autoTargetAtSeaLevel->setEnabled( false );
CAF_PDM_InitScriptableField( &m_isAttachedToParentWell, "AttachedToParentWell", false, "Attached to Parent Well", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_fixedWellPathPoints, "FixedWellPathPoints", "", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_fixedMeasuredDepths, "FixedMeasuredDepths", "", "", "", "" );
CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" );
caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled );
CAF_PDM_InitScriptableField( &m_showSpheres, "ShowSpheres", false, "Spheres", "", "", "" );
CAF_PDM_InitField( &m_sphereColor, "SphereColor", cvf::Color3f( cvf::Color3f::CEETRON ), "Sphere Color", "", "", "" );
CAF_PDM_InitField( &m_sphereRadiusFactor, "SphereRadiusFactor", 0.15, "Sphere Radius Factor", "", "", "" );
}
//--------------------------------------------------------------------------------------------------
@@ -159,6 +167,14 @@ void RimWellPathGeometryDef::setMdAtFirstTarget( double md )
m_mdAtFirstTarget = md;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef::setIsAttachedToParentWell( bool isAttached )
{
m_isAttachedToParentWell = isAttached;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -244,6 +260,30 @@ std::vector<RiaWellPlanCalculator::WellPlanSegment> RimWellPathGeometryDef::well
return wpCalc.wellPlan();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPathGeometryDef::showSpheres() const
{
return m_showSpheres();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimWellPathGeometryDef::sphereColor() const
{
return m_sphereColor();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathGeometryDef::sphereRadiusFactor() const
{
return m_sphereRadiusFactor();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -406,10 +446,19 @@ void RimWellPathGeometryDef::fieldChangedByUi( const caf::PdmFieldHandle* change
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_referencePointUtmXyd );
uiOrdering.add( &m_airGap );
uiOrdering.add( &m_mdAtFirstTarget );
uiOrdering.add( &m_useAutoGeneratedTargetAtSeaLevel );
if ( !m_isAttachedToParentWell )
{
uiOrdering.add( &m_referencePointUtmXyd );
uiOrdering.add( &m_airGap );
uiOrdering.add( &m_mdAtFirstTarget );
uiOrdering.add( &m_useAutoGeneratedTargetAtSeaLevel );
}
auto group = uiOrdering.addNewGroup( "Well Target Appearance" );
group->add( &m_showSpheres );
group->add( &m_sphereColor );
group->add( &m_sphereRadiusFactor );
uiOrdering.add( &m_wellTargets );
uiOrdering.add( &m_pickPointsEnabled );

View File

@@ -28,6 +28,7 @@
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include "cvfColor3.h"
#include "cvfObject.h"
class RimWellPath;
@@ -55,6 +56,7 @@ public:
double mdAtFirstTarget() const;
void setMdAtFirstTarget( double mdrkb );
void setIsAttachedToParentWell( bool isAttached );
void setFixedWellPathPoints( const std::vector<cvf::Vec3d>& points );
void setFixedMeasuredDepths( const std::vector<double>& mds );
@@ -80,6 +82,11 @@ public:
std::vector<RiaWellPlanCalculator::WellPlanSegment> wellPlan() const;
// Well target appearance
bool showSpheres() const;
cvf::Color3f sphereColor() const;
double sphereRadiusFactor() const;
protected:
void defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget ) override;
@@ -116,5 +123,11 @@ private:
caf::PdmField<std::vector<cvf::Vec3d>> m_fixedWellPathPoints;
caf::PdmField<std::vector<double>> m_fixedMeasuredDepths;
caf::PdmField<bool> m_isAttachedToParentWell;
caf::PdmField<bool> m_showSpheres;
caf::PdmField<cvf::Color3f> m_sphereColor;
caf::PdmField<double> m_sphereRadiusFactor;
std::shared_ptr<RicCreateWellTargetsPickEventHandler> m_pickTargetsEventHandler;
};

View File

@@ -96,6 +96,14 @@ bool RimWellPathTarget::isEnabled() const
return m_isEnabled;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setPointXYZ( const cvf::Vec3d& point )
{
m_targetPoint = { point.x(), point.y(), -point.z() };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -42,8 +42,9 @@ public:
void setEnabled( bool enable );
bool isEnabled() const;
void setPointXYZ( const cvf::Vec3d& point );
void setAsPointTargetXYD( const cvf::Vec3d& point );
void setAsPointTargetXYZ( const cvf::Vec3d& point);
void setAsPointTargetXYZ( const cvf::Vec3d& point );
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, const cvf::Vec3d& tangent );
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuth, double inclination );
void setDerivedTangent( double azimuth, double inclination );

View File

@@ -0,0 +1,205 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimWellPathTieIn.h"
#include "RigWellPath.h"
#include "RimModeledWellPath.h"
#include "RimTools.h"
#include "RimWellPathCollection.h"
#include "RimWellPathGeometryDef.h"
#include "RimWellPathTarget.h"
#include "RimWellPathValve.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiDoubleValueEditor.h"
CAF_PDM_SOURCE_INIT( RimWellPathTieIn, "RimWellPathTieIn" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathTieIn::RimWellPathTieIn()
{
CAF_PDM_InitObject( "Well Path Tie In", ":/NotDefined.png", "", "Well Path Tie In description" );
CAF_PDM_InitFieldNoDefault( &m_parentWell, "ParentWellPath", "ParentWellPath", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_childWell, "ChildWellPath", "ChildWellPath", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_tieInMeasuredDepth, "TieInMeasuredDepth", "TieInMeasuredDepth", "", "", "" );
m_tieInMeasuredDepth.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitScriptableField( &m_addValveAtConnection,
"AddValveAtConnection",
false,
"Add Outlet Valve for Branches",
"",
"",
"" );
CAF_PDM_InitScriptableFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" );
m_valve = new RimWellPathValve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTieIn::connectWellPaths( RimWellPath* parentWell, RimWellPath* childWell, double tieInMeasuredDepth )
{
m_parentWell = parentWell;
m_childWell = childWell;
m_tieInMeasuredDepth = tieInMeasuredDepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPathTieIn::parentWell() const
{
return m_parentWell();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathTieIn::tieInMeasuredDepth() const
{
return m_tieInMeasuredDepth();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPathTieIn::childWell() const
{
return m_childWell();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTieIn::updateChildWellGeometry()
{
auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( m_childWell() );
if ( modeledWellPath )
{
modeledWellPath->updateTieInLocationFromParentWell();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTieIn::updateFirstTargetFromParentWell()
{
auto parentWellPath = m_parentWell();
if ( !parentWellPath ) return;
auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( m_childWell() );
if ( modeledWellPath && modeledWellPath->geometryDefinition() )
{
auto [pointVector, measuredDepths] =
parentWellPath->wellPathGeometry()
->clippedPointSubset( parentWellPath->wellPathGeometry()->measuredDepths().front(), m_tieInMeasuredDepth );
if ( pointVector.size() < 2u ) return;
RimWellPathTarget* newTarget = nullptr;
if ( modeledWellPath->geometryDefinition()->activeWellTargets().empty() )
{
newTarget = modeledWellPath->geometryDefinition()->appendTarget();
}
else
{
newTarget = modeledWellPath->geometryDefinition()->activeWellTargets().front();
}
auto lastPoint = pointVector.back();
auto tangent = lastPoint - pointVector[pointVector.size() - 2];
newTarget->setAsPointXYZAndTangentTarget( { lastPoint[0], lastPoint[1], lastPoint[2] }, tangent );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimWellPathValve* RimWellPathTieIn::outletValve() const
{
return m_addValveAtConnection() && m_valve() && m_valve->valveTemplate() ? m_valve() : nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTieIn::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
auto tieInGroup = uiOrdering.addNewGroup( "Tie In Settings" );
tieInGroup->add( &m_parentWell );
tieInGroup->add( &m_tieInMeasuredDepth );
tieInGroup->add( &m_addValveAtConnection );
// Display only ICV valves
m_valve->setComponentTypeFilter( { RiaDefines::WellPathComponentType::ICV } );
if ( m_addValveAtConnection )
{
m_valve->uiOrdering( "TemplateOnly", *tieInGroup );
}
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTieIn::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
if ( changedField == &m_parentWell )
{
updateFirstTargetFromParentWell();
}
updateChildWellGeometry();
// Update all well paths to make sure the visibility of completion settings is updated
// Completions settings is only visible for top-level wells, not for tie-in wells
RimTools::wellPathCollection()->updateAllRequiredEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimWellPathTieIn::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_parentWell )
{
std::vector<RimWellPath*> wellPathsToExclude = { m_childWell() };
RimTools::wellPathOptionItemsSubset( wellPathsToExclude, &options );
options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) );
}
return options;
}

View File

@@ -0,0 +1,62 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
class RimWellPath;
class RimWellPathValve;
class RimWellPathTieIn : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimWellPathTieIn();
void connectWellPaths( RimWellPath* parentWell, RimWellPath* childWell, double tieInMeasuredDepth );
RimWellPath* parentWell() const;
double tieInMeasuredDepth() const;
RimWellPath* childWell() const;
void updateChildWellGeometry();
void updateFirstTargetFromParentWell();
const RimWellPathValve* outletValve() const;
private:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
private:
caf::PdmPtrField<RimWellPath*> m_parentWell;
caf::PdmPtrField<RimWellPath*> m_childWell;
caf::PdmField<double> m_tieInMeasuredDepth;
caf::PdmField<bool> m_addValveAtConnection;
caf::PdmChildField<RimWellPathValve*> m_valve;
};