2017-02-07 09:09:00 +01:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 - Statoil 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 "RimStimPlanFractureTemplate.h"
2017-02-20 15:39:15 +01:00
# include "RiaApplication.h"
2017-02-28 10:01:31 +01:00
# include "RiaLogging.h"
2017-02-20 15:39:15 +01:00
2017-02-07 11:08:56 +01:00
# include "RigStimPlanFractureDefinition.h"
2017-02-07 09:09:00 +01:00
2017-02-20 15:39:15 +01:00
# include "RimEclipseView.h"
2017-02-10 15:29:15 +01:00
# include "RimFracture.h"
# include "RimProject.h"
2017-05-11 12:24:57 +02:00
# include "RigStimPlanFracTemplateCell.h"
2017-02-20 15:39:15 +01:00
# include "RimStimPlanColors.h"
2017-02-17 09:29:46 +01:00
# include "RimStimPlanLegendConfig.h"
2017-02-10 15:29:15 +01:00
2017-03-27 14:19:21 +02:00
# include "RivWellFracturePartMgr.h"
2017-02-07 09:09:00 +01:00
# include "cafPdmObject.h"
2017-02-17 15:10:04 +01:00
# include "cafPdmUiDoubleSliderEditor.h"
2017-02-09 10:52:05 +01:00
# include "cafPdmUiFilePathEditor.h"
2017-02-07 09:09:00 +01:00
# include "cvfVector3.h"
2017-02-09 10:52:05 +01:00
2017-02-07 11:08:56 +01:00
# include <QFileInfo>
2017-02-09 10:52:05 +01:00
# include <QMessageBox>
2017-02-07 09:09:00 +01:00
2017-02-17 11:03:20 +01:00
# include <algorithm>
2017-03-17 11:28:00 +01:00
# include <vector>
2017-04-20 12:16:13 +02:00
# include <cmath>
# include "RigFractureTransCalc.h"
2017-02-17 11:03:20 +01:00
2017-02-07 09:09:00 +01:00
CAF_PDM_SOURCE_INIT ( RimStimPlanFractureTemplate , " RimStimPlanFractureTemplate " ) ;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimStimPlanFractureTemplate : : RimStimPlanFractureTemplate ( void )
{
CAF_PDM_InitObject ( " Fracture Template " , " :/FractureTemplate16x16.png " , " " , " " ) ;
2017-02-22 11:52:06 +01:00
CAF_PDM_InitField ( & m_stimPlanFileName , " StimPlanFileName " , QString ( " " ) , " File Name " , " " , " " , " " ) ;
2017-02-10 15:29:15 +01:00
m_stimPlanFileName . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiFilePathEditor : : uiEditorTypeName ( ) ) ;
2017-02-22 11:52:06 +01:00
CAF_PDM_InitField ( & wellPathDepthAtFracture , " WellPathDepthAtFracture " , 0.0 , " Well/Fracture Intersection Depth " , " " , " " , " " ) ;
2017-02-17 15:10:04 +01:00
wellPathDepthAtFracture . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiDoubleSliderEditor : : uiEditorTypeName ( ) ) ;
2017-02-27 14:55:12 +01:00
CAF_PDM_InitField ( & parameterForPolygon , " parameterForPolyton " , QString ( " " ) , " Parameter " , " " , " " , " " ) ;
2017-04-07 10:17:17 +02:00
CAF_PDM_InitField ( & activeTimeStepIndex , " activeTimeStepIndex " , 0 , " Active TimeStep Index " , " " , " " , " " ) ;
2017-04-25 16:08:44 +02:00
CAF_PDM_InitField ( & showStimPlanMesh , " showStimPlanMesh " , true , " Show StimPlan Mesh " , " " , " " , " " ) ;
2017-02-27 14:55:12 +01:00
2017-04-25 16:08:44 +02:00
//TODO: Is this correct way of doing this...?
wellCenterStimPlanCellIJ = std : : make_pair ( 0 , 0 ) ;
2017-02-07 09:09:00 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimStimPlanFractureTemplate : : ~ RimStimPlanFractureTemplate ( )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : fieldChangedByUi ( const caf : : PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
2017-02-23 09:47:30 +01:00
RimFractureTemplate : : fieldChangedByUi ( changedField , oldValue , newValue ) ;
2017-02-07 11:08:56 +01:00
2017-02-10 15:29:15 +01:00
if ( & m_stimPlanFileName = = changedField )
2017-02-07 11:08:56 +01:00
{
updateUiTreeName ( ) ;
2017-02-17 09:29:46 +01:00
loadDataAndUpdate ( ) ;
2017-03-02 11:43:28 +01:00
setDefaultsBasedOnXMLfile ( ) ;
2017-02-07 11:08:56 +01:00
}
2017-02-10 15:29:15 +01:00
2017-04-07 11:02:31 +02:00
if ( & activeTimeStepIndex = = changedField )
{
2017-04-07 12:46:09 +02:00
setupStimPlanCells ( ) ;
2017-04-07 11:02:31 +02:00
//Changes to this parameters should change all fractures with this fracture template attached.
RimProject * proj ;
this - > firstAncestorOrThisOfType ( proj ) ;
if ( proj )
{
std : : vector < RimFracture * > fractures ;
proj - > descendantsIncludingThisOfType ( fractures ) ;
for ( RimFracture * fracture : fractures )
{
if ( fracture - > attachedFractureDefinition ( ) = = this )
{
fracture - > stimPlanTimeIndexToPlot = activeTimeStepIndex ;
fracture - > setRecomputeGeometryFlag ( ) ;
}
}
proj - > createDisplayModelAndRedrawAllViews ( ) ;
}
}
2017-04-07 10:17:17 +02:00
if ( & wellPathDepthAtFracture = = changedField | | & parameterForPolygon = = changedField | | & activeTimeStepIndex = = changedField | | & showStimPlanMesh = = changedField )
2017-02-10 15:29:15 +01:00
{
RimProject * proj ;
this - > firstAncestorOrThisOfType ( proj ) ;
if ( proj )
{
//Regenerate geometry
std : : vector < RimFracture * > fractures ;
proj - > descendantsIncludingThisOfType ( fractures ) ;
for ( RimFracture * fracture : fractures )
{
if ( fracture - > attachedFractureDefinition ( ) = = this )
{
fracture - > setRecomputeGeometryFlag ( ) ;
}
}
}
proj - > createDisplayModelAndRedrawAllViews ( ) ;
}
2017-02-07 09:09:00 +01:00
}
2017-02-07 11:08:56 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : updateUiTreeName ( )
{
2017-02-10 15:29:15 +01:00
this - > uiCapability ( ) - > setUiName ( fileNameWithOutPath ( ) ) ;
2017-02-07 11:08:56 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setFileName ( const QString & fileName )
{
2017-02-10 15:29:15 +01:00
m_stimPlanFileName = fileName ;
2017-02-07 11:08:56 +01:00
updateUiTreeName ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString & RimStimPlanFractureTemplate : : fileName ( )
{
2017-02-10 15:29:15 +01:00
return m_stimPlanFileName ( ) ;
2017-02-07 11:08:56 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-02-10 15:29:15 +01:00
QString RimStimPlanFractureTemplate : : fileNameWithOutPath ( )
2017-02-07 11:08:56 +01:00
{
2017-02-10 15:29:15 +01:00
QFileInfo stimplanfileFileInfo ( m_stimPlanFileName ( ) ) ;
2017-02-07 11:08:56 +01:00
return stimplanfileFileInfo . fileName ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : readStimPlanXMLFile ( QString * errorMessage )
{
2017-02-28 10:01:31 +01:00
RiaLogging : : info ( QString ( " Starting to open StimPlan XML file: '%1' " ) . arg ( fileName ( ) ) ) ;
2017-02-15 10:32:34 +01:00
m_stimPlanFractureDefinitionData = new RigStimPlanFractureDefinition ;
2017-02-27 10:50:55 +01:00
size_t startingNegXsValues = 0 ;
2017-02-15 10:32:34 +01:00
{
QFile dataFile ( m_stimPlanFileName ( ) ) ;
if ( ! dataFile . open ( QFile : : ReadOnly ) )
{
if ( errorMessage ) ( * errorMessage ) + = " Could not open the File: " + ( m_stimPlanFileName ( ) ) + " \n " ;
return ;
}
QXmlStreamReader xmlStream ;
xmlStream . setDevice ( & dataFile ) ;
xmlStream . readNext ( ) ;
2017-02-27 10:50:55 +01:00
startingNegXsValues = readStimplanGridAndTimesteps ( xmlStream ) ;
2017-02-28 10:01:31 +01:00
2017-02-15 10:32:34 +01:00
if ( xmlStream . hasError ( ) )
{
2017-02-28 10:01:31 +01:00
RiaLogging : : error ( QString ( " Failed to parse file '%1' " ) . arg ( dataFile . fileName ( ) ) ) ;
RiaLogging : : error ( xmlStream . errorString ( ) ) ;
2017-02-15 10:32:34 +01:00
}
dataFile . close ( ) ;
}
2017-02-28 10:01:31 +01:00
size_t numberOfDepthValues = m_stimPlanFractureDefinitionData - > depths . size ( ) ;
RiaLogging : : debug ( QString ( " Grid size X: %1, Y: %2 " ) . arg ( QString : : number ( m_stimPlanFractureDefinitionData - > gridXs . size ( ) ) ,
QString : : number ( numberOfDepthValues ) ) ) ;
size_t numberOfTimeSteps = m_stimPlanFractureDefinitionData - > timeSteps . size ( ) ;
RiaLogging : : debug ( QString ( " Number of time-steps: %1 " ) . arg ( numberOfTimeSteps ) ) ;
2017-02-15 10:32:34 +01:00
//Start reading from top:
2017-02-10 15:29:15 +01:00
QFile dataFile ( m_stimPlanFileName ( ) ) ;
2017-02-09 10:52:05 +01:00
if ( ! dataFile . open ( QFile : : ReadOnly ) )
{
2017-02-10 15:29:15 +01:00
if ( errorMessage ) ( * errorMessage ) + = " Could not open the File: " + ( m_stimPlanFileName ( ) ) + " \n " ;
2017-02-09 10:52:05 +01:00
return ;
}
2017-02-15 10:32:34 +01:00
QXmlStreamReader xmlStream2 ;
xmlStream2 . setDevice ( & dataFile ) ;
2017-02-09 10:52:05 +01:00
QString parameter ;
2017-02-17 10:10:06 +01:00
QString unit ;
2017-02-09 10:52:05 +01:00
2017-02-28 10:01:31 +01:00
RiaLogging : : info ( QString ( " Properties available in file: " ) ) ;
2017-02-15 10:32:34 +01:00
while ( ! xmlStream2 . atEnd ( ) )
2017-02-09 10:52:05 +01:00
{
2017-02-15 10:32:34 +01:00
xmlStream2 . readNext ( ) ;
2017-02-09 10:52:05 +01:00
2017-02-15 10:32:34 +01:00
if ( xmlStream2 . isStartElement ( ) )
2017-02-09 10:52:05 +01:00
{
2017-02-15 10:32:34 +01:00
if ( xmlStream2 . name ( ) = = " property " )
{
2017-02-17 10:10:06 +01:00
unit = getAttributeValueString ( xmlStream2 , " uom " ) ;
2017-02-15 10:32:34 +01:00
parameter = getAttributeValueString ( xmlStream2 , " name " ) ;
2017-02-28 10:01:31 +01:00
RiaLogging : : info ( QString ( " %1 [%2] " ) . arg ( parameter , unit ) ) ;
2017-02-17 10:10:06 +01:00
2017-03-29 14:05:25 +02:00
if ( parameter = = " CONDUCTIVITY " )
{
if ( unit = = " md-ft " )
{
fractureTemplateUnit = RimDefines : : UNITS_FIELD ;
RiaLogging : : info ( QString ( " Setting unit system to Field for StimPlan fracture template %1 " ) . arg ( name ) ) ;
}
if ( unit = = " md-m " )
{
fractureTemplateUnit = RimDefines : : UNITS_METRIC ;
RiaLogging : : info ( QString ( " Setting unit system to Metric for StimPlan fracture template %1 " ) . arg ( name ) ) ;
}
}
2017-02-09 10:52:05 +01:00
}
2017-02-15 10:32:34 +01:00
else if ( xmlStream2 . name ( ) = = " time " )
2017-02-09 10:52:05 +01:00
{
2017-02-15 10:32:34 +01:00
double timeStepValue = getAttributeValueDouble ( xmlStream2 , " value " ) ;
2017-02-27 10:50:55 +01:00
std : : vector < std : : vector < double > > propertyValuesAtTimestep = getAllDepthDataAtTimeStep ( xmlStream2 , startingNegXsValues ) ;
2017-02-15 10:32:34 +01:00
bool valuesOK = numberOfParameterValuesOK ( propertyValuesAtTimestep ) ;
if ( ! valuesOK )
{
2017-02-28 10:01:31 +01:00
RiaLogging : : error ( QString ( " Inconsistency detected in reading XML file: '%1' " ) . arg ( dataFile . fileName ( ) ) ) ;
2017-02-15 10:32:34 +01:00
return ;
}
2017-02-09 10:52:05 +01:00
2017-02-17 12:17:57 +01:00
m_stimPlanFractureDefinitionData - > setDataAtTimeValue ( parameter , unit , propertyValuesAtTimestep , timeStepValue ) ;
2017-02-09 10:52:05 +01:00
}
}
}
dataFile . close ( ) ;
2017-02-15 10:32:34 +01:00
if ( xmlStream2 . hasError ( ) )
2017-02-09 10:52:05 +01:00
{
2017-02-28 10:01:31 +01:00
RiaLogging : : error ( QString ( " Failed to parse file: '%1' " ) . arg ( dataFile . fileName ( ) ) ) ;
RiaLogging : : error ( xmlStream2 . errorString ( ) ) ;
2017-02-09 10:52:05 +01:00
}
else if ( dataFile . error ( ) ! = QFile : : NoError )
{
2017-02-28 10:01:31 +01:00
RiaLogging : : error ( QString ( " Cannot read file: '%1' " ) . arg ( dataFile . fileName ( ) ) ) ;
RiaLogging : : error ( dataFile . errorString ( ) ) ;
}
else
{
RiaLogging : : info ( QString ( " Successfully read XML file: '%1' " ) . arg ( fileName ( ) ) ) ;
2017-02-09 10:52:05 +01:00
}
2017-02-17 10:10:06 +01:00
2017-03-02 11:43:28 +01:00
RimEclipseView * activeView = dynamic_cast < RimEclipseView * > ( RiaApplication : : instance ( ) - > activeReservoirView ( ) ) ;
2017-02-20 15:39:15 +01:00
if ( ! activeView ) return ;
activeView - > stimPlanColors - > loadDataAndUpdate ( ) ;
2017-02-09 10:52:05 +01:00
}
2017-03-02 11:43:28 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setDefaultsBasedOnXMLfile ( )
{
setDepthOfWellPathAtFracture ( ) ;
RiaLogging : : info ( QString ( " Setting well/fracture intersection depth at %1 " ) . arg ( wellPathDepthAtFracture ) ) ;
2017-04-07 10:17:17 +02:00
activeTimeStepIndex = static_cast < int > ( m_stimPlanFractureDefinitionData - > totalNumberTimeSteps ( ) - 1 ) ;
2017-03-02 11:43:28 +01:00
bool polygonPropertySet = setPropertyForPolygonDefault ( ) ;
2017-04-07 10:17:17 +02:00
if ( polygonPropertySet ) RiaLogging : : info ( QString ( " Calculating polygon outline based on %1 at timestep %2 " ) . arg ( parameterForPolygon ) . arg ( m_stimPlanFractureDefinitionData - > timeSteps [ activeTimeStepIndex ] ) ) ;
2017-03-02 11:43:28 +01:00
else RiaLogging : : info ( QString ( " Property for polygon calculation not set. " ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimStimPlanFractureTemplate : : setPropertyForPolygonDefault ( )
{
//first option: Width
for ( std : : pair < QString , QString > property : getStimPlanPropertyNamesUnits ( ) )
{
if ( property . first = = " WIDTH " )
{
2017-03-15 15:02:20 +01:00
parameterForPolygon = property . first ;
2017-03-02 11:43:28 +01:00
return true ;
}
}
//if width not found, use conductivity
for ( std : : pair < QString , QString > property : getStimPlanPropertyNamesUnits ( ) )
{
if ( property . first = = " CONDUCTIVITY " )
{
2017-03-15 15:02:20 +01:00
parameterForPolygon = property . first ;
2017-03-02 11:43:28 +01:00
return true ;
}
}
return false ;
}
2017-02-15 15:49:53 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : loadDataAndUpdate ( )
{
QString errorMessage ;
readStimPlanXMLFile ( & errorMessage ) ;
2017-02-28 10:01:31 +01:00
if ( errorMessage . size ( ) > 0 ) RiaLogging : : error ( errorMessage ) ;
2017-02-17 09:29:46 +01:00
2017-04-07 10:17:17 +02:00
setupStimPlanCells ( ) ;
2017-04-06 09:34:38 +02:00
2017-02-17 09:29:46 +01:00
updateConnectedEditors ( ) ;
2017-02-15 15:49:53 +01:00
}
2017-02-17 14:11:47 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-02-20 09:31:24 +01:00
std : : vector < std : : vector < double > > RimStimPlanFractureTemplate : : getDataAtTimeIndex ( const QString & resultName , const QString & unitName , size_t timeStepIndex ) const
2017-02-17 14:11:47 +01:00
{
2017-02-20 09:31:24 +01:00
return m_stimPlanFractureDefinitionData - > getDataAtTimeIndex ( resultName , unitName , timeStepIndex ) ;
2017-02-17 14:11:47 +01:00
}
2017-03-17 11:28:00 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < std : : vector < double > > RimStimPlanFractureTemplate : : getMirroredDataAtTimeIndex ( const QString & resultName , const QString & unitName , size_t timeStepIndex ) const
{
std : : vector < std : : vector < double > > notMirrordedData = m_stimPlanFractureDefinitionData - > getDataAtTimeIndex ( resultName , unitName , timeStepIndex ) ;
std : : vector < std : : vector < double > > mirroredData ;
for ( std : : vector < double > depthData : notMirrordedData )
{
std : : vector < double > mirrordDepthData = RivWellFracturePartMgr : : mirrorDataAtSingleDepth ( depthData ) ;
mirroredData . push_back ( mirrordDepthData ) ;
}
return mirroredData ;
}
2017-02-27 14:55:12 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf : : PdmOptionItemInfo > RimStimPlanFractureTemplate : : calculateValueOptions ( const caf : : PdmFieldHandle * fieldNeedingOptions , bool * useOptionsOnly )
{
QList < caf : : PdmOptionItemInfo > options ;
if ( fieldNeedingOptions = = & parameterForPolygon )
{
for ( std : : pair < QString , QString > nameUnit : getStimPlanPropertyNamesUnits ( ) )
{
2017-03-15 15:02:20 +01:00
//options.push_back(caf::PdmOptionItemInfo(nameUnit.first + " [" + nameUnit.second + "]", nameUnit.first + " " + nameUnit.second));
options . push_back ( caf : : PdmOptionItemInfo ( nameUnit . first , nameUnit . first ) ) ;
2017-02-27 14:55:12 +01:00
}
}
2017-04-07 10:17:17 +02:00
else if ( fieldNeedingOptions = = & activeTimeStepIndex )
2017-02-27 14:55:12 +01:00
{
std : : vector < double > timeValues = getStimPlanTimeValues ( ) ;
int index = 0 ;
for ( double value : timeValues )
{
options . push_back ( caf : : PdmOptionItemInfo ( QString : : number ( value ) , index ) ) ;
index + + ;
}
}
return options ;
}
2017-02-09 10:52:05 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-02-27 10:50:55 +01:00
size_t RimStimPlanFractureTemplate : : readStimplanGridAndTimesteps ( QXmlStreamReader & xmlStream )
2017-02-15 10:32:34 +01:00
{
2017-02-27 10:50:55 +01:00
size_t startNegValuesXs = 0 ;
size_t startNegValuesYs = 0 ;
2017-02-15 10:32:34 +01:00
xmlStream . readNext ( ) ;
//First, read time steps and grid to establish data structures for putting data into later.
while ( ! xmlStream . atEnd ( ) )
{
xmlStream . readNext ( ) ;
if ( xmlStream . isStartElement ( ) )
{
if ( xmlStream . name ( ) = = " xs " )
{
2017-02-27 10:50:55 +01:00
std : : vector < double > gridValues ;
getGriddingValues ( xmlStream , gridValues , startNegValuesXs ) ;
m_stimPlanFractureDefinitionData - > gridXs = gridValues ;
2017-02-15 10:32:34 +01:00
}
else if ( xmlStream . name ( ) = = " ys " )
{
2017-02-27 10:50:55 +01:00
std : : vector < double > gridValues ;
getGriddingValues ( xmlStream , gridValues , startNegValuesYs ) ;
m_stimPlanFractureDefinitionData - > gridYs = gridValues ;
2017-02-15 10:32:34 +01:00
m_stimPlanFractureDefinitionData - > reorderYgridToDepths ( ) ;
}
else if ( xmlStream . name ( ) = = " time " )
{
double timeStepValue = getAttributeValueDouble ( xmlStream , " value " ) ;
if ( ! m_stimPlanFractureDefinitionData - > timeStepExisist ( timeStepValue ) )
{
m_stimPlanFractureDefinitionData - > timeSteps . push_back ( timeStepValue ) ;
}
}
}
}
2017-02-27 10:50:55 +01:00
if ( startNegValuesYs > 0 )
{
2017-02-28 10:01:31 +01:00
RiaLogging : : error ( QString ( " Negative depth values detected in XML file " ) ) ;
2017-02-27 10:50:55 +01:00
}
return startNegValuesXs ;
2017-02-15 10:32:34 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-02-27 10:50:55 +01:00
std : : vector < std : : vector < double > > RimStimPlanFractureTemplate : : getAllDepthDataAtTimeStep ( QXmlStreamReader & xmlStream , size_t startingNegValuesXs )
2017-02-09 10:52:05 +01:00
{
std : : vector < std : : vector < double > > propertyValuesAtTimestep ;
while ( ! ( xmlStream . isEndElement ( ) & & xmlStream . name ( ) = = " time " ) )
{
xmlStream . readNext ( ) ;
2017-02-15 10:32:34 +01:00
2017-02-09 10:52:05 +01:00
if ( xmlStream . name ( ) = = " depth " )
{
double depth = xmlStream . readElementText ( ) . toDouble ( ) ;
std : : vector < double > propertyValuesAtDepth ;
xmlStream . readNext ( ) ; //read end depth token
xmlStream . readNext ( ) ; //read cdata section with values
if ( xmlStream . isCDATA ( ) )
{
QString depthDataStr = xmlStream . text ( ) . toString ( ) ;
2017-02-27 10:50:55 +01:00
for ( int i = 0 ; i < depthDataStr . split ( ' ' ) . size ( ) ; i + + )
2017-02-09 10:52:05 +01:00
{
2017-02-27 10:50:55 +01:00
if ( i < startingNegValuesXs ) continue ;
else
2017-02-15 10:32:34 +01:00
{
2017-02-27 10:50:55 +01:00
QString value = depthDataStr . split ( ' ' ) [ i ] ;
if ( value ! = " " )
{
propertyValuesAtDepth . push_back ( value . toDouble ( ) ) ;
}
2017-02-15 10:32:34 +01:00
}
2017-02-09 10:52:05 +01:00
}
}
propertyValuesAtTimestep . push_back ( propertyValuesAtDepth ) ;
}
}
return propertyValuesAtTimestep ;
}
2017-02-15 10:32:34 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimStimPlanFractureTemplate : : numberOfParameterValuesOK ( std : : vector < std : : vector < double > > propertyValuesAtTimestep )
{
size_t depths = m_stimPlanFractureDefinitionData - > depths . size ( ) ;
size_t gridXvalues = m_stimPlanFractureDefinitionData - > gridXs . size ( ) ;
if ( propertyValuesAtTimestep . size ( ) ! = depths ) return false ;
for ( std : : vector < double > valuesAtDepthVector : propertyValuesAtTimestep )
{
if ( valuesAtDepthVector . size ( ) ! = gridXvalues ) return false ;
}
return true ;
}
2017-02-17 15:10:04 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setDepthOfWellPathAtFracture ( )
{
if ( ! m_stimPlanFractureDefinitionData . isNull ( ) )
{
double firstDepth = m_stimPlanFractureDefinitionData - > depths [ 0 ] ;
double lastDepth = m_stimPlanFractureDefinitionData - > depths [ m_stimPlanFractureDefinitionData - > depths . size ( ) - 1 ] ;
double averageDepth = ( firstDepth + lastDepth ) / 2 ;
wellPathDepthAtFracture = averageDepth ;
}
}
2017-03-15 15:02:20 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimStimPlanFractureTemplate : : getUnitForStimPlanParameter ( QString parameterName )
{
QString unit ;
bool found = false ;
bool foundMultiple = false ;
for ( std : : pair < QString , QString > nameUnit : getStimPlanPropertyNamesUnits ( ) )
{
if ( nameUnit . first = = parameterName )
{
unit = nameUnit . second ;
if ( found ) foundMultiple = true ;
found = true ;
}
}
if ( foundMultiple ) RiaLogging : : error ( QString ( " Multiple units found for same parameter " ) ) ;
if ( ! found ) RiaLogging : : error ( QString ( " Unit for parameter not found " ) ) ;
return unit ;
}
2017-02-09 10:52:05 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-02-27 10:50:55 +01:00
void RimStimPlanFractureTemplate : : getGriddingValues ( QXmlStreamReader & xmlStream , std : : vector < double > & gridValues , size_t & startNegValues )
2017-02-09 10:52:05 +01:00
{
QString gridValuesString = xmlStream . readElementText ( ) . replace ( ' \n ' , ' ' ) ;
for ( QString value : gridValuesString . split ( ' ' ) )
{
2017-02-27 10:50:55 +01:00
if ( value . size ( ) > 0 )
{
double gridValue = value . toDouble ( ) ;
if ( gridValue > - 1e-5 ) //tolerance of 1e-5
{
gridValues . push_back ( gridValue ) ;
}
else startNegValues + + ;
}
2017-02-09 10:52:05 +01:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimStimPlanFractureTemplate : : getAttributeValueDouble ( QXmlStreamReader & xmlStream , QString parameterName )
{
double value = cvf : : UNDEFINED_DOUBLE ;
for ( const QXmlStreamAttribute & attr : xmlStream . attributes ( ) )
{
if ( attr . name ( ) = = parameterName )
{
value = attr . value ( ) . toString ( ) . toDouble ( ) ;
}
}
return value ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimStimPlanFractureTemplate : : getAttributeValueString ( QXmlStreamReader & xmlStream , QString parameterName )
{
QString parameterValue ;
for ( const QXmlStreamAttribute & attr : xmlStream . attributes ( ) )
{
if ( attr . name ( ) = = parameterName )
{
parameterValue = attr . value ( ) . toString ( ) ;
}
}
return parameterValue ;
2017-02-07 11:08:56 +01:00
}
2017-02-07 09:09:00 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-02 10:08:45 +01:00
void RimStimPlanFractureTemplate : : fractureGeometry ( std : : vector < cvf : : Vec3f > * nodeCoords , std : : vector < cvf : : uint > * triangleIndices , caf : : AppEnum < RimDefines : : UnitSystem > fractureUnit )
2017-02-07 09:09:00 +01:00
{
2017-02-10 15:29:15 +01:00
if ( m_stimPlanFractureDefinitionData . isNull ( ) )
{
2017-02-15 15:49:53 +01:00
loadDataAndUpdate ( ) ;
2017-02-10 15:29:15 +01:00
}
2017-02-13 13:46:49 +01:00
std : : vector < double > xCoords = getNegAndPosXcoords ( ) ;
cvf : : uint lenXcoords = static_cast < cvf : : uint > ( xCoords . size ( ) ) ;
2017-02-10 15:29:15 +01:00
2017-02-13 13:46:49 +01:00
std : : vector < double > adjustedDepths = adjustedDepthCoordsAroundWellPathPosition ( ) ;
2017-02-10 15:29:15 +01:00
2017-03-02 10:08:45 +01:00
if ( fractureUnit = = fractureTemplateUnit ( ) )
{
RiaLogging : : debug ( QString ( " No conversion necessary for %1 " ) . arg ( name ) ) ;
}
else if ( fractureTemplateUnit ( ) = = RimDefines : : UNITS_METRIC & & fractureUnit = = RimDefines : : UNITS_FIELD )
{
RiaLogging : : info ( QString ( " Converting StimPlan geometry from metric to field for fracture template %1 " ) . arg ( name ) ) ;
for ( double & value : adjustedDepths ) value = RimDefines : : meterToFeet ( value ) ;
for ( double & value : xCoords ) value = RimDefines : : meterToFeet ( value ) ;
}
else if ( fractureTemplateUnit ( ) = = RimDefines : : UNITS_FIELD & & fractureUnit = = RimDefines : : UNITS_METRIC )
{
RiaLogging : : info ( QString ( " Converting StimPlan geometry from field to metric for fracture template %1 " ) . arg ( name ) ) ;
for ( double & value : adjustedDepths ) value = RimDefines : : feetToMeter ( value ) ;
for ( double & value : xCoords ) value = RimDefines : : feetToMeter ( value ) ;
}
else
{
//Should never get here...
RiaLogging : : error ( QString ( " Error: Could not convert units for fracture template %1 " ) . arg ( name ) ) ;
return ;
}
2017-02-13 13:46:49 +01:00
for ( cvf : : uint k = 0 ; k < adjustedDepths . size ( ) ; k + + )
2017-02-10 15:29:15 +01:00
{
2017-02-13 13:46:49 +01:00
for ( cvf : : uint i = 0 ; i < lenXcoords ; i + + )
2017-02-10 15:29:15 +01:00
{
2017-02-13 13:46:49 +01:00
cvf : : Vec3f node = cvf : : Vec3f ( xCoords [ i ] , adjustedDepths [ k ] , 0 ) ;
nodeCoords - > push_back ( node ) ;
2017-02-10 15:29:15 +01:00
2017-02-13 13:46:49 +01:00
if ( i < lenXcoords - 1 & & k < adjustedDepths . size ( ) - 1 )
{
2017-02-16 13:05:40 +01:00
if ( xCoords [ i ] < 1e-5 )
{
//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 ) ;
}
2017-02-13 13:46:49 +01:00
}
2017-02-10 15:29:15 +01:00
}
}
2017-02-13 13:46:49 +01:00
2017-02-10 15:29:15 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < double > RimStimPlanFractureTemplate : : getNegAndPosXcoords ( )
{
std : : vector < double > allXcoords ;
for ( const double & xCoord : m_stimPlanFractureDefinitionData - > gridXs )
{
if ( xCoord > 1e-5 )
{
double negXcoord = - xCoord ;
allXcoords . insert ( allXcoords . begin ( ) , negXcoord ) ;
}
}
for ( const double & xCoord : m_stimPlanFractureDefinitionData - > gridXs )
{
allXcoords . push_back ( xCoord ) ;
}
return allXcoords ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < double > RimStimPlanFractureTemplate : : adjustedDepthCoordsAroundWellPathPosition ( )
{
std : : vector < double > depthRelativeToWellPath ;
for ( const double & depth : m_stimPlanFractureDefinitionData - > depths )
{
double adjustedDepth = depth - wellPathDepthAtFracture ( ) ;
2017-04-21 09:29:28 +02:00
adjustedDepth = - adjustedDepth ;
2017-02-10 15:29:15 +01:00
depthRelativeToWellPath . push_back ( adjustedDepth ) ;
}
return depthRelativeToWellPath ;
2017-02-07 09:09:00 +01:00
}
2017-02-15 12:16:01 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < double > RimStimPlanFractureTemplate : : getStimPlanTimeValues ( )
{
2017-02-15 15:49:53 +01:00
if ( m_stimPlanFractureDefinitionData . isNull ( ) ) loadDataAndUpdate ( ) ;
2017-02-15 12:16:01 +01:00
return m_stimPlanFractureDefinitionData - > timeSteps ;
}
2017-02-17 14:11:47 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-02-20 09:31:24 +01:00
std : : vector < std : : pair < QString , QString > > RimStimPlanFractureTemplate : : getStimPlanPropertyNamesUnits ( ) const
2017-02-17 14:11:47 +01:00
{
std : : vector < std : : pair < QString , QString > > propertyNamesUnits ;
2017-02-23 10:14:28 +01:00
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
2017-02-17 14:11:47 +01:00
{
2017-02-23 10:14:28 +01:00
std : : vector < RigStimPlanData > allStimPlanData = m_stimPlanFractureDefinitionData - > stimPlanData ;
for ( RigStimPlanData stimPlanDataEntry : allStimPlanData )
{
propertyNamesUnits . push_back ( std : : make_pair ( stimPlanDataEntry . resultName , stimPlanDataEntry . unit ) ) ;
}
2017-02-17 14:11:47 +01:00
}
return propertyNamesUnits ;
}
2017-02-20 09:31:24 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : computeMinMax ( const QString & resultName , const QString & unitName , double * minValue , double * maxValue ) const
{
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
m_stimPlanFractureDefinitionData - > computeMinMax ( resultName , unitName , minValue , maxValue ) ;
}
}
2017-03-17 11:28:00 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : getStimPlanDataAsPolygonsAndValues ( std : : vector < std : : vector < cvf : : Vec3d > > & cellsAsPolygons , std : : vector < double > & parameterValues , const QString & resultName , const QString & unitName , size_t timeStepIndex )
{
std : : vector < std : : vector < double > > propertyValuesAtTimeStep = getMirroredDataAtTimeIndex ( resultName , unitName , timeStepIndex ) ;
cellsAsPolygons . clear ( ) ;
parameterValues . clear ( ) ;
//TODO: Code partly copied from RivWellFracturePartMgr - can this be combined in some function?
std : : vector < double > depthCoordsAtNodes = adjustedDepthCoordsAroundWellPathPosition ( ) ;
std : : vector < double > xCoordsAtNodes = getNegAndPosXcoords ( ) ;
//Cells are around nodes instead of between nodes
std : : vector < double > xCoords ;
2017-03-17 13:44:46 +01:00
for ( int i = 0 ; i < xCoordsAtNodes . size ( ) - 1 ; i + + ) xCoords . push_back ( ( xCoordsAtNodes [ i ] + xCoordsAtNodes [ i + 1 ] ) / 2 ) ;
2017-03-17 11:28:00 +01:00
std : : vector < double > depthCoords ;
2017-03-17 13:44:46 +01:00
for ( int i = 0 ; i < depthCoordsAtNodes . size ( ) - 1 ; i + + ) depthCoords . push_back ( ( depthCoordsAtNodes [ i ] + depthCoordsAtNodes [ i + 1 ] ) / 2 ) ;
2017-03-17 11:28:00 +01:00
for ( int i = 0 ; i < xCoords . size ( ) - 1 ; i + + )
{
for ( int j = 0 ; j < depthCoords . size ( ) - 1 ; j + + )
{
std : : vector < cvf : : Vec3d > cellAsPolygon ;
cellAsPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i ] ) , static_cast < float > ( depthCoords [ j ] ) , 0.0 ) ) ;
cellAsPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i + 1 ] ) , static_cast < float > ( depthCoords [ j ] ) , 0.0 ) ) ;
cellAsPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i + 1 ] ) , static_cast < float > ( depthCoords [ j + 1 ] ) , 0.0 ) ) ;
cellAsPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i ] ) , static_cast < float > ( depthCoords [ j + 1 ] ) , 0.0 ) ) ;
cellsAsPolygons . push_back ( cellAsPolygon ) ;
//TODO: Values for both neg and pos x values...
parameterValues . push_back ( propertyValuesAtTimeStep [ j + 1 ] [ i + 1 ] ) ; //TODO test that this value exsist...
}
}
}
2017-03-27 14:19:21 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-04-07 10:17:17 +02:00
void RimStimPlanFractureTemplate : : setupStimPlanCells ( )
2017-03-27 14:19:21 +02:00
{
2017-04-07 10:17:17 +02:00
RimEclipseView * activeView = dynamic_cast < RimEclipseView * > ( RiaApplication : : instance ( ) - > activeReservoirView ( ) ) ;
if ( ! activeView ) return ;
QString resultNameFromColors = activeView - > stimPlanColors - > resultName ( ) ;
QString resultUnitFromColors = activeView - > stimPlanColors - > unit ( ) ;
2017-04-06 09:34:38 +02:00
2017-05-11 12:24:57 +02:00
std : : vector < RigStimPlanFracTemplateCell > stimPlanCells ;
2017-04-25 16:08:44 +02:00
bool wellCenterStimPlanCellFound = false ;
2017-04-06 09:34:38 +02:00
2017-04-07 10:17:17 +02:00
std : : vector < std : : vector < double > > displayPropertyValuesAtTimeStep = getMirroredDataAtTimeIndex ( resultNameFromColors , resultUnitFromColors , activeTimeStepIndex ) ;
2017-04-06 09:34:38 +02:00
2017-04-07 10:17:17 +02:00
QString condUnit ;
if ( fractureTemplateUnit = = RimDefines : : UNITS_METRIC ) condUnit = " md-m " ;
if ( fractureTemplateUnit = = RimDefines : : UNITS_FIELD ) condUnit = " md-ft " ;
std : : vector < std : : vector < double > > conductivityValuesAtTimeStep = getMirroredDataAtTimeIndex ( " CONDUCTIVITY " , condUnit , activeTimeStepIndex ) ;
2017-03-27 14:19:21 +02:00
std : : vector < double > depthCoordsAtNodes = adjustedDepthCoordsAroundWellPathPosition ( ) ;
std : : vector < double > xCoordsAtNodes = getNegAndPosXcoords ( ) ;
std : : vector < double > xCoords ;
for ( int i = 0 ; i < xCoordsAtNodes . size ( ) - 1 ; i + + ) xCoords . push_back ( ( xCoordsAtNodes [ i ] + xCoordsAtNodes [ i + 1 ] ) / 2 ) ;
std : : vector < double > depthCoords ;
for ( int i = 0 ; i < depthCoordsAtNodes . size ( ) - 1 ; i + + ) depthCoords . push_back ( ( depthCoordsAtNodes [ i ] + depthCoordsAtNodes [ i + 1 ] ) / 2 ) ;
2017-04-25 16:08:44 +02:00
for ( int i = 0 ; i < xCoords . size ( ) - 1 ; i + + )
2017-03-27 14:19:21 +02:00
{
2017-04-25 16:08:44 +02:00
for ( int j = 0 ; j < depthCoords . size ( ) - 1 ; j + + )
2017-03-27 14:19:21 +02:00
{
std : : vector < cvf : : Vec3d > cellPolygon ;
2017-04-25 16:08:44 +02:00
cellPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i ] ) , static_cast < float > ( depthCoords [ j ] ) , 0.0 ) ) ;
cellPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i + 1 ] ) , static_cast < float > ( depthCoords [ j ] ) , 0.0 ) ) ;
cellPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i + 1 ] ) , static_cast < float > ( depthCoords [ j + 1 ] ) , 0.0 ) ) ;
cellPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ i ] ) , static_cast < float > ( depthCoords [ j + 1 ] ) , 0.0 ) ) ;
2017-03-27 14:19:21 +02:00
2017-05-11 12:24:57 +02:00
RigStimPlanFracTemplateCell stimPlanCell ( cellPolygon , i , j ) ;
2017-04-07 10:17:17 +02:00
if ( conductivityValuesAtTimeStep . size ( ) > 0 ) //Assuming vector to be of correct length, or no values
{
2017-04-25 16:08:44 +02:00
stimPlanCell . setConductivityValue ( conductivityValuesAtTimeStep [ j + 1 ] [ i + 1 ] ) ;
2017-04-07 10:17:17 +02:00
}
else
{
stimPlanCell . setConductivityValue ( cvf : : UNDEFINED_DOUBLE ) ;
}
if ( displayPropertyValuesAtTimeStep . size ( ) > 0 )
{
2017-04-25 16:08:44 +02:00
stimPlanCell . setDisplayValue ( displayPropertyValuesAtTimeStep [ j + 1 ] [ i + 1 ] ) ;
2017-04-07 10:17:17 +02:00
}
else
{
stimPlanCell . setDisplayValue ( cvf : : UNDEFINED_DOUBLE ) ;
}
2017-04-20 12:16:13 +02:00
if ( cellPolygon [ 0 ] . x ( ) < 0.0 & & cellPolygon [ 1 ] . x ( ) > 0.0 )
{
2017-04-25 16:08:44 +02:00
if ( cellPolygon [ 1 ] . y ( ) > 0.0 & & cellPolygon [ 2 ] . y ( ) < 0.0 )
2017-04-20 12:16:13 +02:00
{
2017-04-25 16:08:44 +02:00
wellCenterStimPlanCellIJ = std : : make_pair ( stimPlanCell . getI ( ) , stimPlanCell . getJ ( ) ) ;
RiaLogging : : debug ( QString ( " Setting wellCenterStimPlanCell at cell %1, %2 " ) .
arg ( QString : : number ( stimPlanCell . getI ( ) ) , QString : : number ( stimPlanCell . getJ ( ) ) ) ) ;
wellCenterStimPlanCellFound = true ;
2017-04-20 12:16:13 +02:00
}
}
2017-03-27 14:19:21 +02:00
stimPlanCells . push_back ( stimPlanCell ) ;
}
}
2017-04-25 16:08:44 +02:00
if ( ! wellCenterStimPlanCellFound )
{
RiaLogging : : error ( " Did not find stim plan cell at well crossing! " ) ;
}
2017-04-06 09:34:38 +02:00
m_stimPlanCells = stimPlanCells ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-05-11 12:24:57 +02:00
const std : : vector < RigStimPlanFracTemplateCell > & RimStimPlanFractureTemplate : : getStimPlanCells ( )
2017-04-06 09:34:38 +02:00
{
return m_stimPlanCells ;
2017-03-27 14:19:21 +02:00
}
2017-03-28 13:49:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < cvf : : Vec3d > RimStimPlanFractureTemplate : : getStimPlanRowPolygon ( size_t i ) //Row with constant depth
{
std : : vector < cvf : : Vec3d > rowPolygon ;
std : : vector < double > depthCoordsAtNodes = adjustedDepthCoordsAroundWellPathPosition ( ) ;
std : : vector < double > xCoordsAtNodes = getNegAndPosXcoords ( ) ;
std : : vector < double > xCoords ;
for ( int i = 0 ; i < xCoordsAtNodes . size ( ) - 1 ; i + + ) xCoords . push_back ( ( xCoordsAtNodes [ i ] + xCoordsAtNodes [ i + 1 ] ) / 2 ) ;
std : : vector < double > depthCoords ;
for ( int i = 0 ; i < depthCoordsAtNodes . size ( ) - 1 ; i + + ) depthCoords . push_back ( ( depthCoordsAtNodes [ i ] + depthCoordsAtNodes [ i + 1 ] ) / 2 ) ;
rowPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ 0 ] ) , static_cast < float > ( depthCoords [ i ] ) , 0.0 ) ) ;
rowPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords . back ( ) ) , static_cast < float > ( depthCoords [ i ] ) , 0.0 ) ) ;
rowPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords . back ( ) ) , static_cast < float > ( depthCoords [ i + 1 ] ) , 0.0 ) ) ;
rowPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ 0 ] ) , static_cast < float > ( depthCoords [ i + 1 ] ) , 0.0 ) ) ;
return rowPolygon ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < cvf : : Vec3d > RimStimPlanFractureTemplate : : getStimPlanColPolygon ( size_t j )
{
std : : vector < cvf : : Vec3d > colPolygon ;
std : : vector < double > depthCoordsAtNodes = adjustedDepthCoordsAroundWellPathPosition ( ) ;
std : : vector < double > xCoordsAtNodes = getNegAndPosXcoords ( ) ;
std : : vector < double > xCoords ;
for ( int i = 0 ; i < xCoordsAtNodes . size ( ) - 1 ; i + + ) xCoords . push_back ( ( xCoordsAtNodes [ i ] + xCoordsAtNodes [ i + 1 ] ) / 2 ) ;
std : : vector < double > depthCoords ;
for ( int i = 0 ; i < depthCoordsAtNodes . size ( ) - 1 ; i + + ) depthCoords . push_back ( ( depthCoordsAtNodes [ i ] + depthCoordsAtNodes [ i + 1 ] ) / 2 ) ;
colPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ j ] ) , static_cast < float > ( depthCoords [ 0 ] ) , 0.0 ) ) ;
colPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ j + 1 ] ) , static_cast < float > ( depthCoords [ 0 ] ) , 0.0 ) ) ;
colPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ j + 1 ] ) , static_cast < float > ( depthCoords . back ( ) ) , 0.0 ) ) ;
colPolygon . push_back ( cvf : : Vec3d ( static_cast < float > ( xCoords [ j ] ) , static_cast < float > ( depthCoords . back ( ) ) , 0.0 ) ) ;
return colPolygon ;
}
2017-04-20 12:16:13 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-04-25 16:08:44 +02:00
std : : pair < size_t , size_t > RimStimPlanFractureTemplate : : getStimPlanCellAtWellCenter ( )
{
return wellCenterStimPlanCellIJ ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimStimPlanFractureTemplate : : getGlobalIndexFromIJ ( size_t i , size_t j )
2017-04-20 12:16:13 +02:00
{
2017-04-25 16:08:44 +02:00
size_t length_I = stimPlanGridNumberOfRows ( ) - 1 ;
size_t globIndex = j * length_I + i ;
return globIndex ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-05-11 12:24:57 +02:00
const RigStimPlanFracTemplateCell & RimStimPlanFractureTemplate : : stimPlanCellFromIndex ( size_t index ) const
2017-04-25 16:08:44 +02:00
{
if ( index < m_stimPlanCells . size ( ) )
{
2017-05-11 12:24:57 +02:00
const RigStimPlanFracTemplateCell & cell = m_stimPlanCells [ index ] ;
2017-04-25 16:08:44 +02:00
return cell ;
}
else
{
//TODO: Better error handling?
RiaLogging : : error ( " Requesting non-existent StimPlanCell " ) ;
RiaLogging : : error ( " Returning cell 0, results will be invalid " ) ;
2017-05-11 12:24:57 +02:00
const RigStimPlanFracTemplateCell & cell = m_stimPlanCells [ 0 ] ;
2017-04-25 16:08:44 +02:00
return cell ;
}
2017-04-20 12:16:13 +02:00
}
2017-02-15 15:14:16 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-02 10:08:45 +01:00
std : : vector < cvf : : Vec3f > RimStimPlanFractureTemplate : : fracturePolygon ( caf : : AppEnum < RimDefines : : UnitSystem > fractureUnit )
2017-02-15 15:14:16 +01:00
{
2017-02-17 15:10:04 +01:00
std : : vector < cvf : : Vec3f > polygon ;
2017-02-27 14:55:12 +01:00
2017-03-15 15:02:20 +01:00
QString parameterName = parameterForPolygon ;
QString parameterUnit = getUnitForStimPlanParameter ( parameterName ) ;
2017-04-07 10:17:17 +02:00
std : : vector < std : : vector < double > > dataAtTimeStep = m_stimPlanFractureDefinitionData - > getDataAtTimeIndex ( parameterName , parameterUnit , activeTimeStepIndex ) ;
2017-02-15 15:14:16 +01:00
2017-04-21 09:29:28 +02:00
std : : vector < double > adjustedDepths = adjustedDepthCoordsAroundWellPathPosition ( ) ;
2017-02-17 15:10:04 +01:00
for ( int k = 0 ; k < dataAtTimeStep . size ( ) ; k + + )
{
for ( int i = 0 ; i < dataAtTimeStep [ k ] . size ( ) ; i + + )
{
2017-03-06 11:32:09 +01:00
if ( ( dataAtTimeStep [ k ] ) [ i ] < 1e-7 ) //polygon should consist of nodes with value 0
2017-02-17 15:10:04 +01:00
{
2017-03-06 11:32:09 +01:00
if ( ( i > 0 ) & & ( ( dataAtTimeStep [ k ] ) [ ( i - 1 ) ] > 1e-7 ) ) //side neighbour cell different from 0
2017-02-17 15:10:04 +01:00
{
2017-03-06 11:32:09 +01:00
polygon . push_back ( cvf : : Vec3f ( static_cast < float > ( m_stimPlanFractureDefinitionData - > gridXs [ i ] ) ,
2017-04-21 09:29:28 +02:00
static_cast < float > ( adjustedDepths [ k ] ) , 0.0f ) ) ;
2017-02-17 15:10:04 +01:00
}
2017-03-06 11:32:09 +01:00
else if ( ( k < dataAtTimeStep . size ( ) - 1 ) & & ( ( dataAtTimeStep [ k + 1 ] ) [ ( i ) ] > 1e-7 ) ) //cell below different from 0
{
polygon . push_back ( cvf : : Vec3f ( static_cast < float > ( m_stimPlanFractureDefinitionData - > gridXs [ i ] ) ,
2017-04-21 09:29:28 +02:00
static_cast < float > ( adjustedDepths [ k ] ) , 0.0f ) ) ;
2017-03-06 11:32:09 +01:00
}
else if ( ( k > 0 ) & & ( ( dataAtTimeStep [ k - 1 ] ) [ ( i ) ] > 1e-7 ) ) //cell above different from 0
2017-02-17 15:10:04 +01:00
{
polygon . push_back ( cvf : : Vec3f ( static_cast < float > ( m_stimPlanFractureDefinitionData - > gridXs [ i ] ) ,
2017-04-21 09:29:28 +02:00
static_cast < float > ( adjustedDepths [ k ] ) , 0.0f ) ) ;
2017-02-17 15:10:04 +01:00
}
}
}
}
2017-02-15 15:14:16 +01:00
2017-03-06 11:32:09 +01:00
sortPolygon ( polygon ) ;
2017-02-17 15:10:04 +01:00
std : : vector < cvf : : Vec3f > negPolygon ;
2017-03-02 10:08:45 +01:00
for ( const cvf : : Vec3f & node : polygon )
2017-02-17 15:10:04 +01:00
{
cvf : : Vec3f negNode = node ;
negNode . x ( ) = - negNode . x ( ) ;
negPolygon . insert ( negPolygon . begin ( ) , negNode ) ;
}
2017-03-02 10:08:45 +01:00
for ( const cvf : : Vec3f & negNode : negPolygon )
2017-02-17 15:10:04 +01:00
{
polygon . push_back ( negNode ) ;
}
2017-02-28 14:35:19 +01:00
//Adding first point last - to close the polygon
if ( polygon . size ( ) > 0 ) polygon . push_back ( polygon [ 0 ] ) ;
2017-03-02 10:08:45 +01:00
if ( fractureUnit = = fractureTemplateUnit ( ) )
{
RiaLogging : : debug ( QString ( " No conversion necessary for %1 " ) . arg ( name ) ) ;
}
else if ( fractureTemplateUnit ( ) = = RimDefines : : UNITS_METRIC & & fractureUnit = = RimDefines : : UNITS_FIELD )
{
RiaLogging : : info ( QString ( " Converting StimPlan geometry from metric to field for fracture template %1 " ) . arg ( name ) ) ;
for ( cvf : : Vec3f & node : polygon )
{
float x = RimDefines : : meterToFeet ( node . x ( ) ) ;
float y = RimDefines : : meterToFeet ( node . y ( ) ) ;
float z = RimDefines : : meterToFeet ( node . z ( ) ) ;
node = cvf : : Vec3f ( x , y , z ) ;
}
}
else if ( fractureTemplateUnit ( ) = = RimDefines : : UNITS_FIELD & & fractureUnit = = RimDefines : : UNITS_METRIC )
{
RiaLogging : : info ( QString ( " Converting StimPlan geometry from field to metric for fracture template %1 " ) . arg ( name ) ) ;
for ( cvf : : Vec3f & node : polygon )
{
float x = RimDefines : : feetToMeter ( node . x ( ) ) ;
float y = RimDefines : : feetToMeter ( node . y ( ) ) ;
float z = RimDefines : : feetToMeter ( node . z ( ) ) ;
node = cvf : : Vec3f ( x , y , z ) ;
}
}
else
{
//Should never get here...
RiaLogging : : error ( QString ( " Error: Could not convert units for fracture template %1 " ) . arg ( name ) ) ;
}
2017-02-17 15:10:04 +01:00
return polygon ;
2017-02-07 09:09:00 +01:00
}
2017-03-06 11:32:09 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : sortPolygon ( std : : vector < cvf : : Vec3f > & polygon )
{
2017-03-15 15:02:20 +01:00
if ( polygon . size ( ) = = 0 ) return ;
2017-03-06 11:32:09 +01:00
for ( int i = 1 ; i < polygon . size ( ) - 1 ; i + + )
{
cvf : : Vec3f lastNode = polygon [ i - 1 ] ;
cvf : : Vec3f node = polygon [ i ] ;
cvf : : Vec3f nextNode = polygon [ i + 1 ] ;
if ( node . y ( ) = = nextNode . y ( ) )
{
if ( lastNode . x ( ) < node . x ( ) & & node . x ( ) > nextNode . x ( ) )
{
polygon [ i ] = nextNode ;
polygon [ i + 1 ] = node ;
}
else if ( lastNode . x ( ) > node . x ( ) & & node . x ( ) < nextNode . x ( ) )
{
polygon [ i ] = nextNode ;
polygon [ i + 1 ] = node ;
}
}
}
}
2017-03-28 13:49:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimStimPlanFractureTemplate : : stimPlanGridNumberOfColums ( )
{
return getNegAndPosXcoords ( ) . size ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimStimPlanFractureTemplate : : stimPlanGridNumberOfRows ( )
{
return adjustedDepthCoordsAroundWellPathPosition ( ) . size ( ) ;
}
2017-02-07 09:09:00 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : defineUiOrdering ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
2017-02-10 10:33:07 +01:00
RimFractureTemplate : : defineUiOrdering ( uiConfigName , uiOrdering ) ;
2017-02-07 09:09:00 +01:00
2017-02-10 10:33:07 +01:00
uiOrdering . add ( & name ) ;
2017-03-16 12:02:07 +01:00
uiOrdering . add ( & showStimPlanMesh ) ;
2017-02-10 10:33:07 +01:00
2017-04-07 12:46:09 +02:00
caf : : PdmUiGroup * fileGroup = uiOrdering . addNewGroup ( " Input " ) ;
2017-02-10 15:29:15 +01:00
fileGroup - > add ( & m_stimPlanFileName ) ;
2017-04-07 12:46:09 +02:00
fileGroup - > add ( & activeTimeStepIndex ) ;
2017-02-17 15:10:04 +01:00
fileGroup - > add ( & wellPathDepthAtFracture ) ;
2017-02-10 10:33:07 +01:00
2017-02-22 11:52:06 +01:00
caf : : PdmUiGroup * geometryGroup = uiOrdering . addNewGroup ( " Geometry " ) ;
2017-02-10 10:33:07 +01:00
geometryGroup - > add ( & orientation ) ;
geometryGroup - > add ( & azimuthAngle ) ;
2017-02-22 11:52:06 +01:00
caf : : PdmUiGroup * propertyGroup = uiOrdering . addNewGroup ( " Properties " ) ;
2017-02-10 15:29:15 +01:00
propertyGroup - > add ( & fractureConductivity ) ;
2017-02-10 10:33:07 +01:00
propertyGroup - > add ( & skinFactor ) ;
2017-04-19 11:00:52 +02:00
propertyGroup - > add ( & perforationLength ) ;
propertyGroup - > add ( & perforationEfficiency ) ;
propertyGroup - > add ( & wellRadius ) ;
2017-02-27 14:55:12 +01:00
caf : : PdmUiGroup * polygonGroup = uiOrdering . addNewGroup ( " Fracture Polygon Basis " ) ;
polygonGroup - > add ( & parameterForPolygon ) ;
2017-02-07 09:09:00 +01:00
}
2017-02-07 11:08:56 +01:00
2017-02-17 15:10:04 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : defineEditorAttribute ( const caf : : PdmFieldHandle * field , QString uiConfigName , caf : : PdmUiEditorAttribute * attribute )
{
2017-04-19 11:00:52 +02:00
RimFractureTemplate : : defineEditorAttribute ( field , uiConfigName , attribute ) ;
2017-02-22 14:46:28 +01:00
if ( field = = & m_stimPlanFileName )
{
caf : : PdmUiFilePathEditorAttribute * myAttr = dynamic_cast < caf : : PdmUiFilePathEditorAttribute * > ( attribute ) ;
if ( myAttr )
{
myAttr - > m_fileSelectionFilter = " StimPlan Xml Files(*.xml);;All Files (*.*) " ;
}
}
2017-02-17 15:10:04 +01:00
if ( field = = & wellPathDepthAtFracture )
{
2017-02-22 11:52:06 +01:00
if ( ! m_stimPlanFractureDefinitionData . isNull ( ) & & ( m_stimPlanFractureDefinitionData - > depths . size ( ) > 0 ) )
2017-02-17 15:10:04 +01:00
{
caf : : PdmUiDoubleSliderEditorAttribute * myAttr = dynamic_cast < caf : : PdmUiDoubleSliderEditorAttribute * > ( attribute ) ;
if ( myAttr )
{
myAttr - > m_minimum = m_stimPlanFractureDefinitionData - > depths [ 0 ] ;
2017-02-22 11:52:06 +01:00
myAttr - > m_maximum = m_stimPlanFractureDefinitionData - > depths [ m_stimPlanFractureDefinitionData - > depths . size ( ) - 1 ] ;
2017-02-17 15:10:04 +01:00
}
}
}
}