VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
VM2D::Velocity Class Referenceabstract

Абстрактный класс, определяющий способ вычисления скоростей More...

#include <Velocity2D.h>

Inheritance diagram for VM2D::Velocity:
Collaboration diagram for VM2D::Velocity:

Public Member Functions

 Velocity (const World2D &W_)
 Конструктор
 
void CalcConvVelo ()
 Вычисление конвективных скоростей вихрей и виртуальных вихрей в вихревом следе, а также в точках wakeVP.
 
virtual float CalcConvVeloToSetOfPointsFromWake (const WakeDataBase &pointsDb, std::vector< Point2D > &velo, std::vector< double > &domainRadius, bool calcVelo, bool calcRadius)=0
 Вычисление конвективных скоростей и радиусов вихревых доменов в заданном наборе точек от следа
 
virtual void CalcConvVPVeloToSetOfPointsFromWake (const WakeDataBase &pointsDb, std::vector< Point2D > &velo, std::vector< double > &domainRadius, bool calcVelo, bool calcRadius)
 
virtual void CalcVeloToWakeVP ()
 Вычисление скоростей в точках wakeVP.
 
void CalcDiffVeloI1I2ToSetOfPointsFromWake (const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const WakeDataBase &vorticesDb, std::vector< double > &I1, std::vector< Point2D > &I2)
 Вычисление числителей и знаменателей диффузионных скоростей в заданном наборе точек
 
void CalcDiffVeloI1I2ToSetOfPointsFromSheets (const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const Boundary &bnd, std::vector< double > &I1, std::vector< Point2D > &I2)
 
void CalcDiffVeloI1I2ToWakeFromSheets (const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const Boundary &bnd, std::vector< double > &I1, std::vector< Point2D > &I2)
 
void CalcDiffVeloI1I2ToWakeFromWake (const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const WakeDataBase &vorticesDb, std::vector< double > &I1, std::vector< Point2D > &I2)
 
void CalcDiffVeloI1I2 ()
 Вычисление диффузионных скоростей вихрей и виртуальных вихрей в вихревом следе
 
void CalcDiffVeloI0I3 ()
 
void LimitDiffVelo (std::vector< Point2D > &diffVel)
 Контроль больших значений диффузионных скоростей
 
void CalcDiffVelo ()
 Вычисление диффузионных скоростей
 
void ResizeAndZero ()
 Очистка старых массивов под хранение скоростей, выделение новой памяти и обнуление
 
void SaveVisStress ()
 Сохранение вязких напряжений
 
void GetWakeInfluenceToRhs (const Airfoil &afl, std::vector< double > &wakeRhs) const
 Генерация вектора влияния вихревого следа на профиль
 
void CPUGetFASTWakeInfluenceToRhs (std::vector< double > &wakeRhs, std::vector< double > &wakeRhsLin) const
 
void FillRhs (Eigen::VectorXd &rhsReord) const
 
virtual ~Velocity ()
 Деструктор
 

Public Attributes

VortexesParams wakeVortexesParams
 Струтура, определяющая параметры вихрей в следе
 
std::vector< VortexesParams > virtualVortexesParams
 Вектор струтур, определяющий параметры виртуальных вихрей для профилей
 
OptimizedVelocity optimizedVelocity
 

Protected Attributes

const World2D & W
 Константная ссылка на решаемую задачу
 

Detailed Description

Абстрактный класс, определяющий способ вычисления скоростей

Author
Марчевский Илья Константинович
Сокол Ксения Сергеевна
Рятина Евгения Павловна
Колганова Александра Олеговна
Version
1.14
Date
6 марта 2026 г.

Definition at line 104 of file Velocity2D.h.

Constructor & Destructor Documentation

◆ Velocity()

VM2D::Velocity::Velocity ( const World2D &  W_)
inline

Конструктор

Parameters
[in]W_константная ссылка на решаемую задачу

Definition at line 122 of file Velocity2D.h.

122 :
123 W(W_)
124 {
125 virtualVortexesParams.resize(0);
126 };
std::vector< VortexesParams > virtualVortexesParams
Вектор струтур, определяющий параметры виртуальных вихрей для профилей
Definition Velocity2D.h:115
const World2D & W
Константная ссылка на решаемую задачу
Definition Velocity2D.h:108

◆ ~Velocity()

virtual VM2D::Velocity::~Velocity ( )
inlinevirtual

Деструктор

Definition at line 216 of file Velocity2D.h.

216{ };

Member Function Documentation

◆ CalcConvVelo()

void Velocity::CalcConvVelo ( )

Вычисление конвективных скоростей вихрей и виртуальных вихрей в вихревом следе, а также в точках wakeVP.

Warning
скорости приплюсовываются к уже имеющимся

FMM ///

Definition at line 972 of file Velocity2D.cpp.

973{
974 W.getTimers().start("ConvVel");
975
976 //Влияние следа на след
977#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONV_TOWAKE))
978 //Вызов виртуальной функции
979
982
983 VMlib::vmTimer timerAgpu, timerBgpu;
984
985 std::unique_ptr<BHcu::CudaTreeInfo>& cntrTree = W.getNonConstCuda().cntrTreeWake;
986 auto& treeWake = *W.getNonConstCuda().inflTreeWake;
988 {
989 cntrTree->MemoryAllocate((int)W.getCuda().n_CUDA_wake);
990 cntrTree->Update((int)W.getWake().vtx.size(), W.getWake().devVtxPtr);
991 cntrTree->Build();
992
993 //Перестроение дерева для вихрей //todo //временно для корректного расчета epsast
994 treeWake.MemoryAllocate((int)W.getCuda().n_CUDA_wake);
995 treeWake.Update((int)W.getWake().vtx.size(), W.getWake().devVtxPtr);
996 timerAgpu.start();
997 treeWake.Build();
998 timerAgpu.stop();
999
1000 timerBgpu.start();
1001 treeWake.UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1002 timerBgpu.stop();
1003 }
1004
1005 double timerCgpuduration = GPUCalcConvVeloToSetOfPointsFromWake(W.getNonConstCuda().cntrTreeWake, W.getWake(), wakeVortexesParams.convVelo, wakeVortexesParams.epsastWake, true, true);
1006
1007
1009
1011 /*
1012 std::vector<fmm::particle2d> sources(W.getWake().vtx.size());
1013 #pragma omp parallel for
1014 for (int i = 0; i < (int)sources.size(); ++i)
1015 {
1016 const auto& w = W.getWake().vtx[i];
1017
1018 sources[i].center = fmm::point2d(w.r()[0], w.r()[1]);
1019 sources[i].q = w.g();
1020 sources[i].morton_code = 0;
1021 }
1022
1023 auto targets = sources;
1024 for (int i = 0; i < (int)sources.size(); ++i)
1025 targets[i].q = 0;
1026
1027 double t = omp_get_wtime();
1028 //fmm::ComputeExact<fmm::InteractionType::Potential2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1029 fmm::ComputeExact<fmm::InteractionType::Force2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1030 std::cout << "Compute exact time = " << omp_get_wtime() - t << std::endl;
1031
1032 t = omp_get_wtime();
1033
1034 fmm::FastMultipole fmm(sources, targets, 1.e-8, fmm::FMM_AUTO, fmm::FMM_AUTO); // or fmm::gpu::FastMultipole... for gpu version
1035 fmm::ReadError<fmm::InteractionType::Force2d>(fmm.forces);
1036 //fmm::ReadError<fmm::InteractionType::Potential2d>(fmm.potentials);
1037 std::cout << "Total time = " << omp_get_wtime() - t << std::endl;
1038 */
1039
1040
1041
1043 /*
1044 std::ofstream treeTimeFile;
1045 if (W.getCurrentStep() == 0)
1046 {
1047 treeTimeFile.open(W.getPassport().dir + "/dbg/treeTime.csv");
1048 treeTimeFile << "step,time,N,lev,averPoints,tBUI,tUPW,tDNW,tBUIgpu,tUPWgpu,tDNWgpu\n";
1049 }
1050 else
1051 treeTimeFile.open(W.getPassport().dir + "/dbg/treeTime.csv", std::ios::app);
1052
1053
1054 int estLevel = std::max(4, (int)(log2(W.getWake().vtx.size())));
1055
1056 for (int controlLevel = std::max(estLevel - 2, 1); controlLevel <= estLevel + 2; ++controlLevel)
1057 {
1058 VMlib::vmTimer timerA, timerB;
1059 if (W.getWake().vtx.size() > 0)
1060 {
1061 if (W.getPassport().numericalSchemes.velocityComputation.second == 1)
1062 {
1063 W.getInflTreeWake().Update(W.getWake().vtx, controlLevel);
1064 timerA.start();
1065 W.getInflTreeWake().Build();
1066 timerA.stop();
1067 timerB.start();
1068 W.getInflTreeWake().UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1069 timerB.stop();
1070
1071 W.getCntrTreeWake().Update(W.getWake().vtx, controlLevel);
1072 W.getCntrTreeWake().Build();
1073 W.getCntrTreeWake().UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1074 }
1075
1076 std::vector<Point2D> tempVelo(wakeVortexesParams.convVelo.size());
1077 std::vector<double> tempRadius(wakeVortexesParams.epsastWake.size());
1078
1079 //Вызов виртуальной функции
1080 double timerCduration = CalcConvVeloToSetOfPointsFromWake(W.getWake(), tempVelo, tempRadius, true, false);
1081
1082 int nObjInContr = 0;
1083 for (int c = 0; c < W.getCntrTreeWake().indexControlCells.size(); ++c)
1084 {
1085 const auto& idx = W.getCntrTreeWake().indexControlCells[c];
1086 if (idx > W.getCntrTreeWake().object.size())
1087 nObjInContr += 1;
1088 else
1089 {
1090 nObjInContr += W.getCntrTreeWake().range[idx].second - W.getCntrTreeWake().range[idx].first + 1;
1091 }
1092 }
1093
1094 treeTimeFile << W.getCurrentStep() << ',' << W.getCurrentTime() << ',' << W.getInflTreeWake().object.size() << ',' \
1095 << controlLevel << ',' << (double)nObjInContr / W.getCntrTreeWake().indexControlCells.size() << ',' \
1096 << timerA.duration() << ',' << timerB.duration() << ',' << timerCduration << ',' \
1097 << timerAgpu.duration() << ',' << timerBgpu.duration() << ',' << timerCgpuduration << '\n';
1098 }
1099 }
1100
1101 treeTimeFile.close();
1102 //*/
1103#else
1104 float timeUpd1=0, timeBld1=0, timeUpw1=0, timeUpd2=0, timeBld2=0, timeUpw2=0, timeDnw=0;
1107
1108 VMlib::vmTimer fullTimer;
1109 fullTimer.reset();
1110 fullTimer.start();
1111
1112 if (W.getWake().vtx.size() > 0)
1113 {
1115 {
1116 int estOptLevel = std::max(4, (int)(log2(W.getWake().vtx.size())) - 2);
1117
1118 timeUpd1 = W.getInflTreeWake().Update(W.getWake().vtx, estOptLevel);
1119 timeBld1 = W.getInflTreeWake().Build();
1121
1122 //timeUpd2 = W.getCntrTreeWake().Update(W.getWake().vtx, estOptLevel);
1123 //timeBld2 = W.getCntrTreeWake().Build();
1124 //timeUpw2 = W.getCntrTreeWake().UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1125
1126 //std::cout << "timeUpd = " << timeUpd1 << " " << timeUpd2 << '\n';
1127 //std::cout << "timeBld = " << timeBld1 << " " << timeBld2 << '\n';
1128 //std::cout << "timeUpw = " << timeUpw1 << " " << timeUpw2 << '\n';
1129
1130 }
1131
1132 //Вызов виртуальной функции
1133
1135
1136 //std::string vname = VMlib::fileNameStep("VeloBH", 0, wakeVortexesParams.convVelo.size(), "txt");
1137 //std::ofstream velofile;
1138 //velofile.open(W.getPassport().dir + vname);
1139
1140 //for (int i = 0; i < wakeVortexesParams.convVelo.size(); ++i)
1141 // velofile << wakeVortexesParams.convVelo[i][0] << " " << wakeVortexesParams.convVelo[i][1] << "\n";
1142 //velofile.close();
1143 //exit(-124);
1144
1145 //std::cout << "timeDnw = " << timeDnw << '\n';
1146 }
1147 fullTimer.stop();
1148
1150 //std::cout << "theta = " << W.getPassport().numericalSchemes.nbodyTheta << "\n";
1151
1153 /*
1154 VMlib::vmTimer timerExact;
1155
1156 if (W.getWake().vtx.size() > 0)
1157 {
1158 std::vector<fmm::particle2d> sources(W.getWake().vtx.size());
1159 #pragma omp parallel for
1160 for (int i = 0; i < (int)sources.size(); ++i)
1161 {
1162 const auto& w = W.getWake().vtx[i];
1163
1164 sources[i].center = fmm::point2d(w.r()[0], w.r()[1]);
1165 sources[i].q = w.g();
1166 sources[i].morton_code = 0;
1167 }
1168
1169 auto targets = sources;
1170 for (int i = 0; i < (int)sources.size(); ++i)
1171 targets[i].q = 0;
1172
1173 //double t = omp_get_wtime();
1174 //fmm::ComputeExact<fmm::InteractionType::Potential2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1175 timerExact.start();
1176 fmm::ComputeExact<fmm::InteractionType::Force2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1177 timerExact.stop();
1178 //std::cout << "Compute exact time = " << omp_get_wtime() - t << std::endl;
1179
1180 //t = omp_get_wtime();
1181
1182 fmm::FastMultipole fmm(sources, targets, 1.e-8, fmm::FMM_AUTO, fmm::FMM_AUTO); // or fmm::gpu::FastMultipole... for gpu version
1183 fmm::ReadError<fmm::InteractionType::Force2d>(fmm.forces);
1184 //fmm::ReadError<fmm::InteractionType::Potential2d>(fmm.potentials);
1185 //std::cout << "Total time = " << omp_get_wtime() - t << std::endl;
1186
1187 std::cout << "Hybrid time ConvVelo Wake = " << fullTimer.duration() <<
1188 //W.timerConvVelo.duration() <<
1189 " ( " << timeUpd1 + timeUpd2 + timeBld1 + timeBld2 + timeUpw1 + timeUpw2 + timeDnw << " )" << '\n';
1190
1191 fmm::ReadErrorHyb(*((std::vector<std::array<double, 2>>*) &wakeVortexesParams.convVelo));
1192 std::cout << "Exact time = " << timerExact.duration() << '\n';
1193 }
1194 //*/
1195
1196
1197
1198#endif
1199
1200 std::vector<Point2D> nullVector(0);
1201 //вычисление конвективных скоростей по закону Био-Савара от виртуальных вихрей (точнее, от слоев)
1202 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1203 {
1204 //Влияние на след от панелей
1205#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONVVIRT))
1206
1208 {
1209 case 0:
1210 W.getBoundary(bou).GPUCalcConvVelocityToSetOfPointsFromSheets(W.getWake(), wakeVortexesParams.convVelo);
1211 break;
1212 case 1:
1213 if (bou == 0)
1214 GPUCalcConvVelocityToSetOfPointsFromSheets(W.getNonConstCuda().cntrTreeWake, W.getWake(), wakeVortexesParams.convVelo);
1215 break;
1216 }
1217 //
1218
1219#else
1221#endif
1222 }
1223
1224 //Скорости только что рожденных вихрей
1225 {
1226 size_t nVirtVortices = 0;
1227 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1228 nVirtVortices += W.getBoundary(bou).virtualWake.vtx.size();
1229
1230 size_t counter = wakeVortexesParams.convVelo.size() - nVirtVortices;
1231
1232 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1233 for (size_t v = 0; v < W.getBoundary(bou).virtualWake.vtx.size(); ++v)
1234 {
1237 - W.getV0();
1238 ++counter;
1239 }
1240 }
1241
1242 //Заполнение структур данных виртуальных вихрей
1243 {
1244 size_t nVirtVortices = 0;
1245 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1246 nVirtVortices += W.getBoundary(bou).virtualWake.vtx.size();
1247
1248 size_t counter = wakeVortexesParams.convVelo.size() - nVirtVortices;
1249
1250 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1251 for (size_t v = 0; v < W.getBoundary(bou).virtualWake.vtx.size(); ++v)
1252 {
1253 virtualVortexesParams[bou].convVelo[v] = wakeVortexesParams.convVelo[counter];
1254 virtualVortexesParams[bou].epsastWake[v] = wakeVortexesParams.epsastWake[counter];
1255 ++counter;
1256 }
1257 }
1258
1259 W.getTimers().stop("ConvVel");
1260 W.getTimers().start("VelPres");
1261
1262 //вычисление скоростей в заданных точках только на соответствующем шаге по времени
1264#ifdef OPTIMIZER
1265 if ((W.getCurrentStep() >= OPTIMIZER_START_STEP && W.getCurrentStep() <= OPTIMIZER_STOP_STEP) || W.getCurrentStep() == 0)
1267#else
1268
1269 //t1 = -omp_get_wtime();
1271 //t1 += omp_get_wtime();
1272 //std::cout << "time ConvVelo VP = " << t1 << std::endl;
1273#endif
1274
1276 /*if ((W.getPassport().timeDiscretizationProperties.saveVPstep > 0) && (!(W.getCurrentStep() % W.getPassport().timeDiscretizationProperties.saveVPstep)))
1277 {
1278 int currentStep = W.getCurrentStep();
1279 if (currentStep >= 1100 && currentStep <= 1300)
1280 {
1281 CalcVeloToWakeVP();
1282 optimizedVelocity.AddVelocities(W.getNonConstMeasureVP().getNonConstVelocity());
1283 }
1284
1285 if (currentStep == 1200)
1286 {
1287 optimizedVelocity.PerformAveragingVelo(W.getPassport().dir);
1288 }
1289 }*/
1291
1292 W.getTimers().stop("VelPres");
1293}//CalcConvVelo()
const Point2D & getV(size_t q) const
Возврат константной ссылки на скорость вершины профиля
Definition Airfoil2D.h:137
const Airfoil & afl
Definition Boundary2D.h:77
VirtualWake virtualWake
Виртуальный вихревой след конкретного профиля
Definition Boundary2D.h:86
virtual void CalcConvVelocityToSetOfPointsFromSheets(const WakeDataBase &pointsDb, std::vector< Point2D > &velo) const =0
Вычисление конвективных скоростей в наборе точек, вызываемых наличием слоев вихрей и источников на пр...
float Update(const std::vector< Vortex2D > &vtx, int cntrLev=0)
float UpwardTraversal(int order)
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
Definition Passport2D.h:307
virtual float CalcConvVeloToSetOfPointsFromWake(const WakeDataBase &pointsDb, std::vector< Point2D > &velo, std::vector< double > &domainRadius, bool calcVelo, bool calcRadius)=0
Вычисление конвективных скоростей и радиусов вихревых доменов в заданном наборе точек от следа
VortexesParams wakeVortexesParams
Струтура, определяющая параметры вихрей в следе
Definition Velocity2D.h:112
virtual void CalcVeloToWakeVP()
Вычисление скоростей в точках wakeVP.
std::vector< Point2D > vecHalfGamma
Скорость вихрей виртуального следа конкретного профиля (равна Gamma/2) используется для расчета давле...
std::vector< std::pair< size_t, size_t > > aflPan
Пара чисел: номер профиля и номер панели, на которой рожден виртуальный вихрь
std::vector< Vortex2D > vtx
Список вихревых элементов
VMlib::vmTimer timerConvVelo
Definition World2D.h:371
const Wake & getWake() const
Возврат константной ссылки на вихревой след
Definition World2D.h:232
Gpu & getNonConstCuda() const
Возврат неконстантной ссылки на объект, связанный с видеокартой (GPU)
Definition World2D.h:278
VMlib::TimersGen & getTimers() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
Definition World2D.h:288
Point2D getV0() const
Возврат текущей скорости набегающего потока
Definition World2D.h:148
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
Definition World2D.h:273
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
CpuTreeInfo & getInflTreeWake() const
Definition World2D.h:239
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
void stop(const std::string &timerLabel)
Останов счетчика
Definition TimesGen.cpp:68
void start(const std::string &timerLabel)
Запуск счетчика
Definition TimesGen.cpp:55
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
Definition WorldGen.h:99
Класс засекания времени
Definition TimesGen.h:59
const vmTimer & stop() const
Останов работающего счетчика времени
Definition TimesGen.h:125
const vmTimer & start() const
Запуск (первый или повторный) счетчика времени
Definition TimesGen.h:109
const vmTimer & reset() const
Сброс счетчика времени
Definition TimesGen.h:101
std::pair< std::string, int > velocityComputation
Definition Passport2D.h:180
std::vector< Point2D > convVelo
Вектор конвективных скоростей вихрей
Definition Velocity2D.h:72
std::vector< double > epsastWake
Вектор характерных радиусов вихревых доменов (eps*)
Definition Velocity2D.h:90
int saveVPstep
Шаг вычисления и сохранения скорости и давления
Definition PassportGen.h:86
Here is the call graph for this function:

◆ CalcConvVeloToSetOfPointsFromWake()

virtual float VM2D::Velocity::CalcConvVeloToSetOfPointsFromWake ( const WakeDataBase &  pointsDb,
std::vector< Point2D > &  velo,
std::vector< double > &  domainRadius,
bool  calcVelo,
bool  calcRadius 
)
pure virtual

Вычисление конвективных скоростей и радиусов вихревых доменов в заданном наборе точек от следа

Parameters
[in]pointsDbконстантная ссылка на базу данных пелены из вихрей, в которых надо сосчитать конвективные скорости
[out]veloссылка на вектор скоростей в требуемых точках
[out]domainRadiusссылка на вектор радиусов вихревых доменов
[in]calcVeloпризнак вычисления скоростей в точках
[in]calcRadiusпризнак вычисления радиусов доменов

Implemented in VM2D::VelocityBarnesHut, and VM2D::VelocityBiotSavart.

Here is the caller graph for this function:

◆ CalcConvVPVeloToSetOfPointsFromWake()

virtual void VM2D::Velocity::CalcConvVPVeloToSetOfPointsFromWake ( const WakeDataBase &  pointsDb,
std::vector< Point2D > &  velo,
std::vector< double > &  domainRadius,
bool  calcVelo,
bool  calcRadius 
)
inlinevirtual

Reimplemented in VM2D::VelocityBarnesHut.

Definition at line 141 of file Velocity2D.h.

141{};

◆ CalcDiffVelo()

void Velocity::CalcDiffVelo ( )

Вычисление диффузионных скоростей

Вызывается в CalcVortexVelo()

Definition at line 155 of file Velocity2D.cpp.

156{
157 W.getTimers().start("DiffVel");
158
159 double t12start, t12finish;
160 double t03start, t03finish;
161 double tOtherstart, tOtherfinish;
162
164 {
165 t12start = omp_get_wtime();
167 t12finish = omp_get_wtime();
168
169 t03start = omp_get_wtime();
171 t03finish = omp_get_wtime();
172
173 tOtherstart = omp_get_wtime();
174 for (Point2D& diffV : wakeVortexesParams.diffVelo)
175 diffV *= W.getPassport().physicalProperties.nu;
176
177 //контроль застрелов диффузионной скорости
179
180 for (size_t afl = 0; afl < W.getNumberOfAirfoil(); ++afl)
181 for (size_t i = 0; i < W.getAirfoil(afl).viscousStress.size(); ++i)
183
184 //SaveVisStress();
185
186
187 //Заполнение структуры данных виртуальных вихрей
188 size_t nVirtVortices = 0;
189 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
190 nVirtVortices += W.getBoundary(bou).virtualWake.vtx.size();
191
192 size_t counter = wakeVortexesParams.convVelo.size() - nVirtVortices;
193
194 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
195 for (size_t v = 0; v < W.getBoundary(bou).virtualWake.vtx.size(); ++v)
196 {
197 virtualVortexesParams[bou].diffVelo[v] = wakeVortexesParams.diffVelo[counter];
198 virtualVortexesParams[bou].I0[v] = wakeVortexesParams.I0[counter];
199 virtualVortexesParams[bou].I1[v] = wakeVortexesParams.I1[counter];
200 virtualVortexesParams[bou].I2[v] = wakeVortexesParams.I2[counter];
201 virtualVortexesParams[bou].I3[v] = wakeVortexesParams.I3[counter];
202 ++counter;
203 }
204
205 tOtherfinish = omp_get_wtime();
206 }
207 W.getTimers().stop("DiffVel");
208
209}// CalcDiffVelo()
std::vector< double > viscousStress
Нейросеть для коэффициентов I0 и I3 диффузионной скорости
Definition Airfoil2D.h:268
PhysicalProperties physicalProperties
Структура с физическими свойствами задачи
Definition Passport2D.h:301
void LimitDiffVelo(std::vector< Point2D > &diffVel)
Контроль больших значений диффузионных скоростей
void CalcDiffVeloI0I3()
void CalcDiffVeloI1I2()
Вычисление диффузионных скоростей вихрей и виртуальных вихрей в вихревом следе
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Definition World2D.h:180
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition World2D.h:163
Airfoil & getNonConstAirfoil(size_t i) const
Возврат неконстантной ссылки на объект профиля
Definition World2D.h:175
double nu
Коэффициент кинематической вязкости среды
Definition Passport2D.h:99
std::vector< Point2D > I2
Вектор числителей (I2) диффузионных скоростей вихрей (обусловленных завихренностью)
Definition Velocity2D.h:84
std::vector< double > I0
Вектор знаменателей (I0) диффузионных скоростей вихрей (обусловленных профилем)
Definition Velocity2D.h:78
std::vector< Point2D > diffVelo
Вектор диффузионных скоростей вихрей
Definition Velocity2D.h:75
std::vector< Point2D > I3
Вектор числителей (I3) диффузионных скоростей вихрей (обусловленных профилем)
Definition Velocity2D.h:87
std::vector< double > I1
Вектор знаменателей (I1) диффузионных скоростей вихрей (обусловленных завихренностью)
Definition Velocity2D.h:81
Here is the call graph for this function:

◆ CalcDiffVeloI0I3()

void Velocity::CalcDiffVeloI0I3 ( )

Definition at line 106 of file Velocity2D.cpp.

107{
108 for (size_t afl = 0; afl < W.getNumberOfAirfoil(); ++afl)
109 {
110#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_I0I3))
111 W.getNonConstAirfoil(afl).GPUGetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(wakeVortexesParams.epsastWake, wakeVortexesParams.I0, wakeVortexesParams.I3);
112#else
114#endif
115 }
116
117
118 //влияние поверхности
119 Point2D I3;
120 double I0;
121
122 double domrad = 0.0;
123
124#pragma omp parallel for private(I0, I3, domrad)
125 for (int vt = 0; vt < (int)wakeVortexesParams.diffVelo.size(); ++vt)
126 {
128
129 wakeVortexesParams.I0[vt] *= domrad;
130 wakeVortexesParams.I0[vt] += DPI * sqr(domrad);
131
132
135
136
137 if (fabs(I0) > 1.e-8)
138 wakeVortexesParams.diffVelo[vt] += I3 * (1.0 / I0);
139 }
140}//CalcDiffVeloI0I3()
const double DPI
Число .
Definition defs.h:82
virtual void GetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(const WakeDataBase &pointsDb, std::vector< double > &domainRadius, std::vector< double > &I0, std::vector< Point2D > &I3)
Вычисление числителей и знаменателей диффузионных скоростей в заданном наборе точек,...
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
Definition Passport2D.h:304
T sqr(T x)
Возведение числа в квадрат
Definition defs.h:455
void vt(const Vector3d &x, const Matrix3d *T, Matrix3d &M)
double getMinEpsAst() const
Функция минимально возможного значения для epsAst.
Definition Passport2D.h:153
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalcDiffVeloI1I2()

void Velocity::CalcDiffVeloI1I2 ( )

Вычисление диффузионных скоростей вихрей и виртуальных вихрей в вихревом следе

Вызывает 4 раза функцию CalcDiffVeloToSetOfPoints

Warning
скорости приплюсовываются к уже имеющимся

Definition at line 62 of file Velocity2D.cpp.

63{
64 // !!! пелена на пелену
65#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_I1I2))
67 GPUCalcDiffVeloI1I2ToSetOfPointsFromWake(W.getWake(), wakeVortexesParams.epsastWake, W.getWake(), wakeVortexesParams.I1, wakeVortexesParams.I2);
68 else
70#else
72#endif
73
74
75 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
76 {
77 //не нужно, т.к. сделано выше перед началом вычисления скоростей
78 //W.getNonConstBoundary(bou).virtualWake.WakeSynchronize();
79
80
81 //виртуальные на границе на след
82#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_I1I2))
83 GPUCalcDiffVeloI1I2ToSetOfPointsFromSheets(W.getWake(), wakeVortexesParams.epsastWake, W.getBoundary(bou), wakeVortexesParams.I1, wakeVortexesParams.I2);
84#else
86#endif
87 } //for bou
88
89 Point2D I2;
90 double I1;
91
92#pragma omp parallel for private(I1, I2)
93 for (int vt = 0; vt < (int)wakeVortexesParams.diffVelo.size(); ++vt)
94 {
97
98 if (fabs(I1) < 1.e-8)
99 wakeVortexesParams.diffVelo[vt] = { 0.0, 0.0 };
100 else
102 }
103}//CalcDiffVeloI1I2()
void CalcDiffVeloI1I2ToWakeFromSheets(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const Boundary &bnd, std::vector< double > &I1, std::vector< Point2D > &I2)
void CalcDiffVeloI1I2ToWakeFromWake(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const WakeDataBase &vorticesDb, std::vector< double > &I1, std::vector< Point2D > &I2)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalcDiffVeloI1I2ToSetOfPointsFromSheets()

void Velocity::CalcDiffVeloI1I2ToSetOfPointsFromSheets ( const WakeDataBase &  pointsDb,
const std::vector< double > &  domainRadius,
const Boundary &  bnd,
std::vector< double > &  I1,
std::vector< Point2D > &  I2 
)
Todo:
Понять природу магической константы 8.0 и синхронизировать с GPU
Todo:
Сделать переменной и синхронизировать с GPU
Todo:
Учитываем пока только нулевой момент решения

Definition at line 271 of file Velocity2D.cpp.

272{
273 double tCPUSTART, tCPUEND;
274
275 tCPUSTART = omp_get_wtime();
276
277 std::vector<double> selfI1(pointsDb.vtx.size(), 0.0);
278 std::vector<Point2D> selfI2(pointsDb.vtx.size(), { 0.0, 0.0 });
279
280#pragma warning (push)
281#pragma warning (disable: 4101)
282 //Локальные переменные для цикла
283 Point2D Rij;
284 double rij, expr;
285 double diffRadius;
286 double left;
287 double right;
288 double posJx;
289 double domRad;
290#pragma warning (pop)
291
292
293#pragma omp parallel for default(none) shared(selfI1, selfI2, domainRadius, bnd, pointsDb, std::cout) private(Rij, rij, expr, domRad, diffRadius, left, right, posJx)
294 for (int i = 0; i < pointsDb.vtx.size(); ++i)
295 {
296 const Vortex2D& vtxI = pointsDb.vtx[i];
297
298 domRad = std::max(domainRadius[i], W.getPassport().wakeDiscretizationProperties.getMinEpsAst());
299
301 diffRadius = 8.0 * domRad;
302
303 left = vtxI.r()[0] - diffRadius;
304 right = vtxI.r()[0] + diffRadius;
305
306 for (size_t j = 0; j < bnd.afl.getNumberOfPanels(); ++j)
307 {
309 const int nQuadPt = 3;
310
312 const double ptG = bnd.sheets.freeVortexSheet(j, 0) * bnd.afl.len[j] / nQuadPt;
313
314 for (int q = 0; q < nQuadPt; ++q)
315 {
316 const Point2D& ptJ = bnd.afl.getR(j) + bnd.afl.tau[j] * (q + 0.5) * bnd.afl.len[j] * (1.0 / nQuadPt); // vorticesDb.vtx[j];
317 posJx = ptJ[0];
318
319 if ((left < posJx) && (posJx < right))
320 {
321 Rij = vtxI.r() - ptJ;
322 rij = Rij.length();
323 if (rij < diffRadius && rij > 1.e-10)
324 {
325 expr = exp(-rij / domRad);
326 selfI2[i] += (ptG * expr / rij) * Rij;
327 selfI1[i] += ptG * expr;
328 }
329 }//if (rij>1e-6)
330 }
331 }//for j
332 } // for r
333
334 for (size_t i = 0; i < I1.size(); ++i)
335 {
336 I1[i] += selfI1[i];
337 I2[i] += selfI2[i];
338 }
339
340 tCPUEND = omp_get_wtime();
341 //W.getInfo('t') << "DIFF_CPU: " << tCPUEND - tCPUSTART << std::endl;
342}//CalcDiffVeloI1I2ToSetOfPointsFromSheets(...)
std::vector< double > len
Длины панелей профиля
Definition Airfoil2D.h:94
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition Airfoil2D.h:113
std::vector< Point2D > tau
Касательные к панелям профиля
Definition Airfoil2D.h:91
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition Airfoil2D.h:163
Sheet sheets
Слои на профиле
Definition Boundary2D.h:96
const double & freeVortexSheet(size_t n, size_t moment) const
Definition Sheet2D.h:100
Класс, опеделяющий двумерный вихревой элемент
Definition Vortex2D.h:59
HD Point2D & r()
Функция для доступа к радиус-вектору вихря
Definition Vortex2D.h:92
P length() const
Вычисление 2-нормы (длины) вектора
Definition numvector.h:374
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalcDiffVeloI1I2ToSetOfPointsFromWake()

void Velocity::CalcDiffVeloI1I2ToSetOfPointsFromWake ( const WakeDataBase &  pointsDb,
const std::vector< double > &  domainRadius,
const WakeDataBase &  vorticesDb,
std::vector< double > &  I1,
std::vector< Point2D > &  I2 
)

Вычисление числителей и знаменателей диффузионных скоростей в заданном наборе точек

Parameters
[in]pointsDbконстантная ссылка на базу данных пелены из вихрей, в которых надо сосчитать диффузионные скорости
[in]domainRadiusконстантная ссылка на вектор радиусов вихревых доменов
[in]vorticesDbконстантная ссылка на на базу данных пелены из вихрей,от которых надо сосчитать влияния на points
[out]I1ссылка на вектор величин I1 (знаменателей в диффузионных скоростях) в требуемых точках
[out]I2ссылка на вектор величин I2 (числителей в диффузионных скоростях) в требуемых точках
Todo:
Понять природу магической константы 8.0 и синхронизировать с GPU

Definition at line 213 of file Velocity2D.cpp.

214{
215 std::vector<double> selfI1(pointsDb.vtx.size(), 0.0);
216 std::vector<Point2D> selfI2(pointsDb.vtx.size(), { 0.0, 0.0 });
217
218#pragma warning (push)
219#pragma warning (disable: 4101)
220 //Локальные переменные для цикла
221 Point2D Rij;
222 double rij, expr;
223 double diffRadius, domRad;
224 double left;
225 double right;
226 double posJx;
227#pragma warning (pop)
228
229#pragma omp parallel for default(none) shared(selfI1, selfI2, domainRadius, vorticesDb, pointsDb) private(Rij, rij, expr, diffRadius, domRad, left, right, posJx)
230 for (int i = 0; i < pointsDb.vtx.size(); ++i)
231 {
232 const Vortex2D& vtxI = pointsDb.vtx[i];
233
234 domRad = std::max(domainRadius[i], W.getPassport().wakeDiscretizationProperties.getMinEpsAst());
235
237 diffRadius = 8.0 * domRad;
238
239 left = vtxI.r()[0] - diffRadius;
240 right = vtxI.r()[0] + diffRadius;
241
242 for (size_t j = 0; j < vorticesDb.vtx.size(); ++j)
243 {
244 const Vortex2D& vtxJ = vorticesDb.vtx[j];
245 posJx = vtxJ.r()[0];
246
247 if ((left < posJx) && (posJx < right))
248 {
249 Rij = vtxI.r() - vtxJ.r();
250 rij = Rij.length();
251 if (rij < diffRadius && rij > 1.e-10)
252 {
253 expr = exp(-rij / domRad);
254 selfI2[i] += (vtxJ.g()* expr / rij) * Rij;
255 selfI1[i] += vtxJ.g()*expr;
256 }
257 }//if (rij>1e-6)
258 }//for j
259 } // for r
260
261
262 for (size_t i = 0; i < I1.size(); ++i)
263 {
264 I1[i] += selfI1[i];
265 I2[i] += selfI2[i];
266 }
267}//CalcDiffVeloI1I2ToSetOfPointsFromWake(...)
HD double & g()
Функция для доступа к циркуляции вихря
Definition Vortex2D.h:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalcDiffVeloI1I2ToWakeFromSheets()

void Velocity::CalcDiffVeloI1I2ToWakeFromSheets ( const WakeDataBase &  pointsDb,
const std::vector< double > &  domainRadius,
const Boundary &  bnd,
std::vector< double > &  I1,
std::vector< Point2D > &  I2 
)

Definition at line 1392 of file Velocity2D.cpp.

1393{
1394 CalcDiffVeloI1I2ToSetOfPointsFromSheets(pointsDb, domainRadius, bnd, I1, I2);
1395}
void CalcDiffVeloI1I2ToSetOfPointsFromSheets(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const Boundary &bnd, std::vector< double > &I1, std::vector< Point2D > &I2)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalcDiffVeloI1I2ToWakeFromWake()

void Velocity::CalcDiffVeloI1I2ToWakeFromWake ( const WakeDataBase &  pointsDb,
const std::vector< double > &  domainRadius,
const WakeDataBase &  vorticesDb,
std::vector< double > &  I1,
std::vector< Point2D > &  I2 
)

Definition at line 1387 of file Velocity2D.cpp.

1388{
1389 CalcDiffVeloI1I2ToSetOfPointsFromWake(pointsDb, domainRadius, vorticesDb, I1, I2);
1390}//CalcDiffVeloI1I2ToWakeFromWake(...)
void CalcDiffVeloI1I2ToSetOfPointsFromWake(const WakeDataBase &pointsDb, const std::vector< double > &domainRadius, const WakeDataBase &vorticesDb, std::vector< double > &I1, std::vector< Point2D > &I2)
Вычисление числителей и знаменателей диффузионных скоростей в заданном наборе точек
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalcVeloToWakeVP()

void Velocity::CalcVeloToWakeVP ( )
virtual

Вычисление скоростей в точках wakeVP.

Definition at line 1298 of file Velocity2D.cpp.

1299{
1300 std::vector<Point2D> velConvWake;
1301 std::vector<std::vector<Point2D>> velConvBou;
1302
1303 int addWSize = (int)W.getMeasureVP().getWakeVP().vtx.size();
1304
1305 velConvWake.resize(addWSize, { 0.0, 0.0 });
1306
1307 velConvBou.resize(W.getNumberOfBoundary());
1308 for (size_t i = 0; i < W.getNumberOfBoundary(); ++i)
1309 velConvBou[i].resize(addWSize, { 0.0, 0.0 });
1310
1311 std::vector<Point2D>& velocityRef = W.getNonConstMeasureVP().getNonConstVelocity();
1312 velocityRef.assign(addWSize, W.getV0());
1313
1314#if (defined(USE_CUDA))
1315 W.getNonConstCuda().RefreshVP();
1316#endif
1317
1318#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_VP))
1319 std::unique_ptr<BHcu::CudaTreeInfo>& cntrTree = W.getNonConstCuda().cntrTreeVP;
1320
1322 {
1323 case 1:
1325 {
1326 cntrTree->MemoryAllocate((int)W.getCuda().n_CUDA_velVP);
1327 cntrTree->Update((int)W.getMeasureVP().getWakeVP().vtx.size(), W.getMeasureVP().getWakeVP().devVtxPtr);
1328 cntrTree->Build();
1329 GPUCalcConvVeloToSetOfPointsFromWake(cntrTree, W.getMeasureVP().getWakeVP(), velocityRef, W.getNonConstMeasureVP().getNonConstDomainRadius(), true, false);
1330 }
1331 break;
1332 case 0:
1333 GPUCalcConvVeloToSetOfPointsFromWake(cntrTree, W.getMeasureVP().getWakeVP(), velocityRef, W.getNonConstMeasureVP().getNonConstDomainRadius(), true, false);
1334 break;
1335 }
1336
1337
1338#else
1340 {
1341 case 0:
1343 break;
1344 case 1:
1346 double theta = W.getPassport().numericalSchemes.nbodyTheta;
1347
1349 W.getCntrTreeVP().Build();
1352 }
1353#endif
1354
1355
1356 for (size_t i = 0; i < W.getNumberOfBoundary(); ++i)
1357#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_VP))
1359 {
1360 case 0:
1361 W.getNonConstBoundary(i).GPUCalcConvVelocityToSetOfPointsFromSheets(W.getMeasureVP().getWakeVP(), velConvBou[i]);
1362
1363 for (int s = 0; s < addWSize; ++s)
1364 velocityRef[s] += velConvWake[s];
1365
1366 for (size_t bou = 0; bou < velConvBou.size(); ++bou)
1367 for (int j = 0; j < addWSize; ++j)
1368 velocityRef[j] += velConvBou[bou][j];
1369 break;
1370 case 1:
1371 if (i == 0)
1372 GPUCalcConvVelocityToSetOfPointsFromSheets(cntrTree, W.getMeasureVP().getWakeVP(), velocityRef);
1373 break;
1374 }
1375#else
1377 for (int i = 0; i < addWSize; ++i)
1378 velocityRef[i] += velConvWake[i];
1379
1380 for (size_t bou = 0; bou < velConvBou.size(); ++bou)
1381 for (int j = 0; j < addWSize; ++j)
1382 velocityRef[j] += velConvBou[bou][j];
1383#endif
1384}// CalcVeloToWakeVP()
#define CU_VP
Definition Gpudefs.h:92
float DownwardTraversalVorticesToPoints(CpuTreeInfo &cntrTree, std::vector< Point2D > &vel, std::vector< double > &epsast, double theta, int order, bool calcRadius)
const WakeDataBase & getWakeVP() const
Возврат wakeVP.
std::vector< Point2D > & getNonConstVelocity()
Возврат velocity.
std::vector< double > & getNonConstDomainRadius()
Возврат domainRadius.
bool isAnyMovableOrDeformable() const
Возврат признака того, что хотя бы один из профилей подвижный или деформируемый
Definition World2D.cpp:2349
MeasureVP & getNonConstMeasureVP() const
Возврат неконстантной ссылки на measureVP.
Definition World2D.h:213
Boundary & getNonConstBoundary(size_t i) const
Возврат неконстантной ссылки на объект граничного условия
Definition World2D.h:192
CpuTreeInfo & getCntrTreeVP() const
Definition World2D.h:242
const MeasureVP & getMeasureVP() const
Возврат константной ссылки на measureVP.
Definition World2D.h:208
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CPUGetFASTWakeInfluenceToRhs()

void Velocity::CPUGetFASTWakeInfluenceToRhs ( std::vector< double > &  wakeRhs,
std::vector< double > &  wakeRhsLin 
) const

Definition at line 656 of file Velocity2D.cpp.

657{
658 const size_t nvt = W.getWake().vtx.size();
659
660
661 size_t nTotPan = 0;
662
663 for (size_t s = 0; s < W.getNumberOfAirfoil(); ++s)
664 nTotPan += W.getAirfoil(s).getNumberOfPanels();
665
666 wakeRhs.assign(nTotPan, 0.0);
667 wakeRhsLin.assign(nTotPan, 0.0);
668
669 if (nvt > 0)
670 {
671 auto& inflTree = W.getInflTreeWake();
672
673 auto& cntrTree = W.getCntrTreePnl();
674
676 cntrTree,
677 wakeRhs,
678 wakeRhsLin,
681 }
682}//CPUGetFASTWakeInfluenceToRhs(...)
float DownwardTraversalVorticesToPanels(CpuTreeInfo &cntrTree, std::vector< double > &rhs, std::vector< double > &rhsLin, double theta, int order)
CpuTreeInfo & getCntrTreePnl() const
Definition World2D.h:243
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FillRhs()

void Velocity::FillRhs ( Eigen::VectorXd &  rhsReord) const

!!!!!!!!!!влияние присоединенных слоев от самого себя и от других профилей

Definition at line 809 of file Velocity2D.cpp.

810{
811 Eigen::VectorXd locRhs;
812 std::vector<double> lastRhs(W.getNumberOfBoundary());
813
814 size_t currentRow = 0;
815 size_t currentSkosRow = 0;
816
817 size_t nAllVars = 0;
818 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
819 nAllVars += W.getBoundary(bou).GetUnknownsSize();
820
821 //Временные массивы для хранения правой части по быстрому методу (размеры задаются внутри CPUGetFASTWakeInfluenceToRhs)
822 std::vector<double> fastWakeRhs;
823 std::vector<double> fastWakeRhsLin;
824
825#ifndef USE_CUDA
826 if (W.getPassport().numericalSchemes.velocityComputation.second == 1) //Быстрый метод на CPU
827 CPUGetFASTWakeInfluenceToRhs(fastWakeRhs, fastWakeRhsLin);
828#endif
829
830 size_t curGlobPnl = 0;
831
832 W.timerRhs.reset();
833
834 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
835 {
836 const Airfoil& afl = W.getAirfoil(bou);
837 size_t np = afl.getNumberOfPanels();
838
839 size_t nVars;
840
841 nVars = W.getBoundary(bou).GetUnknownsSize();
842 locRhs.resize(nVars);
843
844 std::vector<double> wakeRhs;
845
846 double tt1 = omp_get_wtime();
847
848#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_RHS))
849 W.timerRhs.start();
851 GPUFASTGetWakeInfluenceToRhs(afl, wakeRhs);
852 else
853 GPUGetWakeInfluenceToRhs(afl, wakeRhs);
854 W.timerRhs.stop();
855#else
856 if (W.getPassport().numericalSchemes.velocityComputation.second == 1) //Собираем результат из быстрого метода
857 {
858 size_t shDim = W.getBoundary(afl.numberInPassport).sheetDim;
859
860 wakeRhs.assign(np * shDim, 0.0);
861
862 for (size_t i = 0; i < np; ++i)
863 {
864 wakeRhs[i] = fastWakeRhs[curGlobPnl + i];
865
866 if (shDim != 1)
867 wakeRhs[np + i] = fastWakeRhsLin[curGlobPnl + i];
868 }
869 curGlobPnl += np;
870 }
871 else
872 GetWakeInfluenceToRhs(afl, wakeRhs); //Прямой расчет
873
874 //std::string vname = VMlib::fileNameStep("rhsLinBH", 0, wakeRhs.size(), "txt");
875 //std::ofstream velofile;
876 //velofile.open(W.getPassport().dir + vname);
877
878 //for (int i = 0; i < wakeRhs.size(); ++i)
879 // velofile << wakeRhs[i] << "\n";
880 //velofile.close();
881 //exit(-124);
882#endif
883
884 std::vector<double> vInfRhs;
885 afl.GetInfluenceFromVInfToPanel(vInfRhs);
886
887#pragma omp parallel for \
888 default(none) \
889 shared(locRhs, afl, bou, wakeRhs, vInfRhs, np) \
890 schedule(dynamic, DYN_SCHEDULE)
891 for (int i = 0; i < (int)afl.getNumberOfPanels(); ++i)
892 {
893 locRhs(i) = -vInfRhs[i] - wakeRhs[i] + 0.25 * ((afl.getV(i) + afl.getV(i + 1)) & afl.tau[i]); //0.25 * (afl.getV(i) + afl.getV(i + 1))*afl.tau[i] - прямолинейные
894 if (W.getBoundary(bou).sheetDim > 1)
895 locRhs(np + i) = -vInfRhs[np + i] - wakeRhs[np + i];
896
898 //Если включен быстрый метод и есть подвижные тела, то пока что все равно вычисляем IQ
900 {
901 for (size_t q = 0; q < W.getNumberOfBoundary(); ++q)
902 {
903 const auto& sht = W.getBoundary(q).sheets;
904 const auto& iq = W.getIQ(bou, q);
905
906 const Airfoil& aflOther = W.getAirfoil(q);
907 if (W.getMechanics(q).isMoves)
908 {
909 for (size_t j = 0; j < aflOther.getNumberOfPanels(); ++j)
910 {
911 if ((i != j) || (bou != q))
912 {
913 locRhs(i) += -iq.first(i, j) * sht.attachedVortexSheet(j, 0);
914 locRhs(i) += -iq.second(i, j) * sht.attachedSourceSheet(j, 0);
915 }//if (i != j)
916
917 }//for j
918 }
919 }//for q
920 }
921 }//for i
922
923 lastRhs[bou] = 0.0;
924
925#pragma omp for
926 for (int q = 0; q < (int)afl.gammaThrough.size(); ++q)
927 lastRhs[bou] += afl.gammaThrough[q];
928
930
931 const double currT = W.getCurrentTime();
932 const double dt = W.getPassport().timeDiscretizationProperties.dt;
933
934 lastRhs[bou] += (W.getMechanics(bou).circulation - W.getMechanics(bou).circulationOld) * (W.getAirfoil(bou).inverse ? 1.0 : -1.0);
935
937
938 //размазываем правую часть
939 for (size_t i = 0; i < nVars; ++i)
940 rhsReord(i + currentSkosRow) = locRhs(i);
941
942 rhsReord(nAllVars + bou) = lastRhs[bou];
943
944 currentRow += nVars + 1;
945 currentSkosRow += nVars;
946 }// for bou
947
948
950 /*
951 std::ofstream treeTimeFile;
952 if (W.getCurrentStep() == 0)
953 {
954 treeTimeFile.open(W.getPassport().dir + "/dbg/rhsTime.csv");
955 treeTimeFile << "step,time,Nvtx,Npnl,tDNW,tDNWgpu\n";
956 }
957 else
958 treeTimeFile.open(W.getPassport().dir + "/dbg/rhsTime.csv", std::ios::app);
959
960
961 treeTimeFile << W.getCurrentStep() << ',' << W.getCurrentTime() << ',' << W.getInflTreeWake().object.size() << ',' << W.getCntrTreePnl().object.size() << ',' \
962 << timerRhsTest.duration() << ',' << W.timerRhs.duration() << '\n';
963
964 treeTimeFile.close();
965 //*/
966}
bool inverse
Признак разворота нормалей (для расчета внутренних течений)
Definition Airfoil2D.h:76
Абстрактный класс, определяющий обтекаемый профиль
Definition Airfoil2D.h:182
std::vector< double > gammaThrough
Суммарные циркуляции вихрей, пересекших панели профиля на прошлом шаге
Definition Airfoil2D.h:276
virtual void GetInfluenceFromVInfToPanel(std::vector< double > &vInfRhs) const
Вычисление влияния набегающего потока на панель для правой части
const size_t numberInPassport
Номер профиля в паспорте
Definition Airfoil2D.h:188
size_t GetUnknownsSize() const
Возврат размерности вектора решения
size_t sheetDim
Размерность параметров каждого из слоев на каждой из панелей
Definition Boundary2D.h:93
const bool isMoves
Переменная, отвечающая за то, двигается профиль или нет
double circulationOld
Циркуляция скорости по границе профиля с предыдущего шага
double circulation
Текущая циркуляция скорости по границе профиля
void GetWakeInfluenceToRhs(const Airfoil &afl, std::vector< double > &wakeRhs) const
Генерация вектора влияния вихревого следа на профиль
void CPUGetFASTWakeInfluenceToRhs(std::vector< double > &wakeRhs, std::vector< double > &wakeRhsLin) const
const Mechanics & getMechanics(size_t i) const
Возврат константной ссылки на объект механики
Definition World2D.h:219
const std::pair< Eigen::MatrixXd, Eigen::MatrixXd > & getIQ(size_t i, size_t j) const
Возврат константной ссылки на объект, связанный с матрицей интегралов от (r-xi)/|r-xi|^2.
Definition World2D.h:283
VMlib::vmTimer timerRhs
Definition World2D.h:367
double getCurrentTime() const
Definition WorldGen.h:100
double dt
Шаг по времени
Definition PassportGen.h:67
Here is the call graph for this function:

◆ GetWakeInfluenceToRhs()

void Velocity::GetWakeInfluenceToRhs ( const Airfoil &  afl,
std::vector< double > &  wakeRhs 
) const

Генерация вектора влияния вихревого следа на профиль

Генерирует вектор влияния вихревого следа на профиль, используемый затем для расчета вектора правой части.

Parameters
[in]aflконстантная ссылка на профиль, правая часть для которого вычисляется
[out]wakeRhsссылка на вектор влияния вихревого следа на ОДИН профиль

Definition at line 619 of file Velocity2D.cpp.

620{
621 size_t np = afl.getNumberOfPanels();
622 size_t shDim = W.getBoundary(afl.numberInPassport).sheetDim;
623
624 wakeRhs.resize(W.getBoundary(afl.numberInPassport).GetUnknownsSize());
625
626 //локальные переменные для цикла
627 std::vector<double> velI(shDim, 0.0);
628
629#pragma omp parallel for default(none) shared(shDim, afl, np, wakeRhs, IDPI) private(velI)
630 for (int i = 0; i < np; ++i)
631 {
632 velI.assign(shDim, 0.0);
633
634 if (W.getWake().vtx.size() > 0)
635 {
636 //Учет влияния следа
637 afl.GetInfluenceFromVorticesToPanel(i, W.getWake().vtx.data(), W.getWake().vtx.size(), velI);
638 }
639
640 if (W.getSource().vtx.size() > 0)
641 {
642 //Учет влияния источников
643 afl.GetInfluenceFromSourcesToPanel(i, W.getSource().vtx.data(), W.getSource().vtx.size(), velI);
644 }
645
646 for (size_t j = 0; j < shDim; ++j)
647 velI[j] *= IDPI / afl.len[i];
648
649 wakeRhs[i] = velI[0];
650
651 if (shDim != 1)
652 wakeRhs[np + i] = velI[1];
653 }//for i
654}//GetWakeInfluenceToRhs(...)
const double IDPI
Число .
Definition defs.h:79
virtual void GetInfluenceFromSourcesToPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &panelRhs) const
Вычисление влияния части подряд идущих источников из области течения на панель для правой части
virtual void GetInfluenceFromVorticesToPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &panelRhs) const
Вычисление влияния части подряд идущих вихрей из вихревого следа на панель для правой части
const WakeDataBase & getSource() const
Возврат константной ссылки на источники в области течения
Definition World2D.h:248
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LimitDiffVelo()

void Velocity::LimitDiffVelo ( std::vector< Point2D > &  diffVel)

Контроль больших значений диффузионных скоростей

Parameters
[in,out]diffVelссылка на вектор диффузионных скоростей

Definition at line 143 of file Velocity2D.cpp.

144{
145 for (size_t i = 0; i < diffVel.size(); ++i)
146 {
147 Point2D& diffV = diffVel[i];
148
149 if (diffV.length() > 1.5 * W.getPassport().physicalProperties.vRef)
151 }
152}
void normalize(P newlen=1.0)
Нормирование вектора на заданную длину
Definition numvector.h:419
double vRef
Референсная скорость
Definition Passport2D.h:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ResizeAndZero()

void Velocity::ResizeAndZero ( )

Очистка старых массивов под хранение скоростей, выделение новой памяти и обнуление

Вызывается в CalcVortexVelo() на каждом шаге расчета перед непосредственно расчетом скоростей

Definition at line 523 of file Velocity2D.cpp.

524{
525 W.getTimers().start("ConvVel");
527 wakeVortexesParams.convVelo.resize(W.getWake().vtx.size(), { 0.0, 0.0 });
528 W.getTimers().stop("ConvVel");
529
530 W.getTimers().start("DiffVel");
531 wakeVortexesParams.I0.clear();
532 wakeVortexesParams.I0.resize(W.getWake().vtx.size(), 0.0);
533
534 wakeVortexesParams.I1.clear();
535 wakeVortexesParams.I1.resize(W.getWake().vtx.size(), 0.0);
536
537 wakeVortexesParams.I2.clear();
538 wakeVortexesParams.I2.resize(W.getWake().vtx.size(), { 0.0, 0.0 });
539
540 wakeVortexesParams.I3.clear();
541 wakeVortexesParams.I3.resize(W.getWake().vtx.size(), { 0.0, 0.0 });
542
544 wakeVortexesParams.diffVelo.resize(W.getWake().vtx.size(), { 0.0, 0.0 });
545
547 wakeVortexesParams.epsastWake.resize(W.getWake().vtx.size(), 0.0);
548 W.getTimers().stop("DiffVel");
549
550 //Создаем массивы под виртуальные вихри
551 W.getTimers().start("ConvVel");
552 virtualVortexesParams.clear();
554 W.getTimers().stop("ConvVel");
555
556 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
557 {
558 W.getTimers().start("ConvVel");
559 virtualVortexesParams[bou].convVelo.clear();
560 virtualVortexesParams[bou].convVelo.resize(W.getBoundary(bou).virtualWake.vtx.size(), { 0.0, 0.0 });
561 W.getTimers().stop("ConvVel");
562
563 W.getTimers().start("DiffVel");
564 virtualVortexesParams[bou].I0.clear();
565 virtualVortexesParams[bou].I0.resize(W.getBoundary(bou).virtualWake.vtx.size(), 0.0);
566
567 virtualVortexesParams[bou].I1.clear();
568 virtualVortexesParams[bou].I1.resize(W.getBoundary(bou).virtualWake.vtx.size(), 0.0);
569
570 virtualVortexesParams[bou].I2.clear();
571 virtualVortexesParams[bou].I2.resize(W.getBoundary(bou).virtualWake.vtx.size(), { 0.0, 0.0 });
572
573 virtualVortexesParams[bou].I3.clear();
574 virtualVortexesParams[bou].I3.resize(W.getBoundary(bou).virtualWake.vtx.size(), { 0.0, 0.0 });
575
576 virtualVortexesParams[bou].diffVelo.clear();
577 virtualVortexesParams[bou].diffVelo.resize(W.getBoundary(bou).virtualWake.vtx.size(), { 0.0, 0.0 });
578
579 virtualVortexesParams[bou].epsastWake.clear();
580 virtualVortexesParams[bou].epsastWake.resize(W.getBoundary(bou).virtualWake.vtx.size(), 0.0);
581
582 W.getTimers().stop("DiffVel");
583 }
584}//ResizeAndZero()
Here is the call graph for this function:

◆ SaveVisStress()

void Velocity::SaveVisStress ( )

Сохранение вязких напряжений

Вызывается в CalcDiffVelo()

Definition at line 587 of file Velocity2D.cpp.

588{
590 // if ((W.getPassport().timeDiscretizationProperties.saveVTK > 0) && (W.ifDivisible(10)) && (W.getNumberOfAirfoil() > 0))
591 {
592 for (size_t q = 0; q < W.getNumberOfAirfoil(); ++q)
593 {
594 if (q == 0)
596
597 std::stringstream ss;
598 ss << "VisStress_" << q << "-";
600 std::ofstream outfile;
601 outfile.open(W.getPassport().dir + "visStress/" + fname);
602
603 outfile << W.getAirfoil(q).viscousStress.size() << std::endl; //Сохранение числа вихрей в пелене
604
605 for (size_t i = 0; i < W.getAirfoil(q).viscousStress.size(); ++i)
606 {
607 const Point2D& r = 0.5 * (W.getAirfoil(q).getR(i + 1) + W.getAirfoil(q).getR(i));
608 double gi = W.getAirfoil(q).viscousStress[i];
609 outfile << static_cast<int>(i) << " " << r[0] << " " << r[1] << " " << gi << std::endl;
610 }//for i
611 outfile.close();
612 }
613 }
614}//SaveVisStress()
bool ifDivisible(int val) const
Definition World2D.h:290
std::string dir
Рабочий каталог задачи
void CreateUserDirectory(const std::string &dir, const std::string &name)
Создание каталога
Definition defs.h:439
std::string fileNameStep(const std::string &name, int length, size_t number, const std::string &ext)
Формирование имени файла
Definition defs.h:379
int saveVtxStep
Шаг сохранения кадров в бинарные файлы
Definition PassportGen.h:81
int saveVisStress
Шаг вычисления и сохранения скорости и давления
Definition PassportGen.h:89
int nameLength
Число разрядов в имени файла
Definition PassportGen.h:76
Here is the call graph for this function:

Member Data Documentation

◆ optimizedVelocity

OptimizedVelocity VM2D::Velocity::optimizedVelocity

Definition at line 117 of file Velocity2D.h.

◆ virtualVortexesParams

std::vector<VortexesParams> VM2D::Velocity::virtualVortexesParams

Вектор струтур, определяющий параметры виртуальных вихрей для профилей

Definition at line 115 of file Velocity2D.h.

◆ W

const World2D& VM2D::Velocity::W
protected

Константная ссылка на решаемую задачу

Definition at line 108 of file Velocity2D.h.

◆ wakeVortexesParams

VortexesParams VM2D::Velocity::wakeVortexesParams

Струтура, определяющая параметры вихрей в следе

Definition at line 112 of file Velocity2D.h.


The documentation for this class was generated from the following files: