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