gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_SU2.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 "MElement.h"
11 
12 static std::string physicalName(GModel *m, int dim, int num)
13 {
14  std::string name = m->getPhysicalName(dim, num);
15  if(name.empty()) {
16  char tmp[256];
17  sprintf(tmp, "%s%d",
18  (dim == 3) ? "PhysicalVolume" :
19  (dim == 2) ? "PhysicalSurface" :
20  "PhysicalLine",
21  num);
22  name = tmp;
23  }
24  for(std::size_t i = 0; i < name.size(); i++)
25  if(name[i] == ' ') name[i] = '_';
26  return name;
27 }
28 
29 int GModel::writeSU2(const std::string &name, bool saveAll,
30  double scalingFactor)
31 {
32  FILE *fp = Fopen(name.c_str(), "w");
33  if(!fp) {
34  Msg::Error("Unable to open file '%s'", name.c_str());
35  return 0;
36  }
37 
38  int ndime = getDim();
39  if(ndime != 2 && ndime != 3) {
40  Msg::Error("SU2 mesh output valid only for 2D or 3D models (not %dD)",
41  ndime);
42  fclose(fp);
43  return 0;
44  }
45 
46  if(noPhysicalGroups()) saveAll = true;
47 
48  fprintf(fp, "NDIME= %d\n", ndime);
49 
50  // all interior elements are printed in a single section; indices start at 0;
51  // node ordering is the same as VTK
52  int nelem = 0;
53  if(ndime == 2) {
54  for(auto it = firstFace(); it != lastFace(); it++)
55  if(saveAll || (*it)->physicals.size())
56  nelem += (*it)->getNumMeshElements();
57  }
58  else {
59  for(auto it = firstRegion(); it != lastRegion(); it++)
60  if(saveAll || (*it)->physicals.size())
61  nelem += (*it)->getNumMeshElements();
62  }
63  int npoin = indexMeshVertices(saveAll);
64 
65  Msg::Info("Writing %d elements and %d nodes", nelem, npoin);
66 
67  // elements
68  fprintf(fp, "NELEM= %d\n", nelem);
69  int num = 0;
70  if(ndime == 2) {
71  for(auto it = firstFace(); it != lastFace(); it++)
72  if(saveAll || (*it)->physicals.size())
73  for(std::size_t i = 0; i < (*it)->getNumMeshElements(); i++)
74  (*it)->getMeshElement(i)->writeSU2(fp, num++);
75  }
76  else {
77  for(auto it = firstRegion(); it != lastRegion(); it++)
78  if(saveAll || (*it)->physicals.size())
79  for(std::size_t i = 0; i < (*it)->getNumMeshElements(); i++)
80  (*it)->getMeshElement(i)->writeSU2(fp, num++);
81  }
82 
83  // vertices
84  fprintf(fp, "NPOIN= %d\n", npoin);
85  std::vector<GEntity *> entities;
86  getEntities(entities);
87  for(std::size_t i = 0; i < entities.size(); i++)
88  for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
89  entities[i]->mesh_vertices[j]->writeSU2(fp, ndime, scalingFactor);
90 
91  // markers for physical groups of dimensions (ndime - 1) and ndime
92  std::map<int, std::vector<GEntity *> > groups[4];
93  getPhysicalGroups(groups);
94  int nmark = groups[ndime - 1].size() + groups[ndime].size();
95  if(nmark) {
96  fprintf(fp, "NMARK= %d\n", nmark);
97  for(int dim = ndime-1; dim <= ndime; dim++) {
98  if(groups[dim].size()) {
99  for(auto it = groups[dim].begin(); it != groups[dim].end(); it++) {
100  std::vector<GEntity *> &entities = it->second;
101  int n = 0;
102  for(std::size_t i = 0; i < entities.size(); i++)
103  n += entities[i]->getNumMeshElements();
104  if(n) {
105  fprintf(fp, "MARKER_TAG= %s\n", physicalName(this, dim, it->first).c_str());
106  fprintf(fp, "MARKER_ELEMS= %d\n", n);
107  for(std::size_t i = 0; i < entities.size(); i++)
108  for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++)
109  entities[i]->getMeshElement(j)->writeSU2(fp, -1);
110  }
111  }
112  }
113  }
114  }
115 
116  fclose(fp);
117  return 1;
118 }
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
OS.h
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GModel::getNumMeshElements
std::size_t getNumMeshElements(int dim=-1) const
Definition: GModel.cpp:1540
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
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
GModel::getDim
int getDim() const
Definition: GModel.cpp:989
GModel
Definition: GModel.h:44
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
GModel::firstRegion
riter firstRegion()
Definition: GModel.h:354
GModel::lastRegion
riter lastRegion()
Definition: GModel.h:358
GModel::writeSU2
int writeSU2(const std::string &name, bool saveAll, double scalingFactor)
Definition: GModelIO_SU2.cpp:29
MElement.h
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
physicalName
static std::string physicalName(GModel *m, int dim, int num)
Definition: GModelIO_SU2.cpp:12
GModel.h
GModel::indexMeshVertices
std::size_t indexMeshVertices(bool all, int singlePartition=0, bool renumber=true)
Definition: GModel.cpp:2135