mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
* Improve tree selection editor - always call defineEditorAttributes - use heightHint in editor attributes - use tree selection editor as default editor for std::vector * Use tree selection editor instead of list selection editor List selection editor must be used when editing std::vector<cvf::vec3d> and similar. Replace other use of list selection editor with tree selection editor. * Set checked state based on text string for integer only models For models with only integer values, use text string to define the items to be selected. The full list will always be visible, and the checked state will be updated when editing the filter text. Example: "1, 5-7" will set items 1, 5, 6, 7 checked and all other items unchecked * Minor fixes - Set placeholder text after content is added (to ensure correct data type) - Fix check of integers. `canConvert<int>()`returns true for both QString and int. Thus convert to string and then check for int conversion. * Activate filtering when unchecking all items in list with only integers - Reactivate filtering when uncheck of all items for a list with only integer values (to keep consistency between filter and list) - Update function name for clarity --------- Co-authored-by: Jørgen Herje <jorgen.herje@ceetronsolutions.com>
1247 lines
49 KiB
C++
1247 lines
49 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2015- Statoil ASA
|
|
// Copyright (C) 2015- Ceetron Solutions AS
|
|
//
|
|
// 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 "RimGeoMechCase.h"
|
|
|
|
#include "RiaLogging.h"
|
|
#include "RiaPreferences.h"
|
|
|
|
#include "RicImportElementPropertyFeature.h"
|
|
#include "RicfCommandObject.h"
|
|
#include "RifOdbReader.h"
|
|
|
|
#include "RigFemPart.h"
|
|
#include "RigFemPartCollection.h"
|
|
#include "RigFemPartGrid.h"
|
|
#include "RigFemPartResultsCollection.h"
|
|
#include "RigFormationNames.h"
|
|
#include "RigGeoMechCaseData.h"
|
|
|
|
#include "Rim2dIntersectionViewCollection.h"
|
|
#include "RimFormationNames.h"
|
|
#include "RimGeoMechCellColors.h"
|
|
#include "RimGeoMechContourMapView.h"
|
|
#include "RimGeoMechContourMapViewCollection.h"
|
|
#include "RimGeoMechPropertyFilter.h"
|
|
#include "RimGeoMechPropertyFilterCollection.h"
|
|
#include "RimGeoMechResultDefinition.h"
|
|
#include "RimGeoMechView.h"
|
|
#include "RimIntersectionCollection.h"
|
|
#include "RimMainPlotCollection.h"
|
|
#include "RimMudWeightWindowParameters.h"
|
|
#include "RimProject.h"
|
|
#include "RimTimeStepFilter.h"
|
|
#include "RimTools.h"
|
|
#include "RimWellLogPlotCollection.h"
|
|
|
|
#include "cafCmdFeatureManager.h"
|
|
#include "cafPdmFieldScriptingCapability.h"
|
|
#include "cafPdmObjectScriptingCapability.h"
|
|
#include "cafPdmUiDoubleValueEditor.h"
|
|
#include "cafPdmUiPropertyViewDialog.h"
|
|
#include "cafPdmUiPushButtonEditor.h"
|
|
#include "cafPdmUiTreeOrdering.h"
|
|
#include "cafUtils.h"
|
|
|
|
#include "cvfVector3.h"
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <array>
|
|
|
|
CAF_PDM_SOURCE_INIT( RimGeoMechCase, "ResInsightGeoMechCase" );
|
|
|
|
namespace caf
|
|
{
|
|
template <>
|
|
void caf::AppEnum<RimGeoMechCase::BiotCoefficientType>::setUp()
|
|
{
|
|
addItem( RimGeoMechCase::BiotCoefficientType::BIOT_NONE, "BIOT_NONE", "None" );
|
|
addItem( RimGeoMechCase::BiotCoefficientType::BIOT_FIXED, "BIOT_FIXED", "Fixed Biot Coefficient" );
|
|
addItem( RimGeoMechCase::BiotCoefficientType::BIOT_PER_ELEMENT, "BIOT_PER_ELEMENT", "Biot coefficient from element properties" );
|
|
setDefault( RimGeoMechCase::BiotCoefficientType::BIOT_NONE );
|
|
}
|
|
|
|
template <>
|
|
void caf::AppEnum<RimGeoMechCase::InitialPermeabilityType>::setUp()
|
|
{
|
|
addItem( RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_FIXED, "INITIAL_PERMEABILITY_FIXED", "Fixed Initial Permeability" );
|
|
addItem( RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_PER_ELEMENT,
|
|
"INITIAL_PERMEABILITY_PER_ELEMENT",
|
|
"Initial permeability from element properties" );
|
|
setDefault( RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_FIXED );
|
|
}
|
|
|
|
} // End namespace caf
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechCase::RimGeoMechCase()
|
|
: m_applyTimeFilter( false )
|
|
{
|
|
CAF_PDM_InitScriptableObjectWithNameAndComment( "GeoMechanical Case",
|
|
":/GeoMechCase48x48.png",
|
|
"",
|
|
"The GeoMechanical Results Case",
|
|
"GeoMechCase",
|
|
"The Abaqus Based GeoMech Case" );
|
|
|
|
CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &geoMechViews, "GeoMechViews", "Views", "", "", "", "All GeoMech Views in the Case" );
|
|
geoMechViews.uiCapability()->setUiTreeHidden( true );
|
|
|
|
CAF_PDM_InitField( &m_cohesion, "CaseCohesion", 10.0, "Cohesion", "", "Used to calculate the SE:SFI result", "" );
|
|
CAF_PDM_InitField( &m_frictionAngleDeg, "FrctionAngleDeg", 30.0, "Friction Angle [Deg]", "", "Used to calculate the SE:SFI result", "" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_elementPropertyFileNames, "ElementPropertyFileNames", "Element Property Files" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_elementPropertyFileNameIndexUiSelection, "ElementPropertyFileNameIndexUiSelection", "" );
|
|
m_elementPropertyFileNameIndexUiSelection.xmlCapability()->disableIO();
|
|
|
|
CAF_PDM_InitField( &m_importElementPropertyFileCommand, "importElementPropertyFileCommad", false, "" );
|
|
caf::PdmUiPushButtonEditor::configureEditorForField( &m_importElementPropertyFileCommand );
|
|
|
|
CAF_PDM_InitField( &m_closeElementPropertyFileCommand, "closeElementPropertyFileCommad", false, "" );
|
|
caf::PdmUiPushButtonEditor::configureEditorForField( &m_closeElementPropertyFileCommand );
|
|
|
|
CAF_PDM_InitField( &m_reloadElementPropertyFileCommand, "reloadElementPropertyFileCommand", false, "" );
|
|
caf::PdmUiPushButtonEditor::configureEditorForField( &m_reloadElementPropertyFileCommand );
|
|
|
|
caf::AppEnum<BiotCoefficientType> defaultBiotCoefficientType = RimGeoMechCase::BiotCoefficientType::BIOT_NONE;
|
|
CAF_PDM_InitField( &m_biotCoefficientType, "BiotCoefficientType", defaultBiotCoefficientType, "Biot Coefficient" );
|
|
CAF_PDM_InitField( &m_biotFixedCoefficient, "BiotFixedCoefficient", 1.0, "Fixed Coefficient" );
|
|
m_biotFixedCoefficient.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
|
|
|
CAF_PDM_InitField( &m_biotResultAddress, "BiotResultAddress", QString( "" ), "Value" );
|
|
|
|
caf::AppEnum<InitialPermeabilityType> defaultInitialPermeabilityType = RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_FIXED;
|
|
CAF_PDM_InitField( &m_initialPermeabilityType, "InitialPermeabilityType", defaultInitialPermeabilityType, "Initial Permeability" );
|
|
CAF_PDM_InitField( &m_initialPermeabilityFixed, "InitialPermeabilityFixed", 1.0, "Fixed Initial Permeability [mD]" );
|
|
m_initialPermeabilityFixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
|
|
|
CAF_PDM_InitField( &m_initialPermeabilityResultAddress, "InitialPermeabilityAddress", QString( "" ), "Value" );
|
|
|
|
CAF_PDM_InitField( &m_permeabilityExponent, "PermeabilityExponent", 1.0, "Permeability Exponent" );
|
|
m_permeabilityExponent.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
|
|
|
CAF_PDM_InitField( &m_waterDensityShearSlipIndicator, "WaterDensityShearSlipIndicator", 1.03, "Water Density" );
|
|
m_waterDensityShearSlipIndicator.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_contourMapCollection, "ContourMaps", "2d Contour Maps" );
|
|
m_contourMapCollection = new RimGeoMechContourMapViewCollection;
|
|
m_contourMapCollection.uiCapability()->setUiTreeHidden( true );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_mudWeightWindowParameters, "MudWeightWindowParameters", "Mud Weight Window Parameters" );
|
|
m_mudWeightWindowParameters = new RimMudWeightWindowParameters;
|
|
m_mudWeightWindowParameters.uiCapability()->setUiTreeHidden( true );
|
|
|
|
m_displayNameOption = RimCaseDisplayNameTools::DisplayName::CUSTOM;
|
|
m_displayNameOption.uiCapability()->setUiHidden( true );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechCase::~RimGeoMechCase()
|
|
{
|
|
geoMechViews.deleteChildren();
|
|
|
|
RimProject* project = RimProject::current();
|
|
if ( project )
|
|
{
|
|
if ( project->mainPlotCollection() )
|
|
{
|
|
RimWellLogPlotCollection* plotCollection = project->mainPlotCollection()->wellLogPlotCollection();
|
|
if ( plotCollection )
|
|
{
|
|
plotCollection->removeExtractors( this->geoMechData() );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( this->geoMechData() )
|
|
{
|
|
// At this point, we assume that memory should be released
|
|
CVF_ASSERT( this->geoMechData()->refCount() == 1 );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigGeoMechCaseData* RimGeoMechCase::geoMechData()
|
|
{
|
|
return m_geoMechCaseData.p();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
const RigGeoMechCaseData* RimGeoMechCase::geoMechData() const
|
|
{
|
|
return m_geoMechCaseData.p();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::reloadDataAndUpdate()
|
|
{
|
|
if ( this->geoMechData() )
|
|
{
|
|
m_geoMechCaseData = nullptr;
|
|
std::string errMsg;
|
|
if ( this->openGeoMechCase( &errMsg ) == CASE_OPEN_ERROR )
|
|
{
|
|
RiaLogging::error( QString::fromStdString( errMsg ) );
|
|
}
|
|
for ( auto& v : geoMechViews() )
|
|
{
|
|
v->resetVizLogic();
|
|
v->loadDataAndUpdate();
|
|
v->setCurrentTimeStep( v->currentTimeStep() );
|
|
}
|
|
|
|
for ( RimGeoMechContourMapView* contourMap : m_contourMapCollection->views() )
|
|
{
|
|
CVF_ASSERT( contourMap );
|
|
contourMap->loadDataAndUpdate();
|
|
contourMap->updateGridBoxData();
|
|
contourMap->updateAnnotationItems();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechView* RimGeoMechCase::createAndAddReservoirView()
|
|
{
|
|
RimGeoMechView* gmv = new RimGeoMechView();
|
|
|
|
gmv->setGeoMechCase( this );
|
|
|
|
geoMechViews.push_back( gmv );
|
|
return gmv;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechView* RimGeoMechCase::createCopyAndAddView( const RimGeoMechView* sourceView )
|
|
{
|
|
RimGeoMechView* rimGeoMechView =
|
|
dynamic_cast<RimGeoMechView*>( sourceView->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
|
|
CVF_ASSERT( rimGeoMechView );
|
|
|
|
rimGeoMechView->setGeoMechCase( this );
|
|
|
|
caf::PdmDocument::updateUiIconStateRecursively( rimGeoMechView );
|
|
|
|
geoMechViews.push_back( rimGeoMechView );
|
|
|
|
// Resolve references after reservoir view has been inserted into Rim structures
|
|
rimGeoMechView->resolveReferencesRecursively();
|
|
rimGeoMechView->initAfterReadRecursively();
|
|
|
|
return rimGeoMechView;
|
|
}
|
|
|
|
RimGeoMechCase* RimGeoMechCase::createCopy( const QString& newInputFileName )
|
|
{
|
|
RimProject* project = RimProject::current();
|
|
|
|
RimGeoMechCase* copycase =
|
|
dynamic_cast<RimGeoMechCase*>( this->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
|
|
CVF_ASSERT( copycase );
|
|
|
|
QFileInfo filenameInfo( newInputFileName );
|
|
QString newCaseName = filenameInfo.completeBaseName();
|
|
|
|
copycase->setCaseUserDescription( newCaseName + " (copy of " + caseUserDescription() + ")" );
|
|
copycase->setGridFileName( newInputFileName );
|
|
|
|
project->assignCaseIdToCase( copycase );
|
|
|
|
return copycase;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechCase::CaseOpenStatus RimGeoMechCase::openGeoMechCase( std::string* errorMessage )
|
|
{
|
|
// If read already, return
|
|
if ( this->m_geoMechCaseData.notNull() ) return CASE_OPEN_OK;
|
|
|
|
if ( !caf::Utils::fileExists( m_caseFileName().path() ) )
|
|
{
|
|
return CASE_OPEN_ERROR;
|
|
}
|
|
|
|
cvf::ref<RigGeoMechCaseData> geoMechCaseData = new RigGeoMechCaseData( m_caseFileName().path().toStdString() );
|
|
bool fileOpenSuccess = geoMechCaseData->open( errorMessage );
|
|
if ( !fileOpenSuccess )
|
|
{
|
|
return CASE_OPEN_ERROR;
|
|
}
|
|
|
|
std::vector<std::string> stepNames;
|
|
if ( !geoMechCaseData->readTimeSteps( errorMessage, &stepNames ) )
|
|
{
|
|
return CASE_OPEN_ERROR;
|
|
}
|
|
|
|
std::vector<std::pair<QString, QDateTime>> timeSteps;
|
|
for ( const std::string& timeStepStringStdString : stepNames )
|
|
{
|
|
QString timeStepString = QString::fromStdString( timeStepStringStdString );
|
|
timeSteps.push_back( std::make_pair( timeStepString, dateTimeFromTimeStepString( timeStepString ) ) );
|
|
}
|
|
|
|
m_timeStepFilter->setTimeStepsFromFile( timeSteps );
|
|
|
|
if ( m_applyTimeFilter )
|
|
{
|
|
m_applyTimeFilter = false; // Clear when we've done this once.
|
|
|
|
caf::PdmUiPropertyViewDialog propertyDialog( nullptr,
|
|
m_timeStepFilter,
|
|
"Time Step Filter",
|
|
"",
|
|
QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
|
|
propertyDialog.resize( QSize( 400, 400 ) );
|
|
|
|
// Push arrow cursor onto the cursor stack so it takes over from the wait cursor.
|
|
QApplication::setOverrideCursor( QCursor( Qt::ArrowCursor ) );
|
|
int propertyReturnValue = propertyDialog.exec();
|
|
// Pop arrow cursor off the cursor stack so that the previous (wait) cursor takes over.
|
|
QApplication::restoreOverrideCursor();
|
|
if ( propertyReturnValue != QDialog::Accepted )
|
|
{
|
|
return CASE_OPEN_CANCELLED;
|
|
}
|
|
m_timeStepFilter->updateFilteredTimeStepsFromUi();
|
|
}
|
|
|
|
// Continue reading the open file
|
|
if ( !geoMechCaseData->readFemParts( errorMessage, m_timeStepFilter->filteredTimeSteps(), m_timeStepFilter->readOnlyLastFrame() ) )
|
|
{
|
|
return CASE_OPEN_ERROR;
|
|
}
|
|
|
|
if ( activeFormationNames() )
|
|
{
|
|
geoMechCaseData->femPartResults()->setActiveFormationNames( activeFormationNames()->formationNamesData() );
|
|
}
|
|
else
|
|
{
|
|
geoMechCaseData->femPartResults()->setActiveFormationNames( nullptr );
|
|
}
|
|
|
|
std::vector<QString> fileNames;
|
|
for ( const caf::FilePath& fileName : m_elementPropertyFileNames.v() )
|
|
{
|
|
fileNames.push_back( fileName.path() );
|
|
}
|
|
geoMechCaseData->femPartResults()->addElementPropertyFiles( fileNames );
|
|
geoMechCaseData->femPartResults()->setCalculationParameters( m_cohesion, cvf::Math::toRadians( m_frictionAngleDeg() ) );
|
|
geoMechCaseData->femPartResults()->setWaterDensityShearSlipIndicator( m_waterDensityShearSlipIndicator );
|
|
|
|
m_geoMechCaseData = geoMechCaseData;
|
|
|
|
m_mudWeightWindowParameters->updateFemPartResults();
|
|
|
|
return CASE_OPEN_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<Rim3dView*> RimGeoMechCase::allSpecialViews() const
|
|
{
|
|
std::vector<Rim3dView*> views;
|
|
for ( size_t vIdx = 0; vIdx < geoMechViews.size(); ++vIdx )
|
|
{
|
|
views.push_back( geoMechViews[vIdx] );
|
|
}
|
|
|
|
for ( RimGeoMechContourMapView* view : m_contourMapCollection->views() )
|
|
{
|
|
views.push_back( view );
|
|
}
|
|
|
|
return views;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/ )
|
|
{
|
|
std::vector<PdmObjectHandle*> children = geoMechViews.children();
|
|
|
|
for ( auto child : children )
|
|
uiTreeOrdering.add( child );
|
|
|
|
if ( !m_2dIntersectionViewCollection->views().empty() )
|
|
{
|
|
uiTreeOrdering.add( &m_2dIntersectionViewCollection );
|
|
}
|
|
|
|
if ( !m_contourMapCollection->views().empty() )
|
|
{
|
|
uiTreeOrdering.add( &m_contourMapCollection );
|
|
}
|
|
|
|
uiTreeOrdering.skipRemainingChildren( true );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechContourMapViewCollection* RimGeoMechCase::contourMapCollection()
|
|
{
|
|
return m_contourMapCollection;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<QDateTime> RimGeoMechCase::timeStepDates() const
|
|
{
|
|
QStringList timeStrings = timeStepStrings();
|
|
|
|
return RimGeoMechCase::vectorOfValidDateTimesFromTimeStepStrings( timeStrings );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::initAfterRead()
|
|
{
|
|
RimCase::initAfterRead();
|
|
|
|
for ( RimGeoMechView* riv : geoMechViews() )
|
|
{
|
|
CVF_ASSERT( riv );
|
|
riv->setGeoMechCase( this );
|
|
}
|
|
|
|
for ( RimGeoMechContourMapView* contourMap : m_contourMapCollection->views() )
|
|
{
|
|
contourMap->setGeoMechCase( this );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QStringList RimGeoMechCase::timeStepStrings() const
|
|
{
|
|
QStringList stringList;
|
|
|
|
const RigGeoMechCaseData* rigCaseData = geoMechData();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
std::vector<std::string> stepNames = rigCaseData->femPartResults()->stepNames();
|
|
for ( size_t i = 0; i < stepNames.size(); i++ )
|
|
{
|
|
stringList += QString::fromStdString( stepNames[i] );
|
|
}
|
|
}
|
|
|
|
return stringList;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimGeoMechCase::timeStepName( int timeStepIdx ) const
|
|
{
|
|
const RigGeoMechCaseData* rigCaseData = geoMechData();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
std::vector<std::string> stepNames = rigCaseData->femPartResults()->stepNames();
|
|
if ( timeStepIdx < static_cast<int>( stepNames.size() ) )
|
|
{
|
|
return QString::fromStdString( stepNames[timeStepIdx] );
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::BoundingBox RimGeoMechCase::reservoirBoundingBox()
|
|
{
|
|
cvf::BoundingBox boundingBox;
|
|
|
|
RigGeoMechCaseData* rigCaseData = this->geoMechData();
|
|
if ( rigCaseData && rigCaseData->femPartResults() && rigCaseData->femParts() )
|
|
{
|
|
for ( int p = 0; p < rigCaseData->femParts()->partCount(); p++ )
|
|
{
|
|
RigFemPart* femPart = rigCaseData->femParts()->part( p );
|
|
const RigFemPartGrid* femPartGrid = femPart->getOrCreateStructGrid();
|
|
|
|
RigFemResultAddress porBarAddr( RigFemResultPosEnum::RIG_ELEMENT_NODAL, "POR-Bar", "" );
|
|
const std::vector<float>& resultValues = rigCaseData->femPartResults()->resultValues( porBarAddr, p, 0, 0 );
|
|
|
|
for ( int i = 0; i < femPart->elementCount(); ++i )
|
|
{
|
|
size_t resValueIdx = femPart->elementNodeResultIdx( (int)i, 0 );
|
|
CVF_ASSERT( resValueIdx < resultValues.size() );
|
|
double scalarValue = resultValues[resValueIdx];
|
|
bool validPorValue = scalarValue != std::numeric_limits<double>::infinity();
|
|
|
|
if ( validPorValue )
|
|
{
|
|
std::array<cvf::Vec3d, 8> hexCorners;
|
|
femPartGrid->cellCornerVertices( i, hexCorners.data() );
|
|
for ( size_t c = 0; c < 8; ++c )
|
|
{
|
|
boundingBox.add( hexCorners[c] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return boundingBox;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::BoundingBox RimGeoMechCase::activeCellsBoundingBox() const
|
|
{
|
|
return allCellsBoundingBox();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::BoundingBox RimGeoMechCase::allCellsBoundingBox() const
|
|
{
|
|
if ( m_geoMechCaseData.notNull() && m_geoMechCaseData->femParts() )
|
|
{
|
|
return m_geoMechCaseData->femParts()->boundingBox();
|
|
}
|
|
else
|
|
{
|
|
return cvf::BoundingBox();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RimGeoMechCase::characteristicCellSize() const
|
|
{
|
|
if ( geoMechData() && geoMechData()->femParts() )
|
|
{
|
|
double cellSize = geoMechData()->femParts()->characteristicElementSize();
|
|
|
|
return cellSize;
|
|
}
|
|
|
|
return 10.0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::addElementPropertyFiles( const std::vector<caf::FilePath>& fileNames )
|
|
{
|
|
std::vector<QString> newFileNames;
|
|
|
|
for ( const caf::FilePath& newFileNameToPossiblyAdd : fileNames )
|
|
{
|
|
bool fileAlreadyAdded = false;
|
|
|
|
for ( const caf::FilePath& existingFileName : m_elementPropertyFileNames() )
|
|
{
|
|
if ( existingFileName == newFileNameToPossiblyAdd )
|
|
{
|
|
fileAlreadyAdded = true;
|
|
break;
|
|
}
|
|
}
|
|
if ( !fileAlreadyAdded )
|
|
{
|
|
newFileNames.push_back( newFileNameToPossiblyAdd.path() );
|
|
m_elementPropertyFileNames.v().push_back( newFileNameToPossiblyAdd );
|
|
}
|
|
}
|
|
|
|
this->updateConnectedEditors();
|
|
|
|
if ( m_geoMechCaseData.notNull() )
|
|
{
|
|
geoMechData()->femPartResults()->addElementPropertyFiles( newFileNames );
|
|
geoMechData()->femPartResults()->deleteAllScalarResults();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RimGeoMechCase::cohesion() const
|
|
{
|
|
return m_cohesion;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RimGeoMechCase::frictionAngleDeg() const
|
|
{
|
|
return m_frictionAngleDeg;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechCase::BiotCoefficientType RimGeoMechCase::biotCoefficientType() const
|
|
{
|
|
return m_biotCoefficientType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RimGeoMechCase::biotFixedCoefficient() const
|
|
{
|
|
return m_biotFixedCoefficient;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimGeoMechCase::biotResultAddress() const
|
|
{
|
|
return m_biotResultAddress;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechCase::InitialPermeabilityType RimGeoMechCase::initialPermeabilityType() const
|
|
{
|
|
return m_initialPermeabilityType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RimGeoMechCase::initialPermeabilityFixed() const
|
|
{
|
|
return m_initialPermeabilityFixed;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimGeoMechCase::initialPermeabilityAddress() const
|
|
{
|
|
return m_initialPermeabilityResultAddress;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RimGeoMechCase::permeabilityExponent() const
|
|
{
|
|
return m_permeabilityExponent;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::setApplyTimeFilter( bool applyTimeFilter )
|
|
{
|
|
m_applyTimeFilter = applyTimeFilter;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::Vec3d RimGeoMechCase::displayModelOffset() const
|
|
{
|
|
auto bb = this->allCellsBoundingBox();
|
|
if ( bb.isValid() )
|
|
{
|
|
return this->allCellsBoundingBox().min();
|
|
}
|
|
|
|
return cvf::Vec3d::ZERO;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<QDateTime> RimGeoMechCase::vectorOfValidDateTimesFromTimeStepStrings( const QStringList& timeStepStrings )
|
|
{
|
|
std::vector<QDateTime> dates;
|
|
|
|
for ( const QString& timeStepString : timeStepStrings )
|
|
{
|
|
QDateTime dateTime = dateTimeFromTimeStepString( timeStepString );
|
|
if ( dateTime.isValid() )
|
|
{
|
|
dates.push_back( dateTime );
|
|
}
|
|
}
|
|
|
|
return dates;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QDateTime RimGeoMechCase::dateTimeFromTimeStepString( const QString& timeStepString )
|
|
{
|
|
QString dateFormat = "yyyyMMdd";
|
|
QString dateStr = subStringOfDigits( timeStepString, dateFormat.size() );
|
|
return QDateTime::fromString( dateStr, dateFormat );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
|
{
|
|
if ( changedField == &m_activeFormationNames )
|
|
{
|
|
updateFormationNamesData();
|
|
}
|
|
|
|
RigGeoMechCaseData* rigCaseData = geoMechData();
|
|
if ( changedField == &m_cohesion || changedField == &m_frictionAngleDeg )
|
|
{
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
rigCaseData->femPartResults()->setCalculationParameters( m_cohesion(), cvf::Math::toRadians( m_frictionAngleDeg() ) );
|
|
}
|
|
|
|
updateConnectedViews();
|
|
}
|
|
else if ( changedField == &m_biotFixedCoefficient || changedField == &m_biotCoefficientType || changedField == &m_biotResultAddress )
|
|
{
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
if ( m_biotCoefficientType() == RimGeoMechCase::BiotCoefficientType::BIOT_NONE )
|
|
{
|
|
rigCaseData->femPartResults()->setBiotCoefficientParameters( 1.0, "" );
|
|
}
|
|
else if ( m_biotCoefficientType() == RimGeoMechCase::BiotCoefficientType::BIOT_FIXED )
|
|
{
|
|
rigCaseData->femPartResults()->setBiotCoefficientParameters( m_biotFixedCoefficient(), "" );
|
|
}
|
|
else if ( m_biotCoefficientType() == RimGeoMechCase::BiotCoefficientType::BIOT_PER_ELEMENT )
|
|
{
|
|
if ( changedField == &m_biotCoefficientType )
|
|
{
|
|
// Show info message to user when selecting "from file" option before
|
|
// an element property has been imported
|
|
std::vector<std::string> elementProperties = possibleElementPropertyFieldNames();
|
|
if ( elementProperties.empty() )
|
|
{
|
|
QString importMessage = QString( "Please import biot coefficients from file (typically called alpha.inp) by "
|
|
"selecting 'Import Element Property Table' on the Geomechanical Model." );
|
|
RiaLogging::info( importMessage );
|
|
// Set back to default value
|
|
m_biotCoefficientType = RimGeoMechCase::BiotCoefficientType::BIOT_NONE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( biotResultAddress().isEmpty() )
|
|
{
|
|
// Automatically select the first available property element if empty
|
|
std::vector<std::string> elementProperties = possibleElementPropertyFieldNames();
|
|
if ( !elementProperties.empty() )
|
|
{
|
|
m_biotResultAddress = QString::fromStdString( elementProperties[0] );
|
|
}
|
|
}
|
|
|
|
rigCaseData->femPartResults()->setBiotCoefficientParameters( 1.0, biotResultAddress() );
|
|
}
|
|
}
|
|
|
|
updateConnectedViews();
|
|
}
|
|
else if ( changedField == &m_initialPermeabilityFixed || changedField == &m_initialPermeabilityType ||
|
|
changedField == &m_initialPermeabilityResultAddress || changedField == &m_permeabilityExponent )
|
|
{
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
if ( m_initialPermeabilityType() == RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_FIXED )
|
|
{
|
|
rigCaseData->femPartResults()->setPermeabilityParameters( initialPermeabilityFixed(), "", permeabilityExponent() );
|
|
}
|
|
else if ( m_initialPermeabilityType() == RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_PER_ELEMENT )
|
|
{
|
|
if ( changedField == &m_initialPermeabilityType )
|
|
{
|
|
// Show info message to user when selecting "from file" option before
|
|
// an element property has been imported
|
|
std::vector<std::string> elementProperties = possibleElementPropertyFieldNames();
|
|
if ( elementProperties.empty() )
|
|
{
|
|
QString importMessage = QString( "Please import initial permeability from file (typically called perm.inp) by "
|
|
"selecting 'Import Element Property Table' on the Geomechanical Model." );
|
|
RiaLogging::info( importMessage );
|
|
// Set back to default value
|
|
m_initialPermeabilityType = RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_FIXED;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( initialPermeabilityAddress().isEmpty() )
|
|
{
|
|
// Automatically select the first available property element if empty
|
|
std::vector<std::string> elementProperties = possibleElementPropertyFieldNames();
|
|
if ( !elementProperties.empty() )
|
|
{
|
|
m_initialPermeabilityResultAddress = QString::fromStdString( elementProperties[0] );
|
|
}
|
|
}
|
|
|
|
rigCaseData->femPartResults()->setPermeabilityParameters( initialPermeabilityFixed(),
|
|
initialPermeabilityAddress(),
|
|
permeabilityExponent() );
|
|
}
|
|
}
|
|
|
|
updateConnectedViews();
|
|
}
|
|
else if ( changedField == &m_waterDensityShearSlipIndicator )
|
|
{
|
|
rigCaseData->femPartResults()->setWaterDensityShearSlipIndicator( m_waterDensityShearSlipIndicator );
|
|
updateConnectedViews();
|
|
}
|
|
else if ( changedField == &m_reloadElementPropertyFileCommand )
|
|
{
|
|
m_reloadElementPropertyFileCommand = false;
|
|
reloadSelectedElementPropertyFiles();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
rigCaseData->femPartResults()->deleteAllScalarResults();
|
|
}
|
|
updateConnectedEditors();
|
|
updateConnectedViews();
|
|
}
|
|
else if ( changedField == &m_closeElementPropertyFileCommand )
|
|
{
|
|
m_closeElementPropertyFileCommand = false;
|
|
closeSelectedElementPropertyFiles();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
rigCaseData->femPartResults()->deleteAllScalarResults();
|
|
}
|
|
updateConnectedEditors();
|
|
updateConnectedViews();
|
|
}
|
|
else if ( changedField == &m_importElementPropertyFileCommand )
|
|
{
|
|
m_importElementPropertyFileCommand = false;
|
|
importElementPropertyFile();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
rigCaseData->femPartResults()->deleteAllScalarResults();
|
|
}
|
|
updateConnectedEditors();
|
|
updateConnectedViews();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::updateFormationNamesData()
|
|
{
|
|
RigGeoMechCaseData* rigCaseData = geoMechData();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
if ( activeFormationNames() )
|
|
{
|
|
rigCaseData->femPartResults()->setActiveFormationNames( activeFormationNames()->formationNamesData() );
|
|
}
|
|
else
|
|
{
|
|
rigCaseData->femPartResults()->setActiveFormationNames( nullptr );
|
|
}
|
|
|
|
RimWellLogPlotCollection* plotCollection = RimMainPlotCollection::current()->wellLogPlotCollection();
|
|
plotCollection->loadDataAndUpdateAllPlots();
|
|
|
|
std::vector<Rim3dView*> views = this->views();
|
|
for ( Rim3dView* view : views )
|
|
{
|
|
RimGeoMechView* geomView = dynamic_cast<RimGeoMechView*>( view );
|
|
|
|
if ( geomView && geomView->isUsingFormationNames() )
|
|
{
|
|
if ( !activeFormationNames() )
|
|
{
|
|
if ( geomView->cellResult()->resultPositionType() == RIG_FORMATION_NAMES )
|
|
{
|
|
geomView->cellResult()->setResultAddress( RigFemResultAddress( RIG_FORMATION_NAMES, "", "" ) );
|
|
geomView->cellResult()->updateConnectedEditors();
|
|
}
|
|
|
|
RimGeoMechPropertyFilterCollection* eclFilColl = geomView->geoMechPropertyFilterCollection();
|
|
for ( RimGeoMechPropertyFilter* propFilter : eclFilColl->propertyFilters )
|
|
{
|
|
if ( propFilter->resultDefinition()->resultPositionType() == RIG_FORMATION_NAMES )
|
|
{
|
|
propFilter->resultDefinition()->setResultAddress( RigFemResultAddress( RIG_FORMATION_NAMES, "", "" ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
RimGeoMechPropertyFilterCollection* eclFilColl = geomView->geoMechPropertyFilterCollection();
|
|
for ( RimGeoMechPropertyFilter* propFilter : eclFilColl->propertyFilters )
|
|
{
|
|
if ( propFilter->resultDefinition->resultPositionType() == RIG_FORMATION_NAMES )
|
|
{
|
|
propFilter->setToDefaultValues();
|
|
propFilter->updateConnectedEditors();
|
|
}
|
|
}
|
|
|
|
geomView->cellResult()->updateConnectedEditors();
|
|
|
|
view->scheduleGeometryRegen( PROPERTY_FILTERED );
|
|
view->scheduleCreateDisplayModelAndRedraw();
|
|
geomView->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimGeoMechCase::subStringOfDigits( const QString& inputString, int numberOfDigitsToFind )
|
|
{
|
|
for ( int j = 0; j < inputString.size(); j++ )
|
|
{
|
|
if ( inputString.at( j ).isDigit() )
|
|
{
|
|
QString digitString;
|
|
|
|
for ( int k = 0; k < numberOfDigitsToFind; k++ )
|
|
{
|
|
if ( j + k < inputString.size() && inputString.at( j + k ).isDigit() )
|
|
{
|
|
digitString += inputString.at( j + k );
|
|
}
|
|
}
|
|
|
|
if ( digitString.size() == numberOfDigitsToFind )
|
|
{
|
|
return digitString;
|
|
}
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
struct descendingComparator
|
|
{
|
|
template <class T>
|
|
bool operator()( T const& a, T const& b ) const
|
|
{
|
|
return a > b;
|
|
}
|
|
};
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::closeSelectedElementPropertyFiles()
|
|
{
|
|
std::sort( m_elementPropertyFileNameIndexUiSelection.v().begin(),
|
|
m_elementPropertyFileNameIndexUiSelection.v().end(),
|
|
descendingComparator() );
|
|
|
|
std::vector<QString> filesToClose;
|
|
|
|
for ( size_t idx : m_elementPropertyFileNameIndexUiSelection.v() )
|
|
{
|
|
filesToClose.push_back( m_elementPropertyFileNames.v().at( idx ).path() );
|
|
m_elementPropertyFileNames.v().erase( m_elementPropertyFileNames.v().begin() + idx );
|
|
}
|
|
|
|
m_elementPropertyFileNameIndexUiSelection.v().clear();
|
|
|
|
std::vector<RigFemResultAddress> addressesToDelete;
|
|
|
|
if ( m_geoMechCaseData.notNull() )
|
|
{
|
|
addressesToDelete = geoMechData()->femPartResults()->removeElementPropertyFiles( filesToClose );
|
|
geoMechData()->femPartResults()->deleteAllScalarResults();
|
|
}
|
|
|
|
for ( RimGeoMechView* view : geoMechViews() )
|
|
{
|
|
for ( RigFemResultAddress address : addressesToDelete )
|
|
{
|
|
if ( address == view->cellResultResultDefinition()->resultAddress() )
|
|
{
|
|
view->cellResult()->setResultAddress( RigFemResultAddress() );
|
|
}
|
|
|
|
if ( address.fieldName == biotResultAddress().toStdString() )
|
|
{
|
|
// If the used biot value is being removed we need to change the biot type back to default
|
|
m_biotCoefficientType = RimGeoMechCase::BiotCoefficientType::BIOT_NONE;
|
|
}
|
|
|
|
for ( RimGeoMechPropertyFilter* propertyFilter : view->geoMechPropertyFilterCollection()->propertyFilters() )
|
|
{
|
|
if ( address == propertyFilter->resultDefinition->resultAddress() )
|
|
{
|
|
propertyFilter->resultDefinition->setResultAddress( RigFemResultAddress() );
|
|
}
|
|
}
|
|
}
|
|
|
|
view->loadDataAndUpdate();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::reloadSelectedElementPropertyFiles()
|
|
{
|
|
std::vector<QString> filesToReload;
|
|
|
|
for ( size_t idx : m_elementPropertyFileNameIndexUiSelection.v() )
|
|
{
|
|
filesToReload.push_back( m_elementPropertyFileNames.v().at( idx ).path() );
|
|
}
|
|
|
|
m_elementPropertyFileNameIndexUiSelection.v().clear();
|
|
|
|
if ( m_geoMechCaseData.notNull() )
|
|
{
|
|
geoMechData()->femPartResults()->removeElementPropertyFiles( filesToReload );
|
|
geoMechData()->femPartResults()->addElementPropertyFiles( filesToReload );
|
|
}
|
|
|
|
for ( RimGeoMechView* view : geoMechViews() )
|
|
{
|
|
view->loadDataAndUpdate();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::importElementPropertyFile()
|
|
{
|
|
RicImportElementPropertyFeature::importElementProperties();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
uiOrdering.add( &m_caseUserDescription );
|
|
uiOrdering.add( &m_caseId );
|
|
uiOrdering.add( &m_caseFileName );
|
|
|
|
caf::PdmUiGroup* caseGroup = uiOrdering.addNewGroup( "Case Options" );
|
|
caseGroup->add( &m_activeFormationNames );
|
|
caseGroup->add( &m_cohesion );
|
|
caseGroup->add( &m_frictionAngleDeg );
|
|
|
|
caf::PdmUiGroup* elmPropGroup = uiOrdering.addNewGroup( "Element Properties" );
|
|
elmPropGroup->add( &m_elementPropertyFileNameIndexUiSelection );
|
|
elmPropGroup->add( &m_importElementPropertyFileCommand );
|
|
elmPropGroup->add( &m_reloadElementPropertyFileCommand );
|
|
elmPropGroup->add( &m_closeElementPropertyFileCommand );
|
|
|
|
caf::PdmUiGroup* biotGroup = uiOrdering.addNewGroup( "Biot Coefficient" );
|
|
biotGroup->add( &m_biotCoefficientType );
|
|
biotGroup->add( &m_biotFixedCoefficient );
|
|
biotGroup->add( &m_biotResultAddress );
|
|
m_biotFixedCoefficient.uiCapability()->setUiHidden( m_biotCoefficientType != RimGeoMechCase::BiotCoefficientType::BIOT_FIXED );
|
|
m_biotResultAddress.uiCapability()->setUiHidden( m_biotCoefficientType != RimGeoMechCase::BiotCoefficientType::BIOT_PER_ELEMENT );
|
|
|
|
caf::PdmUiGroup* permeabilityGroup = uiOrdering.addNewGroup( "Permeability" );
|
|
permeabilityGroup->add( &m_initialPermeabilityType );
|
|
permeabilityGroup->add( &m_initialPermeabilityFixed );
|
|
permeabilityGroup->add( &m_initialPermeabilityResultAddress );
|
|
m_initialPermeabilityFixed.uiCapability()->setUiHidden( m_initialPermeabilityType !=
|
|
RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_FIXED );
|
|
m_initialPermeabilityResultAddress.uiCapability()->setUiHidden(
|
|
m_initialPermeabilityType != RimGeoMechCase::InitialPermeabilityType::INITIAL_PERMEABILITY_PER_ELEMENT );
|
|
permeabilityGroup->add( &m_permeabilityExponent );
|
|
|
|
caf::PdmUiGroup* mudWeightWindowGroup = uiOrdering.addNewGroup( "Mud Weight Window" );
|
|
m_mudWeightWindowParameters->uiOrdering( uiConfigName, *mudWeightWindowGroup );
|
|
|
|
caf::PdmUiGroup* shearSlipIndicatorGroup = uiOrdering.addNewGroup( "Shear Slip Indicator" );
|
|
shearSlipIndicatorGroup->add( &m_waterDensityShearSlipIndicator );
|
|
|
|
caf::PdmUiGroup* timeStepFilterGroup = uiOrdering.addNewGroup( "Time Step Filter" );
|
|
timeStepFilterGroup->setCollapsedByDefault();
|
|
m_timeStepFilter->uiOrdering( uiConfigName, *timeStepFilterGroup );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
|
{
|
|
if ( field == &m_importElementPropertyFileCommand )
|
|
{
|
|
dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute )->m_buttonText = "Import Element Property";
|
|
}
|
|
if ( field == &m_reloadElementPropertyFileCommand )
|
|
{
|
|
dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute )->m_buttonText = "Reload Element Property";
|
|
}
|
|
if ( field == &m_closeElementPropertyFileCommand )
|
|
{
|
|
dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute )->m_buttonText = "Close Element Property";
|
|
}
|
|
|
|
if ( field == &m_biotFixedCoefficient )
|
|
{
|
|
auto uiDoubleValueEditorAttr = dynamic_cast<caf::PdmUiDoubleValueEditorAttribute*>( attribute );
|
|
if ( uiDoubleValueEditorAttr )
|
|
{
|
|
uiDoubleValueEditorAttr->m_decimals = 2;
|
|
uiDoubleValueEditorAttr->m_validator = new QDoubleValidator( 0.0, 1.0, 2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QList<caf::PdmOptionItemInfo> RimGeoMechCase::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
options = RimCase::calculateValueOptions( fieldNeedingOptions );
|
|
|
|
if ( fieldNeedingOptions == &m_elementPropertyFileNameIndexUiSelection )
|
|
{
|
|
for ( size_t i = 0; i < m_elementPropertyFileNames.v().size(); i++ )
|
|
{
|
|
options.push_back( caf::PdmOptionItemInfo( m_elementPropertyFileNames.v().at( i ).path(), (int)i, true ) );
|
|
}
|
|
}
|
|
else if ( fieldNeedingOptions == &m_biotResultAddress || fieldNeedingOptions == &m_initialPermeabilityResultAddress )
|
|
{
|
|
std::vector<std::string> elementProperties = possibleElementPropertyFieldNames();
|
|
|
|
std::vector<QString> paths;
|
|
for ( auto path : m_elementPropertyFileNames.v() )
|
|
{
|
|
paths.push_back( path.path() );
|
|
}
|
|
|
|
std::map<std::string, QString> addressesInFile = geoMechData()->femPartResults()->addressesInElementPropertyFiles( paths );
|
|
|
|
for ( const std::string& elementProperty : elementProperties )
|
|
{
|
|
QString result = QString::fromStdString( elementProperty );
|
|
QString filename = findFileNameForElementProperty( elementProperty, addressesInFile );
|
|
options.push_back( caf::PdmOptionItemInfo( result + " (" + filename + ")", result ) );
|
|
}
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimGeoMechCase::findFileNameForElementProperty( const std::string& elementProperty,
|
|
const std::map<std::string, QString> addressesInFiles ) const
|
|
{
|
|
auto it = addressesInFiles.find( elementProperty );
|
|
if ( it != addressesInFiles.end() )
|
|
{
|
|
QFileInfo fileInfo( it->second );
|
|
return fileInfo.fileName();
|
|
}
|
|
else
|
|
{
|
|
return QString( "Unknown file" );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::updateConnectedViews()
|
|
{
|
|
std::vector<Rim3dView*> views = this->views();
|
|
for ( Rim3dView* view : views )
|
|
{
|
|
if ( view )
|
|
{
|
|
view->scheduleCreateDisplayModelAndRedraw();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::string> RimGeoMechCase::possibleElementPropertyFieldNames()
|
|
{
|
|
std::vector<std::string> fieldNames;
|
|
|
|
if ( geoMechData() )
|
|
{
|
|
std::map<std::string, std::vector<std::string>> fieldWithComponentNames =
|
|
geoMechData()->femPartResults()->scalarFieldAndComponentNames( RIG_ELEMENT );
|
|
|
|
std::map<std::string, std::vector<std::string>>::const_iterator fieldIt;
|
|
for ( fieldIt = fieldWithComponentNames.begin(); fieldIt != fieldWithComponentNames.end(); ++fieldIt )
|
|
{
|
|
fieldNames.push_back( fieldIt->first );
|
|
}
|
|
}
|
|
return fieldNames;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<caf::FilePath> RimGeoMechCase::elementPropertyFileNames() const
|
|
{
|
|
return m_elementPropertyFileNames();
|
|
}
|