mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge remote-tracking branch 'origin/hdf-prototype' into dev
This commit is contained in:
commit
a961221c2c
@ -1146,7 +1146,7 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName)
|
||||
|
||||
//if (!riv->cellResult()->hasResult())
|
||||
//{
|
||||
// riv->cellResult()->setResultVariable(RimDefines::undefinedResultName());
|
||||
// riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
|
||||
//}
|
||||
progress.incrementProgress();
|
||||
progress.setProgressDescription("Loading results information");
|
||||
|
@ -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");
|
||||
@ -98,6 +99,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;
|
||||
}
|
||||
@ -134,6 +151,30 @@ QString RiaDefines::combinedTransmissibilityResultName()
|
||||
return "TRANXYZ";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::combinedWaterFluxResultName()
|
||||
{
|
||||
return "FLRWATIJK";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::combinedOilFluxResultName()
|
||||
{
|
||||
return "FLROILIJK";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::combinedGasFluxResultName()
|
||||
{
|
||||
return "FLRGASIJK";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -28,6 +28,7 @@ namespace RiaDefines
|
||||
{
|
||||
DYNAMIC_NATIVE,
|
||||
STATIC_NATIVE,
|
||||
SOURSIMRL,
|
||||
GENERATED,
|
||||
INPUT_PROPERTY,
|
||||
FORMATION_NAMES,
|
||||
@ -47,6 +48,10 @@ namespace RiaDefines
|
||||
QString undefinedGridFaultName();
|
||||
QString undefinedGridFaultWithInactiveName();
|
||||
QString combinedTransmissibilityResultName();
|
||||
QString combinedWaterFluxResultName();
|
||||
QString combinedOilFluxResultName();
|
||||
QString combinedGasFluxResultName();
|
||||
|
||||
QString ternarySaturationResultName();
|
||||
QString combinedMultResultName();
|
||||
|
||||
|
@ -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,59 @@ endif()
|
||||
|
||||
add_subdirectory(GeoMech/GeoMechDataModel)
|
||||
|
||||
#
|
||||
# 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 THIRD_PARTY_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_USE_HDF5 1)
|
||||
message( STATUS "Using HDF5 from : ${RESINSIGHT_HDF5_DIR}" )
|
||||
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 THIRD_PARTY_LIBRARIES
|
||||
${HDF5_LIBRARIES}
|
||||
)
|
||||
|
||||
set(RESINSIGHT_USE_HDF5 1)
|
||||
message( STATUS "Using HDF5 libraries : ${HDF5_LIBRARIES}" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (${RESINSIGHT_USE_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()
|
||||
|
||||
# make variable available to parent scope
|
||||
set(RESINSIGHT_USE_HDF5 ${RESINSIGHT_USE_HDF5} PARENT_SCOPE)
|
||||
|
||||
#############################################################################
|
||||
# Qt specifics: Moc, ui, resources
|
||||
#############################################################################
|
||||
@ -283,8 +336,6 @@ set( LINK_LIBRARIES
|
||||
${APP_FWK_LIBRARIES}
|
||||
${VIZ_FWK_LIBRARIES}
|
||||
|
||||
${ERT_LIBRARIES}
|
||||
|
||||
${THIRD_PARTY_LIBRARIES}
|
||||
|
||||
${OPENGL_LIBRARIES}
|
||||
|
@ -39,6 +39,8 @@ ${CEE_CURRENT_LIST_DIR}RicDeleteItemExecData.h
|
||||
${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.h
|
||||
${CEE_CURRENT_LIST_DIR}RicDeleteSubItemsFeature.h
|
||||
|
||||
${CEE_CURRENT_LIST_DIR}RicDeleteSourSimDataFeature.h
|
||||
|
||||
${CEE_CURRENT_LIST_DIR}RicCommandFeature.h
|
||||
|
||||
${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.h
|
||||
@ -78,6 +80,8 @@ ${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.cpp
|
||||
|
||||
${CEE_CURRENT_LIST_DIR}RicDeleteSubItemsFeature.cpp
|
||||
|
||||
${CEE_CURRENT_LIST_DIR}RicDeleteSourSimDataFeature.cpp
|
||||
|
||||
${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RicFlyToObjectFeature.cpp
|
||||
)
|
||||
|
67
ApplicationCode/Commands/RicDeleteSourSimDataFeature.cpp
Normal file
67
ApplicationCode/Commands/RicDeleteSourSimDataFeature.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RicDeleteSourSimDataFeature.h"
|
||||
|
||||
#include "RimEclipseResultCase.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicDeleteSourSimDataFeature, "RicDeleteSourSimDataFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicDeleteSourSimDataFeature::isCommandEnabled()
|
||||
{
|
||||
return getSelectedEclipseCase() != nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicDeleteSourSimDataFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
RimEclipseResultCase* eclipseCase = getSelectedEclipseCase();
|
||||
|
||||
if (eclipseCase == nullptr) return;
|
||||
|
||||
eclipseCase->setSourSimFileName(QString());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicDeleteSourSimDataFeature::setupActionLook(QAction* actionToSetup)
|
||||
{
|
||||
actionToSetup->setText("Delete SourSim Data");
|
||||
actionToSetup->setIcon(QIcon(":/Erase.png"));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseResultCase* RicDeleteSourSimDataFeature::getSelectedEclipseCase()
|
||||
{
|
||||
caf::PdmUiItem* selectedItem = caf::SelectionManager::instance()->selectedItem();
|
||||
RimEclipseResultCase* eclipseCase = dynamic_cast<RimEclipseResultCase*>(selectedItem);
|
||||
return eclipseCase;
|
||||
}
|
40
ApplicationCode/Commands/RicDeleteSourSimDataFeature.h
Normal file
40
ApplicationCode/Commands/RicDeleteSourSimDataFeature.h
Normal 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 RicDeleteSourSimDataFeature : 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();
|
||||
};
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,279 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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);
|
||||
if (!summaryPlot)
|
||||
{
|
||||
RimSummaryPlotCollection* summaryPlotCollection = nullptr;
|
||||
destinationObject->firstAncestorOrThisOfType(summaryPlotCollection);
|
||||
if (!summaryPlotCollection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
summaryPlot = RicNewSummaryPlotFeature::createNewSummaryPlot(summaryPlotCollection, nullptr);
|
||||
if (!summaryPlot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RicPasteAsciiDataToSummaryPlotFeatureUi pasteOptions;
|
||||
caf::PdmSettings::readFieldsFromApplicationStore(&pasteOptions);
|
||||
|
||||
caf::PdmUiPropertyViewDialog propertyDialog(NULL, &pasteOptions, "Set Paste Options", "");
|
||||
if (propertyDialog.exec() != QDialog::Accepted) return;
|
||||
|
||||
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;
|
||||
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
RimAsciiDataCurve* curve = new RimAsciiDataCurve();
|
||||
curve->setTimeSteps(timeSteps);
|
||||
curve->setValues(values[i]);
|
||||
curve->setTitle(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;
|
||||
}
|
@ -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);
|
||||
};
|
@ -0,0 +1,158 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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()
|
||||
{
|
||||
CAF_PDM_InitObject("RicPasteAsciiDataToSummaryPlotFeatureUi", "", "", "");
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicPasteAsciiDataToSummaryPlotFeatureUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
{
|
||||
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();
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
|
||||
protected:
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
|
||||
private:
|
||||
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;
|
||||
};
|
@ -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
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@ -42,6 +46,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
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
|
||||
|
467
ApplicationCode/FileInterface/RifHdf5Reader.cpp
Normal file
467
ApplicationCode/FileInterface/RifHdf5Reader.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
62
ApplicationCode/FileInterface/RifHdf5Reader.h
Normal file
62
ApplicationCode/FileInterface/RifHdf5Reader.h
Normal 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
|
||||
};
|
20
ApplicationCode/FileInterface/RifHdf5ReaderInterface.cpp
Normal file
20
ApplicationCode/FileInterface/RifHdf5ReaderInterface.cpp
Normal 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"
|
||||
|
38
ApplicationCode/FileInterface/RifHdf5ReaderInterface.h
Normal file
38
ApplicationCode/FileInterface/RifHdf5ReaderInterface.h
Normal 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;
|
||||
};
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
void generatePartGeometry();
|
||||
void updatePartEffect();
|
||||
|
||||
void updateNNCColors(RimEclipseCellColors* cellResultColors);
|
||||
void updateNNCColors(size_t timeStepIndex, RimEclipseCellColors* cellResultColors);
|
||||
|
||||
caf::FaceCulling faceCullingMode() const;
|
||||
|
||||
|
@ -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;
|
||||
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);
|
||||
}
|
||||
|
||||
const std::vector<double>* nncResultVals = m_nncData->connectionScalarResult(scalarResultIndex);
|
||||
if (!nncResultVals)
|
||||
{
|
||||
textureCoords->setAll(cvf::Vec2f(0.0f, 1.0f));
|
||||
|
@ -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;
|
||||
|
@ -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(RimDefines::INPUT_PROPERTY);
|
||||
//varList += m_reservoirView->gridCellResults()->resultNames(RiaDefines::INPUT_PROPERTY);
|
||||
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
|
@ -416,6 +416,7 @@ QStringList RimContextCommandBuilder::commandsFromSelection()
|
||||
{
|
||||
commandIds << "RicReloadCaseFeature";
|
||||
commandIds << "RicExecuteScriptForCasesFeature";
|
||||
commandIds << "RicDeleteSourSimDataFeature";
|
||||
}
|
||||
else if (dynamic_cast<RimSummaryPlot*>(uiItem))
|
||||
{
|
||||
|
@ -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()->setCombTransmisibilityScalarResultIndex(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "RimTools.h"
|
||||
|
||||
#include "cafPdmSettings.h"
|
||||
#include "cafPdmUiFilePathEditor.h"
|
||||
#include "cafPdmUiPropertyViewDialog.h"
|
||||
#include "cafProgressInfo.h"
|
||||
#include "cafUtils.h"
|
||||
@ -75,7 +76,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;
|
||||
@ -149,6 +154,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 +231,20 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -435,6 +460,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 +514,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -426,27 +426,46 @@ 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
|
||||
// Do not include flow diagnostics results if it is a time history curve
|
||||
if ( timeHistoryCurve != nullptr )
|
||||
{
|
||||
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 )
|
||||
@ -858,6 +877,10 @@ bool RimEclipseResultDefinition::hasDynamicResult() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (m_resultType() == RiaDefines::SOURSIMRL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (m_resultType() == RiaDefines::FLOW_DIAGNOSTICS)
|
||||
{
|
||||
return true;
|
||||
|
@ -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))
|
||||
{
|
||||
@ -415,6 +442,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;
|
||||
}
|
||||
|
||||
@ -496,6 +543,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;
|
||||
|
||||
}
|
||||
@ -990,7 +1057,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();
|
||||
|
||||
@ -1009,7 +1076,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)
|
||||
@ -1250,11 +1318,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)
|
||||
{
|
||||
@ -1383,10 +1452,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();
|
||||
|
||||
|
@ -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
|
||||
|
237
ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp
Normal file
237
ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
82
ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.h
Normal file
82
ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.h
Normal file
@ -0,0 +1,82 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
|
||||
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;
|
||||
};
|
@ -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;
|
||||
}
|
||||
|
||||
@ -691,6 +757,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 +823,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 +850,11 @@ void RimSummaryPlot::loadDataAndUpdate()
|
||||
curve->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
|
||||
{
|
||||
curve->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
this->updateAxes();
|
||||
|
||||
updateZoomInQwt();
|
||||
@ -867,6 +954,11 @@ QWidget* RimSummaryPlot::createViewWidget(QWidget* mainWindowParent)
|
||||
{
|
||||
curve->setParentQwtPlot(m_qwtPlot);
|
||||
}
|
||||
|
||||
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
|
||||
{
|
||||
curve->setParentQwtPlot(m_qwtPlot);
|
||||
}
|
||||
}
|
||||
|
||||
return m_qwtPlot;
|
||||
@ -937,6 +1029,11 @@ void RimSummaryPlot::detachAllCurves()
|
||||
{
|
||||
curve->detachQwtCurve();
|
||||
}
|
||||
|
||||
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
|
||||
{
|
||||
curve->detachQwtCurve();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -960,6 +1057,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 +1079,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();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
@ -125,6 +128,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;
|
||||
|
@ -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;
|
||||
|
@ -113,6 +113,7 @@ public:
|
||||
|
||||
bool mustBeCalculated(size_t scalarResultIndex) const;
|
||||
void setMustBeCalculated(size_t scalarResultIndex);
|
||||
void eraseAllSourSimData();
|
||||
|
||||
|
||||
public:
|
||||
|
@ -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::setCombTransmisibilityScalarResultIndex(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::setCombTransmisibilityScalarResultIndex(size_t scalarResultInde
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
@ -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 setCombTransmisibilityScalarResultIndex(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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -125,6 +125,55 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
|
579
ApplicationCode/SocketInterface/RiaNNCCommands.cpp
Normal file
579
ApplicationCode/SocketInterface/RiaNNCCommands.cpp
Normal 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());
|
@ -38,9 +38,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>
|
||||
|
||||
@ -1108,6 +1111,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 +1155,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());
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
134
ApplicationCode/UnitTests/HDF5FileReader-Test.cpp
Normal file
134
ApplicationCode/UnitTests/HDF5FileReader-Test.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#ifdef USE_HDF5
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "H5Cpp.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <H5Exception.h>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(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, ×tep_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
|
@ -461,3 +461,25 @@ TEST(RigReservoirTest, WellTest)
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(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);
|
||||
}
|
||||
|
@ -1308,9 +1308,9 @@ void RiuMainWindow::hideAllDockWindows()
|
||||
|
||||
if (1)
|
||||
{
|
||||
gridFileNames += RimDefines::mockModelBasicWithResults();
|
||||
gridFileNames += RimDefines::mockModelBasicWithResults();
|
||||
gridFileNames += RimDefines::mockModelBasicWithResults();
|
||||
gridFileNames += RiaDefines::mockModelBasicWithResults();
|
||||
gridFileNames += RiaDefines::mockModelBasicWithResults();
|
||||
gridFileNames += RiaDefines::mockModelBasicWithResults();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,18 @@ 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
|
||||
|
||||
${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()
|
||||
@ -365,18 +343,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} )
|
||||
@ -456,6 +422,9 @@ if(NOT ${OCTAVE_VERSION_STRING} EQUAL "")
|
||||
set (RESINSIGHT_PACKAGE_NAME "${RESINSIGHT_PACKAGE_NAME}_oct-${OCTAVE_VERSION_STRING}")
|
||||
endif()
|
||||
|
||||
if(RESINSIGHT_USE_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 "")
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
73
OctavePlugin/NNCOctaveInterfaceSpecification.txt
Normal file
73
OctavePlugin/NNCOctaveInterfaceSpecification.txt
Normal 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.
|
||||
|
@ -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)
|
||||
|
161
OctavePlugin/riGetDynamicNNCValues.cpp
Normal file
161
OctavePlugin/riGetDynamicNNCValues.cpp
Normal 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);
|
||||
}
|
@ -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)
|
||||
|
199
OctavePlugin/riGetGridPropertyForSelectedCells.cpp
Normal file
199
OctavePlugin/riGetGridPropertyForSelectedCells.cpp
Normal 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);
|
||||
}
|
158
OctavePlugin/riGetNNCConnections.cpp
Normal file
158
OctavePlugin/riGetNNCConnections.cpp
Normal 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();
|
||||
}
|
152
OctavePlugin/riGetNNCPropertyNames.cpp
Normal file
152
OctavePlugin/riGetNNCPropertyNames.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getNNCPropertyNames(std::vector<QString>& propNames, std::vector<QString>& propTypes, 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;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command;
|
||||
command += QString("GetNNCPropertyNames") + " " + QString::number(caseId);
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
QDataStream socketStream(&socket);
|
||||
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
|
||||
|
||||
socketStream << (qint64)(cmdBytes.size());
|
||||
socket.write(cmdBytes);
|
||||
|
||||
// Get response. First wait for the header
|
||||
|
||||
while (socket.bytesAvailable() < (int)(sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error((("Waiting for header: ") + socket.errorString()).toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
QString byteCountString = QString::number(byteCount);
|
||||
|
||||
//error(byteCountString.toLatin1().data());
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error((("Waiting for data: ") + socket.errorString()).toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 propCount;
|
||||
socketStream >> propCount;
|
||||
|
||||
QString propName;
|
||||
QString propType;
|
||||
|
||||
for (size_t i = 0; i < propCount; i++)
|
||||
{
|
||||
socketStream >> propName;
|
||||
socketStream >> propType;
|
||||
|
||||
propNames.push_back(propName);
|
||||
propTypes.push_back(propType);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetNNCPropertyNames, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetNNCPropertyNames([CaseId])\n"
|
||||
"\n"
|
||||
"This function returns the name and type of all the NNC properties in the case as a Vector of Structures.\n"
|
||||
"The Structure is defined as: \n"
|
||||
"PropertyInfo {\n"
|
||||
" PropName = string # Name of the NNC property as received from the analysis tool \n"
|
||||
" PropType = string # The type of the property: \"StaticNative\", \"DynamicNative\", \"Generated\" \n"
|
||||
"} \n"
|
||||
"If the CaseId is not defined, ResInsight's Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetNNCPropertyNames: Too many arguments, this function takes one optional argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetNNCPropertyNames: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 argCaseId = -1;
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
argCaseId = args(0).uint_value();
|
||||
}
|
||||
|
||||
std::vector<QString> propertyNames;
|
||||
std::vector<QString> propertyTypes;
|
||||
|
||||
getNNCPropertyNames(propertyNames, propertyTypes, "127.0.0.1", 40001, argCaseId);
|
||||
|
||||
size_t caseCount = propertyNames.size();
|
||||
|
||||
if (propertyNames.size() != propertyTypes.size() )
|
||||
{
|
||||
error("riGetNNCPropertyNames: Inconsistent data received from ResInsight.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
Cell cellValuesB(caseCount, 1);
|
||||
Cell cellValuesC(caseCount, 1);
|
||||
|
||||
for (size_t i = 0; i < caseCount; i++)
|
||||
{
|
||||
cellValuesB(i) = propertyNames[i].toLatin1().data();
|
||||
cellValuesC(i) = propertyTypes[i].toLatin1().data();
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::propertyInfo_PropName, cellValuesB);
|
||||
m.assign(riOctavePlugin::propertyInfo_PropType, cellValuesC);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
130
OctavePlugin/riGetSelectedCells.cpp
Normal file
130
OctavePlugin/riGetSelectedCells.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#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 getSelectedCells(int32NDArray& selectedCellInfo, 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;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetSelectedCells %1").arg(caseId);
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
QDataStream socketStream(&socket);
|
||||
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
|
||||
|
||||
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 columnCount;
|
||||
quint64 byteCountForOneTimestep;
|
||||
size_t selectedCellCount;
|
||||
|
||||
socketStream >> columnCount;
|
||||
socketStream >> byteCountForOneTimestep;
|
||||
|
||||
selectedCellCount = byteCountForOneTimestep / sizeof(qint32);
|
||||
|
||||
dim_vector dv (2, 1);
|
||||
dv(0) = selectedCellCount;
|
||||
dv(1) = columnCount;
|
||||
selectedCellInfo.resize(dv);
|
||||
|
||||
if (!(byteCountForOneTimestep && columnCount))
|
||||
{
|
||||
error ("No selected cells found in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
qint32* internalMatrixData = (qint32*)selectedCellInfo.fortran_vec()->mex_get_data();
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error(errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
QString tmp = QString("riGetSelectedCells : Read selected cell info");
|
||||
|
||||
octave_stdout << tmp.toStdString() << " Selected cells: " << selectedCellCount << ", Columns: " << columnCount << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetSelectedCells, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" Matrix[numSelectedCells][5] riGetSelectedCells([CaseId])\n"
|
||||
"\n"
|
||||
"This function returns a two dimensional matrix containing cell info for each selected cell.\n"
|
||||
"The columns contain the following information:\n"
|
||||
"[CaseId, GridIdx, I, J, K]\n"
|
||||
" CaseId : The ID of the case the cell resides in.\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"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetSelectedCells: Too many arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetSelectedCells: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 caseId = -1;
|
||||
|
||||
if (nargin > 0)
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
|
||||
int32NDArray propertyFrames;
|
||||
|
||||
getSelectedCells(propertyFrames, "127.0.0.1", 40001, caseId);
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
144
OctavePlugin/riGetStaticNNCValues.cpp
Normal file
144
OctavePlugin/riGetStaticNNCValues.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
#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 getStaticNNCValues(std::vector<double>& propertyValues, const QString &serverName, quint16 serverPort,
|
||||
const qint64& caseId, QString propertyName)
|
||||
{
|
||||
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 += "GetStaticNNCValues " + QString::number(caseId) + " " + propertyName;
|
||||
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
socketStream << (qint64)(cmdBytes.size());
|
||||
socket.write(cmdBytes);
|
||||
|
||||
// Get response. First wait for the header
|
||||
|
||||
while (socket.bytesAvailable() < (int)sizeof(quint64))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error((("Waiting for header: ") + socket.errorString()).toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read connection count and timestep count
|
||||
quint64 connectionCount;
|
||||
|
||||
socketStream >> connectionCount;
|
||||
|
||||
if (!(connectionCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
propertyValues.reserve(connectionCount);
|
||||
|
||||
for (size_t i = 0; i < connectionCount; ++i)
|
||||
{
|
||||
double val;
|
||||
socketStream >> val;
|
||||
propertyValues.push_back(val);
|
||||
}
|
||||
|
||||
QString tmp = QString("riGetStaticNNCValues : 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 << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DEFUN_DLD (riGetStaticNNCValues, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetStaticNNCValues([CaseId], PropertyName)\n"
|
||||
"\n"
|
||||
"This function returns a vector with the static NNC values for each connection.\n"
|
||||
"\n"
|
||||
"See riGetNNCConnections for information about each individual connection.\n"
|
||||
"If the CaseId is not defined, ResInsight's Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin < 1)
|
||||
{
|
||||
error("riGetStaticNNCValues: Too few arguments. The name of the property requested is necessary.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
else if (nargin > 2)
|
||||
{
|
||||
error("riGetStaticNNCValues: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetStaticNNCValues: Missing output argument.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
std::vector<int> argIndices;
|
||||
argIndices.push_back(0);
|
||||
argIndices.push_back(1);
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
std::vector<double> propertyValues;
|
||||
qint32 caseId = -1;
|
||||
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);
|
||||
|
||||
getStaticNNCValues(propertyValues, "127.0.0.1", 40001, caseId, propertyName.c_str());
|
||||
|
||||
dim_vector dv(2, 1);
|
||||
dv(0) = propertyValues.size();
|
||||
dv(1) = 1;
|
||||
NDArray oct_propertyValues(dv);
|
||||
|
||||
for (size_t i = 0; i < propertyValues.size(); ++i)
|
||||
{
|
||||
oct_propertyValues(i) = propertyValues[i];
|
||||
}
|
||||
|
||||
return octave_value(oct_propertyValues);
|
||||
}
|
@ -136,7 +136,7 @@ DEFUN_DLD (riGetWellStatus, args, nargout,
|
||||
|
||||
// Check if we have a Requested TimeSteps
|
||||
int lastArgumentIndex = argIndices[2] ;
|
||||
if (!(nargin > argIndices[2] && args(argIndices[2]).is_matrix_type()))
|
||||
if (!(nargin > argIndices[2] && (args(argIndices[2]).is_matrix_type() || args(argIndices[2]).is_numeric_type())))
|
||||
{
|
||||
argIndices[2] = -1;
|
||||
}
|
||||
|
195
OctavePlugin/riSetNNCProperty.cpp
Normal file
195
OctavePlugin/riSetNNCProperty.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#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 setNNCProperty(const Matrix& propertyFrames, const QString &hostName, quint16 port,
|
||||
const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(hostName, port);
|
||||
|
||||
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 += "SetNNCProperty " + 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);
|
||||
|
||||
// Write property data header
|
||||
|
||||
dim_vector mxDims = propertyFrames.dims();
|
||||
|
||||
qint64 connectionCount = mxDims.elem(0);
|
||||
qint64 timeStepCount = mxDims.elem(1);
|
||||
qint64 timeStepByteCount = connectionCount * sizeof(double);
|
||||
|
||||
socketStream << (qint64)(timeStepCount);
|
||||
socketStream << (qint64)timeStepByteCount;
|
||||
|
||||
const double* internalData = propertyFrames.fortran_vec();
|
||||
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepByteCount*timeStepCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
octave_stdout << errorMessages[i].toStdString();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QString tmp = QString("riSetNNCProperty : Wrote %1").arg(propertyName);
|
||||
|
||||
if (caseId == -1)
|
||||
{
|
||||
tmp += QString(" to current case.");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp += QString(" to case with Id = %1.").arg(caseId);
|
||||
}
|
||||
octave_stdout << tmp.toStdString() << " NNC Connections : " << connectionCount << " Time steps : " << timeStepCount << std::endl;
|
||||
|
||||
while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState)
|
||||
{
|
||||
// octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl;
|
||||
socket.waitForBytesWritten(riOctavePlugin::shortTimeOutMilliSecs);
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
//octave_stdout << " Socket write completed" << std::endl;
|
||||
|
||||
if (socket.bytesToWrite() && socket.state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
error("riSetNNCProperty : ResInsight refused to accept the data. Maybe the dimensions or porosity model is wrong");
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
// TODO: Due to synchronization issues seen on Windows 10, it is required to do a sleep here to be able to catch disconnect
|
||||
// signals from the socket. No sleep causes the server to hang.
|
||||
Sleep(100);
|
||||
#endif //WIN32
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riSetNNCProperty, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"\triSetNNCProperty(Matrix[numNNCConnections][numTimeSteps], [CaseId], PropertyName, [TimeStepIndices]) \n"
|
||||
"\n"
|
||||
"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 time 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.\n"
|
||||
"If the CaseId is not defined, ResInsight's Current Case is used."
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin < 2)
|
||||
{
|
||||
error("riSetNNCProperty: Too few arguments. The data matrix and the name of the property requested is necessary\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
if (nargin > 4)
|
||||
{
|
||||
error("riSetNNCProperty: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
Matrix propertyFrames = args(0).matrix_value();
|
||||
|
||||
if (error_state)
|
||||
{
|
||||
error("riSetNNCProperty: The supplied first argument is not a valid Matrix");
|
||||
print_usage();
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
|
||||
dim_vector mxDims = propertyFrames.dims();
|
||||
if (mxDims.length() != 2)
|
||||
{
|
||||
error("riSetNNCProperty: The supplied Data Matrix must have two dimensions: numNNCConnections*numTimesteps");
|
||||
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[1]).is_numeric_type())
|
||||
{
|
||||
argIndices[1] = -1;
|
||||
for (size_t aIdx = 2; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have a Requested TimeSteps
|
||||
if (!(nargin > argIndices[3] && args(argIndices[3]).is_matrix_type() && !args(argIndices[3]).is_string()))
|
||||
{
|
||||
argIndices[3] = -1;
|
||||
for (size_t aIdx = 4; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
int caseId = -1;
|
||||
std::string propertyName = "UNDEFINED";
|
||||
int32NDArray requestedTimeSteps;
|
||||
|
||||
if (argIndices[1] >= 0) caseId = args(argIndices[1]).int_value();
|
||||
if (argIndices[2] >= 0) propertyName = args(argIndices[2]).char_matrix_value().row_as_string(0);
|
||||
if (argIndices[3] >= 0) requestedTimeSteps = args(argIndices[3]).int32_array_value();
|
||||
|
||||
if (requestedTimeSteps.length())
|
||||
{
|
||||
|
||||
int timeStepCount = mxDims.elem(1);
|
||||
if (requestedTimeSteps.length() != timeStepCount)
|
||||
{
|
||||
error("riSetNNCProperty: The number of time steps in the input matrix must match the number of time steps in the TimeStepIndices array.");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
}
|
||||
|
||||
setNNCProperty(propertyFrames, "127.0.0.1", 40001, caseId, propertyName.c_str(), requestedTimeSteps);
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
@ -60,5 +60,11 @@ namespace riOctavePlugin
|
||||
char timeStepDate_Hour[] = "Hour";
|
||||
char timeStepDate_Minute[] = "Minute";
|
||||
char timeStepDate_Second[] = "Second";
|
||||
|
||||
// Octave data structure : CellIndex
|
||||
char cellIndex_gridIndex[] = "GridIndex";
|
||||
char cellIndex_I[] = "I";
|
||||
char cellIndex_J[] = "J";
|
||||
char cellIndex_K[] = "K";
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
|
||||
set(RESINSIGHT_MAJOR_VERSION 2017)
|
||||
set(RESINSIGHT_MINOR_VERSION 05)
|
||||
set(RESINSIGHT_INCREMENT_VERSION "2-dev.1")
|
||||
set(RESINSIGHT_INCREMENT_VERSION "2-fdev.02")
|
||||
|
||||
|
||||
# https://github.com/CRAVA/crava/tree/master/libs/nrlib
|
||||
set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f")
|
||||
|
||||
# https://github.com/Statoil/libecl
|
||||
set(ERT_GITHUB_SHA "06a39878636af0bc52582430ad0431450e51139c")
|
||||
set(ERT_GITHUB_SHA "ecac8afb4342a321b4366fe1fb8a095e67f2d08a")
|
||||
# Not completely shure this is the correct one. it might be db2b7317c instead or ...
|
||||
|
||||
# https://github.com/OPM/opm-flowdiagnostics
|
||||
set(OPM_FLOWDIAGNOSTICS_SHA "b6e59ddcd2feba450c8612a7402c9239e442c0d4")
|
||||
|
11
ThirdParty/Ert/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
11
ThirdParty/Ert/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
**Task**
|
||||
_Short description of the task_
|
||||
|
||||
|
||||
**Approach**
|
||||
_Short description of the approach_
|
||||
|
||||
|
||||
**Pre un-WIP checklist**
|
||||
- [ ] Statoil tests pass locally
|
||||
- [ ] Have completed graphical integration test steps
|
36
ThirdParty/Ert/.travis.yml
vendored
36
ThirdParty/Ert/.travis.yml
vendored
@ -1,7 +1,16 @@
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: c
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: gcc
|
||||
dist: trusty
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
@ -11,6 +20,9 @@ addons:
|
||||
- valgrind
|
||||
- gcc-4.8
|
||||
- g++-4.8
|
||||
- clang
|
||||
- cmake
|
||||
- cmake-data
|
||||
|
||||
env:
|
||||
global:
|
||||
@ -18,7 +30,18 @@ env:
|
||||
|
||||
install:
|
||||
- if [[ "$CC" == "gcc" ]]; then export CXX="g++-4.8"; fi
|
||||
- wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
export CONDA_OS=MacOSX;
|
||||
else
|
||||
export CONDA_OS=Linux;
|
||||
fi
|
||||
- export TRAVIS_PYTHON_VERSION="2.7"
|
||||
# We do this conditionally because it saves us some downloading if the version is the same.
|
||||
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
|
||||
wget https://repo.continuum.io/miniconda/Miniconda2-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh;
|
||||
else
|
||||
wget https://repo.continuum.io/miniconda/Miniconda3-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh;
|
||||
fi
|
||||
- bash miniconda.sh -b -p $HOME/miniconda
|
||||
- export CONDA_HOME="$HOME/miniconda"
|
||||
- export PATH="$CONDA_HOME/bin:$PATH"
|
||||
@ -29,10 +52,7 @@ install:
|
||||
- conda install pylint numpy pandas
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DBUILD_TESTS=ON -DBUILD_PYTHON=ON -DERT_BUILD_CXX=ON -DBUILD_APPLICATIONS=ON ..
|
||||
- wget https://raw.githubusercontent.com/Statoil/ert/master/travis/build_total.py
|
||||
|
||||
script:
|
||||
- make
|
||||
- ctest --output-on-failure -E ert_util_ping
|
||||
- python build_total.py ecl
|
||||
|
284
ThirdParty/Ert/CMakeLists.txt
vendored
284
ThirdParty/Ert/CMakeLists.txt
vendored
@ -1,6 +1,8 @@
|
||||
cmake_minimum_required( VERSION 2.8 )
|
||||
cmake_minimum_required( VERSION 2.8.12 )
|
||||
project( ERT C CXX )
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
endif()
|
||||
@ -19,15 +21,13 @@ set( ERT_VERSION_MICRO git ) # with "new in Ert Version X.X.X"!
|
||||
option( BUILD_TESTS "Should the tests be built" OFF)
|
||||
option( BUILD_APPLICATIONS "Should we build small utility applications" OFF)
|
||||
option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF)
|
||||
option( BUILD_PYTHON "Run py_compile on the python wrappers" ON )
|
||||
option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF)
|
||||
option( BUILD_SHARED_LIBS "Build shared libraries" ON )
|
||||
option( INSTALL_ERT "Should anything be installed when issuing make install?" ON )
|
||||
option( ERT_USE_OPENMP "Use OpenMP" OFF )
|
||||
option( ERT_DOC "Build ERT documantation" OFF)
|
||||
option( RST_DOC "Build RST documentation" OFF)
|
||||
option( ERT_BUILD_CXX "Build some CXX wrappers" ON)
|
||||
|
||||
|
||||
|
||||
option( USE_RPATH "Don't strip RPATH from libraries and binaries" OFF)
|
||||
option( INSTALL_ERT_LEGACY "Add ert legacy wrappers" OFF)
|
||||
|
||||
|
||||
set(STATOIL_TESTDATA_ROOT "" CACHE PATH "Root to Statoil internal testdata")
|
||||
@ -39,12 +39,22 @@ if (EXISTS ${STATOIL_TESTDATA_ROOT})
|
||||
|
||||
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${STATOIL_TESTDATA_ROOT}" "${LINK}")
|
||||
message(STATUS "Linking testdata: ${LINK} -> ${STATOIL_TESTDATA_ROOT}")
|
||||
|
||||
set(_statoil_test_data ${CMAKE_SOURCE_DIR}/test-data/Statoil)
|
||||
set(_eclpath ${_statoil_test_data}/ECLIPSE)
|
||||
set(_geopath ${_statoil_test_data}/Geometry)
|
||||
endif()
|
||||
|
||||
|
||||
# output libs to some lib/ path for testing
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
|
||||
if (USE_RPATH)
|
||||
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif ()
|
||||
|
||||
include( CheckFunctionExists )
|
||||
include( CheckTypeSize )
|
||||
ENABLE_TESTING()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
@ -84,90 +94,221 @@ if (MSVC)
|
||||
endif()
|
||||
|
||||
|
||||
if (ERT_USE_OPENMP)
|
||||
find_package(OpenMP)
|
||||
if (OPENMP_FOUND)
|
||||
message(STATUS "Enabling OpenMP support")
|
||||
# The actual use of OpenMP is only in the libecl library - the compile flags is only applied there.
|
||||
else()
|
||||
set( ERT_USE_OPENMP OFF )
|
||||
message(STATUS "OpenMP package not found - OpenMP disabled")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
|
||||
find_package(CXX11Features)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
# create targets for (required and optional) dependencies to link to
|
||||
|
||||
find_package(OpenMP)
|
||||
if (NOT OPENMP_FOUND)
|
||||
message(STATUS "OpenMP package not found")
|
||||
set(ERT_USE_OPENMP OFF)
|
||||
endif ()
|
||||
|
||||
if (NOT ERT_USE_OPENMP)
|
||||
message(STATUS "OpenMP disabled")
|
||||
endif ()
|
||||
|
||||
# when cmake can be upgraded to >= 3.0, dependencies should be implemented
|
||||
# either via target-providing FindLib.cmake:
|
||||
# ```
|
||||
# find_package(Threads)
|
||||
# target_link_libraries(lib Threads::Threads)
|
||||
# ```
|
||||
#
|
||||
# or via INTERFACE libraries:
|
||||
# add_library(m INTERFACE)
|
||||
# find_library(M_LIBRARY NAMES m)
|
||||
# if (M_LIBRARY)
|
||||
# target_link_libraries(m ${M_LIBRARY})
|
||||
# endif ()
|
||||
# target_link_libraries(m ${M_LIBRARY})
|
||||
#
|
||||
# These targets can then be exported along with targets provided by this
|
||||
# project. Linking against cmake interface targets will handle include
|
||||
# directories better than raw names given to target_link_libraries
|
||||
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(HAVE_PTHREAD TRUE)
|
||||
set(ERT_HAVE_THREAD_POOL ON)
|
||||
|
||||
set(pthread "${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
if (THREADS_HAVE_PTHREAD_ARG)
|
||||
set(pthreadarg "-pthread")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(dl "${CMAKE_DL_LIBS}")
|
||||
|
||||
find_library(M_LIBRARY NAMES m)
|
||||
if(M_LIBRARY)
|
||||
set(m m)
|
||||
endif ()
|
||||
|
||||
find_package(BLAS)
|
||||
if (BLAS_FOUND)
|
||||
set(blas "${BLAS_LIBRARIES}")
|
||||
endif ()
|
||||
|
||||
set(ERT_HAVE_LAPACK OFF)
|
||||
find_package(LAPACK)
|
||||
if (LAPACK_FOUND)
|
||||
set(ERT_HAVE_LAPACK ON)
|
||||
list(APPEND lapack ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS})
|
||||
endif()
|
||||
|
||||
find_package(ZLIB)
|
||||
if (ZLIB_FOUND)
|
||||
set(ERT_HAVE_ZLIB ON)
|
||||
set(zlib "${ZLIB_LIBRARIES}")
|
||||
endif ()
|
||||
|
||||
find_library(SHLWAPI_LIBRARY NAMES Shlwapi)
|
||||
if (SHLWAPI_LIBRARY)
|
||||
set(shlwapi ${SHLWAPI_LIBRARY})
|
||||
endif ()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
# Checking based on compiling. Some of the code generates warnings, so we just cut down to bare-bone compiler flags.
|
||||
# feature tests
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
set( CMAKE_C_FLAGS_main ${CMAKE_C_FLAGS} )
|
||||
set( CMAKE_CXX_FLAGS_main ${CMAKE_CXX_FLAGS} )
|
||||
check_function_exists( chdir HAVE_POSIX_CHDIR )
|
||||
check_function_exists( _chdir HAVE_WINDOWS_CHDIR )
|
||||
check_function_exists( chmod HAVE_CHMOD )
|
||||
check_function_exists( fnmatch HAVE_FNMATCH )
|
||||
check_function_exists( fork HAVE_FORK )
|
||||
check_function_exists( fseeko HAVE_FSEEKO )
|
||||
check_function_exists( fsync HAVE_FSYNC )
|
||||
check_function_exists( ftruncate HAVE_FTRUNCATE )
|
||||
check_function_exists( getcwd HAVE_POSIX_GETCWD)
|
||||
check_function_exists( _getcwd HAVE_WINDOWS_GETCWD)
|
||||
check_function_exists( getpwuid HAVE_GETPWUID )
|
||||
check_function_exists( GetTempPath HAVE_WINDOWS_GET_TEMP_PATH )
|
||||
check_function_exists( getuid ERT_HAVE_GETUID )
|
||||
check_function_exists( glob ERT_HAVE_GLOB )
|
||||
check_function_exists( gmtime_r HAVE_GMTIME_R )
|
||||
check_function_exists( localtime_r HAVE_LOCALTIME_R )
|
||||
check_function_exists( lockf ERT_HAVE_LOCKF )
|
||||
check_function_exists( mkdir HAVE_POSIX_MKDIR)
|
||||
check_function_exists( _mkdir HAVE_WINDOWS_MKDIR)
|
||||
check_function_exists( opendir ERT_HAVE_OPENDIR )
|
||||
check_function_exists( posix_spawn ERT_HAVE_SPAWN )
|
||||
check_function_exists( pthread_timedjoin_np HAVE_TIMEDJOIN)
|
||||
check_function_exists( pthread_yield HAVE_YIELD)
|
||||
check_function_exists( pthread_yield_np HAVE_YIELD_NP)
|
||||
check_function_exists( readlinkat ERT_HAVE_READLINKAT )
|
||||
check_function_exists( realpath HAVE_REALPATH )
|
||||
check_function_exists( regexec ERT_HAVE_REGEXP )
|
||||
check_function_exists( round HAVE_ROUND )
|
||||
check_function_exists( setenv HAVE_POSIX_SETENV )
|
||||
check_function_exists( symlink ERT_HAVE_SYMLINK )
|
||||
check_function_exists( timegm HAVE_TIMEGM )
|
||||
check_function_exists( usleep HAVE__USLEEP )
|
||||
|
||||
if (NOT ERT_WINDOWS)
|
||||
set( CMAKE_C_FLAGS_main "${CMAKE_C_FLAGS} -std=gnu99" )
|
||||
check_symbol_exists(_tzname time.h HAVE_WINDOWS_TZNAME)
|
||||
check_symbol_exists( tzname time.h HAVE_TZNAME)
|
||||
|
||||
check_include_file(execinfo.h HAVE_EXECINFO)
|
||||
check_include_file(getopt.h ERT_HAVE_GETOPT)
|
||||
check_include_file(unistd.h ERT_HAVE_UNISTD)
|
||||
|
||||
check_type_size(time_t SIZE_OF_TIME_T)
|
||||
if (${SIZE_OF_TIME_T} EQUAL 8)
|
||||
try_run(RUN_RESULT COMPILE_RESULT ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_mktime_before1970.c)
|
||||
if (${COMPILE_RESULT})
|
||||
if (${RUN_RESULT} EQUAL 0)
|
||||
set( ERT_TIME_T_64BIT_ACCEPT_PRE1970 ON )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set( ERT_EXTERNAL_UTIL_LIBS "" )
|
||||
include(cmake/ert_build_check.cmake)
|
||||
include(cmake/ert_api_check.cmake)
|
||||
include(cmake/ert_lib_check.cmake)
|
||||
try_compile( HAVE_VA_COPY ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_va_copy.c )
|
||||
try_compile( HAVE_SIGBUS ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_have_sigbus.c )
|
||||
try_compile( HAVE_PID_T ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_pid_t.c )
|
||||
try_compile( HAVE_MODE_T ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_mode_t.c )
|
||||
try_compile( ERT_HAVE_ISFINITE ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_isfinite.c)
|
||||
|
||||
set( CMAKE_C_FLAGS ${CMAKE_C_FLAGS_main} )
|
||||
set( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_main} )
|
||||
set( BUILD_CXX ON )
|
||||
try_compile( HAVE_CXX_SHARED_PTR ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_shared_ptr.cpp )
|
||||
if (NOT HAVE_CXX_SHARED_PTR)
|
||||
set( BUILD_CXX OFF )
|
||||
endif()
|
||||
|
||||
include(cmake/Modules/UseMultiArch.cmake)
|
||||
include(cmake/ert_link.cmake)
|
||||
if (HAVE_FORK AND HAVE_PTHREAD AND HAVE_EXECINFO AND HAVE_GETPWUID)
|
||||
set( HAVE_UTIL_ABORT_INTERCEPT ON)
|
||||
set( HAVE_BACKTRACE ON)
|
||||
endif()
|
||||
|
||||
if (ERT_WINDOWS)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set( ERT_WINDOWS_LFS ON )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(PING_PATH NAMES ping)
|
||||
if (PING_PATH)
|
||||
set(ERT_HAVE_PING ON)
|
||||
endif()
|
||||
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_SHORT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
else()
|
||||
set( GIT_COMMIT "unknown (git not found!)")
|
||||
set( GIT_COMMIT_SHORT "unknown (git not found!)")
|
||||
message( WARNING "Git not found. Build will not contain git revision info." )
|
||||
endif()
|
||||
|
||||
if (ERT_WINDOWS)
|
||||
execute_process(COMMAND cmd.exe /c "echo %date% %time%" OUTPUT_VARIABLE BUILD_TIME)
|
||||
else() # Linux or Darwin
|
||||
execute_process(COMMAND date "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE BUILD_TIME)
|
||||
endif()
|
||||
string(STRIP ${BUILD_TIME} BUILD_TIME)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
set(INSTALL_GROUP "" CACHE STRING "Group to install as - blank to install as current group")
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
|
||||
|
||||
|
||||
if (MSVC)
|
||||
add_definitions( -D__func__="\\"????\\"")
|
||||
endif()
|
||||
|
||||
if (ERT_WINDOWS)
|
||||
message(WARNING "Python is not supported on Windows")
|
||||
set( BUILD_PYTHON OFF )
|
||||
endif ()
|
||||
|
||||
if (ERT_LINUX)
|
||||
set( NEED_LIBM TRUE )
|
||||
set( LINK_STATIC FALSE )
|
||||
add_definitions( -DHAVE_PROC )
|
||||
else()
|
||||
set( NEED_LIBM FALSE )
|
||||
set( LINK_STATIC TRUE )
|
||||
endif()
|
||||
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/libert_util/include )
|
||||
include_directories( ${PROJECT_BINARY_DIR}/libert_util/include )
|
||||
if (MSVC)
|
||||
include_directories( ${PROJECT_BINARY_DIR}/libert_util/include/ert/util )
|
||||
endif()
|
||||
add_subdirectory( libert_util )
|
||||
add_subdirectory( lib )
|
||||
add_subdirectory( applications )
|
||||
|
||||
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/libgeometry/include )
|
||||
add_subdirectory( libgeometry )
|
||||
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/libecl/include )
|
||||
add_subdirectory( libecl )
|
||||
|
||||
if (ERT_BUILD_CXX)
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/libert_utilxx/include )
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/libeclxx/include )
|
||||
|
||||
add_subdirectory( libert_utilxx )
|
||||
add_subdirectory( libeclxx )
|
||||
endif()
|
||||
|
||||
include_directories( ${PROJECT_SOURCE_DIR}/libecl_well/include )
|
||||
add_subdirectory( libecl_well )
|
||||
|
||||
if (BUILD_PYTHON)
|
||||
if (ERT_WINDOWS)
|
||||
message(WARNING "Python is not supported on Windows")
|
||||
@ -178,7 +319,7 @@ if (BUILD_PYTHON)
|
||||
# will be set to OFF.
|
||||
add_subdirectory( python )
|
||||
|
||||
if(ERT_DOC)
|
||||
if(RST_DOC)
|
||||
add_subdirectory( docs )
|
||||
endif()
|
||||
endif()
|
||||
@ -190,10 +331,9 @@ if (BUILD_PYTHON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (INSTALL_ERT)
|
||||
install(EXPORT ecl-config DESTINATION share/cmake/ecl)
|
||||
endif()
|
||||
|
||||
|
||||
configure_file( cmake/libecl-config.cmake.in libecl-config.cmake @ONLY)
|
||||
configure_file( cmake/libecl-config-version.cmake.in libecl-config-version.cmake @ONLY)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libecl-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libecl-config-version.cmake
|
||||
DESTINATION lib/libecl )
|
||||
export(TARGETS ecl FILE eclConfig.cmake)
|
||||
export(PACKAGE ecl)
|
||||
|
87
ThirdParty/Ert/applications/CMakeLists.txt
vendored
Normal file
87
ThirdParty/Ert/applications/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
project(libecl-applications)
|
||||
|
||||
if (NOT BUILD_APPLICATIONS)
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
add_executable(sum_write ecl/sum_write.c)
|
||||
add_executable(make_grid ecl/make_grid.c)
|
||||
add_executable(grdecl_grid ecl/grdecl_grid.c)
|
||||
add_executable(summary ecl/view_summary.c)
|
||||
target_link_libraries(sum_write ecl)
|
||||
target_link_libraries(make_grid ecl)
|
||||
target_link_libraries(grdecl_grid ecl)
|
||||
target_link_libraries(summary ecl)
|
||||
|
||||
list(APPEND apps make_grid grdecl_grid summary)
|
||||
|
||||
foreach (app ecl_pack
|
||||
ecl_unpack
|
||||
kw_extract
|
||||
grid_info
|
||||
grid_dump
|
||||
grid_dump_ascii
|
||||
select_test
|
||||
load_test
|
||||
)
|
||||
add_executable(${app} ecl/${app}.c)
|
||||
target_link_libraries(${app} ecl)
|
||||
list(APPEND apps ${app})
|
||||
if (ERT_LINUX)
|
||||
# The stupid .x extension creates problems on windows
|
||||
set_target_properties(${app} PROPERTIES SUFFIX ".x")
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
|
||||
if (ERT_LINUX)
|
||||
foreach (app convert esummary grdecl_test kw_list)
|
||||
add_executable(${app} ecl/${app}.c)
|
||||
target_link_libraries(${app} ecl)
|
||||
# The stupid .x extension creates problems on windows
|
||||
set_target_properties(${app} PROPERTIES SUFFIX ".x")
|
||||
list(APPEND apps ${app})
|
||||
endforeach ()
|
||||
|
||||
set_target_properties(summary PROPERTIES SUFFIX ".x")
|
||||
endif ()
|
||||
|
||||
|
||||
# This minor eclipse application depends on the config parser library
|
||||
# and should be moved to the libres repository - it can not be
|
||||
# built here.
|
||||
if (BUILD_ERT)
|
||||
add_executable( ecl_quantile ecl/ecl_quantile.c )
|
||||
target_link_libraries( ecl_quantile config )
|
||||
list(APPEND apps ecl_quantile)
|
||||
endif()
|
||||
|
||||
if (BUILD_ECL_SUMMARY)
|
||||
add_executable(ecl_summary ecl/view_summary.c)
|
||||
target_link_libraries(ecl_summary ecl)
|
||||
list(APPEND apps ecl_summary)
|
||||
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/man/man1/ecl_summary.1
|
||||
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
endif()
|
||||
|
||||
if (PTHREAD_LIBRARY)
|
||||
add_executable(bls block_fs/bls.c)
|
||||
target_link_libraries(bls ecl)
|
||||
list(APPEND apps bls)
|
||||
endif ()
|
||||
|
||||
add_executable(segment_info well/segment_info.c)
|
||||
add_executable(CF_dump well/well_CF_dump.c)
|
||||
add_executable(ri_well_test well/ri_well_test.c)
|
||||
|
||||
target_link_libraries(segment_info ecl)
|
||||
target_link_libraries(CF_dump ecl)
|
||||
target_link_libraries(ri_well_test ecl)
|
||||
|
||||
list(APPEND apps segment_info CF_dump ri_well_test)
|
||||
|
||||
install(TARGETS ${apps}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
@ -72,13 +72,13 @@ void unpack_file(const char * filename) {
|
||||
break;
|
||||
|
||||
if (target_type == ECL_SUMMARY_FILE) {
|
||||
active_view = ecl_file_alloc_global_blockview(src_file, SEQHDR_KW, block_index);
|
||||
active_view = ecl_file_get_global_blockview(src_file, SEQHDR_KW, block_index);
|
||||
report_step += 1;
|
||||
offset = 0;
|
||||
} else {
|
||||
ecl_kw_type * seqnum_kw;
|
||||
active_view = ecl_file_alloc_global_blockview(src_file, SEQNUM_KW, block_index);
|
||||
seqnum_kw = ecl_file_iget_named_kw( src_file , SEQNUM_KW , 0);
|
||||
active_view = ecl_file_get_global_blockview(src_file, SEQNUM_KW, block_index);
|
||||
seqnum_kw = ecl_file_view_iget_named_kw( active_view , SEQNUM_KW , 0);
|
||||
report_step = ecl_kw_iget_int( seqnum_kw , 0);
|
||||
offset = 1;
|
||||
}
|
||||
@ -100,7 +100,6 @@ void unpack_file(const char * filename) {
|
||||
free(target_file);
|
||||
}
|
||||
block_index++;
|
||||
ecl_file_view_free( active_view );
|
||||
}
|
||||
ecl_file_close( src_file );
|
||||
util_safe_free(path);
|
@ -65,7 +65,7 @@ int main(int argc, char ** argv) {
|
||||
{
|
||||
ecl_kw_type * ecl_kw = ecl_kw_alloc_empty();
|
||||
while (true) {
|
||||
if (ecl_kw_fread_header( ecl_kw , fortio_src )) {
|
||||
if (ecl_kw_fread_header( ecl_kw , fortio_src ) == ECL_KW_READ_OK) {
|
||||
const char * header = ecl_kw_get_header( ecl_kw );
|
||||
if (set_has_key( kw_set , header )) {
|
||||
ecl_kw_fread_realloc_data(ecl_kw , fortio_src );
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user