Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
Nektar::LibUtilities::MeshPartition Class Referenceabstract

#include <MeshPartition.h>

Inheritance diagram for Nektar::LibUtilities::MeshPartition:
Inheritance graph
[legend]
Collaboration diagram for Nektar::LibUtilities::MeshPartition:
Collaboration graph
[legend]

Classes

struct  GraphEdgeProperties
 
struct  GraphVertexProperties
 
struct  MeshComposite
 
struct  MeshCurved
 
struct  MeshElement
 
struct  MeshEntity
 
struct  MeshFace
 

Public Member Functions

 MeshPartition (const SessionReaderSharedPtr &pSession)
 
virtual ~MeshPartition ()
 
void PartitionMesh (int nParts, bool shared=false, bool overlapping=false)
 
void WriteLocalPartition (SessionReaderSharedPtr &pSession)
 
void WriteAllPartitions (SessionReaderSharedPtr &pSession)
 
void PrintPartInfo (std::ostream &out)
 
void GetCompositeOrdering (CompositeOrdering &composites)
 
void GetBndRegionOrdering (BndRegionOrdering &composites)
 
void GetElementIDs (const int procid, std::vector< unsigned int > &tmp)
 

Private Types

typedef std::pair< std::string,
int > 
MeshCurvedKey
 
typedef std::vector< unsigned int > MultiWeight
 
typedef boost::adjacency_list
< boost::setS, boost::vecS,
boost::undirectedS,
GraphVertexProperties,
boost::property
< boost::edge_index_t,
unsigned int,
GraphEdgeProperties > > 
BoostGraph
 
typedef boost::subgraph
< BoostGraph
BoostSubGraph
 
typedef boost::graph_traits
< BoostGraph >
::vertex_descriptor 
BoostVertex
 
typedef boost::graph_traits
< BoostGraph >
::edge_descriptor 
BoostEdge
 
typedef boost::graph_traits
< BoostGraph >::edge_iterator 
BoostEdgeIterator
 
typedef boost::graph_traits
< BoostGraph >
::vertex_iterator 
BoostVertexIterator
 
typedef boost::graph_traits
< BoostGraph >
::adjacency_iterator 
BoostAdjacencyIterator
 
typedef std::vector< unsigned int > NumModes
 
typedef std::map< std::string,
NumModes
NummodesPerField
 

Private Member Functions

void ReadExpansions (const SessionReaderSharedPtr &pSession)
 
void ReadGeometry (const SessionReaderSharedPtr &pSession)
 
void ReadConditions (const SessionReaderSharedPtr &pSession)
 
void WeightElements ()
 
void CreateGraph (BoostSubGraph &pGraph)
 
void PartitionGraph (BoostSubGraph &pGraph, int nParts, std::vector< BoostSubGraph > &pLocalPartition, bool overlapping=false)
 Partition the graph. More...
 
virtual void PartitionGraphImpl (int &nVerts, int &nVertConds, Nektar::Array< Nektar::OneD, int > &xadj, Nektar::Array< Nektar::OneD, int > &adjcy, Nektar::Array< Nektar::OneD, int > &vertWgt, Nektar::Array< Nektar::OneD, int > &vertSize, int &nparts, int &volume, Nektar::Array< Nektar::OneD, int > &part)=0
 
void OutputPartition (SessionReaderSharedPtr &pSession, BoostSubGraph &pGraph, TiXmlElement *pGeometry)
 
void CheckPartitions (int nParts, Array< OneD, int > &pPart)
 
int CalculateElementWeight (char elmtType, bool bndWeight, int na, int nb, int nc)
 

Private Attributes

bool m_isCompressed
 
int m_dim
 
int m_numFields
 
std::map< int, MeshVertexm_meshVertices
 
std::map< int, MeshEntitym_meshEdges
 
std::map< int, MeshEntitym_meshFaces
 
std::map< int, MeshEntitym_meshElements
 
std::map< MeshCurvedKey,
MeshCurved
m_meshCurved
 
std::map< int, MeshCurvedPtsm_meshCurvedPts
 
std::map< int, MeshEntitym_meshComposites
 
std::vector< unsigned int > m_domain
 
std::map< std::string,
std::string > 
m_vertexAttributes
 
std::map< int, NummodesPerFieldm_expansions
 
std::map< std::string, int > m_fieldNameToId
 
std::map< int, MultiWeightm_vertWeights
 
BndRegionOrdering m_bndRegOrder
 
BoostSubGraph m_mesh
 
std::vector< BoostSubGraphm_localPartition
 
CommSharedPtr m_comm
 
bool m_weightingRequired
 
bool m_shared
 

Detailed Description

Definition at line 62 of file MeshPartition.h.

Member Typedef Documentation

typedef boost::graph_traits< BoostGraph >::adjacency_iterator Nektar::LibUtilities::MeshPartition::BoostAdjacencyIterator
private

Definition at line 174 of file MeshPartition.h.

typedef boost::graph_traits< BoostGraph >::edge_descriptor Nektar::LibUtilities::MeshPartition::BoostEdge
private

Definition at line 165 of file MeshPartition.h.

typedef boost::graph_traits< BoostGraph >::edge_iterator Nektar::LibUtilities::MeshPartition::BoostEdgeIterator
private

Definition at line 168 of file MeshPartition.h.

typedef boost::adjacency_list< boost::setS, boost::vecS, boost::undirectedS, GraphVertexProperties, boost::property< boost::edge_index_t, unsigned int, GraphEdgeProperties > > Nektar::LibUtilities::MeshPartition::BoostGraph
private

Definition at line 155 of file MeshPartition.h.

Definition at line 158 of file MeshPartition.h.

typedef boost::graph_traits< BoostGraph >::vertex_descriptor Nektar::LibUtilities::MeshPartition::BoostVertex
private

Definition at line 162 of file MeshPartition.h.

typedef boost::graph_traits< BoostGraph >::vertex_iterator Nektar::LibUtilities::MeshPartition::BoostVertexIterator
private

Definition at line 171 of file MeshPartition.h.

typedef std::pair<std::string, int> Nektar::LibUtilities::MeshPartition::MeshCurvedKey
private

Definition at line 125 of file MeshPartition.h.

typedef std::vector<unsigned int> Nektar::LibUtilities::MeshPartition::MultiWeight
private

Definition at line 126 of file MeshPartition.h.

typedef std::vector<unsigned int> Nektar::LibUtilities::MeshPartition::NumModes
private

Definition at line 176 of file MeshPartition.h.

typedef std::map<std::string, NumModes> Nektar::LibUtilities::MeshPartition::NummodesPerField
private

Definition at line 177 of file MeshPartition.h.

Constructor & Destructor Documentation

Nektar::LibUtilities::MeshPartition::MeshPartition ( const SessionReaderSharedPtr pSession)

Definition at line 78 of file MeshPartition.cpp.

References ReadConditions(), ReadExpansions(), and ReadGeometry().

78  :
79  m_isCompressed(false),
80  m_numFields(0),
82  m_comm(pSession->GetComm()),
83  m_weightingRequired(false)
84  {
85  ReadConditions(pSession);
86  ReadGeometry(pSession);
87  ReadExpansions(pSession);
88  }
void ReadConditions(const SessionReaderSharedPtr &pSession)
std::map< std::string, int > m_fieldNameToId
void ReadExpansions(const SessionReaderSharedPtr &pSession)
void ReadGeometry(const SessionReaderSharedPtr &pSession)
Nektar::LibUtilities::MeshPartition::~MeshPartition ( )
virtual

Definition at line 90 of file MeshPartition.cpp.

91  {
92 
93  }

Member Function Documentation

int Nektar::LibUtilities::MeshPartition::CalculateElementWeight ( char  elmtType,
bool  bndWeight,
int  na,
int  nb,
int  nc 
)
private

Definition at line 2171 of file MeshPartition.cpp.

References Nektar::LibUtilities::StdSegData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdTriData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdQuadData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdHexData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdTetData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdPyrData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdPrismData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdSegData::getNumberOfCoefficients(), Nektar::LibUtilities::StdTriData::getNumberOfCoefficients(), Nektar::LibUtilities::StdQuadData::getNumberOfCoefficients(), Nektar::LibUtilities::StdHexData::getNumberOfCoefficients(), Nektar::LibUtilities::StdTetData::getNumberOfCoefficients(), Nektar::LibUtilities::StdPyrData::getNumberOfCoefficients(), and Nektar::LibUtilities::StdPrismData::getNumberOfCoefficients().

Referenced by PrintPartInfo(), and WeightElements().

2177  {
2178  int weight = 0;
2179 
2180  switch (elmtType)
2181  {
2182  case 'A':
2183  weight = bndWeight ?
2185  StdTetData ::getNumberOfCoefficients (na, nb, nc);
2186  break;
2187  case 'R':
2188  weight = bndWeight ?
2190  StdPrismData::getNumberOfCoefficients (na, nb, nc);
2191  break;
2192  case 'H':
2193  weight = bndWeight ?
2195  StdHexData ::getNumberOfCoefficients (na, nb, nc);
2196  break;
2197  case 'P':
2198  weight = bndWeight ?
2200  StdPyrData ::getNumberOfCoefficients (na, nb, nc);
2201  break;
2202  case 'Q':
2203  weight = bndWeight ?
2205  StdQuadData ::getNumberOfCoefficients (na, nb);
2206  break;
2207  case 'T':
2208  weight = bndWeight ?
2210  StdTriData ::getNumberOfCoefficients (na, nb);
2211  break;
2212  case 'S':
2213  weight = bndWeight ?
2215  StdSegData ::getNumberOfCoefficients (na);
2216  break;
2217  case 'V':
2218  weight = 1;
2219  break;
2220  default:
2221  break;
2222  }
2223 
2224  return weight;
2225  }
int getNumberOfBndCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:120
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:159
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:266
int getNumberOfBndCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:139
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:297
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:209
void Nektar::LibUtilities::MeshPartition::CheckPartitions ( int  nParts,
Array< OneD, int > &  pPart 
)
private

Definition at line 1298 of file MeshPartition.cpp.

Referenced by PartitionGraph().

1299  {
1300  unsigned int i = 0;
1301  unsigned int cnt = 0;
1302  bool valid = true;
1303 
1304  // Check that every process has at least one element assigned
1305  for (i = 0; i < nParts; ++i)
1306  {
1307  cnt = std::count(pPart.begin(), pPart.end(), i);
1308  if (cnt == 0)
1309  {
1310  valid = false;
1311  }
1312  }
1313 
1314  // If METIS produced an invalid partition, repartition naively.
1315  // Elements are assigned to processes in a round-robin fashion.
1316  // It is assumed that METIS failure only occurs when the number of
1317  // elements is approx. the number of processes, so this approach
1318  // should not be too inefficient communication-wise.
1319  if (!valid)
1320  {
1321  for (i = 0; i < pPart.num_elements(); ++i)
1322  {
1323  pPart[i] = i % nParts;
1324  }
1325  }
1326  }
void Nektar::LibUtilities::MeshPartition::CreateGraph ( BoostSubGraph pGraph)
private

Definition at line 1103 of file MeshPartition.cpp.

References Nektar::iterator, m_meshElements, m_vertWeights, and m_weightingRequired.

Referenced by PartitionMesh().

1104  {
1105  // Maps edge/face to first mesh element id.
1106  // On locating second mesh element id, graph edge is created instead.
1107  std::map<int, int> vGraphEdges;
1109  int vcnt = 0;
1110 
1111  for (eIt = m_meshElements.begin(); eIt != m_meshElements.end();
1112  ++eIt, ++vcnt)
1113  {
1114  BoostVertex v = boost::add_vertex(pGraph);
1115  pGraph[v].id = eIt->first;
1116  pGraph[v].partition = 0;
1117 
1118  if (m_weightingRequired)
1119  {
1120  pGraph[v].weight = m_vertWeights[eIt->first];
1121  }
1122 
1123  // Process element entries and add graph edges
1124  for (unsigned j = 0; j < eIt->second.list.size(); ++j)
1125  {
1126  int eId = eIt->second.list[j];
1127 
1128  // Look to see if we've examined this edge/face before
1129  // If so, we've got both graph vertices so add edge
1130  if (vGraphEdges.find(eId) != vGraphEdges.end())
1131  {
1132  BoostEdge e = boost::add_edge(vcnt, vGraphEdges[eId], pGraph).first;
1133  pGraph[e].id = vcnt;
1134  }
1135  else
1136  {
1137  vGraphEdges[eId] = vcnt;
1138  }
1139  }
1140  }
1141  }
boost::graph_traits< BoostGraph >::vertex_descriptor BoostVertex
std::map< int, MultiWeight > m_vertWeights
std::map< int, MeshEntity > m_meshElements
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::graph_traits< BoostGraph >::edge_descriptor BoostEdge
void Nektar::LibUtilities::MeshPartition::GetBndRegionOrdering ( BndRegionOrdering composites)

Definition at line 183 of file MeshPartition.cpp.

References m_bndRegOrder.

184  {
185  bndRegs = m_bndRegOrder;
186  }
void Nektar::LibUtilities::MeshPartition::GetCompositeOrdering ( CompositeOrdering composites)

Definition at line 173 of file MeshPartition.cpp.

References Nektar::iterator, and m_meshComposites.

174  {
176  for (it = m_meshComposites.begin();
177  it != m_meshComposites.end(); ++it)
178  {
179  composites[it->first] = it->second.list;
180  }
181  }
std::map< int, MeshEntity > m_meshComposites
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
void Nektar::LibUtilities::MeshPartition::GetElementIDs ( const int  procid,
std::vector< unsigned int > &  tmp 
)

Definition at line 2156 of file MeshPartition.cpp.

References ASSERTL0, m_localPartition, and m_meshElements.

2157  {
2158  BoostVertexIterator vertit, vertit_end;
2159 
2160  ASSERTL0(procid < m_localPartition.size(),"procid is less than the number of partitions");
2161 
2162  // Populate lists of elements, edges and vertices required.
2163  for ( boost::tie(vertit, vertit_end) = boost::vertices(m_localPartition[procid]);
2164  vertit != vertit_end;
2165  ++vertit)
2166  {
2167  elmtid.push_back(m_meshElements[m_localPartition[procid][*vertit].id].id);
2168  }
2169  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
std::map< int, MeshEntity > m_meshElements
std::vector< BoostSubGraph > m_localPartition
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
void Nektar::LibUtilities::MeshPartition::OutputPartition ( LibUtilities::SessionReaderSharedPtr pSession,
BoostSubGraph pGraph,
TiXmlElement *  pGeometry 
)
private

Definition at line 1329 of file MeshPartition.cpp.

References ASSERTL0, Nektar::LibUtilities::MeshPartition::MeshCurved::data, Nektar::LibUtilities::MeshTri::e, Nektar::LibUtilities::MeshQuad::e, Nektar::LibUtilities::MeshCurvedInfo::entityid, Nektar::LibUtilities::MeshPartition::MeshCurved::entityid, Nektar::LibUtilities::MeshPartition::MeshCurved::entitytype, Nektar::LibUtilities::MeshTet::f, Nektar::LibUtilities::MeshPyr::f, Nektar::LibUtilities::MeshPrism::f, Nektar::LibUtilities::MeshHex::f, Nektar::ParseUtils::GenerateSeqString(), Nektar::ParseUtils::GenerateSeqVector(), Nektar::LibUtilities::CompressData::GetBitSizeStr(), Nektar::LibUtilities::CompressData::GetCompressString(), Nektar::LibUtilities::MeshVertex::id, Nektar::LibUtilities::MeshEdge::id, Nektar::LibUtilities::MeshTri::id, Nektar::LibUtilities::MeshQuad::id, Nektar::LibUtilities::MeshTet::id, Nektar::LibUtilities::MeshPyr::id, Nektar::LibUtilities::MeshPrism::id, Nektar::LibUtilities::MeshHex::id, Nektar::LibUtilities::MeshPartition::MeshCurved::id, Nektar::LibUtilities::MeshCurvedInfo::id, Nektar::LibUtilities::MeshCurvedPts::id, Nektar::LibUtilities::MeshCurvedPts::index, Nektar::iterator, Nektar::LibUtilities::kPointsTypeStr, m_bndRegOrder, m_dim, m_domain, m_isCompressed, m_meshComposites, m_meshCurved, m_meshCurvedPts, m_meshEdges, m_meshElements, m_meshFaces, m_meshVertices, m_vertexAttributes, Nektar::LibUtilities::MeshCurvedInfo::npoints, Nektar::LibUtilities::MeshPartition::MeshCurved::npoints, Nektar::LibUtilities::MeshCurvedInfo::ptid, Nektar::LibUtilities::MeshPartition::MeshCurved::ptid, Nektar::LibUtilities::MeshCurvedInfo::ptoffset, Nektar::LibUtilities::MeshPartition::MeshCurved::ptoffset, Nektar::LibUtilities::MeshCurvedPts::pts, Nektar::LibUtilities::MeshCurvedInfo::ptype, Nektar::LibUtilities::SIZE_PointsType, Nektar::LibUtilities::MeshPartition::MeshCurved::type, Nektar::LibUtilities::MeshEdge::v0, Nektar::LibUtilities::MeshEdge::v1, Nektar::LibUtilities::MeshVertex::x, Nektar::LibUtilities::MeshVertex::y, Nektar::LibUtilities::MeshVertex::z, and Nektar::LibUtilities::CompressData::ZlibEncodeToBase64Str().

Referenced by WriteAllPartitions(), and WriteLocalPartition().

1333  {
1334  // Write Geometry data
1335  std::string vDim = pSession->GetElement("Nektar/Geometry")->Attribute("DIM");
1336  std::string vSpace = pSession->GetElement("Nektar/Geometry")->Attribute("SPACE");
1337  std::string vPart = boost::lexical_cast<std::string>(pGraph[*boost::vertices(pGraph).first].partition);
1338  TiXmlElement* vElmtGeometry = new TiXmlElement("GEOMETRY");
1339  vElmtGeometry->SetAttribute("DIM", vDim);
1340  vElmtGeometry->SetAttribute("SPACE", vSpace);
1341  vElmtGeometry->SetAttribute("PARTITION", vPart);
1342 
1343  TiXmlElement *vVertex = new TiXmlElement("VERTEX");
1344  TiXmlElement *vEdge = new TiXmlElement("EDGE");
1345  TiXmlElement *vFace = new TiXmlElement("FACE");
1346  TiXmlElement *vElement = new TiXmlElement("ELEMENT");
1347  TiXmlElement *vCurved = new TiXmlElement("CURVED");
1348  TiXmlElement *vComposite = new TiXmlElement("COMPOSITE");
1349  TiXmlElement *vDomain = new TiXmlElement("DOMAIN");
1350 
1351  TiXmlElement *x;
1352  TiXmlText *y;
1353 
1354  BoostVertexIterator vertit, vertit_end;
1355  int id;
1356 
1357  std::map<int, MeshEntity> vComposites;
1358  std::map<int, MeshEntity> vElements;
1359  std::map<int, MeshEntity> vEdges;
1360  std::map<int, MeshEntity> vFaces;
1361  std::map<int, MeshVertex> vVertices;
1365 
1366  std::vector<unsigned int> idxList;
1367 
1368  // Populate lists of elements, edges and vertices required.
1369  for (boost::tie(vertit, vertit_end) = boost::vertices(pGraph);
1370  vertit != vertit_end;
1371  ++vertit)
1372  {
1373  id = pGraph[*vertit].id;
1374  vElements[id] = m_meshElements[pGraph[*vertit].id];
1375  }
1376 
1377  std::map<int, MeshEntity> * vNext = &vElements;
1378  switch (m_dim)
1379  {
1380  case 3:
1381  {
1382  // Compile list of faces
1383  for (vIt = vNext->begin(); vIt != vNext->end(); vIt++)
1384  {
1385  for (unsigned int j = 0; j < vIt->second.list.size(); ++j)
1386  {
1387  id = vIt->second.list[j];
1388  vFaces[id] = m_meshFaces[id];
1389  }
1390  }
1391  vNext = &vFaces;
1392  }
1393  case 2:
1394  {
1395  // Compile list of edges
1396  for (vIt = vNext->begin(); vIt != vNext->end(); vIt++)
1397  {
1398  for (unsigned int j = 0; j < vIt->second.list.size(); ++j)
1399  {
1400  id = vIt->second.list[j];
1401  vEdges[id] = m_meshEdges[id];
1402  }
1403  }
1404  vNext = &vEdges;
1405  }
1406  case 1:
1407  {
1408  // Compile list of vertices
1409  for (vIt = vNext->begin(); vIt != vNext->end(); vIt++)
1410  {
1411  for (unsigned int j = 0; j < vIt->second.list.size(); ++j)
1412  {
1413  id = vIt->second.list[j];
1414  vVertices[id] = m_meshVertices[id];
1415  }
1416  }
1417  }
1418  }
1419 
1420  // Generate XML data for these mesh entities
1421  if(m_isCompressed)
1422  {
1423  std::vector<MeshVertex> vertInfo;
1424  for (vVertIt = vVertices.begin();
1425  vVertIt != vVertices.end(); vVertIt++)
1426  {
1427  MeshVertex v;
1428  v.id = vVertIt->first;
1429  v.x = vVertIt->second.x;
1430  v.y = vVertIt->second.y;
1431  v.z = vVertIt->second.z;
1432  vertInfo.push_back(v);
1433  }
1434  std::string vertStr;
1435  CompressData::ZlibEncodeToBase64Str(vertInfo,vertStr);
1436  vVertex->SetAttribute("COMPRESSED",
1438  vVertex->SetAttribute("BITSIZE",
1440  vVertex->LinkEndChild(new TiXmlText(vertStr));
1441  }
1442  else
1443  {
1444  for (vVertIt = vVertices.begin(); vVertIt != vVertices.end(); vVertIt++)
1445  {
1446  x = new TiXmlElement("V");
1447  x->SetAttribute("ID", vVertIt->first);
1448  std::stringstream vCoords;
1449  vCoords.precision(12);
1450  vCoords << std::setw(15) << vVertIt->second.x << " "
1451  << std::setw(15) << vVertIt->second.y << " "
1452  << std::setw(15) << vVertIt->second.z << " ";
1453  y = new TiXmlText(vCoords.str());
1454  x->LinkEndChild(y);
1455  vVertex->LinkEndChild(x);
1456  }
1457  }
1458 
1459  // Apply transformation attributes to VERTEX section
1460  for (vAttrIt = m_vertexAttributes.begin();
1461  vAttrIt != m_vertexAttributes.end();
1462  ++ vAttrIt)
1463  {
1464  vVertex->SetAttribute(vAttrIt->first, vAttrIt->second);
1465  }
1466 
1467  if (m_dim >= 2)
1468  {
1469  if(m_isCompressed)
1470  {
1471  std::vector<MeshEdge> edgeInfo;
1472  for (vIt = vEdges.begin(); vIt != vEdges.end(); vIt++)
1473  {
1474  MeshEdge e;
1475  e.id = vIt->first;
1476  e.v0 = vIt->second.list[0];
1477  e.v1 = vIt->second.list[1];
1478  edgeInfo.push_back(e);
1479  }
1480  std::string edgeStr;
1481  CompressData::ZlibEncodeToBase64Str(edgeInfo,edgeStr);
1482  vEdge->SetAttribute("COMPRESSED",
1484  vEdge->SetAttribute("BITSIZE",
1486  vEdge->LinkEndChild(new TiXmlText(edgeStr));
1487  }
1488  else
1489  {
1490  for (vIt = vEdges.begin(); vIt != vEdges.end(); vIt++)
1491  {
1492  x = new TiXmlElement("E");
1493  x->SetAttribute("ID", vIt->first);
1494  std::stringstream vVertices;
1495  vVertices << std::setw(10) << vIt->second.list[0]
1496  << std::setw(10) << vIt->second.list[1]
1497  << " ";
1498  y = new TiXmlText(vVertices.str());
1499  x->LinkEndChild(y);
1500  vEdge->LinkEndChild(x);
1501  }
1502  }
1503  }
1504 
1505  if (m_dim >= 3)
1506  {
1507 
1508  if(m_isCompressed)
1509  {
1510  std::vector<MeshTri> TriFaceInfo;
1511  std::vector<MeshQuad> QuadFaceInfo;
1512 
1513  for (vIt = vFaces.begin(); vIt != vFaces.end(); vIt++)
1514  {
1515  switch(vIt->second.list.size())
1516  {
1517  case 3:
1518  {
1519  MeshTri f;
1520  f.id = vIt->first;
1521  for(int i = 0; i < 3; ++i)
1522  {
1523  f.e[i] = vIt->second.list[i];
1524  }
1525  TriFaceInfo.push_back(f);
1526  }
1527  break;
1528  case 4:
1529  {
1530  MeshQuad f;
1531  f.id = vIt->first;
1532  for(int i = 0; i < 4; ++i)
1533  {
1534  f.e[i] = vIt->second.list[i];
1535  }
1536  QuadFaceInfo.push_back(f);
1537  }
1538  break;
1539  default:
1540  ASSERTL0(false,"Unknown face type.");
1541  }
1542  }
1543 
1544  if(TriFaceInfo.size())
1545  {
1546  std::string vType("T");
1547  x = new TiXmlElement(vType);
1548 
1549  std::string faceStr;
1551  faceStr);
1552  x->SetAttribute("COMPRESSED",
1554  x->SetAttribute("BITSIZE",
1556  x->LinkEndChild(new TiXmlText(faceStr));
1557  vFace->LinkEndChild(x);
1558  }
1559 
1560  if(QuadFaceInfo.size())
1561  {
1562  std::string vType("Q");
1563  x = new TiXmlElement(vType);
1564  std::string faceStr;
1566  faceStr);
1567  x->SetAttribute("COMPRESSED",
1569  x->SetAttribute("BITSIZE",
1571  x->LinkEndChild(new TiXmlText(faceStr));
1572  vFace->LinkEndChild(x);
1573  }
1574  }
1575  else
1576  {
1577  for (vIt = vFaces.begin(); vIt != vFaces.end(); vIt++)
1578  {
1579  std::string vType("F");
1580  vType[0] = vIt->second.type;
1581  x = new TiXmlElement(vType);
1582  x->SetAttribute("ID", vIt->first);
1583  std::stringstream vListStr;
1584  for (unsigned int i = 0; i < vIt->second.list.size(); ++i)
1585  {
1586  vListStr << std::setw(10) << vIt->second.list[i];
1587  }
1588  vListStr << " ";
1589  y = new TiXmlText(vListStr.str());
1590  x->LinkEndChild(y);
1591  vFace->LinkEndChild(x);
1592  }
1593  }
1594  }
1595 
1596 
1597  if(m_isCompressed)
1598  {
1599  std::vector<MeshEdge> SegInfo;
1600  std::vector<MeshTri> TriInfo;
1601  std::vector<MeshQuad> QuadInfo;
1602  std::vector<MeshTet> TetInfo;
1603  std::vector<MeshPyr> PyrInfo;
1604  std::vector<MeshPrism> PrismInfo;
1605  std::vector<MeshHex> HexInfo;
1606 
1607  //gather elemements in groups.
1608  for (vIt = vElements.begin(); vIt != vElements.end(); vIt++)
1609  {
1610  switch(vIt->second.type)
1611  {
1612  case 'S':
1613  {
1614  MeshEdge e;
1615  e.id = vIt->first;
1616  e.v0 = vIt->second.list[0];
1617  e.v1 = vIt->second.list[1];
1618  SegInfo.push_back(e);
1619  }
1620  break;
1621  case 'T':
1622  {
1623  MeshTri f;
1624  f.id = vIt->first;
1625  for(int i = 0; i < 3; ++i)
1626  {
1627  f.e[i] = vIt->second.list[i];
1628  }
1629  TriInfo.push_back(f);
1630  }
1631  break;
1632  case 'Q':
1633  {
1634  MeshQuad f;
1635  f.id = vIt->first;
1636  for(int i = 0; i < 4; ++i)
1637  {
1638  f.e[i] = vIt->second.list[i];
1639  }
1640  QuadInfo.push_back(f);
1641  }
1642  break;
1643  case 'A':
1644  {
1645  MeshTet vol;
1646  vol.id = vIt->first;
1647  for(int i = 0; i < 4; ++i)
1648  {
1649  vol.f[i] = vIt->second.list[i];
1650  }
1651  TetInfo.push_back(vol);
1652  }
1653  break;
1654  case 'P':
1655  {
1656  MeshPyr vol;
1657  vol.id = vIt->first;
1658  for(int i = 0; i < 5; ++i)
1659  {
1660  vol.f[i] = vIt->second.list[i];
1661  }
1662  PyrInfo.push_back(vol);
1663  }
1664  break;
1665  case 'R':
1666  {
1667  MeshPrism vol;
1668  vol.id = vIt->first;
1669  for(int i = 0; i < 5; ++i)
1670  {
1671  vol.f[i] = vIt->second.list[i];
1672  }
1673  PrismInfo.push_back(vol);
1674  }
1675  break;
1676  case 'H':
1677  {
1678  MeshHex vol;
1679  vol.id = vIt->first;
1680  for(int i = 0; i < 6; ++i)
1681  {
1682  vol.f[i] = vIt->second.list[i];
1683  }
1684  HexInfo.push_back(vol);
1685  }
1686  break;
1687  default:
1688  ASSERTL0(false,"Unknown element type");
1689  }
1690  }
1691 
1692  if(SegInfo.size())
1693  {
1694  std::string vType("S");
1695  x = new TiXmlElement(vType);
1696 
1697  std::string segStr;
1698  CompressData::ZlibEncodeToBase64Str(SegInfo,segStr);
1699  x->SetAttribute("COMPRESSED",
1701  x->SetAttribute("BITSIZE",
1703  x->LinkEndChild(new TiXmlText(segStr));
1704  vElement->LinkEndChild(x);
1705  }
1706 
1707  if(TriInfo.size())
1708  {
1709  std::string vType("T");
1710  x = new TiXmlElement(vType);
1711 
1712  std::string faceStr;
1713  CompressData::ZlibEncodeToBase64Str(TriInfo,faceStr);
1714  x->SetAttribute("COMPRESSED",
1716  x->SetAttribute("BITSIZE",
1718  x->LinkEndChild(new TiXmlText(faceStr));
1719  vElement->LinkEndChild(x);
1720  }
1721 
1722  if(QuadInfo.size())
1723  {
1724  std::string vType("Q");
1725  x = new TiXmlElement(vType);
1726  std::string faceStr;
1727  CompressData::ZlibEncodeToBase64Str(QuadInfo,faceStr);
1728  x->SetAttribute("COMPRESSED",
1730  x->SetAttribute("BITSIZE",
1732  x->LinkEndChild(new TiXmlText(faceStr));
1733  vElement->LinkEndChild(x);
1734  }
1735 
1736  if(TetInfo.size())
1737  {
1738  std::string vType("A");
1739  x = new TiXmlElement(vType);
1740  std::string volStr;
1741  CompressData::ZlibEncodeToBase64Str(TetInfo,volStr);
1742  x->SetAttribute("COMPRESSED",
1744  x->SetAttribute("BITSIZE",
1746  x->LinkEndChild(new TiXmlText(volStr));
1747  vElement->LinkEndChild(x);
1748  }
1749 
1750  if(PyrInfo.size())
1751  {
1752  std::string vType("P");
1753  x = new TiXmlElement(vType);
1754  std::string volStr;
1755  CompressData::ZlibEncodeToBase64Str(PyrInfo,volStr);
1756  x->SetAttribute("COMPRESSED",
1758  x->SetAttribute("BITSIZE",
1760  x->LinkEndChild(new TiXmlText(volStr));
1761  vElement->LinkEndChild(x);
1762  }
1763 
1764  if(PrismInfo.size())
1765  {
1766  std::string vType("R");
1767  x = new TiXmlElement(vType);
1768  std::string volStr;
1769  CompressData::ZlibEncodeToBase64Str(PrismInfo,volStr);
1770  x->SetAttribute("COMPRESSED",
1772  x->SetAttribute("BITSIZE",
1774  x->LinkEndChild(new TiXmlText(volStr));
1775  vElement->LinkEndChild(x);
1776  }
1777 
1778  if(HexInfo.size())
1779  {
1780  std::string vType("H");
1781  x = new TiXmlElement(vType);
1782  std::string volStr;
1783  CompressData::ZlibEncodeToBase64Str(HexInfo,volStr);
1784  x->SetAttribute("COMPRESSED",
1786  x->SetAttribute("BITSIZE",
1788  x->LinkEndChild(new TiXmlText(volStr));
1789  vElement->LinkEndChild(x);
1790  }
1791 
1792  }
1793  else
1794  {
1795  for (vIt = vElements.begin(); vIt != vElements.end(); vIt++)
1796  {
1797  std::string vType("T");
1798  vType[0] = vIt->second.type;
1799  x = new TiXmlElement(vType.c_str());
1800  x->SetAttribute("ID", vIt->first);
1801  std::stringstream vEdges;
1802  for (unsigned i = 0; i < vIt->second.list.size(); ++i)
1803  {
1804  vEdges << std::setw(10) << vIt->second.list[i];
1805  }
1806  vEdges << " ";
1807  y = new TiXmlText(vEdges.str());
1808  x->LinkEndChild(y);
1809  vElement->LinkEndChild(x);
1810  }
1811  }
1812 
1813  if (m_dim >= 2)
1814  {
1815  std::map<MeshCurvedKey, MeshCurved>::const_iterator vItCurve;
1816 
1817  if(m_isCompressed)
1818  {
1819  std::vector<MeshCurvedInfo> edgeinfo;
1820  std::vector<MeshCurvedInfo> faceinfo;
1821  MeshCurvedPts curvedpts;
1822  curvedpts.id = 0; // assume all points are going in here
1823  int ptoffset = 0;
1824  int newidx = 0;
1825  std::map<int,int> idxmap;
1826 
1827  for (vItCurve = m_meshCurved.begin();
1828  vItCurve != m_meshCurved.end();
1829  ++vItCurve)
1830  {
1831  MeshCurved c = vItCurve->second;
1832 
1833  bool IsEdge = boost::iequals(c.entitytype,"E");
1834  bool IsFace = boost::iequals(c.entitytype,"F");
1835 
1836  if((IsEdge&&vEdges.find(c.entityid) != vEdges.end())||
1837  (IsFace&&vFaces.find(c.entityid) != vFaces.end()))
1838  {
1839  MeshCurvedInfo cinfo;
1840  // add in
1841  cinfo.id = c.id;
1842  cinfo.entityid = c.entityid;
1843  cinfo.npoints = c.npoints;
1844  for(int i = 0; i < SIZE_PointsType; ++i)
1845  {
1846  if(c.type.compare(kPointsTypeStr[i]) == 0)
1847  {
1848  cinfo.ptype = (PointsType) i;
1849  break;
1850  }
1851  }
1852  cinfo.ptid = 0; // set to just one point set
1853  cinfo.ptoffset = ptoffset;
1854  ptoffset += c.npoints;
1855 
1856  if (IsEdge)
1857  {
1858  edgeinfo.push_back(cinfo);
1859  }
1860  else
1861  {
1862  faceinfo.push_back(cinfo);
1863  }
1864 
1865  // fill in points to list.
1866  for(int i =0; i < c.npoints; ++i)
1867  {
1868  // get index from full list;
1869  int idx = m_meshCurvedPts[c.ptid]
1870  .index[c.ptoffset+i];
1871 
1872  // if index is not already in curved
1873  // points add it or set index to location
1874  if(idxmap.count(idx) == 0)
1875  {
1876  idxmap[idx] = newidx;
1877  curvedpts.index.push_back(newidx);
1878  curvedpts.pts.push_back(
1879  m_meshCurvedPts[c.ptid].pts[idx]);
1880  newidx++;
1881  }
1882  else
1883  {
1884  curvedpts.index.push_back(idxmap[idx]);
1885  }
1886  }
1887  }
1888  }
1889 
1890  // add xml information
1891  if(edgeinfo.size())
1892  {
1893  vCurved->SetAttribute("COMPRESSED",
1895  vCurved->SetAttribute("BITSIZE",
1897 
1898  x = new TiXmlElement("E");
1899  std::string dataStr;
1900  CompressData::ZlibEncodeToBase64Str(edgeinfo,dataStr);
1901  x->LinkEndChild(new TiXmlText(dataStr));
1902  vCurved->LinkEndChild(x);
1903  }
1904 
1905  if(faceinfo.size())
1906  {
1907  vCurved->SetAttribute("COMPRESSED",
1909  vCurved->SetAttribute("BITSIZE",
1911 
1912  x = new TiXmlElement("F");
1913  std::string dataStr;
1914  CompressData::ZlibEncodeToBase64Str(faceinfo,dataStr);
1915  x->LinkEndChild(new TiXmlText(dataStr));
1916  vCurved->LinkEndChild(x);
1917  }
1918 
1919  if(edgeinfo.size()||faceinfo.size())
1920  {
1921  x = new TiXmlElement("DATAPOINTS");
1922  x->SetAttribute("ID", curvedpts.id);
1923 
1924  TiXmlElement *subx = new TiXmlElement("INDEX");
1925  std::string dataStr;
1926  CompressData::ZlibEncodeToBase64Str(curvedpts.index,
1927  dataStr);
1928  subx->LinkEndChild(new TiXmlText(dataStr));
1929  x->LinkEndChild(subx);
1930 
1931  subx = new TiXmlElement("POINTS");
1933  dataStr);
1934  subx->LinkEndChild(new TiXmlText(dataStr));
1935  x->LinkEndChild(subx);
1936 
1937  vCurved->LinkEndChild(x);
1938  }
1939  }
1940  else
1941  {
1942  for (vItCurve = m_meshCurved.begin();
1943  vItCurve != m_meshCurved.end();
1944  ++vItCurve)
1945  {
1946  MeshCurved c = vItCurve->second;
1947 
1948  bool IsEdge = boost::iequals(c.entitytype,"E");
1949  bool IsFace = boost::iequals(c.entitytype,"F");
1950 
1951  if((IsEdge&&vEdges.find(c.entityid) != vEdges.end())||
1952  (IsFace&&vFaces.find(c.entityid) != vFaces.end()))
1953  {
1954  x = new TiXmlElement(c.entitytype);
1955  x->SetAttribute("ID", c.id);
1956  if (IsEdge)
1957  {
1958  x->SetAttribute("EDGEID", c.entityid);
1959  }
1960  else
1961  {
1962  x->SetAttribute("FACEID", c.entityid);
1963  }
1964  x->SetAttribute("TYPE", c.type);
1965  x->SetAttribute("NUMPOINTS", c.npoints);
1966  y = new TiXmlText(c.data);
1967  x->LinkEndChild(y);
1968  vCurved->LinkEndChild(x);
1969  }
1970  }
1971  }
1972  }
1973 
1974  // Generate composites section comprising only those mesh entities
1975  // which belong to this partition.
1976  for (vIt = m_meshComposites.begin(); vIt != m_meshComposites.end(); ++vIt)
1977  {
1978  idxList.clear();
1979 
1980  for (unsigned int j = 0; j < vIt->second.list.size(); ++j)
1981  {
1982  // Based on entity type, check if in this partition
1983  switch (vIt->second.type)
1984  {
1985  case 'V':
1986  if (vVertices.find(vIt->second.list[j]) == vVertices.end())
1987  {
1988  continue;
1989  }
1990  break;
1991  case 'E':
1992  if (vEdges.find(vIt->second.list[j]) == vEdges.end())
1993  {
1994  continue;
1995  }
1996  break;
1997  case 'F':
1998  if (vFaces.find(vIt->second.list[j]) == vFaces.end())
1999  {
2000  continue;
2001  }
2002  break;
2003  default:
2004  if (vElements.find(vIt->second.list[j]) == vElements.end())
2005  {
2006  continue;
2007  }
2008  break;
2009  }
2010 
2011  idxList.push_back(vIt->second.list[j]);
2012  }
2013 
2014  std::string vCompositeStr = ParseUtils::GenerateSeqString(idxList);
2015 
2016  if (vCompositeStr.length() > 0)
2017  {
2018  vComposites[vIt->first] = vIt->second;
2019  x = new TiXmlElement("C");
2020  x->SetAttribute("ID", vIt->first);
2021  vCompositeStr = "X[" + vCompositeStr + "]";
2022  vCompositeStr[0] = vIt->second.type;
2023  y = new TiXmlText(vCompositeStr.c_str());
2024  x->LinkEndChild(y);
2025  vComposite->LinkEndChild(x);
2026  }
2027  }
2028 
2029  idxList.clear();
2030  std::string vDomainListStr;
2031  for (unsigned int i = 0; i < m_domain.size(); ++i)
2032  {
2033  if (vComposites.find(m_domain[i]) != vComposites.end())
2034  {
2035  idxList.push_back(m_domain[i]);
2036  }
2037  }
2038  vDomainListStr = "C[" + ParseUtils::GenerateSeqString(idxList) + "]";
2039  TiXmlText* vDomainList = new TiXmlText(vDomainListStr);
2040  vDomain->LinkEndChild(vDomainList);
2041 
2042  vElmtGeometry->LinkEndChild(vVertex);
2043  if (m_dim >= 2)
2044  {
2045  vElmtGeometry->LinkEndChild(vEdge);
2046  }
2047  if (m_dim >= 3)
2048  {
2049  vElmtGeometry->LinkEndChild(vFace);
2050  }
2051  vElmtGeometry->LinkEndChild(vElement);
2052  if (m_dim >= 2)
2053  {
2054  vElmtGeometry->LinkEndChild(vCurved);
2055  }
2056  vElmtGeometry->LinkEndChild(vComposite);
2057  vElmtGeometry->LinkEndChild(vDomain);
2058 
2059  pNektar->LinkEndChild(vElmtGeometry);
2060 
2061  if (pSession->DefinesElement("Nektar/Conditions"))
2062  {
2063  std::set<int> vBndRegionIdList;
2064  TiXmlElement* vConditions = new TiXmlElement(*pSession->GetElement("Nektar/Conditions"));
2065  TiXmlElement* vBndRegions = vConditions->FirstChildElement("BOUNDARYREGIONS");
2066  TiXmlElement* vBndConditions = vConditions->FirstChildElement("BOUNDARYCONDITIONS");
2067  TiXmlElement* vItem;
2068 
2069  if (vBndRegions)
2070  {
2071  TiXmlElement* vNewBndRegions = new TiXmlElement("BOUNDARYREGIONS");
2072  vItem = vBndRegions->FirstChildElement();
2073  while (vItem)
2074  {
2075  std::string vSeqStr = vItem->FirstChild()->ToText()->Value();
2076  std::string::size_type indxBeg = vSeqStr.find_first_of('[') + 1;
2077  std::string::size_type indxEnd = vSeqStr.find_last_of(']') - 1;
2078  vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
2079  std::vector<unsigned int> vSeq;
2080  ParseUtils::GenerateSeqVector(vSeqStr.c_str(), vSeq);
2081 
2082  idxList.clear();
2083 
2084  for (unsigned int i = 0; i < vSeq.size(); ++i)
2085  {
2086  if (vComposites.find(vSeq[i]) != vComposites.end())
2087  {
2088  idxList.push_back(vSeq[i]);
2089  }
2090  }
2091  int p = atoi(vItem->Attribute("ID"));
2092 
2093  std::string vListStr = ParseUtils::GenerateSeqString(idxList);
2094 
2095  if (vListStr.length() == 0)
2096  {
2097  TiXmlElement* tmp = vItem;
2098  vItem = vItem->NextSiblingElement();
2099  vBndRegions->RemoveChild(tmp);
2100  }
2101  else
2102  {
2103  vListStr = "C[" + vListStr + "]";
2104  TiXmlText* vList = new TiXmlText(vListStr);
2105  TiXmlElement* vNewElement = new TiXmlElement("B");
2106  vNewElement->SetAttribute("ID", p);
2107  vNewElement->LinkEndChild(vList);
2108  vNewBndRegions->LinkEndChild(vNewElement);
2109  vBndRegionIdList.insert(p);
2110  vItem = vItem->NextSiblingElement();
2111  }
2112 
2113  // Store original order of boundary region.
2114  m_bndRegOrder[p] = vSeq;
2115 
2116  }
2117  vConditions->ReplaceChild(vBndRegions, *vNewBndRegions);
2118  }
2119 
2120  if (vBndConditions)
2121  {
2122  vItem = vBndConditions->FirstChildElement();
2123  while (vItem)
2124  {
2126  if ((x = vBndRegionIdList.find(atoi(vItem->Attribute("REF")))) != vBndRegionIdList.end())
2127  {
2128  vItem->SetAttribute("REF", *x);
2129  vItem = vItem->NextSiblingElement();
2130  }
2131  else
2132  {
2133  TiXmlElement* tmp = vItem;
2134  vItem = vItem->NextSiblingElement();
2135  vBndConditions->RemoveChild(tmp);
2136  }
2137  }
2138  }
2139  pNektar->LinkEndChild(vConditions);
2140  }
2141 
2142  // Distribute other sections of the XML to each process as is.
2143  TiXmlElement* vSrc = pSession->GetElement("Nektar")
2144  ->FirstChildElement();
2145  while (vSrc)
2146  {
2147  std::string vName = boost::to_upper_copy(vSrc->ValueStr());
2148  if (vName != "GEOMETRY" && vName != "CONDITIONS")
2149  {
2150  pNektar->LinkEndChild(new TiXmlElement(*vSrc));
2151  }
2152  vSrc = vSrc->NextSiblingElement();
2153  }
2154  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
std::map< std::string, std::string > m_vertexAttributes
std::map< int, MeshEntity > m_meshComposites
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:69
std::map< int, MeshVertex > m_meshVertices
static std::string GenerateSeqString(const std::vector< unsigned int > &elmtids)
Definition: ParseUtils.hpp:159
std::map< MeshCurvedKey, MeshCurved > m_meshCurved
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
std::map< int, MeshEntity > m_meshElements
std::vector< unsigned int > m_domain
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:151
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
std::map< int, MeshEntity > m_meshEdges
std::map< int, MeshEntity > m_meshFaces
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
std::map< int, MeshCurvedPts > m_meshCurvedPts
void Nektar::LibUtilities::MeshPartition::PartitionGraph ( BoostSubGraph pGraph,
int  nParts,
std::vector< BoostSubGraph > &  pLocalPartition,
bool  overlapping = false 
)
private

Partition the graph.

This routine partitions the graph pGraph into nParts, producing subgraphs that are populated in pLocalPartition. If the overlapping option is set (which is used for post-processing purposes), the resulting partitions are extended to cover neighbouring elements by additional vertex on the dual graph, which produces overlapping partitions (i.e. the intersection of two connected partitions is non-empty).

Parameters
pGraphGraph to be partitioned.
nPartsNumber of partitions.
pLocalPartitionVector of sub-graphs representing each partition.
overlappingTrue if resulting partitions should overlap.

Definition at line 1160 of file MeshPartition.cpp.

References CheckPartitions(), ErrorUtil::efatal, m_comm, m_shared, m_weightingRequired, NEKERROR, and PartitionGraphImpl().

Referenced by PartitionMesh().

1164  {
1165  int i;
1166  int nGraphVerts = boost::num_vertices(pGraph);
1167  int nGraphEdges = boost::num_edges(pGraph);
1168 
1169  // Convert boost graph into CSR format
1170  BoostVertexIterator vertit, vertit_end;
1171  BoostAdjacencyIterator adjvertit, adjvertit_end;
1172  Array<OneD, int> part(nGraphVerts,0);
1173 
1174  if (m_comm->GetRowComm()->TreatAsRankZero())
1175  {
1176  int acnt = 0;
1177  int vcnt = 0;
1178  int nWeight = nGraphVerts;
1179  Array<OneD, int> xadj(nGraphVerts+1,0);
1180  Array<OneD, int> adjncy(2*nGraphEdges);
1181  Array<OneD, int> vwgt(nWeight, 1);
1182  Array<OneD, int> vsize(nGraphVerts, 1);
1183 
1184  for ( boost::tie(vertit, vertit_end) = boost::vertices(pGraph);
1185  vertit != vertit_end;
1186  ++vertit)
1187  {
1188  for ( boost::tie(adjvertit, adjvertit_end) = boost::adjacent_vertices(*vertit,pGraph);
1189  adjvertit != adjvertit_end;
1190  ++adjvertit)
1191  {
1192  adjncy[acnt++] = *adjvertit;
1193  }
1194 
1195  xadj[++vcnt] = acnt;
1196 
1197  if (m_weightingRequired)
1198  {
1199  vwgt[vcnt-1] = pGraph[*vertit].weight[0];
1200  }
1201  else
1202  {
1203  vwgt[vcnt-1] = 1;
1204  }
1205  }
1206 
1207  // Call Metis and partition graph
1208  int vol = 0;
1209 
1210  try
1211  {
1212  //////////////////////////////////////////////////////
1213  // On a cartesian communicator do mesh partiotion just on the first column
1214  // so there is no doubt the partitions are all the same in all the columns
1215  if(m_comm->GetColumnComm()->GetRank() == 0)
1216  {
1217  // Attempt partitioning using METIS.
1218  int ncon = 1;
1219  PartitionGraphImpl(nGraphVerts, ncon, xadj, adjncy, vwgt, vsize, nParts, vol, part);
1220 
1221  // Check METIS produced a valid partition and fix if not.
1222  CheckPartitions(nParts, part);
1223  if (!m_shared)
1224  {
1225  // distribute among columns
1226  for (i = 1; i < m_comm->GetColumnComm()->GetSize(); ++i)
1227  {
1228  m_comm->GetColumnComm()->Send(i, part);
1229  }
1230  }
1231  }
1232  else
1233  {
1234  m_comm->GetColumnComm()->Recv(0, part);
1235  }
1236  if (!m_shared)
1237  {
1238  m_comm->GetColumnComm()->Block();
1239 
1240  //////////////////////////////////
1241  // distribute among rows
1242  for (i = 1; i < m_comm->GetRowComm()->GetSize(); ++i)
1243  {
1244  m_comm->GetRowComm()->Send(i, part);
1245  }
1246  }
1247  }
1248  catch (...)
1249  {
1251  "Error in calling metis to partition graph.");
1252  }
1253  }
1254  else
1255  {
1256  m_comm->GetRowComm()->Recv(0, part);
1257  }
1258 
1259  // Create boost subgraph for this process's partitions
1260  int nCols = nParts;
1261  pLocalPartition.resize(nCols);
1262  for (i = 0; i < nCols; ++i)
1263  {
1264  pLocalPartition[i] = pGraph.create_subgraph();
1265  }
1266 
1267  // Populate subgraph
1268  i = 0;
1269  for ( boost::tie(vertit, vertit_end) = boost::vertices(pGraph);
1270  vertit != vertit_end;
1271  ++vertit, ++i)
1272  {
1273  pGraph[*vertit].partition = part[i];
1274  boost::add_vertex(i, pLocalPartition[part[i]]);
1275  }
1276 
1277  // If the overlapping option is set (for post-processing purposes),
1278  // add vertices that correspond to the neighbouring elements.
1279  if (overlapping)
1280  {
1281  for ( boost::tie(vertit, vertit_end) = boost::vertices(pGraph);
1282  vertit != vertit_end;
1283  ++vertit)
1284  {
1285  for (boost::tie(adjvertit, adjvertit_end) = boost::adjacent_vertices(*vertit,pGraph);
1286  adjvertit != adjvertit_end; ++adjvertit)
1287  {
1288  if(part[*adjvertit] != part[*vertit])
1289  {
1290  boost::add_vertex(*adjvertit, pLocalPartition[part[*vertit]]);
1291  }
1292  }
1293  }
1294  }
1295  }
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:158
void CheckPartitions(int nParts, Array< OneD, int > &pPart)
virtual void PartitionGraphImpl(int &nVerts, int &nVertConds, Nektar::Array< Nektar::OneD, int > &xadj, Nektar::Array< Nektar::OneD, int > &adjcy, Nektar::Array< Nektar::OneD, int > &vertWgt, Nektar::Array< Nektar::OneD, int > &vertSize, int &nparts, int &volume, Nektar::Array< Nektar::OneD, int > &part)=0
boost::graph_traits< BoostGraph >::adjacency_iterator BoostAdjacencyIterator
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
virtual void Nektar::LibUtilities::MeshPartition::PartitionGraphImpl ( int &  nVerts,
int &  nVertConds,
Nektar::Array< Nektar::OneD, int > &  xadj,
Nektar::Array< Nektar::OneD, int > &  adjcy,
Nektar::Array< Nektar::OneD, int > &  vertWgt,
Nektar::Array< Nektar::OneD, int > &  vertSize,
int &  nparts,
int &  volume,
Nektar::Array< Nektar::OneD, int > &  part 
)
privatepure virtual
void Nektar::LibUtilities::MeshPartition::PartitionMesh ( int  nParts,
bool  shared = false,
bool  overlapping = false 
)

Definition at line 95 of file MeshPartition.cpp.

References ASSERTL0, CreateGraph(), m_localPartition, m_mesh, m_meshElements, m_shared, m_weightingRequired, PartitionGraph(), and WeightElements().

97  {
98  ASSERTL0(m_meshElements.size() >= nParts,
99  "Too few elements for this many processes.");
100  m_shared = shared;
101 
103  {
104  WeightElements();
105  }
107  PartitionGraph(m_mesh, nParts, m_localPartition, overlapping);
108  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
std::map< int, MeshEntity > m_meshElements
void CreateGraph(BoostSubGraph &pGraph)
std::vector< BoostSubGraph > m_localPartition
void PartitionGraph(BoostSubGraph &pGraph, int nParts, std::vector< BoostSubGraph > &pLocalPartition, bool overlapping=false)
Partition the graph.
void Nektar::LibUtilities::MeshPartition::PrintPartInfo ( std::ostream &  out)

Definition at line 916 of file MeshPartition.cpp.

References ASSERTL0, CalculateElementWeight(), Nektar::iterator, m_dim, m_domain, m_expansions, m_localPartition, m_mesh, and m_meshComposites.

917  {
918  int nElmt = boost::num_vertices(m_mesh);
919  int nPart = m_localPartition.size();
920 
921  out << "# Partition information:" << std::endl;
922  out << "# No. elements : " << nElmt << std::endl;
923  out << "# No. partitions: " << nPart << std::endl;
924  out << "# ID nElmt nLocDof nBndDof" << std::endl;
925 
926  BoostVertexIterator vertit, vertit_end;
927  std::vector<int> partElmtCount(nPart, 0);
928  std::vector<int> partLocCount (nPart, 0);
929  std::vector<int> partBndCount (nPart, 0);
930 
931  std::map<int, int> elmtSizes;
932  std::map<int, int> elmtBndSizes;
933 
934  for (unsigned int i = 0; i < m_domain.size(); ++i)
935  {
936  int cId = m_domain[i];
937  NummodesPerField npf = m_expansions[cId];
938 
939  for (NummodesPerField::iterator it = npf.begin(); it != npf.end(); ++it)
940  {
941  ASSERTL0(it->second.size() == m_dim,
942  " Number of directional" \
943  " modes in expansion spec for composite id = " +
944  boost::lexical_cast<std::string>(cId) +
945  " and field " +
946  boost::lexical_cast<std::string>(it->first) +
947  " does not correspond to mesh dimension");
948 
949  int na = it->second[0];
950  int nb = it->second[1];
951  int nc = 0;
952  if (m_dim == 3)
953  {
954  nc = it->second[2];
955  }
956 
957  int weight = CalculateElementWeight(
958  m_meshComposites[cId].type, false, na, nb, nc);
959  int bndWeight = CalculateElementWeight(
960  m_meshComposites[cId].type, true, na, nb, nc);
961 
962  for (unsigned int j = 0; j < m_meshComposites[cId].list.size(); ++j)
963  {
964  int elid = m_meshComposites[cId].list[j];
965  elmtSizes[elid] = weight;
966  elmtBndSizes[elid] = bndWeight;
967  }
968  }
969  }
970 
971  for (boost::tie(vertit, vertit_end) = boost::vertices(m_mesh);
972  vertit != vertit_end; ++vertit)
973  {
974  int partId = m_mesh[*vertit].partition;
975  partElmtCount[partId]++;
976  partLocCount [partId] += elmtSizes[m_mesh[*vertit].id];
977  partBndCount [partId] += elmtBndSizes[m_mesh[*vertit].id];
978  }
979 
980  for (int i = 0; i < nPart; ++i)
981  {
982  out << i << " " << partElmtCount[i] << " " << partLocCount[i] << " " << partBndCount[i] << std::endl;
983  }
984  }
int CalculateElementWeight(char elmtType, bool bndWeight, int na, int nb, int nc)
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
std::map< int, MeshEntity > m_meshComposites
std::map< std::string, NumModes > NummodesPerField
std::map< int, NummodesPerField > m_expansions
std::vector< unsigned int > m_domain
std::vector< BoostSubGraph > m_localPartition
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
void Nektar::LibUtilities::MeshPartition::ReadConditions ( const SessionReaderSharedPtr pSession)
private

Definition at line 986 of file MeshPartition.cpp.

References ASSERTL0, and m_weightingRequired.

Referenced by MeshPartition().

987  {
988  if (!pSession->DefinesElement("Nektar/Conditions/SolverInfo"))
989  {
990  // No SolverInfo = no change of default action to weight
991  // mesh graph.
992  return;
993  }
994 
995  TiXmlElement* solverInfoElement =
996  pSession->GetElement("Nektar/Conditions/SolverInfo");
997 
998  TiXmlElement* solverInfo =
999  solverInfoElement->FirstChildElement("I");
1000  ASSERTL0(solverInfo, "Cannot read SolverInfo tags");
1001 
1002  while (solverInfo)
1003  {
1004  // read the property name
1005  ASSERTL0(solverInfo->Attribute("PROPERTY"),
1006  "Missing PROPERTY attribute in solver info "
1007  "section. ");
1008  std::string solverProperty =
1009  solverInfo->Attribute("PROPERTY");
1010  ASSERTL0(!solverProperty.empty(),
1011  "Solver info properties must have a non-empty "
1012  "name. ");
1013  // make sure that solver property is capitalised
1014  std::string solverPropertyUpper =
1015  boost::to_upper_copy(solverProperty);
1016 
1017 
1018  // read the value
1019  ASSERTL0(solverInfo->Attribute("VALUE"),
1020  "Missing VALUE attribute in solver info section. ");
1021  std::string solverValue = solverInfo->Attribute("VALUE");
1022  ASSERTL0(!solverValue.empty(),
1023  "Solver info properties must have a non-empty value");
1024  // make sure that property value is capitalised
1025  std::string propertyValueUpper =
1026  boost::to_upper_copy(solverValue);
1027 
1028  if (solverPropertyUpper == "WEIGHTPARTITIONS")
1029  {
1030  if (propertyValueUpper != "UNIFORM")
1031  {
1032  m_weightingRequired = true;
1033  }
1034  return;
1035  }
1036  solverInfo = solverInfo->NextSiblingElement("I");
1037  }
1038  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
void Nektar::LibUtilities::MeshPartition::ReadExpansions ( const SessionReaderSharedPtr pSession)
private

Expansiontypes will contain plenty of data, where relevant at this stage are composite ID(s) that this expansion type describes, nummodes and a list of fields that this expansion relates to. If this does not exist the variable is only set to "DefaultVar".

Definition at line 189 of file MeshPartition.cpp.

References ASSERTL0, Nektar::ParseUtils::GenerateOrderedStringVector(), Nektar::ParseUtils::GenerateOrderedVector(), Nektar::ParseUtils::GenerateSeqVector(), m_dim, m_expansions, m_fieldNameToId, and m_numFields.

Referenced by MeshPartition().

190  {
191  // Find the Expansions tag
192  TiXmlElement *expansionTypes = pSession->GetElement("Nektar/Expansions");
193 
194  // Find the Expansion type
195  TiXmlElement *expansion = expansionTypes->FirstChildElement();
196  std::string expType = expansion->Value();
197 
198 
199  if(expType != "E")
200  {
201  ASSERTL0(false,"Expansion type not defined or not supported at the moment");
202  }
203 
204  /// Expansiontypes will contain plenty of data,
205  /// where relevant at this stage are composite
206  /// ID(s) that this expansion type describes,
207  /// nummodes and a list of fields that this
208  /// expansion relates to. If this does not exist
209  /// the variable is only set to "DefaultVar".
210 
211  while (expansion)
212  {
213  std::vector<unsigned int> composite;
214  std::vector<unsigned int> nummodes;
215  std::vector<std::string> fieldName;
216 
217  const char *nModesStr = expansion->Attribute("NUMMODES");
218  ASSERTL0(nModesStr,"NUMMODES was not defined in EXPANSION section of input");
219  std::string numModesStr = nModesStr;
220  bool valid = ParseUtils::GenerateOrderedVector(numModesStr.c_str(), nummodes);
221  ASSERTL0(valid, "Unable to correctly parse the number of modes.");
222 
223  if (nummodes.size() == 1)
224  {
225  for (int i = 1; i < m_dim; i++)
226  {
227  nummodes.push_back( nummodes[0] );
228  }
229  }
230  ASSERTL0(nummodes.size() == m_dim,"Number of modes should match mesh dimension");
231 
232 
233  const char *fStr = expansion->Attribute("FIELDS");
234  if(fStr)
235  {
236  std::string fieldStr = fStr;
237  bool valid = ParseUtils::GenerateOrderedStringVector(fieldStr.c_str(),fieldName);
238  ASSERTL0(valid,"Unable to correctly parse the field string in ExpansionTypes.");
239 
240  for (int i = 0; i < fieldName.size(); ++i)
241  {
242  if (m_fieldNameToId.count(fieldName[i]) == 0)
243  {
244  int k = m_fieldNameToId.size();
245  m_fieldNameToId[ fieldName[i] ] = k;
246  m_numFields++;
247  }
248  }
249  }
250  else
251  {
252  fieldName.push_back("DefaultVar");
253  int k = m_fieldNameToId.size();
254 
255  if (m_fieldNameToId.count("DefaultVar") == 0)
256  {
257  ASSERTL0(k == 0,
258  "Omitting field variables and explicitly listing " \
259  "them in different ExpansionTypes is wrong practise");
260 
261  m_fieldNameToId[ "DefaultVar" ] = k;
262  m_numFields++;
263  }
264  }
265 
266  std::string compositeStr = expansion->Attribute("COMPOSITE");
267  ASSERTL0(compositeStr.length() > 3, "COMPOSITE must be specified in expansion definition");
268  int beg = compositeStr.find_first_of("[");
269  int end = compositeStr.find_first_of("]");
270  std::string compositeListStr = compositeStr.substr(beg+1,end-beg-1);
271  bool parseGood = ParseUtils::GenerateSeqVector(compositeListStr.c_str(), composite);
272  ASSERTL0(parseGood && !composite.empty(),
273  (std::string("Unable to read composite index range: ") + compositeListStr).c_str());
274 
275 
276  // construct mapping (field name, CompositeID) -> nummodes
277  for (int i = 0; i < composite.size(); ++i)
278  {
279  for (int j = 0; j < fieldName.size(); j++)
280  {
281  m_expansions[composite[i]][fieldName[j]] = nummodes;
282  }
283  }
284 
285  expansion = expansion->NextSiblingElement("E");
286  }
287  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
static bool GenerateOrderedStringVector(const char *const str, std::vector< std::string > &vec)
Definition: ParseUtils.hpp:143
static bool GenerateOrderedVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:97
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
std::map< std::string, int > m_fieldNameToId
std::map< int, NummodesPerField > m_expansions
void Nektar::LibUtilities::MeshPartition::ReadGeometry ( const SessionReaderSharedPtr pSession)
private

Definition at line 292 of file MeshPartition.cpp.

References ASSERTL0, Nektar::LibUtilities::MeshPartition::MeshCurved::data, Nektar::LibUtilities::MeshPartition::MeshCurved::entityid, Nektar::LibUtilities::MeshPartition::MeshCurved::entitytype, Nektar::ParseUtils::GenerateSeqVector(), Nektar::LibUtilities::CompressData::GetCompressString(), Nektar::LibUtilities::MeshVertex::id, Nektar::LibUtilities::MeshPartition::MeshEntity::id, Nektar::LibUtilities::MeshPartition::MeshCurved::id, Nektar::LibUtilities::MeshCurvedPts::id, Nektar::LibUtilities::MeshCurvedPts::index, Nektar::LibUtilities::kPointsTypeStr, Nektar::LibUtilities::MeshPartition::MeshEntity::list, m_dim, m_domain, m_isCompressed, m_meshComposites, m_meshCurved, m_meshCurvedPts, m_meshEdges, m_meshElements, m_meshFaces, m_meshVertices, m_vertexAttributes, Nektar::LibUtilities::MeshPartition::MeshCurved::npoints, Nektar::LibUtilities::MeshPartition::MeshCurved::ptid, Nektar::LibUtilities::MeshPartition::MeshCurved::ptoffset, Nektar::LibUtilities::MeshCurvedPts::pts, Nektar::LibUtilities::MeshPartition::MeshEntity::type, Nektar::LibUtilities::MeshPartition::MeshCurved::type, Nektar::LibUtilities::MeshVertex::x, Nektar::LibUtilities::MeshVertex::y, Nektar::LibUtilities::MeshVertex::z, and Nektar::LibUtilities::CompressData::ZlibDecodeFromBase64Str().

Referenced by MeshPartition().

293  {
294  TiXmlElement* x;
295  TiXmlElement *vGeometry, *vSubElement;
296 
297  vGeometry = pSession->GetElement("Nektar/Geometry");
298  m_dim = atoi(vGeometry->Attribute("DIM"));
299 
300  // Read mesh vertices
301  vSubElement = pSession->GetElement("Nektar/Geometry/Vertex");
302 
303  // Retrieve any VERTEX attributes specifying mesh transforms
304  std::string attr[] = {"XSCALE", "YSCALE", "ZSCALE",
305  "XMOVE", "YMOVE", "ZMOVE" };
306  for (int i = 0; i < 6; ++i)
307  {
308  const char *val = vSubElement->Attribute(attr[i].c_str());
309  if (val)
310  {
311  m_vertexAttributes[attr[i]] = std::string(val);
312  }
313  }
314 
315  // check to see if compressed
316  std::string IsCompressed;
317  vSubElement->QueryStringAttribute("COMPRESSED",&IsCompressed);
318 
319  if(IsCompressed.size())
320  {
321  ASSERTL0(boost::iequals(IsCompressed,
323  "Compressed formats do not match. Expected :"
325  + "but got "+ std::string(IsCompressed));
326 
327  m_isCompressed = true;
328 
329  // Extract the vertex body
330  TiXmlNode* vertexChild = vSubElement->FirstChild();
331  ASSERTL0(vertexChild, "Unable to extract the data "
332  "from the compressed vertex tag.");
333 
334  std::string vertexStr;
335  if (vertexChild->Type() == TiXmlNode::TINYXML_TEXT)
336  {
337  vertexStr += vertexChild->ToText()->ValueStr();
338  }
339 
340  std::vector<MeshVertex> vertData;
341  CompressData::ZlibDecodeFromBase64Str(vertexStr,vertData);
342 
343  for(int i = 0; i < vertData.size(); ++i)
344  {
345  m_meshVertices[vertData[i].id] = vertData[i];
346  }
347  }
348  else
349  {
350  x = vSubElement->FirstChildElement();
351 
352  while(x)
353  {
354  TiXmlAttribute* y = x->FirstAttribute();
355  ASSERTL0(y, "Failed to get attribute.");
356  MeshVertex v;
357  v.id = y->IntValue();
358  std::vector<std::string> vCoords;
359  std::string vCoordStr = x->FirstChild()->ToText()->Value();
360  boost::split(vCoords, vCoordStr, boost::is_any_of("\t "));
361  v.x = atof(vCoords[0].c_str());
362  v.y = atof(vCoords[1].c_str());
363  v.z = atof(vCoords[2].c_str());
364  m_meshVertices[v.id] = v;
365  x = x->NextSiblingElement();
366  }
367  }
368 
369  // Read mesh edges
370  if (m_dim >= 2)
371  {
372  vSubElement = pSession->GetElement("Nektar/Geometry/Edge");
373  ASSERTL0(vSubElement, "Cannot read edges");
374 
375  // check to see if compressed
376  std::string IsCompressed;
377  vSubElement->QueryStringAttribute("COMPRESSED",&IsCompressed);
378 
379  if(IsCompressed.size())
380  {
381  ASSERTL0(boost::iequals(IsCompressed,
383  "Compressed formats do not match. Expected :"
385  + " but got "
386  + boost::lexical_cast<std::string>(IsCompressed));
387 
388  m_isCompressed = true;
389 
390  // Extract the edge body
391  TiXmlNode* edgeChild = vSubElement->FirstChild();
392  ASSERTL0(edgeChild,
393  "Unable to extract the data from the compressed "
394  "edge tag.");
395 
396  std::string edgeStr;
397 
398  if (edgeChild->Type() == TiXmlNode::TINYXML_TEXT)
399  {
400  edgeStr += edgeChild->ToText()->ValueStr();
401  }
402 
403  std::vector<MeshEdge> edgeData;
404  CompressData::ZlibDecodeFromBase64Str(edgeStr,edgeData);
405 
406  for(int i = 0; i < edgeData.size(); ++i)
407  {
408  MeshEntity e;
409  e.id = edgeData[i].id;
410  e.list.push_back(edgeData[i].v0);
411  e.list.push_back(edgeData[i].v1);
412  m_meshEdges[e.id] = e;
413  }
414  }
415  else
416  {
417  x = vSubElement->FirstChildElement();
418 
419  while(x)
420  {
421  TiXmlAttribute* y = x->FirstAttribute();
422  ASSERTL0(y, "Failed to get attribute.");
423  MeshEntity e;
424  e.id = y->IntValue();
425  e.type = 'E';
426  std::vector<std::string> vVertices;
427  std::string vVerticesString = x->FirstChild()->ToText()->Value();
428  boost::split(vVertices, vVerticesString, boost::is_any_of("\t "));
429  e.list.push_back(atoi(vVertices[0].c_str()));
430  e.list.push_back(atoi(vVertices[1].c_str()));
431  m_meshEdges[e.id] = e;
432  x = x->NextSiblingElement();
433  }
434  }
435  }
436 
437  // Read mesh faces
438  if (m_dim == 3)
439  {
440  vSubElement = pSession->GetElement("Nektar/Geometry/Face");
441  ASSERTL0(vSubElement, "Cannot read faces.");
442  x = vSubElement->FirstChildElement();
443 
444  while(x)
445  {
446  // check to see if compressed
447  std::string IsCompressed;
448  x->QueryStringAttribute("COMPRESSED",&IsCompressed);
449 
450  if(IsCompressed.size())
451  {
452  ASSERTL0(boost::iequals(IsCompressed,
454  "Compressed formats do not match. Expected :"
456  + " but got "
457  + boost::lexical_cast<std::string>(
458  IsCompressed));
459  m_isCompressed = true;
460 
461  // Extract the edge body
462  TiXmlNode* faceChild = x->FirstChild();
463  ASSERTL0(faceChild, "Unable to extract the data from "
464  "the compressed edge tag.");
465 
466  std::string faceStr;
467  if (faceChild->Type() == TiXmlNode::TINYXML_TEXT)
468  {
469  faceStr += faceChild->ToText()->ValueStr();
470  }
471 
472  // uncompress and fill in values.
473  const std::string val= x->Value();
474 
475  if(boost::iequals(val,"T")) // triangle
476  {
477  std::vector<MeshTri> faceData;
479  faceData);
480 
481  for(int i= 0; i < faceData.size(); ++i)
482  {
483  MeshEntity f;
484 
485  f.id = faceData[i].id;
486  f.type = 'T';
487  for (int j = 0; j < 3; ++j)
488  {
489  f.list.push_back(faceData[i].e[j]);
490  }
491  m_meshFaces[f.id] = f;
492  }
493  }
494  else if (boost::iequals(val,"Q"))
495  {
496  std::vector<MeshQuad> faceData;
498  faceData);
499 
500  for(int i= 0; i < faceData.size(); ++i)
501  {
502  MeshEntity f;
503 
504  f.id = faceData[i].id;
505  f.type = 'Q';
506  for (int j = 0; j < 4; ++j)
507  {
508  f.list.push_back(faceData[i].e[j]);
509  }
510  m_meshFaces[f.id] = f;
511  }
512  }
513  else
514  {
515  ASSERTL0(false,"Unrecognised face tag");
516  }
517  }
518  else
519  {
520  TiXmlAttribute* y = x->FirstAttribute();
521  ASSERTL0(y, "Failed to get attribute.");
522  MeshEntity f;
523  f.id = y->IntValue();
524  f.type = x->Value()[0];
525  std::vector<std::string> vEdges;
526  std::string vEdgeStr = x->FirstChild()->ToText()->Value();
527  boost::split(vEdges, vEdgeStr, boost::is_any_of("\t "));
528  for (int i = 0; i < vEdges.size(); ++i)
529  {
530  f.list.push_back(atoi(vEdges[i].c_str()));
531  }
532  m_meshFaces[f.id] = f;
533  }
534  x = x->NextSiblingElement();
535  }
536  }
537 
538  // Read mesh elements
539  vSubElement = pSession->GetElement("Nektar/Geometry/Element");
540  ASSERTL0(vSubElement, "Cannot read elements.");
541  x = vSubElement->FirstChildElement();
542  while(x)
543  {
544  // check to see if compressed
545  std::string IsCompressed;
546  x->QueryStringAttribute("COMPRESSED",&IsCompressed);
547 
548  if(IsCompressed.size())
549  {
550  ASSERTL0(boost::iequals(IsCompressed,
552  "Compressed formats do not match. Expected :"
554  + " but got "
555  + boost::lexical_cast<std::string>(IsCompressed));
556  m_isCompressed = true;
557 
558  // Extract the body
559  TiXmlNode* child = x->FirstChild();
560  ASSERTL0(child, "Unable to extract the data from the "
561  "compressed element tag.");
562 
563  std::string elmtStr;
564  if (child->Type() == TiXmlNode::TINYXML_TEXT)
565  {
566  elmtStr += child->ToText()->ValueStr();
567  }
568 
569  // uncompress and fill in values.
570  const std::string val= x->Value();
571 
572  switch(val[0])
573  {
574  case 'S': // segment
575  {
576  std::vector<MeshEdge> data;
578 
579  for(int i= 0; i < data.size(); ++i)
580  {
581  MeshEntity e;
582  e.id = data[i].id;
583  e.type = 'S';
584  e.list.push_back(data[i].v0);
585  e.list.push_back(data[i].v1);
586  m_meshElements[e.id] = e;
587  }
588  }
589  break;
590  case 'T': // triangle
591  {
592  std::vector<MeshTri> data;
594 
595  for(int i= 0; i < data.size(); ++i)
596  {
597  MeshEntity f;
598  f.id = data[i].id;
599  f.type = 'T';
600  for (int j = 0; j < 3; ++j)
601  {
602  f.list.push_back(data[i].e[j]);
603  }
604  m_meshElements[f.id] = f;
605  }
606  }
607  break;
608  case 'Q': // quadrilateral
609  {
610  std::vector<MeshQuad> data;
612 
613  for(int i= 0; i < data.size(); ++i)
614  {
615  MeshEntity f;
616  f.id = data[i].id;
617  f.type = 'Q';
618  for (int j = 0; j < 4; ++j)
619  {
620  f.list.push_back(data[i].e[j]);
621  }
622  m_meshElements[f.id] = f;
623  }
624  }
625  break;
626  case 'A': // tetrahedron
627  {
628  std::vector<MeshTet> data;
630 
631  for(int i= 0; i < data.size(); ++i)
632  {
633  MeshEntity f;
634  f.id = data[i].id;
635  f.type = 'A';
636  for (int j = 0; j < 4; ++j)
637  {
638  f.list.push_back(data[i].f[j]);
639  }
640  m_meshElements[f.id] = f;
641  }
642  }
643  break;
644  case 'P': // prism
645  {
646  std::vector<MeshPyr> data;
648 
649  for(int i= 0; i < data.size(); ++i)
650  {
651  MeshEntity f;
652  f.id = data[i].id;
653  f.type = 'P';
654  for (int j = 0; j < 5; ++j)
655  {
656  f.list.push_back(data[i].f[j]);
657  }
658  m_meshElements[f.id] = f;
659  }
660  }
661  break;
662  case 'R': // pyramid
663  {
664  std::vector<MeshPrism> data;
666 
667  for(int i= 0; i < data.size(); ++i)
668  {
669  MeshEntity f;
670  f.id = data[i].id;
671  f.type = 'R';
672  for (int j = 0; j < 5; ++j)
673  {
674  f.list.push_back(data[i].f[j]);
675  }
676  m_meshElements[f.id] = f;
677  }
678  }
679  break;
680  case 'H': // hexahedron
681  {
682  std::vector<MeshHex> data;
684 
685  for(int i= 0; i < data.size(); ++i)
686  {
687  MeshEntity f;
688  f.id = data[i].id;
689  f.type = 'H';
690  for (int j = 0; j < 6; ++j)
691  {
692  f.list.push_back(data[i].f[j]);
693  }
694  m_meshElements[f.id] = f;
695  }
696  }
697  break;
698  default:
699  ASSERTL0(false,"Unrecognised element tag");
700  }
701  }
702  else
703  {
704  TiXmlAttribute* y = x->FirstAttribute();
705  ASSERTL0(y, "Failed to get attribute.");
706  MeshEntity e;
707  e.id = y->IntValue();
708  std::vector<std::string> vItems;
709  std::string vItemStr = x->FirstChild()->ToText()->Value();
710  boost::split(vItems, vItemStr, boost::is_any_of("\t "));
711  for (int i = 0; i < vItems.size(); ++i)
712  {
713  e.list.push_back(atoi(vItems[i].c_str()));
714  }
715  e.type = x->Value()[0];
716  m_meshElements[e.id] = e;
717  }
718  x = x->NextSiblingElement();
719  }
720 
721  // Read mesh curves
722  if (pSession->DefinesElement("Nektar/Geometry/Curved"))
723  {
724  vSubElement = pSession->GetElement("Nektar/Geometry/Curved");
725 
726  // check to see if compressed
727  std::string IsCompressed;
728  vSubElement->QueryStringAttribute("COMPRESSED",&IsCompressed);
729 
730  x = vSubElement->FirstChildElement();
731  while(x)
732  {
733  if(IsCompressed.size())
734  {
735  ASSERTL0(boost::iequals(IsCompressed,
737  "Compressed formats do not match. Expected :"
739  + " but got "
740  + boost::lexical_cast<std::string>(
741  IsCompressed));
742 
743  m_isCompressed = true;
744 
745  const char *entitytype = x->Value();
746  // The compressed curved information is stored
747  // in two parts: MeshCurvedInfo and
748  // MeshCurvedPts. MeshCurvedPts is just a
749  // list of MeshVertex values of unique vertex
750  // values from which we can make edges and
751  // faces.
752  //
753  // Then there is a list of NekInt64 pieces of
754  // information which make a MeshCurvedInfo
755  // struct. This contains information such as
756  // the curve id, the entity id, the number of
757  // curved points and the offset of where these
758  // points are stored in the pts vector of
759  // MeshVertex values. Finally the point type
760  // is also stored but in NekInt64 format
761  // rather than an enum for binary stride
762  // compatibility.
763  if(boost::iequals(entitytype,"E")||
764  boost::iequals(entitytype,"F"))
765  {
766  // read in data
767  std::string elmtStr;
768  TiXmlNode* child = x->FirstChild();
769 
770  if (child->Type() == TiXmlNode::TINYXML_TEXT)
771  {
772  elmtStr = child->ToText()->ValueStr();
773  }
774 
775  std::vector<MeshCurvedInfo> cinfo;
777  cinfo);
778 
779  // unpack list of curved edge or faces
780  for(int i = 0; i < cinfo.size(); ++i)
781  {
782  MeshCurved c;
783  c.id = cinfo[i].id;
784  c.entitytype = entitytype[0];
785  c.entityid = cinfo[i].entityid;
786  c.npoints = cinfo[i].npoints;
787  c.type = kPointsTypeStr[cinfo[i].ptype];
788  c.ptid = cinfo[i].ptid;
789  c.ptoffset = cinfo[i].ptoffset;
790  m_meshCurved[std::make_pair(c.entitytype,
791  c.id)] = c;
792  }
793  }
794  else if(boost::iequals(entitytype,"DATAPOINTS"))
795  {
796  MeshCurvedPts cpts;
797  NekInt id;
798 
799  ASSERTL0(x->Attribute("ID", &id),
800  "Failed to get ID from PTS section");
801  cpts.id = id;
802 
803  // read in data
804  std::string elmtStr;
805 
806  TiXmlElement* DataIdx =
807  x->FirstChildElement("INDEX");
808  ASSERTL0(DataIdx,
809  "Cannot read data index tag in compressed "
810  "curved section");
811 
812  TiXmlNode* child = DataIdx->FirstChild();
813  if (child->Type() == TiXmlNode::TINYXML_TEXT)
814  {
815  elmtStr = child->ToText()->ValueStr();
816  }
817 
819  cpts.index);
820 
821  TiXmlElement* DataPts
822  = x->FirstChildElement("POINTS");
823  ASSERTL0(DataPts,
824  "Cannot read data pts tag in compressed "
825  "curved section");
826 
827  child = DataPts->FirstChild();
828  if (child->Type() == TiXmlNode::TINYXML_TEXT)
829  {
830  elmtStr = child->ToText()->ValueStr();
831  }
832 
834  cpts.pts);
835 
836  m_meshCurvedPts[cpts.id] = cpts;
837  }
838  else
839  {
840  ASSERTL0(false, "Unknown tag in curved section");
841  }
842 
843  x = x->NextSiblingElement();
844  }
845  else
846  {
847  MeshCurved c;
848  ASSERTL0(x->Attribute("ID", &c.id),
849  "Failed to get attribute ID");
850  c.type = std::string(x->Attribute("TYPE"));
851  ASSERTL0(!c.type.empty(),
852  "Failed to get attribute TYPE");
853  ASSERTL0(x->Attribute("NUMPOINTS", &c.npoints),
854  "Failed to get attribute NUMPOINTS");
855  c.data = x->FirstChild()->ToText()->Value();
856  c.entitytype = x->Value()[0];
857 
858  if (c.entitytype == "E")
859  {
860  ASSERTL0(x->Attribute("EDGEID", &c.entityid),
861  "Failed to get attribute EDGEID");
862  }
863  else if (c.entitytype == "F")
864  {
865  ASSERTL0(x->Attribute("FACEID", &c.entityid),
866  "Failed to get attribute FACEID");
867  }
868  else
869  {
870  ASSERTL0(false, "Unknown curve type.");
871  }
872 
873  m_meshCurved[std::make_pair(c.entitytype, c.id)] = c;
874  x = x->NextSiblingElement();
875  }
876  }
877  }
878 
879  // Read composites
880  vSubElement = pSession->GetElement("Nektar/Geometry/Composite");
881  ASSERTL0(vSubElement, "Cannot read composites.");
882  x = vSubElement->FirstChildElement();
883  while(x)
884  {
885  TiXmlAttribute* y = x->FirstAttribute();
886  ASSERTL0(y, "Failed to get attribute.");
887  MeshEntity c;
888  c.id = y->IntValue();
889  std::string vSeqStr = x->FirstChild()->ToText()->Value();
890  c.type = vSeqStr[0];
891  std::string::size_type indxBeg = vSeqStr.find_first_of('[') + 1;
892  std::string::size_type indxEnd = vSeqStr.find_last_of(']') - 1;
893  vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
894 
895  std::vector<unsigned int> vSeq;
896  ParseUtils::GenerateSeqVector(vSeqStr.c_str(), vSeq);
897 
898  for (int i = 0; i < vSeq.size(); ++i)
899  {
900  c.list.push_back(vSeq[i]);
901  }
902  m_meshComposites[c.id] = c;
903  x = x->NextSiblingElement();
904  }
905 
906  // Read Domain
907  vSubElement = pSession->GetElement("Nektar/Geometry/Domain");
908  ASSERTL0(vSubElement, "Cannot read domain");
909  std::string vSeqStr = vSubElement->FirstChild()->ToText()->Value();
910  std::string::size_type indxBeg = vSeqStr.find_first_of('[') + 1;
911  std::string::size_type indxEnd = vSeqStr.find_last_of(']') - 1;
912  vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
913  ParseUtils::GenerateSeqVector(vSeqStr.c_str(), m_domain);
914  }
boost::int32_t NekInt
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
std::map< std::string, std::string > m_vertexAttributes
std::map< int, MeshEntity > m_meshComposites
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:69
std::map< int, MeshVertex > m_meshVertices
std::map< MeshCurvedKey, MeshCurved > m_meshCurved
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
std::map< int, MeshEntity > m_meshElements
std::vector< unsigned int > m_domain
std::map< int, MeshEntity > m_meshEdges
std::map< int, MeshEntity > m_meshFaces
std::map< int, MeshCurvedPts > m_meshCurvedPts
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:243
void Nektar::LibUtilities::MeshPartition::WeightElements ( )
private

Definition at line 1055 of file MeshPartition.cpp.

References ASSERTL0, CalculateElementWeight(), Nektar::iterator, m_dim, m_domain, m_expansions, m_fieldNameToId, m_meshComposites, m_meshElements, m_numFields, and m_vertWeights.

Referenced by PartitionMesh().

1056  {
1057  std::vector<unsigned int> weight(m_numFields, 1);
1059  for (eIt = m_meshElements.begin(); eIt != m_meshElements.end(); ++eIt)
1060  {
1061  m_vertWeights[eIt->first] = weight;
1062  }
1063 
1064  for (unsigned int i = 0; i < m_domain.size(); ++i)
1065  {
1066  int cId = m_domain[i];
1067  NummodesPerField npf = m_expansions[cId];
1068 
1069  for (NummodesPerField::iterator it = npf.begin(); it != npf.end(); ++it)
1070  {
1071  ASSERTL0(it->second.size() == m_dim,
1072  " Number of directional" \
1073  " modes in expansion spec for composite id = " +
1074  boost::lexical_cast<std::string>(cId) +
1075  " and field " +
1076  boost::lexical_cast<std::string>(it->first) +
1077  " does not correspond to mesh dimension");
1078 
1079  int na = it->second[0];
1080  int nb = 0;
1081  int nc = 0;
1082  if (m_dim >= 2)
1083  {
1084  nb = it->second[1];
1085  }
1086  if (m_dim == 3)
1087  {
1088  nc = it->second[2];
1089  }
1090 
1091  int bndWeight = CalculateElementWeight(
1092  m_meshComposites[cId].type, true, na, nb, nc);
1093 
1094  for (unsigned int j = 0; j < m_meshComposites[cId].list.size(); ++j)
1095  {
1096  int elmtId = m_meshComposites[cId].list[j];
1097  m_vertWeights[elmtId][m_fieldNameToId[it->first]] = bndWeight;
1098  }
1099  }
1100  } // for i
1101  }
int CalculateElementWeight(char elmtType, bool bndWeight, int na, int nb, int nc)
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
std::map< int, MeshEntity > m_meshComposites
std::map< int, MultiWeight > m_vertWeights
std::map< std::string, NumModes > NummodesPerField
std::map< std::string, int > m_fieldNameToId
std::map< int, NummodesPerField > m_expansions
std::map< int, MeshEntity > m_meshElements
std::vector< unsigned int > m_domain
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
void Nektar::LibUtilities::MeshPartition::WriteAllPartitions ( LibUtilities::SessionReaderSharedPtr pSession)

Definition at line 140 of file MeshPartition.cpp.

References m_localPartition, OutputPartition(), and Nektar::LibUtilities::PortablePath().

141  {
142  for (int i = 0; i < m_localPartition.size(); ++i)
143  {
144  TiXmlDocument vNew;
145  TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "utf-8", "");
146  vNew.LinkEndChild(decl);
147 
148  TiXmlElement* vElmtNektar;
149  vElmtNektar = new TiXmlElement("NEKTAR");
150 
151  OutputPartition(pSession, m_localPartition[i], vElmtNektar);
152 
153  vNew.LinkEndChild(vElmtNektar);
154 
155  std::string dirname = pSession->GetSessionName() + "_xml";
156  fs::path pdirname(dirname);
157 
158  boost::format pad("P%1$07d.xml");
159  pad % i;
160  fs::path pFilename(pad.str());
161 
162  fs::path fullpath = pdirname / pFilename;
163 
164  if(!fs::is_directory(dirname))
165  {
166  fs::create_directory(dirname);
167  }
168 
169  vNew.SaveFile(PortablePath(fullpath));
170  }
171  }
std::vector< BoostSubGraph > m_localPartition
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
void OutputPartition(SessionReaderSharedPtr &pSession, BoostSubGraph &pGraph, TiXmlElement *pGeometry)
void Nektar::LibUtilities::MeshPartition::WriteLocalPartition ( LibUtilities::SessionReaderSharedPtr pSession)

Definition at line 110 of file MeshPartition.cpp.

References m_comm, m_localPartition, OutputPartition(), and Nektar::LibUtilities::PortablePath().

111  {
112  TiXmlDocument vNew;
113  TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "utf-8", "");
114  vNew.LinkEndChild(decl);
115 
116  TiXmlElement* vElmtNektar;
117  vElmtNektar = new TiXmlElement("NEKTAR");
118 
119  int rank = m_comm->GetRowComm()->GetRank();
120  OutputPartition(pSession, m_localPartition[rank], vElmtNektar);
121 
122  vNew.LinkEndChild(vElmtNektar);
123 
124  std::string dirname = pSession->GetSessionName() + "_xml";
125  fs::path pdirname(dirname);
126 
127  boost::format pad("P%1$07d.xml");
128  pad % rank;
129  fs::path pFilename(pad.str());
130 
131  if(!fs::is_directory(dirname))
132  {
133  fs::create_directory(dirname);
134  }
135 
136  fs::path fullpath = pdirname / pFilename;
137  vNew.SaveFile(PortablePath(fullpath));
138  }
std::vector< BoostSubGraph > m_localPartition
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
void OutputPartition(SessionReaderSharedPtr &pSession, BoostSubGraph &pGraph, TiXmlElement *pGeometry)

Member Data Documentation

BndRegionOrdering Nektar::LibUtilities::MeshPartition::m_bndRegOrder
private

Definition at line 199 of file MeshPartition.h.

Referenced by GetBndRegionOrdering(), and OutputPartition().

CommSharedPtr Nektar::LibUtilities::MeshPartition::m_comm
private

Definition at line 204 of file MeshPartition.h.

Referenced by PartitionGraph(), and WriteLocalPartition().

int Nektar::LibUtilities::MeshPartition::m_dim
private
std::vector<unsigned int> Nektar::LibUtilities::MeshPartition::m_domain
private

Definition at line 189 of file MeshPartition.h.

Referenced by OutputPartition(), PrintPartInfo(), ReadGeometry(), and WeightElements().

std::map<int, NummodesPerField> Nektar::LibUtilities::MeshPartition::m_expansions
private

Definition at line 194 of file MeshPartition.h.

Referenced by PrintPartInfo(), ReadExpansions(), and WeightElements().

std::map<std::string, int> Nektar::LibUtilities::MeshPartition::m_fieldNameToId
private

Definition at line 196 of file MeshPartition.h.

Referenced by ReadExpansions(), and WeightElements().

bool Nektar::LibUtilities::MeshPartition::m_isCompressed
private

Definition at line 124 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

std::vector<BoostSubGraph> Nektar::LibUtilities::MeshPartition::m_localPartition
private
BoostSubGraph Nektar::LibUtilities::MeshPartition::m_mesh
private

Definition at line 201 of file MeshPartition.h.

Referenced by PartitionMesh(), and PrintPartInfo().

std::map<int, MeshEntity> Nektar::LibUtilities::MeshPartition::m_meshComposites
private
std::map<MeshCurvedKey, MeshCurved> Nektar::LibUtilities::MeshPartition::m_meshCurved
private

Definition at line 186 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

std::map<int, MeshCurvedPts> Nektar::LibUtilities::MeshPartition::m_meshCurvedPts
private

Definition at line 187 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

std::map<int, MeshEntity> Nektar::LibUtilities::MeshPartition::m_meshEdges
private

Definition at line 183 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

std::map<int, MeshEntity> Nektar::LibUtilities::MeshPartition::m_meshElements
private
std::map<int, MeshEntity> Nektar::LibUtilities::MeshPartition::m_meshFaces
private

Definition at line 184 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

std::map<int, MeshVertex> Nektar::LibUtilities::MeshPartition::m_meshVertices
private

Definition at line 182 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

int Nektar::LibUtilities::MeshPartition::m_numFields
private

Definition at line 180 of file MeshPartition.h.

Referenced by ReadExpansions(), and WeightElements().

bool Nektar::LibUtilities::MeshPartition::m_shared
private

Definition at line 207 of file MeshPartition.h.

Referenced by PartitionGraph(), and PartitionMesh().

std::map<std::string, std::string> Nektar::LibUtilities::MeshPartition::m_vertexAttributes
private

Definition at line 190 of file MeshPartition.h.

Referenced by OutputPartition(), and ReadGeometry().

std::map<int, MultiWeight> Nektar::LibUtilities::MeshPartition::m_vertWeights
private

Definition at line 197 of file MeshPartition.h.

Referenced by CreateGraph(), and WeightElements().

bool Nektar::LibUtilities::MeshPartition::m_weightingRequired
private

Definition at line 206 of file MeshPartition.h.

Referenced by CreateGraph(), PartitionGraph(), PartitionMesh(), and ReadConditions().