OpenLB 1.8.1
Loading...
Searching...
No Matches
superVtmWriter2D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2016 Albert Mink, Mathias J. Krause
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
29#ifndef SUPER_VTM_WRITER_2D_HH
30#define SUPER_VTM_WRITER_2D_HH
31
32#include <fstream>
33#include <iostream>
34#include <iomanip>
35#include <string>
36#include "core/singleton.h"
40#include "io/base64.h"
41#include "io/fileName.h"
42#include "io/superVtmWriter2D.h"
43
44
45namespace olb {
46
47
48template<typename T, typename OUT_T, typename W>
49SuperVTMwriter2D<T,OUT_T,W>::SuperVTMwriter2D( std::string name, int overlap, bool binary )
50 : clout( std::cout,"SuperVTMwriter2D" ), _createFile(false), _name(name), _overlap(overlap), _binary(binary)
51{
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");
54}
55
56template<typename T, typename OUT_T, typename W>
57void SuperVTMwriter2D<T,OUT_T,W>::extremes( int nMinOut[], int nMaxOut[],
58 CuboidDecomposition2D<T> const& cGeometry, LoadBalancer<T>& load, std::vector<T> rMin, std::vector<T> rMax, int iCloc)
59{
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() };
62
63 std::vector<T> rMinCuboid = cGeometry.getPhysR(nMinCuboid);
64 std::vector<T> rMaxCuboid = cGeometry.getPhysR(nMaxCuboid);
65
66 std::vector<int> nMin {0,0,0};
67 std::vector<int> nMax {0,0,0};
68
69 cGeometry.getLatticeR(rMin, nMin);
70 cGeometry.getLatticeR(rMax, nMax);
71
72
73 for (int i=0; i<2; i++) {
74 if (rMinCuboid[i] > rMin[i]) {
75 nMinOut[i] = nMinCuboid[i+1];
76 }
77 else {
78 std::vector<T> rMinC {0, 0.};
79 for (int j=0; j<2; j++) {
80 rMinC[j] = (rMinCuboid[j] + rMaxCuboid[j])/2;
81 }
82 rMinC[i] = rMin[i];
83 std::vector<int> nMinC {0,0,0};
84 cGeometry.getLatticeR(rMinC, nMinC);
85 nMinOut[i] = nMinC[i+1];
86 }
87
88 if (rMaxCuboid[i] < rMax[i]) {
89 nMaxOut[i] = nMaxCuboid[i+1];
90 }
91 else {
92 std::vector<T> rMaxC {0, 0.};
93 for (int j=0; j<2; j++) {
94 rMaxC[j] = (rMinCuboid[j] + rMaxCuboid[j])/2;
95 }
96 rMaxC[i] = rMax[i];
97 std::vector<int> nMaxC {0,0,0};
98 cGeometry.getLatticeR(rMaxC, nMaxC);
99 nMaxOut[i] = nMaxC[i+1];
100 }
101 }
102}
103
104template<typename T, typename OUT_T, typename W>
105void SuperVTMwriter2D<T,OUT_T,W>::write(std::vector<T> rMin, std::vector<T> rMax, int iT)
106{
107 int rank = 0;
108#ifdef PARALLEL_MODE_MPI
109 rank = singleton::mpi().getRank();
110#endif
111
112 // !!!!!!!!!!! check whether _pointerVec is empty
113 if ( _pointerVec.empty() ) {
114 clout << "Error: Did you add a Functor ?";
115 }
116 else {
117 // no gaps between vti files (cuboids)
118 for (SuperF2D<T,W>* f : _pointerVec) {
119 f->getSuperStructure().communicate();
120 }
121
122 // to get first element _pointerVec
123 // problem if functors with different SuperStructure are stored
124 // since till now, there is only one origin
125 auto it_begin = _pointerVec.cbegin();
126 if (it_begin == _pointerVec.end()) {
127 throw std::runtime_error("No functor to write");
128 }
129 const auto& cGeometry = (**it_begin).getSuperStructure().getCuboidDecomposition();
130 // no gaps between vti files (cuboids)
131 LoadBalancer<T>& load = (**it_begin).getSuperStructure().getLoadBalancer();
132
133 // PVD, owns all
134 if ( rank == 0 ) {
135 std::string pathPVD = singleton::directories().getVtkOutDir()
136 + createFileName( _name ) + ".pvd";
137 dataPVDmaster( iT, pathPVD, "data/" + createFileName( _name, iT ) + ".vtm" );
138
139 std::string pathVTM = singleton::directories().getVtkOutDir()
140 + "data/" + createFileName( _name, iT ) + ".vtm";
141 preambleVTM(pathVTM);
142 for (int iC = 0; iC < cGeometry.size(); iC++) {
143 dataVTM( iC, pathVTM, createFileName( _name, iT, iC) + ".vti" );
144 }
145 closeVTM(pathVTM);
146 }
147 // VTI, each process writes his cuboids
148 int originLatticeR[3] = {int()};
149 for (int iCloc = 0; iCloc < load.size(); iCloc++) {
150 int nMin[] {0,0};
151 int nMax[] {0,0};
152 extremes(nMin, nMax, cGeometry, load, rMin, rMax, iCloc);
153
154 // to be changed into the following line once local refinement has been implemented
155 // double deltaX = cGeometry.get(load.glob(iCloc)).getDeltaR();
156 T delta = cGeometry.getMotherCuboid().getDeltaR();
157
158 std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/"
159 + createFileName( _name, iT, load.glob(iCloc) ) + ".vti";
160
161 // get dimension/extent for each cuboid
162 originLatticeR[0] = load.glob(iCloc);
163 T originPhysR[2] = {T()};
164 cGeometry.getPhysR(originPhysR,originLatticeR);
165
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) {
168 if (_binary) {
169 dataArrayBinary(fullNameVTI, (*it), load.glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
170 }
171 else {
172 dataArray(fullNameVTI, (*it), load.glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
173 }
174 }
175 closePiece(fullNameVTI);
176 closeVTI(fullNameVTI);
177 }
178 }
179}
180
181
182template<typename T, typename OUT_T, typename W>
184{
185 int rank = 0;
186#ifdef PARALLEL_MODE_MPI
187 rank = singleton::mpi().getRank();
188#endif
189
190 // !!!!!!!!!!! check whether _pointerVec is empty
191 if ( _pointerVec.empty() ) {
192 clout << "Error: Did you add a Functor ?";
193 }
194 else {
195 // no gaps between vti files (cuboids)
196 for (SuperF2D<T,W>* f : _pointerVec) {
197 f->getSuperStructure().communicate();
198 }
199
200 // to get first element _pointerVec
201 // problem if functors with different SuperStructure are stored
202 // since till now, there is only one origin
203 auto it_begin = _pointerVec.cbegin();
204 if (it_begin == _pointerVec.end()) {
205 throw std::runtime_error("No functor to write");
206 }
207 const auto& cGeometry = (**it_begin).getSuperStructure().getCuboidDecomposition();
208 // no gaps between vti files (cuboids)
209 LoadBalancer<T>& load = (**it_begin).getSuperStructure().getLoadBalancer();
210
211 // PVD, owns all
212 if ( rank == 0 ) {
213 std::string pathPVD = singleton::directories().getVtkOutDir()
214 + createFileName( _name ) + ".pvd";
215 dataPVDmaster( iT, pathPVD, "data/" + createFileName( _name, iT ) + ".vtm" );
216
217 std::string pathVTM = singleton::directories().getVtkOutDir()
218 + "data/" + createFileName( _name, iT ) + ".vtm";
219 preambleVTM(pathVTM);
220 for (int iC = 0; iC < cGeometry.size(); iC++) {
221 dataVTM( iC, pathVTM, createFileName( _name, iT, iC) + ".vti" );
222 }
223 closeVTM(pathVTM);
224 }
225 // VTI, each process writes his cuboids
226 LatticeR<3> originLatticeR;
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();
230 // to be changed into the following line once local refinement has been implemented
231 // double deltaX = cGeometry.get(load.glob(iCloc)).getDeltaR();
232 T delta = cGeometry.getMotherCuboid().getDeltaR();
233
234 std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/"
235 + createFileName( _name, iT, load.glob(iCloc) ) + ".vti";
236
237 // get dimension/extent for each cuboid
238 originLatticeR[0] = load.glob(iCloc);
239 auto originPhysR = cGeometry.getPhysR(originLatticeR);
240
241 preambleVTI(fullNameVTI, -_overlap,-_overlap, nx+_overlap-1, ny+_overlap-1, originPhysR[0],originPhysR[1], delta);
242 for (auto it : _pointerVec) {
243 if (_binary) {
244 dataArrayBinary(fullNameVTI, (*it), load.glob(iCloc), 0,nx,0,ny);
245 }
246 else {
247 dataArray(fullNameVTI, (*it), load.glob(iCloc), 0,nx,0,ny);
248 }
249 }
250 closePiece(fullNameVTI);
251 closeVTI(fullNameVTI);
252 }
253 }
254}
255
256template<typename T, typename OUT_T, typename W>
257void SuperVTMwriter2D<T,OUT_T, W>::write(SuperF2D<T,W>& f, std::vector<T> rMin, std::vector<T> rMax, int iT)
258{
259 const auto& cGeometry = f.getSuperStructure().getCuboidDecomposition();
261 // no gaps between vti files (cuboids)
263 T delta = cGeometry.getMotherCuboid().getDeltaR();
264
265 int rank = 0;
266#ifdef PARALLEL_MODE_MPI
267 rank = singleton::mpi().getRank();
268#endif
269
270 // write a pvd file, which links all vti files
271 // each vti file is written by one thread, which may own severals cuboids
272 if ( rank == 0 ) {
273 // master only
274 std::string pathVTM = singleton::directories().getVtkOutDir()
275 + createFileName( f.getName(), iT ) + ".vtm";
276
277 preambleVTM(pathVTM);
278 for (int iC = 0; iC < cGeometry.size(); iC++) {
279 std::string nameVTI = "data/" + createFileName( f.getName(), iT, iC) + ".vti";
280 // puts name of .vti piece to a .pvd file [fullNamePVD]
281 dataVTM( iC, pathVTM, nameVTI );
282 }
283 closeVTM(pathVTM);
284 } // master only
285
286 for (int iCloc = 0; iCloc < load.size(); iCloc++) {
287 int nMin[] {0,0};
288 int nMax[] {0,0};
289 extremes(nMin, nMax, cGeometry, load, rMin, rMax, iCloc);
290
291 std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/"
292 + createFileName( f.getName(), iT, load.glob(iCloc) ) + ".vti";
293
294 // get dimension/extent for each cuboid
295 int const originLatticeR[3] = {load.glob(iCloc),0,0};
296 T originPhysR[2] = {T()};
297 cGeometry.getPhysR(originPhysR,originLatticeR);
298
299 preambleVTI(fullNameVTI, nMin[0]-_overlap,nMin[1]-_overlap, nMax[0]+_overlap-1, nMax[1]+_overlap-1, originPhysR[0],originPhysR[1], delta);
300 if (_binary) {
301 dataArrayBinary(fullNameVTI, f, load.glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
302 }
303 else {
304 dataArray(fullNameVTI, f, load.glob(iCloc), nMin[0],nMax[0],nMin[1],nMax[1]);
305 }
306 closePiece(fullNameVTI);
307 closeVTI(fullNameVTI);
308 } // cuboid
309}
310
311template<typename T, typename OUT_T, typename W>
313{
314 const auto& cGeometry = f.getSuperStructure().getCuboidDecomposition();
316 // no gaps between vti files (cuboids)
318 T delta = cGeometry.getMotherCuboid().getDeltaR();
319
320 int rank = 0;
321#ifdef PARALLEL_MODE_MPI
322 rank = singleton::mpi().getRank();
323#endif
324
325 // write a pvd file, which links all vti files
326 // each vti file is written by one thread, which may own severals cuboids
327 if ( rank == 0 ) {
328 // master only
329 std::string pathVTM = singleton::directories().getVtkOutDir()
330 + createFileName( f.getName(), iT ) + ".vtm";
331
332 preambleVTM(pathVTM);
333 for (int iC = 0; iC < cGeometry.size(); iC++) {
334 std::string nameVTI = "data/" + createFileName( f.getName(), iT, iC) + ".vti";
335 // puts name of .vti piece to a .pvd file [fullNamePVD]
336 dataVTM( iC, pathVTM, nameVTI );
337 }
338 closeVTM(pathVTM);
339 } // master only
340
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();
344
345 std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/"
346 + createFileName( f.getName(), iT, load.glob(iCloc) ) + ".vti";
347
348 // get dimension/extent for each cuboid
349 LatticeR<3> originLatticeR = {load.glob(iCloc),0,0};
350 auto originPhysR = cGeometry.getPhysR(originLatticeR);
351
352 preambleVTI(fullNameVTI, -_overlap,-_overlap, nx+_overlap-1, ny+_overlap-1, originPhysR[0],originPhysR[1], delta);
353 if (_binary) {
354 dataArrayBinary(fullNameVTI, f, load.glob(iCloc), 0,nx,0,ny);
355 }
356 else {
357 dataArray(fullNameVTI, f, load.glob(iCloc), 0,nx,0,ny);
358 }
359 closePiece(fullNameVTI);
360 closeVTI(fullNameVTI);
361 } // cuboid
362}
363
364template<typename T, typename OUT_T, typename W>
365void SuperVTMwriter2D<T,OUT_T,W>::write(std::shared_ptr<SuperF2D<T,W>> ptr_f, std::vector<T> rMin, std::vector<T> rMax, int iT)
366{
367 write(*ptr_f, rMin, rMax, iT);
368}
369
370template<typename T, typename OUT_T, typename W>
371void SuperVTMwriter2D<T,OUT_T,W>::write(std::shared_ptr<SuperF2D<T,W>> ptr_f, int iT)
372{
373 write(*ptr_f, iT);
374}
375
376template<typename T, typename OUT_T, typename W>
378{
379 int rank = 0;
380#ifdef PARALLEL_MODE_MPI
381 rank = singleton::mpi().getRank();
382#endif
383 if ( rank == 0 ) {
384 std::string fullNamePVDmaster = singleton::directories().getVtkOutDir()
385 + createFileName( _name ) + ".pvd";
386 preamblePVD(fullNamePVDmaster);
387 closePVD(fullNamePVDmaster);
388 _createFile = true;
389 }
390}
391
392template<typename T, typename OUT_T, typename W>
394{
395 _pointerVec.push_back(&f);
396}
397
398template<typename T, typename OUT_T, typename W>
399void SuperVTMwriter2D<T,OUT_T,W>::addFunctor(SuperF2D<T,W>& f, const std::string& functorName)
400{
401 f.getName() = functorName;
402 _pointerVec.push_back(&f);
403}
404
405template<typename T, typename OUT_T, typename W>
407{
408 _pointerVec.clear();
409}
410
411template<typename T, typename OUT_T, typename W>
413{
414 return _name;
415}
416
417
418
419
421template<typename T, typename OUT_T, typename W>
422void SuperVTMwriter2D<T,OUT_T,W>::preambleVTI (const std::string& fullName,
423 int x0, int y0, int x1, int y1, T originX, T originY, T delta)
424{
425 const BaseType<T> d_delta = delta;
426 const BaseType<T> d_origin[2] = {originX, originY};
427 std::ofstream fout(fullName, std::ios::trunc);
428 if (!fout) {
429 clout << "Error: could not open " << fullName << std::endl;
430 }
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 <<" "
437 << 0 <<" "<< 0
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";
445 fout.close();
446}
447
448template<typename T, typename OUT_T, typename W>
449void SuperVTMwriter2D<T,OUT_T,W>::closeVTI(const std::string& fullNamePiece)
450{
451 std::ofstream fout(fullNamePiece, std::ios::app );
452 if (!fout) {
453 clout << "Error: could not open " << fullNamePiece << std::endl;
454 }
455 fout << "</ImageData>\n";
456 fout << "</VTKFile>\n";
457 fout.close();
458}
459
460template<typename T, typename OUT_T, typename W>
461void SuperVTMwriter2D<T,OUT_T,W>::preamblePVD(const std::string& fullNamePVD)
462{
463 std::ofstream fout(fullNamePVD, std::ios::trunc);
464 if (!fout) {
465 clout << "Error: could not open " << fullNamePVD << std::endl;
466 }
467 fout << "<?xml version=\"1.0\"?>\n";
468 fout << "<VTKFile type=\"Collection\" version=\"0.1\" "
469 << "byte_order=\"LittleEndian\">\n"
470 << "<Collection>\n";
471 fout.close();
472}
473
474template<typename T, typename OUT_T, typename W>
475void SuperVTMwriter2D<T,OUT_T,W>::closePVD(const std::string& fullNamePVD)
476{
477 std::ofstream fout(fullNamePVD, std::ios::app );
478 if (!fout) {
479 clout << "Error: could not open " << fullNamePVD << std::endl;
480 }
481 fout << "</Collection>\n";
482 fout << "</VTKFile>\n";
483 fout.close();
484}
485
486template<typename T, typename OUT_T, typename W>
487void SuperVTMwriter2D<T,OUT_T,W>::preambleVTM(const std::string& fullNamePVD)
488{
489 std::ofstream fout(fullNamePVD, std::ios::trunc);
490 if (!fout) {
491 clout << "Error: could not open " << fullNamePVD << std::endl;
492 }
493 fout << "<?xml version=\"1.0\"?>\n";
494 fout << "<VTKFile type=\"vtkMultiBlockDataSet\" version=\"1.0\" "
495 << "byte_order=\"LittleEndian\">\n"
496 << "<vtkMultiBlockDataSet>\n" ;
497 fout.close();
498}
499
500template<typename T, typename OUT_T, typename W>
501void SuperVTMwriter2D<T,OUT_T,W>::closeVTM(const std::string& fullNamePVD)
502{
503 std::ofstream fout(fullNamePVD, std::ios::app );
504 if (!fout) {
505 clout << "Error: could not open " << fullNamePVD << std::endl;
506 }
507 fout << "</vtkMultiBlockDataSet>\n";
508 fout << "</VTKFile>\n";
509 fout.close();
510}
511
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)
515{
516 std::ofstream fout(fullNamePVD, std::ios::app);
517 if (!fout) {
518 clout << "Error: could not open " << fullNamePVD << std::endl;
519 }
520 fout << "<Block index=\"" << iC << "\" >\n";
521 fout << "<DataSet index= \"0\" " << "file=\"" << namePiece << "\">\n"
522 << "</DataSet>\n";
523 fout << "</Block>\n";
524 fout.close();
525}
526
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)
531{
532 std::ofstream fout(fullNamePVDMaster, std::ios::in | std::ios::out | std::ios::ate);
533 if (fout) {
534 fout.seekp(-25,std::ios::end); // jump -25 form the end of file to overwrite closePVD
535
536 fout << "<DataSet timestep=\"" << iT << "\" "
537 << "group=\"\" part=\"\" "
538 << "file=\"" << namePiece << "\"/>\n";
539 fout.close();
540 closePVD(fullNamePVDMaster);
541 }
542 else {
543 clout << "Error: could not open " << fullNamePVDMaster << std::endl;
544 }
545}
546
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)
550{
551 // std::cout << "DIOCANE" <<std::endl <<std::endl <<std::endl <<std::endl <<std::endl;
552 std::ofstream fout( fullName, std::ios::out | std::ios::app );
553 if (!fout) {
554 clout << "Error: could not open " << fullName << std::endl;
555 }
556
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";
562 }
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";
567 }
568
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();
573 }
574 // since cuboid has been blowed up by _overlap [every dimension]
575 // looping from -_overlap to ny (= ny+_overlap, as passed)
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]) {
579 f(evaluated,i);
580 for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
581 // tmpVec = {iC,iX,iY,iZ}; // std=c++11
582 fout << evaluated[iDim] << " ";
583 }
584 }
585 }
586 fout << "</DataArray>\n";
587 fout.close();
588}
589
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)
593{
594 std::ofstream fout( fullName, std::ios::out | std::ios::app );
595 if (!fout) {
596 clout << "Error: could not open " << fullName << std::endl;
597 }
598
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";
604 }
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";
609 }
610 fout.close();
611
612 std::ofstream ofstr( fullName, std::ios::out | std::ios::app | std::ios::binary );
613 if (!ofstr) {
614 clout << "Error: could not open " << fullName << std::endl;
615 }
616
617 size_t fullSize = f.getTargetDim() * (nxMax-nxMin+2*_overlap) * (nyMax-nyMin+2*_overlap); // how many numbers to write
618 size_t binarySize = size_t( fullSize*sizeof(OUT_T) );
619 // writes first number, which have to be the size(byte) of the following data
620 Base64Encoder<unsigned int> sizeEncoder(ofstr, 1);
621 unsigned int uintBinarySize = (unsigned int)binarySize;
622 sizeEncoder.encode(&uintBinarySize, 1);
623 // write numbers from functor
624 Base64Encoder<OUT_T>* dataEncoder = new Base64Encoder<OUT_T>( ofstr, fullSize );
625
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();
630 }
631 int itter = 0;
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]) {
635 f(evaluated,i);
636 for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
637 bufferFloat[ itter ] = OUT_T( evaluated[iDim] );
638 itter++;
639 }
640 }
641 }
642 dataEncoder->encode( &bufferFloat[0], fullSize );
643 ofstr.close();
644
645 std::ofstream ffout( fullName, std::ios::out | std::ios::app );
646 if (!ffout) {
647 clout << "Error: could not open " << fullName << std::endl;
648 }
649 ffout << "\n</DataArray>\n";
650 ffout.close();
651 delete dataEncoder;
652}
653
654template<typename T, typename OUT_T, typename W>
655void SuperVTMwriter2D<T,OUT_T,W>::closePiece(const std::string& fullNamePiece)
656{
657 std::ofstream fout(fullNamePiece, std::ios::app );
658 if (!fout) {
659 clout << "Error: could not open " << fullNamePiece << std::endl;
660 }
661 fout << "</PointData>\n";
662 fout << "</Piece>\n";
663 fout.close();
664}
665
666
667} // namespace olb
668
669#endif
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
Definition genericF.hh:51
Base class for all LoadBalancer.
Definition vtiWriter.h:42
int glob(int loc) const
represents all functors that operate on a SuperStructure<T,2> in general
Definition aliases.h:183
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.
Definition aliases.h:74
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
Plain old scalar vector.
std::string getVtkOutDir() const
Definition singleton.h:103
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)
MpiManager & mpi()
Directories & directories()
Definition singleton.h:162
Top level namespace for all of OpenLB.
std::string createFileName(std::string name)
for .pvd masterFile
Definition fileName.hh:34
typename util::BaseTypeHelper< T >::type BaseType
Definition baseType.h:59
Definition of singletons: global, publicly available information.
A method to write vtk data for cuboid geometries (only for uniform grids) – header file.