18 const std::string& grid_generator_function,
19 const std::string& grid_generator_arguments,
20 const unsigned int n_refinements,
21 const bool use_tetrahedral_mesh)
23 if constexpr (std::is_same_v<TriangulationType, parallel::fullydistributed::Triangulation<dim, spacedim>>) {
25 Triangulation<dim, spacedim> serial_tria;
26 GridGenerator::generate_from_name_and_arguments(
28 grid_generator_function,
29 grid_generator_arguments);
31 if (grid_generator_function ==
"hyper_ball")
33 Point<spacedim> center{0., 0., 0.};
34 for (
const auto &cell : serial_tria.active_cell_iterators())
35 if (center.distance(cell->center()) > cell->diameter() / 10)
36 cell->set_all_manifold_ids(0);
39 serial_tria.refine_global(n_refinements);
41 if (use_tetrahedral_mesh && dim == 3 && spacedim == 3) {
42 GridGenerator::convert_hypercube_to_simplex_mesh(serial_tria, serial_tria);
46 tria.set_partitioner([](Triangulation<dim, spacedim>& tria_to_partition,
const unsigned int n_partitions) {
47 GridTools::partition_triangulation_zorder(n_partitions, tria_to_partition);
48 }, TriangulationDescription::Settings::construct_multigrid_hierarchy);
51 auto construction_data = TriangulationDescription::Utilities::create_description_from_triangulation(
52 serial_tria, mpi_communicator,
53 TriangulationDescription::Settings::construct_multigrid_hierarchy);
56 tria.create_triangulation(construction_data);
59 GridGenerator::generate_from_name_and_arguments(
61 grid_generator_function,
62 grid_generator_arguments);
64 if (grid_generator_function ==
"hyper_ball")
66 Point<spacedim> center{0., 0., 0.};
67 for (
const auto &cell : tria.active_cell_iterators())
68 if (center.distance(cell->center()) > cell->diameter() / 10)
69 cell->set_all_manifold_ids(0);
72 tria.refine_global(n_refinements);
74 if (use_tetrahedral_mesh && dim == 3 && spacedim == 3) {
75 GridGenerator::convert_hypercube_to_simplex_mesh(tria, tria);
82 const std::string& source_file)
85 Triangulation<dim, spacedim> serial_source;
86 GridIn<dim, spacedim> grid_in_source;
87 grid_in_source.attach_triangulation(serial_source);
88 bool source_loaded =
false;
91 if (!source_file.empty()) {
92 std::ifstream input_file(source_file);
93 if (input_file.good()) {
96 std::string extension = source_file.substr(source_file.find_last_of(
".") + 1);
97 if (extension ==
"vtk") {
98 grid_in_source.read_vtk(input_file);
99 }
else if (extension ==
"msh") {
100 grid_in_source.read_msh(input_file);
102 throw std::runtime_error(
"Unsupported file format: " + extension);
104 source_loaded =
true;
105 pcout <<
"Source mesh loaded from custom file: " << source_file << std::endl;
106 }
catch (
const std::exception& e) {
107 pcout <<
"Failed to load source mesh from custom file: " << e.what() << std::endl;
110 pcout <<
"Could not open custom source mesh file: " << source_file << std::endl;
115 if (!source_loaded) {
117 std::ifstream in_vtk_source(mesh_directory +
"/source.vtk");
118 if (in_vtk_source.good()) {
120 grid_in_source.read_vtk(in_vtk_source);
121 source_loaded =
true;
122 pcout <<
"Source mesh loaded from VTK format" << std::endl;
123 }
catch (
const std::exception& e) {
124 pcout <<
"Failed to load source mesh from VTK format: " << e.what() << std::endl;
129 if (!source_loaded) {
130 std::ifstream in_msh_source(mesh_directory +
"/source.msh");
131 if (in_msh_source.good()) {
133 grid_in_source.read_msh(in_msh_source);
134 source_loaded =
true;
135 pcout <<
"Source mesh loaded from MSH format" << std::endl;
136 }
catch (
const std::exception& e) {
137 pcout <<
"Failed to load source mesh from MSH format: " << e.what() << std::endl;
143 if (!source_loaded) {
144 throw std::runtime_error(
"Failed to load source mesh from either custom file or default locations");
148 GridTools::partition_triangulation_zorder(n_mpi_processes, serial_source);
151 auto construction_data = TriangulationDescription::Utilities::create_description_from_triangulation(
152 serial_source, mpi_communicator,
153 TriangulationDescription::Settings::default_setting);
154 source_mesh.create_triangulation(construction_data);
161 if (this_mpi_process != 0) {
166 GridIn<dim, spacedim> grid_in_target;
167 grid_in_target.attach_triangulation(target_mesh);
168 bool target_loaded =
false;
171 std::ifstream in_vtk_target(mesh_directory +
"/target.vtk");
172 if (in_vtk_target.good()) {
174 grid_in_target.read_vtk(in_vtk_target);
175 target_loaded =
true;
176 pcout <<
"Target mesh loaded from VTK format" << std::endl;
177 }
catch (
const std::exception& e) {
178 pcout <<
"Failed to load target mesh from VTK format: " << e.what() << std::endl;
183 if (!target_loaded) {
184 std::ifstream in_msh_target(mesh_directory +
"/target.msh");
185 if (in_msh_target.good()) {
187 grid_in_target.read_msh(in_msh_target);
188 target_loaded =
true;
189 pcout <<
"Target mesh loaded from MSH format" << std::endl;
190 }
catch (
const std::exception& e) {
191 pcout <<
"Failed to load target mesh from MSH format: " << e.what() << std::endl;
196 if (!target_loaded) {
197 throw std::runtime_error(
"Failed to load target mesh from either VTK or MSH format");
203 DoFHandler<dim, spacedim>& dof_handler_source,
204 const std::string& mesh_file)
206 pcout <<
"Attempting to load mesh from: " << mesh_file << std::endl;
209 if (!std::filesystem::exists(mesh_file)) {
210 throw std::runtime_error(
"Mesh file does not exist: " + mesh_file);
214 std::ifstream input(mesh_file);
216 throw std::runtime_error(
"Cannot open mesh file: " + mesh_file);
219 input.seekg(0, std::ios::end);
220 if (input.tellg() == 0) {
221 throw std::runtime_error(
"Mesh file is empty: " + mesh_file);
223 input.seekg(0, std::ios::beg);
227 Triangulation<dim, spacedim> serial_source;
228 GridIn<dim, spacedim> grid_in;
229 grid_in.attach_triangulation(serial_source);
231 grid_in.read_msh(input);
234 if (serial_source.n_active_cells() == 0) {
235 throw std::runtime_error(
"Loaded mesh contains no cells");
238 pcout <<
"Successfully loaded serial mesh with "
239 << serial_source.n_active_cells() <<
" cells and "
240 << serial_source.n_vertices() <<
" vertices" << std::endl;
243 GridTools::partition_triangulation_zorder(n_mpi_processes, serial_source);
246 auto construction_data = TriangulationDescription::Utilities::create_description_from_triangulation(
247 serial_source, mpi_communicator,
248 TriangulationDescription::Settings::default_setting);
251 dof_handler_source.clear();
254 source_mesh.create_triangulation(construction_data);
257 const unsigned int n_global_active_cells =
258 Utilities::MPI::sum(source_mesh.n_locally_owned_active_cells(), mpi_communicator);
260 if (n_global_active_cells == 0) {
261 throw std::runtime_error(
"Distributed mesh contains no cells");
264 pcout <<
"Successfully created distributed mesh with "
265 << n_global_active_cells <<
" total cells across "
266 << n_mpi_processes <<
" processes" << std::endl;
268 }
catch (
const std::exception& e) {
269 throw std::runtime_error(
"Failed to load mesh from " + mesh_file +
270 "\nError: " + e.what());
293 const std::string& filepath,
294 const std::vector<std::string>& formats,
295 const std::vector<double>* cell_data,
296 const std::string& data_name)
299 std::filesystem::path path(filepath);
300 std::filesystem::create_directories(path.parent_path());
304 for (
const auto& format : formats) {
305 if (format ==
"vtk") {
306 std::ofstream out_vtk(filepath +
".vtk");
307 if (!out_vtk.is_open()) {
308 pcout <<
"Error: Unable to open file for writing: "
309 << filepath +
".vtk" << std::endl;
312 grid_out.write_vtk(mesh, out_vtk);
313 pcout <<
"Mesh saved to: " << filepath +
".vtk" << std::endl;
315 else if (format ==
"msh") {
317 std::ofstream out_msh(filepath +
".msh");
318 if (!out_msh.is_open()) {
319 pcout <<
"Error: Unable to open file for writing: "
320 << filepath +
".msh" << std::endl;
323 grid_out.write_msh(mesh, out_msh);
327 std::string cmd =
"gmsh " + filepath +
".msh -format msh2 -save_all -3 -o " +
328 filepath +
"_msh2.msh && mv " + filepath +
"_msh2.msh " +
330 int ret = system(cmd.c_str());
332 pcout <<
"Error: Failed to convert mesh to MSH2 format" << std::endl;
335 pcout <<
"Mesh saved and converted to MSH2 format: " << filepath +
".msh" << std::endl;
337 else if (format ==
"vtu") {
338 DataOut<dim, spacedim> data_out;
339 data_out.attach_triangulation(mesh);
342 if (cell_data !=
nullptr) {
343 Assert(cell_data->size() == mesh.n_active_cells(),
344 ExcDimensionMismatch(cell_data->size(),
345 mesh.n_active_cells()));
347 Vector<double> cell_data_vector(cell_data->begin(), cell_data->end());
348 data_out.add_data_vector(cell_data_vector, data_name);
351 data_out.build_patches();
353 std::ofstream out_vtu(filepath +
".vtu");
354 if (!out_vtu.is_open()) {
355 pcout <<
"Error: Unable to open file for writing: "
356 << filepath +
".vtu" << std::endl;
359 data_out.write_vtu(out_vtu);
360 pcout <<
"Mesh saved to: " << filepath +
".vtu" << std::endl;
363 pcout <<
"Warning: Unsupported format '" << format
364 <<
"' requested" << std::endl;
370 catch (
const std::exception& e) {
371 pcout <<
"Error writing mesh: " << e.what() << std::endl;
379 std::vector<std::string> mesh_files;
382 for (
const auto& entry : std::filesystem::directory_iterator(dir)) {
383 if (entry.path().extension() ==
".msh") {
384 mesh_files.push_back(entry.path().string());
389 std::sort(mesh_files.begin(), mesh_files.end(), std::greater<std::string>());
bool write_mesh(const TriangulationType &mesh, const std::string &filepath, const std::vector< std::string > &formats, const std::vector< double > *cell_data=nullptr, const std::string &data_name="cell_data")
Write mesh to file in specified formats with optional cell data.
void generate_mesh(TriangulationType &tria, const std::string &grid_generator_function, const std::string &grid_generator_arguments, const unsigned int n_refinements, const bool use_tetrahedral_mesh)
Generate mesh using deal.II grid generator.
void save_meshes(const parallel::fullydistributed::Triangulation< dim, spacedim > &source_mesh, const Triangulation< dim, spacedim > &target_mesh)
Save source and target meshes to files.
void load_mesh_at_level(parallel::fullydistributed::Triangulation< dim, spacedim > &source_mesh, DoFHandler< dim, spacedim > &dof_handler_source, const std::string &mesh_file)
Load mesh at specific refinement level.