gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
CGNSZoneUnstruct.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 // Contributor(s):
7 // Thomas Toulorge
8 
9 #include "GmshMessage.h"
10 #include "MVertex.h"
11 #include "MElement.h"
12 #include "CGNSCommon.h"
13 #include "CGNSConventions.h"
14 #include "CGNSZoneUnstruct.h"
15 
16 #if defined(HAVE_LIBCGNS)
17 
18 namespace {
19 
20  MElement *createElement(CGNS_ENUMT(ElementType_t) sectEltType,
21  std::size_t vertShift, int entity,
22  const std::vector<MVertex *> &allVert,
23  std::map<int, std::vector<MElement *> > *allElt,
24  const std::vector<cgsize_t> &sectData,
25  const ZoneEltNodeTransfo *eltNodeTransfo,
26  const std::vector<SPoint3> &rawNode,
27  std::size_t &iSectData)
28  {
29  // get element type
30  CGNS_ENUMT(ElementType_t) eltType;
31  if(sectEltType == CGNS_ENUMV(MIXED)) {
32  eltType = static_cast<CGNS_ENUMT(ElementType_t)>(sectData[iSectData]);
33  iSectData++;
34  }
35  else
36  eltType = sectEltType;
37 
38  // get element vertices in Gmsh ordering
39  int mshEltType = cgns2MshEltType(eltType);
40  int nbEltNode = ElementType::getNumVertices(mshEltType);
41 
42  // element high-order node transformation if specified (CPEX0045), otherwise
43  // use the classic CGNS order
44  const std::vector<int> *nodeTransfo = nullptr;
45  if((mshEltType != MSH_PNT) && (eltNodeTransfo != nullptr) &&
46  (eltNodeTransfo->size() > 0)) {
47  nodeTransfo = &((*eltNodeTransfo)[mshEltType]);
48  }
49  else
50  nodeTransfo = &(cgns2MshNodeIndex(mshEltType));
51 
52  // get element vertices
53  std::vector<MVertex *> eltVert(nbEltNode);
54  for(int iEltNode = 0; iEltNode < nbEltNode; iEltNode++, iSectData++) {
55  const int indNode = vertShift + sectData[iSectData] - 1;
56  eltVert[(*nodeTransfo)[iEltNode]] = allVert[indNode];
57  }
58 
59  // create element
60  MElementFactory factory;
61  MElement *e = factory.create(mshEltType, eltVert);
62 
63  // add element to data structure
64  switch(e->getType()) {
65  case TYPE_PNT: allElt[0][entity].push_back(e); break;
66  case TYPE_LIN: allElt[1][entity].push_back(e); break;
67  case TYPE_TRI: allElt[2][entity].push_back(e); break;
68  case TYPE_QUA: allElt[3][entity].push_back(e); break;
69  case TYPE_TET: allElt[4][entity].push_back(e); break;
70  case TYPE_HEX: allElt[5][entity].push_back(e); break;
71  case TYPE_PRI: allElt[6][entity].push_back(e); break;
72  case TYPE_PYR: allElt[7][entity].push_back(e); break;
73  case TYPE_POLYG: allElt[8][entity].push_back(e); break;
74  case TYPE_POLYH: allElt[9][entity].push_back(e); break;
75  default: Msg::Error("Wrong type of element");
76  }
77 
78  return e;
79  }
80 
81 } // namespace
82 
83 CGNSZoneUnstruct::CGNSZoneUnstruct(
84  int fileIndex, int baseIndex, int zoneIndex, int meshDim, cgsize_t startNode,
85  const Family2EltNodeTransfo &allEltNodeTransfo, int &err)
86  : CGNSZone(fileIndex, baseIndex, zoneIndex, CGNS_ENUMV(Unstructured), meshDim,
87  startNode, allEltNodeTransfo, err)
88 {
89  if(err == 0) return;
90 
91  // number of nodes and elements
92  nbNode_ = size_[0];
93  nbElt_ = size_[1];
94 
95  interfaceNode_.resize(nbNode());
96 }
97 
98 int CGNSZoneUnstruct::readSection(
99  int iSect, const std::vector<MVertex *> &allVert,
100  const std::vector<SPoint3> &rawNode,
101  std::map<int, std::vector<MElement *> > *allElt,
102  std::vector<MElement *> &zoneElt)
103 {
104  int cgnsErr;
105 
106  // read section information
107  char sectName[CGNS_MAX_STR_LEN];
108  CGNS_ENUMT(ElementType_t) sectEltType;
109  cgsize_t startElt, endElt;
110  int nbBnd, parentFlag;
111  cgnsErr =
112  cg_section_read(fileIndex(), baseIndex(), index(), iSect, sectName,
113  &sectEltType, &startElt, &endElt, &nbBnd, &parentFlag);
114  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex());
115 
116  // check for compatibility with MIXED element sections
117 #if CGNS_VERSION < 4000
118  if(sectEltType == CGNS_ENUMV(MIXED)) {
119  Msg::Error("Reading 'MIXED' element sections requires CGNS library "
120  "version >= 4");
121  return 0;
122  }
123 #endif
124 
125  // read connectivity data size
126  cgsize_t dataSize;
127  cgnsErr =
128  cg_ElementDataSize(fileIndex(), baseIndex(), index(), iSect, &dataSize);
129  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex());
130 
131  // read connectivity data
132  std::vector<cgsize_t> sectData(dataSize), offsetData(endElt - startElt + 2);
133  if(sectEltType == CGNS_ENUMV(MIXED)) {
134 #if CGNS_VERSION >= 4000
135  cgnsErr =
136  cg_poly_elements_read(fileIndex(), baseIndex(), index(), iSect,
137  sectData.data(), offsetData.data(), nullptr);
138 #endif
139  }
140  else {
141  cgnsErr = cg_elements_read(fileIndex(), baseIndex(), index(), iSect,
142  sectData.data(), nullptr);
143  }
144  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex());
145 
146  // create elements
147  std::size_t iSectData = 0;
148  if(endElt > (cgsize_t)zoneElt.size()) zoneElt.resize(endElt);
149  const cgsize_t iStartElt = startElt - 1, iEndElt = endElt - 1;
150  for(int iElt = iStartElt; iElt <= iEndElt; iElt++) {
151  const auto it = elt2Geom().find(iElt);
152  const int entity = (it == elt2Geom().end()) ? 1 : it->second;
153  MElement *me =
154  createElement(sectEltType, startNode(), entity, allVert, allElt, sectData,
155  eltNodeTransfo(), rawNode, iSectData);
156  zoneElt[iElt] = me;
157  }
158 
159  return 1;
160 }
161 
162 int CGNSZoneUnstruct::readElements(
163  std::vector<MVertex *> &allVert,
164  std::map<int, std::vector<MElement *> > *allElt,
165  std::vector<MElement *> &zoneElt, std::vector<std::string> &allGeomName)
166 {
167  int cgnsErr;
168 
169  // data structures for node coordinate transformation (CPEX0045)
170  // std::vector<bool> nodeUpdated;
171  std::vector<SPoint3> rawNode;
172  if(eltNodeTransfo() != nullptr) {
173  // nodeUpdated = std::vector<bool>(nbNode(), false);
174  rawNode.resize(nbNode());
175  for(int iN = 0; iN < nbNode(); iN++) {
176  rawNode[iN] = allVert[startNode() + iN]->point();
177  }
178  }
179 
180  // read number of sections of element-vertex connectivity
181  int nbSect;
182  cgnsErr = cg_nsections(fileIndex(), baseIndex(), index(), &nbSect);
183  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex());
184 
185  // read sections of element-vertex connectivity
186  zoneElt.reserve(nbElt());
187  for(int iSect = 1; iSect <= nbSect; iSect++) {
188  int err = readSection(iSect, allVert, rawNode, allElt, zoneElt);
189  if(err == 0) return 0;
190  }
191 
192  return 1;
193 }
194 
195 #endif // HAVE_LIBCGNS
MSH_PNT
#define MSH_PNT
Definition: GmshDefines.h:94
TYPE_LIN
#define TYPE_LIN
Definition: GmshDefines.h:65
MElementFactory
Definition: MElement.h:517
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
TYPE_PNT
#define TYPE_PNT
Definition: GmshDefines.h:64
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
GmshMessage.h
TYPE_PRI
#define TYPE_PRI
Definition: GmshDefines.h:70
CGNSZoneUnstruct.h
MElement::getType
virtual int getType() const =0
MVertex.h
MElement
Definition: MElement.h:30
CGNSConventions.h
CGNSCommon.h
TYPE_PYR
#define TYPE_PYR
Definition: GmshDefines.h:69
MElementFactory::create
MElement * create(int type, std::vector< MVertex * > &v, std::size_t num=0, int part=0, bool owner=false, int parent=0, MElement *parent_ptr=nullptr, MElement *d1=nullptr, MElement *d2=nullptr)
Definition: MElement.cpp:2556
TYPE_QUA
#define TYPE_QUA
Definition: GmshDefines.h:67
TYPE_POLYG
#define TYPE_POLYG
Definition: GmshDefines.h:72
MElement.h
TYPE_HEX
#define TYPE_HEX
Definition: GmshDefines.h:71
TYPE_TET
#define TYPE_TET
Definition: GmshDefines.h:68
ElementType::getNumVertices
int getNumVertices(int type)
Definition: ElementType.cpp:456
TYPE_POLYH
#define TYPE_POLYH
Definition: GmshDefines.h:73