summaryrefslogtreecommitdiff
path: root/src/io/superVtmWriter2D.hh
diff options
context:
space:
mode:
authorAdrian Kummerlaender2019-06-24 14:43:36 +0200
committerAdrian Kummerlaender2019-06-24 14:43:36 +0200
commit94d3e79a8617f88dc0219cfdeedfa3147833719d (patch)
treec1a6894679563e271f5c6ea7a17fa3462f7212a3 /src/io/superVtmWriter2D.hh
downloadgrid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.gz
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.bz2
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.lz
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.xz
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.zst
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.zip
Initialize at openlb-1-3
Diffstat (limited to 'src/io/superVtmWriter2D.hh')
-rw-r--r--src/io/superVtmWriter2D.hh448
1 files changed, 448 insertions, 0 deletions
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
+ * <http://www.openlb.net/>
+ *
+ * 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 <fstream>
+#include <iostream>
+#include <iomanip>
+#include <string>
+#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<typename T, typename W>
+SuperVTMwriter2D<T,W>::SuperVTMwriter2D( std::string name, bool binary )
+ : clout( std::cout,"SuperVTMwriter2D" ), _createFile(false), _name(name), _binary(binary)
+{}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::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<T> const& cGeometry = (**it_begin).getSuperStructure().getCuboidGeometry();
+ // no gaps between vti files (cuboids)
+ (**it_begin).getSuperStructure().communicate();
+ LoadBalancer<T>& 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<typename T, typename W>
+void SuperVTMwriter2D<T,W>::write(SuperF2D<T,W>& f, int iT)
+{
+ CuboidGeometry2D<T> const& cGeometry = f.getSuperStructure().getCuboidGeometry();
+ LoadBalancer<T>& 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<typename T, typename W>
+void SuperVTMwriter2D<T,W>::write(std::shared_ptr<SuperF2D<T,W>> ptr_f, int iT)
+{
+ write(*ptr_f, iT);
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::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<typename T, typename W>
+void SuperVTMwriter2D<T,W>::addFunctor(SuperF2D<T,W>& f)
+{
+ _pointerVec.push_back(&f);
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::clearAddedFunctors()
+{
+ _pointerVec.clear();
+}
+
+template<typename T, typename W>
+std::string SuperVTMwriter2D<T,W>::getName() const
+{
+ return _name;
+}
+
+
+
+
+////////////////////private member functions///////////////////////////////////
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::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 << "<?xml version=\"1.0\"?>\n";
+ fout << "<VTKFile type=\"ImageData\" version=\"0.1\" "
+ << "byte_order=\"LittleEndian\">\n";
+ fout << "<ImageData WholeExtent=\""
+ << x0 <<" "<< x1 <<" "
+ << y0 <<" "<< y1 <<" "
+ << 0 <<" "<< 0
+ << "\" Origin=\"" << originX << " " << originY << " " << "0"
+ << "\" Spacing=\"" << delta << " " << delta << " " << delta << "\">\n";
+ fout << "<Piece Extent=\""
+ << x0 <<" "<< x1 <<" "
+ << y0 <<" "<< y1 <<" "
+ << 0 <<" "<< 0 <<"\">\n";
+ fout << "<PointData>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::closeVTI(const std::string& fullNamePiece)
+{
+ std::ofstream fout(fullNamePiece, std::ios::app );
+ if (!fout) {
+ clout << "Error: could not open " << fullNamePiece << std::endl;
+ }
+ fout << "</ImageData>\n";
+ fout << "</VTKFile>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::preamblePVD(const std::string& fullNamePVD)
+{
+ std::ofstream fout(fullNamePVD, std::ios::trunc);
+ if (!fout) {
+ clout << "Error: could not open " << fullNamePVD << std::endl;
+ }
+ fout << "<?xml version=\"1.0\"?>\n";
+ fout << "<VTKFile type=\"Collection\" version=\"0.1\" "
+ << "byte_order=\"LittleEndian\">\n"
+ << "<Collection>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::closePVD(const std::string& fullNamePVD)
+{
+ std::ofstream fout(fullNamePVD, std::ios::app );
+ if (!fout) {
+ clout << "Error: could not open " << fullNamePVD << std::endl;
+ }
+ fout << "</Collection>\n";
+ fout << "</VTKFile>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::preambleVTM(const std::string& fullNamePVD)
+{
+ std::ofstream fout(fullNamePVD, std::ios::trunc);
+ if (!fout) {
+ clout << "Error: could not open " << fullNamePVD << std::endl;
+ }
+ fout << "<?xml version=\"1.0\"?>\n";
+ fout << "<VTKFile type=\"vtkMultiBlockDataSet\" version=\"1.0\" "
+ << "byte_order=\"LittleEndian\">\n"
+ << "<vtkMultiBlockDataSet>\n" ;
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::closeVTM(const std::string& fullNamePVD)
+{
+ std::ofstream fout(fullNamePVD, std::ios::app );
+ if (!fout) {
+ clout << "Error: could not open " << fullNamePVD << std::endl;
+ }
+ fout << "</vtkMultiBlockDataSet>\n";
+ fout << "</VTKFile>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::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 << "<Block index=\"" << iC << "\" >\n";
+ fout << "<DataSet index= \"0\" " << "file=\"" << namePiece << "\">\n"
+ << "</DataSet>\n";
+ fout << "</Block>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::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 << "<DataSet timestep=\"" << iT << "\" "
+ << "group=\"\" part=\"\" "
+ << "file=\"" << namePiece << "\"/>\n";
+ fout.close();
+ closePVD(fullNamePVDMaster);
+ } else {
+ clout << "Error: could not open " << fullNamePVDMaster << std::endl;
+ }
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::dataArray(const std::string& fullName,
+ SuperF2D<T,W>& 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 << "<DataArray " ;
+ fout << "type=\"Float32\" Name=\"" << f.getName() << "\" "
+ << "NumberOfComponents=\"" << f.getTargetDim() <<"\">\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<int> 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 << "</DataArray>\n";
+ fout.close();
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::dataArrayBinary(const std::string& fullName,
+ SuperF2D<T,W>& 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 << "<DataArray ";
+ fout << "type=\"Float32\" Name=\"" << f.getName() << "\" "
+ << "format=\"binary\" encoding=\"base64\" "
+ << "NumberOfComponents=\"" << f.getTargetDim() <<"\">\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<unsigned int> sizeEncoder(ofstr, 1);
+ unsigned int uintBinarySize = (unsigned int)binarySize;
+ sizeEncoder.encode(&uintBinarySize, 1);
+ // write numbers from functor
+ Base64Encoder<float>* dataEncoder = new Base64Encoder<float>( 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<float[]> 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</DataArray>\n";
+ ffout.close();
+ delete dataEncoder;
+}
+
+template<typename T, typename W>
+void SuperVTMwriter2D<T,W>::closePiece(const std::string& fullNamePiece)
+{
+ std::ofstream fout(fullNamePiece, std::ios::app );
+ if (!fout) {
+ clout << "Error: could not open " << fullNamePiece << std::endl;
+ }
+ fout << "</PointData>\n";
+ fout << "</Piece>\n";
+ fout.close();
+}
+
+
+} // namespace olb
+
+#endif