From 193bc35f6b585854f7c1210a3c018c9a91c7217e Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Wed, 15 Jun 2022 15:29:22 +0200 Subject: [PATCH] #8876 Fracture: add option to use align dip with formation dip --- .../Completions/RimFracture.cpp | 8 ++++ .../Completions/RimFracture.h | 1 + .../Completions/RimWellPathFracture.cpp | 37 ++++++++++++++++ .../Completions/RimWellPathFracture.h | 5 ++- .../StimPlanModel/RimStimPlanModel.cpp | 2 +- .../StimPlanModel/RimStimPlanModel.h | 7 +-- .../ProjectDataModelCommands/RimcWellPath.cpp | 43 +++++++++++++++++++ .../ProjectDataModelCommands/RimcWellPath.h | 3 ++ .../import_fractures_on_well.py | 2 + 9 files changed, 102 insertions(+), 6 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp index 2967edc7f2..56219f337a 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp @@ -527,6 +527,14 @@ double RimFracture::dip() const return m_dip(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFracture::setDip( double dip ) +{ + m_dip = dip; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h index 56507fbb91..34d8585f7d 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h @@ -95,6 +95,7 @@ public: size_t globalCellIndex ) const; cvf::Mat4d transformMatrix() const; + void setDip( double dip ); double dip() const; double tilt() const; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.cpp index feba6d6d76..48d4cf7945 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.cpp @@ -134,6 +134,43 @@ double RimWellPathFracture::wellAzimuthAtFracturePosition() const return wellPathAzimuth; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d RimWellPathFracture::computeFractureDirectionNormal() const +{ + RimWellPath* wellPath = nullptr; + this->firstAncestorOrThisOfType( wellPath ); + if ( !wellPath ) return cvf::Vec3d::UNDEFINED; + + RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); + + // Find the well path points closest to the anchor position + cvf::Vec3d p1; + cvf::Vec3d p2; + wellPathGeometry->twoClosestPoints( fracturePosition(), &p1, &p2 ); + + // Create a well direction based on the two points + cvf::Vec3d wellDirection = ( p2 - p1 ).getNormalized(); + + cvf::Vec3d fractureDirectionNormal = wellDirection; + if ( fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH ) + { + cvf::Mat3d azimuthRotation = cvf::Mat3d::fromRotation( cvf::Vec3d::Z_AXIS, cvf::Math::toRadians( 90.0 ) ); + fractureDirectionNormal.transformVector( azimuthRotation ); + } + else if ( fractureTemplate()->orientationType() == RimFractureTemplate::AZIMUTH ) + { + // Azimuth angle of fracture is relative to north. + double wellAzimuth = wellPathGeometry->wellPathAzimuthAngle( fracturePosition() ); + cvf::Mat3d azimuthRotation = + cvf::Mat3d::fromRotation( cvf::Vec3d::Z_AXIS, cvf::Math::toRadians( wellAzimuth - m_azimuth - 90.0 ) ); + fractureDirectionNormal.transformVector( azimuthRotation ); + } + + return fractureDirectionNormal; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.h b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.h index b90a1b8ca9..30b95ea0fa 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathFracture.h @@ -42,8 +42,9 @@ public: double fractureMD() const override; void setMeasuredDepth( double mdValue ); - void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - void updateAzimuthBasedOnWellAzimuthAngle() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void updateAzimuthBasedOnWellAzimuthAngle() override; + cvf::Vec3d computeFractureDirectionNormal() const; double wellAzimuthAtFracturePosition() const override; diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.cpp b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.cpp index 97a39a68fe..30017ee785 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.cpp +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.cpp @@ -747,7 +747,7 @@ cvf::Vec3d RimStimPlanModel::computeFractureDirectionNormal( RimWellPath* wellPa //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimStimPlanModel::projectVectorIntoFracturePlane( const cvf::Vec3d& position, const cvf::Vec3d& fractureDirectionNormal, - const cvf::Vec3d& direction ) const + const cvf::Vec3d& direction ) { // Create a fracture plane cvf::Plane fracturePlane; diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.h b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.h index a313f440fe..c3d1c44119 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.h +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.h @@ -192,6 +192,10 @@ public: QString unitForProperty( RiaDefines::CurveProperty curveProperty ) const; + static cvf::Vec3d projectVectorIntoFracturePlane( const cvf::Vec3d& position, + const cvf::Vec3d& fractureDirectionNormal, + const cvf::Vec3d& direction ); + protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; @@ -208,9 +212,6 @@ private: void updatePerforationInterval(); cvf::Vec3d computeFractureDirectionNormal( RimWellPath* wellPath, const cvf::Vec3d& position ) const; - cvf::Vec3d projectVectorIntoFracturePlane( const cvf::Vec3d& position, - const cvf::Vec3d& fractureDirectionNormal, - const cvf::Vec3d& direction ) const; RigEclipseCaseData* getEclipseCaseData() const; diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.cpp b/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.cpp index 85e09af2a9..d58155fa7e 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.cpp +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.cpp @@ -18,14 +18,21 @@ #include "RimcWellPath.h" +#include "RiaLogging.h" + +#include "RimEclipseCase.h" +#include "RimEclipseCaseTools.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" #include "RimStimPlanFractureTemplate.h" +#include "RimStimPlanModel.h" #include "RimTools.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RimWellPathFracture.h" +#include "RigStimPlanModelTools.h" + #include "FractureCommands/RicNewWellPathFractureFeature.h" #include "cafPdmAbstractFieldScriptingCapability.h" @@ -48,6 +55,8 @@ RimcWellPath_addFracture::RimcWellPath_addFracture( caf::PdmObjectHandle* self ) "", "", "StimPlan Fracture Template" ); + CAF_PDM_InitScriptableField( &m_alignDip, "AlignDip", false, "Align Dip" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_eclipseCase, "EclipseCase", "", "", "", "Eclipse Case" ); } //-------------------------------------------------------------------------------------------------- @@ -61,6 +70,40 @@ caf::PdmObjectHandle* RimcWellPath_addFracture::execute() if ( m_stimPlanFractureTemplate ) wellPathFracture->setFractureTemplate( m_stimPlanFractureTemplate() ); + if ( m_alignDip ) + { + if ( m_eclipseCase && m_eclipseCase->eclipseCaseData() ) + { + RiaLogging::info( "Computing formation dip for fracture alignment" ); + + double boundingBoxHorizontal = 50.0; + double boundingBoxVertical = 100.0; + + cvf::Vec3d position = wellPathFracture->anchorPosition(); + cvf::Vec3d direction = RigStimPlanModelTools::calculateTSTDirection( m_eclipseCase->eclipseCaseData(), + position, + boundingBoxHorizontal, + boundingBoxVertical ); + RiaLogging::info( + QString( "Direction: %1 %2 %3" ).arg( direction.x() ).arg( direction.y() ).arg( direction.z() ) ); + cvf::Vec3d fractureDirectionNormal = wellPathFracture->computeFractureDirectionNormal(); + + cvf::Vec3d formationDirection = + RimStimPlanModel::projectVectorIntoFracturePlane( position, fractureDirectionNormal, direction ); + if ( !formationDirection.isUndefined() ) + { + double formationDip = RigStimPlanModelTools::calculateFormationDip( formationDirection ) - 90.0; + RiaLogging::info( QString( "Computed formation dip: %1" ).arg( formationDip ) ); + + wellPathFracture->setDip( formationDip ); + } + } + else + { + RiaLogging::error( "No eclipse case found. Fracture not aligned with formation dip." ); + } + } + return wellPathFracture; } diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.h b/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.h index aec0c347e3..f0e2acdc51 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.h +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcWellPath.h @@ -26,6 +26,7 @@ #include class RimStimPlanFractureTemplate; +class RimEclipseCase; //================================================================================================== /// @@ -44,6 +45,8 @@ public: private: caf::PdmField m_md; caf::PdmPtrField m_stimPlanFractureTemplate; + caf::PdmField m_alignDip; + caf::PdmPtrField m_eclipseCase; }; //================================================================================================== diff --git a/GrpcInterface/Python/rips/PythonExamples/import_fractures_on_well.py b/GrpcInterface/Python/rips/PythonExamples/import_fractures_on_well.py index cc3b33c12f..97eb8456a7 100644 --- a/GrpcInterface/Python/rips/PythonExamples/import_fractures_on_well.py +++ b/GrpcInterface/Python/rips/PythonExamples/import_fractures_on_well.py @@ -38,6 +38,8 @@ for measured_depth in measured_depths: fracture = well_path.add_fracture( measured_depth=measured_depth, stim_plan_fracture_template=fracture_template, + align_dip=True, + eclipse_case=case, ) # Update the orientation of the fracture