mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge branch 'dev' into sigurdp/vizfwk-qopenglwidget
This commit is contained in:
commit
a0a4e2516c
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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})
|
||||
|
152
ApplicationLibCode/Application/Tools/RiaFileLogger.cpp
Normal file
152
ApplicationLibCode/Application/Tools/RiaFileLogger.cpp
Normal 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 );
|
||||
}
|
45
ApplicationLibCode/Application/Tools/RiaFileLogger.h
Normal file
45
ApplicationLibCode/Application/Tools/RiaFileLogger.h
Normal 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;
|
||||
};
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
|
@ -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 } );
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
@ -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 );
|
||||
}
|
@ -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;
|
||||
};
|
@ -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 );
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 };
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
# ##############################################################################
|
||||
|
@ -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:
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
1
ThirdParty/spdlog
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 8979f7fb2a119754e5fe7fe6d8155f67d934316a
|
Loading…
Reference in New Issue
Block a user