46 #include <sys/types.h> 99 if ((((aflRj - oldPos) ^ (newPos - oldPos)) * ((aflRj1 - oldPos) ^ (newPos - oldPos)) <= 0) && \
100 (((oldPos - aflRj) ^ (aflRj1 - aflRj)) * ((newPos - aflRj) ^ (aflRj1 - aflRj)) <= 0))
200 double dist2 = 1000000000.0;
205 v1 = afl.
getR(i) - newPos;
207 v2 = afl.
getR(i + 1) - newPos;
221 angle += atan2(sn, cs);
224 hit = ((angle > 3.14) || (angle < -3.14));
281 std::vector<double> gamma;
284 std::vector<int> through;
285 through.resize(
vtx.size(), -1);
287 #pragma omp parallel for default(none) shared(afl, oldAfl, isMoves, through, newPos) 288 for (
int i = 0; i < (int)
vtx.size(); ++i)
295 through[i] = (int)minN;
306 for (
size_t q = 0; q < through.size(); ++q)
309 gamma[through[q]] +=
vtx[q].g();
332 #pragma omp parallel for default(none) shared(type, maxG) schedule(dynamic, DYN_SCHEDULE) 333 for (
int i = 0; i <
vtx.size(); ++i)
345 while ( (!found) && ( s + 1 < (int)
vtx.size() ) )
350 r2 =
dist2(vtxI.
r(), vtxK.
r());
353 double mnog = std::max(1.0, (vtxI.
r()[0] - cRBP) / cSP);
368 found = ( fabs(vtxI.
g()*vtxK.
g()) != 0.0) && (fabs(vtxI.
g() + vtxK.
g()) <
sqr(mnog) * maxG);
371 found = (vtxI.
g()*vtxK.
g() < 0.0);
374 found = (vtxI.
g()*vtxK.
g() > 0.0) && (fabs(vtxI.
g() + vtxK.
g()) <
sqr(mnog) * maxG);
386 #if defined(USE_CUDA) 387 void Wake::GPUGetPairs(
int type)
389 size_t npt =
vtx.size();
391 double tCUDASTART = 0.0, tCUDAEND = 0.0;
393 tCUDASTART += omp_get_wtime();
394 std::vector<int> tnei(npt, 0);
401 W.
getCuda().CopyMemFromDev<int, 1>(npt, devNeiPtr,
neighb.data(), 30);
404 tCUDAEND += omp_get_wtime();
418 std::vector<bool> flag;
419 for (
int z = 0; z < times; ++z)
422 #if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_PAIRS)) 438 flag.resize(
vtx.size(),
false);
440 double sumAbsGam, iws;
443 for (
size_t vt = 0; vt + 1 <
vtx.size(); ++vt)
455 if ((ssd < 0) || (ssd >= flag.size()))
456 std::cout <<
"ssd = " << ssd <<
", flag.size() = " << flag.size() <<
", vtx.size() = " <<
vtx.size() << std::endl;
458 if ((ssd != 0) && (!flag[ssd]))
469 sumVtx.
g() = vtxI.
g() + vtxK.
g();
475 sumAbsGam = fabs(vtxI.
g()) + fabs(vtxK.
g());
477 iws = sumAbsGam > 1e-10 ? 1.0 / sumAbsGam : 1.0;
479 sumVtx.
r() = (vtxI.
r() * fabs(vtxI.
g()) + vtxK.
r() * fabs(vtxK.
g())) * iws;
483 sumVtx.
r() = (fabs(vtxI.
g()) > fabs(vtxK.
g())) ? vtxI.
r() : vtxK.
r();
532 std::vector<bool> flag;
533 for (
int z = 0; z < times; ++z)
538 flag.resize(
vtx.size(),
false);
540 double sumAbsGam, iws, r2, r2test;
543 for (
size_t vt = 0; vt + 1 <
vtx.size(); ++vt)
548 for (
int s = 0; s <
knb - 1; ++s)
553 r2 =
dist2(vtxI.
r(), vtxK.r());
555 double mnog = std::max(1.0, (vtxI.
r()[0] - cRBP) / cSP);
560 bool keyGamma =
false;
564 keyGamma = (fabs(vtxI.
g() * vtxK.g()) != 0.0) && (fabs(vtxI.
g() + vtxK.g()) <
sqr(mnog) * maxG);
567 keyGamma = (vtxI.
g() * vtxK.g() < 0.0);
570 keyGamma = (vtxI.
g() * vtxK.g() > 0.0) && (fabs(vtxI.
g() + vtxK.g()) <
sqr(mnog) * maxG);
574 if ((r2 < r2test) && (keyGamma))
576 if ((ssd != 0) && (!flag[ssd]))
581 sumVtx.
g() = vtxI.
g() + vtxK.g();
587 sumAbsGam = fabs(vtxI.
g()) + fabs(vtxK.g());
589 if (sumAbsGam > 1e-10)
590 sumVtx.
r() = (vtxI.
r() * fabs(vtxI.
g()) + vtxK.r() * fabs(vtxK.g())) * (1.0 / sumAbsGam);
592 sumVtx.
r() = 0.5 * (vtxI.
r() + vtxK.r());
597 sumVtx.
r() = (fabs(vtxI.
g()) > fabs(vtxK.g())) ? vtxI.
r() : vtxK.r();
640 Point2D zerovec = { 0.0, 0.0 };
641 #pragma omp parallel for default(none) shared(distFar2, zerovec) reduction(+:nFar) 642 for (
int i = 0; i <static_cast<int>(
vtx.size()); ++i)
644 if (
dist2(
vtx[i].r(), zerovec) > distFar2)
657 const double porog_g = 1e-15;
661 newWake.reserve(
vtx.size());
663 for (
size_t q = 0; q <
vtx.size(); ++q)
664 if (fabs(
vtx[q].g()) > porog_g)
665 newWake.push_back(
vtx[q]);
667 size_t delta =
vtx.size() - newWake.size();
690 std::vector<double> rightBorder, horizSpan;
711 #if defined(__CUDACC__) || defined(USE_CUDA) 727 for (
int collapsStep = 1; collapsStep <= 2; ++collapsStep)
729 #if defined(USE_CUDA) 739 std::vector<std::vector<std::pair<double, size_t>>> initdist(
vtx.size());
740 for (
auto& d : initdist)
741 d.resize(2 *
knb, { -1.0, -1 });
745 std::vector<std::pair<double, size_t>> initdistcuda(
knb *
vtx.size(), { -1.0, -1 });
746 kNNcuda(
vtx,
knb, initdistcuda, vecForKnn);
749 for (
int i = 0; i <
vtx.size(); ++i)
752 neighbNew[i] = (int)initdist[i][1].second;
754 for (
int j = 0; j <
knb - 1; ++j)
755 neighbNew[i * (knb - 1) + j] = (int)initdistcuda[(i * knb) + (j + 1)].second;
Заголовочный файл с описанием класса Passport (двумерный) и cоответствующими структурами ...
Times & getTimestat() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
std::pair< std::string, int > velocityComputation
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса World2D.
Gpu & getNonConstCuda() const
Возврат неконстантной ссылки на объект, связанный с видеокартой (GPU)
bool inverse
Признак разворота нормалей (для расчета внутренних течений)
timePeriod timeRestruct
Начало и конец процесса реструктуризации пелены
Заголовочный файл с описанием класса Airfoil.
double maxGamma
Максимально допустимая циркуляция вихря
const Wake & getWake() const
Возврат константной ссылки на вихревой след
std::vector< double > gammaThrough
Суммарные циркуляции вихрей, пересекших панели профиля на прошлом шаге
Point2D lowLeft
Левый нижний угол габаритного прямоугольника профиля
Заголовочный файл с описанием класса Preprocessor.
Заголовочный файл с описанием класса Mechanics.
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
HD Point2D & r()
Функция для доступа к радиус-вектору вихря
HD double & g()
Функция для доступа к циркуляции вихря
int RemoveFar()
Зануление далеко улетевших вихрей
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
double collapseRightBorderParameter
абсцисса, правее которой происходит линейный (вправо) рост радиуса коллапса
auto length2() const -> typename std::remove_const< typename std::remove_reference< decltype(this->data[0])>::type >::type
Вычисление квадрата нормы (длины) вектора
Класс, обеспечивающий возможность выполнения вычислений на GPU по технологии Nvidia CUDA...
size_t RemoveZero()
Исключение нулевых и мелких вихрей
Point2D upRight
Правый верхний угол габаритного прямоугольника профиля
void GetPairs(int type)
Поиск ближайшего соседа
T sqr(T x)
Возведение числа в квадрат
void GetPairsBS(int type)
Wake & getNonConstWake() const
Возврат неконстантной ссылки на вихревой след
bool MoveInside(const Point2D &newPos, const Point2D &oldPos, const Airfoil &afl, size_t &panThrough)
Проверка проникновения точки через границу профиля
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
bool MoveInsideMovingBoundary(const Point2D &newPos, const Point2D &oldPos, const Airfoil &oldAfl, const Airfoil &afl, size_t &panThrough)
Проверка проникновения точки через границу профиля
Заголовочный файл с описанием класса StreamParser.
auto dist2(const numvector< T, n > &x, const numvector< P, n > &y) -> typename std::remove_const< decltype(x[0]-y[0])>::type
Вычисление квадрата расстояния между двумя точками
std::vector< Vortex2D > vtx
Список вихревых элементов
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
const World2D & W
Константная ссылка на решаемую задачу
Класс, опеделяющий двумерный вектор
Заголовочный файл с описанием класса MeasureVP.
void setCollapseCoeff(double pos_, double refLength_)
Установка правой границы самого правого профиля (для организации увеличения радиуса коллапса) ...
const Passport & getPassport() const
Возврат константной ссылки на паспорт
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
Класс, опеделяющий двумерный вихревой элемент
int Collaps(int type, int times)
Коллапс вихрей
std::vector< int > neighbNew
Абстрактный класс, определяющий обтекаемый профиль
std::vector< int > neighb
Вектор потенциальных соседей для будущего коллапса
double collapseScaleParameter
характерный масштаб, на котором происходит рост радиуса коллапса
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
void WakekNN(const std::vector< Vortex2D > &vtx, const size_t k, std::vector< std::vector< std::pair< double, size_t >>> &initdist)
void Inside(const std::vector< Point2D > &newPos, Airfoil &afl, bool isMoves, const Airfoil &oldAfl)
Проверка пересечения вихрями следа профиля при перемещении
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
Заголовочный файл с описанием класса Velocity.
int CollapsNew(int type, int times)
void Restruct()
Реструктуризация вихревого следа
Заголовочный файл с описанием класса Boundary.
double distFar
Расстояние от центра самого подветренного (правого) профиля, на котором вихри уничтожаются ...
bool isOutsideGabarits(const Point2D &r) const
Определяет, находится ли точка с радиус-вектором вне габаритного прямоугольника профиля ...
double epscol
Радиус коллапса