Fault Reactivation Modeling updates (#10602)

* Add timestep selection
* Add import geomech model to context menu
* Add command for running fault reactivation 
* Change order of nodes for exported elements
* Add command to quickly show model in 3D view
This commit is contained in:
jonjenssen 2023-09-14 08:29:28 +02:00 committed by GitHub
parent e8cbbf5d55
commit bd7f34f835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 536 additions and 11 deletions

View File

@ -11,6 +11,8 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewWellIntegrityAnalysisFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicRunWellIntegrityAnalysisFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewFaultReactModelingFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicRunFaultReactModelingFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicShowFaultReactModelFeature.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -26,6 +28,8 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewWellIntegrityAnalysisFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicRunWellIntegrityAnalysisFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewFaultReactModelingFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicRunFaultReactModelingFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicShowFaultReactModelFeature.cpp
)
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -113,6 +113,7 @@ void RicNewFaultReactModelingFeature::onActionTriggered( bool isChecked )
auto model = eclView->faultReactivationModelCollection()->addNewModel( rimFault, target1, target2, baseDir );
if ( model != nullptr )
{
model->updateTimeSteps();
view->updateAllRequiredEditors();
Riu3DMainWindowTools::selectAsCurrentItem( model );
}

View File

@ -0,0 +1,135 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicRunFaultReactModelingFeature.h"
#include "RiaApplication.h"
#include "RiaPreferencesGeoMech.h"
#include "RifFaultReactivationModelExporter.h"
#include "RimFaultReactivationModel.h"
#include "RimProcess.h"
#include "RimProject.h"
#include "Riu3DMainWindowTools.h"
#include "RiuFileDialogTools.h"
#include "cafProgressInfo.h"
#include "cafSelectionManagerTools.h"
#include <QAction>
#include <QMessageBox>
CAF_CMD_SOURCE_INIT( RicRunFaultReactModelingFeature, "RicRunFaultReactModelingFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicRunFaultReactModelingFeature::isCommandEnabled() const
{
return RiaPreferencesGeoMech::current()->validateFRMSettings();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicRunFaultReactModelingFeature::onActionTriggered( bool isChecked )
{
RimFaultReactivationModel* model = dynamic_cast<RimFaultReactivationModel*>( caf::SelectionManager::instance()->selectedItem() );
if ( model == nullptr ) return;
const QString frmTitle( "Fault Reactivation Modeling" );
caf::ProgressInfo runProgress( 3, frmTitle + " running , please wait..." );
runProgress.setProgressDescription( "Writing input files." );
if ( model->fault() == nullptr )
{
QMessageBox::critical( nullptr, frmTitle, "A fault has not selected. Please check your model settings." );
return;
}
if ( !model->extractModelData() )
{
QMessageBox::critical( nullptr, frmTitle, "Unable to get necessary data from the input model." );
return;
}
QString exportFile = model->inputFilename();
auto [result, errText] = RifFaultReactivationModelExporter::exportToFile( exportFile.toStdString(), *model->model() );
if ( !result )
{
QString outErrorText =
QString( "Failed to export INP model to file %1.\n\n%2" ).arg( exportFile ).arg( QString::fromStdString( errText ) );
QMessageBox::critical( nullptr, frmTitle, outErrorText );
return;
}
if ( RiaPreferencesGeoMech::current()->waitBeforeRun() )
{
runProgress.setProgressDescription( "Waiting for input file modifications." );
QString infoText = "Input parameter files can now be found in the working folder:";
infoText += " \"" + model->baseDir() + "\"\n";
infoText += "\nClick OK to start the Abaqus modeling or Cancel to stop.";
auto reply = QMessageBox::information( nullptr, frmTitle, infoText, QMessageBox::Ok | QMessageBox::Cancel );
if ( reply != QMessageBox::Ok ) return;
}
runProgress.incrementProgress();
runProgress.setProgressDescription( "Running Abaqus modeling." );
QString command = RiaPreferencesGeoMech::current()->geomechFRMCommand();
QStringList parameters = model->commandParameters();
RimProcess process;
process.setCommand( command );
process.setParameters( parameters );
if ( !process.execute() )
{
QMessageBox::critical( nullptr, frmTitle, "Failed to run modeling. Check log window for additional information." );
return;
}
runProgress.incrementProgress();
runProgress.setProgressDescription( "Loading modeling results." );
RiaApplication* app = RiaApplication::instance();
if ( !app->openOdbCaseFromFile( model->outputOdbFilename() ) )
{
QMessageBox::critical( nullptr,
frmTitle,
"Failed to load modeling results from file \"" + model->outputOdbFilename() +
"\". Check log window for additional information." );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicRunFaultReactModelingFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setIcon( QIcon( ":/fault_react_24x24.png" ) );
actionToSetup->setText( "Run..." );
}

View File

@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
//==================================================================================================
///
//==================================================================================================
class RicRunFaultReactModelingFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
bool isCommandEnabled() const override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -0,0 +1,102 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicShowFaultReactModelFeature.h"
#include "RiaApplication.h"
#include "RiaPreferencesGeoMech.h"
#include "RifFaultReactivationModelExporter.h"
#include "RimFaultReactivationModel.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechView.h"
#include "RimProject.h"
#include "Riu3DMainWindowTools.h"
#include "cafSelectionManagerTools.h"
#include <QAction>
#include <QMessageBox>
CAF_CMD_SOURCE_INIT( RicShowFaultReactModelFeature, "RicShowFaultReactModelFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicShowFaultReactModelFeature::isCommandEnabled() const
{
return RiaPreferencesGeoMech::current()->validateFRMSettings();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowFaultReactModelFeature::onActionTriggered( bool isChecked )
{
RimFaultReactivationModel* model = dynamic_cast<RimFaultReactivationModel*>( caf::SelectionManager::instance()->selectedItem() );
if ( model == nullptr ) return;
const QString frmTitle( "Fault Reactivation Modeling" );
const QString exportFile = model->inputFilename();
auto [result, errText] = RifFaultReactivationModelExporter::exportToFile( exportFile.toStdString(), *model->model() );
if ( !result )
{
QString outErrorText =
QString( "Failed to export INP model to file %1.\n\n%2" ).arg( exportFile ).arg( QString::fromStdString( errText ) );
QMessageBox::critical( nullptr, frmTitle, outErrorText );
return;
}
for ( auto gCase : RimProject::current()->geoMechCases() )
{
if ( exportFile == gCase->gridFileName() )
{
gCase->reloadDataAndUpdate();
auto& views = gCase->geoMechViews();
if ( views.size() > 0 )
{
Riu3DMainWindowTools::selectAsCurrentItem( views[0] );
}
else
{
Riu3DMainWindowTools::selectAsCurrentItem( gCase );
}
return;
}
}
RiaApplication* app = RiaApplication::instance();
if ( !app->openOdbCaseFromFile( exportFile ) )
{
QMessageBox::critical( nullptr,
frmTitle,
"Failed to load INP model from file \"" + exportFile + "\". Check log window for additional information." );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowFaultReactModelFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setIcon( QIcon( ":/fault_react_24x24.png" ) );
actionToSetup->setText( "Show Model in 3D View..." );
}

View File

@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
//==================================================================================================
///
//==================================================================================================
class RicShowFaultReactModelFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
bool isCommandEnabled() const override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -19,7 +19,9 @@
#include "RimFaultReactivationModel.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaPreferencesGeoMech.h"
#include "RiaQDateTimeTools.h"
#include "RigBasicPlane.h"
#include "RigFaultReactivationModel.h"
@ -38,14 +40,19 @@
#include "RimFaultInView.h"
#include "RimFaultInViewCollection.h"
#include "RimPolylineTarget.h"
#include "RimTimeStepFilter.h"
#include "RimTools.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiTableViewEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include "cvfPlane.h"
#include "cvfTextureImage.h"
#include <QDateTime>
#include <QDir>
CAF_PDM_SOURCE_INIT( RimFaultReactivationModel, "FaultReactivationModel" );
//--------------------------------------------------------------------------------------------------
@ -91,6 +98,12 @@ RimFaultReactivationModel::RimFaultReactivationModel()
CAF_PDM_InitField( &m_numberOfCellsVertMid, "NumberOfCellsVertMid", 20, "Vertical Number of Cells, Middle Part" );
CAF_PDM_InitField( &m_numberOfCellsVertLow, "NumberOfCellsVertLow", 20, "Vertical Number of Cells, Lower Part" );
// Time Step Selection
CAF_PDM_InitFieldNoDefault( &m_timeStepFilter, "TimeStepFilter", "Available Time Steps" );
CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "TimeSteps", "Select Time Steps" );
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
m_selectedTimeSteps.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
CAF_PDM_InitFieldNoDefault( &m_targets, "Targets", "Targets" );
m_targets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
m_targets.uiCapability()->setUiTreeChildrenHidden( true );
@ -301,6 +314,10 @@ QList<caf::PdmOptionItemInfo> RimFaultReactivationModel::calculateValueOptions(
if ( coll != nullptr ) RimTools::faultOptionItems( &options, coll );
}
}
else if ( fieldNeedingOptions == &m_selectedTimeSteps )
{
RimTimeStepFilter::timeStepOptions( options, &m_selectedTimeSteps, m_availableTimeSteps, m_selectedTimeSteps, m_timeStepFilter() );
}
return options;
}
@ -382,6 +399,10 @@ void RimFaultReactivationModel::defineUiOrdering( QString uiConfigName, caf::Pdm
gridModelGrp->add( &m_numberOfCellsVertMid );
gridModelGrp->add( &m_numberOfCellsVertLow );
auto timeStepGrp = uiOrdering.addNewGroup( "Time Steps" );
timeStepGrp->add( &m_timeStepFilter );
timeStepGrp->add( &m_selectedTimeSteps );
auto appModelGrp = modelGrp->addNewGroup( "Appearance" );
appModelGrp->add( &m_modelPart1Color );
appModelGrp->add( &m_modelPart2Color );
@ -449,12 +470,14 @@ void RimFaultReactivationModel::defineEditorAttribute( const caf::PdmFieldHandle
//--------------------------------------------------------------------------------------------------
RimEclipseCase* RimFaultReactivationModel::eclipseCase()
{
auto activeView = dynamic_cast<RimEclipseView*>( RiaApplication::instance()->activeGridView() );
if ( activeView )
auto eCase = firstAncestorOrThisOfType<RimEclipseCase>();
if ( eCase == nullptr )
{
return activeView->eclipseCase();
eCase = dynamic_cast<RimEclipseCase*>( RiaApplication::instance()->activeGridView()->ownerCase() );
}
return nullptr;
return eCase;
}
//--------------------------------------------------------------------------------------------------
@ -472,3 +495,81 @@ QString RimFaultReactivationModel::baseDir() const
{
return m_baseDir().path();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModel::updateTimeSteps()
{
m_availableTimeSteps.clear();
const auto eCase = eclipseCase();
if ( eCase == nullptr ) return;
m_availableTimeSteps = eCase->timeStepDates();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RimFaultReactivationModel::selectedTimeSteps() const
{
return m_selectedTimeSteps();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RimFaultReactivationModel::commandParameters() const
{
QStringList retlist;
retlist << baseDir();
retlist << inputFilename();
retlist << outputOdbFilename();
return retlist;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFaultReactivationModel::outputOdbFilename() const
{
QDir directory( baseDir() );
return directory.absoluteFilePath( baseFilename() + ".odb" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFaultReactivationModel::inputFilename() const
{
QDir directory( baseDir() );
return directory.absoluteFilePath( baseFilename() + ".inp" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFaultReactivationModel::baseFilename() const
{
QString tmp = m_userDescription();
if ( tmp.isEmpty() ) return "faultReactivation";
tmp.replace( ' ', '_' );
tmp.replace( '/', '_' );
tmp.replace( '\\', '_' );
tmp.replace( ':', '_' );
return tmp;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationModel::extractModelData()
{
// TODO - get values from eclipse and geomech models here
return true;
}

View File

@ -20,6 +20,7 @@
#include "RimCheckableNamedObject.h"
#include "RimPolylinePickerInterface.h"
#include "RimPolylinesDataInterface.h"
#include "RimTimeStepFilter.h"
#include "cafFilePath.h"
#include "cafPdmChildArrayField.h"
@ -31,7 +32,9 @@
#include "cvfColor3.h"
#include "cvfVector3.h"
#include <QDateTime>
#include <QString>
#include <QStringList>
#include <memory>
#include <utility>
@ -40,6 +43,7 @@ class RicPolylineTargetsPickEventHandler;
class RimEclipseCase;
class RimFaultInView;
class RimPolylineTarget;
class RimTimeStepFilter;
class RivFaultReactivationModelPartMgr;
class RigBasicPlane;
class RigFaultReactivationModel;
@ -54,6 +58,8 @@ class RimFaultReactivationModel : public RimCheckableNamedObject, public RimPoly
{
CAF_PDM_HEADER_INIT;
using TimeStepFilterEnum = caf::AppEnum<RimTimeStepFilter::TimeStepFilterTypeEnum>;
public:
RimFaultReactivationModel();
~RimFaultReactivationModel() override;
@ -86,9 +92,19 @@ public:
cvf::ref<RigFaultReactivationModel> model() const;
bool showModel() const;
bool extractModelData();
QString baseDir() const;
void setBaseDir( QString path );
std::vector<QDateTime> selectedTimeSteps() const;
QStringList commandParameters() const;
QString outputOdbFilename() const;
QString inputFilename() const;
void updateTimeSteps();
protected:
caf::PdmFieldHandle* userDescriptionField() override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
@ -101,6 +117,8 @@ protected:
void initAfterRead() override;
QString baseFilename() const;
private:
std::shared_ptr<RicPolylineTargetsPickEventHandler> m_pickTargetsEventHandler;
@ -133,4 +151,9 @@ private:
cvf::ref<RigBasicPlane> m_faultPlane;
cvf::ref<RigFaultReactivationModel> m_modelPlane;
caf::PdmField<TimeStepFilterEnum> m_timeStepFilter;
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
std::vector<QDateTime> m_availableTimeSteps;
};

View File

@ -186,3 +186,14 @@ void RimFaultReactivationModelCollection::appendPartsToModel( Rim3dView*
model->updateBoundingBoxesRecursive();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationModelCollection::syncTimeSteps()
{
for ( auto& frm : m_models )
{
frm->updateTimeSteps();
}
}

View File

@ -65,6 +65,8 @@ public:
caf::DisplayCoordTransform* transform,
const cvf::BoundingBox& boundingBox );
void syncTimeSteps();
protected:
caf::PdmFieldHandle* userDescriptionField() override;

View File

@ -83,6 +83,7 @@
#include "RimGeoMechCellColors.h"
#include "RimGeoMechContourMapView.h"
#include "RimGeoMechContourMapViewCollection.h"
#include "RimGeoMechModels.h"
#include "RimGeoMechPropertyFilter.h"
#include "RimGeoMechPropertyFilterCollection.h"
#include "RimGeoMechView.h"
@ -271,6 +272,11 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder << "Separator";
menuBuilder << "RicNewStatisticsCaseFeature";
}
else if ( dynamic_cast<RimGeoMechModels*>( firstUiItem ) )
{
menuBuilder << "RicImportGeoMechCaseFeature";
menuBuilder << "Separator";
}
else if ( dynamic_cast<RimEclipseStatisticsCase*>( firstUiItem ) )
{
menuBuilder << "RicNewViewFeature";
@ -474,6 +480,9 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
}
else if ( dynamic_cast<RimFaultReactivationModel*>( firstUiItem ) )
{
menuBuilder << "RicRunFaultReactModelingFeature";
menuBuilder << "Separator";
menuBuilder << "RicShowFaultReactModelFeature";
menuBuilder << "RicExportInpFileFeature";
}
else if ( dynamic_cast<RimPressureTable*>( firstUiItem ) )

View File

@ -1115,6 +1115,8 @@ void RimEclipseView::onLoadDataAndUpdate()
m_wellMeasurementCollection->syncWithChangesInWellMeasurementCollection();
m_faultReactivationModelCollection->syncTimeSteps();
scheduleCreateDisplayModelAndRedraw();
}

View File

@ -18,6 +18,7 @@
#include "RimTimeStepFilter.h"
#include "RiaPreferences.h"
#include "RiaQDateTimeTools.h"
#include "RifReaderEclipseOutput.h"
@ -479,3 +480,62 @@ bool RimTimeStepFilter::readOnlyLastFrame() const
{
return m_readOnlyLastFrame;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTimeStepFilter::timeStepOptions( QList<caf::PdmOptionItemInfo>& options,
const caf::PdmFieldHandle* timestepField,
std::vector<QDateTime> availableTimeSteps,
std::vector<QDateTime> selectedTimeSteps,
RimTimeStepFilter::TimeStepFilterTypeEnum filterType )
{
if ( availableTimeSteps.empty() ) return;
std::set<QDateTime> currentlySelectedTimeSteps( selectedTimeSteps.begin(), selectedTimeSteps.end() );
std::set<int> currentlySelectedTimeStepIndices;
std::vector<QDateTime> allDateTimes;
for ( auto& dateTime : availableTimeSteps )
{
if ( currentlySelectedTimeSteps.count( dateTime ) )
{
currentlySelectedTimeStepIndices.insert( (int)allDateTimes.size() );
}
allDateTimes.push_back( dateTime );
}
std::vector<int> filteredTimeStepIndices =
RimTimeStepFilter::filteredTimeStepIndices( allDateTimes, 0, (int)allDateTimes.size() - 1, filterType, 1 );
// Add existing time steps to list of options to avoid removing them when changing filter.
filteredTimeStepIndices.insert( filteredTimeStepIndices.end(),
currentlySelectedTimeStepIndices.begin(),
currentlySelectedTimeStepIndices.end() );
std::sort( filteredTimeStepIndices.begin(), filteredTimeStepIndices.end() );
filteredTimeStepIndices.erase( std::unique( filteredTimeStepIndices.begin(), filteredTimeStepIndices.end() ),
filteredTimeStepIndices.end() );
QString dateFormatString = RiaQDateTimeTools::dateFormatString( RiaPreferences::current()->dateFormat(),
RiaDefines::DateFormatComponents::DATE_FORMAT_YEAR_MONTH_DAY );
QString timeFormatString = RiaQDateTimeTools::timeFormatString( RiaPreferences::current()->timeFormat(),
RiaDefines::TimeFormatComponents::TIME_FORMAT_HOUR_MINUTE );
QString dateTimeFormatString = QString( "%1 %2" ).arg( dateFormatString ).arg( timeFormatString );
bool showTime = ( filterType == RimTimeStepFilter::TS_ALL ) || ( filterType == RimTimeStepFilter::TS_INTERVAL_DAYS );
for ( auto timeStepIndex : filteredTimeStepIndices )
{
QDateTime dateTime = allDateTimes[timeStepIndex];
if ( showTime && dateTime.time() != QTime( 0, 0, 0 ) )
{
options.push_back(
caf::PdmOptionItemInfo( RiaQDateTimeTools::toStringUsingApplicationLocale( dateTime, dateTimeFormatString ), dateTime ) );
}
else
{
options.push_back(
caf::PdmOptionItemInfo( RiaQDateTimeTools::toStringUsingApplicationLocale( dateTime, dateFormatString ), dateTime ) );
}
}
}

View File

@ -63,14 +63,21 @@ public:
void setReadOnlyLastFrame( bool onlyLast );
bool readOnlyLastFrame() const;
std::vector<std::pair<QString, QDateTime>> allTimeSteps() const;
static void timeStepOptions( QList<caf::PdmOptionItemInfo>& options,
const caf::PdmFieldHandle* timestepField,
std::vector<QDateTime> availableTimeSteps,
std::vector<QDateTime> selectedTimeSteps,
TimeStepFilterTypeEnum filterType );
protected:
void initAfterRead() override;
private:
static QDateTime incrementDateTime( const QDateTime& dateTime, TimeStepFilterTypeEnum filterType, int interval );
std::vector<std::pair<QString, QDateTime>> allTimeSteps() const;
std::vector<int> filteredTimeStepIndicesFromUi() const;
std::vector<int> filteredTimeStepIndicesFromUi() const;
void updateFieldVisibility();
RimEclipseResultCase* parentEclipseResultCase() const;

View File

@ -198,16 +198,16 @@ void RigGriddedPart3d::generateGeometry( std::vector<cvf::Vec3d> inputPoints,
{
for ( int t = 0; t < nThicknessCells; t++, elementIdx++ )
{
m_elementIndices[elementIdx].push_back( t + i );
m_elementIndices[elementIdx].push_back( t + i + nThicknessOff );
m_elementIndices[elementIdx].push_back( t + i + nThicknessOff + 1 );
m_elementIndices[elementIdx].push_back( t + i + 1 );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i + nThicknessOff );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i + nThicknessOff + 1 );
m_elementIndices[elementIdx].push_back( t + nextLayerIdxOff + i + 1 );
m_elementIndices[elementIdx].push_back( t + i );
m_elementIndices[elementIdx].push_back( t + i + nThicknessOff );
m_elementIndices[elementIdx].push_back( t + i + nThicknessOff + 1 );
m_elementIndices[elementIdx].push_back( t + i + 1 );
if ( layer == 0 )
{
m_boundaryElements[Boundary::Bottom].push_back( elementIdx );