VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
WakeDataBase2D.cpp
Go to the documentation of this file.
1/*--------------------------------*- VM2D -*-----------------*---------------*\
2| ## ## ## ## #### ##### | | Version 1.14 |
3| ## ## ### ### ## ## ## ## | VM2D: Vortex Method | 2026/03/06 |
4| ## ## ## # ## ## ## ## | for 2D Flow Simulation *----------------*
5| #### ## ## ## ## ## | Open Source Code |
6| ## ## ## ###### ##### | https://www.github.com/vortexmethods/VM2D |
7| |
8| Copyright (C) 2017-2026 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 "Preprocessor.h"
47#include "StreamParser.h"
48#include "Velocity2D.h"
49#include "Wake2D.h"
50#include "World2D.h"
51#include "Gmres2D.h"
52
53using namespace VM2D;
54
55//Считывание вихревого следа из файла
56void WakeDataBase::ReadFromFile(const std::string& dir, const std::string& fileName)
57{
58 std::string filename = dir + fileName;
59 std::ifstream wakeFile, testFile;
60
61 char firstChar = '/', secondChar = '*';
62
63 if (fileExistTest(filename, W.getInfo(), true, { "txt", "TXT" }))
64 {
65 testFile.open(filename);
66 testFile >> firstChar;
67 testFile >> secondChar;
68
69 //std::cout << "CHARS: " << firstChar << " " << secondChar << std::endl;
70 testFile.close();
71 }
72
73
74 //Считывание из словаря
75 if (firstChar == '/' && secondChar == '*')
76 {
77 if (fileExistTest(filename, W.getInfo(), true, { "txt", "TXT" }))
78 {
79 std::stringstream wakeFile(VMlib::Preprocessor(filename).resultString);
80
82 VMlib::StreamParser wakeParser(XXX, "vortex wake file parser", wakeFile);
83
84 wakeParser.get("vtx", vtx);
85
86 for (auto& v : vtx)
88
89 }
90 }
91 else
92 {
93 //Считывание из обычного текстового файла
94 if (fileExistTest(filename, W.getInfo(), true, { "txt", "TXT" }))
95 {
96 wakeFile.open(filename);
97 int nnn;
98 wakeFile >> nnn;
99 vtx.reserve(nnn);
100 for (int i = 0; i < nnn; ++i)
101 {
102 Vortex2D v;
103 wakeFile >> v.r()[0] >> v.r()[1] >> v.g();
105 vtx.push_back(v);
106 }
107
108 wakeFile.close();
109 }
110 }
111
112}//ReadFromFile(...)
113
114
115void WakeDataBase::SaveKadrVtk(const std::string& filePrefix) const
116{
117 W.getTimers().start("Save");
118
120 {
121 std::ofstream outfile;
122 size_t numberNonZero = 0;
123
124 if (vtx.size() > 0)
125 numberNonZero += vtx.size();
126 else
127 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
128 numberNonZero += W.getAirfoil(q).getNumberOfPanels();
130
131 if (W.getPassport().timeDiscretizationProperties.fileTypeVtx.second == 0) //text format vtk
132 {
133 std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "vtk");
134 outfile.open(W.getPassport().dir + "snapshots/" + fname);
135
136 outfile << "# vtk DataFile Version 2.0\n";
137 outfile << "VM2D VTK result: " << (W.getPassport().dir + "snapshots/" + fname).c_str() << " saved " << VMlib::CurrentDataTime() << '\n';
138 outfile << "ASCII\n";
139 outfile << "DATASET UNSTRUCTURED_GRID\n";
140 outfile << "POINTS " << numberNonZero << " float\n";
141
142
143 if (vtx.size() > 0)
144 for (auto& v : vtx)
145 {
146 const Point2D& r = v.r();
147 outfile << r[0] << " " << r[1] << " " << "0.0\n";
148 }//for v
149 else
150 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
151 for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
152 {
153 const Point2D& r = W.getAirfoil(q).getR(s);
154 outfile << r[0] << " " << r[1] << " " << "0.0\n";
155 }
156
157 outfile << "CELLS " << numberNonZero << " " << 2 * numberNonZero << '\n';
158 for (size_t i = 0; i < numberNonZero; ++i)
159 outfile << "1 " << i << '\n';
160
161 outfile << "CELL_TYPES " << numberNonZero << '\n';
162 for (size_t i = 0; i < numberNonZero; ++i)
163 outfile << "1\n";
164
165 outfile << '\n';
166 outfile << "POINT_DATA " << numberNonZero << '\n';
167 outfile << "SCALARS Gamma float 1\n";
168 outfile << "LOOKUP_TABLE default\n";
169
170 if (vtx.size() > 0)
171 for (auto& v : vtx)
172 outfile << v.g() << '\n';
173 else
174 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
175 for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
176 outfile << "0.0\n";
177
178 outfile << "SCALARS Sigma float 1\n";
179 outfile << "LOOKUP_TABLE default\n";
180
181 if (vtx.size() > 0)
182 for (auto& v : vtx)
183 outfile << v.sigma() << '\n';
184 else
185 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
186 for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
187 outfile << "0.0\n";
188
189#ifdef TURB
190 outfile << "SCALARS nut float 1\n";
191 outfile << "LOOKUP_TABLE default\n";
192
193 if (vtx.size() > 0)
194 for (auto& v : vtx)
195 outfile << sqr(v.sigma() / 4.48) / W.getPassport().timeDiscretizationProperties.dt - W.getPassport().physicalProperties.nu << '\n';
196 else
197 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
198 for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
199 outfile << "0.0\n";
200#endif
201
202
203 outfile.close();
204 }//if fileType = text
205 else if (W.getPassport().timeDiscretizationProperties.fileTypeVtx.second == 1) //binary format vtk
206 {
207 //Тест способа хранения чисел
208 uint16_t x = 0x0001;
209 bool littleEndian = (*((uint8_t*)&x));
210 const char eolnBIN[] = "\n";
211
212 std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "vtk");
213 outfile.open(W.getPassport().dir + "snapshots/" + fname, std::ios::out | std::ios::binary);
214
215 outfile << "# vtk DataFile Version 3.0" << "\r\n" << "VM2D VTK result: " << (W.getPassport().dir + "snapshots/" + fname).c_str() << " saved " << VMlib::CurrentDataTime() << eolnBIN;
216 outfile << "BINARY" << eolnBIN;
217 outfile << "DATASET UNSTRUCTURED_GRID" << eolnBIN << "POINTS " << numberNonZero << " " << "float" << eolnBIN;
218
219 if (vtx.size() > 0)
220 {
221 Eigen::VectorXf rData = Eigen::VectorXf::Zero(vtx.size() * 3);
222 for (size_t i = 0; i < vtx.size(); ++i)
223 {
224 rData(3 * i) = (float)(vtx[i].r())[0];
225 rData(3 * i + 1) = (float)(vtx[i].r())[1];
226 }//for i
227
228 if (littleEndian)
229 for (int i = 0; i < vtx.size() * 3; ++i)
230 VMlib::SwapEnd(rData(i));
231 outfile.write(reinterpret_cast<char*>(rData.data()), vtx.size() * 3 * sizeof(float));
232 }
233 else
234 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
235 {
236 Eigen::VectorXf rData = Eigen::VectorXf::Zero(W.getAirfoil(q).getNumberOfPanels() * 3);
237 for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
238 {
239 rData(3 * s) = (float)(W.getAirfoil(q).getR(s))[0];
240 rData(3 * s + 1) = (float)(W.getAirfoil(q).getR(s))[1];
241 }//for i
242
243 if (littleEndian)
244 for (int i = 0; i < W.getAirfoil(q).getNumberOfPanels() * 3; ++i)
245 VMlib::SwapEnd(rData(i));
246 outfile.write(reinterpret_cast<char*>(rData.data()), W.getAirfoil(q).getNumberOfPanels() * 3 * sizeof(float));
247 }
248
249 // CELLS
250 std::vector<int> cells(2 * numberNonZero);
251 for (size_t i = 0; i < numberNonZero; ++i)
252 {
253 cells[2 * i] = 1;
254 cells[2 * i + 1] = (int)i;
255 }
256
257 std::vector<int> cellsTypes;
258 cellsTypes.resize(numberNonZero, 1);
259
260 if (littleEndian)
261 {
262 for (int i = 0; i < numberNonZero * 2; ++i)
263 VMlib::SwapEnd(cells[i]);
264
265 for (int i = 0; i < numberNonZero; ++i)
266 VMlib::SwapEnd(cellsTypes[i]);
267 }
268
269 outfile << eolnBIN << "CELLS " << numberNonZero << " " << numberNonZero * 2 << eolnBIN;
270 outfile.write(reinterpret_cast<char*>(cells.data()), numberNonZero * 2 * sizeof(int));
271 outfile << eolnBIN << "CELL_TYPES " << numberNonZero << eolnBIN;
272 outfile.write(reinterpret_cast<char*>(cellsTypes.data()), numberNonZero * sizeof(int));
273
274 //gammas
275 outfile << eolnBIN << "POINT_DATA " << numberNonZero << eolnBIN;
276 outfile << eolnBIN << "SCALARS Gamma " << "float" << " 1" << eolnBIN;
277 outfile << "LOOKUP_TABLE default" << eolnBIN;
278
279 if (vtx.size() > 0)
280 {
281 Eigen::VectorXf pData = Eigen::VectorXf::Zero(numberNonZero);
282 for (int s = 0; s < vtx.size(); ++s)
283 pData(s) = (float)vtx[s].g();
284
285 if (littleEndian)
286 for (int i = 0; i < vtx.size(); ++i)
287 VMlib::SwapEnd(pData(i));
288 outfile.write(reinterpret_cast<char*>(pData.data()), vtx.size() * sizeof(float));
289 }
290 else
291 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
292 {
293 Eigen::VectorXf pData = Eigen::VectorXf::Zero(W.getAirfoil(q).getNumberOfPanels());
294 for (int s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
295 pData(s) = 0;
296
297 if (littleEndian)
298 for (int i = 0; i < W.getAirfoil(q).getNumberOfPanels(); ++i)
299 VMlib::SwapEnd(pData(i));
300 outfile.write(reinterpret_cast<char*>(pData.data()), W.getAirfoil(q).getNumberOfPanels() * sizeof(float));
301 }
302
303 outfile << eolnBIN;
304
305
306 //sigmas
307 outfile << eolnBIN << "SCALARS Sigma " << "float" << " 1" << eolnBIN;
308 outfile << "LOOKUP_TABLE default" << eolnBIN;
309
310 if (vtx.size() > 0)
311 {
312 Eigen::VectorXf pData = Eigen::VectorXf::Zero(numberNonZero);
313 for (int s = 0; s < vtx.size(); ++s)
314 pData(s) = (float)vtx[s].sigma();
315
316 if (littleEndian)
317 for (int i = 0; i < vtx.size(); ++i)
318 VMlib::SwapEnd(pData(i));
319 outfile.write(reinterpret_cast<char*>(pData.data()), vtx.size() * sizeof(float));
320 }
321 else
322 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
323 {
324 Eigen::VectorXf pData = Eigen::VectorXf::Zero(W.getAirfoil(q).getNumberOfPanels());
325 for (int s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
326 pData(s) = 0;
327
328 if (littleEndian)
329 for (int i = 0; i < W.getAirfoil(q).getNumberOfPanels(); ++i)
330 VMlib::SwapEnd(pData(i));
331 outfile.write(reinterpret_cast<char*>(pData.data()), W.getAirfoil(q).getNumberOfPanels() * sizeof(float));
332 }
333
334 outfile << eolnBIN;
335
336#ifdef TURB
337 //nut
338 outfile << eolnBIN << "SCALARS nut " << "float" << " 1" << eolnBIN;
339 outfile << "LOOKUP_TABLE default" << eolnBIN;
340
341 if (vtx.size() > 0)
342 {
343 Eigen::VectorXf pData = Eigen::VectorXf::Zero(numberNonZero);
344 for (int s = 0; s < vtx.size(); ++s)
345 pData(s) = (float)(sqr(vtx[s].sigma() / 4.48) / W.getPassport().timeDiscretizationProperties.dt - W.getPassport().physicalProperties.nu);;
346
347 if (littleEndian)
348 for (int i = 0; i < vtx.size(); ++i)
349 VMlib::SwapEnd(pData(i));
350 outfile.write(reinterpret_cast<char*>(pData.data()), vtx.size() * sizeof(float));
351 }
352 else
353 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
354 {
355 Eigen::VectorXf pData = Eigen::VectorXf::Zero(W.getAirfoil(q).getNumberOfPanels());
356 for (int s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
357 pData(s) = 0;
358
359 if (littleEndian)
360 for (int i = 0; i < W.getAirfoil(q).getNumberOfPanels(); ++i)
361 VMlib::SwapEnd(pData(i));
362 outfile.write(reinterpret_cast<char*>(pData.data()), W.getAirfoil(q).getNumberOfPanels() * sizeof(float));
363 }
364
365 outfile << eolnBIN;
366#endif
367
368
369 outfile.close();
370 }//if binary
371
373 {
374 std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "csv");
375 outfile.open(W.getPassport().dir + "snapshots/" + fname);
376
377 outfile << "point,x,y,G,S";
378#ifdef TURB
379 outfile << ",nut";
380#endif
381 outfile << '\n';
382
383 int counter = 0;
384
385 if (vtx.size() > 0)
386 for (auto& v : vtx)
387 {
388 outfile << counter++ << "," << v.r()[0] << "," << v.r()[1] << "," << v.g() << "," << v.sigma();
389#ifdef TURB
390 outfile << "," << sqr(v.sigma() / 4.48) / W.getPassport().timeDiscretizationProperties.dt - W.getPassport().physicalProperties.nu;
391#endif
392 outfile << '\n';
393 }
394 else
395 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
396 for (size_t s = 0; s < W.getAirfoil(q).getNumberOfPanels(); ++s)
397 {
398 const Point2D& r = W.getAirfoil(q).getR(s);
399 outfile << counter++ << "," << r[0] << "," << r[1] << "," << "0.0" << "," << "0.0";
400#ifdef TURB
401 outfile << "," << 0.0;
402#endif
403 outfile << '\n';
404 }
405 outfile.close();
406 }//if fileType = text
407
408 }
409
410 W.getTimers().stop("Save");
411}//SaveKadrVtk()
412
413#ifdef TURB
414void WakeDataBase::SaveScalarFields(const std::string& filePrefix,
415 const std::vector<double>& VIP,
416 const std::vector<double>& OIP,
417 const std::vector<double>& nut,
418 const std::vector<Point2D>& grNu,
419 const std::vector<double>& RIP,
420 const std::vector<double>& DELTAG
421) const
422{
423 //W.getTimestat().timeSaveKadr.first += omp_get_wtime();
424
426 {
427 std::ofstream outfile;
428 size_t numberNonZero = vtx.size();
429
431
432 //if (W.getPassport().timeDiscretizationProperties.fileTypeVtx.second == 0) //text format vtk
433 {
434 std::string fname = VMlib::fileNameStep(filePrefix, W.getPassport().timeDiscretizationProperties.nameLength, W.getCurrentStep(), "vtk");
435 outfile.open(W.getPassport().dir + "snapshots/" + fname);
436
437 outfile << "# vtk DataFile Version 2.0\n";
438 outfile << "VM2D VTK result: " << (W.getPassport().dir + "snapshots/" + fname).c_str() << " saved " << VMlib::CurrentDataTime() << '\n';
439 outfile << "ASCII\n";
440 outfile << "DATASET UNSTRUCTURED_GRID\n";
441 outfile << "POINTS " << numberNonZero << " float\n";
442
443 for (auto& v : vtx)
444 {
445 const Point2D& r = v.r();
446 outfile << r[0] << " " << r[1] << " " << "0.0\n";
447 }//for v
448
449
450 outfile << "CELLS " << numberNonZero << " " << 2 * numberNonZero << '\n';
451 for (size_t i = 0; i < numberNonZero; ++i)
452 outfile << "1 " << i << '\n';
453
454 outfile << "CELL_TYPES " << numberNonZero << '\n';
455 for (size_t i = 0; i < numberNonZero; ++i)
456 outfile << "1\n";
457
458 outfile << '\n';
459 outfile << "POINT_DATA " << numberNonZero << '\n';
460 outfile << "SCALARS Gamma float 1\n";
461 outfile << "LOOKUP_TABLE default\n";
462
463 for (auto& v : vtx)
464 outfile << v.g() << '\n';
465
466
467 outfile << "SCALARS Sigma float 1\n";
468 outfile << "LOOKUP_TABLE default\n";
469
470 for (auto& v : W.getWake().vtx)
471 outfile << v.sigma() << '\n';
472
473 outfile << "SCALARS VIP float 1\n";
474 outfile << "LOOKUP_TABLE default\n";
475
476 for (auto& v : VIP)
477 outfile << v << '\n';
478
479 outfile << "SCALARS OIP float 1\n";
480 outfile << "LOOKUP_TABLE default\n";
481
482 for (auto& v : OIP)
483 outfile << v << '\n';
484
485
486 outfile << "SCALARS nut float 1\n";
487 outfile << "LOOKUP_TABLE default\n";
488
489
490 for (auto& v : nut)
491 outfile << v << '\n';
492
493 outfile << "SCALARS RIP float 1\n";
494 outfile << "LOOKUP_TABLE default\n";
495
496 for (auto& v : RIP)
497 outfile << v << '\n';
498
499
500 outfile << "SCALARS DELTAG float 1\n";
501 outfile << "LOOKUP_TABLE default\n";
502
503 for (auto& v : DELTAG)
504 outfile << v << '\n';
505
506
507 outfile << "VECTORS grNu float\n";
508 for (auto& v : grNu)
509 outfile << v[0] << " " << v[1] << " 0.0\n";
510
511 outfile.close();
512 }//if fileType = text
513 }
514
515 //W.getTimestat().timeSaveKadr.second += omp_get_wtime();
516}//SaveScalarFields(...)
517#endif
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса Boundary.
Заголовочный файл с функциями для метода GMRES.
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса Mechanics.
Заголовочный файл с описанием класса Preprocessor.
Заголовочный файл с описанием класса StreamParser.
Заголовочный файл с описанием класса Velocity.
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса WakeDataBase.
Заголовочный файл с описанием класса World2D.
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition Airfoil2D.h:113
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition Airfoil2D.h:163
PhysicalProperties physicalProperties
Структура с физическими свойствами задачи
Definition Passport2D.h:301
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
Definition Passport2D.h:304
std::vector< Vortex2D > vtx
Список вихревых элементов
void ReadFromFile(const std::string &dir, const std::string &fileName)
Считывание вихревого следа из файла
const World2D & W
Константная ссылка на решаемую задачу
void SaveKadrVtk(const std::string &filePrefix="Kadr") const
Сохранение вихревого следа в файл .vtk.
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Definition World2D.h:180
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition World2D.h:163
VMlib::TimersGen & getTimers() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
Definition World2D.h:288
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition World2D.h:263
bool ifDivisible(int val) const
Definition World2D.h:290
Класс, определяющий работу с потоком логов
Definition LogStream.h:57
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
std::string dir
Рабочий каталог задачи
Класс, позволяющий выполнять предварительную обработку файлов
Класс, позволяющий выполнять разбор файлов и строк с настройками и параметрами
bool get(const std::string &name, std::vector< Point2D > &res, const std::vector< Point2D > *defValue=nullptr, bool echoDefault=true) const
Считывание вектора из двумерных точек из базы данных
void stop(const std::string &timerLabel)
Останов счетчика
Definition TimesGen.cpp:68
void start(const std::string &timerLabel)
Запуск счетчика
Definition TimesGen.cpp:55
Класс, опеделяющий двумерный вихревой элемент
Definition Vortex2D.h:59
HD double & sigma()
Функция для доступа к радиусу вихря
Definition Vortex2D.h:108
HD Point2D & r()
Функция для доступа к радиус-вектору вихря
Definition Vortex2D.h:92
HD double & g()
Функция для доступа к циркуляции вихря
Definition Vortex2D.h:100
VMlib::LogStream & getInfo() const
Возврат ссылки на объект LogStream Используется в техничеcких целях для организации вывода
Definition WorldGen.h:82
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
Definition WorldGen.h:99
void CreateUserDirectory(const std::string &dir, const std::string &name)
Создание каталога
Definition defs.h:439
std::string fileNameStep(const std::string &name, int length, size_t number, const std::string &ext)
Формирование имени файла
Definition defs.h:379
std::string CurrentDataTime()
Формирование строки с текущем временем и датой
Definition defs.cpp:47
void SwapEnd(T &var)
Вспомогательная функция перестановки байт местами (нужно для сохранения бинарных VTK)
Definition defs.h:561
double nu
Коэффициент кинематической вязкости среды
Definition Passport2D.h:99
double sigma0
Радиус вихря
Definition Passport2D.h:126
double dt
Шаг по времени
Definition PassportGen.h:67
std::pair< std::string, int > fileTypeVtx
Тип файлов для сохранения скорости и давления
Definition PassportGen.h:79
int saveVtxStep
Шаг сохранения кадров в бинарные файлы
Definition PassportGen.h:81
int nameLength
Число разрядов в имени файла
Definition PassportGen.h:76