VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
Boundary2DConstLayerAver.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: Boundary2DConstLayerAver.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
43
44#include "Airfoil2D.h"
45#include "MeasureVP2D.h"
46#include "Mechanics2D.h"
47#include "StreamParser.h"
48#include "Velocity2D.h"
49#include "Wake2D.h"
50#include "World2D.h"
51
52using namespace VM2D;
53
54
55//Пересчет решения на интенсивность вихревого слоя
57{
58 Vortex2D virtVort;
59 Point2D midNorm;
60
61 size_t np = afl.getNumberOfPanels();
62
64
66
67 //Очистка и резервирование памяти
69 virtualWake.vecHalfGamma.reserve(np * nVortPerPan);
70
71 //Очистка и резервирование памяти
72 virtualWake.aflPan.clear();
73 virtualWake.aflPan.reserve(np * nVortPerPan);
74
75 //Резервирование памяти
76 virtualWake.vtx.clear();
77 virtualWake.vtx.reserve(np * nVortPerPan);
78
79 //Очистка и резервирование памяти
80 vortexBeginEnd.clear();
81 vortexBeginEnd.reserve(np);
82
84
85 std::pair<int, int> pair;
86
87 for (size_t i = 0; i < np; ++i)
88 {
89 midNorm = afl.nrm[i] * delta;
90
91 size_t NEWnVortPerPan = (size_t)std::max((int)std::ceil(fabs(sol(i) * afl.len[i]) / maxG), nVortPerPan);
92
93 pair.first = (int)virtualWake.vtx.size();
94
95
96 Point2D dr = 1.0 / NEWnVortPerPan * (afl.getR(i + 1) - afl.getR(i));
97
98 for (size_t j = 0; j < NEWnVortPerPan; ++j)
99 {
100 virtVort.r() = afl.getR(i) + dr * (j * 1.0 + 0.5) + midNorm;
101 virtVort.g() = sol(i) * afl.len[i] / NEWnVortPerPan;
102 virtualWake.vtx.push_back(virtVort);
103
104 virtualWake.vecHalfGamma.push_back(0.5 * sol(i) * afl.tau[i]);
105 virtualWake.aflPan.push_back({ numberInPassport, i });
106 }
107
108 pair.second = (int)virtualWake.vtx.size();
109 vortexBeginEnd.push_back(pair);
110 }
111
112
113 for (size_t j = 0; j < np; ++j)
114 sheets.freeVortexSheet(j, 0) = sol(j);
115
116}//SolutionToFreeVortexSheetAndVirtualVortex(...)
117
118
119//Генерация блока матрицы
120void BoundaryConstLayerAver::FillMatrixSelf(Eigen::MatrixXd& matr, Eigen::VectorXd& lastLine, Eigen::VectorXd& lactCol)
121{
122 size_t np = afl.getNumberOfPanels();
123
124 for (size_t i = 0; i < np; ++i)
125 {
126 lactCol(i) = 1.0;
127 lastLine(i) = afl.len[i];
128 }
129
130 for (size_t i = 0; i < np; ++i)
131 for (size_t j = 0; j < np; ++j)
132 matr(i, j) = afl.getA(1, i, afl, j)[0];
133
134}//FillMatrixSelf(...)
135
136void BoundaryConstLayerAver::FillIQSelf(std::pair<Eigen::MatrixXd, Eigen::MatrixXd>& IQ)
137{
138 afl.calcIQ(1, afl, IQ);
139}//FillIQSelf(...)
140
141//Генерация блока матрицы влияния от другого профиля того же типа
142void BoundaryConstLayerAver::FillMatrixFromOther(const Boundary& otherBoundary, Eigen::MatrixXd& matr)
143{
144 for (size_t i = 0; i < afl.getNumberOfPanels(); ++i)
145 for (size_t j = 0; j < otherBoundary.afl.getNumberOfPanels(); ++j)
146 matr(i, j) = afl.getA(1, i, otherBoundary.afl, j)[0];
147}//FillMatrixFromOther(...)
148
149
150void BoundaryConstLayerAver::FillIQFromOther(const Boundary& otherBoundary, std::pair<Eigen::MatrixXd, Eigen::MatrixXd>& IQ)
151{
152 afl.calcIQ(1, otherBoundary.afl, IQ);
153}//FillIQFromOther(...)
154
155
156//Вычисление скоростей в наборе точек, вызываемых наличием слоев вихрей и источников на профиле
157void BoundaryConstLayerAver::CalcConvVelocityToSetOfPointsFromSheets(const WakeDataBase& pointsDb, std::vector<Point2D>& velo) const
158{
159 std::vector<Point2D> selfVelo(pointsDb.vtx.size());
160
161 double cft = IDPI;
162
163#pragma warning (push)
164#pragma warning (disable: 4101)
165 //Локальные переменные для цикла
166 Point2D velI;
167 Point2D tempVel;
168 //double dst2eps, dst2;
169#pragma warning (pop)
170
171#pragma omp parallel for default(none) shared(selfVelo, cft, pointsDb, std::cout) private(velI, tempVel)
172 for (int i = 0; i < pointsDb.vtx.size(); ++i)
173 {
175
176 velI.toZero();
177
178 const Point2D& posI = pointsDb.vtx[i].r();
179
182 for (size_t j = 0; j < sheets.getSheetSize(); ++j)
183 {
184 Point2D dj = afl.getR(j + 1) - afl.getR(j);
185 Point2D tauj = dj.unit();
186
187 Point2D s = posI - afl.getR(j);
188 Point2D p = posI - afl.getR(j + 1);
189
190 double a = VMlib::Alpha(p, s);
191
192 double lambda;
193 if ( (s.length2() > 1e-16) && (p.length2() > 1e-16) )
194 lambda = VMlib::Lambda(p, s);
195 else
196 lambda = 0.0;
197
198 Point2D skos = -a * tauj.kcross() + lambda * tauj;
199
200 velI += sheets.freeVortexSheet(j, 0) * skos.kcross();
201 velI += sheets.attachedVortexSheet(j, 0) * skos.kcross();
202 velI += sheets.attachedSourceSheet(j, 0) * skos;
203 }//for j
204
205 velI *= cft;
206 selfVelo[i] = velI;
207 }//for i
208
209 for (size_t i = 0; i < velo.size(); ++i)
210 velo[i] += selfVelo[i];
211}//CalcConvVelocityToSetOfPointsFromSheets(...)
212
213
214#if defined(USE_CUDA)
215void BoundaryConstLayerAver::GPUCalcConvVelocityToSetOfPointsFromSheets(const WakeDataBase& pointsDb, std::vector<Point2D>& velo) const
216{
217 if (afl.numberInPassport == 0)
218 {
219 const size_t npt = pointsDb.vtx.size();
220 double*& dev_ptr_pt = pointsDb.devVtxPtr;
221
222 size_t npnl = afl.getNumberOfPanels();
223 for (size_t q = 1; q < W.getNumberOfAirfoil(); ++q)
224 npnl += W.getAirfoil(q).getNumberOfPanels();
225
226 double*& dev_ptr_r = afl.devRPtr;
227 double*& dev_ptr_freeVortexSheet = afl.devFreeVortexSheetPtr;
228 double*& dev_ptr_attachedVortexSheet = afl.devAttachedVortexSheetPtr;
229 double*& dev_ptr_attachedSourceSheet = afl.devAttachedSourceSheetPtr;
230
231 double*& dev_ptr_freeVortexSheetLin = afl.devFreeVortexSheetLinPtr;
232 double*& dev_ptr_attachedVortexSheetLin = afl.devAttachedVortexSheetLinPtr;
233 double*& dev_ptr_attachedSourceSheetLin = afl.devAttachedSourceSheetLinPtr;
234
235 std::vector<Point2D>& Vel = velo;
236 double*& dev_ptr_vel = pointsDb.devVelPtr;
238
239
240 if (npt > 0)
241 {
242 cuCalculateConvVeloWakeFromVirtual(npt, dev_ptr_pt, npnl, dev_ptr_r, \
243 dev_ptr_freeVortexSheet, dev_ptr_freeVortexSheetLin, \
244 dev_ptr_attachedVortexSheet, dev_ptr_attachedVortexSheetLin, \
245 dev_ptr_attachedSourceSheet, dev_ptr_attachedSourceSheetLin, \
246 dev_ptr_vel, eps2);
247
248 std::vector<Point2D> newV(Vel.size());
249 W.getCuda().CopyMemFromDev<double, 2>(npt, dev_ptr_vel, (double*)newV.data());
250
251 for (size_t q = 0; q < Vel.size(); ++q)
252 Vel[q] += newV[q];
253
254 /* VMlib::CreateDirectory(W.getPassport().dir, "dbg");
255 std::ostringstream sss;
256 sss << "velWakeFromBou";
257 sss << W.currentStep;
258 std::ofstream prmtFile(W.getPassport().dir + "dbg/" + sss.str());
259 prmtFile << "i x y g B2Wx B2Wy" << std::endl;
260 for (size_t i = 0; i < npt; ++i)
261 prmtFile << i << " " \
262 << pointsDb.vtx[i].r()[0] << " " << pointsDb.vtx[i].r()[1] << " " \
263 << pointsDb.vtx[i].g() << " " \
264 << newV[i][0] << " " << newV[i][1] << " " \
265 << std::endl;
266 prmtFile.close();*/
267 }
268 }
269}
270//GPUCalcConvVelocityToSetOfPointsFromSheets(...)
271#endif
272
273
274
275//Вычисление интенсивностей присоединенного вихревого слоя и присоединенного слоя источников
277{
278
279 for (size_t i = 0; i < sheets.getSheetSize(); ++i)
280 {
283 }
284
285 for (size_t i = 0; i < sheets.getSheetSize(); ++i)
286 {
287 sheets.attachedVortexSheet(i, 0) = 0.5 * (afl.getV(i) + afl.getV(i + 1)) & afl.tau[i];
288 sheets.attachedSourceSheet(i, 0) = 0.5 * (afl.getV(i) + afl.getV(i + 1)) & afl.nrm[i];
289 }
290}//ComputeAttachedSheetsIntensity()
291
292
293//Вычисляет влияния части подряд идущих вихрей из вихревого следа на прямолинейную панель для правой части
294void BoundaryConstLayerAver::GetInfluenceFromVorticesToRectPanel(size_t panel, const Vortex2D* ptr, ptrdiff_t count, std::vector<double>& wakeRhs) const
295{
296 double& velI = wakeRhs[0];
297
298 const Point2D& posI0 = afl.getR(panel);
299 const Point2D& posI1 = afl.getR(panel + 1);
300
301
302 for (size_t it = 0; it != count; ++it)
303 {
304 const Vortex2D& vt = ptr[it];
305
306 const Point2D& posJ = vt.r();
307 const double& gamJ = vt.g();
308
309 Point2D s = posJ - posI0;
310 Point2D p = posJ - posI1;
311
312 double alpha = VMlib::Alpha(p, s);
313
314 velI -= gamJ * alpha;
315 }
316}// GetInfluenceFromVorticesToRectPanel(...)
317
318
319
320//Вычисляет влияния части подряд идущих источников в области течения на прямолинейную панель для правой части
321void BoundaryConstLayerAver::GetInfluenceFromSourcesToRectPanel(size_t panel, const Vortex2D* ptr, ptrdiff_t count, std::vector<double>& wakeRhs) const
322{
323 double& velI = wakeRhs[0];
324
325 const Point2D& posI0 = afl.getR(panel);
326 const Point2D& posI1 = afl.getR(panel + 1);
327
328 for (size_t it = 0; it != count; ++it)
329 {
330 const Vortex2D& vt = ptr[it];
331 const Point2D& posJ = vt.r();
332 const double& gamJ = vt.g();
333
334 Point2D s = posJ - posI0;
335 Point2D p = posJ - posI1;
336
337 double lambda = VMlib::Lambda(p, s);
338
339 velI -= gamJ * lambda;
340 }
341}// GetInfluenceFromSourcesToRectPanel(...)
342
343
344//Вычисление влияния слоя источников конкретной прямолинейной панели на вихрь в области течения
346{
347 vel.toZero();
348
349 const Point2D& posI = ptr.r();
350
351 Point2D dj = afl.getR(panel + 1) - afl.getR(panel);
352 Point2D tauj = dj.unit();
353
354 Point2D s = posI - afl.getR(panel);
355 Point2D p = posI - afl.getR(panel + 1);
356
357 double a = VMlib::Alpha(p, s);
358
359 double lambda;
360 if ((s.length2() > 1e-16) && (p.length2() > 1e-16))
361 lambda = VMlib::Lambda(p, s);
362 else
363 lambda = 0.0;
364
365 vel += sheets.attachedSourceSheet(panel, 0) * (-a * tauj.kcross() + lambda * tauj);
366}// GetInfluenceFromSourceSheetAtRectPanelToVortex(...)
367
368//Вычисление влияния вихревых слоев (свободный + присоединенный) конкретной прямолинейной панели на вихрь в области течения
370{
371 vel.toZero();
372
373 const Point2D& posI = ptr.r();
374
375 Point2D dj = afl.getR(panel + 1) - afl.getR(panel);
376 Point2D tauj = dj.unit();
377
378 Point2D s = posI - afl.getR(panel);
379 Point2D p = posI - afl.getR(panel + 1);
380 double a = VMlib::Alpha(p, s);
381
382 double lambda;
383 if ((s.length2() > 1e-16) && (p.length2() > 1e-16))
384 lambda = VMlib::Lambda(p, s);
385 else
386 lambda = 0.0;
387
388 Point2D skos = -a * tauj.kcross() + lambda * tauj;
389
390 vel += sheets.freeVortexSheet(panel, 0) * skos.kcross();
391 vel += sheets.attachedVortexSheet(panel, 0) * skos.kcross();
392
393}// GetInfluenceFromVortexSheetAtRectPanelToVortex(...)
394
395
396//Вычисляет влияния набегающего потока на прямолинейную панель для правой части
397void BoundaryConstLayerAver::GetInfluenceFromVInfToRectPanel(std::vector<double>& vInfRhs) const
398{
399 size_t np = afl.getNumberOfPanels();
400 vInfRhs.resize(np);
401
402#pragma omp parallel for default(none) shared(vInfRhs, np)
403 for (int i = 0; i < np; ++i)
404 vInfRhs[i] = afl.tau[i] & W.getV0();
405
406}// GetInfluenceFromVInfToRectPanel(...)
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса BoundaryConstLayerAver.
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса Mechanics.
Заголовочный файл с описанием класса StreamParser.
Заголовочный файл с описанием класса Velocity.
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса World2D.
std::vector< double > len
Длины панелей профиля
Definition Airfoil2D.h:94
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition Airfoil2D.h:113
const Point2D & getV(size_t q) const
Возврат константной ссылки на скорость вершины профиля
Definition Airfoil2D.h:137
std::vector< Point2D > nrm
Нормали к панелям профиля
Definition Airfoil2D.h:81
std::vector< Point2D > tau
Касательные к панелям профиля
Definition Airfoil2D.h:91
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition Airfoil2D.h:163
virtual void calcIQ(size_t p, const Airfoil &otherAirfoil, std::pair< Eigen::MatrixXd, Eigen::MatrixXd > &matrPair) const
Вычисление коэффициентов матрицы, состоящей из интегралов от (r-xi)/|r-xi|^2.
const size_t numberInPassport
Номер профиля в паспорте
Definition Airfoil2D.h:188
virtual std::vector< double > getA(size_t p, size_t i, const Airfoil &airfoil, size_t j) const
Вычисление коэффициентов матрицы A для расчета влияния панели на панель
virtual void FillMatrixFromOther(const Boundary &otherBoundary, Eigen::MatrixXd &matr) override
Генерация блока матрицы влияния от другого профиля того же типа
virtual void GetInfluenceFromSourcesToRectPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &wakeRhs) const override
Вычисление влияния части подряд источников из области течения на прямолинейную панель для правой част...
virtual void ComputeAttachedSheetsIntensity() override
Вычисление интенсивностей присоединенного вихревого слоя и присоединенного слоя источников
virtual void FillIQSelf(std::pair< Eigen::MatrixXd, Eigen::MatrixXd > &IQ) override
Генерация блока матрицы, состоящей из интегралов от (r-xi)/|r-xi|^2, влияние профиля самого на себя
virtual void GetInfluenceFromSourceSheetAtRectPanelToVortex(size_t panel, const Vortex2D &ptr, Point2D &vel) const override
Вычисление влияния слоя источников конкретной прямолинейной панели на вихрь в области течения
virtual void FillIQFromOther(const Boundary &otherBoundary, std::pair< Eigen::MatrixXd, Eigen::MatrixXd > &IQ) override
Генерация блока матрицы, состоящей из интегралов от (r-xi)/|r-xi|^2, влияние одного профиля на другой
virtual void GetInfluenceFromVortexSheetAtRectPanelToVortex(size_t panel, const Vortex2D &vtx, Point2D &vel) const override
Вычисление влияния вихревых слоев (свободный + присоединенный) конкретной прямолинейной панели на вих...
virtual void FillMatrixSelf(Eigen::MatrixXd &matr, Eigen::VectorXd &lastLine, Eigen::VectorXd &lactCol) override
Генерация блока матрицы
virtual void GetInfluenceFromVInfToRectPanel(std::vector< double > &vInfRhs) const override
Вычисление влияния набегающего потока на прямолинейную панель для правой части
virtual void CalcConvVelocityToSetOfPointsFromSheets(const WakeDataBase &pointsDb, std::vector< Point2D > &velo) const override
Вычисление конвективных скоростей в наборе точек, вызываемых наличием слоев вихрей и источников на пр...
virtual void GetInfluenceFromVorticesToRectPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &wakeRhs) const override
Вычисление влияния части подряд идущих вихрей из вихревого следа на прямолинейную панель для правой ч...
virtual void SolutionToFreeVortexSheetAndVirtualVortex(const Eigen::VectorXd &sol) override
Пересчет решения на интенсивность вихревого слоя и на рождаемые вихри на конкретном профиле
Абстрактный класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле
Definition Boundary2D.h:65
Sheet oldSheets
Слои на профиле с предыдущего шага
Definition Boundary2D.h:99
const World2D & W
Константная ссылка на решаемую задачу
Definition Boundary2D.h:68
const Airfoil & afl
Definition Boundary2D.h:77
Sheet sheets
Слои на профиле
Definition Boundary2D.h:96
std::vector< std::pair< int, int > > vortexBeginEnd
Номера первого и последнего вихрей, рождаемых на каждой панели профиля (формируется после решения СЛА...
Definition Boundary2D.h:83
VirtualWake virtualWake
Виртуальный вихревой след конкретного профиля
Definition Boundary2D.h:86
const size_t numberInPassport
Номер профиля в паспорте
Definition Boundary2D.h:71
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
Definition Passport2D.h:292
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
size_t getSheetSize() const
Definition Sheet2D.h:95
std::vector< Point2D > vecHalfGamma
Скорость вихрей виртуального следа конкретного профиля (равна Gamma/2) используется для расчета давле...
std::vector< std::pair< size_t, size_t > > aflPan
Пара чисел: номер профиля и номер панели, на которой рожден виртуальный вихрь
Класс, опеделяющий набор вихрей
std::vector< Vortex2D > vtx
Список вихревых элементов
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Definition World2D.h:174
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition World2D.h:157
Point2D getV0() const
Возврат текущей скорости набегающего потока
Definition World2D.h:142
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
Definition World2D.h:261
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition World2D.h:251
Класс, опеделяющий двумерный вихревой элемент
Definition Vortex2D.h:59
HD Point2D & r()
Функция для доступа к радиус-вектору вихря
Definition Vortex2D.h:87
HD double & g()
Функция для доступа к циркуляции вихря
Definition Vortex2D.h:95
numvector< T, 2 > kcross() const
Геометрический поворот двумерного вектора на 90 градусов
Definition numvector.h:510
auto length2() const -> typename std::remove_const< typename std::remove_reference< decltype(this->data[0])>::type >::type
Вычисление квадрата нормы (длины) вектора
Definition numvector.h:386
numvector< T, n > & toZero(P val=0)
Установка всех компонент вектора в константу (по умолчанию — нуль)
Definition numvector.h:527
auto unit(P newlen=1) const -> numvector< typename std::remove_const< decltype(this->data[0] *newlen)>::type, n >
Вычисление орта вектора или вектора заданной длины, коллинеарного данному
Definition numvector.h:402
const double IDPI
Число .
Definition defs.h:85
double Lambda(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления логарифма отношения норм векторов
Definition defs.cpp:268
double Alpha(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления угла между векторами
Definition defs.cpp:262
int minVortexPerPanel
Минимальное число вихрей, рождаемых на каждой панели профииля
Definition Passport2D.h:141
double delta
Расстояние, на которое рождаемый вихрь отодвигается от профиля
Definition Passport2D.h:138
double maxGamma
Максимально допустимая циркуляция вихря
Definition Passport2D.h:144
double eps2
Квадрат радиуса вихря
Definition Passport2D.h:129