29#ifndef SUPER_VTM_WRITER_2D_HH
30#define SUPER_VTM_WRITER_2D_HH
48template<
typename T,
typename OUT_T,
typename W>
50 : clout( std::cout,
"SuperVTMwriter2D" ), _createFile(false), _name(name), _overlap(overlap), _binary(binary)
52 static_assert(std::is_same_v<OUT_T, float> || std::is_same_v<OUT_T, double>,
53 "OUT_T must be either float or double");
56template<
typename T,
typename OUT_T,
typename W>
60 std::vector<int> nMinCuboid { load.
glob(iCloc), 0, 0 };
61 std::vector<int> nMaxCuboid { load.
glob(iCloc), cGeometry.
get(load.
glob(iCloc)).getNx() ,cGeometry.
get(load.
glob(iCloc)).getNy() };
63 std::vector<T> rMinCuboid = cGeometry.
getPhysR(nMinCuboid);
64 std::vector<T> rMaxCuboid = cGeometry.
getPhysR(nMaxCuboid);
66 std::vector<int> nMin {0,0,0};
67 std::vector<int> nMax {0,0,0};
73 for (
int i=0; i<2; i++) {
74 if (rMinCuboid[i] > rMin[i]) {
75 nMinOut[i] = nMinCuboid[i+1];
78 std::vector<T> rMinC {0, 0.};
79 for (
int j=0; j<2; j++) {
80 rMinC[j] = (rMinCuboid[j] + rMaxCuboid[j])/2;
83 std::vector<int> nMinC {0,0,0};
85 nMinOut[i] = nMinC[i+1];
88 if (rMaxCuboid[i] < rMax[i]) {
89 nMaxOut[i] = nMaxCuboid[i+1];
92 std::vector<T> rMaxC {0, 0.};
93 for (
int j=0; j<2; j++) {
94 rMaxC[j] = (rMinCuboid[j] + rMaxCuboid[j])/2;
97 std::vector<int> nMaxC {0,0,0};
99 nMaxOut[i] = nMaxC[i+1];
104template<
typename T,
typename OUT_T,
typename W>
108#ifdef PARALLEL_MODE_MPI
113 if ( _pointerVec.empty() ) {
114 clout <<
"Error: Did you add a Functor ?";
119 f->getSuperStructure().communicate();
125 auto it_begin = _pointerVec.cbegin();
126 if (it_begin == _pointerVec.end()) {
127 throw std::runtime_error(
"No functor to write");
129 const auto& cGeometry = (**it_begin).getSuperStructure().getCuboidDecomposition();
131 LoadBalancer<T>& load = (**it_begin).getSuperStructure().getLoadBalancer();
137 dataPVDmaster( iT, pathPVD,
"data/" +
createFileName( _name, iT ) +
".vtm" );
141 preambleVTM(pathVTM);
142 for (
int iC = 0; iC < cGeometry.
size(); iC++) {
148 int originLatticeR[3] = {int()};
149 for (
int iCloc = 0; iCloc < load.
size(); iCloc++) {
152 extremes(nMin, nMax, cGeometry, load, rMin, rMax, iCloc);
162 originLatticeR[0] = load.
glob(iCloc);
163 T originPhysR[2] = {T()};
164 cGeometry.
getPhysR(originPhysR,originLatticeR);
166 preambleVTI(fullNameVTI, nMin[0]-_overlap,nMin[1]-_overlap, nMax[0]+_overlap-1, nMax[1]+_overlap-1, originPhysR[0],originPhysR[1], delta);
167 for (
auto it : _pointerVec) {
169 dataArrayBinary(fullNameVTI, (*it), load.
glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
172 dataArray(fullNameVTI, (*it), load.
glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
175 closePiece(fullNameVTI);
176 closeVTI(fullNameVTI);
182template<
typename T,
typename OUT_T,
typename W>
186#ifdef PARALLEL_MODE_MPI
191 if ( _pointerVec.empty() ) {
192 clout <<
"Error: Did you add a Functor ?";
197 f->getSuperStructure().communicate();
203 auto it_begin = _pointerVec.cbegin();
204 if (it_begin == _pointerVec.end()) {
205 throw std::runtime_error(
"No functor to write");
207 const auto& cGeometry = (**it_begin).getSuperStructure().getCuboidDecomposition();
209 LoadBalancer<T>& load = (**it_begin).getSuperStructure().getLoadBalancer();
215 dataPVDmaster( iT, pathPVD,
"data/" +
createFileName( _name, iT ) +
".vtm" );
219 preambleVTM(pathVTM);
220 for (
int iC = 0; iC < cGeometry.
size(); iC++) {
227 for (
int iCloc = 0; iCloc < load.
size(); iCloc++) {
228 int nx = cGeometry.
get(load.
glob(iCloc)).getNx();
229 int ny = cGeometry.
get(load.
glob(iCloc)).getNy();
238 originLatticeR[0] = load.
glob(iCloc);
239 auto originPhysR = cGeometry.
getPhysR(originLatticeR);
241 preambleVTI(fullNameVTI, -_overlap,-_overlap, nx+_overlap-1, ny+_overlap-1, originPhysR[0],originPhysR[1], delta);
242 for (
auto it : _pointerVec) {
244 dataArrayBinary(fullNameVTI, (*it), load.
glob(iCloc), 0,nx,0,ny);
247 dataArray(fullNameVTI, (*it), load.
glob(iCloc), 0,nx,0,ny);
250 closePiece(fullNameVTI);
251 closeVTI(fullNameVTI);
256template<
typename T,
typename OUT_T,
typename W>
266#ifdef PARALLEL_MODE_MPI
277 preambleVTM(pathVTM);
278 for (
int iC = 0; iC < cGeometry.
size(); iC++) {
281 dataVTM( iC, pathVTM, nameVTI );
286 for (
int iCloc = 0; iCloc < load.
size(); iCloc++) {
289 extremes(nMin, nMax, cGeometry, load, rMin, rMax, iCloc);
295 int const originLatticeR[3] = {load.
glob(iCloc),0,0};
296 T originPhysR[2] = {T()};
297 cGeometry.
getPhysR(originPhysR,originLatticeR);
299 preambleVTI(fullNameVTI, nMin[0]-_overlap,nMin[1]-_overlap, nMax[0]+_overlap-1, nMax[1]+_overlap-1, originPhysR[0],originPhysR[1], delta);
301 dataArrayBinary(fullNameVTI, f, load.
glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
304 dataArray(fullNameVTI, f, load.
glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
306 closePiece(fullNameVTI);
307 closeVTI(fullNameVTI);
311template<
typename T,
typename OUT_T,
typename W>
321#ifdef PARALLEL_MODE_MPI
332 preambleVTM(pathVTM);
333 for (
int iC = 0; iC < cGeometry.
size(); iC++) {
336 dataVTM( iC, pathVTM, nameVTI );
341 for (
int iCloc = 0; iCloc < load.
size(); iCloc++) {
342 int nx = cGeometry.
get(load.
glob(iCloc)).getNx();
343 int ny = cGeometry.
get(load.
glob(iCloc)).getNy();
350 auto originPhysR = cGeometry.
getPhysR(originLatticeR);
352 preambleVTI(fullNameVTI, -_overlap,-_overlap, nx+_overlap-1, ny+_overlap-1, originPhysR[0],originPhysR[1], delta);
354 dataArrayBinary(fullNameVTI, f, load.
glob(iCloc), 0,nx,0,ny);
357 dataArray(fullNameVTI, f, load.
glob(iCloc), 0,nx,0,ny);
359 closePiece(fullNameVTI);
360 closeVTI(fullNameVTI);
364template<
typename T,
typename OUT_T,
typename W>
367 write(*ptr_f, rMin, rMax, iT);
370template<
typename T,
typename OUT_T,
typename W>
376template<
typename T,
typename OUT_T,
typename W>
380#ifdef PARALLEL_MODE_MPI
386 preamblePVD(fullNamePVDmaster);
387 closePVD(fullNamePVDmaster);
392template<
typename T,
typename OUT_T,
typename W>
395 _pointerVec.push_back(&f);
398template<
typename T,
typename OUT_T,
typename W>
402 _pointerVec.push_back(&f);
405template<
typename T,
typename OUT_T,
typename W>
411template<
typename T,
typename OUT_T,
typename W>
421template<
typename T,
typename OUT_T,
typename W>
423 int x0,
int y0,
int x1,
int y1, T originX, T originY, T delta)
426 const BaseType<T> d_origin[2] = {originX, originY};
427 std::ofstream fout(fullName, std::ios::trunc);
429 clout <<
"Error: could not open " << fullName << std::endl;
431 fout <<
"<?xml version=\"1.0\"?>\n";
432 fout <<
"<VTKFile type=\"ImageData\" version=\"0.1\" "
433 <<
"byte_order=\"LittleEndian\">\n";
434 fout <<
"<ImageData WholeExtent=\""
435 << x0 <<
" "<< x1 <<
" "
436 << y0 <<
" "<< y1 <<
" "
438 <<
"\" Origin=\"" << d_origin[0] <<
" " << d_origin[1] <<
" " <<
"0"
439 <<
"\" Spacing=\"" << d_delta <<
" " << d_delta <<
" " << d_delta <<
"\">\n";
440 fout <<
"<Piece Extent=\""
441 << x0 <<
" "<< x1 <<
" "
442 << y0 <<
" "<< y1 <<
" "
443 << 0 <<
" "<< 0 <<
"\">\n";
444 fout <<
"<PointData>\n";
448template<
typename T,
typename OUT_T,
typename W>
449void SuperVTMwriter2D<T,OUT_T,W>::closeVTI(
const std::string& fullNamePiece)
451 std::ofstream fout(fullNamePiece, std::ios::app );
453 clout <<
"Error: could not open " << fullNamePiece << std::endl;
455 fout <<
"</ImageData>\n";
456 fout <<
"</VTKFile>\n";
460template<
typename T,
typename OUT_T,
typename W>
461void SuperVTMwriter2D<T,OUT_T,W>::preamblePVD(
const std::string& fullNamePVD)
463 std::ofstream fout(fullNamePVD, std::ios::trunc);
465 clout <<
"Error: could not open " << fullNamePVD << std::endl;
467 fout <<
"<?xml version=\"1.0\"?>\n";
468 fout <<
"<VTKFile type=\"Collection\" version=\"0.1\" "
469 <<
"byte_order=\"LittleEndian\">\n"
474template<
typename T,
typename OUT_T,
typename W>
475void SuperVTMwriter2D<T,OUT_T,W>::closePVD(
const std::string& fullNamePVD)
477 std::ofstream fout(fullNamePVD, std::ios::app );
479 clout <<
"Error: could not open " << fullNamePVD << std::endl;
481 fout <<
"</Collection>\n";
482 fout <<
"</VTKFile>\n";
486template<
typename T,
typename OUT_T,
typename W>
487void SuperVTMwriter2D<T,OUT_T,W>::preambleVTM(
const std::string& fullNamePVD)
489 std::ofstream fout(fullNamePVD, std::ios::trunc);
491 clout <<
"Error: could not open " << fullNamePVD << std::endl;
493 fout <<
"<?xml version=\"1.0\"?>\n";
494 fout <<
"<VTKFile type=\"vtkMultiBlockDataSet\" version=\"1.0\" "
495 <<
"byte_order=\"LittleEndian\">\n"
496 <<
"<vtkMultiBlockDataSet>\n" ;
500template<
typename T,
typename OUT_T,
typename W>
501void SuperVTMwriter2D<T,OUT_T,W>::closeVTM(
const std::string& fullNamePVD)
503 std::ofstream fout(fullNamePVD, std::ios::app );
505 clout <<
"Error: could not open " << fullNamePVD << std::endl;
507 fout <<
"</vtkMultiBlockDataSet>\n";
508 fout <<
"</VTKFile>\n";
512template<
typename T,
typename OUT_T,
typename W>
513void SuperVTMwriter2D<T,OUT_T,W>::dataVTM(
int iC,
const std::string& fullNamePVD,
514 const std::string& namePiece)
516 std::ofstream fout(fullNamePVD, std::ios::app);
518 clout <<
"Error: could not open " << fullNamePVD << std::endl;
520 fout <<
"<Block index=\"" << iC <<
"\" >\n";
521 fout <<
"<DataSet index= \"0\" " <<
"file=\"" << namePiece <<
"\">\n"
523 fout <<
"</Block>\n";
527template<
typename T,
typename OUT_T,
typename W>
528void SuperVTMwriter2D<T,OUT_T,W>::dataPVDmaster(
int iT,
529 const std::string& fullNamePVDMaster,
530 const std::string& namePiece)
532 std::ofstream fout(fullNamePVDMaster, std::ios::in | std::ios::out | std::ios::ate);
534 fout.seekp(-25,std::ios::end);
536 fout <<
"<DataSet timestep=\"" << iT <<
"\" "
537 <<
"group=\"\" part=\"\" "
538 <<
"file=\"" << namePiece <<
"\"/>\n";
543 clout <<
"Error: could not open " << fullNamePVDMaster << std::endl;
547template<
typename T,
typename OUT_T,
typename W>
548void SuperVTMwriter2D<T,OUT_T,W>::dataArray(
const std::string& fullName,
549 SuperF2D<T,W>& f,
int iC,
int nxMin,
int nxMax,
int nyMin,
int nyMax)
552 std::ofstream fout( fullName, std::ios::out | std::ios::app );
554 clout <<
"Error: could not open " << fullName << std::endl;
557 fout <<
"<DataArray " ;
558 if constexpr (std::is_same_v<OUT_T, float>) {
559 fout <<
"type=\"Float32\" Name=\"" << f.getName() <<
"\" "
560 <<
"format=\"ascii\" "
561 <<
"NumberOfComponents=\"" << f.getTargetDim() <<
"\">\n";
563 else if constexpr (std::is_same_v<OUT_T, double>) {
564 fout <<
"type=\"Float64\" Name=\"" << f.getName() <<
"\" "
565 <<
"format=\"ascii\" "
566 <<
"NumberOfComponents=\"" << f.getTargetDim() <<
"\">\n";
569 int i[3] = {iC, 0, 0};
570 W evaluated[f.getTargetDim()];
571 for (
int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
572 evaluated[iDim] = W();
576 std::vector<int> tmpVec( 3,
int(0) );
577 for (i[2]=nyMin-_overlap; i[2] < nyMax+_overlap; ++i[2]) {
578 for (i[1]=nxMin-_overlap; i[1] < nxMax+_overlap; ++i[1]) {
580 for (
int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
582 fout << evaluated[iDim] <<
" ";
586 fout <<
"</DataArray>\n";
590template<
typename T,
typename OUT_T,
typename W>
591void SuperVTMwriter2D<T,OUT_T,W>::dataArrayBinary(
const std::string& fullName,
592 SuperF2D<T,W>& f,
int iC,
int nxMin,
int nxMax,
int nyMin,
int nyMax)
594 std::ofstream fout( fullName, std::ios::out | std::ios::app );
596 clout <<
"Error: could not open " << fullName << std::endl;
599 fout <<
"<DataArray ";
600 if constexpr (std::is_same_v<OUT_T, float>) {
601 fout <<
"type=\"Float32\" Name=\"" << f.getName() <<
"\" "
602 <<
"format=\"binary\" encoding=\"base64\" "
603 <<
"NumberOfComponents=\"" << f.getTargetDim() <<
"\">\n";
605 else if constexpr (std::is_same_v<OUT_T, double>) {
606 fout <<
"type=\"Float64\" Name=\"" << f.getName() <<
"\" "
607 <<
"format=\"binary\" encoding=\"base64\" "
608 <<
"NumberOfComponents=\"" << f.getTargetDim() <<
"\">\n";
612 std::ofstream ofstr( fullName, std::ios::out | std::ios::app | std::ios::binary );
614 clout <<
"Error: could not open " << fullName << std::endl;
617 size_t fullSize = f.getTargetDim() * (nxMax-nxMin+2*_overlap) * (nyMax-nyMin+2*_overlap);
618 size_t binarySize = size_t( fullSize*
sizeof(OUT_T) );
620 Base64Encoder<unsigned int> sizeEncoder(ofstr, 1);
621 unsigned int uintBinarySize = (
unsigned int)binarySize;
622 sizeEncoder.encode(&uintBinarySize, 1);
624 Base64Encoder<OUT_T>* dataEncoder =
new Base64Encoder<OUT_T>( ofstr, fullSize );
626 int i[3] = {iC, 0, 0};
627 W evaluated[f.getTargetDim()];
628 for (
int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
629 evaluated[iDim] = W();
632 std::unique_ptr<OUT_T[]> bufferFloat(
new OUT_T[fullSize]);
633 for (i[2] = nyMin-_overlap; i[2] < nyMax+_overlap; ++i[2]) {
634 for (i[1] = nxMin-_overlap; i[1] < nxMax+_overlap; ++i[1]) {
636 for (
int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
637 bufferFloat[ itter ] = OUT_T( evaluated[iDim] );
642 dataEncoder->encode( &bufferFloat[0], fullSize );
645 std::ofstream ffout( fullName, std::ios::out | std::ios::app );
647 clout <<
"Error: could not open " << fullName << std::endl;
649 ffout <<
"\n</DataArray>\n";
654template<
typename T,
typename OUT_T,
typename W>
655void SuperVTMwriter2D<T,OUT_T,W>::closePiece(
const std::string& fullNamePiece)
657 std::ofstream fout(fullNamePiece, std::ios::app );
659 clout <<
"Error: could not open " << fullNamePiece << std::endl;
661 fout <<
"</PointData>\n";
662 fout <<
"</Piece>\n";
int size() const
Returns number of cuboids in decomposition.
Vector< T, D > getPhysR(LatticeR< D+1 > latticeR) const
Returns physical position of lattice position.
const Cuboid< T, D > & get(int iC) const
Read access to a single cuboid.
const Cuboid< T, D > & getMotherCuboid() const
Returns the smallest cuboid that includes all cuboids of the structure.
std::optional< LatticeR< D+1 > > getLatticeR(Vector< T, D > physR) const
Returns lattice position for given physical position if it exists.
std::string & getName()
read and write access to name
Base class for all LoadBalancer.
represents all functors that operate on a SuperStructure<T,2> in general
SuperStructure< T, 2 > & getSuperStructure()
virtual void communicate()
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
CuboidDecomposition< T, D > & getCuboidDecomposition()
Read and write access to cuboid geometry.
SuperVTMwriter2D writes any SuperF2D to vtk-based output files.
void createMasterFile()
have to be called before calling write(int iT=0), since it creates
void write(int iT=0)
writes functors stored in pointerVec every thread writes a vti file with data from his cuboids the vt...
SuperVTMwriter2D(std::string name, int overlap=1, bool binary=true)
void clearAddedFunctors()
to clear stored functors, not yet used due to lack of necessity
std::string getName() const
getter for _name
void addFunctor(SuperF2D< T, W > &f)
put functor to _pointerVec to simplify writing process of several functors
std::string getVtkOutDir() const
int getRank() const
Returns the process ID.
These functions help you to create file names.
Wrapper functions that simplify the use of MPI.
void closePVD(const std::string &fullNamePVD, MembraneParticleSystem3D< T, DESCRIPTOR > &sMembrane)
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.