ResInsight/ApplicationLibCode/ProjectDataModel/RimMudWeightWindowParameters.cpp
Magne Sjaastad 833a0e8584 Performance: Cellcount functions are used in many loops, and must be as fast as possible
cellCountIJK was computed based on the value of griPointDimensions. These converstion turned up during profiling. Change implementation to have cellcount as a member variable instead of being computed every time.
2024-01-22 14:52:49 +01:00

665 lines
33 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- 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 "RimMudWeightWindowParameters.h"
#include "RiaLogging.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigGeoMechCaseData.h"
#include "RimGeoMechCase.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiDoubleValueEditor.h"
#include "cafPdmUiPropertyViewDialog.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeSelectionEditor.h"
CAF_PDM_SOURCE_INIT( RimMudWeightWindowParameters, "RimMudWeightWindowParameters" );
namespace caf
{
template <>
void caf::AppEnum<RimMudWeightWindowParameters::SourceType>::setUp()
{
addItem( RimMudWeightWindowParameters::SourceType::FIXED, "FIXED", "Fixed" );
addItem( RimMudWeightWindowParameters::SourceType::PER_ELEMENT, "PER_ELEMENT", "From element properties" );
addItem( RimMudWeightWindowParameters::SourceType::GRID, "GRID", "Grid" );
setDefault( RimMudWeightWindowParameters::SourceType::FIXED );
}
template <>
void caf::AppEnum<RimMudWeightWindowParameters::ParameterType>::setUp()
{
addItem( RimMudWeightWindowParameters::ParameterType::WELL_DEVIATION, "WELL_DEVIATION", "Well Deviation" );
addItem( RimMudWeightWindowParameters::ParameterType::WELL_AZIMUTH, "WELL_AZIMUTH", "Well Azimuth" );
addItem( RimMudWeightWindowParameters::ParameterType::UCS, "UCS", "UCS" );
addItem( RimMudWeightWindowParameters::ParameterType::POISSONS_RATIO, "POISSONS_RARIO", "Poisson's Ratio" );
addItem( RimMudWeightWindowParameters::ParameterType::K0_FG, "K0_FG", "K0 FG" );
addItem( RimMudWeightWindowParameters::ParameterType::OBG0, "OBG0", "Initial Overburden Gradient" );
setDefault( RimMudWeightWindowParameters::ParameterType::WELL_DEVIATION );
}
template <>
void caf::AppEnum<RimMudWeightWindowParameters::UpperLimitType>::setUp()
{
addItem( RimMudWeightWindowParameters::UpperLimitType::FG, "FG", "Fracture Gradient" );
addItem( RimMudWeightWindowParameters::UpperLimitType::SH_MIN, "SH_MIN", "Minimum Horizontal Stress" );
setDefault( RimMudWeightWindowParameters::UpperLimitType::FG );
}
template <>
void caf::AppEnum<RimMudWeightWindowParameters::LowerLimitType>::setUp()
{
addItem( RimMudWeightWindowParameters::LowerLimitType::PORE_PRESSURE, "PORE_PRESSURE", "Pore Pressure" );
addItem( RimMudWeightWindowParameters::LowerLimitType::MAX_OF_PORE_PRESSURE_AND_SFG,
"MAX_OF_PORE_PRESSURE_AND_SFG",
"Maximum of Pore Pressure and SFG" );
setDefault( RimMudWeightWindowParameters::LowerLimitType::PORE_PRESSURE );
}
template <>
void caf::AppEnum<RimMudWeightWindowParameters::FractureGradientCalculationType>::setUp()
{
addItem( RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG, "DERIVED_FROM_K0FG", "FG derived from K0_FG" );
addItem( RimMudWeightWindowParameters::FractureGradientCalculationType::PROPORTIONAL_TO_SH, "PROPORTIONAL_TO_SH", "Proportional to SH" );
setDefault( RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG );
}
template <>
void caf::AppEnum<RimMudWeightWindowParameters::NonReservoirPorePressureType>::setUp()
{
addItem( RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC, "HYDROSTATIC", "Hydrostatic" );
addItem( RimMudWeightWindowParameters::NonReservoirPorePressureType::PER_ELEMENT, "PER_ELEMENT", "From element properties" );
setDefault( RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC );
}
} // End namespace caf
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::RimMudWeightWindowParameters()
{
CAF_PDM_InitScriptableObjectWithNameAndComment( "Mud Weight Window Parameters",
"",
"",
"The Mud Weight Window Calculation Parameters",
"MudWeightWindowParameters",
"" );
caf::AppEnum<SourceType> defaultSourceType = RimMudWeightWindowParameters::SourceType::FIXED;
CAF_PDM_InitField( &m_wellDeviationType, "WellDeviationSourceType", defaultSourceType, "Well Deviation" );
CAF_PDM_InitField( &m_wellDeviationFixed, "WellDeviationFixed", 0.0, "Fixed Well Deviation" );
m_wellDeviationFixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_wellDeviationAddress, "WellDeviationAddress", QString( "" ), "Value" );
m_wellDeviationAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_wellAzimuthType, "WellAzimuthSourceType", defaultSourceType, "Well Azimuth" );
CAF_PDM_InitField( &m_wellAzimuthFixed, "WellAzimuthFixed", 0.0, "Fixed Well Azimuth" );
m_wellAzimuthFixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_wellAzimuthAddress, "WellAzimuthAddress", QString( "" ), "Value" );
m_wellAzimuthAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_UCSType, "UCSSourceType", defaultSourceType, "UCS [Bar]" );
CAF_PDM_InitField( &m_UCSFixed, "UCSFixed", 100.0, "Fixed UCS [Bar]" );
m_UCSFixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_UCSAddress, "UCSAddress", QString( "" ), "Value" );
m_UCSAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_poissonsRatioType, "PoissonsRatioSourceType", defaultSourceType, "Poisson's Ratio" );
CAF_PDM_InitField( &m_poissonsRatioFixed, "PoissonsRatioFixed", 0.35, "Fixed Possion's Ratio" );
m_poissonsRatioFixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_poissonsRatioAddress, "PoissonsRatioAddress", QString( "" ), "Value" );
m_poissonsRatioAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_K0_FGType, "K0_FGSourceType", defaultSourceType, "K0 FG" );
CAF_PDM_InitField( &m_K0_FGFixed, "K0_FGFixed", 0.75, "Fixed K0_FG" );
m_K0_FGFixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_K0_FGAddress, "K0_FGAddress", QString( "" ), "Value" );
m_K0_FGAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
caf::AppEnum<SourceType> defaultOBG0SourceType = RimMudWeightWindowParameters::SourceType::GRID;
CAF_PDM_InitField( &m_obg0Type, "obg0SourceType", defaultOBG0SourceType, "Initial Overburden Gradient" );
CAF_PDM_InitField( &m_obg0Fixed, "obg0Fixed", 0.75, "Fixed Initial Overburden Gradient" );
m_obg0Fixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_obg0Address, "obg0Address", QString( "" ), "Value" );
m_obg0Address.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::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" );
caf::AppEnum<UpperLimitType> defaultUpperLimitType = RimMudWeightWindowParameters::UpperLimitType::FG;
CAF_PDM_InitField( &m_upperLimitType, "UpperLimitType", defaultUpperLimitType, "Upper Limit Type" );
caf::AppEnum<LowerLimitType> defaultLowerLimitType = RimMudWeightWindowParameters::LowerLimitType::MAX_OF_PORE_PRESSURE_AND_SFG;
CAF_PDM_InitField( &m_lowerLimitType, "LowerLimitType", defaultLowerLimitType, "Lower Limit Type" );
caf::AppEnum<FractureGradientCalculationType> defaultFractureGradientCalculationType =
RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG;
CAF_PDM_InitField( &m_fractureGradientCalculationType,
"FractureGradientCalculationType",
defaultFractureGradientCalculationType,
"FG in Shale Calculation" );
caf::AppEnum<NonReservoirPorePressureType> defaultNonReservoirPorePressureType =
RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC;
CAF_PDM_InitField( &m_porePressureNonReservoirSource,
"PorePressureNonReservoirSource",
defaultNonReservoirPorePressureType,
"Non-Reservoir Pore Pressure",
"",
"Data source for Non-Reservoir Pore Pressure",
"" );
CAF_PDM_InitField( &m_userDefinedPPNonReservoir, "UserPPNonReservoir", 1.0, " Multiplier of hydrostatic PP" );
CAF_PDM_InitField( &m_porePressureNonReservoirAddress, "PPNonReservoirAddress", QString( "" ), "Value" );
m_porePressureNonReservoirAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_referenceLayer, "ReferenceLayer", -1, "Reference Layer" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::SourceType RimMudWeightWindowParameters::wellDeviationType() const
{
return m_wellDeviationType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMudWeightWindowParameters::wellDeviation() const
{
return m_wellDeviationFixed;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimMudWeightWindowParameters::wellDeviationAddress() const
{
return m_wellDeviationAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::SourceType RimMudWeightWindowParameters::wellAzimuthType() const
{
return m_wellAzimuthType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMudWeightWindowParameters::wellAzimuth() const
{
return m_wellAzimuthFixed;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimMudWeightWindowParameters::wellAzimuthAddress() const
{
return m_wellAzimuthAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::SourceType RimMudWeightWindowParameters::ucsType() const
{
return m_UCSType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMudWeightWindowParameters::ucs() const
{
return m_UCSFixed;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimMudWeightWindowParameters::ucsAddress() const
{
return m_UCSAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::SourceType RimMudWeightWindowParameters::poissonsRatioType() const
{
return m_poissonsRatioType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMudWeightWindowParameters::poissonsRatio() const
{
return m_poissonsRatioFixed();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimMudWeightWindowParameters::poissonsRatioAddress() const
{
return m_poissonsRatioAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::SourceType RimMudWeightWindowParameters::K0_FG_Type() const
{
return m_K0_FGType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMudWeightWindowParameters::K0_FG() const
{
return m_K0_FGFixed;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimMudWeightWindowParameters::K0_FGAddress() const
{
return m_K0_FGAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMudWeightWindowParameters::airGap() const
{
return m_airGap;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
auto geoMechCase = firstAncestorOrThisOfType<RimGeoMechCase>();
if ( !geoMechCase )
{
return;
}
if ( changedField == &m_wellDeviationFixed || changedField == &m_wellDeviationType || changedField == &m_wellDeviationAddress )
{
handleFieldChanged( geoMechCase,
ParameterType::WELL_DEVIATION,
&m_wellDeviationType,
&m_wellDeviationFixed,
&m_wellDeviationAddress,
changedField == &m_wellDeviationType );
}
else if ( changedField == &m_wellAzimuthFixed || changedField == &m_wellAzimuthType || changedField == &m_wellAzimuthAddress )
{
handleFieldChanged( geoMechCase,
ParameterType::WELL_AZIMUTH,
&m_wellAzimuthType,
&m_wellAzimuthFixed,
&m_wellAzimuthAddress,
changedField == &m_wellAzimuthType );
}
else if ( changedField == &m_UCSFixed || changedField == &m_UCSType || changedField == &m_UCSAddress )
{
handleFieldChanged( geoMechCase, ParameterType::UCS, &m_UCSType, &m_UCSFixed, &m_UCSAddress, changedField == &m_UCSType );
}
else if ( changedField == &m_poissonsRatioFixed || changedField == &m_poissonsRatioType || changedField == &m_poissonsRatioAddress )
{
handleFieldChanged( geoMechCase,
ParameterType::POISSONS_RATIO,
&m_poissonsRatioType,
&m_poissonsRatioFixed,
&m_poissonsRatioAddress,
changedField == &m_poissonsRatioType );
}
else if ( changedField == &m_K0_FGFixed || changedField == &m_K0_FGType || changedField == &m_K0_FGAddress )
{
handleFieldChanged( geoMechCase, ParameterType::K0_FG, &m_K0_FGType, &m_K0_FGFixed, &m_K0_FGAddress, changedField == &m_K0_FGType );
}
else if ( changedField == &m_obg0Fixed || changedField == &m_obg0Type || changedField == &m_obg0Address )
{
handleFieldChanged( geoMechCase, ParameterType::OBG0, &m_obg0Type, &m_obg0Fixed, &m_obg0Address, changedField == &m_obg0Type );
}
else if ( changedField == &m_airGap || changedField == &m_upperLimitType || changedField == &m_lowerLimitType ||
changedField == &m_referenceLayer || changedField == &m_fractureGradientCalculationType || changedField == &m_shMultiplier ||
changedField == &m_porePressureNonReservoirSource || changedField == &m_userDefinedPPNonReservoir ||
changedField == &m_porePressureNonReservoirAddress )
{
RigGeoMechCaseData* rigCaseData = geoMechCase->geoMechData();
if ( rigCaseData && rigCaseData->femPartResults() )
{
rigCaseData->femPartResults()->setMudWeightWindowParameters( m_airGap,
m_upperLimitType.value(),
m_lowerLimitType.value(),
m_referenceLayer,
m_fractureGradientCalculationType.value(),
m_shMultiplier,
m_porePressureNonReservoirSource.value(),
m_userDefinedPPNonReservoir,
m_porePressureNonReservoirAddress );
geoMechCase->updateConnectedViews();
geoMechCase->settingsChanged.send();
}
}
}
void RimMudWeightWindowParameters::handleFieldChanged( RimGeoMechCase* geoMechCase,
ParameterType parameterType,
caf::PdmField<caf::AppEnum<SourceType>>* typeField,
caf::PdmField<double>* fixedField,
caf::PdmField<QString>* addressField,
bool typeFieldChanged )
{
RigGeoMechCaseData* rigCaseData = geoMechCase->geoMechData();
if ( rigCaseData && 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 )
{
if ( typeFieldChanged )
{
// Show info message to user when selecting "from file" option before
// an element property has been imported
std::vector<std::string> elementProperties = geoMechCase->possibleElementPropertyFieldNames();
if ( elementProperties.empty() )
{
QString title = caf::AppEnum<ParameterType>::uiText( parameterType );
QString importMessage = QString( "Please import '%1' from file by "
"selecting 'Import Element Property Table' on the Geomechanical Model." )
.arg( title );
RiaLogging::info( importMessage );
// Set back to default value
*typeField = typeField->defaultValue();
return;
}
}
if ( addressField->value().isEmpty() )
{
// Automatically select the first available property element if empty
std::vector<std::string> elementProperties = geoMechCase->possibleElementPropertyFieldNames();
if ( !elementProperties.empty() )
{
*addressField = QString::fromStdString( elementProperties[0] );
}
}
rigCaseData->femPartResults()->setCalculationParameters( parameterType, addressField->value(), fixedField->value() );
}
}
geoMechCase->updateConnectedViews();
geoMechCase->settingsChanged.send();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
defineGroup( uiOrdering, "Well Deviation", &m_wellDeviationType, &m_wellDeviationFixed, &m_wellDeviationAddress );
defineGroup( uiOrdering, "Well Azimuth", &m_wellAzimuthType, &m_wellAzimuthFixed, &m_wellAzimuthAddress );
defineGroup( uiOrdering, "UCS", &m_UCSType, &m_UCSFixed, &m_UCSAddress );
defineGroup( uiOrdering, "Poisson's Ratio", &m_poissonsRatioType, &m_poissonsRatioFixed, &m_poissonsRatioAddress );
auto geoMechCase = firstAncestorOrThisOfType<RimGeoMechCase>();
if ( !geoMechCase )
{
return;
}
RigGeoMechCaseData* rigCaseData = geoMechCase->geoMechData();
if ( rigCaseData && m_referenceLayer == -1 )
{
m_referenceLayer = (int)rigCaseData->femParts()->part( 0 )->getOrCreateStructGrid()->reservoirIJKBoundingBox().first.z();
}
uiOrdering.add( &m_fractureGradientCalculationType );
uiOrdering.add( &m_shMultiplier );
defineGroup( uiOrdering, "K0 for Fracture Gradient Factor for Shale", &m_K0_FGType, &m_K0_FGFixed, &m_K0_FGAddress );
m_shMultiplier.uiCapability()->setUiHidden( m_fractureGradientCalculationType != FractureGradientCalculationType::PROPORTIONAL_TO_SH );
bool isDerivedFromK0_FG = m_fractureGradientCalculationType == FractureGradientCalculationType::DERIVED_FROM_K0FG;
m_K0_FGType.uiCapability()->setUiHidden( !isDerivedFromK0_FG );
m_K0_FGFixed.uiCapability()->setUiHidden( !( isDerivedFromK0_FG && m_K0_FGType == RimMudWeightWindowParameters::SourceType::FIXED ) );
m_K0_FGAddress.uiCapability()->setUiHidden(
!( isDerivedFromK0_FG && m_K0_FGType == RimMudWeightWindowParameters::SourceType::PER_ELEMENT ) );
defineGroup( uiOrdering, "Initial Overburden Gradient", &m_obg0Type, &m_obg0Fixed, &m_obg0Address );
m_obg0Type.uiCapability()->setUiHidden( !isDerivedFromK0_FG );
m_obg0Fixed.uiCapability()->setUiHidden( true );
m_obg0Address.uiCapability()->setUiHidden( !( isDerivedFromK0_FG && m_obg0Type == RimMudWeightWindowParameters::SourceType::PER_ELEMENT ) );
bool ppNonResPerElement = ( m_porePressureNonReservoirSource == RimMudWeightWindowParameters::NonReservoirPorePressureType::PER_ELEMENT );
m_userDefinedPPNonReservoir.uiCapability()->setUiHidden( ppNonResPerElement );
m_porePressureNonReservoirAddress.uiCapability()->setUiHidden( !ppNonResPerElement );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::defineGroup( caf::PdmUiOrdering& uiOrdering,
const QString& title,
caf::PdmField<caf::AppEnum<SourceType>>* typeField,
caf::PdmField<double>* fixedField,
caf::PdmField<QString>* addressField )
{
uiOrdering.add( typeField );
uiOrdering.add( fixedField );
uiOrdering.add( addressField );
fixedField->uiCapability()->setUiHidden( *typeField != RimMudWeightWindowParameters::SourceType::FIXED );
addressField->uiCapability()->setUiHidden( *typeField != RimMudWeightWindowParameters::SourceType::PER_ELEMENT );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_wellDeviationFixed || field == &m_wellAzimuthFixed )
{
auto uiDoubleValueEditorAttr = dynamic_cast<caf::PdmUiDoubleValueEditorAttribute*>( attribute );
if ( uiDoubleValueEditorAttr )
{
uiDoubleValueEditorAttr->m_validator = new QDoubleValidator( 0.0, 360.0, 3 );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimMudWeightWindowParameters::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
QList<caf::PdmOptionItemInfo> options;
auto geoMechCase = firstAncestorOrThisOfType<RimGeoMechCase>();
if ( geoMechCase != nullptr )
{
if ( fieldNeedingOptions == &m_obg0Type )
{
std::vector<SourceType> sourceTypes = { SourceType::GRID, SourceType::PER_ELEMENT };
for ( auto sourceType : sourceTypes )
{
options.push_back( caf::PdmOptionItemInfo( caf::AppEnum<SourceType>::uiText( sourceType ), sourceType ) );
}
}
else if ( fieldNeedingOptions == &m_wellDeviationType || fieldNeedingOptions == &m_wellAzimuthType ||
fieldNeedingOptions == &m_UCSType || fieldNeedingOptions == &m_poissonsRatioType || fieldNeedingOptions == &m_K0_FGType )
{
std::vector<SourceType> sourceTypes = { SourceType::FIXED, SourceType::PER_ELEMENT };
for ( auto sourceType : sourceTypes )
{
options.push_back( caf::PdmOptionItemInfo( caf::AppEnum<SourceType>::uiText( sourceType ), sourceType ) );
}
}
else if ( fieldNeedingOptions == &m_wellDeviationAddress || fieldNeedingOptions == &m_wellAzimuthAddress ||
fieldNeedingOptions == &m_UCSAddress || fieldNeedingOptions == &m_poissonsRatioAddress ||
fieldNeedingOptions == &m_K0_FGAddress || fieldNeedingOptions == &m_obg0Address ||
fieldNeedingOptions == &m_porePressureNonReservoirAddress )
{
std::vector<std::string> elementProperties = geoMechCase->possibleElementPropertyFieldNames();
std::vector<caf::FilePath> elementPropertyFileNames = geoMechCase->elementPropertyFileNames();
std::vector<QString> paths;
for ( auto path : elementPropertyFileNames )
{
paths.push_back( path.path() );
}
std::map<std::string, QString> addressesInFile =
geoMechCase->geoMechData()->femPartResults()->addressesInElementPropertyFiles( paths );
for ( const std::string& elementProperty : elementProperties )
{
QString result = QString::fromStdString( elementProperty );
QString filename = geoMechCase->findFileNameForElementProperty( elementProperty, addressesInFile );
options.push_back( caf::PdmOptionItemInfo( result + " (" + filename + ")", result ) );
}
}
else if ( fieldNeedingOptions == &m_referenceLayer )
{
if ( geoMechCase->geoMechData() )
{
size_t kCount = geoMechCase->geoMechData()->femParts()->part( 0 )->getOrCreateStructGrid()->cellCountK();
for ( size_t layerIdx = 0; layerIdx < kCount; ++layerIdx )
{
options.push_back( caf::PdmOptionItemInfo( QString::number( layerIdx + 1 ), (int)layerIdx ) );
}
}
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMudWeightWindowParameters::updateFemPartResults() const
{
auto geoMechCase = firstAncestorOrThisOfType<RimGeoMechCase>();
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() );
}
}
}