gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GModelIO_CGNS.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 <vector>
7 #include "Context.h"
8 #include "GModel.h"
9 #include "CGNSCommon.h"
10 #include "CGNSConventions.h"
11 #include "CGNSWrite.h"
12 #include "CGNSWriteStruct.h"
13 #include "CGNSZone.h"
14 #include "CGNSZoneStruct.h"
15 #include "CGNSZoneUnstruct.h"
16 #include "CGNSRead.h"
17 
18 #if defined(HAVE_LIBCGNS)
19 
20 int GModel::readCGNS(const std::string &name,
21  std::vector<std::vector<MVertex *> > &vertPerZone,
22  std::vector<std::vector<MElement *> > &eltPerZone)
23 {
24  int cgnsErr;
25 
26  // open CGNS file and read scale
27  int fileIndex = 0;
28  cgnsErr = cg_open(name.c_str(), CG_MODE_READ, &fileIndex);
29  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);
30 
31  // read base node
32  const int baseIndex = 1;
33  int dim = 0, meshDim = 0;
34  char baseName[CGNS_MAX_STR_LEN];
35  cgnsErr = cg_base_read(fileIndex, baseIndex, baseName, &meshDim, &dim);
36  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);
37 
38  // read scale
39  double scale;
40  int scaleErr = readScale(fileIndex, baseIndex, scale);
41  if(scaleErr == 0) return 0;
42 
43  // per-element node transformation for CPEX0045
44  Family2EltNodeTransfo allEltNodeTransfo;
45  readEltNodeTransfo(fileIndex, baseIndex, allEltNodeTransfo);
46 
47  // define names of geometrical entities
48  // index start at 1 with empty name to account for unclassified elements
49  std::vector<std::string> allGeomName(2, "");
50 
51  // read number of zones (allZones[0] is dummy because index starts at 1)
52  int nbZone = 0;
53  cgnsErr = cg_nzones(fileIndex, baseIndex, &nbZone);
54  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);
55 
56  // create all zones by reading basic info
57  std::vector<CGNSZone *> allZones(nbZone + 1);
58  std::map<std::string, int> name2Zone;
59  bool postpro;
60  createZones(fileIndex, baseIndex, meshDim, allEltNodeTransfo, allZones,
61  name2Zone, postpro);
62 
63  // data structures for element and vertices
64  std::vector<MVertex *> allVert; // all vertices
65  std::map<int, std::vector<MElement *> > allElt[10]; // all elements by type
66 
67  // vertex and element (global) tags per zone for postpro
68  vertPerZone.resize(nbZone + 1);
69  eltPerZone.resize(nbZone + 1);
70 
71  // read mesh in zones
72  for(int iZone = 1; iZone <= nbZone; iZone++) {
73  CGNSZone *zone = allZones[iZone];
74  int err =
75  zone->readMesh(dim, scale, allZones, allVert, allElt, vertPerZone[iZone],
76  eltPerZone[iZone], allGeomName);
77  if((!postpro) || (CTX::instance()->mesh.cgnsImportIgnoreSolution != 0)) {
78  vertPerZone[iZone].clear();
79  eltPerZone[iZone].clear();
80  }
81  if(err == 0) return 0;
82  }
83 
84  // set periodic vertices in each zone
85  for(int iZone = 1; iZone <= nbZone; iZone++) {
86  allZones[iZone]->setPeriodicVertices(allZones, allVert);
87  }
88 
89  // get physical names, index start at 1
90  std::multimap<std::string, int> geomName2Phys;
91  std::vector<std::string> allPhysName(1, "");
92  int errPhys = readPhysicals(fileIndex, baseIndex, allPhysName, geomName2Phys);
93  if(errPhys == 0) return 0;
94 
95  // close file
96  cgnsErr = cg_close(fileIndex);
97  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__);
98 
99  // populate data structures with elements and vertices
100  for(int i = 0; i < 10; i++) _storeElementsInEntities(allElt[i]);
102  _storeVerticesInEntities(allVert);
103 
104  // add periodic vertex correspondence and affine transformation
105  setPeriodicityInEntities(allZones);
106 
107  // remove potential duplicate vertices if several zones (keeping vertices
108  // classified on entities of lowest dimension)
109  // TODO: disable this through option ?
110  if(nbZone > 1) removeDuplicateMeshVertices(CTX::instance()->geom.tolerance);
111 
112  // set names of geometric entities and physical names
113  setGeomAndPhysicalEntities(this, meshDim, allGeomName, allPhysName,
114  geomName2Phys);
115  // destroy all zones
116  for(std::size_t iZone = 0; iZone < allZones.size(); iZone++) {
117  if(allZones[iZone] != nullptr) delete allZones[iZone];
118  }
119 
120  // reconstruct geometrical topology if required
121  if(CTX::instance()->mesh.cgnsConstructTopology) createTopologyFromMesh();
122 
123  return postpro ? 2 : 1;
124 }
125 
126 int GModel::writeCGNS(const std::string &name, bool saveAll,
127  double scalingFactor, bool structured)
128 {
129  int cgnsErr;
130 
131  int cgIndexFile = 0;
132  cgnsErr = cg_open(name.c_str(), CG_MODE_WRITE, &cgIndexFile);
133  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, cgIndexFile);
134 
135  // write the base node
136  int meshDim = getMeshDim(), dim = 3, cgIndexBase = 0;
137  size_t posStartName = name.find_last_of("/\\");
138  if(posStartName == std::string::npos)
139  posStartName = 0;
140  else
141  posStartName++;
142  std::string baseName = cgnsString(name.substr(posStartName));
143  cgnsErr =
144  cg_base_write(cgIndexFile, baseName.c_str(), meshDim, dim, &cgIndexBase);
145  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, cgIndexFile);
146 
147  // write information about who generated the mesh
148  cgnsErr = cg_goto(cgIndexFile, cgIndexBase, "end");
149  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, cgIndexFile);
150  cgnsErr = cg_descriptor_write("About", "Created by Gmsh");
151  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, cgIndexFile);
152 
153  // try to write as structured grid (if it fails, write as unstructured)
154  if(structured &&
155  writeZonesStruct(this, scalingFactor, cgIndexFile, cgIndexBase)) {
156  cgnsErr = cg_close(cgIndexFile);
157  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__);
158  return 1;
159  }
160 
161  // zone names
162  const size_t numPart = getNumPartitions();
163  std::vector<std::string> zoneName(numPart + 1);
164 
165  // index mesh nodes, as CGNS does not store node tags
166  if(noPhysicalGroups()) saveAll = true;
167  const size_t numNodes = indexMeshVertices(saveAll);
168 
169  // get entities from model
170  std::vector<GEntity *> allEntities, entities, entitiesPer, entitiesInterf;
171  getEntities(allEntities);
172  getEntitiesToSave(allEntities, saveAll, entities);
173  getPeriodicEntities(allEntities, entitiesPer);
174  if(numPart > 0) {
175  getPartitionInterfaceEntities(allEntities, saveAll, entitiesInterf);
176  if(entitiesInterf.size() == 0) {
177  Msg::Warning("Partitioned entities not detected");
178  }
179  }
180 
181  // initialize vertex -> (partition, local node index) for periodic and
182  // interface entities
183  Vertex2LocalData interfVert2Local;
184  initInterfVertex2LocalData(entitiesPer, entitiesInterf, interfVert2Local);
185  Msg::Info("%lu periodic/interface nodes", interfVert2Local.size());
186 
187  // write partitions and periodic/partition connectivities
188  std::set<int> eleMshTypes;
189  std::map<GEntity *, std::string> geomEntities;
190  if(numPart == 0) { // mesh not partitioned
191  int err = writeZone(this, saveAll, scalingFactor, meshDim, numNodes, 0,
192  entities, cgIndexFile, cgIndexBase, zoneName,
193  interfVert2Local, eleMshTypes, geomEntities);
194  if(err == 0) return 0;
195  if(entitiesPer.size() > 0) {
196  err = writePeriodic(entitiesPer, cgIndexFile, cgIndexBase, zoneName,
197  interfVert2Local);
198  if(err == 0) return 0;
199  }
200  }
201  else { // partitioned mesh
202  std::vector<std::vector<GEntity *> > entitiesPart;
203  entitiesPart.resize(numPart + 1);
204  getEntitiesInPartitions(entities, entitiesPart);
205  for(std::size_t iPart = 1; iPart <= numPart; iPart++) {
206  printProgress("Writing partition", iPart, numPart);
207  int err =
208  writeZone(this, saveAll, scalingFactor, meshDim, numNodes, iPart,
209  entitiesPart[iPart], cgIndexFile, cgIndexBase, zoneName,
210  interfVert2Local, eleMshTypes, geomEntities);
211  if(err == 0) return 0;
212  } // loop on partitions
213  if(entitiesPer.size() > 0) {
214  int err = writePeriodic(entitiesPer, cgIndexFile, cgIndexBase, zoneName,
215  interfVert2Local);
216  if(err == 0) return 0;
217  }
218  if(entitiesInterf.size() > 0) {
219  int err = writeInterfaces(entitiesInterf, cgIndexFile, cgIndexBase,
220  zoneName, interfVert2Local);
221  if(err == 0) return 0;
222  }
223  } // numPart == 0
224 
225  // write geometric entities in families
226  if(geomEntities.size() > 0) {
227  writeGeomEntities(geomEntities, cgIndexFile, cgIndexBase);
228  }
229 
230  // write element high-orper point info for CPEX0045 if required
231  if(CTX::instance()->mesh.cgnsExportCPEX0045) {
232  int err = writeHOPointInfo(eleMshTypes, cgIndexFile, cgIndexBase);
233  if(err == 0) return 0;
234  }
235 
236  cgnsErr = cg_close(cgIndexFile);
237  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__);
238 
239  return 1;
240 }
241 
242 #else
243 
244 int GModel::readCGNS(const std::string &name,
245  std::vector<std::vector<MVertex *> > &vertPerZone,
246  std::vector<std::vector<MElement *> > &eltPerZone)
247 {
248  Msg::Error("This version of Gmsh was compiled without CGNS support");
249  return 0;
250 }
251 
252 int GModel::writeCGNS(const std::string &name, bool saveAll,
253  double scalingFactor, bool structured)
254 {
255  Msg::Error("This version of Gmsh was compiled without CGNS support");
256  return 0;
257 }
258 
259 #endif
GModel::writeCGNS
int writeCGNS(const std::string &name, bool saveAll=false, double scalingFactor=1.0, bool structured=false)
Definition: GModelIO_CGNS.cpp:252
CGNSZoneStruct.h
CGNSRead.h
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GModel::removeDuplicateMeshVertices
int removeDuplicateMeshVertices(double tolerance, const std::vector< GEntity * > &entities=std::vector< GEntity * >())
Definition: GModel.cpp:2684
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
CGNSZone.h
GModel::getMeshDim
int getMeshDim() const
Definition: GModel.cpp:998
CGNSZoneUnstruct.h
GModel::getNumPartitions
std::size_t getNumPartitions() const
Definition: GModel.h:602
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
GModel::readCGNS
int readCGNS(const std::string &name, std::vector< std::vector< MVertex * > > &vertPerZone, std::vector< std::vector< MElement * > > &eltPerZone)
Definition: GModelIO_CGNS.cpp:244
CGNSWrite.h
getEntitiesToSave
static void getEntitiesToSave(GModel *const model, bool partitioned, int partitionToSave, bool saveAll, std::set< GRegion *, GEntityPtrLessThan > &regions, std::set< GFace *, GEntityPtrLessThan > &faces, std::set< GEdge *, GEntityPtrLessThan > &edges, std::set< GVertex *, GEntityPtrLessThan > &vertices)
Definition: GModelIO_MSH4.cpp:2211
GModel::createTopologyFromMesh
void createTopologyFromMesh()
Definition: GModelCreateTopologyFromMesh.cpp:663
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
CGNSConventions.h
CGNSCommon.h
Context.h
GModel::noPhysicalGroups
bool noPhysicalGroups()
Definition: GModel.cpp:828
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
CGNSWriteStruct.h
GModel::indexMeshVertices
std::size_t indexMeshVertices(bool all, int singlePartition=0, bool renumber=true)
Definition: GModel.cpp:2135
scale
static void scale(std::vector< double > &x, double s)
Definition: ConjugateGradients.cpp:21