(#331) Properly shown POR values by checking for element type.

We are calculating and using an elmNode POR result to correctly
respect the element type.
This commit is contained in:
Jacob Støren 2015-09-28 07:39:57 +02:00
parent 56dae7f71a
commit 5677665dba
6 changed files with 73 additions and 5 deletions

View File

@ -374,3 +374,17 @@ void RigFemPart::findIntersectingCells(const cvf::BoundingBox& inputBB, std::vec
m_elementSearchTree->findIntersections(inputBB, elementIndices);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigFemPart::elementNodeResultCount() const
{
int lastElmIdx = this->elementCount() - 1;
if (lastElmIdx < 0) return 0;
RigElementType elmType = this->elementType(lastElmIdx);
int elmNodeCount = RigFemTypes::elmentNodeCount(elmType);
size_t lastElmResultIdx = this->elementNodeResultIdx(lastElmIdx, elmNodeCount -1);
return lastElmResultIdx + 1;
}

View File

@ -61,6 +61,7 @@ public:
const int* connectivities(size_t elementIdx) const { return &m_allElementConnectivities[m_elementConnectivityStartIndices[elementIdx]];}
size_t elementNodeResultIdx(int elementIdx, int elmLocalNodeIdx) const { return m_elementConnectivityStartIndices[elementIdx] + elmLocalNodeIdx;}
size_t elementNodeResultCount() const;
int nodeIdxFromElementNodeResultIdx(size_t elmNodeResultIdx) const { return m_allElementConnectivities[elmNodeResultIdx]; }
RigFemPartNodes& nodes() {return m_nodes;}

View File

@ -264,6 +264,50 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateBarConvertedResu
return dstDataFrames;
}
//--------------------------------------------------------------------------------------------------
/// Convert POR NODAL result to POR-Bar Elment Nodal result
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultsCollection::calculateEnIpPorBarResult(int partIndex, const RigFemResultAddress &convertedResultAddr)
{
RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR", ""));
RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(convertedResultAddr);
const RigFemPart * femPart = m_femParts->part(partIndex);
float inf = std::numeric_limits<float>::infinity();
int frameCount = srcDataFrames->frameCount();
for (int fIdx = 0; fIdx < frameCount; ++fIdx)
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData(fIdx);
std::vector<float>& dstFrameData = dstDataFrames->frameData(fIdx);
if (!srcFrameData.size()) continue; // Create empty results if we have no POR result.
size_t valCount = femPart->elementNodeResultCount();
dstFrameData.resize(valCount, inf);
int elementCount = femPart->elementCount();
for (int elmIdx = 0; elmIdx < elementCount; ++elmIdx)
{
RigElementType elmType = femPart->elementType(elmIdx);
int elmNodeCount = RigFemTypes::elmentNodeCount(elmType);
if (elmType == HEX8P)
{
for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx)
{
size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx);
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx);
dstFrameData[elmNodResIdx] = 1.0e-5*srcFrameData[nodeIdx];
}
}
}
}
return dstDataFrames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -276,7 +320,10 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in
if (resVarAddr.fieldName == "POR-Bar")
{
return calculateBarConvertedResult(partIndex, resVarAddr, "POR");
if (resVarAddr.resultPosType == RIG_NODAL)
return calculateBarConvertedResult(partIndex, resVarAddr, "POR");
else
return calculateEnIpPorBarResult(partIndex, resVarAddr);
}
if (resVarAddr.fieldName == "NE")
@ -333,7 +380,6 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in
for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx)
{
size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx);
// Todo: Verify that we do not need to check for POR == inf when we have a HEX8P elm
dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx];
}
}

View File

@ -62,6 +62,7 @@ private:
RigFemScalarResultFrames* calculateDerivedResult(int partIndex, const RigFemResultAddress& resVarAddr);
RigFemScalarResultFrames* calculateBarConvertedResult(int partIndex, const RigFemResultAddress &convertedResultAddr, const std::string fieldNameToConvert);
RigFemScalarResultFrames* calculateEnIpPorBarResult(int partIndex, const RigFemResultAddress &convertedResultAddr);
friend class RigFemNativeStatCalc;
cvf::Collection<RigFemPartResults> m_femPartResults;

View File

@ -115,6 +115,9 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c
const double upperBound = propertyFilter->upperBound();
RigFemResultAddress resVarAddress = propertyFilter->resultDefinition->resultAddress();
// Do a "Hack" to use elm nodal and not nodal POR results
if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL;
size_t adjustedTimeStepIndex = timeStepIndex;

View File

@ -234,16 +234,19 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe
RigFemResultAddress resVarAddress = cellResultColors->resultAddress();
// Do a "Hack" to show elm nodal and not nodal POR results
if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL;
const std::vector<float>& resultValues = caseData->femPartResults()->resultValues(resVarAddress, m_gridIdx, (int)timeStepIndex);
const std::vector<size_t>* vxToResultMapping = NULL;
if (cellResultColors->resultPositionType() == RIG_NODAL)
if (resVarAddress.resultPosType == RIG_NODAL)
{
vxToResultMapping = &(m_surfaceGenerator.quadVerticesToNodeIdxMapping());
}
else if ( cellResultColors->resultPositionType() == RIG_ELEMENT_NODAL
|| cellResultColors->resultPositionType() == RIG_INTEGRATION_POINT)
else if ( resVarAddress.resultPosType == RIG_ELEMENT_NODAL
|| resVarAddress.resultPosType == RIG_INTEGRATION_POINT)
{
vxToResultMapping = &(m_surfaceGenerator.quadVerticesToGlobalElmNodeIdx());
}