diff --git a/CMakeLists.txt b/CMakeLists.txt index 442965b3091781bedb443d53fcf41ee3b79f6283..40af6fb2b761d89c1859f587e16f6a80dcc93446 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ set(XdmfSources XdmfItem XdmfItemProperty XdmfObject + XdmfReader XdmfTopology XdmfTopologyType XdmfVisitor diff --git a/Xdmf.i b/Xdmf.i index fc07b36921f72160d48dcaf34bd687ea77009fa0..7a48f89d6724694488c7eb7e4fb61fee29fe6a5d 100644 --- a/Xdmf.i +++ b/Xdmf.i @@ -14,11 +14,12 @@ swig -v -c++ -python -o XdmfPython.cpp Xdmf.i #include #include #include - #include + #include #include #include #include #include + #include #include #include #include @@ -58,6 +59,7 @@ namespace boost { %template(XdmfHDF5WriterPtr) boost::shared_ptr; %template(XdmfItemPtr) boost::shared_ptr; %template(XdmfObjPtr) boost::shared_ptr; +%template(XdmfReaderPtr) boost::shared_ptr; %template(XdmfTopologyPtr) boost::shared_ptr; %template(XdmfVisitorPtr) boost::shared_ptr; %template(XdmfWriterPtr) boost::shared_ptr; @@ -91,6 +93,7 @@ SWIG_SHARED_PTR_DERIVED(XdmfHDF5Writer, XdmfVisitor); SWIG_SHARED_PTR_DERIVED(XdmfHDF5Writer, Loki::BaseVisitor); SWIG_SHARED_PTR_DERIVED(XdmfHDF5Writer, XdmfObject); SWIG_SHARED_PTR_DERIVED(XdmfItem, XdmfObject); +SWIG_SHARED_PTR_DERIVED(XdmfReader, XdmfObject); SWIG_SHARED_PTR_DERIVED(XdmfTopology, XdmfDataItem); SWIG_SHARED_PTR_DERIVED(XdmfTopology, XdmfItem); SWIG_SHARED_PTR_DERIVED(XdmfTopology, XdmfObject); @@ -103,15 +106,15 @@ SWIG_SHARED_PTR_DERIVED(XdmfWriter, XdmfObject); %include XdmfObject.hpp %include XdmfItem.hpp +%include XdmfDataItem.hpp %include XdmfItemProperty.hpp %include XdmfVisitor.hpp %include XdmfHDF5Controller.hpp %include XdmfHDF5Writer.hpp +%include XdmfReader.hpp %include XdmfWriter.hpp -%include XdmfDataItem.hpp - %include XdmfAttribute.hpp %include XdmfAttributeCenter.hpp %include XdmfAttributeType.hpp diff --git a/XdmfArray.cpp b/XdmfArray.cpp index 48afcf7fabbd2e3582c9af30efc29dbe0b8b2c5e..16b1372a1b7aa0397058cfb2cf78603c9ea16899 100644 --- a/XdmfArray.cpp +++ b/XdmfArray.cpp @@ -5,10 +5,12 @@ * Author: kleiter */ +#include +#include +#include #include "XdmfArray.hpp" #include "XdmfHDF5Controller.hpp" #include "XdmfVisitor.hpp" -#include class XdmfArray::Clear : public boost::static_visitor { public: @@ -363,6 +365,8 @@ XdmfArray::~XdmfArray() std::cout << "Deleted Array " << this << std::endl; } +std::string XdmfArray::ItemTag = "DataItem"; + void XdmfArray::copyValues(const unsigned int startIndex, const boost::shared_ptr values, const unsigned int valuesStartIndex, const unsigned int numValues, const unsigned int arrayStride, const unsigned int valuesStride) { if(mHaveArrayPointer) @@ -410,7 +414,14 @@ boost::shared_ptr XdmfArray::getHDF5Controller() const std::map XdmfArray::getItemProperties() const { std::map arrayProperties; - arrayProperties["Format"] = "HDF"; + if(mHDF5Controller) + { + arrayProperties["Format"] = "HDF"; + } + else + { + arrayProperties["Format"] = "XML"; + } arrayProperties["DataType"] = this->getType(); std::stringstream precision; precision << this->getPrecision(); @@ -423,7 +434,7 @@ std::map XdmfArray::getItemProperties() const std::string XdmfArray::getItemTag() const { - return "DataItem"; + return ItemTag; } unsigned int XdmfArray::getPrecision() const @@ -503,6 +514,50 @@ std::string XdmfArray::getValuesString() const return ""; } +void XdmfArray::initialize(const std::string & type, const unsigned int precision) +{ + if(type.compare("Char") == 0 && precision == 1) + { + this->initialize(); + } + else if(type.compare("Short") == 0 && precision == 2) + { + this->initialize(); + } + else if(type.compare("Int") == 0 && precision == 4) + { + this->initialize(); + } + else if(type.compare("Long") == 0 && precision == 8) + { + this->initialize(); + } + else if(type.compare("Float") == 0 && precision == 4) + { + this->initialize(); + } + else if(type.compare("Double") == 0 && precision == 8) + { + this->initialize(); + } + else if(type.compare("UChar") == 0 && precision == 8) + { + this->initialize(); + } + else if(type.compare("UShort") == 0 && precision == 8) + { + this->initialize(); + } + else if(type.compare("UInt") == 0 && precision == 8) + { + this->initialize(); + } + else + { + assert(false); + } +} + void XdmfArray::internalizeArrayPointer() { if(mHaveArrayPointer) @@ -511,6 +566,79 @@ void XdmfArray::internalizeArrayPointer() } } +void XdmfArray::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + std::string contentVal; + int precisionVal; + int sizeVal; + std::string typeVal; + + std::map::const_iterator content = itemProperties.find("Content"); + if(content != itemProperties.end()) + { + contentVal = content->second; + } + else + { + assert(false); + } + std::map::const_iterator precision = itemProperties.find("Precision"); + if(precision != itemProperties.end()) + { + precisionVal = atoi(precision->second.c_str()); + } + else + { + assert(false); + } + std::map::const_iterator size = itemProperties.find("Dimensions"); + if(size != itemProperties.end()) + { + sizeVal = atoi(size->second.c_str()); + } + else + { + assert(false); + } + std::map::const_iterator type = itemProperties.find("DataType"); + if(type != itemProperties.end()) + { + typeVal = type->second; + } + else + { + assert(false); + } + std::map::const_iterator format = itemProperties.find("Format"); + if(format != itemProperties.end()) + { + if(format->second.compare("HDF") == 0) + { + mHDF5Controller = XdmfHDF5Controller::New(contentVal, precisionVal, sizeVal, typeVal); + } + else if(format->second.compare("XML") == 0) + { + this->initialize(typeVal, precisionVal); + this->reserve(sizeVal); + boost::char_separator sep(" "); + boost::tokenizer > tokens(contentVal, sep); + BOOST_FOREACH(std::string t, tokens) + { + double val = atof(t.c_str()); + this->pushBack(val); + } + } + else + { + assert(false); + } + } + else + { + assert(false); + } +} + void XdmfArray::read() { if(mHDF5Controller) diff --git a/XdmfArray.hpp b/XdmfArray.hpp index 9a53ce1e83da30647a574633f9f5d1a68fb3d7eb..e14df328c6a33311bf10f083045e9b758ffe01da 100644 --- a/XdmfArray.hpp +++ b/XdmfArray.hpp @@ -51,6 +51,7 @@ public: XdmfNewMacro(XdmfArray); LOKI_DEFINE_VISITABLE(XdmfArray, XdmfItem) friend class XdmfHDF5Writer; + static std::string ItemTag; /** * Copy values from an XdmfArray into this array. @@ -178,13 +179,19 @@ public: template boost::shared_ptr > initialize(); + /** + * Copy a value to the back of this array + */ + template + void pushBack(T & value); + /** * Read data from disk into memory. */ void read(); /** - * Release all data held by this XdmfArray. + * Release all data from currently held in memory. */ void release(); @@ -200,10 +207,10 @@ public: * to val. If numValues is less than the current size, values at indices larger than numValues are removed. * * @param numValues the number of values to resize this array to. - * @param val the number to initialize newly created values to, if needed. + * @param value the number to initialize newly created values to, if needed. */ template - void resize(const unsigned int numValues, const T & val = 0); + void resize(const unsigned int numValues, const T & value = 0); /** * Attach an hdf5 controller to this XdmfArray. @@ -277,6 +284,7 @@ protected: XdmfArray(); virtual ~XdmfArray(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); private: @@ -287,7 +295,7 @@ private: class Clear; class CopyArrayValues; - template + template class CopyValues; class GetCapacity; @@ -296,20 +304,26 @@ private: class GetSize; class GetType; - template + template class GetValuesCopy; class GetValuesPointer; class GetValuesString; class InternalizeArrayPointer; class NewArray; + + template + class PushBack; + class Reserve; - template + template class Resize; struct NullDeleter; + void initialize(const std::string & type, const unsigned int precision); + /** * After setValues(const T * const array) is called, XdmfArray stores a pointer that is not allowed to be modified through * the XdmfArray API. If the user desires to modify the contents of the pointer, they must do so without calling any diff --git a/XdmfArray.tpp b/XdmfArray.tpp index c8910e1b65a862c0ec12fc08021dd90a1b1057bc..aa5b1efb03261dec64c56470086dc807f9856fa4 100644 --- a/XdmfArray.tpp +++ b/XdmfArray.tpp @@ -1,7 +1,7 @@ // Includes #include "XdmfArray.hpp" -template +template class XdmfArray::CopyValues : public boost::static_visitor { public: @@ -41,7 +41,7 @@ private: const unsigned int mValuesStride; }; -template +template class XdmfArray::GetValuesCopy : public boost::static_visitor { public: @@ -81,7 +81,27 @@ private: const unsigned int mValuesStride; }; -template +template +class XdmfArray::PushBack : public boost::static_visitor { +public: + + PushBack(const T & val) : + mVal(val) + { + } + + template + void operator()(boost::shared_ptr > & array) const + { + array->push_back((U)mVal); + } + +private: + + const T & mVal; +}; + +template class XdmfArray::Resize : public boost::static_visitor { public: @@ -110,7 +130,7 @@ struct XdmfArray::NullDeleter } }; -template +template void XdmfArray::copyValues(const unsigned int startIndex, const T * const valuesPointer, const unsigned int numValues, const unsigned int arrayStride, const unsigned int valuesStride) { if(mHaveArrayPointer) @@ -121,7 +141,7 @@ void XdmfArray::copyValues(const unsigned int startIndex, const T * const values { initialize(); } - boost::apply_visitor( CopyValues(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray); + boost::apply_visitor(CopyValues(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray); } template @@ -167,11 +187,7 @@ void XdmfArray::getValuesCopy(const unsigned int startIndex, T * valuesPointer, { boost::apply_visitor(GetValuesCopy(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArrayPointer); } - else if(mHDF5Controller) - { - assert("Need to complete"); - } - assert("Throw Exception No Data"); + assert(false); } template @@ -193,8 +209,18 @@ boost::shared_ptr > XdmfArray::initialize() return newArray; } +template +void XdmfArray::pushBack(T & value) +{ + if(mHaveArrayPointer) + { + internalizeArrayPointer(); + } + return boost::apply_visitor(PushBack(value), mArray); +} + template -void XdmfArray::resize(const unsigned int numValues, const T & val) +void XdmfArray::resize(const unsigned int numValues, const T & value) { if(mHaveArrayPointer) { @@ -204,10 +230,10 @@ void XdmfArray::resize(const unsigned int numValues, const T & val) { initialize(); } - return boost::apply_visitor(Resize(numValues, val), mArray); + return boost::apply_visitor(Resize(numValues, value), mArray); } -template +template void XdmfArray::setValues(const T * const arrayPointer, const unsigned int numValues, const bool transferOwnership) { // Remove contents of internal array. @@ -229,7 +255,7 @@ void XdmfArray::setValues(const T * const arrayPointer, const unsigned int numVa mArrayPointerNumValues = numValues; } -template +template void XdmfArray::setValues(std::vector & array, const bool transferOwnership) { if(mHaveArrayPointer) @@ -249,7 +275,7 @@ void XdmfArray::setValues(std::vector & array, const bool transferOwnership) mHaveArray = true; } -template +template void XdmfArray::setValues(boost::shared_ptr > array) { if(mHaveArrayPointer) @@ -260,7 +286,7 @@ void XdmfArray::setValues(boost::shared_ptr > array) mHaveArray = true; } -template +template bool XdmfArray::swap(std::vector & array) { if(mHaveArrayPointer) @@ -283,7 +309,7 @@ bool XdmfArray::swap(std::vector & array) } } -template +template bool XdmfArray::swap(boost::shared_ptr > array) { return this->swap(*array.get()); diff --git a/XdmfAttribute.cpp b/XdmfAttribute.cpp index d7a988f9488c68e720afc647b793f9dcff24e2a3..f4c6bc80e03f488824930970f50f9d94fe712f5b 100644 --- a/XdmfAttribute.cpp +++ b/XdmfAttribute.cpp @@ -20,6 +20,8 @@ XdmfAttribute::~XdmfAttribute() std::cout << "Deleted Attribute " << this << std::endl; } +std::string XdmfAttribute::ItemTag = "Attribute"; + XdmfAttributeCenter XdmfAttribute::getAttributeCenter() const { return mAttributeCenter; @@ -41,7 +43,7 @@ std::map XdmfAttribute::getItemProperties() const std::string XdmfAttribute::getItemTag() const { - return "Attribute"; + return ItemTag; } std::string XdmfAttribute::getName() const @@ -49,6 +51,23 @@ std::string XdmfAttribute::getName() const return mName; } +void XdmfAttribute::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + std::map::const_iterator name = itemProperties.find("Name"); + if(name != itemProperties.end()) + { + mName = name->second; + } + else + { + assert(false); + } + mAttributeCenter = XdmfAttributeCenter::New(itemProperties); + mAttributeType = XdmfAttributeType::New(itemProperties); + + XdmfDataItem::populateItem(itemProperties, childItems); +} + void XdmfAttribute::setAttributeCenter(const XdmfAttributeCenter & attributeCenter) { mAttributeCenter = attributeCenter; diff --git a/XdmfAttribute.hpp b/XdmfAttribute.hpp index c515851c02c6c46410f69e027b5ea6a7a77ceb80..c22e731157a549b05acccb1c827a427b9d26ec07 100644 --- a/XdmfAttribute.hpp +++ b/XdmfAttribute.hpp @@ -18,6 +18,7 @@ public: XdmfNewMacro(XdmfAttribute); LOKI_DEFINE_VISITABLE(XdmfAttribute, XdmfDataItem) + static std::string ItemTag; /** * Get the XdmfAttributeCenter associated with this attribute. @@ -69,6 +70,7 @@ protected: XdmfAttribute(); virtual ~XdmfAttribute(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); private: diff --git a/XdmfAttributeCenter.cpp b/XdmfAttributeCenter.cpp index da42f4aa8f5139e8c981b83e1707ba6471bb4c4f..9e9faeccfd2c0828fb9c2581e39c29b36ee56654 100644 --- a/XdmfAttributeCenter.cpp +++ b/XdmfAttributeCenter.cpp @@ -35,13 +35,48 @@ XdmfAttributeCenter XdmfAttributeCenter::Node() XdmfAttributeCenter::XdmfAttributeCenter(const std::string & name) : mName(name) -{}; +{ +} XdmfAttributeCenter::XdmfAttributeCenter(const XdmfAttributeCenter & attributeCenter): mName(attributeCenter.mName) { } +XdmfAttributeCenter XdmfAttributeCenter::New(const std::map & itemProperties) +{ + std::map::const_iterator center = itemProperties.find("Center"); + if(center != itemProperties.end()) + { + const std::string centerVal = center->second; + if(centerVal.compare("Grid") == 0) + { + return Grid(); + } + else if(centerVal.compare("Cell") == 0) + { + return Cell(); + } + else if(centerVal.compare("Face") == 0) + { + return Face(); + } + else if(centerVal.compare("Edge") == 0) + { + return Edge(); + } + else if(centerVal.compare("Node") == 0) + { + return Node(); + } + else + { + assert(false); + } + } + assert(false); +} + XdmfAttributeCenter& XdmfAttributeCenter::operator=(const XdmfAttributeCenter & attributeCenter) { if(this != &attributeCenter) @@ -68,5 +103,5 @@ std::string XdmfAttributeCenter::getName() const void XdmfAttributeCenter::getProperties(std::map & collectedProperties) const { - collectedProperties["Center"] = this->mName; + collectedProperties["Center"] = mName; } diff --git a/XdmfAttributeCenter.hpp b/XdmfAttributeCenter.hpp index c1a8dd0812c3e8587ea38998ae718687d91e9597..35cc1f58cbc6b516ff0c0ad0ec2aa43aa430b163 100644 --- a/XdmfAttributeCenter.hpp +++ b/XdmfAttributeCenter.hpp @@ -23,6 +23,8 @@ class XdmfAttributeCenter : public XdmfItemProperty { public: + friend class XdmfAttribute; + // Supported Xdmf Attribute Centers static XdmfAttributeCenter Grid(); static XdmfAttributeCenter Cell(); @@ -71,6 +73,8 @@ protected: private: + static XdmfAttributeCenter New(const std::map & itemProperties); + std::string mName; }; diff --git a/XdmfAttributeType.cpp b/XdmfAttributeType.cpp index 8213976db5861d5c3feff4be5e1be3181e8f67ce..b80f88ecb9cc3deed7f8032aba91591eb71d1e3a 100644 --- a/XdmfAttributeType.cpp +++ b/XdmfAttributeType.cpp @@ -45,13 +45,56 @@ XdmfAttributeType XdmfAttributeType::GlobalId() XdmfAttributeType::XdmfAttributeType(const std::string & name) : mName(name) -{}; +{ +} XdmfAttributeType::XdmfAttributeType(const XdmfAttributeType & attributeType): mName(attributeType.mName) { } +XdmfAttributeType XdmfAttributeType::New(const std::map & itemProperties) +{ + std::map::const_iterator type = itemProperties.find("AttributeType"); + if(type != itemProperties.end()) + { + const std::string typeVal = type->second; + if(typeVal.compare("None") == 0) + { + return NoAttributeType(); + } + else if(typeVal.compare("Scalar") == 0) + { + return Scalar(); + } + else if(typeVal.compare("Vector") == 0) + { + return Vector(); + } + else if(typeVal.compare("Tensor") == 0) + { + return Tensor(); + } + else if(typeVal.compare("Matrix") == 0) + { + return Matrix(); + } + else if(typeVal.compare("Tensor6") == 0) + { + return Tensor6(); + } + else if(typeVal.compare("GlobalId") == 0) + { + return GlobalId(); + } + else + { + assert(false); + } + } + assert(false); +} + XdmfAttributeType& XdmfAttributeType::operator=(const XdmfAttributeType & attributeType) { if(this != &attributeType) @@ -78,5 +121,5 @@ std::string XdmfAttributeType::getName() const void XdmfAttributeType::getProperties(std::map & collectedProperties) const { - collectedProperties["AttributeType"] = this->mName; + collectedProperties["AttributeType"] = mName; } diff --git a/XdmfAttributeType.hpp b/XdmfAttributeType.hpp index cf06f0157fb7b2f21ec9f29e91d7a31676aa5182..389ace6db295b285232da93bf3a9478e803e6bf9 100644 --- a/XdmfAttributeType.hpp +++ b/XdmfAttributeType.hpp @@ -25,6 +25,8 @@ class XdmfAttributeType : public XdmfItemProperty { public: + friend class XdmfAttribute; + // Supported Xdmf Attribute Types static XdmfAttributeType NoAttributeType(); static XdmfAttributeType Scalar(); @@ -75,6 +77,8 @@ protected: private: + static XdmfAttributeType New(const std::map & itemProperties); + std::string mName; }; diff --git a/XdmfDataItem.cpp b/XdmfDataItem.cpp index 35cb06be19e5d6eb968b9d705ff78030ef8caa9d..7979052ad498e071ff3f2175ce22b702e2b750dd 100644 --- a/XdmfDataItem.cpp +++ b/XdmfDataItem.cpp @@ -29,6 +29,17 @@ boost::shared_ptr XdmfDataItem::getArray() const return mArray; } +void XdmfDataItem::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + for(std::vector >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter) + { + if(boost::shared_ptr array = boost::shared_dynamic_cast(*iter)) + { + this->setArray(array); + } + } +} + void XdmfDataItem::setArray(boost::shared_ptr array) { mArray = array; diff --git a/XdmfDataItem.hpp b/XdmfDataItem.hpp index 8b2ab4261c1f0f584e61486c9e5aa540d32f93f5..e345a76cee9fe4d32e624a5e89943042c4f6faf0 100644 --- a/XdmfDataItem.hpp +++ b/XdmfDataItem.hpp @@ -46,6 +46,7 @@ protected: XdmfDataItem(); virtual ~XdmfDataItem(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); private: diff --git a/XdmfDomain.cpp b/XdmfDomain.cpp index 13da3ca3ea6890f84c02d250d59e782203bd3158..5815010bcfc24dfcc767ea4c2688a26c476de612 100644 --- a/XdmfDomain.cpp +++ b/XdmfDomain.cpp @@ -18,6 +18,8 @@ XdmfDomain::~XdmfDomain() std::cout << "Deleted Domain " << this << std::endl; } +std::string XdmfDomain::ItemTag = "Domain"; + void XdmfDomain::insert(boost::shared_ptr grid) { mGrids.push_back(grid); @@ -51,7 +53,7 @@ std::map XdmfDomain::getItemProperties() const std::string XdmfDomain::getItemTag() const { - return "Domain"; + return ItemTag; } unsigned int XdmfDomain::getNumberOfGrids() const @@ -59,6 +61,14 @@ unsigned int XdmfDomain::getNumberOfGrids() const return mGrids.size(); } +void XdmfDomain::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + for(std::vector >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter) + { + this->insert(boost::shared_dynamic_cast(*iter)); + } +} + void XdmfDomain::traverse(boost::shared_ptr visitor) { for(std::vector >::const_iterator iter = mGrids.begin(); iter != mGrids.end(); ++iter) diff --git a/XdmfDomain.hpp b/XdmfDomain.hpp index e47b99e51f78c6cf3ce8a229b325b91faaf88cc9..e00405366d994a5f7d65679f9aa09ab961d0d175 100644 --- a/XdmfDomain.hpp +++ b/XdmfDomain.hpp @@ -20,6 +20,7 @@ public: XdmfNewMacro(XdmfDomain); LOKI_DEFINE_VISITABLE(XdmfDomain, XdmfItem) + static std::string ItemTag; /** * Get a XdmfGrid attached to the domain. @@ -61,6 +62,7 @@ protected: XdmfDomain(); virtual ~XdmfDomain(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); private: diff --git a/XdmfGeometry.cpp b/XdmfGeometry.cpp index 820f5b53d9911e1699894129926fec689279c4d6..f48a16cf8e45ad4e14c58895fe27560e7e9a24f6 100644 --- a/XdmfGeometry.cpp +++ b/XdmfGeometry.cpp @@ -19,6 +19,8 @@ XdmfGeometry::~XdmfGeometry() std::cout << "Deleted Geometry " << this << std::endl; } +std::string XdmfGeometry::ItemTag = "Geometry"; + XdmfGeometryType XdmfGeometry::getGeometryType() const { return mGeometryType; @@ -33,7 +35,13 @@ std::map XdmfGeometry::getItemProperties() const std::string XdmfGeometry::getItemTag() const { - return "Geometry"; + return ItemTag; +} + +void XdmfGeometry::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + mGeometryType = XdmfGeometryType::New(itemProperties); + XdmfDataItem::populateItem(itemProperties, childItems); } void XdmfGeometry::setGeometryType(const XdmfGeometryType & geometryType) diff --git a/XdmfGeometry.hpp b/XdmfGeometry.hpp index 8517da2e7c9cd391e08bbd6756be58177cbbb6ac..639a755b83fccf9ecb3419df43302eccb19b428c 100644 --- a/XdmfGeometry.hpp +++ b/XdmfGeometry.hpp @@ -18,6 +18,7 @@ public: XdmfNewMacro(XdmfGeometry); LOKI_DEFINE_VISITABLE(XdmfGeometry, XdmfDataItem) + static std::string ItemTag; /** * Get the XdmfGeometryType associated with this geometry. @@ -41,6 +42,7 @@ protected: XdmfGeometry(); virtual ~XdmfGeometry(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); private: diff --git a/XdmfGeometryType.cpp b/XdmfGeometryType.cpp index f3cc802c21d23a2ccc726246a26f342d194bf185..196ba4b1855001e0bad4899e16b8fcf561e48af2 100644 --- a/XdmfGeometryType.cpp +++ b/XdmfGeometryType.cpp @@ -13,34 +13,42 @@ XdmfGeometryType XdmfGeometryType::NoGeometryType() { return XdmfGeometryType("NONE", 0); } + XdmfGeometryType XdmfGeometryType::XYZ() { return XdmfGeometryType("XYZ", 3); } + XdmfGeometryType XdmfGeometryType::XY() { return XdmfGeometryType("XY", 2); } + XdmfGeometryType XdmfGeometryType::X_Y_Z() { return XdmfGeometryType("X_Y_Z", 3); } + XdmfGeometryType XdmfGeometryType::X_Y() { return XdmfGeometryType("X_Y", 2); } + XdmfGeometryType XdmfGeometryType::VXVYVZ() { return XdmfGeometryType("VXVYVZ", 3); } + XdmfGeometryType XdmfGeometryType::Origin_DXDYDZ() { return XdmfGeometryType("ORIGIN_DXDYDZ", 3); } + XdmfGeometryType XdmfGeometryType::VXVY() { return XdmfGeometryType("VXVY", 2); } + XdmfGeometryType XdmfGeometryType::Origin_DXDY() { return XdmfGeometryType("ORIGIN_DXDY", 2); @@ -55,7 +63,58 @@ XdmfGeometryType::XdmfGeometryType(const XdmfGeometryType& geometryType): XdmfGeometryType::XdmfGeometryType(const std::string& name, const int& dimensions) : mName(name), mDimensions(dimensions) -{}; +{ +} + +XdmfGeometryType XdmfGeometryType::New(const std::map & itemProperties) +{ + std::map::const_iterator type = itemProperties.find("GeometryType"); + if(type != itemProperties.end()) + { + const std::string typeVal = type->second; + if(typeVal.compare("NONE") == 0) + { + return NoGeometryType(); + } + else if(typeVal.compare("XYZ") == 0) + { + return XYZ(); + } + else if(typeVal.compare("XY") == 0) + { + return XY(); + } + else if(typeVal.compare("X_Y_Z") == 0) + { + return X_Y_Z(); + } + else if(typeVal.compare("X_Y") == 0) + { + return X_Y(); + } + else if(typeVal.compare("VXVYVZ") == 0) + { + return VXVYVZ(); + } + else if(typeVal.compare("ORIGIN_DXDYDZ") == 0) + { + return Origin_DXDYDZ(); + } + else if(typeVal.compare("VXVY") == 0) + { + return VXVY(); + } + else if(typeVal.compare("ORIGIN_DXDY") == 0) + { + return Origin_DXDY(); + } + else + { + assert(false); + } + } + assert(false); +} XdmfGeometryType& XdmfGeometryType::operator=(const XdmfGeometryType& geometryType) { diff --git a/XdmfGeometryType.hpp b/XdmfGeometryType.hpp index 7903c43460aeeb35d11b7a2bf5c364f124b79df8..fc5641400de9a895cbea93437a0e97764def659c 100644 --- a/XdmfGeometryType.hpp +++ b/XdmfGeometryType.hpp @@ -27,6 +27,8 @@ class XdmfGeometryType : public XdmfItemProperty { public: + friend class XdmfGeometry; + // Supported Xdmf Geometry Types static XdmfGeometryType NoGeometryType(); static XdmfGeometryType XYZ(); @@ -87,6 +89,8 @@ protected: private: + static XdmfGeometryType New(const std::map & itemProperties); + int mDimensions; std::string mName; }; diff --git a/XdmfGrid.cpp b/XdmfGrid.cpp index b61f1857d425fef197157f5228fd7953571c2b6e..84a619ac3f54d00b539e5ea8aa7e269143bf4a63 100644 --- a/XdmfGrid.cpp +++ b/XdmfGrid.cpp @@ -23,6 +23,8 @@ XdmfGrid::~XdmfGrid() std::cout << "Deleted Grid " << this << std::endl; } +std::string XdmfGrid::ItemTag = "Grid"; + boost::shared_ptr XdmfGrid::getAttribute(unsigned int index) { if(index >= mAttributes.size()) @@ -62,7 +64,7 @@ std::map XdmfGrid::getItemProperties() const std::string XdmfGrid::getItemTag() const { - return "Grid"; + return ItemTag; } std::string XdmfGrid::getName() const @@ -90,6 +92,34 @@ void XdmfGrid::insert(boost::shared_ptr attribute) mAttributes.push_back(attribute); } +void XdmfGrid::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + std::map::const_iterator name = itemProperties.find("Name"); + if(name != itemProperties.end()) + { + mName = name->second; + } + else + { + assert(false); + } + for(std::vector >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter) + { + if(boost::shared_ptr attribute = boost::shared_dynamic_cast(*iter)) + { + this->insert(attribute); + } + else if(boost::shared_ptr geometry = boost::shared_dynamic_cast(*iter)) + { + mGeometry = geometry; + } + else if(boost::shared_ptr topology = boost::shared_dynamic_cast(*iter)) + { + mTopology = topology; + } + } +} + void XdmfGrid::setGeometry(boost::shared_ptr geometry) { mGeometry = geometry; diff --git a/XdmfGrid.hpp b/XdmfGrid.hpp index 24ff78ea61b7ac727cc0460ac0edd24f70bbc936..c6814543e669e6c953b28719fb798bae3d1b9ca4 100644 --- a/XdmfGrid.hpp +++ b/XdmfGrid.hpp @@ -23,6 +23,7 @@ public: XdmfNewMacro(XdmfGrid); LOKI_DEFINE_VISITABLE(XdmfGrid, XdmfItem) + static std::string ItemTag; /** * Get an XdmfAttribute attached to this grid. @@ -120,6 +121,7 @@ protected: XdmfGrid(); virtual ~XdmfGrid(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); private: diff --git a/XdmfHDF5Controller.cpp b/XdmfHDF5Controller.cpp index a5090c41f30b303ad55a41c9b7e2ca59b3da12e3..28a971caf54d3278259c5252af6d3ab7fee398a3 100644 --- a/XdmfHDF5Controller.cpp +++ b/XdmfHDF5Controller.cpp @@ -7,14 +7,28 @@ #include "XdmfArray.hpp" #include "XdmfHDF5Controller.hpp" -XdmfHDF5Controller::XdmfHDF5Controller(const std::string & hdf5FilePath, const std::string & dataSetName, const int precision, - const int size, const std::string & type) : - mHDF5FilePath(hdf5FilePath), - mDataSetName(dataSetName), +XdmfHDF5Controller::XdmfHDF5Controller(const std::string & hdf5DataSetPath, const int precision, const int size, const std::string & type) : mPrecision(precision), mSize(size), mType(type) { + size_t colonLocation = hdf5DataSetPath.find(":"); + if(colonLocation != std::string::npos) + { + mHDF5FilePath = hdf5DataSetPath.substr(0, colonLocation); + if(colonLocation + 1 != mHDF5FilePath.size()) + { + mDataSetName = hdf5DataSetPath.substr(colonLocation + 1, mHDF5FilePath.size()); + } + else + { + assert(false); + } + } + else + { + assert(false); + } } XdmfHDF5Controller::~XdmfHDF5Controller() @@ -108,7 +122,7 @@ void XdmfHDF5Controller::read(XdmfArray * const array) } else { - assert("Unsupported HDF5 Data Type"); + assert(false); } H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, valuesPointer); diff --git a/XdmfHDF5Controller.hpp b/XdmfHDF5Controller.hpp index b5998e7b2866c0cc1c80f91c3eb1ca94dabf58f3..e741ed53e870bde3b6b1d72e6ef3fa2dd5480a29 100644 --- a/XdmfHDF5Controller.hpp +++ b/XdmfHDF5Controller.hpp @@ -23,13 +23,10 @@ public: /** * Create a new controller for an hdf5 data set on disk. - * - * @param dataSetPath the path to the hdf5 data set on disk. */ - static boost::shared_ptr New(const std::string & hdf5FilePath, const std::string & dataSetName, - const int precision, const int size, const std::string & type) + static boost::shared_ptr New(const std::string & hdf5DataSetPath, const int precision, const int size, const std::string & type) { - boost::shared_ptr p(new XdmfHDF5Controller(hdf5FilePath, dataSetName, precision, size, type)); + boost::shared_ptr p(new XdmfHDF5Controller(hdf5DataSetPath, precision, size, type)); return p; } @@ -70,8 +67,7 @@ public: protected: - XdmfHDF5Controller(const std::string & hdf5FilePath, const std::string & dataSetName, const int precision, const int size, - const std::string & type); + XdmfHDF5Controller(const std::string & hdf5DataSetPath, const int precision, const int size, const std::string & type); virtual ~XdmfHDF5Controller(); private: diff --git a/XdmfHDF5Writer.cpp b/XdmfHDF5Writer.cpp index 3c815f4a499abbf2be1680a17532fb6cca2cc271..5820491ed2dc56af28bb86c3056fbe3404bcabe1 100644 --- a/XdmfHDF5Writer.cpp +++ b/XdmfHDF5Writer.cpp @@ -167,11 +167,14 @@ void XdmfHDF5Writer::visit(XdmfArray & array, boost::shared_ptr newDataSetController = XdmfHDF5Controller::New(mImpl->mHDF5FilePath, dataSetName.str(), - array.getPrecision(), array.getSize(), array.getType()); - array.setHDF5Controller(newDataSetController); + std::stringstream writtenDataSet; + writtenDataSet << mImpl->mHDF5FilePath << ":" << dataSetName.str(); - mImpl->mLastWrittenDataSet = newDataSetController->getDataSetPath(); + mImpl->mLastWrittenDataSet = writtenDataSet.str(); mImpl->mDataSetId++; + + boost::shared_ptr newDataSetController = XdmfHDF5Controller::New(writtenDataSet.str(), array.getPrecision(), + array.getSize(), array.getType()); + array.setHDF5Controller(newDataSetController); } } diff --git a/XdmfItem.hpp b/XdmfItem.hpp index 46fc8f543ae9315be5700aa00278a30b1acf0a1b..7ef6149e2522c7e682746bf60435b3b006f1fb47 100644 --- a/XdmfItem.hpp +++ b/XdmfItem.hpp @@ -1,6 +1,6 @@ /** * An XdmfItem replaces the XdmfElement class in the previous version of Xdmf. An XdmfItem represents an item that can be - * visited by an XdmfVisitor and have it's contents added to an xdmf file. These include XdmfGrids, XdmfSets, + * visited by an XdmfVisitor and have it's contents added to an Xdmf file. These include XdmfGrids, XdmfSets, * XdmfTopologies, etc. * * This is an abstract base class. @@ -15,6 +15,7 @@ class XdmfVisitor; // Includes #include #include +#include #include "XdmfObject.hpp" /** @@ -29,6 +30,7 @@ class XdmfItem : public XdmfObject, public: LOKI_DEFINE_VISITABLE_BASE() + friend class XdmfReader; /** * Get the tag for this XdmfItem. This is equivalent to tags in XML parlance. @@ -54,10 +56,20 @@ protected: XdmfItem(); virtual ~XdmfItem(); + /** + * Populates an item using a map of key/value property pairs and a vector of its child items. This is intended to be used to + * support generic reading of XdmfItems from disk. + * + * @param itemProperties a map of key/value properties associated with this XdmfItem. + * @param childItems a vector of child items to be added to this XdmfItem. + */ + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems) = 0; + private: XdmfItem(const XdmfItem & item); // Not implemented. void operator=(const XdmfItem & item); // Not implemented. + }; #endif /* XDMFITEM_HPP_ */ diff --git a/XdmfObject.hpp b/XdmfObject.hpp index fd21156abe5ff3c148f142b8c704a0e636e9d181..5fb19e7277253f8b2e2cb301847c81db566b58f8 100644 --- a/XdmfObject.hpp +++ b/XdmfObject.hpp @@ -2,6 +2,7 @@ #define XDMFOBJECT_HPP_ // Includes +#include #include #define XdmfNewMacro(type) \ diff --git a/XdmfReader.cpp b/XdmfReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3373a922ff19683892f78772197fc60df1f7dba --- /dev/null +++ b/XdmfReader.cpp @@ -0,0 +1,123 @@ +// Kenneth Leiter +// Xdmf Smart Pointer Test + +#include "XdmfArray.hpp" +#include "XdmfAttribute.hpp" +#include "XdmfDomain.hpp" +#include "XdmfGeometry.hpp" +#include "XdmfGrid.hpp" +#include "XdmfTopology.hpp" + + +#include +#include +#include "XdmfReader.hpp" + +/** + * PIMPL + */ +class XdmfReader::XdmfReaderImpl { + +public: + + XdmfReaderImpl() + { + }; + + ~XdmfReaderImpl() + { + }; + + boost::shared_ptr constructItem(const std::string & itemTag, const std::map & itemProperties, std::vector > & childItems) const + { + boost::shared_ptr newItem; + if(itemTag.compare(XdmfArray::ItemTag) == 0) + { + newItem = XdmfArray::New(); + } + else if(itemTag.compare(XdmfAttribute::ItemTag) == 0) + { + newItem = XdmfAttribute::New(); + } + else if(itemTag.compare(XdmfDomain::ItemTag) == 0) + { + newItem = XdmfDomain::New(); + } + else if(itemTag.compare(XdmfGeometry::ItemTag) == 0) + { + newItem = XdmfGeometry::New(); + } + else if(itemTag.compare(XdmfGrid::ItemTag) == 0) + { + newItem = XdmfGrid::New(); + } + else if(itemTag.compare(XdmfTopology::ItemTag) == 0) + { + newItem = XdmfTopology::New(); + } + else + { + assert(false); + } + newItem->populateItem(itemProperties, childItems); + return newItem; + } + + std::vector > read(xmlNodePtr currNode) const + { + std::vector > myItems; + + while(currNode != NULL) + { + if(currNode->type == XML_ELEMENT_NODE) + { + std::map itemProperties; + itemProperties["Content"] = (const char *)currNode->children->content; + xmlAttrPtr currAttribute = currNode->properties; + while(currAttribute != NULL) + { + itemProperties[(const char *)currAttribute->name] = (const char *)currAttribute->children->content; + currAttribute = currAttribute->next; + } + std::vector > childItems = this->read(currNode->children); + myItems.push_back(this->constructItem((const char *)currNode->name, itemProperties, childItems)); + } + currNode = currNode->next; + } + return myItems; + } +}; + +XdmfReader::XdmfReader() : + mImpl(new XdmfReaderImpl()) +{ + std::cout << "Created XdmfReader " << this << std::endl; +} + +XdmfReader::~XdmfReader() +{ + delete mImpl; + std::cout << "Deleted XdmfReader " << this << std::endl; +} + +boost::shared_ptr XdmfReader::read(const std::string & filePath) const +{ + xmlDocPtr document; + xmlNodePtr currNode; + + document = xmlReadFile(filePath.c_str(), NULL, 0); + if(document == NULL) + { + assert(false); + } + currNode = xmlDocGetRootElement(document); + + std::vector > toReturn = mImpl->read(currNode->children); + + xmlFreeDoc(document); + xmlCleanupParser(); + + return boost::shared_dynamic_cast(toReturn[0]); +} + + diff --git a/XdmfReader.hpp b/XdmfReader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b58cf448387b664d6bc48d9bedafae09831c0adb --- /dev/null +++ b/XdmfReader.hpp @@ -0,0 +1,42 @@ +#ifndef XDMFREADER_HPP_ +#define XDMFREADER_HPP_ + +// Forward Declarations +class XdmfDomain; + +// Includes +#include "XdmfObject.hpp" + +/** + * @brief Reads an Xdmf file stored on disk into memory. + * + * Reads an Xdmf file stored on disk into an Xdmf structure in memory. All light data is parsed in order to create appropriate + * Xdmf objects. Heavy data controllers are created and attached to XdmfArrays but no heavy data is read into memory. + */ +class XdmfReader : public XdmfObject { + +public: + + XdmfNewMacro(XdmfReader); + + boost::shared_ptr read(const std::string & fileName) const; + +protected: + + XdmfReader(); + virtual ~XdmfReader(); + +private: + + /** + * PIMPL + */ + class XdmfReaderImpl; + + XdmfReader(const XdmfReader & reader); // Not implemented. + void operator=(const XdmfReader & reader); // Not implemented. + + XdmfReaderImpl * mImpl; +}; + +#endif /* XDMFREADER_HPP_ */ diff --git a/XdmfTopology.cpp b/XdmfTopology.cpp index bbc00c81ef267983b475e257ac36f60c53b4a046..7eb549bf70454a194252c3257222d5f0506043cb 100644 --- a/XdmfTopology.cpp +++ b/XdmfTopology.cpp @@ -21,9 +21,11 @@ XdmfTopology::~XdmfTopology() std::cout << "Deleted Topology " << this << std::endl; } +std::string XdmfTopology::ItemTag = "Topology"; + std::string XdmfTopology::getItemTag() const { - return "Topology"; + return ItemTag; } std::map XdmfTopology::getItemProperties() const @@ -50,6 +52,12 @@ XdmfTopologyType XdmfTopology::getTopologyType() const return mTopologyType; } +void XdmfTopology::populateItem(const std::map & itemProperties, std::vector > & childItems) +{ + mTopologyType = XdmfTopologyType::New(itemProperties); + XdmfDataItem::populateItem(itemProperties, childItems); +} + void XdmfTopology::setTopologyType(const XdmfTopologyType & topologyType) { mTopologyType = topologyType; diff --git a/XdmfTopology.hpp b/XdmfTopology.hpp index 9689b17f674295579bbdfe6246cac296098f1ffb..84c1859b547fe1f45161ec779eacfcdbdee1d430 100644 --- a/XdmfTopology.hpp +++ b/XdmfTopology.hpp @@ -18,6 +18,7 @@ public: XdmfNewMacro(XdmfTopology); LOKI_DEFINE_VISITABLE(XdmfTopology, XdmfDataItem) + static std::string ItemTag; std::map getItemProperties() const; @@ -48,6 +49,8 @@ protected: XdmfTopology(); virtual ~XdmfTopology(); + virtual void populateItem(const std::map & itemProperties, std::vector > & childItems); + private: diff --git a/XdmfTopologyType.cpp b/XdmfTopologyType.cpp index a0b84636483759cc80873ab66000ac482cc8c1fb..7aebe42a92dc9a66aa97a78a2be95d26ab1701e5 100644 --- a/XdmfTopologyType.cpp +++ b/XdmfTopologyType.cpp @@ -132,7 +132,8 @@ XdmfTopologyType::XdmfTopologyType(const int& nodesPerElement, const std::string mNodesPerElement(nodesPerElement), mName(name), mCellType(cellType) -{} +{ +} XdmfTopologyType::XdmfTopologyType(const XdmfTopologyType& topologyType): mNodesPerElement(topologyType.mNodesPerElement), @@ -141,6 +142,121 @@ XdmfTopologyType::XdmfTopologyType(const XdmfTopologyType& topologyType): { } +XdmfTopologyType XdmfTopologyType::New(const std::map & itemProperties) +{ + std::map::const_iterator type = itemProperties.find("TopologyType"); + std::map::const_iterator nodesPerElement = itemProperties.find("NodesPerElement"); + if(type != itemProperties.end()) + { + const std::string typeVal = type->second; + if(typeVal.compare("NoTopology") == 0) + { + return NoTopologyType(); + } + else if(typeVal.compare("Polyvertex") == 0) + { + return Polyvertex(); + } + else if(typeVal.compare("Polyline") == 0) + { + return Polyline(); + } + else if(typeVal.compare("Polygon") == 0) + { + if(nodesPerElement != itemProperties.end()) + { + return Polygon(atoi(nodesPerElement->second.c_str())); + } + assert(false); + } + else if(typeVal.compare("Triangle") == 0) + { + return Triangle(); + } + else if(typeVal.compare("Quadrilateral") == 0) + { + return Quadrilateral(); + } + else if(typeVal.compare("Tetrahedron") == 0) + { + return Tetrahedron(); + } + else if(typeVal.compare("Pyramid") == 0) + { + return Pyramid(); + } + else if(typeVal.compare("Wedge") == 0) + { + return Wedge(); + } + else if(typeVal.compare("Hexahedron") == 0) + { + return Hexahedron(); + } + else if(typeVal.compare("Edge_3") == 0) + { + return Edge_3(); + } + else if(typeVal.compare("Triangle_6") == 0) + { + return Triangle_6(); + } + else if(typeVal.compare("Quadrilateral_8") == 0) + { + return Quadrilateral_8(); + } + else if(typeVal.compare("Tetrahedron_10") == 0) + { + return Tetrahedron_10(); + } + else if(typeVal.compare("Pyramid_13") == 0) + { + return Pyramid_13(); + } + else if(typeVal.compare("Wedge_15") == 0) + { + return Wedge_15(); + } + else if(typeVal.compare("Hexahedron_20") == 0) + { + return Hexahedron_20(); + } + else if(typeVal.compare("Mixed") == 0) + { + return Mixed(); + } + else if(typeVal.compare("2DSMesh") == 0) + { + return TwoDSMesh(); + } + else if(typeVal.compare("2DRectMesh") == 0) + { + return TwoDRectMesh(); + } + else if(typeVal.compare("2DCoRectMesh") == 0) + { + return TwoDCoRectMesh(); + } + else if(typeVal.compare("3DSMesh") == 0) + { + return ThreeDSMesh(); + } + else if(typeVal.compare("3DRectMesh") == 0) + { + return ThreeDRectMesh(); + } + else if(typeVal.compare("3DCoRectMesh") == 0) + { + return ThreeDCoRectMesh(); + } + else + { + assert(false); + } + } + assert(false); +} + XdmfTopologyType& XdmfTopologyType::operator=(const XdmfTopologyType& topologyType) { if(this != &topologyType) @@ -180,7 +296,7 @@ unsigned int XdmfTopologyType::getNodesPerElement() const void XdmfTopologyType::getProperties(std::map & collectedProperties) const { collectedProperties["TopologyType"] = this->mName; - if(this->getName().compare("Polygon") == 0) + if(mName.compare("Polygon") == 0) { collectedProperties["NodesPerElement"] = this->mNodesPerElement; } diff --git a/XdmfTopologyType.hpp b/XdmfTopologyType.hpp index eaddcf0caa964fa4d49aac1de98b5e00cc7025d9..330e71001530d085ba4e0885b4e76c00ecb42da9 100644 --- a/XdmfTopologyType.hpp +++ b/XdmfTopologyType.hpp @@ -40,6 +40,8 @@ class XdmfTopologyType : public XdmfItemProperty { public: + friend class XdmfTopology; + enum CellType { NoCellType, Linear, Quadratic, Arbitrary, Structured }; @@ -123,6 +125,8 @@ protected: private: + static XdmfTopologyType New(const std::map & itemProperties); + CellType mCellType; std::string mName; int mNodesPerElement; diff --git a/XdmfWriter.cpp b/XdmfWriter.cpp index ee6906e07a9f2e92442a39c3b3bb54dc8669c79e..9abc03bd08affe9fe33982f667eb8bb056526582 100644 --- a/XdmfWriter.cpp +++ b/XdmfWriter.cpp @@ -18,19 +18,15 @@ public: XdmfWriterImpl(const std::string & xmlFilePath, boost::shared_ptr hdf5Writer) : mHDF5Writer(hdf5Writer), mLightDataLimit(100), - mXMLDocument(xmlNewDoc((xmlChar*)"1.0")), - mXMLCurrentNode(xmlNewNode(NULL, (xmlChar*)"Xdmf")), - mXMLFilePath(xmlFilePath) + mXMLFilePath(xmlFilePath), + mTraverseLevel(0) { - xmlDocSetRootElement(mXMLDocument, mXMLCurrentNode); }; ~XdmfWriterImpl() { - xmlSaveFormatFile("output.xmf", mXMLDocument, 1); - xmlFreeDoc(mXMLDocument); - xmlCleanupParser(); }; boost::shared_ptr mHDF5Writer; + unsigned int mTraverseLevel; unsigned int mLightDataLimit; xmlDocPtr mXMLDocument; xmlNodePtr mXMLCurrentNode; @@ -66,11 +62,25 @@ XdmfWriter::~XdmfWriter() std::cout << "Deleted XdmfWriter " << this << std::endl; } +void XdmfWriter::closeFile() +{ + xmlSaveFormatFile(mImpl->mXMLFilePath.c_str(), mImpl->mXMLDocument, 1); + xmlFreeDoc(mImpl->mXMLDocument); + xmlCleanupParser(); +} + unsigned int XdmfWriter::getLightDataLimit() const { return mImpl->mLightDataLimit; } +void XdmfWriter::openFile() +{ + mImpl->mXMLDocument = xmlNewDoc((xmlChar*)"1.0"); + mImpl->mXMLCurrentNode = xmlNewNode(NULL, (xmlChar*)"Xdmf"); + xmlDocSetRootElement(mImpl->mXMLDocument, mImpl->mXMLCurrentNode); +} + void XdmfWriter::setLightDataLimit(unsigned int numValues) { mImpl->mLightDataLimit = numValues; @@ -78,11 +88,6 @@ void XdmfWriter::setLightDataLimit(unsigned int numValues) void XdmfWriter::visit(XdmfArray & array, boost::shared_ptr visitor) { - this->visit(dynamic_cast(array), visitor); - - xmlNodePtr parentNode = mImpl->mXMLCurrentNode; - mImpl->mXMLCurrentNode = mImpl->mXMLCurrentNode->children; - std::stringstream xmlTextValues; if(array.getHDF5Controller() || array.getSize() > mImpl->mLightDataLimit) { @@ -94,12 +99,17 @@ void XdmfWriter::visit(XdmfArray & array, boost::shared_ptr v xmlTextValues << array.getValuesString(); } - xmlAddChild(mImpl->mXMLCurrentNode, xmlNewText((xmlChar*)xmlTextValues.str().c_str())); - mImpl->mXMLCurrentNode = parentNode; + this->visit(dynamic_cast(array), visitor); + xmlAddChild(mImpl->mXMLCurrentNode->children, xmlNewText((xmlChar*)xmlTextValues.str().c_str())); } void XdmfWriter::visit(XdmfItem & item, boost::shared_ptr visitor) { + if(mImpl->mTraverseLevel == 0) + { + this->openFile(); + } + mImpl->mTraverseLevel++; xmlNodePtr parentNode = mImpl->mXMLCurrentNode; mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode, NULL, (xmlChar*)item.getItemTag().c_str(), NULL); const std::map itemProperties = item.getItemProperties(); @@ -109,4 +119,9 @@ void XdmfWriter::visit(XdmfItem & item, boost::shared_ptr vis } item.traverse(visitor); mImpl->mXMLCurrentNode = parentNode; + mImpl->mTraverseLevel--; + if(mImpl->mTraverseLevel == 0) + { + this->closeFile(); + } } diff --git a/XdmfWriter.hpp b/XdmfWriter.hpp index 139a977dd1db03e6a110b5c8747c52c4599120cc..6670365eb1b7cbc45241337930779c3f6c64009e 100644 --- a/XdmfWriter.hpp +++ b/XdmfWriter.hpp @@ -80,6 +80,7 @@ public: */ void visit(XdmfItem & item, boost::shared_ptr visitor); + protected: XdmfWriter(const std::string & xmlFilePath); @@ -96,6 +97,9 @@ private: XdmfWriter(const XdmfWriter & writer); // Not implemented. void operator=(const XdmfWriter & writer); // Not implemented. + void closeFile(); + void openFile(); + XdmfWriterImpl * mImpl; }; diff --git a/loki/Visitor.h b/loki/Visitor.h index ed733fe3b748a0dc70254fc2d1bf35d5397c2b8e..dcd4a77150087ce621f400788b5ea040b85b05b3 100644 --- a/loki/Visitor.h +++ b/loki/Visitor.h @@ -20,7 +20,6 @@ #ifndef LOKI_VISITOR_INC_ #define LOKI_VISITOR_INC_ -#include #include #include "Typelist.h" #include "HierarchyGenerators.h" @@ -309,7 +308,6 @@ struct DefaultCatchAll { \ if (Loki::Visitor* p = dynamic_cast*>(guest.get())) \ { \ - std::cout << "HERE" << std::endl; \ return p->visit(*this, guest); \ } \ else \ diff --git a/tests/Cxx/CMakeLists.txt b/tests/Cxx/CMakeLists.txt index b7c86db000e0e84f1750fa7aa1e96bc1de47e19b..3efa86fa981b57db314665c1adb3ceeb3a66ddaa 100644 --- a/tests/Cxx/CMakeLists.txt +++ b/tests/Cxx/CMakeLists.txt @@ -6,6 +6,7 @@ set(XdmfCxxTests TestXdmfGeometry TestXdmfGrid TestXdmfHDF5Writer + TestXdmfReader TestXdmfTopology TestXdmfVisitorValueCounter TestXdmfWriter diff --git a/tests/Cxx/TestXdmfReader.cpp b/tests/Cxx/TestXdmfReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f55a8a8340e2613a18387b2faab118d33fb145f4 --- /dev/null +++ b/tests/Cxx/TestXdmfReader.cpp @@ -0,0 +1,41 @@ +#include +#include "XdmfReader.hpp" +#include "XdmfWriter.hpp" + +#include "XdmfTestDataGenerator.hpp" + +int main(int argc, char* argv[]) +{ + boost::shared_ptr writer = XdmfWriter::New("TestXdmfReader1.xmf"); + writer->setLightDataLimit(10); + + boost::shared_ptr grid = XdmfTestDataGenerator::createHexahedron(); + + boost::shared_ptr domain = XdmfDomain::New(); + domain->insert(grid); + domain->accept(writer); + + boost::shared_ptr reader = XdmfReader::New(); + boost::shared_ptr readDomain = reader->read("TestXdmfReader1.xmf"); + + boost::shared_ptr writer2 = XdmfWriter::New("TestXdmfReader2.xmf"); + readDomain->accept(writer2); + + std::ifstream firstFile("TestXdmfReader1.xmf"); + std::ifstream secondFile("TestXdmfReader2.xmf"); + + std::string firstLine; + std::string secondLine; + + while(!firstFile.eof()) + { + std::getline(firstFile, firstLine); + std::getline(secondFile, secondLine); + if(firstLine.compare(secondLine) != 0) + { + assert(false); + } + } + + return 0; +}