gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_KEY.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 "GModel.h"
7 #include "OS.h"
8 #include "MPoint.h"
9 #include "MLine.h"
10 #include "MTriangle.h"
11 #include "MQuadrangle.h"
12 #include "MTetrahedron.h"
13 #include "MHexahedron.h"
14 #include "MPrism.h"
15 #include "MPyramid.h"
16 
17 static std::string physicalName(GModel *m, int dim, int num)
18 {
19  std::string name = m->getPhysicalName(dim, num);
20  if(name.empty()) {
21  char tmp[256];
22  sprintf(tmp, "%s%d",
23  (dim == 3) ? "PhysicalVolume" :
24  (dim == 2) ? "PhysicalSurface" :
25  "PhysicalLine",
26  num);
27  name = tmp;
28  }
29  for(std::size_t i = 0; i < name.size(); i++)
30  if(name[i] == ' ') name[i] = '_';
31  return name;
32 }
33 
34 static int partID(int dim, int num) { return dim * 1000000 + num; }
35 
36 template <class T>
37 static void writeElementsKEY(FILE *fp, GEntity *ge, std::vector<T *> &elements,
38  bool saveAll)
39 {
40  if(elements.size() && (saveAll || ge->physicals.size())) {
41  const char *typ = elements[0]->getStringForKEY();
42  int pid = partID(ge->dim(), ge->tag());
43  if(typ) {
44  fprintf(fp, "*ELEMENT%s\n$#SET_ELEMENT=%s%d\n", typ,
45  physicalName(ge->model(), ge->dim(), ge->tag()).c_str(),
46  ge->tag());
47  for(std::size_t i = 0; i < elements.size(); i++)
48  elements[i]->writeKEY(fp, pid, elements[i]->getNum());
49  }
50  }
51 }
52 
53 int GModel::writeKEY(const std::string &name, int saveAll,
54  int saveGroupsOfNodes, double scalingFactor)
55 {
56  FILE *fp = Fopen(name.c_str(), "w");
57  if(!fp) {
58  Msg::Error("Unable to open file '%s'", name.c_str());
59  return 0;
60  }
61 
62  // FIXME: we should probably use the same conventions here as in the UNV, INP
63  // and TOCHNOG writer, i.e. not mess around with saveAll, and use negative
64  // saveGroupsOfNodes to selectively save groups of different dimensions.
65 
66  if(noPhysicalGroups()) saveAll = 0x51;
67 
68  indexMeshVertices(saveAll & 0x51, 0, false);
69  std::vector<GEntity *> entities;
70  getEntities(entities);
71 
72  fprintf(fp, "$# LS-DYNA Keyword file created by Gmsh\n*KEYWORD\n*TITLE\n");
73  fprintf(fp, " %s\n", name.c_str());
74 
75  fprintf(fp, "*NODE\n");
76  for(std::size_t i = 0; i < entities.size(); i++)
77  for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
78  entities[i]->mesh_vertices[j]->writeKEY(fp, scalingFactor);
79 
80  if(!(saveAll & 0x2)) // save or ignore points (not in GUI)
81  for(auto it = firstVertex(); it != lastVertex(); ++it) {
82  writeElementsKEY(fp, *it, (*it)->points, saveAll & 0x1);
83  }
84  if(!(saveAll & 0x8)) // save or ignore line
85  for(auto it = firstEdge(); it != lastEdge(); ++it) {
86  writeElementsKEY(fp, *it, (*it)->lines, saveAll & 0x4);
87  }
88  if(!(saveAll & 0x20)) // save or ignore surface
89  for(auto it = firstFace(); it != lastFace(); ++it) {
90  writeElementsKEY(fp, *it, (*it)->triangles, saveAll & 0x10);
91  writeElementsKEY(fp, *it, (*it)->quadrangles, saveAll & 0x10);
92  }
93  if(!(saveAll & 0x80)) // save or ignore volume
94  for(auto it = firstRegion(); it != lastRegion(); ++it) {
95  writeElementsKEY(fp, *it, (*it)->tetrahedra, saveAll & 0x40);
96  writeElementsKEY(fp, *it, (*it)->hexahedra, saveAll & 0x40);
97  writeElementsKEY(fp, *it, (*it)->prisms, saveAll & 0x40);
98  writeElementsKEY(fp, *it, (*it)->pyramids, saveAll & 0x40);
99  }
100 
101  std::map<int, std::vector<GEntity *> > groups[4];
102  getPhysicalGroups(groups);
103 
104  int setid = 0;
105  // save elements sets for each physical group
106  if(saveGroupsOfNodes & 0x2) {
107  for(int dim = 0; dim <= 3; dim++) {
108  if(saveAll & (0x2 << (2 * dim))) continue; // elements are ignored
109  for(auto it = groups[dim].begin(); it != groups[dim].end(); it++) {
110  std::vector<GEntity *> &entities = it->second;
111  int n = 0;
112  for(std::size_t i = 0; i < entities.size(); i++) {
113  for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
114  MElement *e = entities[i]->getMeshElement(j);
115  if(!n) {
116  const char *str = (e->getDim() == 3) ? "SOLID" :
117  (e->getDim() == 2) ? "SHELL" :
118  (e->getDim() == 1) ? "BEAM" :
119  "NODE";
120  fprintf(fp, "*SET_%s_LIST\n$# %s\n%d", str,
121  physicalName(this, dim, it->first).c_str(), ++setid);
122  }
123  if(!(n % 8))
124  fprintf(fp, "\n%lu", e->getNum());
125  else
126  fprintf(fp, ", %lu", e->getNum());
127  n++;
128  }
129  }
130  if(n) fprintf(fp, "\n");
131  }
132  }
133  }
134 
135  // save node sets for each physical group, for easier load/b.c.
136  if(saveGroupsOfNodes & 0x1) {
137  for(int dim = 1; dim <= 3; dim++) {
138  for(auto it = groups[dim].begin(); it != groups[dim].end(); it++) {
139  std::set<MVertex *> nodes;
140  std::vector<GEntity *> &entities = it->second;
141  for(std::size_t i = 0; i < entities.size(); i++) {
142  for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
143  MElement *e = entities[i]->getMeshElement(j);
144  for(std::size_t k = 0; k < e->getNumVertices(); k++)
145  nodes.insert(e->getVertex(k));
146  }
147  }
148  fprintf(fp, "*SET_NODE_LIST\n$# %s\n%d",
149  physicalName(this, dim, it->first).c_str(), ++setid);
150  int n = 0;
151  for(auto it2 = nodes.begin(); it2 != nodes.end(); it2++) {
152  if(!(n % 8))
153  fprintf(fp, "\n%ld", (*it2)->getIndex());
154  else
155  fprintf(fp, ", %ld", (*it2)->getIndex());
156  n++;
157  }
158  if(n) fprintf(fp, "\n");
159  }
160  }
161  }
162 
163  fprintf(fp, "*END\n");
164  fclose(fp);
165  return 1;
166 }
MElement::getNum
virtual std::size_t getNum() const
Definition: MElement.h:68
MTriangle.h
GModel::firstEdge
eiter firstEdge()
Definition: GModel.h:356
GModel::writeKEY
int writeKEY(const std::string &name, int saveAll=0, int saveGroupsOfNodes=0, double scalingFactor=1.0)
Definition: GModelIO_KEY.cpp:53
GEntity::model
GModel * model() const
Definition: GEntity.h:277
OS.h
MElement::getDim
virtual int getDim() const =0
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GEntity::physicals
std::vector< int > physicals
Definition: GEntity.h:65
writeElementsKEY
static void writeElementsKEY(FILE *fp, GEntity *ge, std::vector< T * > &elements, bool saveAll)
Definition: GModelIO_KEY.cpp:37
MPoint.h
GModel::firstVertex
viter firstVertex()
Definition: GModel.h:357
MLine.h
GEntity
Definition: GEntity.h:31
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
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::lastFace
fiter lastFace()
Definition: GModel.h:359
GModel::getPhysicalName
std::string getPhysicalName(int dim, int num) const
Definition: GModel.cpp:961
MHexahedron.h
GModel::lastVertex
viter lastVertex()
Definition: GModel.h:361
GModel
Definition: GModel.h:44
MPyramid.h
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
physicalName
static std::string physicalName(GModel *m, int dim, int num)
Definition: GModelIO_KEY.cpp:17
MElement
Definition: MElement.h:30
GEntity::tag
int tag() const
Definition: GEntity.h:280
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
partID
static int partID(int dim, int num)
Definition: GModelIO_KEY.cpp:34
GModel::firstRegion
riter firstRegion()
Definition: GModel.h:354
GModel::lastRegion
riter lastRegion()
Definition: GModel.h:358
MTetrahedron.h
MQuadrangle.h
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
MPrism.h
GModel::lastEdge
eiter lastEdge()
Definition: GModel.h:360
GModel.h
GEntity::dim
virtual int dim() const
Definition: GEntity.h:196
GModel::indexMeshVertices
std::size_t indexMeshVertices(bool all, int singlePartition=0, bool renumber=true)
Definition: GModel.cpp:2135