mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-21 22:13:25 -06:00
1305 lines
52 KiB
C++
1305 lines
52 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 "cafPdmUiListEditor.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( void )
|
|
: 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()->setUiHidden( 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", "", "", "" );
|
|
m_biotResultAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
|
|
|
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", "", "", "" );
|
|
m_initialPermeabilityResultAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
|
|
|
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 );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimGeoMechCase::~RimGeoMechCase( void )
|
|
{
|
|
geoMechViews.deleteAllChildObjects();
|
|
|
|
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->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 )
|
|
{
|
|
RiaApplication* app = RiaApplication::instance();
|
|
RimProject* project = app->project();
|
|
|
|
RimGeoMechCase* copycase = dynamic_cast<RimGeoMechCase*>(
|
|
this->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
|
|
CVF_ASSERT( copycase );
|
|
|
|
QFileInfo filenameInfo( newInputFileName );
|
|
QString newCaseName = filenameInfo.completeBaseName();
|
|
|
|
copycase->caseUserDescription.setValue( newCaseName + " (copy of " + caseUserDescription.value() + ")" );
|
|
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() ) )
|
|
{
|
|
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;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimGeoMechCase::updateFilePathsFromProjectPath( const QString& newProjectPath, const QString& oldProjectPath )
|
|
{
|
|
// No longer in use. Filepaths are now of type caf::FilePath, and updated in RimProject on load.
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
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.childObjects( &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()->filteredStepNames();
|
|
for ( size_t i = 0; i < stepNames.size(); i++ )
|
|
{
|
|
stringList += QString::fromStdString( stepNames[i] );
|
|
}
|
|
}
|
|
|
|
return stringList;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimGeoMechCase::timeStepName( int frameIdx ) const
|
|
{
|
|
const RigGeoMechCaseData* rigCaseData = geoMechData();
|
|
if ( rigCaseData && rigCaseData->femPartResults() )
|
|
{
|
|
std::vector<std::string> stepNames = rigCaseData->femPartResults()->filteredStepNames();
|
|
if ( frameIdx < static_cast<int>( stepNames.size() ) )
|
|
{
|
|
return QString::fromStdString( stepNames[frameIdx] );
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::BoundingBox RimGeoMechCase::reservoirBoundingBox()
|
|
{
|
|
cvf::BoundingBox boundingBox;
|
|
|
|
RigGeoMechCaseData* rigCaseData = this->geoMechData();
|
|
if ( rigCaseData && rigCaseData->femPartResults() && rigCaseData->femParts()->part( 0 ) )
|
|
{
|
|
RigFemPart* femPart = rigCaseData->femParts()->part( 0 );
|
|
const RigFemPartGrid* femPartGrid = femPart->getOrCreateStructGrid();
|
|
|
|
RigFemResultAddress porBarAddr( RigFemResultPosEnum::RIG_ELEMENT_NODAL, "POR-Bar", "" );
|
|
const std::vector<float>& resultValues = rigCaseData->femPartResults()->resultValues( porBarAddr, 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 );
|
|
}
|
|
|
|
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( &caseUserDescription );
|
|
uiOrdering.add( &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( true );
|
|
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,
|
|
bool* useOptionsOnly )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
options = RimCase::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
|
|
|
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();
|
|
}
|