Commit 906019df authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Modify several utils to take XdmfHDF5Controller as an argument so that...

ENH: Modify several utils to take XdmfHDF5Controller as an argument so that they can write data to hdf5 as generated rather than keeping it all in memory.  This is an optional argument.
parent db5298c9
......@@ -188,6 +188,7 @@ public:
* Initializes the array to contain an empty container of a particular type.
*
* @param size the number of values in the initialized array.
*
* @return a smart pointer to the internal vector of values initialized in this array.
*/
template <typename T>
......
......@@ -32,6 +32,7 @@
#include "XdmfGeometry.hpp"
#include "XdmfGeometryType.hpp"
#include "XdmfGrid.hpp"
#include "XdmfHDF5Writer.hpp"
#include "XdmfSet.hpp"
#include "XdmfSetType.hpp"
#include "XdmfTopology.hpp"
......@@ -51,10 +52,9 @@ XdmfExodusReader::~XdmfExodusReader()
{
}
boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName) const
boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName, const boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter) const
{
boost::shared_ptr<XdmfGrid> grid = XdmfGrid::New();
boost::shared_ptr<XdmfGrid> toReturn = XdmfGrid::New();
// Read Exodus II file to XdmfGrid via Exodus II API
float version;
......@@ -62,6 +62,12 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
int IO_word_size = 0; // Get from file
int exodusHandle = ex_open(fileName.c_str(), EX_READ, &CPU_word_size, &IO_word_size, &version);
if(exodusHandle < 0)
{
// Invalid fileName
assert(false);
}
char * title = new char[MAX_LINE_LENGTH+1];
int num_dim, num_nodes, num_elem, num_elem_blk, num_node_sets, num_side_sets;
ex_get_init (exodusHandle, title, &num_dim, &num_nodes, &num_elem, &num_elem_blk, &num_node_sets, &num_side_sets);
......@@ -87,11 +93,11 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
// In the future we may want to do XDMF_GEOMETRY_X_Y_Z?
if(num_dim == 3)
{
grid->getGeometry()->setType(XdmfGeometryType::XYZ());
toReturn->getGeometry()->setType(XdmfGeometryType::XYZ());
}
else if(num_dim = 2)
{
grid->getGeometry()->setType(XdmfGeometryType::XY());
toReturn->getGeometry()->setType(XdmfGeometryType::XY());
}
else
{
......@@ -99,21 +105,27 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
assert(false);
}
grid->getGeometry()->initialize(XdmfArrayType::Float64());
grid->getGeometry()->reserve(num_nodes * num_dim);
toReturn->getGeometry()->initialize(XdmfArrayType::Float64());
toReturn->getGeometry()->reserve(num_nodes * num_dim);
for(unsigned int i=0; i<num_nodes; ++i)
{
grid->getGeometry()->pushBack(x[i]);
grid->getGeometry()->pushBack(y[i]);
toReturn->getGeometry()->pushBack(x[i]);
toReturn->getGeometry()->pushBack(y[i]);
if(num_dim == 3)
{
grid->getGeometry()->pushBack(z[i]);
toReturn->getGeometry()->pushBack(z[i]);
}
}
delete [] x;
delete [] y;
delete [] z;
if(heavyDataWriter)
{
toReturn->getGeometry()->accept(heavyDataWriter);
toReturn->getGeometry()->release();
}
int * blockIds = new int[num_elem_blk];
ex_get_elem_blk_ids(exodusHandle, blockIds);
......@@ -149,21 +161,21 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
if(topologyTypes.size() > 0)
{
grid->getTopology()->setType(topologyTypes[0]);
toReturn->getTopology()->setType(topologyTypes[0]);
if(topologyTypes.size() > 1)
{
for(std::vector<boost::shared_ptr<const XdmfTopologyType> >::const_iterator iter = topologyTypes.begin() + 1; iter != topologyTypes.end(); ++iter)
{
// Cannot be mixed topology!
assert(grid->getTopology()->getType() == *iter);
assert(toReturn->getTopology()->getType() == *iter);
}
}
}
topologyTypes.clear();
grid->getTopology()->initialize(XdmfArrayType::Int32(), totalConns);
int * connectivityPointer = (int *)grid->getTopology()->getValuesPointer();
toReturn->getTopology()->initialize(XdmfArrayType::Int32(), totalConns);
int * connectivityPointer = (int *)toReturn->getTopology()->getValuesPointer();
// Read connectivity from element blocks
int elemIndex = 0;
for(unsigned int i=0; i<num_elem_blk; ++i)
......@@ -173,7 +185,7 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
}
// This is taken from VTK's vtkExodusIIReader and adapted to fit Xdmf element types, which have the same ordering as VTK.
if(grid->getTopology()->getType() == XdmfTopologyType::Hexahedron_20() || grid->getTopology()->getType() == XdmfTopologyType::Hexahedron_27())
if(toReturn->getTopology()->getType() == XdmfTopologyType::Hexahedron_20() || toReturn->getTopology()->getType() == XdmfTopologyType::Hexahedron_27())
{
int * ptr = connectivityPointer;
int itmp[4];
......@@ -194,7 +206,7 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
*ptr = itmp[j];
}
if(grid->getTopology()->getType() == XdmfTopologyType::Hexahedron_27())
if(toReturn->getTopology()->getType() == XdmfTopologyType::Hexahedron_27())
{
for(unsigned int j=0; j<4; ++j, ++ptr)
{
......@@ -207,7 +219,7 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
}
}
}
else if(grid->getTopology()->getType() == XdmfTopologyType::Wedge_15() || grid->getTopology()->getType() == XdmfTopologyType::Wedge_18())
else if(toReturn->getTopology()->getType() == XdmfTopologyType::Wedge_15() || toReturn->getTopology()->getType() == XdmfTopologyType::Wedge_18())
{
int * ptr = connectivityPointer;
int itmp[3];
......@@ -228,7 +240,7 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
*ptr = itmp[j];
}
if(grid->getTopology()->getType() == XdmfTopologyType::Wedge_18())
if(toReturn->getTopology()->getType() == XdmfTopologyType::Wedge_18())
{
itmp[0] = *(ptr);
itmp[1] = *(ptr+1);
......@@ -246,6 +258,12 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
connectivityPointer[i]--;
}
if(heavyDataWriter)
{
toReturn->getTopology()->accept(heavyDataWriter);
toReturn->getTopology()->release();
}
boost::shared_ptr<XdmfAttribute> globalIds = XdmfAttribute::New();
globalIds->setName("GlobalNodeId");
globalIds->setCenter(XdmfAttributeCenter::Node());
......@@ -261,7 +279,13 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
globalIdsPointer[i]--;
}
grid->insert(globalIds);
toReturn->insert(globalIds);
if(heavyDataWriter)
{
globalIds->accept(heavyDataWriter);
globalIds->release();
}
// Read node sets
int * nodeSetIds = new int[num_node_sets];
......@@ -300,28 +324,13 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
set->insert(node_set_node_list[j] - 1);
}
grid->insert(set);
toReturn->insert(set);
/*
if(num_df_in_set > 0)
if(heavyDataWriter)
{
double * node_set_distribution_factors = new double[num_df_in_set];
ex_get_node_set_dist_fact(exodusHandle, nodeSetIds[j], node_set_distribution_factors);
XdmfAttribute * attr = new XdmfAttribute();
attr->SetName("SetAttribute");
attr->SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
attr->SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr->SetDeleteOnGridDelete(true);
XdmfArray * attrVals = attr->GetValues();
attrVals->SetNumberType(XDMF_FLOAT32_TYPE);
attrVals->SetNumberOfElements(num_df_in_set);
attrVals->SetValues(0, node_set_distribution_factors, num_df_in_set, 1, 1);
set->Insert(attr);
delete [] node_set_distribution_factors;
}
*/
set->accept(heavyDataWriter);
set->release();
}
delete [] node_set_node_list;
}
......@@ -393,7 +402,12 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
attribute->setType(XdmfAttributeType::Scalar());
attribute->initialize(XdmfArrayType::Float64());
attribute->pushBack(global_var_vals[i]);
grid->insert(attribute);
toReturn->insert(attribute);
if(heavyDataWriter)
{
attribute->accept(heavyDataWriter);
attribute->release();
}
delete [] global_var_names[i];
}
delete [] global_var_vals;
......@@ -412,7 +426,12 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
attribute->setType(XdmfAttributeType::Scalar());
attribute->initialize(XdmfArrayType::Float64(), num_nodes);
ex_get_nodal_var(exodusHandle, 1, i+1, num_nodes, (double*)attribute->getValuesPointer());
grid->insert(attribute);
toReturn->insert(attribute);
if(heavyDataWriter)
{
attribute->accept(heavyDataWriter);
attribute->release();
}
delete [] nodal_var_names[i];
}
}
......@@ -431,7 +450,12 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
ex_get_elem_var(exodusHandle, 1, i+1, blockIds[j], numElemsInBlock[i], &((double*)attribute->getValuesPointer())[elemIndex]);
elemIndex = elemIndex + numElemsInBlock[i];
}
grid->insert(attribute);
toReturn->insert(attribute);
if(heavyDataWriter)
{
attribute->accept(heavyDataWriter);
attribute->release();
}
delete [] elem_var_names[i];
}
......@@ -440,7 +464,7 @@ boost::shared_ptr<XdmfGrid> XdmfExodusReader::read(const std::string & fileName)
delete [] numElemsInBlock;
delete [] numNodesPerElemInBlock;
delete [] numElemAttrInBlock;
return grid;
return toReturn;
}
boost::shared_ptr<const XdmfTopologyType> XdmfExodusReader::exodusToXdmfTopologyType(std::string exodusTopologyType, const int pointsPerCell) const
......@@ -597,6 +621,3 @@ boost::shared_ptr<const XdmfTopologyType> XdmfExodusReader::exodusToXdmfTopology
}
return XdmfTopologyType::NoTopologyType();
}
......@@ -3,6 +3,7 @@
// Forward Declarations
class XdmfGrid;
class XdmfHDF5Writer;
class XdmfTopologyType;
// Includes
......@@ -29,10 +30,11 @@ public:
* Read the contents of an ExodusII file from disk into an Xdmf structure in memory..
*
* @param fileName containing the path of the exodus file to read.
* @param heavyDataWriter an XdmfHDF5Writer to write the mesh to. If no heavyDataWriter is specified, all mesh data will remain in memory.
*
* @return XdmfGrid containing the mesh stored in the ExodusII file.
*/
boost::shared_ptr<XdmfGrid> read(const std::string & fileName) const;
boost::shared_ptr<XdmfGrid> read(const std::string & fileName, const boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter = boost::shared_ptr<XdmfHDF5Writer>()) const;
protected:
......
......@@ -32,7 +32,6 @@ extern "C"
#include <iostream>
#include <sstream>
#include "XdmfArray.hpp"
#include "XdmfAttribute.hpp"
#include "XdmfAttributeCenter.hpp"
#include "XdmfAttributeType.hpp"
......@@ -64,7 +63,7 @@ XdmfPartitioner::~XdmfPartitioner()
}
boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::shared_ptr<XdmfGrid> gridToPartition, const unsigned int numberOfPartitions,
boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter) const
const boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter) const
{
int metisElementType;
int nodesPerElement;
......@@ -97,9 +96,11 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
assert(false);
}
bool releaseTopology = false;
if(!gridToPartition->getTopology()->isInitialized())
{
gridToPartition->getTopology()->read();
releaseTopology = true;
}
int numElements = gridToPartition->getTopology()->getNumberElements();
......@@ -185,9 +186,11 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
boost::shared_ptr<XdmfGridCollection> partitionedGrids = XdmfGridCollection::New();
partitionedGrids->setType(XdmfGridCollectionType::Spatial());
bool releaseGeometry = false;
if(!gridToPartition->getGeometry()->isInitialized())
{
gridToPartition->getGeometry()->read();
releaseGeometry = true;
}
// Split geometry and topology into proper partitions
......@@ -207,26 +210,23 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
// Fill in geometry for this partition
partitioned->getGeometry()->setType(gridToPartition->getGeometry()->getType());
boost::shared_ptr<XdmfArray> geometryVals = partitioned->getGeometry();
unsigned int numDimensions = partitioned->getGeometry()->getType()->getDimensions();
geometryVals->initialize(gridToPartition->getGeometry()->getArrayType(), currNodeMap.size() * numDimensions);
partitioned->getGeometry()->initialize(gridToPartition->getGeometry()->getArrayType(), currNodeMap.size() * numDimensions);
for(std::map<unsigned int, unsigned int>::const_iterator iter = currNodeMap.begin(); iter != currNodeMap.end(); ++iter)
{
geometryVals->copyValues(iter->second * numDimensions, gridToPartition->getGeometry(), iter->first * numDimensions, numDimensions);
partitioned->getGeometry()->copyValues(iter->second * numDimensions, gridToPartition->getGeometry(), iter->first * numDimensions, numDimensions);
}
if(heavyDataWriter)
{
geometryVals->accept(heavyDataWriter);
geometryVals->release();
partitioned->getGeometry()->accept(heavyDataWriter);
partitioned->getGeometry()->release();
}
// Fill in topology for this partition
partitioned->getTopology()->setType(gridToPartition->getTopology()->getType());
boost::shared_ptr<XdmfArray> topologyVals = partitioned->getTopology();
topologyVals->initialize(gridToPartition->getTopology()->getArrayType(), currElemIds.size() * topologyType->getNodesPerElement());
partitioned->getTopology()->initialize(gridToPartition->getTopology()->getArrayType(), currElemIds.size() * topologyType->getNodesPerElement());
unsigned int index = 0;
for(std::vector<unsigned int>::const_iterator iter = currElemIds.begin(); iter != currElemIds.end(); ++iter)
{
......@@ -234,15 +234,15 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
for(unsigned int j=0; j<topologyType->getNodesPerElement(); ++j)
{
unsigned int globalNodeId = currNodeMap[gridToPartition->getTopology()->getValueCopy<unsigned int>(*iter * topologyType->getNodesPerElement() + j)];
topologyVals->copyValues(index, &globalNodeId, 1);
partitioned->getTopology()->copyValues(index, &globalNodeId, 1);
index++;
}
}
if(heavyDataWriter)
{
topologyVals->accept(heavyDataWriter);
topologyVals->release();
partitioned->getTopology()->accept(heavyDataWriter);
partitioned->getTopology()->release();
}
if (generateGlobalNodeIds)
......@@ -251,34 +251,40 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
globalNodeIds->setName("GlobalNodeId");
globalNodeIds->setType(XdmfAttributeType::GlobalId());
globalNodeIds->setCenter(XdmfAttributeCenter::Node());
boost::shared_ptr<XdmfArray> globalNodeIdsVals = globalNodeIds;
globalNodeIdsVals->resize<unsigned int>(currNodeMap.size());
for (std::map<unsigned int, unsigned int>::const_iterator iter = currNodeMap.begin(); iter != currNodeMap.end(); ++iter)
globalNodeIds->initialize<unsigned int>(currNodeMap.size());
for(std::map<unsigned int, unsigned int>::const_iterator iter = currNodeMap.begin(); iter != currNodeMap.end(); ++iter)
{
globalNodeIdsVals->copyValues(iter->second, &iter->first, 1);
globalNodeIds->copyValues(iter->second, &iter->first, 1);
}
partitioned->insert(globalNodeIds);
if(heavyDataWriter)
{
globalNodeIdsVals->accept(heavyDataWriter);
globalNodeIdsVals->release();
globalNodeIds->accept(heavyDataWriter);
globalNodeIds->release();
}
}
}
}
gridToPartition->getGeometry()->release();
gridToPartition->getTopology()->release();
if(releaseGeometry)
{
gridToPartition->getGeometry()->release();
}
if(releaseTopology)
{
gridToPartition->getTopology()->release();
}
// Split attributes into proper partitions
for(unsigned int i=0; i<gridToPartition->getNumberAttributes(); ++i)
{
boost::shared_ptr<XdmfAttribute> currAttribute = gridToPartition->getAttribute(i);
bool releaseAttribute = false;
if(!currAttribute->isInitialized())
{
currAttribute->read();
releaseAttribute = true;
}
unsigned int partitionId = 0;
for(unsigned int j=0; j<numberOfPartitions; ++j)
......@@ -289,7 +295,7 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
{
boost::shared_ptr<XdmfGrid> partitioned = partitionedGrids->getGrid(partitionId);
partitionId++;
boost::shared_ptr<XdmfAttribute> createdAttribute;
boost::shared_ptr<XdmfAttribute> createdAttribute = boost::shared_ptr<XdmfAttribute>();
if(currAttribute->getCenter() == XdmfAttributeCenter::Grid())
{
if(partitionId == 0)
......@@ -331,22 +337,31 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
partitioned->insert(createdAttribute);
if(heavyDataWriter)
{
if(!createdAttribute->isInitialized())
{
createdAttribute->read();
}
createdAttribute->accept(heavyDataWriter);
createdAttribute->release();
}
}
}
}
currAttribute->release();
if(releaseAttribute)
{
currAttribute->release();
}
}
// Split sets into proper partitions
for(unsigned int i=0; i<gridToPartition->getNumberSets(); ++i)
{
boost::shared_ptr<XdmfSet> currSet = gridToPartition->getSet(i);
bool releaseSet = false;
if(!currSet->isInitialized())
{
currSet->read();
releaseSet = true;
}
unsigned int partitionId = 0;
for(unsigned int j=0; j<numberOfPartitions; ++j)
......@@ -396,7 +411,10 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
}
}
}
currSet->release();
if(releaseSet)
{
currSet->release();
}
}
// Add XdmfMap to map boundary nodes between partitions
......@@ -404,7 +422,10 @@ boost::shared_ptr<XdmfGridCollection> XdmfPartitioner::partition(const boost::sh
for(unsigned int i=0; i<partitionedGrids->getNumberGrids(); ++i)
{
boost::shared_ptr<XdmfAttribute> globalNodeId = partitionedGrids->getGrid(i)->getAttribute("GlobalNodeId");
globalNodeId->read();
if(!globalNodeId->isInitialized())
{
globalNodeId->read();
}
globalNodeIds.push_back(globalNodeId);
}
......
......@@ -53,7 +53,7 @@ public:
* @return a spatial collection containing partitioned grids.
*/
boost::shared_ptr<XdmfGridCollection> partition(const boost::shared_ptr<XdmfGrid> gridToPartition, const unsigned int numberOfPartitions,
boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter) const;
const boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter = boost::shared_ptr<XdmfHDF5Writer>()) const;
protected:
......
This diff is collapsed.
......@@ -3,6 +3,7 @@
// Forward Declarations
class XdmfGrid;
class XdmfHDF5Writer;
class XdmfTopologyType;
// Includes
......@@ -37,10 +38,12 @@ public:
*
* @param gridToConvert the XdmfGrid to convert to a different topology
* @param topologyType the XdmfTopologyType to convert to.
* @param heavyDataWriter an XdmfHDF5Writer to write the converted mesh to. If no heavyDataWriter is specified, all mesh data will remain in memory.
*
* @return the converted XdmfGrid.
*/
boost::shared_ptr<XdmfGrid> convert(const boost::shared_ptr<XdmfGrid> gridToConvert, const boost::shared_ptr<const XdmfTopologyType> topologyType) const;
boost::shared_ptr<XdmfGrid> convert(const boost::shared_ptr<XdmfGrid> gridToConvert, const boost::shared_ptr<const XdmfTopologyType> topologyType,
const boost::shared_ptr<XdmfHDF5Writer> heavyDataWriter = boost::shared_ptr<XdmfHDF5Writer>()) const;
protected:
......
......@@ -39,6 +39,7 @@ swig -v -c++ -python -o XdmfUtilsPython.cpp XdmfUtils.i
#include <XdmfTopologyType.hpp>
// XdmfUtils Includes
#include <XdmfExodusReader.hpp>
//#include <XdmfPartitioner.hpp>
#include <XdmfTopologyConverter.hpp>
%}
......@@ -50,8 +51,10 @@ swig -v -c++ -python -o XdmfUtilsPython.cpp XdmfUtils.i
//}
// Shared Pointer Templates
%shared_ptr(XdmfExodusReader)
//%shared_ptr(XdmfPartitioner)
%shared_ptr(XdmfTopologyConverter)
%include XdmfExodusReader.hpp
//%include XdmfPartitioner.hpp
%include XdmfTopologyConverter.hpp
set(XdmfUtilsCxxTests
TestXdmfExodusReader
TestXdmfTopologyConverter
)
......
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