Add support for radial grids

* Update radial grid operations in submodule
* Optionally display cell center and cell corners when clicking on cell
* Add support for import of radial grids
* Modify node coordinates to match host cell
This commit is contained in:
Magne Sjaastad 2023-02-10 12:39:13 +01:00 committed by GitHub
parent 4615d0b524
commit b3a56a9353
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 611 additions and 19 deletions

View File

@ -77,6 +77,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RifRftSegment.h
${CMAKE_CURRENT_LIST_DIR}/RifPressureDepthTextFileReader.h
${CMAKE_CURRENT_LIST_DIR}/RifReaderPressureDepthData.h
${CMAKE_CURRENT_LIST_DIR}/RifOpmGridTools.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -155,6 +156,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RifRftSegment.cpp
${CMAKE_CURRENT_LIST_DIR}/RifPressureDepthTextFileReader.cpp
${CMAKE_CURRENT_LIST_DIR}/RifReaderPressureDepthData.cpp
${CMAKE_CURRENT_LIST_DIR}/RifOpmGridTools.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -0,0 +1,402 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RifOpmGridTools.h"
#include "RiaLogging.h"
#include "RiaWeightedMeanCalculator.h"
#include "RifReaderEclipseOutput.h"
#include "RigMainGrid.h"
#include "cvfGeometryTools.h"
#include "opm/io/eclipse/EGrid.hpp"
#include <algorithm>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOpmGridTools::importCoordinatesForRadialGrid( const std::string& gridFilePath, RigMainGrid* riMainGrid )
{
CAF_ASSERT( riMainGrid );
try
{
bool isRadialGridPresent = false;
{
// Open the file and only check "GRIDHEAD" to be able to do an early return if no radial grids are present
Opm::EclIO::EclFile gridFile( gridFilePath );
auto arrays = gridFile.getList();
int index = 0;
for ( const auto& [name, arrayType, arraySize] : arrays )
{
if ( name == "GRIDHEAD" )
{
auto gridhead = gridFile.get<int>( index );
if ( gridhead.size() > 26 && gridhead[26] > 0 )
{
isRadialGridPresent = true;
break;
}
}
index++;
}
}
if ( !isRadialGridPresent ) return;
Opm::EclIO::EGrid opmMainGrid( gridFilePath );
if ( opmMainGrid.is_radial() )
{
transferCoordinates( opmMainGrid, opmMainGrid, riMainGrid, riMainGrid );
}
auto lgrNames = opmMainGrid.list_of_lgrs();
for ( const auto& lgrName : lgrNames )
{
Opm::EclIO::EGrid opmLgrGrid( gridFilePath, lgrName );
if ( opmLgrGrid.is_radial() )
{
for ( size_t i = 0; i < riMainGrid->gridCount(); i++ )
{
auto riLgrGrid = riMainGrid->gridByIndex( i );
if ( riLgrGrid->gridName() == lgrName )
{
transferCoordinates( opmMainGrid, opmLgrGrid, riMainGrid, riLgrGrid );
}
}
}
}
}
catch ( ... )
{
RiaLogging::warning( QString( "Failed to open grid case for import of radial coordinates : %1" )
.arg( QString::fromStdString( gridFilePath ) ) );
}
}
//--------------------------------------------------------------------------------------------------
//
// A radial grid is defined by a center point and a set of cylindrical coordinates. The coordinates at the
// outer edge of the grid are defined as a circle, and nodes do not match the geometry of the host cell.
// Adjust the coordinates for these cells to make sure the grid is continuous
//
// Cylindrical coordinates from file gives grid cell with a radial grid in center
// -------------
// | /---- \ |
// | / - \ |
// || | | ||
// | \ - / |
// | \-----/ |
// -------------
//
// Adjusted coordinates to match the grid geometry of host cell. The coordinates for the inner nodes are
// unchanged.
// -------------
// ||---------||
// || - ||
// || | | ||
// || - ||
// ||---------||
// -------------
// 1. If the node is at the outer edge of the radial grid, find the host cell
// 2. Find the closest point on the pillars of the host cell
// 3. Find the closest point on this pillar, and use this point as the adjusted coordinate for the node
//
//--------------------------------------------------------------------------------------------------
void RifOpmGridTools::transferCoordinates( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
RigMainGrid* riMainGrid,
RigGridBase* riGrid )
{
size_t cellCount = opmGrid.totalNumberOfCells();
if ( cellCount != riGrid->cellCount() ) return;
// Read out the corner coordinates from the EGRID file using radial coordinates.
// Prefix OPM structures with _opm_and ResInsight structures with _ri_
// Compute the center of the LGR radial grid cells for each K layer
std::map<int, std::pair<double, double>> radialGridCenterTopLayerOpm =
computeXyCenterForTopOfCells( opmMainGrid, opmGrid, riGrid );
std::array<double, 8> opmX{};
std::array<double, 8> opmY{};
std::array<double, 8> opmZ{};
const auto hostCellGlobalIndices = opmGrid.hostCellsGlobalIndex();
const size_t* cellMappingECLRi = RifReaderEclipseOutput::eclipseCellIndexMapping();
const auto gridDimension = opmGrid.dimension();
auto& riNodes = riMainGrid->nodes();
std::vector<cvf::Vec3d> snapToCoordinatesFromMainGrid;
for ( size_t opmCellIndex = 0; opmCellIndex < cellCount; opmCellIndex++ )
{
opmGrid.getCellCorners( opmCellIndex, opmX, opmY, opmZ );
// Each cell has 8 nodes, use reservoir cell index and multiply to find first node index for cell
auto riNodeStartIndex = riGrid->reservoirCellIndex( opmCellIndex ) * 8;
auto ijkCell = opmGrid.ijk_from_global_index( opmCellIndex );
double xCenterCoordOpm = 0.0;
double yCenterCoordOpm = 0.0;
if ( radialGridCenterTopLayerOpm.count( ijkCell[2] ) > 0 )
{
const auto& [xCenter, yCenter] = radialGridCenterTopLayerOpm[ijkCell[2]];
xCenterCoordOpm = xCenter;
yCenterCoordOpm = yCenter;
}
for ( size_t opmNodeIndex = 0; opmNodeIndex < 8; opmNodeIndex++ )
{
size_t riNodeIndex = riNodeStartIndex + cellMappingECLRi[opmNodeIndex];
// The radial grid is specified with (0,0) as center, add grid center to get correct global coordinates
auto& riNode = riNodes[riNodeIndex];
riNode.x() = opmX[opmNodeIndex] + xCenterCoordOpm;
riNode.y() = opmY[opmNodeIndex] + yCenterCoordOpm;
riNode.z() = -opmZ[opmNodeIndex];
// First grid dimension is radius, check if cell has are at the outer-most slice
if ( !hostCellGlobalIndices.empty() && ( gridDimension[0] - 1 == ijkCell[0] ) )
{
std::array<double, 8> cellRadius{};
std::array<double, 8> cellTheta{};
std::array<double, 8> cellZ{};
opmGrid.getRadialCellCorners( ijkCell, cellRadius, cellTheta, cellZ );
double maxRadius = *std::max_element( cellRadius.begin(), cellRadius.end() );
// Check if the radius is at the outer surface of the radial grid
// Adjust the outer nodes to match the corner pillars of the host cell
const double epsilon = 0.15;
if ( fabs( maxRadius - cellRadius[opmNodeIndex] ) < epsilon * cellRadius[opmNodeIndex] )
{
const auto hostCellIndex = hostCellGlobalIndices[opmCellIndex];
double closestPillarDistance = std::numeric_limits<double>::max();
int closestPillarIndex = -1;
const auto cylinderCoordX = opmX[opmNodeIndex] + xCenterCoordOpm;
const auto cylinderCoordY = opmY[opmNodeIndex] + yCenterCoordOpm;
const auto cylinderCoordZ = opmZ[opmNodeIndex];
const cvf::Vec3d coordinateOnCylinder = cvf::Vec3d( cylinderCoordX, cylinderCoordY, cylinderCoordZ );
const auto candidates = computeSnapToCoordinates( opmMainGrid, opmGrid, hostCellIndex, opmCellIndex );
for ( int pillarIndex = 0; pillarIndex < static_cast<int>( candidates.size() ); pillarIndex++ )
{
for ( const auto& c : candidates[pillarIndex] )
{
double distance = coordinateOnCylinder.pointDistance( c );
if ( distance < closestPillarDistance )
{
closestPillarDistance = distance;
closestPillarIndex = pillarIndex;
}
}
}
if ( closestPillarDistance < std::numeric_limits<double>::max() )
{
const auto& pillarCordinates = candidates[closestPillarIndex];
int layerCount = pillarCordinates.size() / 2;
int layerIndexInMainGridCell = ijkCell[2] % layerCount;
int localNodeIndex = opmNodeIndex % 8;
cvf::Vec3d closestPillarCoord;
if ( localNodeIndex < 4 )
{
// Top of cell
int pillarCoordIndex = layerIndexInMainGridCell * 2;
closestPillarCoord = pillarCordinates[pillarCoordIndex];
}
else
{
// Bottom of cell
int pillarCoordIndex = layerIndexInMainGridCell * 2 + 1;
closestPillarCoord = pillarCordinates[pillarCoordIndex];
}
riNode.x() = closestPillarCoord.x();
riNode.y() = closestPillarCoord.y();
riNode.z() = -closestPillarCoord.z();
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<int, std::pair<double, double>> RifOpmGridTools::computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
RigGridBase* riGrid )
{
if ( !riGrid || riGrid->isMainGrid() ) return {};
size_t cellCount = opmGrid.totalNumberOfCells();
if ( cellCount != riGrid->cellCount() ) return {};
// Read out the corner coordinates from the EGRID file using radial coordinates.
// Prefix OPM structures with _opm_and ResInsight structures with _ri_
// Compute the center of the LGR radial grid cells for each K layer
std::map<int, std::pair<double, double>> radialGridCenterTopLayerOpm;
{
std::array<double, 8> opmX{};
std::array<double, 8> opmY{};
std::array<double, 8> opmZ{};
std::map<int, std::vector<std::pair<double, double>>> xyCenterPerLayer;
auto hostCellGlobalIndices = opmGrid.hostCellsGlobalIndex();
for ( size_t cIdx = 0; cIdx < cellCount; cIdx++ )
{
auto mainGridCellIndex = hostCellGlobalIndices[cIdx];
opmMainGrid.getCellCorners( mainGridCellIndex, opmX, opmY, opmZ );
auto ijkLocalGrid = opmGrid.ijk_from_global_index( cIdx );
auto layer = ijkLocalGrid[2];
// Four corners for top
for ( size_t i = 4; i < 8; i++ )
{
auto& xyCoords = xyCenterPerLayer[layer];
xyCoords.emplace_back( opmX[i], opmY[i] );
}
}
for ( const auto& [k, xyCoords] : xyCenterPerLayer )
{
RiaWeightedMeanCalculator<double> xCoord;
RiaWeightedMeanCalculator<double> yCoord;
for ( const auto& [x, y] : xyCoords )
{
xCoord.addValueAndWeight( x, 1.0 );
yCoord.addValueAndWeight( y, 1.0 );
}
radialGridCenterTopLayerOpm[k] = { xCoord.weightedMean(), yCoord.weightedMean() };
}
}
return radialGridCenterTopLayerOpm;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>> RifOpmGridTools::computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
int mainGridCellIndex,
int lgrCellIndex )
{
auto hostCellIndices = opmGrid.hostCellsGlobalIndex();
auto lgrIjk = opmGrid.ijk_from_global_index( lgrCellIndex );
std::vector<double> zDistanceAlongPillar;
for ( int gridCellIndex = 0; gridCellIndex < opmGrid.totalNumberOfCells(); gridCellIndex++ )
{
if ( hostCellIndices[gridCellIndex] == mainGridCellIndex )
{
auto ijk = opmGrid.ijk_from_global_index( gridCellIndex );
// Find all LGR cells for the same IJ column
if ( ijk[0] == lgrIjk[0] && ijk[1] == lgrIjk[1] )
{
std::array<double, 8> cellX{};
std::array<double, 8> cellY{};
std::array<double, 8> cellZ{};
opmGrid.getCellCorners( gridCellIndex, cellX, cellY, cellZ );
// Get top and bottom of one pillar
zDistanceAlongPillar.push_back( cellZ[0] );
zDistanceAlongPillar.push_back( cellZ[4] );
}
}
}
if ( zDistanceAlongPillar.size() < 2 ) return {};
std::sort( zDistanceAlongPillar.begin(), zDistanceAlongPillar.end() );
auto normalize = []( const std::vector<double>& values ) -> std::vector<double> {
if ( values.size() < 2 ) return {};
std::vector<double> normalizedValues;
double firstValue = values.front();
double lastValue = values.back();
double range = lastValue - firstValue;
// Normalize values to range [0..1]
for ( const auto& value : values )
{
normalizedValues.emplace_back( ( value - firstValue ) / range );
}
return normalizedValues;
};
auto normalizedZValues = normalize( zDistanceAlongPillar );
std::vector<std::vector<cvf::Vec3d>> allCoords;
std::array<double, 8> hostCellX{};
std::array<double, 8> hostCellY{};
std::array<double, 8> hostCellZ{};
opmMainGrid.getCellCorners( mainGridCellIndex, hostCellX, hostCellY, hostCellZ );
for ( int pillarIndex = 0; pillarIndex < 4; pillarIndex++ )
{
std::vector<cvf::Vec3d> pillarCoords;
const cvf::Vec3d p1( hostCellX[0 + pillarIndex], hostCellY[0 + pillarIndex], hostCellZ[0 + pillarIndex] );
const cvf::Vec3d p2( hostCellX[4 + pillarIndex], hostCellY[4 + pillarIndex], hostCellZ[4 + pillarIndex] );
for ( auto t : normalizedZValues )
{
cvf::Vec3d pillarCoord = p1 * ( 1.0 - t ) + t * p2;
pillarCoords.push_back( pillarCoord );
}
allCoords.push_back( pillarCoords );
}
return allCoords;
}

View File

@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfVector3.h"
#include <map>
#include <string>
#include <vector>
namespace Opm
{
namespace EclIO
{
class EGrid;
}
} // namespace Opm
class RigMainGrid;
class RigGridBase;
//==================================================================================================
///
//==================================================================================================
class RifOpmGridTools
{
public:
// If the grid is radial, the coordinates are imported and adjusted to fit the host cells
static void importCoordinatesForRadialGrid( const std::string& gridFilePath, RigMainGrid* mainGrid );
private:
static void transferCoordinates( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
RigMainGrid* riMainGrid,
RigGridBase* riGrid );
static std::map<int, std::pair<double, double>>
computeXyCenterForTopOfCells( Opm::EclIO::EGrid& opmMainGrid, Opm::EclIO::EGrid& opmGrid, RigGridBase* riGrid );
static std::vector<std::vector<cvf::Vec3d>> computeSnapToCoordinates( Opm::EclIO::EGrid& opmMainGrid,
Opm::EclIO::EGrid& opmGrid,
int mainGridCellIndex,
int lgrCellIndex );
};

View File

@ -29,6 +29,7 @@
#include "RifEclipseInputFileTools.h"
#include "RifEclipseOutputFileTools.h"
#include "RifHdf5ReaderInterface.h"
#include "RifOpmGridTools.h"
#include "RifReaderSettings.h"
#ifdef USE_HDF5
@ -414,6 +415,8 @@ bool RifReaderEclipseOutput::open( const QString& fileName, RigEclipseCaseData*
{
auto task = progress.task( "Transferring grid geometry", 10 );
if ( !transferGeometry( mainEclGrid, eclipseCase ) ) return false;
RifOpmGridTools::importCoordinatesForRadialGrid( fileName.toStdString(), eclipseCase->mainGrid() );
}
{

View File

@ -76,14 +76,7 @@ public:
std::vector<QDateTime> allTimeSteps() const;
static bool transferGeometry( const ecl_grid_type* mainEclGrid, RigEclipseCaseData* eclipseCase );
static bool exportGrid( const QString& gridFileName,
RigEclipseCaseData* eclipseCase,
const cvf::Vec3st& min,
const cvf::Vec3st& max,
const cvf::Vec3st& refinement );
static void transferCoarseningInfo( const ecl_grid_type* eclGrid, RigGridBase* grid );
static void importEquilData( const QString& deckFileName,
const QString& includeStatementAbsolutePathPrefix,
RigEclipseCaseData* eclipseCase );

View File

@ -21,6 +21,7 @@
#include "RimEclipseCellColors.h"
#include "RimEclipseView.h"
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
CAF_PDM_SOURCE_INIT( RimMultipleEclipseResults, "RimMultipleEclipseResults" );
@ -32,9 +33,14 @@ RimMultipleEclipseResults::RimMultipleEclipseResults()
{
CAF_PDM_InitObject( "Multiple Result Info", ":/TextAnnotation16x16.png" );
CAF_PDM_InitField( &m_showCenterCoordinates, "showCenterCoordinates", false, "Show Center Coordinates" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_showCenterCoordinates );
CAF_PDM_InitField( &m_showCornerCoordinates, "showCornerCoordinates", false, "Show Corner Coordinates" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_showCornerCoordinates );
CAF_PDM_InitFieldNoDefault( &m_selectedKeywords, "SelectedProperties", "Properties" );
m_selectedKeywords.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
m_selectedKeywords.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
}
@ -74,6 +80,22 @@ std::vector<RigEclipseResultAddress> RimMultipleEclipseResults::additionalResult
return resultAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimMultipleEclipseResults::showCenterCoordinates() const
{
return m_showCenterCoordinates;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimMultipleEclipseResults::showCornerCoordinates() const
{
return m_showCornerCoordinates;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -40,10 +40,16 @@ public:
std::vector<RigEclipseResultAddress> additionalResultAddresses() const;
bool showCenterCoordinates() const;
bool showCornerCoordinates() const;
private:
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
private:
caf::PdmField<bool> m_showCornerCoordinates;
caf::PdmField<bool> m_showCenterCoordinates;
caf::PdmField<std::vector<QString>> m_selectedKeywords;
caf::PdmPointer<RimEclipseView> m_eclipseView;
};

View File

@ -10,6 +10,7 @@
// Disable warning from external library to make sure treat warnings as error works
#pragma warning( disable : 4267 )
#endif
#include "opm/io/eclipse/EGrid.hpp"
#include "opm/io/eclipse/ERft.hpp"
#include "opm/io/eclipse/ESmry.hpp"
#include "opm/io/eclipse/ExtESmry.hpp"
@ -293,3 +294,33 @@ TEST( OpmSummaryTests, OpmComputeSegmentTopology )
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, DISABLED_ReadOpmRadialGrid )
{
{
QString filePath = "e:/models/from_equinor_sftp/2021.10.1-Radial-testcase/global-radial/GLOBAL-RADIAL.EGRID";
Opm::EclIO::EGrid eGrid( filePath.toStdString() );
auto dims = eGrid.dimension();
size_t cellCount = dims[0] * dims[1] * dims[2];
std::array<double, 8> X{};
std::array<double, 8> Y{};
std::array<double, 8> Z{};
for ( size_t cidx = 0; cidx < cellCount; cidx++ )
{
eGrid.getCellCorners( cidx, X, Y, Z );
for ( size_t i = 0; i < 8; i++ )
{
std::cout << X[i] << " " << Y[i] << " " << Z[i] << "\n";
}
}
}
}

View File

@ -39,6 +39,7 @@
#include "RimExtrudedCurveIntersection.h"
#include "RimFormationNames.h"
#include "RimIntersectionResultDefinition.h"
#include "RimMultipleEclipseResults.h"
#include "RimRegularLegendConfig.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimViewLinker.h"
@ -195,7 +196,7 @@ QString RiuResultTextBuilder::mainResultText()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuResultTextBuilder::geometrySelectionText( QString itemSeparator )
QString RiuResultTextBuilder::geometrySelectionText( const QString& itemSeparator )
{
QString text;
@ -234,6 +235,8 @@ QString RiuResultTextBuilder::geometrySelectionText( QString itemSeparator )
size_t globalCellIndex = grid->reservoirCellIndex( m_cellIndex );
text += QString( "Global Cell Index : %4" ).arg( globalCellIndex ) + itemSeparator;
text += coordinatesText( grid, globalCellIndex, itemSeparator );
}
}
@ -251,10 +254,8 @@ QString RiuResultTextBuilder::geometrySelectionText( QString itemSeparator )
if ( !t.isZero() )
{
cvf::Vec3d intPt = m_intersectionPointInDisplay.getTransformedPoint( t );
formattedText = QString( "Intersection point : [E: %1, N: %2, Depth: %3]" )
.arg( intPt.x(), 5, 'f', 2 )
.arg( intPt.y(), 5, 'f', 2 )
.arg( -intPt.z(), 5, 'f', 2 );
formattedText =
createTextFromDomainCoordinate( "Intersection point : [E: %1, N: %2, Depth: %3]", intPt );
text += formattedText;
}
}
@ -265,10 +266,8 @@ QString RiuResultTextBuilder::geometrySelectionText( QString itemSeparator )
cvf::ref<caf::DisplayCoordTransform> transForm = m_displayCoordView->displayCoordTransform();
cvf::Vec3d domainCoord = transForm->translateToDomainCoord( m_intersectionPointInDisplay );
formattedText = QString( "Intersection point : [E: %1, N: %2, Depth: %3]" )
.arg( domainCoord.x(), 5, 'f', 2 )
.arg( domainCoord.y(), 5, 'f', 2 )
.arg( -domainCoord.z(), 5, 'f', 2 );
formattedText =
createTextFromDomainCoordinate( "Intersection point : [E: %1, N: %2, Depth: %3]", domainCoord );
text += formattedText;
}
}
@ -279,6 +278,74 @@ QString RiuResultTextBuilder::geometrySelectionText( QString itemSeparator )
return text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuResultTextBuilder::coordinatesText( const RigGridBase* grid, size_t globalCellIndex, const QString& itemSeparator )
{
QString text;
bool showCenter = false;
bool showCorner = false;
if ( m_eclipseView )
{
std::vector<RimMultipleEclipseResults*> additionalResultSettings;
m_eclipseView->descendantsOfType( additionalResultSettings );
if ( !additionalResultSettings.empty() )
{
showCenter = additionalResultSettings[0]->showCenterCoordinates();
showCorner = additionalResultSettings[0]->showCornerCoordinates();
}
}
if ( showCenter )
{
auto mainGrid = grid->mainGrid();
auto cell = mainGrid->cell( globalCellIndex );
const auto center = cell.center();
text += createTextFromDomainCoordinate( "Cell Center : [%1, %2, %3]", center ) + itemSeparator;
}
if ( showCorner )
{
auto mainGrid = grid->mainGrid();
auto cell = mainGrid->cell( globalCellIndex );
auto indices = cell.cornerIndices();
text += QString( "Cell Corners" ) + itemSeparator;
const std::vector<std::pair<int, std::string>> riNodeOrder{ { 0, "i- j- k+" },
{ 1, "i+ j- k+" },
{ 2, "i+ j+ k+" },
{ 3, "i- j+ k+" },
{ 4, "i- j- k-" },
{ 5, "i+ j- k-" },
{ 6, "i+ j+ k-" },
{ 7, "i- j+ k-" } };
for ( int i = 0; i < 8; i++ )
{
const auto& [nodeIndex, nodeText] = riNodeOrder[i];
auto v = mainGrid->nodes()[indices[nodeIndex]];
text += createTextFromDomainCoordinate( QString::fromStdString( nodeText ) + " : [%1, %2, %3]" + itemSeparator,
v );
}
}
return text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuResultTextBuilder::createTextFromDomainCoordinate( const QString& formatString, const cvf::Vec3d& domainCoord )
{
return formatString.arg( domainCoord.x(), 5, 'f', 2 ).arg( domainCoord.y(), 5, 'f', 2 ).arg( -domainCoord.z(), 5, 'f', 2 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -20,6 +20,7 @@
#pragma once
#include "cafPdmPointer.h"
#include "cvfStructGrid.h"
#include <map>
@ -30,6 +31,7 @@ class Rim2dIntersectionView;
class RigEclipseCaseData;
class RimEclipseResultDefinition;
class RimGridView;
class RigGridBase;
class QString;
@ -62,7 +64,7 @@ public:
QString mainResultText();
QString geometrySelectionText( QString itemSeparator );
QString geometrySelectionText( const QString& itemSeparator );
private:
void appendDetails( QString& text, const QString& details );
@ -90,6 +92,10 @@ private:
std::pair<bool, QStringList> resultTextFromLinkedViews() const;
QString coordinatesText( const RigGridBase* grid, size_t globalCellIndex, const QString& itemSeparator );
static QString createTextFromDomainCoordinate( const QString& formatString, const cvf::Vec3d& domainCoord );
private:
caf::PdmPointer<RimGridView> m_displayCoordView;
caf::PdmPointer<RimEclipseView> m_eclipseView;

@ -1 +1 @@
Subproject commit aa8e9c1f84a8ccfe829c3a89295c442e95bb2a09
Subproject commit c548d4ea4319adee307bba5ddd8d68bb1f44d421