Basic ODB reading, including results

Now reading nodal results and displacements. Reporting results meta data
(names with components).
This commit is contained in:
Stein Dale 2015-04-30 09:31:33 +02:00 committed by Jacob Støren
parent 3dac8807c7
commit ebfad85b5b
4 changed files with 364 additions and 20 deletions

View File

@ -21,7 +21,11 @@
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfVector3.h"
#include <vector>
#include <map>
#include <string>
class RigFemPartCollection;
@ -37,11 +41,12 @@ public:
RifGeoMechReaderInterface();
virtual ~RifGeoMechReaderInterface();
virtual bool readFemParts(const std::string& fileName, RigFemPartCollection* geoMechCase) = 0;
virtual std::vector<double> timeSteps() = 0;
virtual std::vector<std::string> scalarNodeResultNames() = 0;
virtual void readScalarNodeResult(const std::string& resultName, int partIndex, int stepIndex, std::vector<float>* resultValues ) = 0;
virtual bool readFemParts(const std::string& fileName, RigFemPartCollection* geoMechCase) = 0;
virtual std::vector<std::string> steps() = 0;
virtual std::vector<double> frameTimeValues(int stepIndex) = 0;
virtual std::map<std::string, std::vector<std::string> > scalarNodeResultNames() const = 0;
virtual void readScalarNodeResult(const std::string& resultName, const std::string& componmentName, int partIndex, int stepIndex, int frameIndex, std::vector<float>* resultValues) = 0;
virtual void readDisplacements(int partIndex, int stepIndex, int frameIndex, std::vector<cvf::Vec3f>* displacements) = 0;
private:
};

View File

@ -40,12 +40,14 @@ std::map<std::string, RigElementType> initFemTypeMap()
static std::map<std::string, RigElementType> odbElmTypeToRigElmTypeMap = initFemTypeMap();
bool RifOdbReader::sm_odbAPIInitialized = false;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifOdbReader::RifOdbReader()
{
m_odb = NULL;
}
//--------------------------------------------------------------------------------------------------
@ -53,13 +55,52 @@ RifOdbReader::RifOdbReader()
//--------------------------------------------------------------------------------------------------
RifOdbReader::~RifOdbReader()
{
close();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOdbReader::initializeOdbAPI()
{
if (!sm_odbAPIInitialized)
{
odb_initializeAPI();
sm_odbAPIInitialized = true;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOdbReader::finalizeOdbAPI()
{
if (sm_odbAPIInitialized)
{
odb_finalizeAPI();
sm_odbAPIInitialized = false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOdbReader::close()
{
if (m_odb)
{
m_odb->close();
m_odb = NULL;
}
}
void readOdbFile(const std::string& fileName, RigFemPartCollection* femParts)
{
CVF_ASSERT(femParts);
RifOdbReader::initializeOdbAPI();
odb_String path = fileName.c_str();
odb_Odb& odb = openOdb(path);
@ -142,8 +183,6 @@ void readOdbFile(const std::string& fileName, RigFemPartCollection* femParts)
//--------------------------------------------------------------------------------------------------
bool RifOdbReader::readFemParts(const std::string& fileName, RigFemPartCollection* femParts)
{
odb_initializeAPI();
int status = 0;
try
@ -164,15 +203,275 @@ bool RifOdbReader::readFemParts(const std::string& fileName, RigFemPartCollectio
fprintf(stderr, "ODB Application exited with error(s)\n");
}
odb_finalizeAPI();
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RifOdbReader::timeSteps()
std::vector<std::string> RifOdbReader::steps()
{
return std::vector<double>();
CVF_ASSERT(m_odb != NULL);
std::vector<std::string> stepNames;
odb_StepRepository stepRepository = m_odb->steps();
odb_StepRepositoryIT sIter(stepRepository);
for (sIter.first(); !sIter.isDone(); sIter.next())
{
stepNames.push_back(stepRepository[sIter.currentKey()].name().CStr());
}
return stepNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RifOdbReader::frameTimeValues(int stepIndex)
{
CVF_ASSERT(m_odb != NULL);
odb_StepRepository& stepRepository = m_odb->steps();
odb_StepList stepList = stepRepository.stepList();
odb_Step& step = stepList.Get(stepIndex);
odb_SequenceFrame& stepFrames = step.frames();
std::vector<double> frameValues;
int numFrames = stepFrames.size();
for (int f = 0; f < numFrames; f++)
{
odb_Frame frame = stepFrames.constGet(f);
frameValues.push_back(frame.frameValue());
}
return frameValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<std::string, std::vector<std::string> > RifOdbReader::scalarNodeResultNames() const
{
CVF_ASSERT(m_odb != NULL);
std::map<std::string, std::vector<std::string> > resultNamesMap;
odb_StepRepository stepRepository = m_odb->steps();
odb_StepRepositoryIT sIter(stepRepository);
for (sIter.first(); !sIter.isDone(); sIter.next())
{
odb_SequenceFrame& stepFrames = stepRepository[sIter.currentKey()].frames();
int numFrames = stepFrames.size();
for (int f = 0; f < numFrames; f++)
{
odb_Frame frame = stepFrames.constGet(f);
odb_FieldOutputRepository& fieldCon = frame.fieldOutputs();
odb_FieldOutputRepositoryIT fieldConIT(fieldCon);
for (fieldConIT.first(); !fieldConIT.isDone(); fieldConIT.next())
{
odb_FieldOutput& field = fieldCon[fieldConIT.currentKey()];
std::string fieldName = field.name().CStr();
odb_SequenceString components = field.componentLabels();
std::vector<std::string> compVec;
int numComp = components.size();
for (int comp = 0; comp < numComp; comp++)
{
compVec.push_back(components[comp].CStr());
}
resultNamesMap.insert(std::make_pair(fieldName, compVec));
}
}
}
return resultNamesMap;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
odb_Frame RifOdbReader::stepFrame(int stepIndex, int frameIndex) const
{
CVF_ASSERT(m_odb);
odb_StepRepository& stepRepository = m_odb->steps();
odb_StepList stepList = stepRepository.stepList();
odb_Step& step = stepList.Get(stepIndex);
odb_SequenceFrame& stepFrames = step.frames();
return stepFrames.constGet(frameIndex);
}
//--------------------------------------------------------------------------------------------------
/// Get the number of result items (== #nodes or #elements)
//--------------------------------------------------------------------------------------------------
size_t RifOdbReader::resultItemCount(const std::string& resultName, int stepIndex, int frameIndex) const
{
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutputRepository& fieldOutputRepo = frame.fieldOutputs();
odb_String fieldName = resultName.c_str();
CVF_ASSERT(fieldOutputRepo.isMember(fieldName));
const odb_FieldOutput& fieldOutput = fieldOutputRepo[fieldName];
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
size_t resultItemCount = 0;
int numBlocks = seqFieldBulkData.size();
for (int block = 0; block < numBlocks; block++)
{
const odb_FieldBulkData& bulkData = seqFieldBulkData[block];
resultItemCount += bulkData.length();
}
return resultItemCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifOdbReader::componentIndex(const std::string& resultName, const std::string& componentName) const
{
std::map<std::string, std::vector<std::string> > resultCompMap = scalarNodeResultNames();
std::vector<std::string> comps = resultCompMap.at(resultName);
for (size_t i = 0; i < comps.size(); i++)
{
if (comps[i] == componentName)
{
return i;
}
}
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOdbReader::readScalarNodeResult(const std::string& resultName, const std::string& componentName, int partIndex, int stepIndex, int frameIndex, std::vector<float>* resultValues)
{
CVF_ASSERT(resultValues);
size_t dataSize = resultItemCount(resultName, stepIndex, frameIndex);
if (dataSize > 0)
{
resultValues->resize(dataSize);
}
int compIndex = componentIndex(resultName, componentName);
CVF_ASSERT(compIndex >= 0);
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutput& fieldOutput = frame.fieldOutputs()[resultName.c_str()];
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
size_t dataIndex = 0;
int numBlocks = seqFieldBulkData.size();
for (int block = 0; block < numBlocks; block++)
{
const odb_FieldBulkData& bulkData = seqFieldBulkData[block];
if (bulkData.numberOfNodes() > 0)
{
int numNodes = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
for (int i = 0; i < numNodes; i++)
{
(*resultValues)[dataIndex++] = data[i*numComp + compIndex];
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOdbReader::readDisplacements(int partIndex, int stepIndex, int frameIndex, std::vector<cvf::Vec3f>* displacements)
{
CVF_ASSERT(displacements);
//
size_t dataSize = resultItemCount("U", stepIndex, frameIndex);
if (dataSize > 0)
{
displacements->resize(dataSize);
}
const odb_Frame& frame = stepFrame(stepIndex, frameIndex);
const odb_FieldOutput& fieldOutput = frame.fieldOutputs()["U"];
const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks();
size_t dataIndex = 0;
int numBlocks = seqFieldBulkData.size();
for (int block = 0; block < numBlocks; block++)
{
const odb_FieldBulkData& bulkData = seqFieldBulkData[block];
if (bulkData.numberOfNodes() > 0)
{
int numNodes = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
for (int i = 0; i < numNodes; i++)
{
(*displacements)[i + dataIndex].set(data[i*numComp], data[i*numComp + 1], data[i*numComp + 2]);
}
dataIndex += numNodes*numComp;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifOdbReader::openFile(const std::string& fileName)
{
close();
CVF_ASSERT(m_odb == NULL);
if (!sm_odbAPIInitialized)
{
initializeOdbAPI();
}
odb_String path = fileName.c_str();
try
{
m_odb = &openOdb(path);
}
catch (const nex_Exception& nex)
{
fprintf(stderr, "%s\n", nex.UserReport().CStr());
fprintf(stderr, "ODB Application exited with error(s)\n");
}
catch (...)
{
fprintf(stderr, "ODB Application exited with error(s)\n");
}
return true;
}

View File

@ -25,6 +25,9 @@
class RigFemPartCollection;
class odb_Odb;
class odb_Frame;
//==================================================================================================
//
// Data interface base class
@ -37,11 +40,25 @@ public:
RifOdbReader();
virtual ~RifOdbReader();
virtual bool readFemParts(const std::string& fileName, RigFemPartCollection* femParts);
virtual std::vector<double> timeSteps();
virtual std::vector<std::string> scalarNodeResultNames() {return std::vector<std::string> ();};
virtual void readScalarNodeResult(const std::string& resultName, int partIndex, int stepIndex, std::vector<float>* resultValues ) {};
static void initializeOdbAPI();
static void finalizeOdbAPI();
virtual bool readFemParts(const std::string& fileName, RigFemPartCollection* geoMechCase);
virtual std::vector<std::string> steps();
virtual std::vector<double> frameTimeValues(int stepIndex);
virtual std::map<std::string, std::vector<std::string> > scalarNodeResultNames() const;
virtual void readScalarNodeResult(const std::string& resultName, const std::string& componmentName, int partIndex, int stepIndex, int frameIndex, std::vector<float>* resultValues);
virtual void readDisplacements(int partIndex, int stepIndex, int frameIndex, std::vector<cvf::Vec3f>* displacements);
bool openFile(const std::string& fileName);
private:
void close();
size_t resultItemCount(const std::string& resultName, int stepIndex, int frameIndex) const;
odb_Frame stepFrame(int stepIndex, int frameIndex) const;
int componentIndex(const std::string& resultName, const std::string& componentName) const;
private:
odb_Odb* m_odb;
static bool sm_odbAPIInitialized;
};

View File

@ -21,6 +21,9 @@
#include "RifOdbReader.h"
#include "RigGeoMechCaseData.h"
#include <vector>
#include <string>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -33,9 +36,29 @@ TEST(OdbReaderTest, BasicTests)
cvf::ref<RigFemPartCollection> femData = femCase->femParts();
reader->readFemParts(TEST_FILE, femData.p());
EXPECT_EQ(1, femData->partCount());
EXPECT_EQ(149, femData->part(0)->elementCount());
EXPECT_EQ(CAX4, femData->part(0)->elementType(0));
EXPECT_EQ(4320, femData->part(0)->elementCount());
EXPECT_EQ(HEX8, femData->part(0)->elementType(0));
cvf::ref<RifOdbReader> reader2 = new RifOdbReader;
EXPECT_EQ(true, reader2->openFile(TEST_FILE));
EXPECT_EQ(true, reader2->steps().size() == 1);
std::vector<std::string> steps = reader2->steps();
EXPECT_EQ(true, steps.at(0).find("Date_20100930") >= 0);
EXPECT_EQ(2, reader2->frameTimeValues(0).size());
EXPECT_EQ(1.0, reader2->frameTimeValues(0)[1]);
std::map<std::string, std::vector<std::string> > resultNamesMap = reader2->scalarNodeResultNames();
EXPECT_EQ(8, resultNamesMap.size());
std::vector<float> displacementValues;
reader2->readScalarNodeResult("U", "U2", 0, 0, 1, &displacementValues);
EXPECT_EQ(5168, displacementValues.size());
std::vector<cvf::Vec3f> displacements;
reader2->readDisplacements(0, 0, 1, &displacements);
EXPECT_EQ(5168, displacements.size());
EXPECT_FLOAT_EQ(0.047638997, displacements[1].y());
}