25 #if defined(HAVE_LIBCGNS)
29 #ifdef HAVE_LIBCGNS_CPEX0045
31 int readElementInterpolation(
int fileIndex,
int baseIndex,
int familyIndex,
32 int interpIndex, ZoneEltNodeTransfo &nodeTransfo)
37 char interpName[CGNS_MAX_STR_LEN];
38 CGNS_ENUMT(ElementType_t) cgnsType;
39 cgnsErr = cg_element_interpolation_read(fileIndex, baseIndex, familyIndex,
40 interpIndex, interpName, &cgnsType);
41 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
45 cgnsErr = cg_element_lagrange_interpolation_size(cgnsType, &nbPt);
46 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
49 std::vector<double> u(nbPt), v(nbPt), w(nbPt);
50 cgnsErr = cg_element_interpolation_points_read(
51 fileIndex, baseIndex, familyIndex, interpIndex, u.data(), v.data(),
53 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
56 const int mshType = cgns2MshEltType(cgnsType);
59 if(nbPt != mshPts.
size1()) {
60 Msg::Error(
"Internal error: number of interpolation points is different "
61 "between CGNS and Gmsh for Gmsh element %i (parent type %i)",
65 std::vector<double> uMsh(nbPt), vMsh(nbPt), wMsh(nbPt);
66 msh2CgnsReferenceElement(mshType, mshPts, uMsh, vMsh, wMsh);
70 for(
int i = 0; i < nbPt; i++) {
74 uvwMsh(i, 0) = uMsh[i];
75 uvwMsh(i, 1) = vMsh[i];
76 uvwMsh(i, 2) = wMsh[i];
80 std::vector<int> transfo(nbPt);
81 if(!computeReordering(uvw, uvwMsh, transfo)) {
82 Msg::Error(
"Interpolation points '%s' cannot be converted to Gmsh for "
83 "element %i (parent type %i)",
87 nodeTransfo[mshType] = transfo;
96 std::size_t nameIndex(
const std::string &name,
97 std::vector<std::string> &allNames)
99 for(std::size_t i = 0; i < allNames.size(); i++) {
100 if(allNames[i] == name)
return i;
103 allNames.push_back(name);
104 return allNames.size() - 1;
107 int readScale(
int fileIndex,
int baseIndex,
double &
scale)
113 CGNS_ENUMT(MassUnits_t) mass;
114 CGNS_ENUMT(LengthUnits_t)
length;
115 CGNS_ENUMT(TimeUnits_t) time;
116 CGNS_ENUMT(TemperatureUnits_t) temperature;
117 CGNS_ENUMT(AngleUnits_t)
angle;
118 cgnsErr = cg_goto(fileIndex, baseIndex,
"end");
119 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
120 cgnsErr = cg_units_read(&mass, &
length, &time, &temperature, &
angle);
121 if(cgnsErr == CG_NODE_NOT_FOUND) {
122 Msg::Info(
"Length unit in CGNS file not defined, therefore not rescaling");
125 else if(cgnsErr != CG_OK)
126 return cgnsError(__FILE__, __LINE__, fileIndex);
129 case CGNS_ENUMT(Centimeter):
130 Msg::Info(
"Length unit in CGNS file is cm, rescaling");
133 case CGNS_ENUMT(Millimeter):
134 Msg::Info(
"Length unit in CGNS file is mm, rescaling");
137 case CGNS_ENUMT(Foot):
138 Msg::Info(
"Length unit in CGNS file is feet, rescaling");
141 case CGNS_ENUMT(Inch):
142 Msg::Info(
"Length unit in CGNS file is inch, rescaling");
145 case CGNS_ENUMT(Meter):
146 Msg::Info(
"Length unit in CGNS file is meter, not rescaling");
151 Msg::Info(
"Length unit in CGNS file not defined, therefore not rescaling");
158 int readEltNodeTransfo(
int fileIndex,
int baseIndex,
159 Family2EltNodeTransfo &allEltNodeTransfo)
161 #ifdef HAVE_LIBCGNS_CPEX0045
166 cgnsErr = cg_nfamilies(fileIndex, baseIndex, &nbFam);
167 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
170 for(
int iFam = 1; iFam <= nbFam; iFam++) {
174 cg_nelement_interpolation_read(fileIndex, baseIndex, iFam, &nbInterp);
175 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
176 if(nbInterp == 0)
continue;
179 char famName[CGNS_MAX_STR_LEN];
180 int nbFamBC, nbGeoRef;
182 cg_family_read(fileIndex, baseIndex, iFam, famName, &nbFamBC, &nbGeoRef);
183 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
186 ZoneEltNodeTransfo &nodeTransfo = allEltNodeTransfo[std::string(famName)];
187 nodeTransfo.resize(NofValidElementTypes);
188 for(
int iInterp = 1; iInterp <= nbInterp; iInterp++) {
189 int err = readElementInterpolation(fileIndex, baseIndex, iFam, iInterp,
191 if(err == 0)
return 0;
201 int createZones(
int fileIndex,
int baseIndex,
int meshDim,
202 const Family2EltNodeTransfo &allEltNodeTransfo,
203 std::vector<CGNSZone *> &allZones,
204 std::map<std::string, int> &name2Zone,
bool &postpro)
206 const int nbZone = allZones.size() - 1;
211 cgsize_t startNode = 0;
212 for(
int iZone = 1; iZone <= nbZone; iZone++) {
214 CGNS_ENUMT(ZoneType_t) zoneType;
215 cgnsErr = cg_zone_type(fileIndex, baseIndex, iZone, &zoneType);
216 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
220 if(zoneType == CGNS_ENUMV(Structured)) {
223 new CGNSZoneStruct<2>(fileIndex, baseIndex, iZone, meshDim, startNode,
224 allEltNodeTransfo, err);
228 new CGNSZoneStruct<3>(fileIndex, baseIndex, iZone, meshDim, startNode,
229 allEltNodeTransfo, err);
232 else if(zoneType == CGNS_ENUMV(Unstructured)) {
234 new CGNSZoneUnstruct(fileIndex, baseIndex, iZone, meshDim, startNode,
235 allEltNodeTransfo, err);
237 if(err == 0)
return 0;
241 cgnsErr = cg_nsols(fileIndex, baseIndex, iZone, &nbZoneSol);
242 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
243 postpro |= (nbZoneSol > 0);
246 startNode += allZones[iZone]->nbNode();
247 name2Zone[allZones[iZone]->name()] = iZone;
251 for(
int iZone = 1; iZone <= nbZone; iZone++) {
252 allZones[iZone]->readConnectivities(name2Zone, allZones);
258 void setPeriodicityInEntities(
const std::vector<CGNSZone *> &allZones)
262 typedef std::map<GEntity *, GEntity *> EntConnect;
263 typedef std::map<GEntity *, const std::vector<double> *> EntTransfo;
268 for(std::size_t iZone = 1; iZone < allZones.size(); iZone++) {
269 CGNSZone *zone = allZones[iZone];
271 for(
int iPer = 0; iPer < zone->nbPerConnect(); iPer++) {
273 const std::vector<MVertex *> &slaveVert = zone->slaveVert(iPer);
274 const std::vector<MVertex *> &masterVert = zone->masterVert(iPer);
275 for(std::size_t iV = 0; iV < slaveVert.size(); iV++) {
277 MVertex *sVert = slaveVert[iV], *mVert = masterVert[iV];
282 if(sEnt->
dim() != mEnt->dim())
continue;
286 if(entCon.find(sEnt) != entCon.end())
continue;
287 auto itInv = entCon.find(mEnt);
288 if((itInv != entCon.end()) && (itInv->second == sEnt))
continue;
292 entTfo[sEnt] = &(zone->perTransfo(iPer));
299 for(
auto it = entCon.begin(); it != entCon.end(); ++it) {
300 GEntity *sEnt = it->first, *mEnt = it->second;
305 int readPhysicals(
int fileIndex,
int baseIndex,
306 std::vector<std::string> &allPhysName,
307 std::multimap<std::string, int> &geomName2Phys)
313 cgnsErr = cg_nfamilies(fileIndex, baseIndex, &nbFam);
314 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
317 for(
int iFam = 1; iFam <= nbFam; iFam++) {
319 char rawFamName[CGNS_MAX_STR_LEN];
320 int nbFamBC, nbGeoRef;
321 cgnsErr = cg_family_read(fileIndex, baseIndex, iFam, rawFamName, &nbFamBC,
323 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
324 const std::string geomName(rawFamName);
328 cgnsErr = cg_nfamily_names(fileIndex, baseIndex, iFam, &nbFamName);
329 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
330 if(nbFamName == 0)
continue;
333 for(
int iFamName = 1; iFamName <= nbFamName; iFamName++) {
335 char rawNodeName[CGNS_MAX_STR_LEN];
336 cgnsErr = cg_family_name_read(fileIndex, baseIndex, iFam, iFamName,
337 rawNodeName, rawFamName);
338 if(cgnsErr != CG_OK)
return cgnsError(__FILE__, __LINE__, fileIndex);
341 std::string physName;
342 if(std::strcmp(rawFamName,
"") == 0)
343 physName = std::string(rawNodeName);
345 physName = std::string(rawFamName);
348 int physTag = nameIndex(physName, allPhysName);
349 geomName2Phys.insert(std::make_pair(geomName, physTag));
356 void setGeomAndPhysicalEntities(
GModel *model,
int meshDim,
357 std::vector<std::string> &allGeomName,
358 std::vector<std::string> &allPhysName,
359 std::multimap<std::string, int> &geomName2Phys)
362 for(
int d = 0; d <= meshDim; d++) {
364 std::vector<GEntity *> ent;
368 for(std::size_t iEnt = 0; iEnt < ent.size(); iEnt++) {
370 int geomTag = ent[iEnt]->tag();
371 if(geomTag >= (
int)allGeomName.size())
continue;
372 const std::string &geomName = allGeomName[geomTag];
378 auto range = geomName2Phys.equal_range(geomName);
379 for(
auto it = range.first; it != range.second; ++it) {
380 const int physTag = it->second;
381 std::vector<int> &entPhys = ent[iEnt]->physicals;
382 if(std::find(entPhys.begin(), entPhys.end(), physTag) ==
384 entPhys.push_back(physTag);
392 #endif // HAVE_LIBCGNS