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