Merge remote-tracking branch 'origin/dev' into pre-proto

This commit is contained in:
Magne Sjaastad
2017-08-21 10:42:11 +02:00
668 changed files with 11424 additions and 3918 deletions

View File

@@ -1173,7 +1173,7 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName)
//if (!riv->cellResult()->hasResult())
//{
// riv->cellResult()->setResultVariable(RiaEclipseUnitTools::undefinedResultName());
// riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
//}
progress.incrementProgress();
progress.setProgressDescription("Loading results information");

View File

@@ -30,6 +30,7 @@ namespace caf
{
addItem(RiaDefines::DYNAMIC_NATIVE, "DYNAMIC_NATIVE", "Dynamic");
addItem(RiaDefines::STATIC_NATIVE, "STATIC_NATIVE", "Static");
addItem(RiaDefines::SOURSIMRL, "SOURSIMRL", "SourSimRL");
addItem(RiaDefines::GENERATED, "GENERATED", "Generated");
addItem(RiaDefines::INPUT_PROPERTY, "INPUT_PROPERTY", "Input Property");
addItem(RiaDefines::FORMATION_NAMES, "FORMATION_NAMES", "Formation Names");
@@ -99,6 +100,22 @@ bool RiaDefines::isPerCellFaceResult(const QString& resultName)
{
return true;
}
else if (resultName.compare(RiaDefines::combinedWaterFluxResultName(), Qt::CaseInsensitive) == 0)
{
return true;
}
else if (resultName.compare(RiaDefines::combinedOilFluxResultName(), Qt::CaseInsensitive) == 0)
{
return true;
}
else if (resultName.compare(RiaDefines::combinedGasFluxResultName(), Qt::CaseInsensitive) == 0)
{
return true;
}
else if (resultName.endsWith("IJK"))
{
return true;
}
return false;
}
@@ -135,6 +152,30 @@ QString RiaDefines::combinedTransmissibilityResultName()
return "TRANXYZ";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::combinedWaterFluxResultName()
{
return "FLRWATIJK";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::combinedOilFluxResultName()
{
return "FLROILIJK";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::combinedGasFluxResultName()
{
return "FLRGASIJK";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -28,6 +28,7 @@ namespace RiaDefines
{
DYNAMIC_NATIVE,
STATIC_NATIVE,
SOURSIMRL,
GENERATED,
INPUT_PROPERTY,
FORMATION_NAMES,
@@ -48,6 +49,10 @@ namespace RiaDefines
QString undefinedGridFaultName();
QString undefinedGridFaultWithInactiveName();
QString combinedTransmissibilityResultName();
QString combinedWaterFluxResultName();
QString combinedOilFluxResultName();
QString combinedGasFluxResultName();
QString ternarySaturationResultName();
QString combinedMultResultName();

View File

@@ -27,7 +27,6 @@ include_directories(
${ResInsight_SOURCE_DIR}/ThirdParty
${ResInsight_SOURCE_DIR}/ThirdParty/NRLib/nrlib/well
${ResInsight_SOURCE_DIR}/ThirdParty/Qwt/src
${ERT_INCLUDE_DIRS}
${boost-Subset_SOURCE_DIR}
${custom-opm-flowdiagnostics_SOURCE_DIR}/opm-flowdiagnostics/
@@ -77,6 +76,7 @@ set( SOCKET_INTERFACE_FILES
SocketInterface/RiaProjectInfoCommands.cpp
SocketInterface/RiaCaseInfoCommands.cpp
SocketInterface/RiaGeometryCommands.cpp
SocketInterface/RiaNNCCommands.cpp
SocketInterface/RiaPropertyDataCommands.cpp
SocketInterface/RiaWellDataCommands.cpp
SocketInterface/RiaSocketTools.cpp
@@ -174,6 +174,21 @@ endif()
add_subdirectory(GeoMech/GeoMechDataModel)
#
# HDF5
#
if (${RESINSIGHT_FOUND_HDF5})
list( APPEND CPP_SOURCES
FileInterface/RifHdf5Reader.h
FileInterface/RifHdf5Reader.cpp
)
source_group( "FileInterface" FILES FileInterface/RifHdf5Reader.h FileInterface/RifHdf5Reader.cpp )
add_definitions(-DUSE_HDF5)
endif()
#############################################################################
# Qt specifics: Moc, ui, resources
#############################################################################
@@ -251,6 +266,9 @@ set( EXE_FILES
add_executable( ResInsight ${EXE_FILES} )
if (MSVC)
set_target_properties(ResInsight PROPERTIES COMPILE_FLAGS "/wd4190")
endif()
#############################################################################
# Application icon for MacOS X bundle
@@ -283,20 +301,15 @@ set( LINK_LIBRARIES
${APP_FWK_LIBRARIES}
${VIZ_FWK_LIBRARIES}
${ERT_LIBRARIES}
${THIRD_PARTY_LIBRARIES}
${OPENGL_LIBRARIES}
${QT_LIBRARIES}
)
set( EXTERNAL_LINK_LIBRARIES ${ERT_LIBRARY_LIST} )
# According to ivarun this is needed on OpenSuse, and Fedora. See: https://github.com/OPM/ResInsight/pull/7
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set ( EXTERNAL_LINK_LIBRARIES
${EXTERNAL_LINK_LIBRARIES}
list(APPEND EXTERNAL_LINK_LIBRARIES
rt
)
endif()
@@ -314,32 +327,29 @@ target_link_libraries( ResInsight ${LINK_LIBRARIES} ${EXTERNAL_LINK_LIBRARIES})
#############################################################################
if(RESINSIGHT_ENABLE_COTIRE)
# forever is used as variable name, and this symbol is defined by Qt and used in precompiled headers
set_source_files_properties (${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc PROPERTIES COTIRE_EXCLUDED TRUE)
# multiple QRC files are not supported
set_source_files_properties (qrc_cafAnimControl.cxx PROPERTIES COTIRE_EXCLUDED TRUE)
# variables at global file scope
set_source_files_properties (ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set_source_files_properties (ModelVisualization/Intersections/RivIntersectionPartMgr.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set_source_files_properties (ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set( COTIRE_EXCLUDE_FILES
# forever is used as variable name, and this symbol is defined by Qt and used in precompiled headers
${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc
set_source_files_properties (ModelVisualization/GridBox/RivGridBoxGenerator.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set_source_files_properties (Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
# multiple QRC files are not supported
qrc_cafAnimControl.cxx
qrc_ResInsight.cxx
# using namespace cvf
set_source_files_properties (GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set_source_files_properties (UnitTests/cvfGeometryTools-Test.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
# mix of cvf and Qt namespaces
ModelVisualization/GridBox/RivGridBoxGenerator.cpp
ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp
# opm parser
set_source_files_properties (ProjectDataModel/RimProject.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
# exclude file using Eigen
ReservoirDataModel/RigTransmissibilityCondenser.cpp
ReservoirDataModel/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp
ReservoirDataModel/RigCellGeometryTools.cpp
)
# exclude file using Eigen
set_source_files_properties (ReservoirDataModel/RigTransmissibilityCondenser.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set_source_files_properties (ReservoirDataModel/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
set_source_files_properties (ReservoirDataModel/RigCellGeometryTools.cpp PROPERTIES COTIRE_EXCLUDED TRUE)
foreach (fileToExclude ${COTIRE_EXCLUDE_FILES})
set_source_files_properties (${fileToExclude} PROPERTIES COTIRE_EXCLUDED TRUE)
endforeach(fileToExclude)
# disable precompiled headers
set_target_properties(ResInsight PROPERTIES COTIRE_ENABLE_PRECOMPILED_HEADER FALSE)
cotire(ResInsight)
@@ -357,8 +367,19 @@ endif()
# Copy Dlls on MSVC
#############################################################################
# Copy Odb Dlls
# Qt DLLs
if (MSVC)
set (QTLIBLIST QtCore QtCored QtGui QtGuid QtOpenGl QtOpenGld QtNetwork QtNetworkd QtScript QtScriptd QtScriptTools QtScriptToolsd)
foreach (qtlib ${QTLIBLIST})
list(APPEND FILES_TO_COPY ${QT_BINARY_DIR}/${qtlib}4.dll)
endforeach( qtlib )
endif(MSVC)
# Odb Dlls
if ((MSVC) AND (${RESINSIGHT_USE_ODB_API}))
# Find all the dlls
file (GLOB RI_ALL_ODB_DLLS ${RESINSIGHT_ODB_API_DIR}/lib/*.dll)
@@ -369,41 +390,26 @@ if ((MSVC) AND (${RESINSIGHT_USE_ODB_API}))
list(APPEND RI_ODB_DLLS ${filenameWithExt} )
endforeach(aDLL)
# Copy to target directory
foreach (aDLL ${RI_ODB_DLLS})
add_custom_command(TARGET ResInsight POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${RESINSIGHT_ODB_API_DIR}/lib/${aDLL}"
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
if (_unityTargetName)
add_custom_command(TARGET ${_unityTargetName} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${RESINSIGHT_ODB_API_DIR}/lib/${aDLL}"
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
endif()
list(APPEND FILES_TO_COPY ${RESINSIGHT_ODB_API_DIR}/lib/${aDLL})
endforeach()
endif()
# Qt DLLs
# Copy to target directory
foreach (FILE_TO_COPY ${FILES_TO_COPY})
add_custom_command(TARGET ResInsight POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${FILE_TO_COPY}"
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
if (_unityTargetName)
add_custom_command(TARGET ${_unityTargetName} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${FILE_TO_COPY}"
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
endif()
endforeach()
if (MSVC)
set (QTLIBLIST QtCore QtCored QtGui QtGuid QtOpenGl QtOpenGld QtNetwork QtNetworkd QtScript QtScriptd QtScriptTools QtScriptToolsd)
foreach (qtlib ${QTLIBLIST})
add_custom_command(TARGET ResInsight POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${QT_BINARY_DIR}/${qtlib}4.dll"
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
if (_unityTargetName)
add_custom_command(TARGET ResInsight POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${QT_BINARY_DIR}/${qtlib}4.dll"
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
endif()
endforeach( qtlib )
endif(MSVC)
#############################################################################
# Install

View File

@@ -32,6 +32,7 @@ ${CEE_CURRENT_LIST_DIR}RicImportGeoMechCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicImportSummaryCaseFeature.h
${CEE_CURRENT_LIST_DIR}RicExportFeatureImpl.h
${CEE_CURRENT_LIST_DIR}RicSelectOrCreateViewFeatureImpl.h
${CEE_CURRENT_LIST_DIR}RicNewSimWellFractureFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSimWellFractureAtPosFeature.h
${CEE_CURRENT_LIST_DIR}RicNewEllipseFractureTemplateFeature.h
@@ -57,6 +58,8 @@ ${CEE_CURRENT_LIST_DIR}RicDeleteItemExecData.h
${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.h
${CEE_CURRENT_LIST_DIR}RicDeleteSubItemsFeature.h
${CEE_CURRENT_LIST_DIR}RicCloseSourSimDataFeature.h
${CEE_CURRENT_LIST_DIR}RicCommandFeature.h
${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.h
@@ -88,6 +91,7 @@ ${CEE_CURRENT_LIST_DIR}RicImportGeoMechCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicImportSummaryCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicExportFeatureImpl.cpp
${CEE_CURRENT_LIST_DIR}RicSelectOrCreateViewFeatureImpl.cpp
${CEE_CURRENT_LIST_DIR}RicNewSimWellFractureFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSimWellFractureAtPosFeature.cpp
@@ -116,6 +120,8 @@ ${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.cpp
${CEE_CURRENT_LIST_DIR}RicDeleteSubItemsFeature.cpp
${CEE_CURRENT_LIST_DIR}RicCloseSourSimDataFeature.cpp
${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicFlyToObjectFeature.cpp
)

View File

@@ -5,6 +5,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "2.8.2")
endif()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RicAddStoredFlowCharacteristicsPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicShowWellAllocationPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicShowFlowCharacteristicsPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature.h
@@ -17,6 +18,7 @@ ${CEE_CURRENT_LIST_DIR}RicShowTotalAllocationDataFeature.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RicAddStoredFlowCharacteristicsPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicShowWellAllocationPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicShowFlowCharacteristicsPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature.cpp

View File

@@ -0,0 +1,99 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RicAddStoredFlowCharacteristicsPlotFeature.h"
#include "RiaApplication.h"
#include "RimFlowPlotCollection.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RiuMainPlotWindow.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include <QAction>
CAF_CMD_SOURCE_INIT(RicAddStoredFlowCharacteristicsPlotFeature, "RicAddStoredFlowCharacteristicsPlotFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicAddStoredFlowCharacteristicsPlotFeature::isCommandEnabled()
{
if (RiaApplication::instance()->project())
{
RimFlowPlotCollection* flowPlotColl = RiaApplication::instance()->project()->mainPlotCollection->flowPlotCollection();
if (flowPlotColl)
{
RimFlowCharacteristicsPlot* flowCharacteristicsPlot = dynamic_cast<RimFlowCharacteristicsPlot*>(caf::SelectionManager::instance()->selectedItem());
if (flowPlotColl->defaultFlowCharacteristicsPlot() == flowCharacteristicsPlot)
{
return true;
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicAddStoredFlowCharacteristicsPlotFeature::onActionTriggered(bool isChecked)
{
if (RiaApplication::instance()->project())
{
RimFlowPlotCollection* flowPlotColl = RiaApplication::instance()->project()->mainPlotCollection->flowPlotCollection();
if (flowPlotColl)
{
RimFlowCharacteristicsPlot* sourceObject = dynamic_cast<RimFlowCharacteristicsPlot*>(caf::SelectionManager::instance()->selectedItem());
RimFlowCharacteristicsPlot* flowCharacteristicsPlot = dynamic_cast<RimFlowCharacteristicsPlot*>(sourceObject->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance()));
CVF_ASSERT(flowCharacteristicsPlot);
flowPlotColl->addFlowCharacteristicsPlotToStoredPlots(flowCharacteristicsPlot);
flowCharacteristicsPlot->resolveReferencesRecursively();
flowCharacteristicsPlot->loadDataAndUpdate();
flowPlotColl->updateConnectedEditors();
RiuMainPlotWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow();
if (mainPlotWindow)
{
mainPlotWindow->selectAsCurrentItem(flowCharacteristicsPlot);
mainPlotWindow->setExpanded(flowCharacteristicsPlot, true);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicAddStoredFlowCharacteristicsPlotFeature::setupActionLook(QAction* actionToSetup)
{
//actionToSetup->setIcon(QIcon(":/new_icon16x16.png"));
actionToSetup->setText("Add Stored Well Allocation Plot");
}

View File

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

View File

@@ -20,7 +20,7 @@
#include "RiaApplication.h"
#include "RicSelectViewUI.h"
#include "RicSelectOrCreateViewFeatureImpl.h"
#include "RigFlowDiagResultAddress.h"
#include "RigSingleWellResultsData.h"
@@ -41,84 +41,13 @@
#include "cafCmdFeature.h"
#include "cafCmdFeatureManager.h"
#include "cafPdmUiPropertyViewDialog.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseView* RicShowContributingWellsFeatureImpl::maniuplateSelectedView(RimEclipseResultCase* eclipseResultCase, QString wellName, int timeStep)
{
const QString lastUsedViewKey("lastUsedViewKey");
RimEclipseView* defaultSelectedView = nullptr;
{
QString lastUsedViewRef = RiaApplication::instance()->cacheDataObject(lastUsedViewKey).toString();
RimEclipseView* lastUsedView = dynamic_cast<RimEclipseView*>(caf::PdmReferenceHelper::objectFromReference(RiaApplication::instance()->project(), lastUsedViewRef));
if (lastUsedView)
{
RimEclipseResultCase* lastUsedViewResultCase = nullptr;
lastUsedView->firstAncestorOrThisOfTypeAsserted(lastUsedViewResultCase);
if (lastUsedViewResultCase == eclipseResultCase)
{
defaultSelectedView = lastUsedView;
}
}
if (!defaultSelectedView)
{
RimEclipseView* activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeReservoirView());
if (activeView)
{
RimEclipseResultCase* activeViewResultCase = nullptr;
activeView->firstAncestorOrThisOfTypeAsserted(activeViewResultCase);
if (activeViewResultCase == eclipseResultCase)
{
defaultSelectedView = activeView;
}
else
{
if (eclipseResultCase->views().size() > 0)
{
defaultSelectedView = dynamic_cast<RimEclipseView*>(eclipseResultCase->views()[0]);
}
}
}
}
}
RicSelectViewUI featureUi;
if (defaultSelectedView)
{
featureUi.setView(defaultSelectedView);
}
else
{
featureUi.setCase(eclipseResultCase);
}
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &featureUi, "Show Contributing Wells in View", "");
propertyDialog.resize(QSize(400, 200));
if (propertyDialog.exec() != QDialog::Accepted) return nullptr;
RimEclipseView* viewToManipulate = nullptr;
if (featureUi.createNewView())
{
RimEclipseView* createdView = eclipseResultCase->createAndAddReservoirView();
createdView->name = featureUi.newViewName();
// Must be run before buildViewItems, as wells are created in this function
createdView->loadDataAndUpdate();
eclipseResultCase->updateConnectedEditors();
viewToManipulate = createdView;
}
else
{
viewToManipulate = featureUi.selectedView();
}
RimEclipseView* viewToManipulate = RicSelectOrCreateViewFeatureImpl::showViewSelection(eclipseResultCase, "lastUsedWellAllocationView", "Show Contributing Wells in View");
CVF_ASSERT(viewToManipulate);
@@ -128,11 +57,7 @@ RimEclipseView* RicShowContributingWellsFeatureImpl::maniuplateSelectedView(RimE
auto* feature = caf::CmdFeatureManager::instance()->getCommandFeature("RicShowMainWindowFeature");
feature->actionTriggered(false);
RiuMainWindow::instance()->setExpanded(viewToManipulate, true);
RiuMainWindow::instance()->selectAsCurrentItem(viewToManipulate);
QString refFromProjectToView = caf::PdmReferenceHelper::referenceFromRootToObject(RiaApplication::instance()->project(), viewToManipulate);
RiaApplication::instance()->setCacheDataObject(lastUsedViewKey, refFromProjectToView);
RicSelectOrCreateViewFeatureImpl::focusView(viewToManipulate);
return viewToManipulate;
}

View File

@@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RicCloseSourSimDataFeature.h"
#include "RimEclipseResultCase.h"
#include "cafSelectionManager.h"
#include <QAction>
CAF_CMD_SOURCE_INIT(RicCloseSourSimDataFeature, "RicCloseSourSimDataFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicCloseSourSimDataFeature::isCommandEnabled()
{
return getSelectedEclipseCase() != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCloseSourSimDataFeature::onActionTriggered(bool isChecked)
{
RimEclipseResultCase* eclipseCase = getSelectedEclipseCase();
if (eclipseCase == nullptr) return;
eclipseCase->setSourSimFileName(QString());
eclipseCase->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCloseSourSimDataFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setText("Close SourSim Data");
actionToSetup->setIcon(QIcon(":/Erase.png"));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseResultCase* RicCloseSourSimDataFeature::getSelectedEclipseCase()
{
caf::PdmUiItem* selectedItem = caf::SelectionManager::instance()->selectedItem();
RimEclipseResultCase* eclipseCase = dynamic_cast<RimEclipseResultCase*>(selectedItem);
return eclipseCase;
}

View File

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

View File

@@ -49,6 +49,8 @@
#include "RimWellLogTrack.h"
#include "RimFishboneWellPath.h"
#include "RimPerforationInterval.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimAsciiDataCurve.h"
#include "RimWellPathFracture.h"
#include "RimWellPathFractureCollection.h"
@@ -67,6 +69,7 @@ bool isDeletable(caf::PdmUiItem* uiItem)
{
// Enable delete of well allocation plots
if (dynamic_cast<RimWellAllocationPlot*>(uiItem)) return true;
if (dynamic_cast<RimFlowCharacteristicsPlot*>(uiItem)) return true;
// Disable delete of all sub objects of a well allocation plot
caf::PdmObjectHandle* destinationObject = dynamic_cast<caf::PdmObjectHandle*>(uiItem);
@@ -99,9 +102,10 @@ bool isDeletable(caf::PdmUiItem* uiItem)
if (dynamic_cast<RimIntersectionBox*>(uiItem)) return true;
if (dynamic_cast<RimFormationNames*>(uiItem)) return true;
if (dynamic_cast<RimFormationNamesCollection*>(uiItem)) return true;
if (dynamic_cast<RimFishboneWellPath*>(uiItem)) return true;
if (dynamic_cast<RimFishboneWellPath*>(uiItem)) return true;
if (dynamic_cast<RimFishbonesMultipleSubs*>(uiItem)) return true;
if (dynamic_cast<RimPerforationInterval*>(uiItem)) return true;
if (dynamic_cast<RimAsciiDataCurve*>(uiItem)) return true;
if (dynamic_cast<RimWellPathFractureCollection*>(uiItem)) return true;
if (dynamic_cast<RimWellPathFracture*>(uiItem)) return true;
if (dynamic_cast<RimEllipseFractureTemplate*>(uiItem)) return true;

View File

@@ -0,0 +1,131 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RicSelectOrCreateViewFeatureImpl.h"
#include "FlowCommands/RicSelectViewUI.h"
#include "RiaApplication.h"
#include "RimProject.h"
#include "RimEclipseView.h"
#include "RimEclipseResultCase.h"
#include "RiuMainWindow.h"
#include "cafPdmUiPropertyViewDialog.h"
//==================================================================================================
///
//==================================================================================================
RimEclipseView* RicSelectOrCreateViewFeatureImpl::showViewSelection(RimEclipseResultCase* resultCase, const QString& lastUsedViewKey, const QString& dialogTitle)
{
RimEclipseView* defaultSelectedView = getDefaultSelectedView(resultCase, lastUsedViewKey);
RicSelectViewUI featureUi;
if (defaultSelectedView)
{
featureUi.setView(defaultSelectedView);
}
else
{
featureUi.setCase(resultCase);
}
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &featureUi, dialogTitle, "");
propertyDialog.resize(QSize(400, 200));
if (propertyDialog.exec() != QDialog::Accepted) return nullptr;
RimEclipseView* viewToManipulate = nullptr;
if (featureUi.createNewView())
{
RimEclipseView* createdView = resultCase->createAndAddReservoirView();
createdView->name = featureUi.newViewName();
// Must be run before buildViewItems, as wells are created in this function
createdView->loadDataAndUpdate();
resultCase->updateConnectedEditors();
viewToManipulate = createdView;
}
else
{
viewToManipulate = featureUi.selectedView();
}
QString refFromProjectToView = caf::PdmReferenceHelper::referenceFromRootToObject(RiaApplication::instance()->project(), viewToManipulate);
RiaApplication::instance()->setCacheDataObject(lastUsedViewKey, refFromProjectToView);
return viewToManipulate;
}
//==================================================================================================
///
//==================================================================================================
void RicSelectOrCreateViewFeatureImpl::focusView(RimEclipseView* view)
{
RiuMainWindow::instance()->setExpanded(view, true);
RiuMainWindow::instance()->selectAsCurrentItem(view);
RiuMainWindow::instance()->raise();
}
//==================================================================================================
///
//==================================================================================================
RimEclipseView* RicSelectOrCreateViewFeatureImpl::getDefaultSelectedView(RimEclipseResultCase* resultCase, const QString& lastUsedViewKey)
{
RimEclipseView* defaultSelectedView = nullptr;
QString lastUsedViewRef = RiaApplication::instance()->cacheDataObject(lastUsedViewKey).toString();
RimEclipseView* lastUsedView = dynamic_cast<RimEclipseView*>(caf::PdmReferenceHelper::objectFromReference(RiaApplication::instance()->project(), lastUsedViewRef));
if (lastUsedView)
{
RimEclipseResultCase* lastUsedViewResultCase = nullptr;
lastUsedView->firstAncestorOrThisOfTypeAsserted(lastUsedViewResultCase);
if (lastUsedViewResultCase == resultCase)
{
defaultSelectedView = lastUsedView;
}
}
if (!defaultSelectedView)
{
RimEclipseView* activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeReservoirView());
if (activeView)
{
RimEclipseResultCase* activeViewResultCase = nullptr;
activeView->firstAncestorOrThisOfTypeAsserted(activeViewResultCase);
if (activeViewResultCase == resultCase)
{
defaultSelectedView = activeView;
}
else
{
if (resultCase->views().size() > 0)
{
defaultSelectedView = dynamic_cast<RimEclipseView*>(resultCase->views()[0]);
}
}
}
}
return defaultSelectedView;
}

View File

@@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 <QString>
class RimEclipseView;
class RimEclipseResultCase;
//==================================================================================================
///
//==================================================================================================
class RicSelectOrCreateViewFeatureImpl
{
public:
static RimEclipseView* showViewSelection(RimEclipseResultCase* resultCase, const QString& lastUsedViewKey, const QString& dialogTitle);
static void focusView(RimEclipseView* view);
private:
static RimEclipseView* getDefaultSelectedView(RimEclipseResultCase* resultCase, const QString& lastUsedViewKey);
};

View File

@@ -9,6 +9,8 @@ set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RicNewSummaryPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFilterFeature.h
${CEE_CURRENT_LIST_DIR}RicPasteAsciiDataToSummaryPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicPasteAsciiDataToSummaryPlotFeatureUi.h
${CEE_CURRENT_LIST_DIR}RicViewZoomAllFeature.h
${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.h
${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.h
@@ -23,6 +25,8 @@ set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RicNewSummaryPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFilterFeature.cpp
${CEE_CURRENT_LIST_DIR}RicPasteAsciiDataToSummaryPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicPasteAsciiDataToSummaryPlotFeatureUi.cpp
${CEE_CURRENT_LIST_DIR}RicViewZoomAllFeature.cpp
${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.cpp
${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.cpp

View File

@@ -93,7 +93,7 @@ void RicNewSummaryPlotFeature::setupActionLook(QAction* actionToSetup)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewSummaryPlotFeature::createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase)
RimSummaryPlot* RicNewSummaryPlotFeature::createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase)
{
RimSummaryPlot* plot = new RimSummaryPlot();
summaryPlotColl->summaryPlots().push_back(plot);
@@ -118,4 +118,6 @@ void RicNewSummaryPlotFeature::createNewSummaryPlot(RimSummaryPlotCollection* su
mainPlotWindow->selectAsCurrentItem(newCurveFilter);
mainPlotWindow->setExpanded(newCurveFilter, true);
}
return plot;
}

View File

@@ -22,6 +22,7 @@
class RimSummaryCase;
class RimSummaryPlotCollection;
class RimSummaryPlot;
//==================================================================================================
///
@@ -31,7 +32,7 @@ class RicNewSummaryPlotFeature : public caf::CmdFeature
CAF_CMD_HEADER_INIT;
public:
static void createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase);
static RimSummaryPlot* createNewSummaryPlot(RimSummaryPlotCollection* summaryPlotColl, RimSummaryCase* summaryCase);
protected:
// Overrides

View File

@@ -0,0 +1,291 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RicPasteAsciiDataToSummaryPlotFeature.h"
#include "OperationsUsingObjReferences/RicPasteFeatureImpl.h"
#include "RicNewSummaryPlotFeature.h"
#include "RicPasteAsciiDataToSummaryPlotFeatureUi.h"
#include "RiaLogging.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimAsciiDataCurve.h"
#include "RimSummaryCurveAppearanceCalculator.h"
#include "cafPdmDefaultObjectFactory.h"
#include "cafPdmDocument.h"
#include "cafPdmObjectGroup.h"
#include "cafSelectionManager.h"
#include "cafPdmUiPropertyViewDialog.h"
#include "cafPdmSettings.h"
#include "cvfAssert.h"
#include "cvfColor3.h"
#include <QApplication>
#include <QAction>
#include <QClipboard>
#include <QMimeData>
CAF_CMD_SOURCE_INIT(RicPasteAsciiDataToSummaryPlotFeature, "RicPasteExcelToSummaryPlotFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicPasteAsciiDataToSummaryPlotFeature::isCommandEnabled()
{
caf::PdmObjectHandle* destinationObject = dynamic_cast<caf::PdmObjectHandle*>(caf::SelectionManager::instance()->selectedItem());
RimSummaryPlot* summaryPlot = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlot);
if (!summaryPlot)
{
RimSummaryPlotCollection* summaryPlotCollection = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlotCollection);
if (!summaryPlotCollection)
{
return false;
}
}
return hasPastedText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicPasteAsciiDataToSummaryPlotFeature::onActionTriggered(bool isChecked)
{
caf::PdmObjectHandle* destinationObject = dynamic_cast<caf::PdmObjectHandle*>(caf::SelectionManager::instance()->selectedItem());
RimSummaryPlot* summaryPlot = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlot);
RicPasteAsciiDataToSummaryPlotFeatureUi pasteOptions;
if (!summaryPlot) pasteOptions.createNewPlot();
caf::PdmSettings::readFieldsFromApplicationStore(&pasteOptions);
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &pasteOptions, "Set Paste Options", "");
if (propertyDialog.exec() != QDialog::Accepted) return;
if (!summaryPlot)
{
RimSummaryPlotCollection* summaryPlotCollection = nullptr;
destinationObject->firstAncestorOrThisOfType(summaryPlotCollection);
if (!summaryPlotCollection)
{
return;
}
summaryPlot = RicNewSummaryPlotFeature::createNewSummaryPlot(summaryPlotCollection, nullptr);
if (!summaryPlot)
{
return;
}
summaryPlot->setDescription(pasteOptions.plotTitle());
}
caf::PdmSettings::writeFieldsToApplicationStore(&pasteOptions);
QString text = getPastedData();
std::vector<RimAsciiDataCurve*> curves = parseCurves(text, pasteOptions);
for (RimAsciiDataCurve* curve : curves)
{
summaryPlot->addAsciiDataCruve(curve);
}
summaryPlot->updateConnectedEditors();
summaryPlot->loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicPasteAsciiDataToSummaryPlotFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setText("Paste Excel Data to Summary Curve");
RicPasteFeatureImpl::setIconAndShortcuts(actionToSetup);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicPasteAsciiDataToSummaryPlotFeature::getPastedData()
{
if (hasPastedText())
{
QClipboard* clipboard = QApplication::clipboard();
return clipboard->text();
}
return QString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicPasteAsciiDataToSummaryPlotFeature::hasPastedText()
{
QClipboard* clipboard = QApplication::clipboard();
const QMimeData* mimeData = clipboard->mimeData();
return mimeData->hasText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimAsciiDataCurve*> RicPasteAsciiDataToSummaryPlotFeature::parseCurves(QString& data, const RicPasteAsciiDataToSummaryPlotFeatureUi& settings)
{
std::vector<RimAsciiDataCurve*> curves;
std::vector<QString> headers;
QTextStream tableData(&data);
{
QString header;
do {
header = tableData.readLine();
} while (header.isEmpty() && !tableData.atEnd());
// No header row found
if (header.isEmpty()) return curves;
QStringList columnHeaders = header.split('\t');
for (size_t i = 1; i < columnHeaders.size(); ++i)
{
headers.push_back(columnHeaders[static_cast<int>(i)]);
}
// No columns found
if (headers.empty()) return curves;
}
size_t numColumns = headers.size();
std::vector<QDateTime> timeSteps;
std::vector< std::vector<double> > values;
values.resize(numColumns);
size_t row = 0;
while (!tableData.atEnd())
{
++row;
QString line = tableData.readLine();
// Skip empty lines
if (line.isEmpty()) continue;
QStringList columns = line.split(settings.cellSeparator());
if (columns.size() != numColumns + 1)
{
RiaLogging::warning(QString("Invalid number of columns in row %1").arg(row));
continue;
}
QDateTime date = QDateTime::fromString(columns[0], settings.dateFormat());
if (!date.isValid())
{
RiaLogging::warning(QString("First column of row %1 could not be parsed as a date: %2").arg(row).arg(columns[0]));
continue;
}
timeSteps.push_back(date);
for (size_t col = 1; col < columns.size(); ++col)
{
bool ok;
values[col - 1].push_back(settings.decimalLocale().toDouble(columns[static_cast<int>(col)], &ok));
if (!ok)
{
RiaLogging::warning(QString("Could not parse value at row %1 column %2 as double: %3. Defaulting to 0.0").arg(row).arg(col).arg(columns[static_cast<int>(col)]));
}
}
}
std::map< CurveType, std::vector<RimAsciiDataCurve*> > curveToTypeMap;
QString curvePrefix = settings.curvePrefix();
for (size_t i = 0; i < values.size(); ++i)
{
RimAsciiDataCurve* curve = new RimAsciiDataCurve();
curve->setTimeSteps(timeSteps);
curve->setValues(values[i]);
if (curvePrefix.isEmpty())
{
curve->setTitle(headers[i]);
}
else
{
curve->setTitle(QString("%1: %2").arg(curvePrefix).arg(headers[i]));
}
curveToTypeMap[guessCurveType(headers[i])].push_back(curve);
curves.push_back(curve);
}
for (auto& it : curveToTypeMap)
{
for (int i = 0; i < it.second.size(); ++i)
{
cvf::Color3f color;
switch (it.first)
{
case CURVE_GAS:
color = RimSummaryCurveAppearanceCalculator::cycledGreenColor(i);
break;
case CURVE_OIL:
color = RimSummaryCurveAppearanceCalculator::cycledRedColor(i);
break;
case CURVE_WAT:
color = RimSummaryCurveAppearanceCalculator::cycledBlueColor(i);
break;
default:
color = RimSummaryCurveAppearanceCalculator::cycledNoneRGBBrColor(i);
break;
}
it.second[i]->setColor(color);
}
}
return curves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicPasteAsciiDataToSummaryPlotFeature::CurveType RicPasteAsciiDataToSummaryPlotFeature::guessCurveType(const QString& curveName)
{
if (curveName.contains("SW") || curveName.contains("water", Qt::CaseInsensitive))
{
return CURVE_WAT;
}
else if (curveName.contains("oil", Qt::CaseInsensitive))
{
return CURVE_OIL;
}
else if (curveName.contains("gas", Qt::CaseInsensitive))
{
return CURVE_GAS;
}
return CURVE_UNKNOWN;
}

View File

@@ -0,0 +1,62 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
#include "cafPdmPointer.h"
#include <vector>
#include <QDateTime>
class RimSummaryCurve;
class RimSummaryCurveFilter;
class RimAsciiDataCurve;
class RicPasteAsciiDataToSummaryPlotFeatureUi;
//==================================================================================================
///
//==================================================================================================
class RicPasteAsciiDataToSummaryPlotFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
enum CurveType
{
CURVE_GAS,
CURVE_OIL,
CURVE_WAT,
CURVE_UNKNOWN,
};
protected:
// Overrides
virtual bool isCommandEnabled() override;
virtual void onActionTriggered( bool isChecked ) override;
virtual void setupActionLook(QAction* actionToSetup) override;
private:
static QString getPastedData();
static bool hasPastedText();
static std::vector<RimAsciiDataCurve*> parseCurves(QString& data, const RicPasteAsciiDataToSummaryPlotFeatureUi& settings);
static CurveType guessCurveType(const QString& curveName);
};

View File

@@ -0,0 +1,194 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RicPasteAsciiDataToSummaryPlotFeatureUi.h"
namespace caf {
template<>
void RicPasteAsciiDataToSummaryPlotFeatureUi::DecimalSeparatorEnum::setUp()
{
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::DECIMAL_DOT, "DOT", "Dot: .");
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::DECIMAL_COMMA, "COMMA", "Comma: ,");
setDefault(RicPasteAsciiDataToSummaryPlotFeatureUi::DECIMAL_DOT);
}
template<>
void RicPasteAsciiDataToSummaryPlotFeatureUi::DateFormatEnum::setUp()
{
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::DATE_DDMMYYYY_DOT_SEPARATED, "dd.MM.yyyy", "Day.Month.Year (dd.MM.yyyy)");
setDefault(RicPasteAsciiDataToSummaryPlotFeatureUi::DATE_DDMMYYYY_DOT_SEPARATED);
}
template<>
void RicPasteAsciiDataToSummaryPlotFeatureUi::TimeFormatEnum::setUp()
{
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_NONE, "NONE", "None");
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMM, "hh:mm", "Hour:Minute (hh:mm)");
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMMSS, "hh:mm:ss", "Hour:Minute:Second (hh:mm:ss)");
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMMSSZZZ, "hh:mm:ss.zzz", "Hour:Minute:Second.Millisecond (hh:mm:ss.zzz)");
setDefault(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_NONE);
}
template<>
void RicPasteAsciiDataToSummaryPlotFeatureUi::CellSeparatorEnum::setUp()
{
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_TAB, "TAB", "Tab");
addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_COMMA, "COMMA", "Comma");
setDefault(RicPasteAsciiDataToSummaryPlotFeatureUi::CELL_TAB);
}
}
CAF_PDM_SOURCE_INIT(RicPasteAsciiDataToSummaryPlotFeatureUi, "RicPasteExcelToSummaryPlotFeatureUi");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicPasteAsciiDataToSummaryPlotFeatureUi::RicPasteAsciiDataToSummaryPlotFeatureUi() : m_createNewPlot(false)
{
CAF_PDM_InitObject("RicPasteAsciiDataToSummaryPlotFeatureUi", "", "", "");
CAF_PDM_InitField(&m_plotTitle, "PlotTitle", QString(), "Plot Title", "", "", "");
CAF_PDM_InitField(&m_curvePrefix, "CurvePrefix", QString(), "Curve Prefix", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_decimalSeparator, "DecimalSeparator", "Decimal Separator", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_dateFormat, "DateFormat", "Date Format", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_timeFormat, "TimeFormat", "Time Format", "", "", "");
CAF_PDM_InitField(&m_useCustomDateFormat, "UseCustomDateFormat", false, "Use Custom Date Format", "", "", "");
CAF_PDM_InitField(&m_customDateFormat, "CustomDateFormat", QString(), "Custom Date Format", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_cellSeparator, "CellSeparator", "Cell Separator", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicPasteAsciiDataToSummaryPlotFeatureUi::dateFormat() const
{
if (m_useCustomDateFormat())
{
return m_customDateFormat();
}
else
{
QString format = m_dateFormat().text();
if (m_timeFormat() != TIME_NONE)
{
format += " " + m_timeFormat().text();
}
return format;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QLocale RicPasteAsciiDataToSummaryPlotFeatureUi::decimalLocale() const
{
switch (m_decimalSeparator())
{
case DECIMAL_COMMA:
return QLocale::Norwegian;
case DECIMAL_DOT:
default:
return QLocale::c();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicPasteAsciiDataToSummaryPlotFeatureUi::cellSeparator() const
{
switch (m_cellSeparator())
{
case CELL_COMMA:
return ",";
case CELL_TAB:
default:
return "\t";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicPasteAsciiDataToSummaryPlotFeatureUi::plotTitle() const
{
return m_plotTitle();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicPasteAsciiDataToSummaryPlotFeatureUi::curvePrefix() const
{
return m_curvePrefix();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicPasteAsciiDataToSummaryPlotFeatureUi::createNewPlot()
{
m_createNewPlot = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
{
caf::PdmUiGroup* namingGroup = uiOrdering.addNewGroup("Naming");
if (m_createNewPlot)
{
namingGroup->add(&m_plotTitle);
}
namingGroup->add(&m_curvePrefix);
}
{
caf::PdmUiGroup* valuesGroup = uiOrdering.addNewGroup("Values");
valuesGroup->add(&m_decimalSeparator);
}
{
caf::PdmUiGroup* dateGroup = uiOrdering.addNewGroup("Dates");
dateGroup->add(&m_useCustomDateFormat);
if (m_useCustomDateFormat())
{
dateGroup->add(&m_customDateFormat);
}
else
{
dateGroup->add(&m_dateFormat);
dateGroup->add(&m_timeFormat);
}
}
{
caf::PdmUiGroup* cellGroup = uiOrdering.addNewGroup("Cells");
cellGroup->add(&m_cellSeparator);
}
uiOrdering.skipRemainingFields();
}

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "cafPdmObject.h"
#include "cafPdmField.h"
#include "cafAppEnum.h"
#include <QString>
#include <QLocale>
//==================================================================================================
///
//==================================================================================================
class RicPasteAsciiDataToSummaryPlotFeatureUi : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
enum DecimalSeparator
{
DECIMAL_COMMA,
DECIMAL_DOT,
};
typedef caf::AppEnum<DecimalSeparator> DecimalSeparatorEnum;
enum DateFormat
{
DATE_DDMMYYYY_DOT_SEPARATED,
};
typedef caf::AppEnum<DateFormat> DateFormatEnum;
enum TimeFormat
{
TIME_NONE,
TIME_HHMM,
TIME_HHMMSS,
TIME_HHMMSSZZZ,
};
typedef caf::AppEnum<TimeFormat> TimeFormatEnum;
enum CellSeparator
{
CELL_COMMA,
CELL_TAB,
};
typedef caf::AppEnum<CellSeparator> CellSeparatorEnum;
public:
RicPasteAsciiDataToSummaryPlotFeatureUi();
QString dateFormat() const;
QLocale decimalLocale() const;
QString cellSeparator() const;
QString plotTitle() const;
QString curvePrefix() const;
void createNewPlot();
protected:
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
private:
caf::PdmField<QString> m_plotTitle;
caf::PdmField<QString> m_curvePrefix;
caf::PdmField<DecimalSeparatorEnum> m_decimalSeparator;
caf::PdmField<DateFormatEnum> m_dateFormat;
caf::PdmField<TimeFormatEnum> m_timeFormat;
caf::PdmField<bool> m_useCustomDateFormat;
caf::PdmField<QString> m_customDateFormat;
caf::PdmField<CellSeparatorEnum> m_cellSeparator;
bool m_createNewPlot;
};

View File

@@ -22,6 +22,10 @@ ${CEE_CURRENT_LIST_DIR}RifReaderMockModel.h
${CEE_CURRENT_LIST_DIR}RifReaderSettings.h
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.h
${CEE_CURRENT_LIST_DIR}RifWellPathImporter.h
${CEE_CURRENT_LIST_DIR}RifHdf5ReaderInterface.h
# HDF5 file reader is directly included in ResInsight main CmakeList.txt
#${CEE_CURRENT_LIST_DIR}RifHdf5Reader.h
${CEE_CURRENT_LIST_DIR}RifStimPlanXmlReader.h
)
@@ -43,6 +47,10 @@ ${CEE_CURRENT_LIST_DIR}RifReaderMockModel.cpp
${CEE_CURRENT_LIST_DIR}RifReaderSettings.cpp
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.cpp
${CEE_CURRENT_LIST_DIR}RifWellPathImporter.cpp
${CEE_CURRENT_LIST_DIR}RifHdf5ReaderInterface.cpp
# HDF5 file reader is directly included in ResInsight main CmakeList.txt
#${CEE_CURRENT_LIST_DIR}RifHdf5Reader.cpp
${CEE_CURRENT_LIST_DIR}RifStimPlanXmlReader.cpp
)

View File

@@ -99,11 +99,13 @@ public:
virtual void setTimeSteps(const std::vector<QDateTime>& timeSteps) {};
virtual size_t timeStepCount() = 0;
virtual void timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart) = 0;
virtual std::vector<int> reportNumbers() = 0;
virtual std::vector<int> reportNumbers() = 0;
virtual void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts) = 0;
virtual bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values) = 0;
virtual bool dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector<double>* waterFlux, std::vector<double>* oilFlux, std::vector<double>* gasFlux) = 0;
virtual void readWellData(well_info_type * well_info, bool importCompleteMswData) = 0;
virtual int readUnitsType() = 0;
};

View File

@@ -22,6 +22,9 @@
#include "RifEclipseOutputFileTools.h"
#include "cafProgressInfo.h"
#include "ert/ecl/ecl_file.h"
#include "ert/ecl/ecl_nnc_geometry.h"
#include "ert/ecl/ecl_nnc_data.h"
//--------------------------------------------------------------------------------------------------
/// Constructor
@@ -211,6 +214,50 @@ bool RifEclipseRestartFilesetAccess::results(const QString& resultName, size_t t
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifEclipseRestartFilesetAccess::dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector<double>* waterFlux, std::vector<double>* oilFlux, std::vector<double>* gasFlux)
{
if (timeStep > timeStepCount())
{
return false;
}
openTimeStep(timeStep);
if (!m_ecl_files[timeStep])
{
return false;
}
ecl_file_view_type* summaryView = ecl_file_get_global_view(m_ecl_files[timeStep]);
ecl_nnc_geometry_type* nnc_geo = ecl_nnc_geometry_alloc(grid);
{
ecl_nnc_data_type* waterFluxData = ecl_nnc_data_alloc_wat_flux(grid, nnc_geo, summaryView);
const double* waterFluxValues = ecl_nnc_data_get_values(waterFluxData);
waterFlux->insert(waterFlux->end(), &waterFluxValues[0], &waterFluxValues[ecl_nnc_data_get_size(waterFluxData)]);
ecl_nnc_data_free(waterFluxData);
}
{
ecl_nnc_data_type* oilFluxData = ecl_nnc_data_alloc_oil_flux(grid, nnc_geo, summaryView);
const double* oilFluxValues = ecl_nnc_data_get_values(oilFluxData);
oilFlux->insert(oilFlux->end(), &oilFluxValues[0], &oilFluxValues[ecl_nnc_data_get_size(oilFluxData)]);
ecl_nnc_data_free(oilFluxData);
}
{
ecl_nnc_data_type* gasFluxData = ecl_nnc_data_alloc_gas_flux(grid, nnc_geo, summaryView);
const double* gasFluxValues = ecl_nnc_data_get_values(gasFluxData);
gasFlux->insert(gasFlux->end(), &gasFluxValues[0], &gasFluxValues[ecl_nnc_data_get_size(gasFluxData)]);
ecl_nnc_data_free(gasFluxData);
}
ecl_nnc_geometry_free(nnc_geo);
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -49,6 +49,8 @@ public:
void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts);
bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values);
bool dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector<double>* waterFlux, std::vector<double>* oilFlux, std::vector<double>* gasFlux) override;
virtual void readWellData(well_info_type* well_info, bool importCompleteMswData);
virtual int readUnitsType();

View File

@@ -23,6 +23,8 @@
#include "ert/ecl/ecl_file.h"
#include "ert/ecl/ecl_kw_magic.h"
#include "ert/ecl/ecl_nnc_geometry.h"
#include "ert/ecl/ecl_nnc_data.h"
#include <QDebug>
@@ -150,6 +152,48 @@ bool RifEclipseUnifiedRestartFileAccess::results(const QString& resultName, size
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifEclipseUnifiedRestartFileAccess::dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector<double>* waterFlux, std::vector<double>* oilFlux, std::vector<double>* gasFlux)
{
if (timeStep > timeStepCount())
{
return false;
}
if (!openFile())
{
return false;
}
ecl_file_view_type* summaryView = ecl_file_get_restart_view(m_ecl_file, timeStep, 0, 0, 0);
ecl_nnc_geometry_type* nnc_geo = ecl_nnc_geometry_alloc(grid);
{
ecl_nnc_data_type* waterFluxData = ecl_nnc_data_alloc_wat_flux(grid, nnc_geo, summaryView);
const double* waterFluxValues = ecl_nnc_data_get_values(waterFluxData);
waterFlux->insert(waterFlux->end(), &waterFluxValues[0], &waterFluxValues[ecl_nnc_data_get_size(waterFluxData)]);
ecl_nnc_data_free(waterFluxData);
}
{
ecl_nnc_data_type* oilFluxData = ecl_nnc_data_alloc_oil_flux(grid, nnc_geo, summaryView);
const double* oilFluxValues = ecl_nnc_data_get_values(oilFluxData);
oilFlux->insert(oilFlux->end(), &oilFluxValues[0], &oilFluxValues[ecl_nnc_data_get_size(oilFluxData)]);
ecl_nnc_data_free(oilFluxData);
}
{
ecl_nnc_data_type* gasFluxData = ecl_nnc_data_alloc_gas_flux(grid, nnc_geo, summaryView);
const double* gasFluxValues = ecl_nnc_data_get_values(gasFluxData);
gasFlux->insert(gasFlux->end(), &gasFluxValues[0], &gasFluxValues[ecl_nnc_data_get_size(gasFluxData)]);
ecl_nnc_data_free(gasFluxData);
}
ecl_nnc_geometry_free(nnc_geo);
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -52,6 +52,8 @@ public:
void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts);
bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector<double>* values);
bool dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector<double>* waterFlux, std::vector<double>* oilFlux, std::vector<double>* gasFlux) override;
virtual void readWellData(well_info_type * well_info, bool importCompleteMswData);
virtual int readUnitsType();

View File

@@ -0,0 +1,467 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RifHdf5Reader.h"
#include "RiaLogging.h"
#include "H5Cpp.h"
#include "H5Exception.h"
#include "cvfAssert.h"
#include "cvfMath.h"
#include <QStringList>
#include <QDateTime>
#include <QDir>
#include <algorithm>
//--------------------------------------------------------------------------------------------------
/// May reduce constructor content upon discussion of overlying framework.
///
///std::string dateString = getStringAttribute(file, "/KaseStudy/TransientSections", "initial_date");
///QDateTime initalDateTime = sourSimDateTimeToQDateTime(dateString); // may rearrange/change to be a call in timeSteps()
//--------------------------------------------------------------------------------------------------
RifHdf5Reader::RifHdf5Reader(const QString& fileName)
: m_fileName(fileName), m_fileStrategy(0)
{
try
{
H5::H5File file(fileName.toStdString().c_str(), H5F_ACC_RDONLY); // evt fileName.toLatin1().data()
m_fileStrategy = getIntAttribute(file, "/", "file_strategy"); // fileStrategy == 1 means one time step per file
if (m_fileStrategy == 1)
{
m_timeStepFileNames = getSourSimTimeStepFileNames(fileName);
}
}
catch (...) // catch any failure
{
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifHdf5Reader::~RifHdf5Reader()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifHdf5Reader::dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values) const
{
if (m_fileStrategy != 1) return false; // NB: currently incapable of handling all results in one sourres file
try
{
QStringList props = propertyNames();
QStringList::iterator it = std::find(props.begin(), props.end(), result);
int propIdx = (it != props.end()) ? it - props.begin() : 0; // index to 'result' in QStringList props (usually size_t but int gave no warning)
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
std::string fileName = m_timeStepFileNames[stepIndex];
std::string timeStepGroup = "/Timestep_" + getTimeStepNumberAs5DigitString(fileName);
H5::H5File file(fileName.c_str(), H5F_ACC_RDONLY);
std::string groupName = timeStepGroup + "/GridFunctions/GridPart_00000/GridFunction_" + IntTo5DigitString(propIdx + 1); // adjust to HDF5 one based indexing
getElementResultValues(file, groupName, values);
return true;
}
catch (...) // catch any failure
{
RiaLogging::error(QString("Failed to read SourSimRL dynamic results"));
return false;
}
}
//--------------------------------------------------------------------------------------------------
/// Qt alternative fileName.toLatin1().data()
//--------------------------------------------------------------------------------------------------
std::vector<QDateTime> RifHdf5Reader::timeSteps() const
{
std::vector<QDateTime> times;
if (m_fileStrategy != 1) return times; // NB: currently incapable of handling all results in one sourres file
try
{
H5::H5File mainFile(m_fileName.toStdString().c_str(), H5F_ACC_RDONLY); // initial date part is an attribute of SourSimRL main file
std::string dateString = getStringAttribute(mainFile, "/KaseStudy/TransientSections", "initial_date");
QDateTime dtInitial = sourSimDateTimeToQDateTime(dateString);
for (size_t i = 0; i < m_timeStepFileNames.size(); i++)
{
std::string fileName = m_timeStepFileNames[i];
std::string timeStepGroup = "/Timestep_" + getTimeStepNumberAs5DigitString(fileName);
H5::H5File file(fileName.c_str(), H5F_ACC_RDONLY);
double timeStepValue = getDoubleAttribute(file, timeStepGroup, "timestep"); // Assumes only one time step per file
int timeStepDays = cvf::Math::floor(timeStepValue); // NB: open question: unit of SourSimRL time step values, days?
QDateTime dt = dtInitial;
times.push_back(dt.addDays(timeStepDays)); // NB: open question: unit of SourSimRL time step values, days?
}
}
catch (...) // catch any failure
{
times.clear();
RiaLogging::error(QString("Failed to read SourSimRL time steps"));
}
return times;
}
//---------------------------------------------------------------------------------------------------
/// Result variables of first timestep listed by HDF5 subgroups to the following base group:
/// "/Timestep_00001/GridFunctions/GridPart_00000"
/// According to sourres file description, it seems safe to assume equal presence for all time steps.
//---------------------------------------------------------------------------------------------------
QStringList RifHdf5Reader::propertyNames() const
{
QStringList propNames;
if (m_fileStrategy != 1) return propNames; // NB: currently incapable of handling all results in one sourres file
if (m_timeStepFileNames.empty())
{
RiaLogging::error(QString("Failed to read properties. Transient data does not exist."));
return propNames;
}
std::string fileName = m_timeStepFileNames[0]; // assume the result variables to be identical across time steps => extract names from first time step file
std::string groupName = "/Timestep_" + getTimeStepNumberAs5DigitString(fileName) + "/GridFunctions/GridPart_00000";
try
{
H5::H5File file(fileName.c_str(), H5F_ACC_RDONLY);
std::vector<std::string> resultNames = getResultNames(file, groupName);
for (const std::string& s : resultNames)
{
propNames.push_back(s.c_str());
}
}
catch (...) // catch any failure
{
propNames.clear();
RiaLogging::error(QString("Failed to read properties from file : '%1'").arg(fileName.c_str()));
}
return propNames;
}
//=========================== PRIVATE METHODS =====================================================
//
//
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5Reader::getSourSimTimeStepFileNames(const QString& fileName) const
{
QFileInfo fi(fileName);
QString name = fi.fileName();
QString dir = fi.path();
QDir baseDir(dir);
baseDir.setFilter(QDir::Files);
QStringList nameFilters;
nameFilters << name + ".?????";
baseDir.setNameFilters(nameFilters);
QStringList fileNames = baseDir.entryList();
std::vector<std::string> timeStepFileNames;
for (int i = 0; i < fileNames.size(); i++)
{
std::string fullPath = dir.toStdString() + "/" + fileNames[i].toStdString();
timeStepFileNames.push_back(fullPath);
}
return timeStepFileNames;
}
//--------------------------------------------------------------------------------------------------
/// Build a QDateTime based on a SourSimRL HDF date attribute
/// Did not succeed with QDateTime dt = QDateTime::fromString(dateString, "YYYY MM DD hh mm ss");
/// Thus a conversion of substrings via integers
//--------------------------------------------------------------------------------------------------
QDateTime RifHdf5Reader::sourSimDateTimeToQDateTime(std::string dateString) const
{
int year = std::stoi(dateString.substr(0, 4));
int month = std::stoi(dateString.substr(5, 2));
int day = std::stoi(dateString.substr(8, 2));
int hours = std::stoi(dateString.substr(11, 2));
int minutes = std::stoi(dateString.substr(14, 2));
int seconds = std::stoi(dateString.substr(17, 2));
QDate d(year, month, day);
QTime t(hours, minutes, seconds);
QDateTime dt;
dt.setDate(d);
dt.setTime(t);
return dt;
}
//--------------------------------------------------------------------------------------------------
/// Build a string based on an int that consists of exactly 5 characters for HDF5 numbering
//--------------------------------------------------------------------------------------------------
std::string RifHdf5Reader::getTimeStepNumberAs5DigitString(std::string fileName) const
{
return fileName.substr(fileName.size() - 5); // extract the 5 last characters/digits
}
//--------------------------------------------------------------------------------------------------
/// Build a string based on an int that consists of exactly 5 characters for HDF5 numbering
//--------------------------------------------------------------------------------------------------
std::string RifHdf5Reader::IntTo5DigitString(int i) const
{
std::string numString = "00000" + std::to_string(i);
return numString.substr(numString.size() - 5); // extract the 5 last characters/digits
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifHdf5Reader::getIntAttribute(H5::H5File file, std::string groupName, std::string attributeName) const
{
try
{
H5::Group group = file.openGroup(groupName.c_str());
H5::Attribute attr = group.openAttribute(attributeName.c_str());
int value = 0;
H5::DataType type = attr.getDataType();
attr.read(type, &value);
return value;
}
catch (...)
{
return 0;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RifHdf5Reader::getDoubleAttribute(H5::H5File file, std::string groupName, std::string attributeName) const
{
try
{
H5::Group group = file.openGroup(groupName.c_str());
H5::Attribute attr = group.openAttribute(attributeName.c_str());
double value = 0.0;
H5::DataType type = attr.getDataType();
attr.read(type, &value);
return value;
}
catch (...)
{
return 0.0;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifHdf5Reader::getStringAttribute(H5::H5File file, std::string groupName, std::string attributeName) const
{
try
{
H5::Group group = file.openGroup(groupName.c_str());
H5::Attribute attr = group.openAttribute(attributeName.c_str());
std::string stringAttribute(1024, '\0');
H5::DataType nameType = attr.getDataType();
attr.read(nameType, &stringAttribute[0]);
return stringAttribute;
}
catch (...)
{
return "";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5Reader::getSubGroupNames(H5::H5File file, std::string baseGroupName) const
{
H5::Group baseGroup = file.openGroup(baseGroupName.c_str());
std::vector<std::string> subGroupNames;
hsize_t groupSize = baseGroup.getNumObjs();
for (hsize_t i = 0; i < groupSize; i++)
{
std::string nodeName(1024, '\0');
ssize_t slen = baseGroup.getObjnameByIdx(i, &nodeName[0], 1023);
nodeName.resize(slen + 1);
subGroupNames.push_back(nodeName);
}
return subGroupNames;
}
//--------------------------------------------------------------------------------------------------
/// Intended for finding all timesteps of one SourSimRL result file
//--------------------------------------------------------------------------------------------------
std::vector<double> RifHdf5Reader::getStepTimeValues(H5::H5File file, std::string baseGroupName) const
{
std::vector<std::string> subGroupNames = getSubGroupNames(file, baseGroupName);
std::vector<double> stepTimeValues;
for (std::vector<std::string>::iterator it = subGroupNames.begin(); it != subGroupNames.end(); it++)
{
if (it->find("Timestep_") != std::string::npos)
{
std::string groupName = baseGroupName + *it;
double timestep_value = getDoubleAttribute(file, groupName, "timestep");
stepTimeValues.push_back(timestep_value);
}
}
return stepTimeValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5Reader::getResultNames(H5::H5File file, std::string baseGroupName) const
{
H5::Group baseGroup = file.openGroup(baseGroupName.c_str());
std::vector<std::string> subGroupNames = getSubGroupNames(file, baseGroupName);
std::vector<std::string> resultNames;
for (std::vector<std::string>::iterator it = subGroupNames.begin(); it != subGroupNames.end(); it++)
{
std::string groupName = baseGroupName + "/" + *it;
std::string name = getStringAttribute(file, groupName, "name");
resultNames.push_back(name);
}
return resultNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifHdf5Reader::getElementResultValues(H5::H5File file, std::string groupName, std::vector<double>* resultValues) const
{
H5::Group group = file.openGroup(groupName.c_str());
H5::DataSet dataset = H5::DataSet(group.openDataSet("values"));
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims(dims, NULL);
(*resultValues).resize(dims[0]);
dataset.read(resultValues->data(), H5::PredType::NATIVE_DOUBLE);
}

View File

@@ -0,0 +1,62 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RifHdf5ReaderInterface.h"
#include <QString>
#include "H5Cpp.h"
//==================================================================================================
//
//
//==================================================================================================
class RifHdf5Reader : public RifHdf5ReaderInterface
{
public:
explicit RifHdf5Reader(const QString& fileName);
virtual ~RifHdf5Reader();
std::vector<QDateTime> timeSteps() const override;
virtual QStringList propertyNames() const override;
bool dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values) const override;
private:
std::vector<std::string> getSourSimTimeStepFileNames(const QString& fileName) const;
QDateTime sourSimDateTimeToQDateTime(std::string dateString) const;
std::string getTimeStepNumberAs5DigitString(std::string fileName) const;
std::string IntTo5DigitString(int i) const;
int getIntAttribute(H5::H5File file, std::string groupName, std::string attributeName) const;
double getDoubleAttribute(H5::H5File file, std::string groupName, std::string attributeName) const;
std::string getStringAttribute(H5::H5File file, std::string groupName, std::string attributeName) const;
std::vector<std::string> getSubGroupNames(H5::H5File file, std::string baseGroupName) const;
std::vector<double> getStepTimeValues(H5::H5File file, std::string baseGroupName) const;
std::vector<std::string> getResultNames(H5::H5File file, std::string baseGroupName) const;
void getElementResultValues(H5::H5File file, std::string groupName, std::vector<double>* resultValues) const;
private:
QString m_fileName; // name of SourSimRL main file given by user
int m_fileStrategy; // SourSimRL file strategy, fileStrategy == 1 means one time step per file
std::vector<std::string> m_timeStepFileNames; // files containing transient SourSimRL results, one time step per file
};

View File

@@ -0,0 +1,20 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RifHdf5ReaderInterface.h"

View File

@@ -0,0 +1,38 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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
class QString;
class QDateTime;
class QStringList;
#include <vector>
#include <cstddef>
//==================================================================================================
//
//
//==================================================================================================
class RifHdf5ReaderInterface
{
public:
virtual std::vector<QDateTime> timeSteps() const = 0;
virtual QStringList propertyNames() const = 0;
virtual bool dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values) const = 0;
};

View File

@@ -20,10 +20,17 @@
#include "RifReaderEclipseOutput.h"
#include "RiaLogging.h"
#include "RifEclipseInputFileTools.h"
#include "RifEclipseOutputFileTools.h"
#include "RifEclipseRestartFilesetAccess.h"
#include "RifEclipseUnifiedRestartFileAccess.h"
#include "RifHdf5ReaderInterface.h"
#ifdef USE_HDF5
#include "RifHdf5Reader.h"
#endif
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
@@ -38,6 +45,8 @@
#include "ert/ecl/ecl_kw_magic.h"
#include "ert/ecl/ecl_nnc_export.h"
#include "ert/ecl/ecl_nnc_geometry.h"
#include "ert/ecl/ecl_nnc_data.h"
#include <cmath> // Needed for HUGE_VAL on Linux
#include <iostream>
@@ -409,7 +418,10 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e
{
progInfo.setProgressDescription("Reading NNC data");
progInfo.setNextProgressIncrement(5);
transferNNCData(mainEclGrid, m_ecl_init_file, eclipseCase->mainGrid());
transferStaticNNCData(mainEclGrid, m_ecl_init_file, eclipseCase->mainGrid());
progInfo.incrementProgress();
transferDynamicNNCData(mainEclGrid, eclipseCase->mainGrid());
progInfo.incrementProgress();
progInfo.setProgressDescription("Processing NNC data");
@@ -435,6 +447,120 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput::setHdf5FileName(const QString& fileName)
{
CVF_ASSERT(m_eclipseCase);
RigCaseCellResultsData* matrixModelResults = m_eclipseCase->results(RiaDefines::MATRIX_MODEL);
CVF_ASSERT(matrixModelResults);
if (fileName.isEmpty())
{
RiaLogging::info("HDF: Removing all existing Sour Sim data ...");
matrixModelResults->eraseAllSourSimData();
return;
}
RiaLogging::info(QString("HDF: Start import of data from : ").arg(fileName));
RiaLogging::info("HDF: Removing all existing Sour Sim data ...");
matrixModelResults->eraseAllSourSimData();
std::vector<QDateTime> dateTimes;
std::vector<double> daysSinceSimulationStart;
if (m_dynamicResultsAccess.notNull())
{
m_dynamicResultsAccess->timeSteps(&dateTimes, &daysSinceSimulationStart);
}
std::unique_ptr<RifHdf5ReaderInterface> myReader;
#ifdef USE_HDF5
myReader = std::unique_ptr<RifHdf5ReaderInterface>(new RifHdf5Reader(fileName));
#endif // USE_HDF5
if (!myReader)
{
RiaLogging::error("HDF: Failed to import Sour Sim data ");
return;
}
std::vector<QDateTime> hdfTimeSteps = myReader->timeSteps();
if (dateTimes.size() > 0)
{
if (hdfTimeSteps.size() != dateTimes.size())
{
RiaLogging::error("HDF: Time step count does not match");
RiaLogging::error(QString("HDF: Eclipse count %1").arg(dateTimes.size()));
RiaLogging::error(QString("HDF: HDF count %1").arg(hdfTimeSteps.size()));
return;
}
bool isTimeStampsEqual = true;
for (size_t i = 0; i < dateTimes.size(); i++)
{
if (hdfTimeSteps[i].date() != dateTimes[i].date())
{
RiaLogging::error("HDF: Time steps does not match");
QString dateStr("yyyy.MMM.ddd hh:mm");
RiaLogging::error(QString("HDF: Eclipse date %1").arg(dateTimes[i].toString(dateStr)));
RiaLogging::error(QString("HDF: HDF date %1").arg(hdfTimeSteps[i].toString(dateStr)));
isTimeStampsEqual = false;
}
}
if (!isTimeStampsEqual) return;
}
else
{
// Use time steps from HDF to define the time steps
dateTimes = hdfTimeSteps;
QDateTime firstDate = hdfTimeSteps[0];
for (auto d : hdfTimeSteps)
{
daysSinceSimulationStart.push_back(firstDate.daysTo(d));
}
}
std::vector<RigEclipseTimeStepInfo> timeStepInfos;
{
std::vector<int> reportNumbers;
if (m_dynamicResultsAccess.notNull())
{
reportNumbers = m_dynamicResultsAccess->reportNumbers();
}
else
{
for (size_t i = 0; i < dateTimes.size(); i++)
{
reportNumbers.push_back(static_cast<int>(i));
}
}
timeStepInfos = RigEclipseTimeStepInfo::createTimeStepInfos(dateTimes, reportNumbers, daysSinceSimulationStart);
}
QStringList resultNames = myReader->propertyNames();
for (int i = 0; i < resultNames.size(); ++i)
{
size_t resIndex = matrixModelResults->addEmptyScalarResult(RiaDefines::SOURSIMRL, resultNames[i], false);
matrixModelResults->setTimeStepInfos(resIndex, timeStepInfos);
}
m_hdfReaderInterface = std::move(myReader);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -471,37 +597,62 @@ void RifReaderEclipseOutput::importFaults(const QStringList& fileSet, cvf::Colle
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput::transferNNCData( const ecl_grid_type * mainEclGrid , const ecl_file_type * init_file, RigMainGrid * mainGrid)
void RifReaderEclipseOutput::transferStaticNNCData(const ecl_grid_type* mainEclGrid , ecl_file_type* init_file, RigMainGrid* mainGrid)
{
if (!m_ecl_init_file ) return;
CVF_ASSERT(mainEclGrid && mainGrid);
// Get the data from ERT
ecl_nnc_geometry_type* nnc_geo = ecl_nnc_geometry_alloc(mainEclGrid);
ecl_nnc_data_type* tran_data = ecl_nnc_data_alloc_tran(mainEclGrid, nnc_geo, ecl_file_get_global_view(init_file));
int numNNC = ecl_nnc_data_get_size(tran_data);
int geometrySize = ecl_nnc_geometry_size(nnc_geo);
CVF_ASSERT(numNNC == geometrySize);
int numNNC = ecl_nnc_export_get_size( mainEclGrid );
if (numNNC > 0)
{
ecl_nnc_type * eclNNCData= new ecl_nnc_type[numNNC];
ecl_nnc_export(mainEclGrid, init_file, eclNNCData);
// Transform to our own datastructures
//cvf::Trace::show("Reading NNC. Count: " + cvf::String(numNNC));
// Transform to our own data structures
mainGrid->nncData()->connections().resize(numNNC);
std::vector<double>& transmissibilityValues = mainGrid->nncData()->makeConnectionScalarResult(cvf::UNDEFINED_SIZE_T);
std::vector<double>& transmissibilityValues = mainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameCombTrans());
const double* transValues = ecl_nnc_data_get_values(tran_data);
for (int nIdx = 0; nIdx < numNNC; ++nIdx)
{
RigGridBase* grid1 = mainGrid->gridByIndex(eclNNCData[nIdx].grid_nr1);
mainGrid->nncData()->connections()[nIdx].m_c1GlobIdx = grid1->reservoirCellIndex(eclNNCData[nIdx].global_index1);
RigGridBase* grid2 = mainGrid->gridByIndex(eclNNCData[nIdx].grid_nr2);
mainGrid->nncData()->connections()[nIdx].m_c2GlobIdx = grid2->reservoirCellIndex(eclNNCData[nIdx].global_index2);
transmissibilityValues[nIdx] = eclNNCData[nIdx].trans;
const ecl_nnc_pair_type* geometry_pair = ecl_nnc_geometry_iget(nnc_geo, nIdx);
RigGridBase* grid1 = mainGrid->gridByIndex(geometry_pair->grid_nr1);
mainGrid->nncData()->connections()[nIdx].m_c1GlobIdx = grid1->reservoirCellIndex(geometry_pair->global_index1);
RigGridBase* grid2 = mainGrid->gridByIndex(geometry_pair->grid_nr2);
mainGrid->nncData()->connections()[nIdx].m_c2GlobIdx = grid2->reservoirCellIndex(geometry_pair->global_index2);
transmissibilityValues[nIdx] = transValues[nIdx];
}
}
ecl_nnc_geometry_free(nnc_geo);
ecl_nnc_data_free(tran_data);
}
delete[] eclNNCData;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput::transferDynamicNNCData(const ecl_grid_type* mainEclGrid, RigMainGrid* mainGrid)
{
CVF_ASSERT(mainEclGrid && mainGrid);
if (m_dynamicResultsAccess.isNull()) return;
size_t timeStepCount = m_dynamicResultsAccess->timeStepCount();
std::vector< std::vector<double> >& waterFluxData = mainGrid->nncData()->makeDynamicConnectionScalarResult(RigNNCData::propertyNameFluxWat(), timeStepCount);
std::vector< std::vector<double> >& oilFluxData = mainGrid->nncData()->makeDynamicConnectionScalarResult(RigNNCData::propertyNameFluxOil(), timeStepCount);
std::vector< std::vector<double> >& gasFluxData = mainGrid->nncData()->makeDynamicConnectionScalarResult(RigNNCData::propertyNameFluxGas(), timeStepCount);
for (size_t timeStep = 0; timeStep < timeStepCount; ++timeStep)
{
m_dynamicResultsAccess->dynamicNNCResults(mainEclGrid, timeStep, &waterFluxData[timeStep], &oilFluxData[timeStep], &gasFluxData[timeStep]);
}
}
@@ -824,11 +975,46 @@ bool RifReaderEclipseOutput::staticResult(const QString& result, RiaDefines::Por
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput::sourSimRlResult(const QString& result, size_t stepIndex, std::vector<double>* values)
{
values->clear();
if ( !m_hdfReaderInterface ) return;
if ( m_eclipseCase->mainGrid()->gridCount() == 0 )
{
RiaLogging::error("No grids available");
return ;
}
size_t activeCellCount = cvf::UNDEFINED_SIZE_T;
{
RigActiveCellInfo* fracActCellInfo = m_eclipseCase->activeCellInfo(RiaDefines::MATRIX_MODEL);
fracActCellInfo->gridActiveCellCounts(0, activeCellCount);
}
bool readCellResultOk = m_hdfReaderInterface->dynamicResult(result, stepIndex, values);
if (activeCellCount != values->size())
{
values->clear();
RiaLogging::error("SourSimRL results does not match the number of active cells in the grid");
return;
}
}
//--------------------------------------------------------------------------------------------------
/// Get dynamic result at given step index. Will concatenate values for the main grid and all sub grids.
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseOutput::dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values)
{
if (m_dynamicResultsAccess.isNull())
{
m_dynamicResultsAccess = createDynamicResultsAccess();

View File

@@ -24,13 +24,16 @@
#include "cvfCollection.h"
#include <memory>
class RifEclipseOutputFileTools;
class RifEclipseRestartDataAccess;
class RigGridBase;
class RigMainGrid;
class RifHdf5ReaderInterface;
class RigActiveCellInfo;
class RigFault;
class RigEclipseTimeStepInfo;
class RigGridBase;
class RigMainGrid;
struct RigWellResultPoint;
@@ -50,12 +53,14 @@ public:
virtual ~RifReaderEclipseOutput();
bool open(const QString& fileName, RigEclipseCaseData* eclipseCase);
void setHdf5FileName(const QString& fileName);
virtual bool openAndReadActiveCellData(const QString& fileName, const std::vector<QDateTime>& mainCaseTimeSteps, RigEclipseCaseData* eclipseCase);
void close();
bool staticResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector<double>* values);
bool dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values);
void sourSimRlResult(const QString& result, size_t stepIndex, std::vector<double>* values);
static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigEclipseCaseData* eclipseCase);
static void transferCoarseningInfo(const ecl_grid_type* eclGrid, RigGridBase* grid);
@@ -74,8 +79,8 @@ private:
void openInitFile();
void extractResultValuesBasedOnPorosityModel(RiaDefines::PorosityModelType matrixOrFracture, std::vector<double>* values, const std::vector<double>& fileValues);
void transferNNCData( const ecl_grid_type * mainEclGrid , const ecl_file_type * init_file,
RigMainGrid * mainGrid);
void transferStaticNNCData(const ecl_grid_type* mainEclGrid , ecl_file_type* init_file, RigMainGrid* mainGrid);
void transferDynamicNNCData(const ecl_grid_type* mainEclGrid, RigMainGrid* mainGrid);
RifEclipseRestartDataAccess* createDynamicResultsAccess();
@@ -91,4 +96,6 @@ private:
ecl_file_type* m_ecl_init_file; // File access to static results
cvf::ref<RifEclipseRestartDataAccess> m_dynamicResultsAccess; // File access to dynamic results
std::unique_ptr<RifHdf5ReaderInterface> m_hdfReaderInterface;
};

View File

@@ -103,7 +103,7 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell
{
CVF_ASSERT(cellResultColors);
updateNNCColors(cellResultColors);
updateNNCColors(timeStepIndex, cellResultColors);
RimEclipseView* eclipseView = cellResultColors->reservoirView();
RigEclipseCaseData* eclipseCase = eclipseView->eclipseCase()->eclipseCaseData();
@@ -181,7 +181,7 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell
//--------------------------------------------------------------------------------------------------
void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors)
{
updateNNCColors(cellResultColors);
updateNNCColors(timeStepIndex, cellResultColors);
if (m_nativeFaultFaces.notNull())
{
@@ -374,7 +374,7 @@ void RivFaultPartMgr::updatePartEffect()
m_oppositeFaultFaces->setEffect(geometryOnlyEffect.p());
}
updateNNCColors(NULL);
updateNNCColors(0, NULL);
// Update mesh colors as well, in case of change
RiaPreferences* prefs = RiaApplication::instance()->preferences();
@@ -641,12 +641,14 @@ caf::FaceCulling RivFaultPartMgr::faceCullingMode() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultPartMgr::updateNNCColors(RimEclipseCellColors* cellResultColors)
void RivFaultPartMgr::updateNNCColors(size_t timeStepIndex, RimEclipseCellColors* cellResultColors)
{
if (m_NNCFaces.isNull()) return;
bool showNncsWithScalarMappedColor = false;
RimEclipseView* eclipseView = nullptr;
if (cellResultColors)
{
size_t scalarSetIndex = cellResultColors->scalarResultIndex();
@@ -655,15 +657,17 @@ void RivFaultPartMgr::updateNNCColors(RimEclipseCellColors* cellResultColors)
{
showNncsWithScalarMappedColor = true;
}
eclipseView = cellResultColors->reservoirView();
}
if (showNncsWithScalarMappedColor)
{
size_t scalarSetIndex = cellResultColors->scalarResultIndex();
RiaDefines::ResultCatType resultType = cellResultColors->resultType();
const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper();
m_NNCGenerator->textureCoordinates(m_NNCTextureCoords.p(), mapper, scalarSetIndex);
m_NNCGenerator->textureCoordinates(m_NNCTextureCoords.p(), mapper, resultType, scalarSetIndex, timeStepIndex);
cvf::ref<cvf::Effect> nncEffect;
@@ -671,12 +675,14 @@ void RivFaultPartMgr::updateNNCColors(RimEclipseCellColors* cellResultColors)
{
// Move NNC closer to camera to avoid z-fighting with grid surface
caf::ScalarMapperEffectGenerator nncEffgen(mapper, caf::PO_NEG_LARGE);
if (eclipseView) nncEffgen.disableLighting(eclipseView->isLightingDisabled());
nncEffect = nncEffgen.generateCachedEffect();
}
else
{
// If no grid is present, use same offset as grid geometry to be able to see mesh lines
caf::ScalarMapperEffectGenerator nncEffgen(mapper, caf::PO_1);
if (eclipseView) nncEffgen.disableLighting(eclipseView->isLightingDisabled());
nncEffect = nncEffgen.generateCachedEffect();
}

View File

@@ -70,7 +70,7 @@ private:
void generatePartGeometry();
void updatePartEffect();
void updateNNCColors(RimEclipseCellColors* cellResultColors);
void updateNNCColors(size_t timeStepIndex, RimEclipseCellColors* cellResultColors);
caf::FaceCulling faceCullingMode() const;

View File

@@ -145,14 +145,30 @@ void RivNNCGeometryGenerator::computeArrays()
/// Calculates the texture coordinates in a "nearly" one dimensional texture.
/// Undefined values are coded with a y-texture coordinate value of 1.0 instead of the normal 0.5
//--------------------------------------------------------------------------------------------------
void RivNNCGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, size_t scalarResultIndex) const
void RivNNCGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords,
const cvf::ScalarMapper* mapper,
RiaDefines::ResultCatType resultType,
size_t scalarResultIndex,
size_t timeStepIndex) const
{
size_t numVertices = m_vertices->size();
textureCoords->resize(numVertices);
cvf::Vec2f* rawPtr = textureCoords->ptr();
const std::vector<double>* nncResultVals = m_nncData->connectionScalarResult(scalarResultIndex);
const std::vector<double>* nncResultVals;
if (resultType == RiaDefines::STATIC_NATIVE)
{
nncResultVals = m_nncData->staticConnectionScalarResult(scalarResultIndex);
}
else if (resultType == RiaDefines::DYNAMIC_NATIVE)
{
nncResultVals = m_nncData->dynamicConnectionScalarResult(scalarResultIndex, timeStepIndex);
}
else if (resultType == RiaDefines::GENERATED)
{
nncResultVals = m_nncData->generatedConnectionScalarResult(scalarResultIndex, timeStepIndex);
}
if (!nncResultVals)
{
textureCoords->setAll(cvf::Vec2f(0.0f, 1.0f));

View File

@@ -18,6 +18,9 @@
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaDefines.h"
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfArray.h"
@@ -45,7 +48,10 @@ public:
void setCellVisibility( const cvf::UByteArray* cellVisibilities, const RigGridBase * grid);
void textureCoordinates(cvf::Vec2fArray* textureCoords,
const cvf::ScalarMapper* mapper, size_t scalarResultIndex) const;
const cvf::ScalarMapper* mapper,
RiaDefines::ResultCatType resultType,
size_t scalarResultIndex,
size_t timeStepIndex) const;
// Mapping between cells and geometry
cvf::ref<cvf::Array<size_t> > triangleToNNCIndex() const;

View File

@@ -9,6 +9,7 @@ ${CEE_CURRENT_LIST_DIR}RimFlowDiagSolution.h
${CEE_CURRENT_LIST_DIR}RimFlowPlotCollection.h
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.h
${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.h
${CEE_CURRENT_LIST_DIR}RimTofAccumulatedPhaseFractionsPlot.h
${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.h
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.h
${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.h
@@ -19,6 +20,7 @@ ${CEE_CURRENT_LIST_DIR}RimFlowDiagSolution.cpp
${CEE_CURRENT_LIST_DIR}RimFlowPlotCollection.cpp
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.cpp
${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.cpp
${CEE_CURRENT_LIST_DIR}RimTofAccumulatedPhaseFractionsPlot.cpp
${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.cpp
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.cpp
${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.cpp

View File

@@ -23,10 +23,21 @@
#include "RimEclipseResultCase.h"
#include "RimFlowDiagSolution.h"
#include "RimProject.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseView.h"
#include "RimEclipsePropertyFilter.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RicEclipsePropertyFilterFeatureImpl.h"
#include "RicSelectOrCreateViewFeatureImpl.h"
#include "RiuFlowCharacteristicsPlot.h"
#include "RiuMainWindow.h"
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafUtils.h"
#include <QDateTime>
@@ -35,13 +46,13 @@
namespace caf
{
template<>
void AppEnum< RimFlowCharacteristicsPlot::TimeSelectionType >::setUp()
{
addItem(RimFlowCharacteristicsPlot::ALL_AVAILABLE, "ALL_AVAILABLE", "All available");
addItem(RimFlowCharacteristicsPlot::SELECT_AVAILABLE, "SELECT_AVAILABLE", "Select");
setDefault(RimFlowCharacteristicsPlot::ALL_AVAILABLE);
}
template<>
void AppEnum< RimFlowCharacteristicsPlot::TimeSelectionType >::setUp()
{
addItem(RimFlowCharacteristicsPlot::ALL_AVAILABLE, "ALL_AVAILABLE", "All available");
addItem(RimFlowCharacteristicsPlot::SELECT_AVAILABLE, "SELECT_AVAILABLE", "Select");
setDefault(RimFlowCharacteristicsPlot::ALL_AVAILABLE);
}
}
CAF_PDM_SOURCE_INIT(RimFlowCharacteristicsPlot, "FlowCharacteristicsPlot");
@@ -60,10 +71,28 @@ RimFlowCharacteristicsPlot::RimFlowCharacteristicsPlot()
CAF_PDM_InitFieldNoDefault(&m_timeStepSelectionType, "TimeSelectionType", "Time Steps", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "SelectedTimeSteps", "", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_applyTimeSteps, "ApplyTimeSteps", "", "", "", "");
m_applyTimeSteps.xmlCapability()->setIOWritable(false);
m_applyTimeSteps.xmlCapability()->setIOReadable(false);
m_applyTimeSteps.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
m_applyTimeSteps.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&m_maxPvFraction, "CellPVThreshold", 0.1, "Aquifer Cell Threshold", "", "Exclude Aquifer Effects by adding a Cell Pore Volume Threshold as Fraction of Total Pore Volume.", "");
CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Legend", "", "", "");
// Region group
CAF_PDM_InitFieldNoDefault(&m_cellSelection, "CellSelection", "Cell Selection", "", "", "");
CAF_PDM_InitField(&m_tracerFilter, "TracerFilter", QString(), "Filter", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_selectedTracerNames, "SelectedTracerNames", " ", "", "", "");
m_selectedTracerNames.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_showRegion, "ShowRegion", "", "", "", "");
m_showRegion.xmlCapability()->setIOWritable(false);
m_showRegion.xmlCapability()->setIOReadable(false);
m_showRegion.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
m_showRegion.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
this->m_showWindow = false;
setAsPlotMdiWindow();
}
@@ -173,14 +202,66 @@ QList<caf::PdmOptionItemInfo> RimFlowCharacteristicsPlot::calculateValueOptions(
{
if ( m_flowDiagSolution )
{
RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults();
std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
QStringList timeStepDates = m_case->timeStepStrings();
for ( int tsIdx : calculatedTimesteps )
std::vector<int> calculatedTimeSteps = m_flowDiagSolution()->flowDiagResults()->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
for (int tsIdx = 0; tsIdx < timeStepDates.size(); ++tsIdx)
{
options.push_back(caf::PdmOptionItemInfo(timeStepDates[tsIdx], tsIdx));
auto it = std::find(calculatedTimeSteps.begin(), calculatedTimeSteps.end(), tsIdx);
QString itemText = timeStepDates[tsIdx];
if (it == calculatedTimeSteps.end())
{
itemText = itemText + " *";
}
options.push_back(caf::PdmOptionItemInfo(itemText, tsIdx));
}
}
}
else if (fieldNeedingOptions == &m_selectedTracerNames)
{
if (m_flowDiagSolution)
{
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
for (QString tracerName : tracerNames)
{
if (!caf::Utils::isStringMatch(m_tracerFilter, tracerName)) continue;
RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowDiagSolution->tracerStatusOverall(tracerName);
if (tracerStatus == RimFlowDiagSolution::CLOSED) continue;
if (m_cellSelection() == RigFlowDiagResults::CELLS_FLOODED)
{
if (tracerStatus == RimFlowDiagSolution::INJECTOR || tracerStatus == RimFlowDiagSolution::VARYING)
{
options.push_back(caf::PdmOptionItemInfo(tracerName, tracerName));
}
}
else if (m_cellSelection() == RigFlowDiagResults::CELLS_DRAINED)
{
if (tracerStatus == RimFlowDiagSolution::PRODUCER || tracerStatus == RimFlowDiagSolution::VARYING)
{
options.push_back(caf::PdmOptionItemInfo(tracerName, tracerName));
}
}
else if (m_cellSelection() == RigFlowDiagResults::CELLS_COMMUNICATION)
{
QString prefix;
switch (tracerStatus)
{
case RimFlowDiagSolution::INJECTOR:
prefix = "I : ";
break;
case RimFlowDiagSolution::PRODUCER:
prefix = "P : ";
break;
case RimFlowDiagSolution::VARYING:
prefix = "I/P: ";
break;
case RimFlowDiagSolution::UNDEFINED:
prefix = "U : ";
break;
}
options.push_back(caf::PdmOptionItemInfo(prefix + tracerName, tracerName));
}
}
}
}
@@ -198,14 +279,52 @@ void RimFlowCharacteristicsPlot::defineUiOrdering(QString uiConfigName, caf::Pdm
uiOrdering.add(&m_flowDiagSolution);
uiOrdering.add(&m_timeStepSelectionType);
if (m_timeStepSelectionType == SELECT_AVAILABLE) uiOrdering.add(&m_selectedTimeSteps);
if (m_timeStepSelectionType == SELECT_AVAILABLE)
{
uiOrdering.add(&m_selectedTimeSteps);
uiOrdering.add(&m_applyTimeSteps);
}
uiOrdering.add(&m_showLegend);
uiOrdering.add(&m_maxPvFraction);
{
caf::PdmUiGroup* regionGroup = uiOrdering.addNewGroup("Region");
regionGroup->add(&m_cellSelection);
if (m_cellSelection() != RigFlowDiagResults::CELLS_ACTIVE)
{
regionGroup->add(&m_tracerFilter);
regionGroup->add(&m_selectedTracerNames);
}
regionGroup->add(&m_showRegion);
}
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowCharacteristicsPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (field == &m_applyTimeSteps)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(attribute);
if (attrib)
{
attrib->m_buttonText = "Apply";
}
}
else if (field == &m_showRegion)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(attribute);
if (attrib)
{
attrib->m_buttonText = "Show Region";
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -234,6 +353,81 @@ void RimFlowCharacteristicsPlot::fieldChangedByUi(const caf::PdmFieldHandle* cha
m_flowDiagSolution = m_case->defaultFlowDiagSolution();
m_currentlyPlottedTimeSteps.clear();
}
else if (&m_applyTimeSteps == changedField)
{
if (m_flowDiagSolution)
{
// Compute any missing time steps from selected
for (int tsIdx : m_selectedTimeSteps())
{
m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(tsIdx);
}
}
m_applyTimeSteps = false;
}
else if (&m_showRegion == changedField)
{
if (m_case)
{
if (m_cellSelection() != RigFlowDiagResults::CELLS_ACTIVE)
{
RimEclipseView* view = RicSelectOrCreateViewFeatureImpl::showViewSelection(m_case, "FlowCharacteristicsLastUsedView", "Show Region in View");
view->cellResult()->setResultType(RiaDefines::FLOW_DIAGNOSTICS);
view->cellResult()->setFlowDiagTracerSelectionType(RimEclipseResultDefinition::FLOW_TR_BY_SELECTION);
view->cellResult()->setSelectedTracers(m_selectedTracerNames);
if (m_cellSelection() == RigFlowDiagResults::CELLS_COMMUNICATION)
{
view->cellResult()->setResultVariable(RIG_FLD_COMMUNICATION_RESNAME);
}
else
{
view->cellResult()->setResultVariable(RIG_FLD_TOF_RESNAME);
}
int timeStep = 0;
if (m_timeStepSelectionType() == ALL_AVAILABLE)
{
if (m_flowDiagSolution)
{
std::vector<int> timeSteps = m_flowDiagSolution()->flowDiagResults()->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
if (!timeSteps.empty())
{
timeStep = timeSteps[0];
}
}
}
else
{
if (!m_selectedTimeSteps().empty())
{
timeStep = m_selectedTimeSteps()[0];
}
}
// Ensure selected time step has computed results
m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(timeStep);
view->setCurrentTimeStep(timeStep);
for (RimEclipsePropertyFilter* f : view->eclipsePropertyFilterCollection()->propertyFilters())
{
f->isActive = false;
}
RicEclipsePropertyFilterFeatureImpl::addPropertyFilter(view->eclipsePropertyFilterCollection());
view->loadDataAndUpdate();
m_case->updateConnectedEditors();
RicSelectOrCreateViewFeatureImpl::focusView(view);
}
}
}
else if (changedField == &m_cellSelection)
{
m_selectedTracerNames = std::vector<QString>();
}
// All fields update plot
@@ -290,16 +484,25 @@ void RimFlowCharacteristicsPlot::loadDataAndUpdate()
m_flowCharPlotWidget->removeAllCurves();
std::vector<QString> selectedTracerNames = m_selectedTracerNames();
if (m_cellSelection() == RigFlowDiagResults::CELLS_ACTIVE)
{
if (m_flowDiagSolution)
{
selectedTracerNames = m_flowDiagSolution->tracerNames();
}
}
for ( int timeStepIdx: calculatedTimesteps )
{
lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx, m_maxPvFraction()).m_lorenzCoefficient;
lorenzVals[timeStepIdx] = flowResult->flowCharacteristicsResults(timeStepIdx, m_cellSelection(), selectedTracerNames, m_maxPvFraction()).m_lorenzCoefficient;
}
m_flowCharPlotWidget->setLorenzCurve(timeStepStrings, timeStepDates, lorenzVals);
for ( int timeStepIdx: calculatedTimesteps )
{
const auto flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx, m_maxPvFraction());
const auto flowCharResults = flowResult->flowCharacteristicsResults(timeStepIdx, m_cellSelection(), selectedTracerNames, m_maxPvFraction());
m_flowCharPlotWidget->addFlowCapStorageCapCurve(timeStepDates[timeStepIdx],
flowCharResults.m_flowCapStorageCapCurve.first,
flowCharResults.m_flowCapStorageCapCurve.second);

View File

@@ -21,6 +21,8 @@
#include "RimViewWindow.h"
#include "RigFlowDiagResults.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
@@ -62,22 +64,24 @@ public:
virtual void zoomAll() override;
virtual QWidget* createViewWidget(QWidget* mainWindowParent) override;
virtual void deleteViewWidget() override;
virtual void loadDataAndUpdate() override;
enum TimeSelectionType
{
ALL_AVAILABLE,
SELECT_AVAILABLE
};
protected:
// RimViewWindow overrides
virtual void loadDataAndUpdate() override;
virtual QImage snapshotWindowContent() override;
// Overridden PDM methods
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute );
private:
@@ -86,9 +90,15 @@ private:
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
caf::PdmField<caf::AppEnum<TimeSelectionType> > m_timeStepSelectionType;
caf::PdmField<std::vector<int> > m_selectedTimeSteps;
caf::PdmField<bool> m_applyTimeSteps;
caf::PdmField<bool> m_showLegend;
caf::PdmField<double> m_maxPvFraction;
caf::PdmField<RigFlowDiagResults::CellSelectionEnum> m_cellSelection;
caf::PdmField<QString> m_tracerFilter;
caf::PdmField< std::vector<QString> > m_selectedTracerNames;
caf::PdmField<bool> m_showRegion;
std::vector<int> m_currentlyPlottedTimeSteps;
QPointer<RiuFlowCharacteristicsPlot> m_flowCharPlotWidget;

View File

@@ -40,7 +40,8 @@ RimFlowPlotCollection::RimFlowPlotCollection()
CAF_PDM_InitFieldNoDefault(&m_defaultWellAllocPlot, "DefaultWellAllocationPlot", "", "", "", "");
m_defaultWellAllocPlot.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_storedWellAllocPlots, "StoredWellAllocationPlots", "Stored Plots", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_storedWellAllocPlots, "StoredWellAllocationPlots", "Stored Well Allocation Plots", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_storedFlowCharacteristicsPlots, "StoredFlowCharacteristicsPlots", "Stored Flow Characteristics Plots", "", "", "");
}
//--------------------------------------------------------------------------------------------------
@@ -67,6 +68,7 @@ void RimFlowPlotCollection::closeDefaultPlotWindowAndDeletePlots()
delete m_flowCharacteristicsPlot;
m_storedWellAllocPlots.deleteAllChildObjects();
m_storedFlowCharacteristicsPlots.deleteAllChildObjects();
}
//--------------------------------------------------------------------------------------------------
@@ -74,7 +76,7 @@ void RimFlowPlotCollection::closeDefaultPlotWindowAndDeletePlots()
//--------------------------------------------------------------------------------------------------
void RimFlowPlotCollection::loadDataAndUpdate()
{
caf::ProgressInfo plotProgress(m_storedWellAllocPlots.size() + 1, "");
caf::ProgressInfo plotProgress(m_storedWellAllocPlots.size() + m_storedFlowCharacteristicsPlots.size() + 1, "");
if (m_defaultWellAllocPlot) m_defaultWellAllocPlot->loadDataAndUpdate();
plotProgress.incrementProgress();
@@ -84,6 +86,12 @@ void RimFlowPlotCollection::loadDataAndUpdate()
p->loadDataAndUpdate();
plotProgress.incrementProgress();
}
for (RimFlowCharacteristicsPlot* p : m_storedFlowCharacteristicsPlots)
{
p->loadDataAndUpdate();
plotProgress.incrementProgress();
}
}
//--------------------------------------------------------------------------------------------------
@@ -94,6 +102,7 @@ size_t RimFlowPlotCollection::plotCount() const
size_t plotCount = 0;
if (m_defaultWellAllocPlot) plotCount = 1;
plotCount += m_storedWellAllocPlots.size();
plotCount += m_storedFlowCharacteristicsPlots.size();
return plotCount;
}
@@ -105,6 +114,14 @@ void RimFlowPlotCollection::addWellAllocPlotToStoredPlots(RimWellAllocationPlot*
m_storedWellAllocPlots.push_back(plot);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowPlotCollection::addFlowCharacteristicsPlotToStoredPlots(RimFlowCharacteristicsPlot* plot)
{
m_storedFlowCharacteristicsPlots.push_back(plot);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -41,6 +41,7 @@ public:
size_t plotCount() const;
void addWellAllocPlotToStoredPlots(RimWellAllocationPlot* plot);
void addFlowCharacteristicsPlotToStoredPlots(RimFlowCharacteristicsPlot* plot);
RimWellAllocationPlot* defaultWellAllocPlot();
RimFlowCharacteristicsPlot* defaultFlowCharacteristicsPlot();
@@ -48,4 +49,5 @@ private:
caf::PdmChildField<RimFlowCharacteristicsPlot*> m_flowCharacteristicsPlot;
caf::PdmChildField<RimWellAllocationPlot*> m_defaultWellAllocPlot;
caf::PdmChildArrayField<RimWellAllocationPlot*> m_storedWellAllocPlots;
caf::PdmChildArrayField<RimFlowCharacteristicsPlot*> m_storedFlowCharacteristicsPlots;
};

View File

@@ -0,0 +1,215 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RimTofAccumulatedPhaseFractionsPlot.h"
#include "RiaApplication.h"
#include "RimEclipseView.h"
#include "RimEclipseWell.h"
#include "RimEclipseWellCollection.h"
#include "RimWellAllocationPlot.h"
#include "RigSingleWellResultsData.h"
#include "RigTofAccumulatedPhaseFractionsCalculator.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuMainPlotWindow.h"
#include "RiuTofAccumulatedPhaseFractionsPlot.h"
#include "RiuWellAllocationPlot.h"
#include "cvfColor3.h"
CAF_PDM_SOURCE_INIT(RimTofAccumulatedPhaseFractionsPlot, "TofAccumulatedPhaseFractionsPlot");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTofAccumulatedPhaseFractionsPlot::RimTofAccumulatedPhaseFractionsPlot()
{
CAF_PDM_InitObject("Cumulative Saturation by Time of Flight", ":/WellAllocPie16x16.png", "", "");
CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Cumulative Saturation by Time of Flight"), "Name", "", "", "");
m_userName.uiCapability()->setUiReadOnly(true);
CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", "");
m_showWindow = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTofAccumulatedPhaseFractionsPlot::~RimTofAccumulatedPhaseFractionsPlot()
{
removeMdiWindowFromMdiArea();
deleteViewWidget();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTofAccumulatedPhaseFractionsPlot::deleteViewWidget()
{
if (m_tofAccumulatedPhaseFractionsPlotWidget)
{
m_tofAccumulatedPhaseFractionsPlotWidget->deleteLater();
m_tofAccumulatedPhaseFractionsPlotWidget = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTofAccumulatedPhaseFractionsPlot::reloadFromWell()
{
loadDataAndUpdate();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseResultCase* RimTofAccumulatedPhaseFractionsPlot::resultCase()
{
RimWellAllocationPlot* allocationPlot;
firstAncestorOrThisOfTypeAsserted(allocationPlot);
return allocationPlot->rimCase();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimTofAccumulatedPhaseFractionsPlot::tracerName()
{
RimWellAllocationPlot* allocationPlot;
firstAncestorOrThisOfTypeAsserted(allocationPlot);
return allocationPlot->wellName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimTofAccumulatedPhaseFractionsPlot::timeStep()
{
RimWellAllocationPlot* allocationPlot;
firstAncestorOrThisOfTypeAsserted(allocationPlot);
return static_cast<size_t>(allocationPlot->timeStep());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimTofAccumulatedPhaseFractionsPlot::viewWidget()
{
return m_tofAccumulatedPhaseFractionsPlotWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTofAccumulatedPhaseFractionsPlot::zoomAll()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTofAccumulatedPhaseFractionsPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue);
if (changedField == &m_userName ||
changedField == &m_showPlotTitle)
{
updateMdiWindowTitle();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimTofAccumulatedPhaseFractionsPlot::snapshotWindowContent()
{
QImage image;
// TODO
return image;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTofAccumulatedPhaseFractionsPlot::setDescription(const QString& description)
{
m_userName = description;
this->updateMdiWindowTitle();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimTofAccumulatedPhaseFractionsPlot::description() const
{
return m_userName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTofAccumulatedPhaseFractionsPlot::loadDataAndUpdate()
{
updateMdiWindowVisibility();
if (m_tofAccumulatedPhaseFractionsPlotWidget && m_showWindow())
{
RigTofAccumulatedPhaseFractionsCalculator calc(resultCase(), tracerName(), timeStep());
const std::vector<double>& xValues = calc.sortedUniqueTOFValues();
const std::vector<double>& watValues = calc.accumulatedPhaseFractionsSwat();
const std::vector<double>& oilValues = calc.accumulatedPhaseFractionsSoil();
const std::vector<double>& gasValues = calc.accumulatedPhaseFractionsSgas();
m_tofAccumulatedPhaseFractionsPlotWidget->setSamples(xValues, watValues, oilValues, gasValues);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimTofAccumulatedPhaseFractionsPlot::createViewWidget(QWidget* mainWindowParent)
{
if (!m_tofAccumulatedPhaseFractionsPlotWidget)
{
m_tofAccumulatedPhaseFractionsPlotWidget = new RiuTofAccumulatedPhaseFractionsPlot(this, mainWindowParent);
}
return m_tofAccumulatedPhaseFractionsPlotWidget;
}

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RimViewWindow.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include <QPointer>
#include <vector>
class RiuWellAllocationPlot;
class RimEclipseWell;
class RimWellLogPlot;
class RiuTofAccumulatedPhaseFractionsPlot;
class RimEclipseResultCase;
namespace caf {
class PdmOptionItemInfo;
}
namespace cvf {
class Color3f;
}
//==================================================================================================
///
///
//==================================================================================================
class RimTofAccumulatedPhaseFractionsPlot : public RimViewWindow
{
CAF_PDM_HEADER_INIT;
public:
RimTofAccumulatedPhaseFractionsPlot();
virtual ~RimTofAccumulatedPhaseFractionsPlot();
void setDescription(const QString& description);
QString description() const;
// RimViewWindow overrides
virtual QWidget* viewWidget() override;
virtual void zoomAll() override;
virtual QWidget* createViewWidget(QWidget* mainWindowParent) override;
virtual void deleteViewWidget() override;
void reloadFromWell();
RimEclipseResultCase* resultCase();
QString tracerName();
size_t timeStep();
protected:
// RimViewWindow overrides
virtual void loadDataAndUpdate() override;
virtual QImage snapshotWindowContent() override;
// Overridden PDM methods
virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; }
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
private:
caf::PdmField<bool> m_showPlotTitle;
caf::PdmField<QString> m_userName;
QPointer<RiuTofAccumulatedPhaseFractionsPlot> m_tofAccumulatedPhaseFractionsPlotWidget;
};

View File

@@ -41,6 +41,7 @@
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimWellAllocationPlotLegend.h"
#include "RimTofAccumulatedPhaseFractionsPlot.h"
#include "RiuMainPlotWindow.h"
#include "RiuWellAllocationPlot.h"
@@ -102,6 +103,10 @@ RimWellAllocationPlot::RimWellAllocationPlot()
m_wellAllocationPlotLegend.uiCapability()->setUiHidden(true);
m_wellAllocationPlotLegend = new RimWellAllocationPlotLegend;
CAF_PDM_InitFieldNoDefault(&m_tofAccumulatedPhaseFractionsPlot, "TofAccumulatedPhaseFractionsPlot", "TOF Accumulated Phase Fractions", "", "", "");
m_tofAccumulatedPhaseFractionsPlot.uiCapability()->setUiHidden(true);
m_tofAccumulatedPhaseFractionsPlot = new RimTofAccumulatedPhaseFractionsPlot;
this->setAsPlotMdiWindow();
}
@@ -114,6 +119,7 @@ RimWellAllocationPlot::~RimWellAllocationPlot()
delete m_accumulatedWellFlowPlot();
delete m_totalWellAllocationPlot();
delete m_tofAccumulatedPhaseFractionsPlot();
deleteViewWidget();
}
@@ -311,6 +317,10 @@ void RimWellAllocationPlot::updateFromWell()
m_totalWellAllocationPlot->updateConnectedEditors();
accumulatedWellFlowPlot()->updateConnectedEditors();
m_tofAccumulatedPhaseFractionsPlot->reloadFromWell();
m_tofAccumulatedPhaseFractionsPlot->updateConnectedEditors();
if (m_wellAllocationPlotWidget) m_wellAllocationPlotWidget->updateGeometry();
}
@@ -523,6 +533,14 @@ RimTotalWellAllocationPlot* RimWellAllocationPlot::totalWellFlowPlot()
return m_totalWellAllocationPlot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTofAccumulatedPhaseFractionsPlot * RimWellAllocationPlot::tofAccumulatedPhaseFractionsPlot()
{
return m_tofAccumulatedPhaseFractionsPlot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -35,6 +35,7 @@ class RimWellAllocationPlotLegend;
class RimWellLogPlot;
class RiuWellAllocationPlot;
class RimWellLogTrack;
class RimTofAccumulatedPhaseFractionsPlot;
class RigSingleWellResultsData;
namespace cvf {
@@ -72,6 +73,7 @@ public:
RimWellLogPlot* accumulatedWellFlowPlot();
RimTotalWellAllocationPlot* totalWellFlowPlot();
RimTofAccumulatedPhaseFractionsPlot* tofAccumulatedPhaseFractionsPlot();
caf::PdmObject* plotLegend();
RimEclipseResultCase* rimCase();
int timeStep();
@@ -134,4 +136,5 @@ private:
caf::PdmChildField<RimWellLogPlot*> m_accumulatedWellFlowPlot;
caf::PdmChildField<RimTotalWellAllocationPlot*> m_totalWellAllocationPlot;
caf::PdmChildField<RimWellAllocationPlotLegend*> m_wellAllocationPlotLegend;
caf::PdmChildField<RimTofAccumulatedPhaseFractionsPlot*> m_tofAccumulatedPhaseFractionsPlot;
};

View File

@@ -189,7 +189,7 @@ QList<caf::PdmOptionItemInfo> RimCellEdgeColors::calculateValueOptions(const caf
varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(RiaDefines::STATIC_NATIVE);
//TODO: Must also handle input properties
//varList += m_reservoirView->gridCellResults()->resultNames(RiaEclipseUnitTools::INPUT_PROPERTY);
//varList += m_reservoirView->gridCellResults()->resultNames(RiaDefines::INPUT_PROPERTY);
QList<caf::PdmOptionItemInfo> options;

View File

@@ -37,6 +37,7 @@
#include "RimFault.h"
#include "RimFlowDiagSolution.h"
#include "RimFlowPlotCollection.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFormationNames.h"
#include "RimFormationNamesCollection.h"
#include "RimEllipseFractureTemplate.h"
@@ -359,6 +360,10 @@ QStringList RimContextCommandBuilder::commandsFromSelection()
{
commandIds << "RicAddStoredWellAllocationPlotFeature";
}
else if (dynamic_cast<RimFlowCharacteristicsPlot*>(uiItem))
{
commandIds << "RicAddStoredFlowCharacteristicsPlotFeature";
}
else if (dynamic_cast<RimFlowDiagSolution*>(uiItem))
{
commandIds << "RicShowFlowCharacteristicsPlotFeature";
@@ -447,6 +452,7 @@ QStringList RimContextCommandBuilder::commandsFromSelection()
{
commandIds << "RicReloadCaseFeature";
commandIds << "RicExecuteScriptForCasesFeature";
commandIds << "RicCloseSourSimDataFeature";
}
else if (dynamic_cast<RimSummaryPlot*>(uiItem))
{

View File

@@ -601,7 +601,22 @@ bool RimEclipseCase::openReserviorCase()
size_t combinedTransResIdx = results->cellResults()->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName());
if (combinedTransResIdx != cvf::UNDEFINED_SIZE_T)
{
eclipseCaseData()->mainGrid()->nncData()->setCombTransmissibilityScalarResultIndex(combinedTransResIdx);
eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameCombTrans(), combinedTransResIdx);
}
size_t combinedWatFluxResIdx = results->cellResults()->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName());
if (combinedWatFluxResIdx != cvf::UNDEFINED_SIZE_T)
{
eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxWat(), combinedWatFluxResIdx);
}
size_t combinedOilFluxResIdx = results->cellResults()->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName());
if (combinedOilFluxResIdx != cvf::UNDEFINED_SIZE_T)
{
eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxOil(), combinedOilFluxResIdx);
}
size_t combinedGasFluxResIdx = results->cellResults()->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName());
if (combinedGasFluxResIdx != cvf::UNDEFINED_SIZE_T)
{
eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxGas(), combinedGasFluxResIdx);
}
}

View File

@@ -38,8 +38,11 @@
#include "RimReservoirCellResultsStorage.h"
#include "RimTimeStepFilter.h"
#include "RimTools.h"
#include "RimEclipseView.h"
#include "RimEclipseCellColors.h"
#include "cafPdmSettings.h"
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiPropertyViewDialog.h"
#include "cafProgressInfo.h"
#include "cafUtils.h"
@@ -75,7 +78,11 @@ RimEclipseResultCase::RimEclipseResultCase()
flipYAxis.xmlCapability()->setIOWritable(true);
//flipYAxis.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_sourSimFileName, "SourSimFileName", QString(), "SourSim File Name", "", "", "");
m_sourSimFileName.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
#ifndef USE_HDF5
m_sourSimFileName.uiCapability()->setUiHidden(true);
#endif
m_activeCellInfoIsReadFromFile = false;
m_gridAndWellDataIsReadFromFile = false;
@@ -148,6 +155,12 @@ bool RimEclipseResultCase::openEclipseGridFile()
{
m_flowDiagSolutions.push_back(new RimFlowDiagSolution());
}
if (!m_sourSimFileName().isEmpty())
{
RifReaderEclipseOutput* outReader = dynamic_cast<RifReaderEclipseOutput*>(readerInterface.p());
outReader->setHdf5FileName(m_sourSimFileName());
}
return true;
}
@@ -220,6 +233,39 @@ bool RimEclipseResultCase::openAndReadActiveCellData(RigEclipseCaseData* mainEcl
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultCase::loadAndUpdateSourSimData()
{
if (!results(RiaDefines::MATRIX_MODEL)) return;
RifReaderEclipseOutput* rifReaderOutput = dynamic_cast<RifReaderEclipseOutput*>(results(RiaDefines::MATRIX_MODEL)->readerInterface());
if (rifReaderOutput)
{
rifReaderOutput->setHdf5FileName(m_sourSimFileName);
}
if (!hasSourSimFile())
{
// Deselect SourSimRL cell results
for (RimView* view : views())
{
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>(view);
if (eclipseView != nullptr)
{
if (eclipseView->cellResult()->resultType() == RiaDefines::SOURSIMRL)
{
eclipseView->cellResult()->setResultType(RiaDefines::DYNAMIC_NATIVE);
eclipseView->cellResult()->setResultVariable("SOIL");
eclipseView->loadDataAndUpdate();
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -435,6 +481,24 @@ void RimEclipseResultCase::setCaseInfo(const QString& userDescription, const QSt
proj->assignCaseIdToCase(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultCase::setSourSimFileName(const QString& fileName)
{
m_sourSimFileName = fileName;
loadAndUpdateSourSimData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseResultCase::hasSourSimFile()
{
return !m_sourSimFileName().isEmpty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -471,3 +535,31 @@ void RimEclipseResultCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrde
m_timeStepFilter->uiOrdering(uiConfigName, *group1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_sourSimFileName)
{
loadAndUpdateSourSimData();
}
return RimEclipseCase::fieldChangedByUi(changedField, oldValue, newValue);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultCase::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (field == &m_sourSimFileName)
{
caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast<caf::PdmUiFilePathEditorAttribute*>(attribute);
if (myAttr)
{
myAttr->m_fileSelectionFilter = "SourSim (*.sourres)";
myAttr->m_defaultPath = QFileInfo(caseFileName()).absolutePath();
}
}
}

View File

@@ -42,6 +42,8 @@ public:
void setGridFileName(const QString& caseFileName);
void setCaseInfo(const QString& userDescription, const QString& caseFileName);
void setSourSimFileName(const QString& fileName);
bool hasSourSimFile();
virtual bool openEclipseGridFile();
virtual void reloadEclipseGridFile();
@@ -57,6 +59,13 @@ public:
std::vector<RimFlowDiagSolution*> flowDiagSolutions();
RigFlowDiagSolverInterface* flowDiagSolverInterface();
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute);
private:
void loadAndUpdateSourSimData();
private:
cvf::ref<RifReaderInterface> createMockModel(QString modelName);
@@ -69,6 +78,7 @@ private:
// Fields:
caf::PdmField<QString> caseFileName;
caf::PdmChildArrayField<RimFlowDiagSolution*> m_flowDiagSolutions;
caf::PdmField<QString> m_sourSimFileName;
// Obsolete field
@@ -76,4 +86,5 @@ private:
bool m_gridAndWellDataIsReadFromFile;
bool m_activeCellInfoIsReadFromFile;
};

View File

@@ -41,6 +41,7 @@
#include "RimWellLogExtractionCurve.h"
#include "cafPdmUiListEditor.h"
#include "cafUtils.h"
namespace caf
{
@@ -404,19 +405,6 @@ void RimEclipseResultDefinition::loadDataAndUpdate()
}
}
bool isStringMatch(const QString& filterString, const QString& value)
{
if (filterString.isEmpty()) return true;
if (filterString.trimmed() == "*")
{
if (!value.isEmpty()) return true;
else return false;
}
QRegExp searcher(filterString, Qt::CaseInsensitive, QRegExp::WildcardUnix);
return searcher.exactMatch(value);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -426,27 +414,47 @@ QList<caf::PdmOptionItemInfo> RimEclipseResultDefinition::calculateValueOptions(
if ( fieldNeedingOptions == &m_resultTypeUiField )
{
bool hasSourSimRLFile = false;
RimEclipseResultCase* eclResCase = dynamic_cast<RimEclipseResultCase*>(m_eclipseCase.p());
if ( eclResCase && eclResCase->eclipseCaseData() )
{
hasSourSimRLFile = eclResCase->hasSourSimFile();
}
#ifndef USE_HDF5
// If using ResInsight without HDF5 support, ignore SourSim files and
// do not show it as a result category.
hasSourSimRLFile = false;
#endif
RimGridTimeHistoryCurve* timeHistoryCurve;
this->firstAncestorOrThisOfType(timeHistoryCurve);
// Do not include flow diagnostics results if not available or is a time history curve
if ( timeHistoryCurve != nullptr )
// Do not include flow diagnostics results if it is a time history curve
// Do not include SourSimRL if no SourSim file is loaded
if ( timeHistoryCurve != nullptr || !hasSourSimRLFile )
{
using ResCatEnum = caf::AppEnum< RiaDefines::ResultCatType >;
for ( size_t i = 0; i < ResCatEnum::size(); ++i )
{
RiaDefines::ResultCatType resType = ResCatEnum::fromIndex(i);
if ( resType != RiaDefines::FLOW_DIAGNOSTICS )
if ( resType == RiaDefines::FLOW_DIAGNOSTICS
&& (timeHistoryCurve) )
{
QString uiString = ResCatEnum::uiTextFromIndex(i);
options.push_back(caf::PdmOptionItemInfo(uiString, resType));
continue;
}
if ( resType == RiaDefines::SOURSIMRL
&& (!hasSourSimRLFile ) )
{
continue;
}
QString uiString = ResCatEnum::uiTextFromIndex(i);
options.push_back(caf::PdmOptionItemInfo(uiString, resType));
}
}
else
{
// Do nothing, and thereby use the defaults of the AppEnum field
}
}
if ( m_resultTypeUiField() != RiaDefines::FLOW_DIAGNOSTICS )
@@ -460,10 +468,13 @@ QList<caf::PdmOptionItemInfo> RimEclipseResultDefinition::calculateValueOptions(
{
if ( fieldNeedingOptions == &m_resultVariableUiField )
{
options.push_back(caf::PdmOptionItemInfo("Time Of Flight (Average)", RIG_FLD_TOF_RESNAME));
options.push_back(caf::PdmOptionItemInfo("Tracer Cell Fraction (Sum)", RIG_FLD_CELL_FRACTION_RESNAME));
options.push_back(caf::PdmOptionItemInfo("Max Fraction Tracer", RIG_FLD_MAX_FRACTION_TRACER_RESNAME));
options.push_back(caf::PdmOptionItemInfo("Injector Producer Communication", RIG_FLD_COMMUNICATION_RESNAME));
options.push_back(caf::PdmOptionItemInfo("Time Of Flight (Average)", RIG_FLD_TOF_RESNAME));
if (m_phaseSelection() == RigFlowDiagResultAddress::PHASE_ALL)
{
options.push_back(caf::PdmOptionItemInfo("Tracer Cell Fraction (Sum)", RIG_FLD_CELL_FRACTION_RESNAME));
options.push_back(caf::PdmOptionItemInfo("Max Fraction Tracer", RIG_FLD_MAX_FRACTION_TRACER_RESNAME));
options.push_back(caf::PdmOptionItemInfo("Injector Producer Communication", RIG_FLD_COMMUNICATION_RESNAME));
}
}
else if (fieldNeedingOptions == &m_flowSolutionUiField)
{
@@ -855,6 +866,10 @@ bool RimEclipseResultDefinition::hasDynamicResult() const
{
return true;
}
else if (m_resultType() == RiaDefines::SOURSIMRL)
{
return true;
}
else if (m_resultType() == RiaDefines::FLOW_DIAGNOSTICS)
{
return true;
@@ -1097,7 +1112,7 @@ std::vector<QString> RimEclipseResultDefinition::tracerNamesMatchingFilter() con
{
for (const QString& tracerName : tracerNames)
{
if (isStringMatch(m_selectedTracersUiFieldFilter, tracerName))
if (caf::Utils::isStringMatch(m_selectedTracersUiFieldFilter, tracerName))
{
matchingNames.push_back(tracerName);
}

View File

@@ -95,6 +95,7 @@ public:
void updateAnyFieldHasChanged();
void setTofAndSelectTracer(const QString& tracerName);
void setSelectedTracers(const std::vector<QString>& selectedTracers);
protected:
@@ -135,7 +136,6 @@ protected:
caf::PdmPointer<RimEclipseCase> m_eclipseCase;
private:
void setSelectedTracers(const std::vector<QString>& selectedTracers);
void assignFlowSolutionFromCase();
bool hasDualPorFractureResult();

View File

@@ -41,6 +41,7 @@
#include <QFile>
#include <QFileInfo>
#include <QUuid>
#include "RifReaderEclipseOutput.h"
CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage");
@@ -243,6 +244,11 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& res
scalarResultIndex = this->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findOrLoadScalarResult(RiaDefines::SOURSIMRL, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::GENERATED, resultName);
@@ -335,6 +341,27 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RiaDefines::Result
computeRiTRANSbyAreaComponent(resultName);
}
}
else if (type == RiaDefines::DYNAMIC_NATIVE)
{
if (resultName == RiaDefines::combinedWaterFluxResultName())
{
this->findOrLoadScalarResult(type, "FLRWATI+");
this->findOrLoadScalarResult(type, "FLRWATJ+");
this->findOrLoadScalarResult(type, "FLRWATK+");
}
else if (resultName == RiaDefines::combinedOilFluxResultName())
{
this->findOrLoadScalarResult(type, "FLROILI+");
this->findOrLoadScalarResult(type, "FLROILJ+");
this->findOrLoadScalarResult(type, "FLROILK+");
}
else if (resultName == RiaDefines::combinedGasFluxResultName())
{
this->findOrLoadScalarResult(type, "FLRGASI+");
this->findOrLoadScalarResult(type, "FLRGASJ+");
this->findOrLoadScalarResult(type, "FLRGASK+");
}
}
if (isDataPresent(scalarResultIndex))
{
@@ -417,6 +444,26 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RiaDefines::Result
}
}
// Handle SourSimRL reading
if (type == RiaDefines::SOURSIMRL)
{
RifReaderEclipseOutput* eclReader = dynamic_cast<RifReaderEclipseOutput*>(m_readerInterface.p());
if (eclReader)
{
size_t timeStepCount = m_cellResults->infoForEachResultIndex()[scalarResultIndex].m_timeStepInfos.size();
m_cellResults->cellScalarResults(scalarResultIndex).resize(timeStepCount);
size_t i;
for ( i = 0; i < timeStepCount; i++ )
{
std::vector<double>& values = m_cellResults->cellScalarResults(scalarResultIndex)[i];
eclReader->sourSimRlResult(resultName, i, &values);
}
}
}
return scalarResultIndex;
}
@@ -498,6 +545,26 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RiaDefi
}
}
// Handle SourSimRL reading
if (type == RiaDefines::SOURSIMRL)
{
RifReaderEclipseOutput* eclReader = dynamic_cast<RifReaderEclipseOutput*>(m_readerInterface.p());
if (eclReader)
{
size_t timeStepCount = m_cellResults->infoForEachResultIndex()[scalarResultIndex].m_timeStepInfos.size();
m_cellResults->cellScalarResults(scalarResultIndex).resize(timeStepCount);
std::vector<double>& values = m_cellResults->cellScalarResults(scalarResultIndex)[timeStepIndex];
if ( values.size() == 0)
{
eclReader->sourSimRlResult(resultName, timeStepIndex, &values);
}
}
}
return scalarResultIndex;
}
@@ -992,7 +1059,7 @@ void RimReservoirCellResultsStorage::computeNncCombRiTrans()
if (!m_cellResults) return;
size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName());
if (m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransScalarResultIndex)) return;
if (m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransScalarResultIndex)) return;
double cdarchy = darchysValue();
@@ -1011,7 +1078,8 @@ void RimReservoirCellResultsStorage::computeNncCombRiTrans()
std::vector<double> & permXResults = m_cellResults->cellScalarResults(permXResultIdx)[0];
std::vector<double> & permYResults = m_cellResults->cellScalarResults(permYResultIdx)[0];
std::vector<double> & permZResults = m_cellResults->cellScalarResults(permZResultIdx)[0];
std::vector<double> & riCombTransResults = m_ownerMainGrid->nncData()->makeConnectionScalarResult(riCombTransScalarResultIndex);
std::vector<double> & riCombTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTrans());
m_ownerMainGrid->nncData()->setScalarResultIndex(RigNNCData::propertyNameRiCombTrans(), riCombTransScalarResultIndex);
std::vector<double> * ntgResults = NULL;
if (hasNTGResults)
@@ -1252,11 +1320,12 @@ void RimReservoirCellResultsStorage::computeNncCombRiMULT()
size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName());
size_t combTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName());
if (m_ownerMainGrid->nncData()->connectionScalarResult(riCombMultScalarResultIndex)) return;
if (m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombMultScalarResultIndex)) return;
std::vector<double> & riMultResults = m_ownerMainGrid->nncData()->makeConnectionScalarResult(riCombMultScalarResultIndex);
const std::vector<double> * riTransResults = m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransScalarResultIndex);
const std::vector<double> * transResults = m_ownerMainGrid->nncData()->connectionScalarResult(combTransScalarResultIndex);
std::vector<double> & riMultResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombMult());
const std::vector<double> * riTransResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransScalarResultIndex);
const std::vector<double> * transResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(combTransScalarResultIndex);
m_ownerMainGrid->nncData()->setScalarResultIndex(RigNNCData::propertyNameRiCombMult(), riCombMultScalarResultIndex);
for (size_t nncConIdx = 0; nncConIdx < riMultResults.size(); ++nncConIdx)
{
@@ -1385,10 +1454,11 @@ void RimReservoirCellResultsStorage::computeNncCombRiTRANSbyArea()
size_t riCombTransByAreaScResIdx = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiAreaNormTranResultName());
size_t combTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName());
if (m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransByAreaScResIdx)) return;
if (m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransByAreaScResIdx)) return;
std::vector<double> & riAreaNormTransResults = m_ownerMainGrid->nncData()->makeConnectionScalarResult(riCombTransByAreaScResIdx);
const std::vector<double> * transResults = m_ownerMainGrid->nncData()->connectionScalarResult(combTransScalarResultIndex);
std::vector<double> & riAreaNormTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTransByArea());
m_ownerMainGrid->nncData()->setScalarResultIndex(RigNNCData::propertyNameRiCombTransByArea(), riCombTransByAreaScResIdx);
const std::vector<double> * transResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(combTransScalarResultIndex);
const std::vector<RigConnection>& connections = m_ownerMainGrid->nncData()->connections();
@@ -1508,7 +1578,7 @@ void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cell
{
std::vector<double>* data = NULL;
data = &(m_cellResults->cellScalarResults(rIdx, tsIdx));
data = &(m_cellResults->cellScalarResults(resultIndex, tsIdx));
quint64 cellCount = 0;
stream >> cellCount;

View File

@@ -5,6 +5,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "2.8.2")
endif()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RimAsciiDataCurve.h
${CEE_CURRENT_LIST_DIR}RimFileSummaryCase.h
${CEE_CURRENT_LIST_DIR}RimGridSummaryCase.h
${CEE_CURRENT_LIST_DIR}RimSummaryCase.h
@@ -22,6 +23,7 @@ ${CEE_CURRENT_LIST_DIR}RimSummaryYAxisProperties.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RimAsciiDataCurve.cpp
${CEE_CURRENT_LIST_DIR}RimFileSummaryCase.cpp
${CEE_CURRENT_LIST_DIR}RimGridSummaryCase.cpp
${CEE_CURRENT_LIST_DIR}RimSummaryCase.cpp

View File

@@ -0,0 +1,258 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RimAsciiDataCurve.h"
#include "RiaApplication.h"
#include "RifReaderEclipseSummary.h"
#include "RigSummaryCaseData.h"
#include "RiaDefines.h"
#include "RimEclipseResultCase.h"
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryFilter.h"
#include "RimSummaryPlot.h"
#include "RimSummaryTimeAxisProperties.h"
#include "RiuLineSegmentQwtPlotCurve.h"
#include "RiuSummaryQwtPlot.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "qwt_date.h"
CAF_PDM_SOURCE_INIT(RimAsciiDataCurve, "AsciiDataCurve");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimAsciiDataCurve::RimAsciiDataCurve()
{
CAF_PDM_InitObject("ASCII Data Curve", ":/SummaryCurve16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_plotAxis, "PlotAxis", "Axis", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_timeSteps, "TimeSteps", "Time Steps", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_values, "Values", "Values", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_title, "Title", "Title", "", "", "");
m_symbolSkipPixelDistance = 10.0f;
m_curveThickness = 2;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimAsciiDataCurve::~RimAsciiDataCurve()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimAsciiDataCurve::yValues() const
{
return m_values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RimAsciiDataCurve::timeSteps() const
{
static std::vector<time_t> timeSteps;
timeSteps.clear();
for (const QDateTime& dateTime : m_timeSteps())
{
timeSteps.push_back(dateTime.toTime_t());
}
return timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setYAxis(RiaDefines::PlotAxis plotAxis)
{
m_plotAxis = plotAxis;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::PlotAxis RimAsciiDataCurve::yAxis() const
{
return m_plotAxis();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimAsciiDataCurve::createCurveAutoName()
{
return m_title();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::updateZoomInParentPlot()
{
RimSummaryPlot* plot = nullptr;
firstAncestorOrThisOfType(plot);
plot->updateZoomInQwt();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::onLoadDataAndUpdate()
{
this->RimPlotCurve::updateCurvePresentation();
if (isCurveVisible())
{
std::vector<time_t> dateTimes = this->timeSteps();
std::vector<double> values = this->yValues();
RimSummaryPlot* plot = nullptr;
firstAncestorOrThisOfType(plot);
bool isLogCurve = plot->isLogarithmicScaleEnabled(this->yAxis());
if (dateTimes.size() > 0 && dateTimes.size() == values.size())
{
if (plot->timeAxisProperties()->timeMode() == RimSummaryTimeAxisProperties::DATE)
{
m_qwtPlotCurve->setSamplesFromTimeTAndValues(dateTimes, values, isLogCurve);
}
else
{
double timeScale = plot->timeAxisProperties()->fromTimeTToDisplayUnitScale();
std::vector<double> times;
if ( dateTimes.size() )
{
time_t startDate = dateTimes[0];
for ( time_t& date: dateTimes )
{
times.push_back(timeScale*(date - startDate));
}
}
m_qwtPlotCurve->setSamplesFromTimeAndValues(times, values, isLogCurve);
}
}
else
{
m_qwtPlotCurve->setSamplesFromTimeTAndValues(std::vector<time_t>(), std::vector<double>(), isLogCurve);
}
updateZoomInParentPlot();
if (m_parentQwtPlot) m_parentQwtPlot->replot();
}
updateQwtPlotAxis();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::updateQwtPlotAxis()
{
if (m_qwtPlotCurve)
{
if (this->yAxis() == RiaDefines::PLOT_AXIS_LEFT)
{
m_qwtPlotCurve->setYAxis(QwtPlot::yLeft);
}
else
{
m_qwtPlotCurve->setYAxis(QwtPlot::yRight);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setTimeSteps(const std::vector<QDateTime>& timeSteps)
{
m_timeSteps = timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setValues(const std::vector<double>& values)
{
m_values = values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::setTitle(const QString& title)
{
m_title = title;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimAsciiDataCurve::curveData(std::vector<QDateTime>* timeSteps, std::vector<double>* values) const
{
CVF_ASSERT(timeSteps && values);
*timeSteps = m_timeSteps();
*values = m_values();
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimAsciiDataCurve::fieldChangedByUi(const caf::PdmFieldHandle * changedField, const QVariant & oldValue, const QVariant & newValue)
{
RimPlotCurve::fieldChangedByUi(changedField, oldValue, newValue);
RimSummaryPlot* plot = nullptr;
firstAncestorOrThisOfTypeAsserted(plot);
if (changedField == &m_plotAxis)
{
updateQwtPlotAxis();
plot->updateAxes();
}
if (changedField == &m_showCurve)
{
plot->updateAxes();
}
}

View File

@@ -0,0 +1,84 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "cafPdmPtrField.h"
#include "cafPdmChildField.h"
#include "RifEclipseSummaryAddress.h"
#include "RiaDefines.h"
#include "RimPlotCurve.h"
#include "cafAppEnum.h"
#include <QDateTime>
class RifReaderEclipseSummary;
class RimSummaryCase;
class RimSummaryFilter;
class RiuLineSegmentQwtPlotCurve;
class RimAsciiDataCurveAutoName;
//==================================================================================================
///
///
//==================================================================================================
class RimAsciiDataCurve : public RimPlotCurve
{
CAF_PDM_HEADER_INIT;
public:
RimAsciiDataCurve();
virtual ~RimAsciiDataCurve();
std::vector<double> yValues() const;
const std::vector<time_t>& timeSteps() const;
void setYAxis(RiaDefines::PlotAxis plotAxis);
RiaDefines::PlotAxis yAxis() const;
void updateQwtPlotAxis();
void setTimeSteps(const std::vector<QDateTime>& timeSteps);
void setValues(const std::vector<double>& values);
void setTitle(const QString& title);
protected:
// RimPlotCurve overrides
virtual QString createCurveAutoName() override;
virtual void updateZoomInParentPlot() override;
virtual void onLoadDataAndUpdate() override;
private:
bool curveData(std::vector<QDateTime>* timeSteps, std::vector<double>* values) const;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
private:
// Fields
caf::PdmField< caf::AppEnum< RiaDefines::PlotAxis > > m_plotAxis;
caf::PdmField< std::vector<QDateTime> > m_timeSteps;
caf::PdmField< std::vector<double> > m_values;
caf::PdmField< QString > m_title;
};

View File

@@ -24,6 +24,7 @@
#include "RimSummaryCurve.h"
#include "RimSummaryCurveFilter.h"
#include "RimSummaryYAxisProperties.h"
#include "RimAsciiDataCurve.h"
#include "RiuSummaryQwtPlot.h"
@@ -98,10 +99,12 @@ public:
///
//--------------------------------------------------------------------------------------------------
RimSummaryPlotYAxisFormatter::RimSummaryPlotYAxisFormatter(RimSummaryYAxisProperties* axisProperties,
const std::vector<RimSummaryCurve*>& curves,
const std::vector<RimSummaryCurve*>& summaryCurves,
const std::vector<RimAsciiDataCurve*>& asciiCurves,
const std::set<QString>& timeHistoryCurveQuantities)
: m_axisProperties(axisProperties),
m_singleCurves(curves),
m_summaryCurves(summaryCurves),
m_asciiDataCurves(asciiCurves),
m_timeHistoryCurveQuantities(timeHistoryCurveQuantities)
{
}
@@ -193,7 +196,7 @@ QString RimSummaryPlotYAxisFormatter::autoAxisTitle() const
{
std::map<std::string, std::set<std::string> > unitToQuantityNameMap;
for ( RimSummaryCurve* rimCurve : m_singleCurves )
for ( RimSummaryCurve* rimCurve : m_summaryCurves )
{
if ( rimCurve->yAxis() == this->m_axisProperties->plotAxisType() )
{

View File

@@ -22,6 +22,7 @@
#include <vector>
#include <set>
class RimAsciiDataCurve;
class RimSummaryCurve;
class RimSummaryCurveFilter;
class RimSummaryYAxisProperties;
@@ -34,7 +35,8 @@ class RimSummaryPlotYAxisFormatter
{
public:
RimSummaryPlotYAxisFormatter(RimSummaryYAxisProperties* axisProperties,
const std::vector<RimSummaryCurve*>& curves,
const std::vector<RimSummaryCurve*>& summaryCurves,
const std::vector<RimAsciiDataCurve*>& asciiCurves,
const std::set<QString>& timeHistoryCurveQuantities);
void applyYAxisPropertiesToPlot(RiuSummaryQwtPlot* qwtPlot);
@@ -43,9 +45,10 @@ private:
QString autoAxisTitle() const;
private:
RimSummaryYAxisProperties* m_axisProperties;
const std::vector<RimSummaryCurve*> m_singleCurves;
const std::set<QString> m_timeHistoryCurveQuantities;
RimSummaryYAxisProperties* m_axisProperties;
const std::vector<RimSummaryCurve*> m_summaryCurves;
const std::vector<RimAsciiDataCurve*> m_asciiDataCurves;
const std::set<QString> m_timeHistoryCurveQuantities;
};

View File

@@ -28,6 +28,7 @@
#include "RimSummaryPlotCollection.h"
#include "RimSummaryTimeAxisProperties.h"
#include "RimSummaryYAxisProperties.h"
#include "RimAsciiDataCurve.h"
#include "RiuMainPlotWindow.h"
#include "RiuSummaryQwtPlot.h"
@@ -72,6 +73,9 @@ RimSummaryPlot::RimSummaryPlot()
CAF_PDM_InitFieldNoDefault(&m_gridTimeHistoryCurves, "GridTimeHistoryCurves", "", "", "", "");
m_gridTimeHistoryCurves.uiCapability()->setUiTreeHidden(true);
CAF_PDM_InitFieldNoDefault(&m_asciiDataCurves, "AsciiDataCurves", "", "", "", "");
m_asciiDataCurves.uiCapability()->setUiTreeHidden(true);
CAF_PDM_InitFieldNoDefault(&m_leftYAxisProperties, "LeftYAxisProperties", "Left Y Axis", "", "", "");
m_leftYAxisProperties.uiCapability()->setUiTreeHidden(true);
@@ -359,6 +363,68 @@ QString RimSummaryPlot::asciiDataForPlotExport() const
}
}
{
std::vector<std::vector<time_t> > timeSteps;
std::vector<std::vector<std::vector<double> > > allCurveData;
std::vector<std::vector<QString > > allCurveNames;
//Vectors containing cases - curves - data points/curve name
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
if (!curve->isCurveVisible()) continue;
size_t casePosInList = cvf::UNDEFINED_SIZE_T;
if (casePosInList == cvf::UNDEFINED_SIZE_T)
{
std::vector<time_t> curveTimeSteps = curve->timeSteps();
timeSteps.push_back(curveTimeSteps);
std::vector<std::vector<double> > curveDataForCase;
std::vector<double> curveYData = curve->yValues();
curveDataForCase.push_back(curveYData);
allCurveData.push_back(curveDataForCase);
std::vector<QString> curveNamesForCase;
curveNamesForCase.push_back(curve->curveName());
allCurveNames.push_back(curveNamesForCase);
}
else
{
std::vector<double> curveYData = curve->yValues();
allCurveData[casePosInList].push_back(curveYData);
QString curveName = curve->curveName();
allCurveNames[casePosInList].push_back(curveName);
}
}
for (size_t i = 0; i < timeSteps.size(); i++) //cases
{
out += "\n\n";
for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points
{
if (j == 0)
{
out += "Date and time";
for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves
{
out += "\t" + (allCurveNames[i][k]);
}
}
out += "\n";
out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss ");
for (size_t k = 0; k < allCurveData[i].size(); k++) // curves
{
out += "\t" + QString::number(allCurveData[i][k][j], 'g', 6);
}
}
}
}
return out;
}
@@ -391,7 +457,10 @@ void RimSummaryPlot::updateAxis(RiaDefines::PlotAxis plotAxis)
timeHistoryQuantities.insert(c->quantityName());
}
RimSummaryPlotYAxisFormatter calc(yAxisProperties, visibleSummaryCurvesForAxis(plotAxis), timeHistoryQuantities);
RimSummaryPlotYAxisFormatter calc(yAxisProperties,
visibleSummaryCurvesForAxis(plotAxis),
visibleAsciiDataCurvesForAxis(plotAxis),
timeHistoryQuantities);
calc.applyYAxisPropertiesToPlot(m_qwtPlot);
}
else
@@ -426,6 +495,13 @@ void RimSummaryPlot::updateZoomForAxis(RiaDefines::PlotAxis plotAxis)
plotCurves.push_back(c->qwtPlotCurve());
}
for (RimAsciiDataCurve* c : visibleAsciiDataCurvesForAxis(plotAxis))
{
std::vector<double> curveValues = c->yValues();
yValues.insert(yValues.end(), curveValues.begin(), curveValues.end());
plotCurves.push_back(c->qwtPlotCurve());
}
double min, max;
RimSummaryPlotYAxisRangeCalculator calc(plotCurves, yValues);
calc.computeYRange(&min, &max);
@@ -485,6 +561,11 @@ bool RimSummaryPlot::hasVisibleCurvesForAxis(RiaDefines::PlotAxis plotAxis) cons
return true;
}
if (visibleAsciiDataCurvesForAxis(plotAxis).size() > 0)
{
return true;
}
return false;
}
@@ -527,6 +608,24 @@ std::vector<RimGridTimeHistoryCurve*> RimSummaryPlot::visibleTimeHistoryCurvesFo
return curves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimAsciiDataCurve*> RimSummaryPlot::visibleAsciiDataCurvesForAxis(RiaDefines::PlotAxis plotAxis) const
{
std::vector<RimAsciiDataCurve*> curves;
for (auto c : m_asciiDataCurves)
{
if (c->isCurveVisible() && c->yAxis() == plotAxis)
{
curves.push_back(c);
}
}
return curves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -691,6 +790,21 @@ void RimSummaryPlot::addGridTimeHistoryCurve(RimGridTimeHistoryCurve* curve)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::addAsciiDataCruve(RimAsciiDataCurve* curve)
{
CVF_ASSERT(curve);
m_asciiDataCurves.push_back(curve);
if (m_qwtPlot)
{
curve->setParentQwtPlot(m_qwtPlot);
this->updateAxes();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -742,6 +856,7 @@ void RimSummaryPlot::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering
uiTreeOrdering.add(&m_curveFilters);
uiTreeOrdering.add(&m_summaryCurves);
uiTreeOrdering.add(&m_gridTimeHistoryCurves);
uiTreeOrdering.add(&m_asciiDataCurves);
uiTreeOrdering.skipRemainingChildren(true);
}
@@ -768,6 +883,11 @@ void RimSummaryPlot::loadDataAndUpdate()
curve->loadDataAndUpdate();
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->loadDataAndUpdate();
}
this->updateAxes();
updateZoomInQwt();
@@ -867,6 +987,11 @@ QWidget* RimSummaryPlot::createViewWidget(QWidget* mainWindowParent)
{
curve->setParentQwtPlot(m_qwtPlot);
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->setParentQwtPlot(m_qwtPlot);
}
}
return m_qwtPlot;
@@ -937,6 +1062,11 @@ void RimSummaryPlot::detachAllCurves()
{
curve->detachQwtCurve();
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->detachQwtCurve();
}
}
//--------------------------------------------------------------------------------------------------
@@ -960,6 +1090,14 @@ caf::PdmObject* RimSummaryPlot::findRimCurveFromQwtCurve(const QwtPlotCurve* qwt
}
}
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
if (curve->qwtPlotCurve() == qwtCurve)
{
return curve;
}
}
for (RimSummaryCurveFilter* curveFilter: m_curveFilters)
{
RimSummaryCurve* foundCurve = curveFilter->findRimCurveFromQwtCurve(qwtCurve);
@@ -974,7 +1112,7 @@ caf::PdmObject* RimSummaryPlot::findRimCurveFromQwtCurve(const QwtPlotCurve* qwt
//--------------------------------------------------------------------------------------------------
size_t RimSummaryPlot::curveCount() const
{
return m_summaryCurves.size() + m_gridTimeHistoryCurves.size();
return m_summaryCurves.size() + m_gridTimeHistoryCurves.size() + m_asciiDataCurves.size();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -36,6 +36,7 @@ class RimSummaryCurveFilter;
class RimSummaryYAxisProperties;
class RimSummaryTimeAxisProperties;
class RimGridTimeHistoryCurve;
class RimAsciiDataCurve;
class PdmUiTreeOrdering;
class QwtPlotCurve;
@@ -61,6 +62,8 @@ public:
void addGridTimeHistoryCurve(RimGridTimeHistoryCurve* curve);
void addAsciiDataCruve(RimAsciiDataCurve* curve);
caf::PdmObject* findRimCurveFromQwtCurve(const QwtPlotCurve* curve) const;
size_t curveCount() const;
@@ -102,6 +105,7 @@ protected:
private:
std::vector<RimSummaryCurve*> visibleSummaryCurvesForAxis(RiaDefines::PlotAxis plotAxis) const;
std::vector<RimGridTimeHistoryCurve*> visibleTimeHistoryCurvesForAxis(RiaDefines::PlotAxis plotAxis) const;
std::vector<RimAsciiDataCurve*> visibleAsciiDataCurvesForAxis(RiaDefines::PlotAxis plotAxis) const;
bool hasVisibleCurvesForAxis(RiaDefines::PlotAxis plotAxis) const;
RimSummaryYAxisProperties* yAxisPropertiesForAxis(RiaDefines::PlotAxis plotAxis) const;
@@ -125,6 +129,7 @@ private:
caf::PdmChildArrayField<RimGridTimeHistoryCurve*> m_gridTimeHistoryCurves;
caf::PdmChildArrayField<RimSummaryCurve*> m_summaryCurves;
caf::PdmChildArrayField<RimSummaryCurveFilter*> m_curveFilters;
caf::PdmChildArrayField<RimAsciiDataCurve*> m_asciiDataCurves;
caf::PdmField<bool> m_isAutoZoom;
caf::PdmChildField<RimSummaryYAxisProperties*> m_leftYAxisProperties;

View File

@@ -231,6 +231,11 @@ size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName)
scalarResultIndex = this->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RiaDefines::SOURSIMRL, resultName);
}
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = this->findScalarResultIndex(RiaDefines::GENERATED, resultName);
@@ -323,6 +328,39 @@ size_t RigCaseCellResultsData::addEmptyScalarResult(RiaDefines::ResultCatType ty
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranZResultName()));
statisticsCalculator = calc;
}
else if (resultName == RiaDefines::combinedWaterFluxResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATK+"));
statisticsCalculator = calc;
}
else if (resultName == RiaDefines::combinedOilFluxResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILK+"));
statisticsCalculator = calc;
}
else if (resultName == RiaDefines::combinedGasFluxResultName())
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASI+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASJ+"));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASK+"));
statisticsCalculator = calc;
}
else if (resultName.endsWith("IJK"))
{
cvf::ref<RigEclipseMultiPropertyStatCalc> calc = new RigEclipseMultiPropertyStatCalc();
QString baseName = resultName.left(resultName.size() - 3);
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1I").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1J").arg(baseName)));
calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1K").arg(baseName)));
statisticsCalculator = calc;
}
else
{
statisticsCalculator = new RigEclipseNativeStatCalc(this, scalarResultIndex);
@@ -648,6 +686,23 @@ void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::eraseAllSourSimData()
{
std::vector<size_t> sourSimIndices;
for (size_t i = 0; i < m_resultInfos.size(); i++)
{
RigEclipseResultInfo& ri = m_resultInfos[i];
if (ri.m_resultType == RiaDefines::SOURSIMRL)
{
ri.m_resultType = RiaDefines::REMOVED;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -678,6 +733,34 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
}
}
// FLUX
{
size_t waterIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName());
if (waterIndex == cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRWATK+") != cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName(), false);
}
size_t oilIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName());
if (oilIndex == cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLROILK+") != cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName(), false);
}
size_t gasIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName());
if (gasIndex == cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASI+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASJ+") != cvf::UNDEFINED_SIZE_T &&
findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "FLRGASK+") != cvf::UNDEFINED_SIZE_T)
{
addEmptyScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName(), false);
}
}
// TRANSXYZ
{
size_t tranX, tranY, tranZ;

View File

@@ -113,6 +113,7 @@ public:
bool mustBeCalculated(size_t scalarResultIndex) const;
void setMustBeCalculated(size_t scalarResultIndex);
void eraseAllSourSimData();
public:

View File

@@ -31,6 +31,19 @@
#include <cmath> // Needed for HUGE_VAL on Linux
namespace caf
{
template<>
void RigFlowDiagResults::CellSelectionEnum::setUp()
{
addItem(RigFlowDiagResults::CELLS_ACTIVE, "CELLS_ACTIVE", "Active cells");
addItem(RigFlowDiagResults::CELLS_COMMUNICATION, "CELLS_COMMUNICATION", "Communication cells");
addItem(RigFlowDiagResults::CELLS_FLOODED, "CELLS_FLOODED", "Flooded cells");
addItem(RigFlowDiagResults::CELLS_DRAINED, "CELLS_DRAINED", "Drained cells");
setDefault(RigFlowDiagResults::CELLS_ACTIVE);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -678,10 +691,11 @@ std::vector<int> RigFlowDiagResults::calculatedTimeSteps(RigFlowDiagResultAddres
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex, double max_pv_fraction)
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::flowCharacteristicsResults(int frameIndex,
CellSelection cellSelection,
const std::vector<QString>& tracerNames,
double max_pv_fraction)
{
std::vector<QString> tracerNames = m_flowDiagSolution->tracerNames();
std::set<std::string> injectorNames;
std::set<std::string> producerNames;
@@ -701,8 +715,86 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagResults::f
RigFlowDiagResultAddress injectorAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, injectorNames);
RigFlowDiagResultAddress producerAddress(RIG_FLD_TOF_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, producerNames);
const std::vector<double>* injectorResults = resultValues(injectorAddress, frameIndex);
const std::vector<double>* producerResults = resultValues(producerAddress, frameIndex);
const std::vector<double>* allInjectorResults = resultValues(injectorAddress, frameIndex);
const std::vector<double>* allProducerResults = resultValues(producerAddress, frameIndex);
return solverInterface()->calculateFlowCharacteristics(injectorResults, producerResults, max_pv_fraction);
std::vector<double> injectorResults;
std::vector<double> producerResults;
std::vector<size_t> selectedCellIndices;
if (cellSelection == CELLS_COMMUNICATION)
{
std::set<std::string> allTracers;
allTracers.insert(injectorNames.begin(), injectorNames.end());
allTracers.insert(producerNames.begin(), producerNames.end());
RigFlowDiagResultAddress communicationAddress(RIG_FLD_COMMUNICATION_RESNAME, RigFlowDiagResultAddress::PHASE_ALL, allTracers);
const std::vector<double>* communicationResult = resultValues(communicationAddress, frameIndex);
for (size_t i = 0; i < communicationResult->size(); ++i)
{
if (communicationResult->at(i) != HUGE_VAL && communicationResult->at(i) > 0)
{
selectedCellIndices.push_back(i);
if (allInjectorResults != nullptr) injectorResults.push_back(allInjectorResults->at(i));
if (allProducerResults != nullptr) producerResults.push_back(allProducerResults->at(i));
}
}
}
else if (cellSelection == CELLS_FLOODED)
{
if (allInjectorResults != nullptr)
{
for (size_t i = 0; i < allInjectorResults->size(); ++i)
{
if (allInjectorResults->at(i) != HUGE_VAL)
{
selectedCellIndices.push_back(i);
injectorResults.push_back(allInjectorResults->at(i));
if (allProducerResults != nullptr)
{
producerResults.push_back(allProducerResults->at(i));
}
else
{
producerResults.push_back(0);
}
}
}
}
}
else if (cellSelection == CELLS_DRAINED)
{
if (allProducerResults != nullptr)
{
for (size_t i = 0; i < allProducerResults->size(); ++i)
{
if (allProducerResults->at(i) != HUGE_VAL)
{
selectedCellIndices.push_back(i);
producerResults.push_back(allProducerResults->at(i));
if (allInjectorResults != nullptr)
{
injectorResults.push_back(allInjectorResults->at(i));
}
else
{
injectorResults.push_back(0);
}
}
}
}
}
else
{
if (allInjectorResults != nullptr) injectorResults = *allInjectorResults;
if (allProducerResults != nullptr) producerResults = *allProducerResults;
for (size_t i = 0; i < injectorResults.size(); ++i)
{
selectedCellIndices.push_back(i);
}
}
return solverInterface()->calculateFlowCharacteristics(&injectorResults, &producerResults, selectedCellIndices, max_pv_fraction);
}

View File

@@ -24,6 +24,7 @@
#include "RimFlowDiagSolution.h"
#include "cafPdmPointer.h"
#include "cafAppEnum.h"
#include "cvfBase.h"
#include "cvfObject.h"
@@ -38,6 +39,17 @@ class RigActiveCellInfo;
class RigFlowDiagResults: public cvf::Object
{
public:
enum CellSelection
{
CELLS_ACTIVE,
CELLS_COMMUNICATION,
CELLS_FLOODED,
CELLS_DRAINED
};
typedef caf::AppEnum<CellSelection> CellSelectionEnum;
public:
RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount);
virtual ~RigFlowDiagResults();
@@ -67,7 +79,10 @@ public:
std::vector<int> calculatedTimeSteps(RigFlowDiagResultAddress::PhaseSelection phaseSelection);
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex, double max_pv_fraction);
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame flowCharacteristicsResults(int frameIndex,
CellSelection cellSelection,
const std::vector<QString>& tracerNames,
double max_pv_fraction);
private:
const std::vector<double>* findOrCalculateResult (const RigFlowDiagResultAddress& resVarAddr, size_t frameIndex);

View File

@@ -419,6 +419,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInterface::calculateFlowCharacteristics(const std::vector<double>* injector_tof,
const std::vector<double>* producer_tof,
const std::vector<size_t>& selected_cell_indices,
double max_pv_fraction)
{
using namespace Opm::FlowDiagnostics;
@@ -428,12 +429,18 @@ RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame RigFlowDiagSolverInte
{
return result;
}
std::vector<double> poreVolume;
for (size_t cellIndex : selected_cell_indices)
{
poreVolume.push_back(m_opmFlowDiagStaticData->m_poreVolume[cellIndex]);
}
try
{
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve(*injector_tof,
*producer_tof,
m_opmFlowDiagStaticData->m_poreVolume,
poreVolume,
max_pv_fraction);
result.m_flowCapStorageCapCurve = flowCapStorCapCurve;

View File

@@ -86,6 +86,7 @@ public:
FlowCharacteristicsResultFrame calculateFlowCharacteristics(const std::vector<double>* injector_tof,
const std::vector<double>* producer_tof,
const std::vector<size_t>& selected_cell_indices,
double max_pv_fraction);
private:

View File

@@ -166,38 +166,313 @@ void RigNNCData::processConnections(const RigMainGrid& mainGrid)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>& RigNNCData::makeConnectionScalarResult(size_t scalarResultIndex)
std::vector<double>& RigNNCData::makeStaticConnectionScalarResult(QString nncDataType)
{
std::vector<double>& results = m_connectionResults[scalarResultIndex];
results.resize(m_connections.size(), HUGE_VAL);
std::vector< std::vector<double> >& results = m_connectionResults[nncDataType];
results.resize(1);
results[0].resize(m_connections.size(), HUGE_VAL);
return results[0];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigNNCData::staticConnectionScalarResult(size_t scalarResultIndex) const
{
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
std::map<QString, std::vector< std::vector<double> > >::const_iterator it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
CVF_ASSERT(it->second.size() == 1);
return &(it->second[0]);
}
else
{
return nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigNNCData::staticConnectionScalarResultByName(const QString& nncDataType) const
{
std::map<QString, std::vector< std::vector<double> > >::const_iterator it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
CVF_ASSERT(it->second.size() == 1);
return &(it->second[0]);
}
else
{
return nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector< std::vector<double> >& RigNNCData::makeDynamicConnectionScalarResult(QString nncDataType, size_t timeStepCount)
{
auto& results = m_connectionResults[nncDataType];
results.resize(timeStepCount);
return results;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigNNCData::connectionScalarResult(size_t scalarResultIndex) const
const std::vector< std::vector<double> >* RigNNCData::dynamicConnectionScalarResult(size_t scalarResultIndex) const
{
std::map<size_t, std::vector<double> >::const_iterator it = m_connectionResults.find(scalarResultIndex);
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
return &(it->second);
}
else
return NULL;
{
return nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigNNCData::setCombTransmissibilityScalarResultIndex(size_t scalarResultIndex)
const std::vector<double>* RigNNCData::dynamicConnectionScalarResult(size_t scalarResultIndex, size_t timeStep) const
{
std::map<size_t, std::vector<double> >::iterator it = m_connectionResults.find(cvf::UNDEFINED_SIZE_T);
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
std::vector<double>& emptyData = m_connectionResults[scalarResultIndex];
std::vector<double>& realData = m_connectionResults[cvf::UNDEFINED_SIZE_T];
emptyData.swap(realData);
m_connectionResults.erase(cvf::UNDEFINED_SIZE_T);
if (it->second.size() > timeStep)
{
return &(it->second[timeStep]);
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<std::vector<double>>* RigNNCData::dynamicConnectionScalarResultByName(const QString& nncDataType) const
{
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
return &(it->second);
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigNNCData::dynamicConnectionScalarResultByName(const QString& nncDataType, size_t timeStep) const
{
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
if (it->second.size() > timeStep)
{
return &(it->second[timeStep]);
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector< std::vector<double> >& RigNNCData::makeGeneratedConnectionScalarResult(QString nncDataType, size_t timeStepCount)
{
auto& results = m_connectionResults[nncDataType];
results.resize(timeStepCount);
return results;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector< std::vector<double> >* RigNNCData::generatedConnectionScalarResult(size_t scalarResultIndex) const
{
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
return &(it->second);
}
else
{
return nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigNNCData::generatedConnectionScalarResult(size_t scalarResultIndex, size_t timeStep) const
{
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
if (it->second.size() > timeStep)
{
return &(it->second[timeStep]);
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector< std::vector<double> >* RigNNCData::generatedConnectionScalarResult(size_t scalarResultIndex)
{
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
return &(it->second);
}
else
{
return nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* RigNNCData::generatedConnectionScalarResult(size_t scalarResultIndex, size_t timeStep)
{
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return nullptr;
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
if (it->second.size() > timeStep)
{
return &(it->second[timeStep]);
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<std::vector<double>>* RigNNCData::generatedConnectionScalarResultByName(const QString& nncDataType) const
{
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
return &(it->second);
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigNNCData::generatedConnectionScalarResultByName(const QString& nncDataType, size_t timeStep) const
{
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
if (it->second.size() > timeStep)
{
return &(it->second[timeStep]);
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<double>>* RigNNCData::generatedConnectionScalarResultByName(const QString& nncDataType)
{
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
return &(it->second);
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>* RigNNCData::generatedConnectionScalarResultByName(const QString& nncDataType, size_t timeStep)
{
auto it = m_connectionResults.find(nncDataType);
if (it != m_connectionResults.end())
{
if (it->second.size() > timeStep)
{
return &(it->second[timeStep]);
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RigNNCData::availableProperties(NNCResultType resultType) const
{
std::vector<QString> properties;
for (auto it : m_connectionResults)
{
if (resultType == NNC_STATIC && it.second.size() == 1 && it.second[0].size() > 0 && isNative(it.first))
{
properties.push_back(it.first);
}
else if (resultType == NNC_DYNAMIC && it.second.size() > 1 && it.second[0].size() > 0 && isNative(it.first))
{
properties.push_back(it.first);
}
else if (resultType == NNC_GENERATED && !isNative(it.first))
{
properties.push_back(it.first);
}
}
return properties;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigNNCData::setScalarResultIndex(const QString& nncDataType, size_t scalarResultIndex)
{
m_resultIndexToNNCDataType[scalarResultIndex] = nncDataType;
}
//--------------------------------------------------------------------------------------------------
@@ -205,25 +480,40 @@ void RigNNCData::setCombTransmissibilityScalarResultIndex(size_t scalarResultInd
//--------------------------------------------------------------------------------------------------
bool RigNNCData::hasScalarValues(size_t scalarResultIndex)
{
std::map<size_t, std::vector<double> >::iterator it = m_connectionResults.find(scalarResultIndex);
QString nncDataType = getNNCDataTypeFromScalarResultIndex(scalarResultIndex);
if (nncDataType.isNull()) return false;
auto it = m_connectionResults.find(nncDataType);
return (it != m_connectionResults.end());
}
/*
//--------------------------------------------------------------------------------------------------
/// TODO: Possibly not needed !
///
//--------------------------------------------------------------------------------------------------
const std::vector<size_t>& RigNNCData::findConnectionIndices( size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const
const QString RigNNCData::getNNCDataTypeFromScalarResultIndex(size_t scalarResultIndex) const
{
ConnectionSearchMap::const_iterator it;
static std::vector<size_t> empty;
it = m_cellIdxToFaceToConnectionIdxMap.find(reservoirCellIndex);
if (it != m_cellIdxToFaceToConnectionIdxMap.end())
auto it = m_resultIndexToNNCDataType.find(scalarResultIndex);
if (it != m_resultIndexToNNCDataType.end())
{
return it->second[face];
return it->second;
}
return empty;
return QString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigNNCData::isNative(QString nncDataType) const
{
if (nncDataType == RigNNCData::propertyNameCombTrans() ||
nncDataType == RigNNCData::propertyNameFluxGas() ||
nncDataType == RigNNCData::propertyNameFluxOil() ||
nncDataType == RigNNCData::propertyNameFluxWat() ||
nncDataType == RigNNCData::propertyNameRiCombMult() ||
nncDataType == RigNNCData::propertyNameRiCombTrans() ||
nncDataType == RigNNCData::propertyNameRiCombTransByArea())
{
return true;
}
return false;
}
*/

View File

@@ -57,28 +57,61 @@ public:
class RigNNCData : public cvf::Object
{
public:
enum NNCResultType
{
NNC_DYNAMIC,
NNC_STATIC,
NNC_GENERATED
};
static QString propertyNameFluxWat() { return "FLRWAT"; }
static QString propertyNameFluxOil() { return "FLROIL"; }
static QString propertyNameFluxGas() { return "FLRGAS"; }
static QString propertyNameCombTrans() { return "TRAN"; }
static QString propertyNameRiCombTrans() { return "riTRAN"; }
static QString propertyNameRiCombTransByArea() { return "riTRANbyArea"; }
static QString propertyNameRiCombMult() { return "riMULT"; }
RigNNCData();
void processConnections(const RigMainGrid& mainGrid);
std::vector<RigConnection>& connections() { return m_connections; }
const std::vector<RigConnection>& connections() const { return m_connections; };
const std::vector<RigConnection>& connections() const { return m_connections; }
std::vector<double>& makeConnectionScalarResult(size_t scalarResultIndex);
const std::vector<double>* connectionScalarResult(size_t scalarResultIndex) const;
std::vector<double>& makeStaticConnectionScalarResult(QString nncDataType);
const std::vector<double>* staticConnectionScalarResult(size_t scalarResultIndex) const;
const std::vector<double>* staticConnectionScalarResultByName(const QString& nncDataType) const;
void setCombTransmissibilityScalarResultIndex(size_t scalarResultIndex);
std::vector< std::vector<double> >& makeDynamicConnectionScalarResult(QString nncDataType, size_t timeStepCount);
const std::vector< std::vector<double> >* dynamicConnectionScalarResult(size_t scalarResultIndex) const;
const std::vector<double>* dynamicConnectionScalarResult(size_t scalarResultIndex, size_t timeStep) const;
const std::vector< std::vector<double> >* dynamicConnectionScalarResultByName(const QString& nncDataType) const;
const std::vector<double>* dynamicConnectionScalarResultByName(const QString& nncDataType, size_t timeStep) const;
std::vector< std::vector<double> >& makeGeneratedConnectionScalarResult(QString nncDataType, size_t timeStepCount);
const std::vector< std::vector<double> >* generatedConnectionScalarResult(size_t scalarResultIndex) const;
const std::vector<double>* generatedConnectionScalarResult(size_t scalarResultIndex, size_t timeStep) const;
std::vector< std::vector<double> >* generatedConnectionScalarResult(size_t scalarResultIndex);
std::vector<double>* generatedConnectionScalarResult(size_t scalarResultIndex, size_t timeStep);
const std::vector< std::vector<double> >* generatedConnectionScalarResultByName(const QString& nncDataType) const;
const std::vector<double>* generatedConnectionScalarResultByName(const QString& nncDataType, size_t timeStep) const;
std::vector< std::vector<double> >* generatedConnectionScalarResultByName(const QString& nncDataType);
std::vector<double>* generatedConnectionScalarResultByName(const QString& nncDataType, size_t timeStep);
std::vector<QString> availableProperties(NNCResultType resultType) const;
void setScalarResultIndex(const QString& nncDataType, size_t scalarResultIndex);
bool hasScalarValues(size_t scalarResultIndex);
private: // This section is possibly not needed
//const std::vector<size_t>& findConnectionIndices(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const;
//typedef std::map<size_t, caf::FixedArray<std::vector<size_t>, 7 > > ConnectionSearchMap;
//ConnectionSearchMap m_cellIdxToFaceToConnectionIdxMap;
private:
const QString getNNCDataTypeFromScalarResultIndex(size_t scalarResultIndex) const;
bool isNative(QString nncDataType) const;
private:
std::vector<RigConnection> m_connections;
std::map<size_t, std::vector<double> > m_connectionResults; ///< scalarResultIndex to value array map
std::vector<RigConnection> m_connections;
std::map<QString, std::vector< std::vector<double> > > m_connectionResults;
std::map<size_t, QString> m_resultIndexToNNCDataType;
};

View File

@@ -542,7 +542,7 @@ void RigReservoirBuilderMock::addFaults(RigEclipseCaseData* eclipseCase)
addNnc(grid, i1, j1, k1, i2, j2, k2, nncConnections);
}
std::vector<double>& tranVals = grid->nncData()->makeConnectionScalarResult(cvf::UNDEFINED_SIZE_T);
std::vector<double>& tranVals = grid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameCombTrans());
for (size_t cIdx = 0; cIdx < tranVals.size(); ++cIdx)
{
tranVals[cIdx] = 0.2;

View File

@@ -125,6 +125,55 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(con
return cellFaceAccessObject;
}
else if (uiResultName == RiaDefines::combinedWaterFluxResultName())
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
cvf::ref<RigResultAccessor> xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLRWATI+");
cvf::ref<RigResultAccessor> yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLRWATJ+");
cvf::ref<RigResultAccessor> zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLRWATK+");
cellFaceAccessObject->setTransResultAccessors(xRiAreaNormTransAccessor.p(), yRiAreaNormTransAccessor.p(), zRiAreaNormTransAccessor.p());
return cellFaceAccessObject;
}
else if (uiResultName == RiaDefines::combinedOilFluxResultName())
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
cvf::ref<RigResultAccessor> xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLROILI+");
cvf::ref<RigResultAccessor> yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLROILJ+");
cvf::ref<RigResultAccessor> zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLROILK+");
cellFaceAccessObject->setTransResultAccessors(xRiAreaNormTransAccessor.p(), yRiAreaNormTransAccessor.p(), zRiAreaNormTransAccessor.p());
return cellFaceAccessObject;
}
else if (uiResultName == RiaDefines::combinedGasFluxResultName())
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
cvf::ref<RigResultAccessor> xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLRGASI+");
cvf::ref<RigResultAccessor> yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLRGASJ+");
cvf::ref<RigResultAccessor> zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, "FLRGASK+");
cellFaceAccessObject->setTransResultAccessors(xRiAreaNormTransAccessor.p(), yRiAreaNormTransAccessor.p(), zRiAreaNormTransAccessor.p());
return cellFaceAccessObject;
}
else if (uiResultName.endsWith("IJK"))
{
cvf::ref<RigCombTransResultAccessor> cellFaceAccessObject = new RigCombTransResultAccessor(grid);
QString baseName = uiResultName.left(uiResultName.size() - 3);
cvf::ref<RigResultAccessor> iAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, QString("%1I").arg(baseName));
cvf::ref<RigResultAccessor> jAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, QString("%1J").arg(baseName));
cvf::ref<RigResultAccessor> kAccessor = RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, QString("%1K").arg(baseName));
cellFaceAccessObject->setTransResultAccessors(iAccessor.p(), jAccessor.p(), kAccessor.p());
return cellFaceAccessObject;
}
return RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName);
}

View File

@@ -29,7 +29,11 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigTimeHistoryResultAccessor::timeHistoryValues(RigEclipseCaseData* eclipseCaseData, RimEclipseResultDefinition* resultDefinition, size_t gridIndex, size_t cellIndex, size_t timeStepCount)
std::vector<double> RigTimeHistoryResultAccessor::timeHistoryValues(RigEclipseCaseData* eclipseCaseData,
RimEclipseResultDefinition* resultDefinition,
size_t gridIndex,
size_t cellIndex,
size_t timeStepCount)
{
std::vector<double> values;

View File

@@ -55,7 +55,7 @@ RigTofAccumulatedPhaseFractionsCalculator::RigTofAccumulatedPhaseFractionsCalcul
const std::vector<double>* swatResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSwat, timestep));
const std::vector<double>* soilResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSoil, timestep));
const std::vector<double>* sgasResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexSgas, timestep));
const std::vector<double>* porvResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexPorv, timestep));
const std::vector<double>* porvResults = &(eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(scalarResultIndexPorv, 0));
RimFlowDiagSolution* flowDiagSolution = caseToApply->defaultFlowDiagSolution();
@@ -77,10 +77,10 @@ RigTofAccumulatedPhaseFractionsCalculator::RigTofAccumulatedPhaseFractionsCalcul
swatResults,
soilResults,
sgasResults,
m_tofInIncreasingOrder,
m_accumulatedPhaseFractionSwat,
m_accumulatedPhaseFractionSoil,
m_accumulatedPhaseFractionSgas,
m_tofInIncreasingOrder);
m_accumulatedPhaseFractionSgas);
}
//--------------------------------------------------------------------------------------------------
@@ -98,10 +98,16 @@ void RigTofAccumulatedPhaseFractionsCalculator::sortTofAndCalculateAccPhaseFract
std::vector<double>& accumulatedPhaseFractionSgas)
{
if (tofData == nullptr || fractionData == nullptr)
{
return;
}
std::map<double, std::vector<int> > tofAndIndexMap;
for (int i = 0; i < static_cast<int>(tofData->size()); i++)
{
if ((*tofData)[i] == HUGE_VAL) continue;
std::vector<int> vectorOfIndexes;
vectorOfIndexes.push_back(i);

View File

@@ -29,6 +29,10 @@
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigMainGrid.h"
#include "RigGeoMechCaseData.h"
#include "RigFemPartCollection.h"
#include "RigFemPart.h"
#include "RigFemPartGrid.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimCellEdgeColors.h"
@@ -39,6 +43,10 @@
#include "RimEclipseView.h"
#include "RimEclipseWellCollection.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechView.h"
#include "RiuSelectionManager.h"
#include <QTcpSocket>
@@ -538,3 +546,95 @@ public:
static bool RiaGetTimeStepDays_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetTimeStepDays>(RiaGetTimeStepDays::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetSelectedCells: public RiaSocketCommand
{
public:
static QString commandName () { return QString("GetSelectedCells"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
// findCaseFromArgs only returns RimEclipseCase, so geomech cases are not supported because of this.
// The rest of the function supports geomech cases, so using a findCaseFromArgs that supports geomech
// cases is the only change needed to add geomech support.
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
if (!rimCase) return true;
// Write data back to octave: column count, bytes per column, caseId, gridNumber, cellI, cellJ, cellK
std::array<std::vector<qint32>, 5> selectedCellInfo;
getSelectedCells(rimCase,
selectedCellInfo[0],
selectedCellInfo[1],
selectedCellInfo[2],
selectedCellInfo[3],
selectedCellInfo[4]);
// First write column count
quint64 columnCount = 5;
socketStream << columnCount;
// then the byte-size of the size of one column
quint64 columnByteCount = (quint64)(selectedCellInfo[0].size()*sizeof(qint32));
socketStream << columnByteCount;
// Write back table data
for (size_t tIdx = 0; tIdx < columnCount; ++tIdx)
{
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)selectedCellInfo[tIdx].data(), columnByteCount);
}
return true;
}
static void getSelectedCells(const RimCase* reservoirCase,
std::vector<qint32>& caseNumber,
std::vector<qint32>& gridNumber,
std::vector<qint32>& cellI,
std::vector<qint32>& cellJ,
std::vector<qint32>& cellK)
{
std::vector<RiuSelectionItem*> items;
RiuSelectionManager::instance()->selectedItems(items);
for (const RiuSelectionItem* item : items)
{
size_t i, j, k;
size_t gridIndex;
size_t caseId;
if (item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT)
{
const RiuEclipseSelectionItem* eclipseItem = static_cast<const RiuEclipseSelectionItem*>(item);
eclipseItem->m_view->eclipseCase()->eclipseCaseData()->grid(eclipseItem->m_gridIndex)->ijkFromCellIndex(eclipseItem->m_cellIndex, &i, &j, &k);
gridIndex = eclipseItem->m_gridIndex;
caseId = eclipseItem->m_view->eclipseCase()->caseId;
}
else if (item->type() == RiuSelectionItem::GEOMECH_SELECTION_OBJECT)
{
const RiuGeoMechSelectionItem* geomechItem = static_cast<const RiuGeoMechSelectionItem*>(item);
geomechItem->m_view->geoMechCase()->geoMechData()->femParts()->part(geomechItem->m_gridIndex)->structGrid()->ijkFromCellIndex(geomechItem->m_cellIndex, &i, &j, &k);
gridIndex = geomechItem->m_gridIndex;
caseId = geomechItem->m_view->geoMechCase()->caseId;
}
else
{
continue;
}
if (caseId == reservoirCase->caseId)
{
caseNumber.push_back(static_cast<int>(caseId));
gridNumber.push_back(static_cast<int>(gridIndex));
cellI.push_back(static_cast<int>(i + 1));
cellJ.push_back(static_cast<int>(j + 1));
cellK.push_back(static_cast<int>(k + 1));
}
}
}
};
static bool RiaGetSelectedCells_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetSelectedCells>(RiaGetSelectedCells::commandName());

View File

@@ -0,0 +1,579 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RiaSocketCommand.h"
#include "RiaSocketServer.h"
#include "RiaSocketDataTransfer.h"
#include "RiaSocketTools.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigMainGrid.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimCellEdgeColors.h"
#include "RimCellRangeFilterCollection.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseView.h"
#include "RimEclipseWellCollection.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimEclipseInputCase.h"
#include "RimEclipseInputProperty.h"
#include "RimEclipseInputPropertyCollection.h"
#include <QTcpSocket>
#include <QErrorMessage>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetNNCConnections: public RiaSocketCommand
{
public:
static QString commandName () { return QString("GetNNCConnections"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
// Write data back to octave: columnCount, GridNr I J K GridNr I J K
if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()))
{
// No data available
socketStream << (quint64)0;
return true;
}
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
size_t connectionCount = mainGrid->nncData()->connections().size();
socketStream << (quint64)connectionCount;
for (const RigConnection& connection : mainGrid->nncData()->connections())
{
const RigCell& cell1 = mainGrid->globalCellArray()[connection.m_c1GlobIdx];
const RigCell& cell2 = mainGrid->globalCellArray()[connection.m_c2GlobIdx];
sendCellInfo(socketStream, cell1);
sendCellInfo(socketStream, cell2);
}
return true;
}
static void sendCellInfo(QDataStream& socketStream, const RigCell& cell)
{
RigGridBase* hostGrid = cell.hostGrid();
size_t gridLocalCellIndex = cell.gridLocalCellIndex();
size_t i, j, k;
hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k);
socketStream << (qint32)hostGrid->gridIndex();
socketStream << (qint32)(i+1) << (qint32)(j+1) << (qint32)(k+1);
}
};
static bool RiaGetNNCConnections_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetNNCConnections>(RiaGetNNCConnections::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetDynamicNNCValues: public RiaSocketCommand
{
public:
static QString commandName () { return QString("GetDynamicNNCValues"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
// Write data back to octave: connectionCount, timeStepCount, property values
if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()))
{
// No data available
socketStream << (quint64)0 << (quint64)0;
return true;
}
QString propertyName = args[2];
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
const std::vector< std::vector<double> >* nncValues = mainGrid->nncData()->dynamicConnectionScalarResultByName(propertyName);
if (nncValues == nullptr)
{
socketStream << (quint64)0 << (quint64)0;
return true;
}
std::vector<size_t> requestedTimeSteps;
if (args.size() > 3)
{
bool timeStepReadError = false;
for (int argIdx = 3; argIdx < args.size(); ++argIdx)
{
bool conversionOk = false;
int tsIdx = args[argIdx].toInt(&conversionOk);
if (conversionOk)
{
requestedTimeSteps.push_back(tsIdx);
}
else
{
timeStepReadError = true;
}
}
if (timeStepReadError)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: riGetDynamicNNCValues : \n") + RiaSocketServer::tr("An error occurred while interpreting the requested time steps."));
}
}
else
{
for (size_t timeStep = 0; timeStep < nncValues->size(); ++timeStep)
{
requestedTimeSteps.push_back(timeStep);
}
}
// then the connection count and time step count.
size_t connectionCount = mainGrid->nncData()->connections().size();
size_t timeStepCount = requestedTimeSteps.size();
socketStream << (quint64)connectionCount;
socketStream << (quint64)timeStepCount;
for (size_t timeStep : requestedTimeSteps)
{
const std::vector<double>& timeStepValues = nncValues->at(timeStep);
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)timeStepValues.data(), sizeof(double) * timeStepValues.size());
}
return true;
}
};
static bool RiaGetDynamicNNCValues_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetDynamicNNCValues>(RiaGetDynamicNNCValues::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetStaticNNCValues: public RiaSocketCommand
{
public:
static QString commandName () { return QString("GetStaticNNCValues"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
QString propertyName = args[2];
// Write data back to octave: connectionCount, property values
if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()))
{
// No data available
socketStream << (quint64)0;
return true;
}
RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();
const std::vector<double>* nncValues = mainGrid->nncData()->staticConnectionScalarResultByName(propertyName);
if (nncValues == nullptr)
{
socketStream << (quint64)0;
return true;
}
// connection count
size_t connectionCount = mainGrid->nncData()->connections().size();
socketStream << (quint64)connectionCount;
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)nncValues->data(), sizeof(double) * nncValues->size());
return true;
}
};
static bool RiaGetStaticNNCValues_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetStaticNNCValues>(RiaGetStaticNNCValues::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetNNCPropertyNames: public RiaSocketCommand
{
public:
static QString commandName () { return QString("GetNNCPropertyNames"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()))
{
// No data available
socketStream << (quint64)0;
return true;
}
RigNNCData* nncData = rimCase->eclipseCaseData()->mainGrid()->nncData();
std::vector<QString> propertyTypes;
std::vector<QString> propertyNames;
std::vector<RigNNCData::NNCResultType> resultTypes;
std::vector<QString> resultTypeNames;
resultTypes.push_back(RigNNCData::NNC_DYNAMIC);
resultTypeNames.push_back("DynamicNative");
resultTypes.push_back(RigNNCData::NNC_STATIC);
resultTypeNames.push_back("StaticNative");
resultTypes.push_back(RigNNCData::NNC_GENERATED);
resultTypeNames.push_back("Generated");
for (size_t rtIdx = 0; rtIdx < resultTypes.size(); ++rtIdx)
{
std::vector<QString> availableParameters = nncData->availableProperties(resultTypes[rtIdx]);
for (const QString& parameter : availableParameters)
{
propertyNames.push_back(parameter);
propertyTypes.push_back(resultTypeNames[rtIdx]);
}
}
qint64 byteCount = 0;
for (size_t ptIdx = 0; ptIdx < propertyNames.size(); ++ptIdx)
{
byteCount += propertyNames[ptIdx].size() * sizeof(QChar);
byteCount += propertyTypes[ptIdx].size() * sizeof(QChar);
}
// Byte count
socketStream << byteCount;
// Parameter count
socketStream << (quint64)propertyNames.size();
for (size_t ptIdx = 0; ptIdx < propertyNames.size(); ++ptIdx)
{
socketStream << propertyNames[ptIdx];
socketStream << propertyTypes[ptIdx];
}
return true;
}
};
static bool RiaGetNNCPropertyNames_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetNNCPropertyNames>(RiaGetNNCPropertyNames::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaSetNNCProperty: public RiaSocketCommand
{
public:
RiaSetNNCProperty() :
m_currentReservoir(NULL),
m_currentScalarIndex(cvf::UNDEFINED_SIZE_T),
m_timeStepCountToRead(0),
m_bytesPerTimeStepToRead(0),
m_currentTimeStepNumberToRead(0),
m_invalidConnectionCountDetected(false),
m_porosityModelEnum(RiaDefines::MATRIX_MODEL)
{}
static QString commandName () { return QString("SetNNCProperty"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
QString propertyName = args[2];
// Find the requested data, or create a set if we are setting data and it is not found
if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()))
{
QString caseId = args[1];
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find case with id %1").arg(caseId));
return true;
}
// If we have not read the header and there are data enough: Read it.
// Do nothing if we have not enough data
if (m_timeStepCountToRead == 0 || m_bytesPerTimeStepToRead == 0)
{
if (server->currentClient()->bytesAvailable() < (int)sizeof(quint64)*2) return true;
socketStream >> m_timeStepCountToRead;
socketStream >> m_bytesPerTimeStepToRead;
}
RigNNCData* nncData = rimCase->eclipseCaseData()->mainGrid()->nncData();
auto nncResults = nncData->generatedConnectionScalarResultByName(propertyName);
if (nncResults == nullptr)
{
nncData->makeGeneratedConnectionScalarResult(propertyName, m_timeStepCountToRead);
}
if (rimCase && rimCase->results(m_porosityModelEnum))
{
bool ok = createIJKCellResults(rimCase->results(m_porosityModelEnum), propertyName);
if (!ok)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the property named: \"%2\"").arg(propertyName));
return true;
}
size_t scalarResultIndex = rimCase->results(m_porosityModelEnum)->findOrLoadScalarResult(QString("%1IJK").arg(propertyName));
nncData->setScalarResultIndex(propertyName, scalarResultIndex);
}
// Create a list of all the requested time steps
m_requestedTimesteps.clear();
if (args.size() <= 4)
{
// Select all
for (size_t tsIdx = 0; tsIdx < m_timeStepCountToRead; ++tsIdx)
{
m_requestedTimesteps.push_back(tsIdx);
}
}
else
{
bool timeStepReadError = false;
for (int argIdx = 4; argIdx < args.size(); ++argIdx)
{
bool conversionOk = false;
int tsIdx = args[argIdx].toInt(&conversionOk);
if (conversionOk)
{
m_requestedTimesteps.push_back(tsIdx);
}
else
{
timeStepReadError = true;
}
}
if (timeStepReadError)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: riSetNNCProperty : \n") +
RiaSocketServer::tr("An error occurred while interpreting the requested time steps."));
}
}
if (! m_requestedTimesteps.size())
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("No time steps specified"));
return true;
}
m_currentReservoir = rimCase;
m_currentPropertyName = propertyName;
if (server->currentClient()->bytesAvailable())
{
return this->interpretMore(server, server->currentClient());
}
return false;
}
static bool createIJKCellResults(RimReservoirCellResultsStorage* results, QString propertyName)
{
bool ok;
ok = scalarResultExistsOrCreate(results, QString("%1IJK").arg(propertyName));
if (!ok) return false;
ok = scalarResultExistsOrCreate(results, QString("%1I").arg(propertyName));
if (!ok) return false;
ok = scalarResultExistsOrCreate(results, QString("%1J").arg(propertyName));
if (!ok) return false;
ok = scalarResultExistsOrCreate(results, QString("%1K").arg(propertyName));
return ok;
}
static bool scalarResultExistsOrCreate(RimReservoirCellResultsStorage* results, QString propertyName)
{
size_t scalarResultIndex = results->findOrLoadScalarResult(propertyName);
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = results->cellResults()->addEmptyScalarResult(RiaDefines::GENERATED, propertyName, true);
}
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
{
std::vector< std::vector<double> >* scalarResultFrames = nullptr;
scalarResultFrames = &(results->cellResults()->cellScalarResults(scalarResultIndex));
size_t timeStepCount = results->cellResults()->maxTimeStepCount();
scalarResultFrames->resize(timeStepCount);
return true;
}
return false;
}
virtual bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient)
{
if (m_invalidConnectionCountDetected) return true;
// If nothing should be read, or we already have read everything, do nothing
if ((m_timeStepCountToRead == 0) || (m_currentTimeStepNumberToRead >= m_timeStepCountToRead) ) return true;
if (!currentClient->bytesAvailable()) return false;
if (m_timeStepCountToRead != m_requestedTimesteps.size())
{
CVF_ASSERT(false);
}
// Check if a complete timestep is available, return and whait for readyRead() if not
if (currentClient->bytesAvailable() < (int)m_bytesPerTimeStepToRead) return false;
RigNNCData* nncData = m_currentReservoir->eclipseCaseData()->mainGrid()->nncData();
size_t connectionCountFromOctave = m_bytesPerTimeStepToRead / sizeof(double);
size_t connectionCount = nncData->connections().size();
std::vector< std::vector<double> >* resultsToAdd = nncData->generatedConnectionScalarResultByName(m_currentPropertyName);
if (connectionCountFromOctave != connectionCount)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") +
RiaSocketServer::tr("The number of connections in the data coming from octave does not match the case: '%1'\n").arg(m_currentReservoir->caseUserDescription()) +
RiaSocketServer::tr(" Octave: %1\n").arg(connectionCountFromOctave) +
RiaSocketServer::tr(" %1: Connection count: %2").arg(m_currentReservoir->caseUserDescription()).arg(connectionCount));
connectionCountFromOctave = 0;
m_invalidConnectionCountDetected = true;
currentClient->abort();
return true;
}
for (size_t tIdx = 0; tIdx < m_timeStepCountToRead; ++tIdx)
{
size_t tsId = m_requestedTimesteps[tIdx];
resultsToAdd->at(tsId).resize(connectionCount, HUGE_VAL);
}
std::vector<double> readBuffer;
double * internalMatrixData = nullptr;
QDataStream socketStream(currentClient);
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
// Read available complete time step data
while ((currentClient->bytesAvailable() >= (int)m_bytesPerTimeStepToRead) && (m_currentTimeStepNumberToRead < m_timeStepCountToRead))
{
internalMatrixData = resultsToAdd->at(m_requestedTimesteps[m_currentTimeStepNumberToRead]).data();
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(internalMatrixData), m_bytesPerTimeStepToRead, errorMessages))
{
for (int i = 0; i < errorMessages.size(); i++)
{
server->errorMessageDialog()->showMessage(errorMessages[i]);
}
currentClient->abort();
return true;
}
++m_currentTimeStepNumberToRead;
}
// If we have read all the data, refresh the views
if (m_currentTimeStepNumberToRead == m_timeStepCountToRead)
{
if (m_currentReservoir != nullptr)
{
// Create a new input property if we have an input reservoir
RimEclipseInputCase* inputRes = dynamic_cast<RimEclipseInputCase*>(m_currentReservoir);
if (inputRes)
{
RimEclipseInputProperty* inputProperty = inputRes->m_inputPropertyCollection->findInputProperty(m_currentPropertyName);
if (!inputProperty)
{
inputProperty = new RimEclipseInputProperty;
inputProperty->resultName = m_currentPropertyName;
inputProperty->eclipseKeyword = "";
inputProperty->fileName = "";
inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty);
inputRes->m_inputPropertyCollection()->updateConnectedEditors();
}
inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED;
}
if( m_currentScalarIndex != cvf::UNDEFINED_SIZE_T &&
m_currentReservoir->eclipseCaseData() &&
m_currentReservoir->eclipseCaseData()->results(m_porosityModelEnum) )
{
m_currentReservoir->eclipseCaseData()->results(m_porosityModelEnum)->recalculateStatistics(m_currentScalarIndex);
}
for (size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i)
{
if (m_currentReservoir->reservoirViews[i])
{
// As new result might have been introduced, update all editors connected
m_currentReservoir->reservoirViews[i]->cellResult->updateConnectedEditors();
// It is usually not needed to create new display model, but if any derived geometry based on generated data (from Octave)
// a full display model rebuild is required
m_currentReservoir->reservoirViews[i]->scheduleCreateDisplayModelAndRedraw();
}
}
}
return true;
}
return false;
}
private:
RimEclipseCase* m_currentReservoir;
size_t m_currentScalarIndex;
QString m_currentPropertyName;
std::vector<size_t> m_requestedTimesteps;
RiaDefines::PorosityModelType m_porosityModelEnum;
quint64 m_timeStepCountToRead;
quint64 m_bytesPerTimeStepToRead;
size_t m_currentTimeStepNumberToRead;
bool m_invalidConnectionCountDetected;
};
static bool RiaSetNNCProperty_init = RiaSocketCommandFactory::instance()->registerCreator<RiaSetNNCProperty>(RiaSetNNCProperty::commandName());

View File

@@ -30,6 +30,7 @@
#include "RigResultAccessorFactory.h"
#include "RigResultModifier.h"
#include "RigResultModifierFactory.h"
#include "RigEclipseResultInfo.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
@@ -38,9 +39,12 @@
#include "RimEclipseInputPropertyCollection.h"
#include "RimEclipseView.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimGeoMechView.h"
#include "RimGeoMechCase.h"
#include "RiuMainWindow.h"
#include "RiuProcessMonitor.h"
#include "RiuSelectionManager.h"
#include <QErrorMessage>
@@ -412,6 +416,11 @@ public:
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
scalarResultIndex = rimCase->results(m_porosityModelEnum)->cellResults()->addEmptyScalarResult(RiaDefines::GENERATED, propertyName, true);
size_t scalarResWithMostTimeSteps = cvf::UNDEFINED_SIZE_T;
rimCase->results(m_porosityModelEnum)->cellResults()->maxTimeStepCount(&scalarResWithMostTimeSteps);
const std::vector<RigEclipseTimeStepInfo> timeStepInfos = rimCase->results(m_porosityModelEnum)->cellResults()->timeStepInfos(scalarResWithMostTimeSteps);
rimCase->results(m_porosityModelEnum)->cellResults()->setTimeStepInfos(scalarResultIndex, timeStepInfos);
}
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
@@ -1108,6 +1117,8 @@ public:
std::vector<QString> resTypeNames;
resTypes.push_back(RiaDefines::DYNAMIC_NATIVE);
resTypeNames.push_back("DynamicNative");
resTypes.push_back(RiaDefines::SOURSIMRL);
resTypeNames.push_back("SourSimRL");
resTypes.push_back(RiaDefines::STATIC_NATIVE );
resTypeNames.push_back("StaticNative");
resTypes.push_back(RiaDefines::GENERATED );
@@ -1150,3 +1161,163 @@ public:
};
static bool RiaGetPropertyNames_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetPropertyNames>(RiaGetPropertyNames::commandName());
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaGetGridPropertyForSelectedCells: public RiaSocketCommand
{
public:
static QString commandName() { return QString("GetGridPropertyForSelectedCells"); }
virtual bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream)
{
RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);
if (!rimCase) return true;
QString propertyName = args[2];
RiaDefines::PorosityModelType porosityModel = RiaDefines::MATRIX_MODEL;
if (args.size() > 1)
{
QString prorosityModelString = args[3];
if (prorosityModelString.toUpper() == "FRACTURE")
{
porosityModel = RiaDefines::FRACTURE_MODEL;
}
}
size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T;
if (rimCase && rimCase->results(porosityModel))
{
scalarResultIndex = rimCase->results(porosityModel)->findOrLoadScalarResult(propertyName);
}
std::vector<size_t> requestedTimesteps;
if (args.size() < 5)
{
// Select all
for (size_t tsIdx = 0; tsIdx < rimCase->results(porosityModel)->cellResults()->timeStepCount(scalarResultIndex); ++tsIdx)
{
requestedTimesteps.push_back(tsIdx);
}
}
else
{
bool timeStepReadError = false;
for (int argIdx = 4; argIdx < args.size(); ++argIdx)
{
bool conversionOk = false;
int tsIdx = args[argIdx].toInt(&conversionOk);
if (conversionOk)
{
requestedTimesteps.push_back(tsIdx);
}
else
{
timeStepReadError = true;
}
}
if (timeStepReadError)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: riGetGridProperty : \n")
+ RiaSocketServer::tr("An error occurred while interpreting the requested time steps."));
}
}
if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()) )
{
// No data available
socketStream << (quint64)0 << (quint64)0 ;
return true;
}
std::vector< std::pair<size_t, size_t> > selectedCells = getSelectedCellsForCase(rimCase);
// First write column count
quint64 timestepCount = (quint64)requestedTimesteps.size();
socketStream << timestepCount;
// then the byte-size of the size of one column
quint64 timestepByteCount = (quint64)(selectedCells.size()*sizeof(double));
socketStream << timestepByteCount;
size_t valueCount = RiaSocketDataTransfer::maximumValueCountInBlock();
std::vector<double> values(valueCount);
size_t valueIndex = 0;
for (size_t timeStep : requestedTimesteps)
{
const std::vector<double>& scalarResults = rimCase->results(porosityModel)->cellResults()->cellScalarResults(scalarResultIndex, timeStep);
for (const std::pair<size_t, size_t> selectedCell : selectedCells)
{
cvf::ref<RigResultAccessor> resultAccessor = RigResultAccessorFactory::createFromUiResultName(rimCase->eclipseCaseData(), selectedCell.first, porosityModel, timeStep, propertyName);
if (resultAccessor.isNull())
{
return false;
}
values[valueIndex] = resultAccessor->cellScalar(selectedCell.second);
valueIndex++;
if (valueIndex >= valueCount)
{
if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double)))
{
return false;
}
valueIndex = 0;
}
}
}
// Write remaining data
if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double)))
{
return false;
}
return true;
}
static std::vector< std::pair<size_t, size_t> > getSelectedCellsForCase(const RimCase* reservoirCase)
{
std::vector<RiuSelectionItem*> items;
RiuSelectionManager::instance()->selectedItems(items);
std::vector< std::pair<size_t, size_t> > selectedCells;
for (const RiuSelectionItem* item : items)
{
if (item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT)
{
const RiuEclipseSelectionItem* eclipseItem = static_cast<const RiuEclipseSelectionItem*>(item);
if (eclipseItem->m_view->eclipseCase()->caseId == reservoirCase->caseId)
{
selectedCells.push_back(std::make_pair(eclipseItem->m_gridIndex, eclipseItem->m_cellIndex));
}
}
else if (item->type() == RiuSelectionItem::GEOMECH_SELECTION_OBJECT)
{
const RiuGeoMechSelectionItem* geomechItem = static_cast<const RiuGeoMechSelectionItem*>(item);
if (geomechItem->m_view->geoMechCase()->caseId == reservoirCase->caseId)
{
selectedCells.push_back(std::make_pair(geomechItem->m_gridIndex, geomechItem->m_cellIndex));
}
}
}
return selectedCells;
}
};
static bool RiaGetGridPropertyForSelectedCells_init = RiaSocketCommandFactory::instance()->registerCreator<RiaGetGridPropertyForSelectedCells>(RiaGetGridPropertyForSelectedCells::commandName());

View File

@@ -25,6 +25,7 @@ ${CEE_CURRENT_LIST_DIR}ScalarMapper-Test.cpp
${CEE_CURRENT_LIST_DIR}WellPathAsciiFileReader-Test.cpp
${CEE_CURRENT_LIST_DIR}opm-flowdiagnostics-Test.cpp
${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator-Test.cpp
${CEE_CURRENT_LIST_DIR}HDF5FileReader-Test.cpp
${CEE_CURRENT_LIST_DIR}RigCellGeometryTools-Test.cpp
${CEE_CURRENT_LIST_DIR}RigTransmissibilityCondenser-Test.cpp
${CEE_CURRENT_LIST_DIR}RigHexIntersectionTools-Test.cpp

View File

@@ -0,0 +1,134 @@
#ifdef USE_HDF5
#include "gtest/gtest.h"
#include "H5Cpp.h"
#include <iostream>
#include <H5Exception.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(DISABLED_HDFTests, BasicFileRead)
{
std::string file_path = "D:/ResInsight/SourSim/PKMUNK_NOV_TEST_SS.sourpre.00001";
try
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
H5::H5File file(file_path.c_str(), H5F_ACC_RDONLY);
{
H5::Group timestep = file.openGroup("Timestep_00001");
H5::Attribute attr = timestep.openAttribute("timestep");
double timestep_value = 0.0;
H5::DataType type = attr.getDataType();
attr.read(type, &timestep_value);
//std::cout << "Timestep value " << timestep_value << std::endl;
EXPECT_NEAR(timestep_value, 1.0, 1e-1);
}
{
// Group size is not an attribute!
H5::Group GridFunctions = file.openGroup("Timestep_00001/GridParts/GridPart_00000/GridFunctions");
hsize_t group_size = GridFunctions.getNumObjs();
//std::cout << "GridFunctions group_size " << group_size << std::endl;
EXPECT_EQ(group_size, 20);
/* for (hsize_t i = 0; i < group_size; i++)
{
// H5std_string node_name = GridFunctions.getObjnameByIdx(i); // crashes on VS2017 due to lib/heap/runtime differences to HDF5 VS2015 lib
std::string node_name;
node_name.resize(1024);
ssize_t slen = GridFunctions.getObjnameByIdx(i, &node_name[0], 1023);
node_name.resize(slen + 1);
std::cout << "GridFunctions sub-node name " << node_name << std::endl;
}
*/
std::string first_subnode(1024, '\0');
ssize_t slen = GridFunctions.getObjnameByIdx(0, &first_subnode[0], 1023);
first_subnode.resize(slen + 1);
EXPECT_TRUE(first_subnode.compare(0, slen, "GridFunction_00002") == 0);
}
{
H5::Group GridFunction_00002 = file.openGroup("Timestep_00001/GridParts/GridPart_00000/GridFunctions/GridFunction_00002");
H5::Attribute attr = GridFunction_00002.openAttribute("limits_max");
double limits_max = 0.0;
H5::DataType type = attr.getDataType();
attr.read(type, &limits_max);
// std::cout << "limits_max " << limits_max << std::endl;
EXPECT_NEAR(limits_max, 0.3970204292629652, 1e-10);
}
{
H5::Group GridFunction_00002 = file.openGroup("Timestep_00001/GridParts/GridPart_00000/GridFunctions/GridFunction_00002");
H5::DataSet dataset = H5::DataSet(GridFunction_00002.openDataSet("values"));
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims(dims, NULL);
std::vector<double> values;
values.resize(dims[0]);
dataset.read(values.data(), H5::PredType::NATIVE_DOUBLE);
/* for (hsize_t i = 0; i < dims[0]; i++)
{
std::cout << "value " << i << " " << values[i] << std::endl;
}
*/
EXPECT_NEAR(values[0], 0.32356910366452146, 1e-10);
EXPECT_NEAR(values[dims[0] - 1], 0.12200070891582514, 1e-10);
}
} // end of try block
catch (H5::FileIException error) // catch failure caused by the H5File operations
{
std::cout << error.getCDetailMsg();
}
catch (H5::DataSetIException error) // catch failure caused by the DataSet operations
{
std::cout << error.getCDetailMsg();
}
catch (H5::DataSpaceIException error) // catch failure caused by the DataSpace operations
{
std::cout << error.getCDetailMsg();
}
catch (H5::DataTypeIException error) // catch failure caused by the DataSpace operations
{
std::cout << error.getCDetailMsg();
}
}
#endif //USE_HDF5

View File

@@ -461,3 +461,25 @@ TEST(RigReservoirTest, WellTest)
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(DISABLED_RigReservoirTest, WellTest)
{
cvf::ref<RifReaderEclipseOutput> readerInterfaceEcl = new RifReaderEclipseOutput;
cvf::ref<RigEclipseCaseData> reservoir = new RigEclipseCaseData;
// Location of test dataset received from Håkon Høgstøl in July 2011 with 10k active cells
#ifdef WIN32
QString filename("d:/Models/Statoil/soursim/PKMUNK_NOV_TEST_SS.GRID");
QString sourSim("d:/Models/Statoil/soursim/result.sourres.00001");
#else
QString filename("/mnt/hgfs/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.EGRID");
QString sourSim("d:/Models/Statoil/soursim/result.sourres");
#endif
bool result = readerInterfaceEcl->open(filename, reservoir.p());
EXPECT_TRUE(result);
readerInterfaceEcl->setHdf5FileName(sourSim);
}

View File

@@ -33,6 +33,7 @@ ${CEE_CURRENT_LIST_DIR}RiuSelectionChangedHandler.h
${CEE_CURRENT_LIST_DIR}RiuSelectionManager.h
${CEE_CURRENT_LIST_DIR}RiuSimpleHistogramWidget.h
${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h
${CEE_CURRENT_LIST_DIR}RiuTofAccumulatedPhaseFractionsPlot.h
${CEE_CURRENT_LIST_DIR}RiuToolTipMenu.h
${CEE_CURRENT_LIST_DIR}RiuTreeViewEventFilter.h
${CEE_CURRENT_LIST_DIR}RiuViewer.h
@@ -79,6 +80,7 @@ ${CEE_CURRENT_LIST_DIR}RiuSelectionChangedHandler.cpp
${CEE_CURRENT_LIST_DIR}RiuSelectionManager.cpp
${CEE_CURRENT_LIST_DIR}RiuSimpleHistogramWidget.cpp
${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.cpp
${CEE_CURRENT_LIST_DIR}RiuTofAccumulatedPhaseFractionsPlot.cpp
${CEE_CURRENT_LIST_DIR}RiuToolTipMenu.cpp
${CEE_CURRENT_LIST_DIR}RiuTreeViewEventFilter.cpp
${CEE_CURRENT_LIST_DIR}RiuViewer.cpp
@@ -119,6 +121,7 @@ ${CEE_CURRENT_LIST_DIR}RiuWellLogPlot.h
${CEE_CURRENT_LIST_DIR}RiuWellLogTrack.h
${CEE_CURRENT_LIST_DIR}RiuRecentFileActionProvider.h
${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h
${CEE_CURRENT_LIST_DIR}RiuTofAccumulatedPhaseFractionsPlot.h
${CEE_CURRENT_LIST_DIR}RiuQwtScalePicker.h
${CEE_CURRENT_LIST_DIR}RiuQwtPlotWheelZoomer.h
${CEE_CURRENT_LIST_DIR}RiuEditPerforationCollectionWidget.h

View File

@@ -1308,9 +1308,9 @@ void RiuMainWindow::hideAllDockWindows()
if (1)
{
gridFileNames += RiaEclipseUnitTools::mockModelBasicWithResults();
gridFileNames += RiaEclipseUnitTools::mockModelBasicWithResults();
gridFileNames += RiaEclipseUnitTools::mockModelBasicWithResults();
gridFileNames += RiaDefines::mockModelBasicWithResults();
gridFileNames += RiaDefines::mockModelBasicWithResults();
gridFileNames += RiaDefines::mockModelBasicWithResults();
}
else
{

View File

@@ -121,7 +121,7 @@ QSize RiuNightchartsWidget::sizeHint() const
if (m_showPie)
{
int maxPieSize = 180;
int maxPieSize = 350;
widthHint = widthHint + maxPieSize;
heightHint = heightHint > maxPieSize ? heightHint : maxPieSize;

View File

@@ -348,7 +348,16 @@ QString RiuResultTextBuilder::nncResultText()
if (m_reservoirView->currentFaultResultColors())
{
size_t scalarResultIdx = m_reservoirView->currentFaultResultColors()->scalarResultIndex();
const std::vector<double>* nncValues = nncData->connectionScalarResult(scalarResultIdx);
RiaDefines::ResultCatType resultType = m_reservoirView->currentFaultResultColors()->resultType();
const std::vector<double>* nncValues;
if (resultType == RiaDefines::STATIC_NATIVE)
{
nncValues = nncData->staticConnectionScalarResult(scalarResultIdx);
}
else if (resultType == RiaDefines::DYNAMIC_NATIVE)
{
nncValues = nncData->dynamicConnectionScalarResult(scalarResultIdx, m_timeStepIndex);
}
if (nncValues)
{
QString resultVar = m_reservoirView->currentFaultResultColors()->resultVariableUiName();

View File

@@ -109,9 +109,10 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuEclipseSelec
return;
}
else if (eclipseView->cellResult()->hasDynamicResult() &&
eclipseView->eclipseCase() &&
eclipseView->eclipseCase()->eclipseCaseData())
else if (eclipseView->cellResult()->hasDynamicResult()
&& !RiaDefines::isPerCellFaceResult(eclipseView->cellResult()->resultVariable())
&& eclipseView->eclipseCase()
&& eclipseView->eclipseCase()->eclipseCaseData())
{
RiaDefines::PorosityModelType porosityModel = eclipseView->cellResult()->porosityModel();

View File

@@ -0,0 +1,290 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuTofAccumulatedPhaseFractionsPlot.h"
#include "RimContextCommandBuilder.h"
#include "RimTofAccumulatedPhaseFractionsPlot.h"
#include "RiuMainWindow.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include "qwt_legend.h"
#include "qwt_plot_grid.h"
#include <QFocusEvent>
#include <QHBoxLayout>
#include <QMdiSubWindow>
#include <QMenu>
#include <math.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuTofAccumulatedPhaseFractionsPlot::RiuTofAccumulatedPhaseFractionsPlot(RimTofAccumulatedPhaseFractionsPlot* plotDefinition, QWidget* parent)
: QwtPlot(parent), m_watCurve(nullptr), m_oilCurve(nullptr), m_gasCurve(nullptr)
{
Q_ASSERT(plotDefinition);
m_plotDefinition = plotDefinition;
QPalette newPalette(palette());
newPalette.setColor(QPalette::Background, Qt::white);
setPalette(newPalette);
setAutoFillBackground(true);
setDefaults();
QwtText title("Cumulative Saturation by Time of Flight");
QFont titleFont = title.font();
titleFont.setPixelSize(12);
title.setFont(titleFont);
setTitle(title);
m_watCurve = new QwtPlotCurve;
setCurveColor(m_watCurve, QColor(62, 122, 167)); // Blue
m_watCurve->setZ(0.9);
m_watCurve->setTitle("Water");
m_watCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_oilCurve = new QwtPlotCurve;
setCurveColor(m_oilCurve, QColor(169, 18, 16)); // Red
m_oilCurve->setZ(0.8);
m_oilCurve->setTitle("Oil");
m_oilCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_gasCurve = new QwtPlotCurve;
setCurveColor(m_gasCurve, QColor(123, 167, 0)); // Green
m_gasCurve->setZ(0.7);
m_gasCurve->setTitle("Gas");
m_gasCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_watCurve->attach(this);
m_oilCurve->attach(this);
m_gasCurve->attach(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuTofAccumulatedPhaseFractionsPlot::~RiuTofAccumulatedPhaseFractionsPlot()
{
if (m_plotDefinition)
{
m_plotDefinition->handleMdiWindowClosed();
}
if (m_watCurve)
{
m_watCurve->detach();
delete m_watCurve;
m_watCurve = nullptr;
}
if (m_oilCurve)
{
m_oilCurve->detach();
delete m_oilCurve;
m_oilCurve = nullptr;
}
if (m_gasCurve)
{
m_gasCurve->detach();
delete m_gasCurve;
m_gasCurve = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuTofAccumulatedPhaseFractionsPlot::sizeHint() const
{
return QSize(350, 250);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuTofAccumulatedPhaseFractionsPlot::heightForWidth(int w) const
{
return static_cast<int>(static_cast<double>(w) / 1.1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTofAccumulatedPhaseFractionsPlot* RiuTofAccumulatedPhaseFractionsPlot::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimViewWindow* RiuTofAccumulatedPhaseFractionsPlot::ownerViewWindow() const
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuTofAccumulatedPhaseFractionsPlot::setSamples(std::vector<double> xSamples,
std::vector<double> watValues,
std::vector<double> oilValues,
std::vector<double> gasValues)
{
m_xValues.clear();
m_watValues.clear();
m_oilValues.clear();
m_gasValues.clear();
m_watValues.swap(watValues);
for (size_t i = 0; i < xSamples.size(); ++i)
{
m_xValues.push_back(xSamples[i] / 365.2425);
m_oilValues.push_back(oilValues[i] + m_watValues[i]);
m_gasValues.push_back(gasValues[i] + m_oilValues[i]);
}
m_watCurve->setSamples(m_xValues.data(), m_watValues.data(), static_cast<int>(m_xValues.size()));
m_oilCurve->setSamples(m_xValues.data(), m_oilValues.data(), static_cast<int>(m_xValues.size()));
m_gasCurve->setSamples(m_xValues.data(), m_gasValues.data(), static_cast<int>(m_xValues.size()));
if (!m_xValues.empty())
{
double maxVal = 0;
for (double val : m_xValues)
{
maxVal = std::max(val, maxVal);
}
setAxisScale(QwtPlot::xBottom, 0, maxVal);
updateAxes();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuTofAccumulatedPhaseFractionsPlot::setDefaults()
{
setCommonPlotBehaviour(this);
setAxisTitle(QwtPlot::xBottom, "Years");
enableAxis(QwtPlot::xBottom, true);
enableAxis(QwtPlot::yLeft, true);
setAxisScale(QwtPlot::yLeft, 0, 1, 0.2);
enableAxis(QwtPlot::xTop, false);
enableAxis(QwtPlot::yRight, false);
setAxisMaxMinor(QwtPlot::xBottom, 2);
setAxisMaxMinor(QwtPlot::yLeft, 3);
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
sizePolicy.setHeightForWidth(true);
setSizePolicy(sizePolicy);
updateGeometry();
// The legend will be deleted in the destructor of the plot or when
// another legend is inserted.
QwtLegend* legend = new QwtLegend(this);
this->insertLegend(legend, BottomLegend);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuTofAccumulatedPhaseFractionsPlot::setCommonPlotBehaviour(QwtPlot* plot)
{
// Plot background and frame look
QPalette newPalette(plot->palette());
newPalette.setColor(QPalette::Background, Qt::white);
plot->setPalette(newPalette);
plot->setAutoFillBackground(true);
plot->setCanvasBackground(Qt::white);
QFrame* canvasFrame = dynamic_cast<QFrame*>(plot->canvas());
if (canvasFrame)
{
canvasFrame->setFrameShape(QFrame::NoFrame);
}
// Grid
QwtPlotGrid* grid = new QwtPlotGrid;
grid->attach(plot);
QPen gridPen(Qt::SolidLine);
gridPen.setColor(Qt::lightGray);
grid->setPen(gridPen);
// Axis number font
QFont axisFont = plot->axisFont(QwtPlot::xBottom);
axisFont.setPixelSize(11);
plot->setAxisFont(QwtPlot::xBottom, axisFont);
plot->setAxisFont(QwtPlot::xTop, axisFont);
plot->setAxisFont(QwtPlot::yLeft, axisFont);
plot->setAxisFont(QwtPlot::yRight, axisFont);
// Axis title font
QwtText axisTitle = plot->axisTitle(QwtPlot::xBottom);
QFont axisTitleFont = axisTitle.font();
axisTitleFont.setPixelSize(11);
axisTitleFont.setBold(false);
axisTitle.setFont(axisTitleFont);
axisTitle.setRenderFlags(Qt::AlignRight);
plot->setAxisTitle(QwtPlot::xBottom, axisTitle);
plot->setAxisTitle(QwtPlot::xTop, axisTitle);
plot->setAxisTitle(QwtPlot::yLeft, axisTitle);
plot->setAxisTitle(QwtPlot::yRight, axisTitle);
// Enable mouse tracking and event filter
plot->canvas()->setMouseTracking(true);
plot->canvas()->installEventFilter(plot);
// plot->plotLayout()->setAlignCanvasToScales(true);
// new RiuQwtCurvePointTracker(plot, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuTofAccumulatedPhaseFractionsPlot::setCurveColor(QwtPlotCurve* curve, QColor color)
{
curve->setBrush(QBrush(color));
QLinearGradient gradient;
gradient.setCoordinateMode(QGradient::StretchToDeviceMode);
gradient.setColorAt(0, color.darker(110));
gradient.setColorAt(0.15, color);
gradient.setColorAt(0.25, color);
gradient.setColorAt(0.4, color.darker(110));
gradient.setColorAt(0.6, color);
gradient.setColorAt(0.8, color.darker(110));
gradient.setColorAt(1, color);
curve->setBrush(gradient);
}

View File

@@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmPointer.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include <QList>
#include <QPointer>
#include <QWidget>
#include "RiuInterfaceToViewWindow.h"
class RimTofAccumulatedPhaseFractionsPlot;
//==================================================================================================
//
// RiuTofAccumulatedPhaseFractionsPlot
//
//==================================================================================================
class RiuTofAccumulatedPhaseFractionsPlot : public QwtPlot, public RiuInterfaceToViewWindow
{
Q_OBJECT
public:
RiuTofAccumulatedPhaseFractionsPlot(RimTofAccumulatedPhaseFractionsPlot* plotDefinition, QWidget* parent = NULL);
virtual ~RiuTofAccumulatedPhaseFractionsPlot();
RimTofAccumulatedPhaseFractionsPlot* ownerPlotDefinition();
virtual RimViewWindow* ownerViewWindow() const override;
void setSamples(std::vector<double> xSamples,
std::vector<double> watValues,
std::vector<double> oilValues,
std::vector<double> gasValues);
protected:
virtual QSize sizeHint() const override;
virtual int heightForWidth(int w) const override;
private:
void setDefaults();
static void setCommonPlotBehaviour(QwtPlot* plot);
void setCurveColor(QwtPlotCurve* curve, QColor color);
private:
caf::PdmPointer<RimTofAccumulatedPhaseFractionsPlot> m_plotDefinition;
QwtPlotCurve* m_watCurve;
QwtPlotCurve* m_oilCurve;
QwtPlotCurve* m_gasCurve;
std::vector<double> m_watValues;
std::vector<double> m_oilValues;
std::vector<double> m_gasValues;
std::vector<double> m_xValues;
};

View File

@@ -25,6 +25,7 @@
#include "RimWellAllocationPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimTofAccumulatedPhaseFractionsPlot.h"
#include "RiuContextMenuLauncher.h"
#include "RiuNightchartsWidget.h"
@@ -89,7 +90,8 @@ RiuWellAllocationPlot::RiuWellAllocationPlot(RimWellAllocationPlot* plotDefiniti
new RiuPlotObjectPicker(totalFlowAllocationWidget, m_plotDefinition->totalWellFlowPlot());
new RiuContextMenuLauncher(totalFlowAllocationWidget, commandIds);
rightColumnLayout->addWidget(totalFlowAllocationWidget);
rightColumnLayout->addWidget(totalFlowAllocationWidget, Qt::AlignTop);
rightColumnLayout->addWidget(m_plotDefinition->tofAccumulatedPhaseFractionsPlot()->createViewWidget(this), Qt::AlignTop);
rightColumnLayout->addStretch();
QWidget* wellFlowWidget = m_plotDefinition->accumulatedWellFlowPlot()->createViewWidget(this);

View File

@@ -79,25 +79,21 @@ if (RESINSIGHT_ERT_EXTERNAL_LIB_ROOT OR RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT)
message(FATAL_ERROR "Both RESINSIGHT_ERT_EXTERNAL_LIB_ROOT and RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT must be defined")
endif()
message(FATAL_ERROR "TODO: Building using and external system installed ERT is broken.")
list(APPEND ERT_INCLUDE_DIRS
${RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT}
)
list(APPEND ERT_LIBRARIES
${RESINSIGHT_ERT_EXTERNAL_LIB_ROOT}/libecl.so
${RESINSIGHT_ERT_EXTERNAL_LIB_ROOT}/libeclxx.so
${RESINSIGHT_ERT_EXTERNAL_LIB_ROOT}/libecl_well.so
${RESINSIGHT_ERT_EXTERNAL_LIB_ROOT}/libert_geometry.so
${RESINSIGHT_ERT_EXTERNAL_LIB_ROOT}/libert_util.so
)
else()
# Disable install of ERT libs and headers, as Ert code is compiled and linked directly
SET(INSTALL_ERT OFF CACHE BOOL "ERT: Install library")
SET(BUILD_PYTHON OFF CACHE BOOL "ERT: Run py_compile on the python wrappers")
SET(ERT_USE_OPENMP ${OPENMP_FOUND} CACHE BOOL "ERT: Compile using OpenMP")
SET(ERT_BUILD_CXX ON CACHE BOOL "ERT: Enable build of CXX wrappers" FORCE)
# Remember original state
set(ORIGINAL_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
@@ -115,36 +111,23 @@ else()
endif()
if (RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT)
set(ERT_INCLUDE_ROOT "${RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT}")
add_subdirectory(${ERT_SOURCE_PATH} ${CMAKE_BINARY_DIR}/ThirdParty/Ert)
add_subdirectory(${RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT} ${CMAKE_BINARY_DIR}/ThirdParty/Ert)
else()
set(ERT_INCLUDE_ROOT ${CMAKE_SOURCE_DIR}/ThirdParty/Ert)
add_subdirectory(ThirdParty/Ert)
endif ()
list(APPEND ERT_INCLUDE_DIRS
${ERT_INCLUDE_ROOT}/libecl/include/
${ERT_INCLUDE_ROOT}/libert_util/include/
${ERT_INCLUDE_ROOT}/libgeometry/include/
${ERT_INCLUDE_ROOT}/libecl_well/include/
${ERT_INCLUDE_ROOT}/libeclxx/include
${ERT_INCLUDE_ROOT}/libert_utilxx/include
if (MSVC)
# libecl : Disable some warnings
set_target_properties(ecl PROPERTIES COMPILE_FLAGS "/wd4244 /wd4267 /wd4013 /wd4190 /wd4018 /wd4477 /wd4098 /wd4293 /wd4305 /wd4020 /wd4028 /wd4715")
endif()
${CMAKE_BINARY_DIR}/ThirdParty/Ert/libert_util/include
)
list(APPEND ERT_LIBRARIES
ecl
eclxx
ecl_well
ert_geometry
ert_util
list(APPEND THIRD_PARTY_LIBRARIES
ecl
)
if (MSVC)
set_property(TARGET
${ERT_LIBRARIES}
ecl_lfs
ecl
PROPERTY FOLDER "Thirdparty/ERT"
)
endif()
@@ -155,6 +138,54 @@ else()
endif(RESINSIGHT_ERT_EXTERNAL_LIB_ROOT OR RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT)
################################################################################
# HDF5
################################################################################
option (RESINSIGHT_USE_HDF5 "Use HDF5 library" OFF)
if (RESINSIGHT_USE_HDF5)
if(MSVC)
# Must specyfy libraries manually
# Using find_package causes linking of zlib, and crashes with linking of zlib defined by Qt
set(RESINSIGHT_HDF5_DIR "" CACHE PATH "Path to HDF5")
if(NOT ${RESINSIGHT_HDF5_DIR} EQUAL "")
include_directories(${RESINSIGHT_HDF5_DIR}/include)
list(APPEND EXTERNAL_LINK_LIBRARIES
# libzlib.lib is not included here, as it is linked implicitly by Qt
${RESINSIGHT_HDF5_DIR}/lib/libhdf5.lib
${RESINSIGHT_HDF5_DIR}/lib/libhdf5_cpp.lib
${RESINSIGHT_HDF5_DIR}/lib/libszip.lib
)
set(RESINSIGHT_FOUND_HDF5 1)
message( STATUS "Using HDF5 from : ${RESINSIGHT_HDF5_DIR}" )
else()
message( WARNING "Use of HDF5 is enabled, but RESINSIGHT_HDF5_DIR is empty. Specify RESINSIGHT_HDF5_DIR to be able to use HDF5" )
endif()
else()
add_definitions(-DH5_BUILT_AS_DYNAMIC_LIB)
find_package(HDF5 REQUIRED COMPONENTS CXX)
if (HDF5_FOUND)
add_definitions(${HDF5_DEFINITIONS})
include_directories(${HDF5_INCLUDE_DIRS})
list(APPEND EXTERNAL_LINK_LIBRARIES
${HDF5_LIBRARIES}
)
set(RESINSIGHT_FOUND_HDF5 1)
message( STATUS "Using HDF5 libraries : ${HDF5_LIBRARIES}" )
else()
message( WARNING "Use of HDF5 is enabled, but no HDF5 is found." )
endif() # HDF5_FOUND
endif() # MSVC
endif() # RESINSIGHT_USE_HDF5
################################################################################
# Subset of Boost, used by NRLib and flow diagnostics application
################################################################################
@@ -381,18 +412,6 @@ if (RESINSIGHT_PRIVATE_INSTALL)
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl.so
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl.so.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl.so.2.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libeclxx.so
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libeclxx.so.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libeclxx.so.2.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl_well.so
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl_well.so.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl_well.so.2.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libert_geometry.so
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libert_geometry.so.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libert_geometry.so.2.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libert_util.so
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libert_util.so.2
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libert_util.so.2.2
)
install(FILES ${ERT_SHARED_LIB_FILES} DESTINATION ${RESINSIGHT_INSTALL_FOLDER} )
@@ -472,6 +491,9 @@ if(NOT ${OCTAVE_VERSION_STRING} EQUAL "")
set (RESINSIGHT_PACKAGE_NAME "${RESINSIGHT_PACKAGE_NAME}_oct-${OCTAVE_VERSION_STRING}")
endif()
if(RESINSIGHT_FOUND_HDF5)
set (RESINSIGHT_PACKAGE_NAME "${RESINSIGHT_PACKAGE_NAME}_hdf5")
endif()
# Append el5 when compiled on RHEL5 and el6 if compiled on RHEL6
if (NOT "${RESINSIGHT_RHEL_SYSTEM_NAME}" STREQUAL "")

View File

@@ -251,4 +251,20 @@ QString Utils::fileExtension(const QString & fileName)
return fi.suffix();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Utils::isStringMatch(const QString& filterString, const QString& value)
{
if (filterString.isEmpty()) return true;
if (filterString.trimmed() == "*")
{
if (!value.isEmpty()) return true;
else return false;
}
QRegExp searcher(filterString, Qt::CaseInsensitive, QRegExp::WildcardUnix);
return searcher.exactMatch(value);
}
} // namespace caf

View File

@@ -66,6 +66,8 @@ public:
static bool fileExists(const QString& fileName);
static QString fileExtension(const QString& fileName);
static bool isStringMatch(const QString& filterString, const QString& value);
};
}

View File

@@ -56,7 +56,7 @@ public: // Virtual
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) {}
/// Method to re-implement to supply option values for a specific field
virtual QList<PdmOptionItemInfo>
virtual QList<caf::PdmOptionItemInfo>
calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
protected:

View File

@@ -154,7 +154,14 @@ void PdmUiFilePathEditor::fileSelectionClicked()
QString defaultPath;
if ( m_lineEdit->text().isEmpty())
{
defaultPath = QDir::homePath();
if (m_attributes.m_defaultPath.isNull())
{
defaultPath = QDir::homePath();
}
else
{
defaultPath = m_attributes.m_defaultPath;
}
}
else
{

View File

@@ -61,6 +61,7 @@ public:
m_selectSaveFileName = false;
m_fileSelectionFilter = "All files (*.* *)";
m_defaultPath = QString();
m_selectDirectory = false;
m_appendUiSelectedFolderToText = false;
m_multipleItemSeparator = ';';
@@ -69,6 +70,7 @@ public:
bool m_selectSaveFileName;
QString m_fileSelectionFilter;
QString m_defaultPath;
bool m_selectDirectory;
bool m_appendUiSelectedFolderToText;
QChar m_multipleItemSeparator;

View File

@@ -8,9 +8,14 @@ set(CPP_SOURCES
riSetActiveCellProperty.cpp
riGetActiveCellInfo.cpp
riGetMainGridDimensions.cpp
riGetNNCConnections.cpp
riGetNNCPropertyNames.cpp
riGetCurrentCase.cpp
riGetCaseGroups.cpp
riGetDynamicNNCValues.cpp
riGetStaticNNCValues.cpp
riGetSelectedCases.cpp
riGetSelectedCells.cpp
riGetCases.cpp
riGetTimeStepDates.cpp
riGetTimeStepDays.cpp
@@ -22,10 +27,12 @@ set(CPP_SOURCES
riGetActiveCellCorners.cpp
riGetGridProperty.cpp
riSetGridProperty.cpp
riGetGridPropertyForSelectedCells.cpp
riGetPropertyNames.cpp
riGetWellNames.cpp
riGetWellStatus.cpp
riGetWellCells.cpp
riSetNNCProperty.cpp
)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@@ -172,9 +179,14 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE)
"${CMAKE_CURRENT_BINARY_DIR}/riSetActiveCellProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetActiveCellInfo.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetMainGridDimensions.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetNNCConnections.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetNNCPropertyNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetDynamicNNCValues.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetStaticNNCValues.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetCurrentCase.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetCaseGroups.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetSelectedCases.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetSelectedCells.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetCases.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetTimeStepDates.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetTimeStepDays.oct"
@@ -186,10 +198,12 @@ if (RESINSIGHT_OCTAVE_PLUGIN_QMAKE AND RESINSIGHT_OCTAVE_PLUGIN_MKOCTFILE)
"${CMAKE_CURRENT_BINARY_DIR}/riGetActiveCellCorners.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetGridProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riSetGridProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetGridPropertyForSelectedCells.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetPropertyNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riSetNNCProperty.oct"
SOURCES
${CPP_SOURCES}
riSettings.h

View File

@@ -0,0 +1,73 @@
#### Matrix[numSelectedCells][5] riGetSelectedCells([CaseId])
This function returns a two dimensional matrix containing the cell info for each selected cell in the case with `CaseId`.
The columns contain the following information:
[CaseId, GridIdx, I, J, K]
CaseId # The ID of the case the cell resides in.
GridIdx # The index of the grid the cell resides in.
# Main grid has index 0
I, J, K # 1-based index of the cell in the grid.
If the CaseId is not defined, ResInsight's Current Case is used.
#### Matrix[numSelectedCells][numTimestepsRequested] riGetGridPropertyForSelectedCells([CaseId], PropertyName, [RequestedTimeSteps], [PorosityModel = "Matrix"|"Fracture"] )
This function returns a two dimensional matrix: [numSelectedCells][numTimestepsRequested] containing the requested property data from the case with CaseId.
If the CaseId is not defined, ResInsight's Current Case is used.
The RequestedTimeSteps must contain a list of 1-based indices to the requested time steps. If not defined, all the time steps are returned.
#### Vector[PropertyInfo] riGetNNCPropertyNames([CaseId])
This function returns the name and type of all NNC properties in the case as a vector of structures.
The structure is defined as:
PropertyInfo {
PropName = string # Name of the property as received from
# the analysis tool
PropType = string # The type of the property: "StaticNative",
# "DynamicNative", "Generated"
}
If the CaseId is not defined, ResInsight's Current Case is used.
#### Matrix[numNNCConnections][2] riGetNNCConnections([CaseId])
This function returns a two dimensional matrix containing grid and IJK information about each NNC connection.
Each row contains a from and to cell for the connection.
The cells are specified in a structure defined as:
CellInfo = {
GridIndex = int # Index of the grid the cell resides in.
# Main grid has index 0.
I, J, K = int # 1-based index address of the cell in the grid.
}
#### Matrix[numConnections][numTimestepsRequested] riGetDynamicNNCValues([CaseId], PropertyName, [RequestedTimeSteps])
This function returns a two dimensional matrix: [Num Connections][Num Time Steps Requested] containing the value of the requested property from the case with CaseId. The order of connections is the same as the order from `riGetNNCConnectio
If the CaseId is not defined, ResInsight's Current Case is used.
The RequestedTimeSteps must contain a list of indices to the requested time steps. If not defined, all the timesteps are returned.
#### Vector[numConnections] riGetStaticNNCValues([CaseId], PropertyName)
This function returns a vector of values for the requested static property for each NNC connection. The order of connections is the same as the order from `riGetNNCConnections`.
If the CaseId is not defined, ResInsight's Current Case is used.
#### riSetNNCProperty(Matrix[numNNCConnections][numTimeSteps], [CaseId], PropertyName, [TimeStepIndices])
Interprets the supplied matrix as a property set defined for the NNC connections in the case, and puts the data into ResInsight as a "Generated" property with the name "PropertyName".
The "TimeStepIndices" argument is used to "label" all the steps present in the supplied data matrix and must thus be complete.
The time step data will then be put into ResInsight at the time steps requested.
If the CaseId is not defined, ResInsight's Current Case is used.

View File

@@ -148,7 +148,7 @@ DEFUN_DLD (riGetActiveCellProperty, args, nargout,
// Check if we have a Requested TimeSteps
if (!(nargin > argIndices[2] && args(argIndices[2]).is_matrix_type() && !args(argIndices[2]).is_string()))
if (!(nargin > argIndices[2] && (args(argIndices[2]).is_matrix_type() || args(argIndices[2]).is_numeric_type()) && !args(argIndices[2]).is_string()))
{
argIndices[2] = -1;
for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx)

View File

@@ -0,0 +1,161 @@
#include <QtNetwork>
#include <QStringList>
#include <octave/oct.h>
#include "riSettings.h"
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
void getDynamicNNCValues(Matrix& propertyFrames, const QString &serverName, quint16 serverPort,
const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps)
{
QTcpSocket socket;
socket.connectToHost(serverName, serverPort);
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
{
error((("Connection: ") + socket.errorString()).toLatin1().data());
return;
}
QDataStream socketStream(&socket);
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
// Create command as a string with arguments , and send it:
QString command;
command += "GetDynamicNNCValues " + QString::number(caseId) + " " + propertyName;
for (int i = 0; i < requestedTimeSteps.length(); ++i)
{
if (i == 0) command += " ";
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
if (i != requestedTimeSteps.length() -1) command += " ";
}
QByteArray cmdBytes = command.toLatin1();
socketStream << (qint64)(cmdBytes.size());
socket.write(cmdBytes);
// Get response. First wait for the header
while (socket.bytesAvailable() < (int)(2*sizeof(quint64)))
{
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
{
error((("Waiting for header: ") + socket.errorString()).toLatin1().data());
return;
}
}
// Read connection count and timestep count
quint64 connectionCount;
quint64 timestepCount;
socketStream >> connectionCount;
socketStream >> timestepCount;
propertyFrames.resize(connectionCount, timestepCount);
if (!(connectionCount && timestepCount))
{
error ("Could not find the requested data in ResInsight");
return;
}
quint64 totalByteCount = timestepCount * connectionCount * sizeof(double);
double* internalMatrixData = propertyFrames.fortran_vec();
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages))
{
for (int i = 0; i < errorMessages.size(); i++)
{
error(errorMessages[i].toLatin1().data());
}
return;
}
QString tmp = QString("riGetDynamicNNCValues : Read %1").arg(propertyName);
if (caseId < 0)
{
tmp += QString(" from current case.");
}
else
{
tmp += QString(" from case with Id: %1.").arg(caseId);
}
octave_stdout << tmp.toStdString() << " Connections: " << connectionCount << ", Time steps : " << timestepCount << std::endl;
return;
}
DEFUN_DLD (riGetDynamicNNCValues, args, nargout,
"Usage:\n"
"\n"
" riGetDynamicNNCValues([CaseId], PropertyName, [RequestedTimeSteps])\n"
"\n"
"This function returns a matrix with the dynamic NNC values for each connection for the requested time steps.\n"
"The matrix has a number of rows equal to the number of NNC connections and a number of columns equal to the requested time steps.\n"
"\n"
"See riGetNNCConnections for information about each individual connection.\n"
"If the CaseId is not defined, ResInsight's Current Case is used.\n"
"If RequestedTimeSteps are left empty, values for all time steps will be returned.\n"
)
{
int nargin = args.length ();
if (nargin < 1)
{
error("riGetDynamicNNCValues: Too few arguments. The name of the property requested is necessary.\n");
print_usage();
return octave_value_list();
}
else if (nargin > 3)
{
error("riGetDynamicNNCValues: Too many arguments.\n");
print_usage();
return octave_value_list();
}
else if (nargout < 1)
{
error("riGetDynamicNNCValues: Missing output argument.\n");
print_usage();
return octave_value_list();
}
std::vector<int> argIndices;
argIndices.push_back(0);
argIndices.push_back(1);
argIndices.push_back(2);
// Check if we have a CaseId:
if (!args(argIndices[0]).is_numeric_type())
{
argIndices[0] = -1;
for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx)
--argIndices[aIdx];
}
// Check if we have a Requested TimeSteps
if (!(nargin > argIndices[2] && args(argIndices[2]).is_matrix_type()))
{
argIndices[2] = -1;
}
Matrix propertyFrames;
qint32 caseId = -1;
int32NDArray requestedTimeSteps;
std::string propertyName;
if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value();
if (argIndices[1] >= 0) propertyName = args(argIndices[1]).char_matrix_value().row_as_string(0);
if (argIndices[2] >= 0) requestedTimeSteps = args(argIndices[2]).int32_array_value();
getDynamicNNCValues(propertyFrames, "127.0.0.1", 40001, caseId, propertyName.c_str(), requestedTimeSteps);
return octave_value(propertyFrames);
}

View File

@@ -163,7 +163,7 @@ DEFUN_DLD (riGetGridProperty, args, nargout,
// Check if we have a Requested TimeSteps
if (!(nargin > argIndices[3] && args(argIndices[3]).is_matrix_type() && !args(argIndices[3]).is_string()))
if (!(nargin > argIndices[3] && (args(argIndices[3]).is_matrix_type() || args(argIndices[3]).is_numeric_type()) && !args(argIndices[3]).is_string()))
{
argIndices[3] = -1;
for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx)

View File

@@ -0,0 +1,199 @@
#include <QtNetwork>
#include <QStringList>
#include <octave/oct.h>
#include "riSettings.h"
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
void getGridPropertyForSelectedCells(Matrix& propertyFrames, const QString &serverName, quint16 serverPort,
const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel)
{
QTcpSocket socket;
socket.connectToHost(serverName, serverPort);
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
{
error((("Connection: ") + socket.errorString()).toLatin1().data());
return;
}
QDataStream socketStream(&socket);
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
// Create command as a string with arguments , and send it:
QString command;
command += "GetGridPropertyForSelectedCells " + QString::number(caseId) + " " + propertyName + " " + porosityModel;
for (int i = 0; i < requestedTimeSteps.length(); ++i)
{
if (i == 0) command += " ";
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
if (i != requestedTimeSteps.length() - 1) command += " ";
}
QByteArray cmdBytes = command.toLatin1();
socketStream << (qint64)(cmdBytes.size());
socket.write(cmdBytes);
// Get response. First wait for the header
while (socket.bytesAvailable() < (int)(2*sizeof(quint64)))
{
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
{
error((("Waiting for header: ") + socket.errorString()).toLatin1().data());
return;
}
}
// Read timestep count and blocksize
quint64 timestepCount;
quint64 byteCount;
size_t selectedCellCount;
socketStream >> timestepCount;
socketStream >> byteCount;
selectedCellCount = byteCount / sizeof(double);
propertyFrames.resize(selectedCellCount, timestepCount);
if (!(byteCount && timestepCount))
{
error ("Could not find the requested data in ResInsight");
return;
}
quint64 totalByteCount = byteCount * timestepCount;
double* internalMatrixData = propertyFrames.fortran_vec();
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages))
{
for (int i = 0; i < errorMessages.size(); i++)
{
error(errorMessages[i].toLatin1().data());
}
return;
}
QString tmp = QString("riGetGridPropertyForSelectedCells : Read %1").arg(propertyName);
if (caseId < 0)
{
tmp += QString(" from current case.");
}
else
{
tmp += QString(" from case with Id: %1.").arg(caseId);
}
octave_stdout << tmp.toStdString() << " Selected cells cells : " << selectedCellCount << ", Time steps : " << timestepCount << std::endl;
return;
}
DEFUN_DLD (riGetGridPropertyForSelectedCells, args, nargout,
"Usage:\n"
"\n"
"Matrix[numSelectedCells][numTimestepsRequested]\n"
" riGetGridPropertyForSelectedCells([CaseId], PropertyName, [RequestedTimeSteps], [PorosityModel = \"Matrix\"|\"Fracture\"] )\n"
"\n"
"This function returns a two dimensional matrix: [numSelectedCells][numTimestepsRequested] containing the requested property data from the case with CaseId.\n"
"If the CaseId is not defined, ResInsight's Current Case is used.\n"
"The RequestedTimeSteps must contain a list of 1-based indices to the requested time steps. If not defined, all the time steps are returned.\n"
)
{
if (nargout < 1)
{
error("riGetGridPropertyForSelectedCells: Missing output argument.\n");
print_usage();
return octave_value_list ();
}
int nargin = args.length ();
if (nargin < 1)
{
error("riGetGridPropertyForSelectedCells: Too few arguments. The name of the property requested is necessary.\n");
print_usage();
return octave_value_list ();
}
if (nargin > 4)
{
error("riGetGridPropertyForSelectedCells: Too many arguments.\n");
print_usage();
return octave_value_list ();
}
std::vector<int> argIndices;
argIndices.push_back(0);
argIndices.push_back(1);
argIndices.push_back(2);
argIndices.push_back(3);
// Check if we have a CaseId:
if (!args(argIndices[0]).is_numeric_type())
{
argIndices[0] = -1;
for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx)
--argIndices[aIdx];
}
// Check if we have a Requested TimeSteps
if (!(nargin > argIndices[2] && (args(argIndices[2]).is_matrix_type() || args(argIndices[2]).is_numeric_type()) && !args(argIndices[2]).is_string()))
{
argIndices[2] = -1;
for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx)
--argIndices[aIdx];
}
// Check if we have a PorosityModel
int lastArgumentIndex = argIndices[3] ;
if (!(nargin > argIndices[3] && args(argIndices[3]).is_string()))
{
argIndices[3] = -1;
for (size_t aIdx = 4; aIdx < argIndices.size(); ++aIdx)
--argIndices[aIdx];
}
// Check if we have more arguments than we should
if (nargin > lastArgumentIndex + 1)
{
error("riGetGridPropertyForSelectedCells: Unexpected argument after the PorosityModel.\n");
print_usage();
return octave_value_list ();
}
// Setup the argument list
Matrix propertyFrames;
int caseId = -1;
std::string propertyName = "UNDEFINED";
int32NDArray requestedTimeSteps;
std::string porosityModel = "Matrix";
if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value();
if (argIndices[1] >= 0) propertyName = args(argIndices[1]).char_matrix_value().row_as_string(0);
if (argIndices[2] >= 0) requestedTimeSteps = args(argIndices[2]).int32_array_value();
if (argIndices[3] >= 0) porosityModel = args(argIndices[3]).string_value();
if (porosityModel != "Matrix" && porosityModel != "Fracture")
{
error("riGetGridPropertyForSelectedCells: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
print_usage();
return octave_value_list ();
}
getGridPropertyForSelectedCells(propertyFrames, "127.0.0.1", 40001, caseId, propertyName.c_str(), requestedTimeSteps, porosityModel.c_str());
return octave_value(propertyFrames);
}

View File

@@ -0,0 +1,158 @@
#include <QtNetwork>
#include <octave/oct.h>
#include <octave/oct-map.h>
#include "riSettings.h"
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
struct GridLocalCell
{
int gridIndex;
int i;
int j;
int k;
};
struct Connection
{
GridLocalCell fromCell;
GridLocalCell toCell;
};
void getNNCConnections(std::vector<Connection>& connections, const QString& hostName, quint16 port, const qint64& caseId)
{
QString serverName = hostName;
quint16 serverPort = port;
QTcpSocket socket;
socket.connectToHost(serverName, serverPort);
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
{
error((("Connection: ") + socket.errorString()).toLatin1().data());
return;
}
QString command = QString("GetNNCConnections %1").arg(caseId);
QByteArray cmdBytes = command.toLatin1();
QDataStream socketStream(&socket);
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
socketStream << (qint64)(cmdBytes.size());
socket.write(cmdBytes);
while (socket.bytesAvailable() < (int)sizeof(quint64))
{
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
{
error((("Waiting for header: ") + socket.errorString()).toLatin1().data());
return;
}
OCTAVE_QUIT;
}
quint64 connectionCount;
quint64 byteCount;
quint64 rowByteSize = sizeof(qint32) * 4 * 2;
socketStream >> connectionCount;
byteCount = connectionCount * rowByteSize;
while (socket.bytesAvailable() < (int)byteCount)
{
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
{
error((("Waiting for data: ") + socket.errorString()).toLatin1().data());
return;
}
OCTAVE_QUIT;
}
connections.resize(connectionCount);
for (size_t i = 0; i < connectionCount; ++i)
{
socketStream >> connections[i].fromCell.gridIndex;
socketStream >> connections[i].fromCell.i >> connections[i].fromCell.j >> connections[i].fromCell.k;
socketStream >> connections[i].toCell.gridIndex;
socketStream >> connections[i].toCell.i >> connections[i].toCell.j >> connections[i].toCell.k;
}
return;
}
DEFUN_DLD(riGetNNCConnections, args, nargout,
"Usage:\n"
"\n"
" riGetNNCConnections([CaseId])\n"
"\n"
"This function returns a two dimensional matrix containing grid and IJK information for each NNC in the requested case.\n"
"The columns contain the following information:\n"
"[GridIdx, I, J, K]:\n"
" GridIdx : The index of the grid the cell resides in. (Main grid has index 0)\n"
" I, J, K : 1-based index address of the cell in the grid.\n"
"\n"
"If the CaseId is not defined, ResInsight's Current Case is used.\n"
)
{
int nargin = args.length();
if (nargin > 1)
{
error("riGetNNCConnections: Too many arguments, CaseId are optional input arguments.\n");
print_usage();
}
else if (nargout < 1)
{
error("riGetNNCConnections: Missing output argument.\n");
print_usage();
}
else
{
std::vector<Connection> connections;
qint64 caseId = -1;
if (nargin > 0)
{
if (args(0).is_numeric_type())
{
unsigned int argCaseId = args(0).uint_value();
caseId = argCaseId;
}
}
getNNCConnections(connections, "127.0.0.1", 40001, caseId);
Cell cellValuesGridIndex(connections.size(), 2);
Cell cellValuesI(connections.size(), 2);
Cell cellValuesJ(connections.size(), 2);
Cell cellValuesK(connections.size(), 2);
for (size_t i = 0; i < connections.size(); ++i)
{
cellValuesGridIndex(i, 0) = connections[i].fromCell.gridIndex;
cellValuesGridIndex(i, 1) = connections[i].toCell.gridIndex;
cellValuesI(i, 0) = connections[i].fromCell.i;
cellValuesI(i, 1) = connections[i].toCell.i;
cellValuesJ(i, 0) = connections[i].fromCell.j;
cellValuesJ(i, 1) = connections[i].toCell.j;
cellValuesK(i, 0) = connections[i].fromCell.k;
cellValuesK(i, 1) = connections[i].toCell.k;
}
octave_map m;
m.assign(riOctavePlugin::cellIndex_gridIndex, cellValuesGridIndex);
m.assign(riOctavePlugin::cellIndex_I, cellValuesI);
m.assign(riOctavePlugin::cellIndex_J, cellValuesJ);
m.assign(riOctavePlugin::cellIndex_K, cellValuesK);
return octave_value(m);
}
return octave_value();
}

Some files were not shown because too many files have changed in this diff Show More