37 #ifndef MESH_PARTITION_TOOL_H 38 #define MESH_PARTITION_TOOL_H 1
47 #include <boost/shared_ptr.hpp> 48 #include <Epetra_MpiComm.h> 49 #include <Teuchos_ParameterList.hpp> 51 #include <lifev/core/LifeV.hpp> 52 #include <lifev/core/fem/DOF.hpp> 53 #include <lifev/core/mesh/RegionMesh.hpp> 54 #include <lifev/core/mesh/GraphCutterParMETIS.hpp> 55 #include <lifev/core/mesh/GraphCutterZoltan.hpp> 56 #include <lifev/core/mesh/GraphUtil.hpp> 57 #include <lifev/core/mesh/MeshPartBuilder.hpp> 98 template <
typename MeshType>
132 const std::shared_ptr<Epetra_Comm>& comm,
133 const Teuchos::ParameterList parameters
142 void showMe (std::ostream& output = std::cout)
const;
183 return M_secondStageParts->at (0);
234 template <
typename MeshType>
237 const std::shared_ptr<Epetra_Comm>& comm,
238 const Teuchos::ParameterList parameters) :
253 if (! M_graphLib.compare (
"parmetis") )
255 M_graphCutter.reset (
new GraphCutterParMETIS<mesh_Type> (M_originalMesh, M_comm, M_parameters) );
257 else if (! M_graphLib.compare (
"zoltan") )
259 M_graphCutter.reset (
new GraphCutterZoltan<mesh_Type> (M_originalMesh, M_comm, M_parameters) );
263 std::cout <<
"Graph partitioner type not defined.\n";
273 template <
typename MeshType>
278 std::cout <<
"Partitioning mesh graph ..." << std::endl;
282 if (M_graphCutter->run() )
291 M_graphCutter.reset();
294 bool offlineMode = M_parameters.get<
bool> (
"offline-mode",
false);
301 std::cout <<
"Performing second stage partitioning ..." 306 std::shared_ptr<Epetra_Comm>
307 secondStageComm (
new Epetra_MpiComm (MPI_COMM_SELF) );
309 std::shared_ptr<Epetra_Comm>
310 secondStageComm (
new Epetra_SerialComm);
313 Teuchos::ParameterList secondStageParams;
314 secondStageParams.set<Int> (
"num-parts", M_secondStageNumParts);
315 secondStageParams.set<Int> (
"my-pid", M_myPID);
316 secondStageParams.set<
bool> (
"verbose",
false);
319 M_secondStageParts->resize (1);
321 const idListPtr_Type currentIds = graph->at (M_myPID);
322 partitionGraphParMETIS (currentIds, *M_originalMesh,
324 M_secondStageParts->at (0),
329 M_secondStageParts->resize (graph->size() );
331 for (size_t i = 0; i < graph->size(); ++i)
333 const idListPtr_Type& currentIds = graph->at (i);
334 partitionGraphParMETIS (currentIds, *M_originalMesh,
336 M_secondStageParts->at (i),
345 std::cout <<
"Filling entity PID lists ..." << std::endl;
347 fillEntityPID (graph);
351 std::cout <<
"Building mesh parts ..." << std::endl;
357 M_meshPart.reset (
new mesh_Type (M_comm) );
358 M_meshPart->setIsPartitioned (
true);
359 M_meshPartBuilder->run (M_meshPart, graph, M_entityPID, M_myPID);
368 M_meshPartBuilder->reset();
376 if (M_comm->NumProc() != 1)
380 std::cout <<
"Offline partition must be done in serial." 393 Int numParts = M_parameters.get<Int> (
"num-parts");
394 M_allMeshParts.reset (
new partMesh_Type (numParts) );
395 for (
Int curPart = 0; curPart < numParts; ++curPart)
399 M_allMeshParts->at (curPart).reset (
new mesh_Type);
400 M_allMeshParts->at (curPart)->setIsPartitioned (
true);
401 M_meshPartBuilder->run (M_allMeshParts->at (curPart),
407 * (graph->at (curPart) ) = backup;
416 M_meshPartBuilder->reset();
426 std::cout <<
"Mesh partition complete." << std::endl;
429 M_meshPartBuilder.reset();
431 M_originalMesh.reset();
434 template<
typename MeshType>
436 MeshPartitionTool<MeshType>::fillEntityPID (idTablePtr_Type graph)
438 Int numParts = graph->size();
441 M_entityPID.points.resize ( M_originalMesh->numPoints(), 0 );
442 M_entityPID.elements.resize ( M_originalMesh->numElements(), 0 );
443 M_entityPID.facets.resize ( M_originalMesh->numFacets(), 0 );
444 M_entityPID.ridges.resize ( M_originalMesh->numRidges(), 0 );
448 for ( Int p = 1; p < numParts; p++ )
450 for ( UInt e = 0; e < graph->at (p)->size(); e++ )
453 for ( UInt k = 0; k < mesh_Type::element_Type::S_numPoints; k++ )
455 const ID& pointID = M_originalMesh->element ( graph->at (p)->at (e) ).point ( k ).id();
457 M_entityPID.points[ pointID ] = std::max ( M_entityPID.points[ pointID ], p );
461 const ID& elemID = M_originalMesh->element ( graph->at (p)->at (e) ).id();
463 M_entityPID.elements[ elemID ] = p;
466 for ( UInt k = 0; k < mesh_Type::element_Type::S_numFacets; k++ )
468 const ID& facetID = M_originalMesh->facet ( M_originalMesh->localFacetId ( elemID, k ) ).id();
470 M_entityPID.facets[ facetID ] = std::max ( M_entityPID.facets[ facetID ], p );
474 for ( UInt k = 0; k < mesh_Type::element_Type::S_numRidges; k++ )
476 const ID& ridgeID = M_originalMesh->ridge ( M_originalMesh->localRidgeId ( elemID, k ) ).id();
478 M_entityPID.ridges[ ridgeID ] = std::max ( M_entityPID.ridges[ ridgeID ], p );
484 template <
typename MeshType>
486 MeshPartitionTool < MeshType >::globalToLocal (
const Int curPart)
488 const std::map<Int, Int>& globalToLocalMap =
489 M_meshPartBuilder->globalToLocalElement();
490 idTable_Type& currentGraph = * (M_secondStageParts->at (curPart) );
492 for (size_t i = 0; i < currentGraph.size(); ++i)
494 int currentSize = currentGraph[i]->size();
495 idList_Type& currentElements = * (currentGraph[i]);
496 for (Int j = 0; j < currentSize; ++j)
498 currentElements[j] = globalToLocalMap.find (currentElements[j])->second;
503 template <
typename MeshType>
505 MeshPartitionTool < MeshType >::showMe (std::ostream& output)
const 507 output <<
"Sorry, this method is not implemented, yet." << std::endl
508 <<
"We appreciate your interest." << std::endl
509 <<
"Check back in a bit!" << std::endl;
Graph cutter base class (abstract)
int32_type Int
Generic integer data.
std::vector< LifeV::Int > idList_Type
Class that builds a mesh part, after the graph has been partitioned.
std::shared_ptr< idTable_Type > idTablePtr_Type