mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Make it possible to build Octave plugins independent to main build
The building of Octave plugins within main ResInsight build on RHEL8 cause the build to use gcc-12, and gcc-12 is extremely slow when building opm-common. Adjust the CMake configuration so it is possible to build the Octave plugins as an independent build job. The plugin binaries can then be uploaded to an external server. The main ResInsight build can download the binaries and include them in the install package for ResInsight. Use the flag RESINSIGHT_USE_EXTERNAL_OCTAVE_PLUGINS to download external Octave plugin binaries.
This commit is contained in:
33
Octave/CMakeLists.txt
Normal file
33
Octave/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(OctavePlugins)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
find_package(Octave)
|
||||
|
||||
if(CEE_USE_QT6)
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS
|
||||
REQUIRED Core Gui OpenGL Widgets Network
|
||||
)
|
||||
set(QT_LIBRARIES Qt6::Core Qt6::Gui Qt6::OpenGL Qt6::Widgets Qt6::Network)
|
||||
qt_standard_project_setup()
|
||||
else()
|
||||
find_package(
|
||||
Qt5
|
||||
COMPONENTS
|
||||
REQUIRED Core Gui OpenGL Widgets Network
|
||||
)
|
||||
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::OpenGL Qt5::Widgets Qt5::Network)
|
||||
endif()
|
||||
|
||||
add_subdirectory(OctavePlugin)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(CPACK_GENERATOR TGZ)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
278
Octave/OctavePlugin/CMakeLists.txt
Normal file
278
Octave/OctavePlugin/CMakeLists.txt
Normal file
@@ -0,0 +1,278 @@
|
||||
# Some of the functionality in this CMakeLists.txt might be easier to maintain
|
||||
# if we use a CMake macro to find configuration info for Octave This file is
|
||||
# currently (2.8.12) not part of default CMake installation See
|
||||
# http://www.cmake.org/Wiki/CMakeUserFindOctave
|
||||
|
||||
set(CPP_SOURCES
|
||||
riGetActiveCellProperty.cpp
|
||||
riSetActiveCellProperty.cpp
|
||||
riGetActiveCellInfo.cpp
|
||||
riGetMainGridDimensions.cpp
|
||||
riGetNNCConnections.cpp
|
||||
riGetNNCPropertyNames.cpp
|
||||
riGetCurrentCase.cpp
|
||||
riGetCaseGroups.cpp
|
||||
riGetDynamicNNCValues.cpp
|
||||
riGetStaticNNCValues.cpp
|
||||
riGetSelectedCases.cpp
|
||||
riGetSelectedCells.cpp
|
||||
riGetCases.cpp
|
||||
riGetTimeStepDates.cpp
|
||||
riGetTimeStepDays.cpp
|
||||
riGetGridDimensions.cpp
|
||||
riGetCoarseningInfo.cpp
|
||||
riGetCellCenters.cpp
|
||||
riGetActiveCellCenters.cpp
|
||||
riGetCellCorners.cpp
|
||||
riGetActiveCellCorners.cpp
|
||||
riGetGridProperty.cpp
|
||||
riSetGridProperty.cpp
|
||||
riGetGridPropertyForSelectedCells.cpp
|
||||
riGetPropertyNames.cpp
|
||||
riGetWellNames.cpp
|
||||
riGetWellStatus.cpp
|
||||
riGetWellCells.cpp
|
||||
riSetNNCProperty.cpp
|
||||
)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
# since the compiler passes the option to the linker, double quoting is
|
||||
# necessary
|
||||
set(RPATH_COMMAND "-Wl,-rpath,'\\$$ORIGIN'")
|
||||
endif()
|
||||
|
||||
# recreate the magic that CMake does for MacOS X frameworks in the include list
|
||||
# when we call mkoctfile as a custom command
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(QT_INCLUDES)
|
||||
set(QT_FRAMEWORKS)
|
||||
# QT_INCLUDE_DIR contains two items; the first is the directory containing
|
||||
# header files, the second is the framework. This setup is specially processed
|
||||
# in include_directories (); CMake will add -F before the frameworks. We will
|
||||
# have to replicate that setup here when we want to pass it directly to a
|
||||
# command see <http://www.cmake.org/Bug/print_bug_page.php?bug_id=10632>
|
||||
foreach(item IN ITEMS ${QT_QTNETWORK_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR}
|
||||
${QT_INCLUDE_DIR}
|
||||
)
|
||||
if("${item}" MATCHES ".framework$")
|
||||
get_filename_component(frmwrk_path ${item} PATH)
|
||||
get_filename_component(frmwrk_name ${item} NAME_WE)
|
||||
# mkoctfile doesn't support arbitrary compiler command, so we must wrap in
|
||||
# -Wl, to pass to the linker
|
||||
list(APPEND QT_FRAMEWORKS "-Wl,-F${frmwrk_path}")
|
||||
list(APPEND QT_FRAMEWORKS "-Wl,-framework,${frmwrk_name}")
|
||||
else()
|
||||
list(APPEND QT_INCLUDES "-I${item}")
|
||||
endif()
|
||||
endforeach(item)
|
||||
if(QT_INCLUDES)
|
||||
list(REMOVE_DUPLICATES QT_INCLUDES)
|
||||
endif()
|
||||
if(QT_FRAMEWORKS)
|
||||
list(REMOVE_DUPLICATES QT_FRAMEWORKS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Compiling Octave plugins using : ${OCTAVE_MKOCTFILE}")
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
option(RESINSIGHT_OCTAVE_PLUGIN_QT
|
||||
"Compile Octave plugin using Qt located insided Octave root folder" ON
|
||||
)
|
||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
||||
if(RESINSIGHT_OCTAVE_PLUGIN_QT)
|
||||
|
||||
message(
|
||||
STATUS
|
||||
"Compiling Octave plugins using custom Qt located at ${OCTAVE_ROOT_DIR}"
|
||||
)
|
||||
|
||||
if(EXISTS ${OCTAVE_ROOT_DIR}/qt5)
|
||||
set(OCTAVE_QT_INCLUDE_DIR ${OCTAVE_ROOT_DIR}/qt5/include)
|
||||
set(OCTAVE_QT_QTCORE_INCLUDE_DIR ${OCTAVE_ROOT_DIR}/qt5/include/QtCore)
|
||||
set(OCTAVE_QT_QTNETWORK_INCLUDE_DIR
|
||||
${OCTAVE_ROOT_DIR}/qt5/include/QtNetwork
|
||||
)
|
||||
set(OCTAVE_QT_LIBRARY_DIR ${OCTAVE_ROOT_DIR}/qt5/lib)
|
||||
set(OCTAVE_QT_QTCORE_LIB Qt5Core)
|
||||
set(OCTAVE_QT_QTNETWORK_LIB Qt5Network)
|
||||
else()
|
||||
set(OCTAVE_QT_INCLUDE_DIR ${OCTAVE_ROOT_DIR}/include)
|
||||
set(OCTAVE_QT_QTCORE_INCLUDE_DIR ${OCTAVE_ROOT_DIR}/include/QtCore)
|
||||
set(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${OCTAVE_ROOT_DIR}/include/QtNetwork)
|
||||
set(OCTAVE_QT_LIBRARY_DIR ${OCTAVE_ROOT_DIR}/lib)
|
||||
set(OCTAVE_QT_QTCORE_LIB QtCore4)
|
||||
set(OCTAVE_QT_QTNETWORK_LIB QtNetwork4)
|
||||
endif(EXISTS ${OCTAVE_ROOT_DIR}/qt5)
|
||||
|
||||
else()
|
||||
|
||||
if(Qt5Core_FOUND)
|
||||
message(STATUS "Compiling Octave plugins using system Qt5")
|
||||
|
||||
set(OCTAVE_QT_QTCORE_INCLUDE_DIR ${Qt5Core_INCLUDE_DIRS})
|
||||
set(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${Qt5Network_INCLUDE_DIRS})
|
||||
set(OCTAVE_QT_LIBRARY_DIR ${QT_LIBRARY_DIR})
|
||||
set(OCTAVE_QT_QTCORE_LIB Qt5Core)
|
||||
set(OCTAVE_QT_QTNETWORK_LIB Qt5Network)
|
||||
|
||||
endif(Qt5Core_FOUND)
|
||||
|
||||
endif(RESINSIGHT_OCTAVE_PLUGIN_QT)
|
||||
|
||||
list(APPEND MKOCTFILE_INCLUDE_DIRS ${OCTAVE_QT_INCLUDE_DIR})
|
||||
list(APPEND MKOCTFILE_INCLUDE_DIRS ${OCTAVE_QT_QTCORE_INCLUDE_DIR})
|
||||
list(APPEND MKOCTFILE_INCLUDE_DIRS ${OCTAVE_QT_QTNETWORK_INCLUDE_DIR})
|
||||
|
||||
# Add socket interface source code folder
|
||||
list(APPEND MKOCTFILE_INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ApplicationLibCode/SocketInterface
|
||||
)
|
||||
|
||||
list(REMOVE_DUPLICATES MKOCTFILE_INCLUDE_DIRS)
|
||||
foreach(item ${MKOCTFILE_INCLUDE_DIRS})
|
||||
list(APPEND MKOCTFILE_INCLUDE_TEMP -I${item})
|
||||
endforeach(item)
|
||||
|
||||
string(REPLACE ";" " " MKOCTFILE_INCLUDE_TEMP "${MKOCTFILE_INCLUDE_TEMP}")
|
||||
|
||||
# Use special command to avoid double quoting in add_custom_command()
|
||||
separate_arguments(
|
||||
MKOCTFILE_INCLUDE_COMMAND_STRING WINDOWS_COMMAND "${MKOCTFILE_INCLUDE_TEMP}"
|
||||
)
|
||||
|
||||
# Clear the list of binary oct files to be produced
|
||||
set(OCTAVE_BINARY_OCT_FILES)
|
||||
|
||||
if(OCTAVE_MKOCTFILE)
|
||||
foreach(srcFileName IN LISTS CPP_SOURCES)
|
||||
|
||||
if(NOT IS_ABSOLUTE "${srcFileName}")
|
||||
set(srcFileName "${CMAKE_CURRENT_SOURCE_DIR}/${srcFileName}")
|
||||
endif()
|
||||
|
||||
get_filename_component(baseFilename "${srcFileName}" NAME_WE)
|
||||
|
||||
set(octFileName "${CMAKE_CURRENT_BINARY_DIR}/${baseFilename}.oct")
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
add_custom_command(
|
||||
OUTPUT "${octFileName}"
|
||||
COMMAND set "OCTAVE_HOME=${OCTAVE_ROOT_DIR}"
|
||||
COMMAND set "PATH=%OCTAVE_HOME%\\bin;%PATH%"
|
||||
COMMAND
|
||||
${OCTAVE_MKOCTFILE} ${MKOCTFILE_INCLUDE_COMMAND_STRING}
|
||||
${RPATH_COMMAND} -L${OCTAVE_QT_LIBRARY_DIR} -l${OCTAVE_QT_QTCORE_LIB}
|
||||
-l${OCTAVE_QT_QTNETWORK_LIB} -o "${octFileName}" "${srcFileName}"
|
||||
DEPENDS "${srcFileName}"
|
||||
COMMENT "===> Generating ${octFileName}"
|
||||
)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
add_custom_command(
|
||||
OUTPUT "${octFileName}"
|
||||
COMMAND
|
||||
${OCTAVE_MKOCTFILE} ${QT_INCLUDES} ${QT_FRAMEWORKS}
|
||||
-I${ResInsight_SOURCE_DIR}/ApplicationLibCode/SocketInterface
|
||||
${RPATH_COMMAND} -L${QT_LIBRARY_DIR} -Wl,-framework,QtCore
|
||||
-Wl,-framework,QtNetwork -o "${octFileName}" "${srcFileName}"
|
||||
DEPENDS "${srcFileName}"
|
||||
COMMENT "===> Generating ${octFileName}"
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT "${octFileName}"
|
||||
COMMAND
|
||||
OCTAVE_HOME=${OCTAVE_ROOT_DIR} ${OCTAVE_MKOCTFILE}
|
||||
${MKOCTFILE_INCLUDE_COMMAND_STRING} ${RPATH_COMMAND}
|
||||
-L${OCTAVE_QT_LIBRARY_DIR} -l${OCTAVE_QT_QTCORE_LIB}
|
||||
-l${OCTAVE_QT_QTNETWORK_LIB} -o "${octFileName}" "${srcFileName}"
|
||||
DEPENDS "${srcFileName}"
|
||||
COMMENT "===> Generating ${octFileName}"
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND OCTAVE_BINARY_OCT_FILES "${octFileName}")
|
||||
|
||||
endforeach()
|
||||
|
||||
# Create depencedy string represeting the full path to all generated oct-files
|
||||
foreach(item ${CPP_SOURCES})
|
||||
string(REPLACE ".cpp" ".oct" item ${item})
|
||||
list(APPEND DEPENDENCY_STRING ${CMAKE_CURRENT_BINARY_DIR}/${item})
|
||||
endforeach(item)
|
||||
|
||||
# message("DEPENDENCY_STRING : ${DEPENDENCY_STRING}")
|
||||
|
||||
add_custom_target(
|
||||
octave_plugins ALL
|
||||
DEPENDS ${DEPENDENCY_STRING}
|
||||
SOURCES ${CPP_SOURCES} riSettings.h
|
||||
)
|
||||
|
||||
# Copy Octave generated *.oct files to application folder, will make it
|
||||
# possible to use Octave functions directly from the location of the
|
||||
# ResInsight binaries
|
||||
if(TARGET ResInsight)
|
||||
message(
|
||||
STATUS
|
||||
"Target ResInsight exists, add copy of Octave plugins to ApplicationExeCode folder"
|
||||
)
|
||||
|
||||
# Make ResInsight dependant on Octave, makes it easiser to debug Octave
|
||||
# functionality by compiling ResInsight
|
||||
add_dependencies(ResInsight octave_plugins)
|
||||
|
||||
foreach(oct_bin ${OCTAVE_BINARY_OCT_FILES})
|
||||
get_filename_component(Filename "${oct_bin}" NAME)
|
||||
|
||||
if(MSVC)
|
||||
add_custom_command(
|
||||
TARGET octave_plugins
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different "${oct_bin}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../../ApplicationExeCode/$<CONFIGURATION>/${Filename}"
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET octave_plugins
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different "${oct_bin}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../../ApplicationExeCode/${Filename}"
|
||||
)
|
||||
endif(MSVC)
|
||||
endforeach(oct_bin)
|
||||
|
||||
if(RESINSIGHT_PRIVATE_INSTALL)
|
||||
install(FILES ${OCTAVE_BINARY_OCT_FILES}
|
||||
DESTINATION ${RESINSIGHT_INSTALL_FOLDER}
|
||||
)
|
||||
else(RESINSIGHT_PRIVATE_INSTALL)
|
||||
# probe for site location of .oct files
|
||||
if(NOT OCTAVE_SITE_OCT_DIR)
|
||||
find_program(
|
||||
OCTAVE_CONFIG_COMMAND octave-config
|
||||
DOC "Path to Octave component and library information retrieval"
|
||||
)
|
||||
exec_program(
|
||||
${OCTAVE_CONFIG_COMMAND} ARGS
|
||||
--oct-site-dir
|
||||
OUTPUT_VARIABLE OCTAVE_SITE_OCT_DIR
|
||||
)
|
||||
set(OCTAVE_SITE_OCT_DIR
|
||||
"${OCTAVE_SITE_OCT_DIR}"
|
||||
CACHE LOCATION "Octave plugin directory"
|
||||
)
|
||||
endif(NOT OCTAVE_SITE_OCT_DIR)
|
||||
|
||||
install(FILES ${OCTAVE_BINARY_OCT_FILES}
|
||||
DESTINATION ${OCTAVE_SITE_OCT_DIR}
|
||||
)
|
||||
endif(RESINSIGHT_PRIVATE_INSTALL)
|
||||
else()
|
||||
install(FILES ${OCTAVE_BINARY_OCT_FILES} DESTINATION .)
|
||||
endif(TARGET ResInsight)
|
||||
|
||||
endif(OCTAVE_MKOCTFILE)
|
||||
17
Octave/OctavePlugin/MinGWBuildConfigurationForOctave.txt
Normal file
17
Octave/OctavePlugin/MinGWBuildConfigurationForOctave.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Build configuration MinGW
|
||||
==================================
|
||||
|
||||
http://wiki.octave.org/Windows_Installer
|
||||
|
||||
To be able to build with 64-bit indexing, run the following
|
||||
|
||||
./configure --enable-64
|
||||
|
||||
|
||||
|
||||
// To get changes from server
|
||||
hg pull
|
||||
hg update
|
||||
|
||||
http://hgbook.red-bean.com/read/a-tour-of-mercurial-the-basics.html
|
||||
|
||||
73
Octave/OctavePlugin/NNCOctaveInterfaceSpecification.txt
Normal file
73
Octave/OctavePlugin/NNCOctaveInterfaceSpecification.txt
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
#### Matrix[numSelectedCells][5] riGetSelectedCells([CaseId])
|
||||
|
||||
This function returns a two dimensional matrix containing the cell info for each selected cell in the case with `CaseId`.
|
||||
The columns contain the following information:
|
||||
|
||||
[CaseId, GridIdx, I, J, K]
|
||||
CaseId # The ID of the case the cell resides in.
|
||||
GridIdx # The index of the grid the cell resides in.
|
||||
# Main grid has index 0
|
||||
I, J, K # 1-based index of the cell in the grid.
|
||||
|
||||
|
||||
If the CaseId is not defined, ResInsight's Current Case is used.
|
||||
|
||||
|
||||
#### Matrix[numSelectedCells][numTimestepsRequested] riGetGridPropertyForSelectedCells([CaseId], PropertyName, [RequestedTimeSteps], [PorosityModel = "Matrix"|"Fracture"] )
|
||||
|
||||
This function returns a two dimensional matrix: [numSelectedCells][numTimestepsRequested] containing the requested property data from the case with CaseId.
|
||||
|
||||
If the CaseId is not defined, ResInsight's Current Case is used.
|
||||
The RequestedTimeSteps must contain a list of 1-based indices to the requested time steps. If not defined, all the time steps are returned.
|
||||
|
||||
|
||||
#### Vector[PropertyInfo] riGetNNCPropertyNames([CaseId])
|
||||
|
||||
This function returns the name and type of all NNC properties in the case as a vector of structures.
|
||||
|
||||
The structure is defined as:
|
||||
|
||||
PropertyInfo {
|
||||
PropName = string # Name of the property as received from
|
||||
# the analysis tool
|
||||
PropType = string # The type of the property: "StaticNative",
|
||||
# "DynamicNative", "Generated"
|
||||
}
|
||||
|
||||
If the CaseId is not defined, ResInsight's Current Case is used.
|
||||
|
||||
|
||||
#### Matrix[numNNCConnections][2] riGetNNCConnections([CaseId])
|
||||
|
||||
This function returns a two dimensional matrix containing grid and IJK information about each NNC connection.
|
||||
Each row contains a from and to cell for the connection.
|
||||
The cells are specified in a structure defined as:
|
||||
|
||||
CellInfo = {
|
||||
GridIndex = int # Index of the grid the cell resides in.
|
||||
# Main grid has index 0.
|
||||
I, J, K = int # 1-based index address of the cell in the grid.
|
||||
}
|
||||
|
||||
#### Matrix[numConnections][numTimestepsRequested] riGetDynamicNNCValues([CaseId], PropertyName, [RequestedTimeSteps])
|
||||
|
||||
This function returns a two dimensional matrix: [Num Connections][Num Time Steps Requested] containing the value of the requested property from the case with CaseId. The order of connections is the same as the order from `riGetNNCConnectio
|
||||
|
||||
If the CaseId is not defined, ResInsight's Current Case is used.
|
||||
The RequestedTimeSteps must contain a list of indices to the requested time steps. If not defined, all the timesteps are returned.
|
||||
|
||||
#### Vector[numConnections] riGetStaticNNCValues([CaseId], PropertyName)
|
||||
|
||||
This function returns a vector of values for the requested static property for each NNC connection. The order of connections is the same as the order from `riGetNNCConnections`.
|
||||
|
||||
If the CaseId is not defined, ResInsight's Current Case is used.
|
||||
|
||||
#### riSetNNCProperty(Matrix[numNNCConnections][numTimeSteps], [CaseId], PropertyName, [TimeStepIndices])
|
||||
|
||||
Interprets the supplied matrix as a property set defined for the NNC connections in the case, and puts the data into ResInsight as a "Generated" property with the name "PropertyName".
|
||||
The "TimeStepIndices" argument is used to "label" all the steps present in the supplied data matrix and must thus be complete.
|
||||
The time step data will then be put into ResInsight at the time steps requested.
|
||||
|
||||
If the CaseId is not defined, ResInsight's Current Case is used.
|
||||
|
||||
13
Octave/OctavePlugin/OctaveScripts/InputPropTest.m
Normal file
13
Octave/OctavePlugin/OctaveScripts/InputPropTest.m
Normal file
@@ -0,0 +1,13 @@
|
||||
addpath("/home/builder/Projects/ResInsightBuildDir/OctavePlugin");
|
||||
|
||||
tic();
|
||||
PORO = riGetActiveCellProperty("PORO");
|
||||
PERMX = riGetActiveCellProperty("PERMX");
|
||||
IJK = riGetMainGridDimensions();
|
||||
|
||||
GENERATED = PORO .* PERMX;
|
||||
|
||||
riSetActiveCellProperty(GENERATED, "PORO*PERMX");
|
||||
|
||||
elapsed_time = toc();
|
||||
disp("Elapsed time: "), disp(elapsed_time)
|
||||
14
Octave/OctavePlugin/OctaveScripts/LGRSOIL.m
Normal file
14
Octave/OctavePlugin/OctaveScripts/LGRSOIL.m
Normal file
@@ -0,0 +1,14 @@
|
||||
# Keep the values in the first LGR only
|
||||
|
||||
CInfo = riGetActiveCellInfo();
|
||||
SOIL = riGetActiveCellProperty("SOIL");
|
||||
|
||||
Mask = (CInfo(:,1) != 1);
|
||||
|
||||
LGRSOIL = SOIL;
|
||||
i = 0;
|
||||
for i = (1:columns(LGRSOIL))
|
||||
LGRSOIL(Mask,i) = nan;
|
||||
endfor
|
||||
|
||||
riSetActiveCellProperty(LGRSOIL, "LGRSOIL");
|
||||
10
Octave/OctavePlugin/OctaveScripts/SatNum.m
Normal file
10
Octave/OctavePlugin/OctaveScripts/SatNum.m
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
SATNUM = riGetActiveCellProperty("SATNUM");
|
||||
SOIL = riGetActiveCellProperty( "SOIL");
|
||||
|
||||
# Set all SOIL data to 0.0 for all cells with SATNUM different
|
||||
# from 7 for timestep 1
|
||||
|
||||
GENERATED = (SATNUM == 7) .* SOIL(:, 1);
|
||||
|
||||
riSetActiveCellProperty(GENERATED, "SOIL_IN_SATNUM_Eq_7");
|
||||
12
Octave/OctavePlugin/OctaveScripts/SoilAverage.m
Normal file
12
Octave/OctavePlugin/OctaveScripts/SoilAverage.m
Normal file
@@ -0,0 +1,12 @@
|
||||
addpath("C:/cmake_build/ResInsightQt5/OctavePlugin");
|
||||
|
||||
tic();
|
||||
|
||||
timeSteps = riGetTimeStepDates(0)
|
||||
disp("Number of time steps: "), disp(size(timeSteps))
|
||||
for i = 1:size(timeSteps)
|
||||
SOIL = riGetActiveCellProperty(0, "SOIL", i);
|
||||
avg = mean(SOIL)
|
||||
endfor
|
||||
elapsed_time = toc();
|
||||
disp("Elapsed time: "), disp(elapsed_time)
|
||||
17
Octave/OctavePlugin/OctaveScripts/SoilTimeDiff.m
Normal file
17
Octave/OctavePlugin/OctaveScripts/SoilTimeDiff.m
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
SOIL = riGetActiveCellProperty("SOIL");
|
||||
|
||||
SOILDIFF = SOIL;
|
||||
|
||||
# Calculate change of oil saturation from timestep to timestep
|
||||
i = 0;
|
||||
for timestep = SOIL
|
||||
if (i > 0)
|
||||
SOILDIFF(:,i) = timestep - SOIL(:,i);
|
||||
endif
|
||||
i++;
|
||||
endfor
|
||||
SOILDIFF(:,i) = 0;
|
||||
|
||||
riSetActiveCellProperty(SOILDIFF, "SOILDIFF");
|
||||
|
||||
24
Octave/OctavePlugin/OctaveScripts/kaverage.m
Normal file
24
Octave/OctavePlugin/OctaveScripts/kaverage.m
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
CInfo = riGetActiveCellInfo();
|
||||
SOIL = riGetActiveCellProperty("SOIL");
|
||||
|
||||
SOIL_KAverage = SOIL;
|
||||
SOIL_KAverage(:) = nan;
|
||||
|
||||
mini = min(CInfo(:,2))
|
||||
maxi = max(CInfo(:,2))
|
||||
|
||||
minj = min(CInfo(:,3))
|
||||
maxj = max(CInfo(:,3))
|
||||
|
||||
for i = mini:maxi
|
||||
for j = minj:maxj
|
||||
Mask = (CInfo(:,1) == 0) & (CInfo(:,2) == i) & (CInfo(:,3) == j) ;
|
||||
|
||||
for ts = (1:columns(SOIL))
|
||||
SOIL_KAverage(Mask, ts) = mean(SOIL(Mask, ts));
|
||||
endfor
|
||||
endfor
|
||||
endfor
|
||||
|
||||
riSetActiveCellProperty(SOIL_KAverage, "SOIL_KAverage");
|
||||
13
Octave/OctavePlugin/OctaveScripts/kslice.m
Normal file
13
Octave/OctavePlugin/OctaveScripts/kslice.m
Normal file
@@ -0,0 +1,13 @@
|
||||
# Set all values to "Undefined" exept k-layers from 17 to 20
|
||||
|
||||
CInfo = riGetActiveCellInfo();
|
||||
SOIL = riGetActiveCellProperty("SOIL");
|
||||
|
||||
Mask = (CInfo(:,4) < 17) | (CInfo(:,4) > 20)
|
||||
LGRSOIL = SOIL;
|
||||
i = 0;
|
||||
for i = (1:columns(LGRSOIL))
|
||||
LGRSOIL(Mask,i) = nan;
|
||||
endfor
|
||||
|
||||
riSetActiveCellProperty(LGRSOIL, "KSlice");
|
||||
147
Octave/OctavePlugin/ResInsightOctaveInterfaceSpecification.txt
Normal file
147
Octave/OctavePlugin/ResInsightOctaveInterfaceSpecification.txt
Normal file
@@ -0,0 +1,147 @@
|
||||
Considerations
|
||||
==================================
|
||||
|
||||
This function interface towards ResInsight is currently a Draft,
|
||||
and not addressing some issues. The known issues are :
|
||||
|
||||
1. How do we address Cases in the future when we have Case Groups ?
|
||||
Where do we write/store the generated data ?
|
||||
2. Users wants to run octave operations on several cases/groups.
|
||||
There are two ways (at least) of doing that. Either from ResInsight:
|
||||
1 Command to call a specified Octave Script for each selected Case
|
||||
2 Creating Scripts that loops over all selections in ResInsight
|
||||
Option 2 is needed if users wants to do cross-case operations
|
||||
Option 1 seems intuitive for one case operations
|
||||
How does these two relate ?
|
||||
|
||||
3. Do we need functions to retreive the selected/active cases/groups ?
|
||||
4. Do we need functions to retreive info on what Parent cells an LGR occupies ?
|
||||
|
||||
|
||||
Project Information
|
||||
==================================
|
||||
|
||||
Vector[Casenames] riGetCaseNames()
|
||||
|
||||
Returns a vector of all the case names in the current ResInsight project
|
||||
Use this to determine the number of cases as well
|
||||
|
||||
This probably needs some additions related to Case Groups
|
||||
|
||||
|
||||
Retreiving Grid Metadata
|
||||
==================================
|
||||
|
||||
Matrix[ActiveCells][8] riGetActiveCellInfo( [CaseName/CaseIndex])
|
||||
|
||||
Returns a two dimensional matrix: [ActiveCells][8]
|
||||
|
||||
Containing grid and ijk information about the cells from the Eclipse Case defined.
|
||||
The columns contain the following information:
|
||||
1: GridIndex: The index of the grid the cell resides in. (Main grid has index 0)
|
||||
2, 3, 4: I, J, K: 1-based index address of the cell in the grid.
|
||||
5: ParentGridIndex. The index to the grid that this cell's grid is residing in.
|
||||
6, 7, 8: PI, PJ, PK address of the parent grid cell that this cell is a part of.
|
||||
If the Eclipse Case is not defined, the active View in ResInsight is used.
|
||||
|
||||
|
||||
|
||||
Matrix[g0I, g0J, g0K; ... ; gnI, gnJ, gnK] riGetGridDimensions ( [CaseName/CaseIndex])
|
||||
|
||||
Returns a matrix: [NuberOfGrids][3]
|
||||
containing the I, J, K dimensions of the main grid and all the LGR's
|
||||
|
||||
# Unnecessary ? # Vector(3)[ICount, JCount, KCount] riGetMainGridDimensions( [CaseName/CaseIndex])
|
||||
# Unnecessary ? #
|
||||
# Unnecessary ? # Returns a vector of size 3: [ICount, JCount, KCount]
|
||||
# Unnecessary ? # Containing the dimensions of the main grid in the requested case.
|
||||
# Unnecessary ? # If the Eclipse Case is not defined, the active View in ResInsight is used."
|
||||
# Unnecessary ? #
|
||||
# Unnecessary ? # NumberOfGrids riGetNumLGRs([Casename/CaseIndex])
|
||||
# Unnecessary ? #
|
||||
# Unnecessary ? # Returns an integer telling the number of LGRS in this case
|
||||
|
||||
|
||||
|
||||
Vector[Dates] riGetTimestepDates([Casename/CaseIndex])
|
||||
|
||||
Returns a vector of all the timesteps in a case as dates YYYY.MM.DD
|
||||
|
||||
|
||||
Vector[Days] riGetTimestepDays([Casename/CaseIndex])
|
||||
|
||||
Returns a vector of all the timesteps in a case as days from start
|
||||
|
||||
|
||||
Retreiving property data
|
||||
==================================
|
||||
|
||||
Matrix[ActiveCells][Timesteps] riGetActiveCellProperty( [CaseName/CaseIndex], PropertyName )
|
||||
|
||||
Returns a two dimentional matrix: [ActiveCells][Timesteps]
|
||||
|
||||
Containing the requested property data from the Eclipse Case defined.
|
||||
If the Eclipse Case is not defined, the active View in ResInsight is used.
|
||||
|
||||
|
||||
Matrix[numI][numJ][numK][timeSteps] riGetGridProperty( [Casename/CaseIndex], GridIndex , PropertyName )
|
||||
Matrix[numI][numJ][numK] riGetGridProperty( [Casename/CaseIndex], GridIndex , PropertyName, TimeStep )
|
||||
|
||||
Returns a 4D or 3D matrix of the requested property data for all the gridcells in the requested grid.
|
||||
Grids are indexed from 0 - main grid to Max num LGR's
|
||||
|
||||
Writing Back to ResInsight
|
||||
==================================
|
||||
|
||||
riSetActiveCellProperty( Matrix(nActiveCells, nTimesteps), [CaseName/CaseIndex], PropertyName )
|
||||
|
||||
Interprets the supplied matrix as an eclipse property set, and puts the data into
|
||||
ResInsight as a "Generated" property with the name "PropertyName". The property
|
||||
is added to the active case if no case specification is given, or to the Eclipse Case
|
||||
named "CaseName" or to the case number "CaseIndex". "
|
||||
|
||||
|
||||
riSetGridProperty( Matrix[numI][numJ][numK][timeSteps] , [CaseName/CaseIndex], GridIndex, PropertyName )
|
||||
riSetGridProperty( Matrix[numI][numJ][numK], [CaseName/CaseIndex], GridIndex, PropertyName , TimeStep)
|
||||
|
||||
Interprets the supplied matrix as an eclipse property set defined for all cells in one of the grids in a case,
|
||||
and puts the data into ResInsight as a "Generated" property with the name "PropertyName". The property
|
||||
is added to the active case if no case specification is given, or to the Eclipse Case
|
||||
named "CaseName" or to the case number "CaseIndex". "
|
||||
|
||||
Cell geometry functions:
|
||||
=================================
|
||||
|
||||
Matrix[numI*Vector(3)][numJ*Vec(3)] [numK*Vec(3)] riGetCellCenters( [Casename/CaseIndex], GridIndex )
|
||||
|
||||
Returns the UTM coordinates (X, Y, Z) for centerpoint of all cells
|
||||
|
||||
|
||||
Matrix[numI*8*Vector(3)][numJ*8*Vec(3)] [numK*8*Vec(3)] riGetCellCorners( [Casename/CaseIndex], GridIndex )
|
||||
|
||||
Returns the UTM coordinates of the each cells 8 corners
|
||||
|
||||
|
||||
Well data functions
|
||||
=================================
|
||||
Vector[WellNames] riGetWellNames([Casename/CaseIndex])
|
||||
|
||||
Returns the names of all the wells in the case
|
||||
|
||||
Vector[ I, J, K, GridNr] riGetWellCells([Casename/CaseIndex], WellName/WellIndex, TimeStep, Producing/Injecting/Any)
|
||||
|
||||
Returns the cells that has the requested production status for the given well and timestep
|
||||
|
||||
|
||||
Comments to remember/consider
|
||||
=================================
|
||||
<EFBFBD>Execute for all cases within group<75> in script-tree
|
||||
|
||||
Well trajectories (alternative trajectory like Planned / Drilled /Real Time/ Project ahead?)
|
||||
riGetTrajectories(well, case) ? MD, Inc, Az, Norht(X), East(Y), TVD(Z),DLS,BUR,TR,prop/log/connections?
|
||||
|
||||
Operator to restrict operation to be carried out inside a given polygon object
|
||||
riInside(polygon)
|
||||
|
||||
Set Octave function Case ID as a function parameter (enable for loops)
|
||||
Write grid data to file on .grdecl format (and read & append?)
|
||||
150
Octave/OctavePlugin/riGetActiveCellCenters.cpp
Normal file
150
Octave/OctavePlugin/riGetActiveCellCenters.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#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 getActiveCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetActiveCellCenters %1 %2").arg(caseId).arg(porosityModel);
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read timestep count and blocksize
|
||||
|
||||
quint64 activeCellCount;
|
||||
quint64 byteCount;
|
||||
|
||||
socketStream >> activeCellCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
if (!(byteCount && activeCellCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
dim_vector dv;
|
||||
dv.resize(2);
|
||||
dv(0) = activeCellCount;
|
||||
dv(1) = 3;
|
||||
|
||||
cellCenterValues.resize(dv);
|
||||
|
||||
double* internalMatrixData = cellCenterValues.fortran_vec();
|
||||
QStringList errorMessages;
|
||||
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetActiveCellCenters, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetActiveCellCenters([CaseId], [PorosityModel = <20>Matrix<69>|<7C>Fracture<72>] )\n"
|
||||
"\n"
|
||||
"This function returns the UTM coordinates (X, Y, Z) of the center point of all the cells in the grid.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
|
||||
if (nargout < 1)
|
||||
{
|
||||
error("riGetActiveCellCenters: Missing output argument.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
int nargin = args.length ();
|
||||
if (nargin > 2)
|
||||
{
|
||||
error("riGetActiveCellCenters: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
qint32 caseId = -1;
|
||||
std::string porosityModel = "Matrix";
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
caseId = args(0).uint_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
porosityModel = args(0).string_value();
|
||||
}
|
||||
}
|
||||
else if (nargin == 2)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
caseId = args(0).uint_value();
|
||||
porosityModel = args(1).string_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
caseId = args(1).uint_value();
|
||||
porosityModel = args(0).string_value();
|
||||
}
|
||||
}
|
||||
|
||||
if (porosityModel != "Matrix" && porosityModel != "Fracture")
|
||||
{
|
||||
error("riGetActiveCellProperty: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
NDArray cellCenterValues;
|
||||
getActiveCellCenters(cellCenterValues, "127.0.0.1", riOctavePlugin::portNumber(), caseId, porosityModel.c_str());
|
||||
|
||||
return octave_value(cellCenterValues);
|
||||
}
|
||||
|
||||
150
Octave/OctavePlugin/riGetActiveCellCorners.cpp
Normal file
150
Octave/OctavePlugin/riGetActiveCellCorners.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#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 getActiveCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const QString& porosityModel)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetActiveCellCorners %1 %2").arg(caseId).arg(porosityModel);
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read timestep count and blocksize
|
||||
|
||||
quint64 activeCellCount;
|
||||
quint64 byteCount;
|
||||
|
||||
socketStream >> activeCellCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
if (!(byteCount && activeCellCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
dim_vector dv;
|
||||
dv.resize(3);
|
||||
dv(0) = activeCellCount;
|
||||
dv(1) = 8;
|
||||
dv(2) = 3;
|
||||
cellCornerValues.resize(dv);
|
||||
|
||||
double* internalMatrixData = cellCornerValues.fortran_vec();
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetActiveCellCorners, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetActiveCellCorners([CaseId], [PorosityModel = <20>Matrix<69>|<7C>Fracture<72>] )\n"
|
||||
"\n"
|
||||
"This function returns the UTM coordinates (X, Y, Z) of the 8 corners of each of the active cells.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
|
||||
if (nargout < 1)
|
||||
{
|
||||
error("riGetActiveCellCorners: Missing output argument.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
int nargin = args.length ();
|
||||
|
||||
if (nargin > 2)
|
||||
{
|
||||
error("riGetActiveCellCorners: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
qint32 caseId = -1;
|
||||
std::string porosityModel = "Matrix";
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
caseId = args(0).uint_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
porosityModel = args(0).string_value();
|
||||
}
|
||||
}
|
||||
else if (nargin == 2)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
caseId = args(0).uint_value();
|
||||
porosityModel = args(1).string_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
caseId = args(1).uint_value();
|
||||
porosityModel = args(0).string_value();
|
||||
}
|
||||
}
|
||||
|
||||
if (porosityModel != "Matrix" && porosityModel != "Fracture")
|
||||
{
|
||||
error("riGetActiveCellProperty: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
NDArray cellCornerValues;
|
||||
getActiveCellCorners(cellCornerValues, "127.0.0.1", riOctavePlugin::portNumber(), caseId, porosityModel.c_str());
|
||||
|
||||
return octave_value(cellCornerValues);
|
||||
}
|
||||
|
||||
168
Octave/OctavePlugin/riGetActiveCellInfo.cpp
Normal file
168
Octave/OctavePlugin/riGetActiveCellInfo.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#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 getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, quint16 port, const qint64& caseId, const QString& porosityModel)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetActiveCellInfo %1 %2").arg(caseId).arg(porosityModel);
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read timestep count and blocksize
|
||||
|
||||
quint64 columnCount;
|
||||
quint64 byteCountForOneTimestep;
|
||||
size_t activeCellCount;
|
||||
|
||||
socketStream >> columnCount;
|
||||
socketStream >> byteCountForOneTimestep;
|
||||
|
||||
activeCellCount = byteCountForOneTimestep / sizeof(qint32);
|
||||
|
||||
dim_vector dv (2, 1);
|
||||
dv(0) = activeCellCount;
|
||||
dv(1) = columnCount;
|
||||
activeCellInfo.resize(dv);
|
||||
|
||||
if (!(byteCountForOneTimestep && columnCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
#if OCTAVE_MAJOR_VERSION > 6
|
||||
auto internalMatrixData = (qint32*)activeCellInfo.fortran_vec();
|
||||
#else
|
||||
qint32* internalMatrixData = (qint32*)activeCellInfo.fortran_vec()->mex_get_data();
|
||||
#endif
|
||||
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
QString tmp = QString("riGetActiveCellInfo : Read active cell info");
|
||||
if (caseId < 0)
|
||||
{
|
||||
tmp += QString(" from current case.");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp += QString(" from caseID: %1.").arg(caseId);
|
||||
}
|
||||
|
||||
octave_stdout << tmp.toStdString() << " Active cells: " << activeCellCount << ", Columns: " << columnCount << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetActiveCellInfo, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetActiveCellInfo([CaseId], [PorosityModel = <20>Matrix<69>|<7C>Fracture<72>] )\n"
|
||||
"\n"
|
||||
"This function returns a two dimensional matrix containing grid and IJK information\n"
|
||||
"for each of the active cells in the requested case.\n"
|
||||
"The columns contain the following information:\n"
|
||||
"[GridIdx, I, J, K, ParentGridIdx, PI, PJ, PK, CoarseBoxIdx]\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"
|
||||
" ParentGridIdx : The index to the grid that this cell's grid is residing in.\n"
|
||||
" PI, PJ, PK : 1-based address of the parent grid cell that this cell is a part of.\n"
|
||||
" CoarseBoxIdx : Coarsening box index, -1 if none.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used. If PorosityModel is not defined, <20>Matrix<69> is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 2)
|
||||
{
|
||||
error("riGetActiveCellInfo: Too many arguments. CaseId and PorosityModel are optional input arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetActiveCellInfo: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
int32NDArray propertyFrames;
|
||||
|
||||
qint64 caseId = -1;
|
||||
QString porosityModel = "Matrix";
|
||||
|
||||
if (nargin > 0)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
else
|
||||
{
|
||||
porosityModel = args(0).char_matrix_value().row_as_string(0).c_str();
|
||||
}
|
||||
}
|
||||
|
||||
if (nargin > 1)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(1)))
|
||||
{
|
||||
unsigned int argCaseId = args(1).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
else
|
||||
{
|
||||
porosityModel = args(1).char_matrix_value().row_as_string(0).c_str();
|
||||
}
|
||||
}
|
||||
|
||||
getActiveCellInfo(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), caseId, porosityModel);
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
199
Octave/OctavePlugin/riGetActiveCellProperty.cpp
Normal file
199
Octave/OctavePlugin/riGetActiveCellProperty.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
#include <QtNetwork>
|
||||
#include <QStringList>
|
||||
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
|
||||
|
||||
void getActiveCellProperty(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: %s",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 += "GetActiveCellProperty " + QString::number(caseId) + " " + propertyName + " " + porosityModel;
|
||||
|
||||
for (int i = 0; i < requestedTimeSteps.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() -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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read timestep count and blocksize
|
||||
|
||||
quint64 timestepCount;
|
||||
quint64 byteCount;
|
||||
size_t activeCellCount;
|
||||
|
||||
socketStream >> timestepCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
activeCellCount = byteCount / sizeof(double);
|
||||
propertyFrames.resize(activeCellCount, 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("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QString tmp = QString("riGetActiveCellProperty : 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() << " Active cells : " << activeCellCount << ", Timesteps : " << timestepCount << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetActiveCellProperty, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"Matrix[numActiveCells][numTimestepsRequested] riGetActiveCellProperty([CaseId], PropertyName, [RequestedTimeSteps], [PorosityModel = \"Matrix\"|\"Fracture\"] )"
|
||||
"\n"
|
||||
"This function returns a two dimensional matrix: [ActiveCells][Num TimestepsRequested] containing the requested property data from the case with CaseId."
|
||||
"If the case contains coarse-cells, the results are expanded onto the active cells."
|
||||
"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 timesteps. If not defined, all the timesteps are returned."
|
||||
)
|
||||
{
|
||||
if (nargout < 1)
|
||||
{
|
||||
error("riGetActiveCellProperty: Missing output argument.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
int nargin = args.length ();
|
||||
if (nargin < 1)
|
||||
{
|
||||
error("riGetActiveCellProperty: Too few arguments. The name of the property requested is neccesary.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
if (nargin > 4)
|
||||
{
|
||||
error("riGetActiveCellProperty: 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 (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[0])))
|
||||
{
|
||||
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() || riOctavePlugin::isOctaveValueNumeric(args(argIndices[2]))) && !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("riGetActiveCellProperty: 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("riGetActiveCellProperty: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
getActiveCellProperty(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), caseId, propertyName.c_str(), requestedTimeSteps, porosityModel.c_str());
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
140
Octave/OctavePlugin/riGetCaseGroups.cpp
Normal file
140
Octave/OctavePlugin/riGetCaseGroups.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getCaseGroups(std::vector<QString>& groupNames, std::vector<int>& groupIds, const QString &hostName, quint16 port)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
QString command("GetCaseGroups");
|
||||
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 data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
quint64 groupCount;
|
||||
socketStream >> groupCount;
|
||||
|
||||
|
||||
// Get response. Read all data for command
|
||||
while (socket.bytesAvailable() < (int)byteCount)
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 group = 0;
|
||||
while (group < groupCount)
|
||||
{
|
||||
QString caseGroupName;
|
||||
qint64 caseGroupId;
|
||||
|
||||
socketStream >> caseGroupName;
|
||||
socketStream >> caseGroupId;
|
||||
|
||||
groupNames.push_back(caseGroupName);
|
||||
groupIds.push_back(caseGroupId);
|
||||
|
||||
group++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DEFUN_DLD (riGetCaseGroups, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetCaseGroups()\n"
|
||||
"\n"
|
||||
"This function returns a CaseGroupInfo Structure for each of the case groups in the current ResInsight project.\n"
|
||||
"CaseGroupInfo = {\n"
|
||||
" CaseGroupId = int # A project-unique integer used to address this particular CaseGroup\n"
|
||||
" CaseGroupName = string # The name assigned to the CaseGroup in ResInsight\n"
|
||||
"}\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 0)
|
||||
{
|
||||
error("riGetCaseGroups: Too many arguments, this function does not take any arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetCaseGroups: Wrong number of output arguments, expects one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<QString> groupNames;
|
||||
std::vector<int> groupIds;
|
||||
getCaseGroups(groupNames, groupIds, "127.0.0.1", riOctavePlugin::portNumber());
|
||||
|
||||
size_t groupCount = groupNames.size();
|
||||
|
||||
if (groupCount != groupIds.size())
|
||||
{
|
||||
error("riGetCurrentCase: Inconsistent data received from ResInsight.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
Cell cellValuesA(groupCount, 1);
|
||||
Cell cellValuesB(groupCount, 1);
|
||||
|
||||
for (size_t i = 0; i < groupCount; i++)
|
||||
{
|
||||
cellValuesA(i) = groupIds[i];
|
||||
cellValuesB(i) = groupNames[i].toLatin1().data();
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::caseGroupInfo_CaseGroupId, cellValuesA);
|
||||
m.assign(riOctavePlugin::caseGroupInfo_CaseGroupName, cellValuesB);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
160
Octave/OctavePlugin/riGetCases.cpp
Normal file
160
Octave/OctavePlugin/riGetCases.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getCases(std::vector<qint64>& caseIds, std::vector<QString>& caseNames, std::vector<QString>& caseTypes, std::vector<qint64>& caseGroupIds, const qint64& caseGroupId, const QString &hostName, quint16 port)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetCases %1").arg(caseGroupId);
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 caseCount;
|
||||
socketStream >> caseCount;
|
||||
|
||||
qint64 caseId = -1;
|
||||
QString caseName;
|
||||
QString caseType;
|
||||
qint64 caseGroupIdFromSocket = -1;
|
||||
|
||||
for (size_t i = 0; i < caseCount; i++)
|
||||
{
|
||||
socketStream >> caseId;
|
||||
socketStream >> caseName;
|
||||
socketStream >> caseType;
|
||||
socketStream >> caseGroupIdFromSocket;
|
||||
|
||||
caseIds.push_back(caseId);
|
||||
caseNames.push_back(caseName);
|
||||
caseTypes.push_back(caseType);
|
||||
caseGroupIds.push_back(caseGroupIdFromSocket);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetCases, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetCases([CaseGroupId])\n"
|
||||
"\n"
|
||||
"This function returns a CaseInfo Structure for all the cases in the current ResInsight project,\n"
|
||||
"including the Statistics cases and Source cases in a Grid Case Group.\n"
|
||||
"If a CaseGroupId is provided, only the cases in that Case Group will be returned.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetCases: Too many arguments, this function takes one optional argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetCases: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<qint64> caseIds;
|
||||
std::vector<QString> caseNames;
|
||||
std::vector<QString> caseTypes;
|
||||
std::vector<qint64> caseGroupIds;
|
||||
|
||||
qint64 caseGroupId = -1;
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseGroupId = argCaseId;
|
||||
}
|
||||
|
||||
getCases(caseIds, caseNames, caseTypes, caseGroupIds, caseGroupId, "127.0.0.1", riOctavePlugin::portNumber());
|
||||
|
||||
size_t caseCount = caseIds.size();
|
||||
|
||||
if (caseCount != caseNames.size() ||
|
||||
caseCount != caseTypes.size() ||
|
||||
caseCount != caseGroupIds.size())
|
||||
{
|
||||
error("riGetCases: Inconsistent data received from ResInsight.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
Cell cellValuesA(caseCount, 1);
|
||||
Cell cellValuesB(caseCount, 1);
|
||||
Cell cellValuesC(caseCount, 1);
|
||||
Cell cellValuesD(caseCount, 1);
|
||||
|
||||
for (size_t i = 0; i < caseCount; i++)
|
||||
{
|
||||
cellValuesA(i) = caseIds[i];
|
||||
cellValuesB(i) = caseNames[i].toLatin1().data();
|
||||
cellValuesC(i) = caseTypes[i].toLatin1().data();
|
||||
cellValuesD(i) = caseGroupIds[i];
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::caseInfo_CaseId, cellValuesA);
|
||||
m.assign(riOctavePlugin::caseInfo_CaseName, cellValuesB);
|
||||
m.assign(riOctavePlugin::caseInfo_CaseType, cellValuesC);
|
||||
m.assign(riOctavePlugin::caseInfo_CaseGroupId, cellValuesD);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
136
Octave/OctavePlugin/riGetCellCenters.cpp
Normal file
136
Octave/OctavePlugin/riGetCellCenters.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#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 getCellCenters(NDArray& cellCenterValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetCellCenters %1 %2").arg(caseId).arg(gridIndex);
|
||||
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)(5 * sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 cellCountI;
|
||||
quint64 cellCountJ;
|
||||
quint64 cellCountK;
|
||||
quint64 cellCount;
|
||||
quint64 byteCount;
|
||||
|
||||
socketStream >> cellCount;
|
||||
socketStream >> cellCountI;
|
||||
socketStream >> cellCountJ;
|
||||
socketStream >> cellCountK;
|
||||
socketStream >> byteCount;
|
||||
|
||||
if (!(byteCount && cellCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
dim_vector dv;
|
||||
dv.resize(4);
|
||||
dv(0) = cellCountI;
|
||||
dv(1) = cellCountJ;
|
||||
dv(2) = cellCountK;
|
||||
dv(3) = 3;
|
||||
cellCenterValues.resize(dv);
|
||||
|
||||
double* internalMatrixData = cellCenterValues.fortran_vec();
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetCellCenters, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetCellCenters([CaseId], GridIndex )\n"
|
||||
"\n"
|
||||
"This function returns the UTM coordinates (X, Y, Z) of the center point of all the cells in the grid.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 2)
|
||||
{
|
||||
error("riGetCellCenters: Too many arguments. CaseId is optional input argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetCellCenters: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
NDArray cellCenterValues;
|
||||
|
||||
qint32 caseId = -1;
|
||||
quint32 gridIndex = 0;
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
gridIndex = args(0).uint_value();
|
||||
}
|
||||
else if (nargin == 2)
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
|
||||
gridIndex = args(1).uint_value();
|
||||
}
|
||||
|
||||
getCellCenters(cellCenterValues, "127.0.0.1", riOctavePlugin::portNumber(), caseId, gridIndex);
|
||||
|
||||
return octave_value(cellCenterValues);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
138
Octave/OctavePlugin/riGetCellCorners.cpp
Normal file
138
Octave/OctavePlugin/riGetCellCorners.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#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 getCellCorners(NDArray& cellCornerValues, const QString &hostName, quint16 port, const qint32& caseId, const quint32& gridIndex)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetCellCorners %1 %2").arg(caseId).arg(gridIndex);
|
||||
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)(5 * sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 cellCountI;
|
||||
quint64 cellCountJ;
|
||||
quint64 cellCountK;
|
||||
quint64 cellCount;
|
||||
quint64 byteCount;
|
||||
|
||||
socketStream >> cellCount;
|
||||
socketStream >> cellCountI;
|
||||
socketStream >> cellCountJ;
|
||||
socketStream >> cellCountK;
|
||||
socketStream >> byteCount;
|
||||
|
||||
if (!(byteCount && cellCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
dim_vector dv;
|
||||
dv.resize(5);
|
||||
dv(0) = cellCountI;
|
||||
dv(1) = cellCountJ;
|
||||
dv(2) = cellCountK;
|
||||
dv(3) = 8;
|
||||
dv(4) = 3;
|
||||
cellCornerValues.resize(dv);
|
||||
|
||||
double* internalMatrixData = cellCornerValues.fortran_vec();
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), byteCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetCellCorners, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetCellCorners([CaseId], GridIndex )\n"
|
||||
"\n"
|
||||
"This function returns the UTM coordinates (X, Y, Z) of the 8 corners of all the cells in the grid.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 2)
|
||||
{
|
||||
error("riGetCellCorners: Too many arguments. CaseId is optional input argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetCellCorners: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
NDArray cellCornerValues;
|
||||
|
||||
qint32 caseId = -1;
|
||||
quint32 gridIndex = 0;
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
gridIndex = args(0).uint_value();
|
||||
}
|
||||
else if (nargin == 2)
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
|
||||
gridIndex = args(1).uint_value();
|
||||
}
|
||||
|
||||
getCellCorners(cellCornerValues, "127.0.0.1", riOctavePlugin::portNumber(), caseId, gridIndex);
|
||||
|
||||
return octave_value(cellCornerValues);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
125
Octave/OctavePlugin/riGetCoarseningInfo.cpp
Normal file
125
Octave/OctavePlugin/riGetCoarseningInfo.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
|
||||
void getCoarseningInfo(int32NDArray& coarseningInfo, 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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetCoarseningInfo %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)(sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
quint64 boxCount = byteCount / (6 * sizeof(qint32));
|
||||
|
||||
dim_vector dv (1, 1);
|
||||
dv(0) = boxCount;
|
||||
dv(1) = 6;
|
||||
|
||||
coarseningInfo.resize(dv);
|
||||
|
||||
for (size_t i = 0; i < boxCount; i++)
|
||||
{
|
||||
qint32 i1;
|
||||
qint32 i2;
|
||||
qint32 j1;
|
||||
qint32 j2;
|
||||
qint32 k1;
|
||||
qint32 k2;
|
||||
|
||||
socketStream >> i1;
|
||||
socketStream >> i2;
|
||||
socketStream >> j1;
|
||||
socketStream >> j2;
|
||||
socketStream >> k1;
|
||||
socketStream >> k2;
|
||||
|
||||
coarseningInfo(i, 0) = i1;
|
||||
coarseningInfo(i, 1) = i2;
|
||||
coarseningInfo(i, 2) = j1;
|
||||
coarseningInfo(i, 3) = j2;
|
||||
coarseningInfo(i, 4) = k1;
|
||||
coarseningInfo(i, 5) = k2;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetCoarseningInfo, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetCoarseningInfo([CaseId])\n"
|
||||
"\n"
|
||||
"This function returns all the coarse box definitions used in the grid.\n"
|
||||
"The columns contain the following information:\n"
|
||||
"[I1, I2, J1, J2, K1, K2]: 1-based index addresses of the min and max corners of the coarsening box.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetCoarseningInfo: Too many arguments. Only the name or index of the case is valid input.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetCoarseningInfo: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 caseId = -1;
|
||||
if (nargin > 0)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
}
|
||||
|
||||
int32NDArray coarseningInfo;
|
||||
getCoarseningInfo(coarseningInfo, "127.0.0.1", riOctavePlugin::portNumber(), caseId);
|
||||
|
||||
return octave_value(coarseningInfo);
|
||||
}
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
110
Octave/OctavePlugin/riGetCurrentCase.cpp
Normal file
110
Octave/OctavePlugin/riGetCurrentCase.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getCurrentCase(qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId, const QString &hostName, quint16 port)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command("GetCurrentCase");
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
socketStream >> caseId;
|
||||
socketStream >> caseName;
|
||||
socketStream >> caseType;
|
||||
socketStream >> caseGroupId;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetCurrentCase, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetCurrentCase()\n"
|
||||
"\n"
|
||||
"This function returns a CaseInfo Structure for the Case considered being the 'Current Case' by ResInsight.\n"
|
||||
"When ResInsigt loops over a selection of cases and executes an Octave script for each of them,\n"
|
||||
"this function returns the CaseInfo for that particular Case.\n"
|
||||
)
|
||||
{
|
||||
octave_value retval;
|
||||
|
||||
int nargin = args.length ();
|
||||
if (nargin > 0)
|
||||
{
|
||||
error("riGetCurrentCase: Too many input arguments, this function does not take any input arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetCurrentCase: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 caseId = -1;
|
||||
QString caseName;
|
||||
QString caseType;
|
||||
qint64 caseGroupId = -1;
|
||||
|
||||
getCurrentCase(caseId, caseName, caseType, caseGroupId, "127.0.0.1", riOctavePlugin::portNumber());
|
||||
|
||||
octave_map fieldMap;
|
||||
|
||||
fieldMap.assign(riOctavePlugin::caseInfo_CaseId, Cell(caseId));
|
||||
fieldMap.assign(riOctavePlugin::caseInfo_CaseName, Cell(std::string(caseName.toLatin1().data()), true));
|
||||
fieldMap.assign(riOctavePlugin::caseInfo_CaseType, Cell(std::string(caseType.toLatin1().data()), true));
|
||||
fieldMap.assign(riOctavePlugin::caseInfo_CaseGroupId, Cell(caseGroupId));
|
||||
|
||||
retval = octave_value(fieldMap);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
161
Octave/OctavePlugin/riGetDynamicNNCValues.cpp
Normal file
161
Octave/OctavePlugin/riGetDynamicNNCValues.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include <QtNetwork>
|
||||
#include <QStringList>
|
||||
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
|
||||
|
||||
void getDynamicNNCValues(Matrix& propertyFrames, const QString &serverName, quint16 serverPort,
|
||||
const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() -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: %s",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("%s",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 (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[0])))
|
||||
{
|
||||
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", riOctavePlugin::portNumber(), caseId, propertyName.c_str(), requestedTimeSteps);
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
129
Octave/OctavePlugin/riGetGridDimensions.cpp
Normal file
129
Octave/OctavePlugin/riGetGridDimensions.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
|
||||
void getGridDimensions(int32NDArray& gridDimensions, 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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetGridDimensions %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)(sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
quint64 gridCount = byteCount / (3 * sizeof(quint64));
|
||||
|
||||
dim_vector dv (1, 1);
|
||||
dv(0) = gridCount;
|
||||
dv(1) = 3;
|
||||
|
||||
gridDimensions.resize(dv);
|
||||
|
||||
for (size_t i = 0; i < gridCount; i++)
|
||||
{
|
||||
quint64 iCount;
|
||||
quint64 jCount;
|
||||
quint64 kCount;
|
||||
|
||||
socketStream >> iCount;
|
||||
socketStream >> jCount;
|
||||
socketStream >> kCount;
|
||||
|
||||
gridDimensions(i, 0) = iCount;
|
||||
gridDimensions(i, 1) = jCount;
|
||||
gridDimensions(i, 2) = kCount;
|
||||
}
|
||||
|
||||
QString tmp = QString("riGetGridDimensions : Read grid dimensions");
|
||||
if (caseId < 0)
|
||||
{
|
||||
tmp += QString(" from current case.");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp += QString(" from caseID: %1.").arg(caseId);
|
||||
}
|
||||
|
||||
octave_stdout << tmp.toStdString() << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetGridDimensions, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetGridDimensions([CaseId])\n"
|
||||
"\n"
|
||||
"This function returns a two dimensional matrix: One row for each grid, starting with the main grid.\n"
|
||||
"NOTE: This means that the <20>normal<61> GridIndices where 0 means Main Grid does not work directly with this matrix. You have to add 1.\n"
|
||||
"The columns contain the following information:\n"
|
||||
"[NI, NJ, NK]: I, J, K dimensions of the grid.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetGridDimensions: Too many arguments. Only the name or index of the case is valid input.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetGridDimensions: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 caseId = -1;
|
||||
if (nargin > 0)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
}
|
||||
|
||||
int32NDArray gridDimensions;
|
||||
getGridDimensions(gridDimensions, "127.0.0.1", riOctavePlugin::portNumber(), caseId);
|
||||
|
||||
return octave_value(gridDimensions);
|
||||
}
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
217
Octave/OctavePlugin/riGetGridProperty.cpp
Normal file
217
Octave/OctavePlugin/riGetGridProperty.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
#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 getGridProperty(NDArray& propertyFrames, const QString &serverName, quint16 serverPort,
|
||||
const int& caseId, int gridIdx, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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 += "GetGridProperty " + QString::number(caseId) + " " + QString::number(gridIdx) + " " + propertyName + " " + porosityModel;
|
||||
|
||||
for (qint64 i = 0; i < requestedTimeSteps.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() -1) command += " ";
|
||||
}
|
||||
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
socketStream << (qint64)(cmdBytes.size());
|
||||
socket.write(cmdBytes);
|
||||
|
||||
// Get response. First wait for the header
|
||||
|
||||
while (socket.bytesAvailable() < (qint64)(4*sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read sizes
|
||||
|
||||
quint64 totalByteCount;
|
||||
|
||||
quint64 cellCountI;
|
||||
quint64 cellCountJ;
|
||||
quint64 cellCountK;
|
||||
quint64 timestepCount;
|
||||
|
||||
socketStream >> cellCountI;
|
||||
socketStream >> cellCountJ;
|
||||
socketStream >> cellCountK;
|
||||
socketStream >> timestepCount;
|
||||
|
||||
totalByteCount = cellCountI*cellCountJ*cellCountK*timestepCount*sizeof(double);
|
||||
|
||||
if (!(totalByteCount))
|
||||
{
|
||||
error ("Could not find the requested data in ResInsight");
|
||||
return;
|
||||
}
|
||||
|
||||
dim_vector dv;
|
||||
dv.resize(4);
|
||||
dv(0) = cellCountI;
|
||||
dv(1) = cellCountJ;
|
||||
dv(2) = cellCountK;
|
||||
dv(3) = timestepCount;
|
||||
|
||||
propertyFrames.resize(dv);
|
||||
|
||||
double* internalMatrixData = propertyFrames.fortran_vec();
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), totalByteCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",errorMessages[i].toLatin1().data());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QString tmp = QString("riGetGridProperty : Read %1").arg(propertyName);
|
||||
|
||||
if (caseId < 0)
|
||||
{
|
||||
tmp += QString(" from current case,");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp += QString(" from case with Id: %1,").arg(caseId);
|
||||
}
|
||||
|
||||
tmp += QString(" grid index: %1, ").arg(gridIdx);
|
||||
|
||||
octave_stdout << tmp.toStdString() << " I, J, K " << cellCountI << ", " << cellCountJ << ", " << cellCountK << ", Timesteps : " << timestepCount << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetGridProperty, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"Matrix[numI][numJ][numK][numTimestepsRequested] riGetGridProperty([CaseId], GridIndex , PropertyName, [RequestedTimeSteps], [PorosityModel = \"Matrix\"|\"Fracture\"])"
|
||||
"\n"
|
||||
"This function returns a matrix of the requested property data for all the grid cells in the requested grid for each requested time step.\n"
|
||||
"Grids are indexed from 0 (main grid) to max number of LGR's.\n"
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used.\n"
|
||||
"The RequestedTimeSteps must contain a list of indices to the requested time steps. If not defined, all the time steps are returned.\n"
|
||||
)
|
||||
{
|
||||
if (nargout < 1)
|
||||
{
|
||||
error("riGetGridProperty: Missing output argument.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
int nargin = args.length ();
|
||||
if (nargin < 2)
|
||||
{
|
||||
error("riGetGridProperty: Too few arguments. The name of the property and index of the grid requested is neccesary.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
if (nargin > 5)
|
||||
{
|
||||
error("riGetGridProperty: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
std::vector<int> argIndices;
|
||||
argIndices.push_back(0); // caseId
|
||||
argIndices.push_back(1); // GridIndex
|
||||
argIndices.push_back(2); // PropertyName
|
||||
argIndices.push_back(3); // TimeSteps
|
||||
argIndices.push_back(4); // PorosityModel
|
||||
|
||||
// Check if we do not have a CaseId:
|
||||
if (args(argIndices[1]).is_string()) // Check if second argument is a text. If it is, the caseid is missing
|
||||
{
|
||||
argIndices[0] = -1;
|
||||
for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have a Requested TimeSteps
|
||||
|
||||
if (!(nargin > argIndices[3] && (args(argIndices[3]).is_matrix_type() || riOctavePlugin::isOctaveValueNumeric(args(argIndices[3]))) && !args(argIndices[3]).is_string()))
|
||||
{
|
||||
argIndices[3] = -1;
|
||||
for (size_t aIdx = 3; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have a PorosityModel
|
||||
|
||||
int lastArgumentIndex = argIndices[4] ;
|
||||
if (!(nargin > argIndices[4] && args(argIndices[4]).is_string()))
|
||||
{
|
||||
argIndices[4] = -1;
|
||||
for (size_t aIdx = 5; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have more arguments than we should
|
||||
if (nargin > lastArgumentIndex + 1)
|
||||
{
|
||||
error("riGetGridProperty: Unexpected argument after the PorosityModel.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
// Setup the argument list
|
||||
|
||||
NDArray propertyFrames;
|
||||
int caseId = -1;
|
||||
int gridIdx = 0;
|
||||
std::string propertyName = "UNDEFINED";
|
||||
int32NDArray requestedTimeSteps;
|
||||
std::string porosityModel = "Matrix";
|
||||
|
||||
if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value();
|
||||
if (argIndices[1] >= 0) gridIdx = 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 (argIndices[4] >= 0) porosityModel = args(argIndices[4]).string_value();
|
||||
|
||||
|
||||
if (porosityModel != "Matrix" && porosityModel != "Fracture")
|
||||
{
|
||||
error("riGetGridProperty: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
getGridProperty(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), caseId, gridIdx, propertyName.c_str(), requestedTimeSteps, porosityModel.c_str());
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
199
Octave/OctavePlugin/riGetGridPropertyForSelectedCells.cpp
Normal file
199
Octave/OctavePlugin/riGetGridPropertyForSelectedCells.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
#include <QtNetwork>
|
||||
#include <QStringList>
|
||||
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
|
||||
|
||||
void getGridPropertyForSelectedCells(Matrix& propertyFrames, const QString &serverName, quint16 serverPort,
|
||||
const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() - 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: %s",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("%s",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 (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[0])))
|
||||
{
|
||||
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() || riOctavePlugin::isOctaveValueNumeric(args(argIndices[2]))) && !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", riOctavePlugin::portNumber(), caseId, propertyName.c_str(), requestedTimeSteps, porosityModel.c_str());
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
113
Octave/OctavePlugin/riGetMainGridDimensions.cpp
Normal file
113
Octave/OctavePlugin/riGetMainGridDimensions.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getMainGridDimensions(int32NDArray& gridDimensions, const QString &hostName, quint16 port, QString caseName)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command("GetMainGridDimensions ");
|
||||
command += caseName;
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
QDataStream socketStream(&socket);
|
||||
socketStream.setVersion(QDataStream::Qt_4_0);
|
||||
|
||||
socketStream << (qint64)(cmdBytes.size());
|
||||
socket.write(cmdBytes);
|
||||
|
||||
// Get response. First wait for the header
|
||||
|
||||
while (socket.bytesAvailable() < (int)(3*sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read timestep count and blocksize
|
||||
|
||||
quint64 iCount;
|
||||
quint64 jCount;
|
||||
quint64 kCount;
|
||||
|
||||
socketStream >> iCount;
|
||||
socketStream >> jCount;
|
||||
socketStream >> kCount;
|
||||
|
||||
dim_vector dv (1, 1);
|
||||
dv(0) = 3;
|
||||
|
||||
gridDimensions.resize(dv);
|
||||
gridDimensions(0) = iCount;
|
||||
gridDimensions(1) = jCount;
|
||||
gridDimensions(2) = kCount;
|
||||
|
||||
|
||||
QString tmp = QString("riGetMainGridDimensions : Read main grid dimensions");
|
||||
if (caseName.isEmpty())
|
||||
{
|
||||
tmp += QString(" from active case.");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp += QString(" from %1.").arg(caseName);
|
||||
}
|
||||
octave_stdout << tmp.toStdString() << " Dimensions: " << iCount << ", " << jCount << ", " << kCount << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetMainGridDimensions, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetMainGridDimensions( [CaseName/CaseIndex])\n"
|
||||
"\n"
|
||||
"Returns a vector of size 3: [ICount, JCount, KCount] \n"
|
||||
"Containing the dimensions of the main grid in the requested case.\n"
|
||||
"If the Eclipse Case is not defined, the active View in ResInsight is used."
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetActiveCellInfo: Too many arguments. Only the name or index of the case is valid input.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout < 1)
|
||||
{
|
||||
error("riGetActiveCellInfo: Missing output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
int32NDArray propertyFrames;
|
||||
|
||||
if (nargin > 0)
|
||||
getMainGridDimensions(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), args(0).char_matrix_value().row_as_string(0).c_str());
|
||||
else
|
||||
getMainGridDimensions(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), "");
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
158
Octave/OctavePlugin/riGetNNCConnections.cpp
Normal file
158
Octave/OctavePlugin/riGetNNCConnections.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
|
||||
|
||||
struct GridLocalCell
|
||||
{
|
||||
int gridIndex;
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
};
|
||||
|
||||
struct Connection
|
||||
{
|
||||
GridLocalCell fromCell;
|
||||
GridLocalCell toCell;
|
||||
};
|
||||
|
||||
void getNNCConnections(std::vector<Connection>& connections, const QString& hostName, quint16 port, const qint64& caseId)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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: %s",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: %s",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 (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
}
|
||||
|
||||
getNNCConnections(connections, "127.0.0.1", riOctavePlugin::portNumber(), caseId);
|
||||
|
||||
Cell cellValuesGridIndex(connections.size(), 2);
|
||||
Cell cellValuesI(connections.size(), 2);
|
||||
Cell cellValuesJ(connections.size(), 2);
|
||||
Cell cellValuesK(connections.size(), 2);
|
||||
|
||||
for (size_t i = 0; i < connections.size(); ++i)
|
||||
{
|
||||
cellValuesGridIndex(i, 0) = connections[i].fromCell.gridIndex;
|
||||
cellValuesGridIndex(i, 1) = connections[i].toCell.gridIndex;
|
||||
|
||||
cellValuesI(i, 0) = connections[i].fromCell.i;
|
||||
cellValuesI(i, 1) = connections[i].toCell.i;
|
||||
|
||||
cellValuesJ(i, 0) = connections[i].fromCell.j;
|
||||
cellValuesJ(i, 1) = connections[i].toCell.j;
|
||||
|
||||
cellValuesK(i, 0) = connections[i].fromCell.k;
|
||||
cellValuesK(i, 1) = connections[i].toCell.k;
|
||||
}
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::cellIndex_gridIndex, cellValuesGridIndex);
|
||||
m.assign(riOctavePlugin::cellIndex_I, cellValuesI);
|
||||
m.assign(riOctavePlugin::cellIndex_J, cellValuesJ);
|
||||
m.assign(riOctavePlugin::cellIndex_K, cellValuesK);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
152
Octave/OctavePlugin/riGetNNCPropertyNames.cpp
Normal file
152
Octave/OctavePlugin/riGetNNCPropertyNames.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getNNCPropertyNames(std::vector<QString>& propNames, std::vector<QString>& propTypes, const QString &hostName, quint16 port,
|
||||
const qint64& caseId)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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: %s",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: %s",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", riOctavePlugin::portNumber(), 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();
|
||||
}
|
||||
|
||||
172
Octave/OctavePlugin/riGetPropertyNames.cpp
Normal file
172
Octave/OctavePlugin/riGetPropertyNames.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getPropertyNames(std::vector<QString>& propNames, std::vector<QString>& propTypes, const QString &hostName, quint16 port,
|
||||
const qint64& caseId, QString porosityModel)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command;
|
||||
command += QString("GetPropertyNames") + " " + QString::number(caseId) + " " + porosityModel;
|
||||
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: %s",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: %s",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 (riGetPropertyNames, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetPropertyNames([CaseId]), [PorosityModel = \"Matrix\"|\"Fracture\"] \n"
|
||||
"\n"
|
||||
"This function returns the name and type of all the properties in the case as a Vector of Structures.\n"
|
||||
"The Structure is defined as: \n"
|
||||
"PropertyInfo {\n"
|
||||
" PropName = string # Name of the property as received from the analysis tool \n"
|
||||
" PropType = string # The type of the property: \"StaticNative\", \"DynamicNative\", \"Input\", \"Generated\" \n"
|
||||
"} \n"
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 2)
|
||||
{
|
||||
error("riGetPropertyNames: Too many arguments, this function takes two optional arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetPropertyNames: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 argCaseId = -1;
|
||||
QString porosityModel = "Matrix";
|
||||
|
||||
if (nargin == 1)
|
||||
{
|
||||
if (args(0).is_string())
|
||||
{
|
||||
porosityModel = args(0).char_matrix_value().row_as_string(0).c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
argCaseId = args(0).uint_value();
|
||||
}
|
||||
}
|
||||
else if (nargin == 2)
|
||||
{
|
||||
argCaseId = args(0).uint_value();
|
||||
porosityModel = args(1).char_matrix_value().row_as_string(0).c_str();
|
||||
}
|
||||
|
||||
if (porosityModel != "Matrix" && porosityModel != "Fracture")
|
||||
{
|
||||
error("riGetPropertyNames: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
std::vector<QString> propertyNames;
|
||||
std::vector<QString> propertyTypes;
|
||||
|
||||
getPropertyNames(propertyNames, propertyTypes, "127.0.0.1", riOctavePlugin::portNumber(), argCaseId, porosityModel);
|
||||
|
||||
size_t caseCount = propertyNames.size();
|
||||
|
||||
if (propertyNames.size() != propertyTypes.size() )
|
||||
{
|
||||
error("riGetPropertyNames: 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();
|
||||
}
|
||||
|
||||
150
Octave/OctavePlugin/riGetSelectedCases.cpp
Normal file
150
Octave/OctavePlugin/riGetSelectedCases.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getSelectedCases(std::vector<qint64>& caseIds, std::vector<QString>& caseNames, std::vector<QString>& caseTypes, std::vector<qint64>& caseGroupIds, const QString &hostName, quint16 port)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command("GetSelectedCases");
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 selectionCount;
|
||||
socketStream >> selectionCount;
|
||||
|
||||
qint64 caseId = -1;
|
||||
QString caseName;
|
||||
QString caseType;
|
||||
qint64 caseGroupId = -1;
|
||||
|
||||
for (size_t i = 0; i < selectionCount; i++)
|
||||
{
|
||||
socketStream >> caseId;
|
||||
socketStream >> caseName;
|
||||
socketStream >> caseType;
|
||||
socketStream >> caseGroupId;
|
||||
|
||||
caseIds.push_back(caseId);
|
||||
caseNames.push_back(caseName);
|
||||
caseTypes.push_back(caseType);
|
||||
caseGroupIds.push_back(caseGroupId);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetSelectedCases, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetSelectedCases()\n"
|
||||
"\n"
|
||||
"This function returns a CaseInfo Structure for each of the cases selected in ResInsight at the time when the script was launched.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 0)
|
||||
{
|
||||
error("riGetSelectedCases: Too many arguments, this function does not take any arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetSelectedCases: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<qint64> caseIds;
|
||||
std::vector<QString> caseNames;
|
||||
std::vector<QString> caseTypes;
|
||||
std::vector<qint64> caseGroupIds;
|
||||
|
||||
getSelectedCases(caseIds, caseNames, caseTypes, caseGroupIds, "127.0.0.1", riOctavePlugin::portNumber());
|
||||
|
||||
size_t caseCount = caseIds.size();
|
||||
|
||||
if (caseCount != caseNames.size() ||
|
||||
caseCount != caseTypes.size() ||
|
||||
caseCount != caseGroupIds.size())
|
||||
{
|
||||
error("riGetSelectedCases: Inconsistent data received from ResInsight.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
Cell cellValuesA(caseCount, 1);
|
||||
Cell cellValuesB(caseCount, 1);
|
||||
Cell cellValuesC(caseCount, 1);
|
||||
Cell cellValuesD(caseCount, 1);
|
||||
|
||||
for (size_t i = 0; i < caseCount; i++)
|
||||
{
|
||||
cellValuesA(i) = caseIds[i];
|
||||
cellValuesB(i) = caseNames[i].toLatin1().data();
|
||||
cellValuesC(i) = caseTypes[i].toLatin1().data();
|
||||
cellValuesD(i) = caseGroupIds[i];
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::caseInfo_CaseId, cellValuesA);
|
||||
m.assign(riOctavePlugin::caseInfo_CaseName, cellValuesB);
|
||||
m.assign(riOctavePlugin::caseInfo_CaseType, cellValuesC);
|
||||
m.assign(riOctavePlugin::caseInfo_CaseGroupId, cellValuesD);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
135
Octave/OctavePlugin/riGetSelectedCells.cpp
Normal file
135
Octave/OctavePlugin/riGetSelectedCells.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#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: %s",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: %s",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;
|
||||
}
|
||||
|
||||
#if OCTAVE_MAJOR_VERSION > 6
|
||||
auto internalMatrixData = (qint32*)selectedCellInfo.fortran_vec();
|
||||
#else
|
||||
qint32* internalMatrixData = (qint32*)selectedCellInfo.fortran_vec()->mex_get_data();
|
||||
#endif
|
||||
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::readBlockDataFromSocket(&socket, (char*)(internalMatrixData), columnCount * byteCountForOneTimestep, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
error("%s",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", riOctavePlugin::portNumber(), caseId);
|
||||
|
||||
return octave_value(propertyFrames);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
144
Octave/OctavePlugin/riGetStaticNNCValues.cpp
Normal file
144
Octave/OctavePlugin/riGetStaticNNCValues.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#include <QtNetwork>
|
||||
#include <QStringList>
|
||||
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
#include "RiaSocketDataTransfer.cpp" // NB! Include cpp-file to avoid linking of additional file in oct-compile configuration
|
||||
|
||||
void getStaticNNCValues(std::vector<double>& propertyValues, const QString &serverName, quint16 serverPort,
|
||||
const qint64& caseId, QString propertyName)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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: %s",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 (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[0])))
|
||||
{
|
||||
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", riOctavePlugin::portNumber(), 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);
|
||||
}
|
||||
182
Octave/OctavePlugin/riGetTimeStepDates.cpp
Normal file
182
Octave/OctavePlugin/riGetTimeStepDates.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getTimeStepDates( std::vector<qint32>& yearValues,
|
||||
std::vector<qint32>& monthValues,
|
||||
std::vector<qint32>& dayValues,
|
||||
std::vector<qint32>& hourValues,
|
||||
std::vector<qint32>& minuteValues,
|
||||
std::vector<qint32>& secondValues,
|
||||
const qint64& caseId,
|
||||
const QString& hostName,
|
||||
quint16 port)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetTimeStepDates %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)(sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 timeStepCount;
|
||||
socketStream >> timeStepCount;
|
||||
|
||||
for (size_t i = 0; i < timeStepCount; i++)
|
||||
{
|
||||
qint32 intValue;
|
||||
|
||||
socketStream >> intValue;
|
||||
yearValues.push_back(intValue);
|
||||
|
||||
socketStream >> intValue;
|
||||
monthValues.push_back(intValue);
|
||||
|
||||
socketStream >> intValue;
|
||||
dayValues.push_back(intValue);
|
||||
|
||||
socketStream >> intValue;
|
||||
hourValues.push_back(intValue);
|
||||
|
||||
socketStream >> intValue;
|
||||
minuteValues.push_back(intValue);
|
||||
|
||||
socketStream >> intValue;
|
||||
secondValues.push_back(intValue);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetTimeStepDates, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetTimeStepDates()\n"
|
||||
"\n"
|
||||
"This function returns the date information for each of the time steps in the case as a Vector of Structures.\n"
|
||||
"The Structure is defined as:\n"
|
||||
"TimeStepDate = {\n"
|
||||
" Year = int # The year eg. 2013\n"
|
||||
" Month = int # The month. Eg. 12\n"
|
||||
" Day = int # The day in the month. Eg. 24\n"
|
||||
" Hour = int # The hour of the day. Eg. 17\n"
|
||||
" Minute = int # The minute in the hour. Eg. 55\n"
|
||||
" Second = int # The second within the minute. Eg. 30\n"
|
||||
"}\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetTimeStepDates: Too many arguments, this function takes one optional argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetTimeStepDates: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 caseId = -1;
|
||||
if (nargin > 0)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<qint32> yearValues;
|
||||
std::vector<qint32> monthValues;
|
||||
std::vector<qint32> dayValues;
|
||||
std::vector<qint32> hourValues;
|
||||
std::vector<qint32> minuteValues;
|
||||
std::vector<qint32> secondValues;
|
||||
|
||||
getTimeStepDates(yearValues, monthValues, dayValues, hourValues, minuteValues, secondValues, caseId, "127.0.0.1", riOctavePlugin::portNumber());
|
||||
|
||||
size_t timeStepDateCount = yearValues.size();
|
||||
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
Cell cellValuesA(timeStepDateCount, 1);
|
||||
Cell cellValuesB(timeStepDateCount, 1);
|
||||
Cell cellValuesC(timeStepDateCount, 1);
|
||||
Cell cellValuesD(timeStepDateCount, 1);
|
||||
Cell cellValuesE(timeStepDateCount, 1);
|
||||
Cell cellValuesF(timeStepDateCount, 1);
|
||||
|
||||
for (size_t i = 0; i < timeStepDateCount; i++)
|
||||
{
|
||||
cellValuesA(i) = yearValues[i];
|
||||
cellValuesB(i) = monthValues[i];
|
||||
cellValuesC(i) = dayValues[i];
|
||||
cellValuesD(i) = hourValues[i];
|
||||
cellValuesE(i) = minuteValues[i];
|
||||
cellValuesF(i) = secondValues[i];
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::timeStepDate_Year, cellValuesA);
|
||||
m.assign(riOctavePlugin::timeStepDate_Month, cellValuesB);
|
||||
m.assign(riOctavePlugin::timeStepDate_Day, cellValuesC);
|
||||
m.assign(riOctavePlugin::timeStepDate_Hour, cellValuesD);
|
||||
m.assign(riOctavePlugin::timeStepDate_Minute, cellValuesE);
|
||||
m.assign(riOctavePlugin::timeStepDate_Second, cellValuesF);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
128
Octave/OctavePlugin/riGetTimeStepDays.cpp
Normal file
128
Octave/OctavePlugin/riGetTimeStepDays.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getTimeStepDates( std::vector<double>& decimalDays,
|
||||
const qint64& caseId,
|
||||
const QString& hostName,
|
||||
quint16 port)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command = QString("GetTimeStepDays %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)(sizeof(quint64)))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for header: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 timeStepCount;
|
||||
socketStream >> timeStepCount;
|
||||
|
||||
octave_stdout << "byte count: " << byteCount << ", Timesteps: " << timeStepCount << std::endl;
|
||||
|
||||
for (size_t i = 0; i < timeStepCount; i++)
|
||||
{
|
||||
double doubleValue;
|
||||
|
||||
socketStream >> doubleValue;
|
||||
decimalDays.push_back(doubleValue);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetTimeStepDays, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetTimeStepDays()\n"
|
||||
"\n"
|
||||
"This function returns the time from the simulation start\n"
|
||||
"as decimal days for all the time steps as a Vector of doubles.\n"
|
||||
"If the CaseId is not defined, ResInsight<68>s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetTimeStepDays: Too many arguments, this function takes one optional argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetTimeStepDays: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 caseId = -1;
|
||||
if (nargin > 0)
|
||||
{
|
||||
if (riOctavePlugin::isOctaveValueNumeric(args(0)))
|
||||
{
|
||||
unsigned int argCaseId = args(0).uint_value();
|
||||
caseId = argCaseId;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> decimalDays;
|
||||
|
||||
getTimeStepDates(decimalDays, caseId, "127.0.0.1", riOctavePlugin::portNumber());
|
||||
|
||||
dim_vector dv(2, 1);
|
||||
dv(0) = decimalDays.size();
|
||||
dv(1) = 1;
|
||||
NDArray oct_decimalDays(dv);
|
||||
|
||||
for (size_t i = 0; i < decimalDays.size(); i++)
|
||||
{
|
||||
oct_decimalDays(i) = decimalDays[i];
|
||||
}
|
||||
|
||||
return octave_value(oct_decimalDays);
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
265
Octave/OctavePlugin/riGetWellCells.cpp
Normal file
265
Octave/OctavePlugin/riGetWellCells.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getWellCells( std::vector<int>& cellIs,
|
||||
std::vector<int>& cellJs,
|
||||
std::vector<int>& cellKs,
|
||||
std::vector<int>& gridIndices,
|
||||
std::vector<int>& cellStatuses,
|
||||
std::vector<int>& branchIds,
|
||||
std::vector<int>& segmentIds,
|
||||
const QString &hostName, quint16 port,
|
||||
const qint64& caseId, const QString& wellName, int requestedTimeStep)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command;
|
||||
command += QString("GetWellCells") + " " + QString::number(caseId) + " " + wellName + " " + QString::number(requestedTimeStep) ;
|
||||
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
if (byteCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 cellCount;
|
||||
socketStream >> cellCount;
|
||||
|
||||
octave_stdout << "riGetWellCells: Number of cells in well " << wellName.toLatin1().data() << " : " << cellCount << std::endl;
|
||||
|
||||
cellIs .reserve(cellCount);
|
||||
cellJs .reserve(cellCount);
|
||||
cellKs .reserve(cellCount);
|
||||
gridIndices .reserve(cellCount);
|
||||
cellStatuses .reserve(cellCount);
|
||||
branchIds .reserve(cellCount);
|
||||
segmentIds .reserve(cellCount);
|
||||
|
||||
qint32 i, j, k, gIdx, cStat, bId, sId;
|
||||
|
||||
for (size_t cIdx = 0; cIdx < cellCount; cIdx++)
|
||||
{
|
||||
socketStream >> i;
|
||||
socketStream >> j;
|
||||
socketStream >> k;
|
||||
socketStream >> gIdx;
|
||||
socketStream >> cStat;
|
||||
socketStream >> bId;
|
||||
socketStream >> sId;
|
||||
|
||||
cellIs.push_back (i);
|
||||
cellJs.push_back (j);
|
||||
cellKs.push_back (k);
|
||||
gridIndices.push_back (gIdx);
|
||||
cellStatuses.push_back(cStat);
|
||||
branchIds.push_back (bId);
|
||||
segmentIds.push_back (sId);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetWellCells, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetWellCells ([CaseId], WellName, TimeStep) \n"
|
||||
"\n"
|
||||
"This function returns the cells defined in the specified well for the time step requested \n"
|
||||
"as a vector of Structures. \n"
|
||||
"The Structure is defined as:\n"
|
||||
"WellCellInfo { \n"
|
||||
" I, J, K = int # Index to the cell in the grid\n"
|
||||
" GridIndex = int # the index of the grid. Main grid has index 0.\n"
|
||||
" CellStatus = int # is either 0 or 1, meaning the cell is closed or open respectively\n"
|
||||
" BranchId = int # Branch id of the branch intersecting the cell\n"
|
||||
" SegmentId = int # Branch segment id of the branch intersecting the cell\n"
|
||||
"}\n"
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
if (nargout != 1)
|
||||
{
|
||||
error("riGetWellCells: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
int nargin = args.length ();
|
||||
if (nargin < 2)
|
||||
{
|
||||
error("riGetWellCells: Too few arguments, this function needs at least the well name and a timestep as input.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
if (nargin > 3)
|
||||
{
|
||||
error("riGetWellCells: Too many arguments, this function takes at most three arguments.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
std::vector<int> argIndices;
|
||||
argIndices.push_back(0); // caseId
|
||||
argIndices.push_back(1); // WellName
|
||||
argIndices.push_back(2); // TimeStep
|
||||
|
||||
// Check if we do not have a CaseId:
|
||||
if (args(argIndices[0]).is_string()) // Check if first argument is a text. If it is, the caseId is missing
|
||||
{
|
||||
argIndices[0] = -1;
|
||||
for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
if (!args(argIndices[1]).is_string()) // Check if the WellName argument is actually a string
|
||||
{
|
||||
error("riGetWellCells: Missing Well Name. this function needs at least the well name and a timestep as input.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
if (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[2]))) // Check if the TimeStep argument is actually a number
|
||||
{
|
||||
error("riGetWellCells: The last argument must be a timestep index.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
// Setup the argument list
|
||||
|
||||
int caseId = -1;
|
||||
std::string wellName = "UNDEFINED";
|
||||
int requestedTimeStep = -1;
|
||||
|
||||
if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value();
|
||||
if (argIndices[1] >= 0) wellName = args(argIndices[1]).char_matrix_value().row_as_string(0);
|
||||
if (argIndices[2] >= 0) requestedTimeStep = args(argIndices[2]).int_value();
|
||||
|
||||
if (wellName == "UNDEFINED")
|
||||
{
|
||||
error("riGetWellCells: The argument must be a text containing the well name.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
if (requestedTimeStep == -1)
|
||||
{
|
||||
error("riGetWellCells: The last argument must be a timestep index (1 - timestepCount).\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
std::vector<int> cellIs, cellJs, cellKs;
|
||||
std::vector<int> gridIndices;
|
||||
std::vector<int> cellStatuses;
|
||||
std::vector<int> branchIds;
|
||||
std::vector<int> segmentIds;
|
||||
|
||||
getWellCells( cellIs, cellJs, cellKs,
|
||||
gridIndices,
|
||||
cellStatuses,
|
||||
branchIds,
|
||||
segmentIds,
|
||||
"127.0.0.1", riOctavePlugin::portNumber(),
|
||||
caseId, QString::fromStdString(wellName), requestedTimeStep);
|
||||
|
||||
size_t cellCount = cellIs.size();
|
||||
|
||||
if (cellJs.size() != cellCount
|
||||
|| cellKs.size() != cellCount
|
||||
|| gridIndices.size() != cellCount
|
||||
|| cellStatuses.size() != cellCount
|
||||
|| branchIds.size() != cellCount
|
||||
|| segmentIds.size() != cellCount )
|
||||
{
|
||||
error("riGetWellCells: Inconsistent data received from ResInsight.\n");
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
Cell cellIscv (cellCount, 1);
|
||||
Cell cellJscv (cellCount, 1);
|
||||
Cell cellKscv (cellCount, 1);
|
||||
Cell gridIndicescv (cellCount, 1);
|
||||
Cell cellStatusescv (cellCount, 1);
|
||||
Cell branchIdscv (cellCount, 1);
|
||||
Cell segmentIdscv (cellCount, 1);
|
||||
|
||||
for (size_t i = 0; i < cellCount; i++)
|
||||
{
|
||||
cellIscv (i) = cellIs [i];
|
||||
cellJscv (i) = cellJs [i];
|
||||
cellKscv (i) = cellKs [i];
|
||||
gridIndicescv (i) = gridIndices [i];
|
||||
cellStatusescv (i) = cellStatuses[i];
|
||||
branchIdscv (i) = branchIds [i];
|
||||
segmentIdscv (i) = segmentIds [i];
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::wellCellInfo_I, cellIscv );
|
||||
m.assign(riOctavePlugin::wellCellInfo_J, cellJscv );
|
||||
m.assign(riOctavePlugin::wellCellInfo_K, cellKscv );
|
||||
m.assign(riOctavePlugin::wellCellInfo_GridIndex , gridIndicescv );
|
||||
m.assign(riOctavePlugin::wellCellInfo_CellStatus, cellStatusescv);
|
||||
m.assign(riOctavePlugin::wellCellInfo_BranchId, branchIdscv );
|
||||
m.assign(riOctavePlugin::wellCellInfo_SegmentId, segmentIdscv );
|
||||
|
||||
return octave_value(m);
|
||||
|
||||
}
|
||||
|
||||
126
Octave/OctavePlugin/riGetWellNames.cpp
Normal file
126
Octave/OctavePlugin/riGetWellNames.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getWellNames(std::vector<QString>& wellNames, 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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command;
|
||||
command += QString("GetWellNames") + " " + 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: %s",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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 wellCount;
|
||||
socketStream >> wellCount;
|
||||
|
||||
QString wellName;
|
||||
|
||||
for (size_t i = 0; i < wellCount; i++)
|
||||
{
|
||||
socketStream >> wellName;
|
||||
|
||||
wellNames.push_back(wellName);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetWellNames, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetWellNames([CaseId]) \n"
|
||||
"\n"
|
||||
"This function returns the names of all the wells in the case as a Vector of strings.\n"
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin > 1)
|
||||
{
|
||||
error("riGetWellNames: Too many arguments, this function takes one optional arguments.\n");
|
||||
print_usage();
|
||||
}
|
||||
else if (nargout != 1)
|
||||
{
|
||||
error("riGetWellNames: 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> wellNames;
|
||||
|
||||
getWellNames(wellNames, "127.0.0.1", riOctavePlugin::portNumber(), argCaseId);
|
||||
|
||||
size_t caseCount = wellNames.size();
|
||||
|
||||
// Create cells with N items for each field in the data structure
|
||||
|
||||
string_vector octaveWellNames;
|
||||
for (size_t i = 0; i < caseCount; i++)
|
||||
{
|
||||
octaveWellNames.append(wellNames[i].toStdString());
|
||||
}
|
||||
|
||||
return octave_value(Cell(octaveWellNames));
|
||||
}
|
||||
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
206
Octave/OctavePlugin/riGetWellStatus.cpp
Normal file
206
Octave/OctavePlugin/riGetWellStatus.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
#include <QtNetwork>
|
||||
#include <octave/oct.h>
|
||||
#include <octave/oct-map.h>
|
||||
|
||||
#include "riSettings.h"
|
||||
|
||||
void getWellStatus(std::vector<QString>& wellTypes, std::vector<int>& wellStatuses, const QString &hostName, quint16 port,
|
||||
const qint64& caseId, const QString& wellName, const int32NDArray& requestedTimeSteps)
|
||||
{
|
||||
QString serverName = hostName;
|
||||
quint16 serverPort = port;
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(serverName, serverPort);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create command and send it:
|
||||
|
||||
QString command;
|
||||
command += QString("GetWellStatus") + " " + QString::number(caseId) + " " + wellName;
|
||||
|
||||
for (int i = 0; i < requestedTimeSteps.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() -1) command += " ";
|
||||
}
|
||||
|
||||
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: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
quint64 byteCount;
|
||||
socketStream >> byteCount;
|
||||
|
||||
while (socket.bytesAvailable() < (int)(byteCount))
|
||||
{
|
||||
if (!socket.waitForReadyRead(riOctavePlugin::longTimeOutMilliSecs))
|
||||
{
|
||||
error("Waiting for data: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
quint64 timeStepCount;
|
||||
socketStream >> timeStepCount;
|
||||
|
||||
QString wellType;
|
||||
qint32 wellStatus;
|
||||
|
||||
for (size_t i = 0; i < timeStepCount; i++)
|
||||
{
|
||||
socketStream >> wellType;
|
||||
socketStream >> wellStatus;
|
||||
|
||||
wellTypes.push_back(wellType);
|
||||
wellStatuses.push_back(wellStatus);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN_DLD (riGetWellStatus, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" riGetWellStatus ([CaseId], WellName, [RequestedTimeSteps]) \n"
|
||||
"\n"
|
||||
"This function returns the status information for a specified well for each\n"
|
||||
"requested time step as a vector of Structures. \n"
|
||||
"The Structure is defined as:\n"
|
||||
"WellStatus { \n"
|
||||
" WellType = string # \"Producer\", \"OilInjector\", \"WaterInjector\", \"GasInjector\", \"NotDefined\" \n"
|
||||
" WellStatus = int # is either 0 or 1, meaning the well is shut or open respectively.\n"
|
||||
"}\n"
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used.\n"
|
||||
|
||||
)
|
||||
{
|
||||
if (nargout != 1)
|
||||
{
|
||||
error("riGetWellStatus: Wrong number of output arguments, this function requires one output argument.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
int nargin = args.length ();
|
||||
if (nargin < 1)
|
||||
{
|
||||
error("riGetWellStatus: Too few arguments, this function needs at least the well name as input.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
if (nargin > 3)
|
||||
{
|
||||
error("riGetWellStatus: Too many arguments, this function takes at most three arguments.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
std::vector<int> argIndices;
|
||||
argIndices.push_back(0); // caseId
|
||||
argIndices.push_back(1); // WellName
|
||||
argIndices.push_back(2); // TimeSteps
|
||||
|
||||
// Check if we do not have a CaseId:
|
||||
if (args(argIndices[0]).is_string()) // Check if first argument is a text. If it is, the caseId is missing
|
||||
{
|
||||
argIndices[0] = -1;
|
||||
for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have a Requested TimeSteps
|
||||
int lastArgumentIndex = argIndices[2] ;
|
||||
if (!(nargin > argIndices[2] && (args(argIndices[2]).is_matrix_type() || riOctavePlugin::isOctaveValueNumeric(args(argIndices[2])))))
|
||||
{
|
||||
argIndices[2] = -1;
|
||||
}
|
||||
|
||||
// Check if we have more arguments than we should
|
||||
if (nargin > lastArgumentIndex + 1)
|
||||
{
|
||||
error("riGetWellStatus: Unexpected argument at the end.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
// Setup the argument list
|
||||
|
||||
NDArray propertyFrames;
|
||||
int caseId = -1;
|
||||
std::string wellName = "UNDEFINED";
|
||||
int32NDArray requestedTimeSteps;
|
||||
|
||||
if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value();
|
||||
if (argIndices[1] >= 0) wellName = args(argIndices[1]).char_matrix_value().row_as_string(0);
|
||||
if (argIndices[2] >= 0) requestedTimeSteps = args(argIndices[2]).int32_array_value();
|
||||
|
||||
if (wellName == "UNDEFINED")
|
||||
{
|
||||
error("riGetWellStatus: The argument must be a text containing the well name.\n");
|
||||
print_usage();
|
||||
return octave_value();
|
||||
}
|
||||
|
||||
std::vector<QString> wellType;
|
||||
std::vector<int> wellStatus;
|
||||
|
||||
getWellStatus(wellType, wellStatus, "127.0.0.1", riOctavePlugin::portNumber(), caseId, QString::fromStdString(wellName), requestedTimeSteps);
|
||||
|
||||
size_t caseCount = wellType.size();
|
||||
|
||||
if (wellType.size() != wellStatus.size() )
|
||||
{
|
||||
error("riGetWellStatus: Inconsistent data received from ResInsight.\n");
|
||||
return octave_value();
|
||||
}
|
||||
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) = wellType[i].toLatin1().data();
|
||||
cellValuesC(i) = wellStatus[i];
|
||||
}
|
||||
|
||||
// Build a map between the field name and field cell values
|
||||
|
||||
octave_map m;
|
||||
|
||||
m.assign(riOctavePlugin::wellStatus_WellType, cellValuesB);
|
||||
m.assign(riOctavePlugin::wellStatus_WellStatus, cellValuesC);
|
||||
|
||||
return octave_value(m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
226
Octave/OctavePlugin/riSetActiveCellProperty.cpp
Normal file
226
Octave/OctavePlugin/riSetActiveCellProperty.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
#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
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif //WIN32
|
||||
|
||||
|
||||
void setEclipseProperty(const Matrix& propertyFrames, const QString &hostName, quint16 port,
|
||||
const qint64& caseId, QString propertyName, const int32NDArray& requestedTimeSteps, QString porosityModel)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(hostName, port);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",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 += "SetActiveCellProperty " + QString::number(caseId) + " " + propertyName + " " + porosityModel;
|
||||
|
||||
for (int i = 0; i < requestedTimeSteps.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() -1) command += " ";
|
||||
}
|
||||
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
socketStream << (qint64)(cmdBytes.size());
|
||||
socket.write(cmdBytes);
|
||||
|
||||
// Write property data header
|
||||
|
||||
dim_vector mxDims = propertyFrames.dims();
|
||||
|
||||
qint64 cellCount = mxDims.elem(0);
|
||||
qint64 timeStepCount = mxDims.elem(1);
|
||||
qint64 timeStepByteCount = cellCount * sizeof(double);
|
||||
|
||||
socketStream << (qint64)(timeStepCount);
|
||||
socketStream << (qint64)timeStepByteCount;
|
||||
|
||||
#if OCTAVE_MAJOR_VERSION > 6
|
||||
auto internalData = propertyFrames.data();
|
||||
#else
|
||||
const double* internalData = propertyFrames.fortran_vec();
|
||||
#endif
|
||||
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepByteCount*timeStepCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
octave_stdout << errorMessages[i].toStdString();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QString tmp = QString("riSetActiveCellProperty : 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() << " Active Cells : " << cellCount << " 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("riSetActiveCellProperty : 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 (riSetActiveCellProperty, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"\triSetActiveCellProperty( Matrix[numActiveCells][numTimeSteps], [CaseId], PropertyName, [TimeStepIndices], [PorosityModel = \"Matrix\"|\"Fracture\"] ) \n"
|
||||
"\n"
|
||||
"Interprets the supplied matrix as a property set defined for the active cells 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."
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used."
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin < 2)
|
||||
{
|
||||
error("riSetActiveCellProperty: Too few arguments. The data matrix and the name of the property requested is neccesary\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
if (nargin > 5)
|
||||
{
|
||||
error("riSetActiveCellProperty: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
Matrix propertyFrames = args(0).matrix_value();
|
||||
|
||||
dim_vector mxDims = propertyFrames.dims();
|
||||
if (mxDims.length() != 2)
|
||||
{
|
||||
error("riSetActiveCellProperty: The supplied Data Matrix must have two dimensions: NumActiveCells*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);
|
||||
argIndices.push_back(4);
|
||||
|
||||
// Check if we have a CaseId:
|
||||
if (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[1])))
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
// Check if we have a PorosityModel
|
||||
|
||||
int lastArgumentIndex = argIndices[4] ;
|
||||
if (!(nargin > argIndices[4] && args(argIndices[4]).is_string()))
|
||||
{
|
||||
argIndices[4] = -1;
|
||||
for (size_t aIdx = 5; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have more arguments than we should
|
||||
if (nargin > lastArgumentIndex + 1)
|
||||
{
|
||||
error("riSetActiveCellProperty: Unexpected argument after the PorosityModel.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
|
||||
int caseId = -1;
|
||||
std::string propertyName = "UNDEFINED";
|
||||
int32NDArray requestedTimeSteps;
|
||||
std::string porosityModel = "Matrix";
|
||||
|
||||
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 (argIndices[4] >= 0) porosityModel = args(argIndices[4]).string_value();
|
||||
|
||||
if (requestedTimeSteps.numel())
|
||||
{
|
||||
|
||||
int timeStepCount = mxDims.elem(1);
|
||||
if (requestedTimeSteps.numel() != timeStepCount)
|
||||
{
|
||||
error("riSetActiveCellProperty: The number of timesteps in the input matrix must match the number of timesteps in the TimeStepIndices array.");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
}
|
||||
|
||||
if (porosityModel != "Matrix" && porosityModel != "Fracture")
|
||||
{
|
||||
error("riSetActiveCellProperty: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
setEclipseProperty(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), caseId, propertyName.c_str(), requestedTimeSteps, porosityModel.c_str());
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
265
Octave/OctavePlugin/riSetGridProperty.cpp
Normal file
265
Octave/OctavePlugin/riSetGridProperty.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
#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
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif //WIN32
|
||||
|
||||
|
||||
void setEclipseProperty(const NDArray& propertyFrames, const QString &hostName, quint16 port,
|
||||
const qint64& caseId, const qint64& gridIndex, QString propertyName, const int32NDArray& timeStepIndices, QString porosityModel)
|
||||
{
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(hostName, port);
|
||||
|
||||
if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs))
|
||||
{
|
||||
error("Connection: %s",socket.errorString().toLatin1().data());
|
||||
return;
|
||||
}
|
||||
|
||||
QDataStream socketStream(&socket);
|
||||
socketStream.setVersion(riOctavePlugin::qtDataStreamVersion);
|
||||
|
||||
// Create command as a string with arguments , and send it:
|
||||
|
||||
QString command = QString("SetGridProperty %1 %2 %3 %4").arg(caseId).arg(gridIndex).arg(propertyName).arg(porosityModel);
|
||||
|
||||
for (int i = 0; i < timeStepIndices.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(timeStepIndices.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != timeStepIndices.numel() -1) command += " ";
|
||||
}
|
||||
|
||||
QByteArray cmdBytes = command.toLatin1();
|
||||
|
||||
socketStream << (qint64)(cmdBytes.size());
|
||||
socket.write(cmdBytes);
|
||||
|
||||
// Write property data header
|
||||
|
||||
dim_vector mxDims = propertyFrames.dims();
|
||||
|
||||
qint64 cellCountI = mxDims.elem(0);
|
||||
qint64 cellCountJ = mxDims.elem(1);
|
||||
qint64 cellCountK = mxDims.elem(2);
|
||||
|
||||
qint64 timeStepCount = 0;
|
||||
if (mxDims.length() > 3)
|
||||
{
|
||||
timeStepCount = mxDims.elem(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeStepCount = 1;
|
||||
}
|
||||
|
||||
qint64 singleTimeStepByteCount = cellCountI * cellCountJ * cellCountK * sizeof(double);
|
||||
|
||||
//octave_stdout << " Cell count I: " << cellCountI << " Cell count J: " << cellCountJ << " Cell count K: " << cellCountK << std::endl;
|
||||
//octave_stdout << " Time step count: " << timeStepCount << std::endl;
|
||||
|
||||
socketStream << (qint64)(cellCountI);
|
||||
socketStream << (qint64)(cellCountJ);
|
||||
socketStream << (qint64)(cellCountK);
|
||||
socketStream << (qint64)(timeStepCount);
|
||||
socketStream << (qint64)singleTimeStepByteCount;
|
||||
|
||||
#if OCTAVE_MAJOR_VERSION > 6
|
||||
auto internalData = propertyFrames.data();
|
||||
#else
|
||||
const double* internalData = propertyFrames.fortran_vec();
|
||||
#endif
|
||||
|
||||
QStringList errorMessages;
|
||||
if (!RiaSocketDataTransfer::writeBlockDataToSocket(&socket, (const char *)internalData, timeStepCount*singleTimeStepByteCount, errorMessages))
|
||||
{
|
||||
for (int i = 0; i < errorMessages.size(); i++)
|
||||
{
|
||||
octave_stdout << errorMessages[i].toStdString();
|
||||
}
|
||||
|
||||
size_t cellCount = cellCountI * cellCountJ * cellCountK;
|
||||
error("riSetGridProperty : Was not able to write the proper amount of data to ResInsight:");
|
||||
octave_stdout << " Cell count : " << cellCount << "Time steps : " << timeStepCount << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QString tmp = QString("riSetGridProperty : Wrote %1").arg(propertyName);
|
||||
|
||||
if (caseId == -1)
|
||||
{
|
||||
tmp += QString(" to current case,");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp += QString(" to case with Id = %1,").arg(caseId);
|
||||
}
|
||||
|
||||
tmp += QString(" grid index: %1, ").arg(gridIndex);
|
||||
|
||||
octave_stdout << tmp.toStdString() << " Time steps : " << timeStepCount << std::endl;
|
||||
|
||||
while(socket.bytesToWrite() && socket.state() == QAbstractSocket::ConnectedState)
|
||||
{
|
||||
// octave_stdout << "Bytes to write: " << socket.bytesToWrite() << std::endl << std::flush;
|
||||
socket.waitForBytesWritten(riOctavePlugin::shortTimeOutMilliSecs);
|
||||
OCTAVE_QUIT;
|
||||
}
|
||||
|
||||
if (socket.bytesToWrite() && socket.state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
error("riSetGridProperty : ResInsight refused to accept the data. Maybe the dimensions or porosity model is wrong.\n");
|
||||
}
|
||||
|
||||
#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 (riSetGridProperty, args, nargout,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"\triSetGridProperty( Matrix[numI][numJ][numK][numTimeSteps], [CaseId], GridIndex, PropertyName, [TimeStepIndices], [PorosityModel = \"Matrix\"|\"Fracture\"] ) \n"
|
||||
"\n"
|
||||
"Interprets the supplied matrix as a property set defined for all cells in one of the grids in a case, and puts the data into ResInsight as a \"Generated\" property with the name \"PropertyName\".\n"
|
||||
"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."
|
||||
"If the CaseId is not defined, ResInsight’s Current Case is used.\n"
|
||||
)
|
||||
{
|
||||
int nargin = args.length ();
|
||||
if (nargin < 2)
|
||||
{
|
||||
error("riSetGridProperty: Too few arguments, required input parameters are the data matrix, grid index and property name.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
if (nargin > 6)
|
||||
{
|
||||
error("riSetGridProperty: Too many arguments.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
NDArray propertyFrames = args(0).array_value();
|
||||
|
||||
|
||||
dim_vector mxDims = propertyFrames.dims();
|
||||
if (!(mxDims.length() == 3 || mxDims.length() == 4))
|
||||
{
|
||||
error("riSetGridProperty: The supplied Data Matrix must have three dimensions (numI*numJ*numK*1) or four dimensions (numI*numJ*numK*numTimeSteps)");
|
||||
print_usage();
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
std::vector<int> argIndices;
|
||||
argIndices.push_back(0); // Array data
|
||||
argIndices.push_back(1); // Case Id
|
||||
argIndices.push_back(2); // GridIndex
|
||||
argIndices.push_back(3); // Property name
|
||||
argIndices.push_back(4); // Time step indices
|
||||
argIndices.push_back(5); // Porosity model
|
||||
|
||||
// Check that the second argument is an integer
|
||||
if (!args(argIndices[1]).is_real_scalar()) // Check if second argument is an int. If it is
|
||||
{
|
||||
error("riSetGridProperty: The GridIndex argument is missing");
|
||||
print_usage();
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
// Check if we do not have a CaseId:
|
||||
if (args(argIndices[2]).is_string()) // Check if second argument is a text. If it is, the caseid is missing
|
||||
{
|
||||
argIndices[1] = -1;
|
||||
for (size_t aIdx = 2; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have a Requested TimeSteps
|
||||
|
||||
if (!(nargin > argIndices[4] && args(argIndices[4]).is_matrix_type() && !args(argIndices[4]).is_string()))
|
||||
{
|
||||
argIndices[4] = -1;
|
||||
for (size_t aIdx = 5; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have a PorosityModel
|
||||
|
||||
int lastArgumentIndex = argIndices[5] ;
|
||||
if (!(nargin > argIndices[5] && args(argIndices[5]).is_string()))
|
||||
{
|
||||
argIndices[5] = -1;
|
||||
for (size_t aIdx = 6; aIdx < argIndices.size(); ++aIdx)
|
||||
--argIndices[aIdx];
|
||||
}
|
||||
|
||||
// Check if we have more arguments than we should
|
||||
if (nargin > lastArgumentIndex + 1)
|
||||
{
|
||||
error("riSetGridProperty: Unexpected argument after the PorosityModel.\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
|
||||
int caseId = -1;
|
||||
int gridIndex = 0;
|
||||
std::string propertyName = "UNDEFINED";
|
||||
int32NDArray timeStepIndices;
|
||||
std::string porosityModel = "Matrix";
|
||||
|
||||
if (argIndices[1] >= 0) caseId = args(argIndices[1]).int_value();
|
||||
if (argIndices[2] >= 0) gridIndex = args(argIndices[2]).int_value();
|
||||
if (argIndices[3] >= 0) propertyName = args(argIndices[3]).char_matrix_value().row_as_string(0);
|
||||
if (argIndices[4] >= 0) timeStepIndices = args(argIndices[4]).int32_array_value();
|
||||
if (argIndices[5] >= 0) porosityModel = args(argIndices[5]).string_value();
|
||||
|
||||
if (timeStepIndices.numel() > 1)
|
||||
{
|
||||
if (mxDims.length() == 3)
|
||||
{
|
||||
error("riSetGridProperty: The input matrix has three dimensions, but there are more than one time step in [TimeStepIndices]. If more than one time step is defined, the data matrix must be 4D.");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
int timeStepCount = mxDims.elem(3);
|
||||
if (timeStepIndices.numel() != timeStepCount)
|
||||
{
|
||||
error("riSetGridProperty: 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 ();
|
||||
}
|
||||
}
|
||||
|
||||
if (porosityModel != "Matrix" && porosityModel != "Fracture")
|
||||
{
|
||||
error("riSetGridProperty: The value for \"PorosityModel\" is unknown. Please use either \"Matrix\" or \"Fracture\"\n");
|
||||
print_usage();
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
setEclipseProperty(propertyFrames, "127.0.0.1", riOctavePlugin::portNumber(), caseId, gridIndex, propertyName.c_str(), timeStepIndices, porosityModel.c_str());
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
193
Octave/OctavePlugin/riSetNNCProperty.cpp
Normal file
193
Octave/OctavePlugin/riSetNNCProperty.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#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
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif //WIN32
|
||||
|
||||
|
||||
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: %s",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.numel(); ++i)
|
||||
{
|
||||
if (i == 0) command += " ";
|
||||
command += QString::number(static_cast<int>(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based
|
||||
if (i != requestedTimeSteps.numel() -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();
|
||||
|
||||
|
||||
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 (!riOctavePlugin::isOctaveValueNumeric(args(argIndices[1])))
|
||||
{
|
||||
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.numel())
|
||||
{
|
||||
|
||||
int timeStepCount = mxDims.elem(1);
|
||||
if (requestedTimeSteps.numel() != 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", riOctavePlugin::portNumber(), caseId, propertyName.c_str(), requestedTimeSteps);
|
||||
|
||||
return octave_value_list ();
|
||||
}
|
||||
|
||||
91
Octave/OctavePlugin/riSettings.h
Normal file
91
Octave/OctavePlugin/riSettings.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "../../ApplicationLibCode/SocketInterface/RiaSocketServerDefines.h"
|
||||
|
||||
namespace riOctavePlugin
|
||||
{
|
||||
const int connectTimeOutMilliSecs = 5000;
|
||||
const int shortTimeOutMilliSecs = 1000;
|
||||
const int longTimeOutMilliSecs = 6000000;
|
||||
|
||||
const int socketMaxByteCount = 100000;
|
||||
|
||||
// Octave data structure : CaseInfo
|
||||
char caseInfo_CaseId[] = "CaseId";
|
||||
char caseInfo_CaseName[] = "CaseName";
|
||||
char caseInfo_CaseType[] = "CaseType";
|
||||
char caseInfo_CaseGroupId[] = "CaseGroupId";
|
||||
|
||||
// Octave data structure: PropertyInfo
|
||||
char propertyInfo_PropName[] = "PropName";
|
||||
char propertyInfo_PropType[] = "PropType";
|
||||
|
||||
// Octave data structure: WellStatus
|
||||
char wellStatus_WellType[] = "WellType";
|
||||
char wellStatus_WellStatus[] = "WellStatus";
|
||||
|
||||
// Octave data structure : CaseGroupInfo
|
||||
char caseGroupInfo_CaseGroupId[] = "CaseGroupId";
|
||||
char caseGroupInfo_CaseGroupName[] = "CaseGroupName";
|
||||
|
||||
// Octave data structure : WellCellInfo
|
||||
char wellCellInfo_I[] = "I";
|
||||
char wellCellInfo_J[] = "J";
|
||||
char wellCellInfo_K[] = "K";
|
||||
char wellCellInfo_GridIndex [] = "GridIndex";
|
||||
char wellCellInfo_CellStatus[] = "CellStatus";
|
||||
char wellCellInfo_BranchId[] = "BranchId";
|
||||
char wellCellInfo_SegmentId[] = "SegmentId";
|
||||
|
||||
// Octave data structure : TimeStepDate
|
||||
char timeStepDate_Year[] = "Year";
|
||||
char timeStepDate_Month[] = "Month";
|
||||
char timeStepDate_Day[] = "Day";
|
||||
char timeStepDate_Hour[] = "Hour";
|
||||
char timeStepDate_Minute[] = "Minute";
|
||||
char timeStepDate_Second[] = "Second";
|
||||
|
||||
// Octave data structure : CellIndex
|
||||
char cellIndex_gridIndex[] = "GridIndex";
|
||||
char cellIndex_I[] = "I";
|
||||
char cellIndex_J[] = "J";
|
||||
char cellIndex_K[] = "K";
|
||||
|
||||
bool isOctaveValueNumeric(const octave_value& value)
|
||||
{
|
||||
#if (OCTAVE_MAJOR_VERSION > 4 || (OCTAVE_MAJOR_VERSION == 4 && OCTAVE_MINOR_VERSION >= 4))
|
||||
return value.isnumeric();
|
||||
#else
|
||||
return value.is_numeric_type();
|
||||
#endif
|
||||
}
|
||||
|
||||
int portNumber()
|
||||
{
|
||||
QString portStr = getenv(riOctavePlugin::portNumberKey().data());
|
||||
if (!portStr.isEmpty())
|
||||
{
|
||||
return portStr.toInt();
|
||||
}
|
||||
|
||||
return riOctavePlugin::defaultPortNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
205
Octave/cmake/FindOctave.cmake
Normal file
205
Octave/cmake/FindOctave.cmake
Normal file
@@ -0,0 +1,205 @@
|
||||
# - Find Octave
|
||||
# GNU Octave is a high-level interpreted language, primarily intended for numerical computations.
|
||||
# available at http://www.gnu.org/software/octave/
|
||||
#
|
||||
# This module defines:
|
||||
# OCTAVE_EXECUTABLE - octave interpreter
|
||||
# OCTAVE_INCLUDE_DIRS - include path for mex.h, mexproto.h
|
||||
# OCTAVE_LIBRARIES - required libraries: octinterp, octave, cruft
|
||||
# OCTAVE_OCTINTERP_LIBRARY - path to the library octinterp
|
||||
# OCTAVE_OCTAVE_LIBRARY - path to the library octave
|
||||
# OCTAVE_CRUFT_LIBRARY - path to the library cruft
|
||||
# OCTAVE_VERSION_STRING - octave version string
|
||||
# OCTAVE_MAJOR_VERSION - major version
|
||||
# OCTAVE_MINOR_VERSION - minor version
|
||||
# OCTAVE_PATCH_VERSION - patch version
|
||||
# OCTAVE_OCT_FILE_DIR - object files that will be dynamically loaded
|
||||
# OCTAVE_OCT_LIB_DIR - oct libraries
|
||||
# OCTAVE_ROOT_DIR - octave prefix
|
||||
# OCTAVE_M_SITE_DIR - .m files site dir
|
||||
# OCTAVE_OCT_SITE_DIR - .oct files site dir
|
||||
#
|
||||
# The macro octave_add_oct allows to create compiled modules.
|
||||
# octave_add_oct (target_name
|
||||
# [SOURCES] source1 [source2 ...]
|
||||
# [LINK_LIBRARIES lib1 [lib2 ...]]
|
||||
# [EXTENSION ext]
|
||||
#)
|
||||
#
|
||||
# To install it, you can the use the variable OCTAVE_OCT_FILE_DIR as follow:
|
||||
# file (RELATIVE_PATH PKG_OCTAVE_OCT_SITE_DIR ${OCTAVE_ROOT_DIR} ${OCTAVE_OCT_SITE_DIR})
|
||||
# install (
|
||||
# TARGETS target_name
|
||||
# DESTINATION ${PKG_OCTAVE_OCT_SITE_DIR}
|
||||
#)
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2013, Julien Schueller
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# The views and conclusions contained in the software and documentation are those
|
||||
# of the authors and should not be interpreted as representing official policies,
|
||||
# either expressed or implied, of the FreeBSD Project.
|
||||
#=============================================================================
|
||||
|
||||
find_program(OCTAVE_CONFIG_EXECUTABLE
|
||||
NAMES octave-config
|
||||
)
|
||||
|
||||
|
||||
if (OCTAVE_CONFIG_EXECUTABLE)
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -p OCTAVE_HOME
|
||||
OUTPUT_VARIABLE OCTAVE_ROOT_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} --m-site-dir
|
||||
OUTPUT_VARIABLE OCTAVE_M_SITE_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} --oct-site-dir
|
||||
OUTPUT_VARIABLE OCTAVE_OCT_SITE_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -p BINDIR
|
||||
OUTPUT_VARIABLE OCTAVE_BIN_PATHS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -p OCTINCLUDEDIR
|
||||
OUTPUT_VARIABLE OCTAVE_INCLUDE_PATHS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -p OCTLIBDIR
|
||||
OUTPUT_VARIABLE OCTAVE_LIBRARIES_PATHS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -p OCTFILEDIR
|
||||
OUTPUT_VARIABLE OCTAVE_OCT_FILE_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -p OCTLIBDIR
|
||||
OUTPUT_VARIABLE OCTAVE_OCT_LIB_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process (COMMAND ${OCTAVE_CONFIG_EXECUTABLE} -v
|
||||
OUTPUT_VARIABLE OCTAVE_VERSION_STRING
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if (OCTAVE_VERSION_STRING)
|
||||
string (REGEX REPLACE "([0-9]+)\\..*" "\\1" OCTAVE_MAJOR_VERSION ${OCTAVE_VERSION_STRING})
|
||||
string (REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" OCTAVE_MINOR_VERSION ${OCTAVE_VERSION_STRING})
|
||||
string (REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" OCTAVE_PATCH_VERSION ${OCTAVE_VERSION_STRING})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
find_program(OCTAVE_EXECUTABLE
|
||||
HINTS ${OCTAVE_BIN_PATHS}
|
||||
NAMES octave
|
||||
)
|
||||
|
||||
find_program(OCTAVE_MKOCTFILE
|
||||
HINTS ${OCTAVE_BIN_PATHS}
|
||||
NAMES mkoctfile
|
||||
)
|
||||
|
||||
find_library(OCTAVE_OCTINTERP_LIBRARY
|
||||
NAMES octinterp liboctinterp
|
||||
HINTS ${OCTAVE_LIBRARIES_PATHS}
|
||||
)
|
||||
find_library(OCTAVE_OCTAVE_LIBRARY
|
||||
NAMES octave liboctave
|
||||
HINTS ${OCTAVE_LIBRARIES_PATHS}
|
||||
)
|
||||
find_library(OCTAVE_CRUFT_LIBRARY
|
||||
NAMES cruft libcruft
|
||||
HINTS ${OCTAVE_LIBRARIES_PATHS}
|
||||
)
|
||||
|
||||
set (OCTAVE_LIBRARIES ${OCTAVE_OCTINTERP_LIBRARY})
|
||||
list (APPEND OCTAVE_LIBRARIES ${OCTAVE_OCTAVE_LIBRARY})
|
||||
if (OCTAVE_CRUFT_LIBRARY)
|
||||
list (APPEND OCTAVE_LIBRARIES ${OCTAVE_CRUFT_LIBRARY})
|
||||
endif ()
|
||||
|
||||
find_path (OCTAVE_INCLUDE_DIR
|
||||
NAMES octave/oct.h
|
||||
PATHS "${OCTAVE_INCLUDE_PATHS}/.."
|
||||
)
|
||||
|
||||
set (OCTAVE_INCLUDE_DIRS ${OCTAVE_INCLUDE_DIR} ${OCTAVE_INCLUDE_DIR}/octave)
|
||||
|
||||
|
||||
macro (octave_add_oct FUNCTIONNAME)
|
||||
set (_CMD SOURCES)
|
||||
set (_SOURCES)
|
||||
set (_LINK_LIBRARIES)
|
||||
set (_EXTENSION)
|
||||
set (_OCT_EXTENSION oct)
|
||||
foreach (_ARG ${ARGN})
|
||||
if (${_ARG} MATCHES SOURCES)
|
||||
set (_CMD SOURCES)
|
||||
elseif (${_ARG} MATCHES LINK_LIBRARIES)
|
||||
set (_CMD LINK_LIBRARIES)
|
||||
elseif (${_ARG} MATCHES EXTENSION)
|
||||
set (_CMD EXTENSION)
|
||||
else ()
|
||||
if (${_CMD} MATCHES SOURCES)
|
||||
list (APPEND _SOURCES "${_ARG}")
|
||||
elseif (${_CMD} MATCHES LINK_LIBRARIES)
|
||||
list (APPEND _LINK_LIBRARIES "${_ARG}")
|
||||
elseif (${_CMD} MATCHES EXTENSION)
|
||||
set (_OCT_EXTENSION ${_ARG})
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
add_library (${FUNCTIONNAME} SHARED ${_SOURCES})
|
||||
target_link_libraries (${FUNCTIONNAME} ${OCTAVE_LIBRARIES} ${_LINK_LIBRARIES})
|
||||
set_target_properties (${FUNCTIONNAME} PROPERTIES
|
||||
PREFIX ""
|
||||
SUFFIX ".${_OCT_EXTENSION}"
|
||||
)
|
||||
endmacro ()
|
||||
|
||||
|
||||
# handle REQUIRED and QUIET options
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (Octave REQUIRED_VARS OCTAVE_EXECUTABLE OCTAVE_ROOT_DIR OCTAVE_INCLUDE_DIRS OCTAVE_LIBRARIES VERSION_VAR OCTAVE_VERSION_STRING)
|
||||
|
||||
|
||||
mark_as_advanced (
|
||||
OCTAVE_OCT_FILE_DIR
|
||||
OCTAVE_OCT_LIB_DIR
|
||||
OCTAVE_OCTINTERP_LIBRARY
|
||||
OCTAVE_OCTAVE_LIBRARY
|
||||
OCTAVE_CRUFT_LIBRARY
|
||||
OCTAVE_LIBRARIES
|
||||
OCTAVE_INCLUDE_DIR
|
||||
OCTAVE_INCLUDE_DIRS
|
||||
OCTAVE_ROOT_DIR
|
||||
OCTAVE_VERSION_STRING
|
||||
OCTAVE_MAJOR_VERSION
|
||||
OCTAVE_MINOR_VERSION
|
||||
OCTAVE_PATCH_VERSION
|
||||
)
|
||||
|
||||
|
||||
20
Octave/cmake/cmake-format.py
Normal file
20
Octave/cmake/cmake-format.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# -----------------------------
|
||||
# Options effecting formatting.
|
||||
# See: https://github.com/cheshirekow/cmake_format
|
||||
# -----------------------------
|
||||
with section("format"):
|
||||
# How wide to allow formatted cmake files
|
||||
line_width = 80
|
||||
|
||||
# How many spaces to tab for indent
|
||||
tab_size = 2
|
||||
|
||||
# If true, separate flow control names from their parentheses with a space
|
||||
separate_ctrl_name_with_space = False
|
||||
|
||||
# If true, separate function names from parentheses with a space
|
||||
separate_fn_name_with_space = False
|
||||
|
||||
# If a statement is wrapped to more than one line, than dangle the closing
|
||||
# parenthesis on its own line.
|
||||
dangle_parens = True
|
||||
Reference in New Issue
Block a user