NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
meshPartitioner Class Reference

Detailed Description

Definition at line 96 of file meshPartitioner.H.

Public Member Functions

 meshPartitioner (int nNde, int nElm, const std::vector< int > &elemConn, MeshType_t meshType)
 
 meshPartitioner (const meshBase *inMB)
 
 ~meshPartitioner ()
 
void setNPartition (int nPartition)
 
int getNPartition () const
 
int partition (int nPartition)
 
int partition ()
 
std::vector< double > getPartedNde () const
 
std::vector< double > getPartedElm () const
 
void setPartedElm (const std::vector< double > &prtElm)
 
std::vector< double > getCrds (int iPart, const std::vector< double > &crds) const
 
std::vector< int > getConns (int iPart) const
 
int getNNdePart (int iPart) const
 
int getNElmPart (int iPart) const
 
std::map< int, int > getPartToGlobNodeMap (int iPart) const
 
std::map< int, int > getPartToGlobElmMap (int iPart) const
 
std::vector< double > getNdeSlnScalar (int iPart, const std::vector< double > &slns) const
 
std::vector< double > getElmSlnScalar (int iPart, const std::vector< double > &slns) const
 
std::vector< double > getElmSlnVec (int iPart, const std::vector< double > &slns, int nComp) const
 

Private Member Functions

void buildPartitions ()
 

Private Attributes

int nNde
 
int nElm
 
int nPart
 
std::vector< int > elmConnVec
 
std::vector< int > elmConn
 
MeshType_t meshType
 
std::vector< int > epart
 
std::vector< int > npart
 
std::vector< meshPartition * > meshParts
 

Constructor & Destructor Documentation

◆ meshPartitioner() [1/2]

meshPartitioner::meshPartitioner ( int  nNde,
int  nElm,
const std::vector< int > &  elemConn,
MeshType_t  meshType 
)
inline

Definition at line 101 of file meshPartitioner.H.

Referenced by meshPartitioner().

103  :
105  {
106  elmConn.insert(elmConn.begin(), elemConn.begin(), elemConn.end());
107  }
MeshType_t meshType
std::vector< int > elmConn

◆ meshPartitioner() [2/2]

meshPartitioner::meshPartitioner ( const meshBase inMB)
explicit

Definition at line 169 of file meshPartitioner.C.

References meshBase::getConnectivities(), meshBase::getDataSet(), meshBase::getNumberOfCells(), meshBase::getNumberOfPoints(), MESH_TETRA_4, MESH_TRI_3, meshPartitioner(), meshPartition::nElm, NEM::MSH::New(), and meshPartition::nNde.

170 {
171  vtkSmartPointer<vtkCellTypes> celltypes = vtkSmartPointer<vtkCellTypes>::New();
172  inMB->getDataSet()->GetCellTypes(celltypes);
173  for (int i = 0; i < celltypes->GetNumberOfTypes(); ++i)
174  {
175  if (!(celltypes->IsType(VTK_TETRA)) && !(celltypes->IsType(VTK_TRIANGLE))) {
176  std::cerr
177  << "Partitioner works for 4-node tet and 3-node tri elements only."
178  << std::endl;
179  exit(-1);
180  }
181  }
182  nNde = inMB->getNumberOfPoints();
183  // FIXME: METIS uses int for vertex indices. NEMoSys uses nemId_t (= size_t).
184  // This is a narrowing conversion!
185  std::vector<nemId_t> elmConnVec_nemId_t = inMB->getConnectivities();
186  elmConnVec = std::vector<int>(elmConnVec_nemId_t.begin(),
187  elmConnVec_nemId_t.end());
189  // 1 based index for elmConnVec, 0 based for elmConn
190  for (int &i : elmConnVec)
191  {
192  i = i + 1;
193  }
194  nElm = inMB->getNumberOfCells();
195  if (celltypes->IsType(VTK_TETRA))
197  else if (celltypes->IsType(VTK_TRIANGLE))
199  else {
200  std::cerr << "Mesh with unsupported element types." << std::endl;
201  exit(-1);
202  }
203  nPart = 0;
204  std::cout << " ------------------- Partitioner Stats ---------------------\n";
205  std::cout << "Mesh type : "
206  << (meshType == MeshType_t::MESH_TRI_3 ? "Triangular"
207  : "Tetrahedral")
208  << "\n";
209  std::cout << "Number of nodes = " << nNde << "\n"
210  << "Number of elements = " << nElm << "\n";
211  std::cout << "Size of elmConn = " << elmConnVec.size() << "\n";
212  std::cout << "Min connectivity passed to partitioner = "
213  << *std::min_element(elmConnVec.begin(), elmConnVec.end()) << "\n";
214  std::cout << "Max connectivity passed to partitioner = "
215  << *std::max_element(elmConnVec.begin(), elmConnVec.end()) << "\n";
216  std::cout << " ----------------------------------------------------------"
217  << std::endl;
218 }
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
MeshType_t meshType
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
std::vector< int > elmConn
virtual std::vector< nemId_t > getConnectivities() const =0
get connectivities.
std::vector< int > elmConnVec
nemId_t getNumberOfPoints() const
return the number of points
Definition: meshBase.H:545
nemId_t getNumberOfCells() const
return the number of cells
Definition: meshBase.H:550

◆ ~meshPartitioner()

meshPartitioner::~meshPartitioner ( )
inline

Definition at line 121 of file meshPartitioner.H.

122  {
123  if (!meshParts.empty())
124  for (int iPart = 0; iPart < nPart; iPart++)
125  delete meshParts[iPart];
126  };
std::vector< meshPartition * > meshParts

Member Function Documentation

◆ buildPartitions()

void meshPartitioner::buildPartitions ( )
private

Definition at line 424 of file meshPartitioner.C.

References meshPartition::meshPartition().

425 {
426  for (int iPart = 0; iPart < nPart; iPart++)
427  {
428  auto *newPart = new meshPartition(iPart, epart, elmConnVec, meshType);
429  meshParts.push_back(newPart);
430  }
431 }
std::vector< int > epart
MeshType_t meshType
std::vector< meshPartition * > meshParts
std::vector< int > elmConnVec

◆ getConns()

std::vector<int> meshPartitioner::getConns ( int  iPart) const
inline

Definition at line 142 of file meshPartitioner.H.

143  { return meshParts[iPart]->getConns(); }
std::vector< meshPartition * > meshParts

◆ getCrds()

std::vector<double> meshPartitioner::getCrds ( int  iPart,
const std::vector< double > &  crds 
) const
inline

Definition at line 139 of file meshPartitioner.H.

141  { return meshParts[iPart]->getCrds(crds); }
std::vector< meshPartition * > meshParts

◆ getElmSlnScalar()

std::vector<double> meshPartitioner::getElmSlnScalar ( int  iPart,
const std::vector< double > &  slns 
) const
inline

Definition at line 158 of file meshPartitioner.H.

160  { return meshParts[iPart]->getElmSlns(slns); }
std::vector< meshPartition * > meshParts

◆ getElmSlnVec()

std::vector<double> meshPartitioner::getElmSlnVec ( int  iPart,
const std::vector< double > &  slns,
int  nComp 
) const
inline

Definition at line 161 of file meshPartitioner.H.

164  { return meshParts[iPart]->getElmSlnsVec(slns, nComp); }
std::vector< meshPartition * > meshParts

◆ getNdeSlnScalar()

std::vector<double> meshPartitioner::getNdeSlnScalar ( int  iPart,
const std::vector< double > &  slns 
) const
inline

Definition at line 154 of file meshPartitioner.H.

156  { return getCrds(iPart, slns); }
std::vector< double > getCrds(int iPart, const std::vector< double > &crds) const

◆ getNElmPart()

int meshPartitioner::getNElmPart ( int  iPart) const
inline

Definition at line 145 of file meshPartitioner.H.

145 { return meshParts[iPart]->nElm; }
std::vector< meshPartition * > meshParts

◆ getNNdePart()

int meshPartitioner::getNNdePart ( int  iPart) const
inline

Definition at line 144 of file meshPartitioner.H.

144 { return meshParts[iPart]->nNde; }
std::vector< meshPartition * > meshParts

◆ getNPartition()

int meshPartitioner::getNPartition ( ) const
inline

Definition at line 130 of file meshPartitioner.H.

130 { return nPart; }

◆ getPartedElm()

std::vector< double > meshPartitioner::getPartedElm ( ) const

Definition at line 406 of file meshPartitioner.C.

407 {
408  std::vector<double> elmParted(epart.begin(), epart.end());
409  return elmParted;
410 }
std::vector< int > epart

◆ getPartedNde()

std::vector< double > meshPartitioner::getPartedNde ( ) const

Definition at line 400 of file meshPartitioner.C.

401 {
402  std::vector<double> ndeParted(npart.begin(), npart.end());
403  return ndeParted;
404 }
std::vector< int > npart

◆ getPartToGlobElmMap()

std::map< int, int > meshPartitioner::getPartToGlobElmMap ( int  iPart) const

Definition at line 445 of file meshPartitioner.C.

446 {
447  if (iPart > meshParts.size())
448  {
449  std::cerr << "requested partition number exceeds available partitions"
450  << std::endl;
451  exit(1);
452  }
453  return meshParts[iPart]->getPartToGlobElmMap();
454 }
std::vector< meshPartition * > meshParts

◆ getPartToGlobNodeMap()

std::map< int, int > meshPartitioner::getPartToGlobNodeMap ( int  iPart) const

Definition at line 434 of file meshPartitioner.C.

435 {
436  if (iPart > meshParts.size())
437  {
438  std::cerr << "requested partition number exceeds available partitions"
439  << std::endl;
440  exit(1);
441  }
442  return meshParts[iPart]->getPartToGlobNodeMap();
443 }
std::vector< meshPartition * > meshParts

◆ partition() [1/2]

int meshPartitioner::partition ( int  nPartition)

Definition at line 270 of file meshPartitioner.C.

271 {
272  setNPartition(nPartition);
273  return partition();
274 }
void setNPartition(int nPartition)

◆ partition() [2/2]

int meshPartitioner::partition ( )

Definition at line 276 of file meshPartitioner.C.

References MESH_TETRA_4, MESH_TRI_3, meshPartition::nElm, and meshPartition::nNde.

277 {
278  // check
279  if (nPart == 0)
280  {
281  std::cerr << "Number of partitions must be set." << std::endl;
282  exit(-1);
283  }
284 
285  std::cout << "Partitioning the mesh." << std::endl;
286 #ifdef HAVE_METIS
287  // prepare metis datastructs
288  std::vector<idx_t> eptr(nElm + 1);
289  idx_t objval = 0;
290  epart.resize(nElm, 0);
291  npart.resize(nNde, 0);
292  int ncommon = 1;
293  switch (meshType)
294  {
296  eptr[0] = 0;
297  for (int iElm = 1; iElm <= nElm; iElm++)
298  eptr[iElm] = iElm * 4;
299  ncommon = 3;
300  break;
302  eptr[0] = 0;
303  for (int iElm = 1; iElm <= nElm; iElm++)
304  eptr[iElm] = iElm * 3;
305  ncommon = 2;
306  break;
307  default:
308  std::cerr << "Unknown or unimplemented element type." << std::endl;
309  }
310  // setting options (some default values, should be tailored)
311  int res;
312 
313  METIS_SetDefaultOptions(options);
314  options[METIS_OPTION_NUMBERING] = 0; // 0-based index
315  options[METIS_OPTION_CONTIG] = 1; // try for contiguous partitions
316  options[METIS_OPTION_PTYPE] = METIS_PTYPE_KWAY; // multilevel k-way partitioning
317  //options[METIS_OPTION_PTYPE] = METIS_PTYPE_RB; // multilevel recursive bisectioning
318  options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_VOL; // minimize edge cut METIS_OBJTYPE_VOL(comm vol)
319  //options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
320  options[METIS_OPTION_UFACTOR] = 1; // load imbalance of 1.001
321  //options[METIS_OPTION_CTYPE] = METIS_CTYPE_SHEM; // sorted heavy-edge matching
322 
323  // To try to match METIS in Rocstar partitioner, the options can be changed to:
324  // - Add SHEM method: options[METIS_OPTION_CTYPE] = METIS_CTYPE_SHEM;
325  // - Replace KWAY with RB: options[METIS_OPTION_PTYPE] = METIS_PTYPE_RB
326  // - Replace VOL with CUT: options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT
327 
328  //options[METIS_OPTION_DBGLVL] = METIS_DBG_INFO | METIS_DBG_TIME |
329  // METIS_DBG_CONNINFO | METIS_DBG_CONTIGINFO;
330  res = METIS_OK;
331 
332  /*
333  // DEBUG: checking equivalent graph of the mesh
334  std::cout << "METIS: Calculating mesh dual graph...." << std::endl;
335  idx_t *xadj, *adjncy;
336  idx_t numflag = 0;
337  res = METIS_MeshToDual(&nElm, &nNde, &eptr[0], &elmConn[0], &ncommon,
338  &numflag, &xadj, &adjncy);
339  std::ofstream graphFile;
340  graphFile.open("dualGraph.txt");
341  for (int iElm = 0; iElm < nElm; iElm++)
342  {
343  graphFile << " Elm Idx " << iElm + 1 << " -> ";
344  for (int iAdj = xadj[iElm]; iAdj < xadj[iElm + 1]; iAdj++)
345  graphFile << adjncy[iAdj] << " ";
346  graphFile << " *** " << std::endl;
347  }
348  graphFile.close();
349  std::cout << "Dual graph for the mesh is written to -> dualGraph.txt "
350  << std::endl;
351  */
352 
353  // calling metis partioner
354  if (nPart > 1)
355  {
356  /*
357  // DEBUG Information
358  std::cout << "Sending data to METIS..." << std::endl;
359  std::cout << "nElm = " << nElm << std::endl;
360  std::cout << "nNde = " << nNde << std::endl;
361  std::cout << "eptr[0] = " << eptr[0] << std::endl;
362  std::cout << "eptr[end] = " << eptr[nElm] << std::endl;
363  std::cout << "eind = " << elmConn[0] << std::endl;
364  */
365 
366 // res = METIS_PartMeshNodal(&nElm, &nNde, &eptr[0], &elmConn[0], nullptr,
367 // nullptr, &nPart, nullptr, options, &objval,
368 // &epart[0], &npart[0]);
369  res = METIS_PartMeshDual(&nElm, &nNde, &eptr[0], &elmConn[0], nullptr,
370  nullptr, &ncommon, &nPart, nullptr, options,
371  &objval, &epart[0], &npart[0]);
372 
373  std::cout << "Received data from METIS" << std::endl;
374  }
375  // output partitioning results
376  // check success
377  if (res == METIS_OK)
378  {
379  std::cout << "Successfully partitioned the mesh." << std::endl;
380  // removing the first member of the npart as default
381  // index starts from 1
382  npart.erase(npart.begin());
383  buildPartitions();
384  return 0;
385  }
386  else
387  {
388  std::cerr << "Failed to partition with error code " << res << std::endl;
389  return 1;
390  }
391 #else
392  std::cerr
393  << "METIS is not enabled during build. Build NEMoSys with ENABLE_METIS to use this method."
394  << std::endl;
395  exit(1);
396 #endif
397 }
std::vector< int > epart
MeshType_t meshType
std::vector< int > npart
std::vector< int > elmConn

◆ setNPartition()

void meshPartitioner::setNPartition ( int  nPartition)
inline

Definition at line 129 of file meshPartitioner.H.

129 { nPart = nPartition; }

◆ setPartedElm()

void meshPartitioner::setPartedElm ( const std::vector< double > &  prtElm)

Definition at line 413 of file meshPartitioner.C.

414 {
415  int minp, maxp;
416  minp = (int)*std::min_element(prtElm.begin(), prtElm.end());
417  maxp = (int)*std::max_element(prtElm.begin(), prtElm.end());
418  setNPartition(maxp - minp + 1);
419  epart.insert(epart.begin(), prtElm.begin(), prtElm.end());
420  buildPartitions();
421 }
std::vector< int > epart
void setNPartition(int nPartition)

Member Data Documentation

◆ elmConn

std::vector<int> meshPartitioner::elmConn
private

Definition at line 174 of file meshPartitioner.H.

◆ elmConnVec

std::vector<int> meshPartitioner::elmConnVec
private

Definition at line 173 of file meshPartitioner.H.

◆ epart

std::vector<int> meshPartitioner::epart
private

Definition at line 180 of file meshPartitioner.H.

◆ meshParts

std::vector<meshPartition *> meshPartitioner::meshParts
private

Definition at line 183 of file meshPartitioner.H.

◆ meshType

MeshType_t meshPartitioner::meshType
private

Definition at line 175 of file meshPartitioner.H.

◆ nElm

int meshPartitioner::nElm
private

Definition at line 171 of file meshPartitioner.H.

◆ nNde

int meshPartitioner::nNde
private

Definition at line 170 of file meshPartitioner.H.

◆ nPart

int meshPartitioner::nPart
private

Definition at line 172 of file meshPartitioner.H.

◆ npart

std::vector<int> meshPartitioner::npart
private

Definition at line 181 of file meshPartitioner.H.


The documentation for this class was generated from the following files: