Merge pull request #7960 from OPM/geomech_WIA4

GeoMech: Well Integrity Analysis
This commit is contained in:
jonjenssen
2021-09-09 17:34:27 +02:00
committed by GitHub
parent c603e6fe90
commit a5b80c649b
49 changed files with 2778 additions and 30 deletions

View File

@@ -10,6 +10,11 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTarget.h
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTieIn.h
${CMAKE_CURRENT_LIST_DIR}/RimWellIASettings.h
${CMAKE_CURRENT_LIST_DIR}/RimWellIASettingsCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimWellIAModelBox.h
${CMAKE_CURRENT_LIST_DIR}/RimWellIAModelData.h
${CMAKE_CURRENT_LIST_DIR}/RimWellIADataAccess.h
)
set(SOURCE_GROUP_SOURCE_FILES
@@ -24,6 +29,11 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGroup.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTarget.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellPathTieIn.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellIASettings.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellIASettingsCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellIAModelBox.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellIAModelData.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellIADataAccess.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@@ -0,0 +1,130 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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 "RimWellIADataAccess.h"
#include "RigFemClosestResultIndexCalculator.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigGeoMechCaseData.h"
#include "RimGeoMechCase.h"
#include "../cafHexInterpolator/cafHexInterpolator.h" // Use relative path, as this is a header only file not part of a library
#include "cvfBoundingBox.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIADataAccess::RimWellIADataAccess( RimGeoMechCase* thecase )
: m_case( thecase )
, m_caseData( nullptr )
{
if ( m_case ) m_caseData = m_case->geoMechData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIADataAccess::~RimWellIADataAccess()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimWellIADataAccess::resultIndex( RigFemResultPosEnum resultType, cvf::Vec3d position )
{
int closestCell = elementIndex( position );
if ( closestCell < 0 ) return -1;
RigFemClosestResultIndexCalculator closestIndexCalc( m_caseData->femParts()->part( 0 ), resultType, closestCell, -1, position );
return closestIndexCalc.resultIndexToClosestResult();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimWellIADataAccess::elementIndex( cvf::Vec3d position )
{
cvf::BoundingBox bb;
bb.add( position );
std::vector<size_t> closeCells;
m_caseData->femParts()->part( 0 )->findIntersectingCells( bb, &closeCells );
if ( closeCells.size() == 0 ) return -1;
return (int)closeCells[0];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIADataAccess::resultValue( QString fieldName,
QString componentName,
RigFemResultPosEnum resultType,
size_t resultIndex,
int timeStep )
{
RigFemResultAddress address( resultType, fieldName.toStdString(), componentName.toStdString() );
const std::vector<float>& scalarResults = m_caseData->femPartResults()->resultValues( address, 0, timeStep );
if ( resultIndex < scalarResults.size() ) return scalarResults[resultIndex];
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIADataAccess::interpolatedResultValue( QString fieldName,
QString componentName,
RigFemResultPosEnum resultType,
cvf::Vec3d position,
int timeStep )
{
RigFemResultAddress address( resultType, fieldName.toStdString(), componentName.toStdString() );
int elmIdx = elementIndex( position );
RigFemPart* femPart = m_caseData->femParts()->part( 0 );
RigElementType elmType = femPart->elementType( elmIdx );
const int* elementConn = femPart->connectivities( elmIdx );
int elmNodeCount = RigFemTypes::elementNodeCount( elmType );
const std::vector<float>& scalarResults = m_caseData->femPartResults()->resultValues( address, 0, timeStep );
std::array<double, 8> nodeResults;
std::array<cvf::Vec3d, 8> nodeCorners;
for ( int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx )
{
int nodeIdx = elementConn[lNodeIdx];
size_t resIdx = femPart->resultValueIdxFromResultPosType( resultType, elmIdx, lNodeIdx );
if ( resIdx >= scalarResults.size() )
nodeResults[lNodeIdx] = 0.0;
else
nodeResults[lNodeIdx] = scalarResults[resIdx];
nodeCorners[lNodeIdx] = cvf::Vec3d( femPart->nodes().coordinates[nodeIdx] );
}
return caf::HexInterpolator::interpolateHex( nodeCorners, nodeResults, position );
}

View File

@@ -0,0 +1,58 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemResultPosEnum.h"
#include "cvfVector3.h"
#include <QString>
#include <vector>
class RimGeoMechCase;
class RigGeoMechCaseData;
//==================================================================================================
///
///
//==================================================================================================
class RimWellIADataAccess
{
public:
RimWellIADataAccess( RimGeoMechCase* thecase );
~RimWellIADataAccess();
int resultIndex( RigFemResultPosEnum resultType, cvf::Vec3d position );
int elementIndex( cvf::Vec3d position );
double resultValue( QString fieldName,
QString componentName,
RigFemResultPosEnum resultType,
size_t resultIndex,
int timeStep );
double interpolatedResultValue( QString fieldname,
QString componentName,
RigFemResultPosEnum resultType,
cvf::Vec3d position,
int timeStep );
private:
RimGeoMechCase* m_case;
RigGeoMechCaseData* m_caseData;
};

View File

@@ -0,0 +1,109 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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 "RimWellIAModelBox.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIAModelBox::RimWellIAModelBox()
{
m_vertices.resize( 8 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIAModelBox::~RimWellIAModelBox()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RimWellIAModelBox::vertices() const
{
return m_vertices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RimWellIAModelBox::center() const
{
return m_center;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellIAModelBox::updateBox( cvf::Vec3d startPos, cvf::Vec3d endPos, double xyBuffer, double depthBuffer )
{
m_center = startPos + endPos;
m_center /= 2.0;
cvf::Vec3d upwards = startPos - endPos;
upwards.normalize();
cvf::Vec3d downwards = upwards * -1.0;
cvf::Vec3d xdir = upwards.perpendicularVector();
xdir.normalize();
cvf::Vec3d ydir = upwards ^ xdir;
ydir.normalize();
cvf::Vec3d topCenter = startPos + upwards * depthBuffer;
cvf::Vec3d bottomCenter = endPos + downwards * depthBuffer;
std::vector<cvf::Vec3d> topVertices = generateRectangle( topCenter, xdir, ydir, xyBuffer );
std::vector<cvf::Vec3d> bottomVertices = generateRectangle( bottomCenter, xdir, ydir, xyBuffer );
for ( size_t i = 0; i < 4; i++ )
{
m_vertices[i] = bottomVertices[i];
m_vertices[i + 4] = topVertices[i];
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d>
RimWellIAModelBox::generateRectangle( cvf::Vec3d center, cvf::Vec3d unitX, cvf::Vec3d unitY, double buffer )
{
std::vector<cvf::Vec3d> corners;
corners.resize( 4 );
corners[0] = center;
corners[0] -= unitX * buffer;
corners[0] -= unitY * buffer;
corners[1] = center;
corners[1] += unitX * buffer;
corners[1] -= unitY * buffer;
corners[2] = center;
corners[2] += unitX * buffer;
corners[2] += unitY * buffer;
corners[3] = center;
corners[3] -= unitX * buffer;
corners[3] += unitY * buffer;
return corners;
}

View File

@@ -0,0 +1,47 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfVector3.h"
#include <QString>
#include <map>
#include <vector>
//==================================================================================================
///
///
//==================================================================================================
class RimWellIAModelBox
{
public:
RimWellIAModelBox();
~RimWellIAModelBox();
std::vector<cvf::Vec3d> vertices() const;
cvf::Vec3d center() const;
bool updateBox( cvf::Vec3d startPos, cvf::Vec3d endPos, double xyBuffer, double depthBuffer );
private:
std::vector<cvf::Vec3d> generateRectangle( cvf::Vec3d center, cvf::Vec3d unitX, cvf::Vec3d unitY, double buffer );
std::vector<cvf::Vec3d> m_vertices;
cvf::Vec3d m_center;
};

View File

@@ -0,0 +1,120 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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 "RimWellIAModelData.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIAModelData::RimWellIAModelData()
{
m_displacements.resize( 8 );
m_casingPressure = 0.0;
m_formationPressure = 0.0;
m_temperature = 0.0;
m_dayoffset = 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIAModelData::~RimWellIAModelData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RimWellIAModelData::displacements() const
{
return m_displacements;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIAModelData::setDisplacement( int cornerIndex, cvf::Vec3d displacement )
{
size_t ci = cornerIndex;
if ( ( cornerIndex >= 0 ) && ( ci < m_displacements.size() ) ) m_displacements[ci] = displacement;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIAModelData::setCasingPressure( double pressure )
{
m_casingPressure = pressure;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIAModelData::casingPressure() const
{
return m_casingPressure;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIAModelData::setFormationPressure( double pressure )
{
m_formationPressure = pressure;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIAModelData::formationPressure() const
{
return m_formationPressure;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIAModelData::setTemperature( double temp )
{
m_temperature = temp;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIAModelData::temperature() const
{
return m_temperature;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimWellIAModelData::dayOffset() const
{
return m_dayoffset;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIAModelData::setDayOffset( int days )
{
m_dayoffset = days;
}

View File

@@ -0,0 +1,58 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfVector3.h"
#include <QString>
#include <map>
#include <vector>
//==================================================================================================
///
///
//==================================================================================================
class RimWellIAModelData
{
public:
RimWellIAModelData();
~RimWellIAModelData();
std::vector<cvf::Vec3d> displacements() const;
void setDisplacement( int cornerIndex, cvf::Vec3d displacement );
void setCasingPressure( double pressure );
double casingPressure() const;
void setFormationPressure( double pressure );
double formationPressure() const;
void setTemperature( double temp );
double temperature() const;
int dayOffset() const;
void setDayOffset( int days );
private:
std::vector<cvf::Vec3d> m_displacements;
double m_casingPressure;
double m_formationPressure;
double m_temperature;
int m_dayoffset;
};

View File

@@ -0,0 +1,640 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 - Equinor 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 "RimWellIASettings.h"
#include "RiaApplication.h"
#include "RiaPreferencesGeoMech.h"
#include "RigWellPath.h"
#include "RigWellPathGeometryTools.h"
#include "RimDoubleParameter.h"
#include "RimGenericParameter.h"
#include "RimGeoMechCase.h"
#include "RimIntegerParameter.h"
#include "RimParameterGroup.h"
#include "RimProject.h"
#include "RimStringParameter.h"
#include "RimTools.h"
#include "RimWellIADataAccess.h"
#include "RimWellIAModelData.h"
#include "RimWellPath.h"
#include "RifParameterXmlReader.h"
#include "cafPdmFieldCvfVec3d.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiDateEditor.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiTableViewEditor.h"
#include <QDebug>
#include <QFileInfo>
#include <cmath>
CAF_PDM_SOURCE_INIT( RimWellIASettings, "RimWellIASettings" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIASettings::RimWellIASettings()
{
CAF_PDM_InitObject( "Integrity Analysis Model Settings", ":/WellIntAnalysis.png", "", "" );
setName( "Model" );
CAF_PDM_InitFieldNoDefault( &m_geomechCase, "GeomechCase", "GeoMech Case", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_baseDir, "BaseDir", "Working Directory", "", "", "" );
m_baseDir.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitField( &m_startMD, "StartMeasuredDepth", 0.0, "Start MD", "", "", "" );
CAF_PDM_InitField( &m_endMD, "EndMeasuredDepth", 0.0, "End MD", "", "", "" );
m_startMD.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
m_endMD.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_bufferXY, "BufferXY", 20.0, "Model Size (XY)", "", "", "" );
CAF_PDM_InitField( &m_bufferZ, "BufferZ", 15.0, "Depth buffer size", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_parameters, "ModelingParameters", "Modeling Parameters", ":/Bullet.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_csvParameters, "TimeStepParameters", "Time Step Parameters", ":/Bullet.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_nameProxy, "NameProxy", "Name Proxy", "", "", "" );
m_nameProxy.registerGetMethod( this, &RimWellIASettings::fullName );
m_nameProxy.uiCapability()->setUiReadOnly( true );
m_nameProxy.uiCapability()->setUiHidden( true );
m_nameProxy.xmlCapability()->disableIO();
CAF_PDM_InitField( &m_showBox, "showBox", false, "Show model box", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_geostaticDate, "startDate", "Start Date (geostatic):", "", "", "" );
CAF_PDM_InitField( &m_boxValid, "boxValid", false, "Model box is valid", "", "", "" );
m_boxValid.uiCapability()->setUiHidden( true );
this->setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIASettings::~RimWellIASettings()
{
resetResInsightParameters();
resetModelData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellIASettings::initSettings( QString& outErrmsg )
{
initCsvParameters();
RifParameterXmlReader basicreader( RiaPreferencesGeoMech::current()->geomechWIADefaultXML() );
if ( !basicreader.parseFile( outErrmsg ) ) return false;
m_parameters.clear();
for ( auto group : basicreader.parameterGroups() )
{
m_parameters.push_back( group );
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::updateVisualization()
{
generateModelBox();
RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
if ( ( changedField == &m_startMD ) || ( changedField == &m_endMD ) || ( changedField == objectToggleField() ) ||
( changedField == &m_bufferXY ) || ( changedField == &m_bufferZ ) || ( changedField == &m_showBox ) )
{
updateVisualization();
}
this->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimWellIASettings::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_geomechCase )
{
RimTools::geoMechCaseOptionItems( &options );
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
RimWellPath* wellPath;
firstAncestorOrThisOfType( wellPath );
if ( wellPath )
{
if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_METRIC )
{
m_startMD.uiCapability()->setUiName( "Start MD [m]" );
m_endMD.uiCapability()->setUiName( "End MD [m]" );
}
else if ( wellPath->unitSystem() == RiaDefines::EclipseUnitSystem::UNITS_FIELD )
{
m_startMD.uiCapability()->setUiName( "Start MD [ft]" );
m_endMD.uiCapability()->setUiName( "End MD [ft]" );
}
}
auto generalGroup = uiOrdering.addNewGroup( "General" );
generalGroup->add( nameField() );
generalGroup->add( &m_baseDir );
auto geoGroup = uiOrdering.addNewGroup( "GeoMechanical Settings" );
geoGroup->add( &m_geomechCase );
geoGroup->add( &m_geostaticDate );
auto modelGroup = uiOrdering.addNewGroup( "Model Settings" );
modelGroup->add( &m_startMD );
modelGroup->add( &m_endMD );
modelGroup->add( &m_bufferXY );
modelGroup->add( &m_bufferZ );
modelGroup->add( &m_showBox );
uiOrdering.skipRemainingFields( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_startMD || field == &m_endMD )
{
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
if ( myAttr )
{
RimWellPath* wellPath = nullptr;
this->firstAncestorOrThisOfType( wellPath );
if ( !wellPath ) return;
myAttr->m_minimum = wellPath->uniqueStartMD();
myAttr->m_maximum = wellPath->uniqueEndMD();
}
}
else if ( field == &m_geostaticDate )
{
caf::PdmUiDateEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDateEditorAttribute*>( attribute );
if ( myAttr )
{
myAttr->dateFormat = "dd MMM yyyy";
}
}
}
//--------------------------------------------------------------------------------------------------
/// Return the name to show in the tree selector
//--------------------------------------------------------------------------------------------------
QString RimWellIASettings::fullName() const
{
return QString( "%1 - [%2 - %3]" ).arg( name() ).arg( m_startMD ).arg( m_endMD );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellIASettings::modelBoxValid() const
{
return m_boxValid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RimWellIASettings::modelBoxVertices() const
{
return m_modelbox.vertices();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellIAModelData*> RimWellIASettings::modelData() const
{
return m_modelData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellIASettings::userDescriptionField()
{
return &m_nameProxy;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellIASettings::geomechCaseFilename() const
{
if ( m_geomechCase ) return m_geomechCase->gridFileName();
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellIASettings::geomechCaseName() const
{
QFileInfo fi( geomechCaseFilename() );
return fi.baseName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCase* RimWellIASettings::geomechCase() const
{
return m_geomechCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RimWellIASettings::geostaticDate() const
{
return m_geostaticDate;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellIASettings::outputBaseDirectory() const
{
return m_baseDir();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellIASettings::jsonInputFilename() const
{
return m_baseDir() + "/model_input.json";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellIASettings::csvInputFilename() const
{
return m_baseDir() + "/model_input.csv";
}
QStringList RimWellIASettings::commandParameters() const
{
QStringList retlist;
retlist << m_baseDir();
retlist << jsonInputFilename();
retlist << csvInputFilename();
return retlist;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::setGeoMechCase( RimGeoMechCase* geomechCase )
{
m_geomechCase = geomechCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::setOutputBaseDirectory( QString baseDir )
{
m_baseDir = baseDir;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::setShowBox( bool show )
{
m_showBox = show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellIASettings::showBox() const
{
return m_showBox && m_boxValid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::list<RimParameterGroup*> RimWellIASettings::inputParameterGroups() const
{
std::list<RimParameterGroup*> retlist;
for ( auto& group : m_parameters )
retlist.push_back( group );
return retlist;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::list<RimParameterGroup*> RimWellIASettings::resinsightParameterGroups() const
{
std::list<RimParameterGroup*> retlist;
for ( auto& group : m_parametersRI )
retlist.push_back( group );
return retlist;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::resetResInsightParameters()
{
for ( auto& group : m_parametersRI )
{
delete group;
}
m_parametersRI.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::updateResInsightParameters()
{
resetResInsightParameters();
RimParameterGroup* wellcoords = new RimParameterGroup();
wellcoords->setName( "well_coordinates" );
wellcoords->setLabel( "Well Coordinates" );
wellcoords->addParameter( "x_well", m_modelbox.center().x() );
wellcoords->addParameter( "y_well", m_modelbox.center().y() );
wellcoords->addParameter( "z_well", m_modelbox.center().z() );
m_parametersRI.push_back( wellcoords );
RimParameterGroup* initcond = new RimParameterGroup();
initcond->setName( "BC_initial_conditions" );
initcond->setLabel( "BC Initial Conditions" );
initcond->addParameter( "analysis_depth", std::abs( m_modelbox.center().z() ) );
m_parametersRI.push_back( initcond );
RimParameterGroup* initialStress = new RimParameterGroup();
initialStress->setName( "initial_stress" );
initialStress->setLabel( "Initial Stress" );
initialStress->setComment(
"SXX is in North direction, SYY is East, SZZ is vertical; PP is the initial pore pressure in the "
"formation, set to 0 for hydrostatic assumption; inclination is 0 for a vertical well" );
cvf::Vec3d position = m_modelbox.center();
RimWellIADataAccess dataAccess( m_geomechCase );
std::vector<QString> nativeKeys{ "S11", "S22", "S33", "S12", "S13", "S23" };
std::vector<QString> paramKeys{ "SXX", "SYY", "SZZ", "SXY", "SXZ", "SYZ" };
for ( size_t i = 0; i < nativeKeys.size(); i++ )
{
double stressValue =
dataAccess.interpolatedResultValue( "ST", nativeKeys[i], RigFemResultPosEnum::RIG_ELEMENT_NODAL, position, 0 );
initialStress->addParameter( paramKeys[i], stressValue );
}
double ppValue = dataAccess.interpolatedResultValue( "POR-Bar", "", RigFemResultPosEnum::RIG_NODAL, position, 0 );
initialStress->addParameter( "PP", ppValue );
auto angles = RigWellPathGeometryTools::calculateAzimuthAndInclinationAtMd( ( m_startMD + m_endMD ) / 2.0,
wellPath()->wellPathGeometry() );
initialStress->addParameter( "azimuth_well", angles.first );
initialStress->addParameter( "inclination_well", angles.second );
m_parametersRI.push_back( initialStress );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::addCsvGroup( QString name, QStringList timeSteps, double defaultValue /* = 0.0 */ )
{
RimParameterGroup* group = new RimParameterGroup();
group->setName( name );
const int noParams = timeSteps.size();
for ( int i = 0; i < noParams; i++ )
{
group->addParameter( timeSteps[i], defaultValue );
}
m_csvParameters.push_back( group );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::initCsvParameters()
{
m_csvParameters.clear();
QStringList timeSteps = m_geomechCase->timeStepStrings();
addCsvGroup( m_csvGroupNames[(size_t)CSV_GROUPNAME::CASING_PRESSURE], timeSteps );
addCsvGroup( m_csvGroupNames[(size_t)CSV_GROUPNAME::FORMATION_PRESSURE], timeSteps );
addCsvGroup( m_csvGroupNames[(size_t)CSV_GROUPNAME::TEMPERATURE], timeSteps, 70.0 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::setDepthInterval( double startMD, double endMD )
{
m_startMD = startMD;
m_endMD = endMD;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIASettings::startMD()
{
return m_startMD;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellIASettings::endMD()
{
return m_endMD;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::resetModelData()
{
for ( auto& modeldata : m_modelData )
{
delete modeldata;
}
m_modelData.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellIASettings::wellPath() const
{
RimWellPath* wellpath = nullptr;
this->firstAncestorOrThisOfTypeAsserted( wellpath );
return wellpath;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::generateModelBox()
{
RimWellPath* path = wellPath();
if ( !path ) return;
RigWellPath* wellgeom = path->wellPathGeometry();
if ( !wellgeom ) return;
cvf::Vec3d startPos = wellgeom->interpolatedPointAlongWellPath( m_startMD );
cvf::Vec3d endPos = wellgeom->interpolatedPointAlongWellPath( m_endMD );
m_boxValid = m_modelbox.updateBox( startPos, endPos, m_bufferXY, m_bufferZ );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettings::extractModelData()
{
generateModelBox();
updateResInsightParameters();
resetModelData();
QDateTime startDate = geostaticDate();
int timestep = 0;
auto timeStepStrings = m_geomechCase->timeStepStrings();
for ( auto& date : timeStepDates() )
{
RimWellIAModelData* data = new RimWellIAModelData();
data->setDayOffset( startDate.daysTo( date ) );
for ( auto& group : m_csvParameters )
{
if ( group->name() == m_csvGroupNames[(size_t)CSV_GROUPNAME::CASING_PRESSURE] )
{
data->setCasingPressure( group->parameterValue( timeStepStrings[timestep] ).toDouble() );
}
else if ( group->name() == m_csvGroupNames[(size_t)CSV_GROUPNAME::FORMATION_PRESSURE] )
{
data->setFormationPressure( group->parameterValue( timeStepStrings[timestep] ).toDouble() );
}
else if ( group->name() == m_csvGroupNames[(size_t)CSV_GROUPNAME::TEMPERATURE] )
{
data->setTemperature( group->parameterValue( timeStepStrings[timestep] ).toDouble() );
}
}
const std::vector<cvf::Vec3d> displacements = extractDisplacments( m_modelbox.vertices(), timestep );
for ( size_t i = 0; i < displacements.size(); i++ )
{
data->setDisplacement( (int)i, displacements[i] );
}
m_modelData.push_back( data );
timestep++;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RimWellIASettings::timeStepDates()
{
std::vector<QDateTime> dates = m_geomechCase->timeStepDates();
if ( dates.size() < (size_t)m_geomechCase->timeStepStrings().size() )
dates.insert( dates.begin(), m_geostaticDate );
return dates;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RimWellIASettings::extractDisplacments( std::vector<cvf::Vec3d> corners, int timeStep )
{
RimWellIADataAccess dataAccess( m_geomechCase );
std::vector<cvf::Vec3d> displacements;
for ( auto& pos : corners )
{
double u1 = dataAccess.interpolatedResultValue( "U", "U1", RigFemResultPosEnum::RIG_NODAL, pos, timeStep );
double u2 = dataAccess.interpolatedResultValue( "U", "U2", RigFemResultPosEnum::RIG_NODAL, pos, timeStep );
double u3 = dataAccess.interpolatedResultValue( "U", "U3", RigFemResultPosEnum::RIG_NODAL, pos, timeStep );
displacements.push_back( cvf::Vec3d( u1, u2, u3 ) );
}
return displacements;
}

View File

@@ -0,0 +1,145 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimCheckableNamedObject.h"
#include "RimWellIAModelBox.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmFieldCvfVec3d.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmPtrField.h"
#include "cvfVector3.h"
#include <QDateTime>
#include <QString>
#include <QStringList>
#include <list>
#include <string>
#include <vector>
class RimGeoMechCase;
class RimParameterGroup;
class RimGenericParameter;
class RimWellPath;
class RimWellIAModelData;
class RimWellIASettings : public RimCheckableNamedObject
{
CAF_PDM_HEADER_INIT;
public:
RimWellIASettings();
~RimWellIASettings() override;
bool initSettings( QString& outErrmsg );
void setGeoMechCase( RimGeoMechCase* geomechCase );
RimGeoMechCase* geomechCase() const;
QString geomechCaseFilename() const;
QString geomechCaseName() const;
QDateTime geostaticDate() const;
void setOutputBaseDirectory( QString baseDir );
QString outputBaseDirectory() const;
bool showBox() const;
void setShowBox( bool show );
const std::list<RimParameterGroup*> inputParameterGroups() const;
const std::list<RimParameterGroup*> resinsightParameterGroups() const;
void setDepthInterval( double startMD, double endMD );
double startMD();
double endMD();
QString jsonInputFilename() const;
QString csvInputFilename() const;
QStringList commandParameters() const;
RimWellPath* wellPath() const;
bool modelBoxValid() const;
std::vector<cvf::Vec3d> modelBoxVertices() const;
std::vector<RimWellIAModelData*> modelData() const;
void extractModelData();
void updateVisualization();
protected:
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
caf::PdmFieldHandle* userDescriptionField() override;
QString fullName() const;
private:
std::vector<QDateTime> timeStepDates();
void initCsvParameters();
void updateResInsightParameters();
void generateModelBox();
void resetModelData();
void resetResInsightParameters();
void addCsvGroup( QString name, QStringList timeSteps, double defaultValue = 0.0 );
std::vector<cvf::Vec3d> extractDisplacments( std::vector<cvf::Vec3d> corners, int timeStep );
private:
caf::PdmProxyValueField<QString> m_nameProxy;
caf::PdmPtrField<RimGeoMechCase*> m_geomechCase;
caf::PdmField<QString> m_baseDir;
caf::PdmField<bool> m_showBox;
caf::PdmField<bool> m_boxValid;
caf::PdmField<double> m_startMD;
caf::PdmField<double> m_endMD;
caf::PdmField<double> m_bufferXY;
caf::PdmField<double> m_bufferZ;
caf::PdmField<QDateTime> m_geostaticDate;
caf::PdmChildArrayField<RimParameterGroup*> m_parameters;
std::vector<RimParameterGroup*> m_parametersRI;
caf::PdmChildArrayField<RimParameterGroup*> m_csvParameters;
RimWellIAModelBox m_modelbox;
std::vector<RimWellIAModelData*> m_modelData;
enum class CSV_GROUPNAME
{
FORMATION_PRESSURE = 0,
CASING_PRESSURE = 1,
TEMPERATURE = 2
};
const std::vector<QString> m_csvGroupNames{ "Formation Pressure", "Casing Pressure", "Temperature" };
};

View File

@@ -0,0 +1,119 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 Equinor 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 "RimWellIASettingsCollection.h"
#include "RiaApplication.h"
#include "RiaLogging.h"
#include "RimGeoMechCase.h"
#include "RimProject.h"
#include "RimWellIASettings.h"
#include "RimWellPath.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "QFile"
CAF_PDM_SOURCE_INIT( RimWellIASettingsCollection, "RimWellIASettingsCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIASettingsCollection::RimWellIASettingsCollection()
{
CAF_PDM_InitObject( "Integrity Analysis Models", ":/WellIntAnalysis.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_wellIASettings, "WellIASettings", "Settings", "", "", "" );
m_wellIASettings.uiCapability()->setUiTreeHidden( true );
setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIASettingsCollection::~RimWellIASettingsCollection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIASettings* RimWellIASettingsCollection::startWellIntegrationAnalysis( QString baseDir,
RimWellPath* wellPath,
double measuredDepth,
RimGeoMechCase* theCase,
QString& outErrmsg )
{
RimWellIASettings* modelSettings = new RimWellIASettings();
modelSettings->setGeoMechCase( theCase );
double depthSize = 50;
if ( theCase ) depthSize = theCase->characteristicCellSize();
modelSettings->setDepthInterval( measuredDepth, measuredDepth + depthSize );
modelSettings->setOutputBaseDirectory( baseDir );
QString errmsg;
if ( !modelSettings->initSettings( errmsg ) )
{
delete modelSettings;
outErrmsg = "Unable to load default parameters from the WIA default parameter XML file:\n" + errmsg;
return nullptr;
}
m_wellIASettings.push_back( modelSettings );
return modelSettings;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellIASettings*> RimWellIASettingsCollection::settings() const
{
return m_wellIASettings.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellIASettingsCollection::isEnabled() const
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellIASettingsCollection::hasSettings() const
{
return m_wellIASettings.size() > 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellIASettingsCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects )
{
RimWellPath* wellPath;
this->firstAncestorOrThisOfType( wellPath );
if ( wellPath ) wellPath->updateConnectedEditors();
RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews();
}

View File

@@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2021 Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmField.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmObject.h"
#include <QString>
class RimWellIASettings;
class RimWellPath;
class RimGeoMechCase;
class RimWellIASettingsCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimWellIASettingsCollection();
~RimWellIASettingsCollection() override;
std::vector<RimWellIASettings*> settings() const;
bool isEnabled() const;
bool hasSettings() const;
RimWellIASettings* startWellIntegrationAnalysis( QString baseDir,
RimWellPath* wellPath,
double measuredDepth,
RimGeoMechCase* theCase,
QString& outErrmsg );
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
private:
caf::PdmChildArrayField<RimWellIASettings*> m_wellIASettings;
};

View File

@@ -42,6 +42,7 @@
#include "RimProject.h"
#include "RimStimPlanModelCollection.h"
#include "RimTools.h"
#include "RimWellIASettingsCollection.h"
#include "RimWellLogFile.h"
#include "RimWellLogFileChannel.h"
#include "RimWellLogPlotCollection.h"
@@ -137,6 +138,12 @@ RimWellPath::RimWellPath()
CAF_PDM_InitFieldNoDefault( &m_wellPathTieIn, "WellPathTieIn", "well Path Tie-In", "", "", "" );
m_wellPathTieIn = new RimWellPathTieIn;
m_wellPathTieIn->connectWellPaths( nullptr, this, 0.0 );
CAF_PDM_InitFieldNoDefault( &m_wellIASettingsCollection, "WellIASettings", "Integrity Analysis Settings", "", "", "" );
m_wellIASettingsCollection = new RimWellIASettingsCollection();
m_wellIASettingsCollection->uiCapability()->setUiTreeHidden( true );
this->setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
@@ -610,6 +617,14 @@ const RimWellPathAttributeCollection* RimWellPath::attributeCollection() const
return m_wellPathAttributes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellIASettingsCollection* RimWellPath::wellIASettingsCollection()
{
return m_wellIASettingsCollection;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -714,6 +729,11 @@ void RimWellPath::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering,
{
uiTreeOrdering.add( &m_wellLogFiles );
if ( m_wellIASettingsCollection()->isEnabled() && m_wellIASettingsCollection()->hasSettings() )
{
uiTreeOrdering.add( m_wellIASettingsCollection() );
}
if ( m_completionSettings() && !allCompletionsRecursively().empty() )
{
uiTreeOrdering.add( m_completionSettings() );

View File

@@ -59,6 +59,7 @@ class Rim3dWellLogCurve;
class Rim3dWellLogCurveCollection;
class RimWellPathTieIn;
class RimMswCompletionParameters;
class RimWellIASettingsCollection;
//==================================================================================================
///
@@ -136,6 +137,7 @@ public:
const RimStimPlanModelCollection* stimPlanModelCollection() const;
RimWellPathAttributeCollection* attributeCollection();
const RimWellPathAttributeCollection* attributeCollection() const;
RimWellIASettingsCollection* wellIASettingsCollection();
bool showWellPathLabel() const;
bool showWellPath() const;
@@ -210,6 +212,7 @@ private:
caf::PdmChildField<RimWellPathCompletionSettings*> m_completionSettings;
caf::PdmChildField<RimWellPathCompletions*> m_completions;
caf::PdmChildField<RimWellPathAttributeCollection*> m_wellPathAttributes;
caf::PdmChildField<RimWellIASettingsCollection*> m_wellIASettingsCollection;
caf::PdmChildField<RimWellPathTieIn*> m_wellPathTieIn;