From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/io/superVtmWriter2D.hh | 448 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 src/io/superVtmWriter2D.hh (limited to 'src/io/superVtmWriter2D.hh') diff --git a/src/io/superVtmWriter2D.hh b/src/io/superVtmWriter2D.hh new file mode 100644 index 0000000..da828a3 --- /dev/null +++ b/src/io/superVtmWriter2D.hh @@ -0,0 +1,448 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2016 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 SUPER_VTM_WRITER_2D_HH +#define SUPER_VTM_WRITER_2D_HH + +#include +#include +#include +#include +#include "core/singleton.h" +#include "communication/loadBalancer.h" +#include "geometry/cuboidGeometry2D.h" +#include "communication/mpiManager.h" +#include "io/base64.h" +#include "io/fileName.h" +#include "io/superVtmWriter2D.h" + + +namespace olb { + + +template +SuperVTMwriter2D::SuperVTMwriter2D( std::string name, bool binary ) + : clout( std::cout,"SuperVTMwriter2D" ), _createFile(false), _name(name), _binary(binary) +{} + +template +void SuperVTMwriter2D::write(int iT) +{ + int rank = 0; +#ifdef PARALLEL_MODE_MPI + rank = singleton::mpi().getRank(); +#endif + + // !!!!!!!!!!! check whether _pointerVec is empty + if ( _pointerVec.empty() ) { + clout << "Error: Did you add a Functor ?"; + } else { + // to get first element _pointerVec + // problem if functors with different SuperStructure are stored + // since till now, there is only one origin + auto it_begin = _pointerVec.cbegin(); + CuboidGeometry2D const& cGeometry = (**it_begin).getSuperStructure().getCuboidGeometry(); + // no gaps between vti files (cuboids) + (**it_begin).getSuperStructure().communicate(); + LoadBalancer& load = (**it_begin).getSuperStructure().getLoadBalancer(); + + // PVD, owns all + if ( rank == 0 ) { + std::string pathPVD = singleton::directories().getVtkOutDir() + + createFileName( _name ) + ".pvd"; + dataPVDmaster( iT, pathPVD, "data/" + createFileName( _name, iT ) + ".vtm" ); + + std::string pathVTM = singleton::directories().getVtkOutDir() + + "data/" + createFileName( _name, iT ) + ".vtm"; + preambleVTM(pathVTM); + for (int iC = 0; iC < cGeometry.getNc(); iC++) { + dataVTM( iC, pathVTM, createFileName( _name, iT, iC) + ".vti" ); + } + closeVTM(pathVTM); + } + // VTI, each process writes his cuboids + int originLatticeR[3] = {int()}; + for (int iCloc = 0; iCloc < load.size(); iCloc++) { + int nx = cGeometry.get(load.glob(iCloc)).getNx(); + int ny = cGeometry.get(load.glob(iCloc)).getNy(); + // to be changed into the following line once local refinement has been implemented + // double deltaX = cGeometry.get(load.glob(iCloc)).getDeltaR(); + T delta = cGeometry.getMotherCuboid().getDeltaR(); + + std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/" + + createFileName( _name, iT, load.glob(iCloc) ) + ".vti"; + + // get dimension/extent for each cuboid + originLatticeR[0] = load.glob(iCloc); + T originPhysR[2] = {T()}; + cGeometry.getPhysR(originPhysR,originLatticeR); + + preambleVTI(fullNameVTI, -1,-1,nx,ny, originPhysR[0],originPhysR[1], delta); + for (auto it : _pointerVec) { + if(_binary) { + dataArrayBinary(fullNameVTI, (*it), load.glob(iCloc), nx,ny); + } else { + dataArray(fullNameVTI, (*it), load.glob(iCloc), nx,ny); + } + } + closePiece(fullNameVTI); + closeVTI(fullNameVTI); + } + } +} + +template +void SuperVTMwriter2D::write(SuperF2D& f, int iT) +{ + CuboidGeometry2D const& cGeometry = f.getSuperStructure().getCuboidGeometry(); + LoadBalancer& load = f.getSuperStructure().getLoadBalancer(); + // no gaps between vti files (cuboids) + f.getSuperStructure().communicate(); + T delta = cGeometry.getMotherCuboid().getDeltaR(); + + int rank = 0; +#ifdef PARALLEL_MODE_MPI + rank = singleton::mpi().getRank(); +#endif + + // write a pvd file, which links all vti files + // each vti file is written by one thread, which may own severals cuboids + if ( rank == 0 ) { + // master only + std::string pathVTM = singleton::directories().getVtkOutDir() + + createFileName( f.getName(), iT ) + ".vtm"; + + preambleVTM(pathVTM); + for (int iC = 0; iC < cGeometry.getNc(); iC++) { + std::string nameVTI = "data/" + createFileName( f.getName(), iT, iC) + ".vti"; + // puts name of .vti piece to a .pvd file [fullNamePVD] + dataVTM( iC, pathVTM, nameVTI ); + } + closeVTM(pathVTM); + } // master only + + for (int iCloc = 0; iCloc < load.size(); iCloc++) { + // cuboid + int nx = cGeometry.get(load.glob(iCloc)).getNx(); + int ny = cGeometry.get(load.glob(iCloc)).getNy(); + // to be changed into the following line once local refinement has been implemented + // double deltaX = cGeometry.get(load.glob(iCloc)).getDeltaR(); + + std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/" + + createFileName( f.getName(), iT, load.glob(iCloc) ) + ".vti"; + + // get dimension/extent for each cuboid + int const originLatticeR[3] = {load.glob(iCloc),0,0}; + T originPhysR[2] = {T()}; + cGeometry.getPhysR(originPhysR,originLatticeR); + + preambleVTI(fullNameVTI, -1,-1, nx,ny, originPhysR[0],originPhysR[1], delta); + if(_binary) { + dataArrayBinary(fullNameVTI, f, load.glob(iCloc), nx,ny); + } else { + dataArray(fullNameVTI, f, load.glob(iCloc), nx,ny); + } + closePiece(fullNameVTI); + closeVTI(fullNameVTI); + } // cuboid +} + +template +void SuperVTMwriter2D::write(std::shared_ptr> ptr_f, int iT) +{ + write(*ptr_f, iT); +} + +template +void SuperVTMwriter2D::createMasterFile() +{ + int rank = 0; +#ifdef PARALLEL_MODE_MPI + rank = singleton::mpi().getRank(); +#endif + if ( rank == 0 ) { + std::string fullNamePVDmaster = singleton::directories().getVtkOutDir() + + createFileName( _name ) + ".pvd"; + preamblePVD(fullNamePVDmaster); + closePVD(fullNamePVDmaster); + _createFile = true; + } +} + +template +void SuperVTMwriter2D::addFunctor(SuperF2D& f) +{ + _pointerVec.push_back(&f); +} + +template +void SuperVTMwriter2D::clearAddedFunctors() +{ + _pointerVec.clear(); +} + +template +std::string SuperVTMwriter2D::getName() const +{ + return _name; +} + + + + +////////////////////private member functions/////////////////////////////////// +template +void SuperVTMwriter2D::preambleVTI (const std::string& fullName, + int x0, int y0, int x1, int y1, T originX, T originY, T delta) +{ + std::ofstream fout(fullName, std::ios::trunc); + if (!fout) { + clout << "Error: could not open " << fullName << std::endl; + } + fout << "\n"; + fout << "\n"; + fout << "\n"; + fout << "\n"; + fout << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::closeVTI(const std::string& fullNamePiece) +{ + std::ofstream fout(fullNamePiece, std::ios::app ); + if (!fout) { + clout << "Error: could not open " << fullNamePiece << std::endl; + } + fout << "\n"; + fout << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::preamblePVD(const std::string& fullNamePVD) +{ + std::ofstream fout(fullNamePVD, std::ios::trunc); + if (!fout) { + clout << "Error: could not open " << fullNamePVD << std::endl; + } + fout << "\n"; + fout << "\n" + << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::closePVD(const std::string& fullNamePVD) +{ + std::ofstream fout(fullNamePVD, std::ios::app ); + if (!fout) { + clout << "Error: could not open " << fullNamePVD << std::endl; + } + fout << "\n"; + fout << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::preambleVTM(const std::string& fullNamePVD) +{ + std::ofstream fout(fullNamePVD, std::ios::trunc); + if (!fout) { + clout << "Error: could not open " << fullNamePVD << std::endl; + } + fout << "\n"; + fout << "\n" + << "\n" ; + fout.close(); +} + +template +void SuperVTMwriter2D::closeVTM(const std::string& fullNamePVD) +{ + std::ofstream fout(fullNamePVD, std::ios::app ); + if (!fout) { + clout << "Error: could not open " << fullNamePVD << std::endl; + } + fout << "\n"; + fout << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::dataVTM(int iC, const std::string& fullNamePVD, + const std::string& namePiece) +{ + std::ofstream fout(fullNamePVD, std::ios::app); + if (!fout) { + clout << "Error: could not open " << fullNamePVD << std::endl; + } + fout << "\n"; + fout << "\n" + << "\n"; + fout << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::dataPVDmaster(int iT, + const std::string& fullNamePVDMaster, + const std::string& namePiece) +{ + std::ofstream fout(fullNamePVDMaster, std::ios::in | std::ios::out | std::ios::ate); + if (fout) { + fout.seekp(-25,std::ios::end); // jump -25 form the end of file to overwrite closePVD + + fout << "\n"; + fout.close(); + closePVD(fullNamePVDMaster); + } else { + clout << "Error: could not open " << fullNamePVDMaster << std::endl; + } +} + +template +void SuperVTMwriter2D::dataArray(const std::string& fullName, + SuperF2D& f, int iC, int nx, int ny) +{ + std::ofstream fout( fullName, std::ios::out | std::ios::app ); + if (!fout) { + clout << "Error: could not open " << fullName << std::endl; + } + + fout << "\n"; + + int i[3] = {iC, 0, 0}; + W evaluated[f.getTargetDim()]; + for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { + evaluated[iDim] = W(); + } + // since cuboid has been blowed up by 1 [every dimension] + // looping from -1 to ny (= ny+1, as passed) + std::vector tmpVec( 3,int(0) ); + for (i[2]=-1; i[2] < ny+1; ++i[2]) { + for (i[1]=-1; i[1] < nx+1; ++i[1]) { + f(evaluated,i); + for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { + // tmpVec = {iC,iX,iY,iZ}; // std=c++11 + fout << evaluated[iDim] << " "; + } + } + } + fout << "\n"; + fout.close(); +} + +template +void SuperVTMwriter2D::dataArrayBinary(const std::string& fullName, + SuperF2D& f, int iC, int nx, int ny) +{ + std::ofstream fout( fullName, std::ios::out | std::ios::app ); + if (!fout) { + clout << "Error: could not open " << fullName << std::endl; + } + + fout << "\n"; + fout.close(); + + std::ofstream ofstr( fullName, std::ios::out | std::ios::app | std::ios::binary ); + if (!ofstr) { + clout << "Error: could not open " << fullName << std::endl; + } + + size_t fullSize = f.getTargetDim() * (nx+2) * (ny+2); // how many numbers to write + 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 = new Base64Encoder( ofstr, fullSize ); + + int i[3] = {iC, 0, 0}; + W evaluated[f.getTargetDim()]; + for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { + evaluated[iDim] = W(); + } + int itter = 0; + std::unique_ptr bufferFloat(new float[fullSize]); + for (i[2] = -1; i[2] < ny+1; ++i[2]) { + for (i[1] = -1; i[1] < nx+1; ++i[1]) { + f(evaluated,i); + for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) { + bufferFloat[ itter ] = float( evaluated[iDim] ); + itter++; + } + } + } + dataEncoder->encode( &bufferFloat[0], fullSize ); + ofstr.close(); + + std::ofstream ffout( fullName, std::ios::out | std::ios::app ); + if (!ffout) { + clout << "Error: could not open " << fullName << std::endl; + } + ffout << "\n\n"; + ffout.close(); + delete dataEncoder; +} + +template +void SuperVTMwriter2D::closePiece(const std::string& fullNamePiece) +{ + std::ofstream fout(fullNamePiece, std::ios::app ); + if (!fout) { + clout << "Error: could not open " << fullNamePiece << std::endl; + } + fout << "\n"; + fout << "\n"; + fout.close(); +} + + +} // namespace olb + +#endif -- cgit v1.2.3