gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_UNV.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <stdlib.h>
7 #include <string.h>
8 #include "GModel.h"
9 #include "OS.h"
10 #include "GmshConfig.h"
11 
12 #include "MLine.h"
13 #include "MTriangle.h"
14 #include "MQuadrangle.h"
15 #include "MTetrahedron.h"
16 #include "MHexahedron.h"
17 #include "MPrism.h"
18 #include "Context.h"
19 
20 //#define COMPRESSED_UNV
21 #if defined(COMPRESSED_UNV) && defined(HAVE_LIBZ)
22 #include <zlib.h>
23 typedef gzFile gmshFILE;
24 #define gmshopen gzopen
25 #define gmshgets(a, b, c) gzgets((c), (a), (b))
26 #define gmshclose gzclose
27 #define gmsheof gzeof
28 #else
29 typedef FILE *gmshFILE;
30 #define gmshopen Fopen
31 #define gmshgets fgets
32 #define gmshclose fclose
33 #define gmsheof feof
34 #endif
35 
36 int GModel::readUNV(const std::string &name, bool readGroupsOfElements)
37 {
38  gmshFILE fp = gmshopen(name.c_str(), "r");
39  if(!fp) {
40  Msg::Error("Unable to open file '%s'", name.c_str());
41  return 0;
42  }
43 
44  char buffer[256];
45  std::map<int, std::vector<MElement *> > elements[7];
46  std::map<int, std::map<int, std::string> > physicals[4];
47  std::map<int, MElement *> elementTags;
48  std::map<MElement *, std::vector<int>, MElementPtrLessThan> elementGroups;
49  std::map<int, std::string> groupNames;
50  _vertexMapCache.clear();
51 
52  while(!gmsheof(fp)) {
53  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
54  if(!strncmp(buffer, " -1", 6)) {
55  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
56  if(!strncmp(buffer, " -1", 6))
57  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
58  int record = 0;
59  sscanf(buffer, "%d", &record);
60  if(record == 2411) { // nodes
61  Msg::Info("Reading nodes");
62  while(gmshgets(buffer, sizeof(buffer), fp)) {
63  if(!strncmp(buffer, " -1", 6)) break;
64  int num, dum;
65  if(sscanf(buffer, "%d %d %d %d", &num, &dum, &dum, &dum) != 4) break;
66  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
67  double x, y, z;
68  for(std::size_t i = 0; i < strlen(buffer); i++)
69  if(buffer[i] == 'D') buffer[i] = 'E';
70  if(sscanf(buffer, "%lf %lf %lf", &x, &y, &z) != 3) break;
71  _vertexMapCache[num] = new MVertex(x, y, z, nullptr, num);
72  }
73  }
74  else if(record == 2412) { // elements
75  Msg::Info("Reading elements");
76  std::map<int, int> warn;
77  while(gmshgets(buffer, sizeof(buffer), fp)) {
78  if(strlen(buffer) < 3)
79  continue; // possible line ending after last fgets
80  if(!strncmp(buffer, " -1", 6)) break;
81  int num, type, elementary, physical, color, numNodes;
82  if(!CTX::instance()->mesh.switchElementTags) {
83  if(sscanf(buffer, "%d %d %d %d %d %d", &num, &type, &elementary,
84  &physical, &color, &numNodes) != 6)
85  break;
86  }
87  else {
88  if(sscanf(buffer, "%d %d %d %d %d %d", &num, &type, &physical,
89  &elementary, &color, &numNodes) != 6)
90  break;
91  }
92  if(elementary < 0) elementary = getMaxElementaryNumber(-1) + 1;
93  if(physical < 0) physical = 0;
94  if(!type) {
95  if(warn[type]++ == 1)
96  Msg::Warning("No element type: guessing from number of nodes");
97  switch(numNodes) {
98  case 2: type = 11; break; // line
99  case 3: type = 41; break; // tri
100  case 4: type = 111; break; // tet
101  }
102  }
103 
104  switch(type) {
105  case 11:
106  case 21:
107  case 22:
108  case 31:
109  case 23:
110  case 24:
111  case 32:
112  // beam elements
113  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
114  int dum;
115  if(sscanf(buffer, "%d %d %d", &dum, &dum, &dum) != 3) break;
116  break;
117  }
118  std::vector<MVertex *> vertices(numNodes);
119  for(int i = 0; i < numNodes; i++) {
120  int n;
121  if(!gmshgets(buffer, 11, fp)) {
122  gmshclose(fp);
123  return 0;
124  }
125  if(strlen(buffer) < 10)
126  if(!gmshgets(buffer, 11, fp)) {
127  gmshclose(fp);
128  return 0;
129  }
130  if(!sscanf(buffer, "%d", &n)) {
131  gmshclose(fp);
132  return 0;
133  }
135  if(!vertices[i]) {
136  Msg::Error("Wrong node index %d", n);
137  gmshclose(fp);
138  return 0;
139  }
140  }
141  int dim = -1;
142  MElement *e = nullptr;
143  switch(type) {
144  case 11:
145  case 21:
146  case 22:
147  case 31:
148  e = new MLine(vertices, num);
149  elements[0][elementary].push_back(e);
150  dim = 1;
151  break;
152  case 23:
153  case 24:
154  case 32:
155  e = new MLine3(vertices[0], vertices[2], vertices[1], num);
156  elements[0][elementary].push_back(e);
157  dim = 1;
158  break;
159  case 41:
160  case 51:
161  case 61:
162  case 74:
163  case 81:
164  case 91:
165  e = new MTriangle(vertices, num);
166  elements[1][elementary].push_back(e);
167  dim = 2;
168  break;
169  case 42:
170  case 52:
171  case 62:
172  case 72:
173  case 82:
174  case 92:
175  e = new MTriangle6(vertices[0], vertices[2], vertices[4],
176  vertices[1], vertices[3], vertices[5], num);
177  elements[1][elementary].push_back(e);
178  dim = 2;
179  break;
180  case 44:
181  case 54:
182  case 64:
183  case 71:
184  case 84:
185  case 94:
186  e = new MQuadrangle(vertices, num);
187  elements[2][elementary].push_back(e);
188  dim = 2;
189  break;
190  case 45:
191  case 55:
192  case 65:
193  case 75:
194  case 85:
195  case 95:
196  e = new MQuadrangle8(vertices[0], vertices[2], vertices[4],
197  vertices[6], vertices[1], vertices[3],
198  vertices[5], vertices[7], num);
199  elements[2][elementary].push_back(e);
200  dim = 2;
201  break;
202  case 111:
203  e = new MTetrahedron(vertices, num);
204  elements[3][elementary].push_back(e);
205  dim = 3;
206  break;
207  case 118:
208  e = new MTetrahedron10(vertices[0], vertices[2], vertices[4],
209  vertices[9], vertices[1], vertices[3],
210  vertices[5], vertices[6], vertices[8],
211  vertices[7], num);
212  elements[3][elementary].push_back(e);
213  dim = 3;
214  break;
215  case 104:
216  case 115:
217  e = new MHexahedron(vertices, num);
218  elements[4][elementary].push_back(e);
219  dim = 3;
220  break;
221  case 105:
222  case 116:
223  e = new MHexahedron20(vertices[0], vertices[2], vertices[4],
224  vertices[6], vertices[12], vertices[14],
225  vertices[16], vertices[18], vertices[1],
226  vertices[7], vertices[8], vertices[3],
227  vertices[9], vertices[5], vertices[10],
228  vertices[11], vertices[13], vertices[19],
229  vertices[15], vertices[17], num);
230  elements[4][elementary].push_back(e);
231  dim = 3;
232  break;
233  case 101:
234  case 112:
235  e = new MPrism(vertices, num);
236  elements[5][elementary].push_back(e);
237  dim = 3;
238  break;
239  case 102:
240  case 113:
241  e = new MPrism15(vertices[0], vertices[2], vertices[4],
242  vertices[9], vertices[11], vertices[13],
243  vertices[1], vertices[5], vertices[6],
244  vertices[3], vertices[7], vertices[8],
245  vertices[10], vertices[14], vertices[12], num);
246  elements[5][elementary].push_back(e);
247  dim = 3;
248  break;
249  default:
250  if(warn[type]++ == 1)
251  Msg::Warning("Skipping unknown type of element %d", type);
252  break;
253  }
254 
255  if(dim >= 0 && physical &&
256  (!physicals[dim].count(elementary) ||
257  !physicals[dim][elementary].count(physical)))
258  physicals[dim][elementary][physical] = "unnamed";
259 
260  if(e) {
261  elementTags[num] = e;
262  elementGroups[e].push_back(elementary);
263  elementGroups[e].push_back(physical);
264  }
265  }
266  }
267  else if(record == 2477 || record == 2452 || record == 2435) {
268  if(!readGroupsOfElements) {
269  Msg::Info("Ignoring groups (set Mesh.ReadGroupsOfElements to read "
270  "groups of elements)");
271  }
272  else {
273  Msg::Info("Reading groups");
274  while(gmshgets(buffer, sizeof(buffer), fp)) {
275  if(strlen(buffer) < 3)
276  continue; // possible line ending after last fgets
277  if(!strncmp(buffer, " -1", 6)) break;
278  int num, constraint, restraint, load, dof, temperature, contact, n;
279  if(sscanf(buffer, "%d %d %d %d %d %d %d %d", &num, &constraint,
280  &restraint, &load, &dof, &temperature, &contact, &n) != 8)
281  break;
282  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
283  char name[256];
284  if(!sscanf(buffer, "%s", name)) break;
285  groupNames[num] = name;
286  int e = 0;
287  while(e < n) {
288  if(!gmshgets(buffer, sizeof(buffer), fp)) break;
289  int type, tag, leaf, comp, type2, tag2, leaf2, comp2;
290  int r = sscanf(buffer, "%d %d %d %d %d %d %d %d", &type, &tag,
291  &leaf, &comp, &type2, &tag2, &leaf2, &comp2);
292  if(r >= 4) {
293  e++;
294  if(type == 8) elementGroups[elementTags[tag]].push_back(num);
295  }
296  if(r == 8) {
297  e++;
298  if(type2 == 8) elementGroups[elementTags[tag2]].push_back(num);
299  }
300  if(r != 4 && r != 8) break;
301  }
302  }
303  }
304  }
305  }
306  }
307 
308  if(groupNames.size()) {
309  // if element groups are given, create new elementary entity tags for each
310  // unique combination of (elementary, physical, group(s)), as (elementary,
311  // physical) has no garantee to be coherent with the element groups (and is
312  // usually not - see e.g. the UNV files created by ANSA, where e.g. all
313  // surface elements can be associated with the same (elementary, physical)
314  // pair but be split amongst (possibly overlapping) element groups)
315  std::map<std::vector<int>, int> entity;
316  std::map<int, std::vector<MElement *> > elementsNew[7];
317 
318  int maxgroup = 0;
319  for(auto g : groupNames) maxgroup = std::max(g.first, maxgroup);
320 
321  for(auto &it : elementGroups) {
322  MElement *e = it.first;
323  if(e) {
324  int elementaryNew = 0;
325  auto ent = entity.find(it.second);
326  if(ent == entity.end()) {
327  elementaryNew = entity.size() + 1;
328  entity[it.second] = elementaryNew;
329  }
330  else
331  elementaryNew = ent->second;
332  int t = e->getType();
333  int k = (t == TYPE_LIN) ? 0 :
334  (t == TYPE_TRI) ? 1 :
335  (t == TYPE_QUA) ? 2 :
336  (t == TYPE_TET) ? 3 :
337  (t == TYPE_HEX) ? 4 :
338  (t == TYPE_PRI) ? 5 : -1;
339  int dim = e->getDim();
340  if(k >= 0) {
341  elementsNew[k][elementaryNew].push_back(e);
342  if(it.second.size() > 2) {
343  // we have one or more element groups
344  for(std::size_t g = 2; g < it.second.size(); g++) {
345  int physicalNew = it.second[g];
346  if(!physicals[dim].count(elementaryNew) ||
347  !physicals[dim][elementaryNew].count(physicalNew))
348  physicals[dim][elementaryNew][physicalNew] =
349  groupNames[physicalNew];
350  }
351  }
352  else if(it.second.size() > 1) {
353  int physicalNew = CTX::instance()->mesh.switchElementTags ?
354  it.second[0] : it.second[1];
355  // if the group num exists, add an offset (we could also simply not
356  // define physical groups other than those in the element
357  // groups... not sure what's best)
358  if(groupNames.count(physicalNew)) physicalNew += maxgroup;
359  if(!physicals[dim].count(elementaryNew) ||
360  !physicals[dim][elementaryNew].count(physicalNew))
361  physicals[dim][elementaryNew][physicalNew] = "unnamed";
362  }
363  }
364  }
365  }
366  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
367  elements[i] = elementsNew[i];
368  }
369 
370  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
371  _storeElementsInEntities(elements[i]);
374 
375  for(int i = 0; i < 4; i++) _storePhysicalTagsInEntities(i, physicals[i]);
376 
377  gmshclose(fp);
378  return 1;
379 }
380 
381 static std::string physicalName(GModel *m, int dim, int num)
382 {
383  std::string name = m->getPhysicalName(dim, num);
384  if(name.empty()) {
385  char tmp[256];
386  sprintf(tmp, "%s%d",
387  (dim == 3) ? "PhysicalVolume" :
388  (dim == 2) ? "PhysicalSurface" :
389  "PhysicalLine",
390  num);
391  name = tmp;
392  }
393  for(std::size_t i = 0; i < name.size(); i++)
394  if(name[i] == ' ') name[i] = '_';
395  return name;
396 }
397 
398 int GModel::writeUNV(const std::string &name, bool saveAll,
399  int saveGroupsOfElements, int saveGroupsOfNodes,
400  double scalingFactor)
401 {
402  FILE *fp = Fopen(name.c_str(), "w");
403  if(!fp) {
404  Msg::Error("Unable to open file '%s'", name.c_str());
405  return 0;
406  }
407 
408  if(noPhysicalGroups()) saveAll = true;
409 
410  indexMeshVertices(saveAll, 0, false);
411 
412  std::vector<GEntity *> entities;
413  getEntities(entities);
414 
415  // nodes
416  fprintf(fp, "%6d\n", -1);
417  fprintf(fp, "%6d\n", 2411);
418  for(std::size_t i = 0; i < entities.size(); i++)
419  for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
420  entities[i]->mesh_vertices[j]->writeUNV(
421  fp, CTX::instance()->mesh.unvStrictFormat ? true : false,
422  scalingFactor);
423  fprintf(fp, "%6d\n", -1);
424 
425  // elements
426  fprintf(fp, "%6d\n", -1);
427  fprintf(fp, "%6d\n", 2412);
428  for(std::size_t i = 0; i < entities.size(); i++) {
429  if(saveAll || entities[i]->physicals.size()) {
430  for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
431  MElement *e = entities[i]->getMeshElement(j);
432  e->writeUNV(fp, e->getNum(), entities[i]->tag(), 0);
433  }
434  }
435  }
436  fprintf(fp, "%6d\n", -1);
437 
438  // save groups of nodes (resp. elements) for each physical group if
439  // saveGroupsOfNodes (resp. saveGroupsOfElements) is positive; if negative,
440  // only save groups if the (dim+1)^th least significant digit of
441  // -saveGroupsOfNodes (resp. -saveGroupsOfElements) is non-zero.
442  if(saveGroupsOfNodes || saveGroupsOfElements) {
443  std::map<int, std::vector<GEntity *> > groups[4];
444  getPhysicalGroups(groups);
445 
446  fprintf(fp, "%6d\n", -1);
447  fprintf(fp, "%6d\n", 2477);
448  for(int dim = 0; dim <= 3; dim++) {
449  bool saveNodes =
450  (saveGroupsOfNodes > 0 ||
451  (saveGroupsOfNodes < 0 &&
452  ((-saveGroupsOfNodes / (int)std::pow(10, dim)) % 10) == 1));
453  bool saveElements =
454  (saveGroupsOfElements > 0 ||
455  (saveGroupsOfElements < 0 &&
456  ((-saveGroupsOfElements / (int)std::pow(10, dim)) % 10) == 1));
457 
458  for(auto it = groups[dim].begin(); it != groups[dim].end(); it++) {
459  std::vector<GEntity *> &entities = it->second;
460 
461  std::set<MVertex *, MVertexPtrLessThan> nodes;
462  if(saveNodes) {
463  for(std::size_t i = 0; i < entities.size(); i++) {
464  for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
465  MElement *e = entities[i]->getMeshElement(j);
466  for(std::size_t k = 0; k < e->getNumVertices(); k++)
467  nodes.insert(e->getVertex(k));
468  }
469  }
470  }
471 
472  int nele = 0;
473  if(saveElements) {
474  for(std::size_t i = 0; i < entities.size(); i++)
475  nele += entities[i]->getNumMeshElements();
476  }
477 
478  fprintf(fp, "%10d%10d%10d%10d%10d%10d%10d%10d\n", it->first, 0, 0, 0, 0,
479  0, 0, (int)nodes.size() + nele);
480  fprintf(fp, "%s\n", physicalName(this, dim, it->first).c_str());
481 
482  int row = 0;
483  if(saveNodes) {
484  for(auto it2 = nodes.begin(); it2 != nodes.end(); it2++) {
485  if(row == 2) {
486  fprintf(fp, "\n");
487  row = 0;
488  }
489  fprintf(fp, "%10d%10ld%10d%10d", 7, (*it2)->getIndex(), 0, 0);
490  row++;
491  }
492  }
493 
494  // this output will be consumed by legacy codes that rely on full lines,
495  // each having two entities even if the first is a node and the second
496  // is an element
497  if(row == 2) {
498  fprintf(fp, "\n");
499  row = 0;
500  }
501 
502  if(saveElements) {
503  for(std::size_t i = 0; i < entities.size(); i++) {
504  for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
505  MElement *e = entities[i]->getMeshElement(j);
506  if(row == 2) {
507  fprintf(fp, "\n");
508  row = 0;
509  }
510  fprintf(fp, "%10d%10lu%10d%10d", 8, e->getNum(), 0, 0);
511  row++;
512  }
513  }
514  fprintf(fp, "\n");
515  }
516  else {
517  // print a final newline only if the count is odd
518  if(row == 1) { fprintf(fp, "\n"); }
519  }
520  }
521  }
522  fprintf(fp, "%6d\n", -1);
523  }
524 
525  fclose(fp);
526  return 1;
527 }
MElement::getNum
virtual std::size_t getNum() const
Definition: MElement.h:68
MTriangle.h
gmshclose
#define gmshclose
Definition: GModelIO_UNV.cpp:32
MPrism15
Definition: MPrism.h:263
GModel::getMaxElementaryNumber
int getMaxElementaryNumber(int dim)
Definition: GModel.cpp:817
GModel::readUNV
int readUNV(const std::string &name, bool readGroupsOfElements=true)
Definition: GModelIO_UNV.cpp:36
TYPE_LIN
#define TYPE_LIN
Definition: GmshDefines.h:65
MTetrahedron
Definition: MTetrahedron.h:34
MLine3
Definition: MLine.h:128
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
physicalName
static std::string physicalName(GModel *m, int dim, int num)
Definition: GModelIO_UNV.cpp:381
OS.h
GModel::load
void load(const std::string &fileName)
Definition: GModel.cpp:3424
MVertex
Definition: MVertex.h:24
MElement::getDim
virtual int getDim() const =0
MElementPtrLessThan
Definition: MElement.h:527
MElement::writeUNV
virtual void writeUNV(FILE *fp, int num=0, int elementary=1, int physical=1)
Definition: MElement.cpp:1741
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GModel::_storeElementsInEntities
void _storeElementsInEntities(std::map< int, std::vector< MElement * > > &map)
Definition: GModel.cpp:2273
GModel::getMeshVertexByTag
MVertex * getMeshVertexByTag(int n)
Definition: GModel.cpp:1953
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
MTetrahedron10
Definition: MTetrahedron.h:233
MPrism
Definition: MPrism.h:34
MLine.h
GModel::getNumMeshElements
std::size_t getNumMeshElements(int dim=-1) const
Definition: GModel.cpp:1540
TYPE_PRI
#define TYPE_PRI
Definition: GmshDefines.h:70
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
MLine
Definition: MLine.h:21
contextMeshOptions::switchElementTags
int switchElementTags
Definition: Context.h:67
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
GModel::getPhysicalGroups
void getPhysicalGroups(std::map< int, std::vector< GEntity * > > groups[4]) const
Definition: GModel.cpp:837
GModel::getPhysicalName
std::string getPhysicalName(int dim, int num) const
Definition: GModel.cpp:961
MElement::getType
virtual int getType() const =0
MHexahedron.h
gmshopen
#define gmshopen
Definition: GModelIO_UNV.cpp:30
gmsheof
#define gmsheof
Definition: GModelIO_UNV.cpp:33
MQuadrangle8
Definition: MQuadrangle.h:203
GModel
Definition: GModel.h:44
GModel::vertices
std::set< GVertex *, GEntityPtrLessThan > vertices
Definition: GModel.h:146
MHexahedron
Definition: MHexahedron.h:28
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
MElement
Definition: MElement.h:30
GModel::_vertexMapCache
std::map< int, MVertex * > _vertexMapCache
Definition: GModel.h:102
GModel::writeUNV
int writeUNV(const std::string &name, bool saveAll=false, int saveGroupsOfElements=0, int saveGroupsOfNodes=0, double scalingFactor=1.0)
Definition: GModelIO_UNV.cpp:398
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
MTriangle
Definition: MTriangle.h:26
gmshgets
#define gmshgets
Definition: GModelIO_UNV.cpp:31
TYPE_QUA
#define TYPE_QUA
Definition: GmshDefines.h:67
gmshFILE
FILE * gmshFILE
Definition: GModelIO_UNV.cpp:29
Context.h
MTetrahedron.h
MTriangle6
Definition: MTriangle.h:191
MHexahedron20
Definition: MHexahedron.h:251
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MQuadrangle.h
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
TYPE_HEX
#define TYPE_HEX
Definition: GmshDefines.h:71
MPrism.h
TYPE_TET
#define TYPE_TET
Definition: GmshDefines.h:68
GModel::mesh
int mesh(int dimension)
Definition: GModel.cpp:1066
GModel.h
GModel::_storeVerticesInEntities
void _storeVerticesInEntities(std::map< int, MVertex * > &vertices)
Definition: GModel.cpp:2496
GModel::_associateEntityWithMeshVertices
void _associateEntityWithMeshVertices()
Definition: GModel.cpp:2470
MQuadrangle
Definition: MQuadrangle.h:26
GModel::indexMeshVertices
std::size_t indexMeshVertices(bool all, int singlePartition=0, bool renumber=true)
Definition: GModel.cpp:2135
GModel::_storePhysicalTagsInEntities
void _storePhysicalTagsInEntities(int dim, std::map< int, std::map< int, std::string > > &map)
Definition: GModel.cpp:2568