Reads a GMS *.3dm file and converts it to an CFEMesh.
171{
172 std::string line;
173
174 std::ifstream in(filename.c_str());
175 if (!in.is_open())
176 {
177 ERR(
"GMSInterface::readMesh(): Could not open file {:s}.", filename);
178 return nullptr;
179 }
180
181
182 std::getline(in, line);
183 if (line != "MESH3D" && line != "MESH2D")
184 {
185 ERR(
"GMSInterface::readMesh(): Could not read expected file "
186 "header.");
187 return nullptr;
188 }
189 bool const is_3d = (line == "MESH3D");
190
192 INFO(
"Reading SMS/GMS mesh...");
193 std::vector<MeshLib::Node*> nodes;
194 std::vector<MeshLib::Element*> elements;
195 std::vector<int> mat_ids;
196 std::map<unsigned, unsigned> id_map;
197
198
199
200 std::string dummy;
201 unsigned id(0);
202 unsigned count(0);
203 double x[3];
204
205 while (std::getline(in, line))
206 {
207 if (line[0] == 'N')
208 {
209 std::stringstream str(line);
210 str >> dummy >> id >> x[0] >> x[1] >> x[2];
212 id_map.insert(std::pair<unsigned, unsigned>(id, count++));
213 nodes.push_back(node);
214 }
215 }
216 in.close();
217
218
219
220 in.open(filename.c_str());
221 std::getline(in, line);
222 unsigned node_idx[6];
223 int mat_id(0);
224 while (std::getline(in, line))
225 {
226 std::string element_id(line.substr(0, 3));
227 std::stringstream str(line);
228
229 if (element_id == "MES")
230 {
231 str >> dummy >> mesh_name;
232 mesh_name = mesh_name.substr(1, mesh_name.length() - 2);
233 }
234 else if (!is_3d && element_id == "E3T")
235 {
236 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
237 mat_id;
238 std::array<MeshLib::Node*, 3> tri_nodes{};
239 for (unsigned k(0); k < 3; k++)
240 {
241 tri_nodes[k] = nodes[id_map.find(node_idx[k])->second];
242 }
244 mat_ids.push_back(mat_id);
245 }
246 else if (!is_3d && element_id == "E6T")
247 {
248 str >> dummy >> id >> node_idx[0] >> node_idx[3] >> node_idx[1] >>
249 node_idx[4] >> node_idx[2] >> node_idx[5] >> mat_id;
250 std::array<MeshLib::Node*, 3> tri_nodes{};
251 for (unsigned k(0); k < 3; k++)
252 {
253 tri_nodes[k] = nodes[id_map.find(node_idx[k])->second];
254 }
256 mat_ids.push_back(mat_id);
257 }
258 else if (is_3d && element_id == "E6W")
259 {
260 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
261 node_idx[3] >> node_idx[4] >> node_idx[5] >> mat_id;
262 std::array<MeshLib::Node*, 6> prism_nodes{};
263 for (unsigned k(0); k < 6; k++)
264 {
265 prism_nodes[k] = nodes[id_map.find(node_idx[k])->second];
266 }
268 mat_ids.push_back(mat_id);
269 }
270 else if (is_3d && element_id == "E4T")
271 {
272 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
273 node_idx[3] >> mat_id;
274 std::array<MeshLib::Node*, 4> tet_nodes{};
275 for (unsigned k(0); k < 4; k++)
276 {
277 tet_nodes[k] = nodes[id_map.find(node_idx[k])->second];
278 }
280 mat_ids.push_back(mat_id);
281 }
282
283 else if (is_3d && (element_id == "E4P" || element_id == "E5P"))
284 {
285 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
286 node_idx[3] >> node_idx[4] >> mat_id;
287 std::array<MeshLib::Node*, 5> pyramid_nodes{};
288 for (unsigned k(0); k < 5; k++)
289 {
290 pyramid_nodes[k] = nodes[id_map.find(node_idx[k])->second];
291 }
293 mat_ids.push_back(mat_id);
294 }
295 else if (element_id == "ND ")
296 {
297 continue;
298 }
299 else
300 {
302 "GMSInterface::readMesh() - Element type '{:s}' not "
303 "recognised.",
304 element_id);
305 return nullptr;
306 }
307 }
308
309 in.close();
311
312 MeshLib::Properties properties;
313 if (mat_ids.size() == elements.size())
314 {
317 if (!opt_pv)
318 {
319 ERR(
"Could not create PropertyVector for material ids.");
321 return nullptr;
322 }
324 }
325 else
326 {
327 ERR(
"Ignoring Material IDs information (does not match number of "
328 "elements).");
329 }
330 return new MeshLib::Mesh(mesh_name, nodes, elements,
331 true , properties);
332}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)
constexpr void assign(R &&r)
void cleanupVectorElements(std::vector< T * > &items)
std::string extractBaseNameWithoutExtension(std::string const &pathname)
TemplateElement< MeshLib::TetRule4 > Tet
TemplateElement< MeshLib::TriRule3 > Tri
TemplateElement< MeshLib::PyramidRule5 > Pyramid
TemplateElement< MeshLib::PrismRule6 > Prism