Chi-Tech
MeshGenerator_01_setupmesh.cc
Go to the documentation of this file.
1#include "MeshGenerator.h"
2
3#include "mesh/Cell/cell.h"
6
7#include "chi_log.h"
8
9namespace chi_mesh
10{
11/**Builds a cell-graph and executes the partitioner.*/
12std::vector<int64_t>
14 int num_partitions)
15{
16 const auto& raw_cells = input_umesh.GetRawCells();
17 const size_t num_raw_cells = raw_cells.size();
18
19 ChiLogicalErrorIf(num_raw_cells == 0, "No cells in final input mesh");
20
21 //============================================= Build cell graph and centroids
22 typedef std::vector<uint64_t> CellGraphNode;
23 typedef std::vector<CellGraphNode> CellGraph;
24 CellGraph cell_graph;
25 std::vector<chi_mesh::Vector3> cell_centroids;
26
27 cell_graph.reserve(num_raw_cells);
28 cell_centroids.reserve(num_raw_cells);
29 {
30 for (const auto& raw_cell_ptr : raw_cells)
31 {
32 CellGraphNode cell_graph_node; // <-- Note A
33 for (auto& face : raw_cell_ptr->faces)
34 if (face.has_neighbor) cell_graph_node.push_back(face.neighbor);
35
36 cell_graph.push_back(cell_graph_node);
37 cell_centroids.push_back(raw_cell_ptr->centroid);
38 }
39 }
40
41 // Note A: We do not add the diagonal here. If we do it, ParMETIS seems
42 // to produce sub-optimal partitions
43
44 //============================================= Execute partitioner
45 std::vector<int64_t> cell_pids =
46 partitioner_->Partition(cell_graph, cell_centroids, num_partitions);
47
48 std::vector<size_t> partI_num_cells(num_partitions, 0);
49 for (int64_t pid : cell_pids)
50 partI_num_cells[pid] += 1;
51
52 size_t max_num_cells = partI_num_cells.front();
53 size_t min_num_cells = partI_num_cells.front();
54 size_t avg_num_cells = 0;
55 for (size_t count : partI_num_cells)
56 {
57 max_num_cells = std::max(max_num_cells, count);
58 min_num_cells = std::min(min_num_cells, count);
59 avg_num_cells += count;
60 }
61 avg_num_cells /= num_partitions;
62
63 Chi::log.Log() << "Partitioner num_cells allocated max,min,avg = "
64 << max_num_cells << "," << min_num_cells << "," << avg_num_cells;
65
66 return cell_pids;
67}
68
69/**Executes the partitioner and configures the mesh as a real mesh.*/
70std::shared_ptr<MeshContinuum>
71MeshGenerator::SetupMesh(std::unique_ptr<UnpartitionedMesh> input_umesh_ptr,
72 const std::vector<int64_t>& cell_pids)
73{
74 //============================================= Convert mesh
75 auto grid_ptr = chi_mesh::MeshContinuum::New();
76
77 grid_ptr->GetBoundaryIDMap() =
78 input_umesh_ptr->GetMeshOptions().boundary_id_map;
79
80 auto& vertex_subs = input_umesh_ptr->GetVertextCellSubscriptions();
81 size_t cell_globl_id = 0;
82 for (auto& raw_cell : input_umesh_ptr->GetRawCells())
83 {
84 if (CellHasLocalScope(Chi::mpi.location_id,
85 *raw_cell,
86 cell_globl_id,
87 vertex_subs,
88 cell_pids))
89 {
90 auto cell =
91 SetupCell(*raw_cell,
92 cell_globl_id,
93 cell_pids[cell_globl_id],
94 STLVertexListHelper(input_umesh_ptr->GetVertices()));
95
96 for (uint64_t vid : cell->vertex_ids_)
97 grid_ptr->vertices.Insert(vid, input_umesh_ptr->GetVertices()[vid]);
98
99 grid_ptr->cells.push_back(std::move(cell));
100 }
101
102 delete raw_cell;
103 raw_cell = nullptr;
104
105 ++cell_globl_id;
106 } // for raw_cell
107
108 SetGridAttributes(*grid_ptr,
109 input_umesh_ptr->GetMeshAttributes(),
110 {input_umesh_ptr->GetMeshOptions().ortho_Nx,
111 input_umesh_ptr->GetMeshOptions().ortho_Ny,
112 input_umesh_ptr->GetMeshOptions().ortho_Nz});
113
114 grid_ptr->SetGlobalVertexCount(input_umesh_ptr->GetVertices().size());
115
116 ComputeAndPrintStats(*grid_ptr);
117
118 return grid_ptr;
119}
120
121} // namespace chi_mesh
#define ChiLogicalErrorIf(condition, message)
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
virtual std::vector< int64_t > Partition(const std::vector< std::vector< uint64_t > > &graph, const std::vector< chi_mesh::Vector3 > &centroids, int number_of_parts)=0
static std::shared_ptr< MeshContinuum > New()
bool CellHasLocalScope(int location_id, const chi_mesh::UnpartitionedMesh::LightWeightCell &lwcell, uint64_t cell_global_id, const std::vector< std::set< uint64_t > > &vertex_subscriptions, const std::vector< int64_t > &cell_partition_ids) const
std::shared_ptr< MeshContinuum > SetupMesh(std::unique_ptr< UnpartitionedMesh > input_umesh_ptr, const std::vector< int64_t > &cell_pids)
chi::GraphPartitioner * partitioner_
static void ComputeAndPrintStats(const chi_mesh::MeshContinuum &grid)
static void SetGridAttributes(chi_mesh::MeshContinuum &grid, MeshAttributes new_attribs, std::array< size_t, 3 > ortho_cells_per_dimension)
static std::unique_ptr< chi_mesh::Cell > SetupCell(const UnpartitionedMesh::LightWeightCell &raw_cell, uint64_t global_id, uint64_t partition_id, const VertexListHelper &vertices)
std::vector< int64_t > PartitionMesh(const UnpartitionedMesh &input_umesh, int num_partitions)
std::vector< LightWeightCell * > & GetRawCells()