#4669 Calculate nodal gradients for POR.

This commit is contained in:
Kristian Bendiksen
2020-01-30 09:10:56 +01:00
parent 5556fb39b1
commit 967d8b9bd4
4 changed files with 116 additions and 17 deletions

View File

@@ -352,6 +352,9 @@ std::map<std::string, std::vector<std::string>>
{
fieldCompNames = m_readerInterface->scalarNodeFieldAndComponentNames();
fieldCompNames["POR-Bar"];
fieldCompNames["PORG"].push_back( "X" );
fieldCompNames["PORG"].push_back( "Y" );
fieldCompNames["PORG"].push_back( "Z" );
fieldCompNames[FIELD_NAME_COMPACTION];
}
else if ( resPos == RIG_ELEMENT_NODAL )
@@ -1078,6 +1081,103 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateStressGradient(
return requestedStress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultsCollection::calculateNodalGradient( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "PORG" );
CVF_ASSERT( resVarAddr.componentName == "X" || resVarAddr.componentName == "Y" || resVarAddr.componentName == "Z" );
caf::ProgressInfo frameCountProgress( this->frameCount() * 5, "" );
frameCountProgress.setProgressDescription(
"Calculating gradient: " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( this->frameCount() );
RigFemScalarResultFrames* dataFramesX = m_femPartResults[partIndex]->createScalarResult(
RigFemResultAddress( RIG_NODAL, resVarAddr.fieldName, "X" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( this->frameCount() );
RigFemScalarResultFrames* dataFramesY = m_femPartResults[partIndex]->createScalarResult(
RigFemResultAddress( RIG_NODAL, resVarAddr.fieldName, "Y" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( this->frameCount() );
RigFemScalarResultFrames* dataFramesZ = m_femPartResults[partIndex]->createScalarResult(
RigFemResultAddress( RIG_NODAL, resVarAddr.fieldName, "Z" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( this->frameCount() );
RigFemResultAddress porResultAddr( RIG_NODAL, "POR-Bar", "" );
RigFemScalarResultFrames* srcDataFrames = this->findOrLoadScalarResult( partIndex, porResultAddr );
frameCountProgress.incrementProgress();
const RigFemPart* femPart = m_femParts->part( partIndex );
float inf = std::numeric_limits<float>::infinity();
const std::vector<cvf::Vec3f>& nodeCoords = femPart->nodes().coordinates;
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameDataX = dataFramesX->frameData( fIdx );
std::vector<float>& dstFrameDataY = dataFramesY->frameData( fIdx );
std::vector<float>& dstFrameDataZ = dataFramesZ->frameData( fIdx );
if ( srcFrameData.empty() ) continue; // Create empty results if we have no POR result.
size_t valCount = femPart->elementNodeResultCount();
dstFrameDataX.resize( valCount, inf );
dstFrameDataY.resize( valCount, inf );
dstFrameDataZ.resize( valCount, inf );
int elementCount = femPart->elementCount();
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( !( elmType == HEX8P ) ) continue;
// Find the corner coordinates and values for the node
std::array<cvf::Vec3d, 8> hexCorners;
std::array<double, 8> cornerValues;
int elmNodeCount = RigFemTypes::elmentNodeCount( elmType );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
int nodeIdx = femPart->resultValueIdxFromResultPosType( RIG_NODAL, elmIdx, elmNodIdx );
cornerValues[elmNodIdx] = srcFrameData[nodeIdx];
hexCorners[elmNodIdx] = cvf::Vec3d( nodeCoords[nodeIdx] );
}
std::array<cvf::Vec3d, 8> gradients = RigHexGradientTools::gradients( hexCorners, cornerValues );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
int nodeIdx = femPart->resultValueIdxFromResultPosType( RIG_NODAL, elmIdx, elmNodIdx );
dstFrameDataX[nodeIdx] = gradients[elmNodIdx].x();
dstFrameDataY[nodeIdx] = gradients[elmNodIdx].y();
dstFrameDataZ[nodeIdx] = gradients[elmNodIdx].z();
}
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedGradient = this->findOrLoadScalarResult( partIndex, resVarAddr );
CVF_ASSERT( requestedGradient );
return requestedGradient;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -2287,6 +2387,12 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult( i
return calculateEnIpPorBarResult( partIndex, resVarAddr );
}
if ( resVarAddr.fieldName == "PORG" &&
( resVarAddr.componentName == "X" || resVarAddr.componentName == "Y" || resVarAddr.componentName == "Z" ) )
{
return calculateNodalGradient( partIndex, resVarAddr );
}
if ( ( resVarAddr.fieldName == "NE" ) && ( resVarAddr.componentName == "E11" || resVarAddr.componentName == "E22" ||
resVarAddr.componentName == "E33" || resVarAddr.componentName == "E12" ||
resVarAddr.componentName == "E13" || resVarAddr.componentName == "E23" ) )