mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge pull request #6332 from OPM/mud-weight-fracture-gradient-fix-6301
Mud weight fracture gradient fix 6301
This commit is contained in:
commit
14e0a9c2da
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -381,6 +381,8 @@ RimGeoMechCase::CaseOpenStatus RimGeoMechCase::openGeoMechCase( std::string* err
|
||||
|
||||
m_geoMechCaseData = geoMechCaseData;
|
||||
|
||||
m_mudWeightWindowParameters->updateFemPartResults();
|
||||
|
||||
return CASE_OPEN_OK;
|
||||
}
|
||||
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user