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#include "Gmres2D.h"
52
53using namespace VM2D;
54
55
56//Пересчет решения на интенсивность вихревого слоя
58{
59 Vortex2D virtVort;
60 Point2D midNorm;
61
62 size_t np = afl.getNumberOfPanels();
63
65
67
68 //Очистка и резервирование памяти
70 virtualWake.vecHalfGamma.reserve(np * nVortPerPan);
71
72 //Очистка и резервирование памяти
73 virtualWake.aflPan.clear();
74 virtualWake.aflPan.reserve(np * nVortPerPan);
75
76 //Резервирование памяти
77 virtualWake.vtx.clear();
78 virtualWake.vtx.reserve(np * nVortPerPan);
79
80 //Очистка и резервирование памяти
81 vortexBeginEnd.clear();
82 vortexBeginEnd.reserve(np);
83
85
86 std::pair<int, int> pair;
87
88 for (size_t i = 0; i < np; ++i)
89 {
90 midNorm = afl.nrm[i] * delta;
91
92 size_t NEWnVortPerPan = (size_t)std::max((int)std::ceil(fabs(sol(i) * afl.len[i]) / maxG), nVortPerPan);
93
94 pair.first = (int)virtualWake.vtx.size();
95
96
97 Point2D dr = 1.0 / NEWnVortPerPan * (afl.getR(i + 1) - afl.getR(i));
98
99 for (size_t j = 0; j < NEWnVortPerPan; ++j)
100 {
101 virtVort.r() = afl.getR(i) + dr * (j * 1.0 + 0.5) + midNorm;
102 virtVort.g() = sol(i) * afl.len[i] / NEWnVortPerPan;
103 virtualWake.vtx.push_back(virtVort);
104
105 virtualWake.vecHalfGamma.push_back(0.5 * sol(i) * afl.tau[i]);
106 virtualWake.aflPan.push_back({ numberInPassport, i });
107 }
108
109 pair.second = (int)virtualWake.vtx.size();
110 vortexBeginEnd.push_back(pair);
111 }
112
113
114 for (size_t j = 0; j < np; ++j)
115 sheets.freeVortexSheet(j, 0) = sol(j);
116
117}//SolutionToFreeVortexSheetAndVirtualVortex(...)
118
119
120//Генерация блока матрицы
121void BoundaryConstLayerAver::FillMatrixSelf(Eigen::MatrixXd& matr, Eigen::VectorXd& lastLine, Eigen::VectorXd& lactCol)
122{
123 size_t np = afl.getNumberOfPanels();
124
125 for (size_t i = 0; i < np; ++i)
126 {
127 lactCol(i) = 1.0;
128 lastLine(i) = afl.len[i];
129 }
130
131 for (size_t i = 0; i < np; ++i)
132 for (size_t j = 0; j < np; ++j)
133 matr(i, j) = afl.getA(1, i, afl, j)[0];
134
135}//FillMatrixSelf(...)
136
137void BoundaryConstLayerAver::FillIQSelf(std::pair<Eigen::MatrixXd, Eigen::MatrixXd>& IQ)
138{
139 afl.calcIQ(1, afl, IQ);
140}//FillIQSelf(...)
141
142//Генерация блока матрицы влияния от другого профиля того же типа
143void BoundaryConstLayerAver::FillMatrixFromOther(const Boundary& otherBoundary, Eigen::MatrixXd& matr)
144{
145 for (size_t i = 0; i < afl.getNumberOfPanels(); ++i)
146 for (size_t j = 0; j < otherBoundary.afl.getNumberOfPanels(); ++j)
147 matr(i, j) = afl.getA(1, i, otherBoundary.afl, j)[0];
148}//FillMatrixFromOther(...)
149
150
151void BoundaryConstLayerAver::FillIQFromOther(const Boundary& otherBoundary, std::pair<Eigen::MatrixXd, Eigen::MatrixXd>& IQ)
152{
153 afl.calcIQ(1, otherBoundary.afl, IQ);
154}//FillIQFromOther(...)
155
156
157//Вычисление скоростей в наборе точек, вызываемых наличием слоев вихрей и источников на профиле
158void BoundaryConstLayerAver::CalcConvVelocityToSetOfPointsFromSheets(const WakeDataBase& pointsDb, std::vector<Point2D>& velo) const
159{
160 std::vector<Point2D> selfVelo(pointsDb.vtx.size());
161
162 double cft = IDPI;
163
164#pragma warning (push)
165#pragma warning (disable: 4101)
166 //Локальные переменные для цикла
167 Point2D velI;
168 Point2D tempVel;
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;
237
238
239 if (npt > 0)
240 {
241 cuCalculateConvVeloWakeFromVirtual(npt, dev_ptr_pt, npnl, dev_ptr_r, \
242 dev_ptr_freeVortexSheet, dev_ptr_freeVortexSheetLin, \
243 dev_ptr_attachedVortexSheet, dev_ptr_attachedVortexSheetLin, \
244 dev_ptr_attachedSourceSheet, dev_ptr_attachedSourceSheetLin, \
245 dev_ptr_vel);
246
247 std::vector<Point2D> newV(Vel.size());
248 W.getCuda().CopyMemFromDev<double, 2>(npt, dev_ptr_vel, (double*)newV.data());
249
250 for (size_t q = 0; q < Vel.size(); ++q)
251 Vel[q] += newV[q];
252
253 /* VMlib::CreateUserDirectory(W.getPassport().dir, "dbg");
254 std::ostringstream sss;
255 sss << "velWakeFromBou";
256 sss << W.currentStep;
257 std::ofstream prmtFile(W.getPassport().dir + "dbg/" + sss.str());
258 prmtFile << "i x y g B2Wx B2Wy" << std::endl;
259 for (size_t i = 0; i < npt; ++i)
260 prmtFile << i << " " \
261 << pointsDb.vtx[i].r()[0] << " " << pointsDb.vtx[i].r()[1] << " " \
262 << pointsDb.vtx[i].g() << " " \
263 << newV[i][0] << " " << newV[i][1] << " " \
264 << std::endl;
265 prmtFile.close();*/
266 }
267 }
268}
269//GPUCalcConvVelocityToSetOfPointsFromSheets(...)
270#endif
271
272
273
274//Вычисление интенсивностей присоединенного вихревого слоя и присоединенного слоя источников
276{
277
278 for (size_t i = 0; i < sheets.getSheetSize(); ++i)
279 {
282 }
283
284 for (size_t i = 0; i < sheets.getSheetSize(); ++i)
285 {
286 sheets.attachedVortexSheet(i, 0) = 0.5 * (afl.getV(i) + afl.getV(i + 1)) & afl.tau[i];
287 sheets.attachedSourceSheet(i, 0) = 0.5 * (afl.getV(i) + afl.getV(i + 1)) & afl.nrm[i];
288 }
289}//ComputeAttachedSheetsIntensity()
290
291
292//Вычисляет влияния части подряд идущих вихрей из вихревого следа на прямолинейную панель для правой части
293void BoundaryConstLayerAver::GetInfluenceFromVorticesToRectPanel(size_t panel, const Vortex2D* ptr, ptrdiff_t count, std::vector<double>& wakeRhs) const
294{
295 double& velI = wakeRhs[0];
296
297 const Point2D& posI0 = afl.getR(panel);
298 const Point2D& posI1 = afl.getR(panel + 1);
299
300
301 for (size_t it = 0; it != count; ++it)
302 {
303 const Vortex2D& vt = ptr[it];
304
305 const Point2D& posJ = vt.r();
306 const double& gamJ = vt.g();
307
308 Point2D s = posJ - posI0;
309 Point2D p = posJ - posI1;
310
311 double alpha = VMlib::Alpha(p, s);
312
313 velI -= gamJ * alpha;
314 }
315}// GetInfluenceFromVorticesToRectPanel(...)
316
317
318
319//Вычисляет влияния части подряд идущих источников в области течения на прямолинейную панель для правой части
320void BoundaryConstLayerAver::GetInfluenceFromSourcesToRectPanel(size_t panel, const Vortex2D* ptr, ptrdiff_t count, std::vector<double>& wakeRhs) const
321{
322 double& velI = wakeRhs[0];
323
324 const Point2D& posI0 = afl.getR(panel);
325 const Point2D& posI1 = afl.getR(panel + 1);
326
327 for (size_t it = 0; it != count; ++it)
328 {
329 const Vortex2D& vt = ptr[it];
330 const Point2D& posJ = vt.r();
331 const double& gamJ = vt.g();
332
333 Point2D s = posJ - posI0;
334 Point2D p = posJ - posI1;
335
336 double lambda = VMlib::Lambda(p, s);
337
338 velI -= gamJ * lambda;
339 }
340}// GetInfluenceFromSourcesToRectPanel(...)
341
342
343//Вычисление влияния слоя источников конкретной прямолинейной панели на вихрь в области течения
345{
346 vel.toZero();
347
348 const Point2D& posI = ptr.r();
349
350 Point2D dj = afl.getR(panel + 1) - afl.getR(panel);
351 Point2D tauj = dj.unit();
352
353 Point2D s = posI - afl.getR(panel);
354 Point2D p = posI - afl.getR(panel + 1);
355
356 double a = VMlib::Alpha(p, s);
357
358 double lambda;
359 if ((s.length2() > 1e-16) && (p.length2() > 1e-16))
360 lambda = VMlib::Lambda(p, s);
361 else
362 lambda = 0.0;
363
364 vel += sheets.attachedSourceSheet(panel, 0) * (-a * tauj.kcross() + lambda * tauj);
365}// GetInfluenceFromSourceSheetAtRectPanelToVortex(...)
366
367//Вычисление влияния вихревых слоев (свободный + присоединенный) конкретной прямолинейной панели на вихрь в области течения
369{
370 vel.toZero();
371
372 const Point2D& posI = ptr.r();
373
374 Point2D dj = afl.getR(panel + 1) - afl.getR(panel);
375 Point2D tauj = dj.unit();
376
377 Point2D s = posI - afl.getR(panel);
378 Point2D p = posI - afl.getR(panel + 1);
379 double a = VMlib::Alpha(p, s);
380
381 double lambda;
382 if ((s.length2() > 1e-16) && (p.length2() > 1e-16))
383 lambda = VMlib::Lambda(p, s);
384 else
385 lambda = 0.0;
386
387 Point2D skos = -a * tauj.kcross() + lambda * tauj;
388
389 vel += sheets.freeVortexSheet(panel, 0) * skos.kcross();
390 vel += sheets.attachedVortexSheet(panel, 0) * skos.kcross();
391
392}// GetInfluenceFromVortexSheetAtRectPanelToVortex(...)
393
394
395//Вычисляет влияния набегающего потока на прямолинейную панель для правой части
396void BoundaryConstLayerAver::GetInfluenceFromVInfToRectPanel(std::vector<double>& vInfRhs) const
397{
398 size_t np = afl.getNumberOfPanels();
399 vInfRhs.resize(np);
400
401#pragma omp parallel for default(none) shared(vInfRhs, np)
402 for (int i = 0; i < np; ++i)
403 vInfRhs[i] = afl.tau[i] & W.getV0();
404
405}// GetInfluenceFromVInfToRectPanel(...)
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса BoundaryConstLayerAver.
Заголовочный файл с функциями для метода GMRES.
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса Mechanics.
Заголовочный файл с описанием класса StreamParser.
const double IDPI
Число .
Definition defs.h:79
Заголовочный файл с описанием класса 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:304
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:180
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition World2D.h:163
Point2D getV0() const
Возврат текущей скорости набегающего потока
Definition World2D.h:148
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
Definition World2D.h:273
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition World2D.h:263
Класс, опеделяющий двумерный вихревой элемент
Definition Vortex2D.h:59
HD Point2D & r()
Функция для доступа к радиус-вектору вихря
Definition Vortex2D.h:92
HD double & g()
Функция для доступа к циркуляции вихря
Definition Vortex2D.h:100
numvector< T, 2 > kcross() const
Геометрический поворот двумерного вектора на 90 градусов
Definition numvector.h:511
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:528
auto unit(P newlen=1) const -> numvector< typename std::remove_const< decltype(this->data[0] *newlen)>::type, n >
Вычисление орта вектора или вектора заданной длины, коллинеарного данному
Definition numvector.h:402
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