74 double tt1 = omp_get_wtime();
77 #if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONV_TOWAKE)) 89 double tt2 = omp_get_wtime();
115 std::vector<Point2D> nullVector(0);
119 #if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONV_TOBOU)) 132 #if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONVVIRT)) 165 std::vector<Point2D> velConvWake;
166 std::vector<std::vector<Point2D>> velConvBou;
170 velConvWake.resize(addWSize, { 0.0, 0.0 });
174 velConvBou[i].resize(addWSize, { 0.0, 0.0 });
176 #if (defined(USE_CUDA)) 180 #if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_VP)) 187 #
if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(
CU_VP))
196 for (
int i = 0; i < addWSize; ++i)
197 velocityRef[i] += velConvWake[i];
199 for (
size_t bou = 0; bou < velConvBou.size(); ++bou)
200 for (
int j = 0; j < addWSize; ++j)
201 velocityRef[j] += velConvBou[bou][j];
233 std::vector<Point2D> selfVelo(pointsDb.
vtx.size());
234 domainRadius.resize(pointsDb.
vtx.size());
238 #pragma warning (push) 239 #pragma warning (disable: 4101) 243 double dst2eps, dst2;
244 #pragma warning (pop) 250 #pragma omp parallel for default(none) shared(selfVelo, cft, calcVelo, calcRadius, eps2, pointsDb, domainRadius) private(tempVel, velI, dst2, dst2eps) schedule(dynamic, DYN_SCHEDULE) 251 for (
int i = 0; i < pointsDb.
vtx.size(); ++i)
253 double ee2[3] = { 10000.0, 10000.0, 10000.0 };
259 for (
size_t j = 0; j <
W.
getWake().
vtx.size(); ++j)
263 dst2 = (posI-posJ).length2();
269 #endif // !TESTONLYVELO 276 tempVel = { -posI[1] + posJ[1], posI[0] - posJ[0] };
277 tempVel *= (gamJ / dst2eps);
288 dst2 =
dist2(posI, posJ);
291 tempVel = { posI[0] - posJ[0], posI[1] - posJ[1] };
292 tempVel *= (gamJ / dst2eps);
302 for (
size_t j = 0; j < bou.virtualWake.vtx.size(); ++j)
313 domainRadius[i] = 1.0 * sqrt((ee2[0] + ee2[1] + ee2[2]) / 3.0);
319 #pragma omp parallel for default(none) shared(selfVelo, cft, calcVelo, calcRadius, pointsDb, domainRadius) private(tempVel, velI, dst2) schedule(dynamic, DYN_SCHEDULE) 320 for (
int i = 0; i < pointsDb.
vtx.size(); ++i)
322 double ee2[3] = { 10000.0, 10000.0, 10000.0 };
328 for (
size_t j = 0; j <
W.
getWake().
vtx.size(); ++j)
332 dst2 =
dist2(posI, posJ);
343 dst2 =
dist2(posI, posJ);
360 domainRadius[i] = 1.0 * sqrt((ee2[0] + ee2[1] + ee2[2]) / 3.0);
366 for (
size_t i = 0; i < velo.size(); ++i)
367 velo[i] += selfVelo[i];
371 #if defined(USE_CUDA) 372 void VelocityBiotSavart::GPUWakeToWakeFAST(
const WakeDataBase& pointsDb, std::vector<Point2D>& velo, std::vector<double>& domainRadius,
bool calcVelo,
bool calcRadius)
374 size_t npt = pointsDb.
vtx.size();
375 double*& dev_ptr_pt = pointsDb.devVtxPtr;
378 double*& dev_ptr_vt =
W.
getWake().devVtxPtr;
381 double*& dev_ptr_sr =
W.
getSource().devVtxPtr;
385 size_t*
const& dev_nVortices =
W.
getCuda().dev_ptr_nVortices;
387 double**
const& dev_ptr_ptr_vtx =
W.
getCuda().dev_ptr_ptr_vtx;
389 std::vector<Point2D> Vel(npt);
390 std::vector<double> Rad(npt);
392 std::vector<Point2D> newV(npt);
395 double*& dev_ptr_vel = pointsDb.devVelPtr;
396 double*& dev_ptr_rad = pointsDb.devRadPtr;
409 nbou, dev_nVortices, dev_ptr_ptr_vtx);
419 W.
getCuda().CopyMemFromDev<double, 2>(npt, dev_ptr_vel, (
double*)newV.data(), 20);
487 for (
size_t q = 0; q < npt; ++q)
490 for (
size_t q = 0; q < npt; ++q)
503 W.
getCuda().CopyMemFromDev<double, 1>(npt, dev_ptr_rad, Rad.data(), 212);
507 for (
size_t q = 0; q < Rad.size(); ++q)
508 domainRadius[q] = Rad[q];
526 #if defined(USE_CUDA) 527 void VelocityBiotSavart::GPUCalcConvVeloToSetOfPointsFromWake(
const WakeDataBase& pointsDb, std::vector<Point2D>& velo, std::vector<double>& domainRadius,
bool calcVelo,
bool calcRadius)
531 size_t npt = pointsDb.
vtx.size();
532 double*& dev_ptr_pt = pointsDb.devVtxPtr;
541 double*& dev_ptr_vt =
W.
getWake().devVtxPtr;
543 double*& dev_ptr_sr =
W.
getSource().devVtxPtr;
547 size_t*
const& dev_nVortices =
W.
getCuda().dev_ptr_nVortices;
549 double**
const& dev_ptr_ptr_vtx =
W.
getCuda().dev_ptr_ptr_vtx;
551 std::vector<Point2D> Vel(npt);
552 std::vector<double> Rad(npt);
554 std::vector<Point2D> newV(npt);
556 double*& dev_ptr_vel = pointsDb.devVelPtr;
557 double*& dev_ptr_rad = pointsDb.devRadPtr;
563 cuCalculateConvVeloWake(npt, dev_ptr_pt, nvt, dev_ptr_vt, nsr, dev_ptr_sr, nbou, dev_nVortices, dev_ptr_ptr_vtx, dev_ptr_vel, dev_ptr_rad, eps2, calcVelo, calcRadius);
571 W.
getCuda().CopyMemFromDev<double, 2>(npt, dev_ptr_vel, (
double*)newV.data(), 20);
578 for (
size_t q = 0; q < npt; ++q)
583 for (
size_t q = 0; q < npt; ++q)
604 W.
getCuda().CopyMemFromDev<double, 1>(npt, dev_ptr_rad, Rad.data(), 211);
611 for (
size_t q = 0; q < Rad.size(); ++q)
612 domainRadius[q] = Rad[q];
618 size_t curGlobPnl = 0;
622 for (
size_t q = 0; q < nv; ++q)
649 std::vector<double> velI(shDim, 0.0);
651 #pragma omp parallel for default(none) shared(shDim, afl, np, wakeRhs, IDPI) private(velI) 652 for (
int i = 0; i < np; ++i)
654 velI.assign(shDim, 0.0);
668 for (
size_t j = 0; j < shDim; ++j)
671 wakeRhs[i] = velI[0];
674 wakeRhs[np + i] = velI[1];
680 #if defined(USE_CUDA) 682 void VelocityBiotSavart::GPUGetWakeInfluenceToRhs(
const Airfoil& afl, std::vector<double>& wakeVelo)
const 696 double*& dev_ptr_pt = afl.devRPtr;
697 double*& dev_ptr_vt =
W.
getWake().devVtxPtr;
698 double*& dev_ptr_sr =
W.
getSource().devVtxPtr;
699 double*& dev_ptr_rhs = afl.devRhsPtr;
700 double*& dev_ptr_rhsLin = afl.devRhsLinPtr;
702 std::vector<double> locrhs(nTotPan);
703 std::vector<double> locrhsLin(nTotPan);
707 if ((nvt > 0) || (nsr > 0))
709 cuCalculateRhs(nTotPan, dev_ptr_pt, nvt, dev_ptr_vt, nsr, dev_ptr_sr, eps2, dev_ptr_rhs, dev_ptr_rhsLin);
711 std::vector<double> newRhs(nTotPan), newRhsLin(nTotPan);
713 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhs, newRhs.data(), 22);
715 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhsLin, newRhsLin.data(), 22);
721 size_t curGlobPnl = 0;
727 tmpRhs.insert(tmpRhs.end(), newRhs.begin() + curGlobPnl, newRhs.begin() + curGlobPnl + np);
729 tmpRhs.insert(tmpRhs.end(), newRhsLin.begin() + curGlobPnl, newRhsLin.begin() + curGlobPnl + np);
736 if ((nvt > 0) || (nsr > 0))
737 wakeVelo = std::move(afl.tmpRhs);
744 #if defined(USE_CUDA) 746 void VelocityBiotSavart::GPUFASTGetWakeInfluenceToRhs(
const Airfoil& afl, std::vector<double>& wakeVelo)
const 760 double*& dev_ptr_pt = afl.devRPtr;
761 double*& dev_ptr_vt =
W.
getWake().devVtxPtr;
762 double*& dev_ptr_sr =
W.
getSource().devVtxPtr;
763 double*& dev_ptr_rhs = afl.devRhsPtr;
764 double*& dev_ptr_rhsLin = afl.devRhsLinPtr;
765 std::vector<double> locrhs(nTotPan);
766 std::vector<double> locrhsLin(nTotPan);
768 if ((nvt > 0) || (nsr > 0))
772 double timingsToRHS[7];
777 (
double*)dev_ptr_rhs,
778 (
double*)((shDim == 1) ?
nullptr : dev_ptr_rhsLin),
796 std::vector<double> newRhs(nTotPan), newRhsLin(nTotPan);
798 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhs, newRhs.data(), 22);
800 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhsLin, newRhsLin.data(), 22);
806 size_t curGlobPnl = 0;
812 tmpRhs.insert(tmpRhs.end(), newRhs.begin() + curGlobPnl, newRhs.begin() + curGlobPnl + np);
814 tmpRhs.insert(tmpRhs.end(), newRhsLin.begin() + curGlobPnl, newRhsLin.begin() + curGlobPnl + np);
822 if ((nvt > 0) || (nsr > 0))
823 wakeVelo = std::move(afl.tmpRhs);
834 Eigen::VectorXd locRhs;
837 size_t currentRow = 0;
849 locRhs.resize(nVars);
852 std::vector<double> wakeRhs;
854 double tt1 = omp_get_wtime();
856 #if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_RHS)) 858 GPUFASTGetWakeInfluenceToRhs(afl, wakeRhs);
866 double tt2 = omp_get_wtime();
870 std::vector<double> vInfRhs;
887 #pragma omp parallel for \ 889 shared(locRhs, afl, bou, wakeRhs, vInfRhs, np) \ 890 schedule(dynamic, DYN_SCHEDULE) 893 locRhs(i) = -vInfRhs[i] - wakeRhs[i] + 0.25 * ((afl.
getV(i) + afl.
getV(i + 1)) & afl.
tau[i]);
895 locRhs(np + i) = -vInfRhs[np + i] - wakeRhs[np + i];
901 const auto& iq =
W.
getIQ(bou, q);
908 if ((i != j) || (bou != q))
910 locRhs(i) += -iq.first(i, j) * sht.attachedVortexSheet(j, 0);
911 locRhs(i) += -iq.second(i, j) * sht.attachedSourceSheet(j, 0);
957 for (
size_t i = 0; i < nVars; ++i)
958 rhs(i + currentRow) = locRhs(i);
960 rhs(currentRow + nVars) = lastRhs[bou];
962 currentRow += nVars + 1;
const std::pair< Eigen::MatrixXd, Eigen::MatrixXd > & getIQ(size_t i, size_t j) const
Возврат константной ссылки на объект, связанный с матрицей интегралов от (r-xi)/|r-xi|^2.
Заголовочный файл с описанием класса Passport (двумерный) и cоответствующими структурами ...
Times & getTimestat() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
virtual void CalcConvVelocityAtVirtualVortexes(std::vector< Point2D > &velo) const =0
Вычисление конвективной скорости в точках расположения виртуальных вихрей
double wrapperInfluence(const realVortex *vtxl, realPoint *vell, real *epsastl, CUDApointers &ptrs, int nbodies, double *timing, real eps, real theta, size_t &nbodiesOld, int nbodiesUp, int order, size_t nAfls, size_t *nVtxs, double **ptrVtxs)
void CalcDiffVeloI1I2ToSetOfPointsFromWake(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const WakeDataBase &vorticesDb, std::vector< double > &I1, std::vector< Point2D > &I2)
Вычисление числителей и знаменателей диффузионных скоростей в заданном наборе точек ...
Заголовочный файл с описанием класса Wake.
std::pair< std::string, int > boundaryCondition
Метод аппроксимации граничных условий
Заголовочный файл с описанием класса World2D.
double area
Площадь профиля
Boundary & getNonConstBoundary(size_t i) const
Возврат неконстантной ссылки на объект граничного условия
Gpu & getNonConstCuda() const
Возврат неконстантной ссылки на объект, связанный с видеокартой (GPU)
bool inverse
Признак разворота нормалей (для расчета внутренних течений)
void CalcDiffVeloI1I2ToWakeFromSheets(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const Boundary &bnd, std::vector< double > &I1, std::vector< Point2D > &I2) override
size_t getNumberOfBoundary() const
Возврат количества граничных условий в задаче
Заголовочный файл с описанием класса Airfoil.
const Velocity & getVelocity() const
Возврат константной ссылки на объект для вычисления скоростей
double currTime
Текущее время
Абстрактный класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле ...
const Wake & getWake() const
Возврат константной ссылки на вихревой след
Заголовочный файл с описанием класса VelocityBiotSavart.
std::vector< double > gammaThrough
Суммарные циркуляции вихрей, пересекших панели профиля на прошлом шаге
Mechanics & getNonConstMechanics(size_t i) const
Возврат неконстантной ссылки на объект механики
const size_t numberInPassport
Номер профиля в паспорте
virtual ~VelocityBiotSavart()
Деструктор
void CalcConvVeloToSetOfPointsFromWake(const WakeDataBase &pointsDb, std::vector< Point2D > &velo, std::vector< double > &domainRadius, bool calcVelo, bool calcRadius)
Вычисление конвективных скоростей и радиусов вихревых доменов в заданном наборе точек от следа ...
Заголовочный файл с описанием класса Mechanics.
PhysicalProperties physicalProperties
Структура с физическими свойствами задачи
const World2D & W
Константная ссылка на решаемую задачу
const Point2D & getV(size_t q) const
Возврат константной ссылки на скорость вершины профиля
timePeriod timeCalcVortexConvVelo
Начало и конец процесса вычисления конвективных скоростей вихрей
const bool isMoves
Переменная, отвечающая за то, двигается профиль или нет
void ModifyE2(double *ee2, double dst2)
Модифицирует массив квадратов расстояний до ближайших вихрей из wake.
const Mechanics & getMechanics(size_t i) const
Возврат константной ссылки на объект механики
const WakeDataBase & getSource() const
Возврат константной ссылки на источники в области течения
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
void CalcDiffVeloI1I2ToWakeFromWake(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const WakeDataBase &vorticesDb, std::vector< double > &I1, std::vector< Point2D > &I2) override
VelocityBiotSavart(const World2D &W_)
Конструктор
void GetWakeInfluenceToRhs(const Airfoil &afl, std::vector< double > &wakeRhs) const
Генерация вектора влияния вихревого следа на профиль
virtual void FillRhs(Eigen::VectorXd &rhs) const override
Расчет вектора правой части (всего)
std::vector< VortexesParams > virtualVortexesParams
Вектор струтур, определяющий параметры виртуальных вихрей для профилей
double accelCft() const
Функция-множитель, позволяющая моделировать разгон
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
double wrapperInfluenceToRHS(const realVortex *dev_ptr_vt, const double *dev_ptr_pt, double *dev_ptr_rhs, double *dev_ptr_rhslin, CUDApointers &ptrs, bool rebuild, int nvt, int nTotPan, double *timingsToRHS, double theta, size_t &nbodiesOld, int nbodiesUp, int order, int scheme)
const Boundary & getBoundary(size_t i) const
Возврат константной ссылки на объект граничного условия
void CalcDiffVeloI1I2ToSetOfPointsFromSheets(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const Boundary &bnd, std::vector< double > &I1, std::vector< Point2D > &I2)
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
virtual void CalcConvVelocityToSetOfPointsFromSheets(const WakeDataBase &pointsDb, std::vector< Point2D > &velo) const =0
Вычисление конвективных скоростей в наборе точек, вызываемых наличием слоев вихрей и источников на пр...
const MeasureVP & getMeasureVP() const
Возврат константной ссылки на measureVP.
int saveVPstep
Шаг вычисления и сохранения скорости и давления
Заголовочный файл с описанием класса 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
Структура с используемыми численными схемами
virtual double AngularVelocityOfAirfoil(double currTime)=0
Вычисление угловой скорости профиля
std::vector< Point2D > & getNonConstVelocity()
Возврат velocity.
virtual void GetInfluenceFromVorticesToPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &panelRhs) const =0
Вычисление влияния части подряд идущих вихрей из вихревого следа на панель для правой части ...
Velocity & getNonConstVelocity() const
Возврат неконстантной ссылки на объект для вычисления скоростей
Класс, опеделяющий двумерный вектор
std::vector< Point2D > tau
Касательные к панелям профиля
void ModifyE2(double *ee2, double dst2)
Модифицирует массив квадратов расстояний до ближайших вихрей из wake.
Sheet sheets
Слои на профиле
virtual void CalcConvVelo() override
Вычисление конвективных скоростей вихрей и виртуальных вихрей в вихревом следе, а также в точках wake...
Заголовочный файл с описанием класса MeasureVP.
const Passport & getPassport() const
Возврат константной ссылки на паспорт
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
VortexesParams wakeVortexesParams
Струтура, определяющая параметры вихрей в следе
virtual void GetInfluenceFromVInfToPanel(std::vector< double > &vInfRhs) const =0
Вычисление влияния набегающего потока на панель для правой части
Класс, опеделяющий двумерный вихревой элемент
double boundDenom(double r2, double eps2)
Способ сглаживания скорости вихря (вихрь Рэнкина или вихрь Ламба)
std::vector< double > epsastWake
Вектор характерных радиусов вихревых доменов (eps*)
const bool isDeform
Переменная, отвечающая за то, деформируется профиль или нет
VirtualWake virtualWake
Виртуальный вихревой след конкретного профиля
MeasureVP & getNonConstMeasureVP() const
Возврат неконстантной ссылки на measureVP.
timePeriod timeVP
Начало и конец процесса подсчета полей скоростей и давления и сохранения их в файл ...
Абстрактный класс, определяющий обтекаемый профиль
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
size_t sheetDim
Размерность параметров каждого из слоев на каждой из панелей
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Point2D V0() const
Функция скорости набегающего потока с учетом разгона
Класс, опеделяющий текущую решаемую задачу
Абстрактный класс, определяющий способ вычисления скоростей
Класс, опеделяющий набор вихрей
numvector< T, n > & toZero(P val=0)
Установка всех компонент вектора в константу (по умолчанию — нуль)
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
std::vector< double > len
Длины панелей профиля
const WakeDataBase & getWakeVP() const
Возврат wakeVP.
std::vector< double > & getNonConstDomainRadius()
Возврат domainRadius.
Airfoil & getNonConstAirfoil(size_t i) const
Возврат неконстантной ссылки на объект профиля
std::vector< Point2D > convVelo
Вектор конвективных скоростей вихрей
virtual void CalcVeloToWakeVP() override
Вычисление скоростей в точках wakeVP.
virtual void GetInfluenceFromSourcesToPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &panelRhs) const =0
Вычисление влияния части подряд идущих источников из области течения на панель для правой части ...
double eps2
Квадрат радиуса вихря
Заголовочный файл с описанием класса Boundary.
size_t GetUnknownsSize() const
Возврат размерности вектора решения