38 const std::string msh_filename,
39 const bool decoupled_edges
43 std::ifstream file(msh_filename);
45 throw std::runtime_error(
"Could not open mesh file: " + msh_filename);
49 std::getline(file, line);
50 if (line !=
"$MeshFormat")
51 throw std::runtime_error(
"Invalid Gmsh file format: missing $MeshFormat header");
53 std::getline(file, line);
54 std::istringstream iss (line);
56 int file_type, data_size;
57 iss >> version >> file_type >> data_size;
59 if (version < 2.0 || version >= 3.0)
60 throw std::runtime_error(
".msh file version must be 2.x");
62 std::getline(file, line);
65 std::size_t num_vertices = 0;
66 std::size_t num_faces = 0;
68 bool in_elements =
false;
69 bool in_physical_names =
false;
71 std::map<Index, Index> surface_to_num_elems;
72 std::map<Index, Index> physical_to_num_elems;
73 std::vector<std::string> physical_names;
77 while (std::getline(file, line))
81 std::getline(file, line);
82 num_vertices = std::stoull(line);
85 if (line ==
"$EndNodes")
89 if (line ==
"$Elements")
92 std::getline(file, line);
95 if (line ==
"$EndElements")
100 if (line ==
"$PhysicalNames")
102 in_physical_names =
true;
103 std::getline(file, line);
106 if (line ==
"$EndPhysicalNames")
108 in_physical_names =
false;
112 if (in_physical_names)
114 std::istringstream iss(line);
117 iss >> n1 >> n2 >> name;
118 name.erase(std::remove(name.begin(), name.end(),
'\"' ), name.end());
119 physical_names.push_back(name);
125 std::istringstream iss(line);
126 std::size_t elm_id, elm_type, num_tags, phys_tag, surf_tag;
127 iss >> elm_id >> elm_type >> num_tags >> phys_tag >> surf_tag;
132 if (elm_type == elm_map)
136 bool inserted_surface = surface_to_num_elems.insert(std::make_pair(surf_tag, 1)).second;
137 if (!inserted_surface)
138 surface_to_num_elems[surf_tag]++;
140 bool inserted_physical = physical_to_num_elems.insert(std::make_pair(phys_tag, 1)).second;
141 if (!inserted_physical)
142 physical_to_num_elems[phys_tag]++;
151 std::map<Index, EigRowVec<Index>> surface_elems;
152 std::map<Index, Index> surface_elem_counters;
153 for (
auto& [key, value]: surface_to_num_elems)
156 surface_elem_counters[key] = 0;
159 std::map<Index, EigRowVec<Index>> physical_elems;
160 std::map<Index, Index> physical_elem_counters;
161 for (
auto& [key, value]: physical_to_num_elems)
164 physical_elem_counters[key] = 0;
172 while (std::getline(file, line) && line !=
"$Nodes") {}
173 std::getline(file, line);
176 std::size_t vertex_idx = 0;
177 while (std::getline(file, line) && line !=
"$EndNodes")
179 std::istringstream iss(line);
180 std::size_t vertex_id;
182 iss >> vertex_id >> x >> y >> z;
183 verts.col(vertex_idx++) << x, y, z;
187 while (std::getline(file, line) && line !=
"$Elements") {}
188 std::getline(file, line);
191 std::size_t face_idx = 0;
192 while (std::getline(file, line) && line !=
"$EndElements")
194 std::istringstream iss(line);
195 std::size_t elm_id, elm_type, num_tags;
196 iss >> elm_id >> elm_type >> num_tags;
199 throw std::runtime_error(
200 "Unexpected number of tags in file " + msh_filename +
" for element " + std::to_string(elm_id)
203 std::vector<std::size_t> tags (num_tags);
204 for (std::size_t ii = 0; ii < num_tags; ++ii)
207 std::size_t ptag = tags[0] - 1;
208 std::size_t stag = tags[1] - 1;
211 if (elm_type == elm_map)
213 physical_elems[ptag][physical_elem_counters[ptag]++] = face_idx;
214 surface_elems[stag][surface_elem_counters[stag]++] = face_idx;
216 for (std::size_t ii = 0; ii < 3; ++ii)
221 elems(ii, face_idx) = v - 1;
224 elem_tags[face_idx] = ptag;
229 structure.mesh().set_data(verts, elems, elem_tags, decoupled_edges);
231 for (
const auto& [key, value]: surface_elems)
233 MeshView view (structure.mesh(), value,
"surface_id_" + std::to_string(key));
235 structure.add_metacomponent(metacomp);
237 for (
const auto& [key, value]: physical_elems)
239 std::string name = physical_names[key] +
"_physical_id_" + std::to_string(key);
240 MeshView view (structure.mesh(), value, name);
242 structure.add_component(comp);
252 const std::string msh_filename,
253 const std::string extension
257 std::ofstream file(msh_filename +
"." + extension);
259 throw std::runtime_error(
"Could not open mesh file: " + msh_filename +
"." + extension);
262 file <<
"$MeshFormat\n";
264 file <<
"$EndMeshFormat\n";
267 file <<
"$PhysicalNames\n";
268 file << structure.components().size() <<
"\n";
269 for (
Index ii = 0; ii < structure.components().size(); ++ii)
270 file <<
"2 " << ii + 1 <<
" \"" << structure.components()[ii].name() <<
"\"\n";
271 file <<
"$EndPhysicalNames\n";
275 file << structure.mesh().num_verts() <<
"\n";
276 for (
Index ii = 0; ii < structure.mesh().num_verts(); ++ii)
279 file << (ii + 1) <<
" " << v[0] <<
" " << v[1] <<
" " << v[2] <<
"\n";
281 file <<
"$EndNodes\n";
285 for (
Index jj = 0; jj < structure.components().size(); ++jj)
286 num_elems += structure.components()[jj].mesh_view().elem_inds().size();
288 file <<
"$Elements\n";
289 file << num_elems <<
"\n";
291 for (
Index jj = 0; jj < structure.components().size(); ++jj)
293 for (
Index ii = 0; ii < structure.components()[jj].mesh_view().elem_inds().size(); ++ii)
296 structure.components()[jj].mesh_view().elem_inds()[ii]
298 file << elem_idx++ <<
" 2 2 ";
299 file << jj + 1 <<
" " << jj + 1 <<
" ";
300 file << (fv[0] + 1) <<
" " << (fv[1] + 1) <<
" " << (fv[2] + 1) <<
"\n";
303 file <<
"$EndElements\n";