1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkAMReXGridReaderInternal.hpp
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 /**
16  * @class   vtkAMReXGridReaderInternal
17  * @brief   Consists of the low-level AMReX Reader used by the vtkAMReXGridReader.
18  *
19  * @sa
20  *  vtkAMReXGridReader
21  */
22 
23 #ifndef vtkAMReXGridReaderInternal_h
24 #define vtkAMReXGridReaderInternal_h
25 #ifndef __VTK_WRAP__
26 
27 #include <map>
28 #include <string>
29 #include <vector>
30 
31 #include "vtkDataSet.h"
32 #include "vtkSOADataArrayTemplate.h"
33 
34 class vtkIndent;
35 
36 //==============================================================================
37 //            I N T E R N A L   A M R e X     R E A D E R
38 //==============================================================================
39 
40 // ----------------------------------------------------------------------------
41 //                     Class  RealDecriptor (begin)
42 // ----------------------------------------------------------------------------
43 
44 /*
45    floating point format specification (fmt):
46     -   fmt[0] = # of bits per number
47     -   fmt[1] = # of bits in exponent
48     -   fmt[2] = # of bits in mantissa
49     -   fmt[3] = start bit of sign
50     -   fmt[4] = start bit of exponent
51     -   fmt[5] = start bit of mantissa
52     -   fmt[6] = high order mantissa bit (CRAY needs this)
53     -   fmt[7] = bias of exponent
54 
55     64 11 52 0 1 12 0 1023 - IEEE Double
56 
57    byte order (ord) handles endianness (and defines size such as float or double)
58     -   ord[0] = byte in 1st byte
59     -   ord[1] = byte in 2nd byte
60     -   ord[2] = byte in 3rd byte
61     -   ord[3] = byte in 4th byte
62     -   ...
63 */
64 
65 class RealDescriptor
66 {
67 public:
68   RealDescriptor();
69   RealDescriptor(const long* format, const int* order, int order_length);
70   const long* format() const&;
71   const std::vector<long>& formatarray() const&;
72   const int* order() const&;
73   const std::vector<int>& orderarray() const&;
74   int numBytes() const;
75   bool operator==(const RealDescriptor& rd) const;
76 
77 private:
78   std::vector<long> fr;
79   std::vector<int> ord;
80 };
81 
82 // ----------------------------------------------------------------------------
83 //                     Class  RealDecriptor ( end )
84 // ----------------------------------------------------------------------------
85 
86 // ----------------------------------------------------------------------------
87 //                     Class  vtkAMReXGridHeader (begin)
88 // ----------------------------------------------------------------------------
89 
90 class vtkAMReXGridHeader
91 {
92 public:
93   std::string versionName;
94   int variableNamesSize;
95   std::vector<std::string> variableNames;
96 
97   // prefix string indicating a variable is a vector component
98   // Note: this prefix will be removed from any variable name
99   // whether or not the variable name is a properly formed
100   // vector variable name (contains a proper postfix)
101   std::string vectorNamePrefix = "amrexvec";
102 
103   // delimeter must be the same after prefix and before postfix
104   char nameDelim = '_';
105 
106   // variableNames map to (potentially a collection of) variableNames indices
107   std::map<std::string, std::vector<int>> parsedVariableNames;
108 
109   int dim;
110   double time;
111   int finestLevel;
112   std::vector<double> problemDomainLoEnd;
113   std::vector<double> problemDomainHiEnd;
114   std::vector<int> refinementRatio;
115   std::vector<std::vector<std::vector<int>>> levelDomains;
116   std::vector<int> levelSteps;
117   std::vector<std::vector<double>> cellSize;
118   int geometryCoord;
119   int magicZero;
120   std::vector<int> levelSize;
121   std::vector<std::vector<std::vector<std::vector<double>>>> levelCells;
122   std::vector<std::string> levelPrefix;
123   std::vector<std::string> multiFabPrefix;
124   bool debugHeader;
125 
126   vtkAMReXGridHeader();
127 
128   void PrintSelf(std::ostream& os, vtkIndent indent);
129   void PrintSelfGenericHeader(std::ostream& os, vtkIndent indent);
130   bool Parse(const std::string& headerData);
131   bool ParseGenericHeader(const std::string& headerData);
132 
133   void SetVectorNamePrefix(const std::string& prefix);
134   void SetNameDelimiter(const char delim);
135 
136 private:
137   // if the vectorNamePrefix is detected at the beginning of the name,
138   // remove it along with the expected x/y/z postfix. Otherwise, return
139   // the original string
140   std::string GetBaseVariableName(const std::string& name);
141 
142   // returns 0 if postfix is x, 1 for y and 2 for z. returns -1 otherwise
143   int CheckComponent(const std::string& name);
144 
145   // check if name has the vectorNamePrefix
146   bool HasVectorPrefix(const std::string& name);
147 };
148 
149 // ----------------------------------------------------------------------------
150 //                     Class  vtkAMReXGridHeader ( end )
151 // ----------------------------------------------------------------------------
152 
153 // ----------------------------------------------------------------------------
154 //                     Class  vtkAMReXGridLevelHeader (begin)
155 // ----------------------------------------------------------------------------
156 
157 class vtkAMReXGridLevelHeader
158 {
159   enum Version
160   {
161     Undefined_v1 = 0,          // ---- undefined
162     Version_v1 = 1,            // ---- auto converting version with headers
163                                // ---- for each fab in the data files and
164                                // ---- min and max values for each fab in the header
165     NoFabHeader_v1 = 2,        // ---- no fab headers, no fab mins or maxes
166     NoFabHeaderMinMax_v1 = 3,  // ---- no fab headers,
167                                // ---- min and max values for each fab in the header
168     NoFabHeaderFAMinMax_v1 = 4 // ---- no fab headers, no fab mins or maxes,
169                                // ---- min and max values for each FabArray in the header
170   };
171   enum Ordering
172   {
173     NormalOrder = 1,
174     ReverseOrder = 2
175   };
176 
177 public:
178   int level;
179   int dim;
180   int levelVersion;
181   int levelHow;
182   int levelNumberOfComponents;
183   int levelNumberOfGhostCells;
184   int levelBoxArraySize;
185   int levelMagicZero;
186   std::vector<std::vector<std::vector<int>>> levelBoxArrays;
187   int levelNumberOfFABOnDisk;
188   std::string levelFabOnDiskPrefix;
189   std::vector<std::string> levelFABFile;
190   std::vector<long> levelFileOffset;
191   std::vector<std::vector<double>> levelMinimumsFAB;
192   std::vector<std::vector<double>> levelMaximumsFAB;
193   std::vector<double> levelFABArrayMinimum;
194   std::vector<double> levelFABArrayMaximum;
195   int levelRealNumberOfBytes;
196   int levelRealOrder;
197   bool debugLevelHeader;
198 
199   vtkAMReXGridLevelHeader();
200   void PrintSelf(std::ostream& os, vtkIndent indent);
201   void PrintSelfLevelHeader(std::ostream& os, vtkIndent indent);
202   bool Parse(int _level, int _dim, const std::string& headerData);
203   bool ParseLevelHeader(int _level, int _dim, const std::string& headerData);
204 };
205 
206 // ----------------------------------------------------------------------------
207 //                     Class  vtkAMReXGridLevelHeader ( end )
208 // ----------------------------------------------------------------------------
209 
210 // ----------------------------------------------------------------------------
211 //                     Class  vtkAMReXGridReaderInternal (begin)
212 // ----------------------------------------------------------------------------
213 
214 class vtkAMReXGridReaderInternal
215 {
216 public:
217   vtkAMReXGridReaderInternal();
218   ~vtkAMReXGridReaderInternal();
219   void DestroyHeader();
220   void DestroyLevelHeader();
221   void PrintSelf(std::ostream& os, vtkIndent indent);
222   void SetFileName(char* fName);
223 
224   void ReadMetaData();
225   bool ReadHeader();
226   bool ReadLevelHeader();
227   int GetNumberOfLevels();
228   int GetBlockLevel(const int blockIdx);
229   int GetNumberOfBlocks();
230   int GetBlockIndexWithinLevel(int blockIdx, int level);
231   void GetBlockAttribute(const char* attribute, int blockIdx, vtkDataSet* pDataSet);
232   int GetOffsetOfAttribute(const char* attribute);
233   void ReadFAB(std::istream& is);
234   int ReadVersion(std::istream& is);
235   void ReadOrder(std::istream& is, std::vector<int>& ar);
236   void PrintOrder(std::vector<int>& ar);
237   void ReadFormat(std::istream& is, std::vector<long>& ar);
238   void PrintFormat(std::vector<long>& ar);
239   RealDescriptor* ReadRealDescriptor(std::istream& is);
240   int ReadBoxArray(std::istream& is, int* boxArray, int* boxArrayDim);
241   void PrintBoxArray(int* boxArray);
242   int ReadNumberOfAttributes(std::istream& is);
243   void ReadBlockAttribute(std::istream& is, int numberOfPoints, int size, char* buffer);
244   void Convert(
245     void* out, const void* in, long nitems, const RealDescriptor& ord, const RealDescriptor& ird);
246   void PermuteOrder(
247     void* out, const void* in, long nitems, const int* outord, const int* inord, int REALSIZE);
248 
249   template <typename T>
250   void CreateVTKAttributeArray(vtkAOSDataArrayTemplate<T>* dataArray, const RealDescriptor* ord,
251     const RealDescriptor* ird, const std::vector<std::vector<char>>& buffers,
252     const int numberOfPoints, const std::string& attribute);
253 
254   bool headersAreRead;
255   bool debugReader;
256   std::string FileName;
257   vtkAMReXGridHeader* Header;
258   friend class vtkAMReXGridHeader;
259   std::vector<vtkAMReXGridLevelHeader*> LevelHeader;
260   friend class vtkAMReXGridLeveHeader;
261 };
262 
263 template <typename T>
CreateVTKAttributeArray(vtkAOSDataArrayTemplate<T> * dataArray,const RealDescriptor * ord,const RealDescriptor * ird,const std::vector<std::vector<char>> & buffers,const int numberOfPoints,const std::string & attribute)264 void vtkAMReXGridReaderInternal::CreateVTKAttributeArray(vtkAOSDataArrayTemplate<T>* dataArray,
265   const RealDescriptor* ord, const RealDescriptor* ird,
266   const std::vector<std::vector<char>>& buffers, const int numberOfPoints,
267   const std::string& attribute)
268 {
269   int nComps = static_cast<int>(this->Header->parsedVariableNames[attribute].size());
270   dataArray->SetName(attribute.c_str());
271   dataArray->SetNumberOfComponents(nComps);
272   dataArray->SetNumberOfTuples(numberOfPoints);
273   T* arrayPtr = new T[numberOfPoints];
274   for (int j = 0; j < nComps; ++j)
275   {
276     this->Convert(arrayPtr, buffers[j].data(), numberOfPoints, *ord, *ird);
277 
278     // Copy to data array component
279     for (int i = 0; i < numberOfPoints; ++i)
280     {
281       dataArray->SetTypedComponent(i, j, arrayPtr[i]);
282     }
283   }
284   delete[] arrayPtr;
285 }
286 
287 // ----------------------------------------------------------------------------
288 //                     Class  vtkAMReXGridReaderInternal ( end )
289 // ----------------------------------------------------------------------------
290 #endif
291 #endif /* vtkAMReXGridReaderInternal_h */
292 // VTK-HeaderTest-Exclude: vtkAMReXGridReaderInternal.h
293