15 const std::string fname =
"chi_mesh::UnpartitionedMesh::ReadFromMsh";
23 <<
"Failed to open file: "<< options.
file_name<<
" in call "
24 <<
"to ReadFromMsh \n";
28 Chi::log.
Log() <<
"Making Unpartitioned mesh from msh format file "
33 std::string file_line;
34 std::istringstream iss;
35 const std::string node_section_name=
"$Nodes";
36 const std::string elements_section_name =
"$Elements";
37 const std::string format_section_name =
"$MeshFormat";
41 while (std::getline(file, file_line))
42 if ( format_section_name == file_line )
break;
44 std::getline(file, file_line);
45 iss = std::istringstream(file_line);
47 if ( !(iss >> format) )
48 throw std::logic_error(fname +
": Failed to read the file format.");
49 else if (format != 2.2)
50 throw std::logic_error(fname +
": Currently, only msh format 2.2 is supported.");
56 while (std::getline(file, file_line))
57 if ( node_section_name == file_line )
break;
59 std::getline(file, file_line);
60 iss = std::istringstream(file_line);
62 if ( !(iss >> num_nodes) )
63 throw std::logic_error(fname +
": Failed while trying to read "
64 "the number of nodes.");
69 for (
int n=0; n<num_nodes; n++)
71 std::getline(file, file_line);
72 iss = std::istringstream(file_line);
75 if ( !(iss >> vert_index) )
76 throw std::logic_error(fname +
": Failed to read vertex index.");
81 throw std::logic_error(fname +
": Failed while reading the vertex "
87 auto ReadNodes = [&iss,&fname](
int num_nodes)
89 std::vector<int> raw_nodes(num_nodes,0);
90 for (
int i=0; i<num_nodes; ++i)
91 if ( !(iss >> raw_nodes[i]) )
92 throw std::logic_error(fname +
": Failed when reading element "
95 std::vector<uint64_t> nodes(num_nodes,0);
96 for (
int i=0; i<num_nodes; ++i)
97 if ((raw_nodes[i]-1)>=0)
98 nodes[i] = raw_nodes[i]-1;
103 auto IsElementType1D = [](
int element_type)
105 if (element_type == 1)
112 auto IsElementType2D = [](
int element_type)
114 if (element_type == 2 or element_type == 3)
121 auto IsElementType3D = [](
int element_type)
123 if (element_type >= 4 and element_type <= 7)
130 auto IsElementSupported = [](
int element_type)
132 if (element_type >= 1 and element_type <= 7)
139 auto CellTypeFromMSHTypeID = [](
int element_type)
148 else if (element_type == 6 or
161 bool mesh_is_2D_assumption =
true;
163 while (std::getline(file, file_line))
164 if ( elements_section_name == file_line )
break;
166 std::getline(file, file_line);
167 iss = std::istringstream(file_line);
169 if (!(iss >> num_elems))
170 throw std::logic_error(fname +
": Failed to read number of elements.");
172 for (
int n=0; n<num_elems; n++)
174 int elem_type, num_tags, physical_reg, tag, element_index;
176 std::getline(file, file_line);
177 iss = std::istringstream(file_line);
179 if ( !(iss >> element_index >> elem_type >> num_tags) )
180 throw std::logic_error(fname +
": Failed while reading element index, "
181 "element type, and number of tags.");
183 if( !(iss>>physical_reg) )
184 throw std::logic_error(fname +
": Failed while reading physical region.");
186 for (
int i=1; i<num_tags; i++)
188 throw std::logic_error(fname +
": Failed when reading tags.");
190 if (IsElementType3D(elem_type))
192 mesh_is_2D_assumption =
false;
200 if (not IsElementSupported(elem_type))
201 throw std::logic_error(fname +
": Unsupported element encountered.");
208 while (std::getline(file, file_line))
209 if ( elements_section_name == file_line )
break;
211 std::getline(file, file_line);
212 iss = std::istringstream(file_line);
213 if (!(iss >> num_elems))
214 throw std::logic_error(fname +
": Failed to read number of elements.");
216 for (
int n=0; n<num_elems; n++)
218 int elem_type, num_tags, physical_reg, tag, element_index;
220 std::getline(file, file_line);
221 iss = std::istringstream(file_line);
223 if ( !(iss >> element_index >> elem_type >> num_tags) )
224 throw std::logic_error(fname +
": Failed while reading element index, "
225 "element type, and number of tags.");
227 if( !(iss>>physical_reg) )
228 throw std::logic_error(fname +
": Failed while reading physical region.");
230 for (
int i=1; i<num_tags; i++)
232 throw std::logic_error(fname +
": Failed when reading tags.");
237 if (not IsElementSupported(elem_type))
238 throw std::logic_error(fname +
": Unsupported element encountered.");
241 <<
" type: " << elem_type;
246 else if (elem_type == 2)
248 else if (elem_type == 3 or elem_type == 4)
250 else if (elem_type == 5)
258 if (mesh_is_2D_assumption)
260 if (IsElementType1D(elem_type))
266 else if (IsElementType2D(elem_type))
269 CellTypeFromMSHTypeID(elem_type));
276 if (IsElementType2D(elem_type))
279 CellTypeFromMSHTypeID(elem_type));
283 else if (IsElementType3D(elem_type))
286 CellTypeFromMSHTypeID(elem_type));
292 if (raw_cell ==
nullptr)
continue;
294 auto& cell = *raw_cell;
296 cell.vertex_ids = ReadNodes(num_cell_nodes);
307 cell.faces.push_back(face0);
308 cell.faces.push_back(face1);
310 else if (elem_type == 2 or elem_type == 3)
312 size_t num_verts = cell.vertex_ids.size();
313 for (
size_t e=0; e<num_verts; e++)
315 size_t ep1 = (e<(num_verts-1))? e+1 : 0;
318 face.
vertex_ids = {cell.vertex_ids[e], cell.vertex_ids[ep1]};
320 cell.faces.push_back(std::move(face));
323 else if (elem_type == 4)
325 auto& v = cell.vertex_ids;
326 std::vector<LightWeightFace> lw_faces(4);
327 lw_faces[0].vertex_ids = {v[0], v[2], v[1]};
328 lw_faces[1].vertex_ids = {v[0], v[3], v[2]};
329 lw_faces[2].vertex_ids = {v[3], v[1], v[2]};
330 lw_faces[3].vertex_ids = {v[3], v[0], v[1]};
332 for (
auto& lw_face : lw_faces) cell.faces.push_back(lw_face);
334 else if (elem_type == 5)
336 auto& v = cell.vertex_ids;
337 std::vector<LightWeightFace> lw_faces(6);
338 lw_faces[0].vertex_ids = {v[5], v[1], v[2], v[6]};
339 lw_faces[1].vertex_ids = {v[0], v[4], v[7], v[3]};
340 lw_faces[2].vertex_ids = {v[0], v[3], v[2], v[1]};
341 lw_faces[3].vertex_ids = {v[4], v[5], v[6], v[7]};
342 lw_faces[4].vertex_ids = {v[2], v[3], v[7], v[6]};
343 lw_faces[5].vertex_ids = {v[0], v[1], v[5], v[4]};
345 for (
auto& lw_face : lw_faces) cell.faces.push_back(lw_face);
348 throw std::runtime_error(fname +
": Unsupported cell type");
355 std::set<int> material_ids_set_as_read;
356 std::map<int,int> material_mapping;
359 material_ids_set_as_read.insert(cell->material_id);
361 std::set<int> boundary_ids_set_as_read;
362 std::map<int,int> boundary_mapping;
365 boundary_ids_set_as_read.insert(cell->material_id);
369 for (
const auto& mat_id : material_ids_set_as_read)
370 material_mapping.insert(std::make_pair(mat_id,m++));
373 for (
const auto& bndry_id : boundary_ids_set_as_read)
374 boundary_mapping.insert(std::make_pair(bndry_id,b++));
378 cell->material_id = material_mapping[cell->material_id];
381 cell->material_id = boundary_mapping[cell->material_id];
385 if (not mesh_is_2D_assumption) dimension =
DIMENSION_3;
393 <<
"Number of nodes read: " <<
vertices_.size() <<
"\n"
394 <<
"Number of cells read: " <<
raw_cells_.size();
static void Exit(int error_code)
static chi::MPI_Info & mpi
LogStream Log(LOG_LVL level=LOG_0)
void ComputeCentroidsAndCheckQuality()
void BuildMeshConnectivity()
std::vector< chi_mesh::Vertex > vertices_
MeshAttributes attributes_
void ReadFromMsh(const Options &options)
std::vector< LightWeightCell * > raw_cells_
std::vector< LightWeightCell * > raw_boundary_cells_
std::vector< uint64_t > vertex_ids