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