VTK  9.5.20250904
LSDynaFamily.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-FileCopyrightText: Copyright (c) Sandia Corporation
3// SPDX-License-Identifier: BSD-3-Clause
4
5// .NAME LSDynaFamily
6// .SECTION Description
7// A class to abstract away I/O from families of output files.
8// This performs the actual reads and writes plus any required byte swapping.
9// Also contains a subclass, LSDynaFamilyAdaptLevel, used to store
10// file+offset
11// information for each mesh adaptation's state info.
12
13#ifndef __LSDynaFamily_h
14#define __LSDynaFamily_h
15
16#include "vtkStringFormatter.h"
17#include "vtkType.h"
18
19#include <fcntl.h>
20#include <iostream>
21#include <stdio.h>
22#include <string.h>
23#include <string>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <vector>
27
28// this is needs to be moved over to fseekpos and ftellpos
29// in the future
30#ifndef _WIN32
31#include <unistd.h>
32typedef off_t vtkLSDynaOff_t; // sanity
33typedef int vtkLSDynaFile_t;
34#define VTK_LSDYNA_BADFILE -1
35#define VTK_LSDYNA_TELL(fid) lseek(fid, 0, SEEK_CUR)
36#define VTK_LSDYNA_SEEK(fid, off, whence) lseek(fid, off, whence)
37#define VTK_LSDYNA_SEEKTELL(fid, off, whence) lseek(fid, off, whence)
38#define VTK_LSDYNA_READ(fid, ptr, cnt) read(fid, ptr, cnt)
39#define VTK_LSDYNA_ISBADFILE(fid) (fid < 0)
40#define VTK_LSDYNA_CLOSEFILE(fid) close(fid)
41#else // _WIN32
42typedef long vtkLSDynaOff_t; // insanity
43typedef FILE* vtkLSDynaFile_t;
44#define VTK_LSDYNA_BADFILE 0
45#define VTK_LSDYNA_TELL(fid) ftell(fid)
46#define VTK_LSDYNA_SEEK(fid, off, whence) fseek(fid, off, whence)
47#define VTK_LSDYNA_SEEKTELL(fid, off, whence) fseek(fid, off, whence), ftell(fid)
48#define VTK_LSDYNA_READ(fid, ptr, cnt) fread(ptr, 1, cnt, fid)
49#define VTK_LSDYNA_ISBADFILE(fid) (fid == 0)
50#define VTK_LSDYNA_CLOSEFILE(fid) fclose(fid)
51#endif
52#ifdef VTKSNL_HAVE_ERRNO_H
53#include <errno.h>
54#endif
55
56VTK_ABI_NAMESPACE_BEGIN
58{
59public:
62
64 {
67 };
68
69 void SetDatabaseDirectory(const std::string& dd);
70 std::string GetDatabaseDirectory();
71
72 void SetDatabaseBaseName(const std::string& bn);
73 std::string GetDatabaseBaseName();
74
76
78 {
79 // These are the "section" marks:
80 // They are absolute (independent of current timestep).
84 // These are the "subsection" marks:
85 // == ControlSection has no subsections
86 // == StaticSection has these "absolute" marks:
96 // == TimeStepSection has these marks, relative to timestep 0 (so they are
97 // not valid for an arbitrary timestep, but may easily be used to compute
98 // an offset for any time step by adding a multiple of the state size):
102 // THIS MUST BE LAST
104 };
105
107 {
108 public:
110
112 {
114 mark.FileNumber = 0;
115 mark.Offset = 0;
116 for (int i = 0; i < LSDynaFamily::NumberOfSectionTypes; ++i)
117 {
118 this->Marks[i] = mark;
119 }
120 }
121 };
122
123 static const char* SectionTypeNames[];
124
126 {
129 Int
130 };
131
132 static const float EOFMarker;
133 static const char* SectionTypeToString(SectionType s);
134
135 int SkipToWord(SectionType sType, vtkIdType sId, vtkIdType wordNumber);
137 int SkipWords(vtkIdType numWords);
138 int BufferChunk(WordType wType, vtkIdType chunkSizeInWords);
140
141 // Description:
142 // Setup reading of a number of words to be split across multiple
143 // bufferChunk. This is used to read really large buffer sections
144 // in more reasonable sizes. The parameters are used to specify the total buffer
145 // size. The buffer size will always be evenly divisible by numComps and total
146 // word size of all buffers will be numTuples*numComps
147 vtkIdType InitPartialChunkBuffering(const vtkIdType& numTuples, const vtkIdType& numComps);
149
150 inline char* GetNextWordAsChars();
151 inline double GetNextWordAsFloat();
153
154 // Get the raw chunk buffer as a buffer of type T
155 template <typename T>
156 T* GetBufferAs();
157
158 // Not needed (yet):
159 // void GetCurrentWord( SectionType& stype, vtkIdType& sId, vtkIdType& wN );
161 void MarkSectionStart(int adaptLevel, SectionType m);
162
165
168
170 std::string GetFileName(int i);
172
173 int GetCurrentAdaptLevel() const { return this->FAdapt; }
174 int TimeAdaptLevel(int i) const { return this->TimeAdaptLevels[i]; }
175
176 vtkIdType GetCurrentFWord() const { return this->FWord; }
177
178 int GetWordSize() const;
179 // Reset erases all information about the current database.
180 // It does not free memory allocated for the current chunk.
181 void Reset();
182
184 void DumpMarks(std::ostream& os);
185
186 // Closes the current file descriptor. This is called after
187 // we are done reading in request data
189
191
192protected:
194 std::string DatabaseDirectory;
197 std::string DatabaseBaseName;
199 std::vector<std::string> Files;
202 std::vector<vtkIdType> FileSizes;
204 std::vector<int> FileAdaptLevels;
207 std::vector<int> Adaptations;
219 // std::vector<double> TimeValues;
230 std::vector<LSDynaFamilyAdaptLevel> AdaptationsMarkers;
233 std::vector<LSDynaFamilySectionMark> TimeStepMarks;
235 std::vector<int> TimeAdaptLevels;
237 unsigned char* Chunk;
241 // How much of the allocated space is filled with valid data (assert
242 // ChunkValid <= ChunkAlloc).
246
248 struct BufferingInfo;
249 BufferingInfo* BufferInfo;
250};
251
252//-----------------------------------------------------------------------------
254{
255 if (this->ChunkWord >= this->ChunkValid)
256 vtk::print(stderr, "Read char past end of buffer\n");
257 return (char*)(&this->Chunk[(this->ChunkWord++) * this->WordSize]);
258}
259
260//-----------------------------------------------------------------------------
262{
263 if (this->ChunkWord >= this->ChunkValid)
264 vtk::print(stderr, "Read float past end of buffer\n");
265 switch (this->WordSize)
266 {
267 case 4:
268 {
269 vtkTypeFloat32 value;
270 memcpy(&value, &this->Chunk[this->ChunkWord++ << 2], sizeof(value));
271 return value;
272 }
273 case 8:
274 default:
275 {
276 vtkTypeFloat64 value;
277 memcpy(&value, &this->Chunk[this->ChunkWord++ << 3], sizeof(value));
278 return value;
279 }
280 }
281}
282
283//-----------------------------------------------------------------------------
285{
286 if (this->ChunkWord >= this->ChunkValid)
287 {
288 vtk::print(stderr, "Read int past end of buffer\n");
289 }
290 switch (this->WordSize)
291 {
292 case 4:
293 {
294 vtkTypeInt32 value;
295 memcpy(&value, &this->Chunk[this->ChunkWord++ << 2], sizeof(value));
296 return value;
297 }
298 case 8:
299 default:
300 {
301 vtkIdType value;
302 memcpy(&value, &this->Chunk[this->ChunkWord++ << 3], sizeof(value));
303 return value;
304 }
305 }
306}
307
308//-----------------------------------------------------------------------------
309template <typename T>
311{
312 return reinterpret_cast<T*>(this->Chunk);
313}
314
315VTK_ABI_NAMESPACE_END
316#endif // __LSDynaFamily_h
int vtkLSDynaFile_t
off_t vtkLSDynaOff_t
LSDynaFamilySectionMark Marks[NumberOfSectionTypes]
vtkIdType GetCurrentFWord() const
int BufferChunk(WordType wType, vtkIdType chunkSizeInWords)
int ScanDatabaseDirectory()
vtkIdType GetNextWordAsInt()
static const char * SectionTypeNames[]
unsigned char * Chunk
A buffer containing file contents of file FNum starting with word FWord.
bool FileHandlesClosed
BufferingInfo * BufferInfo
vtkIdType StateSize
How many words is a timestep on disk?
void SetDatabaseBaseName(const std::string &bn)
int WordSize
Whether words are 4 or 8 bytes.
std::vector< int > Adaptations
Which files mark the start of a new mesh adaptation.
std::vector< int > TimeAdaptLevels
The adaptation level associated with each time step.
void OpenFileHandles()
int GetCurrentAdaptLevel() const
void CloseFileHandles()
std::vector< LSDynaFamilyAdaptLevel > AdaptationsMarkers
A vector of arrays of offsets to various header information sections (that do not vary with timestep)...
static const float EOFMarker
int DetermineStorageModel()
int SkipToWord(SectionType sType, vtkIdType sId, vtkIdType wordNumber)
vtkIdType TimeStep
A comprehensive list of all time values across all files (and mesh adaptations)
int AdvanceFile()
double GetNextWordAsFloat()
vtkIdType GetNumberOfFiles()
int FAdapt
The current adaptation level.
int SkipWords(vtkIdType numWords)
int SwapEndian
Whether files are reverse endian-ness of architecture.
vtkIdType GetNextChunk(const WordType &wType)
std::string GetDatabaseBaseName()
int MarkTimeStep()
std::string GetDatabaseDirectory()
vtkIdType FNum
The index of currently open file descriptor into list of files.
std::vector< vtkIdType > FileSizes
The size of each file in the database.
int GetWordSize() const
void SetDatabaseDirectory(const std::string &dd)
std::string DatabaseDirectory
The directory containing d3plot files.
vtkLSDynaFile_t FD
The currently open file descriptor.
vtkIdType GetStateSize() const
vtkIdType ChunkWord
A pointer to the next word in Chunk that will be returned when the reader requests a word.
vtkIdType GetFileSize(int i)
vtkIdType InitPartialChunkBuffering(const vtkIdType &numTuples, const vtkIdType &numComps)
std::vector< int > FileAdaptLevels
The adaptation level associated with each file.
void DumpMarks(std::ostream &os)
Print all adaptation and time step marker information.
vtkIdType ChunkAlloc
The allocated size (in words) of Chunk.
std::string DatabaseBaseName
The name (title string) of the database.
int ClearBuffer()
int TimeAdaptLevel(int i) const
void MarkSectionStart(int adaptLevel, SectionType m)
vtkIdType ChunkValid
std::string GetFileName(int i)
void SetStateSize(vtkIdType sz)
static const char * SectionTypeToString(SectionType s)
std::vector< LSDynaFamilySectionMark > TimeStepMarks
An array of bookmarks pointing to the start of state information for each timestep.
int JumpToMark(SectionType m)
char * GetNextWordAsChars()
std::vector< std::string > Files
The list of files that make up the database.
vtkIdType FWord
The offset of Chunk in currently open file.
Optimized C++ utilities for formatting values to strings and files.
int vtkIdType
Definition vtkType.h:332