Commit 0532b592 authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Modift XdmfWriter to utilize new genericized getItemTag and getItemProperties methods

to write out the Xdmf graph.  Modify some random include statements for style.
parent b9dd6799
......@@ -473,8 +473,12 @@ std::map<std::string, std::string> XdmfArray::getItemProperties() const
std::map<std::string, std::string> arrayProperties;
arrayProperties["Format"] = "HDF";
arrayProperties["DataType"] = this->getType();
arrayProperties["Precision"] = this->getPrecision();
arrayProperties["Dimensions"] = this->getSize();
std::stringstream precision;
precision << this->getPrecision();
arrayProperties["Precision"] = precision.str();
std::stringstream size;
size << this->getSize();
arrayProperties["Dimensions"] = size.str();
return arrayProperties;
}
......
......@@ -6,7 +6,6 @@
*/
#include "XdmfAttribute.hpp"
#include "XdmfVisitor.hpp"
XdmfAttribute::XdmfAttribute() :
mName(""),
......
......@@ -2,6 +2,7 @@
#define XDMFATTRIBUTECENTER_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -2,6 +2,7 @@
#define XDMFATTRIBUTETYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -7,7 +7,6 @@
#include "XdmfDomain.hpp"
#include "XdmfGrid.hpp"
#include "XdmfVisitor.hpp"
XdmfDomain::XdmfDomain()
{
......
......@@ -5,8 +5,8 @@
class XdmfGrid;
// Includes
#include "XdmfItem.hpp"
#include <vector>
#include "XdmfItem.hpp"
/**
* @brief The root XdmfItem that contains XdmfGrids.
......
......@@ -6,7 +6,6 @@
*/
#include "XdmfGeometry.hpp"
#include "XdmfVisitor.hpp"
XdmfGeometry::XdmfGeometry() :
mGeometryType(XdmfGeometryType::NoGeometryType()),
......
......@@ -5,6 +5,7 @@
* Author: kleiter
*/
#include <map>
#include "XdmfGeometryType.hpp"
// Supported XdmfGeometryTypes
......
......@@ -2,6 +2,7 @@
#define XDMFGEOMETRYTYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -9,8 +9,6 @@
#include "XdmfGrid.hpp"
#include "XdmfGeometry.hpp"
#include "XdmfTopology.hpp"
#include "XdmfVisitor.hpp"
#include <sstream>
XdmfGrid::XdmfGrid() :
mGeometry(XdmfGeometry::New()),
......
#include "XdmfItem.hpp"
#include "XdmfVisitor.hpp"
XdmfItem::XdmfItem()
{
......
......@@ -2,7 +2,6 @@
#define XDMFITEMPROPERTY_HPP_
// Includes
#include <string>
#include <map>
#include "XdmfObject.hpp"
......
......@@ -4,7 +4,6 @@
// Includes
#include <boost/shared_ptr.hpp>
#define XdmfNewMacro(type) \
template <typename T> friend void boost::checked_delete(T * x); \
static boost::shared_ptr<type> New() \
......
......@@ -5,9 +5,9 @@
* Author: kleiter
*/
#include <sstream>
#include "XdmfArray.hpp"
#include "XdmfTopology.hpp"
#include "XdmfVisitor.hpp"
XdmfTopology::XdmfTopology() :
mTopologyType(XdmfTopologyType::NoTopologyType()),
......@@ -30,6 +30,9 @@ std::map<std::string, std::string> XdmfTopology::getItemProperties() const
{
std::map<std::string, std::string> topologyProperties;
mTopologyType.getProperties(topologyProperties);
std::stringstream numElements;
numElements << this->getNumberElements();
topologyProperties["Dimensions"] = numElements.str();
return topologyProperties;
}
......
......@@ -8,7 +8,7 @@
/**
* @brief Handles the connectivity information in an XdmfGrid.
*
* XdmfTopology is a required part of an XdmfGrid. It stores the connectivty information
* XdmfTopology is a required part of an XdmfGrid. It stores the connectivity information
* between all points contained in an XdmfGrid. XdmfTopology contains an XdmfTopologyType property
* which should be set that specifies the element type stored.
*/
......
......@@ -2,6 +2,7 @@
#define XDMFTOPOLOGYTYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
* @brief Property describing the types of elements stored in an XdmfTopology.
......
// Kenneth Leiter
// Xdmf Smart Pointer Test
#include <sstream>
#include "XdmfArray.hpp"
#include "XdmfAttribute.hpp"
#include "XdmfDomain.hpp"
#include "XdmfGeometry.hpp"
#include "XdmfGrid.hpp"
#include "XdmfTopology.hpp"
#include "XdmfItem.hpp"
#include "XdmfWriter.hpp"
//#include <iomanip>
XdmfWriter::XdmfWriter() :
mLightDataLimit(100),
mHeavyFileName("output.h5"),
hdf5Handle(H5Fcreate("output.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)),
xmlDocument(xmlNewDoc((xmlChar*)"1.0")),
xmlCurrentNode(xmlNewNode(NULL, (xmlChar*)"Xdmf"))
mHDF5Handle(H5Fcreate("output.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)),
mXMLDocument(xmlNewDoc((xmlChar*)"1.0")),
mXMLCurrentNode(xmlNewNode(NULL, (xmlChar*)"Xdmf"))
{
xmlDocSetRootElement(xmlDocument, xmlCurrentNode);
xmlDocSetRootElement(mXMLDocument, mXMLCurrentNode);
std::cout << "Created visitor " << this << std::endl;
}
XdmfWriter::~XdmfWriter()
{
xmlSaveFormatFile("output.xmf", xmlDocument, 1);
xmlFreeDoc(xmlDocument);
xmlSaveFormatFile("output.xmf", mXMLDocument, 1);
xmlFreeDoc(mXMLDocument);
xmlCleanupParser();
herr_t status = H5Fclose(hdf5Handle);
herr_t status = H5Fclose(mHDF5Handle);
std::cout << "Deleted visitor " << this << std::endl;
}
void XdmfWriter::visit(XdmfAttribute & attribute, boost::shared_ptr<Loki::BaseVisitor> visitor)
std::string XdmfWriter::createHDF5Group(std::stringstream & groupPath, int index)
{
std::cout << "Writing Attribute" << std::endl;
xmlNodePtr parentNode = xmlCurrentNode;
xmlCurrentNode = xmlNewChild(xmlCurrentNode, NULL, (xmlChar*)"Attribute", NULL);
xmlNewProp(xmlCurrentNode, (xmlChar*)"Name", (xmlChar*)attribute.getName().c_str());
xmlNewProp(xmlCurrentNode, (xmlChar*)"AttributeType", (xmlChar*)attribute.getAttributeType().getName().c_str());
xmlNewProp(xmlCurrentNode, (xmlChar*)"Center", (xmlChar*)attribute.getAttributeCenter().getName().c_str());
dataHierarchy.push_back(attribute.getName());
attribute.traverse(visitor);
dataHierarchy.pop_back();
xmlCurrentNode = parentNode;
groupPath << "/" << mDataHierarchy[index];
hid_t handle = H5Gopen(mHDF5Handle, groupPath.str().c_str(), H5P_DEFAULT);
if(handle < 0)
{
// Open failed, create a new group
handle = H5Gcreate(mHDF5Handle, groupPath.str().c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
}
H5Gclose(handle);
// + 2 because we ignore last value in mDataHierarchy (== dataset name)
if(index + 2 < mDataHierarchy.size())
{
return createHDF5Group(groupPath, index + 1);
}
return groupPath.str().c_str();
}
void XdmfWriter::visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> visitor)
std::string XdmfWriter::getHDF5GroupHandle()
{
std::cout << "Writing Array" << std::endl;
xmlNodePtr parentNode = xmlCurrentNode;
xmlCurrentNode = xmlNewChild(xmlCurrentNode, NULL, (xmlChar*)"DataItem", NULL);
std::string format = "XML";
if(array.getSize() > mLightDataLimit)
if(mDataHierarchy.size() > 1)
{
format = "HDF";
// Save old error handler and turn off error handling for now
H5E_auto_t old_func;
void* old_client_data;
H5Eget_auto(0, &old_func, &old_client_data);
H5Eset_auto2(0, NULL, NULL);
std::stringstream emptyPath;
std::string handle = createHDF5Group(emptyPath);
// Restore previous error handler
H5Eset_auto2(0, old_func, old_client_data);
return handle;
}
return "";
}
xmlNewProp(xmlCurrentNode, (xmlChar*)"Format", (xmlChar*)format.c_str());
xmlNewProp(xmlCurrentNode, (xmlChar*)"DataType", (xmlChar*)array.getType().c_str());
std::stringstream precisionString;
precisionString << array.getPrecision();
xmlNewProp(xmlCurrentNode, (xmlChar*)"Precision", (xmlChar*)precisionString.str().c_str());
std::stringstream dimensionString;
dimensionString << array.getSize();
xmlNewProp(xmlCurrentNode, (xmlChar*)"Dimensions", (xmlChar*)dimensionString.str().c_str());
unsigned int XdmfWriter::getLightDataLimit() const
{
return mLightDataLimit;
}
void XdmfWriter::setLightDataLimit(unsigned int numValues)
{
mLightDataLimit = numValues;
}
void XdmfWriter::visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
this->visit(dynamic_cast<XdmfItem &>(array), visitor);
xmlNodePtr parentNode = mXMLCurrentNode;
mXMLCurrentNode = mXMLCurrentNode->children;
std::stringstream xmlTextValues;
if(array.getSize() > mLightDataLimit)
......@@ -74,32 +90,19 @@ void XdmfWriter::visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> v
herr_t status;
hsize_t size = array.getSize();
hid_t dataspace = H5Screate_simple(1, &size, NULL);
hid_t handle = hdf5Handle;
std::string groupName = getHDF5GroupName();
// Need to make sure this group exists before we add to it.
if(dataHierarchy.size() > 1)
hid_t handle = mHDF5Handle;
std::string groupName = getHDF5GroupHandle();
if(groupName.compare("") != 0)
{
// Save old error handler
H5E_auto_t old_func;
void* old_client_data;
H5Eget_auto(0, &old_func, &old_client_data);
// Turn off error handling
H5Eset_auto2(0, NULL, NULL);
// Probe. May fail, but that's okay
handle = H5Gopen(hdf5Handle, groupName.c_str(), H5P_DEFAULT);
// Restore previous error handler
H5Eset_auto2(0, old_func, old_client_data);
if(handle < 0)
{
handle = H5Gcreate(hdf5Handle, groupName.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
}
handle = H5Gopen(mHDF5Handle, groupName.c_str(), H5P_DEFAULT);
}
hid_t dataset = H5Dcreate(handle, dataHierarchy.back().c_str(), array.getHDF5Type(), dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
xmlTextValues << mHeavyFileName << ":" << groupName << "/" << dataHierarchy.back();
hid_t dataset = H5Dcreate(handle, mDataHierarchy.back().c_str(), array.getHDF5Type(), dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
xmlTextValues << mHeavyFileName << ":" << groupName << "/" << mDataHierarchy.back();
status = H5Dwrite(dataset, array.getHDF5Type(), H5S_ALL, H5S_ALL, H5P_DEFAULT, array.getValuesPointer());
if(groupName.compare("") != 0)
{
H5Gclose(handle);
}
status = H5Dclose(dataset);
status = H5Sclose(dataspace);
}
......@@ -108,82 +111,31 @@ void XdmfWriter::visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> v
xmlTextValues << array.getValuesString();
}
xmlAddChild(xmlCurrentNode, xmlNewText((xmlChar*)xmlTextValues.str().c_str()));
xmlCurrentNode = parentNode;
}
void XdmfWriter::visit(XdmfDomain & domain, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
std::cout << "Writing Domain" << std::endl;
xmlNodePtr parentNode = xmlCurrentNode;
xmlCurrentNode = xmlNewChild(xmlCurrentNode, NULL, (xmlChar*)"Domain", NULL);
domain.traverse(visitor);
xmlCurrentNode = parentNode;
}
void XdmfWriter::visit(XdmfGeometry & geometry, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
std::cout << "Writing Geometry" << std::endl;
xmlNodePtr parentNode = xmlCurrentNode;
xmlCurrentNode = xmlNewChild(xmlCurrentNode, NULL, (xmlChar*)"Geometry", NULL);
xmlNewProp(xmlCurrentNode, (xmlChar*)"GeometryType", (xmlChar*)geometry.getGeometryType().getName().c_str());
dataHierarchy.push_back("XYZ");
geometry.traverse(visitor);
dataHierarchy.pop_back();
xmlCurrentNode = parentNode;
xmlAddChild(mXMLCurrentNode, xmlNewText((xmlChar*)xmlTextValues.str().c_str()));
mXMLCurrentNode = parentNode;
}
void XdmfWriter::visit(XdmfGrid & grid, boost::shared_ptr<Loki::BaseVisitor> visitor)
void XdmfWriter::visit(XdmfItem & item, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
std::cout << "Writing Grid" << std::endl;
xmlNodePtr parentNode = xmlCurrentNode;
xmlCurrentNode = xmlNewChild(xmlCurrentNode, NULL, (xmlChar*)"Grid", NULL);
xmlNewProp(xmlCurrentNode, (xmlChar*)"Name", (xmlChar*)grid.getName().c_str());
dataHierarchy.push_back(grid.getName());
grid.traverse(visitor);
dataHierarchy.pop_back();
xmlCurrentNode = parentNode;
}
void XdmfWriter::visit(XdmfTopology & topology, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
std::cout << "Writing Topology" << std::endl;
xmlNodePtr parentNode = xmlCurrentNode;
xmlCurrentNode = xmlNewChild(xmlCurrentNode, NULL, (xmlChar*)"Topology", NULL);
xmlNewProp(xmlCurrentNode, (xmlChar*)"TopologyType", (xmlChar*)topology.getTopologyType().getName().c_str());
std::stringstream numberElementsString;
numberElementsString << topology.getNumberElements();
xmlNewProp(xmlCurrentNode, (xmlChar*)"NumberOfElements", (xmlChar*)numberElementsString.str().c_str());
dataHierarchy.push_back("Connectivity");
topology.traverse(visitor);
dataHierarchy.pop_back();
xmlCurrentNode = parentNode;
}
unsigned int XdmfWriter::getLightDataLimit() const
{
return mLightDataLimit;
}
void XdmfWriter::setLightDataLimit(unsigned int numValues)
{
mLightDataLimit = numValues;
}
std::string XdmfWriter::getHDF5GroupName()
{
std::stringstream datasetName;
for(unsigned int i=0; i<dataHierarchy.size() - 1; ++i)
xmlNodePtr parentNode = mXMLCurrentNode;
mXMLCurrentNode = xmlNewChild(mXMLCurrentNode, NULL, (xmlChar*)item.getItemTag().c_str(), NULL);
const std::map<std::string, std::string> itemProperties = item.getItemProperties();
bool pushedHDF5Name = false;
for(std::map<std::string, std::string>::const_iterator iter = itemProperties.begin(); iter != itemProperties.end(); ++iter)
{
datasetName << "/" << dataHierarchy[i];
if(iter->first.compare("Name") == 0)
{
mDataHierarchy.push_back(iter->second);
pushedHDF5Name = true;
}
xmlNewProp(mXMLCurrentNode, (xmlChar*)iter->first.c_str(), (xmlChar*)iter->second.c_str());
}
return datasetName.str();
if(!pushedHDF5Name)
{
mDataHierarchy.push_back(item.getItemTag());
}
item.traverse(visitor);
mXMLCurrentNode = parentNode;
mDataHierarchy.pop_back();
}
......@@ -3,16 +3,10 @@
// Forward Declarations
class XdmfArray;
class XdmfAttribute;
class XdmfDomain;
class XdmfGeometry;
class XdmfGrid;
class XdmfTopology;
// Includes
#include <hdf5.h>
#include <libxml/tree.h>
#include <sstream>
#include <vector>
#include "XdmfVisitor.hpp"
......@@ -24,12 +18,7 @@ class XdmfTopology;
* The XdmfItem as well as all children attached to the XdmfItem are written to disk.
*/
class XdmfWriter : public XdmfVisitor,
public Loki::Visitor<XdmfArray>,
public Loki::Visitor<XdmfAttribute>,
public Loki::Visitor<XdmfDomain>,
public Loki::Visitor<XdmfGeometry>,
public Loki::Visitor<XdmfGrid>,
public Loki::Visitor<XdmfTopology> {
public Loki::Visitor<XdmfArray> {
public:
......@@ -58,44 +47,12 @@ public:
void visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> visitor);
/**
* Write an XdmfAttribute to disk
* Write an XdmfItem to disk
*
* @param attribute a pointer to an XdmfAttribute to write to disk.
* @param item a pointer to an XdmfItem to write to disk.
* @param visitor a smart pointer to this XdmfVisitor --- aids in grid traversal.
*/
void visit(XdmfAttribute & attribute, boost::shared_ptr<Loki::BaseVisitor> visitor);
/**
* Write an XdmfDomain to disk
*
* @param domain a pointer to an XdmfDomain to write to disk.
* @param visitor a smart pointer to this XdmfVisitor --- aids in grid traversal.
*/
void visit(XdmfDomain & domain, boost::shared_ptr<Loki::BaseVisitor> visitor);
/**
* Write an XdmfGeometry to disk
*
* @param geometry a pointer to an XdmfGeometry to write to disk.
* @param visitor a smart pointer to this XdmfVisitor --- aids in grid traversal.
*/
void visit(XdmfGeometry & geometry, boost::shared_ptr<Loki::BaseVisitor> visitor);
/**
* Write an XdmfGrid to disk
*
* @param grid a pointer to an XdmfGrid to write to disk.
* @param visitor a smart pointer to this XdmfVisitor --- aids in grid traversal.
*/
void visit(XdmfGrid & grid, boost::shared_ptr<Loki::BaseVisitor> visitor);
/**
* Write an XdmfTopology to disk
*
* @param topology a pointer to an XdmfTopology to write to disk.
* @param visitor a smart pointer to this XdmfVisitor --- aids in grid traversal.
*/
void visit(XdmfTopology & topology, boost::shared_ptr<Loki::BaseVisitor> visitor);
void visit(XdmfItem & item, boost::shared_ptr<Loki::BaseVisitor> visitor);
protected:
......@@ -108,18 +65,30 @@ private:
void operator=(const XdmfWriter & writer); // Not implemented.
/**
* Uses the dataHierarchy to construct an appropriate hdf5 group name at the current point in writing.
* Create a new HDF5 group if needed based on the dataHierarchy. This is a recursive function used by getHDF5GroupHandle to construct
* new hdf5 groups.
*
* @param groupPath the current place in the dataHierarchy being processed.
* @param index the index in the dataHierarchy being processed.
*
* @return a string containing the path to the created group.
*/
std::string createHDF5Group(std::stringstream & groupPath, int index = 0);
/**
* Get a handle to a hdf5 group to write into. Uses the dataHierarchy to construct an appropriate hdf5 group name
* at the current point in writing.
*
* @return a string containing the hdf5 group name.
* @return a string containing the path to the created group.
*/
std::string getHDF5GroupName();
std::string getHDF5GroupHandle();
std::vector<std::string> dataHierarchy;
hid_t hdf5Handle;
std::vector<std::string> mDataHierarchy;
hid_t mHDF5Handle;
std::string mHeavyFileName;
unsigned int mLightDataLimit;
xmlDocPtr xmlDocument;
xmlNodePtr xmlCurrentNode;
xmlDocPtr mXMLDocument;
xmlNodePtr mXMLCurrentNode;
};
#endif /* XDMFWRITER_HPP_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment