2017-02-07 02:09:00 -06: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 08:39:15 -06:00
# include "RiaApplication.h"
2018-01-25 05:14:54 -06:00
# include "RiaFractureDefines.h"
2017-02-28 03:01:31 -06:00
# include "RiaLogging.h"
2017-02-20 08:39:15 -06:00
2017-08-03 06:21:19 -05:00
# include "RifStimPlanXmlReader.h"
2017-02-07 04:08:56 -06:00
# include "RigStimPlanFractureDefinition.h"
2017-06-08 15:54:06 -05:00
# include "RigFractureGrid.h"
2017-02-07 02:09:00 -06:00
2017-08-03 06:21:19 -05:00
# include "RigFractureCell.h"
2017-02-20 08:39:15 -06:00
# include "RimEclipseView.h"
2017-02-10 08:29:15 -06:00
# include "RimFracture.h"
2017-08-03 06:21:19 -05:00
# include "RimFractureContainment.h"
2017-02-10 08:29:15 -06:00
# include "RimProject.h"
2017-02-20 08:39:15 -06:00
# include "RimStimPlanColors.h"
2017-02-17 02:29:46 -06:00
# include "RimStimPlanLegendConfig.h"
2017-08-03 06:21:19 -05:00
# include "RimTools.h"
2017-02-10 08:29:15 -06:00
2017-03-27 07:19:21 -05:00
# include "RivWellFracturePartMgr.h"
2017-02-07 02:09:00 -06:00
# include "cafPdmObject.h"
2017-02-17 08:10:04 -06:00
# include "cafPdmUiDoubleSliderEditor.h"
2017-02-09 03:52:05 -06:00
# include "cafPdmUiFilePathEditor.h"
2017-02-07 02:09:00 -06:00
# include "cvfVector3.h"
2017-02-09 03:52:05 -06:00
2017-02-07 04:08:56 -06:00
# include <QFileInfo>
2017-02-07 02:09:00 -06:00
2017-02-17 04:03:20 -06:00
# include <algorithm>
2017-03-17 05:28:00 -05:00
# include <vector>
2017-04-20 05:16:13 -05:00
# include <cmath>
2017-02-17 04:03:20 -06:00
2018-01-30 06:48:28 -06:00
static std : : vector < double > EMPTY_DOUBLE_VECTOR ;
2017-02-07 02:09:00 -06:00
CAF_PDM_SOURCE_INIT ( RimStimPlanFractureTemplate , " RimStimPlanFractureTemplate " ) ;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-01-25 05:27:36 -06:00
RimStimPlanFractureTemplate : : RimStimPlanFractureTemplate ( )
2017-02-07 02:09:00 -06:00
{
CAF_PDM_InitObject ( " Fracture Template " , " :/FractureTemplate16x16.png " , " " , " " ) ;
2017-12-15 07:26:59 -06:00
CAF_PDM_InitField ( & m_stimPlanFileName , " StimPlanFileName " , QString ( " " ) , " File Name " , " " , " " , " " ) ;
2017-02-10 08:29:15 -06:00
m_stimPlanFileName . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiFilePathEditor : : uiEditorTypeName ( ) ) ;
2017-12-15 07:26:59 -06:00
CAF_PDM_InitField ( & m_wellPathDepthAtFracture , " WellPathDepthAtFracture " , 0.0 , " Well/Fracture Intersection Depth " , " " , " " , " " ) ;
2017-06-12 07:42:35 -05:00
m_wellPathDepthAtFracture . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiDoubleSliderEditor : : uiEditorTypeName ( ) ) ;
2017-02-27 07:55:12 -06:00
2017-12-15 07:26:59 -06:00
CAF_PDM_InitField ( & m_borderPolygonResultName , " BorderPolygonResultName " , QString ( " " ) , " Parameter " , " " , " " , " " ) ;
2017-06-30 05:54:51 -05:00
m_borderPolygonResultName . uiCapability ( ) - > setUiHidden ( true ) ;
2018-01-25 05:14:54 -06:00
CAF_PDM_InitField ( & m_activeTimeStepIndex , " ActiveTimeStepIndex " , 0 , " Active TimeStep Index " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_conductivityResultNameOnFile , " ConductivityResultName " , QString ( " " ) , " Active Conductivity Result Name " , " " , " " , " " ) ;
2017-02-27 07:55:12 -06:00
2018-02-02 02:06:24 -06:00
CAF_PDM_InitField ( & m_showStimPlanMesh_OBSOLETE , " ShowStimPlanMesh " , true , " " , " " , " " , " " ) ;
m_showStimPlanMesh_OBSOLETE . uiCapability ( ) - > setUiHidden ( true ) ;
2017-05-30 07:57:21 -05:00
m_fractureGrid = new RigFractureGrid ( ) ;
2018-01-30 06:48:28 -06:00
m_readError = false ;
2017-02-07 02:09:00 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimStimPlanFractureTemplate : : ~ RimStimPlanFractureTemplate ( )
{
}
2018-01-25 05:27:36 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimStimPlanFractureTemplate : : activeTimeStepIndex ( )
{
return m_activeTimeStepIndex ;
}
2017-02-07 02:09:00 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : fieldChangedByUi ( const caf : : PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
2017-02-23 02:47:30 -06:00
RimFractureTemplate : : fieldChangedByUi ( changedField , oldValue , newValue ) ;
2017-02-07 04:08:56 -06:00
2017-02-10 08:29:15 -06:00
if ( & m_stimPlanFileName = = changedField )
2017-02-07 04:08:56 -06:00
{
2018-01-30 06:48:28 -06:00
m_readError = false ;
2017-02-17 02:29:46 -06:00
loadDataAndUpdate ( ) ;
2017-03-02 04:43:28 -06:00
setDefaultsBasedOnXMLfile ( ) ;
2017-02-07 04:08:56 -06:00
}
2017-02-10 08:29:15 -06:00
2017-06-12 07:42:35 -05:00
if ( & m_activeTimeStepIndex = = changedField )
2017-04-07 04:02:31 -05: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 )
{
2017-06-09 10:21:59 -05:00
if ( fracture - > fractureTemplate ( ) = = this )
2017-04-07 04:02:31 -05:00
{
2018-01-12 03:21:10 -06:00
fracture - > setStimPlanTimeIndexToPlot ( m_activeTimeStepIndex ) ;
2017-04-07 04:02:31 -05:00
}
}
proj - > createDisplayModelAndRedrawAllViews ( ) ;
}
}
2017-08-03 06:39:52 -05:00
if ( & m_wellPathDepthAtFracture = = changedField
| | & m_borderPolygonResultName = = changedField
| | & m_activeTimeStepIndex = = changedField
2018-01-25 05:14:54 -06:00
| | & m_stimPlanFileName = = changedField
| | & m_conductivityResultNameOnFile = = changedField )
2017-02-10 08:29:15 -06:00
{
2018-02-14 02:35:02 -06:00
updateFractureGrid ( ) ;
2017-02-10 08:29:15 -06:00
RimProject * proj ;
this - > firstAncestorOrThisOfType ( proj ) ;
if ( proj )
{
2018-01-03 04:00:05 -06:00
proj - > createDisplayModelAndRedrawAllViews ( ) ;
2017-02-10 08:29:15 -06:00
}
}
2018-03-01 07:16:08 -06:00
2018-03-05 03:20:47 -06:00
if ( changedField = = & m_scaleApplyButton )
2018-03-01 07:16:08 -06:00
{
2018-03-05 03:20:47 -06:00
m_scaleApplyButton = false ;
2018-03-02 07:33:47 -06:00
reload ( ) ;
2018-03-01 07:16:08 -06:00
}
2017-02-07 02:09:00 -06:00
}
2017-02-07 04:08:56 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setFileName ( const QString & fileName )
{
2017-02-10 08:29:15 -06:00
m_stimPlanFileName = fileName ;
2017-02-07 04:08:56 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString & RimStimPlanFractureTemplate : : fileName ( )
{
2017-02-10 08:29:15 -06:00
return m_stimPlanFileName ( ) ;
2017-02-07 04:08:56 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-08-03 06:21:19 -05:00
void RimStimPlanFractureTemplate : : updateFilePathsFromProjectPath ( const QString & newProjectPath , const QString & oldProjectPath )
{
m_stimPlanFileName = RimTools : : relocateFile ( m_stimPlanFileName ( ) , newProjectPath , oldProjectPath , nullptr , nullptr ) ;
}
2017-02-09 03:52:05 -06:00
2017-03-02 04:43:28 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setDefaultsBasedOnXMLfile ( )
{
2018-01-15 01:58:15 -06:00
if ( m_stimPlanFractureDefinitionData . isNull ( ) ) return ;
2017-03-02 04:43:28 -06:00
setDepthOfWellPathAtFracture ( ) ;
2018-01-31 05:25:58 -06:00
setPerforationLength ( ) ;
2017-06-12 07:42:35 -05:00
RiaLogging : : info ( QString ( " Setting well/fracture intersection depth at %1 " ) . arg ( m_wellPathDepthAtFracture ) ) ;
m_activeTimeStepIndex = static_cast < int > ( m_stimPlanFractureDefinitionData - > totalNumberTimeSteps ( ) - 1 ) ;
2017-06-13 04:23:53 -05:00
bool polygonPropertySet = setBorderPolygonResultNameToDefault ( ) ;
2017-03-02 04:43:28 -06:00
2017-06-14 02:20:15 -05:00
if ( polygonPropertySet ) RiaLogging : : info ( QString ( " Calculating polygon outline based on %1 at timestep %2 " ) . arg ( m_borderPolygonResultName ) . arg ( m_stimPlanFractureDefinitionData - > timeSteps ( ) [ m_activeTimeStepIndex ] ) ) ;
2017-03-02 04:43:28 -06:00
else RiaLogging : : info ( QString ( " Property for polygon calculation not set. " ) ) ;
2018-01-25 06:53:14 -06:00
if ( ! m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . isEmpty ( ) )
{
m_conductivityResultNameOnFile = m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . front ( ) ;
}
2017-03-02 04:43:28 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-06-13 04:23:53 -05:00
bool RimStimPlanFractureTemplate : : setBorderPolygonResultNameToDefault ( )
2017-03-02 04:43:28 -06:00
{
2017-09-14 06:48:30 -05:00
// first option: Width
2018-01-25 05:14:54 -06:00
for ( std : : pair < QString , QString > property : uiResultNamesWithUnit ( ) )
2017-03-02 04:43:28 -06:00
{
if ( property . first = = " WIDTH " )
{
2017-06-13 04:23:53 -05:00
m_borderPolygonResultName = property . first ;
2017-03-02 04:43:28 -06:00
return true ;
}
}
2017-09-14 06:48:30 -05:00
// if width not found, use conductivity
if ( hasConductivity ( ) )
2017-03-02 04:43:28 -06:00
{
2018-01-25 06:30:36 -06:00
m_borderPolygonResultName = m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . first ( ) ;
2017-09-14 06:48:30 -05:00
return true ;
2017-03-02 04:43:28 -06:00
}
2017-09-14 06:48:30 -05:00
// else: Set to first property
2018-01-25 05:27:36 -06:00
if ( ! uiResultNamesWithUnit ( ) . empty ( ) )
2017-06-30 05:54:51 -05:00
{
2018-01-25 05:14:54 -06:00
m_borderPolygonResultName = uiResultNamesWithUnit ( ) [ 0 ] . first ;
2017-06-30 05:54:51 -05:00
return true ;
}
2017-03-02 04:43:28 -06:00
return false ;
}
2017-02-15 08:49:53 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : loadDataAndUpdate ( )
{
QString errorMessage ;
2018-01-30 06:48:28 -06:00
if ( m_readError ) return ;
2018-02-08 04:05:01 -06:00
m_stimPlanFractureDefinitionData = RifStimPlanXmlReader : : readStimPlanXMLFile ( m_stimPlanFileName ( ) ,
2018-03-05 04:55:34 -06:00
m_conductivityScaleFactor ( ) ,
2018-03-01 07:16:08 -06:00
m_widthScaleFactor ( ) ,
m_heightScaleFactor ( ) ,
- m_wellPathDepthAtFracture ( ) ,
2018-02-08 04:05:01 -06:00
RifStimPlanXmlReader : : MIRROR_AUTO ,
2018-02-20 08:15:06 -06:00
fractureTemplateUnit ( ) ,
2018-02-08 04:05:01 -06:00
& errorMessage ) ;
2017-02-28 03:01:31 -06:00
if ( errorMessage . size ( ) > 0 ) RiaLogging : : error ( errorMessage ) ;
2017-02-17 02:29:46 -06:00
2017-06-12 07:30:18 -05:00
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
2018-03-06 01:16:39 -06:00
setDefaultConductivityResultIfEmpty ( ) ;
2018-02-20 08:15:06 -06:00
if ( fractureTemplateUnit ( ) = = RiaEclipseUnitTools : : UNITS_UNKNOWN )
{
setFractureTemplateUnit ( m_stimPlanFractureDefinitionData - > unitSet ( ) ) ;
}
2018-01-30 06:48:28 -06:00
m_readError = false ;
2017-06-12 07:30:18 -05:00
}
else
{
2018-02-08 06:57:43 -06:00
setFractureTemplateUnit ( RiaEclipseUnitTools : : UNITS_UNKNOWN ) ;
2018-01-30 06:48:28 -06:00
m_readError = true ;
2017-06-12 07:30:18 -05:00
}
2017-06-13 04:38:22 -05:00
updateFractureGrid ( ) ;
2017-04-06 02:34:38 -05:00
2017-06-12 07:30:18 -05:00
// Todo: Must update all views using this fracture template
RimEclipseView * activeView = dynamic_cast < RimEclipseView * > ( RiaApplication : : instance ( ) - > activeReservoirView ( ) ) ;
2018-03-01 00:51:30 -06:00
if ( activeView ) activeView - > fractureColors ( ) - > loadDataAndUpdate ( ) ;
2017-06-12 07:30:18 -05:00
2017-02-17 02:29:46 -06:00
updateConnectedEditors ( ) ;
2017-02-15 08:49:53 -06:00
}
2017-02-27 07:55:12 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf : : PdmOptionItemInfo > RimStimPlanFractureTemplate : : calculateValueOptions ( const caf : : PdmFieldHandle * fieldNeedingOptions , bool * useOptionsOnly )
{
QList < caf : : PdmOptionItemInfo > options ;
2018-02-16 07:17:28 -06:00
options = RimFractureTemplate : : calculateValueOptions ( fieldNeedingOptions , useOptionsOnly ) ;
2017-06-13 04:23:53 -05:00
if ( fieldNeedingOptions = = & m_borderPolygonResultName )
2017-02-27 07:55:12 -06:00
{
2018-01-25 05:14:54 -06:00
for ( std : : pair < QString , QString > nameUnit : uiResultNamesWithUnit ( ) )
2017-02-27 07:55:12 -06:00
{
2017-03-15 09:02:20 -05:00
options . push_back ( caf : : PdmOptionItemInfo ( nameUnit . first , nameUnit . first ) ) ;
2017-02-27 07:55:12 -06:00
}
}
2017-06-12 07:42:35 -05:00
else if ( fieldNeedingOptions = = & m_activeTimeStepIndex )
2017-02-27 07:55:12 -06:00
{
2017-06-13 04:38:22 -05:00
std : : vector < double > timeValues = timeSteps ( ) ;
2018-02-21 12:53:22 -06:00
int index = 0 ;
2017-02-27 07:55:12 -06:00
for ( double value : timeValues )
{
options . push_back ( caf : : PdmOptionItemInfo ( QString : : number ( value ) , index ) ) ;
index + + ;
}
}
2018-01-25 05:14:54 -06:00
else if ( fieldNeedingOptions = = & m_conductivityResultNameOnFile )
{
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
QStringList conductivityResultNames = m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) ;
for ( const auto & resultName : conductivityResultNames )
{
options . push_back ( caf : : PdmOptionItemInfo ( resultName , resultName ) ) ;
}
}
}
2017-02-27 07:55:12 -06:00
return options ;
}
2017-02-17 08:10:04 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setDepthOfWellPathAtFracture ( )
{
if ( ! m_stimPlanFractureDefinitionData . isNull ( ) )
{
2018-01-31 05:25:58 -06:00
double firstTvd = m_stimPlanFractureDefinitionData - > topPerfTvd ( ) ;
double lastTvd = m_stimPlanFractureDefinitionData - > bottomPerfTvd ( ) ;
if ( firstTvd ! = HUGE_VAL & & lastTvd ! = HUGE_VAL )
{
m_wellPathDepthAtFracture = ( firstTvd + lastTvd ) / 2 ;
}
else
{
firstTvd = m_stimPlanFractureDefinitionData - > minDepth ( ) ;
lastTvd = m_stimPlanFractureDefinitionData - > maxDepth ( ) ;
m_wellPathDepthAtFracture = ( firstTvd + lastTvd ) / 2 ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setPerforationLength ( )
{
if ( ! m_stimPlanFractureDefinitionData . isNull ( ) )
{
double firstTvd = m_stimPlanFractureDefinitionData - > topPerfTvd ( ) ;
double lastTvd = m_stimPlanFractureDefinitionData - > bottomPerfTvd ( ) ;
if ( firstTvd ! = HUGE_VAL & & lastTvd ! = HUGE_VAL )
{
2018-02-08 04:34:18 -06:00
m_perforationLength = std : : round ( cvf : : Math : : abs ( firstTvd - lastTvd ) ) ;
2018-01-31 05:25:58 -06:00
}
2018-01-31 05:43:42 -06:00
}
2018-02-08 06:57:43 -06:00
if ( fractureTemplateUnit ( ) = = RiaEclipseUnitTools : : UNITS_METRIC & & m_perforationLength < 10 )
2018-01-31 05:43:42 -06:00
{
2018-02-08 04:34:18 -06:00
m_perforationLength = 10 ;
2018-01-31 05:43:42 -06:00
}
2018-02-08 06:57:43 -06:00
else if ( fractureTemplateUnit ( ) = = RiaEclipseUnitTools : : UNITS_FIELD & & m_perforationLength < RiaEclipseUnitTools : : meterToFeet ( 10 ) )
2018-01-31 05:43:42 -06:00
{
2018-02-08 04:34:18 -06:00
m_perforationLength = std : : round ( RiaEclipseUnitTools : : meterToFeet ( 10 ) ) ;
2017-02-17 08:10:04 -06:00
}
}
2017-03-15 09:02:20 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimStimPlanFractureTemplate : : getUnitForStimPlanParameter ( QString parameterName )
{
QString unit ;
bool found = false ;
bool foundMultiple = false ;
2018-01-25 05:14:54 -06:00
for ( std : : pair < QString , QString > nameUnit : uiResultNamesWithUnit ( ) )
2017-03-15 09:02:20 -05:00
{
if ( nameUnit . first = = parameterName )
{
unit = nameUnit . second ;
if ( found ) foundMultiple = true ;
found = true ;
}
}
if ( foundMultiple ) RiaLogging : : error ( QString ( " Multiple units found for same parameter " ) ) ;
2017-07-03 04:36:58 -05:00
if ( ! found ) RiaLogging : : error ( QString ( " Requested unit / parameter not found for %1 template " ) . arg ( name ( ) ) ) ;
2017-03-15 09:02:20 -05:00
return unit ;
}
2018-02-14 06:35:35 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
FractureWidthAndConductivity RimStimPlanFractureTemplate : : widthAndConductivityAtWellPathIntersection ( ) const
{
FractureWidthAndConductivity values ;
if ( m_fractureGrid . notNull ( ) )
{
std : : pair < size_t , size_t > wellCellIJ = m_fractureGrid - > fractureCellAtWellCenter ( ) ;
size_t wellCellIndex = m_fractureGrid - > getGlobalIndexFromIJ ( wellCellIJ . first , wellCellIJ . second ) ;
const RigFractureCell & wellCell = m_fractureGrid - > cellFromIndex ( wellCellIndex ) ;
double conductivity = wellCell . getConductivtyValue ( ) ;
std : : vector < std : : pair < QString , QString > > propertyNamesUnitsOnFile = m_stimPlanFractureDefinitionData - > getStimPlanPropertyNamesUnits ( ) ;
2018-02-16 07:17:28 -06:00
QString propertyNameForFractureWidth ;
2018-02-14 06:35:35 -06:00
{
2018-02-16 07:17:28 -06:00
QString widthParameterName ;
QString effWidthParameterName ;
for ( const auto & nameUnit : propertyNamesUnitsOnFile )
2018-02-14 06:35:35 -06:00
{
2018-02-16 07:17:28 -06:00
if ( effWidthParameterName . isEmpty ( ) & & nameUnit . first . contains ( " effective width " , Qt : : CaseInsensitive ) )
{
effWidthParameterName = nameUnit . first ;
}
2018-02-14 06:35:35 -06:00
2018-02-16 07:17:28 -06:00
if ( widthParameterName . isEmpty ( ) & & nameUnit . first . contains ( " width " , Qt : : CaseInsensitive ) )
{
widthParameterName = nameUnit . first ;
}
}
2018-02-14 06:35:35 -06:00
2018-02-16 07:17:28 -06:00
if ( ! effWidthParameterName . isEmpty ( ) )
{
propertyNameForFractureWidth = effWidthParameterName ;
}
else
{
propertyNameForFractureWidth = widthParameterName ;
}
}
if ( ! propertyNameForFractureWidth . isEmpty ( ) )
{
for ( const auto & nameUnit : propertyNamesUnitsOnFile )
{
if ( nameUnit . first = = propertyNameForFractureWidth )
2018-02-14 06:35:35 -06:00
{
2018-03-05 02:43:06 -06:00
double widthInRequiredUnit = HUGE_VAL ;
{
auto resultValues = m_stimPlanFractureDefinitionData - > fractureGridResults ( nameUnit . first , nameUnit . second , m_activeTimeStepIndex ) ;
double widthInFileUnitSystem = resultValues [ wellCellIndex ] ;
2018-02-16 07:17:28 -06:00
2018-03-05 02:43:06 -06:00
if ( fractureTemplateUnit ( ) = = RiaEclipseUnitTools : : UNITS_METRIC )
{
QString unitText = nameUnit . second ;
2018-02-16 07:17:28 -06:00
2018-03-05 02:43:06 -06:00
widthInRequiredUnit = RiaEclipseUnitTools : : convertToMeter ( widthInFileUnitSystem , unitText ) ;
}
else if ( fractureTemplateUnit ( ) = = RiaEclipseUnitTools : : UNITS_FIELD )
{
QString unitText = nameUnit . second ;
widthInRequiredUnit = RiaEclipseUnitTools : : convertToFeet ( widthInFileUnitSystem , unitText ) ;
}
}
if ( widthInRequiredUnit ! = HUGE_VAL & & fabs ( widthInRequiredUnit ) > 1e-20 )
2018-02-16 07:17:28 -06:00
{
2018-03-05 02:43:06 -06:00
values . m_width = widthInRequiredUnit ;
values . m_permeability = conductivity / widthInRequiredUnit ;
2018-02-16 07:17:28 -06:00
}
2018-02-14 06:35:35 -06:00
}
}
}
}
return values ;
}
2018-02-01 08:37:05 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : setDefaultConductivityResultIfEmpty ( )
{
if ( m_conductivityResultNameOnFile ( ) . isEmpty ( ) )
{
if ( ! m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . isEmpty ( ) )
{
m_conductivityResultNameOnFile = m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . front ( ) ;
}
}
}
2018-01-25 05:14:54 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimStimPlanFractureTemplate : : mapUiResultNameToFileResultName ( const QString & uiResultName ) const
{
QString fileResultName ;
if ( uiResultName = = RiaDefines : : conductivityResultName ( ) )
{
fileResultName = m_conductivityResultNameOnFile ( ) ;
}
else
{
fileResultName = uiResultName ;
}
return fileResultName ;
}
2017-02-07 02:09:00 -06:00
//--------------------------------------------------------------------------------------------------
2018-02-02 02:06:24 -06:00
///
//--------------------------------------------------------------------------------------------------
bool RimStimPlanFractureTemplate : : showStimPlanMesh ( ) const
{
return m_showStimPlanMesh_OBSOLETE ( ) ;
}
//--------------------------------------------------------------------------------------------------
2018-02-20 08:15:06 -06:00
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : convertToUnitSystem ( RiaEclipseUnitTools : : UnitSystem neededUnit )
{
2018-02-21 12:07:03 -06:00
if ( m_fractureTemplateUnit ( ) = = neededUnit ) return ;
2018-02-20 08:15:06 -06:00
setFractureTemplateUnit ( neededUnit ) ;
2018-02-21 02:50:50 -06:00
RimFractureTemplate : : convertToUnitSystem ( neededUnit ) ;
2018-02-20 08:15:06 -06:00
m_readError = false ;
loadDataAndUpdate ( ) ;
2018-02-21 02:50:50 -06:00
if ( m_stimPlanFractureDefinitionData . isNull ( ) ) return ;
if ( neededUnit = = RiaEclipseUnitTools : : UNITS_FIELD )
{
m_wellPathDepthAtFracture = RiaEclipseUnitTools : : meterToFeet ( m_wellPathDepthAtFracture ) ;
}
else if ( neededUnit = = RiaEclipseUnitTools : : UNITS_METRIC )
{
m_wellPathDepthAtFracture = RiaEclipseUnitTools : : feetToMeter ( m_wellPathDepthAtFracture ) ;
}
m_activeTimeStepIndex = static_cast < int > ( m_stimPlanFractureDefinitionData - > totalNumberTimeSteps ( ) - 1 ) ;
bool polygonPropertySet = setBorderPolygonResultNameToDefault ( ) ;
if ( polygonPropertySet ) RiaLogging : : info ( QString ( " Calculating polygon outline based on %1 at timestep %2 " ) . arg ( m_borderPolygonResultName ) . arg ( m_stimPlanFractureDefinitionData - > timeSteps ( ) [ m_activeTimeStepIndex ] ) ) ;
else RiaLogging : : info ( QString ( " Property for polygon calculation not set. " ) ) ;
if ( ! m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . isEmpty ( ) )
{
m_conductivityResultNameOnFile = m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . front ( ) ;
}
2018-02-20 08:15:06 -06:00
}
2018-03-02 07:33:47 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : reload ( )
{
loadDataAndUpdate ( ) ;
RimProject * proj ;
this - > firstAncestorOrThisOfType ( proj ) ;
if ( proj )
{
proj - > createDisplayModelAndRedrawAllViews ( ) ;
}
}
2018-02-20 08:15:06 -06:00
//--------------------------------------------------------------------------------------------------
2017-02-07 02:09:00 -06:00
///
//--------------------------------------------------------------------------------------------------
2018-01-15 01:58:15 -06:00
std : : vector < double > RimStimPlanFractureTemplate : : timeSteps ( )
2017-02-15 05:16:01 -06:00
{
2018-01-15 01:58:15 -06:00
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
return m_stimPlanFractureDefinitionData - > timeSteps ( ) ;
}
return std : : vector < double > ( ) ;
2017-02-15 05:16:01 -06:00
}
2017-02-17 07:11:47 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-01-25 05:14:54 -06:00
std : : vector < std : : pair < QString , QString > > RimStimPlanFractureTemplate : : uiResultNamesWithUnit ( ) const
2017-02-17 07:11:47 -06:00
{
2018-01-25 05:14:54 -06:00
std : : vector < std : : pair < QString , QString > > propertyNamesAndUnits ;
2017-02-23 03:14:28 -06:00
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
2017-02-17 07:11:47 -06:00
{
2018-01-25 05:14:54 -06:00
QString conductivityUnit = " mD/s " ;
std : : vector < std : : pair < QString , QString > > tmp ;
std : : vector < std : : pair < QString , QString > > propertyNamesUnitsOnFile = m_stimPlanFractureDefinitionData - > getStimPlanPropertyNamesUnits ( ) ;
for ( const auto & nameUnitPair : propertyNamesUnitsOnFile )
{
2018-01-25 06:30:36 -06:00
if ( nameUnitPair . first . contains ( RiaDefines : : conductivityResultName ( ) , Qt : : CaseInsensitive ) )
2018-01-25 05:14:54 -06:00
{
conductivityUnit = nameUnitPair . second ;
}
else
{
tmp . push_back ( nameUnitPair ) ;
}
}
propertyNamesAndUnits . push_back ( std : : make_pair ( RiaDefines : : conductivityResultName ( ) , conductivityUnit ) ) ;
for ( const auto & nameUnitPair : tmp )
{
propertyNamesAndUnits . push_back ( nameUnitPair ) ;
}
2017-02-17 07:11:47 -06:00
}
2018-01-25 05:14:54 -06:00
return propertyNamesAndUnits ;
2017-02-17 07:11:47 -06:00
}
2017-03-27 07:19:21 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-01-25 05:14:54 -06:00
std : : vector < std : : vector < double > > RimStimPlanFractureTemplate : : resultValues ( const QString & uiResultName , const QString & unitName , size_t timeStepIndex ) const
2017-06-13 04:38:22 -05:00
{
2018-01-15 01:58:15 -06:00
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
2018-01-25 05:14:54 -06:00
QString fileResultName = mapUiResultNameToFileResultName ( uiResultName ) ;
return m_stimPlanFractureDefinitionData - > getDataAtTimeIndex ( fileResultName , unitName , timeStepIndex ) ;
2018-01-15 01:58:15 -06:00
}
return std : : vector < std : : vector < double > > ( ) ;
2017-06-13 04:38:22 -05:00
}
2017-06-26 03:28:23 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-01-25 05:14:54 -06:00
std : : vector < double > RimStimPlanFractureTemplate : : fractureGridResults ( const QString & uiResultName , const QString & unitName , size_t timeStepIndex ) const
2017-06-26 03:28:23 -05:00
{
2018-01-15 01:58:15 -06:00
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
2018-01-25 05:14:54 -06:00
QString fileResultName = mapUiResultNameToFileResultName ( uiResultName ) ;
return m_stimPlanFractureDefinitionData - > fractureGridResults ( fileResultName , unitName , timeStepIndex ) ;
2018-01-15 01:58:15 -06:00
}
return std : : vector < double > ( ) ;
2017-06-26 03:28:23 -05:00
}
2017-09-14 06:48:30 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimStimPlanFractureTemplate : : hasConductivity ( ) const
{
if ( m_stimPlanFractureDefinitionData . notNull ( ) & &
2018-01-25 06:30:36 -06:00
! m_stimPlanFractureDefinitionData - > conductivityResultNames ( ) . isEmpty ( ) )
2017-09-14 06:48:30 -05:00
{
return true ;
}
return false ;
}
2018-03-04 03:36:39 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimStimPlanFractureTemplate : : resultValueAtIJ ( const QString & uiResultName , const QString & unitName , size_t timeStepIndex , size_t i , size_t j )
{
auto values = resultValues ( uiResultName , unitName , timeStepIndex ) ;
if ( values . empty ( ) ) return HUGE_VAL ;
size_t adjustedI = i + 1 ;
size_t adjustedJ = j + 1 ;
if ( adjustedI > = fractureGrid ( ) - > iCellCount ( ) | | adjustedJ > = fractureGrid ( ) - > jCellCount ( ) )
{
2018-03-05 02:43:06 -06:00
2018-03-04 03:36:39 -06:00
return HUGE_VAL ;
}
return values [ adjustedJ ] [ adjustedI ] ;
}
2017-06-13 04:38:22 -05:00
//--------------------------------------------------------------------------------------------------
2018-01-19 02:10:30 -06:00
///
//--------------------------------------------------------------------------------------------------
2018-01-25 05:14:54 -06:00
void RimStimPlanFractureTemplate : : appendDataToResultStatistics ( const QString & uiResultName , const QString & unit ,
2018-01-19 02:10:30 -06:00
MinMaxAccumulator & minMaxAccumulator ,
PosNegAccumulator & posNegAccumulator ) const
{
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
2018-01-25 05:14:54 -06:00
QString fileResultName = mapUiResultNameToFileResultName ( uiResultName ) ;
m_stimPlanFractureDefinitionData - > appendDataToResultStatistics ( fileResultName , unit , minMaxAccumulator , posNegAccumulator ) ;
2018-01-19 02:10:30 -06:00
}
}
//--------------------------------------------------------------------------------------------------
///
2017-06-13 04:38:22 -05:00
//--------------------------------------------------------------------------------------------------
const RigFractureGrid * RimStimPlanFractureTemplate : : fractureGrid ( ) const
{
return m_fractureGrid . p ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : updateFractureGrid ( )
2017-03-27 07:19:21 -05:00
{
2018-01-15 01:58:15 -06:00
m_fractureGrid = nullptr ;
if ( m_stimPlanFractureDefinitionData . notNull ( ) )
{
2018-01-25 05:14:54 -06:00
m_fractureGrid = m_stimPlanFractureDefinitionData - > createFractureGrid ( m_conductivityResultNameOnFile ,
m_activeTimeStepIndex ,
2018-03-05 02:43:06 -06:00
m_wellPathDepthAtFracture ,
m_fractureTemplateUnit ( ) ) ;
2018-01-15 01:58:15 -06:00
}
2017-04-06 02:34:38 -05:00
}
2017-06-13 04:38:22 -05:00
2017-06-13 07:44:04 -05:00
2017-04-06 02:34:38 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-06-13 04:38:22 -05:00
void RimStimPlanFractureTemplate : : fractureTriangleGeometry ( std : : vector < cvf : : Vec3f > * nodeCoords ,
2018-02-21 01:18:55 -06:00
std : : vector < cvf : : uint > * triangleIndices )
2017-04-06 02:34:38 -05:00
{
2017-06-13 04:38:22 -05:00
if ( m_stimPlanFractureDefinitionData . isNull ( ) )
{
loadDataAndUpdate ( ) ;
}
2018-03-12 05:12:39 -05:00
else
2018-01-15 01:58:15 -06:00
{
m_stimPlanFractureDefinitionData - > createFractureTriangleGeometry ( m_wellPathDepthAtFracture ,
2018-02-08 06:57:43 -06:00
name ( ) ,
2018-01-15 01:58:15 -06:00
nodeCoords ,
triangleIndices ) ;
}
2017-03-27 07:19:21 -05:00
}
2017-02-15 08:14:16 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-02-21 01:18:55 -06:00
std : : vector < cvf : : Vec3f > RimStimPlanFractureTemplate : : fractureBorderPolygon ( )
2017-02-15 08:14:16 -06:00
{
2018-03-08 04:01:04 -06:00
// Not implemented
2018-01-15 01:58:15 -06:00
return std : : vector < cvf : : Vec3f > ( ) ;
2017-02-07 02:09:00 -06:00
}
2017-03-06 04:32:09 -06:00
2017-02-07 02:09:00 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : defineUiOrdering ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
2018-02-08 06:57:43 -06:00
uiOrdering . add ( & m_name ) ;
2018-03-02 02:33:17 -06:00
uiOrdering . add ( & m_id ) ;
2017-02-10 03:33:07 -06:00
2017-04-07 05:46:09 -05:00
caf : : PdmUiGroup * fileGroup = uiOrdering . addNewGroup ( " Input " ) ;
2017-02-10 08:29:15 -06:00
fileGroup - > add ( & m_stimPlanFileName ) ;
2017-06-12 07:42:35 -05:00
fileGroup - > add ( & m_activeTimeStepIndex ) ;
fileGroup - > add ( & m_wellPathDepthAtFracture ) ;
2017-02-10 03:33:07 -06:00
2017-02-22 04:52:06 -06:00
caf : : PdmUiGroup * geometryGroup = uiOrdering . addNewGroup ( " Geometry " ) ;
2018-02-08 06:57:43 -06:00
geometryGroup - > add ( & m_orientationType ) ;
2018-02-08 04:34:18 -06:00
geometryGroup - > add ( & m_azimuthAngle ) ;
2017-02-10 03:33:07 -06:00
2017-06-08 15:54:06 -05:00
caf : : PdmUiGroup * trGr = uiOrdering . addNewGroup ( " Fracture Truncation " ) ;
2017-06-09 10:21:59 -05:00
m_fractureContainment ( ) - > defineUiOrdering ( uiConfigName , * trGr ) ;
2017-06-08 15:54:06 -05:00
2017-02-22 04:52:06 -06:00
caf : : PdmUiGroup * propertyGroup = uiOrdering . addNewGroup ( " Properties " ) ;
2018-01-25 05:14:54 -06:00
propertyGroup - > add ( & m_conductivityResultNameOnFile ) ;
2018-02-08 04:34:18 -06:00
propertyGroup - > add ( & m_conductivityType ) ;
propertyGroup - > add ( & m_skinFactor ) ;
propertyGroup - > add ( & m_perforationLength ) ;
propertyGroup - > add ( & m_perforationEfficiency ) ;
propertyGroup - > add ( & m_wellDiameter ) ;
2018-02-09 00:26:48 -06:00
RimFractureTemplate : : defineUiOrdering ( uiConfigName , uiOrdering ) ;
2017-02-07 02:09:00 -06:00
}
2017-02-07 04:08:56 -06:00
2017-02-17 08:10:04 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimStimPlanFractureTemplate : : defineEditorAttribute ( const caf : : PdmFieldHandle * field , QString uiConfigName , caf : : PdmUiEditorAttribute * attribute )
{
2017-04-19 04:00:52 -05:00
RimFractureTemplate : : defineEditorAttribute ( field , uiConfigName , attribute ) ;
2017-02-22 07:46:28 -06: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-06-12 07:42:35 -05:00
if ( field = = & m_wellPathDepthAtFracture )
2017-02-17 08:10:04 -06:00
{
2018-02-08 04:05:01 -06:00
if ( ! m_stimPlanFractureDefinitionData . isNull ( ) & & ( m_stimPlanFractureDefinitionData - > yCount ( ) > 0 ) )
2017-02-17 08:10:04 -06:00
{
2017-06-14 02:20:15 -05:00
caf : : PdmUiDoubleSliderEditorAttribute * myAttr = dynamic_cast < caf : : PdmUiDoubleSliderEditorAttribute * > ( attribute ) ;
if ( myAttr )
{
myAttr - > m_minimum = m_stimPlanFractureDefinitionData - > minDepth ( ) ;
myAttr - > m_maximum = m_stimPlanFractureDefinitionData - > maxDepth ( ) ;
}
2017-02-17 08:10:04 -06:00
}
}
}