VM2D  1.12
Vortex methods for 2D flows simulation
WakeDataBase2D.cpp
Go to the documentation of this file.
1 /*--------------------------------*- VM2D -*-----------------*---------------*\
2 | ## ## ## ## #### ##### | | Version 1.12 |
3 | ## ## ### ### ## ## ## ## | VM2D: Vortex Method | 2024/01/14 |
4 | ## ## ## # ## ## ## ## | for 2D Flow Simulation *----------------*
5 | #### ## ## ## ## ## | Open Source Code |
6 | ## ## ## ###### ##### | https://www.github.com/vortexmethods/VM2D |
7 | |
8 | Copyright (C) 2017-2024 I. Marchevsky, K. Sokol, E. Ryatina, A. Kolganova |
9 *-----------------------------------------------------------------------------*
10 | File name: WakeDataBase2D.cpp |
11 | Info: Source code of VM2D |
12 | |
13 | This file is part of VM2D. |
14 | VM2D is free software: you can redistribute it and/or modify it |
15 | under the terms of the GNU General Public License as published by |
16 | the Free Software Foundation, either version 3 of the License, or |
17 | (at your option) any later version. |
18 | |
19 | VM2D is distributed in the hope that it will be useful, but WITHOUT |
20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
22 | for more details. |
23 | |
24 | You should have received a copy of the GNU General Public License |
25 | along with VM2D. If not, see <http://www.gnu.org/licenses/>. |
26 \*---------------------------------------------------------------------------*/
27 
28 
40 #include "WakeDataBase2D.h"
41 
42 #include "Airfoil2D.h"
43 #include "Boundary2D.h"
44 #include "MeasureVP2D.h"
45 #include "Mechanics2D.h"
46 #include "Passport2D.h"
47 #include "Preprocessor.h"
48 #include "StreamParser.h"
49 #include "Velocity2D.h"
50 #include "Wake2D.h"
51 #include "World2D.h"
52 
53 using namespace VM2D;
54 
55 //Считывание вихревого следа из файла
56 void WakeDataBase::ReadFromFile(const std::string& dir, const std::string& fileName)
57 {
58  std::string filename = dir + fileName;
59  std::ifstream wakeFile;
60 
61  if (fileExistTest(filename, W.getInfo(), { "txt", "TXT" }))
62  {
63  std::stringstream wakeFile(VMlib::Preprocessor(filename).resultString);
64 
65  VMlib::LogStream XXX;
66  VMlib::StreamParser wakeParser(XXX, "vortex wake file parser", wakeFile);
67 
68  wakeParser.get("vtx", vtx);
69  }
70 }//ReadFromFile(...)
71 
72 
73 void WakeDataBase::SaveKadrVtk(const std::string& filePrefix) const
74 {
75  W.getTimestat().timeSaveKadr.first += omp_get_wtime();
76 
78  {
79  std::ofstream outfile;
80  size_t numberNonZero = 0;
81 
82  if (vtx.size() > 0)
83  numberNonZero += vtx.size();
84  else
85  for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
86  numberNonZero += W.getAirfoil(q).getNumberOfPanels();
87  VMlib::CreateDirectory(W.getPassport().dir, "snapshots");
88 
89  if (W.getPassport().timeDiscretizationProperties.fileTypeVtx.second == 0) //text format vtk
90  {
91  std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "vtk");
92  outfile.open(W.getPassport().dir + "snapshots/" + fname);
93 
94  outfile << "# vtk DataFile Version 2.0" << std::endl;
95  outfile << "VM2D VTK result: " << (W.getPassport().dir + "snapshots/" + fname).c_str() << " saved " << VMlib::CurrentDataTime() << std::endl;
96  outfile << "ASCII" << std::endl;
97  outfile << "DATASET UNSTRUCTURED_GRID" << std::endl;
98  outfile << "POINTS " << numberNonZero << " float" << std::endl;
99 
100  if (vtx.size() > 0)
101  for (auto& v : vtx)
102  {
103  const Point2D& r = v.r();
104  outfile << r[0] << " " << r[1] << " " << "0.0" << std::endl;
105  }//for v
106  else
107  for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
108  for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
109  {
110  const Point2D& r = W.getAirfoil(q).getR(s);
111  outfile << r[0] << " " << r[1] << " " << "0.0" << std::endl;
112  }
113 
114  outfile << "CELLS " << numberNonZero << " " << 2 * numberNonZero << std::endl;
115  for (size_t i = 0; i < numberNonZero; ++i)
116  outfile << "1 " << i << std::endl;
117 
118  outfile << "CELL_TYPES " << numberNonZero << std::endl;
119  for (size_t i = 0; i < numberNonZero; ++i)
120  outfile << "1" << std::endl;
121 
122  outfile << std::endl;
123  outfile << "POINT_DATA " << numberNonZero << std::endl;
124  outfile << "SCALARS Gamma float 1" << std::endl;
125  outfile << "LOOKUP_TABLE default" << std::endl;
126 
127  if (vtx.size() > 0)
128  for (auto& v : vtx)
129  outfile << v.g() << std::endl;
130  else
131  for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
132  for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
133  {
134  //const Point2D& r = W.getAirfoil(q).getR(s);
135  outfile << "0.0" << std::endl;
136  }
137 
138  outfile.close();
139  }//if fileType = text
140  else if (W.getPassport().timeDiscretizationProperties.fileTypeVtx.second == 1) //binary format vtk
141  {
142  //Тест способа хранения чисел
143  uint16_t x = 0x0001;
144  bool littleEndian = (*((uint8_t*)&x));
145  const char eolnBIN[] = "\n";
146 
147  std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "vtk");
148  outfile.open(W.getPassport().dir + "snapshots/" + fname, std::ios::out | std::ios::binary);
149 
150  outfile << "# vtk DataFile Version 3.0" << "\r\n" << "VM2D VTK result: " << (W.getPassport().dir + "snapshots/" + fname).c_str() << " saved " << VMlib::CurrentDataTime() << eolnBIN;
151  outfile << "BINARY" << eolnBIN;
152  outfile << "DATASET UNSTRUCTURED_GRID" << eolnBIN << "POINTS " << numberNonZero << " " << "float" << eolnBIN;
153 
154 
155  if (vtx.size() > 0)
156  {
157  Eigen::VectorXf rData = Eigen::VectorXf::Zero(vtx.size() * 3);
158  for (size_t i = 0; i < vtx.size(); ++i)
159  {
160  rData(3 * i) = (float)(vtx[i].r())[0];
161  rData(3 * i + 1) = (float)(vtx[i].r())[1];
162  }//for i
163 
164  if (littleEndian)
165  for (int i = 0; i < vtx.size() * 3; ++i)
166  VMlib::SwapEnd(rData(i));
167  outfile.write(reinterpret_cast<char*>(rData.data()), vtx.size() * 3 * sizeof(float));
168  }
169  else
170  for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
171  {
172  Eigen::VectorXf rData = Eigen::VectorXf::Zero(W.getAirfoil(q).getNumberOfPanels() * 3);
173  for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
174  {
175  rData(3 * s) = (float)(W.getAirfoil(q).getR(s))[0];
176  rData(3 * s + 1) = (float)(W.getAirfoil(q).getR(s))[1];
177  }//for i
178 
179  if (littleEndian)
180  for (int i = 0; i < W.getAirfoil(q).getNumberOfPanels() * 3; ++i)
181  VMlib::SwapEnd(rData(i));
182  outfile.write(reinterpret_cast<char*>(rData.data()), W.getAirfoil(q).getNumberOfPanels() * 3 * sizeof(float));
183  }
184 
185  // CELLS
186  std::vector<int> cells(2 * numberNonZero);
187  for (size_t i = 0; i < numberNonZero; ++i)
188  {
189  cells[2 * i] = 1;
190  cells[2 * i + 1] = (int)i;
191  }
192 
193  std::vector<int> cellsTypes;
194  cellsTypes.resize(numberNonZero, 1);
195 
196  if (littleEndian)
197  {
198  for (int i = 0; i < numberNonZero * 2; ++i)
199  VMlib::SwapEnd(cells[i]);
200 
201  for (int i = 0; i < numberNonZero; ++i)
202  VMlib::SwapEnd(cellsTypes[i]);
203  }
204 
205  outfile << eolnBIN << "CELLS " << numberNonZero << " " << numberNonZero * 2 << eolnBIN;
206  outfile.write(reinterpret_cast<char*>(cells.data()), numberNonZero * 2 * sizeof(int));
207  outfile << eolnBIN << "CELL_TYPES " << numberNonZero << eolnBIN;
208  outfile.write(reinterpret_cast<char*>(cellsTypes.data()), numberNonZero * sizeof(int));
209 
210  //gammas
211  outfile << eolnBIN << "POINT_DATA " << numberNonZero << eolnBIN;
212  outfile << eolnBIN << "SCALARS Gamma " << "float" << " 1" << eolnBIN;
213  outfile << "LOOKUP_TABLE default" << eolnBIN;
214 
215  if (vtx.size() > 0)
216  {
217  Eigen::VectorXf pData = Eigen::VectorXf::Zero(numberNonZero);
218  for (int s = 0; s < vtx.size(); ++s)
219  pData(s) = (float)vtx[s].g();
220 
221  if (littleEndian)
222  for (int i = 0; i < vtx.size(); ++i)
223  VMlib::SwapEnd(pData(i));
224  outfile.write(reinterpret_cast<char*>(pData.data()), vtx.size() * sizeof(float));
225  }
226  else
227  for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
228  {
229  Eigen::VectorXf pData = Eigen::VectorXf::Zero(W.getAirfoil(q).getNumberOfPanels());
230  for (int s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
231  pData(s) = 0;
232 
233  if (littleEndian)
234  for (int i = 0; i < W.getAirfoil(q).getNumberOfPanels(); ++i)
235  VMlib::SwapEnd(pData(i));
236  outfile.write(reinterpret_cast<char*>(pData.data()), W.getAirfoil(q).getNumberOfPanels() * sizeof(float));
237  }
238 
239  outfile << eolnBIN;
240  outfile.close();
241  }//if binary
242  if (W.getPassport().timeDiscretizationProperties.fileTypeVtx.second == 2) //csv
243  {
244  std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "csv");
245  outfile.open(W.getPassport().dir + "snapshots/" + fname);
246 
247  outfile << "point,x,y,G " << std::endl;
248 
249  int counter = 0;
250  if (vtx.size() > 0)
251  for (auto& v : vtx)
252  outfile << counter++ << "," << v.r()[0] << "," << v.r()[1] << "," << v.g() << std::endl;
253  else
254  for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
255  for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
256  {
257  const Point2D& r = W.getAirfoil(q).getR(s);
258  outfile << counter++ << "," << r[0] << "," << r[1] << "," << "0.0" << std::endl;
259  }
260  outfile.close();
261  }//if fileType = text
262 
263  }
264 
265  W.getTimestat().timeSaveKadr.second += omp_get_wtime();
266 }//SaveKadrVtk()
Заголовочный файл с описанием класса Passport (двумерный) и cоответствующими структурами ...
Times & getTimestat() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
Definition: World2D.h:242
int saveVtxStep
Шаг сохранения кадров в бинарные файлы
Definition: PassportGen.h:73
std::string CurrentDataTime()
Формирование строки с текущем временем и датой
Definition: defs.cpp:44
Класс, определяющий работу с потоком логов
Definition: LogStream.h:53
Заголовочный файл с описанием класса Wake.
void ReadFromFile(const std::string &dir, const std::string &fileName)
Считывание вихревого следа из файла
Заголовочный файл с описанием класса World2D.
int nameLength
Число разрядов в имени файла
Definition: PassportGen.h:68
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса WakeDataBase.
std::string dir
Рабочий каталог задачи
Definition: PassportGen.h:118
Заголовочный файл с описанием класса Preprocessor.
Класс, позволяющий выполнять предварительную обработку файлов
Definition: Preprocessor.h:59
Заголовочный файл с описанием класса Mechanics.
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition: Airfoil2D.h:101
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition: Airfoil2D.h:139
void SaveKadrVtk(const std::string &filePrefix="Kadr") const
Сохранение вихревого следа в файл .vtk.
std::string fileNameStep(const std::string &name, int length, size_t number, const std::string &ext)
Формирование имени файла
Definition: defs.h:357
bool ifDivisible(int val) const
Definition: World2D.h:244
timePeriod timeSaveKadr
Начало и конец процесса сохранения кадра в файл
Definition: Times2D.h:107
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
Definition: PassportGen.h:127
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Definition: World2D.h:147
Definition: Airfoil2D.h:45
Заголовочный файл с описанием класса StreamParser.
std::vector< Vortex2D > vtx
Список вихревых элементов
const World2D & W
Константная ссылка на решаемую задачу
Класс, опеделяющий двумерный вектор
Definition: Point2D.h:75
bool fileExistTest(std::string &fileName, LogStream &info, const std::list< std::string > &extList={})
Проверка существования файла
Definition: defs.h:324
VMlib::LogStream & getInfo() const
Возврат ссылки на объект LogStream Используется в техничеcких целях для организации вывода ...
Definition: WorldGen.h:74
Заголовочный файл с описанием класса MeasureVP.
std::pair< std::string, int > fileTypeVtx
Тип файлов для сохранения скорости и давления
Definition: PassportGen.h:71
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition: World2D.h:222
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
Definition: WorldGen.h:91
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition: World2D.h:130
Заголовочный файл с описанием класса Velocity.
void SwapEnd(T &var)
Вспомогательная функция перестановки байт местами (нужно для сохранения бинарных VTK) ...
Definition: defs.h:528
void CreateDirectory(const std::string &dir, const std::string &name)
Создание каталога
Definition: defs.h:414
Класс, позволяющий выполнять разбор файлов и строк с настройками и параметрами
Definition: StreamParser.h:151
bool get(const std::string &name, std::vector< Point2D > &res, const std::vector< Point2D > *defValue=nullptr, bool echoDefault=true) const
Считывание вектора из двумерных точек из базы данных
Definition: StreamParser.h:314
Заголовочный файл с описанием класса Boundary.