VTK  9.2.6
vtkCGNSReaderInternal.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkCGNSReaderInternal.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // Copyright (c) 2013-2014 Mickael Philit
16 
26 #ifndef vtkCGNSReaderInternal_h
27 #define vtkCGNSReaderInternal_h
28 
29 #include <iostream>
30 #include <map>
31 #include <string.h> // for inline strcmp
32 #include <string>
33 #include <vector>
34 
35 #include "vtkCGNSReader.h"
36 #include "vtkDataArraySelection.h"
37 #include "vtkIdTypeArray.h"
39 #include "vtkNew.h"
40 #include "vtkPoints.h"
41 
42 // .clang-format off
43 #include "vtk_cgns.h"
44 #include VTK_CGNS(cgnslib.h)
45 #include VTK_CGNS(cgns_io.h)
46 // .clang-format on
47 
48 namespace CGNSRead
49 {
50 
51 namespace detail
52 {
53 template <typename T>
54 struct is_double
55 {
56  static const bool value = false;
57 };
58 
59 template <>
60 struct is_double<double>
61 {
62  static const bool value = true;
63 };
64 
65 template <typename T>
66 struct is_float
67 {
68  static const bool value = false;
69 };
70 
71 template <>
72 struct is_float<float>
73 {
74  static const bool value = true;
75 };
76 }
77 
78 namespace detail
79 {
80 template <typename T>
81 constexpr const char* cgns_type_name() noexcept
82 {
83  return "MT";
84 }
85 
86 template <>
87 constexpr const char* cgns_type_name<float>() noexcept
88 {
89  return "R4";
90 }
91 
92 template <>
93 constexpr const char* cgns_type_name<double>() noexcept
94 {
95  return "R8";
96 }
97 
98 template <>
99 constexpr const char* cgns_type_name<vtkTypeInt32>() noexcept
100 {
101  return "I4";
102 }
103 
104 template <>
105 constexpr const char* cgns_type_name<vtkTypeInt64>() noexcept
106 {
107  return "I8";
108 }
109 }
110 
111 typedef char char_33[33];
112 
113 //------------------------------------------------------------------------------
114 class vtkCGNSArraySelection : public std::map<std::string, bool>
115 {
116 public:
117  void Merge(const vtkCGNSArraySelection& other)
118  {
119  vtkCGNSArraySelection::const_iterator iter = other.begin();
120  for (; iter != other.end(); ++iter)
121  {
122  (*this)[iter->first] = iter->second;
123  }
124  }
125 
126  void AddArray(const char* name, bool status = true) { (*this)[name] = status; }
127 
128  bool ArrayIsEnabled(const char* name)
129  {
130  vtkCGNSArraySelection::iterator iter = this->find(name);
131  if (iter != this->end())
132  {
133  return iter->second;
134  }
135 
136  // don't know anything about this array, enable it by default.
137  return true;
138  }
139 
140  bool HasArray(const char* name)
141  {
142  vtkCGNSArraySelection::iterator iter = this->find(name);
143  return (iter != this->end());
144  }
145 
146  int GetArraySetting(const char* name) { return this->ArrayIsEnabled(name) ? 1 : 0; }
147 
148  void SetArrayStatus(const char* name, bool status) { this->AddArray(name, status); }
149 
150  const char* GetArrayName(int index)
151  {
152  int cc = 0;
153  for (vtkCGNSArraySelection::iterator iter = this->begin(); iter != this->end(); ++iter)
154  {
155 
156  if (cc == index)
157  {
158  return iter->first.c_str();
159  }
160  cc++;
161  }
162  return NULL;
163  }
164 
165  int GetNumberOfArrays() { return static_cast<int>(this->size()); }
166 };
167 
168 //------------------------------------------------------------------------------
169 typedef struct
170 {
171  int cnt; // 0 1 or 3
172  int pos; // variable position in zone
173  int xyzIndex;
175  CGNS_ENUMT(DataType_t) dt;
176  char_33 name;
177 } Variable;
178 
179 //------------------------------------------------------------------------------
180 typedef struct
181 {
182  int xyzIndex;
184  CGNS_ENUMT(DataType_t) dt;
185  char_33 name;
186 } CGNSVariable;
187 
188 //------------------------------------------------------------------------------
189 typedef struct
190 {
191  int numComp;
192  char_33 name;
193  int xyzIndex[3];
194 } CGNSVector;
195 
196 //------------------------------------------------------------------------------
197 typedef struct
198 {
199  bool isVector;
200  int xyzIndex;
201  char_33 name;
202 } VTKVariable;
203 
204 //------------------------------------------------------------------------------
206 {
207 public:
208  char_33 name;
211  : family(32, '\0')
212  {
213  this->name[0] = '\0';
214  }
215 };
216 
217 //------------------------------------------------------------------------------
219 {
220 public:
221  char_33 name;
223  std::vector<CGNSRead::ZoneBCInformation> bcs;
225  : family(32, '\0')
226  {
227  this->name[0] = '\0';
228  }
229 };
230 
231 //------------------------------------------------------------------------------
233 {
234 public:
236  bool isBC;
237 };
238 
239 //------------------------------------------------------------------------------
241 {
242 public:
243  char_33 name;
244 
245  int32_t cellDim;
246  int32_t physicalDim;
247  //
249 
250  std::vector<int32_t> steps;
251  std::vector<double> times;
252 
253  // For unsteady meshes :
254  // if useGridPointers == True:
255  // loadGridPointers for first zone
256  // and assume every zone use the same
257  // notation
258  // else :
259  // assume only one grid is stored
260  // only first grid is read
261  //
262  // For unsteady flow
263  // if useFlowPointers == True :
264  // same behavior as GridPointers
265  // else if ( nstates > 1 ) :
266  // assume flow_solution are sorted
267  // to keep VisIt like behavior
268  // else :
269  // only first solution is read
270  //
271 
272  bool useGridPointers; // for unsteady mesh
273  bool useFlowPointers; // for unsteady flow
274 
275  std::vector<CGNSRead::FamilyInformation> family;
276  std::map<std::string, double> referenceState;
277 
278  std::vector<CGNSRead::ZoneInformation> zones;
279 
280  int nzones;
281 
282  // std::vector<CGNSRead::zone> zone;
286 };
287 
288 //==============================================================================
289 
291 
295 bool ReadBase(vtkCGNSReader* reader, const BaseInformation& baseInfo);
296 bool ReadGridForZone(
297  vtkCGNSReader* reader, const BaseInformation& baseInfo, const ZoneInformation& zoneInfo);
298 bool ReadPatchesForBase(vtkCGNSReader* reader, const BaseInformation&);
299 bool ReadPatch(vtkCGNSReader* reader, const BaseInformation&, const ZoneInformation& zoneInfo,
300  const std::string& patchFamilyname);
302 
303 //==============================================================================
305 {
306 public:
311  bool Parse(const char* cgnsFileName);
312 
316  int GetNumberOfBaseNodes() { return static_cast<int>(this->baseList.size()); }
317 
321  const CGNSRead::BaseInformation& GetBase(int numBase) { return this->baseList[numBase]; }
322 
326  std::vector<double>& GetTimes() { return this->GlobalTime; }
327 
331  void PrintSelf(std::ostream& os);
332 
333  void Broadcast(vtkMultiProcessController* controller, int rank);
334 
336 
339  vtkCGNSMetaData() = default;
340  ~vtkCGNSMetaData() = default;
342 
343 private:
344  vtkCGNSMetaData(const vtkCGNSMetaData&) = delete;
345  void operator=(const vtkCGNSMetaData&) = delete;
346 
347  std::vector<CGNSRead::BaseInformation> baseList;
348  std::string LastReadFilename;
349  // Not very elegant :
350  std::vector<double> GlobalTime;
351 };
352 
353 //------------------------------------------------------------------------------
354 // compare name return true if name1 == name2
355 inline bool compareName(const char_33 nameOne, const char_33 nameTwo)
356 {
357  return (strncmp(nameOne, nameTwo, 32) == 0);
358 }
359 
360 //------------------------------------------------------------------------------
361 // remove trailing whitespaces
362 inline void removeTrailingWhiteSpaces(char_33 name)
363 {
364  char* end = name + strlen(name) - 1;
365  while (end >= name && isspace(*end))
366  {
367  --end;
368  }
369  ++end;
370  assert(end >= name && end < name + 33);
371  *end = '\0';
372 }
373 
374 //------------------------------------------------------------------------------
375 // get vector from name
376 inline std::vector<CGNSVector>::iterator getVectorFromName(
377  std::vector<CGNSVector>& vectorList, const char_33 name)
378 {
379  for (std::vector<CGNSVector>::iterator iter = vectorList.begin(); iter != vectorList.end();
380  ++iter)
381  {
382  if (strncmp(iter->name, name, 31) == 0)
383  {
384  return iter;
385  }
386  }
387  return vectorList.end();
388 }
389 
390 //------------------------------------------------------------------------------
391 inline bool isACGNSVariable(const std::vector<CGNSVariable>& varList, const char_33 name)
392 {
393  for (std::vector<CGNSVariable>::const_iterator iter = varList.begin(); iter != varList.end();
394  ++iter)
395  {
396  if (strncmp(iter->name, name, 32) == 0)
397  {
398  return true;
399  }
400  }
401  return false;
402 }
403 
404 //------------------------------------------------------------------------------
405 void fillVectorsFromVars(std::vector<CGNSRead::CGNSVariable>& vars,
406  std::vector<CGNSRead::CGNSVector>& vectors, const int physicalDim);
407 //------------------------------------------------------------------------------
408 int setUpRind(const int cgioNum, const double rindId, int* rind);
409 //------------------------------------------------------------------------------
414 int getFirstNodeId(
415  const int cgioNum, const double parentId, const char* label, double* id, const char* name = NULL);
416 //------------------------------------------------------------------------------
417 int get_section_connectivity(const int cgioNum, const double cgioSectionId, const int dim,
418  const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
419  const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
420  const cgsize_t* memDim, vtkIdType* localElements);
421 //------------------------------------------------------------------------------
422 int get_section_start_offset(const int cgioNum, const double cgioSectionId, const int dim,
423  const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
424  const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
425  const cgsize_t* memDim, vtkIdType* localElementsIdx);
426 //------------------------------------------------------------------------------
427 int GetVTKElemType(
428  CGNS_ENUMT(ElementType_t) elemType, bool& higherOrderWarning, bool& cgnsOrderFlag);
429 //------------------------------------------------------------------------------
430 void CGNS2VTKorder(const vtkIdType size, const int* cells_types, vtkIdType* elements);
431 //------------------------------------------------------------------------------
432 void CGNS2VTKorderMonoElem(const vtkIdType size, const int cell_type, vtkIdType* elements);
433 //------------------------------------------------------------------------------
434 template <typename T, typename Y>
435 int get_XYZ_mesh(const int cgioNum, const std::vector<double>& gridChildId,
436  const std::size_t& nCoordsArray, const int cellDim, const vtkIdType nPts,
437  const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
438  const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
439  const cgsize_t* memDims, vtkPoints* points)
440 {
441  T* coords = static_cast<T*>(points->GetVoidPointer(0));
442  T* currentCoord = static_cast<T*>(&(coords[0]));
443 
444  CGNSRead::char_33 coordName;
445  std::size_t len;
446  bool sameType = true;
447  double coordId;
448 
449  memset(coords, 0, 3 * nPts * sizeof(T));
450 
451  for (std::size_t c = 1; c <= nCoordsArray; ++c)
452  {
453  // Read CoordName
454  if (cgio_get_name(cgioNum, gridChildId[c - 1], coordName) != CG_OK)
455  {
456  char message[81];
457  cgio_error_message(message);
458  std::cerr << "get_XYZ_mesh : cgio_get_name :" << message;
459  }
460 
461  // Read node data type
462  CGNSRead::char_33 dataType;
463  if (cgio_get_data_type(cgioNum, gridChildId[c - 1], dataType))
464  {
465  continue;
466  }
467 
468  if (strcmp(dataType, "R8") == 0)
469  {
470  const bool doubleType = detail::is_double<T>::value;
471  sameType = doubleType;
472  }
473  else if (strcmp(dataType, "R4") == 0)
474  {
475  const bool floatType = detail::is_float<T>::value;
476  sameType = floatType;
477  }
478  else
479  {
480  std::cerr << "Invalid datatype for GridCoordinates\n";
481  continue;
482  }
483 
484  // Determine direction X,Y,Z
485  len = strlen(coordName) - 1;
486  switch (coordName[len])
487  {
488  case 'X':
489  currentCoord = static_cast<T*>(&(coords[0]));
490  break;
491  case 'Y':
492  currentCoord = static_cast<T*>(&(coords[1]));
493  break;
494  case 'Z':
495  currentCoord = static_cast<T*>(&(coords[2]));
496  break;
497  }
498 
499  coordId = gridChildId[c - 1];
500 
501  // quick transfer of data if same data types
502  if (sameType == true)
503  {
504  constexpr const char* dtNameT = detail::cgns_type_name<T>();
505  if (cgio_read_data_type(cgioNum, coordId, srcStart, srcEnd, srcStride, dtNameT, cellDim,
506  memEnd, memStart, memEnd, memStride, (void*)currentCoord))
507  {
508  char message[81];
509  cgio_error_message(message);
510  std::cerr << "cgio_read_data_type :" << message;
511  }
512  }
513  else
514  {
515  constexpr const char* dtNameY = detail::cgns_type_name<Y>();
516  Y* dataArray = 0;
517  const cgsize_t memNoStride[3] = { 1, 1, 1 };
518 
519  // need to read into temp array to convert data
520  dataArray = new Y[nPts];
521  if (dataArray == 0)
522  {
523  std::cerr << "Error allocating buffer array\n";
524  break;
525  }
526  if (cgio_read_data_type(cgioNum, coordId, srcStart, srcEnd, srcStride, dtNameY, cellDim,
527  memDims, memStart, memDims, memNoStride, (void*)dataArray))
528  {
529  delete[] dataArray;
530  char message[81];
531  cgio_error_message(message);
532  std::cerr << "Buffer array cgio_read_data_type :" << message;
533  break;
534  }
535  for (vtkIdType ii = 0; ii < nPts; ++ii)
536  {
537  currentCoord[memStride[0] * ii] = static_cast<T>(dataArray[ii]);
538  }
539  delete[] dataArray;
540  }
541  }
542  return 0;
543 }
544 }
545 
546 #endif // vtkCGNSReaderInternal_h
547 // VTK-HeaderTest-Exclude: vtkCGNSReaderInternal.h
std::vector< CGNSRead::ZoneBCInformation > bcs
bool ReadBase(vtkCGNSReader *reader, const BaseInformation &baseInfo)
Helpers to encapsulate all logic to read various nodes (zones, bc patches etc.).
std::vector< double > & GetTimes()
return reference to GlobalTime
void SetArrayStatus(const char *name, bool status)
constexpr const char * cgns_type_name< vtkTypeInt32 >() noexcept
void PrintSelf(std::ostream &os)
print object debugging purpose
void fillVectorsFromVars(std::vector< CGNSRead::CGNSVariable > &vars, std::vector< CGNSRead::CGNSVector > &vectors, const int physicalDim)
void CGNS2VTKorder(const vtkIdType size, const int *cells_types, vtkIdType *elements)
int get_XYZ_mesh(const int cgioNum, const std::vector< double > &gridChildId, const std::size_t &nCoordsArray, const int cellDim, const vtkIdType nPts, const cgsize_t *srcStart, const cgsize_t *srcEnd, const cgsize_t *srcStride, const cgsize_t *memStart, const cgsize_t *memEnd, const cgsize_t *memStride, const cgsize_t *memDims, vtkPoints *points)
vtkCGNSArraySelection PointDataArraySelection
int GetNumberOfBaseNodes()
return number of base nodes
bool isACGNSVariable(const std::vector< CGNSVariable > &varList, const char_33 name)
~vtkCGNSMetaData()=default
Constructor/Destructor.
constexpr const char * cgns_type_name< float >() noexcept
void removeTrailingWhiteSpaces(char_33 name)
void Merge(const vtkCGNSArraySelection &other)
int GetVTKElemType(CGNS_ENUMT(ElementType_t) elemType, bool &higherOrderWarning, bool &cgnsOrderFlag)
int vtkIdType
Definition: vtkType.h:332
std::vector< CGNSRead::FamilyInformation > family
constexpr const char * cgns_type_name() noexcept
int getFirstNodeId(const int cgioNum, const double parentId, const char *label, double *id, const char *name=NULL)
Find the first node with the given label.
bool ReadPatch(vtkCGNSReader *reader, const BaseInformation &, const ZoneInformation &zoneInfo, const std::string &patchFamilyname)
Helpers to encapsulate all logic to read various nodes (zones, bc patches etc.).
std::vector< int32_t > steps
const char * GetArrayName(int index)
vtkCGNSArraySelection FaceDataArraySelection
std::map< std::string, double > referenceState
constexpr const char * cgns_type_name< double >() noexcept
void * GetVoidPointer(const int id)
Return a void pointer.
Definition: vtkPoints.h:97
vtkCGNSReader creates a multi-block dataset and reads unstructured grids and structured meshes from b...
Definition: vtkCGNSReader.h:50
std::vector< CGNSRead::ZoneInformation > zones
void AddArray(const char *name, bool status=true)
vtkCGNSMetaData()=default
Constructor/Destructor.
bool Parse(const char *cgnsFileName)
quick parsing of cgns file to get interesting information from a VTK point of view ...
int get_section_connectivity(const int cgioNum, const double cgioSectionId, const int dim, const cgsize_t *srcStart, const cgsize_t *srcEnd, const cgsize_t *srcStride, const cgsize_t *memStart, const cgsize_t *memEnd, const cgsize_t *memStride, const cgsize_t *memDim, vtkIdType *localElements)
int setUpRind(const int cgioNum, const double rindId, int *rind)
int get_section_start_offset(const int cgioNum, const double cgioSectionId, const int dim, const cgsize_t *srcStart, const cgsize_t *srcEnd, const cgsize_t *srcStride, const cgsize_t *memStart, const cgsize_t *memEnd, const cgsize_t *memStride, const cgsize_t *memDim, vtkIdType *localElementsIdx)
vtkCGNSArraySelection CellDataArraySelection
std::vector< CGNSVector >::iterator getVectorFromName(std::vector< CGNSVector > &vectorList, const char_33 name)
bool ReadGridForZone(vtkCGNSReader *reader, const BaseInformation &baseInfo, const ZoneInformation &zoneInfo)
Helpers to encapsulate all logic to read various nodes (zones, bc patches etc.).
void Broadcast(vtkMultiProcessController *controller, int rank)
void CGNS2VTKorderMonoElem(const vtkIdType size, const int cell_type, vtkIdType *elements)
const CGNSRead::BaseInformation & GetBase(int numBase)
return const reference to a base information
bool compareName(const char_33 nameOne, const char_33 nameTwo)
constexpr const char * cgns_type_name< vtkTypeInt64 >() noexcept
represent and manipulate 3D points
Definition: vtkPoints.h:39
Multiprocessing communication superclass.
bool ReadPatchesForBase(vtkCGNSReader *reader, const BaseInformation &)
Helpers to encapsulate all logic to read various nodes (zones, bc patches etc.).