mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Thermal Fracture: Add visualization of results
This commit is contained in:
@@ -34,10 +34,10 @@
|
||||
#include "RimFractureContainment.h"
|
||||
#include "RimFractureContainmentTools.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimMeshFractureTemplate.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSimWellInView.h"
|
||||
#include "RimStimPlanColors.h"
|
||||
#include "RimStimPlanFractureTemplate.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
|
||||
@@ -94,8 +94,8 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel( cvf::ModelBasicList* mo
|
||||
double characteristicCellSize = eclView.ownerCase()->characteristicCellSize();
|
||||
|
||||
cvf::Collection<cvf::Part> parts;
|
||||
RimStimPlanFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimStimPlanFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
RimMeshFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
|
||||
if ( stimPlanFracTemplate )
|
||||
{
|
||||
@@ -228,7 +228,7 @@ const QString RivWellFracturePartMgr::resultInfoText( const RimEclipseView& acti
|
||||
if ( m_rimFracture.isNull() ) return text;
|
||||
|
||||
auto* ellipseFractureTemplate = dynamic_cast<RimEllipseFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
auto* stimPlanTemplate = dynamic_cast<RimStimPlanFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
auto* stimPlanTemplate = dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
|
||||
if ( ellipseFractureTemplate )
|
||||
{
|
||||
@@ -285,7 +285,7 @@ const RigFractureCell* RivWellFracturePartMgr::getFractureCellAtDomainCoord( cvf
|
||||
cvf::Mat4d toFractureXf = m_rimFracture->transformMatrix().getInverted();
|
||||
cvf::Vec3d fractureCoord = domainCoord.getTransformedPoint( toFractureXf );
|
||||
|
||||
auto* stimPlanTempl = dynamic_cast<RimStimPlanFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
auto* stimPlanTempl = dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
if ( !stimPlanTempl ) return nullptr;
|
||||
|
||||
const RigFractureGrid* grid = m_rimFracture->fractureGrid();
|
||||
@@ -403,8 +403,8 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createEllipseSurfacePart( const RimE
|
||||
cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfacePart( const RimEclipseView& activeView )
|
||||
{
|
||||
CVF_ASSERT( m_rimFracture );
|
||||
RimStimPlanFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimStimPlanFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
RimMeshFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
CVF_ASSERT( stimPlanFracTemplate );
|
||||
|
||||
auto displayCoordTransform = activeView.displayCoordTransform();
|
||||
@@ -542,8 +542,8 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createSingleColorSurfacePart( const
|
||||
cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanElementColorSurfacePart( const RimEclipseView& activeView )
|
||||
{
|
||||
CVF_ASSERT( m_rimFracture );
|
||||
RimStimPlanFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimStimPlanFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
RimMeshFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
CVF_ASSERT( stimPlanFracTemplate );
|
||||
|
||||
if ( !m_rimFracture->fractureGrid() ) return nullptr;
|
||||
@@ -1002,8 +1002,8 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanMeshPart( const RimEcl
|
||||
{
|
||||
if ( !m_rimFracture->fractureTemplate() ) return nullptr;
|
||||
|
||||
RimStimPlanFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimStimPlanFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
RimMeshFractureTemplate* stimPlanFracTemplate =
|
||||
dynamic_cast<RimMeshFractureTemplate*>( m_rimFracture->fractureTemplate() );
|
||||
if ( !stimPlanFracTemplate ) return nullptr;
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> stimPlanMeshGeo = createStimPlanMeshDrawable( stimPlanFracTemplate, activeView );
|
||||
@@ -1030,7 +1030,7 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanMeshPart( const RimEcl
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellFracturePartMgr::createVisibleFracturePolygons( RimStimPlanFractureTemplate* stimPlanFracTemplate,
|
||||
void RivWellFracturePartMgr::createVisibleFracturePolygons( RimMeshFractureTemplate* stimPlanFracTemplate,
|
||||
const RimEclipseView& activeView )
|
||||
{
|
||||
if ( !m_rimFracture->fractureGrid() ) return;
|
||||
@@ -1060,8 +1060,7 @@ void RivWellFracturePartMgr::createVisibleFracturePolygons( RimStimPlanFractureT
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<cvf::DrawableGeo>
|
||||
RivWellFracturePartMgr::createStimPlanMeshDrawable( RimStimPlanFractureTemplate* stimPlanFracTemplate,
|
||||
cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable( RimMeshFractureTemplate* stimPlanFracTemplate,
|
||||
const RimEclipseView& activeView )
|
||||
{
|
||||
if ( !m_rimFracture->fractureGrid() ) return nullptr;
|
||||
|
@@ -44,7 +44,7 @@ class DisplayCoordTransform;
|
||||
|
||||
class RimFracture;
|
||||
class RimFractureTemplate;
|
||||
class RimStimPlanFractureTemplate;
|
||||
class RimMeshFractureTemplate;
|
||||
class RimEclipseView;
|
||||
class RigFractureCell;
|
||||
|
||||
@@ -79,11 +79,10 @@ private:
|
||||
void appendFracturePerforationLengthParts( const RimEclipseView& activeView, cvf::ModelBasicList* model );
|
||||
|
||||
cvf::ref<cvf::Part> createStimPlanMeshPart( const RimEclipseView& activeView );
|
||||
cvf::ref<cvf::DrawableGeo> createStimPlanMeshDrawable( RimStimPlanFractureTemplate* stimPlanFracTemplate,
|
||||
cvf::ref<cvf::DrawableGeo> createStimPlanMeshDrawable( RimMeshFractureTemplate* stimPlanFracTemplate,
|
||||
const RimEclipseView& activeView );
|
||||
|
||||
void createVisibleFracturePolygons( RimStimPlanFractureTemplate* stimPlanFracTemplate,
|
||||
const RimEclipseView& activeView );
|
||||
void createVisibleFracturePolygons( RimMeshFractureTemplate* stimPlanFracTemplate, const RimEclipseView& activeView );
|
||||
|
||||
std::vector<cvf::Vec3d> fractureBorderPolygon();
|
||||
|
||||
|
@@ -658,10 +658,9 @@ QList<caf::PdmOptionItemInfo> RimFracture::calculateValueOptions( const caf::Pdm
|
||||
if ( fractureTemplate() )
|
||||
{
|
||||
RimFractureTemplate* fracTemplate = fractureTemplate();
|
||||
if ( dynamic_cast<RimStimPlanFractureTemplate*>( fracTemplate ) )
|
||||
if ( dynamic_cast<RimMeshFractureTemplate*>( fracTemplate ) )
|
||||
{
|
||||
RimStimPlanFractureTemplate* fracTemplateStimPlan =
|
||||
dynamic_cast<RimStimPlanFractureTemplate*>( fracTemplate );
|
||||
RimMeshFractureTemplate* fracTemplateStimPlan = dynamic_cast<RimMeshFractureTemplate*>( fracTemplate );
|
||||
std::vector<double> timeValues = fracTemplateStimPlan->timeSteps();
|
||||
int index = 0;
|
||||
for ( double value : timeValues )
|
||||
@@ -750,7 +749,7 @@ void RimFracture::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& ui
|
||||
}
|
||||
|
||||
RimFractureTemplate* fracTemplate = fractureTemplate();
|
||||
if ( dynamic_cast<RimStimPlanFractureTemplate*>( fracTemplate ) )
|
||||
if ( dynamic_cast<RimMeshFractureTemplate*>( fracTemplate ) )
|
||||
{
|
||||
m_stimPlanTimeIndexToPlot.uiCapability()->setUiHidden( false );
|
||||
|
||||
|
@@ -163,6 +163,8 @@ void RimThermalFractureTemplate::loadDataAndUpdate()
|
||||
// {
|
||||
// setUnitSystem( m_fractureDefinitionData->unitSet() );
|
||||
// }
|
||||
// TODO: handle other units
|
||||
setUnitSystem( RiaDefines::EclipseUnitSystem::UNITS_METRIC );
|
||||
|
||||
if ( !m_userDefinedWellPathDepthAtFracture )
|
||||
{
|
||||
@@ -200,6 +202,8 @@ void RimThermalFractureTemplate::loadDataAndUpdate()
|
||||
QStringList RimThermalFractureTemplate::conductivityResultNames() const
|
||||
{
|
||||
QStringList resultNames;
|
||||
if ( !m_fractureDefinitionData ) return resultNames;
|
||||
|
||||
for ( auto [name, unit] : m_fractureDefinitionData->getPropertyNamesUnits() )
|
||||
{
|
||||
resultNames.append( name );
|
||||
@@ -616,10 +620,12 @@ void RimThermalFractureTemplate::appendDataToResultStatistics( const QString&
|
||||
{
|
||||
if ( m_fractureDefinitionData )
|
||||
{
|
||||
// QString fileResultName = mapUiResultNameToFileResultName( uiResultName );
|
||||
|
||||
// m_fractureDefinitionData->appendDataToResultStatistics( fileResultName, unit, minMaxAccumulator,
|
||||
// posNegAccumulator );
|
||||
QString fileResultName = mapUiResultNameToFileResultName( uiResultName );
|
||||
RigThermalFractureResultUtil::appendDataToResultStatistics( m_fractureDefinitionData,
|
||||
fileResultName,
|
||||
unit,
|
||||
minMaxAccumulator,
|
||||
posNegAccumulator );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,6 +639,7 @@ void RimThermalFractureTemplate::fractureTriangleGeometry( std::vector<cvf::Vec3
|
||||
if ( m_fractureDefinitionData )
|
||||
{
|
||||
RigThermalFractureResultUtil::createFractureTriangleGeometry( m_fractureDefinitionData,
|
||||
m_activeTimeStepIndex,
|
||||
m_halfLengthScaleFactor(),
|
||||
m_heightScaleFactor(),
|
||||
wellPathDepthAtFracture,
|
||||
|
@@ -125,3 +125,46 @@ double RigThermalFractureDefinition::getPropertyValue( int propertyIndex, int no
|
||||
{
|
||||
return m_results[propertyIndex].getValue( nodeIndex, timeStepIndex );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RigThermalFractureDefinition::getPropertyIndex( const QString& name ) const
|
||||
{
|
||||
for ( size_t i = 0; i < m_results.size(); i++ )
|
||||
if ( name == m_results[i].name() ) return static_cast<int>( i );
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<cvf::Vec3d> RigThermalFractureDefinition::relativeCoordinates( int timeStepIndex ) const
|
||||
{
|
||||
std::vector<cvf::Vec3d> relCoords;
|
||||
|
||||
int xIndex = getPropertyIndex( "XCoord" );
|
||||
int yIndex = getPropertyIndex( "YCoord" );
|
||||
int zIndex = getPropertyIndex( "ZCoord" );
|
||||
if ( xIndex == -1 || yIndex == -1 || zIndex == -1 )
|
||||
{
|
||||
return relCoords;
|
||||
}
|
||||
|
||||
// The first node is the center node
|
||||
int centerNodeIndex = 0;
|
||||
cvf::Vec3d centerNode( getPropertyValue( xIndex, centerNodeIndex, timeStepIndex ),
|
||||
getPropertyValue( yIndex, centerNodeIndex, timeStepIndex ),
|
||||
getPropertyValue( zIndex, centerNodeIndex, timeStepIndex ) );
|
||||
|
||||
for ( size_t nodeIndex = 0; nodeIndex < numNodes(); nodeIndex++ )
|
||||
{
|
||||
cvf::Vec3d nodePos( getPropertyValue( xIndex, static_cast<int>( nodeIndex ), timeStepIndex ),
|
||||
getPropertyValue( yIndex, static_cast<int>( nodeIndex ), timeStepIndex ),
|
||||
getPropertyValue( zIndex, static_cast<int>( nodeIndex ), timeStepIndex ) );
|
||||
relCoords.push_back( nodePos - centerNode );
|
||||
}
|
||||
|
||||
return relCoords;
|
||||
}
|
||||
|
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <vector>
|
||||
@@ -36,8 +38,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
QString name() { return m_name; }
|
||||
QString unit() { return m_unit; }
|
||||
QString name() const { return m_name; }
|
||||
QString unit() const { return m_unit; }
|
||||
|
||||
void appendValue( int nodeIndex, int timeStepIndex, double value )
|
||||
{
|
||||
@@ -85,6 +87,10 @@ public:
|
||||
|
||||
double getPropertyValue( int propertyIndex, int nodeIndex, int timeStepIndex ) const;
|
||||
|
||||
int getPropertyIndex( const QString& name ) const;
|
||||
|
||||
std::vector<cvf::Vec3d> relativeCoordinates( int timeStepIndex ) const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
|
||||
|
@@ -18,7 +18,20 @@
|
||||
|
||||
#include "RigThermalFractureResultUtil.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigCellGeometryTools.h"
|
||||
#include "RigFractureGrid.h"
|
||||
#include "RigStatisticsMath.h"
|
||||
#include "RigThermalFractureDefinition.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
int numSamplesX = 40;
|
||||
int numSamplesY = 40;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -43,7 +56,60 @@ std::vector<std::vector<double>>
|
||||
const QString& unitName,
|
||||
size_t timeStepIndex )
|
||||
{
|
||||
return std::vector<std::vector<double>>();
|
||||
int propertyIndex = fractureDefinition->getPropertyIndex( resultName );
|
||||
|
||||
std::vector<cvf::Vec3d> relativePos = fractureDefinition->relativeCoordinates( timeStepIndex );
|
||||
CAF_ASSERT( relativePos.size() == fractureDefinition->numNodes() );
|
||||
|
||||
// Create bounding box
|
||||
cvf::BoundingBox boundingBox;
|
||||
for ( auto p : relativePos )
|
||||
boundingBox.add( p );
|
||||
|
||||
// Generate a uniform mesh
|
||||
auto [xCoordsAtNodes, yCoordsAtNodes] = generateUniformMesh( boundingBox, numSamplesX, numSamplesY );
|
||||
|
||||
// Find center points
|
||||
std::vector<double> xCoords;
|
||||
for ( int i = 0; i < static_cast<int>( xCoordsAtNodes.size() ) - 1; i++ )
|
||||
xCoords.push_back( ( xCoordsAtNodes[i] + xCoordsAtNodes[i + 1] ) / 2 );
|
||||
std::vector<double> depthCoords;
|
||||
for ( int i = 0; i < static_cast<int>( yCoordsAtNodes.size() ) - 1; i++ )
|
||||
depthCoords.push_back( ( yCoordsAtNodes[i] + yCoordsAtNodes[i + 1] ) / 2 );
|
||||
|
||||
std::vector<std::vector<double>> vec;
|
||||
|
||||
// Fill with invalid value
|
||||
for ( int i = 0; i < numSamplesY; i++ )
|
||||
{
|
||||
std::vector<double> junk( numSamplesX, HUGE_VAL );
|
||||
vec.push_back( junk );
|
||||
}
|
||||
|
||||
// Loop through each polygon and check if point is inside.
|
||||
for ( int i = 0; i < static_cast<int>( xCoords.size() ) - 1; i++ )
|
||||
{
|
||||
for ( int j = 0; j < static_cast<int>( depthCoords.size() ) - 1; j++ )
|
||||
{
|
||||
std::vector<cvf::Vec3d> cellPolygon;
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i], depthCoords[j], 0.0 ) );
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i + 1], depthCoords[j], 0.0 ) );
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i + 1], depthCoords[j + 1], 0.0 ) );
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i], depthCoords[j + 1], 0.0 ) );
|
||||
|
||||
for ( size_t nodeIndex = 0; nodeIndex < fractureDefinition->numNodes(); nodeIndex++ )
|
||||
{
|
||||
if ( RigCellGeometryTools::pointInsidePolygon2D( relativePos[nodeIndex], cellPolygon ) )
|
||||
{
|
||||
double value = fractureDefinition->getPropertyValue( propertyIndex, nodeIndex, timeStepIndex );
|
||||
|
||||
vec[j][i] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -51,12 +117,64 @@ std::vector<std::vector<double>>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigThermalFractureResultUtil::createFractureTriangleGeometry(
|
||||
std::shared_ptr<const RigThermalFractureDefinition> fractureDefinition,
|
||||
int activeTimeStepIndex,
|
||||
double xScaleFactor,
|
||||
double yScaleFactor,
|
||||
double wellPathIntersectionAtFractureDepth,
|
||||
std::vector<cvf::Vec3f>* vertices,
|
||||
std::vector<cvf::uint>* triangleIndices )
|
||||
{
|
||||
// Convert to coordinates relative to center node
|
||||
std::vector<cvf::Vec3d> points = fractureDefinition->relativeCoordinates( activeTimeStepIndex );
|
||||
|
||||
// Create bounding box
|
||||
cvf::BoundingBox boundingBox;
|
||||
for ( auto p : points )
|
||||
boundingBox.add( p );
|
||||
|
||||
// Generate a uniform mesh
|
||||
auto [xCoords, depthCoords] = generateUniformMesh( boundingBox, numSamplesX, numSamplesY );
|
||||
|
||||
// Code adapted from RigStimPlanFractureDefinition
|
||||
std::vector<double> adjustedYs = depthCoords;
|
||||
cvf::uint lenXcoords = static_cast<cvf::uint>( xCoords.size() );
|
||||
|
||||
for ( cvf::uint k = 0; k < adjustedYs.size(); k++ )
|
||||
{
|
||||
for ( cvf::uint i = 0; i < lenXcoords; i++ )
|
||||
{
|
||||
cvf::Vec3f node = cvf::Vec3f( xCoords[i], adjustedYs[k], 0 );
|
||||
vertices->push_back( node );
|
||||
|
||||
if ( i < lenXcoords - 1 && k < adjustedYs.size() - 1 )
|
||||
{
|
||||
double THRESHOLD_VALUE = 1e-5;
|
||||
|
||||
if ( xCoords[i] < THRESHOLD_VALUE )
|
||||
{
|
||||
// Upper triangle
|
||||
triangleIndices->push_back( i + k * lenXcoords );
|
||||
triangleIndices->push_back( ( i + 1 ) + k * lenXcoords );
|
||||
triangleIndices->push_back( ( i + 1 ) + ( k + 1 ) * lenXcoords );
|
||||
// Lower triangle
|
||||
triangleIndices->push_back( i + k * lenXcoords );
|
||||
triangleIndices->push_back( ( i + 1 ) + ( k + 1 ) * lenXcoords );
|
||||
triangleIndices->push_back( ( i ) + ( k + 1 ) * lenXcoords );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Upper triangle
|
||||
triangleIndices->push_back( i + k * lenXcoords );
|
||||
triangleIndices->push_back( ( i + 1 ) + k * lenXcoords );
|
||||
triangleIndices->push_back( ( i ) + ( k + 1 ) * lenXcoords );
|
||||
// Lower triangle
|
||||
triangleIndices->push_back( ( i + 1 ) + k * lenXcoords );
|
||||
triangleIndices->push_back( ( i + 1 ) + ( k + 1 ) * lenXcoords );
|
||||
triangleIndices->push_back( ( i ) + ( k + 1 ) * lenXcoords );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -68,7 +186,27 @@ std::vector<double>
|
||||
const QString& unitName,
|
||||
size_t timeStepIndex )
|
||||
{
|
||||
return std::vector<double>();
|
||||
std::vector<double> fractureGridResults;
|
||||
const std::vector<std::vector<double>>& resultValuesAtTimeStep =
|
||||
getDataAtTimeIndex( fractureDefinition, resultName, unitName, timeStepIndex );
|
||||
|
||||
for ( int i = 0; i < static_cast<int>( numSamplesX ) - 2; i++ )
|
||||
{
|
||||
for ( int j = 0; j < static_cast<int>( numSamplesY ) - 2; j++ )
|
||||
{
|
||||
if ( j + 1 < static_cast<int>( resultValuesAtTimeStep.size() ) &&
|
||||
i + 1 < static_cast<int>( resultValuesAtTimeStep[j + 1].size() ) )
|
||||
{
|
||||
fractureGridResults.push_back( resultValuesAtTimeStep[j + 1][i + 1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
fractureGridResults.push_back( HUGE_VAL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fractureGridResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -83,13 +221,167 @@ cvf::cref<RigFractureGrid>
|
||||
double wellPathIntersectionAtFractureDepth,
|
||||
RiaDefines::EclipseUnitSystem requiredUnitSet )
|
||||
{
|
||||
cvf::ref<RigFractureGrid> fractureGrid = new RigFractureGrid;
|
||||
// Convert to coordinates relative to center node
|
||||
std::vector<cvf::Vec3d> points = fractureDefinition->relativeCoordinates( activeTimeStepIndex );
|
||||
|
||||
QString conductivityUnitTextOnFile;
|
||||
|
||||
std::vector<std::pair<QString, QString>> propertyNamesUnitsOnFile = fractureDefinition->getPropertyNamesUnits();
|
||||
for ( auto properyNameUnit : propertyNamesUnitsOnFile )
|
||||
{
|
||||
if ( resultName == properyNameUnit.first )
|
||||
{
|
||||
conductivityUnitTextOnFile = properyNameUnit.second;
|
||||
}
|
||||
}
|
||||
|
||||
CAF_ASSERT( !conductivityUnitTextOnFile.isEmpty() );
|
||||
if ( conductivityUnitTextOnFile.isEmpty() )
|
||||
{
|
||||
RiaLogging::error( "Did not find unit for conductivity on file" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> conductivityValues =
|
||||
getDataAtTimeIndex( fractureDefinition, resultName, conductivityUnitTextOnFile, activeTimeStepIndex );
|
||||
if ( conductivityValues.empty() )
|
||||
{
|
||||
RiaLogging::error( QString( "No conductivity values found for result: %1" ).arg( resultName ) );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create bounding box
|
||||
cvf::BoundingBox boundingBox;
|
||||
for ( auto p : points )
|
||||
boundingBox.add( p );
|
||||
|
||||
// Generate a uniform mesh
|
||||
auto [xCoordsAtNodes, yCoordsAtNodes] = generateUniformMesh( boundingBox, numSamplesX, numSamplesY );
|
||||
|
||||
// Find center points
|
||||
std::vector<double> xCoords;
|
||||
for ( int i = 0; i < static_cast<int>( xCoordsAtNodes.size() ) - 1; i++ )
|
||||
xCoords.push_back( ( xCoordsAtNodes[i] + xCoordsAtNodes[i + 1] ) / 2 );
|
||||
std::vector<double> depthCoords;
|
||||
for ( int i = 0; i < static_cast<int>( yCoordsAtNodes.size() ) - 1; i++ )
|
||||
depthCoords.push_back( ( yCoordsAtNodes[i] + yCoordsAtNodes[i + 1] ) / 2 );
|
||||
|
||||
std::pair<size_t, size_t> wellCenterStimPlanCellIJ = std::make_pair( 0, 0 );
|
||||
std::vector<RigFractureCell> stimPlanCells;
|
||||
for ( int i = 0; i < static_cast<int>( xCoords.size() ) - 1; i++ )
|
||||
{
|
||||
for ( int j = 0; j < static_cast<int>( depthCoords.size() ) - 1; j++ )
|
||||
{
|
||||
std::vector<cvf::Vec3d> cellPolygon;
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i], depthCoords[j], 0.0 ) );
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i + 1], depthCoords[j], 0.0 ) );
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i + 1], depthCoords[j + 1], 0.0 ) );
|
||||
cellPolygon.push_back( cvf::Vec3d( xCoords[i], depthCoords[j + 1], 0.0 ) );
|
||||
|
||||
RigFractureCell stimPlanCell( cellPolygon, i, j );
|
||||
if ( !conductivityValues.empty() ) // Assuming vector to be of correct length, or no values
|
||||
{
|
||||
stimPlanCell.setConductivityValue( conductivityValues[j + 1][i + 1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
stimPlanCell.setConductivityValue( cvf::UNDEFINED_DOUBLE );
|
||||
}
|
||||
|
||||
// The well path is intersecting the fracture at origo in the fracture coordinate system
|
||||
// Find the Stimplan cell where the well path is intersecting
|
||||
|
||||
if ( cellPolygon[0].x() <= 0.0 && cellPolygon[1].x() >= 0.0 )
|
||||
{
|
||||
if ( cellPolygon[1].y() >= 0.0 && cellPolygon[2].y() <= 0.0 )
|
||||
{
|
||||
wellCenterStimPlanCellIJ = std::make_pair( stimPlanCell.getI(), stimPlanCell.getJ() );
|
||||
}
|
||||
}
|
||||
|
||||
stimPlanCells.push_back( stimPlanCell );
|
||||
}
|
||||
}
|
||||
|
||||
cvf::ref<RigFractureGrid> fractureGrid = new RigFractureGrid;
|
||||
fractureGrid->setFractureCells( stimPlanCells );
|
||||
// fractureGrid->setWellCenterFractureCellIJ( wellCenterStimPlanCellIJ );
|
||||
// fractureGrid->setICellCount( this->m_Xs.size() - 2 );
|
||||
// fractureGrid->setJCellCount( this->m_Ys.size() - 2 );
|
||||
// fractureGrid->ensureCellSearchTreeIsBuilt();
|
||||
fractureGrid->setWellCenterFractureCellIJ( wellCenterStimPlanCellIJ );
|
||||
fractureGrid->setICellCount( numSamplesX - 2 );
|
||||
fractureGrid->setJCellCount( numSamplesY - 2 );
|
||||
fractureGrid->ensureCellSearchTreeIsBuilt();
|
||||
|
||||
return cvf::cref<RigFractureGrid>( fractureGrid.p() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// TODO: adapted from RimEnsembleFractureStatistics. Maybe extract?
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<std::vector<double>, std::vector<double>>
|
||||
RigThermalFractureResultUtil::generateUniformMesh( const cvf::BoundingBox& bb, int numSamplesX, int numSamplesY )
|
||||
{
|
||||
CAF_ASSERT( numSamplesX > 0 );
|
||||
CAF_ASSERT( numSamplesY > 0 );
|
||||
|
||||
double minX = bb.min().x();
|
||||
double maxX = bb.max().x();
|
||||
|
||||
double minY = bb.min().y();
|
||||
double maxY = bb.max().y();
|
||||
|
||||
std::vector<double> gridXs;
|
||||
double sampleDistanceX = linearSampling( minX, maxX, numSamplesX, gridXs );
|
||||
|
||||
std::vector<double> gridYs;
|
||||
double sampleDistanceY = linearSampling( minY, maxY, numSamplesY, gridYs );
|
||||
|
||||
RiaLogging::info( QString( "Uniform Mesh. Output size: %1x%2. Sampling Distance X = %3 Sampling Distance Y = %4" )
|
||||
.arg( numSamplesX )
|
||||
.arg( numSamplesY )
|
||||
.arg( sampleDistanceX )
|
||||
.arg( sampleDistanceY ) );
|
||||
|
||||
return std::make_pair( gridXs, gridYs );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// TODO: duplicated from RimEnsembleFractureStatistics. Extract to util.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigThermalFractureResultUtil::linearSampling( double minValue,
|
||||
double maxValue,
|
||||
int numSamples,
|
||||
std::vector<double>& samples )
|
||||
{
|
||||
CAF_ASSERT( numSamples > 0 );
|
||||
double sampleDistance = ( maxValue - minValue ) / numSamples;
|
||||
|
||||
for ( int s = 0; s < numSamples; s++ )
|
||||
{
|
||||
double pos = minValue + s * sampleDistance + sampleDistance * 0.5;
|
||||
samples.push_back( pos );
|
||||
}
|
||||
|
||||
return sampleDistance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigThermalFractureResultUtil::appendDataToResultStatistics( std::shared_ptr<const RigThermalFractureDefinition> fractureDefinition,
|
||||
const QString& resultName,
|
||||
const QString& unit,
|
||||
MinMaxAccumulator& minMaxAccumulator,
|
||||
PosNegAccumulator& posNegAccumulator )
|
||||
{
|
||||
int propertyIndex = fractureDefinition->getPropertyIndex( resultName );
|
||||
|
||||
size_t maxTs = fractureDefinition->timeSteps().size();
|
||||
for ( size_t ts = 0; ts < maxTs; ts++ )
|
||||
{
|
||||
for ( size_t nodeIndex = 0; nodeIndex < fractureDefinition->numNodes(); nodeIndex++ )
|
||||
{
|
||||
double value = fractureDefinition->getPropertyValue( propertyIndex, nodeIndex, ts );
|
||||
minMaxAccumulator.addValue( value );
|
||||
posNegAccumulator.addValue( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,6 +31,14 @@
|
||||
class RigThermalFractureDefinition;
|
||||
class RigFractureGrid;
|
||||
|
||||
class MinMaxAccumulator;
|
||||
class PosNegAccumulator;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class BoundingBox;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -47,6 +55,7 @@ public:
|
||||
size_t timeStepIndex );
|
||||
|
||||
static void createFractureTriangleGeometry( std::shared_ptr<const RigThermalFractureDefinition> fractureDefinition,
|
||||
int activeTimeStepIndex,
|
||||
double xScaleFactor,
|
||||
double yScaleFactor,
|
||||
double wellPathIntersectionAtFractureDepth,
|
||||
@@ -66,4 +75,16 @@ public:
|
||||
double yScaleFactor,
|
||||
double wellPathIntersectionAtFractureDepth,
|
||||
RiaDefines::EclipseUnitSystem requiredUnitSet );
|
||||
|
||||
static void appendDataToResultStatistics( std::shared_ptr<const RigThermalFractureDefinition> fractureDefinition,
|
||||
const QString& resultName,
|
||||
const QString& unit,
|
||||
MinMaxAccumulator& minMaxAccumulator,
|
||||
PosNegAccumulator& posNegAccumulator );
|
||||
|
||||
private:
|
||||
static std::pair<std::vector<double>, std::vector<double>>
|
||||
generateUniformMesh( const cvf::BoundingBox& bb, int numSamplesX, int numSamplesY );
|
||||
|
||||
static double linearSampling( double minValue, double maxValue, int numSamples, std::vector<double>& samples );
|
||||
};
|
||||
|
@@ -789,8 +789,8 @@ void RiuViewerCommands::handlePickAction( int winPosX, int winPosY, Qt::Keyboard
|
||||
}
|
||||
}
|
||||
|
||||
RimStimPlanFractureTemplate* stimPlanTempl =
|
||||
fracture ? dynamic_cast<RimStimPlanFractureTemplate*>( fracture->fractureTemplate() ) : nullptr;
|
||||
RimMeshFractureTemplate* stimPlanTempl =
|
||||
fracture ? dynamic_cast<RimMeshFractureTemplate*>( fracture->fractureTemplate() ) : nullptr;
|
||||
RimEllipseFractureTemplate* ellipseTempl =
|
||||
fracture ? dynamic_cast<RimEllipseFractureTemplate*>( fracture->fractureTemplate() ) : nullptr;
|
||||
if ( stimPlanTempl || ellipseTempl )
|
||||
|
Reference in New Issue
Block a user