// DO NOT EDIT ! // This file is generated using the MantaFlow preprocessor (prep generate). /****************************************************************************** * * MantaFlow fluid solver framework * Copyright 2011-2016 Tobias Pfaff, Nils Thuerey * * This program is free software, distributed under the terms of the * Apache License, Version 2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Loading and writing grids and meshes to disk * ******************************************************************************/ #include #include #include #include #if NO_ZLIB != 1 extern "C" { # include } #endif #include "mantaio.h" #include "grid.h" #include "particle.h" #include "vector4d.h" #include "grid4d.h" using namespace std; namespace Manta { static const int STR_LEN_PDATA = 256; //! pdata uni header, v3 (similar to grid header) typedef struct { int dim; // number of partilces int dimX, dimY, dimZ; // underlying solver resolution (all data in local coordinates!) int elementType, bytesPerElement; // type id and byte size char info[STR_LEN_PDATA]; // mantaflow build information unsigned long long timestamp; // creation time } UniPartHeader; //***************************************************************************** // conversion functions for double precision // (note - uni files always store single prec. values) //***************************************************************************** #if NO_ZLIB != 1 template void pdataConvertWrite(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, UniPartHeader &head) { errMsg("pdataConvertWrite: unknown type, not yet supported"); } template<> void pdataConvertWrite(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, UniPartHeader &head) { gzwrite(gzf, &head, sizeof(UniPartHeader)); gzwrite(gzf, &pdata[0], sizeof(int) * head.dim); } template<> void pdataConvertWrite(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, UniPartHeader &head) { head.bytesPerElement = sizeof(float); gzwrite(gzf, &head, sizeof(UniPartHeader)); float *ptrf = (float *)ptr; for (int i = 0; i < pdata.size(); ++i, ++ptrf) { *ptrf = (float)pdata[i]; } gzwrite(gzf, ptr, sizeof(float) * head.dim); } template<> void pdataConvertWrite(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, UniPartHeader &head) { head.bytesPerElement = sizeof(Vector3D); gzwrite(gzf, &head, sizeof(UniPartHeader)); float *ptrf = (float *)ptr; for (int i = 0; i < pdata.size(); ++i) { for (int c = 0; c < 3; ++c) { *ptrf = (float)pdata[i][c]; ptrf++; } } gzwrite(gzf, ptr, sizeof(Vector3D) * head.dim); } template void pdataReadConvert(gzFile &gzf, ParticleDataImpl &grid, void *ptr, int bytesPerElement) { errMsg("pdataReadConvert: unknown pdata type, not yet supported"); } template<> void pdataReadConvert(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, int bytesPerElement) { gzread(gzf, ptr, sizeof(int) * pdata.size()); assertMsg(bytesPerElement == sizeof(int), "pdata element size doesn't match " << bytesPerElement << " vs " << sizeof(int)); // int dont change in double precision mode - copy over memcpy(&(pdata[0]), ptr, sizeof(int) * pdata.size()); } template<> void pdataReadConvert(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, int bytesPerElement) { gzread(gzf, ptr, sizeof(float) * pdata.size()); assertMsg(bytesPerElement == sizeof(float), "pdata element size doesn't match " << bytesPerElement << " vs " << sizeof(float)); float *ptrf = (float *)ptr; for (int i = 0; i < pdata.size(); ++i, ++ptrf) { pdata[i] = double(*ptrf); } } template<> void pdataReadConvert(gzFile &gzf, ParticleDataImpl &pdata, void *ptr, int bytesPerElement) { gzread(gzf, ptr, sizeof(Vector3D) * pdata.size()); assertMsg(bytesPerElement == sizeof(Vector3D), "pdata element size doesn't match " << bytesPerElement << " vs " << sizeof(Vector3D)); float *ptrf = (float *)ptr; for (int i = 0; i < pdata.size(); ++i) { Vec3 v; for (int c = 0; c < 3; ++c) { v[c] = double(*ptrf); ptrf++; } pdata[i] = v; } } #endif // NO_ZLIB!=1 //***************************************************************************** // particles and particle data //***************************************************************************** static const int PartSysSize = sizeof(Vector3D) + sizeof(int); int writeParticlesUni(const std::string &name, const BasicParticleSystem *parts) { debMsg("writing particles " << parts->getName() << " to uni file " << name, 1); #if NO_ZLIB != 1 char ID[5] = "PB02"; UniPartHeader head; head.dim = parts->size(); Vec3i gridSize = parts->getParent()->getGridSize(); head.dimX = gridSize.x; head.dimY = gridSize.y; head.dimZ = gridSize.z; head.bytesPerElement = PartSysSize; head.elementType = 0; // 0 for base data snprintf(head.info, STR_LEN_PDATA, "%s", buildInfoString().c_str()); MuTime stamp; head.timestamp = stamp.time; gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression if (!gzf) { errMsg("can't open file " << name); return 0; } gzwrite(gzf, ID, 4); # if FLOATINGPOINT_PRECISION != 1 // warning - hard coded conversion of byte size here... gzwrite(gzf, &head, sizeof(UniPartHeader)); for (int i = 0; i < parts->size(); ++i) { Vector3D pos = toVec3f((*parts)[i].pos); int flag = (*parts)[i].flag; gzwrite(gzf, &pos, sizeof(Vector3D)); gzwrite(gzf, &flag, sizeof(int)); } # else assertMsg(sizeof(BasicParticleData) == PartSysSize, "particle data size doesn't match"); gzwrite(gzf, &head, sizeof(UniPartHeader)); gzwrite(gzf, &((*parts)[0]), PartSysSize * head.dim); # endif return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); return 0; #endif }; int readParticlesUni(const std::string &name, BasicParticleSystem *parts) { debMsg("reading particles " << parts->getName() << " from uni file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); if (!gzf) { errMsg("can't open file " << name); return 0; } char ID[5] = {0, 0, 0, 0, 0}; gzread(gzf, ID, 4); if (!strcmp(ID, "PB01")) { errMsg("particle uni file format v01 not supported anymore"); return 0; } else if (!strcmp(ID, "PB02")) { // current file format UniPartHeader head; assertMsg(gzread(gzf, &head, sizeof(UniPartHeader)) == sizeof(UniPartHeader), "can't read file, no header present"); assertMsg(((head.bytesPerElement == PartSysSize) && (head.elementType == 0)), "particle type doesn't match"); // re-allocate all data parts->resizeAll(head.dim); assertMsg(head.dim == parts->size(), "particle size doesn't match"); # if FLOATINGPOINT_PRECISION != 1 for (int i = 0; i < parts->size(); ++i) { Vector3D pos; int flag; gzread(gzf, &pos, sizeof(Vector3D)); gzread(gzf, &flag, sizeof(int)); (*parts)[i].pos = toVec3d(pos); (*parts)[i].flag = flag; } # else assertMsg(sizeof(BasicParticleData) == PartSysSize, "particle data size doesn't match"); IndexInt bytes = PartSysSize * head.dim; IndexInt readBytes = gzread(gzf, &(parts->getData()[0]), bytes); assertMsg(bytes == readBytes, "can't read uni file, stream length does not match, " << bytes << " vs " << readBytes); # endif parts->transformPositions(Vec3i(head.dimX, head.dimY, head.dimZ), parts->getParent()->getGridSize()); } return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); return 0; #endif }; template int writePdataUni(const std::string &name, ParticleDataImpl *pdata) { debMsg("writing particle data " << pdata->getName() << " to uni file " << name, 1); #if NO_ZLIB != 1 char ID[5] = "PD01"; UniPartHeader head; head.dim = pdata->size(); Vec3i gridSize = pdata->getParent()->getGridSize(); head.dimX = gridSize.x; head.dimY = gridSize.y; head.dimZ = gridSize.z; head.bytesPerElement = sizeof(T); head.elementType = 1; // 1 for particle data, todo - add sub types? snprintf(head.info, STR_LEN_PDATA, "%s", buildInfoString().c_str()); MuTime stamp; head.timestamp = stamp.time; gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression if (!gzf) { errMsg("can't open file " << name); return 0; } gzwrite(gzf, ID, 4); # if FLOATINGPOINT_PRECISION != 1 // always write float values, even if compiled with double precision (as for grids) ParticleDataImpl temp(pdata->getParent()); temp.resize(pdata->size()); pdataConvertWrite(gzf, *pdata, &(temp[0]), head); # else gzwrite(gzf, &head, sizeof(UniPartHeader)); gzwrite(gzf, &(pdata->get(0)), sizeof(T) * head.dim); # endif return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); return 0; #endif }; template int readPdataUni(const std::string &name, ParticleDataImpl *pdata) { debMsg("reading particle data " << pdata->getName() << " from uni file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); if (!gzf) { errMsg("can't open file " << name); return 0; } char ID[5] = {0, 0, 0, 0, 0}; gzread(gzf, ID, 4); if (!strcmp(ID, "PD01")) { UniPartHeader head; assertMsg(gzread(gzf, &head, sizeof(UniPartHeader)) == sizeof(UniPartHeader), "can't read file, no header present"); pdata->getParticleSys()->resize(head.dim); // ensure that parent particle system has same size pdata->resize(head.dim); assertMsg(head.dim == pdata->size(), "pdata size doesn't match"); # if FLOATINGPOINT_PRECISION != 1 ParticleDataImpl temp(pdata->getParent()); temp.resize(pdata->size()); pdataReadConvert(gzf, *pdata, &(temp[0]), head.bytesPerElement); # else assertMsg(((head.bytesPerElement == sizeof(T)) && (head.elementType == 1)), "pdata type doesn't match"); IndexInt bytes = sizeof(T) * head.dim; IndexInt readBytes = gzread(gzf, &(pdata->get(0)), sizeof(T) * head.dim); assertMsg(bytes == readBytes, "can't read uni file, stream length does not match, " << bytes << " vs " << readBytes); # endif } return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); return 0; #endif } // explicit instantiation template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); } // namespace Manta