38 #include <vtkCellTypes.h> 43 const std::vector<int> &glbElmPartedIdx,
44 const std::vector<int> &glbElmConn,
57 for (
int ie : glbElmPartedIdx)
67 for (
int iNde = 0; iNde <
nNdeElm; iNde++)
69 int glbNdeIdx = glbElmConn[(glbElmIdx - 1) * nNdeElm + iNde];
86 partNdeIdx = it->second;
113 std::vector<double> x;
115 x.push_back(crds[in - 1]);
122 std::vector<double> x;
124 x.push_back(slns[ie - 1]);
132 std::vector<double> x;
134 for (
int iComp = 0; iComp < nComp; iComp++)
135 x.push_back(slns[(ie - 1) * nComp + iComp]);
173 for (
int i = 0; i < celltypes->GetNumberOfTypes(); ++i)
175 if (!(celltypes->IsType(VTK_TETRA)) && !(celltypes->IsType(VTK_TRIANGLE))) {
177 <<
"Partitioner works for 4-node tet and 3-node tri elements only." 186 elmConnVec = std::vector<int>(elmConnVec_nemId_t.begin(),
187 elmConnVec_nemId_t.end());
188 elmConn = elmConnVec;
190 for (
int &i : elmConnVec)
195 if (celltypes->IsType(VTK_TETRA))
197 else if (celltypes->IsType(VTK_TRIANGLE))
200 std::cerr <<
"Mesh with unsupported element types." << std::endl;
204 std::cout <<
" ------------------- Partitioner Stats ---------------------\n";
205 std::cout <<
"Mesh type : " 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 <<
" ----------------------------------------------------------" 224 if (inMesh->nbQuads != 0 || inMesh->nbHexes != 0 || inMesh->nbPrisms != 0)
226 std::cerr <<
"Partitioner works 4-node tet and 3-node tri elements only." 234 nNde = MAd::M_numVertices(inMesh);
235 elmConnVec = MAd::M_getConnectivities(inMesh);
236 elmConn.insert(elmConn.begin(), elmConnVec.begin(), elmConnVec.end());
238 for (
int &it : elmConn)
240 if (M_numTets(inMesh) > 0)
242 nElm = MAd::M_numRegions(inMesh);
245 else if (M_numTriangles(inMesh) > 0)
247 nElm = MAd::M_numTriangles(inMesh);
252 std::cerr <<
"Mesh with unsupported element types." << std::endl;
256 std::cout <<
" ------------------- Partitioner Stats ---------------------\n";
257 std::cout <<
"Mesh type : " << (meshType ==
MeshType_t::MESH_TRI_3 ?
"Triangular" :
"Tetrahedral") <<
"\n";
258 std::cout <<
"Number of nodes = " <<
nNde <<
"\n" 259 <<
"Number of elements = " <<
nElm <<
"\n";
260 std::cout <<
"Size of elmConn = " << elmConnVec.size() <<
"\n";
261 std::cout <<
"Min connectivity passed to partitioner = " 262 << *std::min_element(elmConnVec.begin(), elmConnVec.end()) <<
"\n";
263 std::cout <<
"Max connectivity passed to partitioner = " 264 << *std::max_element(elmConnVec.begin(), elmConnVec.end()) <<
"\n";
265 std::cout <<
" -----------------------------------------------------------" 272 setNPartition(nPartition);
281 std::cerr <<
"Number of partitions must be set." << std::endl;
285 std::cout <<
"Partitioning the mesh." << std::endl;
288 std::vector<idx_t> eptr(
nElm + 1);
290 epart.resize(
nElm, 0);
291 npart.resize(
nNde, 0);
297 for (
int iElm = 1; iElm <=
nElm; iElm++)
298 eptr[iElm] = iElm * 4;
303 for (
int iElm = 1; iElm <=
nElm; iElm++)
304 eptr[iElm] = iElm * 3;
308 std::cerr <<
"Unknown or unimplemented element type." << std::endl;
313 METIS_SetDefaultOptions(options);
314 options[METIS_OPTION_NUMBERING] = 0;
315 options[METIS_OPTION_CONTIG] = 1;
316 options[METIS_OPTION_PTYPE] = METIS_PTYPE_KWAY;
318 options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_VOL;
320 options[METIS_OPTION_UFACTOR] = 1;
369 res = METIS_PartMeshDual(&
nElm, &
nNde, &eptr[0], &elmConn[0],
nullptr,
370 nullptr, &ncommon, &nPart,
nullptr, options,
371 &objval, &epart[0], &npart[0]);
373 std::cout <<
"Received data from METIS" << std::endl;
379 std::cout <<
"Successfully partitioned the mesh." << std::endl;
382 npart.erase(npart.begin());
388 std::cerr <<
"Failed to partition with error code " << res << std::endl;
393 <<
"METIS is not enabled during build. Build NEMoSys with ENABLE_METIS to use this method." 402 std::vector<double> ndeParted(npart.begin(), npart.end());
408 std::vector<double> elmParted(epart.begin(), epart.end());
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());
426 for (
int iPart = 0; iPart < nPart; iPart++)
428 auto *newPart =
new meshPartition(iPart, epart, elmConnVec, meshType);
429 meshParts.push_back(newPart);
436 if (iPart > meshParts.size())
438 std::cerr <<
"requested partition number exceeds available partitions" 442 return meshParts[iPart]->getPartToGlobNodeMap();
447 if (iPart > meshParts.size())
449 std::cerr <<
"requested partition number exceeds available partitions" 453 return meshParts[iPart]->getPartToGlobElmMap();
std::vector< double > getPartedElm() const
std::map< int, int > getPartToGlobNodeMap(int iPart) const
std::map< int, int > getPartToGlobElmMap(int iPart) const
meshPartitioner(int nNde, int nElm, const std::vector< int > &elemConn, MeshType_t meshType)
A brief description of meshBase.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
meshPartition(int pidx, const std::vector< int > &glbElmPartedIdx, const std::vector< int > &glbElmConn, MeshType_t inMshType)
std::vector< int > globNdeIdx
std::map< int, int > ndeIdxPartToGlob
std::vector< double > getElmSlns(const std::vector< double > &slns) const
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes' dataSet
virtual std::vector< nemId_t > getConnectivities() const =0
get connectivities.
std::vector< double > getElmSlnsVec(const std::vector< double > &slns, int nComp) const
nemId_t getNumberOfPoints() const
return the number of points
std::map< int, int > ndeIdxGlobToPart
std::vector< int > globElmIdx
std::map< int, int > elmIdxGlobToPart
std::vector< int > partElmConn
nemId_t getNumberOfCells() const
return the number of cells
std::vector< double > getCrds(const std::vector< double > &crds) const
std::vector< double > getPartedNde() const
void setPartedElm(const std::vector< double > &prtElm)
std::map< int, int > elmIdxPartToGlob