/* This file is part of the OpenLB library * * Copyright (C) 2014 Albert Mink, Mathias J. Krause * E-mail contact: info@openlb.net * The most recent release of OpenLB can be downloaded at * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** \file * A method to write vtk data for cuboid geometries * (only for uniform grids) -- generic implementation. */ #ifndef BLOCK_VTK_WRITER_2D_HH #define BLOCK_VTK_WRITER_2D_HH #include #include #include "communication/mpiManager.h" #include "core/singleton.h" #include "io/blockVtkWriter2D.h" #include "io/base64.h" #include "io/fileName.h" namespace olb { template BlockVTKwriter2D::BlockVTKwriter2D( std::string name, bool binary ) : clout( std::cout,"BlockVTKwriter2D" ), _name(name), _binary(binary) {} template BlockVTKwriter2D::~BlockVTKwriter2D () { clearAddedFunctors(); } // iteration on _pointerVec is realized by function // dataArray() respective dataArrayBinary() template void BlockVTKwriter2D::write(int iT) { if ( _pointerVec.empty() ) { clout << "Error: Please add functor via addFunctor()"; } else { auto it = _pointerVec.cbegin(); T originX = 0; T originY = 0; T originZ = 0; int nx = (**it).getBlockStructure().getNx() -1; int ny = (**it).getBlockStructure().getNy() -1; std::string fullNameVti = singleton::directories().getVtkOutDir() + createFileName( _name, iT ) + ".vti"; preamble( fullNameVti, nx,ny, originX,originY,originZ ); if ( _binary ) { for ( auto functor = _pointerVec.cbegin(); functor != _pointerVec.cend(); ++functor) { writeRawDataBinary( fullNameVti, **functor, nx, ny); } } else { for ( auto functor = _pointerVec.cbegin(); functor != _pointerVec.cend(); ++functor) { writeRawData( fullNameVti, **functor, nx, ny); } } closePreamble( fullNameVti ); } } template void BlockVTKwriter2D::write(BlockF2D& f, int iT) { T originX = 0; T originY = 0; T originZ = 0; int nx = f.getBlockStructure().getNx() -1; int ny = f.getBlockStructure().getNy() -1; std::string fullNameVti = singleton::directories().getVtkOutDir() + createFileName( f.getName(), iT ) + ".vti"; preamble( fullNameVti, nx,ny, originX,originY,originZ ); if ( _binary ) { writeRawDataBinary( fullNameVti, f, nx,ny ); } else { writeRawData( fullNameVti, f, nx,ny ); } closePreamble( fullNameVti ); } template void BlockVTKwriter2D::addFunctor(BlockF2D& f) { _pointerVec.push_back(&f); } template void BlockVTKwriter2D::clearAddedFunctors() { _pointerVec.clear(); } template void BlockVTKwriter2D::preamble(const std::string& fullName, int nx, int ny, T originX, T originY, T originZ) { if (singleton::mpi().getRank()==0) { std::ofstream fout(fullName.c_str()); if (!fout) { clout << "Error: could not open " << fullName << std::endl; } // spacing is not known for BlockF2D classes // prone to error: spacing might correspond to extension in y direction // at the end of the day, is can be fixed by apply a scaling in paraview double spacing = double(1.0/nx); fout << "\n"; fout << "\n"; fout << "\n"; fout << "\n"; fout << "\n"; fout.close(); } } template void BlockVTKwriter2D::closePreamble(const std::string& fullNamePiece) { if (singleton::mpi().getRank()==0) { std::ofstream fout(fullNamePiece.c_str(), std::ios::app ); if (!fout) { clout << "Error: could not open " << fullNamePiece << std::endl; } fout << "\n"; fout << "\n"; fout << "\n"; fout << "\n"; fout.close(); } } template void BlockVTKwriter2D::writeRawData(const std::string& fullNameVti, BlockF2D& f, int nx, int ny) { std::ofstream fout(fullNameVti.c_str(), std::ios::app); if (!fout) { clout << "Error: could not open " << fullNameVti << std::endl; } if (singleton::mpi().getRank()==0) { fout << "\n"; } int i[2] = {int()}; T evaluated[f.getTargetDim()]; for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { evaluated[iDim] = T(); } for (i[1] = 0; i[1] < ny+1; ++i[1]) { for (i[0] = 0; i[0] < nx+1; ++i[0]) { f(evaluated,i); for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { if (singleton::mpi().getRank()==0) { fout << evaluated[iDim] << " "; } } } } if (singleton::mpi().getRank()==0) { fout << "\n\n"; } fout.close(); } template void BlockVTKwriter2D::writeRawDataBinary(const std::string& fullNameVti, BlockF2D& f, int nx, int ny) { const char* fileName = fullNameVti.c_str(); std::ofstream fout(fileName, std::ios::app); if (!fout) { clout << "Error: could not open " << fileName << std::endl; } if (singleton::mpi().getRank()==0) { fout << "\n"; } else { fout << "type=\"Float32\" Name=\"" << f.getName() << "\" " << "format=\"binary\" encoding=\"base64\" " << "NumberOfComponents=\"" << f.getTargetDim() <<"\">\n"; } } fout.close(); std::ofstream ofstr( fileName, std::ios::out | std::ios::app | std::ios::binary ); if (!ofstr) { clout << "Error: could not open " << fileName << std::endl; } size_t fullSize = f.getTargetDim() * (1 + nx) * (1 + ny) * (1); size_t binarySize = size_t( fullSize * sizeof(float) ); // writes first number, which have to be the size(byte) of the following data Base64Encoder sizeEncoder(ofstr, 1); unsigned int uintBinarySize = (unsigned int)binarySize; sizeEncoder.encode(&uintBinarySize, 1); // write numbers from functor Base64Encoder* dataEncoder = nullptr; dataEncoder = new Base64Encoder( ofstr, fullSize ); int i[2] = {int()}; T evaluated[f.getTargetDim()]; for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { evaluated[iDim] = T(); } for (i[1] = 0; i[1] < ny+1; ++i[1]) { for (i[0] = 0; i[0] < nx+1; ++i[0]) { f(evaluated,i); for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { if (singleton::mpi().getRank()==0) { const float evaluated2 = float( evaluated[iDim] ); dataEncoder->encode( &evaluated2, 1 ); } } } } ofstr.close(); if (singleton::mpi().getRank()==0) { std::ofstream foutt(fileName, std::ios::out | std::ios::app); if (!foutt) { clout << "Error: could not open " << fileName << std::endl; } foutt << "\n\n"; foutt.close(); } delete dataEncoder; } } // namespace olb #endif