diff --git a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h index 24828a076c..54d8c90afa 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h +++ b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h @@ -58,6 +58,10 @@ public: virtual void readScalarElementNodeField(const std::string& fieldName, const std::string& componmentName, int partIndex, int stepIndex, int frameIndex, std::vector* resultValues) = 0; virtual void readScalarIntegrationPointField(const std::string& fieldName, const std::string& componmentName, int partIndex, int stepIndex, int frameIndex, std::vector* resultValues) = 0; virtual void readDisplacements(int partIndex, int stepIndex, int frameIndex, std::vector* displacements) = 0; + + virtual void readNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; + virtual void readElementNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; + virtual void readIntegrationPointField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; private: }; diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp index 85c24cc743..5004aa9733 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp @@ -295,16 +295,16 @@ std::map< RifOdbReader::RifOdbResultKey, std::vector > RifOdbReader switch (fieldLocation.position()) { case odb_Enum::NODAL: - resultsMap[RifOdbResultKey(RifOdbResultKey::NODAL, fieldName)] = compVec; + resultsMap[RifOdbResultKey(NODAL, fieldName)] = compVec; break; case odb_Enum::ELEMENT_NODAL: - resultsMap[RifOdbResultKey(RifOdbResultKey::ELEMENT_NODAL, fieldName)] = compVec; + resultsMap[RifOdbResultKey(ELEMENT_NODAL, fieldName)] = compVec; break; case odb_Enum::INTEGRATION_POINT: - resultsMap[RifOdbResultKey(RifOdbResultKey::INTEGRATION_POINT, fieldName)] = compVec; - resultsMap[RifOdbResultKey(RifOdbResultKey::ELEMENT_NODAL, fieldName)] = compVec; + resultsMap[RifOdbResultKey(INTEGRATION_POINT, fieldName)] = compVec; + resultsMap[RifOdbResultKey(ELEMENT_NODAL, fieldName)] = compVec; break; default: @@ -543,7 +543,7 @@ std::vector RifOdbReader::elementSet(int partIndex, int setIndex) //-------------------------------------------------------------------------------------------------- std::map > RifOdbReader::scalarNodeFieldAndComponentNames() { - return fieldAndComponentNames(RifOdbResultKey::NODAL); + return fieldAndComponentNames(NODAL); } @@ -552,7 +552,7 @@ std::map > RifOdbReader::scalarNodeFieldAn //-------------------------------------------------------------------------------------------------- std::map > RifOdbReader::scalarElementNodeFieldAndComponentNames() { - return fieldAndComponentNames(RifOdbResultKey::ELEMENT_NODAL); + return fieldAndComponentNames(ELEMENT_NODAL); } @@ -561,7 +561,7 @@ std::map > RifOdbReader::scalarElementNode //-------------------------------------------------------------------------------------------------- std::map > RifOdbReader::scalarIntegrationPointFieldAndComponentNames() { - return fieldAndComponentNames(RifOdbResultKey::INTEGRATION_POINT); + return fieldAndComponentNames(INTEGRATION_POINT); } @@ -607,6 +607,31 @@ odb_Instance* RifOdbReader::instance(int instanceIndex) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const odb_SequenceFieldBulkData& RifOdbReader::fieldBulkData(const std::string& fieldName, ResultPosition position, odb_Instance* instance, const odb_Frame& frame) +{ + odb_FieldOutput& fieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*instance); + + switch (position) + { + case ELEMENT_NODAL: + fieldOutput = fieldOutput.getSubset(odb_Enum::ELEMENT_NODAL); + break; + + case INTEGRATION_POINT: + fieldOutput = fieldOutput.getSubset(odb_Enum::INTEGRATION_POINT); + break; + + default: + break; + } + + return fieldOutput.bulkDataBlocks(); +} + + //-------------------------------------------------------------------------------------------------- /// Get the number of result items (== #nodes or #elements) //-------------------------------------------------------------------------------------------------- @@ -631,6 +656,17 @@ size_t RifOdbReader::resultItemCount(const std::string& fieldName, int partIndex return resultItemCount; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RifOdbReader::componentsCount(const std::string& fieldName, ResultPosition position) +{ + std::vector compNames = componentNames(RifOdbResultKey(position, fieldName)); + return compNames.size() > 0 ? compNames.size() : 1; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -677,7 +713,7 @@ std::vector RifOdbReader::componentNames(const RifOdbResultKey& res //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::map > RifOdbReader::fieldAndComponentNames(RifOdbResultKey::ResultPosition position) +std::map > RifOdbReader::fieldAndComponentNames(ResultPosition position) { assertMetaDataLoaded(); @@ -710,8 +746,7 @@ void RifOdbReader::readScalarNodeField(const std::string& fieldName, const std:: size_t dataSize = nodeIdToIdxMap.size(); CVF_ASSERT(dataSize > 0); - - int compIndex = componentIndex(RifOdbResultKey(RifOdbResultKey::NODAL, fieldName), componentName); + int compIndex = componentIndex(RifOdbResultKey(NODAL, fieldName), componentName); if (compIndex < 0) return; @@ -758,7 +793,7 @@ void RifOdbReader::readScalarElementNodeField(const std::string& fieldName, cons std::map& elementIdToIdxMap = m_elementIdToIdxMaps[partIndex]; CVF_ASSERT(elementIdToIdxMap.size() > 0); - int compIndex = componentIndex(RifOdbResultKey(RifOdbResultKey::ELEMENT_NODAL, fieldName), componentName); + int compIndex = componentIndex(RifOdbResultKey(ELEMENT_NODAL, fieldName), componentName); if (compIndex < 0) return; size_t dataSize = resultItemCount(fieldName, partIndex, stepIndex, frameIndex); @@ -819,8 +854,7 @@ void RifOdbReader::readScalarIntegrationPointField( const std::string& fieldName std::map& elementIdToIdxMap = m_elementIdToIdxMaps[partIndex]; CVF_ASSERT(elementIdToIdxMap.size() > 0); - - int compIndex = componentIndex(RifOdbResultKey(RifOdbResultKey::INTEGRATION_POINT, fieldName), componentName); + int compIndex = componentIndex(RifOdbResultKey(INTEGRATION_POINT, fieldName), componentName); if (compIndex < 0) return; size_t dataSize = resultItemCount(fieldName, partIndex, stepIndex, frameIndex); @@ -914,3 +948,198 @@ void RifOdbReader::readDisplacements(int partIndex, int stepIndex, int frameInde } } } + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifOdbReader::readNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) +{ + CVF_ASSERT(resultValues); + + odb_Instance* partInstance = instance(partIndex); + CVF_ASSERT(partInstance != NULL); + + size_t compCount = componentsCount(fieldName, NODAL); + CVF_ASSERT(compCount == resultValues->size()); + + std::map& nodeIdToIdxMap = m_nodeIdToIdxMaps[partIndex]; + + size_t dataSize = nodeIdToIdxMap.size()*compCount; + if (dataSize > 0) + { + for (int comp = 0; comp < compCount; comp++) + { + CVF_ASSERT((*resultValues)[comp]); + + (*resultValues)[comp]->resize(dataSize); + (*resultValues)[comp]->assign(dataSize, std::numeric_limits::infinity()); + } + } + + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_SequenceFieldBulkData& seqFieldBulkData = fieldBulkData(fieldName, NODAL, partInstance, frame); + + size_t dataIndex = 0; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + RifOdbBulkDataGetter bulkDataGetter(bulkData); + + int numNodes = bulkData.length(); + int numComp = bulkData.width(); + int* nodeLabels = bulkData.nodeLabels(); + float* data = bulkDataGetter.data(); + + for (int i = 0; i < numNodes; i++) + { + for (int comp = 0; comp < numComp; comp++) + { + (*(*resultValues)[comp])[nodeIdToIdxMap[nodeLabels[i]]] = data[i*numComp + comp]; + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifOdbReader::readElementNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) +{ + CVF_ASSERT(resultValues); + + odb_Instance* partInstance = instance(partIndex); + CVF_ASSERT(partInstance != NULL); + + size_t compCount = componentsCount(fieldName, ELEMENT_NODAL); + CVF_ASSERT(compCount == resultValues->size()); + + size_t dataSize = resultItemCount(fieldName, partIndex, stepIndex, frameIndex)*compCount; + if (dataSize > 0) + { + for (int comp = 0; comp < compCount; comp++) + { + CVF_ASSERT((*resultValues)[comp]); + + (*resultValues)[comp]->resize(dataSize); + (*resultValues)[comp]->assign(dataSize, std::numeric_limits::infinity()); + } + } + + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_SequenceFieldBulkData& seqFieldBulkData = fieldBulkData(fieldName, ELEMENT_NODAL, partInstance, frame); + + std::map& elementIdToIdxMap = m_elementIdToIdxMaps[partIndex]; + CVF_ASSERT(elementIdToIdxMap.size() > 0); + + size_t dataIndex = 0; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + RifOdbBulkDataGetter bulkDataGetter(bulkData); + + int numValues = bulkData.length(); + int numComp = bulkData.width(); + int elemCount = bulkData.numberOfElements(); + int ipCount = numValues/elemCount; + int* elementLabels = bulkData.elementLabels(); + float* data = bulkDataGetter.data(); + + RigElementType eType = toRigElementType(bulkData.baseElementType()); + const int* elmNodeToIpResultMapping = localElmNodeToIntegrationPointMapping(eType); + if (!elmNodeToIpResultMapping) continue; + + for (int elem = 0; elem < elemCount; elem++) + { + int elementIdx = elementIdToIdxMap[elementLabels[elem*ipCount]]; + int elementResultStartDestIdx = elementIdx*ipCount; // Ikke generellt riktig ! + int elementResultStartSourceIdx = elem*ipCount*numComp; + + for (int ipIdx = 0; ipIdx < ipCount; ipIdx++) + { + int resultIpIdx = elmNodeToIpResultMapping[ipIdx]; + int destIdx = elementResultStartDestIdx + ipIdx; + int srcIdx = elementResultStartSourceIdx + resultIpIdx*numComp; + + for (int comp = 0; comp < numComp; comp++) + { + (*(*resultValues)[comp])[destIdx] = data[srcIdx + comp]; + } + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifOdbReader::readIntegrationPointField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) +{ + CVF_ASSERT(resultValues); + + odb_Instance* partInstance = instance(partIndex); + CVF_ASSERT(partInstance != NULL); + + size_t compCount = componentsCount(fieldName, INTEGRATION_POINT); + CVF_ASSERT(compCount == resultValues->size()); + + size_t dataSize = resultItemCount(fieldName, partIndex, stepIndex, frameIndex)*compCount; + if (dataSize > 0) + { + for (int comp = 0; comp < compCount; comp++) + { + CVF_ASSERT((*resultValues)[comp]); + + (*resultValues)[comp]->resize(dataSize); + (*resultValues)[comp]->assign(dataSize, std::numeric_limits::infinity()); + } + } + + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_SequenceFieldBulkData& seqFieldBulkData = fieldBulkData(fieldName, INTEGRATION_POINT, partInstance, frame); + + std::map& elementIdToIdxMap = m_elementIdToIdxMaps[partIndex]; + CVF_ASSERT(elementIdToIdxMap.size() > 0); + + size_t dataIndex = 0; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + RifOdbBulkDataGetter bulkDataGetter(bulkData); + + int numValues = bulkData.length(); + int numComp = bulkData.width(); + int elemCount = bulkData.numberOfElements(); + int ipCount = numValues/elemCount; + int* elementLabels = bulkData.elementLabels(); + float* data = bulkDataGetter.data(); + + RigElementType eType = toRigElementType(bulkData.baseElementType()); + const int* elmNodeToIpResultMapping = localElmNodeToIntegrationPointMapping(eType); + if (!elmNodeToIpResultMapping) continue; + + for (int elem = 0; elem < elemCount; elem++) + { + int elementIdx = elementIdToIdxMap[elementLabels[elem*ipCount]]; + int elementResultStartDestIdx = elementIdx*ipCount; // Ikke generellt riktig ! + int elementResultStartSourceIdx = elem*ipCount*numComp; + + for (int ipIdx = 0; ipIdx < ipCount; ipIdx++) + { + int resultIpIdx = elmNodeToIpResultMapping[ipIdx]; + int destIdx = elementResultStartDestIdx + ipIdx; + int srcIdx = elementResultStartSourceIdx + resultIpIdx*numComp; + + for (int comp = 0; comp < numComp; comp++) + { + (*(*resultValues)[comp])[destIdx] = data[srcIdx + comp]; + } + } + } + } +} diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h index ea7180a8d3..300de3ae0e 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h @@ -28,6 +28,7 @@ class RigFemPartCollection; class odb_Odb; class odb_Frame; class odb_Instance; +class odb_SequenceFieldBulkData; //================================================================================================== // @@ -58,17 +59,21 @@ public: virtual void readScalarIntegrationPointField(const std::string& fieldName, const std::string& componmentName, int partIndex, int stepIndex, int frameIndex, std::vector* resultValues); virtual void readDisplacements(int partIndex, int stepIndex, int frameIndex, std::vector* displacements); + virtual void readNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues); + virtual void readElementNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues); + virtual void readIntegrationPointField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues); + private: + enum ResultPosition + { + NODAL, + ELEMENT_NODAL, + INTEGRATION_POINT + }; + class RifOdbResultKey { public: - enum ResultPosition - { - NODAL, - ELEMENT_NODAL, - INTEGRATION_POINT - }; - RifOdbResultKey(ResultPosition aResultPostion, const std::string& aFieldName) : resultPostion(aResultPostion), fieldName(aFieldName) {}; @@ -89,11 +94,13 @@ private: void assertMetaDataLoaded(); void close(); size_t resultItemCount(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex); + size_t componentsCount(const std::string& fieldName, ResultPosition position); const odb_Frame& stepFrame(int stepIndex, int frameIndex) const; odb_Instance* instance(int instanceIndex); + const odb_SequenceFieldBulkData& fieldBulkData(const std::string& fieldName, ResultPosition position, odb_Instance*, const odb_Frame& frame); int componentIndex(const RifOdbResultKey& result, const std::string& componentName); std::vector componentNames(const RifOdbResultKey& result); - std::map< std::string, std::vector > fieldAndComponentNames(RifOdbResultKey::ResultPosition position); + std::map< std::string, std::vector > fieldAndComponentNames(ResultPosition position); std::map< RifOdbResultKey, std::vector > readResultsMetaData(odb_Odb* odb); private: