OpenLB 1.7
Loading...
Searching...
No Matches
blockVtkWriter3D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2014 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 BLOCK_VTK_WRITER_3D_HH
30#define BLOCK_VTK_WRITER_3D_HH
31
32#include <fstream>
33#include <iostream>
35#include "core/singleton.h"
36#include "io/blockVtkWriter3D.h"
37#include "io/base64.h"
38#include "io/fileName.h"
39
40namespace olb {
41
42template<typename T>
43BlockVTKwriter3D<T>::BlockVTKwriter3D( std::string name, bool binary )
44 : clout( std::cout,"BlockVTKwriter3D" ), _name(name), _binary(binary)
45{}
46
47template<typename T>
49{
50 clearAddedFunctors();
51}
52
53template<typename T>
55{
56 if ( _pointerVec.empty() ) {
57 clout << "Error: Please add functor via addFunctor()";
58 }
59 else {
60 // get first functor
61 auto it = _pointerVec.cbegin();
62
63 T originX = 0;
64 T originY = 0;
65 T originZ = 0;
66 int nx = (**it).getBlockStructure().getNx() -1;
67 int ny = (**it).getBlockStructure().getNy() -1;
68 int nz = (**it).getBlockStructure().getNz() -1;
69
70 std::string fullNameVti = singleton::directories().getVtkOutDir()
71 + createFileName( _name, iT ) + ".vti";
72
73 preamble( fullNameVti, nx,ny,nz, originX,originY,originZ );
74 if ( _binary ) {
75 // iterate on functors
76 for ( auto functor = _pointerVec.cbegin(); functor != _pointerVec.cend(); ++functor) {
77 writeRawDataBinary( fullNameVti, **functor, nx, ny, nz);
78 }
79 }
80 else {
81 for ( auto functor = _pointerVec.cbegin(); functor != _pointerVec.cend(); ++functor) {
82 writeRawData( fullNameVti, **functor, nx, ny, nz);
83 }
84 }
85 closePreamble( fullNameVti );
86 }
87}
88
89template<typename T>
91{
92 T originX = 0;
93 T originY = 0;
94 T originZ = 0;
95 int nx = f.getBlockStructure().getNx() -1;
96 int ny = f.getBlockStructure().getNy() -1;
97 int nz = f.getBlockStructure().getNz() -1;
98
99 std::string fullNameVti = singleton::directories().getVtkOutDir()
100 + createFileName( f.getName(), iT ) + ".vti";
101
102 preamble( fullNameVti, nx,ny,nz, originX,originY,originZ );
103 if ( _binary ) {
104 writeRawData( fullNameVti, f, nx,ny,nz );
105 }
106 else {
107 writeRawDataBinary( fullNameVti, f, nx,ny,nz );
108 }
109 closePreamble( fullNameVti );
110}
111
112template<typename T>
114{
115 _pointerVec.push_back(&f);
116}
117
118template<typename T>
120{
121 _pointerVec.clear();
122}
123
124template<typename T>
125void BlockVTKwriter3D<T>::preamble(const std::string& fullName, int nx, int ny, int nz,
126 T originX, T originY, T originZ)
127{
128 if (singleton::mpi().getRank()==0) {
129 std::ofstream fout(fullName.c_str());
130 if (!fout) {
131 clout << "Error: could not open " << fullName << std::endl;
132 }
133 // spacing is not known for BlockF3D classes
134 // prone to error: spacing might correspond to extension in y or z direction
135 // at the end of the day, is can be fixed by apply a scaling in paraview
136 double spacing = 1/double(nx);
137
138 fout << "<?xml version=\"1.0\"?>\n";
139 fout << "<VTKFile type=\"ImageData\" version=\"0.1\" "
140 << "byte_order=\"LittleEndian\">\n";
141 fout << "<ImageData WholeExtent=\""
142 << "0" <<" "<< nx <<" "
143 << "0" <<" "<< ny <<" "
144 << "0" <<" "<< nz
145 << "\" Origin=\"" << originX << " " << originY << " " << originZ
146 << "\" Spacing=\"" << spacing << " " << spacing << " " << spacing << "\">\n";
147
148 fout << "<Piece Extent=\""
149 << 0 <<" "<< nx <<" "
150 << 0 <<" "<< ny <<" "
151 << 0 <<" "<< nz <<"\">\n";
152
153 fout << "<PointData>\n";
154 fout.close();
155 }
156}
157
158template<typename T>
159void BlockVTKwriter3D<T>::closePreamble(const std::string& fullNamePiece)
160{
161 if (singleton::mpi().getRank()==0) {
162 std::ofstream fout(fullNamePiece.c_str(), std::ios::app );
163 if (!fout) {
164 clout << "Error: could not open " << fullNamePiece << std::endl;
165 }
166 fout << "</PointData>\n";
167 fout << "</Piece>\n";
168 fout << "</ImageData>\n";
169 fout << "</VTKFile>\n";
170 fout.close();
171 }
172}
173
174
175
176template<typename T>
177void BlockVTKwriter3D<T>::writeRawData(const std::string& fullNameVti, BlockF3D<T>& f,
178 int nx, int ny, int nz)
179{
180 std::ofstream fout(fullNameVti.c_str(), std::ios::app);
181 if (!fout) {
182 clout << "Error: could not open " << fullNameVti << std::endl;
183 }
184
185 if (singleton::mpi().getRank()==0) {
186 fout << "<DataArray " ;
187 fout << "type=\"Float32\" Name=\"" << f.getName() << "\" "
188 << "NumberOfComponents=\"" << f.getTargetDim() << "\">\n";
189 }
190
191 int i[3] = {int()};
192 T evaluated[f.getTargetDim()];
193 for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
194 evaluated[iDim] = T();
195 }
196 for (i[2] = 0; i[2] < nz+1; ++i[2]) {
197 for (i[1] = 0; i[1] < ny+1; ++i[1]) {
198 for (i[0] = 0; i[0] < nx+1; ++i[0]) {
199 f(evaluated,i);
200 for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
201 if (singleton::mpi().getRank()==0) {
202 fout << evaluated[iDim] << " ";
203 }
204 }
205 }
206 }
207 }
208 if (singleton::mpi().getRank()==0) {
209 fout << "\n</DataArray>\n";
210 }
211
212 fout.close();
213}
214
215// uses base64 encoder to write binary output
216// first number is written by a seperate sizeEncoder
217// this number indicates how many numbers will be stored.
218// then dataEncoder will be called to write output.
219// !!code is fixed to float functor values!!
220template<typename T>
221void BlockVTKwriter3D<T>::writeRawDataBinary(const std::string& fullNameVti,
222 BlockF3D<T>& f, int nx, int ny, int nz)
223{
224 const char* fileName = fullNameVti.c_str();
225 std::ofstream fout(fileName, std::ios::app);
226 if (!fout) {
227 clout << "Error: could not open " << fileName << std::endl;
228 }
229
230 if (singleton::mpi().getRank()==0) {
231 fout << "<DataArray " ;
232 if (f.getTargetDim() == 1) {
233 fout << "type=\"Float32\" Name=\"" << f.getName() << "\" "
234 << "format=\"binary\" encoding=\"base64\">\n";
235 }
236 else {
237 fout << "type=\"Float32\" Name=\"" << f.getName() << "\" "
238 << "format=\"binary\" encoding=\"base64\" "
239 << "NumberOfComponents=\"" << f.getTargetDim() << "\">\n";
240 }
241 }
242 fout.close();
243
244 std::ofstream ofstr( fileName, std::ios::out | std::ios::app | std::ios::binary );
245 if (!ofstr) {
246 clout << "Error: could not open " << fileName << std::endl;
247 }
248
249 size_t fullSize = f.getTargetDim() * (1 + nx) * (1 + ny) * (1 + nz);
250 size_t binarySize = size_t( fullSize * sizeof(float) );
251 // writes first number, which have to be the size(byte) of the following data
252 Base64Encoder<unsigned int> sizeEncoder(ofstr, 1);
253 unsigned int uintBinarySize = (unsigned int)binarySize;
254 sizeEncoder.encode(&uintBinarySize, 1);
255 // write numbers from functor
256 Base64Encoder<float>* dataEncoder = nullptr;
257 dataEncoder = new Base64Encoder<float>( ofstr, fullSize );
258
259 int i[3] = {int()};
260 T evaluated[f.getTargetDim()];
261 for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
262 evaluated[iDim] = T();
263 }
264 for (i[2] = 0; i[2] < nz+1; ++i[2]) {
265 for (i[1] = 0; i[1] < ny+1; ++i[1]) {
266 for (i[0] = 0; i[0] < nx+1; ++i[0]) {
267 f(evaluated,i);
268 for (int iDim = 0; iDim<f.getTargetDim(); ++iDim) {
269 if (singleton::mpi().getRank()==0) {
270 const float evaluated2 = float( evaluated[iDim] );
271 dataEncoder->encode( &evaluated2, 1 );
272 }
273 }
274 }
275 }
276 }
277 ofstr.close();
278
279 if (singleton::mpi().getRank()==0) {
280 std::ofstream foutt(fileName, std::ios::out | std::ios::app);
281 if (!foutt) {
282 clout << "Error: could not open " << fileName << std::endl;
283 }
284 foutt << "\n</DataArray>\n";
285 foutt.close();
286 }
287 delete dataEncoder;
288}
289
290
291} // namespace olb
292
293#endif
A method to write vtk data for block geometries (only for uniform grids) – header file.
represents all functors that operate on a cuboid in general, mother class of BlockLatticeF,...
virtual BlockStructureD< 3 > & getBlockStructure() const
int getNy() const
Read only access to block height.
int getNx() const
Read only access to block width.
int getNz() const
Read only access to block height.
BlockVTKwriter3D writes any BLockF3D to vtk-based output files.
BlockVTKwriter3D(std::string name, bool binary=true)
void clearAddedFunctors()
to clear stored functors
void write(BlockF3D< T > &f, int iT=0)
method calls preamble(), pointData(), data() and coresponding closing methods.
void addFunctor(BlockF3D< T > &f)
put functor to _pointerVec to simplify writing process of several functors
std::string & getName()
read and write access to name
Definition genericF.hh:51
std::string getVtkOutDir() const
Definition singleton.h:97
These functions help you to create file names.
Wrapper functions that simplify the use of MPI.
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
Definition of singletons: global, publicly available information.