VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
Gpu2D.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: Gpu2D.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 "Gpu2D.h"
41
42#include "Airfoil2D.h"
43#include "Boundary2D.h"
44#include "MeasureVP2D.h"
45#include "Mechanics2D.h"
46#include "StreamParser.h"
47#include "Velocity2D.h"
48#include "Wake2D.h"
49#include "World2D.h"
50#include "Gmres2D.h"
51
52using namespace VM2D;
53
54
55//int Gpu::nReserve = 0;
56
57Gpu::Gpu(const World2D& W_)
58 : W(W_)
59{
60#if defined(__CUDACC__) || defined(USE_CUDA)
61
62
63// Откомментировать следующую строку, если запускается счет на кластере, каждый узел которого
64// имеет несколько видеокарт, при этом хочется одновременно решать несколько задач --- каждую на своей видеокарте ---
65// каждая задача по своему номеру, деленному по модулю числа видеокарт на узле будет привязана к своей видеокарте;
66// на каждый узел при этом отправлять СТОЛЬКО MPI-нитей, СКОЛЬКО ТАМ ВИДЕОКАРТ;
67// число задач НАСТОЯТЕЛЬНО РЕКОМЕНДУЕТСЯ ВЫБИРАТЬ ТОЧНО РАВНЫМ СУММАРНОМУ ЧИСЛУ ВИДЕОКАРТ,
68// т.е. чтобы все задачи стартовали сразу же.
69//
70// Uncomment the following string if the program runs on the computer cluster with several graphic cards on every node
71// and you want to solve several tasks simultaneously --- EVERY TASK ON ITS OWN GRAPHIC CARD;
72// every task will be associated with separate graphic card;
73// send THE SAME AMOUNT OF MPI-THREADS for the node as THE NUMBER OF GRAPHIC CARDS on this node;
74// IT IS STRONGLY RECOMMENDED TO CHOOSE THE NUMBER OF TASKS EXACTLY EQUAL TO TOTAL VIDEO CARDs NUMBERS,
75// i.e. to start all the tasks simultaneously.
76
77
78// blocks = cuSelect(W.getPassport().problemNumber % 4); //The index of the used video card will be equal to the task number
79 // in the task list (to modulo 4 --- number of graphic cards on each node)
80
81 blocks = cuSelect(0); //The index of the used video card will be equal to the task number
82 cuReserveDevMem((void*&)dev_blocks, sizeof(int), 0);
83 cuCopyFixedArray(dev_blocks, &blocks, sizeof(int), 0);
84
85 cuSetConstants(sizeof(Vortex2D)/sizeof(double), Vortex2D::offsPos / sizeof(double), Vortex2D::offsGam / sizeof(double), Vortex2D::offsSgm / sizeof(double));
86
87 n_CUDA_wake = 0;
88 inflTreeWake.reset(new BHcu::CudaTreeInfo(blocks, tree_T::vortex, object_T::point4, scheme_T::noScheme, true));
89 cntrTreeWake.reset(new BHcu::CudaTreeInfo(blocks, tree_T::contr, object_T::point4, scheme_T::noScheme, false));
90#ifdef TURB
91 cntrTreeNut.reset(new BHcu::CudaTreeInfo(blocks, tree_T::contr, object_T::point4, scheme_T::noScheme, false));
92#endif
93
94 scheme_T sch;
96 {
97 case 1:
99 break;
100 case 2:
102 break;
103 }
104 cntrTreePnl.reset(new BHcu::CudaTreeInfo(blocks, tree_T::contr, object_T::panel, sch, false));
105 inflTreePnlVortex.reset(new BHcu::CudaTreeInfo(blocks, tree_T::vortex, object_T::panel, sch, false));
106 inflTreePnlSource.reset(new BHcu::CudaTreeInfo(blocks, tree_T::source, object_T::panel, sch, false));
107
108 n_CUDA_velVP = 0;
109 cntrTreeVP.reset(new BHcu::CudaTreeInfo(blocks, tree_T::contr, object_T::point2, scheme_T::noScheme, false));
110
111 //вспомогательное дерево панелей для контроля протыкания
112 auxTreePnl.reset(new BHcu::CudaTreeInfo(blocks, tree_T::aux, object_T::panel, scheme_T::noScheme, false));
113 cntrTreePoint.reset(new BHcu::CudaTreeInfo(blocks, tree_T::contr, object_T::point2, scheme_T::noScheme, false));
114 cntrTreeSegment.reset(new BHcu::CudaTreeInfo(blocks, tree_T::contr, object_T::panel, scheme_T::noScheme, false));
115
116
117 n_CUDA_source = 0;
118 n_CUDA_afls = 0;
119 n_CUDA_pnls = 0;
120
121#endif
122}
123
124
126{
127#if defined(__CUDACC__) || defined(USE_CUDA)
128 inflTreePnlVortex->MemoryFreeForGMRES();
129
130 ReleaseDevMem(W.getWake().devVtxPtr, 1);
131 ReleaseDevMem(W.getWake().devVelPtr, 2);
132 ReleaseDevMem(W.getWake().devRadPtr, 3);
133 ReleaseDevMem(W.getWake().devI0Ptr, 4);
134 ReleaseDevMem(W.getWake().devI0fPtr, 4);
135 ReleaseDevMem(W.getWake().devI1Ptr, 5);
136 ReleaseDevMem(W.getWake().devI2Ptr, 6);
137 ReleaseDevMem(W.getWake().devI3Ptr, 7);
138 ReleaseDevMem(W.getWake().devI3fPtr, 7);
139
140 ReleaseDevMem(W.getWake().devMeshPtr, 8);
141 ReleaseDevMem(W.getWake().devNeiPtr, 9);
142 ReleaseDevMem(W.getWake().devNearestPanelPtr, 9);
143
144 if (W.getSource().vtx.size() > 0)
145 ReleaseDevMem(W.getSource().devVtxPtr, 10);
146
147 if (W.getNumberOfAirfoil() > 0)
148 for (size_t s = 0; s < 1/*n_CUDA_afls*/; ++s)
149 {
150 ReleaseDevMem(W.getBoundary(s).virtualWake.devVtxPtr, 11);
151 ReleaseDevMem(W.getBoundary(s).virtualWake.devVelPtr, 12);
152 ReleaseDevMem(W.getBoundary(s).virtualWake.devRadPtr, 13);
153 ReleaseDevMem(W.getBoundary(s).virtualWake.devI0Ptr, 14);
154 ReleaseDevMem(W.getBoundary(s).virtualWake.devI0fPtr, 14);
155 ReleaseDevMem(W.getBoundary(s).virtualWake.devI1Ptr, 15);
156 ReleaseDevMem(W.getBoundary(s).virtualWake.devI2Ptr, 16);
157 ReleaseDevMem(W.getBoundary(s).virtualWake.devI3Ptr, 17);
158 ReleaseDevMem(W.getBoundary(s).virtualWake.devI3fPtr, 17);
159
160 ReleaseDevMem(W.getBoundary(s).afl.devRPtr, 18);
161 ReleaseDevMem(W.getBoundary(s).afl.devPsnPtr, 181);
162 ReleaseDevMem(W.getBoundary(s).afl.devRhsPtr, 19);
163 ReleaseDevMem(W.getBoundary(s).afl.devRhsLinPtr, 191);
164
165 ReleaseDevMem(W.getBoundary(s).afl.devFreeVortexSheetPtr, 20);
166 ReleaseDevMem(W.getBoundary(s).afl.devAttachedVortexSheetPtr, 21);
167 ReleaseDevMem(W.getBoundary(s).afl.devAttachedSourceSheetPtr, 22);
168
169 ReleaseDevMem(W.getBoundary(s).afl.devFreeVortexSheetLinPtr, 20);
170 ReleaseDevMem(W.getBoundary(s).afl.devAttachedVortexSheetLinPtr, 21);
171 ReleaseDevMem(W.getBoundary(s).afl.devAttachedSourceSheetLinPtr, 22);
172
173 ReleaseDevMem(W.getBoundary(s).afl.devMeanEpsOverPanelPtr, 23);
174 ReleaseDevMem(W.getBoundary(s).afl.devViscousStressesPtr, 24);
175 }
176
177 if (n_CUDA_afls)
178 {
179 ReleaseDevMem(dev_ptr_nPanels, 25);
180 ReleaseDevMem(dev_ptr_nVortices, 26);
181
182 ReleaseDevMem(dev_ptr_ptr_vtx, 27);
183 ReleaseDevMem(dev_ptr_ptr_vel, 28);
184 ReleaseDevMem(dev_ptr_ptr_rad, 29);
185 ReleaseDevMem(dev_ptr_ptr_i0, 30);
186 ReleaseDevMem(dev_ptr_ptr_i0f, 30);
187 ReleaseDevMem(dev_ptr_ptr_i1, 31);
188 ReleaseDevMem(dev_ptr_ptr_i2, 32);
189 ReleaseDevMem(dev_ptr_ptr_i3, 33);
190 ReleaseDevMem(dev_ptr_ptr_i3f, 33);
191
192 ReleaseDevMem(dev_ptr_ptr_r, 34);
193 ReleaseDevMem(dev_ptr_ptr_rhs, 35);
194
195 ReleaseDevMem(dev_ptr_ptr_freeVortexSheet, 36);
196 ReleaseDevMem(dev_ptr_ptr_attachedVortexSheet, 37);
197 ReleaseDevMem(dev_ptr_ptr_attachedSourceSheet, 38);
198
199 ReleaseDevMem(dev_ptr_ptr_meanEpsOverPanel, 39);
200
201 ReleaseDevMem(dev_ptr_ptr_viscousStresses, 40);
202 }
203
204 if (W.getMeasureVP().getWakeVP().vtx.size())
205 {
206 ReleaseDevMem(W.getMeasureVP().getWakeVP().devVtxPtr, 41);
207 ReleaseDevMem(W.getMeasureVP().getWakeVP().devVelPtr, 42);
208 ReleaseDevMem(W.getMeasureVP().getWakeVP().devRadPtr, 43);
209 ReleaseDevMem(W.getMeasureVP().devPressurePtr, 43);
210
211 }
212
213 ReleaseDevMem(dev_blocks, 44);
214#endif
215}
216
217#if defined(__CUDACC__) || defined(USE_CUDA)
218
219
220//Обновление состояния следа wake
221void Gpu::RefreshWake(int code)
222{
223 if (W.getWake().vtx.size() > 0)
224 {
225 //Если зарезервировано меньше, чем вихрей в пелене
226 if (W.getWake().vtx.size() > n_CUDA_wake)
227 {
228 size_t curLength = n_CUDA_wake;
229
230 //Освобождаем всю память на видеокарте
231 if (curLength > 0)
232 {
233 ReleaseDevMem(W.getWake().devVtxPtr, 44);
234 ReleaseDevMem(W.getWake().devVelPtr, 45);
235 ReleaseDevMem(W.getWake().devRadPtr, 46);
236 ReleaseDevMem(W.getWake().devI0Ptr, 47);
237 ReleaseDevMem(W.getWake().devI0fPtr, 47);
238 ReleaseDevMem(W.getWake().devI1Ptr, 48);
239 ReleaseDevMem(W.getWake().devI2Ptr, 49);
240 ReleaseDevMem(W.getWake().devI3Ptr, 50);
241 ReleaseDevMem(W.getWake().devI3fPtr, 50);
242
243 ReleaseDevMem(W.getWake().devMeshPtr, 51);
244 ReleaseDevMem(W.getWake().devNeiPtr, 52);
245 ReleaseDevMem(W.getWake().devNearestPanelPtr, 52);
246 }
247
248 size_t sz = curLength;
249 while (W.getWake().vtx.size() > sz)
250 sz += INC_VORT_DEV;
251
252 //Резервируем новое количество памяти
253 W.getWake().devVtxPtr = ReserveDevMem<double, sizeof(Vortex2D) / sizeof(double)>(sz, n_CUDA_wake);
254
255 W.getWake().devVelPtr = ReserveDevMem<double, 2>(sz, n_CUDA_wake);
256 W.getWake().devRadPtr = ReserveDevMem<double, 1>(sz, n_CUDA_wake);
257
258 W.getWake().devI0Ptr = ReserveDevMem<double, 1>(sz, n_CUDA_wake);
259 W.getWake().devI0fPtr = ReserveDevMem<float, 1>(sz, n_CUDA_wake);
260 W.getWake().devI1Ptr = ReserveDevMem<double, 1>(sz, n_CUDA_wake);
261 W.getWake().devI2Ptr = ReserveDevMem<double, 2>(sz, n_CUDA_wake);
262 W.getWake().devI3Ptr = ReserveDevMem<double, 2>(sz, n_CUDA_wake);
263 W.getWake().devI3fPtr = ReserveDevMem<float, 2>(sz, n_CUDA_wake);
264
265 W.getWake().devMeshPtr = ReserveDevMem<int, 2>(sz, n_CUDA_wake);
266 W.getWake().devNeiPtr = ReserveDevMem<int, 1>(sz, n_CUDA_wake);
267 W.getWake().devNearestPanelPtr = ReserveDevMem<int, 1>(sz, n_CUDA_wake);
268
269 //mesh.resize(n_CUDA_vel, { 0, 0 });
270
271 W.getInfo('i') << "CUDA memory resize: " << curLength << " -> " << n_CUDA_wake << " vortices" << std::endl;
272 }// if (W.getWake().vtx.size() > n_CUDA_wake)
273
274 //Обнуляем память, выделенную выше для хранения следа
275 cuClearWakeMem(W.getWake().vtx.size(), W.getWake().devVtxPtr);
276
277 //Копирование следа на видеокарту
278 //double t1 = omp_get_wtime();
279 //cuCopyWakeToDevAsync(W.getWake().vtx.size(), W.getWake().vtx.data(), W.getWake().devVtxPtr, 1);
280 cuCopyWakeToDev(W.getWake().vtx.size(), W.getWake().vtx.data(), W.getWake().devVtxPtr, 1);
281 //double t2 = omp_get_wtime();
282 //std::cout << "CopyTime = " << t2 - t1 << std::endl;
283 }
284
285 if (W.getSource().vtx.size() > 0)
286 {
287 //Если зарезервировано меньше, чем источников в пелене
288 if (W.getSource().vtx.size() > n_CUDA_source)
289 {
290 size_t curLength = n_CUDA_source;
291
292 //Освобождаем всю память на видеокарте
293 if (curLength > 0)
294 ReleaseDevMem(W.getSource().devVtxPtr, 53);
295
296 size_t sz = curLength;
297 while (W.getSource().vtx.size() > sz)
298 sz += INC_VORT_DEV;
299
300 //Резервируем новое количество памяти
301 W.getSource().devVtxPtr = ReserveDevMem<double, sizeof(Vortex2D) / sizeof(double)>(sz, n_CUDA_source);
302
303
304 W.getInfo('i') << "CUDA memory resize: " << curLength << " -> " << sz << " sources" << std::endl;
305 }// if (W.getSource().vtx.size() > N_CUDA_source)
306
307
308 //Обнуляем память, выделенную выше для хранения следа
309 cuClearWakeMem(W.getSource().vtx.size(), W.getSource().devVtxPtr);
310
311 //Копирование следа на видеокарту
312 cuCopyWakeToDev(W.getSource().vtx.size(), W.getSource().vtx.data(), W.getSource().devVtxPtr, 2);
313
314
315 }
316}
317
318
319
320//Обновление состояния сетки для вычисления VP
321void Gpu::RefreshVP(int code)
322{
323 if (W.getMeasureVP().getWakeVP().vtx.size() > 0)
324 {
325 //Если зарезервировано меньше, чем вихрей в пелене
326 if (W.getMeasureVP().getWakeVP().vtx.size() > n_CUDA_velVP)
327 {
328 size_t curLength = n_CUDA_velVP;
329
330 //Освобождаем всю память на видеокарте
331 if (curLength > 0)
332 {
333 ReleaseDevMem(W.getMeasureVP().getWakeVP().devVtxPtr, 54);
334 ReleaseDevMem(W.getMeasureVP().getWakeVP().devVelPtr, 55);
335 ReleaseDevMem(W.getMeasureVP().getWakeVP().devRadPtr, 56);
336 ReleaseDevMem(W.getMeasureVP().devPressurePtr, 56);
337
338 }
339
340 size_t sz = curLength;
341 while (W.getMeasureVP().getWakeVP().vtx.size() > sz)
342 sz += INC_VORT_DEV;
343
344 //Резервируем новое количество памяти
345 W.getMeasureVP().getWakeVP().devVtxPtr = ReserveDevMem<double, sizeof(Vortex2D) / sizeof(double)>(sz, n_CUDA_velVP);
346 W.getMeasureVP().getWakeVP().devVelPtr = ReserveDevMem<double, 2>(sz, n_CUDA_velVP);
347 W.getMeasureVP().getWakeVP().devRadPtr = ReserveDevMem<double, 1>(sz, n_CUDA_velVP);
348 W.getMeasureVP().devPressurePtr = ReserveDevMem<double, 1>(sz, n_CUDA_velVP);
349
350 W.getInfo('i') << "CUDA memory resize: " << curLength << " -> " << n_CUDA_velVP << " points_VP" << std::endl;
351 }// if (W.getWake().vtx.size() > N_CUDA_velvp)
352
353 //Обнуляем память, выделенную выше для хранения следа
354 cuClearWakeMem(W.getMeasureVP().getWakeVP().vtx.size(), W.getMeasureVP().getWakeVP().devVtxPtr);
355
356 //Копирование следа на видеокарту
357 cuCopyWakeToDev(W.getMeasureVP().getWakeVP().vtx.size(), W.getMeasureVP().getWakeVP().vtx.data(), W.getMeasureVP().getWakeVP().devVtxPtr, 3);
358 }
359}
360
361void Gpu::AllocateSolution(double*& dev_sol, size_t n)
362{
363 size_t new_n;
364 dev_sol = ReserveDevMem<double, 1>(n, new_n);
365}
366
367void Gpu::SetSolution(double* sol, double* dev_sol, size_t n)
368{
369 CopyMemToDev<double,1>(n, sol, dev_sol);
370 //dev_sol = ReserveDevMemAndCopyFixedArray(n, sol);
371}
372
373void Gpu::ReleaseSolution(double* dev_sol)
374{
375 ReleaseDevMem(dev_sol, 100);
376}
377
378//Обновление состояния всех профилей и слоев на них
379void Gpu::RefreshAfls(int code)
380{
381 //std::cout << "RefreshAfls (code = " << code << ") start" << std::endl;
382
383 if (W.getNumberOfBoundary() > 0)
384 {
385 if (W.getNumberOfBoundary() > n_CUDA_afls)
386 {
387 if (n_CUDA_afls)
388 for (size_t s = 0; s < 1/*n_CUDA_afls*/; ++s)
389 {
390 ReleaseDevMem(W.getBoundary(s).afl.devRPtr, 57);
391 ReleaseDevMem(W.getBoundary(s).afl.devPsnPtr, 571);
392 ReleaseDevMem(W.getBoundary(s).afl.devRhsPtr, 58);
393 ReleaseDevMem(W.getBoundary(s).afl.devRhsLinPtr, 581);
394 ReleaseDevMem(W.getBoundary(s).afl.devMeanEpsOverPanelPtr, 59);
395
396 ReleaseDevMem(W.getBoundary(s).afl.devFreeVortexSheetPtr, 60);
397 ReleaseDevMem(W.getBoundary(s).afl.devAttachedVortexSheetPtr, 61);
398 ReleaseDevMem(W.getBoundary(s).afl.devAttachedSourceSheetPtr, 62);
399
400 ReleaseDevMem(W.getBoundary(s).afl.devFreeVortexSheetLinPtr, 60);
401 ReleaseDevMem(W.getBoundary(s).afl.devAttachedVortexSheetLinPtr, 61);
402 ReleaseDevMem(W.getBoundary(s).afl.devAttachedSourceSheetLinPtr, 62);
403
404 ReleaseDevMem(W.getBoundary(s).afl.devViscousStressesPtr, 63);
405 }
406
407 if (n_CUDA_afls)
408 {
409 ReleaseDevMem(dev_ptr_nPanels, 64);
410 ReleaseDevMem(dev_ptr_ptr_r, 65);
411 ReleaseDevMem(dev_ptr_ptr_rhs, 66);
412
413 ReleaseDevMem(dev_ptr_ptr_freeVortexSheet, 67);
414 ReleaseDevMem(dev_ptr_ptr_attachedVortexSheet, 68);
415 ReleaseDevMem(dev_ptr_ptr_attachedSourceSheet, 69);
416
417 ReleaseDevMem(dev_ptr_nVortices, 70);
418 ReleaseDevMem(dev_ptr_ptr_vtx, 71);
419 ReleaseDevMem(dev_ptr_ptr_rad, 72);
420 ReleaseDevMem(dev_ptr_ptr_vel, 73);
421 ReleaseDevMem(dev_ptr_ptr_i0, 74);
422 ReleaseDevMem(dev_ptr_ptr_i0f, 74);
423 ReleaseDevMem(dev_ptr_ptr_i1, 75);
424 ReleaseDevMem(dev_ptr_ptr_i2, 76);
425 ReleaseDevMem(dev_ptr_ptr_i3, 77);
426 ReleaseDevMem(dev_ptr_ptr_i3f, 77);
427 }
428
429 //Временный массив для агрегации числа панелей (без округления вверх до блока) на профилях для их последующей отправки в dev_ptr_nPanels
430 std::vector<size_t> host_nPanels(0);
431
432 size_t totnPanels = 0;
433
434 for (size_t s = 0; s < W.getNumberOfBoundary(); ++s)
435 {
436 const size_t& nps = W.getBoundary(s).afl.getNumberOfPanels();
437 host_nPanels.push_back(nps);
438 totnPanels += nps;
439 }
440 dev_ptr_nPanels = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_nPanels.data());
441
442 const int totNVars = (int)totnPanels * (W.getPassport().numericalSchemes.boundaryCondition.second);
443
444 W.getBoundary(0).afl.devRPtr = ReserveDevMem<double, 4>(totnPanels, n_CUDA_pnls);
445 W.getBoundary(0).afl.devPsnPtr = ReserveDevMem<double, 6>(totnPanels, n_CUDA_pnls);
446 W.getBoundary(0).afl.devRhsPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
447 W.getBoundary(0).afl.devRhsLinPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
448 W.getBoundary(0).afl.devMeanEpsOverPanelPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
449
450 W.getBoundary(0).afl.devFreeVortexSheetPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
451 W.getBoundary(0).afl.devAttachedVortexSheetPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
452 W.getBoundary(0).afl.devAttachedSourceSheetPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
453
455 {
456 W.getBoundary(0).afl.devFreeVortexSheetLinPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
457 W.getBoundary(0).afl.devAttachedVortexSheetLinPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
458 W.getBoundary(0).afl.devAttachedSourceSheetLinPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);
459 }
460 else
461 {
462 W.getBoundary(0).afl.devFreeVortexSheetLinPtr = nullptr;
463 W.getBoundary(0).afl.devAttachedVortexSheetLinPtr = nullptr;
464 W.getBoundary(0).afl.devAttachedSourceSheetLinPtr = nullptr;
465 }
466
467 W.getBoundary(0).afl.devViscousStressesPtr = ReserveDevMem<double, 1>(totnPanels, n_CUDA_pnls);//ViscousStress
468
469 for (size_t s = 1; s < W.getNumberOfBoundary(); ++s)
470 {
471 W.getBoundary(s).afl.devRPtr = W.getBoundary(s - 1).afl.devRPtr + 4 * host_nPanels[s - 1];
472 W.getBoundary(s).afl.devPsnPtr = W.getBoundary(s - 1).afl.devPsnPtr + 6 * host_nPanels[s - 1];
473 W.getBoundary(s).afl.devRhsPtr = W.getBoundary(s - 1).afl.devRhsPtr + 1 * host_nPanels[s - 1];
474 W.getBoundary(s).afl.devRhsLinPtr = W.getBoundary(s - 1).afl.devRhsLinPtr + 1 * host_nPanels[s - 1];
475 W.getBoundary(s).afl.devMeanEpsOverPanelPtr = W.getBoundary(s - 1).afl.devMeanEpsOverPanelPtr + 1 * host_nPanels[s - 1];
476
477 W.getBoundary(s).afl.devFreeVortexSheetPtr = W.getBoundary(s - 1).afl.devFreeVortexSheetPtr + 1 * host_nPanels[s - 1];
478 W.getBoundary(s).afl.devAttachedVortexSheetPtr = W.getBoundary(s - 1).afl.devAttachedVortexSheetPtr + 1 * host_nPanels[s - 1];
479 W.getBoundary(s).afl.devAttachedSourceSheetPtr = W.getBoundary(s - 1).afl.devAttachedSourceSheetPtr + 1 * host_nPanels[s - 1];
480
482 {
483 W.getBoundary(s).afl.devFreeVortexSheetLinPtr = W.getBoundary(s - 1).afl.devFreeVortexSheetLinPtr + 1 * host_nPanels[s - 1];
484 W.getBoundary(s).afl.devAttachedVortexSheetLinPtr = W.getBoundary(s - 1).afl.devAttachedVortexSheetLinPtr + 1 * host_nPanels[s - 1];
485 W.getBoundary(s).afl.devAttachedSourceSheetLinPtr = W.getBoundary(s - 1).afl.devAttachedSourceSheetLinPtr + 1 * host_nPanels[s - 1];
486 }
487 else
488 {
489 W.getBoundary(s).afl.devFreeVortexSheetLinPtr = nullptr;
490 W.getBoundary(s).afl.devAttachedVortexSheetLinPtr = nullptr;
491 W.getBoundary(s).afl.devAttachedSourceSheetLinPtr = nullptr;
492 }
493
494
495 W.getBoundary(s).afl.devViscousStressesPtr = W.getBoundary(s - 1).afl.devViscousStressesPtr + 1 * host_nPanels[s - 1];
496 }
497
498 for (size_t s = 0; s < W.getNumberOfBoundary(); ++s)
499 {
500 W.getBoundary(s).afl.tmpRhs.resize(totNVars, 0.0);
501 W.getBoundary(s).afl.tmpViscousStresses.resize(W.getBoundary(s).afl.getNumberOfPanels(), 0.0);
502 }// for s
503
504 //Временные массивы для агрегации указателей на видеокарте
505 std::vector<double*> host_ptr_r;
506 std::vector<double*> host_ptr_psn;
507 std::vector<double*> host_ptr_rhs;
508 std::vector<double*> host_ptr_rhsLin;
509
510 std::vector<double*> host_ptr_freeVortexSheet;
511 std::vector<double*> host_ptr_attachedVortexSheet;
512 std::vector<double*> host_ptr_attachedSourceSheet;
513
514 std::vector<double*> host_ptr_freeVortexSheetLin;
515 std::vector<double*> host_ptr_attachedVortexSheetLin;
516 std::vector<double*> host_ptr_attachedSourceSheetLin;
517
518 std::vector<double*> host_ptr_meanEpsOverPanel;
519
520 std::vector<double*> host_ptr_viscousStresses;
521
522 for (size_t q = 0; q < W.getNumberOfBoundary(); ++q)
523 {
524 host_ptr_r.push_back(W.getBoundary(q).afl.devRPtr);
525 host_ptr_psn.push_back(W.getBoundary(q).afl.devPsnPtr);
526 host_ptr_rhs.push_back(W.getBoundary(q).afl.devRhsPtr);
527 host_ptr_rhsLin.push_back(W.getBoundary(q).afl.devRhsLinPtr);
528
529 host_ptr_freeVortexSheet.push_back(W.getBoundary(q).afl.devFreeVortexSheetPtr);
530 host_ptr_attachedVortexSheet.push_back(W.getBoundary(q).afl.devAttachedVortexSheetPtr);
531 host_ptr_attachedSourceSheet.push_back(W.getBoundary(q).afl.devAttachedSourceSheetPtr);
532
533 host_ptr_freeVortexSheetLin.push_back(W.getBoundary(q).afl.devFreeVortexSheetLinPtr);
534 host_ptr_attachedVortexSheetLin.push_back(W.getBoundary(q).afl.devAttachedVortexSheetLinPtr);
535 host_ptr_attachedSourceSheetLin.push_back(W.getBoundary(q).afl.devAttachedSourceSheetLinPtr);
536
537 host_ptr_meanEpsOverPanel.push_back(W.getBoundary(q).afl.devMeanEpsOverPanelPtr);
538
539 host_ptr_viscousStresses.push_back(W.getBoundary(q).afl.devViscousStressesPtr);
540 }
541
542 dev_ptr_ptr_r = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_r.data());
543 dev_ptr_ptr_rhs = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_rhs.data());
544
545 dev_ptr_ptr_freeVortexSheet = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_freeVortexSheet.data());
546 dev_ptr_ptr_attachedVortexSheet = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_attachedVortexSheet.data());
547 dev_ptr_ptr_attachedSourceSheet = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_attachedSourceSheet.data());
548
549 dev_ptr_ptr_viscousStresses = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_viscousStresses.data());
550
551 dev_ptr_ptr_meanEpsOverPanel = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), host_ptr_meanEpsOverPanel.data());
552
553 std::vector<double*> zeroPtrVec(W.getNumberOfBoundary(), nullptr);
554 std::vector<float*> zeroPtrVecf(W.getNumberOfBoundary(), nullptr);
555 dev_ptr_ptr_vtx = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
556 dev_ptr_ptr_rad = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
557 dev_ptr_ptr_vel = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
558 dev_ptr_ptr_i0 = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
559 dev_ptr_ptr_i0f = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVecf.data());
560 dev_ptr_ptr_i1 = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
561 dev_ptr_ptr_i2 = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
562 dev_ptr_ptr_i3 = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVec.data());
563 dev_ptr_ptr_i3f = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroPtrVecf.data());
564
565 std::vector<size_t> zeroVec(W.getNumberOfBoundary(), 0);
566 dev_ptr_nVortices = ReserveDevMemAndCopyFixedArray(W.getNumberOfBoundary(), zeroVec.data());
567
568 }//if (W.getNumberOfBoundary() > n_CUDA_afls)
569
570
571 for (size_t s = 0; s < W.getNumberOfBoundary(); ++s)
572 {
573 size_t np = W.getBoundary(s).afl.getNumberOfPanels();
574 //size_t nv = W.getBoundary(s).GetUnknownsSize();
575
576 //Копирование вершин профиля на видеокарту
577 std::vector<double> rbegend(4 * np);
578 std::vector<double> pseudonorm(6 * np);
579 for (size_t q = 0; q < np; ++q)
580 {
581 rbegend[4 * q + 0] = W.getBoundary(s).afl.getR(q)[0];
582 rbegend[4 * q + 1] = W.getBoundary(s).afl.getR(q)[1];
583 rbegend[4 * q + 2] = W.getBoundary(s).afl.getR(q+1)[0];
584 rbegend[4 * q + 3] = W.getBoundary(s).afl.getR(q+1)[1];
585
586 pseudonorm[6 * q + 0] = W.getBoundary(s).afl.psn[q].first[0];
587 pseudonorm[6 * q + 1] = W.getBoundary(s).afl.psn[q].first[1];
588 pseudonorm[6 * q + 2] = W.getBoundary(s).afl.nrm[q][0];
589 pseudonorm[6 * q + 3] = W.getBoundary(s).afl.nrm[q][1];
590 pseudonorm[6 * q + 4] = W.getBoundary(s).afl.psn[q].second[0];
591 pseudonorm[6 * q + 5] = W.getBoundary(s).afl.psn[q].second[1];
592 }
593
594 cuCopyFixedArrayPoint4D(W.getBoundary(s).afl.devRPtr, (Point2D*)rbegend.data(), np, code);
595 cuCopyFixedArrayPoint6D(W.getBoundary(s).afl.devPsnPtr, (Point2D*)pseudonorm.data(), np, code);
596
597 //Копирование слоев на видеокарту
598 std::vector<double> host_freeVortexSheet(np);
599 std::vector<double> host_attachedVortexSheet(np);
600 std::vector<double> host_attachedSourceSheet(np);
601
602 std::vector<double> host_freeVortexSheetLin(np);
603 std::vector<double> host_attachedVortexSheetLin(np);
604 std::vector<double> host_attachedSourceSheetLin(np);
605
606 const Sheet& sh = W.getBoundary(s).sheets;
607
609
610 for (size_t p = 0; p < np; ++p)
611 {
612 host_attachedVortexSheet[p] = sh.attachedVortexSheet(p, 0);
613 host_attachedSourceSheet[p] = sh.attachedSourceSheet(p, 0);
614 host_freeVortexSheet[p] = sh.freeVortexSheet(p, 0);
615
616 if (sch == 2)
617 {
618 host_attachedVortexSheetLin[p] = sh.attachedVortexSheet(p, 1);
619 host_attachedSourceSheetLin[p] = sh.attachedSourceSheet(p, 1);
620 host_freeVortexSheetLin[p] = sh.freeVortexSheet(p, 1);
621 }//for p
622 }//for p
623
624 cuCopyFixedArray(W.getBoundary(s).afl.devFreeVortexSheetPtr, host_freeVortexSheet.data(), sizeof(double) * host_freeVortexSheet.size(), 102);
625 cuCopyFixedArray(W.getBoundary(s).afl.devAttachedVortexSheetPtr, host_attachedVortexSheet.data(), sizeof(double)* host_attachedVortexSheet.size(), 103);
626 cuCopyFixedArray(W.getBoundary(s).afl.devAttachedSourceSheetPtr, host_attachedSourceSheet.data(), sizeof(double)* host_attachedSourceSheet.size(), 104);
627
628 if (sch == 2)
629 {
630 cuCopyFixedArray(W.getBoundary(s).afl.devFreeVortexSheetLinPtr, host_freeVortexSheetLin.data(), sizeof(double) * host_freeVortexSheetLin.size(), 105);
631 cuCopyFixedArray(W.getBoundary(s).afl.devAttachedVortexSheetLinPtr, host_attachedVortexSheetLin.data(), sizeof(double) * host_attachedVortexSheetLin.size(), 106);
632 cuCopyFixedArray(W.getBoundary(s).afl.devAttachedSourceSheetLinPtr, host_attachedSourceSheetLin.data(), sizeof(double) * host_attachedSourceSheetLin.size(), 107);
633 }
634 }
635 }
636 n_CUDA_afls = W.getNumberOfBoundary();
637}//RefreshAfls()
638
639
640//Обновление состояния "виртуальных следов" - только что рожденных вихрей на профилях
641void Gpu::RefreshVirtualWakes(int code)
642{
643 if (n_CUDA_virtWake.size() == 0)
644 {
645 n_CUDA_virtWake.resize(W.getNumberOfBoundary(), 0);
646 n_CUDA_totalVirtWake = 0;
647 }
648
649 size_t totnVirt = 0, totnPan = 0;
650 for (size_t s = 0; s < W.getNumberOfBoundary(); ++s)
651 {
652 totnVirt += W.getBoundary(s).virtualWake.vtx.size();
653 totnPan += W.getBoundary(s).afl.getNumberOfPanels();
654 }
655
656 const size_t& szVtx = std::max(totnVirt, W.getPassport().wakeDiscretizationProperties.minVortexPerPanel * totnPan);
657
658 //Чистим все массивы
659 if (szVtx > n_CUDA_totalVirtWake)
660 {
661 if (n_CUDA_totalVirtWake > 0)
662 for (size_t s = 0; s < 1/*W.getNumberOfBoundary()*/; ++s)
663 {
664 ReleaseDevMem(W.getBoundary(s).virtualWake.devVtxPtr, 70);
665 ReleaseDevMem(W.getBoundary(s).virtualWake.devVelPtr, 71);
666 ReleaseDevMem(W.getBoundary(s).virtualWake.devRadPtr, 72);
667 ReleaseDevMem(W.getBoundary(s).virtualWake.devI0Ptr, 73);
668 ReleaseDevMem(W.getBoundary(s).virtualWake.devI0fPtr, 73);
669 ReleaseDevMem(W.getBoundary(s).virtualWake.devI1Ptr, 74);
670 ReleaseDevMem(W.getBoundary(s).virtualWake.devI2Ptr, 75);
671 ReleaseDevMem(W.getBoundary(s).virtualWake.devI3Ptr, 76);
672 ReleaseDevMem(W.getBoundary(s).virtualWake.devI3fPtr, 76);
673 }
674
675 if (n_CUDA_afls)
676 {
677 W.getBoundary(0).virtualWake.devVtxPtr = ReserveDevMem<double, sizeof(Vortex2D) / sizeof(double)>(szVtx, n_CUDA_totalVirtWake, 80);
678 W.getBoundary(0).virtualWake.devVelPtr = ReserveDevMem<double, 2>(szVtx, n_CUDA_totalVirtWake, 81);
679 W.getBoundary(0).virtualWake.devRadPtr = ReserveDevMem<double, 1>(szVtx, n_CUDA_totalVirtWake, 82);
680
681 //std::cout << "szVtx = " << szVtx << ", n_CUDA_totalVirtWake = " << n_CUDA_totalVirtWake << std::endl;
682
683 W.getBoundary(0).virtualWake.devI0Ptr = ReserveDevMem<double, 1>(szVtx, n_CUDA_totalVirtWake, 83);
684 W.getBoundary(0).virtualWake.devI0fPtr = ReserveDevMem<float, 1>(szVtx, n_CUDA_totalVirtWake, 84);
685 W.getBoundary(0).virtualWake.devI1Ptr = ReserveDevMem<double, 1>(szVtx, n_CUDA_totalVirtWake, 85);
686 W.getBoundary(0).virtualWake.devI2Ptr = ReserveDevMem<double, 2>(szVtx, n_CUDA_totalVirtWake, 86);
687 W.getBoundary(0).virtualWake.devI3Ptr = ReserveDevMem<double, 2>(szVtx, n_CUDA_totalVirtWake, 87);
688 W.getBoundary(0).virtualWake.devI3fPtr = ReserveDevMem<float, 2>(szVtx, n_CUDA_totalVirtWake, 88);
689 }
690 }
691
692 for (size_t s = 1; s < W.getNumberOfBoundary(); ++s)
693 {
694 size_t nprev = W.getBoundary(s - 1).virtualWake.vtx.size();
695 W.getBoundary(s).virtualWake.devVtxPtr = W.getBoundary(s - 1).virtualWake.devVtxPtr + (sizeof(Vortex2D) / sizeof(double)) * nprev;
696 W.getBoundary(s).virtualWake.devVelPtr = W.getBoundary(s - 1).virtualWake.devVelPtr + 2 * nprev;
697 W.getBoundary(s).virtualWake.devRadPtr = W.getBoundary(s - 1).virtualWake.devRadPtr + 1 * nprev;
698 W.getBoundary(s).virtualWake.devI0Ptr = W.getBoundary(s - 1).virtualWake.devI0Ptr + 1 * nprev;
699 W.getBoundary(s).virtualWake.devI0fPtr = W.getBoundary(s - 1).virtualWake.devI0fPtr + 1 * nprev;
700 W.getBoundary(s).virtualWake.devI1Ptr = W.getBoundary(s - 1).virtualWake.devI1Ptr + 1 * nprev;
701 W.getBoundary(s).virtualWake.devI2Ptr = W.getBoundary(s - 1).virtualWake.devI2Ptr + 2 * nprev;
702 W.getBoundary(s).virtualWake.devI3Ptr = W.getBoundary(s - 1).virtualWake.devI3Ptr + 2 * nprev;
703 W.getBoundary(s).virtualWake.devI3fPtr = W.getBoundary(s - 1).virtualWake.devI3fPtr + 2 * nprev;
704 }
705
706 std::vector<size_t> host_nVortices(0);
707 host_nVortices.reserve(W.getNumberOfBoundary());
708
709 for (size_t q = 0; q < W.getNumberOfBoundary(); ++q)
710 host_nVortices.push_back(W.getBoundary(q).virtualWake.vtx.size());
711
712 cuCopyFixedArray(dev_ptr_nVortices, host_nVortices.data(), W.getNumberOfBoundary()*sizeof(size_t), 108);
713
714 for (size_t s = 0; s < W.getNumberOfBoundary(); ++s)
715 {
716 //Временные массивы для агрегации указателей на видеокарте
717 std::vector<double*> host_ptr_vtx;
718 std::vector<double*> host_ptr_vel;
719 std::vector<double*> host_ptr_rad;
720 std::vector<double*> host_ptr_i0;
721 std::vector<float*> host_ptr_i0f;
722 std::vector<double*> host_ptr_i1;
723 std::vector<double*> host_ptr_i2;
724 std::vector<double*> host_ptr_i3;
725 std::vector<float*> host_ptr_i3f;
726
727 for (size_t q = 0; q < W.getNumberOfBoundary(); ++q)
728 {
729 host_ptr_vtx.push_back(W.getBoundary(q).virtualWake.devVtxPtr);
730 host_ptr_vel.push_back(W.getBoundary(q).virtualWake.devVelPtr);
731 host_ptr_rad.push_back(W.getBoundary(q).virtualWake.devRadPtr);
732 host_ptr_i0.push_back(W.getBoundary(q).virtualWake.devI0Ptr);
733 host_ptr_i0f.push_back(W.getBoundary(q).virtualWake.devI0fPtr);
734 host_ptr_i1.push_back(W.getBoundary(q).virtualWake.devI1Ptr);
735 host_ptr_i2.push_back(W.getBoundary(q).virtualWake.devI2Ptr);
736 host_ptr_i3.push_back(W.getBoundary(q).virtualWake.devI3Ptr);
737 host_ptr_i3f.push_back(W.getBoundary(q).virtualWake.devI3fPtr);
738 }
739
740 size_t nBytes = W.getNumberOfBoundary() * sizeof(double*);
741 cuCopyFixedArray(dev_ptr_ptr_vtx, host_ptr_vtx.data(), nBytes, 109);
742 cuCopyFixedArray(dev_ptr_ptr_rad, host_ptr_rad.data(), nBytes, 110);
743 cuCopyFixedArray(dev_ptr_ptr_vel, host_ptr_vel.data(), nBytes, 111);
744 cuCopyFixedArray(dev_ptr_ptr_i0, host_ptr_i0.data(), nBytes, 112);
745 cuCopyFixedArray(dev_ptr_ptr_i0f, host_ptr_i0f.data(), nBytes, 112);
746 cuCopyFixedArray(dev_ptr_ptr_i1, host_ptr_i1.data(), nBytes, 113);
747 cuCopyFixedArray(dev_ptr_ptr_i2, host_ptr_i2.data(), nBytes, 114);
748 cuCopyFixedArray(dev_ptr_ptr_i3, host_ptr_i3.data(), nBytes, 115);
749 cuCopyFixedArray(dev_ptr_ptr_i3f, host_ptr_i3f.data(), nBytes, 115);
750 }//if (n_CUDA_virtWake[s] < W.getBoundary(s).virtualWake.vtx.size())
751
752 //Обнуляем память, выделенную выше для хранения виртуального следа
753 if (W.getNumberOfBoundary() > 0)
754 {
755 cuClearWakeMem(szVtx, W.getBoundary(0).virtualWake.devVtxPtr);
756 for (size_t s = 0; s < W.getNumberOfBoundary(); ++s)
757 cuCopyWakeToDev(W.getBoundary(s).virtualWake.vtx.size(), W.getBoundary(s).virtualWake.vtx.data(), W.getBoundary(s).virtualWake.devVtxPtr, 4);
758 }
759}
760
761#endif
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса Boundary.
Заголовочный файл с функциями для метода GMRES.
Заголовочный файл с описанием класса Gpu.
#define INC_VORT_DEV
Definition Gpudefs.h:83
scheme_T
Definition Gpudefs.h:158
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса Mechanics.
Заголовочный файл с описанием класса StreamParser.
Заголовочный файл с описанием класса Velocity.
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса World2D.
std::vector< std::pair< Point2D, Point2D > > psn
Псевдонормали к панелям профиля
Definition Airfoil2D.h:86
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition Airfoil2D.h:113
std::vector< Point2D > nrm
Нормали к панелям профиля
Definition Airfoil2D.h:81
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition Airfoil2D.h:163
const Airfoil & afl
Definition Boundary2D.h:77
Sheet sheets
Слои на профиле
Definition Boundary2D.h:96
VirtualWake virtualWake
Виртуальный вихревой след конкретного профиля
Definition Boundary2D.h:86
const World2D & W
Константная ссылка на решаемую задачу
Definition Gpu2D.h:74
Gpu(const World2D &W_)
Конструктор
Definition Gpu2D.cpp:57
const WakeDataBase & getWakeVP() const
Возврат wakeVP.
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
Definition Passport2D.h:304
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
Definition Passport2D.h:307
Класс, опеделяющий слои на поверхности обтекаемого профиля
Definition Sheet2D.h:63
const double & attachedVortexSheet(size_t n, size_t moment) const
Definition Sheet2D.h:105
const double & attachedSourceSheet(size_t n, size_t moment) const
Definition Sheet2D.h:110
const double & freeVortexSheet(size_t n, size_t moment) const
Definition Sheet2D.h:100
std::vector< Vortex2D > vtx
Список вихревых элементов
Класс, опеделяющий текущую решаемую задачу
Definition World2D.h:77
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Definition World2D.h:180
const Wake & getWake() const
Возврат константной ссылки на вихревой след
Definition World2D.h:232
const WakeDataBase & getSource() const
Возврат константной ссылки на источники в области течения
Definition World2D.h:248
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition World2D.h:263
const Boundary & getBoundary(size_t i) const
Возврат константной ссылки на объект граничного условия
Definition World2D.h:186
size_t getNumberOfBoundary() const
Возврат количества граничных условий в задаче
Definition World2D.h:197
const MeasureVP & getMeasureVP() const
Возврат константной ссылки на measureVP.
Definition World2D.h:208
Класс, опеделяющий двумерный вихревой элемент
Definition Vortex2D.h:59
VMlib::LogStream & getInfo() const
Возврат ссылки на объект LogStream Используется в техничеcких целях для организации вывода
Definition WorldGen.h:82
std::pair< std::string, int > boundaryCondition
Метод аппроксимации граничных условий
Definition Passport2D.h:190
int minVortexPerPanel
Минимальное число вихрей, рождаемых на каждой панели профииля
Definition Passport2D.h:141