ParaView
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 <cgns_io.h> // Low level IO for fast parsing
33 #include <cgnslib.h> // DataType, and other definition
34 
35 #include <iostream>
36 #include <map>
37 #include <string.h> // for inline strcmp
38 #include <string>
39 #include <vector>
40 
41 #include "vtkIdTypeArray.h"
42 #include "vtkPoints.h"
43 
44 #include "vtkMultiProcessController.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 <>
58 struct is_double<double>
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 typedef char char_33[33];
77 
78 //------------------------------------------------------------------------------
79 class vtkCGNSArraySelection : public std::map<std::string, bool>
80 {
81 public:
82  void Merge(const vtkCGNSArraySelection& other)
83  {
84  vtkCGNSArraySelection::const_iterator iter = other.begin();
85  for (; iter != other.end(); ++iter)
86  {
87  (*this)[iter->first] = iter->second;
88  }
89  }
90 
91  void AddArray(const char* name, bool status = true) { (*this)[name] = status; }
92 
93  bool ArrayIsEnabled(const char* name)
94  {
95  vtkCGNSArraySelection::iterator iter = this->find(name);
96  if (iter != this->end())
97  {
98  return iter->second;
99  }
100 
101  // don't know anything about this array, enable it by default.
102  return true;
103  }
104 
105  bool HasArray(const char* name)
106  {
107  vtkCGNSArraySelection::iterator iter = this->find(name);
108  return (iter != this->end());
109  }
110 
111  int GetArraySetting(const char* name) { return this->ArrayIsEnabled(name) ? 1 : 0; }
112 
113  void SetArrayStatus(const char* name, bool status) { this->AddArray(name, status); }
114 
115  const char* GetArrayName(int index)
116  {
117  int cc = 0;
118  for (vtkCGNSArraySelection::iterator iter = this->begin(); iter != this->end(); ++iter)
119  {
120 
121  if (cc == index)
122  {
123  return iter->first.c_str();
124  }
125  cc++;
126  }
127  return NULL;
128  }
129 
130  int GetNumberOfArrays() { return static_cast<int>(this->size()); }
131 };
132 
133 //------------------------------------------------------------------------------
134 typedef struct
135 {
136  int cnt; // 0 1 or 3
137  int pos; // variable position in zone
138  int xyzIndex;
140  CGNS_ENUMT(DataType_t) dt;
141  char_33 name;
142 } Variable;
143 
144 //------------------------------------------------------------------------------
145 typedef struct
146 {
147  int xyzIndex;
149  CGNS_ENUMT(DataType_t) dt;
150  char_33 name;
151 } CGNSVariable;
152 
153 //------------------------------------------------------------------------------
154 typedef struct
155 {
156  int numComp;
157  char_33 name;
158  int xyzIndex[3];
159 } CGNSVector;
160 
161 //------------------------------------------------------------------------------
162 typedef struct
163 {
164  bool isVector;
165  int xyzIndex;
166  char_33 name;
167 } VTKVariable;
168 
169 //------------------------------------------------------------------------------
171 {
172 public:
173  char_33 name;
174 };
175 
176 //------------------------------------------------------------------------------
178 {
179 public:
180  char_33 name;
181  bool isBC;
182 };
183 
184 //------------------------------------------------------------------------------
186 {
187 public:
188  char_33 name;
189 
190  int cellDim;
192  //
194 
195  std::vector<int> steps;
196  std::vector<double> times;
197 
198  // For unsteady meshes :
199  // if useGridPointers == True:
200  // loadGridPointers for first zone
201  // and assume every zone use the same
202  // notation
203  // else :
204  // assume only one grid is stored
205  // only first grid is read
206  //
207  // For unsteady flow
208  // if useFlowPointers == True :
209  // same behavior as GridPointers
210  // else if ( nstates > 1 ) :
211  // assume flow_solution are sorted
212  // to keep VisIt like behavior
213  // else :
214  // only first solution is read
215  //
216 
217  bool useGridPointers; // for unsteady mesh
218  bool useFlowPointers; // for unsteady flow
219 
220  std::vector<CGNSRead::FamilyInformation> family;
221  std::map<std::string, double> referenceState;
222 
223  int nzones;
224 
225  // std::vector<CGNSRead::zone> zone;
228 };
229 
230 //------------------------------------------------------------------------------
232 {
233 public:
238  bool Parse(const char* cgnsFileName);
239 
243  int GetNumberOfBaseNodes() { return static_cast<int>(this->baseList.size()); }
244 
248  const CGNSRead::BaseInformation& GetBase(int numBase) { return this->baseList[numBase]; }
249 
253  std::vector<double>& GetTimes() { return this->GlobalTime; }
254 
258  void PrintSelf(std::ostream& os);
259 
260  void Broadcast(vtkMultiProcessController* controller, int rank);
261 
263 
266  vtkCGNSMetaData();
267  ~vtkCGNSMetaData();
269 
270 private:
271  vtkCGNSMetaData(const vtkCGNSMetaData&) VTK_DELETE_FUNCTION;
272  void operator=(const vtkCGNSMetaData&) VTK_DELETE_FUNCTION;
273 
274  std::vector<CGNSRead::BaseInformation> baseList;
275  std::string LastReadFilename;
276  // Not very elegant :
277  std::vector<double> GlobalTime;
278 };
279 
280 //------------------------------------------------------------------------------
281 // sort variables by name helper function
282 static int sortVariablesByName(const void* vOne, const void* vTwo)
283 {
284  Variable* varOne = (Variable*)vOne;
285  Variable* varTwo = (Variable*)vTwo;
286 
287  return (strcmp(varOne->name, varTwo->name));
288 }
289 
290 //------------------------------------------------------------------------------
291 // compare name return true if name1 == name2
292 inline bool compareName(const char_33 nameOne, const char_33 nameTwo)
293 {
294  return (strncmp(nameOne, nameTwo, 32) == 0);
295 }
296 
297 //------------------------------------------------------------------------------
298 // get vector from name
299 inline std::vector<CGNSVector>::iterator getVectorFromName(
300  std::vector<CGNSVector>& vectorList, const char_33 name)
301 {
302  for (std::vector<CGNSVector>::iterator iter = vectorList.begin(); iter != vectorList.end();
303  ++iter)
304  {
305  if (strncmp(iter->name, name, 31) == 0)
306  {
307  return iter;
308  }
309  }
310  return vectorList.end();
311 }
312 
313 //------------------------------------------------------------------------------
314 inline bool isACGNSVariable(const std::vector<CGNSVariable>& varList, const char_33 name)
315 {
316  for (std::vector<CGNSVariable>::const_iterator iter = varList.begin(); iter != varList.end();
317  ++iter)
318  {
319  if (strncmp(iter->name, name, 32) == 0)
320  {
321  return true;
322  }
323  }
324  return false;
325 }
326 
327 //------------------------------------------------------------------------------
328 void fillVectorsFromVars(std::vector<CGNSRead::CGNSVariable>& vars,
329  std::vector<CGNSRead::CGNSVector>& vectors, const int physicalDim);
330 //------------------------------------------------------------------------------
331 int setUpRind(const int cgioNum, const double rindId, int* rind);
332 //------------------------------------------------------------------------------
333 int getFirstNodeId(const int cgioNum, const double parentId, const char* label, double* id);
334 //------------------------------------------------------------------------------
335 int get_section_connectivity(const int cgioNum, const double cgioSectionId, const int dim,
336  const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
337  const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
338  const cgsize_t* memDim, vtkIdType* localElements);
339 //------------------------------------------------------------------------------
340 int GetVTKElemType(
341  CGNS_ENUMT(ElementType_t) elemType, bool& higherOrderWarning, bool& cgnsOrderFlag);
342 //------------------------------------------------------------------------------
343 void CGNS2VTKorder(const vtkIdType size, const int* cells_types, vtkIdType* elements);
344 //------------------------------------------------------------------------------
345 void CGNS2VTKorderMonoElem(const vtkIdType size, const int cell_type, vtkIdType* elements);
346 //------------------------------------------------------------------------------
347 template <typename T, typename Y>
348 int get_XYZ_mesh(const int cgioNum, const std::vector<double>& gridChildId,
349  const std::size_t& nCoordsArray, const int cellDim, const vtkIdType nPts,
350  const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
351  const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
352  const cgsize_t* memDims, vtkPoints* points)
353 {
354  T* coords = static_cast<T*>(points->GetVoidPointer(0));
355  T* currentCoord = static_cast<T*>(&(coords[0]));
356 
357  CGNSRead::char_33 coordName;
358  std::size_t len;
359  bool sameType = true;
360  double coordId;
361 
362  memset(coords, 0, 3 * nPts * sizeof(T));
363 
364  for (std::size_t c = 1; c <= nCoordsArray; ++c)
365  {
366  // Read CoordName
367  if (cgio_get_name(cgioNum, gridChildId[c - 1], coordName) != CG_OK)
368  {
369  char message[81];
370  cgio_error_message(message);
371  std::cerr << "get_XYZ_mesh : cgio_get_name :" << message;
372  }
373 
374  // Read node data type
375  CGNSRead::char_33 dataType;
376  if (cgio_get_data_type(cgioNum, gridChildId[c - 1], dataType))
377  {
378  continue;
379  }
380 
381  if (strcmp(dataType, "R8") == 0)
382  {
383  const bool doubleType = detail::is_double<T>::value;
384  sameType = doubleType;
385  }
386  else if (strcmp(dataType, "R4") == 0)
387  {
388  const bool floatType = detail::is_float<T>::value;
389  sameType = floatType;
390  }
391  else
392  {
393  std::cerr << "Invalid datatype for GridCoordinates\n";
394  continue;
395  }
396 
397  // Determine direction X,Y,Z
398  len = strlen(coordName) - 1;
399  switch (coordName[len])
400  {
401  case 'X':
402  currentCoord = static_cast<T*>(&(coords[0]));
403  break;
404  case 'Y':
405  currentCoord = static_cast<T*>(&(coords[1]));
406  break;
407  case 'Z':
408  currentCoord = static_cast<T*>(&(coords[2]));
409  break;
410  }
411 
412  coordId = gridChildId[c - 1];
413 
414  // quick transfer of data if same data types
415  if (sameType == true)
416  {
417  if (cgio_read_data(cgioNum, coordId, srcStart, srcEnd, srcStride, cellDim, memEnd, memStart,
418  memEnd, memStride, (void*)currentCoord))
419  {
420  char message[81];
421  cgio_error_message(message);
422  std::cerr << "cgio_read_data :" << message;
423  }
424  }
425  else
426  {
427  Y* dataArray = 0;
428  const cgsize_t memNoStride[3] = { 1, 1, 1 };
429 
430  // need to read into temp array to convert data
431  dataArray = new Y[nPts];
432  if (dataArray == 0)
433  {
434  std::cerr << "Error allocating buffer array\n";
435  break;
436  }
437  if (cgio_read_data(cgioNum, coordId, srcStart, srcEnd, srcStride, cellDim, memDims, memStart,
438  memDims, memNoStride, (void*)dataArray))
439  {
440  delete[] dataArray;
441  char message[81];
442  cgio_error_message(message);
443  std::cerr << "Buffer array cgio_read_data :" << message;
444  break;
445  }
446  for (vtkIdType ii = 0; ii < nPts; ++ii)
447  {
448  currentCoord[memStride[0] * ii] = static_cast<T>(dataArray[ii]);
449  }
450  delete[] dataArray;
451  }
452  }
453  return 0;
454 }
455 }
456 
457 #endif // vtkCGNSReaderInternal_h
458 // VTK-HeaderTest-Exclude: vtkCGNSReaderInternal.h
std::vector< double > & GetTimes()
return reference to GlobalTime
void SetArrayStatus(const char *name, bool status)
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)
void Merge(const vtkCGNSArraySelection &other)
int GetVTKElemType(CGNS_ENUMT(ElementType_t) elemType, bool &higherOrderWarning, bool &cgnsOrderFlag)
std::vector< CGNSRead::FamilyInformation > family
int getFirstNodeId(const int cgioNum, const double parentId, const char *label, double *id)
const char * GetArrayName(int index)
static int sortVariablesByName(const void *vOne, const void *vTwo)
std::map< std::string, double > referenceState
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)
vtkCGNSArraySelection CellDataArraySelection
std::vector< CGNSVector >::iterator getVectorFromName(std::vector< CGNSVector > &vectorList, const char_33 name)
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)
bool ArrayIsEnabled(const char *name)