1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
#include "VPICHeader.h"
//////////////////////////////////////////////////////////////////////////////
//
// Header information for every complete file where each time step has
// a file for each processor which ran the original application
//
//////////////////////////////////////////////////////////////////////////////
VPICHeader::VPICHeader()
{
this->headerSize = 123;
}
VPICHeader::~VPICHeader()
{
}
//////////////////////////////////////////////////////////////////////////////
//
// Read the header including consistency information and size information
// Return the header size in bytes if successful
//
//////////////////////////////////////////////////////////////////////////////
int VPICHeader::readHeader(FILE* filePtr)
{
// Consistency check to see if file can be read on this machine
int consistent = parseBoilerPlate(filePtr);
if (consistent == 0) {
cerr << "Data file is not consistent on this machine" << endl;
}
// Version and dump type
fread(&this->version, sizeof(int), 1, filePtr);
fread(&this->dumpType, sizeof(int), 1, filePtr);
if (this->dumpType != VPIC_FIELD && this->dumpType != VPIC_HYDRO)
cerr << "Bad VPIC dump type (not field or hydro)" << endl;
// Information
fread(&this->dumpTime, sizeof(int), 1, filePtr);
fread(this->gridSize, sizeof(int), DIMENSION, filePtr);
fread(&this->deltaTime, sizeof(float), 1, filePtr);
fread(this->gridStep, sizeof(float), DIMENSION, filePtr);
fread(this->gridOrigin, sizeof(float), DIMENSION, filePtr);
fread(&this->cvac, sizeof(float), 1, filePtr);
fread(&this->epsilon, sizeof(float), 1, filePtr);
fread(&this->damp, sizeof(float), 1, filePtr);
fread(&this->rank, sizeof(int), 1, filePtr);
fread(&this->totalRank, sizeof(int), 1, filePtr);
fread(&this->spid, sizeof(int), 1, filePtr);
fread(&this->spqm, sizeof(float), 1, filePtr);
// Array size/dimension
fread(&this->recordSize, sizeof(int), 1, filePtr);
fread(&this->numberOfDimensions, sizeof(int), 1, filePtr);
fread(this->ghostSize, sizeof(int), DIMENSION, filePtr);
return this->headerSize;
}
//////////////////////////////////////////////////////////////////////////////
//
// Read the first 23 bytes of the file to verify the word boundaries,
// sizes of numerical types, and endianness
//
// 5 bytes of sizes for long, short, int, real, double (8,2,4,4,8)
// 2 bytes where the hex word spells "cafe"
// 4 bytes where the hex word spells "deadbeef"
// 4 bytes of real with value 1.0
// 8 bytes of double with value 1.0
//
// With UNIX octal dump utility do:
// od -b (to see sizes)
// od -h -j 5 (to see hex "words")
// od -f -j 11 (to see real 1.0)
// od -F -j 15 (to see double 1.0)
//
//////////////////////////////////////////////////////////////////////////////
int VPICHeader::parseBoilerPlate(FILE* fp)
{
char byteSize[5];
short int cafe;
int deadbeef;
float floatone;
double doubleone;
fread(byteSize, sizeof(char), 5, fp);
if (byteSize[0] != sizeof(long long) ||
byteSize[1] != sizeof(short) ||
byteSize[2] != sizeof(int) ||
byteSize[3] != sizeof(float) ||
byteSize[4] != sizeof(double))
{
cerr << "Numerical type byte sizes do not match:" << endl;
cerr << "long: " << (short) byteSize[0] << " != "
<< sizeof(long long) << endl;
cerr << "short: " << (short) byteSize[1] << " != "
<< sizeof(short) << endl;
cerr << "int: " << (short) byteSize[2] << " != "
<< sizeof(int) << endl;
cerr << "float: " << (short) byteSize[3] << " != "
<< sizeof(float) << endl;
cerr << "double: " << (short) byteSize[4] << " != "
<< sizeof(double) << endl;
return 0;
}
fread(&cafe, sizeof(short int), 1, fp);
if (cafe != (short int) 0xcafe) {
cerr << "Endianness does not match" << endl;
return 0;
}
fread(&deadbeef, sizeof(int), 1, fp);
if (deadbeef != (int) 0xdeadbeef) {
cerr << "Endianness does not match" << endl;
return 0;
}
fread(&floatone, sizeof(float), 1, fp);
if (floatone != 1.0) {
cerr << "Could not locate float 1.0" << endl;
return 0;
}
fread(&doubleone, sizeof(double), 1, fp);
if (doubleone != 1.0) {
cerr << "Could not locate double 1.0" << endl;
return 0;
}
return 1;
}
//////////////////////////////////////////////////////////////////////////////
//
// Access methods
//
//////////////////////////////////////////////////////////////////////////////
void VPICHeader::getGridSize(int gridsize[])
{
for (int dim = 0; dim < DIMENSION; dim++)
gridsize[dim] = this->gridSize[dim];
}
void VPICHeader::getGhostSize(int ghostsize[])
{
for (int dim = 0; dim < DIMENSION; dim++)
ghostsize[dim] = this->ghostSize[dim];
}
void VPICHeader::getOrigin(float origin[])
{
for (int dim = 0; dim < DIMENSION; dim++)
origin[dim] = this->gridOrigin[dim];
}
void VPICHeader::getStep(float step[])
{
for (int dim = 0; dim < DIMENSION; dim++)
step[dim] = this->gridStep[dim];
}
//////////////////////////////////////////////////////////////////////////////
//
// Print header information
//
//////////////////////////////////////////////////////////////////////////////
void VPICHeader::PrintSelf(ostream& os, int vpicNotUsed(indent))
{
os << "Version: " << this->version << endl;
if (this->dumpType == VPIC_FIELD)
os << "Dump type: VPIC FIELD DATA" << endl;
else
os << "Dump type: VPIC HYDRO DATA" << endl;
os << "step: " << this->dumpTime << endl;
for (int i = 0; i < DIMENSION; i++)
os << "Grid size[" << i << "]: " << this->gridSize[i] << endl;
os << "Delta time: " << this->deltaTime << endl;
for (int i = 0; i < DIMENSION; i++)
os << "Delta grid[" << i << "]: " << this->gridStep[i] << endl;
for (int i = 0; i < DIMENSION; i++)
os << "Origin grid[" << i << "]: " << this->gridOrigin[i] << endl;
os << "cvac: " << this->cvac << endl;
os << "epsilon: " << this->epsilon << endl;
os << "damp: " << this->damp << endl;
os << "Rank: " << this->rank << endl;
os << "Total ranks: " << this->totalRank << endl;
os << "spid: " << this->spid << endl;
os << "spqm: " << this->spqm << endl;
os << "Record size: " << this->recordSize << endl;
os << "Number of dimensions: " << this->numberOfDimensions << endl;
for (int i = 0; i < DIMENSION; i++) {
os << "Ghost grid size[" << i << "]: "
<< this->ghostSize[i] << endl;
}
}
|