INP import updates (#10952)

Support reading element type results
Automatically load properties from INP include files generated by Fault Reactivation Model exporter
Some refactoring of element and result types.
This commit is contained in:
jonjenssen
2023-12-14 08:46:41 +01:00
committed by GitHub
parent 77e5d642e9
commit 1fab743d56
32 changed files with 671 additions and 146 deletions

View File

@@ -92,6 +92,14 @@ int RigFemPart::elementCount() const
return static_cast<int>( m_elementId.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemPart::nodeCount() const
{
return static_cast<int>( m_nodes.nodeIds.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -442,7 +450,7 @@ float RigFemPart::characteristicElementSize() const
{
if ( m_characteristicElementSize != std::numeric_limits<float>::infinity() ) return m_characteristicElementSize;
std::vector<RigElementType> elementPriority = { HEX8P, HEX8 };
std::vector<RigElementType> elementPriority = { RigElementType::HEX8P, RigElementType::HEX8 };
for ( auto elmType : elementPriority )
{
@@ -604,7 +612,7 @@ size_t RigFemPart::resultValueIdxFromResultPosType( RigFemResultPosEnum resultPo
bool RigFemPart::isHexahedron( size_t elementIdx ) const
{
RigElementType elType = elementType( elementIdx );
return elType == HEX8 || elType == HEX8P;
return RigFemTypes::is8NodeElement( elType );
}
//--------------------------------------------------------------------------------------------------

View File

@@ -58,6 +58,7 @@ public:
void appendElement( RigElementType elmType, int elementId, const int* connectivities );
int elementCount() const;
int nodeCount() const;
int allConnectivitiesCount() const;
int elmId( size_t elementIdx ) const;

View File

@@ -200,7 +200,7 @@ void RigFemPartGrid::generateStructGridData()
RigElementType elementType = m_femPart->elementType( elmIdx );
size_t i, j, k;
bool validIndex = ijkFromCellIndex( elmIdx, &i, &j, &k );
if ( elementType == HEX8P && validIndex )
if ( ( elementType == RigElementType::HEX8P ) && validIndex )
{
if ( i < min.x() ) min.x() = i;
if ( j < min.y() ) min.y() = j;
@@ -254,7 +254,7 @@ cvf::Vec3i RigFemPartGrid::findMainIJKFaces( int elementIndex ) const
// Record three independent main direction vectors for the element, and what face they are created from
cvf::Vec3f mainElmDirections[3];
int mainElmDirOriginFaces[3];
if ( eType == HEX8 || eType == HEX8P )
if ( RigFemTypes::is8NodeElement( eType ) )
{
mainElmDirections[0] = normals[0] - normals[1]; // To get a better "average" direction vector
mainElmDirections[1] = normals[2] - normals[3];

View File

@@ -92,7 +92,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorEnIpPorBar::calculate( int p
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
int elmNodeCount = RigFemTypes::elementNodeCount( elmType );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )

View File

@@ -135,7 +135,7 @@ void RigFemPartResultCalculatorGamma::calculateGammaFromFrames( int
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -94,7 +94,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorInitialPorosity::calculate(
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -124,7 +124,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNodalGradients::calculate( i
for ( int elmIdx : elements )
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
// Find the corner coordinates and values for the node
std::array<cvf::Vec3d, 8> hexCorners;

View File

@@ -94,7 +94,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNormalSE::calculate( int par
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -102,7 +102,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNormalST::calculate( int par
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -123,7 +123,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorNormalized::calculate( int p
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( elmType != HEX8 && elmType != HEX8P ) continue;
if ( !RigFemTypes::is8NodeElement( elmType ) ) continue;
bool porRegion = false;
for ( int elmLocalNodeIdx = 0; elmLocalNodeIdx < 8; ++elmLocalNodeIdx )

View File

@@ -170,7 +170,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorPoreCompressibility::calcula
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -165,7 +165,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorPorosityPermeability::calcul
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -96,7 +96,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorShearSE::calculate( int part
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
if ( elmType == RigElementType::HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{

View File

@@ -133,7 +133,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorStressGradients::calculate(
const int* cornerIndices = femPart->connectivities( elmIdx );
RigElementType elmType = femPart->elementType( elmIdx );
if ( elmType != HEX8P && elmType != HEX8 ) continue;
if ( !RigFemTypes::is8NodeElement( elmType ) ) continue;
// Find the corner coordinates for element
std::array<cvf::Vec3d, 8> hexCorners;

View File

@@ -443,6 +443,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::findOrLoadScalarResult( i
frames = calculateDerivedResult( partIndex, resVarAddr );
if ( frames ) return frames;
// is it available as an imported property
if ( resVarAddr.resultPosType == RIG_ELEMENT )
{
std::map<std::string, std::vector<float>> elementProperties =
@@ -463,11 +464,6 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::findOrLoadScalarResult( i
{
return frames;
}
else
{
// Create a dummy empty result
return m_femPartResults[partIndex]->createScalarResult( resVarAddr );
}
}
// We need to read the data as bulk fields, and populate the correct scalar caches
@@ -504,6 +500,9 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::findOrLoadScalarResult( i
case RIG_NODAL:
m_readerInterface->readNodeField( resVarAddr.fieldName, partIndex, stepIndex, frameIndex, &componentDataVectors );
break;
case RIG_ELEMENT:
m_readerInterface->readElementField( resVarAddr.fieldName, partIndex, stepIndex, frameIndex, &componentDataVectors );
break;
case RIG_ELEMENT_NODAL:
m_readerInterface->readElementNodeField( resVarAddr.fieldName, partIndex, stepIndex, frameIndex, &componentDataVectors );
break;
@@ -573,14 +572,20 @@ std::map<std::string, std::vector<std::string>> RigFemPartResultsCollection::sca
if ( resPos == RIG_NODAL )
{
fieldCompNames = m_readerInterface->scalarNodeFieldAndComponentNames();
if ( fieldCompNames.contains( "U" ) ) fieldCompNames["U"].push_back( "U_LENGTH" );
fieldCompNames[RigFemAddressDefines::porBar()];
fieldCompNames[FIELD_NAME_COMPACTION];
if ( m_readerInterface->populateDerivedResultNames() )
{
if ( fieldCompNames.contains( "U" ) ) fieldCompNames["U"].push_back( "U_LENGTH" );
fieldCompNames[FIELD_NAME_COMPACTION];
}
}
else if ( resPos == RIG_ELEMENT_NODAL )
{
fieldCompNames = m_readerInterface->scalarElementNodeFieldAndComponentNames();
if ( !m_readerInterface->populateDerivedResultNames() ) return fieldCompNames;
fieldCompNames["SE"].push_back( "SM" );
fieldCompNames["SE"].push_back( "SFI" );
fieldCompNames["SE"].push_back( "DSM" );
@@ -677,6 +682,8 @@ std::map<std::string, std::vector<std::string>> RigFemPartResultsCollection::sca
{
fieldCompNames = m_readerInterface->scalarIntegrationPointFieldAndComponentNames();
if ( !m_readerInterface->populateDerivedResultNames() ) return fieldCompNames;
fieldCompNames["SE"].push_back( "SM" );
fieldCompNames["SE"].push_back( "SFI" );
fieldCompNames["SE"].push_back( "DSM" );
@@ -779,6 +786,8 @@ std::map<std::string, std::vector<std::string>> RigFemPartResultsCollection::sca
}
else if ( resPos == RIG_ELEMENT_NODAL_FACE )
{
if ( !m_readerInterface->populateDerivedResultNames() ) return fieldCompNames;
fieldCompNames["Plane"].push_back( "Pinc" );
fieldCompNames["Plane"].push_back( "Pazi" );
@@ -799,9 +808,11 @@ std::map<std::string, std::vector<std::string>> RigFemPartResultsCollection::sca
}
else if ( resPos == RIG_ELEMENT )
{
fieldCompNames = m_readerInterface->scalarElementFieldAndComponentNames();
for ( const std::string& field : m_elementPropertyReader->scalarElementFields() )
{
fieldCompNames[field];
fieldCompNames[field] = {};
}
}
else if ( resPos == RIG_WELLPATH_DERIVED )
@@ -883,6 +894,9 @@ std::vector<RigFemResultAddress> RigFemPartResultsCollection::getResAddrToCompon
case RIG_NODAL:
fieldAndComponentNames = m_readerInterface->scalarNodeFieldAndComponentNames();
break;
case RIG_ELEMENT:
fieldAndComponentNames = m_readerInterface->scalarElementFieldAndComponentNames();
break;
case RIG_ELEMENT_NODAL:
fieldAndComponentNames = m_readerInterface->scalarElementNodeFieldAndComponentNames();
break;

View File

@@ -30,7 +30,7 @@ int RigFemTypes::elementNodeCount( RigElementType elmType )
{
static int elementTypeCounts[3] = { 8, 8, 4 };
return elementTypeCounts[elmType];
return elementTypeCounts[(unsigned int)elmType];
}
//--------------------------------------------------------------------------------------------------
@@ -40,7 +40,7 @@ int RigFemTypes::elementFaceCount( RigElementType elmType )
{
const static int elementFaceCounts[3] = { 6, 6, 1 };
return elementFaceCounts[elmType];
return elementFaceCounts[(unsigned int)elmType];
}
//--------------------------------------------------------------------------------------------------
@@ -63,12 +63,12 @@ const int* RigFemTypes::localElmNodeIndicesForFace( RigElementType elmType, int
switch ( elmType )
{
case HEX8:
case HEX8P:
case RigElementType::HEX8:
case RigElementType::HEX8P:
( *faceNodeCount ) = 4;
return HEX8_Faces[faceIdx];
break;
case CAX4:
case RigElementType::CAX4:
( *faceNodeCount ) = 4;
return CAX4_Faces;
break;
@@ -86,11 +86,11 @@ int RigFemTypes::oppositeFace( RigElementType elmType, int faceIdx )
switch ( elmType )
{
case HEX8:
case HEX8P:
case RigElementType::HEX8:
case RigElementType::HEX8P:
return HEX8_OppositeFaces[faceIdx];
break;
case CAX4:
case RigElementType::CAX4:
return faceIdx;
break;
default:
@@ -111,11 +111,11 @@ const int* RigFemTypes::localElmNodeToIntegrationPointMapping( RigElementType el
switch ( elmType )
{
case HEX8:
case HEX8P:
case RigElementType::HEX8:
case RigElementType::HEX8P:
return HEX8_Mapping;
break;
case CAX4:
case RigElementType::CAX4:
return HEX8_Mapping; // First four is identical to HEX8
break;
default:
@@ -129,22 +129,22 @@ const int* RigFemTypes::localElmNodeToIntegrationPointMapping( RigElementType el
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RigFemTypes::elementTypeText( RigElementType elemType )
std::string RigFemTypes::elementTypeText( RigElementType elemType )
{
QString txt = "UNKNOWN_ELM_TYPE";
std::string txt = "UNKNOWN_ELM_TYPE";
switch ( elemType )
{
case HEX8:
case RigElementType::HEX8:
txt = "HEX8";
break;
case HEX8P:
case RigElementType::HEX8P:
txt = "HEX8P";
break;
case CAX4:
case RigElementType::CAX4:
txt = "CAX4";
break;
case UNKNOWN_ELM_TYPE:
case RigElementType::UNKNOWN_ELM_TYPE:
break;
default:
break;
@@ -152,3 +152,45 @@ QString RigFemTypes::elementTypeText( RigElementType elemType )
return txt;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<std::string, RigElementType> RigFemTypes::femTypeMap()
{
std::map<std::string, RigElementType> typeMap;
typeMap["C3D8R"] = RigElementType::HEX8;
typeMap["C3D8"] = RigElementType::HEX8;
typeMap["C3D8P"] = RigElementType::HEX8P;
typeMap["CAX4"] = RigElementType::CAX4;
typeMap["C3D20RT"] = RigElementType::HEX8;
typeMap["C3D8RT"] = RigElementType::HEX8;
typeMap["C3D8T"] = RigElementType::HEX8;
return typeMap;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigElementType RigFemTypes::toRigElementType( const std::string odbTypeName )
{
static std::map<std::string, RigElementType> odbElmTypeToRigElmTypeMap = femTypeMap();
std::map<std::string, RigElementType>::iterator it = odbElmTypeToRigElmTypeMap.find( odbTypeName );
if ( it == odbElmTypeToRigElmTypeMap.end() )
{
return RigElementType::UNKNOWN_ELM_TYPE;
}
return it->second;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemTypes::is8NodeElement( RigElementType elmType )
{
return ( elmType == RigElementType::HEX8 ) || ( elmType == RigElementType::HEX8P );
}

View File

@@ -19,9 +19,10 @@
#pragma once
class QString;
#include <map>
#include <string>
enum RigElementType
enum class RigElementType
{
HEX8,
HEX8P,
@@ -32,10 +33,15 @@ enum RigElementType
class RigFemTypes
{
public:
static int elementNodeCount( RigElementType elmType );
static int elementFaceCount( RigElementType elmType );
static const int* localElmNodeIndicesForFace( RigElementType elmType, int faceIdx, int* faceNodeCount );
static int oppositeFace( RigElementType elmType, int faceIdx );
static const int* localElmNodeToIntegrationPointMapping( RigElementType elmType );
static QString elementTypeText( RigElementType elemType );
static int elementNodeCount( RigElementType elmType );
static int elementFaceCount( RigElementType elmType );
static const int* localElmNodeIndicesForFace( RigElementType elmType, int faceIdx, int* faceNodeCount );
static int oppositeFace( RigElementType elmType, int faceIdx );
static const int* localElmNodeToIntegrationPointMapping( RigElementType elmType );
static std::string elementTypeText( RigElementType elemType );
static RigElementType toRigElementType( const std::string odbTypeName );
static bool is8NodeElement( RigElementType elmType );
private:
static std::map<std::string, RigElementType> femTypeMap();
};