mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#8027 StimPlan Model Export: Add perforation, formation and facies info
This commit is contained in:
@@ -18,10 +18,13 @@
|
||||
|
||||
#include "RifStimPlanModelGeologicalFrkExporter.h"
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RifCsvDataTableFormatter.h"
|
||||
#include "RifStimPlanModelPerfsFrkExporter.h"
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
|
||||
#include "RimStimPlanModel.h"
|
||||
#include "RimStimPlanModelCalculator.h"
|
||||
@@ -140,15 +143,33 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFile( RimStimPlanModel* stimP
|
||||
values["zonePoroElas"] = stimPlanModel->calculator()->calculatePoroElasticConstant();
|
||||
values["zoneThermalExp"] = stimPlanModel->calculator()->calculateThermalExpansionCoefficient();
|
||||
|
||||
auto [faciesIndex, faciesNames] = stimPlanModel->calculator()->calculateFacies();
|
||||
values["faciesIdx"] = faciesIndex;
|
||||
if ( faciesIndex.size() != tvd.size() || faciesNames.size() != tvd.size() ) return false;
|
||||
|
||||
auto [formationIndex, formationNames] = stimPlanModel->calculator()->calculateFormation();
|
||||
values["formationIdx"] = formationIndex;
|
||||
if ( formationIndex.size() != tvd.size() || formationNames.size() != tvd.size() ) return false;
|
||||
|
||||
// Special values for csv export
|
||||
auto [depthStart, depthEnd] = createDepthRanges( tvd );
|
||||
values["dpthstart"] = depthStart;
|
||||
values["dpthend"] = depthEnd;
|
||||
std::vector<QString> csvLabels = { "dpthstart", "dpthend" };
|
||||
auto [depthStart, depthEnd] = createDepthRanges( tvd );
|
||||
values["dpthstart"] = depthStart;
|
||||
values["dpthend"] = depthEnd;
|
||||
|
||||
auto [perforationTop, perforationBottom] =
|
||||
RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel, stimPlanModel->wellPath() );
|
||||
|
||||
values["perfs"] = createPerforationValues( depthStart,
|
||||
depthEnd,
|
||||
RiaEclipseUnitTools::meterToFeet( perforationTop ),
|
||||
RiaEclipseUnitTools::meterToFeet( perforationBottom ) );
|
||||
|
||||
std::vector<QString> csvLabels = { "dpthstart", "dpthend", "faciesIdx", "formationIdx", "perfs" };
|
||||
for ( const QString& label : labels )
|
||||
csvLabels.push_back( label );
|
||||
|
||||
return writeToFrkFile( filepath, labels, values ) && writeToCsvFile( filepath, csvLabels, values );
|
||||
return writeToFrkFile( filepath, labels, values ) &&
|
||||
writeToCsvFile( filepath, csvLabels, values, faciesNames, formationNames );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -187,8 +208,9 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFrkFile( const QString&
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifStimPlanModelGeologicalFrkExporter::writeToCsvFile( const QString& filepath,
|
||||
const std::vector<QString>& labels,
|
||||
const std::map<QString, std::vector<double>>& values )
|
||||
|
||||
const std::map<QString, std::vector<double>>& values,
|
||||
const std::vector<QString>& faciesNames,
|
||||
const std::vector<QString>& formationNames )
|
||||
{
|
||||
// Create the csv in the same directory as the frk file
|
||||
QFileInfo fi( filepath );
|
||||
@@ -210,6 +232,8 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToCsvFile( const QString&
|
||||
{
|
||||
header.push_back( RifTextDataTableColumn( label, RifTextDataTableDoubleFormat::RIF_FLOAT ) );
|
||||
}
|
||||
header.push_back( RifTextDataTableColumn( "Facies" ) );
|
||||
header.push_back( RifTextDataTableColumn( "Formation" ) );
|
||||
formatter.header( header );
|
||||
|
||||
// The length of the vectors are assumed to be equal
|
||||
@@ -230,6 +254,11 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToCsvFile( const QString&
|
||||
formatter.add( vals->second[idx] );
|
||||
}
|
||||
}
|
||||
if ( !isDone )
|
||||
{
|
||||
formatter.add( faciesNames[idx] );
|
||||
formatter.add( formationNames[idx] );
|
||||
}
|
||||
formatter.rowCompleted();
|
||||
idx++;
|
||||
}
|
||||
@@ -374,3 +403,25 @@ std::pair<std::vector<double>, std::vector<double>>
|
||||
|
||||
return std::make_pair( startTvd, endTvd );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RifStimPlanModelGeologicalFrkExporter::createPerforationValues( const std::vector<double>& depthStart,
|
||||
const std::vector<double>& depthEnd,
|
||||
double perforationTop,
|
||||
double perforationBottom )
|
||||
{
|
||||
std::vector<double> perfs;
|
||||
for ( size_t idx = 0; idx < depthStart.size(); idx++ )
|
||||
{
|
||||
double top = depthStart[idx];
|
||||
double bottom = depthEnd[idx];
|
||||
|
||||
// Layer is perforation if end points are inside the perforation interval
|
||||
bool isPerforation = !( bottom < perforationTop || top > perforationBottom );
|
||||
perfs.push_back( static_cast<double>( isPerforation ) );
|
||||
}
|
||||
|
||||
return perfs;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@ private:
|
||||
const std::map<QString, std::vector<double>>& values );
|
||||
static bool writeToCsvFile( const QString& filepath,
|
||||
const std::vector<QString>& labels,
|
||||
const std::map<QString, std::vector<double>>& values );
|
||||
const std::map<QString, std::vector<double>>& values,
|
||||
const std::vector<QString>& faciesNames,
|
||||
const std::vector<QString>& formationNames );
|
||||
|
||||
static void appendHeaderToStream( QTextStream& stream );
|
||||
static void appendToStream( QTextStream& stream, const QString& label, const std::vector<double>& values );
|
||||
@@ -59,4 +61,9 @@ private:
|
||||
|
||||
static bool warnOnInvalidData( const QString& label, const std::vector<double>& values );
|
||||
static bool hasInvalidData( const std::vector<double>& values );
|
||||
|
||||
static std::vector<double> createPerforationValues( const std::vector<double>& depthStart,
|
||||
const std::vector<double>& depthEnd,
|
||||
double perforationTop,
|
||||
double perforationBottom );
|
||||
};
|
||||
|
||||
@@ -59,12 +59,7 @@ bool RifStimPlanModelPerfsFrkExporter::writeToFile( RimStimPlanModel* stimPlanMo
|
||||
appendFractureOrientationToStream( stream, isTransverse );
|
||||
|
||||
// Unit: meter
|
||||
double perforationLength = stimPlanModel->perforationLength();
|
||||
|
||||
double anchorPositionMD = computeMeasuredDepthForPosition( wellPath, stimPlanModel->anchorPosition() );
|
||||
double topMD = anchorPositionMD - ( perforationLength / 2.0 );
|
||||
double bottomMD = anchorPositionMD + ( perforationLength / 2.0 );
|
||||
|
||||
auto [topMD, bottomMD] = calculateTopAndBottomMeasuredDepth( stimPlanModel, wellPath );
|
||||
appendPerforationToStream( stream,
|
||||
1,
|
||||
RiaEclipseUnitTools::meterToFeet( topMD ),
|
||||
@@ -158,3 +153,19 @@ double RifStimPlanModelPerfsFrkExporter::computeMeasuredDepthForPosition( const
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<double, double>
|
||||
RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( RimStimPlanModel* stimPlanModel,
|
||||
RimWellPath* wellPath )
|
||||
{
|
||||
double perforationLength = stimPlanModel->perforationLength();
|
||||
|
||||
double anchorPositionMD = computeMeasuredDepthForPosition( wellPath, stimPlanModel->anchorPosition() );
|
||||
double topMD = anchorPositionMD - ( perforationLength / 2.0 );
|
||||
double bottomMD = anchorPositionMD + ( perforationLength / 2.0 );
|
||||
|
||||
return std::make_pair( topMD, bottomMD );
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
class RimStimPlanModel;
|
||||
class RimWellPath;
|
||||
|
||||
@@ -34,10 +36,14 @@ class RifStimPlanModelPerfsFrkExporter
|
||||
public:
|
||||
static bool writeToFile( RimStimPlanModel* stimPlanModel, 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 std::pair<double, double> calculateTopAndBottomMeasuredDepth( RimStimPlanModel* stimPlanModel,
|
||||
RimWellPath* wellPath );
|
||||
|
||||
static double computeMeasuredDepthForPosition( const RimWellPath* wellPath, const cvf::Vec3d& position );
|
||||
|
||||
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 );
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user