VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
AnalyticalResults2DToVTKWriterImp.cpp
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
32//=======================================================================================
34
35#include <cmath>
36#include <fstream>
37#include <sstream>
38#include <stdio.h>
39
41
42#include "Parameter/Parameter.h"
43
45#include "lbm/constants/D3Q27.h"
46
48
50#include <mpi.h>
52
53using namespace vf::gpu;
54
55std::shared_ptr<AnalyticalResults2DToVTKWriterImp>
57{
58 static std::shared_ptr<AnalyticalResults2DToVTKWriterImp> uniqueInstance;
59 if (!uniqueInstance)
60 uniqueInstance = std::shared_ptr<AnalyticalResults2DToVTKWriterImp>(
61 new AnalyticalResults2DToVTKWriterImp(writeAnalyticalResults));
62 return uniqueInstance;
63}
64
65AnalyticalResults2DToVTKWriterImp::AnalyticalResults2DToVTKWriterImp(bool writeAnalyticalResults)
66 : writeAnalyticalResults(writeAnalyticalResults)
67{
68}
69
71 std::shared_ptr<AnalyticalResults> analyticalResult)
72{
73 if (writeAnalyticalResults) {
74 std::cout << "Write Analytical Result To VTK-Files" << std::endl;
75 for (int level = para->getCoarse(); level <= para->getFine(); level++) {
76#pragma omp parallel for
77 for (int timeStep = 0; timeStep < analyticalResult->getNumberOfTimeSteps(); timeStep++) {
78 const unsigned int numberOfParts = FilePartCalculator::calculateNumberOfParts(para->getParH(level)->numberOfNodes);
79 std::vector<std::string> fname;
80 unsigned int time =
81 analyticalResult->getTimeSteps().at(timeStep) * analyticalResult->getTimeStepLength();
82 for (int j = 1; j <= numberOfParts; j++) {
83 std::string filePath = para->getFName();
84 filePath.resize(filePath.size() - 5);
85 fname.push_back(filePath + "AnalyticalResult/Analytical_cells_bin_lev_" +
86 StringUtil::toString<int>(level) + "_ID_" +
87 StringUtil::toString<int>(para->getMyProcessID()) + "_Part_" +
88 StringUtil::toString<int>(j) + "_t_" + StringUtil::toString<int>(time) + ".vtk");
89 }
90 std::cout << "\t Write TimeStep=" << timeStep << " t=" << time << "...";
91 writeTimeStep(para, analyticalResult, level, fname, timeStep);
92 std::cout << "done." << std::endl;
93 }
94 }
95 std::cout << std::endl;
96 }
97}
98
99void AnalyticalResults2DToVTKWriterImp::writeTimeStep(std::shared_ptr<Parameter> para,
100 std::shared_ptr<AnalyticalResults> analyticalResult, int level,
101 std::vector<std::string> &fname, int timeStep)
102{
103 std::vector<UbTupleFloat3> nodes;
104 std::vector<UbTupleUInt8> cells;
105 std::vector<std::string> nodedatanames;
106 nodedatanames.push_back("press");
107 nodedatanames.push_back("rho");
108 nodedatanames.push_back("vx1");
109 nodedatanames.push_back("vx2");
110 nodedatanames.push_back("vx3");
111 nodedatanames.push_back("geo");
113 uint dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
115 unsigned int startpos = 0;
116 unsigned int endpos = 0;
117 unsigned int sizeOfNodes = 0;
118 std::vector<std::vector<double>> nodedata(nodedatanames.size());
119
120 maxX = para->getGridX().at(level);
121 maxY = para->getGridY().at(level);
122 maxZ = para->getGridZ().at(level);
123
124 std::vector<double> press = analyticalResult->getPress()[timeStep];
125 std::vector<double> rho = analyticalResult->getRho()[timeStep];
126 std::vector<double> vx = analyticalResult->getVx()[timeStep];
127 std::vector<double> vy = analyticalResult->getVy()[timeStep];
128 std::vector<double> vz = analyticalResult->getVz()[timeStep];
129
130 for (unsigned int part = 0; part < fname.size(); part++) {
131 sizeOfNodes = FilePartCalculator::calculateNumberOfNodesInPart(para->getParH(level)->numberOfNodes, part);
132
137 cells.clear();
138 nodes.resize(sizeOfNodes);
139 nodedata[0].resize(sizeOfNodes);
140 nodedata[1].resize(sizeOfNodes);
141 nodedata[2].resize(sizeOfNodes);
142 nodedata[3].resize(sizeOfNodes);
143 nodedata[4].resize(sizeOfNodes);
144 nodedata[5].resize(sizeOfNodes);
146 for (unsigned int pos = startpos; pos < endpos; pos++) {
147 std::cout << "BEGIN POS: " << pos << std::endl;
148 if (para->getParH(level)->typeOfGridNode[pos] == GEO_FLUID) {
150 double x1 = para->getParH(level)->coordinateX[pos];
151 double x2 = para->getParH(level)->coordinateY[pos];
152 double x3 = para->getParH(level)->coordinateZ[pos];
154 number1 = pos;
155 dn1 = pos - startpos;
156 neighborsAreFluid = true;
158 nodes[dn1] = (makeUbTuple((float)(x1), (float)(x2), (float)(x3)));
159
160 int numberInResults = CoordResults2DTo1D(x1 - 1.0, x3 - 1.0);
161 nodedata[0][dn1] = press[numberInResults];
162 nodedata[1][dn1] = rho[numberInResults];
163 nodedata[2][dn1] = vx[numberInResults];
164 nodedata[3][dn1] = vy[numberInResults];
165 nodedata[4][dn1] = vz[numberInResults];
166 nodedata[5][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
168 number2 = para->getParH(level)->neighborX[number1];
169 number3 = para->getParH(level)->neighborY[number2];
170 number4 = para->getParH(level)->neighborY[number1];
171 number5 = para->getParH(level)->neighborZ[number1];
172 number6 = para->getParH(level)->neighborZ[number2];
173 number7 = para->getParH(level)->neighborZ[number3];
174 number8 = para->getParH(level)->neighborZ[number4];
175 std::cout << "NeighborIndex1 " << number1 << std::endl <<
176 "NeighborIndex2 " << number2 << std::endl <<
177 "NeighborIndex3 " << number3 << std::endl <<
178 "NeighborIndex4 " << number4 << std::endl <<
179 "NeighborIndex5 " << number5 << std::endl <<
180 "NeighborIndex6 " << number6 << std::endl <<
181 "NeighborIndex7 " << number7 << std::endl <<
182 "NeighborIndex8 " << number8 << std::endl;
184 auto neighbor1 = para->getParH(level)->typeOfGridNode[number2];
185 auto neighbor2 = para->getParH(level)->typeOfGridNode[number3];
186 auto neighbor3 = para->getParH(level)->typeOfGridNode[number4];
187 auto neighbor4 = para->getParH(level)->typeOfGridNode[number5]; //breaks!
188 auto neighbor5 = para->getParH(level)->typeOfGridNode[number6];
189 auto neighbor6 = para->getParH(level)->typeOfGridNode[number7];
190 auto neighbor7 = para->getParH(level)->typeOfGridNode[number8];
191 std::cout << "Neighbor1 " << neighbor1 << std::endl <<
192 "Neighbor2 " << neighbor2 << std::endl <<
193 "Neighbor3 " << neighbor3 << std::endl <<
194 "Neighbor4 " << neighbor4 << std::endl <<
195 "Neighbor5 " << neighbor5 << std::endl <<
196 "Neighbor6 " << neighbor6 << std::endl <<
197 "Neighbor7 " << neighbor7 << std::endl;
198
199 if (para->getParH(level)->typeOfGridNode[number2] != GEO_FLUID ||
200 para->getParH(level)->typeOfGridNode[number3] != GEO_FLUID ||
201 para->getParH(level)->typeOfGridNode[number4] != GEO_FLUID ||
202 para->getParH(level)->typeOfGridNode[number5] != GEO_FLUID ||
203 para->getParH(level)->typeOfGridNode[number6] != GEO_FLUID ||
204 para->getParH(level)->typeOfGridNode[number7] != GEO_FLUID ||
205 para->getParH(level)->typeOfGridNode[number8] != GEO_FLUID)
206 neighborsAreFluid = false;
210 neighborsAreFluid = false;
212 dn2 = number2 - startpos;
213 dn3 = number3 - startpos;
214 dn4 = number4 - startpos;
215 dn5 = number5 - startpos;
216 dn6 = number6 - startpos;
217 dn7 = number7 - startpos;
218 dn8 = number8 - startpos;
221 cells.push_back(makeUbTuple(dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8));
222 std::cout << "END POS: " << pos << std::endl;
223 }
224 }
226 }
227}
228
229int AnalyticalResults2DToVTKWriterImp::CoordResults2DTo1D(int x, int z)
230{
231 return z * (maxX - 1) + x;
232}
233
static WbWriterVtkXmlBinary * getInstance()
static uint calculateNumberOfParts(uint numberOfNodes)
calculate how many output vtk-files are created for one timestep of the given grid level
static uint calculateStartingPostionOfPart(uint indexOfPart)
static uint calculateNumberOfNodesInPart(uint numberOfNodes, uint indexOfFilePart)
calculate how many grid nodes are written to the file with the given index
static std::shared_ptr< AnalyticalResults2DToVTKWriterImp > getInstance(bool writeAnalyticalResults)
void writeAnalyticalResult(std::shared_ptr< vf::gpu::Parameter > para, std::shared_ptr< AnalyticalResults > analyticalResult)
std::shared_ptr< T > SPtr
unsigned int uint
Definition DataTypes.h:47
@ z
Definition Axis.h:44
@ x
Definition Axis.h:42
#define GEO_FLUID
Definition Calculation.h:45
UbTuple< T1 > makeUbTuple(T1 const &a1)
Definition UbTuple.h:542
std::string writeOctsWithNodeData(const std::string &filename, std::vector< UbTupleFloat3 > &nodes, std::vector< UbTupleUInt8 > &cells, std::vector< std::string > &datanames, std::vector< std::vector< double > > &nodedata) override