OpenLB 1.7
Loading...
Searching...
No Matches
vtkWriter.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2013-2016 Thomas Henn, Mathias J. Krause
4 * 2016-2017 Albert Mink, Maximilian Gaedtke, Markus Morhard, Mathias J. Krause
5 * 2021 Nicolas Hafen, Mathias J. Krause
6 * E-mail contact: info@openlb.net
7 * The most recent release of OpenLB can be downloaded at
8 * <http://www.openlb.net/>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 */
25
26#ifndef VTK_WRITER_HH
27#define VTK_WRITER_HH
28
29
30
31namespace olb {
32
33
34template<typename T, typename FUNCTOR, vtkType VTKTYPE>
35VTKwriter<T,FUNCTOR,VTKTYPE>::VTKwriter( const std::string & name, bool binary, bool compress )
36 : clout( std::cout, "VTKwriter" ), _createFile(false), _name(name), _binary(binary), _compress(compress)
37{}
38
39
40template<typename T, typename FUNCTOR, vtkType VTKTYPE>
42{
43 _pointerVec.push_back(&f);
44}
45
46template<typename T, typename FUNCTOR, vtkType VTKTYPE>
47void VTKwriter<T,FUNCTOR,VTKTYPE>::addFunctor(FUNCTOR& f, const std::string& functorName)
48{
49 f.getName() = functorName;
50 _pointerVec.push_back(&f);
51}
52
53
54template<typename T, typename FUNCTOR, vtkType VTKTYPE>
55template<bool vtmAsMaster>
56void VTKwriter<T,FUNCTOR,VTKTYPE>::writeVTM( int iT, int rankSize, std::string fileExtension, std::string nameCollection)
57{
58 //Evaluate vtmAsMaster
59 std::string nameVTM;
60 std::string pathPrefixFileData;
61 if constexpr(!vtmAsMaster){
62 //Name of vtm
63 nameVTM = "data/" + createFileName(nameCollection, iT ) + ".vtm";
64 //path prefix
65 pathPrefixFileData = "";
66 //Create PVD
67 std::string fullNamePVD = singleton::directories().getVtkOutDir()
68 + createFileName(nameCollection) + ".pvd";
69 dataPVD(iT, fullNamePVD, nameVTM);
70 } else {
71 nameVTM = createFileName(nameCollection, iT) + ".vtm";
72 pathPrefixFileData = "data/";
73 }
74 //Create full name VTM
75 std::string fullNameVTM = singleton::directories().getVtkOutDir() + nameVTM;
76 //Write preamble VTM
77 preambleVTM(fullNameVTM);
78 //Loop over all cuboids (globIcs)
79 for (int iC = 0; iC < rankSize; iC++) {
80 std::string nameFileData = pathPrefixFileData + createFileName(nameCollection, iT, iC) + fileExtension;
81 // puts name of .vti piece to a .pvd file [fullNameVTM]
82 dataVTM(iC, fullNameVTM, nameFileData);
83 // adds a namePiece to master.pvd file.
84 }
85 // To do so we overwrite closePVD() and add new entry.
86 closeVTM(fullNameVTM); // timestep
87}
88
89
90template<typename T, typename FUNCTOR, vtkType VTKTYPE>
91template<bool vtmAsMaster, typename F>
92void VTKwriter<T,FUNCTOR,VTKTYPE>::write(int iT, std::string nameCollection, F applyFunctors)
93{
94
95 std::string fileExtension;
96
97 int rank = 0;
98 int rankSize;
99#ifdef PARALLEL_MODE_MPI
100 rank = singleton::mpi().getRank();
101#endif
102
103 if ( _pointerVec.empty() ) {
104 clout << "Error: Did you add a Functor ?" << std::endl;
105 } else {
106
107 //PARALLEL FUNCTORTYPE
108 if constexpr (parallel) {
109
110 //VTI
111 if constexpr(VTKTYPE==VTI){
112 fileExtension = ".vti";
113
114 //Retrieve cuboidGeometry from first functor (TODO: include into common functortype)
115 auto& superStructure = dynamic_cast<SuperF<D,T>*>(_pointerVec[0])->getSuperStructure();
116 auto const& cGeometry = superStructure.getCuboidGeometry();
117 LoadBalancer<T> const& loadBalancer = superStructure.getLoadBalancer();
118 rankSize = loadBalancer.getRankSize();
119 //Ensure no gaps between vti files (TODO: still necessary?)
120 superStructure.communicate();
121 //Retrieve delta
122 const T delta = cGeometry.getMotherCuboid().getDeltaR();
123
124 //Cor each cuboid
125 for (int iCloc = 0; iCloc < loadBalancer.size(); iCloc++) {
126
127 //Retrieve global IC
128 int globIC = loadBalancer.glob(iCloc);
129 //Retrieve BlockGeometry
130 auto blockGeometry = cGeometry.get(globIC);
131 //Retrieve extent
132 Vector<int,D> extent0(-1);
133 Vector<int,D> extent1( blockGeometry.getExtent() );
134
135 //Name of Data file
136 std::string fullNameFileData = singleton::directories().getVtkOutDir()
137 + "data/" + createFileName(nameCollection, iT, globIC ) + fileExtension;
138
139 // get dimension/extent for each cuboid
140 LatticeR<D> originCuboid(0.);
141 T originPhysR[D] = {T()};
142 cGeometry.getPhysR(originPhysR, globIC, originCuboid);
143 //Write preamble VTU
144 preambleVTI(fullNameFileData, extent0, extent1, originPhysR, delta);
145 //Loop over functors or call individual one
146 applyFunctors(fullNameFileData, extent1, globIC);
147 //Close piece and vti
148 closePiece(fullNameFileData);
149 closeVTI(fullNameFileData);
150 }
151
152 //VTU
153 } else if constexpr(VTKTYPE==VTU){
154 fileExtension = ".vtu";
155
156 //Retrive loadBalancer from first functor (TODO: include into common functortype)
157 LoadBalancer<T> const& loadBalancer = _pointerVec[0]->getLoadBalancer();
158 rankSize = loadBalancer.getRankSize();
159
160 //Cor each cuboid
161 for (int iCloc = 0; iCloc < loadBalancer.size(); iCloc++) {
162 //Retrieve global IC
163 int globIC = loadBalancer.glob(iCloc);
164 // Retrieve container size (number of particles) (TODO: include into common functortype)
165 Vector<int,1> extent1 = _pointerVec[0]->getContainerF(iCloc).getContainerSize();
166 //Name of VTU
167 std::string fullNameFileData = singleton::directories().getVtkOutDir()
168 + "data/" + createFileName(nameCollection, iT, globIC ) + fileExtension;
169 //Write preamble VTU
170 preambleVTU(fullNameFileData,extent1);
171 //Loop over functors or call individual one
172 applyFunctors(fullNameFileData, extent1, globIC);
173 // Write celldata (connectivity, offset, types)
174 this->cellDataVTU(fullNameFileData, extent1);
175 // Write points
176 this->dataArrayPoints(fullNameFileData, extent1, globIC);
177 // CloseVTU
178 closeVTU(fullNameFileData);
179 }
180
181 //VTP
182 } else {
183 fileExtension = ".vtp";
184 clout << "Error: VTP type not implemented yet" << std::endl;
185 }
186
187 //Write VTM (only master)
188 if (rank == 0) { writeVTM<vtmAsMaster>(iT,rankSize,fileExtension,nameCollection); }
189
190 //UNPARRALLIZED FUNCTORTYPE (for now only relevant for VTU)
191 } else {
192 fileExtension = ".vtu";
193
194 //if master
195 if (rank == 0) {
196 // Full name pvd
197 std::string fullNamePVD = singleton::directories().getVtkOutDir()
198 + createFileName(nameCollection) + ".pvd";
199 // Retrieve container size (number of particles)(TODO: include into common functortype)
200 Vector<int,1> extent1(_pointerVec[0]->getContainerSize());
201 // Name VTU
202 std::string nameFileData = "data/" + createFileName(nameCollection, iT ) + fileExtension;
203 // Create PVD
204 dataPVD(iT, fullNamePVD, nameFileData);
205 // Full Name VTU
206 std::string fullNameFileData = singleton::directories().getVtkOutDir() + nameFileData;
207 // Write preample VTU
208 preambleVTU(fullNameFileData, extent1);
209 //Loop over functors or call individual one
210 applyFunctors(fullNameFileData, extent1);
211 // Write celldata (connectivity, offset, types)
212 this->cellDataVTU(fullNameFileData, extent1);
213 // Write points
214 this->dataArrayPoints(fullNameFileData, extent1);
215 // CloseVTU
216 closeVTU(fullNameFileData);
217 } // master only
218 } // if parralized type
219 } //if ( _pointerVec.empty() )
220}
221
222
223template<typename T, typename FUNCTOR, vtkType VTKTYPE>
225{
226 //VTI
227 if constexpr(VTKTYPE==VTI){
228 //Define functors to be applied
229 auto applyFunctors = [&](std::string fullNameFileData, Vector<int,D> extent1, int globIC=0 )
230 {
231 for (int iF=0; iF<_pointerVec.size(); ++iF) {
232 this->dataArraySingleFunctor(fullNameFileData, *_pointerVec[iF], extent1, globIC);
233 }
234 };
235 //Call write
236 write<false>(iT,_name,applyFunctors);
237
238 //VTU
239 } else if constexpr(VTKTYPE==VTU){
240 //Define functors to be applied
241 auto applyFunctors = [&](std::string fullNameFileData, Vector<int,1> extent1, int globIC=0 )
242 {
243 for (std::size_t iF=1; iF<_pointerVec.size(); ++iF) {
244 this->dataArraySingleFunctor(fullNameFileData, *_pointerVec[iF], extent1, globIC);
245 }
246 };
247 //Call write
248 write<false>(iT,_name, applyFunctors);
249 }
250}
251
252
253template<typename T, typename FUNCTOR, vtkType VTKTYPE>
255{
256 //VTI
257 if constexpr(VTKTYPE==VTI){
258 //Define functor
259 auto applyFunctors = [&](std::string fullNameFileData, Vector<int,D> extent1, int globIC=0 ){
260 this->dataArraySingleFunctor(fullNameFileData, f, extent1, globIC); };
261 //Call write
262 write<true>(iT,f.getName(),applyFunctors);
263
264 //VTU
265 } else if constexpr(VTKTYPE==VTU){
266 //Define functor
267 auto applyFunctors = [&](std::string fullNameFileData, Vector<int,1> extent1, int globIC=0 ){
268 this->dataArraySingleFunctor(fullNameFileData, f, extent1, globIC); };
269 //Call write
270 write<true>(iT,f.getName(),applyFunctors);
271 }
272
273}
274
275template<typename T, typename FUNCTOR, vtkType VTKTYPE>
276void VTKwriter<T,FUNCTOR,VTKTYPE>::write(std::shared_ptr<FUNCTOR> ptr_f, int iT)
277{
278 write(*ptr_f, iT);
279}
280
281
282template<typename T, typename FUNCTOR, vtkType VTKTYPE>
284{
285 int rank = 0;
286#ifdef PARALLEL_MODE_MPI
287 rank = singleton::mpi().getRank();
288#endif
289 if (rank == 0) {
290 std::string fullNamePVD = singleton::directories().getVtkOutDir()
291 + createFileName(_name) + ".pvd";
292 preamblePVD(fullNamePVD);
293 closePVD(fullNamePVD);
294 _createFile = true;
295 }
296}
297
298template<typename T, typename FUNCTOR, vtkType VTKTYPE>
300 const std::string& fullName, Vector<int,1> extent1)
301{
302 std::ofstream fout(fullName, std::ios::trunc);
303 if (!fout) {
304 clout << "Error: could not open " << fullName << std::endl;
305 }
306 fout << "<?xml version=\"1.0\"?>\n";
307 fout << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" ";
308 if (_compress) {
309 fout << "byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n";
310 }
311 else {
312 fout << "byte_order=\"LittleEndian\">\n";
313 }
314 fout << "<UnstructuredGrid>" << std::endl;
315 fout << "<Piece NumberOfPoints=\"" << extent1[0]
316 << "\" NumberOfCells=\"" << extent1[0] << "\">"
317 << std::endl;
318 fout << "<PointData Vectors=\"Particles\">" << std::endl;
319 fout.close();
320}
321
322template<typename T, typename FUNCTOR, vtkType VTKTYPE>
324 const std::string& fullNamePiece)
325{
326 std::ofstream fout(fullNamePiece.c_str(), std::ios::app);
327 if (!fout) {
328 clout << "Error: could not open " << fullNamePiece << std::endl;
329 }
330 fout << "</Piece>" << std::endl;
331 fout << "</UnstructuredGrid>\n";
332 fout << "</VTKFile>\n";
333 fout.close();
334}
335
336
337
338
339//TODO: make dimension insensitive
340template<typename T, typename FUNCTOR, vtkType VTKTYPE>
342 const std::string& fullName,
343 const LatticeR<D> extent0, const LatticeR<D> extent1,
344 PhysR<T,D> origin, T delta)
345{
346 std::ofstream fout(fullName, std::ios::trunc);
347 if (!fout) {
348 clout << "Error: could not open " << fullName << std::endl;
349 }
350 fout << "<?xml version=\"1.0\"?>\n";
351 fout << "<VTKFile type=\"ImageData\" version=\"0.1\" ";
352 if (_compress) {
353 fout << "byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n";
354 }
355 else {
356 fout << "byte_order=\"LittleEndian\">\n";
357 }
358
359 fout << "<ImageData WholeExtent=\""
360 << extent0[0] <<" "<< extent1[0];
361 for (unsigned iDim=1; iDim<D; ++iDim){
362 fout << " " << extent0[iDim] << " " << extent1[iDim];
363 }
364 fout << "\" Origin=\"" << origin[0];
365 for (unsigned iDim=1; iDim<D; ++iDim){
366 fout << " " << origin[iDim];
367 }
368 fout << "\" Spacing=\"" << delta << " " << delta << " " << delta << "\">\n";
369 fout << "<Piece Extent=\""
370 << extent0[0] <<" "<< extent1[0];
371 for (unsigned iDim=1; iDim<D; ++iDim){
372 fout << " " << extent0[iDim] <<" "<< extent1[iDim];
373 }
374 fout <<"\">\n";
375 fout << "<PointData>\n";
376 fout.close();
377}
378
379
380template<typename T, typename FUNCTOR, vtkType VTKTYPE>
382 const std::string& fullNamePiece)
383{
384 std::ofstream fout(fullNamePiece, std::ios::app );
385 if (!fout) {
386 clout << "Error: could not open " << fullNamePiece << std::endl;
387 }
388 fout << "</ImageData>\n";
389 fout << "</VTKFile>\n";
390 fout.close();
391}
392
393template<typename T, typename FUNCTOR, vtkType VTKTYPE>
394void VTKwriter<T,FUNCTOR,VTKTYPE>::closePiece(const std::string& fullNamePiece)
395{
396 std::ofstream fout(fullNamePiece, std::ios::app );
397 if (!fout) {
398 clout << "Error: could not open " << fullNamePiece << std::endl;
399 }
400 fout << "</PointData>\n";
401 fout << "</Piece>\n";
402 fout.close();
403}
404
405
406template<typename T, typename FUNCTOR, vtkType VTKTYPE>
408 const std::string& fullNamePVD)
409{
410 std::ofstream fout(fullNamePVD.c_str(), std::ios::trunc);
411 if (!fout) {
412 clout << "Error: could not open " << fullNamePVD << std::endl;
413 }
414
415 fout << "<?xml version=\"1.0\"?>\n";
416 fout << "<VTKFile type=\"Collection\" version=\"0.1\" "
417 << "byte_order=\"LittleEndian\">\n" << "<Collection>\n";
418 fout.close();
419}
420
421template<typename T, typename FUNCTOR, vtkType VTKTYPE>
423 const std::string& fullNamePVD)
424{
425 std::ofstream fout(fullNamePVD.c_str(), std::ios::app);
426 if (!fout) {
427 clout << "Error: could not open " << fullNamePVD << std::endl;
428 }
429 fout << "</Collection>\n";
430 fout << "</VTKFile>\n";
431 fout.close();
432}
433
434
435
436
437template<typename T, typename FUNCTOR, vtkType VTKTYPE>
438void VTKwriter<T,FUNCTOR,VTKTYPE>::preambleVTM(const std::string& fullNameVTM)
439{
440 std::ofstream fout(fullNameVTM, std::ios::trunc);
441 if (!fout) {
442 clout << "Error: could not open " << fullNameVTM << std::endl;
443 }
444 fout << "<?xml version=\"1.0\"?>\n";
445 fout << "<VTKFile type=\"vtkMultiBlockDataSet\" version=\"1.0\" "
446 << "byte_order=\"LittleEndian\">\n"
447 << "<vtkMultiBlockDataSet>\n" ;
448 fout.close();
449}
450
451template<typename T, typename FUNCTOR, vtkType VTKTYPE>
452void VTKwriter<T,FUNCTOR,VTKTYPE>::closeVTM(const std::string& fullNameVTM)
453{
454 std::ofstream fout(fullNameVTM, std::ios::app );
455 if (!fout) {
456 clout << "Error: could not open " << fullNameVTM << std::endl;
457 }
458 fout << "</vtkMultiBlockDataSet>\n";
459 fout << "</VTKFile>\n";
460 fout.close();
461}
462
463
464template<typename T, typename FUNCTOR, vtkType VTKTYPE>
465void VTKwriter<T,FUNCTOR,VTKTYPE>::dataVTM(int iC, const std::string& fullNameVTM,
466 const std::string& namePiece)
467{
468 std::ofstream fout(fullNameVTM, std::ios::app);
469 if (!fout) {
470 clout << "Error: could not open " << fullNameVTM << std::endl;
471 }
472 fout << "<Block index=\"" << iC << "\" >\n";
473 fout << "<DataSet index= \"0\" " << "file=\"" << namePiece << "\">\n"
474 << "</DataSet>\n";
475 fout << "</Block>\n";
476 fout.close();
477}
478
479template<typename T, typename FUNCTOR, vtkType VTKTYPE>
481 const std::string& fullNamePVD, const std::string& namePiece)
482{
483 std::ofstream fout(fullNamePVD.c_str(),
484 std::ios::in | std::ios::out | std::ios::ate);
485 if (fout) {
486 fout.seekp(-25, std::ios::end); // jump -25 form the end of file to overwrite closePVD
487
488 fout << "<DataSet timestep=\"" << iT << "\" "
489 << "group=\"\" part=\"\" "
490 << "file=\"" << namePiece << "\"/>\n";
491 fout.close();
492 closePVD(fullNamePVD);
493 }
494 else {
495 clout << "Error: could not open " << fullNamePVD << std::endl;
496 }
497}
498
499template<typename T, typename FUNCTOR, vtkType VTKTYPE>
500template<unsigned sourceDim>
502 const std::string& fullName,
503 Vector<int,sourceDim> extent1, int iC )
504
505{
506 std::ofstream fout(fullName.c_str(), std::ios::app);
507 if (!fout) {
508 clout << "Error: could not open " << fullName << std::endl;
509 }
510 fout << "<Points>" << std::endl;
511 // Call dataArray with first functor (which should contain points)
512 this->dataArraySingleFunctor(fullName, *_pointerVec[0], extent1, iC);
513 fout << "</Points>" << std::endl;
514}
515
516
517
518template<typename T, typename FUNCTOR, vtkType VTKTYPE>
519void VTKwriter<T,FUNCTOR,VTKTYPE>::cellDataVTU( const std::string& fullName, Vector<int, 1> extent1 ){
520 std::ofstream fout(fullName.c_str(), std::ios::app);
521 if (!fout) {
522 clout << "Error: could not open " << fullName << std::endl;
523 }
524 fout << "</PointData>" << std::endl;
525 fout << "<CellData /> " << std::endl; //TODO: open tag missing?
526 fout << "<Cells>" << std::endl;
527 fout << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">"
528 << std::endl;
529 int32_t i32 = 0;
530 for (int iTmp=0; iTmp<extent1[0]; ++iTmp){ fout << i32++ << " "; }
531 fout << "</DataArray>" << std::endl;
532 fout << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">"
533 << std::endl;
534 i32 = 1;
535 for (int iTmp=0; iTmp<extent1[0]; ++iTmp){ fout << i32++ << " "; }
536 fout << "</DataArray>" << std::endl;
537 fout << "<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">"
538 << std::endl;
539 for (int iTmp=0; iTmp<extent1[0]; ++iTmp){ fout << 1 << " "; }
540 fout << "</DataArray>" << std::endl;
541 fout << "</Cells>" << std::endl;
542}
543
544
545
546template<typename T, typename FUNCTOR, vtkType VTKTYPE>
547template<unsigned sourceDim>
549 const std::string& fullName,
550 FUNCTOR& f,
551 Vector<int,sourceDim> extent1, int iC)
552{
553 std::ofstream fout(fullName.c_str(), std::ios::app);
554 if (!fout) {
555 clout << "Error: could not open " << fullName << std::endl;
556 }
557 fout << "<DataArray type=\"Float32\" Name=\"" << f.getName() << "\" NumberOfComponents=\"" << f.getTargetDim() << "\" ";
558 if (_compress || _binary) {
559 fout << "format=\"binary\" encoding=\"base64\">\n";
560 }
561 else {
562 fout << ">\n";
563 }
564
565 // Create functor input and output
566 int i[4] = {0}; //4 as maximum dimension
567 std::vector<T> evaluated(f.getTargetDim());
568
569 //Set ic if parallel
570 if constexpr(parallel){ i[0] = iC;}
571
572 //Create float array
573 size_t numberOfFloats;
574 std::unique_ptr<float[]> streamFloat;
575 int itter = 0;
576
577 //VTI
578 if constexpr(VTKTYPE==VTI){
579 //2D
580 if constexpr(D==2){
581 numberOfFloats = f.getTargetDim() * (extent1[0]+2) * (extent1[1]+2);
582 streamFloat = std::make_unique<float[]>(numberOfFloats);
583 for (i[2]=-1; i[2]<extent1[1]+1; ++i[2]) {
584 for (i[1]=-1; i[1]<extent1[0]+1; ++i[1]) {
585 f(evaluated.data(),i);
586 for (int iDim=0; iDim < f.getTargetDim(); ++iDim){
587 streamFloat[itter] = float( evaluated[iDim] );
588 ++itter;
589 }
590 }
591 }
592 //3D
593 } else if constexpr(D==3){
594 numberOfFloats = f.getTargetDim() * (extent1[0]+2) * (extent1[1]+2) * (extent1[2]+2);
595 streamFloat = std::make_unique<float[]>(numberOfFloats);
596 for (i[3]=-1; i[3]<extent1[2]+1; ++i[3]) {
597 for (i[2]=-1; i[2]<extent1[1]+1; ++i[2]) {
598 for (i[1]=-1; i[1]<extent1[0]+1; ++i[1]) {
599 f(evaluated.data(),i);
600 for (int iDim=0; iDim < f.getTargetDim(); ++iDim){
601 streamFloat[itter] = float( evaluated[iDim] );
602 ++itter;
603 }
604 }
605 }
606 }
607 } else {
608 clout << "Error: only 2D and 3D supportet" << std::endl;
609 }
610
611 //VTU
612 } else if constexpr(VTKTYPE==VTU){
613 numberOfFloats = f.getTargetDim() * extent1[0];
614 streamFloat = std::make_unique<float[]>(numberOfFloats);
615 //PARALLEL
616 if constexpr(parallel){
617 for (i[1]=0; i[1]<extent1[0]; ++i[1]) {
618 f(evaluated.data(),i);
619 for (int iDim=0; iDim < f.getTargetDim(); ++iDim){
620 streamFloat[itter] = float( evaluated[iDim] );
621 ++itter;
622 }
623 }
624 //NONPARALLEL
625 } else {
626 for (i[0]=0; i[0]<extent1[0]; ++i[0]) {
627 f(evaluated.data(),i);
628 for (int iDim=0; iDim < f.getTargetDim(); ++iDim){
629 streamFloat[itter] = float( evaluated[iDim] );
630 ++itter;
631 }
632 }
633 }
634 } else {
635 clout << "Error: VTP format not implemented yet" << std::endl;
636 }
637
638 //Define binarSize from number of floats
639 uint32_t binarySize = static_cast<uint32_t>( numberOfFloats*sizeof(float) );
640
641 //Write data (TODO: repair for non parallised vtu version)
642 if (_compress) {
643 // char buffer for functor data
644 const unsigned char* charData = reinterpret_cast<unsigned char*>(streamFloat.get());
645 // buffer for compression
646 std::unique_ptr<unsigned char[]> comprData(new unsigned char[ binarySize ]); // stack may be too small
647
648 // compress data (not yet decoded as base64) by zlib
649 uLongf sizeCompr = compressBound(binarySize);
650 compress2( comprData.get(), &sizeCompr, charData, binarySize, -1);
651
652 // encode prefix to base64 documented in http://www.earthmodels.org/software/vtk-and-paraview/vtk-file-formats
653 Base64Encoder<uint32_t> prefixEncoder(fout, 4);
654 uint32_t prefix[4] = {1,binarySize,binarySize,static_cast<uint32_t>(sizeCompr)};
655 prefixEncoder.encode(prefix, 4);
656
657 // encode compressed data to base64
658 Base64Encoder<unsigned char> dataEncoder( fout, sizeCompr );
659 dataEncoder.encode(comprData.get(), sizeCompr);
660 } else if (_binary) {
661 // encode prefix to base64 documented in http://www.earthmodels.org/software/vtk-and-paraview/vtk-file-formats
662 Base64Encoder<uint32_t> prefixEncoder(fout, 1);
663 prefixEncoder.encode(&binarySize, 1);
664 // write numbers from functor
665 Base64Encoder<float> dataEncoder(fout, numberOfFloats);
666 dataEncoder.encode(streamFloat.get(),numberOfFloats);
667 } else {
668 for ( size_t iOut = 0; iOut < numberOfFloats; ++iOut ) {
669 fout << streamFloat[iOut] << " ";
670 }
671 }
672 fout.close();
673
674 std::ofstream ffout( fullName, std::ios::out | std::ios::app );
675 if (!ffout) {
676 clout << "Error: could not open " << fullName << std::endl;
677 }
678 ffout << "\n</DataArray>\n";
679 ffout.close();
680}
681
682
683} // namespace OLB
684
685#endif
void encode(const T *data, size_t length)
Definition base64.hh:59
Base class for all LoadBalancer.
int getRankSize() const
int glob(int loc) const
void closeVTI(const std::string &fullNamePiece)
performes </ImageData> and </VTKFile>
Definition vtkWriter.hh:381
void dataArraySingleFunctor(const std::string &fullName, FUNCTOR &f, Vector< int, sourceDim > extent1, int iC=0)
writes functors stored at pointerVec
Definition vtkWriter.hh:548
void closeVTU(const std::string &fullNamePiece)
performes </ImageData> and </VTKFile>
Definition vtkWriter.hh:323
void preambleVTM(const std::string &fullNameVTM)
performes <VTKFile ...> and <Collection>
Definition vtkWriter.hh:438
VTKwriter(const std::string &name, bool binary=true, bool compress=true)
constructor
Definition vtkWriter.hh:35
void preamblePVD(const std::string &fullNamePVD)
performes <VTKFile ...> and <Collection>
Definition vtkWriter.hh:407
void createMasterFile()
have to be called before calling write(int iT=0), since it creates
Definition vtkWriter.hh:283
void closeVTM(const std::string &fullNameVTM)
performes </Collection> and </VTKFile>
Definition vtkWriter.hh:452
void dataVTM(int iC, const std::string &fullNameVTM, const std::string &namePiece)
performes <DataSet timestep= ... file=namePiece > used for linking vti into pvd files
Definition vtkWriter.hh:465
void dataArrayPoints(const std::string &fullName, Vector< int, sourceDim > extent1, int iC=0)
writes points necessary for VTU
Definition vtkWriter.hh:501
void write(int iT, std::string nameCollection, F applyFunctors)
to clear stored functors, not yet used due to lack of necessity
Definition vtkWriter.hh:92
void closePiece(const std::string &fullNamePiece)
performes </PointData> and </Piece>
Definition vtkWriter.hh:394
void preambleVTU(const std::string &fullName, Vector< int, 1 > extent1)
performes <VTKFile ...>, <ImageData ...> and <PieceExtent ...>
Definition vtkWriter.hh:299
void preambleVTI(const std::string &fullName, const LatticeR< D > extent0, const LatticeR< D > extent1, PhysR< T, D > origin, T delta)
performes <VTKFile ...>, <ImageData ...>, <PieceExtent ...> and <PointData ...>
Definition vtkWriter.hh:341
void closePVD(const std::string &fullNamePVD)
performes </Collection> and </VTKFile>
Definition vtkWriter.hh:422
void cellDataVTU(const std::string &fullName, Vector< int, 1 > extent1)
TODO: add description: connectivity, offsete, type of unscructured nodes.
Definition vtkWriter.hh:519
void addFunctor(FUNCTOR &f)
put functor to _pointerVec to simplify writing process of several functors
Definition vtkWriter.hh:41
void writeVTM(int iT, int rankSize, std::string fileExtension, std::string nameCollection)
wrapper for VTM file creation
Definition vtkWriter.hh:56
void dataPVD(int iT, const std::string &fullNamePVD, const std::string &namePiece)
performes <DataSet timestep= ... file=namePiece >
Definition vtkWriter.hh:480
Plain old scalar vector.
Definition vector.h:47
std::string getVtkOutDir() const
Definition singleton.h:97
int getRank() const
Returns the process ID.
MpiManager & mpi()
Directories & directories()
Definition singleton.h:150
Top level namespace for all of OpenLB.
std::string createFileName(std::string name)
for .pvd masterFile
Definition fileName.hh:34
std::conditional_t< D==2, SuperF2D< T, U >, SuperF3D< T, U > > SuperF
Definition aliases.h:198
@ VTU
Definition vtkWriter.h:52
@ VTI
Definition vtkWriter.h:52