From 85ba3a3bc901993c3a51b2e09405eea9fff22620 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Mon, 7 Sep 2020 13:43:19 +0200 Subject: [PATCH] #6424 Fracture Model: Export Perfs.frk file. --- .../FileInterface/CMakeLists_files.cmake | 2 + .../RifFractureModelPerfsFrkExporter.cpp | 163 ++++++++++++++++++ .../RifFractureModelPerfsFrkExporter.h | 43 +++++ .../RifFractureModelPlotExporter.cpp | 4 +- .../Completions/RimFractureModel.cpp | 40 +++++ .../Completions/RimFractureModel.h | 12 ++ 6 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.cpp create mode 100644 ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.h diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake index 96e0500451..2563ca3a0a 100644 --- a/ApplicationCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -57,6 +57,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifElasticPropertiesReader.h ${CMAKE_CURRENT_LIST_DIR}/RifFractureModelPlotExporter.h ${CMAKE_CURRENT_LIST_DIR}/RifFractureModelGeologicalFrkExporter.h ${CMAKE_CURRENT_LIST_DIR}/RifFractureModelDeviationFrkExporter.h +${CMAKE_CURRENT_LIST_DIR}/RifFractureModelPerfsFrkExporter.h ${CMAKE_CURRENT_LIST_DIR}/RifSurfaceExporter.h @@ -120,6 +121,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifElasticPropertiesReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFractureModelPlotExporter.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFractureModelGeologicalFrkExporter.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFractureModelDeviationFrkExporter.cpp +${CMAKE_CURRENT_LIST_DIR}/RifFractureModelPerfsFrkExporter.cpp ${CMAKE_CURRENT_LIST_DIR}/RifSurfaceExporter.cpp # HDF5 file reader is directly included in ResInsight main CmakeList.txt diff --git a/ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.cpp b/ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.cpp new file mode 100644 index 0000000000..823b1c41bd --- /dev/null +++ b/ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.cpp @@ -0,0 +1,163 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifFractureModelPerfsFrkExporter.h" + +#include "RiaLogging.h" + +#include "RimFractureModel.h" +#include "RimFractureModelPlot.h" +#include "RimWellPath.h" + +#include "RigWellPath.h" +#include "RigWellPathGeometryTools.h" + +#include +#include + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifFractureModelPerfsFrkExporter::writeToFile( RimFractureModelPlot* plot, const QString& filepath ) +{ + RimFractureModel* fractureModel = plot->fractureModel(); + if ( !fractureModel ) + { + return false; + } + + RimWellPath* wellPath = fractureModel->wellPath(); + if ( !wellPath ) + { + return false; + } + + QFile data( filepath ); + if ( !data.open( QFile::WriteOnly | QFile::Truncate ) ) + { + return false; + } + + QTextStream stream( &data ); + appendHeaderToStream( stream ); + + bool isTransverse = fractureModel->fractureOrientation() == RimFractureModel::FractureOrientation::TRANSVERSE_WELL_PATH; + appendFractureOrientationToStream( stream, isTransverse ); + + // Unit: meter + double perforationLength = fractureModel->perforationLength(); + + double anchorPositionMD = computeMeasuredDepthForPosition( wellPath, fractureModel->anchorPosition() ); + double topMD = anchorPositionMD - ( perforationLength / 2.0 ); + double bottomMD = anchorPositionMD + ( perforationLength / 2.0 ); + + appendPerforationToStream( stream, + 1, + RiaEclipseUnitTools::meterToFeet( topMD ), + RiaEclipseUnitTools::meterToFeet( bottomMD ) ); + + appendFooterToStream( stream ); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifFractureModelPerfsFrkExporter::appendHeaderToStream( QTextStream& stream ) +{ + stream << "" << endl << "" << endl; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifFractureModelPerfsFrkExporter::appendFractureOrientationToStream( QTextStream& stream, bool isTransverse ) +{ + stream << "" << endl << static_cast( isTransverse ) << endl << "" << endl; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifFractureModelPerfsFrkExporter::appendPerforationToStream( QTextStream& stream, int index, double topMD, double bottomMD ) +{ + stream << "" << endl + << "" << endl + << topMD << endl + << "" << endl + << "" << endl + << bottomMD << endl + << "" << endl + << "" << endl; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifFractureModelPerfsFrkExporter::appendFooterToStream( QTextStream& stream ) +{ + stream << "" << endl; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RifFractureModelPerfsFrkExporter::computeMeasuredDepthForPosition( const RimWellPath* wellPath, + const cvf::Vec3d& position ) +{ + const RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); + + const std::vector& mdValuesOfWellPath = wellPathGeometry->measureDepths(); + const std::vector& tvdValuesOfWellPath = wellPathGeometry->trueVerticalDepths(); + const double targetTvd = -position.z(); + + std::vector tvDepthValues; + size_t index = 0; + bool isAdded = false; + for ( size_t i = 0; i < tvdValuesOfWellPath.size(); i++ ) + { + double currentTvd = tvdValuesOfWellPath[i]; + double prevTvd = 0.0; + if ( i > 0 ) prevTvd = tvdValuesOfWellPath[i - 1]; + + if ( !isAdded && targetTvd > prevTvd && targetTvd <= currentTvd ) + { + // Insert the anchor position at correct order in well depths + index = i; + isAdded = true; + tvDepthValues.push_back( targetTvd ); + } + + tvDepthValues.push_back( currentTvd ); + } + + // Generate MD data by interpolation + std::vector measuredDepthValues = + RigWellPathGeometryTools::interpolateMdFromTvd( mdValuesOfWellPath, tvdValuesOfWellPath, tvDepthValues ); + + if ( index < measuredDepthValues.size() ) + return measuredDepthValues[index]; + else + { + RiaLogging::error( "Unable to compute measured depth from well path data." ); + return -1.0; + } +} diff --git a/ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.h b/ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.h new file mode 100644 index 0000000000..72dce83eba --- /dev/null +++ b/ApplicationCode/FileInterface/RifFractureModelPerfsFrkExporter.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfVector3.h" + +class RimFractureModelPlot; +class RimWellPath; + +class QString; +class QTextStream; + +//================================================================================================== +// +//================================================================================================== +class RifFractureModelPerfsFrkExporter +{ +public: + static bool writeToFile( RimFractureModelPlot* plot, const QString& filepath ); + +private: + static void appendHeaderToStream( QTextStream& stream ); + static void appendFractureOrientationToStream( QTextStream& stream, bool isTranseverse ); + static void appendPerforationToStream( QTextStream& stream, int index, double topMd, double bottomMd ); + static void appendFooterToStream( QTextStream& stream ); + static double computeMeasuredDepthForPosition( const RimWellPath* wellPath, const cvf::Vec3d& position ); +}; diff --git a/ApplicationCode/FileInterface/RifFractureModelPlotExporter.cpp b/ApplicationCode/FileInterface/RifFractureModelPlotExporter.cpp index 6d68b77d12..6391b3f610 100644 --- a/ApplicationCode/FileInterface/RifFractureModelPlotExporter.cpp +++ b/ApplicationCode/FileInterface/RifFractureModelPlotExporter.cpp @@ -20,6 +20,7 @@ #include "RifFractureModelDeviationFrkExporter.h" #include "RifFractureModelGeologicalFrkExporter.h" +#include "RifFractureModelPerfsFrkExporter.h" #include "RimFractureModelPlot.h" @@ -31,5 +32,6 @@ bool RifFractureModelPlotExporter::writeToDirectory( RimFractureModelPlot* plot, const QString& directoryPath ) { return RifFractureModelGeologicalFrkExporter::writeToFile( plot, useDetailedFluidLoss, directoryPath + "/Geological.frk" ) && - RifFractureModelDeviationFrkExporter::writeToFile( plot, directoryPath + "/Deviation.frk" ); + RifFractureModelDeviationFrkExporter::writeToFile( plot, directoryPath + "/Deviation.frk" ) && + RifFractureModelPerfsFrkExporter::writeToFile( plot, directoryPath + "/Perfs.frk" ); } diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.cpp index 2594b785a5..fb5a52770a 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.cpp @@ -79,6 +79,17 @@ void caf::AppEnum::setUp() setDefault( RimFractureModel::ExtractionType::TRUE_VERTICAL_THICKNESS ); } + +template <> +void caf::AppEnum::setUp() +{ + addItem( RimFractureModel::FractureOrientation::ALONG_WELL_PATH, "ALONG_WELL_PATH", "Along Well Path" ); + addItem( RimFractureModel::FractureOrientation::TRANSVERSE_WELL_PATH, + "TRANSVERSE_WELL_PATH", + "Transverse (normal) to Well Path" ); + + setDefault( RimFractureModel::FractureOrientation::TRANSVERSE_WELL_PATH ); +} }; // namespace caf //-------------------------------------------------------------------------------------------------- @@ -206,6 +217,15 @@ RimFractureModel::RimFractureModel() "", "" ); + CAF_PDM_InitScriptableField( &m_perforationLength, "PerforationLength", 10.0, "Perforation Length [m]", "", "", "" ); + CAF_PDM_InitScriptableField( &m_fractureOrientation, + "FractureOrientation", + caf::AppEnum( FractureOrientation::ALONG_WELL_PATH ), + "Fracture Orientation", + "", + "", + "" ); + CAF_PDM_InitScriptableFieldNoDefault( &m_elasticProperties, "ElasticProperties", "Elastic Properties", "", "", "" ); m_elasticProperties.uiCapability()->setUiHidden( true ); m_elasticProperties.uiCapability()->setUiTreeHidden( true ); @@ -557,6 +577,10 @@ void RimFractureModel::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin temperatureGroup->add( &m_referenceTemperature ); temperatureGroup->add( &m_referenceTemperatureGradient ); temperatureGroup->add( &m_referenceTemperatureDepth ); + + caf::PdmUiOrdering* perforationGroup = uiOrdering.addNewGroup( "Perforation" ); + perforationGroup->add( &m_perforationLength ); + perforationGroup->add( &m_fractureOrientation ); } //-------------------------------------------------------------------------------------------------- @@ -1019,3 +1043,19 @@ double RimFractureModel::computeDefaultStressDepth() // Use top of active cells as reference stress depth return -eclipseCase->activeCellsBoundingBox().max().z(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFractureModel::perforationLength() const +{ + return m_perforationLength(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFractureModel::FractureOrientation RimFractureModel::fractureOrientation() const +{ + return m_fractureOrientation(); +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.h b/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.h index 4d3652973c..3eab348acc 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureModel.h @@ -53,6 +53,12 @@ public: TRUE_STRATIGRAPHIC_THICKNESS, }; + enum class FractureOrientation + { + ALONG_WELL_PATH, + TRANSVERSE_WELL_PATH + }; + RimFractureModel( void ); ~RimFractureModel( void ) override; @@ -92,6 +98,9 @@ public: bool useDetailedFluidLoss() const; + double perforationLength() const; + FractureOrientation fractureOrientation() const; + // RimWellPathCompletionsInterface overrides. RiaDefines::WellPathComponentType componentType() const override; QString componentLabel() const override; @@ -172,4 +181,7 @@ protected: caf::PdmField m_poroElasticConstantDefault; caf::PdmField m_thermalExpansionCoeffientDefault; caf::PdmField m_useDetailedFluidLoss; + + caf::PdmField> m_fractureOrientation; + caf::PdmField m_perforationLength; };