Merge branch 'dev' into sigurdp/vizfwk-qopenglwidget

This commit is contained in:
Sigurd Pettersen 2024-01-19 00:11:22 +01:00
commit a0a4e2516c
47 changed files with 1744 additions and 304 deletions

3
.gitmodules vendored
View File

@ -25,3 +25,6 @@
[submodule "ThirdParty/qtadvanceddocking"]
path = ThirdParty/qtadvanceddocking
url = https://github.com/CeetronSolutions/qtadvanceddocking.git
[submodule "ThirdParty/spdlog"]
path = ThirdParty/spdlog
url = https://github.com/gabime/spdlog.git

View File

@ -398,11 +398,7 @@ foreach(riFileName ${RI_FILENAMES})
$<TARGET_FILE_DIR:ResInsightDummyTarget>
)
endforeach()
add_custom_target(
PreBuildFileCopy
COMMENT "PreBuildFileCopy step: copy runtime files into build folder"
${copyCommands}
)
add_custom_target(PreBuildFileCopy ${copyCommands})
set_property(TARGET PreBuildFileCopy PROPERTY FOLDER "FileCopyTargets")
# Make ResInsight depend on the prebuild target.

View File

@ -17,7 +17,6 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiaArgumentParser.h"
#include "RiaLogging.h"
#include "RiaMainTools.h"
#ifdef ENABLE_GRPC
@ -72,8 +71,6 @@ int main( int argc, char* argv[] )
return 1;
}
#endif
// Global initialization
RiaLogging::loggerInstance()->setLevel( int( RILogLevel::RI_LL_DEBUG ) );
// Create feature manager before the application object is created
RiaMainTools::initializeSingletons();

View File

@ -103,8 +103,9 @@ void RiaConsoleApplication::initialize()
RiaApplication::initialize();
RiaLogging::setLoggerInstance( std::make_unique<RiaStdOutLogger>() );
RiaLogging::loggerInstance()->setLevel( int( RiaLogging::logLevelBasedOnPreferences() ) );
auto logger = std::make_unique<RiaStdOutLogger>();
logger->setLevel( int( RiaLogging::logLevelBasedOnPreferences() ) );
RiaLogging::appendLoggerInstance( std::move( logger ) );
m_socketServer = new RiaSocketServer( this );
}

View File

@ -23,6 +23,7 @@
#include "RiaArgumentParser.h"
#include "RiaBaseDefs.h"
#include "RiaDefines.h"
#include "RiaFileLogger.h"
#include "RiaFilePathTools.h"
#include "RiaFontCache.h"
#include "RiaImportEclipseCaseTools.h"
@ -432,9 +433,18 @@ void RiaGuiApplication::initialize()
auto logger = std::make_unique<RiuMessagePanelLogger>();
logger->addMessagePanel( m_mainWindow->messagePanel() );
logger->addMessagePanel( m_mainPlotWindow->messagePanel() );
RiaLogging::setLoggerInstance( std::move( logger ) );
logger->setLevel( int( RiaLogging::logLevelBasedOnPreferences() ) );
RiaLogging::loggerInstance()->setLevel( int( RiaLogging::logLevelBasedOnPreferences() ) );
RiaLogging::appendLoggerInstance( std::move( logger ) );
auto filename = RiaPreferences::current()->loggerFilename();
if ( !filename.isEmpty() )
{
auto fileLogger = std::make_unique<RiaFileLogger>( filename.toStdString() );
fileLogger->setLevel( int( RiaLogging::logLevelBasedOnPreferences() ) );
RiaLogging::appendLoggerInstance( std::move( fileLogger ) );
}
}
m_socketServer = new RiaSocketServer( this );
}
@ -501,7 +511,7 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments( gsl::not_n
auto stdLogger = std::make_unique<RiaStdOutLogger>();
stdLogger->setLevel( int( RILogLevel::RI_LL_DEBUG ) );
RiaLogging::setLoggerInstance( std::move( stdLogger ) );
RiaLogging::appendLoggerInstance( std::move( stdLogger ) );
RiaRegressionTestRunner::instance()->executeRegressionTests( regressionTestPath, QStringList() );
return ApplicationStatus::EXIT_COMPLETED;
@ -964,10 +974,14 @@ void RiaGuiApplication::createMainWindow()
m_mainWindow->showWindow();
// if there is an existing logger, reconnect to it
auto logger = dynamic_cast<RiuMessagePanelLogger*>( RiaLogging::loggerInstance() );
if ( logger )
for ( auto logger : RiaLogging::loggerInstances() )
{
logger->addMessagePanel( m_mainWindow->messagePanel() );
auto messagePanelLogger = dynamic_cast<RiuMessagePanelLogger*>( logger );
if ( messagePanelLogger )
{
messagePanelLogger->addMessagePanel( m_mainWindow->messagePanel() );
}
}
}

View File

@ -34,6 +34,7 @@
#include "cafPdmFieldCvfColor.h"
#include "cafPdmSettings.h"
#include "cafPdmUiCheckBoxAndTextEditor.h"
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiFieldHandle.h"
@ -125,6 +126,18 @@ RiaPreferences::RiaPreferences()
m_pythonExecutable.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
CAF_PDM_InitField( &showPythonDebugInfo, "pythonDebugInfo", false, "Show Python Debug Info" );
auto defaultFilename = QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation );
if ( defaultFilename.isEmpty() )
{
defaultFilename = QStandardPaths::writableLocation( QStandardPaths::HomeLocation );
}
defaultFilename += "/ResInsight.log";
CAF_PDM_InitField( &m_loggerFilename, "loggerFilename", std::make_pair( false, defaultFilename ), "Logging To File" );
m_loggerFilename.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxAndTextEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_loggerFlushInterval, "loggerFlushInterval", 500, "Logging Flush Interval [ms]" );
CAF_PDM_InitField( &ssihubAddress, "ssihubAddress", QString( "http://" ), "SSIHUB Address" );
ssihubAddress.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
@ -461,6 +474,11 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
caf::PdmUiGroup* otherGroup = uiOrdering.addNewGroup( "Other" );
otherGroup->add( &m_gridCalculationExpressionFolder );
otherGroup->add( &m_summaryCalculationExpressionFolder );
caf::PdmUiGroup* loggingGroup = uiOrdering.addNewGroup( "Logging" );
loggingGroup->add( &m_loggerFilename );
loggingGroup->add( &m_loggerFlushInterval );
m_loggerFlushInterval.uiCapability()->setUiReadOnly( !m_loggerFilename().first );
}
else if ( RiaApplication::enableDevelopmentFeatures() && uiConfigName == RiaPreferences::tabNameSystem() )
{
@ -932,6 +950,27 @@ QString RiaPreferences::octaveExecutable() const
return m_octaveExecutable().trimmed();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaPreferences::loggerFilename() const
{
if ( m_loggerFilename().first )
{
return m_loggerFilename().second;
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiaPreferences::loggerFlushInterval() const
{
return m_loggerFlushInterval();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -117,6 +117,9 @@ public:
QString pythonExecutable() const;
QString octaveExecutable() const;
QString loggerFilename() const;
int loggerFlushInterval() const;
RiaPreferencesGeoMech* geoMechPreferences() const;
RiaPreferencesSummary* summaryPreferences() const;
RiaPreferencesSystem* systemPreferences() const;
@ -203,6 +206,10 @@ private:
caf::PdmField<QString> m_octaveExecutable;
caf::PdmField<QString> m_pythonExecutable;
// Logging
caf::PdmField<std::pair<bool, QString>> m_loggerFilename;
caf::PdmField<int> m_loggerFlushInterval;
// Surface Import
caf::PdmField<double> m_surfaceImportResamplingDistance;

View File

@ -53,6 +53,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaOpenMPTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaNumericalTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTextTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaFileLogger.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -103,6 +104,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaOpenMPTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaNumericalTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTextTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaFileLogger.cpp
)
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})

View File

@ -0,0 +1,152 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 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 "RiaFileLogger.h"
#include "RiaPreferences.h"
#include "spdlog/logger.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/spdlog.h"
class RiaFileLogger::Impl
{
public:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Impl( const std::string& fileName )
{
try
{
m_spdlogger = spdlog::basic_logger_mt( "basic_logger", fileName );
auto flushInterval = RiaPreferences::current()->loggerFlushInterval();
spdlog::flush_every( std::chrono::milliseconds( flushInterval ) );
}
catch ( ... )
{
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void log( const std::string& message )
{
if ( m_spdlogger ) m_spdlogger->info( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void info( const std::string& message )
{
if ( m_spdlogger ) m_spdlogger->info( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void debug( const std::string& message )
{
if ( m_spdlogger ) m_spdlogger->debug( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void error( const std::string& message )
{
if ( m_spdlogger ) m_spdlogger->error( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void warning( const std::string& message )
{
if ( m_spdlogger ) m_spdlogger->warn( message );
}
private:
std::shared_ptr<spdlog::logger> m_spdlogger;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaFileLogger::RiaFileLogger( const std::string& filename )
: m_impl( new Impl( filename ) )
, m_logLevel( int( RILogLevel::RI_LL_DEBUG ) )
{
}
//--------------------------------------------------------------------------------------------------
/// The destructor must be located in the cpp file after the definition of RiaFileLogger::Impl to make sure the Impl class is defined when
/// the destructor of std::unique_ptr<Impl> is called
//--------------------------------------------------------------------------------------------------
RiaFileLogger::~RiaFileLogger() = default;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiaFileLogger::level() const
{
return m_logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaFileLogger::setLevel( int logLevel )
{
m_logLevel = logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaFileLogger::error( const char* message )
{
m_impl->error( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaFileLogger::warning( const char* message )
{
m_impl->warning( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaFileLogger::info( const char* message )
{
m_impl->info( message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaFileLogger::debug( const char* message )
{
m_impl->debug( message );
}

View File

@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RiaLogging.h"
//==================================================================================================
//
//==================================================================================================
class RiaFileLogger : public RiaLogger
{
public:
explicit RiaFileLogger( const std::string& filename );
~RiaFileLogger() override;
int level() const override;
void setLevel( int logLevel ) override;
void error( const char* message ) override;
void warning( const char* message ) override;
void info( const char* message ) override;
void debug( const char* message ) override;
private:
int m_logLevel;
class Impl;
std::unique_ptr<Impl> m_impl;
};

View File

@ -169,22 +169,28 @@ void RiaDefaultConsoleLogger::writeToConsole( const std::string& str )
//
//==================================================================================================
std::unique_ptr<RiaLogger> RiaLogging::sm_logger = std::make_unique<RiaDefaultConsoleLogger>();
std::vector<std::unique_ptr<RiaLogger>> RiaLogging::sm_logger;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaLogger* RiaLogging::loggerInstance()
std::vector<RiaLogger*> RiaLogging::loggerInstances()
{
return sm_logger.get();
std::vector<RiaLogger*> loggerInstances;
for ( auto& logger : sm_logger )
{
loggerInstances.push_back( logger.get() );
}
return loggerInstances;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaLogging::setLoggerInstance( std::unique_ptr<RiaLogger> loggerInstance )
void RiaLogging::appendLoggerInstance( std::unique_ptr<RiaLogger> loggerInstance )
{
sm_logger = std::move( loggerInstance );
sm_logger.push_back( std::move( loggerInstance ) );
}
//--------------------------------------------------------------------------------------------------
@ -202,10 +208,13 @@ RILogLevel RiaLogging::logLevelBasedOnPreferences()
//--------------------------------------------------------------------------------------------------
void RiaLogging::error( const QString& message )
{
if ( sm_logger && sm_logger->level() >= int( RILogLevel::RI_LL_ERROR ) )
for ( const auto& logger : sm_logger )
{
if ( logger && logger->level() >= int( RILogLevel::RI_LL_ERROR ) )
{
#pragma omp critical( critical_section_logging )
sm_logger->error( message.toLatin1().constData() );
logger->error( message.toLatin1().constData() );
}
}
}
@ -214,10 +223,13 @@ void RiaLogging::error( const QString& message )
//--------------------------------------------------------------------------------------------------
void RiaLogging::warning( const QString& message )
{
if ( sm_logger && sm_logger->level() >= int( RILogLevel::RI_LL_WARNING ) )
for ( const auto& logger : sm_logger )
{
if ( logger && logger->level() >= int( RILogLevel::RI_LL_WARNING ) )
{
#pragma omp critical( critical_section_logging )
sm_logger->warning( message.toLatin1().constData() );
logger->warning( message.toLatin1().constData() );
}
}
}
@ -226,10 +238,13 @@ void RiaLogging::warning( const QString& message )
//--------------------------------------------------------------------------------------------------
void RiaLogging::info( const QString& message )
{
if ( sm_logger && sm_logger->level() >= int( RILogLevel::RI_LL_INFO ) )
for ( const auto& logger : sm_logger )
{
if ( logger && logger->level() >= int( RILogLevel::RI_LL_INFO ) )
{
#pragma omp critical( critical_section_logging )
sm_logger->info( message.toLatin1().constData() );
logger->info( message.toLatin1().constData() );
}
}
}
@ -238,10 +253,13 @@ void RiaLogging::info( const QString& message )
//--------------------------------------------------------------------------------------------------
void RiaLogging::debug( const QString& message )
{
if ( sm_logger && sm_logger->level() >= int( RILogLevel::RI_LL_DEBUG ) )
for ( const auto& logger : sm_logger )
{
if ( logger && logger->level() >= int( RILogLevel::RI_LL_DEBUG ) )
{
#pragma omp critical( critical_section_logging )
sm_logger->debug( message.toLatin1().constData() );
logger->debug( message.toLatin1().constData() );
}
}
}

View File

@ -60,8 +60,8 @@ public:
class RiaLogging
{
public:
static RiaLogger* loggerInstance();
static void setLoggerInstance( std::unique_ptr<RiaLogger> loggerInstance );
static std::vector<RiaLogger*> loggerInstances();
static void appendLoggerInstance( std::unique_ptr<RiaLogger> loggerInstance );
static RILogLevel logLevelBasedOnPreferences();
@ -73,7 +73,7 @@ public:
static void errorInMessageBox( QWidget* parent, const QString& title, const QString& text );
private:
static std::unique_ptr<RiaLogger> sm_logger;
static std::vector<std::unique_ptr<RiaLogger>> sm_logger;
};
//==================================================================================================

View File

@ -40,7 +40,9 @@
#include "opm/io/eclipse/ERst.hpp"
#include "opm/io/eclipse/RestartFileView.hpp"
#include "opm/io/eclipse/rst/state.hpp"
#include "opm/output/eclipse/VectorItems/doubhead.hpp"
#include "opm/output/eclipse/VectorItems/group.hpp"
#include "opm/output/eclipse/VectorItems/intehead.hpp"
#include "opm/output/eclipse/VectorItems/well.hpp"
using namespace Opm;
@ -434,28 +436,24 @@ void RifReaderOpmCommon::readWellCells( std::shared_ptr<EclIO::ERst> restartFil
//--------------------------------------------------------------------------------------------------
std::vector<RifReaderOpmCommon::TimeDataFile> RifReaderOpmCommon::readTimeSteps( std::shared_ptr<EclIO::ERst> restartFile )
{
// It is required to create a deck as the input parameter to runspec. The default() initialization of the runspec keyword does not
// initialize the object as expected.
Deck deck;
Runspec runspec( deck );
Parser parser( false );
std::vector<RifReaderOpmCommon::TimeDataFile> reportTimeData;
try
{
namespace VI = Opm::RestartIO::Helpers::VectorItems;
for ( auto seqNumber : restartFile->listOfReportStepNumbers() )
{
auto fileView = std::make_shared<EclIO::RestartFileView>( restartFile, seqNumber );
auto state = RestartIO::RstState::load( fileView, runspec, parser );
auto header = state.header;
auto intehead = fileView->intehead();
int year = header.year;
int month = header.month;
int day = header.mday;
auto year = intehead[VI::intehead::YEAR];
auto month = intehead[VI::intehead::MONTH];
auto day = intehead[VI::intehead::DAY];
double daySinceSimStart = header.next_timestep1;
auto doubhead = fileView->doubhead();
auto daySinceSimStart = doubhead[VI::doubhead::TsInit];
reportTimeData.emplace_back(
TimeDataFile{ .sequenceNumber = seqNumber, .year = year, .month = month, .day = day, .simulationTimeFromStart = daySinceSimStart } );

View File

@ -141,6 +141,7 @@ RimPolygonFilter::RimPolygonFilter()
CAF_PDM_InitField( &m_showLines, "ShowLines", true, "Show Lines" );
CAF_PDM_InitField( &m_showSpheres, "ShowSpheres", false, "Show Spheres" );
CAF_PDM_InitField( &m_closePolygon, "ClosePolygon", true, "Closed Polygon" );
CAF_PDM_InitField( &m_lineThickness, "LineThickness", 3, "Line Thickness" );
CAF_PDM_InitField( &m_sphereRadiusFactor, "SphereRadiusFactor", 0.15, "Sphere Radius Factor" );
@ -359,18 +360,19 @@ void RimPolygonFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin
auto group = uiOrdering.addNewGroup( "General" );
group->add( &m_filterMode );
group->add( &m_enableFiltering );
group->add( &m_showLines );
group->add( &m_showSpheres );
group->add( &m_closePolygon );
auto group1 = uiOrdering.addNewGroup( "Polygon Selection" );
group1->add( &m_polyFilterMode );
group1->add( &m_polyIncludeType );
if ( m_closePolygon() ) group1->add( &m_polyIncludeType );
group1->add( &m_targets );
group1->add( &m_enablePicking );
m_polyIncludeType.uiCapability()->setUiName( "Cells to " + modeString() );
auto group2 = uiOrdering.addNewGroup( "Appearance" );
group2->add( &m_showLines );
group2->add( &m_showSpheres );
if ( m_showLines )
{
group2->add( &m_lineThickness );
@ -399,6 +401,16 @@ void RimPolygonFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin
{
objField->uiCapability()->setUiReadOnly( readOnlyState );
}
if ( !m_closePolygon() )
{
m_polyFilterMode = RimPolygonFilter::PolygonFilterModeType::INDEX_K;
m_polyFilterMode.uiCapability()->setUiReadOnly( true );
}
else
{
m_polyFilterMode.uiCapability()->setUiReadOnly( readOnlyState );
}
}
//--------------------------------------------------------------------------------------------------
@ -527,6 +539,9 @@ bool RimPolygonFilter::cellInsidePolygon2D( cvf::Vec3d center, std::array<cvf::V
return bInside;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& points, const RigGridBase* grid )
{
// we should look in depth using Z coordinate
@ -568,9 +583,10 @@ void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>&
const int gIdx = static_cast<int>( grid->gridIndex() );
std::list<size_t> foundCells;
const bool closedPolygon = m_closePolygon();
#pragma omp parallel for
// find all cells in the K layer that matches the polygon
#pragma omp parallel for
for ( int i = 0; i < (int)grid->cellCountI(); i++ )
{
for ( size_t j = 0; j < grid->cellCountJ(); j++ )
@ -584,11 +600,23 @@ void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>&
std::array<cvf::Vec3d, 8> hexCorners;
grid->cellCornerVertices( cellIdx, hexCorners.data() );
// check if the polygon includes the cell
if ( cellInsidePolygon2D( cell.center(), hexCorners, points ) )
if ( closedPolygon )
{
// check if the polygon includes the cell
if ( cellInsidePolygon2D( cell.center(), hexCorners, points ) )
{
#pragma omp critical
foundCells.push_back( cellIdx );
foundCells.push_back( cellIdx );
}
}
else
{
// check if the polyline touches the top face of the cell
if ( RigCellGeometryTools::polylineIntersectsCellNegK2D( points, hexCorners ) )
{
#pragma omp critical
foundCells.push_back( cellIdx );
}
}
}
}
@ -624,6 +652,8 @@ void RimPolygonFilter::updateCellsForEclipse( const std::vector<cvf::Vec3d>& poi
if ( m_polyFilterMode == PolygonFilterModeType::DEPTH_Z )
{
if ( !m_closePolygon() ) return;
for ( size_t gridIndex = 0; gridIndex < data->gridCount(); gridIndex++ )
{
auto grid = data->grid( gridIndex );
@ -690,6 +720,8 @@ void RimPolygonFilter::updateCellsDepthGeoMech( const std::vector<cvf::Vec3d>& p
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::updateCellsKIndexGeoMech( const std::vector<cvf::Vec3d>& points, const RigFemPartGrid* grid, int partId )
{
const bool closedPolygon = m_closePolygon();
// we need to find the K layer we hit with the first point
size_t nk;
// move the point a bit downwards to make sure it is inside something
@ -753,11 +785,23 @@ void RimPolygonFilter::updateCellsKIndexGeoMech( const std::vector<cvf::Vec3d>&
grid->cellCornerVertices( cellIdx, hexCorners.data() );
cvf::Vec3d center = grid->cellCentroid( cellIdx );
// check if the polygon includes the cell
if ( cellInsidePolygon2D( center, hexCorners, points ) )
if ( closedPolygon )
{
// check if the polygon includes the cell
if ( cellInsidePolygon2D( center, hexCorners, points ) )
{
#pragma omp critical
foundCells.push_back( cellIdx );
foundCells.push_back( cellIdx );
}
}
else
{
// check if the polyline touches the top face of the cell
if ( RigCellGeometryTools::polylineIntersectsCellNegK2D( points, hexCorners ) )
{
#pragma omp critical
foundCells.push_back( cellIdx );
}
}
}
}
@ -795,7 +839,10 @@ void RimPolygonFilter::updateCellsForGeoMech( const std::vector<cvf::Vec3d>& poi
if ( m_polyFilterMode == PolygonFilterModeType::DEPTH_Z )
{
updateCellsDepthGeoMech( points, grid, i );
if ( m_closePolygon() )
{
updateCellsDepthGeoMech( points, grid, i );
}
}
else if ( m_polyFilterMode == PolygonFilterModeType::INDEX_K )
{
@ -823,11 +870,11 @@ void RimPolygonFilter::updateCells()
if ( target->isEnabled() ) points.push_back( target->targetPointXYZ() );
}
// We need at least three points to make a sensible polygon
if ( points.size() < 3 ) return;
// We need at least three points to make a closed polygon, or just 2 for a polyline
if ( ( !m_closePolygon() && ( points.size() < 2 ) ) || ( m_closePolygon() && ( points.size() < 3 ) ) ) return;
// make sure first and last point is the same (req. by polygon methods used later)
points.push_back( points.front() );
// make sure first and last point is the same (req. by closed polygon methods used later)
if ( m_closePolygon() ) points.push_back( points.front() );
RimEclipseCase* eCase = eclipseCase();
RimGeoMechCase* gCase = geoMechCase();
@ -855,7 +902,7 @@ cvf::ref<RigPolyLinesData> RimPolygonFilter::polyLinesData() const
}
pld->setPolyLine( line );
pld->setLineAppearance( m_lineThickness, m_lineColor, true );
pld->setLineAppearance( m_lineThickness, m_lineColor, m_closePolygon );
pld->setSphereAppearance( m_sphereRadiusFactor, m_sphereColor );
pld->setZPlaneLock( m_lockPolygonToPlane, -m_polygonPlaneDepth );

View File

@ -133,6 +133,7 @@ private:
caf::PdmField<bool> m_lockPolygonToPlane;
caf::PdmField<bool> m_enableKFilter;
caf::PdmField<QString> m_kFilterStr;
caf::PdmField<bool> m_closePolygon;
std::shared_ptr<RicPolylineTargetsPickEventHandler> m_pickTargetsEventHandler;

View File

@ -11,6 +11,8 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorTemperature.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorGeoMech.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorStress.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorStressGeoMech.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorStressEclipse.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorWellLogExtraction.h
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationEnums.h
)
@ -28,6 +30,8 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorTemperature.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorGeoMech.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorStress.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorStressGeoMech.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorStressEclipse.cpp
${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccessorWellLogExtraction.cpp
)

View File

@ -35,7 +35,8 @@
#include "RimFaultReactivationDataAccessor.h"
#include "RimFaultReactivationDataAccessorGeoMech.h"
#include "RimFaultReactivationDataAccessorPorePressure.h"
#include "RimFaultReactivationDataAccessorStress.h"
#include "RimFaultReactivationDataAccessorStressEclipse.h"
#include "RimFaultReactivationDataAccessorStressGeoMech.h"
#include "RimFaultReactivationDataAccessorTemperature.h"
#include "RimFaultReactivationDataAccessorVoidRatio.h"
#include "RimFaultReactivationEnums.h"
@ -56,6 +57,14 @@ RimFaultReactivationDataAccess::RimFaultReactivationDataAccess( const RimFaultRe
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorPorePressure>( thecase, porePressureGradient, seabedDepth ) );
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorVoidRatio>( thecase, 0.0001 ) );
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorTemperature>( thecase, topTemperature, seabedDepth ) );
std::vector<RimFaultReactivation::Property> stressProperties = { RimFaultReactivation::Property::StressTop,
RimFaultReactivation::Property::DepthTop,
RimFaultReactivation::Property::StressBottom,
RimFaultReactivation::Property::DepthBottom,
RimFaultReactivation::Property::LateralStressComponentX,
RimFaultReactivation::Property::LateralStressComponentY };
if ( geoMechCase )
{
std::vector<RimFaultReactivation::Property> properties = { RimFaultReactivation::Property::YoungsModulus,
@ -67,16 +76,39 @@ RimFaultReactivationDataAccess::RimFaultReactivationDataAccess( const RimFaultRe
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorGeoMech>( geoMechCase, property ) );
}
std::vector<RimFaultReactivation::Property> stressProperties = { RimFaultReactivation::Property::StressTop,
RimFaultReactivation::Property::DepthTop,
RimFaultReactivation::Property::StressBottom,
RimFaultReactivation::Property::DepthBottom,
RimFaultReactivation::Property::LateralStressComponentX,
RimFaultReactivation::Property::LateralStressComponentY };
for ( auto property : stressProperties )
{
m_accessors.push_back(
std::make_shared<RimFaultReactivationDataAccessorStress>( geoMechCase, property, porePressureGradient, seabedDepth ) );
std::make_shared<RimFaultReactivationDataAccessorStressGeoMech>( geoMechCase, property, porePressureGradient, seabedDepth ) );
}
}
else
{
auto extractDensities = []( const RimFaultReactivationModel& model )
{
std::map<RimFaultReactivation::ElementSets, double> densities;
std::vector<RimFaultReactivation::ElementSets> elementSets = { RimFaultReactivation::ElementSets::OverBurden,
RimFaultReactivation::ElementSets::UnderBurden,
RimFaultReactivation::ElementSets::Reservoir,
RimFaultReactivation::ElementSets::IntraReservoir };
for ( auto e : elementSets )
{
densities[e] = model.materialParameters( e )[2];
}
return densities;
};
std::map<RimFaultReactivation::ElementSets, double> densities = extractDensities( model );
for ( auto property : stressProperties )
{
m_accessors.push_back( std::make_shared<RimFaultReactivationDataAccessorStressEclipse>( thecase,
property,
porePressureGradient,
seabedDepth,
model.waterDensity(),
model.lateralStressCoefficientX(),
model.lateralStressCoefficientY(),
densities ) );
}
}
}

View File

@ -30,7 +30,6 @@
#include "RigGeoMechCaseData.h"
#include "RigGeoMechWellLogExtractor.h"
#include "RigGriddedPart3d.h"
#include "RigResultAccessorFactory.h"
#include "RigWellPath.h"
#include "RimFaultReactivationDataAccessorWellLogExtraction.h"
@ -46,16 +45,13 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationDataAccessorStress::RimFaultReactivationDataAccessorStress( RimGeoMechCase* geoMechCase,
RimFaultReactivation::Property property,
RimFaultReactivationDataAccessorStress::RimFaultReactivationDataAccessorStress( RimFaultReactivation::Property property,
double gradient,
double seabedDepth )
: m_geoMechCase( geoMechCase )
, m_property( property )
: m_property( property )
, m_gradient( gradient )
, m_seabedDepth( seabedDepth )
{
m_geoMechCaseData = geoMechCase->geoMechData();
}
//--------------------------------------------------------------------------------------------------
@ -65,69 +61,6 @@ RimFaultReactivationDataAccessorStress::~RimFaultReactivationDataAccessorStress(
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationDataAccessorStress::updateResultAccessor()
{
const int partIndex = 0;
auto loadFrameLambda = [&]( auto femParts, RigFemResultAddress addr, int timeStepIndex ) -> RigFemScalarResultFrames*
{
auto result = femParts->findOrLoadScalarResult( partIndex, addr );
int frameIndex = result->frameCount( timeStepIndex ) - 1;
if ( result->frameData( timeStepIndex, frameIndex ).empty() )
{
return nullptr;
}
return result;
};
auto femParts = m_geoMechCaseData->femPartResults();
m_femPart = femParts->parts()->part( partIndex );
int timeStepIndex = 0;
m_s33Frames = loadFrameLambda( femParts, getResultAddress( "ST", "S33" ), timeStepIndex );
m_s11Frames = loadFrameLambda( femParts, getResultAddress( "ST", "S11" ), timeStepIndex );
m_s22Frames = loadFrameLambda( femParts, getResultAddress( "ST", "S22" ), timeStepIndex );
auto [faultTopPosition, faultBottomPosition] = m_model->faultTopBottom();
auto faultNormal = m_model->faultNormal();
double distanceFromFault = 1.0;
RigFemPartCollection* geoMechPartCollection = m_geoMechCaseData->femParts();
std::string errorName = "fault reactivation data access";
{
std::vector<cvf::Vec3d> wellPoints =
RimFaultReactivationDataAccessorWellLogExtraction::generateWellPoints( faultTopPosition,
faultBottomPosition,
m_seabedDepth,
faultNormal * distanceFromFault );
m_faceAWellPath = new RigWellPath( wellPoints, RimFaultReactivationDataAccessorWellLogExtraction::generateMds( wellPoints ) );
m_partIndexA = geoMechPartCollection->getPartIndexFromPoint( wellPoints[1] );
m_extractorA = new RigGeoMechWellLogExtractor( m_geoMechCaseData, partIndex, m_faceAWellPath.p(), errorName );
}
{
std::vector<cvf::Vec3d> wellPoints =
RimFaultReactivationDataAccessorWellLogExtraction::generateWellPoints( faultTopPosition,
faultBottomPosition,
m_seabedDepth,
-faultNormal * distanceFromFault );
m_faceBWellPath = new RigWellPath( wellPoints, RimFaultReactivationDataAccessorWellLogExtraction::generateMds( wellPoints ) );
m_partIndexB = geoMechPartCollection->getPartIndexFromPoint( wellPoints[1] );
m_extractorB = new RigGeoMechWellLogExtractor( m_geoMechCaseData, partIndex, m_faceBWellPath.p(), errorName );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemResultAddress RimFaultReactivationDataAccessorStress::getResultAddress( const std::string& fieldName, const std::string& componentName )
{
return RigFemResultAddress( RIG_ELEMENT_NODAL, fieldName, componentName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -146,36 +79,26 @@ double RimFaultReactivationDataAccessorStress::valueAtPosition( const cvf::Vec3d
double bottomDepth,
size_t elementIndex ) const
{
if ( !m_s11Frames || !m_s22Frames || !m_s33Frames || !m_femPart ) return std::numeric_limits<double>::infinity();
RimWellIADataAccess iaDataAccess( m_geoMechCase );
int centerElementIdx = iaDataAccess.elementIndex( position );
if ( !isDataAvailable() ) return std::numeric_limits<double>::infinity();
cvf::Vec3d topPosition( position.x(), position.y(), topDepth );
int topElementIdx = iaDataAccess.elementIndex( topPosition );
cvf::Vec3d bottomPosition( position.x(), position.y(), bottomDepth );
int bottomElementIdx = iaDataAccess.elementIndex( bottomPosition );
if ( centerElementIdx != -1 && topElementIdx != -1 && bottomElementIdx != -1 )
if ( isPositionValid( position, topPosition, bottomPosition, gridPart ) )
{
int timeStepIndex = 0;
int frameIndex = m_s33Frames->frameCount( timeStepIndex ) - 1;
const std::vector<float>& s33Data = m_s33Frames->frameData( timeStepIndex, frameIndex );
if ( m_property == RimFaultReactivation::Property::StressTop )
{
auto [porBar, extractionPos] = calculatePorBar( topPosition, m_gradient, timeStepIndex, frameIndex );
auto [porBar, extractionPos] = calculatePorBar( topPosition, m_gradient, gridPart );
if ( std::isinf( porBar ) ) return porBar;
double s33 = interpolatedResultValue( iaDataAccess, m_femPart, extractionPos, s33Data );
return RiaEclipseUnitTools::barToPascal( s33 - porBar );
double s33 = extractStressValue( StressType::S33, extractionPos, gridPart );
return -RiaEclipseUnitTools::barToPascal( s33 - porBar );
}
else if ( m_property == RimFaultReactivation::Property::StressBottom )
{
auto [porBar, extractionPos] = calculatePorBar( bottomPosition, m_gradient, timeStepIndex, frameIndex );
auto [porBar, extractionPos] = calculatePorBar( bottomPosition, m_gradient, gridPart );
if ( std::isinf( porBar ) ) return porBar;
double s33 = interpolatedResultValue( iaDataAccess, m_femPart, extractionPos, s33Data );
return RiaEclipseUnitTools::barToPascal( s33 - porBar );
double s33 = extractStressValue( StressType::S33, extractionPos, gridPart );
return -RiaEclipseUnitTools::barToPascal( s33 - porBar );
}
else if ( m_property == RimFaultReactivation::Property::DepthTop )
{
@ -187,23 +110,11 @@ double RimFaultReactivationDataAccessorStress::valueAtPosition( const cvf::Vec3d
}
else if ( m_property == RimFaultReactivation::Property::LateralStressComponentX )
{
auto [porBar, extractionPos] = calculatePorBar( position, m_gradient, timeStepIndex, frameIndex );
if ( std::isinf( porBar ) ) return porBar;
const std::vector<float>& s11Data = m_s11Frames->frameData( timeStepIndex, frameIndex );
double s11 = interpolatedResultValue( iaDataAccess, m_femPart, extractionPos, s11Data );
double s33 = interpolatedResultValue( iaDataAccess, m_femPart, extractionPos, s33Data );
return ( s11 - porBar ) / ( s33 - porBar );
return lateralStressComponentX( position, gridPart );
}
else if ( m_property == RimFaultReactivation::Property::LateralStressComponentY )
{
auto [porBar, extractionPos] = calculatePorBar( position, m_gradient, timeStepIndex, frameIndex );
if ( std::isinf( porBar ) ) return porBar;
const std::vector<float>& s22Data = m_s22Frames->frameData( timeStepIndex, frameIndex );
double s22 = interpolatedResultValue( iaDataAccess, m_femPart, extractionPos, s22Data );
double s33 = interpolatedResultValue( iaDataAccess, m_femPart, extractionPos, s33Data );
return ( s22 - porBar ) / ( s33 - porBar );
return lateralStressComponentY( position, gridPart );
}
}
@ -213,32 +124,23 @@ double RimFaultReactivationDataAccessorStress::valueAtPosition( const cvf::Vec3d
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationDataAccessorStress::interpolatedResultValue( RimWellIADataAccess& iaDataAccess,
const RigFemPart* femPart,
const cvf::Vec3d& position,
const std::vector<float>& scalarResults ) const
double RimFaultReactivationDataAccessorStress::lateralStressComponentX( const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const
{
return iaDataAccess.interpolatedResultValue( femPart, scalarResults, RIG_ELEMENT_NODAL, position );
auto [porBar, extractionPos] = calculatePorBar( position, m_gradient, gridPart );
if ( std::isinf( porBar ) ) return porBar;
double s11 = extractStressValue( StressType::S11, extractionPos, gridPart );
double s33 = extractStressValue( StressType::S33, extractionPos, gridPart );
return ( s11 - porBar ) / ( s33 - porBar );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, cvf::Vec3d>
RimFaultReactivationDataAccessorStress::calculatePorBar( const cvf::Vec3d& position, double gradient, int timeStepIndex, int frameIndex ) const
double RimFaultReactivationDataAccessorStress::lateralStressComponentY( const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const
{
RigFemPartCollection* partCollection = m_geoMechCaseData->femParts();
cvf::ref<RigGeoMechWellLogExtractor> extractor = m_partIndexA == partCollection->getPartIndexFromPoint( position ) ? m_extractorA
: m_extractorB;
if ( !extractor->valid() )
{
RiaLogging::error( "Invalid extractor when extracting PorBar" );
return { std::numeric_limits<double>::infinity(), cvf::Vec3d::UNDEFINED };
}
RigFemResultAddress resAddr = RigFemAddressDefines::nodalPorBarAddress();
std::vector<double> values;
extractor->curveData( resAddr, timeStepIndex, frameIndex, &values );
return RimFaultReactivationDataAccessorWellLogExtraction::calculatePorBar( extractor->intersections(), values, position, gradient );
auto [porBar, extractionPos] = calculatePorBar( position, m_gradient, gridPart );
if ( std::isinf( porBar ) ) return porBar;
double s22 = extractStressValue( StressType::S22, extractionPos, gridPart );
double s33 = extractStressValue( StressType::S33, extractionPos, gridPart );
return ( s22 - porBar ) / ( s33 - porBar );
}

View File

@ -21,8 +21,6 @@
#include "RimFaultReactivationDataAccessor.h"
#include "RimFaultReactivationEnums.h"
#include "RigFemResultAddress.h"
#include <vector>
#include "cafPdmField.h"
@ -30,17 +28,9 @@
#include "cvfObject.h"
class RigFemPart;
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigGeoMechCaseData;
class RigGriddedPart3d;
class RimGeoMechCase;
class RimWellIADataAccess;
class RimModeledWellPath;
class RigWellPath;
class RigFemPartCollection;
class RigGeoMechWellLogExtractor;
//==================================================================================================
///
@ -49,11 +39,15 @@ class RigGeoMechWellLogExtractor;
class RimFaultReactivationDataAccessorStress : public RimFaultReactivationDataAccessor
{
public:
RimFaultReactivationDataAccessorStress( RimGeoMechCase* geoMechCase,
RimFaultReactivation::Property property,
double gradient,
double seabedDepth );
~RimFaultReactivationDataAccessorStress();
enum class StressType
{
S11,
S22,
S33
};
RimFaultReactivationDataAccessorStress( RimFaultReactivation::Property property, double gradient, double seabedDepth );
virtual ~RimFaultReactivationDataAccessorStress();
bool isMatching( RimFaultReactivation::Property property ) const override;
@ -64,32 +58,23 @@ public:
double bottomDepth = std::numeric_limits<double>::infinity(),
size_t elementIndex = std::numeric_limits<size_t>::max() ) const override;
private:
void updateResultAccessor() override;
protected:
virtual bool isDataAvailable() const = 0;
static RigFemResultAddress getResultAddress( const std::string& fieldName, const std::string& componentName );
virtual double extractStressValue( StressType stressType, const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const = 0;
double interpolatedResultValue( RimWellIADataAccess& iaDataAccess,
const RigFemPart* femPart,
const cvf::Vec3d& position,
const std::vector<float>& scalarResults ) const;
virtual std::pair<double, cvf::Vec3d>
calculatePorBar( const cvf::Vec3d& position, double gradient, RimFaultReactivation::GridPart gridPart ) const = 0;
std::pair<double, cvf::Vec3d> calculatePorBar( const cvf::Vec3d& position, double gradient, int timeStepIndex, int frameIndex ) const;
virtual bool isPositionValid( const cvf::Vec3d& position,
const cvf::Vec3d& topPosition,
const cvf::Vec3d& bottomPosition,
RimFaultReactivation::GridPart gridPart ) const = 0;
virtual double lateralStressComponentX( const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const;
virtual double lateralStressComponentY( const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const;
RimGeoMechCase* m_geoMechCase;
RimFaultReactivation::Property m_property;
double m_gradient;
double m_seabedDepth;
RigGeoMechCaseData* m_geoMechCaseData;
RigFemScalarResultFrames* m_s11Frames;
RigFemScalarResultFrames* m_s22Frames;
RigFemScalarResultFrames* m_s33Frames;
const RigFemPart* m_femPart;
cvf::ref<RigWellPath> m_faceAWellPath;
cvf::ref<RigWellPath> m_faceBWellPath;
int m_partIndexA;
int m_partIndexB;
cvf::ref<RigGeoMechWellLogExtractor> m_extractorA;
cvf::ref<RigGeoMechWellLogExtractor> m_extractorB;
};

View File

@ -0,0 +1,304 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimFaultReactivationDataAccessorStressEclipse.h"
#include "RiaEclipseUnitTools.h"
#include "RiaInterpolationTools.h"
#include "RiaLogging.h"
#include "RiaWellLogUnitTools.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseResultAddress.h"
#include "RigEclipseWellLogExtractor.h"
#include "RigFaultReactivationModel.h"
#include "RigGriddedPart3d.h"
#include "RigResultAccessorFactory.h"
#include "RigWellPath.h"
#include "RimEclipseCase.h"
#include "RimFaultReactivationDataAccessorStress.h"
#include "RimFaultReactivationDataAccessorWellLogExtraction.h"
#include "RimFaultReactivationEnums.h"
#include "cvfObject.h"
#include "cvfVector3.h"
#include <cmath>
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationDataAccessorStressEclipse::RimFaultReactivationDataAccessorStressEclipse(
RimEclipseCase* eclipseCase,
RimFaultReactivation::Property property,
double gradient,
double seabedDepth,
double waterDensity,
double lateralStressComponentX,
double lateralStressComponentY,
const std::map<RimFaultReactivation::ElementSets, double>& densities )
: RimFaultReactivationDataAccessorStress( property, gradient, seabedDepth )
, m_eclipseCase( eclipseCase )
, m_caseData( nullptr )
, m_mainGrid( nullptr )
, m_waterDensity( waterDensity )
, m_lateralStressComponentX( lateralStressComponentX )
, m_lateralStressComponentY( lateralStressComponentY )
, m_densities( densities )
{
if ( m_eclipseCase )
{
m_caseData = m_eclipseCase->eclipseCaseData();
m_mainGrid = m_eclipseCase->mainGrid();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationDataAccessorStressEclipse::~RimFaultReactivationDataAccessorStressEclipse()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationDataAccessorStressEclipse::updateResultAccessor()
{
if ( !m_caseData ) return;
RigEclipseResultAddress resVarAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "PRESSURE" );
m_eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->ensureKnownResultLoaded( resVarAddress );
m_resultAccessor =
RigResultAccessorFactory::createFromResultAddress( m_caseData, 0, RiaDefines::PorosityModelType::MATRIX_MODEL, m_timeStep, resVarAddress );
auto [wellPaths, extractors] =
RimFaultReactivationDataAccessorWellLogExtraction::createEclipseWellPathExtractors( *m_model, *m_caseData, m_seabedDepth );
m_wellPaths = wellPaths;
m_extractors = extractors;
for ( auto [gridPart, wellPath] : m_wellPaths )
{
auto extractor = m_extractors[gridPart];
std::vector<cvf::Vec3d> intersections = extractor->intersections();
addOverburdenAndUnderburdenPoints( intersections, wellPath->wellPathPoints() );
m_stressValues[gridPart] =
integrateVerticalStress( *wellPath.p(), intersections, *m_model, gridPart, m_seabedDepth, m_waterDensity, m_densities );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationDataAccessorStressEclipse::addOverburdenAndUnderburdenPoints( std::vector<cvf::Vec3d>& intersections,
const std::vector<cvf::Vec3d>& wellPathPoints )
{
// Insert points at top of overburden and under underburden
intersections.insert( intersections.begin(), wellPathPoints.front() );
intersections.push_back( wellPathPoints.back() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationDataAccessorStressEclipse::isDataAvailable() const
{
return m_mainGrid != nullptr && m_resultAccessor.notNull();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationDataAccessorStressEclipse::extractStressValue( StressType stressType,
const cvf::Vec3d& position,
RimFaultReactivation::GridPart gridPart ) const
{
CAF_ASSERT( m_extractors.find( gridPart ) != m_extractors.end() );
auto extractor = m_extractors.find( gridPart )->second;
CAF_ASSERT( m_stressValues.find( gridPart ) != m_stressValues.end() );
auto stressValues = m_stressValues.find( gridPart )->second;
CAF_ASSERT( m_wellPaths.find( gridPart ) != m_wellPaths.end() );
auto wellPath = m_wellPaths.find( gridPart )->second;
auto intersections = extractor->intersections();
addOverburdenAndUnderburdenPoints( intersections, wellPath->wellPathPoints() );
CAF_ASSERT( stressValues.size() == intersections.size() );
auto [topIdx, bottomIdx] = RimFaultReactivationDataAccessorWellLogExtraction::findIntersectionsForTvd( intersections, position.z() );
if ( topIdx != -1 && bottomIdx != -1 )
{
double topValue = stressValues[topIdx];
double bottomValue = stressValues[bottomIdx];
if ( !std::isinf( topValue ) && !std::isinf( bottomValue ) )
{
// Interpolate value from the two closest points.
std::vector<double> xs = { intersections[bottomIdx].z(), intersections[topIdx].z() };
std::vector<double> ys = { stressValues[bottomIdx], stressValues[topIdx] };
return RiaEclipseUnitTools::pascalToBar( RiaInterpolationTools::linear( xs, ys, position.z() ) );
}
}
else if ( position.z() <= intersections.back().z() )
{
return RiaEclipseUnitTools::pascalToBar( stressValues.back() );
}
return std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationDataAccessorStressEclipse::isPositionValid( const cvf::Vec3d& position,
const cvf::Vec3d& topPosition,
const cvf::Vec3d& bottomPosition,
RimFaultReactivation::GridPart gridPart ) const
{
auto [porBar, extractionPosition] = calculatePorBar( position, m_gradient, gridPart );
return !std::isinf( porBar ) && extractionPosition != cvf::Vec3d::UNDEFINED;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, cvf::Vec3d> RimFaultReactivationDataAccessorStressEclipse::calculatePorBar( const cvf::Vec3d& position,
double gradient,
RimFaultReactivation::GridPart gridPart ) const
{
if ( ( m_mainGrid != nullptr ) && m_resultAccessor.notNull() )
{
CAF_ASSERT( m_extractors.find( gridPart ) != m_extractors.end() );
auto extractor = m_extractors.find( gridPart )->second;
CAF_ASSERT( m_wellPaths.find( gridPart ) != m_wellPaths.end() );
auto wellPath = m_wellPaths.find( gridPart )->second;
auto [values, intersections] =
RimFaultReactivationDataAccessorWellLogExtraction::extractValuesAndIntersections( *m_resultAccessor.p(), *extractor.p(), *wellPath );
auto [value, pos] = RimFaultReactivationDataAccessorWellLogExtraction::calculatePorBar( intersections, values, position, m_gradient );
return { value, pos };
}
return { std::numeric_limits<double>::infinity(), cvf::Vec3d::UNDEFINED };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>
RimFaultReactivationDataAccessorStressEclipse::integrateVerticalStress( const RigWellPath& wellPath,
const std::vector<cvf::Vec3d>& intersections,
const RigFaultReactivationModel& model,
RimFaultReactivation::GridPart gridPart,
double seabedDepth,
double waterDensity,
const std::map<RimFaultReactivation::ElementSets, double>& densities )
{
double gravity = RiaWellLogUnitTools<double>::gravityAcceleration();
double seaWaterLoad = gravity * std::abs( seabedDepth ) * waterDensity;
std::vector<double> values = { seaWaterLoad };
auto part = model.grid( gridPart );
CAF_ASSERT( part );
auto elementSets = part->elementSets();
double previousDensity = densities.find( RimFaultReactivation::ElementSets::OverBurden )->second;
for ( size_t i = 1; i < intersections.size(); i++ )
{
double previousValue = values[i - 1];
double previousDepth = intersections[i - 1].z();
double currentDepth = intersections[i].z();
double deltaDepth = previousDepth - currentDepth;
double density = previousDensity;
auto [isOk, elementSet] = findElementSetForPoint( *part, intersections[i], elementSets );
if ( isOk )
{
// Unit: kg/m^3
CAF_ASSERT( densities.find( elementSet ) != densities.end() );
density = densities.find( elementSet )->second;
}
double value = previousValue + density * gravity * deltaDepth;
values.push_back( value );
previousDensity = density;
}
return values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<bool, RimFaultReactivation::ElementSets> RimFaultReactivationDataAccessorStressEclipse::findElementSetForPoint(
const RigGriddedPart3d& part,
const cvf::Vec3d& point,
const std::map<RimFaultReactivation::ElementSets, std::vector<unsigned int>>& elementSets )
{
for ( auto [elementSet, elements] : elementSets )
{
for ( unsigned int elementIndex : elements )
{
// Find nodes from element
auto positions = part.elementCorners( elementIndex );
std::array<cvf::Vec3d, 8> coordinates;
for ( size_t i = 0; i < positions.size(); ++i )
{
coordinates[i] = positions[i];
}
if ( RigHexIntersectionTools::isPointInCell( point, coordinates.data() ) )
{
return { true, elementSet };
}
}
}
return { false, RimFaultReactivation::ElementSets::OverBurden };
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationDataAccessorStressEclipse::lateralStressComponentX( const cvf::Vec3d& position,
RimFaultReactivation::GridPart gridPart ) const
{
return m_lateralStressComponentX;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationDataAccessorStressEclipse::lateralStressComponentY( const cvf::Vec3d& position,
RimFaultReactivation::GridPart gridPart ) const
{
return m_lateralStressComponentY;
}

View File

@ -0,0 +1,101 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimFaultReactivationDataAccessorStress.h"
#include "RimFaultReactivationEnums.h"
#include "cafPdmField.h"
#include "cafPdmPtrField.h"
#include "cvfObject.h"
#include <vector>
class RigGriddedPart3d;
class RimModeledWellPath;
class RigWellPath;
class RimEclipseCase;
class RigEclipseCaseData;
class RigResultAccessor;
class RigEclipseWellLogExtractor;
//==================================================================================================
///
///
//==================================================================================================
class RimFaultReactivationDataAccessorStressEclipse : public RimFaultReactivationDataAccessorStress
{
public:
RimFaultReactivationDataAccessorStressEclipse( RimEclipseCase* geoMechCase,
RimFaultReactivation::Property property,
double gradient,
double seabedDepth,
double waterDensity,
double lateralStressComponentX,
double lateralStressComponentY,
const std::map<RimFaultReactivation::ElementSets, double>& densities );
~RimFaultReactivationDataAccessorStressEclipse() override;
private:
void updateResultAccessor() override;
bool isDataAvailable() const override;
double extractStressValue( StressType stressType, const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const override;
std::pair<double, cvf::Vec3d>
calculatePorBar( const cvf::Vec3d& position, double gradient, RimFaultReactivation::GridPart gridPart ) const override;
bool isPositionValid( const cvf::Vec3d& position,
const cvf::Vec3d& topPosition,
const cvf::Vec3d& bottomPosition,
RimFaultReactivation::GridPart gridPart ) const override;
double lateralStressComponentX( const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const override;
double lateralStressComponentY( const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const override;
static std::vector<double> integrateVerticalStress( const RigWellPath& wellPath,
const std::vector<cvf::Vec3d>& intersections,
const RigFaultReactivationModel& model,
RimFaultReactivation::GridPart gridPart,
double seabedDepth,
double waterDensity,
const std::map<RimFaultReactivation::ElementSets, double>& densities );
static void addOverburdenAndUnderburdenPoints( std::vector<cvf::Vec3d>& intersections, const std::vector<cvf::Vec3d>& wellPathPoints );
static std::pair<bool, RimFaultReactivation::ElementSets>
findElementSetForPoint( const RigGriddedPart3d& part,
const cvf::Vec3d& point,
const std::map<RimFaultReactivation::ElementSets, std::vector<unsigned int>>& elementSets );
RimEclipseCase* m_eclipseCase;
RigEclipseCaseData* m_caseData;
const RigMainGrid* m_mainGrid;
cvf::ref<RigResultAccessor> m_resultAccessor;
double m_waterDensity;
double m_lateralStressComponentX;
double m_lateralStressComponentY;
std::map<RimFaultReactivation::GridPart, cvf::ref<RigWellPath>> m_wellPaths;
std::map<RimFaultReactivation::GridPart, cvf::ref<RigEclipseWellLogExtractor>> m_extractors;
std::map<RimFaultReactivation::GridPart, std::vector<double>> m_stressValues;
std::map<RimFaultReactivation::ElementSets, double> m_densities;
};

View File

@ -0,0 +1,237 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimFaultReactivationDataAccessorStressGeoMech.h"
#include "RiaEclipseUnitTools.h"
#include "RiaLogging.h"
#include "RigFaultReactivationModel.h"
#include "RigFemAddressDefines.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "RigGeoMechCaseData.h"
#include "RigGeoMechWellLogExtractor.h"
#include "RigGriddedPart3d.h"
#include "RigResultAccessorFactory.h"
#include "RigWellPath.h"
#include "RimFaultReactivationDataAccessorStress.h"
#include "RimFaultReactivationDataAccessorWellLogExtraction.h"
#include "RimFaultReactivationEnums.h"
#include "RimGeoMechCase.h"
#include "RimWellIADataAccess.h"
#include "cvfVector3.h"
#include <cmath>
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationDataAccessorStressGeoMech::RimFaultReactivationDataAccessorStressGeoMech( RimGeoMechCase* geoMechCase,
RimFaultReactivation::Property property,
double gradient,
double seabedDepth )
: RimFaultReactivationDataAccessorStress( property, gradient, seabedDepth )
, m_geoMechCase( geoMechCase )
{
m_geoMechCaseData = geoMechCase->geoMechData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimFaultReactivationDataAccessorStressGeoMech::~RimFaultReactivationDataAccessorStressGeoMech()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFaultReactivationDataAccessorStressGeoMech::updateResultAccessor()
{
const int partIndex = 0;
auto loadFrameLambda = [&]( auto femParts, RigFemResultAddress addr, int timeStepIndex ) -> RigFemScalarResultFrames*
{
auto result = femParts->findOrLoadScalarResult( partIndex, addr );
int frameIndex = result->frameCount( timeStepIndex ) - 1;
if ( result->frameData( timeStepIndex, frameIndex ).empty() )
{
return nullptr;
}
return result;
};
auto femParts = m_geoMechCaseData->femPartResults();
m_femPart = femParts->parts()->part( partIndex );
int timeStepIndex = 0;
m_s33Frames = loadFrameLambda( femParts, getResultAddress( "ST", "S33" ), timeStepIndex );
m_s11Frames = loadFrameLambda( femParts, getResultAddress( "ST", "S11" ), timeStepIndex );
m_s22Frames = loadFrameLambda( femParts, getResultAddress( "ST", "S22" ), timeStepIndex );
auto [faultTopPosition, faultBottomPosition] = m_model->faultTopBottom();
auto faultNormal = m_model->faultNormal() ^ cvf::Vec3d::Z_AXIS;
faultNormal.normalize();
double distanceFromFault = 1.0;
auto [topDepth, bottomDepth] = m_model->depthTopBottom();
RigFemPartCollection* geoMechPartCollection = m_geoMechCaseData->femParts();
std::string errorName = "fault reactivation data access";
{
std::vector<cvf::Vec3d> wellPoints =
RimFaultReactivationDataAccessorWellLogExtraction::generateWellPoints( faultTopPosition,
faultBottomPosition,
m_seabedDepth,
bottomDepth,
faultNormal * distanceFromFault );
m_faceAWellPath = new RigWellPath( wellPoints, RimFaultReactivationDataAccessorWellLogExtraction::generateMds( wellPoints ) );
m_partIndexA = geoMechPartCollection->getPartIndexFromPoint( wellPoints[1] );
m_extractorA = new RigGeoMechWellLogExtractor( m_geoMechCaseData, partIndex, m_faceAWellPath.p(), errorName );
}
{
std::vector<cvf::Vec3d> wellPoints =
RimFaultReactivationDataAccessorWellLogExtraction::generateWellPoints( faultTopPosition,
faultBottomPosition,
m_seabedDepth,
bottomDepth,
-faultNormal * distanceFromFault );
m_faceBWellPath = new RigWellPath( wellPoints, RimFaultReactivationDataAccessorWellLogExtraction::generateMds( wellPoints ) );
m_partIndexB = geoMechPartCollection->getPartIndexFromPoint( wellPoints[1] );
m_extractorB = new RigGeoMechWellLogExtractor( m_geoMechCaseData, partIndex, m_faceBWellPath.p(), errorName );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemResultAddress RimFaultReactivationDataAccessorStressGeoMech::getResultAddress( const std::string& fieldName,
const std::string& componentName )
{
return RigFemResultAddress( RIG_ELEMENT_NODAL, fieldName, componentName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationDataAccessorStressGeoMech::isDataAvailable() const
{
return m_s11Frames && m_s22Frames && m_s33Frames && m_femPart;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationDataAccessorStressGeoMech::extractStressValue( StressType stressType,
const cvf::Vec3d& position,
RimFaultReactivation::GridPart gridPart ) const
{
RimWellIADataAccess iaDataAccess( m_geoMechCase );
int timeStepIndex = 0;
RigFemScalarResultFrames* frames = dataFrames( stressType );
int frameIndex = frames->frameCount( timeStepIndex ) - 1;
const std::vector<float>& s11Data = frames->frameData( timeStepIndex, frameIndex );
return interpolatedResultValue( iaDataAccess, m_femPart, position, s11Data );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RimFaultReactivationDataAccessorStressGeoMech::dataFrames( StressType stressType ) const
{
if ( stressType == StressType::S11 )
return m_s11Frames;
else if ( stressType == StressType::S22 )
return m_s22Frames;
else
{
CAF_ASSERT( stressType == StressType::S33 );
return m_s33Frames;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, cvf::Vec3d> RimFaultReactivationDataAccessorStressGeoMech::calculatePorBar( const cvf::Vec3d& position,
double gradient,
RimFaultReactivation::GridPart gridPart ) const
{
int timeStepIndex = 0;
int frameIndex = m_s33Frames->frameCount( timeStepIndex ) - 1;
return calculatePorBar( position, m_gradient, timeStepIndex, frameIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFaultReactivationDataAccessorStressGeoMech::isPositionValid( const cvf::Vec3d& position,
const cvf::Vec3d& topPosition,
const cvf::Vec3d& bottomPosition,
RimFaultReactivation::GridPart gridPart ) const
{
RimWellIADataAccess iaDataAccess( m_geoMechCase );
int centerElementIdx = iaDataAccess.elementIndex( position );
int bottomElementIdx = iaDataAccess.elementIndex( bottomPosition );
int topElementIdx = iaDataAccess.elementIndex( topPosition );
return ( centerElementIdx != -1 && topElementIdx != -1 && bottomElementIdx != -1 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationDataAccessorStressGeoMech::interpolatedResultValue( RimWellIADataAccess& iaDataAccess,
const RigFemPart* femPart,
const cvf::Vec3d& position,
const std::vector<float>& scalarResults ) const
{
return iaDataAccess.interpolatedResultValue( femPart, scalarResults, RIG_ELEMENT_NODAL, position );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, cvf::Vec3d> RimFaultReactivationDataAccessorStressGeoMech::calculatePorBar( const cvf::Vec3d& position,
double gradient,
int timeStepIndex,
int frameIndex ) const
{
RigFemPartCollection* partCollection = m_geoMechCaseData->femParts();
cvf::ref<RigGeoMechWellLogExtractor> extractor = m_partIndexA == partCollection->getPartIndexFromPoint( position ) ? m_extractorA
: m_extractorB;
if ( !extractor->valid() )
{
RiaLogging::error( "Invalid extractor when extracting PorBar" );
return { std::numeric_limits<double>::infinity(), cvf::Vec3d::UNDEFINED };
}
RigFemResultAddress resAddr = RigFemAddressDefines::nodalPorBarAddress();
std::vector<double> values;
extractor->curveData( resAddr, timeStepIndex, frameIndex, &values );
return RimFaultReactivationDataAccessorWellLogExtraction::calculatePorBar( extractor->intersections(), values, position, gradient );
}

View File

@ -0,0 +1,97 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimFaultReactivationDataAccessorStress.h"
#include "RimFaultReactivationEnums.h"
#include "RigFemResultAddress.h"
#include <vector>
#include "cafPdmField.h"
#include "cafPdmPtrField.h"
#include "cvfObject.h"
class RigFemPart;
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigGeoMechCaseData;
class RigGriddedPart3d;
class RimGeoMechCase;
class RimWellIADataAccess;
class RimModeledWellPath;
class RigWellPath;
class RigFemPartCollection;
class RigGeoMechWellLogExtractor;
//==================================================================================================
///
///
//==================================================================================================
class RimFaultReactivationDataAccessorStressGeoMech : public RimFaultReactivationDataAccessorStress
{
public:
RimFaultReactivationDataAccessorStressGeoMech( RimGeoMechCase* geoMechCase,
RimFaultReactivation::Property property,
double gradient,
double seabedDepth );
~RimFaultReactivationDataAccessorStressGeoMech() override;
private:
void updateResultAccessor() override;
bool isDataAvailable() const override;
double extractStressValue( StressType stressType, const cvf::Vec3d& position, RimFaultReactivation::GridPart gridPart ) const override;
std::pair<double, cvf::Vec3d>
calculatePorBar( const cvf::Vec3d& position, double gradient, RimFaultReactivation::GridPart gridPart ) const override;
bool isPositionValid( const cvf::Vec3d& position,
const cvf::Vec3d& topPosition,
const cvf::Vec3d& bottomPosition,
RimFaultReactivation::GridPart gridPart ) const override;
static RigFemResultAddress getResultAddress( const std::string& fieldName, const std::string& componentName );
double interpolatedResultValue( RimWellIADataAccess& iaDataAccess,
const RigFemPart* femPart,
const cvf::Vec3d& position,
const std::vector<float>& scalarResults ) const;
std::pair<double, cvf::Vec3d> calculatePorBar( const cvf::Vec3d& position, double gradient, int timeStepIndex, int frameIndex ) const;
RigFemScalarResultFrames* dataFrames( StressType stressType ) const;
RimGeoMechCase* m_geoMechCase;
RigGeoMechCaseData* m_geoMechCaseData;
RigFemScalarResultFrames* m_s11Frames;
RigFemScalarResultFrames* m_s22Frames;
RigFemScalarResultFrames* m_s33Frames;
const RigFemPart* m_femPart;
cvf::ref<RigWellPath> m_faceAWellPath;
cvf::ref<RigWellPath> m_faceBWellPath;
int m_partIndexA;
int m_partIndexB;
cvf::ref<RigGeoMechWellLogExtractor> m_extractorA;
cvf::ref<RigGeoMechWellLogExtractor> m_extractorB;
};

View File

@ -69,7 +69,7 @@ void RimFaultReactivationDataAccessorTemperature::updateResultAccessor()
{
if ( !m_caseData ) return;
RigEclipseResultAddress resVarAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "SOIL" );
RigEclipseResultAddress resVarAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "TEMP" );
m_eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->ensureKnownResultLoaded( resVarAddress );
m_resultAccessor =
RigResultAccessorFactory::createFromResultAddress( m_caseData, 0, RiaDefines::PorosityModelType::MATRIX_MODEL, m_timeStep, resVarAddress );

View File

@ -115,6 +115,10 @@ std::pair<double, cvf::Vec3d>
return { porBar, extractionPosition };
}
}
else if ( position.z() <= intersections.back().z() )
{
return { values.back(), intersections.back() };
}
return { std::numeric_limits<double>::infinity(), cvf::Vec3d::UNDEFINED };
}
@ -244,12 +248,13 @@ void RimFaultReactivationDataAccessorWellLogExtraction::fillInMissingValuesWithT
std::vector<cvf::Vec3d> RimFaultReactivationDataAccessorWellLogExtraction::generateWellPoints( const cvf::Vec3d& faultTopPosition,
const cvf::Vec3d& faultBottomPosition,
double seabedDepth,
double bottomDepth,
const cvf::Vec3d& offset )
{
cvf::Vec3d faultTop = faultTopPosition + offset;
cvf::Vec3d seabed( faultTop.x(), faultTop.y(), seabedDepth );
cvf::Vec3d faultBottom = faultBottomPosition + offset;
cvf::Vec3d underburdenBottom( faultBottom.x(), faultBottom.y(), -10000.0 );
cvf::Vec3d underburdenBottom( faultBottom.x(), faultBottom.y(), bottomDepth );
return { seabed, faultTop, faultBottom, underburdenBottom };
}
@ -280,19 +285,23 @@ std::pair<std::map<RimFaultReactivation::GridPart, cvf::ref<RigWellPath>>, std::
double seabedDepth )
{
auto [faultTopPosition, faultBottomPosition] = model.faultTopBottom();
auto faultNormal = model.faultNormal();
double distanceFromFault = 1.0;
auto faultNormal = model.faultNormal() ^ cvf::Vec3d::Z_AXIS;
faultNormal.normalize();
double distanceFromFault = 1.0;
auto [topDepth, bottomDepth] = model.depthTopBottom();
std::map<RimFaultReactivation::GridPart, cvf::ref<RigWellPath>> wellPaths;
std::map<RimFaultReactivation::GridPart, cvf::ref<RigEclipseWellLogExtractor>> extractors;
for ( auto gridPart : model.allGridParts() )
{
double sign = model.normalPointsAt() == gridPart ? 1.0 : -1.0;
double sign = model.normalPointsAt() == gridPart ? -1.0 : 1.0;
std::vector<cvf::Vec3d> wellPoints =
RimFaultReactivationDataAccessorWellLogExtraction::generateWellPoints( faultTopPosition,
faultBottomPosition,
seabedDepth,
bottomDepth,
sign * faultNormal * distanceFromFault );
cvf::ref<RigWellPath> wellPath =
new RigWellPath( wellPoints, RimFaultReactivationDataAccessorWellLogExtraction::generateMds( wellPoints ) );
@ -347,7 +356,7 @@ std::vector<double> RimFaultReactivationDataAccessorWellLogExtraction::extractDe
std::vector<double> intersectionsZ;
for ( auto i : intersections )
{
intersectionsZ.push_back( i.z() );
intersectionsZ.push_back( -i.z() );
}
return intersectionsZ;
}

View File

@ -54,6 +54,7 @@ public:
static std::vector<cvf::Vec3d> generateWellPoints( const cvf::Vec3d& faultTopPosition,
const cvf::Vec3d& faultBottomPosition,
double seabedDepth,
double bottomDepth,
const cvf::Vec3d& offset );
static std::vector<double> generateMds( const std::vector<cvf::Vec3d>& points );
@ -61,9 +62,9 @@ public:
static std::pair<std::vector<double>, std::vector<cvf::Vec3d>> extractValuesAndIntersections( const RigResultAccessor& resultAccessor,
RigEclipseWellLogExtractor& extractor,
const RigWellPath& wellPath );
static std::pair<int, int> findIntersectionsForTvd( const std::vector<cvf::Vec3d>& intersections, double tvd );
protected:
static std::pair<int, int> findIntersectionsForTvd( const std::vector<cvf::Vec3d>& intersections, double tvd );
static std::pair<int, int> findOverburdenAndUnderburdenIndex( const std::vector<double>& values );
static double computeValueWithGradient( const std::vector<cvf::Vec3d>& intersections,
const std::vector<double>& values,

View File

@ -105,6 +105,7 @@ RimFaultReactivationModel::RimFaultReactivationModel()
CAF_PDM_InitField( &m_modelPart2Color, "ModelPart2Color", cvf::Color3f( cvf::Color3f::BLUE ), "Part 2 Color" );
CAF_PDM_InitField( &m_maxReservoirCellHeight, "MaxReservoirCellHeight", 20.0, "Max. Reservoir Cell Height" );
CAF_PDM_InitField( &m_minReservoirCellHeight, "MinReservoirCellHeight", 0.5, "Min. Reservoir Cell Height" );
CAF_PDM_InitField( &m_cellHeightGrowFactor, "CellHeightGrowFactor", 1.05, "Cell Height Grow Factor" );
CAF_PDM_InitField( &m_minReservoirCellWidth, "MinReservoirCellWidth", 20.0, "Reservoir Cell Width" );
@ -129,6 +130,9 @@ RimFaultReactivationModel::RimFaultReactivationModel()
CAF_PDM_InitField( &m_frictionAngleDeg, "FrictionAngle", 20.0, "Friction Angle [degree]" );
CAF_PDM_InitField( &m_seabedTemperature, "SeabedTemperature", 5.0, "Seabed Temperature [C]" );
CAF_PDM_InitField( &m_lateralStressCoefficientX, "LateralStressCoefficientX", 0.5, "Lateral Stress Coeff. X" );
CAF_PDM_InitField( &m_lateralStressCoefficientY, "LateralStressCoefficientY", 0.5, "Lateral Stress Coeff. Y" );
CAF_PDM_InitFieldNoDefault( &m_targets, "Targets", "Targets" );
m_targets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
m_targets.uiCapability()->setUiTreeChildrenHidden( true );
@ -326,7 +330,11 @@ void RimFaultReactivationModel::updateVisualization()
generator->setModelSize( m_modelMinZ, m_modelBelowSize, m_modelExtentFromAnchor );
generator->setFaultBufferDepth( m_faultExtendUpwards, m_faultExtendDownwards );
generator->setModelThickness( m_modelThickness );
generator->setModelGriddingOptions( m_maxReservoirCellHeight, m_cellHeightGrowFactor, m_minReservoirCellWidth, m_cellWidthGrowFactor );
generator->setModelGriddingOptions( m_minReservoirCellHeight,
m_maxReservoirCellHeight,
m_cellHeightGrowFactor,
m_minReservoirCellWidth,
m_cellWidthGrowFactor );
generator->setupLocalCoordinateTransform();
generator->setUseLocalCoordinates( m_useLocalCoordinates );
@ -385,6 +393,7 @@ QList<caf::PdmOptionItemInfo> RimFaultReactivationModel::calculateValueOptions(
else if ( fieldNeedingOptions == &m_geomechCase )
{
RimTools::geoMechCaseOptionItems( &options );
options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) );
}
return options;
@ -452,6 +461,7 @@ void RimFaultReactivationModel::defineUiOrdering( QString uiConfigName, caf::Pdm
faultGrp->add( &m_faultExtendDownwards );
auto gridModelGrp = modelGrp->addNewGroup( "Grid Definition" );
gridModelGrp->add( &m_minReservoirCellHeight );
gridModelGrp->add( &m_maxReservoirCellHeight );
gridModelGrp->add( &m_cellHeightGrowFactor );
@ -479,15 +489,20 @@ void RimFaultReactivationModel::defineUiOrdering( QString uiConfigName, caf::Pdm
{
propertiesGrp->add( &m_useGridDensity );
propertiesGrp->add( &m_useGridElasticProperties );
propertiesGrp->add( &m_useGridStress );
propertiesGrp->add( &m_waterDensity );
propertiesGrp->add( &m_useGridStress );
propertiesGrp->add( &m_seabedTemperature );
bool useTemperatureFromGrid = m_useGridTemperature();
m_seabedTemperature.uiCapability()->setUiReadOnly( !useTemperatureFromGrid );
}
if ( !hasGeoMechCase || !m_useGridStress() )
{
propertiesGrp->add( &m_lateralStressCoefficientX );
propertiesGrp->add( &m_lateralStressCoefficientY );
}
propertiesGrp->add( &m_frictionAngleDeg );
uiOrdering.skipRemainingFields();
@ -804,3 +819,19 @@ double RimFaultReactivationModel::seabedTemperature() const
{
return m_seabedTemperature;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationModel::lateralStressCoefficientX() const
{
return m_lateralStressCoefficientX;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimFaultReactivationModel::lateralStressCoefficientY() const
{
return m_lateralStressCoefficientY;
}

View File

@ -129,6 +129,8 @@ public:
double waterDensity() const;
double frictionAngleDeg() const;
double seabedTemperature() const;
double lateralStressCoefficientX() const;
double lateralStressCoefficientY() const;
RimEclipseCase* eclipseCase() const;
RimGeoMechCase* geoMechCase() const;
@ -168,6 +170,7 @@ private:
caf::PdmField<double> m_faultExtendDownwards;
caf::PdmField<double> m_maxReservoirCellHeight;
caf::PdmField<double> m_minReservoirCellHeight;
caf::PdmField<double> m_cellHeightGrowFactor;
caf::PdmField<double> m_minReservoirCellWidth;
caf::PdmField<double> m_cellWidthGrowFactor;
@ -184,6 +187,8 @@ private:
caf::PdmField<double> m_waterDensity;
caf::PdmField<double> m_frictionAngleDeg;
caf::PdmField<double> m_seabedTemperature;
caf::PdmField<double> m_lateralStressCoefficientX;
caf::PdmField<double> m_lateralStressCoefficientY;
caf::PdmField<size_t> m_startCellIndex;
caf::PdmField<int> m_startCellFace;

View File

@ -63,6 +63,9 @@ void RimEclipseStatisticsCaseEvaluator::addNamedResult( RigCaseCellResultsData*
size_t timeStepCount = std::max( size_t( 1 ), sourceTimeStepInfos.size() );
// Limit to one time step for static native results
if ( resultType == RiaDefines::ResultCatType::STATIC_NATIVE ) timeStepCount = 1;
dataValues->resize( timeStepCount );
// Initializes the size of the destination dataset to active union cell count

View File

@ -36,16 +36,20 @@
#include "RimEclipseCase.h"
#include "RimEclipseCaseTools.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseResultAddress.h"
#include "RimEclipseStatisticsCase.h"
#include "RimEclipseView.h"
#include "RimGridCalculationCollection.h"
#include "RimGridCalculationVariable.h"
#include "RimProject.h"
#include "RimReloadCaseTools.h"
#include "RimResultSelectionUi.h"
#include "RimTools.h"
#include "expressionparser/ExpressionParser.h"
#include "cafPdmUiPropertyViewDialog.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include <QCheckBox>
@ -76,7 +80,18 @@ RimGridCalculation::RimGridCalculation()
CAF_PDM_InitField( &m_defaultValue, "DefaultValue", 0.0, "Custom Value" );
CAF_PDM_InitFieldNoDefault( &m_destinationCase, "DestinationCase", "Destination Case" );
CAF_PDM_InitField( &m_applyToAllCases, "AllDestinationCase", false, "Apply to All Cases" );
CAF_PDM_InitField( &m_defaultPropertyVariableIndex, "DefaultPropertyVariableName", 0, "Property Variable Name" );
CAF_PDM_InitFieldNoDefault( &m_nonVisibleResultAddress, "NonVisibleResultAddress", "" );
m_nonVisibleResultAddress = new RimEclipseResultAddress;
CAF_PDM_InitField( &m_editNonVisibleResultAddress, "EditNonVisibleResultAddress", false, "Edit" );
m_editNonVisibleResultAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
m_editNonVisibleResultAddress.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitFieldNoDefault( &m_nonVisibleResultText, "NonVisibleResultText", "" );
m_nonVisibleResultText.registerGetMethod( this, &RimGridCalculation::nonVisibleResultAddressText );
m_nonVisibleResultText.uiCapability()->setUiReadOnly( true );
m_nonVisibleResultText.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "SelectedTimeSteps", "Time Step Selection" );
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
@ -156,6 +171,29 @@ bool RimGridCalculation::calculate()
}
}
if ( m_defaultValueType() == DefaultValueType::FROM_PROPERTY )
{
bool isDataSourceAvailable = false;
if ( m_nonVisibleResultAddress->eclipseCase() )
{
auto data = m_nonVisibleResultAddress->eclipseCase()->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
if ( data && data->hasResultEntry(
RigEclipseResultAddress( m_nonVisibleResultAddress->resultType(), m_nonVisibleResultAddress->resultName() ) ) )
{
isDataSourceAvailable = true;
}
}
if ( !isDataSourceAvailable )
{
QString msg = "No data available for result defined in 'Non-visible Cell Value'";
RiaLogging::errorInMessageBox( nullptr, "Grid Property Calculator", msg );
return false;
}
}
cvf::UByteArray* inputValueVisibilityFilter = nullptr;
if ( m_cellFilterView() )
{
@ -226,6 +264,20 @@ RimGridCalculation::DefaultValueConfig RimGridCalculation::defaultValueConfigura
return std::make_pair( m_defaultValueType(), HUGE_VAL );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCalculation::nonVisibleResultAddressText() const
{
QString txt;
if ( m_nonVisibleResultAddress->eclipseCase() ) txt += m_nonVisibleResultAddress->eclipseCase()->caseUserDescription() + " : ";
txt += m_nonVisibleResultAddress->resultName();
return txt;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -251,7 +303,10 @@ void RimGridCalculation::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
filterGroup->add( &m_defaultValueType );
if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::FROM_PROPERTY )
filterGroup->add( &m_defaultPropertyVariableIndex );
{
filterGroup->add( &m_nonVisibleResultText );
filterGroup->add( &m_editNonVisibleResultAddress, { .newRow = false } );
}
else if ( m_defaultValueType() == RimGridCalculation::DefaultValueType::USER_DEFINED )
filterGroup->add( &m_defaultValue );
}
@ -278,7 +333,16 @@ QList<caf::PdmOptionItemInfo> RimGridCalculation::calculateValueOptions( const c
RimProject::current()->allViews( views );
RimEclipseCase* firstEclipseCase = nullptr;
if ( !inputCases().empty() ) firstEclipseCase = inputCases().front();
if ( !inputCases().empty() )
{
firstEclipseCase = inputCases().front();
}
else
{
// If no input cases are defined, use the destination case to determine the grid size. This will enable use of expressions with
// no input cases like "calculation := 1.0"
firstEclipseCase = m_destinationCase();
}
if ( firstEclipseCase )
{
@ -311,16 +375,6 @@ QList<caf::PdmOptionItemInfo> RimGridCalculation::calculateValueOptions( const c
options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) );
}
else if ( fieldNeedingOptions == &m_defaultPropertyVariableIndex )
{
for ( int i = 0; i < static_cast<int>( m_variables.size() ); i++ )
{
auto v = dynamic_cast<RimGridCalculationVariable*>( m_variables[i] );
QString optionText = v->name();
options.push_back( caf::PdmOptionItemInfo( optionText, i ) );
}
}
else if ( &m_selectedTimeSteps == fieldNeedingOptions )
{
RimEclipseCase* firstEclipseCase = nullptr;
@ -358,6 +412,49 @@ void RimGridCalculation::initAfterRead()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
RimUserDefinedCalculation::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_editNonVisibleResultAddress )
{
auto eclipseCase = m_nonVisibleResultAddress->eclipseCase();
if ( !eclipseCase ) eclipseCase = m_destinationCase;
RimResultSelectionUi selectionUi;
selectionUi.setEclipseResultAddress( eclipseCase, m_nonVisibleResultAddress->resultType(), m_nonVisibleResultAddress->resultName() );
caf::PdmUiPropertyViewDialog propertyDialog( nullptr, &selectionUi, "Select Result", "" );
if ( propertyDialog.exec() == QDialog::Accepted )
{
m_nonVisibleResultAddress->setEclipseCase( selectionUi.eclipseCase() );
m_nonVisibleResultAddress->setResultType( selectionUi.resultType() );
m_nonVisibleResultAddress->setResultName( selectionUi.resultVariable() );
}
m_editNonVisibleResultAddress = false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
{
RimUserDefinedCalculation::defineEditorAttribute( field, uiConfigName, attribute );
if ( field == &m_editNonVisibleResultAddress )
{
if ( auto attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute ) )
{
attrib->m_buttonText = "Edit";
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -414,16 +511,12 @@ RigEclipseResultAddress RimGridCalculation::outputAddress() const
std::vector<double> RimGridCalculation::getDataForVariable( RimGridCalculationVariable* variable,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* destinationCase,
bool useDataFromDestinationCase ) const
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const
{
// The data can be taken from the destination case or from the calculation variable.
auto eclipseCase = useDataFromDestinationCase ? destinationCase : variable->eclipseCase();
if ( !eclipseCase ) return {};
int timeStep = variable->timeStep();
if ( !sourceCase || !destinationCase ) return {};
int timeStep = variable->timeStep();
auto resultCategoryType = variable->resultCategoryType();
// General case is to use the data from the given time step
@ -440,9 +533,31 @@ std::vector<double> RimGridCalculation::getDataForVariable( RimGridCalculationVa
timeStepToUse = timeStep;
}
RigEclipseResultAddress resAddr( resultCategoryType, variable->resultVariable() );
return getDataForResult( variable->resultVariable(), resultCategoryType, timeStepToUse, porosityModel, sourceCase, destinationCase );
}
auto eclipseCaseData = eclipseCase->eclipseCaseData();
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGridCalculation::getDataForResult( const QString& resultName,
const RiaDefines::ResultCatType resultCategoryType,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const
{
if ( !sourceCase || !destinationCase ) return {};
size_t timeStepToUse = tsId;
if ( resultCategoryType == RiaDefines::ResultCatType::STATIC_NATIVE )
{
// Use the first time step for static data for all time steps
timeStepToUse = 0;
}
RigEclipseResultAddress resAddr( resultCategoryType, resultName );
auto eclipseCaseData = sourceCase->eclipseCaseData();
auto rigCaseCellResultsData = eclipseCaseData->results( porosityModel );
if ( !rigCaseCellResultsData->ensureKnownResultLoaded( resAddr ) ) return {};
@ -517,6 +632,7 @@ void RimGridCalculation::replaceFilteredValuesWithDefaultValue( double
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values,
size_t timeStep,
RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues,
@ -528,12 +644,22 @@ void RimGridCalculation::filterResults( RimGridView*
if ( defaultValueType == RimGridCalculation::DefaultValueType::FROM_PROPERTY )
{
if ( m_defaultPropertyVariableIndex < static_cast<int>( values.size() ) )
replaceFilteredValuesWithVector( values[m_defaultPropertyVariableIndex], visibility, resultValues, porosityModel, outputEclipseCase );
auto nonVisibleValues = getDataForResult( m_nonVisibleResultAddress->resultName(),
m_nonVisibleResultAddress->resultType(),
timeStep,
porosityModel,
m_nonVisibleResultAddress->eclipseCase(),
outputEclipseCase );
if ( !nonVisibleValues.empty() )
{
replaceFilteredValuesWithVector( nonVisibleValues, visibility, resultValues, porosityModel, outputEclipseCase );
}
else
{
QString errorMessage = "Invalid input data for default result property, no data assigned to non-visible cells.";
RiaLogging::errorInMessageBox( nullptr, "Grid Property Calculator", errorMessage );
QString errorMessage =
"Grid Property Calculator: Invalid input data for default result property, no data assigned to non-visible cells.";
RiaLogging::error( errorMessage );
}
}
else
@ -703,8 +829,9 @@ bool RimGridCalculation::calculateForCases( const std::vector<RimEclipseCase*>&
CAF_ASSERT( v != nullptr );
bool useDataFromDestinationCase = ( v->eclipseCase() == m_destinationCase );
auto sourceCase = useDataFromDestinationCase ? m_destinationCase : calculationCase;
auto dataForVariable = getDataForVariable( v, tsId, porosityModel, calculationCase, useDataFromDestinationCase );
auto dataForVariable = getDataForVariable( v, tsId, porosityModel, sourceCase, m_destinationCase );
if ( dataForVariable.empty() )
{
RiaLogging::error( QString( " No data found for variable '%1'." ).arg( v->name() ) );
@ -727,7 +854,15 @@ bool RimGridCalculation::calculateForCases( const std::vector<RimEclipseCase*>&
}
std::vector<double> resultValues;
resultValues.resize( dataForAllVariables[0].size() );
if ( m_destinationCase && m_destinationCase->eclipseCaseData() )
{
// Find number of active cells in the destination case.
auto activeCellInfoDestination = m_destinationCase->eclipseCaseData()->activeCellInfo( porosityModel );
if ( activeCellInfoDestination )
{
resultValues.resize( activeCellInfoDestination->reservoirActiveCellCount() );
}
}
parser.assignVector( leftHandSideVariableName, resultValues );
QString errorText;
@ -753,6 +888,7 @@ bool RimGridCalculation::calculateForCases( const std::vector<RimEclipseCase*>&
{
filterResults( m_cellFilterView(),
dataForAllVariables,
tsId,
m_defaultValueType(),
m_defaultValue(),
resultValues,

View File

@ -22,7 +22,9 @@
#include "RimGridCalculationVariable.h"
#include "RimUserDefinedCalculation.h"
#include "cafPdmChildField.h"
#include "cafSignal.h"
#include "cvfArray.h"
#include <optional>
@ -30,6 +32,7 @@
class RimEclipseCase;
class RimGridView;
class RigEclipseResultAddress;
class RimEclipseResultAddress;
//==================================================================================================
///
@ -80,11 +83,19 @@ protected:
std::vector<double> getDataForVariable( RimGridCalculationVariable* variable,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* destinationCase,
bool useDataFromDestinationCase ) const;
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const;
std::vector<double> getDataForResult( const QString& resultName,
const RiaDefines::ResultCatType resultCategoryType,
size_t tsId,
RiaDefines::PorosityModelType porosityModel,
RimEclipseCase* sourceCase,
RimEclipseCase* destinationCase ) const;
void filterResults( RimGridView* cellFilterView,
const std::vector<std::vector<double>>& values,
size_t timeStep,
RimGridCalculation::DefaultValueType defaultValueType,
double defaultValue,
std::vector<double>& resultValues,
@ -106,9 +117,13 @@ protected:
using DefaultValueConfig = std::pair<RimGridCalculation::DefaultValueType, double>;
DefaultValueConfig defaultValueConfiguration() const;
QString nonVisibleResultAddressText() const;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
void initAfterRead() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
private:
void onVariableUpdated( const SignalEmitter* emitter );
@ -125,5 +140,7 @@ private:
caf::PdmField<std::vector<int>> m_selectedTimeSteps;
caf::PdmField<int> m_defaultPropertyVariableIndex;
caf::PdmProxyValueField<QString> m_nonVisibleResultText;
caf::PdmChildField<RimEclipseResultAddress*> m_nonVisibleResultAddress;
caf::PdmField<bool> m_editNonVisibleResultAddress;
};

View File

@ -28,6 +28,8 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <utility>
#include <vector>
//--------------------------------------------------------------------------------------------------
@ -698,7 +700,7 @@ double RigCellGeometryTools::getLengthOfPolygonAlongLine( const std::pair<cvf::V
{
cvf::BoundingBox lineBoundingBox;
for ( cvf::Vec3d polygonPoint : polygon )
for ( const cvf::Vec3d& polygonPoint : polygon )
{
cvf::Vec3d pointOnLine = cvf::GeometryTools::projectPointOnLine( line.first, line.second, polygonPoint, nullptr );
lineBoundingBox.add( pointOnLine );
@ -794,6 +796,7 @@ inline double RigCellGeometryTools::isLeftOfLine2D( const cvf::Vec3d& point1, co
//--------------------------------------------------------------------------------------------------
/// winding number test for a point in a polygon
/// Operates only in the XY plane
/// Input: point = the point to test,
/// polygon[] = vertex points of a closed polygon of size n, where polygon[n-1]=polygon[0]
///
@ -831,3 +834,101 @@ bool RigCellGeometryTools::pointInsidePolygon2D( const cvf::Vec3d point, const s
}
return wn != 0;
}
//--------------------------------------------------------------------------------------------------
/// Returns the intersection of line 1 (a1 to b1) and line 2 (a2 to b2).
/// - operates only in the XY plane
/// - returns true and the x,y intersection if the lines intersect
/// - returns false if they do not intersect
/// ref. http://www.paulbourke.net/geometry/pointlineplane/pdb.c
//--------------------------------------------------------------------------------------------------
std::pair<bool, cvf::Vec2d>
RigCellGeometryTools::lineLineIntersection2D( const cvf::Vec3d a1, const cvf::Vec3d b1, const cvf::Vec3d a2, const cvf::Vec3d b2 )
{
constexpr double EPS = 0.000001;
double mua, mub;
double denom, numera, numerb;
const double x1 = a1.x(), x2 = b1.x();
const double x3 = a2.x(), x4 = b2.x();
const double y1 = a1.y(), y2 = b1.y();
const double y3 = a2.y(), y4 = b2.y();
denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 );
numera = ( x4 - x3 ) * ( y1 - y3 ) - ( y4 - y3 ) * ( x1 - x3 );
numerb = ( x2 - x1 ) * ( y1 - y3 ) - ( y2 - y1 ) * ( x1 - x3 );
// Are the lines coincident?
if ( ( std::abs( numera ) < EPS ) && ( std::abs( numerb ) < EPS ) && ( std::abs( denom ) < EPS ) )
{
return std::make_pair( true, cvf::Vec2d( ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 ) );
}
// Are the lines parallel?
if ( std::abs( denom ) < EPS )
{
return std::make_pair( false, cvf::Vec2d() );
}
// Is the intersection along the segments?
mua = numera / denom;
mub = numerb / denom;
if ( mua < 0 || mua > 1 || mub < 0 || mub > 1 )
{
return std::make_pair( false, cvf::Vec2d() );
}
return std::make_pair( true, cvf::Vec2d( x1 + mua * ( x2 - x1 ), y1 + mua * ( y2 - y1 ) ) );
}
//--------------------------------------------------------------------------------------------------
///
/// Returns true if the line from a1 to b1 intersects the line from a2 to b2
/// Operates only in the XY plane
///
//--------------------------------------------------------------------------------------------------
bool RigCellGeometryTools::lineIntersectsLine2D( const cvf::Vec3d a1, const cvf::Vec3d b1, const cvf::Vec3d a2, const cvf::Vec3d b2 )
{
return lineLineIntersection2D( a1, b1, a2, b2 ).first;
}
//--------------------------------------------------------------------------------------------------
///
/// Returns true if the line from a to b intersects the closed, simple polygon defined by the corner
/// points in the input polygon vector, otherwise false
/// Operates only in the XY plane
///
//--------------------------------------------------------------------------------------------------
bool RigCellGeometryTools::lineIntersectsPolygon2D( const cvf::Vec3d a, const cvf::Vec3d b, const std::vector<cvf::Vec3d>& polygon )
{
int nPolyLines = (int)polygon.size();
for ( int i = 1; i < nPolyLines; i++ )
{
if ( lineIntersectsLine2D( a, b, polygon[i - 1], polygon[i] ) ) return true;
}
return lineIntersectsLine2D( a, b, polygon[nPolyLines - 1], polygon[0] );
}
//--------------------------------------------------------------------------------------------------
///
/// Returns true if the polyline intersects the simple polygon defined by the NEGK face corners of the input cell
/// Operates only in the XY plane
///
//--------------------------------------------------------------------------------------------------
bool RigCellGeometryTools::polylineIntersectsCellNegK2D( const std::vector<cvf::Vec3d>& polyline, const std::array<cvf::Vec3d, 8>& cellCorners )
{
const int nPoints = (int)polyline.size();
const int nCorners = 4;
for ( int i = 1; i < nPoints; i++ )
{
for ( int j = 1; j < nCorners; j++ )
{
if ( lineIntersectsLine2D( polyline[i - 1], polyline[i], cellCorners[j - 1], cellCorners[j] ) ) return true;
}
if ( lineIntersectsLine2D( polyline[i - 1], polyline[i], cellCorners[nCorners - 1], cellCorners[0] ) ) return true;
}
return false;
}

View File

@ -76,7 +76,14 @@ public:
static std::vector<cvf::Vec3d> unionOfPolygons( const std::vector<std::vector<cvf::Vec3d>>& polygons );
// *** the 2D methods only looks at the X and Y coordinates of the input points ***
static bool pointInsidePolygon2D( const cvf::Vec3d point, const std::vector<cvf::Vec3d>& polygon );
static std::pair<bool, cvf::Vec2d>
lineLineIntersection2D( const cvf::Vec3d a1, const cvf::Vec3d b1, const cvf::Vec3d a2, const cvf::Vec3d b2 );
static bool lineIntersectsLine2D( const cvf::Vec3d a1, const cvf::Vec3d b1, const cvf::Vec3d a2, const cvf::Vec3d b2 );
static bool lineIntersectsPolygon2D( const cvf::Vec3d a, const cvf::Vec3d b, const std::vector<cvf::Vec3d>& polygon );
static bool polylineIntersectsCellNegK2D( const std::vector<cvf::Vec3d>& polyline, const std::array<cvf::Vec3d, 8>& cellCorners );
private:
static std::vector<cvf::Vec3d> ajustPolygonToAvoidIntersectionsAtVertex( const std::vector<cvf::Vec3d>& polyLine,

View File

@ -21,6 +21,8 @@
#include "RigFaultReactivationModelGenerator.h"
#include "RigGriddedPart3d.h"
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -226,6 +228,16 @@ const std::pair<cvf::Vec3d, cvf::Vec3d> RigFaultReactivationModel::faultTopBotto
return m_generator->faultTopBottomPoints();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RigFaultReactivationModel::depthTopBottom() const
{
if ( m_generator.get() == nullptr )
return std::make_pair( std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity() );
return m_generator->depthTopBottom();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -84,6 +84,7 @@ public:
const cvf::Vec3d faultNormal() const;
const std::pair<cvf::Vec3d, cvf::Vec3d> faultTopBottom() const;
std::pair<double, double> depthTopBottom() const;
RimFaultReactivation::GridPart normalPointsAt() const;

View File

@ -42,12 +42,14 @@ RigFaultReactivationModelGenerator::RigFaultReactivationModelGenerator( cvf::Vec
, m_bufferAboveFault( 0.0 )
, m_bufferBelowFault( 0.0 )
, m_startDepth( 0.0 )
, m_bottomDepth( 0.0 )
, m_depthBelowFault( 100.0 )
, m_horzExtentFromFault( 1000.0 )
, m_modelThickness( 100.0 )
, m_useLocalCoordinates( false )
, m_cellSizeHeightFactor( 1.0 )
, m_cellSizeWidthFactor( 1.0 )
, m_minCellHeight( 0.5 )
, m_maxCellHeight( 20.0 )
, m_minCellWidth( 20.0 )
{
@ -122,11 +124,13 @@ void RigFaultReactivationModelGenerator::setUseLocalCoordinates( bool useLocalCo
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModelGenerator::setModelGriddingOptions( double maxCellHeight,
void RigFaultReactivationModelGenerator::setModelGriddingOptions( double minCellHeight,
double maxCellHeight,
double cellSizeFactorHeight,
double minCellWidth,
double cellSizeFactorWidth )
{
m_minCellHeight = minCellHeight;
m_maxCellHeight = maxCellHeight;
m_cellSizeHeightFactor = cellSizeFactorHeight;
m_minCellWidth = minCellWidth;
@ -291,14 +295,14 @@ void RigFaultReactivationModelGenerator::generatePointsFrontBack()
auto alongModel = m_normal ^ cvf::Vec3d::Z_AXIS;
alongModel.normalize();
double top_depth = -m_startDepth;
double bottom_depth = m_bottomFault.z() - m_depthBelowFault;
double top_depth = -m_startDepth;
m_bottomDepth = m_bottomFault.z() - m_depthBelowFault;
cvf::Vec3d edge_front = m_startPosition - m_horzExtentFromFault * alongModel;
cvf::Vec3d edge_back = m_startPosition + m_horzExtentFromFault * alongModel;
points[8] = m_bottomFault;
points[8].z() = bottom_depth;
points[8].z() = m_bottomDepth;
points[9] = m_bottomFault;
points[10] = m_bottomReservoirBack;
@ -476,6 +480,9 @@ void RigFaultReactivationModelGenerator::generateGeometry( size_t
}
m_topFault = top_point;
mergeTinyLayers( zPositionsFront, kLayersFront, m_minCellHeight );
mergeTinyLayers( zPositionsBack, kLayersBack, m_minCellHeight );
splitLargeLayers( zPositionsFront, kLayersFront, m_maxCellHeight );
splitLargeLayers( zPositionsBack, kLayersBack, m_maxCellHeight );
@ -565,6 +572,68 @@ cvf::Vec3d RigFaultReactivationModelGenerator::extrapolatePoint( cvf::Vec3d star
return endPoint + ( buffer * direction );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFaultReactivationModelGenerator::mergeTinyLayers( std::map<double, cvf::Vec3d>& layers, std::vector<int>& kLayers, double minHeight )
{
std::vector<int> newKLayers;
std::vector<cvf::Vec3d> newLayers;
const int nLayers = (int)layers.size();
std::vector<double> keys;
std::vector<cvf::Vec3d> vals;
for ( auto& layer : layers )
{
keys.push_back( layer.first );
vals.push_back( layer.second );
}
// bottom layer must always be included
newLayers.push_back( vals.front() );
newKLayers.push_back( kLayers.front() );
// remove any layer that is less than minHeight above the previous layer, starting at the bottom
for ( int k = 1; k < nLayers - 1; k++ )
{
if ( std::abs( keys[k] - keys[k - 1] ) < minHeight )
{
continue;
}
newKLayers.push_back( kLayers[k] );
newLayers.push_back( vals[k] );
}
// top layer must always be included
newLayers.push_back( vals.back() );
// make sure the top two layers aren't too close, if so, remove the second topmost
const int nNewLayers = (int)newLayers.size();
if ( nNewLayers > 2 )
{
if ( std::abs( newLayers[nNewLayers - 1].z() - newLayers[nNewLayers - 2].z() ) < minHeight )
{
newKLayers.pop_back();
newLayers.pop_back();
newLayers.pop_back();
newLayers.push_back( vals.back() );
}
}
layers.clear();
for ( auto& p : newLayers )
{
layers[p.z()] = p;
}
kLayers.clear();
for ( auto k : newKLayers )
{
kLayers.push_back( k );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -656,3 +725,11 @@ const std::pair<cvf::Vec3d, cvf::Vec3d> RigFaultReactivationModelGenerator::faul
{
return std::make_pair( m_topFault, m_bottomFault );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RigFaultReactivationModelGenerator::depthTopBottom() const
{
return { -m_startDepth, m_bottomDepth };
}

View File

@ -46,7 +46,11 @@ public:
void setFaultBufferDepth( double aboveFault, double belowFault );
void setModelSize( double startDepth, double depthBelowFault, double horzExtentFromFault );
void setModelThickness( double thickness );
void setModelGriddingOptions( double maxCellHeight, double cellSizeFactorHeight, double minCellWidth, double cellSizeFactorWidth );
void setModelGriddingOptions( double minCellHeight,
double maxCellHeight,
double cellSizeFactorHeight,
double minCellWidth,
double cellSizeFactorWidth );
void setUseLocalCoordinates( bool useLocalCoordinates );
void setupLocalCoordinateTransform();
@ -62,6 +66,7 @@ public:
const std::array<cvf::Vec3d, 12>& backPoints() const;
const cvf::Vec3d normal() const;
const std::pair<cvf::Vec3d, cvf::Vec3d> faultTopBottomPoints() const;
std::pair<double, double> depthTopBottom() const;
protected:
static const std::array<int, 4> faceIJCornerIndexes( cvf::StructGridInterface::FaceType face );
@ -71,6 +76,7 @@ protected:
static cvf::Vec3d lineIntersect( const cvf::Plane& plane, cvf::Vec3d lineA, cvf::Vec3d lineB );
static cvf::Vec3d extrapolatePoint( cvf::Vec3d startPoint, cvf::Vec3d endPoint, double stopDepth );
static void splitLargeLayers( std::map<double, cvf::Vec3d>& layers, std::vector<int>& kLayers, double maxHeight );
static void mergeTinyLayers( std::map<double, cvf::Vec3d>& layers, std::vector<int>& kLayers, double minHeight );
std::map<double, cvf::Vec3d> elementLayers( cvf::StructGridInterface::FaceType face, std::vector<size_t>& cellIndexColumn );
std::vector<int> elementKLayers( const std::vector<size_t>& cellIndexColumn );
@ -98,10 +104,12 @@ private:
double m_bufferBelowFault;
double m_startDepth;
double m_bottomDepth;
double m_depthBelowFault;
double m_horzExtentFromFault;
double m_modelThickness;
double m_minCellHeight;
double m_maxCellHeight;
double m_cellSizeHeightFactor;
double m_minCellWidth;

View File

@ -284,6 +284,55 @@ TEST( RigCellGeometryTools, lengthCalcTestTriangle )
EXPECT_LT( length, 1.8 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RigCellGeometryTools, lineIntersectsLine2DTest )
{
cvf::Vec3d a1( 0, 0, 0 );
cvf::Vec3d b1( 1, 1, 1 );
cvf::Vec3d a2( 0, 1, 500 );
cvf::Vec3d b2( 1, 0, 7000 );
cvf::Vec3d a3( -10, -10, 0 );
cvf::Vec3d b3( -4, -1, 0 );
EXPECT_TRUE( RigCellGeometryTools::lineIntersectsLine2D( a1, b1, a2, b2 ) );
EXPECT_FALSE( RigCellGeometryTools::lineIntersectsLine2D( a1, b1, a3, b3 ) );
auto [intersect, point] = RigCellGeometryTools::lineLineIntersection2D( a1, b1, a2, b2 );
EXPECT_TRUE( intersect );
EXPECT_DOUBLE_EQ( 0.5, point.x() );
EXPECT_DOUBLE_EQ( 0.5, point.y() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RigCellGeometryTools, lineIntersectsPolygon2DTest )
{
cvf::Vec3d a1( 0, 0, 0 );
cvf::Vec3d b1( 1, 1, 1 );
cvf::Vec3d a2( 5, -5, 0 );
cvf::Vec3d b2( 15, 25, 0 );
cvf::Vec3d p1( 10, 10, 0 );
cvf::Vec3d p2( 11, 20, 1000 );
cvf::Vec3d p3( 20, 7, -20 );
cvf::Vec3d p4( 21, -1, 55 );
std::vector<cvf::Vec3d> polygon;
polygon.push_back( p1 );
polygon.push_back( p2 );
polygon.push_back( p3 );
polygon.push_back( p4 );
EXPECT_FALSE( RigCellGeometryTools::lineIntersectsPolygon2D( a1, b1, polygon ) );
EXPECT_TRUE( RigCellGeometryTools::lineIntersectsPolygon2D( a2, b2, polygon ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -623,6 +623,13 @@ set_property(
add_subdirectory(ThirdParty/tomlplusplus)
# ##############################################################################
# spdlog
# ##############################################################################
add_subdirectory(ThirdParty/spdlog)
list(APPEND THIRD_PARTY_LIBRARIES spdlog)
# ##############################################################################
# Thirdparty libraries are put in ThirdParty solution folder
# ##############################################################################

View File

@ -285,9 +285,9 @@ class Instance:
raise Exception(
"Error: Wrong Version of ResInsight at ",
location,
self.version_string(),
"Executable : " + self.version_string(),
" ",
self.client_version_string(),
"rips : " + self.client_version_string(),
)
def __version_message(self) -> App_pb2.Version:

View File

@ -63,7 +63,12 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu
return;
}
#if OCTAVE_MAJOR_VERSION > 6
auto internalMatrixData = (qint32*)activeCellInfo.fortran_vec();
#else
qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data();
#endif
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages))
{

View File

@ -63,7 +63,12 @@ void getSelectedCells(int32NDArray& selectedCellInfo, const QString &hostName, q
return;
}
#if OCTAVE_MAJOR_VERSION > 6
auto internalMatrixData = (qint32*)selectedCellInfo.fortran_vec();
#else
qint32* internalMatrixData = (qint32*)selectedCellInfo.fortran_vec()->mex_get_data();
#endif
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages))
{

View File

@ -54,7 +54,11 @@ void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, q
socketStream << (qint64)(timeStepCount);
socketStream << (qint64)timeStepByteCount;
#if OCTAVE_MAJOR_VERSION > 6
auto internalData = propertyFrames.data();
#else
const double* internalData = propertyFrames.fortran_vec();
#endif
QStringList errorMessages;
if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepByteCount*timeStepCount, errorMessages))
@ -135,15 +139,6 @@ DEFUN_DLD (riSetActiveCellProperty, args, nargout,
Matrix propertyFrames = args(0).matrix_value();
if (error_state)
{
error("riSetActiveCellProperty: The supplied first argument is not a valid Matrix");
print_usage();
return octave_value_list ();
}
dim_vector mxDims = propertyFrames.dims();
if (mxDims.length() != 2)
{

View File

@ -71,7 +71,11 @@ void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName,
socketStream << (qint64)(timeStepCount);
socketStream << (qint64)singleTimeStepByteCount;
#if OCTAVE_MAJOR_VERSION > 6
auto internalData = propertyFrames.data();
#else
const double* internalData = propertyFrames.fortran_vec();
#endif
QStringList errorMessages;
if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepCount*singleTimeStepByteCount, errorMessages))
@ -155,14 +159,6 @@ DEFUN_DLD (riSetGridProperty, args, nargout,
NDArray propertyFrames = args(0).array_value();
if (error_state)
{
error("riSetGridProperty: The supplied first argument is not a valid Matrix");
print_usage();
return octave_value_list ();
}
dim_vector mxDims = propertyFrames.dims();
if (!(mxDims.length() == 3 || mxDims.length() == 4))

View File

@ -135,14 +135,6 @@ DEFUN_DLD (riSetNNCProperty, args, nargout,
Matrix propertyFrames = args(0).matrix_value();
if (error_state)
{
error("riSetNNCProperty: The supplied first argument is not a valid Matrix");
print_usage();
return octave_value_list ();
}
dim_vector mxDims = propertyFrames.dims();
if (mxDims.length() != 2)

View File

@ -11,7 +11,7 @@ set(RESINSIGHT_VERSION_TEXT "-dev")
# Must be unique and increasing within one combination of major/minor/patch version
# The uniqueness of this text is independent of RESINSIGHT_VERSION_TEXT
# Format of text must be ".xx"
set(RESINSIGHT_DEV_VERSION ".07")
set(RESINSIGHT_DEV_VERSION ".10")
# https://github.com/CRAVA/crava/tree/master/libs/nrlib
set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f")

1
ThirdParty/spdlog vendored Submodule

@ -0,0 +1 @@
Subproject commit 8979f7fb2a119754e5fe7fe6d8155f67d934316a