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/superVtmWriter3D.hh | 439 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 439 insertions(+)
create mode 100644 src/io/superVtmWriter3D.hh
(limited to 'src/io/superVtmWriter3D.hh')
diff --git a/src/io/superVtmWriter3D.hh b/src/io/superVtmWriter3D.hh
new file mode 100644
index 0000000..b5ad6a2
--- /dev/null
+++ b/src/io/superVtmWriter3D.hh
@@ -0,0 +1,439 @@
+/* This file is part of the OpenLB library
+ *
+ * Copyright (C) 2016-2017 Albert Mink, Maximilian Gaedtke, Markus Morhard 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_3D_HH
+#define SUPER_VTM_WRITER_3D_HH
+
+#include
+#include
+#include
+#include
+#include "core/singleton.h"
+#include "communication/loadBalancer.h"
+#include "geometry/cuboidGeometry3D.h"
+#include "communication/mpiManager.h"
+#include "io/fileName.h"
+#include "io/superVtmWriter3D.h"
+#include "io/base64.h"
+
+#include
+#include
+#include "zlib.h"
+
+
+
+namespace olb {
+
+
+template
+SuperVTMwriter3D::SuperVTMwriter3D( const std::string& name, bool binary, bool compress)
+ : clout( std::cout,"SuperVTMwriter3D" ), _createFile(false), _name(name), _binary(binary), _compress(compress)
+{}
+
+template
+void SuperVTMwriter3D::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
+ const auto it_begin = _pointerVec.cbegin();
+ CuboidGeometry3D const& cGeometry = (**it_begin).getSuperStructure().getCuboidGeometry();
+ // no gaps between vti files (cuboids)
+ (**it_begin).getSuperStructure().communicate();
+ LoadBalancer& load = (**it_begin).getSuperStructure().getLoadBalancer();
+ const T delta = cGeometry.getMotherCuboid().getDeltaR();
+
+ // PVD, owns all
+ if ( rank == 0 ) {
+ const std::string pathPVD = singleton::directories().getVtkOutDir()
+ + createFileName( _name ) + ".pvd";
+ dataPVDmaster( iT, pathPVD, "data/" + createFileName( _name, iT ) + ".vtm" );
+
+ const 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 its cuboids
+ for (int iCloc = 0; iCloc < load.size(); iCloc++) {
+ // get piece/whole extent
+ const Vector extent0(-1,-1,-1);
+ const Vector extent1( cGeometry.get(load.glob(iCloc)).getExtend() );
+
+ const std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/"
+ + createFileName( _name, iT, load.glob(iCloc) ) + ".vti";
+
+ // get dimension/extent for each cuboid
+ const int originLatticeR[4] = {load.glob(iCloc),0,0,0};
+ T originPhysR[3] = {T()};
+ cGeometry.getPhysR(originPhysR,originLatticeR);
+
+ preambleVTI(fullNameVTI, extent0, extent1, originPhysR, delta);
+ for (auto it : _pointerVec) {
+ dataArray(fullNameVTI, *it, load.glob(iCloc), extent1);
+ }
+ closePiece(fullNameVTI);
+ closeVTI(fullNameVTI);
+ }
+ }
+}
+
+template
+void SuperVTMwriter3D::write(SuperF3D& f, int iT)
+{
+ CuboidGeometry3D const& cGeometry = f.getSuperStructure().getCuboidGeometry();
+ LoadBalancer& load = f.getSuperStructure().getLoadBalancer();
+ // no gaps between vti files (cuboids)
+ f.getSuperStructure().communicate();
+ const 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
+ const std::string pathVTM = singleton::directories().getVtkOutDir()
+ + createFileName( f.getName(), iT ) + ".vtm";
+
+ preambleVTM(pathVTM);
+ for (int iC = 0; iC < cGeometry.getNc(); iC++) {
+ const 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++) {
+ // get piece/whole extent
+ const Vector extent0(-1,-1,-1);
+ const Vector extent1( cGeometry.get(load.glob(iCloc)).getExtend() );
+
+ const std::string fullNameVTI = singleton::directories().getVtkOutDir() + "data/"
+ + createFileName( f.getName(), iT, load.glob(iCloc) ) + ".vti";
+
+ // get dimension/extent for each cuboid
+ const int originLatticeR[4] = {load.glob(iCloc),0,0,0};
+ T originPhysR[3] = {T()};
+ cGeometry.getPhysR(originPhysR,originLatticeR);
+
+ preambleVTI(fullNameVTI, extent0, extent1, originPhysR, delta);
+
+ dataArray(fullNameVTI, f, load.glob(iCloc), extent1);
+ closePiece(fullNameVTI);
+ closeVTI(fullNameVTI);
+ } // cuboid
+}
+
+
+template
+void SuperVTMwriter3D::write(std::shared_ptr> ptr_f, int iT)
+{
+ write(*ptr_f, iT);
+}
+
+template
+void SuperVTMwriter3D::createMasterFile()
+{
+ int rank = 0;
+#ifdef PARALLEL_MODE_MPI
+ rank = singleton::mpi().getRank();
+#endif
+ if ( rank == 0 ) {
+ const std::string fullNamePVDmaster = singleton::directories().getVtkOutDir()
+ + createFileName( _name ) + ".pvd";
+ preamblePVD(fullNamePVDmaster);
+ closePVD(fullNamePVDmaster);
+ _createFile = true;
+ }
+}
+
+template
+void SuperVTMwriter3D::addFunctor(SuperF3D& f)
+{
+ _pointerVec.push_back(&f);
+}
+
+template
+void SuperVTMwriter3D::clearAddedFunctors()
+{
+ _pointerVec.clear();
+}
+
+template
+std::string SuperVTMwriter3D::getName() const
+{
+ return _name;
+}
+
+
+
+
+////////////////////private member functions///////////////////////////////////
+template
+void SuperVTMwriter3D::preambleVTI (const std::string& fullName,
+ const Vector extent0, const Vector extent1, T origin[], T delta)
+{
+ double d_delta = delta;
+ double d_origin[3] = {origin[0], origin[1], origin[2]};
+
+ std::ofstream fout(fullName, std::ios::trunc);
+ if (!fout) {
+ clout << "Error: could not open " << fullName << std::endl;
+ }
+ fout << "\n";
+ fout << "\n";
+ } else {
+ fout << "byte_order=\"LittleEndian\">\n";
+ }
+ fout << "\n";
+ fout << "\n";
+ fout << "\n";
+ fout.close();
+}
+
+template
+void SuperVTMwriter3D::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 SuperVTMwriter3D::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 SuperVTMwriter3D::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 SuperVTMwriter3D::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 SuperVTMwriter3D::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 SuperVTMwriter3D::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 SuperVTMwriter3D::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 SuperVTMwriter3D::dataArray(const std::string& fullName,
+ SuperF3D& f, int iC, const Vector extent1)
+{
+ std::ofstream fout( fullName, std::ios::out | std::ios::app );
+ if (!fout) {
+ clout << "Error: could not open " << fullName << std::endl;
+ }
+
+ fout << "\n";
+ } else {
+ fout << ">\n";
+ }
+
+ int i[4] = {iC, 0, 0, 0};
+ W evaluated[f.getTargetDim()];
+ for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
+ evaluated[iDim] = W();
+ }
+
+ size_t numberOfFloats = f.getTargetDim() * (extent1[0]+2) * (extent1[1]+2) * (extent1[2]+2);
+ uint32_t binarySize = static_cast( numberOfFloats*sizeof(float) );
+
+ std::unique_ptr streamFloat(new float[numberOfFloats]); // stack may be too small
+ int itter = 0;
+ // fill buffer with functor data
+ for (i[3] = -1; i[3] < extent1[2]+1; ++i[3]) {
+ for (i[2] = -1; i[2] < extent1[1]+1; ++i[2]) {
+ for (i[1] = -1; i[1] < extent1[0]+1; ++i[1]) {
+ f(evaluated,i);
+ for (int iDim = 0; iDim < f.getTargetDim(); ++iDim) {
+ streamFloat[itter] = float( evaluated[iDim] );
+ ++itter;
+ }
+ }
+ }
+ }
+
+ if (_compress) {
+ // char buffer for functor data
+ const unsigned char* charData = reinterpret_cast(streamFloat.get());
+ // buffer for compression
+ std::unique_ptr comprData(new unsigned char[ binarySize ]); // stack may be too small
+
+ // compress data (not yet decoded as base64) by zlib
+ uLongf sizeCompr = compressBound(binarySize);
+ compress2( comprData.get(), &sizeCompr, charData, binarySize, -1);
+
+ // encode prefix to base64 documented in http://www.earthmodels.org/software/vtk-and-paraview/vtk-file-formats
+ Base64Encoder prefixEncoder(fout, 4);
+ uint32_t prefix[4] = {1,binarySize,binarySize,static_cast(sizeCompr)};
+ prefixEncoder.encode(prefix, 4);
+
+ // encode compressed data to base64
+ Base64Encoder dataEncoder( fout, sizeCompr );
+ dataEncoder.encode(comprData.get(), sizeCompr);
+ } else if(_binary) {
+ // encode prefix to base64 documented in http://www.earthmodels.org/software/vtk-and-paraview/vtk-file-formats
+ Base64Encoder prefixEncoder(fout, 1);
+ prefixEncoder.encode(&binarySize, 1);
+ // write numbers from functor
+ Base64Encoder dataEncoder(fout, numberOfFloats);
+ dataEncoder.encode(streamFloat.get(),numberOfFloats);
+ } else {
+ for( size_t iOut = 0; iOut < numberOfFloats; ++iOut ) {
+ fout << streamFloat[iOut] << " ";
+ }
+ }
+ fout.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();
+}
+
+template
+void SuperVTMwriter3D::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