Merge pull request #6332 from OPM/mud-weight-fracture-gradient-fix-6301

Mud weight fracture gradient fix 6301
This commit is contained in:
Kristian Bendiksen 2020-08-24 14:30:43 +02:00 committed by GitHub
commit 14e0a9c2da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 307 additions and 93 deletions

View File

@ -39,6 +39,22 @@ RigFemPart::~RigFemPart()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::elementPartId() const
{
return m_elementPartId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFemPart::setElementPartId( int partId )
{
m_elementPartId = partId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -67,6 +83,94 @@ void RigFemPart::appendElement( RigElementType elmType, int id, const int* conne
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::elementCount() const
{
return static_cast<int>( m_elementId.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::elmId( size_t elementIdx ) const
{
return m_elementId[elementIdx];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigElementType RigFemPart::elementType( size_t elementIdx ) const
{
return m_elementTypes[elementIdx];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const int* RigFemPart::connectivities( size_t elementIdx ) const
{
return &m_allElementConnectivities[m_elementConnectivityStartIndices[elementIdx]];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigFemPart::elementNodeResultIdx( int elementIdx, int elmLocalNodeIdx ) const
{
return m_elementConnectivityStartIndices[elementIdx] + elmLocalNodeIdx;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::nodeIdxFromElementNodeResultIdx( size_t elmNodeResultIdx ) const
{
return m_allElementConnectivities[elmNodeResultIdx];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::elementNeighbor( int elementIndex, int faceIndex ) const
{
return m_elmNeighbors[elementIndex].indicesToNeighborElms[faceIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::neighborFace( int elementIndex, int faceIndex ) const
{
return m_elmNeighbors[elementIndex].faceInNeighborElm[faceIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<int>& RigFemPart::elementIdxToId() const
{
return m_elementId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartNodes& RigFemPart::nodes()
{
return m_nodes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigFemPartNodes& RigFemPart::nodes() const
{
return m_nodes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -332,6 +436,14 @@ float RigFemPart::characteristicElementSize() const
return m_characteristicElementSize;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<int>& RigFemPart::possibleGridCornerElements() const
{
return m_possibleGridCornerElements;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -441,3 +553,12 @@ size_t RigFemPart::resultValueIdxFromResultPosType( RigFemResultPosEnum resultPo
CVF_ASSERT( false );
return 0u;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPart::isHexahedron( size_t elementIdx ) const
{
RigElementType elType = elementType( elementIdx );
return elType == HEX8 || elType == HEX8P;
}

View File

@ -49,51 +49,38 @@ public:
RigFemPart();
~RigFemPart() override;
int elementPartId() const { return m_elementPartId; }
void setElementPartId( int partId ) { m_elementPartId = partId; }
int elementPartId() const;
void setElementPartId( int partId );
void preAllocateElementStorage( int elementCount );
void appendElement( RigElementType elmType, int elementId, const int* connectivities );
int elementCount() const { return static_cast<int>( m_elementId.size() ); }
int elementCount() const;
int elmId( size_t elementIdx ) const { return m_elementId[elementIdx]; }
RigElementType elementType( size_t elementIdx ) const { return m_elementTypes[elementIdx]; }
const int* connectivities( size_t elementIdx ) const
{
return &m_allElementConnectivities[m_elementConnectivityStartIndices[elementIdx]];
}
int elmId( size_t elementIdx ) const;
RigElementType elementType( size_t elementIdx ) const;
bool isHexahedron( size_t elementIdx ) const;
const int* connectivities( size_t elementIdx ) const;
size_t elementNodeResultIdx( int elementIdx, int elmLocalNodeIdx ) const
{
return m_elementConnectivityStartIndices[elementIdx] + elmLocalNodeIdx;
}
size_t elementNodeResultIdx( int elementIdx, int elmLocalNodeIdx ) const;
size_t elementNodeResultCount() const;
int nodeIdxFromElementNodeResultIdx( size_t elmNodeResultIdx ) const
{
return m_allElementConnectivities[elmNodeResultIdx];
}
int nodeIdxFromElementNodeResultIdx( size_t elmNodeResultIdx ) const;
size_t resultValueIdxFromResultPosType( RigFemResultPosEnum resultPosType, int elementIdx, int elmLocalNodeIdx ) const;
RigFemPartNodes& nodes() { return m_nodes; }
const RigFemPartNodes& nodes() const { return m_nodes; }
RigFemPartNodes& nodes();
const RigFemPartNodes& nodes() const;
void assertNodeToElmIndicesIsCalculated();
const std::vector<int>& elementsUsingNode( int nodeIndex ) const;
const std::vector<unsigned char>& elementLocalIndicesForNode( int nodeIndex ) const;
void assertElmNeighborsIsCalculated();
int elementNeighbor( int elementIndex, int faceIndex ) const
{
return m_elmNeighbors[elementIndex].indicesToNeighborElms[faceIndex];
}
int neighborFace( int elementIndex, int faceIndex ) const
{
return m_elmNeighbors[elementIndex].faceInNeighborElm[faceIndex];
}
int elementNeighbor( int elementIndex, int faceIndex ) const;
int neighborFace( int elementIndex, int faceIndex ) const;
cvf::BoundingBox boundingBox() const;
float characteristicElementSize() const;
const std::vector<int>& possibleGridCornerElements() const { return m_possibleGridCornerElements; }
const std::vector<int>& possibleGridCornerElements() const;
void findIntersectingCells( const cvf::BoundingBox& inputBB, std::vector<size_t>* elementIndices ) const;
void findIntersectingCellsWithExistingSearchTree( const cvf::BoundingBox& inputBB,
std::vector<size_t>* elementIndices ) const;
@ -103,7 +90,7 @@ public:
cvf::Vec3f faceNormal( int elementIndex, int faceIndex ) const;
const RigFemPartGrid* getOrCreateStructGrid() const;
const std::vector<int>& elementIdxToId() const { return m_elementId; }
const std::vector<int>& elementIdxToId() const;
private:
int m_elementPartId;

View File

@ -103,7 +103,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
// Pore pressure
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* porePressureDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, "POR-Bar", "" ) );
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( RIG_ELEMENT_NODAL, "POR-Bar", "" ) );
frameCountProgress.incrementProgress();
// Stress (ST.S3)
@ -209,68 +209,68 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
bool isHexahedron = femPart->isHexahedron( elmIdx );
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
double wellPathDeviation = getValueForElement( RimMudWeightWindowParameters::ParameterType::WELL_DEVIATION,
// Use hydrostatic pressure from cell centroid.
// Use centroid to avoid intra-element differences
cvf::Vec3d cellCentroid = femPartGrid->cellCentroid( elmIdx );
double cellCentroidTvdRKB = -cellCentroid.z() + airGap;
double waterDensityGCM3 = 1.03;
double hydroStaticPressure =
RigGeoMechWellLogExtractor::hydroStaticPorePressureAtDepth( cellCentroidTvdRKB, waterDensityGCM3 );
double hydroStaticPressureForNormalization =
RigGeoMechWellLogExtractor::hydroStaticPorePressureAtDepth( cellCentroidTvdRKB, 1.0 );
if ( isHexahedron && hydroStaticPressureForNormalization != 0.0 )
{
double wellPathDeviation = getValueForElement( RimMudWeightWindowParameters::ParameterType::WELL_DEVIATION,
parameterFrameData,
parameterValues,
elmIdx );
double wellPathAzimuth = getValueForElement( RimMudWeightWindowParameters::ParameterType::WELL_AZIMUTH,
parameterFrameData,
parameterValues,
elmIdx );
double ucsBar = getValueForElement( RimMudWeightWindowParameters::ParameterType::UCS,
parameterFrameData,
parameterValues,
elmIdx );
double poissonsRatio = getValueForElement( RimMudWeightWindowParameters::ParameterType::POISSONS_RATIO,
parameterFrameData,
parameterValues,
elmIdx );
double wellPathAzimuth = getValueForElement( RimMudWeightWindowParameters::ParameterType::WELL_AZIMUTH,
parameterFrameData,
parameterValues,
elmIdx );
double K0_FG = getValueForElement( RimMudWeightWindowParameters::ParameterType::K0_FG,
parameterFrameData,
parameterValues,
elmIdx );
double ucsBar = getValueForElement( RimMudWeightWindowParameters::ParameterType::UCS,
parameterFrameData,
parameterValues,
elmIdx );
double poissonsRatio = getValueForElement( RimMudWeightWindowParameters::ParameterType::POISSONS_RATIO,
parameterFrameData,
parameterValues,
elmIdx );
double K0_FG = getValueForElement( RimMudWeightWindowParameters::ParameterType::K0_FG,
double OBG0 = 0.0;
if ( !OBG0FromGrid )
{
OBG0 = getValueForElement( RimMudWeightWindowParameters::ParameterType::OBG0,
parameterFrameData,
parameterValues,
elmIdx );
}
double OBG0 = 0.0;
if ( !OBG0FromGrid )
{
OBG0 = getValueForElement( RimMudWeightWindowParameters::ParameterType::OBG0,
parameterFrameData,
parameterValues,
elmIdx );
}
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P || elmType == HEX8 )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
// Use hydrostatic pressure from cell centroid.
// Use centroid to avoid intra-element differences
cvf::Vec3d cellCentroid = femPartGrid->cellCentroid( elmIdx );
double cellCentroidTvdRKB = -cellCentroid.z() + airGap;
double cellCenterHydroStaticPressure =
RigGeoMechWellLogExtractor::hydroStaticPorePressureAtDepth( cellCentroidTvdRKB );
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < stressFrameData.size() )
{
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
// Pore pressure (unit: Bar)
float porePressureBar = porFrameData[nodeIdx];
float initialPorePressureBar = initialPorFrameData[nodeIdx];
float porePressureBar = porFrameData[elmNodResIdx];
float initialPorePressureBar = initialPorFrameData[elmNodResIdx];
// Initial overburden gradient
if ( OBG0FromGrid )
{
OBG0 = obg0FrameData[nodeIdx];
OBG0 = obg0FrameData[elmNodResIdx];
}
// FG is for sands, SFG for shale. Sands has valid PP, shale does not.
@ -283,8 +283,8 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
if ( PP_NonReservoirType ==
RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC )
{
porePressureBar = cellCenterHydroStaticPressure * hydrostaticMultiplier;
initialPorePressureBar = cellCenterHydroStaticPressure * hydrostaticMultiplier;
porePressureBar = hydroStaticPressure * hydrostaticMultiplier;
initialPorePressureBar = hydroStaticPressure * hydrostaticMultiplier;
}
else if ( !nonReservoirPP.empty() )
{
@ -294,7 +294,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
}
}
caf::Ten3d segmentStress = caf::Ten3d( vertexStressesFloat[nodeIdx] );
caf::Ten3d segmentStress = caf::Ten3d( vertexStressesFloat[elmNodResIdx] );
cvf::Vec3d wellPathTangent = calculateWellPathTangent( wellPathAzimuth, wellPathDeviation );
caf::Ten3d wellPathStressFloat =
@ -302,21 +302,20 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
segmentStress );
caf::Ten3d wellPathStressDouble( wellPathStressFloat );
RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble,
porePressureBar,
poissonsRatio,
ucsBar,
32 );
// Calculate upper limit
float upperLimit = inf;
if ( upperLimitParameter == RimMudWeightWindowParameters::UpperLimitType::FG && isSand )
{
upperLimit = sigmaCalculator.solveFractureGradient();
RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble,
porePressureBar,
poissonsRatio,
ucsBar,
32 );
upperLimit = sigmaCalculator.solveFractureGradient() / hydroStaticPressureForNormalization;
}
else if ( upperLimitParameter == RimMudWeightWindowParameters::UpperLimitType::SH_MIN )
{
upperLimit = stressFrameData[elmNodResIdx];
upperLimit = stressFrameData[elmNodResIdx] / hydroStaticPressureForNormalization;
}
//
@ -325,11 +324,14 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
if ( fractureGradientCalculationType ==
RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG )
{
upperLimit = K0_FG * ( OBG0 - initialPorePressureBar ) + initialPorePressureBar;
float PP0 = initialPorePressureBar / hydroStaticPressureForNormalization;
float normalizedOBG0 = OBG0 / hydroStaticPressureForNormalization;
upperLimit = K0_FG * ( normalizedOBG0 - PP0 ) + PP0;
}
else
{
upperLimit = stressFrameData[elmNodResIdx] * shMultiplier;
upperLimit =
stressFrameData[elmNodResIdx] * shMultiplier / hydroStaticPressureForNormalization;
}
}
@ -348,14 +350,22 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
}
else
{
RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble,
hydroStaticPressureForNormalization,
poissonsRatio,
ucsBar,
32 );
double SFG = sigmaCalculator.solveStassiDalia();
lowerLimit = std::max( porePressureBar, static_cast<float>( SFG ) );
}
}
// Upper limit values have already been normalized where appropriate
upperMudWeightLimitFrameData[elmNodResIdx] = upperLimit;
// Normalize by hydrostatic pore pressure
upperMudWeightLimitFrameData[elmNodResIdx] = upperLimit / cellCenterHydroStaticPressure;
lowerMudWeightLimitFrameData[elmNodResIdx] = lowerLimit / cellCenterHydroStaticPressure;
lowerMudWeightLimitFrameData[elmNodResIdx] = lowerLimit / hydroStaticPressureForNormalization;
}
}
}
@ -380,7 +390,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
bool isHexahedron = femPart->isHexahedron( elmIdx );
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
@ -389,7 +399,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
size_t kMin = std::min( k, kRefLayer );
size_t kMax = std::max( k, kRefLayer );
if ( elmType == HEX8P && validIndex )
if ( isHexahedron && validIndex )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
@ -401,9 +411,9 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
for ( size_t currentK = kMin; currentK < kMax; currentK++ )
{
size_t kElmIdx = femPartGrid->cellIndexFromIJK( i, j, currentK );
if ( kElmIdx != cvf::UNDEFINED_SIZE_T && femPart->elementType( kElmIdx ) == HEX8P )
if ( kElmIdx != cvf::UNDEFINED_SIZE_T && femPart->isHexahedron( kElmIdx ) )
{
size_t kElmNodResIdx = femPart->elementNodeResultIdx( kElmIdx, elmNodIdx );
size_t kElmNodResIdx = femPart->elementNodeResultIdx( static_cast<int>( kElmIdx ), elmNodIdx );
float currentLowerMudWeightLimit = lowerMudWeightLimitFrameData[kElmNodResIdx];
if ( currentLowerMudWeightLimit > maxLowerMudWeightLimit )
@ -454,7 +464,7 @@ cvf::Vec3d RigFemPartResultCalculatorMudWeightWindow::calculateWellPathTangent(
//--------------------------------------------------------------------------------------------------
void RigFemPartResultCalculatorMudWeightWindow::loadParameterFramesOrValue(
RimMudWeightWindowParameters::ParameterType parameterType,
size_t partIndex,
int partIndex,
std::map<RimMudWeightWindowParameters::ParameterType, RigFemScalarResultFrames*>& parameterFrames,
std::map<RimMudWeightWindowParameters::ParameterType, float>& parameterValues )
{

View File

@ -45,7 +45,7 @@ public:
private:
void loadParameterFramesOrValue( RimMudWeightWindowParameters::ParameterType parameterType,
size_t partIndex,
int partIndex,
std::map<RimMudWeightWindowParameters::ParameterType, RigFemScalarResultFrames*>& parameterFrames,
std::map<RimMudWeightWindowParameters::ParameterType, float>& parameterValues );

View File

@ -381,6 +381,8 @@ RimGeoMechCase::CaseOpenStatus RimGeoMechCase::openGeoMechCase( std::string* err
m_geoMechCaseData = geoMechCaseData;
m_mudWeightWindowParameters->updateFemPartResults();
return CASE_OPEN_OK;
}

View File

@ -158,6 +158,19 @@ RimMudWeightWindowParameters::RimMudWeightWindowParameters( void )
CAF_PDM_InitField( &m_obg0Address, "obg0Address", QString( "" ), "Value", "", "", "" );
m_obg0Address.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
m_parameterFields[RimMudWeightWindowParameters::ParameterType::WELL_DEVIATION] =
std::make_tuple( &m_wellDeviationType, &m_wellDeviationFixed, &m_wellDeviationAddress );
m_parameterFields[RimMudWeightWindowParameters::ParameterType::WELL_AZIMUTH] =
std::make_tuple( &m_wellAzimuthType, &m_wellAzimuthFixed, &m_wellAzimuthAddress );
m_parameterFields[RimMudWeightWindowParameters::ParameterType::UCS] =
std::make_tuple( &m_UCSType, &m_UCSFixed, &m_UCSAddress );
m_parameterFields[RimMudWeightWindowParameters::ParameterType::POISSONS_RATIO] =
std::make_tuple( &m_poissonsRatioType, &m_poissonsRatioFixed, &m_poissonsRatioAddress );
m_parameterFields[RimMudWeightWindowParameters::ParameterType::K0_FG] =
std::make_tuple( &m_K0_FGType, &m_K0_FGFixed, &m_K0_FGAddress );
m_parameterFields[RimMudWeightWindowParameters::ParameterType::OBG0] =
std::make_tuple( &m_obg0Type, &m_obg0Fixed, &m_obg0Address );
CAF_PDM_InitField( &m_airGap, "AirGap", 0.0, "Air Gap", "", "", "" );
CAF_PDM_InitField( &m_shMultiplier, "SHMultiplier", 1.05, "SH Multplier for FG in Shale", "", "", "" );
@ -620,3 +633,74 @@ QList<caf::PdmOptionItemInfo>
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::updateFemPartResults() const
{
RimGeoMechCase* geoMechCase = nullptr;
firstAncestorOrThisOfType( geoMechCase );
if ( !geoMechCase )
{
return;
}
RigGeoMechCaseData* rigCaseData = geoMechCase->geoMechData();
if ( !rigCaseData )
{
return;
}
for ( size_t i = 0; i < caf::AppEnum<ParameterType>::size(); ++i )
{
updateFemPartsForParameter( caf::AppEnum<ParameterType>::fromIndex( i ), rigCaseData );
}
// Make sure the reference layer is valid
int referenceLayer = m_referenceLayer();
if ( referenceLayer == -1 )
{
referenceLayer =
(int)rigCaseData->femParts()->part( 0 )->getOrCreateStructGrid()->reservoirIJKBoundingBox().first.z();
}
rigCaseData->femPartResults()->setMudWeightWindowParameters( m_airGap,
m_upperLimitType.value(),
m_lowerLimitType.value(),
referenceLayer,
m_fractureGradientCalculationType.value(),
m_shMultiplier,
m_porePressureNonReservoirSource.value(),
m_userDefinedPPNonReservoir,
m_porePressureNonReservoirAddress );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::updateFemPartsForParameter( ParameterType parameterType,
RigGeoMechCaseData* rigCaseData ) const
{
auto it = m_parameterFields.find( parameterType );
if ( it == m_parameterFields.end() ) return;
caf::PdmField<caf::AppEnum<SourceType>>* typeField = std::get<0>( it->second );
caf::PdmField<double>* fixedField = std::get<1>( it->second );
caf::PdmField<QString>* addressField = std::get<2>( it->second );
if ( rigCaseData->femPartResults() )
{
if ( typeField->value() == RimMudWeightWindowParameters::SourceType::FIXED ||
typeField->value() == RimMudWeightWindowParameters::SourceType::GRID )
{
rigCaseData->femPartResults()->setCalculationParameters( parameterType, "", fixedField->value() );
}
else if ( typeField->value() == RimMudWeightWindowParameters::SourceType::PER_ELEMENT )
{
rigCaseData->femPartResults()->setCalculationParameters( parameterType,
addressField->value(),
fixedField->value() );
}
}
}

View File

@ -21,7 +21,10 @@
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include <map>
class RimGeoMechCase;
class RigGeoMechCaseData;
//==================================================================================================
///
@ -97,6 +100,8 @@ public:
double airGap() const;
void updateFemPartResults() const;
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
@ -120,6 +125,8 @@ private:
caf::PdmField<QString>* addressField,
bool typeFieldChanged );
void updateFemPartsForParameter( ParameterType parameterType, RigGeoMechCaseData* rigCaseData ) const;
private:
caf::PdmField<caf::AppEnum<SourceType>> m_wellDeviationType;
caf::PdmField<double> m_wellDeviationFixed;
@ -145,6 +152,9 @@ private:
caf::PdmField<double> m_obg0Fixed;
caf::PdmField<QString> m_obg0Address;
typedef std::tuple<caf::PdmField<caf::AppEnum<SourceType>>*, caf::PdmField<double>*, caf::PdmField<QString>*> ParameterPdmFields;
std::map<ParameterType, ParameterPdmFields> m_parameterFields;
caf::PdmField<double> m_airGap;
caf::PdmField<double> m_shMultiplier;
caf::PdmField<double> m_userDefinedPPNonReservoir;