Reads a GMS *.3dm file and converts it to an CFEMesh.
181{
182 std::string line;
183
184 std::ifstream in(filename.c_str());
185 if (!in.is_open())
186 {
187 ERR(
"GMSInterface::readMesh(): Could not open file {:s}.", filename);
188 return nullptr;
189 }
190
191
192 std::getline(in, line);
193 if (line != "MESH3D" && line != "MESH2D")
194 {
195 ERR(
"GMSInterface::readMesh(): Could not read expected file "
196 "header.");
197 return nullptr;
198 }
199 bool const is_3d = (line == "MESH3D");
200
202 INFO(
"Reading SMS/GMS mesh...");
203 std::vector<MeshLib::Node*> nodes;
204 std::vector<MeshLib::Element*> elements;
205 std::vector<int> mat_ids;
206 std::map<unsigned, unsigned> id_map;
207
208
209
210 std::string dummy;
211 unsigned id(0);
212 unsigned count(0);
213 double x[3];
214
215 while (std::getline(in, line))
216 {
217 if (line[0] == 'N')
218 {
219 std::stringstream str(line);
220 str >> dummy >> id >> x[0] >> x[1] >> x[2];
222 id_map.insert(std::pair<unsigned, unsigned>(id, count++));
223 nodes.push_back(node);
224 }
225 }
226 in.close();
227
228
229
230 in.open(filename.c_str());
231 std::getline(in, line);
232 unsigned node_idx[6];
233 int mat_id(0);
234 while (std::getline(in, line))
235 {
236 std::string element_id(line.substr(0, 3));
237 std::stringstream str(line);
238
239 if (element_id == "MES")
240 {
241 str >> dummy >> mesh_name;
242 mesh_name = mesh_name.substr(1, mesh_name.length() - 2);
243 }
244 else if (!is_3d && element_id == "E3T")
245 {
246 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
247 mat_id;
248 std::array<MeshLib::Node*, 3> tri_nodes;
249 for (unsigned k(0); k < 3; k++)
250 {
251 tri_nodes[k] = nodes[id_map.find(node_idx[k])->second];
252 }
254 mat_ids.push_back(mat_id);
255 }
256 else if (!is_3d && element_id == "E6T")
257 {
258 str >> dummy >> id >> node_idx[0] >> node_idx[3] >> node_idx[1] >>
259 node_idx[4] >> node_idx[2] >> node_idx[5] >> mat_id;
260 std::array<MeshLib::Node*, 3> tri_nodes;
261 for (unsigned k(0); k < 3; k++)
262 {
263 tri_nodes[k] = nodes[id_map.find(node_idx[k])->second];
264 }
266 mat_ids.push_back(mat_id);
267 }
268 else if (is_3d && element_id == "E6W")
269 {
270 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
271 node_idx[3] >> node_idx[4] >> node_idx[5] >> mat_id;
272 std::array<MeshLib::Node*, 6> prism_nodes;
273 for (unsigned k(0); k < 6; k++)
274 {
275 prism_nodes[k] = nodes[id_map.find(node_idx[k])->second];
276 }
278 mat_ids.push_back(mat_id);
279 }
280 else if (is_3d && element_id == "E4T")
281 {
282 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
283 node_idx[3] >> mat_id;
284 std::array<MeshLib::Node*, 4> tet_nodes;
285 for (unsigned k(0); k < 4; k++)
286 {
287 tet_nodes[k] = nodes[id_map.find(node_idx[k])->second];
288 }
290 mat_ids.push_back(mat_id);
291 }
292
293 else if (is_3d && (element_id == "E4P" || element_id == "E5P"))
294 {
295 str >> dummy >> id >> node_idx[0] >> node_idx[1] >> node_idx[2] >>
296 node_idx[3] >> node_idx[4] >> mat_id;
297 std::array<MeshLib::Node*, 5> pyramid_nodes;
298 for (unsigned k(0); k < 5; k++)
299 {
300 pyramid_nodes[k] = nodes[id_map.find(node_idx[k])->second];
301 }
303 mat_ids.push_back(mat_id);
304 }
305 else if (element_id == "ND ")
306 {
307 continue;
308 }
309 else
310 {
312 "GMSInterface::readMesh() - Element type '{:s}' not "
313 "recognised.",
314 element_id);
315 return nullptr;
316 }
317 }
318
319 in.close();
321
323 if (mat_ids.size() == elements.size())
324 {
327 if (!opt_pv)
328 {
329 ERR(
"Could not create PropertyVector for material ids.");
331 return nullptr;
332 }
333 opt_pv->reserve(mat_ids.size());
334 std::copy(mat_ids.cbegin(), mat_ids.cend(),
335 std::back_inserter(*opt_pv));
336 }
337 else
338 {
339 ERR(
"Ignoring Material IDs information (does not match number of "
340 "elements).");
341 }
343 true , properties);
344}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)
void cleanupVectorElements(std::vector< T * > &items)
std::string extractBaseNameWithoutExtension(std::string const &pathname)