Merge remote-tracking branch 'origin/hdf-prototype' into dev

This commit is contained in:
Magne Sjaastad 2017-08-17 07:30:01 +02:00
commit a961221c2c
632 changed files with 9748 additions and 3722 deletions

View File

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

View File

@ -30,6 +30,7 @@ namespace caf
{ {
addItem(RiaDefines::DYNAMIC_NATIVE, "DYNAMIC_NATIVE", "Dynamic"); addItem(RiaDefines::DYNAMIC_NATIVE, "DYNAMIC_NATIVE", "Dynamic");
addItem(RiaDefines::STATIC_NATIVE, "STATIC_NATIVE", "Static"); addItem(RiaDefines::STATIC_NATIVE, "STATIC_NATIVE", "Static");
addItem(RiaDefines::SOURSIMRL, "SOURSIMRL", "SourSimRL");
addItem(RiaDefines::GENERATED, "GENERATED", "Generated"); addItem(RiaDefines::GENERATED, "GENERATED", "Generated");
addItem(RiaDefines::INPUT_PROPERTY, "INPUT_PROPERTY", "Input Property"); addItem(RiaDefines::INPUT_PROPERTY, "INPUT_PROPERTY", "Input Property");
addItem(RiaDefines::FORMATION_NAMES, "FORMATION_NAMES", "Formation Names"); addItem(RiaDefines::FORMATION_NAMES, "FORMATION_NAMES", "Formation Names");
@ -98,6 +99,22 @@ bool RiaDefines::isPerCellFaceResult(const QString& resultName)
{ {
return true; 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; return false;
} }
@ -134,6 +151,30 @@ QString RiaDefines::combinedTransmissibilityResultName()
return "TRANXYZ"; return "TRANXYZ";
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::combinedWaterFluxResultName()
{
return "FLRWATIJK";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::combinedOilFluxResultName()
{
return "FLROILIJK";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::combinedGasFluxResultName()
{
return "FLRGASIJK";
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

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

View File

@ -27,7 +27,6 @@ include_directories(
${ResInsight_SOURCE_DIR}/ThirdParty ${ResInsight_SOURCE_DIR}/ThirdParty
${ResInsight_SOURCE_DIR}/ThirdParty/NRLib/nrlib/well ${ResInsight_SOURCE_DIR}/ThirdParty/NRLib/nrlib/well
${ResInsight_SOURCE_DIR}/ThirdParty/Qwt/src ${ResInsight_SOURCE_DIR}/ThirdParty/Qwt/src
${ERT_INCLUDE_DIRS}
${boost-Subset_SOURCE_DIR} ${boost-Subset_SOURCE_DIR}
${custom-opm-flowdiagnostics_SOURCE_DIR}/opm-flowdiagnostics/ ${custom-opm-flowdiagnostics_SOURCE_DIR}/opm-flowdiagnostics/
@ -77,6 +76,7 @@ set( SOCKET_INTERFACE_FILES
SocketInterface/RiaProjectInfoCommands.cpp SocketInterface/RiaProjectInfoCommands.cpp
SocketInterface/RiaCaseInfoCommands.cpp SocketInterface/RiaCaseInfoCommands.cpp
SocketInterface/RiaGeometryCommands.cpp SocketInterface/RiaGeometryCommands.cpp
SocketInterface/RiaNNCCommands.cpp
SocketInterface/RiaPropertyDataCommands.cpp SocketInterface/RiaPropertyDataCommands.cpp
SocketInterface/RiaWellDataCommands.cpp SocketInterface/RiaWellDataCommands.cpp
SocketInterface/RiaSocketTools.cpp SocketInterface/RiaSocketTools.cpp
@ -174,6 +174,59 @@ endif()
add_subdirectory(GeoMech/GeoMechDataModel) 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 # Qt specifics: Moc, ui, resources
############################################################################# #############################################################################
@ -283,8 +336,6 @@ set( LINK_LIBRARIES
${APP_FWK_LIBRARIES} ${APP_FWK_LIBRARIES}
${VIZ_FWK_LIBRARIES} ${VIZ_FWK_LIBRARIES}
${ERT_LIBRARIES}
${THIRD_PARTY_LIBRARIES} ${THIRD_PARTY_LIBRARIES}
${OPENGL_LIBRARIES} ${OPENGL_LIBRARIES}

View File

@ -39,6 +39,8 @@ ${CEE_CURRENT_LIST_DIR}RicDeleteItemExecData.h
${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.h ${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.h
${CEE_CURRENT_LIST_DIR}RicDeleteSubItemsFeature.h ${CEE_CURRENT_LIST_DIR}RicDeleteSubItemsFeature.h
${CEE_CURRENT_LIST_DIR}RicDeleteSourSimDataFeature.h
${CEE_CURRENT_LIST_DIR}RicCommandFeature.h ${CEE_CURRENT_LIST_DIR}RicCommandFeature.h
${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.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}RicDeleteSubItemsFeature.cpp
${CEE_CURRENT_LIST_DIR}RicDeleteSourSimDataFeature.cpp
${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.cpp ${CEE_CURRENT_LIST_DIR}RicReloadCaseFeature.cpp
${CEE_CURRENT_LIST_DIR}RicFlyToObjectFeature.cpp ${CEE_CURRENT_LIST_DIR}RicFlyToObjectFeature.cpp
) )

View 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;
}

View File

@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
class RimEclipseResultCase;
//==================================================================================================
///
//==================================================================================================
class 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();
};

View File

@ -9,6 +9,8 @@ set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RicNewSummaryPlotFeature.h ${CEE_CURRENT_LIST_DIR}RicNewSummaryPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.h ${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.h
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFilterFeature.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}RicViewZoomAllFeature.h
${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.h ${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.h
${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.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}RicNewSummaryPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.cpp ${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFeature.cpp
${CEE_CURRENT_LIST_DIR}RicNewSummaryCurveFilterFeature.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}RicViewZoomAllFeature.cpp
${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.cpp ${CEE_CURRENT_LIST_DIR}RicSummaryCurveSwitchAxisFeature.cpp
${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.cpp ${CEE_CURRENT_LIST_DIR}RicPasteSummaryPlotFeature.cpp

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

@ -0,0 +1,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();
}

View File

@ -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;
};

View File

@ -22,6 +22,10 @@ ${CEE_CURRENT_LIST_DIR}RifReaderMockModel.h
${CEE_CURRENT_LIST_DIR}RifReaderSettings.h ${CEE_CURRENT_LIST_DIR}RifReaderSettings.h
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.h ${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.h
${CEE_CURRENT_LIST_DIR}RifWellPathImporter.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 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}RifReaderSettings.cpp
${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.cpp ${CEE_CURRENT_LIST_DIR}RifEclipseSummaryAddress.cpp
${CEE_CURRENT_LIST_DIR}RifWellPathImporter.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 list(APPEND CODE_HEADER_FILES

View File

@ -99,11 +99,13 @@ public:
virtual void setTimeSteps(const std::vector<QDateTime>& timeSteps) {}; virtual void setTimeSteps(const std::vector<QDateTime>& timeSteps) {};
virtual size_t timeStepCount() = 0; virtual size_t timeStepCount() = 0;
virtual void timeSteps(std::vector<QDateTime>* timeSteps, std::vector<double>* daysSinceSimulationStart) = 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 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 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 void readWellData(well_info_type * well_info, bool importCompleteMswData) = 0;
virtual int readUnitsType() = 0; virtual int readUnitsType() = 0;
}; };

View File

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

View File

@ -49,6 +49,8 @@ public:
void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts); 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 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 void readWellData(well_info_type* well_info, bool importCompleteMswData);
virtual int readUnitsType(); virtual int readUnitsType();

View File

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

View File

@ -52,6 +52,8 @@ public:
void resultNames(QStringList* resultNames, std::vector<size_t>* resultDataItemCounts); 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 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 void readWellData(well_info_type * well_info, bool importCompleteMswData);
virtual int readUnitsType(); virtual int readUnitsType();

View File

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

View File

@ -0,0 +1,62 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RifHdf5ReaderInterface.h"
#include <QString>
#include "H5Cpp.h"
//==================================================================================================
//
//
//==================================================================================================
class RifHdf5Reader : public RifHdf5ReaderInterface
{
public:
explicit RifHdf5Reader(const QString& fileName);
virtual ~RifHdf5Reader();
std::vector<QDateTime> timeSteps() const override;
virtual QStringList propertyNames() const override;
bool dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values) const override;
private:
std::vector<std::string> getSourSimTimeStepFileNames(const QString& fileName) const;
QDateTime sourSimDateTimeToQDateTime(std::string dateString) const;
std::string getTimeStepNumberAs5DigitString(std::string fileName) const;
std::string IntTo5DigitString(int i) const;
int getIntAttribute(H5::H5File file, std::string groupName, std::string attributeName) const;
double getDoubleAttribute(H5::H5File file, std::string groupName, std::string attributeName) const;
std::string getStringAttribute(H5::H5File file, std::string groupName, std::string attributeName) const;
std::vector<std::string> getSubGroupNames(H5::H5File file, std::string baseGroupName) const;
std::vector<double> getStepTimeValues(H5::H5File file, std::string baseGroupName) const;
std::vector<std::string> getResultNames(H5::H5File file, std::string baseGroupName) const;
void getElementResultValues(H5::H5File file, std::string groupName, std::vector<double>* resultValues) const;
private:
QString m_fileName; // name of SourSimRL main file given by user
int m_fileStrategy; // SourSimRL file strategy, fileStrategy == 1 means one time step per file
std::vector<std::string> m_timeStepFileNames; // files containing transient SourSimRL results, one time step per file
};

View File

@ -0,0 +1,20 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RifHdf5ReaderInterface.h"

View File

@ -0,0 +1,38 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class QString;
class QDateTime;
class QStringList;
#include <vector>
#include <cstddef>
//==================================================================================================
//
//
//==================================================================================================
class RifHdf5ReaderInterface
{
public:
virtual std::vector<QDateTime> timeSteps() const = 0;
virtual QStringList propertyNames() const = 0;
virtual bool dynamicResult(const QString& result, size_t stepIndex, std::vector<double>* values) const = 0;
};

View File

@ -20,10 +20,17 @@
#include "RifReaderEclipseOutput.h" #include "RifReaderEclipseOutput.h"
#include "RiaLogging.h"
#include "RifEclipseInputFileTools.h" #include "RifEclipseInputFileTools.h"
#include "RifEclipseOutputFileTools.h" #include "RifEclipseOutputFileTools.h"
#include "RifEclipseRestartFilesetAccess.h" #include "RifEclipseRestartFilesetAccess.h"
#include "RifEclipseUnifiedRestartFileAccess.h" #include "RifEclipseUnifiedRestartFileAccess.h"
#include "RifHdf5ReaderInterface.h"
#ifdef USE_HDF5
#include "RifHdf5Reader.h"
#endif
#include "RigActiveCellInfo.h" #include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h" #include "RigCaseCellResultsData.h"
@ -38,6 +45,8 @@
#include "ert/ecl/ecl_kw_magic.h" #include "ert/ecl/ecl_kw_magic.h"
#include "ert/ecl/ecl_nnc_export.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 <cmath> // Needed for HUGE_VAL on Linux
#include <iostream> #include <iostream>
@ -409,7 +418,10 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e
{ {
progInfo.setProgressDescription("Reading NNC data"); progInfo.setProgressDescription("Reading NNC data");
progInfo.setNextProgressIncrement(5); 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.incrementProgress();
progInfo.setProgressDescription("Processing NNC data"); progInfo.setProgressDescription("Processing NNC data");
@ -435,6 +447,120 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e
return true; 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; if (!m_ecl_init_file ) return;
CVF_ASSERT(mainEclGrid && mainGrid); CVF_ASSERT(mainEclGrid && mainGrid);
// Get the data from ERT // 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) if (numNNC > 0)
{ {
ecl_nnc_type * eclNNCData= new ecl_nnc_type[numNNC]; // Transform to our own data structures
ecl_nnc_export(mainEclGrid, init_file, eclNNCData);
// Transform to our own datastructures
//cvf::Trace::show("Reading NNC. Count: " + cvf::String(numNNC));
mainGrid->nncData()->connections().resize(numNNC); 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) for (int nIdx = 0; nIdx < numNNC; ++nIdx)
{ {
RigGridBase* grid1 = mainGrid->gridByIndex(eclNNCData[nIdx].grid_nr1); const ecl_nnc_pair_type* geometry_pair = ecl_nnc_geometry_iget(nnc_geo, nIdx);
mainGrid->nncData()->connections()[nIdx].m_c1GlobIdx = grid1->reservoirCellIndex(eclNNCData[nIdx].global_index1); RigGridBase* grid1 = mainGrid->gridByIndex(geometry_pair->grid_nr1);
RigGridBase* grid2 = mainGrid->gridByIndex(eclNNCData[nIdx].grid_nr2); mainGrid->nncData()->connections()[nIdx].m_c1GlobIdx = grid1->reservoirCellIndex(geometry_pair->global_index1);
mainGrid->nncData()->connections()[nIdx].m_c2GlobIdx = grid2->reservoirCellIndex(eclNNCData[nIdx].global_index2); RigGridBase* grid2 = mainGrid->gridByIndex(geometry_pair->grid_nr2);
transmissibilityValues[nIdx] = eclNNCData[nIdx].trans; 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; 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. /// 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) bool RifReaderEclipseOutput::dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector<double>* values)
{ {
if (m_dynamicResultsAccess.isNull()) if (m_dynamicResultsAccess.isNull())
{ {
m_dynamicResultsAccess = createDynamicResultsAccess(); m_dynamicResultsAccess = createDynamicResultsAccess();

View File

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

View File

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

View File

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

View File

@ -145,14 +145,30 @@ void RivNNCGeometryGenerator::computeArrays()
/// Calculates the texture coordinates in a "nearly" one dimensional texture. /// 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 /// 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(); size_t numVertices = m_vertices->size();
textureCoords->resize(numVertices); textureCoords->resize(numVertices);
cvf::Vec2f* rawPtr = textureCoords->ptr(); cvf::Vec2f* rawPtr = textureCoords->ptr();
const std::vector<double>* nncResultVals;
const std::vector<double>* nncResultVals = m_nncData->connectionScalarResult(scalarResultIndex); if (resultType == RiaDefines::STATIC_NATIVE)
{
nncResultVals = m_nncData->staticConnectionScalarResult(scalarResultIndex);
}
else if (resultType == RiaDefines::DYNAMIC_NATIVE)
{
nncResultVals = m_nncData->dynamicConnectionScalarResult(scalarResultIndex, timeStepIndex);
}
else if (resultType == RiaDefines::GENERATED)
{
nncResultVals = m_nncData->generatedConnectionScalarResult(scalarResultIndex, timeStepIndex);
}
if (!nncResultVals) if (!nncResultVals)
{ {
textureCoords->setAll(cvf::Vec2f(0.0f, 1.0f)); textureCoords->setAll(cvf::Vec2f(0.0f, 1.0f));

View File

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

View File

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

View File

@ -416,6 +416,7 @@ QStringList RimContextCommandBuilder::commandsFromSelection()
{ {
commandIds << "RicReloadCaseFeature"; commandIds << "RicReloadCaseFeature";
commandIds << "RicExecuteScriptForCasesFeature"; commandIds << "RicExecuteScriptForCasesFeature";
commandIds << "RicDeleteSourSimDataFeature";
} }
else if (dynamic_cast<RimSummaryPlot*>(uiItem)) else if (dynamic_cast<RimSummaryPlot*>(uiItem))
{ {

View File

@ -601,7 +601,22 @@ bool RimEclipseCase::openReserviorCase()
size_t combinedTransResIdx = results->cellResults()->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); size_t combinedTransResIdx = results->cellResults()->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName());
if (combinedTransResIdx != cvf::UNDEFINED_SIZE_T) 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);
} }
} }

View File

@ -40,6 +40,7 @@
#include "RimTools.h" #include "RimTools.h"
#include "cafPdmSettings.h" #include "cafPdmSettings.h"
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiPropertyViewDialog.h" #include "cafPdmUiPropertyViewDialog.h"
#include "cafProgressInfo.h" #include "cafProgressInfo.h"
#include "cafUtils.h" #include "cafUtils.h"
@ -75,7 +76,11 @@ RimEclipseResultCase::RimEclipseResultCase()
flipYAxis.xmlCapability()->setIOWritable(true); flipYAxis.xmlCapability()->setIOWritable(true);
//flipYAxis.uiCapability()->setUiHidden(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_activeCellInfoIsReadFromFile = false;
m_gridAndWellDataIsReadFromFile = false; m_gridAndWellDataIsReadFromFile = false;
@ -148,6 +153,12 @@ bool RimEclipseResultCase::openEclipseGridFile()
{ {
m_flowDiagSolutions.push_back(new RimFlowDiagSolution()); m_flowDiagSolutions.push_back(new RimFlowDiagSolution());
} }
if (!m_sourSimFileName().isEmpty())
{
RifReaderEclipseOutput* outReader = dynamic_cast<RifReaderEclipseOutput*>(readerInterface.p());
outReader->setHdf5FileName(m_sourSimFileName());
}
return true; return true;
} }
@ -220,6 +231,20 @@ bool RimEclipseResultCase::openAndReadActiveCellData(RigEclipseCaseData* mainEcl
return true; 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); 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); m_timeStepFilter->uiOrdering(uiConfigName, *group1);
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_sourSimFileName)
{
loadAndUpdateSourSimData();
}
return RimEclipseCase::fieldChangedByUi(changedField, oldValue, newValue);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultCase::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (field == &m_sourSimFileName)
{
caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast<caf::PdmUiFilePathEditorAttribute*>(attribute);
if (myAttr)
{
myAttr->m_fileSelectionFilter = "SourSim (*.sourres)";
myAttr->m_defaultPath = QFileInfo(caseFileName()).absolutePath();
}
}
}

View File

@ -42,6 +42,8 @@ public:
void setGridFileName(const QString& caseFileName); void setGridFileName(const QString& caseFileName);
void setCaseInfo(const QString& userDescription, const QString& caseFileName); void setCaseInfo(const QString& userDescription, const QString& caseFileName);
void setSourSimFileName(const QString& fileName);
bool hasSourSimFile();
virtual bool openEclipseGridFile(); virtual bool openEclipseGridFile();
virtual void reloadEclipseGridFile(); virtual void reloadEclipseGridFile();
@ -57,6 +59,13 @@ public:
std::vector<RimFlowDiagSolution*> flowDiagSolutions(); std::vector<RimFlowDiagSolution*> flowDiagSolutions();
RigFlowDiagSolverInterface* flowDiagSolverInterface(); 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: private:
cvf::ref<RifReaderInterface> createMockModel(QString modelName); cvf::ref<RifReaderInterface> createMockModel(QString modelName);
@ -69,6 +78,7 @@ private:
// Fields: // Fields:
caf::PdmField<QString> caseFileName; caf::PdmField<QString> caseFileName;
caf::PdmChildArrayField<RimFlowDiagSolution*> m_flowDiagSolutions; caf::PdmChildArrayField<RimFlowDiagSolution*> m_flowDiagSolutions;
caf::PdmField<QString> m_sourSimFileName;
// Obsolete field // Obsolete field
@ -76,4 +86,5 @@ private:
bool m_gridAndWellDataIsReadFromFile; bool m_gridAndWellDataIsReadFromFile;
bool m_activeCellInfoIsReadFromFile; bool m_activeCellInfoIsReadFromFile;
}; };

View File

@ -426,27 +426,46 @@ QList<caf::PdmOptionItemInfo> RimEclipseResultDefinition::calculateValueOptions(
if ( fieldNeedingOptions == &m_resultTypeUiField ) 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; RimGridTimeHistoryCurve* timeHistoryCurve;
this->firstAncestorOrThisOfType(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 ) if ( timeHistoryCurve != nullptr )
{ {
using ResCatEnum = caf::AppEnum< RiaDefines::ResultCatType >; using ResCatEnum = caf::AppEnum< RiaDefines::ResultCatType >;
for ( size_t i = 0; i < ResCatEnum::size(); ++i ) for ( size_t i = 0; i < ResCatEnum::size(); ++i )
{ {
RiaDefines::ResultCatType resType = ResCatEnum::fromIndex(i); RiaDefines::ResultCatType resType = ResCatEnum::fromIndex(i);
if ( resType != RiaDefines::FLOW_DIAGNOSTICS ) if ( resType == RiaDefines::FLOW_DIAGNOSTICS
&& (timeHistoryCurve) )
{ {
QString uiString = ResCatEnum::uiTextFromIndex(i); continue;
options.push_back(caf::PdmOptionItemInfo(uiString, resType));
} }
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 ) if ( m_resultTypeUiField() != RiaDefines::FLOW_DIAGNOSTICS )
@ -858,6 +877,10 @@ bool RimEclipseResultDefinition::hasDynamicResult() const
{ {
return true; return true;
} }
else if (m_resultType() == RiaDefines::SOURSIMRL)
{
return true;
}
else if (m_resultType() == RiaDefines::FLOW_DIAGNOSTICS) else if (m_resultType() == RiaDefines::FLOW_DIAGNOSTICS)
{ {
return true; return true;

View File

@ -41,6 +41,7 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QUuid> #include <QUuid>
#include "RifReaderEclipseOutput.h"
CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage"); CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage");
@ -243,6 +244,11 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& res
scalarResultIndex = this->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, resultName); 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) if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{ {
scalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::GENERATED, resultName); scalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::GENERATED, resultName);
@ -335,6 +341,27 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RiaDefines::Result
computeRiTRANSbyAreaComponent(resultName); 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)) 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; 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; return scalarResultIndex;
} }
@ -990,7 +1057,7 @@ void RimReservoirCellResultsStorage::computeNncCombRiTrans()
if (!m_cellResults) return; if (!m_cellResults) return;
size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName()); 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(); double cdarchy = darchysValue();
@ -1009,7 +1076,8 @@ void RimReservoirCellResultsStorage::computeNncCombRiTrans()
std::vector<double> & permXResults = m_cellResults->cellScalarResults(permXResultIdx)[0]; std::vector<double> & permXResults = m_cellResults->cellScalarResults(permXResultIdx)[0];
std::vector<double> & permYResults = m_cellResults->cellScalarResults(permYResultIdx)[0]; std::vector<double> & permYResults = m_cellResults->cellScalarResults(permYResultIdx)[0];
std::vector<double> & permZResults = m_cellResults->cellScalarResults(permZResultIdx)[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; std::vector<double> * ntgResults = NULL;
if (hasNTGResults) if (hasNTGResults)
@ -1250,11 +1318,12 @@ void RimReservoirCellResultsStorage::computeNncCombRiMULT()
size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName()); size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName());
size_t combTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); 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); std::vector<double> & riMultResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombMult());
const std::vector<double> * riTransResults = m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransScalarResultIndex); const std::vector<double> * riTransResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransScalarResultIndex);
const std::vector<double> * transResults = m_ownerMainGrid->nncData()->connectionScalarResult(combTransScalarResultIndex); 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) 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 riCombTransByAreaScResIdx = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiAreaNormTranResultName());
size_t combTransScalarResultIndex = m_cellResults->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); 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); std::vector<double> & riAreaNormTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTransByArea());
const std::vector<double> * transResults = m_ownerMainGrid->nncData()->connectionScalarResult(combTransScalarResultIndex); 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(); const std::vector<RigConnection>& connections = m_ownerMainGrid->nncData()->connections();

View File

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

View 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;
}

View 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;
};

View File

@ -28,6 +28,7 @@
#include "RimSummaryPlotCollection.h" #include "RimSummaryPlotCollection.h"
#include "RimSummaryTimeAxisProperties.h" #include "RimSummaryTimeAxisProperties.h"
#include "RimSummaryYAxisProperties.h" #include "RimSummaryYAxisProperties.h"
#include "RimAsciiDataCurve.h"
#include "RiuMainPlotWindow.h" #include "RiuMainPlotWindow.h"
#include "RiuSummaryQwtPlot.h" #include "RiuSummaryQwtPlot.h"
@ -72,6 +73,9 @@ RimSummaryPlot::RimSummaryPlot()
CAF_PDM_InitFieldNoDefault(&m_gridTimeHistoryCurves, "GridTimeHistoryCurves", "", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_gridTimeHistoryCurves, "GridTimeHistoryCurves", "", "", "", "");
m_gridTimeHistoryCurves.uiCapability()->setUiTreeHidden(true); 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", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_leftYAxisProperties, "LeftYAxisProperties", "Left Y Axis", "", "", "");
m_leftYAxisProperties.uiCapability()->setUiTreeHidden(true); 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; 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_curveFilters);
uiTreeOrdering.add(&m_summaryCurves); uiTreeOrdering.add(&m_summaryCurves);
uiTreeOrdering.add(&m_gridTimeHistoryCurves); uiTreeOrdering.add(&m_gridTimeHistoryCurves);
uiTreeOrdering.add(&m_asciiDataCurves);
uiTreeOrdering.skipRemainingChildren(true); uiTreeOrdering.skipRemainingChildren(true);
} }
@ -768,6 +850,11 @@ void RimSummaryPlot::loadDataAndUpdate()
curve->loadDataAndUpdate(); curve->loadDataAndUpdate();
} }
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->loadDataAndUpdate();
}
this->updateAxes(); this->updateAxes();
updateZoomInQwt(); updateZoomInQwt();
@ -867,6 +954,11 @@ QWidget* RimSummaryPlot::createViewWidget(QWidget* mainWindowParent)
{ {
curve->setParentQwtPlot(m_qwtPlot); curve->setParentQwtPlot(m_qwtPlot);
} }
for (RimAsciiDataCurve* curve : m_asciiDataCurves)
{
curve->setParentQwtPlot(m_qwtPlot);
}
} }
return m_qwtPlot; return m_qwtPlot;
@ -937,6 +1029,11 @@ void RimSummaryPlot::detachAllCurves()
{ {
curve->detachQwtCurve(); 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) for (RimSummaryCurveFilter* curveFilter: m_curveFilters)
{ {
RimSummaryCurve* foundCurve = curveFilter->findRimCurveFromQwtCurve(qwtCurve); RimSummaryCurve* foundCurve = curveFilter->findRimCurveFromQwtCurve(qwtCurve);
@ -974,7 +1079,7 @@ caf::PdmObject* RimSummaryPlot::findRimCurveFromQwtCurve(const QwtPlotCurve* qwt
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
size_t RimSummaryPlot::curveCount() const size_t RimSummaryPlot::curveCount() const
{ {
return m_summaryCurves.size() + m_gridTimeHistoryCurves.size(); return m_summaryCurves.size() + m_gridTimeHistoryCurves.size() + m_asciiDataCurves.size();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@ class RimSummaryCurveFilter;
class RimSummaryYAxisProperties; class RimSummaryYAxisProperties;
class RimSummaryTimeAxisProperties; class RimSummaryTimeAxisProperties;
class RimGridTimeHistoryCurve; class RimGridTimeHistoryCurve;
class RimAsciiDataCurve;
class PdmUiTreeOrdering; class PdmUiTreeOrdering;
class QwtPlotCurve; class QwtPlotCurve;
@ -61,6 +62,8 @@ public:
void addGridTimeHistoryCurve(RimGridTimeHistoryCurve* curve); void addGridTimeHistoryCurve(RimGridTimeHistoryCurve* curve);
void addAsciiDataCruve(RimAsciiDataCurve* curve);
caf::PdmObject* findRimCurveFromQwtCurve(const QwtPlotCurve* curve) const; caf::PdmObject* findRimCurveFromQwtCurve(const QwtPlotCurve* curve) const;
size_t curveCount() const; size_t curveCount() const;
@ -125,6 +128,7 @@ private:
caf::PdmChildArrayField<RimGridTimeHistoryCurve*> m_gridTimeHistoryCurves; caf::PdmChildArrayField<RimGridTimeHistoryCurve*> m_gridTimeHistoryCurves;
caf::PdmChildArrayField<RimSummaryCurve*> m_summaryCurves; caf::PdmChildArrayField<RimSummaryCurve*> m_summaryCurves;
caf::PdmChildArrayField<RimSummaryCurveFilter*> m_curveFilters; caf::PdmChildArrayField<RimSummaryCurveFilter*> m_curveFilters;
caf::PdmChildArrayField<RimAsciiDataCurve*> m_asciiDataCurves;
caf::PdmField<bool> m_isAutoZoom; caf::PdmField<bool> m_isAutoZoom;
caf::PdmChildField<RimSummaryYAxisProperties*> m_leftYAxisProperties; caf::PdmChildField<RimSummaryYAxisProperties*> m_leftYAxisProperties;

View File

@ -231,6 +231,11 @@ size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName)
scalarResultIndex = this->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, resultName); 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) if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
{ {
scalarResultIndex = this->findScalarResultIndex(RiaDefines::GENERATED, resultName); 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())); calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranZResultName()));
statisticsCalculator = calc; 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 else
{ {
statisticsCalculator = new RigEclipseNativeStatCalc(this, scalarResultIndex); 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 // TRANSXYZ
{ {
size_t tranX, tranY, tranZ; size_t tranX, tranY, tranZ;

View File

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

View File

@ -166,38 +166,313 @@ void RigNNCData::processConnections(const RigMainGrid& mainGrid)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<double>& RigNNCData::makeConnectionScalarResult(size_t scalarResultIndex) std::vector<double>& RigNNCData::makeStaticConnectionScalarResult(QString nncDataType)
{ {
std::vector<double>& results = m_connectionResults[scalarResultIndex]; std::vector< std::vector<double> >& results = m_connectionResults[nncDataType];
results.resize(m_connections.size(), HUGE_VAL); 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; 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()) if (it != m_connectionResults.end())
{
return &(it->second); return &(it->second);
}
else 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()) if (it != m_connectionResults.end())
{ {
std::vector<double>& emptyData = m_connectionResults[scalarResultIndex]; if (it->second.size() > timeStep)
std::vector<double>& realData = m_connectionResults[cvf::UNDEFINED_SIZE_T]; {
emptyData.swap(realData); return &(it->second[timeStep]);
m_connectionResults.erase(cvf::UNDEFINED_SIZE_T); }
} }
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) 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()); 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; auto it = m_resultIndexToNNCDataType.find(scalarResultIndex);
static std::vector<size_t> empty; if (it != m_resultIndexToNNCDataType.end())
it = m_cellIdxToFaceToConnectionIdxMap.find(reservoirCellIndex);
if (it != m_cellIdxToFaceToConnectionIdxMap.end())
{ {
return it->second[face]; return it->second;
} }
return QString();
return empty; }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigNNCData::isNative(QString nncDataType) const
{
if (nncDataType == RigNNCData::propertyNameCombTrans() ||
nncDataType == RigNNCData::propertyNameFluxGas() ||
nncDataType == RigNNCData::propertyNameFluxOil() ||
nncDataType == RigNNCData::propertyNameFluxWat() ||
nncDataType == RigNNCData::propertyNameRiCombMult() ||
nncDataType == RigNNCData::propertyNameRiCombTrans() ||
nncDataType == RigNNCData::propertyNameRiCombTransByArea())
{
return true;
}
return false;
} }
*/

View File

@ -57,28 +57,61 @@ public:
class RigNNCData : public cvf::Object class RigNNCData : public cvf::Object
{ {
public: 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(); RigNNCData();
void processConnections(const RigMainGrid& mainGrid); void processConnections(const RigMainGrid& mainGrid);
std::vector<RigConnection>& connections() { return m_connections; } 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); std::vector<double>& makeStaticConnectionScalarResult(QString nncDataType);
const std::vector<double>* connectionScalarResult(size_t scalarResultIndex) const; 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); bool hasScalarValues(size_t scalarResultIndex);
private: // This section is possibly not needed private:
//const std::vector<size_t>& findConnectionIndices(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const; const QString getNNCDataTypeFromScalarResultIndex(size_t scalarResultIndex) const;
//typedef std::map<size_t, caf::FixedArray<std::vector<size_t>, 7 > > ConnectionSearchMap; bool isNative(QString nncDataType) const;
//ConnectionSearchMap m_cellIdxToFaceToConnectionIdxMap;
private: private:
std::vector<RigConnection> m_connections; std::vector<RigConnection> m_connections;
std::map<size_t, std::vector<double> > m_connectionResults; ///< scalarResultIndex to value array map std::map<QString, std::vector< std::vector<double> > > m_connectionResults;
std::map<size_t, QString> m_resultIndexToNNCDataType;
}; };

View File

@ -542,7 +542,7 @@ void RigReservoirBuilderMock::addFaults(RigEclipseCaseData* eclipseCase)
addNnc(grid, i1, j1, k1, i2, j2, k2, nncConnections); 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) for (size_t cIdx = 0; cIdx < tranVals.size(); ++cIdx)
{ {
tranVals[cIdx] = 0.2; tranVals[cIdx] = 0.2;

View File

@ -125,6 +125,55 @@ cvf::ref<RigResultAccessor> RigResultAccessorFactory::createFromUiResultName(Rig
return cellFaceAccessObject; 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); return RigResultAccessorFactory::createNativeFromUiResultName(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName);
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@ ${CEE_CURRENT_LIST_DIR}ScalarMapper-Test.cpp
${CEE_CURRENT_LIST_DIR}WellPathAsciiFileReader-Test.cpp ${CEE_CURRENT_LIST_DIR}WellPathAsciiFileReader-Test.cpp
${CEE_CURRENT_LIST_DIR}opm-flowdiagnostics-Test.cpp ${CEE_CURRENT_LIST_DIR}opm-flowdiagnostics-Test.cpp
${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator-Test.cpp ${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator-Test.cpp
${CEE_CURRENT_LIST_DIR}HDF5FileReader-Test.cpp
) )
list(APPEND CODE_HEADER_FILES list(APPEND CODE_HEADER_FILES

View 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, &timestep_value);
//std::cout << "Timestep value " << timestep_value << std::endl;
EXPECT_NEAR(timestep_value, 1.0, 1e-1);
}
{
// Group size is not an attribute!
H5::Group GridFunctions = file.openGroup("Timestep_00001/GridParts/GridPart_00000/GridFunctions");
hsize_t group_size = GridFunctions.getNumObjs();
//std::cout << "GridFunctions group_size " << group_size << std::endl;
EXPECT_EQ(group_size, 20);
/* for (hsize_t i = 0; i < group_size; i++)
{
// H5std_string node_name = GridFunctions.getObjnameByIdx(i); // crashes on VS2017 due to lib/heap/runtime differences to HDF5 VS2015 lib
std::string node_name;
node_name.resize(1024);
ssize_t slen = GridFunctions.getObjnameByIdx(i, &node_name[0], 1023);
node_name.resize(slen + 1);
std::cout << "GridFunctions sub-node name " << node_name << std::endl;
}
*/
std::string first_subnode(1024, '\0');
ssize_t slen = GridFunctions.getObjnameByIdx(0, &first_subnode[0], 1023);
first_subnode.resize(slen + 1);
EXPECT_TRUE(first_subnode.compare(0, slen, "GridFunction_00002") == 0);
}
{
H5::Group GridFunction_00002 = file.openGroup("Timestep_00001/GridParts/GridPart_00000/GridFunctions/GridFunction_00002");
H5::Attribute attr = GridFunction_00002.openAttribute("limits_max");
double limits_max = 0.0;
H5::DataType type = attr.getDataType();
attr.read(type, &limits_max);
// std::cout << "limits_max " << limits_max << std::endl;
EXPECT_NEAR(limits_max, 0.3970204292629652, 1e-10);
}
{
H5::Group GridFunction_00002 = file.openGroup("Timestep_00001/GridParts/GridPart_00000/GridFunctions/GridFunction_00002");
H5::DataSet dataset = H5::DataSet(GridFunction_00002.openDataSet("values"));
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims(dims, NULL);
std::vector<double> values;
values.resize(dims[0]);
dataset.read(values.data(), H5::PredType::NATIVE_DOUBLE);
/* for (hsize_t i = 0; i < dims[0]; i++)
{
std::cout << "value " << i << " " << values[i] << std::endl;
}
*/
EXPECT_NEAR(values[0], 0.32356910366452146, 1e-10);
EXPECT_NEAR(values[dims[0] - 1], 0.12200070891582514, 1e-10);
}
} // end of try block
catch (H5::FileIException error) // catch failure caused by the H5File operations
{
std::cout << error.getCDetailMsg();
}
catch (H5::DataSetIException error) // catch failure caused by the DataSet operations
{
std::cout << error.getCDetailMsg();
}
catch (H5::DataSpaceIException error) // catch failure caused by the DataSpace operations
{
std::cout << error.getCDetailMsg();
}
catch (H5::DataTypeIException error) // catch failure caused by the DataSpace operations
{
std::cout << error.getCDetailMsg();
}
}
#endif //USE_HDF5

View File

@ -461,3 +461,25 @@ TEST(RigReservoirTest, WellTest)
#endif #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);
}

View File

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

View File

@ -348,7 +348,16 @@ QString RiuResultTextBuilder::nncResultText()
if (m_reservoirView->currentFaultResultColors()) if (m_reservoirView->currentFaultResultColors())
{ {
size_t scalarResultIdx = m_reservoirView->currentFaultResultColors()->scalarResultIndex(); 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) if (nncValues)
{ {
QString resultVar = m_reservoirView->currentFaultResultColors()->resultVariableUiName(); QString resultVar = m_reservoirView->currentFaultResultColors()->resultVariableUiName();

View File

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

View File

@ -79,25 +79,21 @@ if (RESINSIGHT_ERT_EXTERNAL_LIB_ROOT OR RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT)
message(FATAL_ERROR "Both RESINSIGHT_ERT_EXTERNAL_LIB_ROOT and RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT must be defined") message(FATAL_ERROR "Both RESINSIGHT_ERT_EXTERNAL_LIB_ROOT and RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT must be defined")
endif() endif()
message(FATAL_ERROR "TODO: Building using and external system installed ERT is broken.")
list(APPEND ERT_INCLUDE_DIRS list(APPEND ERT_INCLUDE_DIRS
${RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT} ${RESINSIGHT_ERT_EXTERNAL_INCLUDE_ROOT}
) )
list(APPEND ERT_LIBRARIES list(APPEND ERT_LIBRARIES
${RESINSIGHT_ERT_EXTERNAL_LIB_ROOT}/libecl.so ${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() else()
# Disable install of ERT libs and headers, as Ert code is compiled and linked directly # 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(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_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 # Remember original state
set(ORIGINAL_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) set(ORIGINAL_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
@ -115,36 +111,18 @@ else()
endif() endif()
if (RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT) if (RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT)
set(ERT_INCLUDE_ROOT "${RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT}") add_subdirectory(${RESINSIGHT_ERT_EXTERNAL_SOURCE_ROOT} ${CMAKE_BINARY_DIR}/ThirdParty/Ert)
add_subdirectory(${ERT_SOURCE_PATH} ${CMAKE_BINARY_DIR}/ThirdParty/Ert)
else() else()
set(ERT_INCLUDE_ROOT ${CMAKE_SOURCE_DIR}/ThirdParty/Ert)
add_subdirectory(ThirdParty/Ert) add_subdirectory(ThirdParty/Ert)
endif () endif ()
list(APPEND ERT_INCLUDE_DIRS list(APPEND THIRD_PARTY_LIBRARIES
${ERT_INCLUDE_ROOT}/libecl/include/ ecl
${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
) )
if (MSVC) if (MSVC)
set_property(TARGET set_property(TARGET
${ERT_LIBRARIES} ecl
ecl_lfs
PROPERTY FOLDER "Thirdparty/ERT" PROPERTY FOLDER "Thirdparty/ERT"
) )
endif() 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
${CMAKE_BINARY_DIR}/ThirdParty/Ert/${CMAKE_INSTALL_LIBDIR}/libecl.so.2 ${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}/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} ) 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}") set (RESINSIGHT_PACKAGE_NAME "${RESINSIGHT_PACKAGE_NAME}_oct-${OCTAVE_VERSION_STRING}")
endif() 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 # Append el5 when compiled on RHEL5 and el6 if compiled on RHEL6
if (NOT "${RESINSIGHT_RHEL_SYSTEM_NAME}" STREQUAL "") if (NOT "${RESINSIGHT_RHEL_SYSTEM_NAME}" STREQUAL "")

View File

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

View File

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

View File

@ -8,9 +8,14 @@ set(CPP_SOURCES
riSetActiveCellProperty.cpp riSetActiveCellProperty.cpp
riGetActiveCellInfo.cpp riGetActiveCellInfo.cpp
riGetMainGridDimensions.cpp riGetMainGridDimensions.cpp
riGetNNCConnections.cpp
riGetNNCPropertyNames.cpp
riGetCurrentCase.cpp riGetCurrentCase.cpp
riGetCaseGroups.cpp riGetCaseGroups.cpp
riGetDynamicNNCValues.cpp
riGetStaticNNCValues.cpp
riGetSelectedCases.cpp riGetSelectedCases.cpp
riGetSelectedCells.cpp
riGetCases.cpp riGetCases.cpp
riGetTimeStepDates.cpp riGetTimeStepDates.cpp
riGetTimeStepDays.cpp riGetTimeStepDays.cpp
@ -22,10 +27,12 @@ set(CPP_SOURCES
riGetActiveCellCorners.cpp riGetActiveCellCorners.cpp
riGetGridProperty.cpp riGetGridProperty.cpp
riSetGridProperty.cpp riSetGridProperty.cpp
riGetGridPropertyForSelectedCells.cpp
riGetPropertyNames.cpp riGetPropertyNames.cpp
riGetWellNames.cpp riGetWellNames.cpp
riGetWellStatus.cpp riGetWellStatus.cpp
riGetWellCells.cpp riGetWellCells.cpp
riSetNNCProperty.cpp
) )
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") 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}/riSetActiveCellProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetActiveCellInfo.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetActiveCellInfo.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetMainGridDimensions.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}/riGetCurrentCase.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetCaseGroups.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetCaseGroups.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetSelectedCases.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetSelectedCases.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetSelectedCells.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetCases.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetCases.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetTimeStepDates.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetTimeStepDates.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetTimeStepDays.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}/riGetActiveCellCorners.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetGridProperty.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetGridProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riSetGridProperty.oct" "${CMAKE_CURRENT_BINARY_DIR}/riSetGridProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetGridPropertyForSelectedCells.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetPropertyNames.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetPropertyNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetWellCells.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riSetNNCProperty.oct"
SOURCES SOURCES
${CPP_SOURCES} ${CPP_SOURCES}
riSettings.h riSettings.h

View File

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

View File

@ -148,7 +148,7 @@ DEFUN_DLD (riGetActiveCellProperty, args, nargout,
// Check if we have a Requested TimeSteps // 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; argIndices[2] = -1;
for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx) for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx)

View File

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

View File

@ -163,7 +163,7 @@ DEFUN_DLD (riGetGridProperty, args, nargout,
// Check if we have a Requested TimeSteps // 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; argIndices[3] = -1;
for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx) for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx)

View File

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

View File

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

View 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();
}

View 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();
}

View 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);
}

View File

@ -136,7 +136,7 @@ DEFUN_DLD (riGetWellStatus, args, nargout,
// Check if we have a Requested TimeSteps // Check if we have a Requested TimeSteps
int lastArgumentIndex = argIndices[2] ; 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; argIndices[2] = -1;
} }

View 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 ();
}

View File

@ -60,5 +60,11 @@ namespace riOctavePlugin
char timeStepDate_Hour[] = "Hour"; char timeStepDate_Hour[] = "Hour";
char timeStepDate_Minute[] = "Minute"; char timeStepDate_Minute[] = "Minute";
char timeStepDate_Second[] = "Second"; char timeStepDate_Second[] = "Second";
// Octave data structure : CellIndex
char cellIndex_gridIndex[] = "GridIndex";
char cellIndex_I[] = "I";
char cellIndex_J[] = "J";
char cellIndex_K[] = "K";
} }

View File

@ -1,14 +1,15 @@
set(RESINSIGHT_MAJOR_VERSION 2017) set(RESINSIGHT_MAJOR_VERSION 2017)
set(RESINSIGHT_MINOR_VERSION 05) 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 # https://github.com/CRAVA/crava/tree/master/libs/nrlib
set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f") set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f")
# https://github.com/Statoil/libecl # 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 # https://github.com/OPM/opm-flowdiagnostics
set(OPM_FLOWDIAGNOSTICS_SHA "b6e59ddcd2feba450c8612a7402c9239e442c0d4") set(OPM_FLOWDIAGNOSTICS_SHA "b6e59ddcd2feba450c8612a7402c9239e442c0d4")

View 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

View File

@ -1,7 +1,16 @@
dist: trusty
sudo: false
language: c language: c
matrix:
fast_finish: true
include:
- os: osx
osx_image: xcode7.3
compiler: clang
- os: linux
sudo: false
compiler: gcc
dist: trusty
addons: addons:
apt: apt:
sources: sources:
@ -11,6 +20,9 @@ addons:
- valgrind - valgrind
- gcc-4.8 - gcc-4.8
- g++-4.8 - g++-4.8
- clang
- cmake
- cmake-data
env: env:
global: global:
@ -18,7 +30,18 @@ env:
install: install:
- if [[ "$CC" == "gcc" ]]; then export CXX="g++-4.8"; fi - 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 - bash miniconda.sh -b -p $HOME/miniconda
- export CONDA_HOME="$HOME/miniconda" - export CONDA_HOME="$HOME/miniconda"
- export PATH="$CONDA_HOME/bin:$PATH" - export PATH="$CONDA_HOME/bin:$PATH"
@ -29,10 +52,7 @@ install:
- conda install pylint numpy pandas - conda install pylint numpy pandas
before_script: before_script:
- mkdir build - wget https://raw.githubusercontent.com/Statoil/ert/master/travis/build_total.py
- cd build
- cmake -DBUILD_TESTS=ON -DBUILD_PYTHON=ON -DERT_BUILD_CXX=ON -DBUILD_APPLICATIONS=ON ..
script: script:
- make - python build_total.py ecl
- ctest --output-on-failure -E ert_util_ping

View File

@ -1,6 +1,8 @@
cmake_minimum_required( VERSION 2.8 ) cmake_minimum_required( VERSION 2.8.12 )
project( ERT C CXX ) project( ERT C CXX )
include(GNUInstallDirs)
if(POLICY CMP0042) if(POLICY CMP0042)
cmake_policy(SET CMP0042 OLD) cmake_policy(SET CMP0042 OLD)
endif() 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_TESTS "Should the tests be built" OFF)
option( BUILD_APPLICATIONS "Should we build small utility applications" OFF) option( BUILD_APPLICATIONS "Should we build small utility applications" OFF)
option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" 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( 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_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( 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") 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}") EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${STATOIL_TESTDATA_ROOT}" "${LINK}")
message(STATUS "Linking testdata: ${LINK} -> ${STATOIL_TESTDATA_ROOT}") 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() 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() ENABLE_TESTING()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -66,7 +76,7 @@ endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
# Set the possible values of build type for cmake-gui # Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
@ -84,90 +94,221 @@ if (MSVC)
endif() 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) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
find_package(CXX11Features) 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} ) check_function_exists( chdir HAVE_POSIX_CHDIR )
set( CMAKE_CXX_FLAGS_main ${CMAKE_CXX_FLAGS} ) 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) check_symbol_exists(_tzname time.h HAVE_WINDOWS_TZNAME)
set( CMAKE_C_FLAGS_main "${CMAKE_C_FLAGS} -std=gnu99" ) 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() endif()
set( ERT_EXTERNAL_UTIL_LIBS "" ) try_compile( HAVE_VA_COPY ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_va_copy.c )
include(cmake/ert_build_check.cmake) try_compile( HAVE_SIGBUS ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_have_sigbus.c )
include(cmake/ert_api_check.cmake) try_compile( HAVE_PID_T ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_pid_t.c )
include(cmake/ert_lib_check.cmake) 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( BUILD_CXX ON )
set( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_main} ) 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) if (HAVE_FORK AND HAVE_PTHREAD AND HAVE_EXECINFO AND HAVE_GETPWUID)
include(cmake/ert_link.cmake) 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(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) if (MSVC)
add_definitions( -D__func__="\\"????\\"") add_definitions( -D__func__="\\"????\\"")
endif() endif()
if (ERT_WINDOWS)
message(WARNING "Python is not supported on Windows")
set( BUILD_PYTHON OFF )
endif ()
if (ERT_LINUX) if (ERT_LINUX)
set( NEED_LIBM TRUE )
set( LINK_STATIC FALSE )
add_definitions( -DHAVE_PROC ) add_definitions( -DHAVE_PROC )
else()
set( NEED_LIBM FALSE )
set( LINK_STATIC TRUE )
endif() endif()
include_directories( ${PROJECT_SOURCE_DIR}/libert_util/include ) add_subdirectory( lib )
include_directories( ${PROJECT_BINARY_DIR}/libert_util/include ) add_subdirectory( applications )
if (MSVC)
include_directories( ${PROJECT_BINARY_DIR}/libert_util/include/ert/util )
endif()
add_subdirectory( libert_util )
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 (BUILD_PYTHON)
if (ERT_WINDOWS) if (ERT_WINDOWS)
message(WARNING "Python is not supported on Windows") message(WARNING "Python is not supported on Windows")
@ -178,7 +319,7 @@ if (BUILD_PYTHON)
# will be set to OFF. # will be set to OFF.
add_subdirectory( python ) add_subdirectory( python )
if(ERT_DOC) if(RST_DOC)
add_subdirectory( docs ) add_subdirectory( docs )
endif() endif()
endif() endif()
@ -190,10 +331,9 @@ if (BUILD_PYTHON)
endif() endif()
endif() endif()
if (INSTALL_ERT)
install(EXPORT ecl-config DESTINATION share/cmake/ecl)
endif()
export(TARGETS ecl FILE eclConfig.cmake)
configure_file( cmake/libecl-config.cmake.in libecl-config.cmake @ONLY) export(PACKAGE ecl)
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 )

View 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})

View File

@ -72,13 +72,13 @@ void unpack_file(const char * filename) {
break; break;
if (target_type == ECL_SUMMARY_FILE) { 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; report_step += 1;
offset = 0; offset = 0;
} else { } else {
ecl_kw_type * seqnum_kw; ecl_kw_type * seqnum_kw;
active_view = ecl_file_alloc_global_blockview(src_file, SEQNUM_KW, block_index); active_view = ecl_file_get_global_blockview(src_file, SEQNUM_KW, block_index);
seqnum_kw = ecl_file_iget_named_kw( src_file , SEQNUM_KW , 0); seqnum_kw = ecl_file_view_iget_named_kw( active_view , SEQNUM_KW , 0);
report_step = ecl_kw_iget_int( seqnum_kw , 0); report_step = ecl_kw_iget_int( seqnum_kw , 0);
offset = 1; offset = 1;
} }
@ -100,7 +100,6 @@ void unpack_file(const char * filename) {
free(target_file); free(target_file);
} }
block_index++; block_index++;
ecl_file_view_free( active_view );
} }
ecl_file_close( src_file ); ecl_file_close( src_file );
util_safe_free(path); util_safe_free(path);

View File

@ -65,7 +65,7 @@ int main(int argc, char ** argv) {
{ {
ecl_kw_type * ecl_kw = ecl_kw_alloc_empty(); ecl_kw_type * ecl_kw = ecl_kw_alloc_empty();
while (true) { 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 ); const char * header = ecl_kw_get_header( ecl_kw );
if (set_has_key( kw_set , header )) { if (set_has_key( kw_set , header )) {
ecl_kw_fread_realloc_data(ecl_kw , fortio_src ); 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