VTK GeoMech: pore pressure from node data, derived results

Read the VTK point data, not only "disp" (now found by name, not
position). "pressure" becomes the nodal pore pressure POR, other scalar
point arrays keep their name. OPM Flow writes them with
--vtk-write-geo-mech-nodal, recovered from its cell values.

Stress and strain are cell values in the simulator, so S and E at
element-nodal (and integration-point) position give every element corner
its cell's value. S is effective stress, tension positive, while OPM
writes total stress, compression positive: S = POR * I - stress at each
corner, so ST = -S + POR returns the simulator's stress exactly.

With S present, populateDerivedResultNames() returns true, so SE, ST,
principal stresses, SFI, DSM, FOS, NE etc. are available.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hnilandClaude Opus 5.5 authored and Magne Sjaastad committed 2026-10-24 13:59:38 +02:00
1 parent 6d8ee8d685
commit d7b3e60520
6 files changed
+189 -21

No files matched your search

@@ -71,8 +71,8 @@ std::vector<cvf::Vec3f> RifVtkImportUtil::readDisplacements( const pugi::xml_nod
auto pointData = piece.child( "PointData" );
if ( !pointData ) return {};
auto dataArray = pointData.child( "DataArray" );
if ( !dataArray || std::string( dataArray.attribute( "Name" ).value() ) != "disp" ) return {};
auto dataArray = pointData.find_child_by_attribute( "DataArray", "Name", "disp" );
if ( !dataArray ) return {};
std::string_view text = dataArray.text().get();
std::vector<cvf::Vec3f> displacements = parseVec3fs( text );
@@ -119,12 +119,27 @@ std::vector<unsigned> RifVtkImportUtil::readConnectivity( const pugi::xml_node&
//--------------------------------------------------------------------------------------------------
std::map<std::string, std::vector<float>> RifVtkImportUtil::readProperties( const pugi::xml_node& piece )
{
auto cellData = piece.child( "CellData" );
if ( !cellData ) return {};
return readDataArrays( piece.child( "CellData" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<std::string, std::vector<float>> RifVtkImportUtil::readPointProperties( const pugi::xml_node& piece )
{
return readDataArrays( piece.child( "PointData" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<std::string, std::vector<float>> RifVtkImportUtil::readDataArrays( const pugi::xml_node& data )
{
if ( !data ) return {};
std::map<std::string, std::vector<float>> properties;
for ( const auto& dataArray : cellData.children( "DataArray" ) )
for ( const auto& dataArray : data.children( "DataArray" ) )
{
const char* name = dataArray.attribute( "Name" ).value();
if ( name && *name )
@@ -45,8 +45,10 @@ public:
static std::vector<cvf::Vec3f> readDisplacements( const pugi::xml_node& piece );
static std::vector<unsigned> readConnectivity( const pugi::xml_node& piece );
static std::map<std::string, std::vector<float>> readProperties( const pugi::xml_node& piece );
static std::map<std::string, std::vector<float>> readPointProperties( const pugi::xml_node& piece );
private:
static std::vector<cvf::Vec3d> parseVec3ds( std::string_view text );
static std::vector<cvf::Vec3f> parseVec3fs( std::string_view text );
static std::map<std::string, std::vector<float>> readDataArrays( const pugi::xml_node& data );
static std::vector<cvf::Vec3d> parseVec3ds( std::string_view text );
static std::vector<cvf::Vec3f> parseVec3fs( std::string_view text );
};