Chi-Tech
MeshGenerator.cc
Go to the documentation of this file.
1#include "MeshGenerator.h"
2
9
10#include "ChiObjectFactory.h"
11
12#include "chi_runtime.h"
13#include "chi_log.h"
14
15namespace chi_mesh
16{
17
19
21{
23
24 params.SetGeneralDescription("The base class for all mesh generators");
25 params.SetDocGroup("doc_MeshGenerators");
26
28 "scale", 1.0, "Uniform scale to apply to the mesh after reading.");
29
31 "inputs",
32 std::vector<size_t>{},
33 "A list of handles to MeshGenerator objects");
34
36 "partitioner",
37 0,
38 "Handle to a GraphPartitioner object to use for parallel partitioning."
39 "This will default to PETScGraphPartitioner with a \"parmetis\" setting");
40
42 "replicated_mesh",
43 false,
44 "Flag, when set, makes the mesh appear in full fidelity on each process");
45
46 return params;
47}
48
50 : ChiObject(params),
51 scale_(params.GetParamValue<double>("scale")),
52 replicated_(params.GetParamValue<bool>("replicated_mesh"))
53{
54 //============================================= Convert input handles
55 auto input_handles = params.GetParamVectorValue<size_t>("inputs");
56
57 for (const size_t input_handle : input_handles)
58 {
59 auto& mesh_generator = Chi::GetStackItem<MeshGenerator>(
60 Chi::object_stack, input_handle, __FUNCTION__);
61 inputs_.push_back(&mesh_generator);
62 }
63
64 //============================================= Set partitioner
65 size_t partitioner_handle;
66 if (params.ParametersAtAssignment().Has("partitioner"))
67 partitioner_handle = params.GetParamValue<size_t>("partitioner");
68 else
69 {
70 auto& factory = ChiObjectFactory::GetInstance();
72 partitioner_handle = factory.MakeRegisteredObjectOfType(
73 "chi::PETScGraphPartitioner", chi::ParameterBlock());
74 }
75 partitioner_ = &Chi::GetStackItem<chi::GraphPartitioner>(
76 Chi::object_stack, partitioner_handle, __FUNCTION__);
77}
78
79// ##################################################################
80/**Default behavior here is to return the input umesh unaltered.*/
81std::unique_ptr<UnpartitionedMesh> MeshGenerator::GenerateUnpartitionedMesh(
82 std::unique_ptr<UnpartitionedMesh> input_umesh)
83{
84 return input_umesh;
85}
86
87/**Final execution step. */
89{
90 //======================================== Execute all input generators
91 // Note these could be empty
92 std::unique_ptr<UnpartitionedMesh> current_umesh = nullptr;
93 for (auto mesh_generator_ptr : inputs_)
94 {
95 auto new_umesh =
96 mesh_generator_ptr->GenerateUnpartitionedMesh(std::move(current_umesh));
97 current_umesh = std::move(new_umesh);
98 }
99
100 //======================================== Generate final umesh and convert it
101 current_umesh = GenerateUnpartitionedMesh(std::move(current_umesh));
102
103 std::vector<int64_t> cell_pids;
104 if (Chi::mpi.location_id == 0)
105 cell_pids = PartitionMesh(*current_umesh, Chi::mpi.process_count);
106
107 BroadcastPIDs(cell_pids, 0, Chi::mpi.comm);
108
109 auto grid_ptr = SetupMesh(std::move(current_umesh), cell_pids);
110
111 //======================================== Assign the mesh to a VolumeMesher
112 auto new_mesher =
113 std::make_shared<chi_mesh::VolumeMesher>(VolumeMesherType::UNPARTITIONED);
114 new_mesher->SetContinuum(grid_ptr);
115
117
118 auto& cur_hndlr = chi_mesh::GetCurrentHandler();
119 cur_hndlr.SetVolumeMesher(new_mesher);
120
122}
123
126 MeshAttributes new_attribs,
127 std::array<size_t, 3> ortho_cells_per_dimension)
128{
129 grid.SetAttributes(new_attribs, ortho_cells_per_dimension);
130}
131
133{
134 const size_t num_local_cells = grid.local_cells.size();
135 size_t num_global_cells = 0;
136
137 MPI_Allreduce(&num_local_cells, // sendbuf
138 &num_global_cells, // recvbuf
139 1, // count
140 MPI_UNSIGNED_LONG_LONG, // datatype
141 MPI_SUM, // operation
142 Chi::mpi.comm); // communicator
143
144 size_t max_num_local_cells;
145 MPI_Allreduce(&num_local_cells, // sendbuf
146 &max_num_local_cells, // recvbuf
147 1, // count
148 MPI_UNSIGNED_LONG_LONG, // datatype
149 MPI_MAX, // operation
150 Chi::mpi.comm); // communicator
151
152 size_t min_num_local_cells;
153 MPI_Allreduce(&num_local_cells, // sendbuf
154 &min_num_local_cells, // recvbuf
155 1, // count
156 MPI_UNSIGNED_LONG_LONG, // datatype
157 MPI_MIN, // operation
158 Chi::mpi.comm); // communicator
159
160 const size_t avg_num_local_cells = num_global_cells / Chi::mpi.process_count;
161 const size_t num_local_ghosts = grid.cells.GetNumGhosts();
162 const double local_ghost_to_local_cell_ratio =
163 double(num_local_ghosts) / double(num_local_cells);
164
165 double average_ghost_ratio;
166 MPI_Allreduce(&local_ghost_to_local_cell_ratio, // sendbuf
167 &average_ghost_ratio, // recvbuf
168 1, // count
169 MPI_DOUBLE, // datatype
170 MPI_SUM, // operation
171 Chi::mpi.comm); // communicator
172
173 average_ghost_ratio /= Chi::mpi.process_count;
174
175 std::stringstream outstr;
176 outstr << "Mesh statistics:\n";
177 outstr << " Global cell count : " << num_global_cells << "\n";
178 outstr << " Local cell count (avg,max,min): ";
179 outstr << avg_num_local_cells << ",";
180 outstr << max_num_local_cells << ",";
181 outstr << min_num_local_cells << "\n";
182 outstr << " Ghost-to-local ratio (avg) : " << average_ghost_ratio;
183
184 Chi::log.Log() << "\n" << outstr.str() << "\n\n";
185
187 << Chi::mpi.location_id << "Local cells=" << num_local_cells;
188}
189
190} // namespace chi_mesh
static std::vector< ChiObjectPtr > object_stack
Definition: chi_runtime.h:96
static chi::ChiLog & log
Definition: chi_runtime.h:81
static int current_mesh_handler
Definition: chi_runtime.h:84
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
static ChiObjectFactory & GetInstance() noexcept
static chi::InputParameters GetInputParameters()
Definition: ChiObject.cc:4
LogStream LogAllVerbose2()
Definition: chi_log.h:242
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
void SetDocGroup(const std::string &doc_group)
const ParameterBlock & ParametersAtAssignment() const
void AddOptionalParameter(const std::string &name, T value, const std::string &doc_string)
void SetGeneralDescription(const std::string &description)
void AddOptionalParameterArray(const std::string &name, const std::vector< T > &array, const std::string &doc_string)
void Barrier() const
Definition: mpi_info.cc:38
const int & process_count
Total number of processes.
Definition: mpi_info.h:27
const int & location_id
Current process rank.
Definition: mpi_info.h:26
static InputParameters GetInputParameters()
bool Has(const std::string &param_name) const
T GetParamValue(const std::string &param_name) const
std::vector< T > GetParamVectorValue(const std::string &param_name) const
LocalCellHandler local_cells
GlobalCellHandler cells
void SetAttributes(MeshAttributes new_attribs, std::array< size_t, 3 > ortho_Nis={0, 0, 0})
virtual void Execute()
std::shared_ptr< MeshContinuum > SetupMesh(std::unique_ptr< UnpartitionedMesh > input_umesh_ptr, const std::vector< int64_t > &cell_pids)
chi::GraphPartitioner * partitioner_
MeshGenerator(const chi::InputParameters &params)
static void ComputeAndPrintStats(const chi_mesh::MeshContinuum &grid)
static void BroadcastPIDs(std::vector< int64_t > &cell_pids, int root, MPI_Comm communicator)
static void SetGridAttributes(chi_mesh::MeshContinuum &grid, MeshAttributes new_attribs, std::array< size_t, 3 > ortho_cells_per_dimension)
std::vector< MeshGenerator * > inputs_
std::vector< int64_t > PartitionMesh(const UnpartitionedMesh &input_umesh, int num_partitions)
virtual std::unique_ptr< UnpartitionedMesh > GenerateUnpartitionedMesh(std::unique_ptr< UnpartitionedMesh > input_umesh)
static chi::InputParameters GetInputParameters()
size_t PushNewHandlerAndGetIndex()
RegisterChiObject(chi_mesh, BooleanLogicalVolume)
MeshAttributes
Definition: chi_mesh.h:70
MeshHandler & GetCurrentHandler()