29#ifndef SUPER_VTM_WRITER_3D_HH
30#define SUPER_VTM_WRITER_3D_HH
53template<
typename T,
typename OUT_T,
typename W>
55 : clout( std::cout,
"SuperVTMwriter3D" ), _createFile(false), _name(name), _overlap(overlap), _binary(binary), _compress(compress)
57 static_assert(std::is_same_v<OUT_T, float> || std::is_same_v<OUT_T, double>,
58 "OUT_T must be either float or double");
61template<
typename T,
typename OUT_T,
typename W>
63 const std::string& name,
int overlap,
bool binary,
bool compress)
66 _cGeometry = &cGeometry;
69template<
typename T,
typename OUT_T,
typename W>
74 f->getSuperStructure().communicate();
80 const auto it_begin = _pointerVec.cbegin();
81 if (!_cGeometry && it_begin == _pointerVec.end()) {
82 throw std::runtime_error(
"No functor to write");
84 CuboidGeometry3D<T> const& cGeometry = _cGeometry ? *_cGeometry : (**it_begin).getSuperStructure().getCuboidGeometry();
90 for (
int iC = 0; iC < cGeometry.
getNc(); ++iC) {
91 writeGlobalVTI(iT, iC);
94 LoadBalancer<T>& load = (**it_begin).getSuperStructure().getLoadBalancer();
96 for (
int iCloc = 0; iCloc < load.
size(); iCloc++) {
102template<
typename T,
typename OUT_T,
typename W>
108 const auto it_begin = _pointerVec.cbegin();
109 CuboidGeometry3D<T> const& cGeometry = _cGeometry ? *_cGeometry : (**it_begin).getSuperStructure().getCuboidGeometry();
115 dataPVDmaster(iT, pathPVD,
"data/" +
createFileName(_name, iT) +
".vtm");
119 preambleVTM(pathVTM);
120 for (
int iC = 0; iC < cGeometry.
getNc(); iC++) {
127template<
typename T,
typename OUT_T,
typename W>
130 const auto it_begin = _pointerVec.cbegin();
131 CuboidGeometry3D<T> const& cGeometry = _cGeometry ? *_cGeometry : (**it_begin).getSuperStructure().getCuboidGeometry();
142 const int originLatticeR[4] = {iC,0,0,0};
143 T originPhysR[3] = {T()};
144 cGeometry.
getPhysR(originPhysR,originLatticeR);
146 preambleVTI(fullNameVTI, extent0, (extent1+_overlap-1), originPhysR, delta);
147 for (
auto it : _pointerVec) {
148 dataArray(fullNameVTI, *it, iC, extent1);
150 closePiece(fullNameVTI);
151 closeVTI(fullNameVTI);
154template<
typename T,
typename OUT_T,
typename W>
157 const auto it_begin = _pointerVec.cbegin();
158 CuboidGeometry3D<T> const& cGeometry = (**it_begin).getSuperStructure().getCuboidGeometry();
159 LoadBalancer<T>& load = (**it_begin).getSuperStructure().getLoadBalancer();
170 const int originLatticeR[4] = {load.
glob(iCloc),0,0,0};
171 T originPhysR[3] = {T()};
172 cGeometry.
getPhysR(originPhysR,originLatticeR);
174 preambleVTI(fullNameVTI, extent0, (extent1+_overlap-1), originPhysR, delta);
175 for (
auto it : _pointerVec) {
176 dataArray(fullNameVTI, *it, load.
glob(iCloc), extent1);
178 closePiece(fullNameVTI);
179 closeVTI(fullNameVTI);
182template<
typename T,
typename OUT_T,
typename W>
192#ifdef PARALLEL_MODE_MPI
203 preambleVTM(pathVTM);
204 for (
int iC = 0; iC < cGeometry.
getNc(); iC++) {
207 dataVTM( iC, pathVTM, nameVTI );
212 for (
int iCloc = 0; iCloc < load.
size(); iCloc++) {
221 const int originLatticeR[4] = {load.
glob(iCloc),0,0,0};
222 T originPhysR[3] = {T()};
223 cGeometry.
getPhysR(originPhysR,originLatticeR);
225 preambleVTI(fullNameVTI, extent0, (extent1+_overlap-1.), originPhysR, delta);
227 dataArray(fullNameVTI, f, load.
glob(iCloc), extent1);
228 closePiece(fullNameVTI);
229 closeVTI(fullNameVTI);
234template<
typename T,
typename OUT_T,
typename W>
240template<
typename T,
typename OUT_T,
typename W>
244#ifdef PARALLEL_MODE_MPI
250 preamblePVD(fullNamePVDmaster);
251 closePVD(fullNamePVDmaster);
256template<
typename T,
typename OUT_T,
typename W>
259 _pointerVec.push_back(&f);
262template<
typename T,
typename OUT_T,
typename W>
266 _pointerVec.push_back(&f);
269template<
typename T,
typename OUT_T,
typename W>
275template<
typename T,
typename OUT_T,
typename W>
285template<
typename T,
typename OUT_T,
typename W>
290 const BaseType<T> d_origin[3] = {origin[0], origin[1], origin[2]};
292 std::ofstream fout(fullName, std::ios::trunc);
294 clout <<
"Error: could not open " << fullName << std::endl;
296 fout <<
"<?xml version=\"1.0\"?>\n";
297 fout <<
"<VTKFile type=\"ImageData\" version=\"0.1\" ";
299 fout <<
"byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n";
302 fout <<
"byte_order=\"LittleEndian\">\n";
304 fout <<
"<ImageData WholeExtent=\""
305 << extent0[0] <<
" "<< extent1[0] <<
" "
306 << extent0[1] <<
" "<< extent1[1] <<
" "
307 << extent0[2] <<
" "<< extent1[2]
308 <<
"\" Origin=\"" << d_origin[0] <<
" " << d_origin[1] <<
" " << d_origin[2]
309 <<
"\" Spacing=\"" << d_delta <<
" " << d_delta <<
" " << d_delta <<
"\">\n";
310 fout <<
"<Piece Extent=\""
311 << extent0[0] <<
" "<< extent1[0] <<
" "
312 << extent0[1] <<
" "<< extent1[1] <<
" "
313 << extent0[2] <<
" "<< extent1[2] <<
"\">\n";
314 fout <<
"<PointData>\n";
318template<
typename T,
typename OUT_T,
typename W>
319void SuperVTMwriter3D<T,OUT_T,W>::closeVTI(
const std::string& fullNamePiece)
321 std::ofstream fout(fullNamePiece, std::ios::app );
323 clout <<
"Error: could not open " << fullNamePiece << std::endl;
325 fout <<
"</ImageData>\n";
326 fout <<
"</VTKFile>\n";
330template<
typename T,
typename OUT_T,
typename W>
331void SuperVTMwriter3D<T,OUT_T,W>::preamblePVD(
const std::string& fullNamePVD)
333 std::ofstream fout(fullNamePVD, std::ios::trunc);
335 clout <<
"Error: could not open " << fullNamePVD << std::endl;
337 fout <<
"<?xml version=\"1.0\"?>\n";
338 fout <<
"<VTKFile type=\"Collection\" version=\"0.1\" "
339 <<
"byte_order=\"LittleEndian\">\n"
344template<
typename T,
typename OUT_T,
typename W>
345void SuperVTMwriter3D<T,OUT_T,W>::closePVD(
const std::string& fullNamePVD)
347 std::ofstream fout(fullNamePVD, std::ios::app );
349 clout <<
"Error: could not open " << fullNamePVD << std::endl;
351 fout <<
"</Collection>\n";
352 fout <<
"</VTKFile>\n";
356template<
typename T,
typename OUT_T,
typename W>
357void SuperVTMwriter3D<T,OUT_T,W>::preambleVTM(
const std::string& fullNamePVD)
359 std::ofstream fout(fullNamePVD, std::ios::trunc);
361 clout <<
"Error: could not open " << fullNamePVD << std::endl;
363 fout <<
"<?xml version=\"1.0\"?>\n";
364 fout <<
"<VTKFile type=\"vtkMultiBlockDataSet\" version=\"1.0\" "
365 <<
"byte_order=\"LittleEndian\">\n"
366 <<
"<vtkMultiBlockDataSet>\n" ;
370template<
typename T,
typename OUT_T,
typename W>
371void SuperVTMwriter3D<T,OUT_T,W>::closeVTM(
const std::string& fullNamePVD)
373 std::ofstream fout(fullNamePVD, std::ios::app );
375 clout <<
"Error: could not open " << fullNamePVD << std::endl;
377 fout <<
"</vtkMultiBlockDataSet>\n";
378 fout <<
"</VTKFile>\n";
382template<
typename T,
typename OUT_T,
typename W>
383void SuperVTMwriter3D<T,OUT_T,W>::dataVTM(
int iC,
const std::string& fullNamePVD,
384 const std::string& namePiece)
386 std::ofstream fout(fullNamePVD, std::ios::app);
388 clout <<
"Error: could not open " << fullNamePVD << std::endl;
390 fout <<
"<Block index=\"" << iC <<
"\" >\n";
391 fout <<
"<DataSet index= \"0\" " <<
"file=\"" << namePiece <<
"\">\n"
393 fout <<
"</Block>\n";
397template<
typename T,
typename OUT_T,
typename W>
398void SuperVTMwriter3D<T,OUT_T,W>::dataPVDmaster(
int iT,
399 const std::string& fullNamePVDMaster,
400 const std::string& namePiece)
402 std::ofstream fout(fullNamePVDMaster, std::ios::in | std::ios::out | std::ios::ate);
404 fout.seekp(-25,std::ios::end);
406 fout <<
"<DataSet timestep=\"" << iT <<
"\" "
407 <<
"group=\"\" part=\"\" "
408 <<
"file=\"" << namePiece <<
"\"/>\n";
410 closePVD(fullNamePVDMaster);
413 clout <<
"Error: could not open " << fullNamePVDMaster << std::endl;
417template<
typename T,
typename OUT_T,
typename W>
418void SuperVTMwriter3D<T,OUT_T,W>::dataArray(
const std::string& fullName,
419 SuperF3D<T,W>& f,
int iC,
const Vector<int,3> extent1)
421 std::ofstream fout( fullName, std::ios::out | std::ios::app );
423 clout <<
"Error: could not open " << fullName << std::endl;
426 if constexpr (std::is_same_v<OUT_T, float>) {
427 fout <<
"<DataArray type=\"Float32\" Name=\"" << f.getName() <<
"\" NumberOfComponents=\"" << f.getTargetDim() <<
"\" ";
429 else if constexpr (std::is_same_v<OUT_T, double>) {
430 fout <<
"<DataArray type=\"Float64\" Name=\"" << f.getName() <<
"\" NumberOfComponents=\"" << f.getTargetDim() <<
"\" ";
432 if (_compress || _binary) {
433 fout <<
"format=\"binary\" encoding=\"base64\">\n";
439 int i[4] = {iC, 0, 0, 0};
440 W evaluated[f.getTargetDim()];
441 for (
int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
442 evaluated[iDim] = W();
445 size_t numberOfFloats = f.getTargetDim() * (extent1[0]+2*_overlap) * (extent1[1]+2*_overlap) * (extent1[2]+2*_overlap);
446 uint32_t binarySize =
static_cast<uint32_t
>( numberOfFloats*
sizeof(float) );
448 std::unique_ptr<float[]> streamFloat(
new float[numberOfFloats]);
451 for (i[3] = -_overlap; i[3] < extent1[2]+_overlap; ++i[3]) {
452 for (i[2] = -_overlap; i[2] < extent1[1]+_overlap; ++i[2]) {
453 for (i[1] = -_overlap; i[1] < extent1[0]+_overlap; ++i[1]) {
455 for (
int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
456 streamFloat[itter] = float( evaluated[iDim] );
465 const unsigned char* charData =
reinterpret_cast<unsigned char*
>(streamFloat.get());
467 std::unique_ptr<unsigned char[]> comprData(
new unsigned char[ binarySize ]);
470 uLongf sizeCompr = compressBound(binarySize);
471 compress2( comprData.get(), &sizeCompr, charData, binarySize, -1);
474 Base64Encoder<uint32_t> prefixEncoder(fout, 4);
475 uint32_t prefix[4] = {1,binarySize,binarySize,
static_cast<uint32_t
>(sizeCompr)};
476 prefixEncoder.encode(prefix, 4);
479 Base64Encoder<unsigned char> dataEncoder( fout, sizeCompr );
480 dataEncoder.encode(comprData.get(), sizeCompr);
484 Base64Encoder<uint32_t> prefixEncoder(fout, 1);
485 prefixEncoder.encode(&binarySize, 1);
487 Base64Encoder<float> dataEncoder(fout, numberOfFloats);
488 dataEncoder.encode(streamFloat.get(),numberOfFloats);
491 for (
size_t iOut = 0; iOut < numberOfFloats; ++iOut ) {
492 fout << streamFloat[iOut] <<
" ";
497 std::ofstream ffout( fullName, std::ios::out | std::ios::app );
499 clout <<
"Error: could not open " << fullName << std::endl;
501 ffout <<
"\n</DataArray>\n";
505template<
typename T,
typename OUT_T,
typename W>
506void SuperVTMwriter3D<T,OUT_T,W>::closePiece(
const std::string& fullNamePiece)
508 std::ofstream fout(fullNamePiece, std::ios::app );
510 clout <<
"Error: could not open " << fullNamePiece << std::endl;
512 fout <<
"</PointData>\n";
513 fout <<
"</Piece>\n";
A cuboid geometry represents a voxel mesh.
Cuboid3D< T > & get(int iC)
Read and write access to a single cuboid.
int getNc() const
Returns the number of cuboids in the structure.
Cuboid3D< T > getMotherCuboid()
Returns the smallest cuboid that includes all cuboids of the structure.
void getPhysR(T physR[3], const int &iCglob, const int &iX, const int &iY, const int &iZ) const
Returns the physical position to the given lattice position respecting periodicity for the overlap no...
std::string & getName()
read and write access to name
Base class for all LoadBalancer.
represents all functors that operate on a SuperStructure<T,3> in general
SuperStructure< T, 3 > & getSuperStructure()
CuboidGeometry< T, D > & getCuboidGeometry()
Read and write access to cuboid geometry.
virtual void communicate()
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
SuperVTMwriter3D writes any SuperF3D to vtk-based output files.
std::string getName() const
getter for _name
void write(int iT=0)
writes functors stored in pointerVec every process writes a vti file with data for each of its cuboid...
void createMasterFile()
have to be called before calling write(int iT=0), since it creates
void writeGlobalVTI(int iT, int iC)
writes the vti file for cuboid iC at timestep iT
void clearAddedFunctors()
to clear stored functors, not yet used due to lack of necessity
SuperVTMwriter3D(const std::string &name, int overlap=1, bool binary=true, bool compress=true)
Construct writer for functor output.
void addFunctor(SuperF3D< T, W > &f)
put functor to _pointerVec to simplify writing process of several functors
void writeVTI(int iT, int iCloc)
writes the vti file for cuboid iCloc at timestep iT
void writePVD(int iT)
writes only the linking pvd file for timestep iT, blocks must be written separately (e....
std::string getVtkOutDir() const
int getRank() const
Returns the process ID.
The description of a vector of 3D cuboid – header file.
These functions help you to create file names.
Wrapper functions that simplify the use of MPI.
Directories & directories()
Top level namespace for all of OpenLB.
std::string createFileName(std::string name)
for .pvd masterFile
typename util::BaseTypeHelper< T >::type BaseType
Definition of singletons: global, publicly available information.
A method to write vtk data for cuboid geometries (only for uniform grids) – header file.