Commit 86eefce2 authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Allow arbitrary elements to be partitioned by metis.

The new version of metis uses a different format to supply connectivity
information to the partitioning algorithm. The new format allows generic
element types to be passed (as well as mixed topology formats). These changes
expand the number of element types we can partition in metis (this was tested
on high-order hexahedron, linear hexahedron, and polyline topologies)
parent 6afc622c
......@@ -91,40 +91,7 @@ XdmfPartitioner::partition(const shared_ptr<XdmfUnstructuredGrid> gridToPartitio
const shared_ptr<const XdmfTopologyType> topologyType =
topology->getType();
unsigned int nodesPerElement = 0;
if(topologyType == XdmfTopologyType::Triangle() ||
topologyType == XdmfTopologyType::Triangle_6()) {
nodesPerElement = 3;
}
else if(topologyType == XdmfTopologyType::Quadrilateral() ||
topologyType == XdmfTopologyType::Quadrilateral_8()) {
nodesPerElement = 4;
}
else if(topologyType == XdmfTopologyType::Tetrahedron() ||
topologyType == XdmfTopologyType::Tetrahedron_10()) {
nodesPerElement = 4;
}
else if(topologyType == XdmfTopologyType::Hexahedron() ||
topologyType == XdmfTopologyType::Hexahedron_20() ||
topologyType == XdmfTopologyType::Hexahedron_24() ||
topologyType == XdmfTopologyType::Hexahedron_27() ||
topologyType == XdmfTopologyType::Hexahedron_64() ||
topologyType == XdmfTopologyType::Hexahedron_125() ||
topologyType == XdmfTopologyType::Hexahedron_216() ||
topologyType == XdmfTopologyType::Hexahedron_343() ||
topologyType == XdmfTopologyType::Hexahedron_512() ||
topologyType == XdmfTopologyType::Hexahedron_729() ||
topologyType == XdmfTopologyType::Hexahedron_1000() ||
topologyType == XdmfTopologyType::Hexahedron_1331()) {
nodesPerElement = 8;
}
else {
XdmfError::message(XdmfError::FATAL,
"Topology type is not 'Triangle', 'Quadrilateral', "
"'Tetrahedron', 'Hexahedron' in "
"XdmfPartition::partition");
}
const unsigned int nodesPerElement = topologyType->getNodesPerElement();
bool releaseTopology = false;
if(!topology->isInitialized()) {
......@@ -133,6 +100,7 @@ XdmfPartitioner::partition(const shared_ptr<XdmfUnstructuredGrid> gridToPartitio
}
int numElements = topology->getNumberElements();
int numNodes = geometry->getNumberPoints();
// allocate metisConnectivity arrays
idx_t * metisConnectivityEptr = new idx_t[numElements + 1];
......@@ -153,29 +121,6 @@ XdmfPartitioner::partition(const shared_ptr<XdmfUnstructuredGrid> gridToPartitio
metisConnectivityPtr += nodesPerElement;
}
int numNodes = geometry->getNumberPoints();
// Need to remap connectivity for nonlinear elements so that metis handles
// it properly.
std::map<idx_t, idx_t> xdmfIdToMetisId;
if(nodesPerElement != topologyType->getNodesPerElement()) {
unsigned int index = 0;
for (unsigned int i=0; i<numElements * nodesPerElement; ++i) {
std::map<idx_t, idx_t>::const_iterator val =
xdmfIdToMetisId.find(metisConnectivityEind[i]);
if (val != xdmfIdToMetisId.end()) {
metisConnectivityEind[i] = val->second;
}
else {
// Haven't seen this id before, map to index and set to new id
xdmfIdToMetisId[metisConnectivityEind[i]] = index;
metisConnectivityEind[i] = index;
index++;
}
}
numNodes = index;
}
idx_t * vwgt = NULL; // equal weight
idx_t * vsize = NULL; // equal size
idx_t ncommon = 1; // FIXME
......@@ -218,7 +163,7 @@ XdmfPartitioner::partition(const shared_ptr<XdmfUnstructuredGrid> gridToPartitio
}
else {
XdmfError::message(XdmfError::FATAL,
"Invalid metis partitioning scheme selected in"
"Invalid metis partitioning scheme selected in "
"XdmfPartitioner::partition");
}
......@@ -676,10 +621,10 @@ namespace {
int main(int argc, char* argv[])
{
std::string inputFileName;
std::string inputFileName = "";
std::string outputFileName = "";
unsigned int numPartitions;
XdmfPartitioner::MetisScheme metisScheme;
XdmfPartitioner::MetisScheme metisScheme = XdmfPartitioner::DUAL_GRAPH;
processCommandLine(inputFileName,
outputFileName,
......
......@@ -60,7 +60,7 @@ public:
virtual ~XdmfPartitioner();
/**
* Ingore set when partitioning. Set is not partitioned or added to
* Ignore set when partitioning. Set is not partitioned or added to
* resulting grid.
*
* @param set the set to ignore when partitioning.
......@@ -68,27 +68,15 @@ public:
void ignore(const shared_ptr<const XdmfSet> set);
/**
* Partitions an XdmfGrid using the metis library.
* Currently supported topology types are:
*
* XdmfTopologyType::Triangle
* XdmfTopologyType::Triangle_6
* XdmfTopologyType::Quadrilateral
* XdmfTopologyType::Quadrilateral_8
* XdmfTopologyType::Tetrahedron
* XdmfTopologyType::Tetrahedron_10
* XdmfTopologyType::Hexahedron
* XdmfTopologyType::Hexahedron_20
* XdmfTopologyType::Hexahedron_24
* XdmfTopologyType::Hexahedron_27
* XdmfTopologyType::Hexahedron_64
* Partitions an XdmfUnstructuredGrid using the metis library.
*
* The partitioner splits the XdmfGridUnstructured and all attached
* XdmfAttributes and XdmfSets into their proper partition. An
* XdmfAttribute named "GlobalNodeId" is added to each partitioned
* grid to map partitioned node ids to their original unpartitioned
* id. All arrays attached to the passed gridToPartition are read
* from disk if not initialized.
* id. An XdmfMap is added to each partitioned grid mapping shared
* nodes to other processors. All arrays attached to the passed
* gridToPartition are read from disk if not initialized.
*
* @param gridToPartition an XdmfGridUnstructured to partition.
* @param numberOfPartitions the number of pieces to partition the grid into.
......
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