42 #include <boost/algorithm/string.hpp>
51 ModuleKey InputNek5000::m_className[1] = {
54 "Reads Nek5000 field file.")
66 unsigned char u8[
sizeof(T)];
71 for (
size_t k = 0; k <
sizeof(T); k++)
73 dest.u8[k] = source.u8[
sizeof(T) - k - 1];
110 if (
m_f->m_comm->TreatAsRankZero())
112 cout <<
"Processing Nek5000 field file" << endl;
116 string fldending =
"fld5000";
117 ifstream file(
m_f->m_inputfiles[fldending][0].c_str(), ios::binary);
120 vector<char> data(132);
121 file.read(&data[0], 132);
124 string check(&data[0], 4);
125 string header(&data[4], 128);
127 ASSERTL0(check ==
"#std",
"Unable to read file");
131 bool byteSwap =
false;
134 file.read((
char *)(&test), 4);
135 if (test > 6.5 && test < 6.6)
143 "Unable to determine endian-ness of input file");
150 int nBytes, nBlocksXYZ[3], nBlocks, nTotBlocks, dir, nDirs, nCycle, nDim;
155 ss >> nBytes >> nBlocksXYZ[0] >> nBlocksXYZ[1] >> nBlocksXYZ[2]
156 >> nBlocks >> nTotBlocks >> time >> nCycle >> dir >> nDirs >> remain;
159 nDim = nBlocksXYZ[2] == 1 ? 2 : 3;
164 cout <<
"Found header information:" << endl;
165 cout <<
" -- " << (byteSwap ?
"" :
"do not ") <<
"need to swap endian"
167 cout <<
" -- Data byte size : " << nBytes << endl;
168 cout <<
" -- Number of xyz blocks : " << nBlocksXYZ[0] <<
"x"
169 << nBlocksXYZ[1] <<
"x" << nBlocksXYZ[2] << endl;
170 cout <<
" -- Blocks in file/total : " << nBlocks <<
"/" << nTotBlocks
172 cout <<
" -- Simulation time : " << time << endl;
173 cout <<
" -- Number of cycles : " << nCycle << endl;
174 cout <<
" -- Number of dirs : " << dir <<
"/" << nDirs << endl;
175 cout <<
" -- Remaining header : " << remain << endl;
179 ASSERTL0(nDirs == 1,
"Number of directories must be one");
182 ASSERTL0(nBlocks == nTotBlocks,
"Partial field output not supported");
185 ASSERTL0(nBytes == 8,
"Data file must contain double-precision data");
191 fielddef->m_numHomogeneousDir = 0;
192 fielddef->m_homoStrips =
false;
193 fielddef->m_pointsDef =
false;
194 fielddef->m_uniOrder =
true;
195 fielddef->m_numPointsDef =
false;
197 for (
int i = 0; i < nDim; ++i)
200 fielddef->m_numModes.push_back(nBlocksXYZ[i]);
204 NekUInt32 maxID = 0, minID = numeric_limits<NekUInt32>::max();
208 file.read((
char *)&blockNum, 4);
213 fielddef->m_elementIDs.push_back(blockNum-1);
215 maxID = maxID > blockNum ? maxID : blockNum;
216 minID = minID < blockNum ? minID : blockNum;
220 size_t blockSize = nBlocksXYZ[0] * nBlocksXYZ[1] * nBlocksXYZ[2];
221 size_t dataSize = blockSize * nBlocks;
223 for (string::size_type i = 0; i < remain.size(); ++i)
228 fielddef->m_fields.push_back(
"u");
229 fielddef->m_fields.push_back(
"v");
232 fielddef->m_fields.push_back(
"w");
236 fielddef->m_fields.push_back(
"p");
239 fielddef->m_fields.push_back(
"T");
244 fielddef->m_fields.push_back(
string(
"scalar") + remain[i]);
249 cerr <<
"Field contains unknown variable: " << remain[i] << endl;
254 m_f->m_data.resize(1);
255 m_f->m_data[0].resize(fielddef->m_fields.size() * dataSize);
258 for (
size_t i = 0, cnt = 0; i < remain.size(); ++i)
265 cnt, cnt + dataSize, cnt + 2*dataSize
268 for (
size_t j = 0; j < nBlocks; ++j)
270 for (
size_t k = 0; k < nDim; ++k)
273 (
char *)&
m_f->m_data[0][cntVel[k]],
275 cntVel[k] += blockSize;
279 cnt += nDim * dataSize;
285 (
char *)&
m_f->m_data[0][cnt],
295 (
char *)&
m_f->m_data[0][cnt],
305 m_f->m_fielddef.push_back(fielddef);
void swap_endian(T &u)
Swap endian ordering of the input variable.
#define ASSERTL0(condition, msg)
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
boost::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
pair< ModuleType, string > ModuleKey
Metadata that describes the storage properties of field output.
boost::shared_ptr< Field > FieldSharedPtr
#define dest(otri, vertexptr)
boost::uint32_t NekUInt32
ModuleFactory & GetModuleFactory()
FieldSharedPtr m_f
Field object.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.