Results per part instance

Improved reading of results. Made sure that field subsets for the
correct part instance are used. Keeping id to index maps for elements
and nodes, which are used when reading results. Note: Geometry must have
been read before reading results.
This commit is contained in:
Stein Dale 2015-05-06 09:47:19 +02:00
parent 64bbcc04f8
commit 5ad9cf80e3
2 changed files with 125 additions and 40 deletions

View File

@ -26,6 +26,7 @@
#include <map>
#include <iostream>
#include <limits>
std::map<std::string, RigElementType> initFemTypeMap()
{
@ -277,7 +278,8 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts)
odb_InstanceRepositoryIT iter(instanceRepository);
for (iter.first(); !iter.isDone(); iter.next())
int instanceCount = 0;
for (iter.first(); !iter.isDone(); iter.next(), instanceCount++)
{
odb_Instance& inst = instanceRepository[iter.currentKey()];
@ -301,6 +303,9 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts)
nodeIdToIdxMap[odbNode.label()] = nIdx;
}
// Keep node id to index map per instance
m_instanceToNodeIdToIdxMap[instanceCount] = nodeIdToIdxMap;
// Extract elements
const odb_SequenceElement& elements = inst.elements();
@ -308,11 +313,14 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts)
femPart->preAllocateElementStorage(elmCount);
std::map<std::string, RigElementType>::const_iterator it;
std::vector<int> indexBasedConnectivities;
std::map<int, int> elementIdToIdxMap;
for (int elmIdx = 0; elmIdx < elmCount; ++elmIdx)
{
const odb_Element odbElm = elements.element(elmIdx);
elementIdToIdxMap[odbElm.label()] = elmIdx;
// Get the type
it = odbElmTypeToRigElmTypeMap.find(odbElm.type().cStr());
@ -339,6 +347,9 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts)
femPart->appendElement(elmType, odbElm.label(), indexBasedConnectivities.data());
}
// Keep element id to index map per instance
m_instanceToElementIdToIdxMap[instanceCount] = elementIdToIdxMap;
femPart->setElementPartId(femParts->partCount());
femParts->addFemPart(femPart);
}
@ -436,6 +447,32 @@ odb_Frame RifOdbReader::stepFrame(int stepIndex, int frameIndex) const
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
odb_Instance* RifOdbReader::instance(int instanceIndex)
{
CVF_ASSERT(m_odb != NULL);
odb_Assembly& rootAssembly = m_odb->rootAssembly();
odb_InstanceRepository& instanceRepository = m_odb->rootAssembly().instances();
odb_InstanceRepositoryIT iter(instanceRepository);
int instanceCount = 0;
for (iter.first(); !iter.isDone(); iter.next(), instanceCount++)
{
odb_Instance& inst = instanceRepository[iter.currentKey()];
if (instanceCount == instanceIndex)
{
return &inst;
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
/// Get the number of result items (== #nodes or #elements)
//--------------------------------------------------------------------------------------------------
@ -530,17 +567,25 @@ void RifOdbReader::readScalarNodeField(const std::string& fieldName, const std::
{
CVF_ASSERT(resultValues);
size_t dataSize = resultItemCount(fieldName, stepIndex, frameIndex);
if (dataSize > 0)
{
resultValues->resize(dataSize);
}
odb_Instance* partInstance = instance(partIndex);
CVF_ASSERT(partInstance != NULL);
auto nodeIdToIdxMapIt = m_instanceToNodeIdToIdxMap.find(partIndex);
CVF_ASSERT(nodeIdToIdxMapIt != m_instanceToNodeIdToIdxMap.end());
auto nodeIdToIdxMap = nodeIdToIdxMapIt->second;
size_t dataSize = nodeIdToIdxMap.size();
CVF_ASSERT(dataSize > 0);
resultValues->resize(dataSize);
resultValues->assign(dataSize, std::numeric_limits<float>::infinity());
int compIndex = componentIndex(RifOdbResultPosition::NODAL, fieldName, componentName);
CVF_ASSERT(compIndex >= 0);
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutput& fieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(odb_Enum::NODAL);
const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance);
const odb_FieldOutput& fieldOutput = instanceFieldOutput.getSubset(odb_Enum::NODAL);
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
size_t dataIndex = 0;
@ -549,16 +594,14 @@ void RifOdbReader::readScalarNodeField(const std::string& fieldName, const std::
{
const odb_FieldBulkData& bulkData = seqFieldBulkData[block];
if (bulkData.numberOfNodes() > 0)
{
int numNodes = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
int numNodes = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
int* nodeLabels = bulkData.nodeLabels();
for (int i = 0; i < numNodes; i++)
{
(*resultValues)[dataIndex++] = data[i*numComp + compIndex];
}
for (int i = 0; i < numNodes; i++)
{
(*resultValues)[nodeIdToIdxMap[nodeLabels[i]]] = data[i*numComp + compIndex];
}
}
}
@ -571,21 +614,28 @@ void RifOdbReader::readScalarElementNodeField(const std::string& fieldName, cons
{
CVF_ASSERT(resultValues);
// TODO:
// Need example files containing element node results for testing
// Or, consider reporting integration point results as element node results too, and extrapolate when requested
odb_Instance* partInstance = instance(partIndex);
CVF_ASSERT(partInstance != NULL);
size_t dataSize = resultItemCount(fieldName, stepIndex, frameIndex);
auto elementIdToIdxMapIt = m_instanceToElementIdToIdxMap.find(partIndex);
CVF_ASSERT(elementIdToIdxMapIt != m_instanceToElementIdToIdxMap.end());
auto elementIdToIdxMap = elementIdToIdxMapIt->second;
CVF_ASSERT(elementIdToIdxMap.size() > 0);
size_t dataSize = resultItemCount(fieldName, stepIndex, frameIndex);
if (dataSize > 0)
{
resultValues->resize(dataSize);
resultValues->assign(dataSize, std::numeric_limits<float>::infinity());
}
int compIndex = componentIndex(RifOdbResultPosition::ELEMENT_NODAL, fieldName, componentName);
CVF_ASSERT(compIndex >= 0);
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutput& fieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(odb_Enum::ELEMENT_NODAL);
const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance);
const odb_FieldOutput& fieldOutput = instanceFieldOutput.getSubset(odb_Enum::ELEMENT_NODAL);
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
size_t dataIndex = 0;
@ -594,17 +644,24 @@ void RifOdbReader::readScalarElementNodeField(const std::string& fieldName, cons
{
const odb_FieldBulkData& bulkData = seqFieldBulkData[block];
if (bulkData.numberOfNodes() > 0)
{
int numNodes = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
int numValues = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
int elemCount = bulkData.numberOfElements();
int elemNodeCount = numValues/elemCount;
int* elementLabels = bulkData.elementLabels();
for (int i = 0; i < numNodes; i++)
{
(*resultValues)[dataIndex++] = data[i*numComp + compIndex];
}
}
for (int elem = 0; elem < elemCount; elem++)
{
int elementIdx = elementIdToIdxMap[elementLabels[elem*elemNodeCount]];
for (int elemNode = 0; elemNode < elemNodeCount; elemNode++)
{
int destIdx = elementIdx*elemNodeCount + elemNode;
int srcIdx = elem*elemNodeCount*numComp + elemNode*numComp + compIndex;
(*resultValues)[destIdx] = data[srcIdx];
}
}
}
}
@ -616,17 +673,28 @@ void RifOdbReader::readScalarIntegrationPointField(const std::string& fieldName,
{
CVF_ASSERT(resultValues);
size_t dataSize = resultItemCount(fieldName, stepIndex, frameIndex);
odb_Instance* partInstance = instance(partIndex);
CVF_ASSERT(partInstance != NULL);
auto elementIdToIdxMapIt = m_instanceToElementIdToIdxMap.find(partIndex);
CVF_ASSERT(elementIdToIdxMapIt != m_instanceToElementIdToIdxMap.end());
auto elementIdToIdxMap = elementIdToIdxMapIt->second;
CVF_ASSERT(elementIdToIdxMap.size() > 0);
size_t dataSize = resultItemCount(fieldName, stepIndex, frameIndex);
if (dataSize > 0)
{
resultValues->resize(dataSize);
resultValues->assign(dataSize, std::numeric_limits<float>::infinity());
}
int compIndex = componentIndex(RifOdbResultPosition::INTEGRATION_POINT, fieldName, componentName);
CVF_ASSERT(compIndex >= 0);
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutput& fieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(odb_Enum::INTEGRATION_POINT);
const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance);
const odb_FieldOutput& fieldOutput = instanceFieldOutput.getSubset(odb_Enum::INTEGRATION_POINT);
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
size_t dataIndex = 0;
@ -635,14 +703,24 @@ void RifOdbReader::readScalarIntegrationPointField(const std::string& fieldName,
{
const odb_FieldBulkData& bulkData = seqFieldBulkData[block];
int numNodes = bulkData.length();
int numValues = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
int elemCount = bulkData.numberOfElements();
int ipCount = numValues/elemCount;
int* elementLabels = bulkData.elementLabels();
for (int i = 0; i < numNodes; i++)
{
(*resultValues)[dataIndex++] = data[i*numComp + compIndex];
}
for (int elem = 0; elem < elemCount; elem++)
{
int elementIdx = elementIdToIdxMap[elementLabels[elem*ipCount]];
for (int ip = 0; ip < ipCount; ip++)
{
int destIdx = elementIdx*ipCount + ip;
int srcIdx = elem*ipCount*numComp + ip*numComp + compIndex;
(*resultValues)[destIdx] = data[srcIdx];
}
}
}
}
@ -654,6 +732,9 @@ void RifOdbReader::readDisplacements(int partIndex, int stepIndex, int frameInde
{
CVF_ASSERT(displacements);
odb_Instance* partInstance = instance(partIndex);
CVF_ASSERT(partInstance != NULL);
size_t dataSize = resultItemCount("U", stepIndex, frameIndex);
if (dataSize > 0)
{
@ -661,8 +742,8 @@ void RifOdbReader::readDisplacements(int partIndex, int stepIndex, int frameInde
}
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutput& fieldOutput = frame.fieldOutputs()["U"];
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()["U"].getSubset(*partInstance);
const odb_SequenceFieldBulkData& seqFieldBulkData = instanceFieldOutput.bulkDataBlocks();
size_t dataIndex = 0;
int numBlocks = seqFieldBulkData.size();

View File

@ -27,6 +27,7 @@ class RigFemPartCollection;
class odb_Odb;
class odb_Frame;
class odb_Instance;
enum RifOdbResultPosition
{
@ -67,6 +68,7 @@ private:
void close();
size_t resultItemCount(const std::string& fieldName, int stepIndex, int frameIndex) const;
odb_Frame stepFrame(int stepIndex, int frameIndex) const;
odb_Instance* instance(int instanceIndex);
int componentIndex(RifOdbResultPosition position, const std::string& fieldName, const std::string& componentName) const;
std::vector<std::string> componentNames(RifOdbResultPosition position, const std::string& fieldName) const;
std::map<std::string, std::vector<std::string> > fieldAndComponentNames(RifOdbResultPosition position);
@ -77,6 +79,8 @@ private:
private:
odb_Odb* m_odb;
std::map< std::pair<RifOdbResultPosition, std::string>, std::vector<std::string> > m_resultsMetaData;
std::map< int, std::map<int, int> > m_instanceToNodeIdToIdxMap;
std::map< int, std::map<int, int> > m_instanceToElementIdToIdxMap;
static bool sm_odbAPIInitialized;
};