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 "RimFractureTemplate.h"
2018-02-14 13:35:35 +01:00
#include "RiaFractureDefines.h"
2017-02-07 09:09:00 +01:00
#include "RigTesselatorTools.h"
#include "RimFracture.h"
2018-01-05 11:38:58 +01:00
#include "RimFractureContainment.h"
2017-02-07 09:09:00 +01:00
#include "RimProject.h"
#include "cafPdmObject.h"
2017-04-19 11:00:52 +02:00
#include "cafPdmUiDoubleSliderEditor.h"
2018-02-16 10:14:41 +01:00
#include "cafPdmUiDoubleValueEditor.h"
2018-02-14 13:35:35 +01:00
#include "cafPdmUiTextEditor.h"
2018-03-01 14:16:08 +01:00
#include "cafPdmUiPushButtonEditor.h"
2017-02-07 09:09:00 +01:00
#include "cvfVector3.h"
2018-01-05 11:38:58 +01:00
#include <cmath>
2017-02-07 09:09:00 +01:00
namespace caf
{
template <>
void caf :: AppEnum < RimFractureTemplate :: FracOrientationEnum >:: setUp ()
{
2018-02-21 19:53:22 +01:00
addItem ( RimFractureTemplate :: AZIMUTH , "Az" , "Azimuth" );
addItem ( RimFractureTemplate :: ALONG_WELL_PATH , "AlongWellPath" , "Along Well Path" );
addItem ( RimFractureTemplate :: TRANSVERSE_WELL_PATH , "TransverseWellPath" , "Transverse (normal) to Well Path" );
2017-02-07 09:09:00 +01:00
setDefault ( RimFractureTemplate :: TRANSVERSE_WELL_PATH );
}
2017-02-10 13:29:31 +01:00
2017-02-10 13:43:22 +01:00
template <>
2017-02-10 13:29:31 +01:00
void caf :: AppEnum < RimFractureTemplate :: FracConductivityEnum >:: setUp ()
{
2017-02-22 11:52:06 +01:00
addItem ( RimFractureTemplate :: INFINITE_CONDUCTIVITY , "InfiniteConductivity" , "Infinite Conductivity" );
2018-02-21 19:53:22 +01:00
addItem ( RimFractureTemplate :: FINITE_CONDUCTIVITY , "FiniteConductivity" , "Finite Conductivity" );
2017-02-10 13:29:31 +01:00
setDefault ( RimFractureTemplate :: INFINITE_CONDUCTIVITY );
}
2017-02-14 09:49:14 +01:00
2018-02-14 13:35:35 +01:00
template <>
2018-02-15 20:01:41 +01:00
void caf :: AppEnum < RimFractureTemplate :: PermeabilityEnum >:: setUp ()
2018-02-14 13:35:35 +01:00
{
2018-02-21 19:53:22 +01:00
addItem ( RimFractureTemplate :: USER_DEFINED_PERMEABILITY , "UserDefinedPermeability" , "User Defined" );
addItem ( RimFractureTemplate :: CONDUCTIVITY_FROM_FRACTURE , "FractureConductivity" , "Use Fracture Conductivity" );
2018-02-14 13:35:35 +01:00
setDefault ( RimFractureTemplate :: CONDUCTIVITY_FROM_FRACTURE );
}
2018-02-15 20:01:41 +01:00
template <>
void caf :: AppEnum < RimFractureTemplate :: WidthEnum >:: setUp ()
{
2018-02-21 19:53:22 +01:00
addItem ( RimFractureTemplate :: USER_DEFINED_WIDTH , "UserDefinedWidth" , "User Defined" );
addItem ( RimFractureTemplate :: WIDTH_FROM_FRACTURE , "FractureWidth" , "Use Fracture Width" );
2017-02-14 09:49:14 +01:00
2018-02-15 20:01:41 +01:00
setDefault ( RimFractureTemplate :: WIDTH_FROM_FRACTURE );
}
2018-02-15 21:43:35 +01:00
template <>
void caf :: AppEnum < RimFractureTemplate :: NonDarcyFlowEnum >:: setUp ()
{
2018-02-21 19:53:22 +01:00
addItem ( RimFractureTemplate :: NON_DARCY_NONE , "None" , "None" );
2018-03-20 10:58:06 +01:00
addItem ( RimFractureTemplate :: NON_DARCY_COMPUTED , "Computed" , "Compute D-factor" );
addItem ( RimFractureTemplate :: NON_DARCY_USER_DEFINED , "UserDefined" , "User Defined D-factor" );
2018-02-15 21:43:35 +01:00
setDefault ( RimFractureTemplate :: NON_DARCY_NONE );
}
2017-02-07 09:09:00 +01:00
}
2018-02-09 07:26:48 +01:00
// TODO Move to cafPdmObject.h
#define CAF_PDM_InitField_Basic(field, keyword, default, uiName) CAF_PDM_InitField(field, keyword, default, uiName, "", "", "")
2017-02-07 09:09:00 +01:00
CAF_PDM_XML_ABSTRACT_SOURCE_INIT ( RimFractureTemplate , "RimFractureTemplate" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-01-10 07:44:26 +01:00
RimFractureTemplate :: RimFractureTemplate ()
2017-02-07 09:09:00 +01:00
{
CAF_PDM_InitObject ( "Fracture Template" , ":/FractureTemplate16x16.png" , "" , "" );
2018-03-02 09:33:17 +01:00
CAF_PDM_InitField ( & m_id , "Id" , - 1 , "ID" , "" , "" , "" );
m_id . uiCapability () -> setUiReadOnly ( true );
2018-02-08 13:57:43 +01:00
CAF_PDM_InitField ( & m_name , "UserDescription" , QString ( "Fracture Template" ), "Name" , "" , "" , "" );
2018-02-19 13:54:29 +01:00
CAF_PDM_InitFieldNoDefault ( & m_nameAndUnit , "NameAndUnit" , "NameAndUnit" , "" , "" , "" );
m_nameAndUnit . registerGetMethod ( this , & RimFractureTemplate :: nameAndUnit );
m_nameAndUnit . uiCapability () -> setUiHidden ( true );
m_nameAndUnit . xmlCapability () -> disableIO ();
2018-02-21 19:53:22 +01:00
CAF_PDM_InitField ( & m_fractureTemplateUnit , "UnitSystem" , caf :: AppEnum < RiaEclipseUnitTools :: UnitSystem > ( RiaEclipseUnitTools :: UNITS_METRIC ), "Units System" , "" , "" , "" );
2018-02-08 13:57:43 +01:00
m_fractureTemplateUnit . uiCapability () -> setUiReadOnly ( true );
2017-02-14 09:49:14 +01:00
2018-02-08 13:57:43 +01:00
CAF_PDM_InitField ( & m_orientationType , "Orientation" , caf :: AppEnum < FracOrientationEnum > ( TRANSVERSE_WELL_PATH ), "Fracture Orientation" , "" , "" , "" );
2018-02-08 11:34:18 +01:00
CAF_PDM_InitField ( & m_azimuthAngle , "AzimuthAngle" , 0.0f , "Azimuth Angle" , "" , "" , "" ); //Is this correct description?
CAF_PDM_InitField ( & m_skinFactor , "SkinFactor" , 0.0f , "Skin Factor" , "" , "" , "" );
2017-02-10 13:29:31 +01:00
2018-02-08 11:34:18 +01:00
CAF_PDM_InitField ( & m_perforationLength , "PerforationLength" , 1.0 , "Perforation Length" , "" , "" , "" );
2018-02-21 19:53:22 +01:00
2018-02-08 11:34:18 +01:00
CAF_PDM_InitField ( & m_perforationEfficiency , "PerforationEfficiency" , 1.0 , "Perforation Efficiency" , "" , "" , "" );
m_perforationEfficiency . uiCapability () -> setUiEditorTypeName ( caf :: PdmUiDoubleSliderEditor :: uiEditorTypeName ());
2017-04-19 11:00:52 +02:00
2018-02-21 19:53:22 +01:00
CAF_PDM_InitField ( & m_wellDiameter , "WellDiameter" , 0.216 , "Well Diameter at Fracture" , "" , "" , "" );
2018-02-08 11:34:18 +01:00
CAF_PDM_InitField ( & m_conductivityType , "ConductivityType" , caf :: AppEnum < FracConductivityEnum > ( FINITE_CONDUCTIVITY ), "Conductivity in Fracture" , "" , "" , "" );
2017-02-10 13:29:31 +01:00
2017-12-15 14:26:59 +01:00
CAF_PDM_InitFieldNoDefault ( & m_fractureContainment , "FractureContainmentField" , "Fracture Containment" , "" , "" , "" );
2017-06-09 17:21:59 +02:00
m_fractureContainment = new RimFractureContainment ();
m_fractureContainment . uiCapability () -> setUiTreeHidden ( true );
m_fractureContainment . uiCapability () -> setUiTreeChildrenHidden ( true );
2018-02-09 07:26:48 +01:00
// Non-Darcy Flow options
2018-02-15 21:43:35 +01:00
CAF_PDM_InitFieldNoDefault ( & m_nonDarcyFlowType , "NonDarcyFlowType" , "Non-Darcy Flow" , "" , "" , "" );
CAF_PDM_InitField ( & m_userDefinedDFactor , "UserDefinedDFactor" , 1.0 , "D Factor" , "" , "" , "" );
2018-02-15 20:01:41 +01:00
CAF_PDM_InitFieldNoDefault ( & m_fractureWidthType , "FractureWidthType" , "Type" , "" , "" , "" );
2018-03-20 10:42:53 +01:00
CAF_PDM_InitField_Basic ( & m_fractureWidth , "FractureWidth" , 0.01 , "Fracture Width (h)" );
2018-02-15 20:01:41 +01:00
2018-03-20 10:58:06 +01:00
CAF_PDM_InitField_Basic ( & m_inertialCoefficient , "InertialCoefficient" , 0.006083236 , "<html>Inertial Coefficient (β)</html> [Forch. unit]" );
2018-02-14 13:35:35 +01:00
2018-02-15 15:38:27 +01:00
CAF_PDM_InitFieldNoDefault ( & m_permeabilityType , "PermeabilityType" , "Type" , "" , "" , "" );
CAF_PDM_InitField_Basic ( & m_relativePermeability , "RelativePermeability" , 1.0 , "Relative Permeability" );
2018-02-15 20:01:41 +01:00
CAF_PDM_InitField ( & m_userDefinedEffectivePermeability , "EffectivePermeability" , 0.0 , "Effective Permeability (Ke) [mD]" , "" , "" , "" );
2018-02-14 13:35:35 +01:00
2018-02-15 21:43:35 +01:00
CAF_PDM_InitField ( & m_relativeGasDensity , "RelativeGasDensity" , 0.8 , "<html>Relative Gas Density (γ)</html>" , "" , "Relative density of gas at surface conditions with respect to air at STP" , "" );
2018-02-21 19:25:05 +01:00
CAF_PDM_InitField ( & m_gasViscosity , "GasViscosity" , 0.02 , "<html>Gas Viscosity (μ)</html> [cP]" , "" , "Gas viscosity at bottom hole pressure" , "" );
2018-02-14 13:35:35 +01:00
CAF_PDM_InitFieldNoDefault ( & m_dFactorDisplayField , "dFactorDisplayField" , "D Factor" , "" , "" , "" );
2018-02-16 07:58:07 +01:00
m_dFactorDisplayField . registerGetMethod ( this , & RimFractureTemplate :: dFactor );
2018-02-16 10:14:41 +01:00
m_dFactorDisplayField . uiCapability () -> setUiEditorTypeName ( caf :: PdmUiDoubleValueEditor :: uiEditorTypeName ());
2018-02-14 13:35:35 +01:00
m_dFactorDisplayField . uiCapability () -> setUiReadOnly ( true );
2018-02-19 13:54:29 +01:00
m_dFactorDisplayField . xmlCapability () -> disableIO ();
2018-02-14 13:35:35 +01:00
CAF_PDM_InitFieldNoDefault ( & m_dFactorSummaryText , "dFactorSummaryText" , "D Factor Summary" , "" , "" , "" );
m_dFactorSummaryText . registerGetMethod ( this , & RimFractureTemplate :: dFactorSummary );
m_dFactorSummaryText . uiCapability () -> setUiReadOnly ( true );
m_dFactorSummaryText . uiCapability () -> setUiEditorTypeName ( caf :: PdmUiTextEditor :: uiEditorTypeName ());
m_dFactorSummaryText . uiCapability () -> setUiLabelPosition ( caf :: PdmUiItemInfo :: LabelPosType :: TOP );
2018-02-19 13:54:29 +01:00
m_dFactorSummaryText . xmlCapability () -> disableIO ();
2018-03-01 14:16:08 +01:00
2018-03-05 10:20:47 +01:00
CAF_PDM_InitField ( & m_heightScaleFactor , "HeightScaleFactor" , 1.0 , "Height" , "" , "" , "" );
CAF_PDM_InitField ( & m_widthScaleFactor , "WidthScaleFactor" , 1.0 , "Width" , "" , "" , "" );
CAF_PDM_InitField ( & m_dFactorScaleFactor , "DFactorScaleFactor" , 1.0 , "D-factor" , "" , "" , "" );
2018-03-05 11:55:34 +01:00
CAF_PDM_InitField ( & m_conductivityScaleFactor , "ConductivityFactor" , 1.0 , "Conductivity" , "" , "The conductivity values read from file will be scaled with this parameters" , "" );
2018-03-05 10:20:47 +01:00
CAF_PDM_InitField ( & m_scaleApplyButton , "ScaleApplyButton" , false , "Apply" , "" , "" , "" );
2018-03-05 11:55:34 +01:00
2018-03-05 10:20:47 +01:00
m_scaleApplyButton . xmlCapability () -> disableIO ();
m_scaleApplyButton . uiCapability () -> setUiEditorTypeName ( caf :: PdmUiPushButtonEditor :: uiEditorTypeName ());
m_scaleApplyButton . uiCapability () -> setUiLabelPosition ( caf :: PdmUiItemInfo :: HIDDEN );
2017-02-07 09:09:00 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFractureTemplate ::~ RimFractureTemplate ()
{
}
2018-03-02 09:33:17 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimFractureTemplate :: id () const
{
return m_id ;
}
2018-02-08 13:57:43 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: setName ( const QString & name )
{
m_name = name ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: setFractureTemplateUnit ( RiaEclipseUnitTools :: UnitSystemType unitSystem )
{
m_fractureTemplateUnit = unitSystem ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFractureTemplate :: name () const
{
return m_name ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFractureTemplate :: FracOrientationEnum RimFractureTemplate :: orientationType () const
{
return m_orientationType ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaEclipseUnitTools :: UnitSystemType RimFractureTemplate :: fractureTemplateUnit () const
{
return m_fractureTemplateUnit ();
}
2017-02-07 09:09:00 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf :: PdmFieldHandle * RimFractureTemplate :: userDescriptionField ()
{
2018-02-19 13:54:29 +01:00
return & m_nameAndUnit ;
2017-02-07 09:09:00 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: fieldChangedByUi ( const caf :: PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
2018-02-08 13:57:43 +01:00
if ( changedField == & m_azimuthAngle || changedField == & m_orientationType )
2017-02-23 09:47:30 +01:00
{
//Changes to one of these parameters should change all fractures with this fracture template attached.
RimProject * proj ;
this -> firstAncestorOrThisOfType ( proj );
if ( proj )
{
//Regenerate geometry
std :: vector < RimFracture *> fractures ;
proj -> descendantsIncludingThisOfType ( fractures );
for ( RimFracture * fracture : fractures )
{
2017-06-09 17:21:59 +02:00
if ( fracture -> fractureTemplate () == this )
2017-02-23 09:47:30 +01:00
{
2018-02-08 11:34:18 +01:00
if ( changedField == & m_azimuthAngle && ( fabs ( oldValue . toDouble () - fracture -> m_azimuth ()) < 1e-5 ))
2017-02-23 09:47:30 +01:00
{
2018-02-08 11:34:18 +01:00
fracture -> m_azimuth = m_azimuthAngle ;
2017-02-23 09:47:30 +01:00
}
2018-02-08 13:57:43 +01:00
if ( changedField == & m_orientationType )
2017-02-23 09:47:30 +01:00
{
2017-06-29 15:06:44 +02:00
if ( newValue == AZIMUTH )
{
2018-02-08 11:34:18 +01:00
fracture -> m_azimuth = m_azimuthAngle ;
2017-06-29 15:06:44 +02:00
}
else fracture -> updateAzimuthBasedOnWellAzimuthAngle ();
2017-02-23 09:47:30 +01:00
}
}
}
proj -> createDisplayModelAndRedrawAllViews ();
}
}
2017-02-07 09:09:00 +01:00
2018-02-08 11:34:18 +01:00
if ( changedField == & m_perforationLength || changedField == & m_perforationEfficiency || changedField == & m_wellDiameter )
2017-04-19 11:00:52 +02:00
{
RimProject * proj ;
this -> firstAncestorOrThisOfType ( proj );
if ( ! proj ) return ;
std :: vector < RimFracture *> fractures ;
proj -> descendantsIncludingThisOfType ( fractures );
for ( RimFracture * fracture : fractures )
{
2017-06-09 17:21:59 +02:00
if ( fracture -> fractureTemplate () == this )
2017-04-19 11:00:52 +02:00
{
2018-02-08 11:34:18 +01:00
if ( changedField == & m_perforationLength && ( fabs ( oldValue . toDouble () - fracture -> m_perforationLength ()) < 1e-5 ))
2017-04-19 11:00:52 +02:00
{
2018-02-08 11:34:18 +01:00
fracture -> m_perforationLength = m_perforationLength ;
2017-04-19 11:00:52 +02:00
}
2018-02-08 11:34:18 +01:00
if ( changedField == & m_perforationEfficiency && ( fabs ( oldValue . toDouble () - fracture -> m_perforationEfficiency ()) < 1e-5 ))
2017-04-19 11:00:52 +02:00
{
2018-02-08 11:34:18 +01:00
fracture -> m_perforationEfficiency = m_perforationEfficiency ;
2017-04-19 11:00:52 +02:00
}
2018-02-08 11:34:18 +01:00
if ( changedField == & m_wellDiameter && ( fabs ( oldValue . toDouble () - fracture -> m_wellDiameter ()) < 1e-5 ))
2017-04-19 11:00:52 +02:00
{
2018-02-08 11:34:18 +01:00
fracture -> m_wellDiameter = m_wellDiameter ;
2017-04-19 11:00:52 +02:00
}
}
}
}
2018-01-19 15:08:28 +01:00
2018-02-08 11:34:18 +01:00
if ( changedField == & m_perforationLength )
2018-01-19 15:08:28 +01:00
{
RimProject * proj ;
this -> firstAncestorOrThisOfType ( proj );
if ( proj )
{
proj -> createDisplayModelAndRedrawAllViews ();
}
}
2017-04-19 11:00:52 +02:00
}
2017-02-07 09:09:00 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: defineUiOrdering ( QString uiConfigName , caf :: PdmUiOrdering & uiOrdering )
{
2018-02-09 07:26:48 +01:00
prepareFieldsForUiDisplay ();
2018-03-01 14:16:08 +01:00
{
2018-03-05 10:20:47 +01:00
auto group = uiOrdering . addNewGroup ( "Sensitivity Scale Factors" );
2018-03-01 14:16:08 +01:00
group -> setCollapsedByDefault ( false );
group -> add ( & m_heightScaleFactor );
group -> add ( & m_widthScaleFactor );
2018-03-05 10:20:47 +01:00
group -> add ( & m_dFactorScaleFactor );
2018-03-20 08:22:38 +01:00
group -> add ( & m_conductivityScaleFactor );
2018-03-05 11:55:34 +01:00
2018-03-05 10:20:47 +01:00
group -> add ( & m_scaleApplyButton );
2018-03-01 14:16:08 +01:00
}
2018-02-15 20:01:41 +01:00
auto nonDarcyFlowGroup = uiOrdering . addNewGroup ( "Non-Darcy Flow" );
2018-02-15 21:43:35 +01:00
nonDarcyFlowGroup -> add ( & m_nonDarcyFlowType );
if ( m_nonDarcyFlowType == RimFractureTemplate :: NON_DARCY_USER_DEFINED )
2018-02-14 13:35:35 +01:00
{
2018-02-15 21:43:35 +01:00
nonDarcyFlowGroup -> add ( & m_userDefinedDFactor );
2018-02-14 13:35:35 +01:00
}
2018-02-15 21:43:35 +01:00
if ( m_nonDarcyFlowType == RimFractureTemplate :: NON_DARCY_COMPUTED )
2018-02-15 20:01:41 +01:00
{
2018-02-15 21:43:35 +01:00
nonDarcyFlowGroup -> add ( & m_inertialCoefficient );
{
auto group = nonDarcyFlowGroup -> addNewGroup ( "Effective Permeability" );
group -> add ( & m_permeabilityType );
group -> add ( & m_relativePermeability );
group -> add ( & m_userDefinedEffectivePermeability );
}
2018-02-15 20:01:41 +01:00
2018-02-15 21:43:35 +01:00
{
auto group = nonDarcyFlowGroup -> addNewGroup ( "Width" );
group -> add ( & m_fractureWidthType );
group -> add ( & m_fractureWidth );
}
2018-02-14 13:35:35 +01:00
2018-02-15 21:43:35 +01:00
nonDarcyFlowGroup -> add ( & m_relativeGasDensity );
nonDarcyFlowGroup -> add ( & m_gasViscosity );
nonDarcyFlowGroup -> add ( & m_dFactorDisplayField );
{
auto group = nonDarcyFlowGroup -> addNewGroup ( "D Factor Details" );
group -> setCollapsedByDefault ( true );
group -> add ( & m_dFactorSummaryText );
}
2018-02-14 13:35:35 +01:00
}
2018-02-09 07:26:48 +01:00
uiOrdering . add ( & m_fractureTemplateUnit );
2018-02-15 21:43:35 +01:00
uiOrdering . skipRemainingFields ( true );
2018-02-09 07:26:48 +01:00
}
2017-02-14 09:49:14 +01:00
2018-02-09 07:26:48 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: defineEditorAttribute ( const caf :: PdmFieldHandle * field , QString uiConfigName , caf :: PdmUiEditorAttribute * attribute )
{
if ( field == & m_perforationEfficiency )
{
auto myAttr = dynamic_cast < caf :: PdmUiDoubleSliderEditorAttribute *> ( attribute );
if ( myAttr )
{
myAttr -> m_minimum = 0 ;
myAttr -> m_maximum = 1.0 ;
}
}
2018-02-14 13:35:35 +01:00
if ( field == & m_dFactorSummaryText )
{
auto myAttr = dynamic_cast < caf :: PdmUiTextEditorAttribute *> ( attribute );
if ( myAttr )
{
myAttr -> wrapMode = caf :: PdmUiTextEditorAttribute :: NoWrap ;
QFont font ( "Monospace" , 10 );
myAttr -> font = font ;
myAttr -> textMode = caf :: PdmUiTextEditorAttribute :: HTML ;
}
}
2018-03-01 14:16:08 +01:00
2018-03-05 10:20:47 +01:00
if ( field == & m_scaleApplyButton )
2018-03-01 14:16:08 +01:00
{
caf :: PdmUiPushButtonEditorAttribute * attrib = dynamic_cast < caf :: PdmUiPushButtonEditorAttribute *> ( attribute );
if ( attrib )
{
attrib -> m_buttonText = "Apply" ;
}
}
2018-02-14 13:35:35 +01:00
}
2018-02-09 07:26:48 +01:00
//--------------------------------------------------------------------------------------------------
2018-02-16 14:17:28 +01:00
///
//--------------------------------------------------------------------------------------------------
QList < caf :: PdmOptionItemInfo > RimFractureTemplate :: calculateValueOptions ( const caf :: PdmFieldHandle * fieldNeedingOptions ,
bool * useOptionsOnly )
{
QList < caf :: PdmOptionItemInfo > options ;
if ( fieldNeedingOptions == & m_fractureWidthType )
{
options . push_back ( caf :: PdmOptionItemInfo ( caf :: AppEnum < WidthEnum >:: uiText ( USER_DEFINED_WIDTH ), USER_DEFINED_WIDTH ));
auto widthAndCond = widthAndConductivityAtWellPathIntersection ();
if ( widthAndCond . isValid ())
{
options . push_back ( caf :: PdmOptionItemInfo ( caf :: AppEnum < WidthEnum >:: uiText ( WIDTH_FROM_FRACTURE ), WIDTH_FROM_FRACTURE ));
}
else
{
m_fractureWidthType = USER_DEFINED_WIDTH ;
}
}
return options ;
}
//--------------------------------------------------------------------------------------------------
///
2018-02-09 07:26:48 +01:00
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: prepareFieldsForUiDisplay ()
{
2018-02-08 13:57:43 +01:00
if ( m_fractureTemplateUnit == RiaEclipseUnitTools :: UNITS_METRIC )
2017-06-08 11:00:35 +02:00
{
2018-02-08 11:34:18 +01:00
m_wellDiameter . uiCapability () -> setUiName ( "Well Diameter [m]" );
m_perforationLength . uiCapability () -> setUiName ( "Perforation Length [m]" );
2018-02-21 19:25:05 +01:00
m_fractureWidth . uiCapability () -> setUiName ( "Fracture Width [m]" );
2017-06-08 11:00:35 +02:00
}
2018-02-08 13:57:43 +01:00
else if ( m_fractureTemplateUnit == RiaEclipseUnitTools :: UNITS_FIELD )
2017-06-08 11:00:35 +02:00
{
2018-02-08 11:34:18 +01:00
m_wellDiameter . uiCapability () -> setUiName ( "Well Diameter [inches]" );
2018-02-21 19:25:05 +01:00
m_perforationLength . uiCapability () -> setUiName ( "Perforation Length [ft]" );
m_fractureWidth . uiCapability () -> setUiName ( "Fracture Width [ft]" );
2017-06-08 11:00:35 +02:00
}
2018-02-08 13:57:43 +01:00
if ( m_orientationType == RimFractureTemplate :: ALONG_WELL_PATH
|| m_orientationType == RimFractureTemplate :: TRANSVERSE_WELL_PATH )
2017-02-10 10:33:07 +01:00
{
2018-02-08 11:34:18 +01:00
m_azimuthAngle . uiCapability () -> setUiHidden ( true );
2017-02-10 10:33:07 +01:00
}
2018-02-08 13:57:43 +01:00
else if ( m_orientationType == RimFractureTemplate :: AZIMUTH )
2017-02-10 10:33:07 +01:00
{
2018-02-08 11:34:18 +01:00
m_azimuthAngle . uiCapability () -> setUiHidden ( false );
2017-02-10 10:33:07 +01:00
}
2017-06-02 15:34:37 +02:00
2018-02-08 13:57:43 +01:00
if ( m_orientationType == RimFractureTemplate :: ALONG_WELL_PATH )
2017-06-02 15:34:37 +02:00
{
2018-02-08 11:34:18 +01:00
m_perforationEfficiency . uiCapability () -> setUiHidden ( false );
m_perforationLength . uiCapability () -> setUiHidden ( false );
2017-06-02 15:34:37 +02:00
}
else
{
2018-02-08 11:34:18 +01:00
m_perforationEfficiency . uiCapability () -> setUiHidden ( true );
m_perforationLength . uiCapability () -> setUiHidden ( true );
2017-06-02 15:34:37 +02:00
}
2017-06-26 10:43:14 +02:00
2018-02-08 11:34:18 +01:00
if ( m_conductivityType == FINITE_CONDUCTIVITY )
2017-06-26 10:43:14 +02:00
{
2018-02-08 11:34:18 +01:00
m_wellDiameter . uiCapability () -> setUiHidden ( false );
2017-06-26 10:43:14 +02:00
}
2018-02-08 11:34:18 +01:00
else if ( m_conductivityType == INFINITE_CONDUCTIVITY )
2017-06-26 10:43:14 +02:00
{
2018-02-08 11:34:18 +01:00
m_wellDiameter . uiCapability () -> setUiHidden ( true );
2017-06-26 10:43:14 +02:00
}
2017-04-19 11:00:52 +02:00
2018-02-09 07:26:48 +01:00
// Non Darcy Flow
2018-02-14 13:35:35 +01:00
2018-02-16 14:17:28 +01:00
auto values = widthAndConductivityAtWellPathIntersection ();
if ( ! values . isValid ())
{
m_fractureWidthType = RimFractureTemplate :: USER_DEFINED_WIDTH ;
}
2018-02-15 21:43:35 +01:00
if ( m_fractureWidthType == RimFractureTemplate :: USER_DEFINED_WIDTH )
2018-02-14 13:35:35 +01:00
{
2018-02-15 21:43:35 +01:00
m_fractureWidth . uiCapability () -> setUiReadOnly ( false );
}
else
{
m_fractureWidth = values . m_width ;
2018-02-15 20:01:41 +01:00
2018-02-15 21:43:35 +01:00
m_fractureWidth . uiCapability () -> setUiReadOnly ( true );
}
2018-02-15 20:01:41 +01:00
2018-02-16 07:58:07 +01:00
if ( m_permeabilityType == RimFractureTemplate :: USER_DEFINED_PERMEABILITY )
2018-02-15 21:43:35 +01:00
{
2018-02-16 07:58:07 +01:00
m_relativePermeability . uiCapability () -> setUiHidden ( true );
m_userDefinedEffectivePermeability . uiCapability () -> setUiHidden ( false );
}
else
{
m_relativePermeability . uiCapability () -> setUiHidden ( false );
m_userDefinedEffectivePermeability . uiCapability () -> setUiHidden ( true );
2018-02-14 13:35:35 +01:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFractureTemplate :: dFactorSummary () const
{
QString text ;
2018-02-16 07:58:07 +01:00
auto val = dFactor ();
text += QString ( "D-factor : %1" ). arg ( val );
2018-02-14 13:35:35 +01:00
text += "<br>" ;
text += "<br>" ;
auto alpha = RiaDefines :: nonDarcyFlowAlpha ( m_fractureTemplateUnit ());
text += QString ( "α : %1" ). arg ( alpha );
text += "<br>" ;
auto beta = m_inertialCoefficient ;
text += QString ( "β : %1" ). arg ( beta );
text += "<br>" ;
double effPerm = effectivePermeability ();
text += QString ( "Ke : %1" ). arg ( effPerm );
text += "<br>" ;
double gamma = m_relativeGasDensity ;
text += QString ( "γ : %1" ). arg ( gamma );
text += "<br>" ;
2018-02-15 20:01:41 +01:00
auto h = fractureWidth ();
2018-02-14 13:35:35 +01:00
text += QString ( "h : %1" ). arg ( h );
text += "<br>" ;
auto wellRadius = m_wellDiameter / 2.0 ;
text += QString ( "rw : %1" ). arg ( wellRadius );
text += "<br>" ;
auto mu = m_gasViscosity ;
text += QString ( "μ : %1" ). arg ( mu );
return text ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFractureTemplate :: effectivePermeability () const
{
if ( m_permeabilityType () == RimFractureTemplate :: USER_DEFINED_PERMEABILITY )
{
2018-02-15 15:38:27 +01:00
return m_userDefinedEffectivePermeability ;
2018-02-14 13:35:35 +01:00
}
else
{
auto values = widthAndConductivityAtWellPathIntersection ();
auto fracPermeability = values . m_permeability ;
2018-02-15 15:38:27 +01:00
return fracPermeability * m_relativePermeability ;
2018-02-14 13:35:35 +01:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-02-16 07:58:07 +01:00
double RimFractureTemplate :: dFactor () const
2018-02-14 13:35:35 +01:00
{
2018-03-05 10:20:47 +01:00
double d ;
2018-02-15 21:43:35 +01:00
if ( m_nonDarcyFlowType == RimFractureTemplate :: NON_DARCY_USER_DEFINED )
{
2018-03-05 10:20:47 +01:00
d = m_userDefinedDFactor ;
2018-02-15 21:43:35 +01:00
}
2018-03-05 10:20:47 +01:00
else
{
auto alpha = RiaDefines :: nonDarcyFlowAlpha ( m_fractureTemplateUnit ());
auto beta = m_inertialCoefficient ;
auto effPerm = effectivePermeability ();
auto gamma = m_relativeGasDensity ;
2018-02-15 21:43:35 +01:00
2018-03-05 10:20:47 +01:00
auto radius = m_wellDiameter / 2.0 ;
auto mu = m_gasViscosity ;
auto h = fractureWidth ();
double numerator = alpha * beta * effPerm * gamma ;
double denumerator = h * radius * mu ;
2018-02-14 13:35:35 +01:00
2018-03-05 10:20:47 +01:00
if ( denumerator < 1e-10 ) return HUGE_VAL ;
2018-02-14 13:35:35 +01:00
2018-03-05 10:20:47 +01:00
d = numerator / denumerator ;
}
2018-02-14 13:35:35 +01:00
2018-03-05 10:20:47 +01:00
return d * m_dFactorScaleFactor ;
2018-02-14 13:35:35 +01:00
}
2018-02-16 07:58:07 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFractureTemplate :: kh () const
{
2018-03-20 10:48:06 +01:00
// kh = permeability * h
// conductivity = permeability * h
auto values = widthAndConductivityAtWellPathIntersection ();
if ( values . m_conductivity != HUGE_VAL )
{
// If conductivity is found in stim plan file, use this directly
return values . m_conductivity ;
}
2018-02-16 07:58:07 +01:00
return effectivePermeability () * fractureWidth ();
}
2018-02-21 09:50:50 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: convertToUnitSystem ( RiaEclipseUnitTools :: UnitSystem neededUnit )
{
2018-03-09 09:40:10 +01:00
if ( neededUnit == RiaEclipseUnitTools :: UNITS_METRIC )
2018-02-21 09:50:50 +01:00
{
m_perforationLength = RiaEclipseUnitTools :: feetToMeter ( m_perforationLength );
m_wellDiameter = RiaEclipseUnitTools :: inchToMeter ( m_wellDiameter );
2018-02-21 19:25:05 +01:00
m_fractureWidth = RiaEclipseUnitTools :: feetToMeter ( m_fractureWidth );
2018-02-21 09:50:50 +01:00
}
2018-03-09 09:40:10 +01:00
else if ( neededUnit == RiaEclipseUnitTools :: UNITS_FIELD )
2018-02-21 09:50:50 +01:00
{
m_perforationLength = RiaEclipseUnitTools :: meterToFeet ( m_perforationLength );
m_wellDiameter = RiaEclipseUnitTools :: meterToInch ( m_wellDiameter );
2018-02-21 19:25:05 +01:00
m_fractureWidth = RiaEclipseUnitTools :: meterToFeet ( m_fractureWidth );
2018-02-21 09:50:50 +01:00
}
}
2018-02-21 19:07:03 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: disconnectAllFracturesAndRedrawViews () const
{
// The unit has changed. Disconnect all fractures referencing this fracture template to avoid mix of units between fracture
// and template
std :: vector < caf :: PdmObjectHandle *> referringObjects ;
this -> objectsWithReferringPtrFields ( referringObjects );
for ( auto objHandle : referringObjects )
{
RimFracture * fracture = dynamic_cast < RimFracture *> ( objHandle );
if ( fracture )
{
fracture -> setFractureTemplate ( nullptr );
}
}
RimProject * proj ;
this -> firstAncestorOrThisOfType ( proj );
if ( proj )
{
proj -> createDisplayModelAndRedrawAllViews ();
}
}
2018-03-02 09:33:17 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: setId ( int id )
{
m_id = id ;
}
2018-03-02 14:33:47 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-03-05 11:55:34 +01:00
void RimFractureTemplate :: setScaleFactors ( double width , double height , double dFactor , double conductivity )
2018-03-02 14:33:47 +01:00
{
m_widthScaleFactor = width ;
m_heightScaleFactor = height ;
2018-03-05 10:20:47 +01:00
m_dFactorScaleFactor = dFactor ;
2018-03-20 08:22:38 +01:00
m_conductivityScaleFactor = conductivity ;
2018-03-02 14:33:47 +01:00
}
2018-03-05 14:17:18 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: setContainmentTopKLayer ( int topKLayer )
{
m_fractureContainment -> setTopKLayer ( topKLayer );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: setContainmentBaseKLayer ( int baseKLayer )
{
m_fractureContainment -> setBaseKLayer ( baseKLayer );
}
2018-02-14 13:35:35 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-02-15 20:01:41 +01:00
double RimFractureTemplate :: fractureWidth () const
2018-02-14 13:35:35 +01:00
{
2018-02-15 20:01:41 +01:00
if ( m_fractureWidthType == RimFractureTemplate :: WIDTH_FROM_FRACTURE )
2018-02-09 07:26:48 +01:00
{
2018-02-14 13:35:35 +01:00
auto values = widthAndConductivityAtWellPathIntersection ();
return values . m_width ;
2017-04-19 11:00:52 +02:00
}
2018-02-15 20:01:41 +01:00
return m_fractureWidth ;
2017-04-19 11:00:52 +02:00
}
2017-06-08 09:15:50 +02:00
2018-02-19 13:54:29 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFractureTemplate :: nameAndUnit () const
{
QString decoratedName ;
if ( m_fractureTemplateUnit == RiaEclipseUnitTools :: UNITS_METRIC )
{
decoratedName += "[M] - " ;
}
else if ( m_fractureTemplateUnit == RiaEclipseUnitTools :: UNITS_FIELD )
{
decoratedName += "[F] - " ;
}
decoratedName += m_name ;
return decoratedName ;
}
2017-06-15 10:49:27 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-02-21 10:10:22 +01:00
double RimFractureTemplate :: wellDiameter ()
2017-06-15 10:49:27 +02:00
{
2018-02-21 09:10:08 +01:00
return m_wellDiameter ;
2017-06-15 10:49:27 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-02-21 10:10:22 +01:00
double RimFractureTemplate :: perforationLength ()
2017-06-15 10:49:27 +02:00
{
2018-02-21 09:10:08 +01:00
return m_perforationLength ;
2017-06-15 10:49:27 +02:00
}
2017-06-20 11:18:19 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimFractureContainment * RimFractureTemplate :: fractureContainment ()
{
return m_fractureContainment ();
}
2018-02-08 11:34:18 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFractureTemplate :: FracConductivityEnum RimFractureTemplate :: conductivityType () const
{
return m_conductivityType ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RimFractureTemplate :: azimuthAngle () const
{
return m_azimuthAngle ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RimFractureTemplate :: skinFactor () const
{
return m_skinFactor ;
}
2017-06-08 09:15:50 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureTemplate :: setDefaultWellDiameterFromUnit ()
{
2018-02-08 13:57:43 +01:00
if ( m_fractureTemplateUnit == RiaEclipseUnitTools :: UNITS_FIELD )
2017-06-08 09:15:50 +02:00
{
2018-02-08 11:34:18 +01:00
m_wellDiameter = 8.5 ;
2017-06-08 09:15:50 +02:00
}
2018-02-08 13:57:43 +01:00
else if ( m_fractureTemplateUnit == RiaEclipseUnitTools :: UNITS_METRIC )
2017-06-08 09:15:50 +02:00
{
2018-02-08 11:34:18 +01:00
m_wellDiameter = 0.216 ;
2017-06-08 09:15:50 +02:00
}
2018-01-10 07:44:26 +01:00
}
2018-02-16 07:58:07 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFractureTemplate :: isNonDarcyFlowEnabled () const
{
return m_nonDarcyFlowType () != RimFractureTemplate :: NON_DARCY_NONE ;
}