18 #if defined(HAVE_LIBCGNS)
20 CGNSZone::CGNSZone(
int fileIndex,
int baseIndex,
int zoneIndex,
21 CGNS_ENUMT(ZoneType_t) type,
int meshDim, cgsize_t startNode,
22 const Family2EltNodeTransfo &allEltNodeTransfo,
int &err)
23 : fileIndex_(fileIndex), baseIndex_(baseIndex), meshDim_(meshDim),
24 zoneIndex_(zoneIndex), type_(type), startNode_(startNode),
25 eltNodeTransfo_(nullptr), nbPerConnect_(0)
30 char name[CGNS_MAX_STR_LEN];
31 cgnsErr = cg_zone_read(fileIndex, baseIndex, zoneIndex, name, size_);
32 if(cgnsErr != CG_OK) err = cgnsError(__FILE__, __LINE__, fileIndex);
33 name_ = std::string(name);
36 cgnsErr = cg_goto(fileIndex, baseIndex,
"Zone_t", zoneIndex,
"end");
37 if(cgnsErr != CG_OK) err = cgnsError(__FILE__, __LINE__, fileIndex);
38 char famName[CGNS_MAX_STR_LEN];
39 cgnsErr = cg_famname_read(famName);
40 if(cgnsErr != CG_NODE_NOT_FOUND) {
41 if(cgnsErr == CG_OK) {
42 auto it = allEltNodeTransfo.find(std::string(famName));
43 if(it != allEltNodeTransfo.end()) eltNodeTransfo_ = &(it->second);
46 err = cgnsError(__FILE__, __LINE__, fileIndex);
53 int CGNSZone::readBoundaryCondition(
int iZoneBC,
54 const std::vector<CGNSZone *> &allZones,
55 std::vector<std::string> &allGeomName)
60 char rawBCName[CGNS_MAX_STR_LEN];
61 CGNS_ENUMT(BCType_t) bcType;
62 CGNS_ENUMT(PointSetType_t) ptSetType;
63 cgsize_t nbVal, normalSize;
64 CGNS_ENUMT(DataType_t) normalType;
67 cgnsErr = cg_boco_info(fileIndex(), baseIndex(), index(), iZoneBC, rawBCName,
68 &bcType, &ptSetType, &nbVal, &normalIndex, &normalSize,
69 &normalType, &nbDataSet);
70 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
75 cgnsErr = cg_goto(fileIndex(), baseIndex(),
"Zone_t", index(),
"ZoneBC_t", 1,
76 "BC_t", iZoneBC,
"end");
77 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
78 char rawFamilyName[CGNS_MAX_STR_LEN];
79 cgnsErr = cg_famname_read(rawFamilyName);
80 if(cgnsErr != CG_NODE_NOT_FOUND) {
82 geomName = std::string(rawFamilyName);
84 return cgnsError(__FILE__, __LINE__, fileIndex());
87 geomName = std::string(rawBCName);
88 const int indGeom = nameIndex(geomName, allGeomName);
91 CGNS_ENUMT(GridLocation_t) location;
92 cgnsErr = cg_boco_gridlocation_read(fileIndex(), baseIndex(), index(),
94 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
97 if((type() == CGNS_ENUMV(Unstructured)) && (meshDim() == 2) &&
98 (location != CGNS_ENUMV(CellCenter)) &&
99 (location != CGNS_ENUMV(EdgeCenter))) {
100 Msg::Warning(
"Boundary condition %s is specified on %s instead of "
101 "CellCenter/EdgeCenter in a 2D zone, skipping",
102 geomName.c_str(), cg_GridLocationName(location));
105 else if((type() == CGNS_ENUMV(Unstructured)) && (meshDim() == 3) &&
106 (location != CGNS_ENUMV(CellCenter)) &&
107 (location != CGNS_ENUMV(FaceCenter))) {
108 Msg::Warning(
"Boundary condition %s is specified on %s instead of "
109 "CellCenter/FaceCenter in a 3D zone, skipping",
110 geomName.c_str(), cg_GridLocationName(location));
115 std::vector<cgsize_t> bcElt;
117 case CGNS_ENUMV(ElementRange):
118 case CGNS_ENUMV(PointRange):
119 readBoundaryConditionRange(iZoneBC, bcElt);
121 case CGNS_ENUMV(ElementList):
122 case CGNS_ENUMV(PointList):
123 readBoundaryConditionList(iZoneBC, nbVal, bcElt);
126 Msg::Error(
"Wrong point set type %s is for boundary condition %s",
127 cg_PointSetTypeName(ptSetType), geomName.c_str());
131 for(std::size_t iElt = 0; iElt < bcElt.size(); iElt++) {
132 elt2Geom()[bcElt[iElt]] = indGeom;
138 int CGNSZone::readVertices(
int dim,
double scale,
139 std::vector<CGNSZone *> &allZones,
140 std::vector<MVertex *> &zoneVert)
146 cgnsErr = cg_ncoords(fileIndex(), baseIndex(), index(), &dimZone);
147 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
149 Msg::Warning(
"%i coordinates in CGNS zone %i, while base has dimension %i,"
150 " discarding upper dimensions",
151 dimZone, index(), dim);
153 else if(dimZone < dim) {
154 Msg::Error(
"%i coordinates in CGNS zone %i, while base has dimension %i",
155 dimZone, index(), dim);
160 std::vector<double> xyz[3];
161 for(
int iXYZ = 0; iXYZ < dim; iXYZ++) {
162 char xyzName[CGNS_MAX_STR_LEN];
163 CGNS_ENUMT(DataType_t) dataType;
164 cgnsErr = cg_coord_info(fileIndex(), baseIndex(), index(), iXYZ + 1,
166 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
167 const cgsize_t startInd[3] = {1, 1, 1};
168 xyz[iXYZ].resize(nbNode());
170 cg_coord_read(fileIndex(), baseIndex(), index(), xyzName,
171 CGNS_ENUMV(RealDouble), startInd, size(), xyz[iXYZ].data());
172 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
176 zoneVert.reserve(nbNode());
177 for(
int i = 0; i < nbNode(); i++) {
178 const double x = xyz[0][i] *
scale;
179 const double y = (dim > 1) ? xyz[1][i] *
scale : 0.;
180 const double z = (dim > 2) ? xyz[2][i] *
scale : 0.;
181 zoneVert.push_back(
new MVertex(x, y,
z));
187 int CGNSZone::readConnectivities(
const std::map<std::string, int> &name2Zone,
188 std::vector<CGNSZone *> &allZones)
194 cgnsErr = cg_nconns(fileIndex(), baseIndex(), index(), &nbConnect);
195 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
198 perTransfo_.reserve(nbConnect);
199 slaveNode_.reserve(nbConnect);
200 slaveVert_.reserve(nbConnect);
201 masterZone_.reserve(nbConnect);
202 masterNode_.reserve(nbConnect);
203 masterVert_.reserve(nbConnect);
205 for(
int iConnect = 1; iConnect <= nbConnect; iConnect++) {
207 char connectName[CGNS_MAX_STR_LEN], donorName[CGNS_MAX_STR_LEN];
208 CGNS_ENUMT(GridLocation_t) location;
209 CGNS_ENUMT(GridConnectivityType_t) connectType;
210 CGNS_ENUMT(PointSetType_t) ptSetType, ptSetTypeDonor;
211 cgsize_t connectSize, connectSizeDonor;
212 CGNS_ENUMT(ZoneType_t) zoneTypeDonor;
213 CGNS_ENUMT(DataType_t) dataTypeDonor;
214 cgnsErr = cg_conn_info(fileIndex(), baseIndex(), index(), iConnect,
215 connectName, &location, &connectType, &ptSetType,
216 &connectSize, donorName, &zoneTypeDonor,
217 &ptSetTypeDonor, &dataTypeDonor, &connectSizeDonor);
218 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
221 float rotCenter[3], rotAngle[3], trans[3];
222 cgnsErr = cg_conn_periodic_read(fileIndex(), baseIndex(), index(), iConnect,
223 rotCenter, rotAngle, trans);
224 if(cgnsErr == CG_NODE_NOT_FOUND)
continue;
225 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
229 for(
int d = 0; d < 3; d++) {
230 rotAngle[d] = -rotAngle[d];
231 trans[d] = -trans[d];
235 if(connectType != CGNS_ENUMV(Abutting1to1)) {
236 Msg::Warning(
"Non-conformal connection not supported in CGNS reader");
239 if(location != CGNS_ENUMV(
Vertex)) {
240 Msg::Warning(
"Only vertex connections are supported in CGNS reader");
245 const std::string masterName(donorName);
246 const auto itMasterName = name2Zone.find(masterName);
247 if(itMasterName == name2Zone.end()) {
248 Msg::Error(
"Zone name '%s' in not found in connection %i of zone %i",
249 masterName.c_str(), iConnect, index());
252 const int masterZoneIndex = itMasterName->second;
253 CGNSZone *mZone = allZones[masterZoneIndex];
254 if(mZone->type() != zoneTypeDonor) {
255 Msg::Error(
"Inconsistent type for zone '%s' in connection %i of zone %i",
256 masterName.c_str(), iConnect, index());
261 std::vector<cgsize_t> slaveData(indexDataSize(connectSize));
262 std::vector<cgsize_t> masterData(mZone->indexDataSize(connectSizeDonor));
263 cgnsErr = cg_conn_read(fileIndex(), baseIndex(), index(), iConnect,
264 slaveData.data(), dataTypeDonor, masterData.data());
265 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
268 std::vector<cgsize_t> sNode, mNode;
269 if(ptSetType == CGNS_ENUMV(PointRange))
270 nodeFromRange(slaveData, sNode);
271 else if(ptSetType == CGNS_ENUMV(PointList))
272 nodeFromList(slaveData, sNode);
273 if(ptSetTypeDonor != CGNS_ENUMV(PointListDonor)) {
274 Msg::Error(
"Only PointListDonor sets are supported for donnor points for "
275 "general connections in CGNS reader");
278 mZone->nodeFromList(masterData, mNode);
282 perTransfo_.push_back(std::vector<double>());
284 masterZone_.push_back(masterZoneIndex);
285 slaveNode_.push_back(sNode);
286 slaveVert_.push_back(std::vector<MVertex *>());
287 masterNode_.push_back(mNode);
288 masterVert_.push_back(std::vector<MVertex *>());
294 int CGNSZone::readMesh(
int dim,
double scale, std::vector<CGNSZone *> &allZones,
295 std::vector<MVertex *> &allVert,
296 std::map<
int, std::vector<MElement *> > *allElt,
297 std::vector<MVertex *> &zoneVert,
298 std::vector<MElement *> &zoneElt,
299 std::vector<std::string> &allGeomName)
305 cgnsErr = cg_nbocos(fileIndex(), baseIndex(), index(), &nbZoneBC);
306 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
307 for(
int iZoneBC = 1; iZoneBC <= nbZoneBC; iZoneBC++) {
308 int errBC = readBoundaryCondition(iZoneBC, allZones, allGeomName);
309 if(errBC == 0)
return 0;
314 int errVert = readVertices(dim,
scale, allZones, zoneVert);
315 if(errVert == 0)
return 0;
316 allVert.insert(allVert.end(), zoneVert.begin(), zoneVert.end());
319 int err = readElements(allVert, allElt, zoneElt, allGeomName);
320 if(err == 0)
return 0;
328 void CGNSZone::setPeriodicVertices(
const std::vector<CGNSZone *> &allZones,
329 const std::vector<MVertex *> &allVert)
331 for(
int iPer = 0; iPer < nbPerConnect(); iPer++) {
332 const std::vector<cgsize_t> &sNode = slaveNode(iPer);
333 const std::vector<cgsize_t> &mNode = masterNode(iPer);
334 std::vector<MVertex *> &sVert = slaveVert(iPer);
335 std::vector<MVertex *> &mVert = masterVert(iPer);
336 CGNSZone *mZone = allZones[masterZone(iPer)];
337 for(std::size_t iN = 0; iN < sNode.size(); iN++) {
338 const cgsize_t sInd = startNode() + sNode[iN];
339 const cgsize_t mInd = mZone->startNode() + mNode[iN];
340 sVert.push_back(allVert[sInd]);
341 mVert.push_back(allVert[mInd]);
346 int CGNSZone::readBoundaryConditionRange(
int iZoneBC,
347 std::vector<cgsize_t> &bcElt)
351 std::vector<cgsize_t> bcData(indexDataSize(2));
352 cgnsErr = cg_boco_read(fileIndex(), baseIndex(), index(), iZoneBC,
353 bcData.data(),
nullptr);
354 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
357 eltFromRange(bcData, bcElt);
362 int CGNSZone::readBoundaryConditionList(
int iZoneBC, cgsize_t nbVal,
363 std::vector<cgsize_t> &bcElt)
368 std::vector<cgsize_t> bcData(indexDataSize(nbVal));
369 cgnsErr = cg_boco_read(fileIndex(), baseIndex(), index(), iZoneBC,
370 bcData.data(),
nullptr);
371 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex());
374 eltFromList(bcData, bcElt);
379 #endif // HAVE_LIBCGNS