Commit 28e67e9a authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Add XdmfGridCollection and begin adding XdmfPartitioner.

parent e31b3ce0
# - Try to find the Metis graph partitioning library
# Once done this will define
#
# METIS_FOUND - System has metis
# METIS_INCLUDE_DIR - The metis include directory
# METIS_LIBRARIES - The libraries needed to use metis
FIND_PATH(METIS_INCLUDE_DIR NAMES metis.h)
FIND_LIBRARY(METIS_LIBRARIES NAMES metis)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Metis DEFAULT_MSG METIS_LIBRARIES METIS_INCLUDE_DIR)
MARK_AS_ADVANCED(METIS_INCLUDE_DIR METIS_LIBRARIES)
......@@ -42,6 +42,8 @@ set(XdmfSources
XdmfGeometry
XdmfGeometryType
XdmfGrid
XdmfGridCollection
XdmfGridCollectionType
XdmfHDF5Controller
XdmfHDF5Writer
XdmfItem
......@@ -70,3 +72,8 @@ if(BUILD_TESTING)
include(CTest)
add_subdirectory(tests)
endif(BUILD_TESTING)
option(BUILD_UTILS OFF)
if(BUILD_UTILS)
add_subdirectory(utils)
endif(BUILD_UTILS)
......@@ -14,6 +14,8 @@ swig -v -c++ -python -o XdmfPython.cpp Xdmf.i
#include <XdmfGeometry.hpp>
#include <XdmfGeometryType.hpp>
#include <XdmfGrid.hpp>
#include <XdmfGridCollection.hpp>
#include <XdmfGridCollectionType.hpp>
#include <XdmfHDF5Controller.hpp>
#include <XdmfHDF5Writer.hpp>
#include <XdmfItem.hpp>
......@@ -57,6 +59,7 @@ namespace boost {
%template(XdmfDomainPtr) boost::shared_ptr<XdmfDomain>;
%template(XdmfGeometryPtr) boost::shared_ptr<XdmfGeometry>;
%template(XdmfGridPtr) boost::shared_ptr<XdmfGrid>;
%template(XdmfGridCollectionPtr) boost::shared_ptr<XdmfGridCollection>;
%template(XdmfHDF5ControllerPtr) boost::shared_ptr<XdmfHDF5Controller>;
%template(XdmfHDF5WriterPtr) boost::shared_ptr<XdmfHDF5Writer>;
%template(XdmfItemPtr) boost::shared_ptr<XdmfItem>;
......@@ -91,6 +94,9 @@ SWIG_SHARED_PTR_DERIVED(XdmfGeometry, XdmfItem);
SWIG_SHARED_PTR_DERIVED(XdmfGeometry, XdmfObject);
SWIG_SHARED_PTR_DERIVED(XdmfGrid, XdmfItem);
SWIG_SHARED_PTR_DERIVED(XdmfGrid, XdmfObject);
SWIG_SHARED_PTR_DERIVED(XdmfGridCollection, XdmfGrid);
SWIG_SHARED_PTR_DERIVED(XdmfGridCollection, XdmfItem);
SWIG_SHARED_PTR_DERIVED(XdmfGridCollection, XdmfObject);
SWIG_SHARED_PTR_DERIVED(XdmfHDF5Controller, XdmfObject);
SWIG_SHARED_PTR_DERIVED(XdmfHDF5Writer, XdmfVisitor);
SWIG_SHARED_PTR_DERIVED(XdmfHDF5Writer, Loki::BaseVisitor);
......@@ -134,6 +140,9 @@ SWIG_SHARED_PTR_DERIVED(XdmfWriter, XdmfObject);
%include XdmfTopology.hpp
%include XdmfTopologyType.hpp
%include XdmfGridCollection.hpp
%include XdmfGridCollectionType.hpp
// Provide accessors from python lists to XdmfArrays
%extend XdmfArray {
void copyValueAsChar(int index, char value) {
......
......@@ -8,7 +8,6 @@ class XdmfHDF5Controller;
#include "XdmfItem.hpp"
#include <boost/shared_array.hpp>
#include <boost/variant.hpp>
#include <vector>
/**
* @brief Provides a single interface for storing a wide variety of data types.
......@@ -46,6 +45,7 @@ class XdmfHDF5Controller;
* Unsigned Int
*/
class XdmfArray : public XdmfItem {
public:
XdmfNewMacro(XdmfArray);
......
......@@ -2,7 +2,6 @@
#define XDMFATTRIBUTECENTER_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -2,7 +2,6 @@
#define XDMFATTRIBUTETYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -69,6 +69,15 @@ void XdmfDomain::populateItem(const std::map<std::string, std::string> & itemPro
}
}
void XdmfDomain::removeGrid(const unsigned int index)
{
if(index >= mGrids.size())
{
assert(false);
}
mGrids.erase(mGrids.begin() + index);
}
void XdmfDomain::traverse(boost::shared_ptr<Loki::BaseVisitor> visitor)
{
for(std::vector<boost::shared_ptr<XdmfGrid> >::const_iterator iter = mGrids.begin(); iter != mGrids.end(); ++iter)
......
......@@ -5,7 +5,6 @@
class XdmfGrid;
// Includes
#include <vector>
#include "XdmfItem.hpp"
/**
......@@ -56,6 +55,13 @@ public:
*/
void insert(boost::shared_ptr<XdmfGrid> grid);
/**
* Remove an XdmfGrid from the domain.
*
* @param index of the XdmfGrid to remove.
*/
void removeGrid(const unsigned int index);
virtual void traverse(boost::shared_ptr<Loki::BaseVisitor> visitor);
protected:
......
......@@ -5,7 +5,6 @@
* Author: kleiter
*/
#include <map>
#include "XdmfGeometryType.hpp"
// Supported XdmfGeometryTypes
......
......@@ -2,7 +2,6 @@
#define XDMFGEOMETRYTYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -140,7 +140,7 @@ void XdmfGrid::populateItem(const std::map<std::string, std::string> & itemPrope
{
mGeometry = geometry;
}
if(boost::shared_ptr<XdmfSet> set = boost::shared_dynamic_cast<XdmfSet>(*iter))
else if(boost::shared_ptr<XdmfSet> set = boost::shared_dynamic_cast<XdmfSet>(*iter))
{
this->insert(set);
}
......@@ -148,6 +148,10 @@ void XdmfGrid::populateItem(const std::map<std::string, std::string> & itemPrope
{
mTopology = topology;
}
else
{
assert(false);
}
}
}
......
......@@ -9,7 +9,6 @@ class XdmfTopology;
// Includes
#include "XdmfItem.hpp"
#include <vector>
/**
* @brief A mesh that consists of elements, points, and values attached to the mesh.
......@@ -169,6 +168,8 @@ protected:
virtual ~XdmfGrid();
virtual void populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems);
std::string mName;
private:
XdmfGrid(const XdmfGrid & grid); // Not implemented.
......@@ -178,7 +179,6 @@ private:
boost::shared_ptr<XdmfGeometry> mGeometry;
std::vector<boost::shared_ptr<XdmfSet> > mSets;
boost::shared_ptr<XdmfTopology> mTopology;
std::string mName;
};
#endif /* XDMFGRID_HPP_ */
/*
* XdmfGridCollection.cpp
*
* Created on: Jan 25, 2010
* Author: kleiter
*/
#include "XdmfGridCollection.hpp"
XdmfGridCollection::XdmfGridCollection() :
mCollectionType(XdmfGridCollectionType::NoCollectionType())
{
mName = "Collection";
std::cout << "Created Collection " << this << std::endl;
}
XdmfGridCollection::~XdmfGridCollection()
{
std::cout << "Deleted Collection " << this << std::endl;
}
std::string XdmfGridCollection::ItemTag = "Grid";
boost::shared_ptr<XdmfGrid> XdmfGridCollection::getGrid(unsigned int index)
{
if(index >= mGrids.size())
{
assert(false);
}
return mGrids[index];
}
boost::shared_ptr<const XdmfGrid> XdmfGridCollection::getGrid(unsigned int index) const
{
if(index >= mGrids.size())
{
assert(false);
}
return mGrids[index];
}
XdmfGridCollectionType XdmfGridCollection::getGridCollectionType() const
{
return mCollectionType;
}
std::map<std::string, std::string> XdmfGridCollection::getItemProperties() const
{
std::map<std::string, std::string> collectionProperties;
collectionProperties["Name"] = mName;
collectionProperties["GridType"] = "Collection";
mCollectionType.getProperties(collectionProperties);
return collectionProperties;
}
unsigned int XdmfGridCollection::getNumberOfGrids() const
{
return mGrids.size();
}
void XdmfGridCollection::insert(boost::shared_ptr<XdmfGrid> grid)
{
mGrids.push_back(grid);
}
void XdmfGridCollection::populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems)
{
for(std::vector<boost::shared_ptr<XdmfItem> >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter)
{
if(boost::shared_ptr<XdmfGrid> grid = boost::shared_dynamic_cast<XdmfGrid>(*iter))
{
this->insert(grid);
}
else
{
assert(false);
}
}
XdmfGrid::populateItem(itemProperties, childItems);
}
void XdmfGridCollection::removeGrid(const unsigned int index)
{
if(index >= mGrids.size())
{
assert(false);
}
mGrids.erase(mGrids.begin() + index);
}
void XdmfGridCollection::setGridCollectionType(const XdmfGridCollectionType & collectionType)
{
mCollectionType = collectionType;
}
void XdmfGridCollection::traverse(boost::shared_ptr<Loki::BaseVisitor> visitor)
{
for(std::vector<boost::shared_ptr<XdmfGrid> >::const_iterator iter = mGrids.begin(); iter != mGrids.end(); ++iter)
{
(*iter)->accept(visitor);
}
}
#ifndef XDMFGRIDCOLLECTION_HPP_
#define XDMFGRIDCOLLECTION_HPP_
// Includes
#include "XdmfGrid.hpp"
#include "XdmfGridCollectionType.hpp"
/**
* @brief A spatial or temporal collection of XdmfGrids.
*
* A temporal collection is timestep data. Each child grid represents the state at a single timestep.
* A spatial collection consists of XdmfGrids that are arranged together in space. E.g. a partitioned mesh.
*
* It is valid to nest collections. A spatial collection within a temporal collection is commonly used.
*/
class XdmfGridCollection : public XdmfGrid {
public:
XdmfNewMacro(XdmfGridCollection);
LOKI_DEFINE_VISITABLE(XdmfGridCollection, XdmfGrid)
static std::string ItemTag;
/**
* Get a grid from this collection.
*
* @param index of grid to retrieve.
* @return the requested XdmfGrid.
*/
boost::shared_ptr<XdmfGrid> getGrid(unsigned int index);
/**
* Get a grid from this collection (const version).
*
* @param index of the grid to retrieve.
* @return the requested XdmfGrid.
*/
boost::shared_ptr<const XdmfGrid> getGrid(unsigned int index) const;
/**
* Get the XdmfGridCollectionType associated with this grid collection.
*
* @return XdmfGridCollectionType of this collection.
*/
XdmfGridCollectionType getGridCollectionType() const;
std::map<std::string, std::string> getItemProperties() const;
/**
* Get the number of grids in this collection.
*
* @return unsigned int containing the number of XdmfGrids in this collection.
*/
unsigned int getNumberOfGrids() const;
/**
* Insert a grid into this collection.
*
* @param grid an XdmfGrid to insert into this collection.
*/
void insert(boost::shared_ptr<XdmfGrid> grid);
/**
* Remove a grid from this collection.
*
* @param index of the XdmfGrid to remove.
*/
void removeGrid(const unsigned int index);
/**
* Set the XdmfGridCollectionType associated with this grid collection.
*
* @param collectionType the XdmfGridCollectionType to set.
*/
void setGridCollectionType(const XdmfGridCollectionType & collectionType);
virtual void traverse(boost::shared_ptr<Loki::BaseVisitor> visitor);
protected:
XdmfGridCollection();
virtual ~XdmfGridCollection();
virtual void populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems);
private:
XdmfGridCollection(const XdmfGridCollection & collection); // Not implemented.
void operator=(const XdmfGridCollection & collection); // Not implemented.
XdmfGridCollectionType mCollectionType;
std::vector<boost::shared_ptr<XdmfGrid> > mGrids;
};
#endif /* XDMFGRID_HPP_ */
/*
* XdmfGridCollectionType.cpp
*
* Created on: Jan 29, 2010
* Author: kleiter
*/
#include "XdmfGridCollectionType.hpp"
// Supported XdmfGridCollectionTypes
XdmfGridCollectionType XdmfGridCollectionType::NoCollectionType()
{
return XdmfGridCollectionType("None");
}
XdmfGridCollectionType XdmfGridCollectionType::Spatial()
{
return XdmfGridCollectionType("Spatial");
}
XdmfGridCollectionType XdmfGridCollectionType::Temporal()
{
return XdmfGridCollectionType("Temporal");
}
XdmfGridCollectionType::XdmfGridCollectionType(const std::string & name) :
mName(name)
{
}
XdmfGridCollectionType::XdmfGridCollectionType(const XdmfGridCollectionType & collectionType):
mName(collectionType.mName)
{
}
XdmfGridCollectionType XdmfGridCollectionType::New(const std::map<std::string, std::string> & itemProperties)
{
std::map<std::string, std::string>::const_iterator type = itemProperties.find("CollectionType");
if(type != itemProperties.end())
{
const std::string typeVal = type->second;
if(typeVal.compare("None") == 0)
{
return NoCollectionType();
}
else if(typeVal.compare("Spatial") == 0)
{
return Spatial();
}
else if(typeVal.compare("Temporal") == 0)
{
return Temporal();
}
else
{
assert(false);
}
}
assert(false);
}
XdmfGridCollectionType & XdmfGridCollectionType::operator=(const XdmfGridCollectionType & collectionType)
{
if(this != &collectionType)
{
mName = collectionType.mName;
}
return *this;
}
bool XdmfGridCollectionType::operator==(const XdmfGridCollectionType & collectionType) const
{
return mName.compare(collectionType.mName) == 0;
}
bool XdmfGridCollectionType::operator!=(const XdmfGridCollectionType & collectionType) const
{
return !this->operator==(collectionType);
}
void XdmfGridCollectionType::getProperties(std::map<std::string, std::string> & collectedProperties) const
{
collectedProperties["CollectionType"] = mName;
}
#ifndef XDMFGRIDCOLLECTIONTYPE_HPP_
#define XDMFGRIDCOLLECTIONTYPE_HPP_
// Includes
#include "XdmfItemProperty.hpp"
/**
* @brief Property describing the type of an XdmfGridCollection.
*
* XdmfGridCollectionType is a property used by XdmfGridCollection to specify what type of collection the
* XdmfGridCollection contains. A specific XdmfGridCollectionType can be created by calling one of the static methods
* in the class, i.e. XdmfGridCollectionType::Temporal().
*
* Xdmf supports the following collection types:
* NoCollectionType
* Spatial
* Temporal
*/
class XdmfGridCollectionType : public XdmfItemProperty {
public:
friend class XdmfGridCollection;
// Supported XdmfGridCollectionTypes
static XdmfGridCollectionType NoCollectionType();
static XdmfGridCollectionType Spatial();
static XdmfGridCollectionType Temporal();
void getProperties(std::map<std::string, std::string> & collectedProperties) const;
/*
* Compare two XdmfGridCollectionTypes for equality.
*
* @param collectionType an XdmfGridCollectionType to compare equality to.
* @return true if the XdmfGridCollectionTypes are equal.
*/
bool operator==(const XdmfGridCollectionType & collectionype) const;
/**
* Compare two XdmfGridCollectionTypes for inequality.
*
* @param collectionType an XdmfGridCollectionType to compare inequality to.
* @return true if the XdmfGridCollectionTypes are not equal.
*/
bool operator!=(const XdmfGridCollectionType & collectionType) const;
XdmfGridCollectionType(const XdmfGridCollectionType & collectionType);
XdmfGridCollectionType & operator=(const XdmfGridCollectionType & collectionType);
protected:
/**
* Protected constructor for XdmfGridCollectionType. The constructor is protected because all collection types supported
* by Xdmf should be accessed through more specific static methods that construct XdmfGridCollectionType - i.e.
* XdmfGridCollectionType::Temporal().
*
* @param name the name of the XdmfGridCollectionType to construct.
*/
XdmfGridCollectionType(const std::string & name);
private:
static XdmfGridCollectionType New(const std::map<std::string, std::string> & itemProperties);
std::string mName;
};
#endif /* XDMFGRIDCOLLECTIONTYPE_HPP_ */
......@@ -3,7 +3,6 @@
#include <hdf5.h>
#include <sstream>
#include <vector>
#include "XdmfArray.hpp"
#include "XdmfHDF5Controller.hpp"
......
......@@ -5,7 +5,6 @@
class XdmfArray;
// Includes
#include <string>
#include "XdmfObject.hpp"
/**
......
......@@ -57,7 +57,7 @@ protected:
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
* Populates an item using a map of key/value property pairs and a vector of its child items. This is used to
* support generic reading of XdmfItems from disk.
*
* @param itemProperties a map of key/value properties associated with this XdmfItem.
......
......@@ -11,7 +11,6 @@
#include <libxml/xmlreader.h>
#include <map>
#include "XdmfReader.hpp"
/**
......
......@@ -9,9 +9,9 @@
* @brief Holds a collection of individual nodes, cells, faces, or edges that are part of an XdmfGrid.
*
* An XdmfSet holds a collection of nodes, cells, faces, or edges that are part of an XdmfGrid. For instance,
* a simulation may want to record a set of nodes along a boundary. The individual elements making up the
* set are determined by their id. An XdmfSet can have XdmfAttributes attached that give extra values
* attached to the components of the set.
* a simulation may want to hold a set of nodes along a boundary. The individual elements making up the
* set are determined by their id. An XdmfSet can have XdmfAttributes attached that contain extra values
* attached to the elements in the set.
*/
class XdmfSet : public XdmfDataItem {
......
......@@ -2,7 +2,6 @@
#define XDMFSETTYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
......
......@@ -2,7 +2,6 @@
#define XDMFTOPOLOGYTYPE_HPP_
// Includes
#include <string>
#include "XdmfItemProperty.hpp"
/**
* @brief Property describing the types of elements stored in an XdmfTopology.
......
option(BUILD_PARTITIONER OFF)
set(XdmfUtilsSources)
set(XdmfUtilsLibraries)
if(BUILD_PARTITIONER)
find_package(Metis REQUIRED)
if(METIS_FOUND)
include_directories(${METIS_INCLUDE_DIR})
endif(METIS_FOUND)
set(XdmfUtilsSources ${XdmfUtilsSources} XdmfPartitioner)
set(XdmfUtilsLibraries ${XdmfUtilsLibraries} ${METIS_LIBRARY})
endif(BUILD_PARTITIONER)
add_library(XdmfUtils ${XdmfUtilsSources})
target_link_libraries(XdmfUtils Xdmf)
/*******************************************************************/
/* XDMF */
/* eXtensible Data Model and Format */
/* */
/* Id : Id */
/* Date : $Date$ */
/* Version : $Revision$ */
/* */
/* Author: */
/* Kenneth Leiter */
/* kenneth.leiter@arl.army.mil */
/* US Army Research Laboratory */
/* Aberdeen Proving Ground, MD */
/* */
/* Copyright @ 2010 US Army Research Laboratory */
/* All Rights Reserved */
/* See Copyright.txt or http://www.arl.hpc.mil/ice for details */
/* */
/* This software is distributed WITHOUT ANY WARRANTY; without */
/* even the implied warranty of MERCHANTABILITY or FITNESS */
/* FOR A PARTICULAR PURPOSE. See the above copyright notice */
/* for more information. */
/* */
/*******************************************************************/
#include "XdmfPartitioner.hpp"
#ifndef BUILD_EXE
extern "C"
{
#include <metis.h>
}
#include "XdmfGrid.hpp"
XdmfPartitioner::XdmfPartitioner()
{
}
XdmfPartitioner::~XdmfPartitioner()
{
}
boost::shared_ptr<XdmfGrid> XdmfPartitioner::partition(boost::shared_ptr<XdmfGrid> gridToPartition, const unsigned int numberOfPartitions)
{
/*int metisElementType;
int numNodesPerElement;
switch(grid->GetTopology()->GetTopologyType())
{
case(XDMF_TRI):
case(XDMF_TRI_6):
metisElementType = 1;
numNodesPerElement = 3;
break;
case(XDMF_QUAD):
case(XDMF_QUAD_8):
metisElementType = 4;
numNodesPerElement = 4;
break;
case(XDMF_TET):
case(XDMF_TET_10):
metisElementType = 2;
numNodesPerElement = 4;
break;
case(XDMF_HEX):
case(XDMF_HEX_20):
case(XDMF_HEX_24):
case(XDMF_HEX_27):
case(XDMF_HEX_64):
metisElementType = 3;
numNodesPerElement = 8;
break;
default:
std::cout << "Cannot partition grid with element type: " << grid->GetTopology()->GetTopologyTypeAsString() << std::endl;
return NULL;
}
int numElements = grid->GetTopology()->GetNumberOfElements();
idxtype * metisConnectivity = new idxtype[numNodesPerElement * numElements];
for(int i=0; i<numElements; ++i)
{
grid->GetTopology()->GetConnectivity()->GetValues(i*grid->GetTopology()->GetNodesPerElement(), &metisConnectivity[i*numNodesPerElement], numNodesPerElement);
}
int numNodes = grid->GetGeometry()->GetNumberOfPoints();
// Need to remap connectivity for nonlinear elements so that metis handles it properly
std::map<idxtype, idxtype> xdmfIdToMetisId;
if(numNodesPerElement != grid->GetTopology()->GetNodesPerElement())
{
int index = 0;
for(int i=0; i<numElements * numNodesPerElement; ++i)
{
std::map<idxtype, idxtype>::const_iterator val = xdmfIdToMetisId.find(metisConnectivity[i]);
if(val != xdmfIdToMetisId.end())
{
metisConnectivity[i] = val->second;
}
else
{
// Haven't seen this id before, map to index and set to new id
xdmfIdToMetisId[metisConnectivity[i]] = index;
metisConnectivity[i] = index;
index++;
}
}
numNodes = index;
}