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< VortexesParamsvirtualVortexesParams
 Вектор струтур, определяющий параметры виртуальных вихрей для профилей
 
OptimizedVelocity optimizedVelocity
 

Protected Attributes

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

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 952 of file Velocity2D.cpp.

953{
954 W.getTimers().start("ConvVel");
955
956 //Влияние следа на след
957#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONV_TOWAKE))
958 //Вызов виртуальной функции
959
962
963 VMlib::vmTimer timerAgpu, timerBgpu;
964
965 std::unique_ptr<BHcu::CudaTreeInfo>& cntrTree = W.getNonConstCuda().cntrTreeWake;
966 auto& treeWake = *W.getNonConstCuda().inflTreeWake;
968 {
969 cntrTree->MemoryAllocate((int)W.getCuda().n_CUDA_wake);
970 cntrTree->Update((int)W.getWake().vtx.size(), W.getWake().devVtxPtr);
971 cntrTree->Build();
972
973 //Перестроение дерева для вихрей //todo //временно для корректного расчета epsast
974 treeWake.MemoryAllocate((int)W.getCuda().n_CUDA_wake);
975 treeWake.Update((int)W.getWake().vtx.size(), W.getWake().devVtxPtr);
976 timerAgpu.start();
977 treeWake.Build();
978 timerAgpu.stop();
979
980 timerBgpu.start();
981 treeWake.UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
982 timerBgpu.stop();
983 }
984
985 double timerCgpuduration = GPUCalcConvVeloToSetOfPointsFromWake(W.getNonConstCuda().cntrTreeWake, W.getWake(), wakeVortexesParams.convVelo, wakeVortexesParams.epsastWake, true, true);
986
987
989
991 /*
992 std::vector<fmm::particle2d> sources(W.getWake().vtx.size());
993 #pragma omp parallel for
994 for (int i = 0; i < (int)sources.size(); ++i)
995 {
996 const auto& w = W.getWake().vtx[i];
997
998 sources[i].center = fmm::point2d(w.r()[0], w.r()[1]);
999 sources[i].q = w.g();
1000 sources[i].morton_code = 0;
1001 }
1002
1003 auto targets = sources;
1004 for (int i = 0; i < (int)sources.size(); ++i)
1005 targets[i].q = 0;
1006
1007 double t = omp_get_wtime();
1008 //fmm::ComputeExact<fmm::InteractionType::Potential2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1009 fmm::ComputeExact<fmm::InteractionType::Force2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1010 std::cout << "Compute exact time = " << omp_get_wtime() - t << std::endl;
1011
1012 t = omp_get_wtime();
1013
1014 fmm::FastMultipole fmm(sources, targets, 1.e-8, fmm::FMM_AUTO, fmm::FMM_AUTO); // or fmm::gpu::FastMultipole... for gpu version
1015 fmm::ReadError<fmm::InteractionType::Force2d>(fmm.forces);
1016 //fmm::ReadError<fmm::InteractionType::Potential2d>(fmm.potentials);
1017 std::cout << "Total time = " << omp_get_wtime() - t << std::endl;
1018 */
1019
1020
1021
1023 /*
1024 std::ofstream treeTimeFile;
1025 if (W.getCurrentStep() == 0)
1026 {
1027 treeTimeFile.open(W.getPassport().dir + "/dbg/treeTime.csv");
1028 treeTimeFile << "step,time,N,lev,averPoints,tBUI,tUPW,tDNW,tBUIgpu,tUPWgpu,tDNWgpu\n";
1029 }
1030 else
1031 treeTimeFile.open(W.getPassport().dir + "/dbg/treeTime.csv", std::ios::app);
1032
1033
1034 int estLevel = std::max(4, (int)(log2(W.getWake().vtx.size())));
1035
1036 for (int controlLevel = std::max(estLevel - 2, 1); controlLevel <= estLevel + 2; ++controlLevel)
1037 {
1038 VMlib::vmTimer timerA, timerB;
1039 if (W.getWake().vtx.size() > 0)
1040 {
1041 if (W.getPassport().numericalSchemes.velocityComputation.second == 1)
1042 {
1043 W.getInflTreeWake().Update(W.getWake().vtx, controlLevel);
1044 timerA.start();
1045 W.getInflTreeWake().Build();
1046 timerA.stop();
1047 timerB.start();
1048 W.getInflTreeWake().UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1049 timerB.stop();
1050
1051 W.getCntrTreeWake().Update(W.getWake().vtx, controlLevel);
1052 W.getCntrTreeWake().Build();
1053 W.getCntrTreeWake().UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1054 }
1055
1056 std::vector<Point2D> tempVelo(wakeVortexesParams.convVelo.size());
1057 std::vector<double> tempRadius(wakeVortexesParams.epsastWake.size());
1058
1059 //Вызов виртуальной функции
1060 double timerCduration = CalcConvVeloToSetOfPointsFromWake(W.getWake(), tempVelo, tempRadius, true, false);
1061
1062 int nObjInContr = 0;
1063 for (int c = 0; c < W.getCntrTreeWake().indexControlCells.size(); ++c)
1064 {
1065 const auto& idx = W.getCntrTreeWake().indexControlCells[c];
1066 if (idx > W.getCntrTreeWake().object.size())
1067 nObjInContr += 1;
1068 else
1069 {
1070 nObjInContr += W.getCntrTreeWake().range[idx].second - W.getCntrTreeWake().range[idx].first + 1;
1071 }
1072 }
1073
1074 treeTimeFile << W.getCurrentStep() << ',' << W.getCurrentTime() << ',' << W.getInflTreeWake().object.size() << ',' \
1075 << controlLevel << ',' << (double)nObjInContr / W.getCntrTreeWake().indexControlCells.size() << ',' \
1076 << timerA.duration() << ',' << timerB.duration() << ',' << timerCduration << ',' \
1077 << timerAgpu.duration() << ',' << timerBgpu.duration() << ',' << timerCgpuduration << '\n';
1078 }
1079 }
1080
1081 treeTimeFile.close();
1082 */
1083#else
1084 float timeUpd1=0, timeBld1=0, timeUpw1=0, timeUpd2=0, timeBld2=0, timeUpw2=0, timeDnw=0;
1087
1088 VMlib::vmTimer fullTimer;
1089 fullTimer.reset();
1090 fullTimer.start();
1091
1092 if (W.getWake().vtx.size() > 0)
1093 {
1095 {
1096 int estOptLevel = std::max(4, (int)(log2(W.getWake().vtx.size())) - 2);
1097
1098 timeUpd1 = W.getInflTreeWake().Update(W.getWake().vtx, estOptLevel);
1099 timeBld1 = W.getInflTreeWake().Build();
1101
1102 //timeUpd2 = W.getCntrTreeWake().Update(W.getWake().vtx, estOptLevel);
1103 //timeBld2 = W.getCntrTreeWake().Build();
1104 //timeUpw2 = W.getCntrTreeWake().UpwardTraversal(W.getPassport().numericalSchemes.nbodyMultipoleOrder);
1105
1106 //std::cout << "timeUpd = " << timeUpd1 << " " << timeUpd2 << '\n';
1107 //std::cout << "timeBld = " << timeBld1 << " " << timeBld2 << '\n';
1108 //std::cout << "timeUpw = " << timeUpw1 << " " << timeUpw2 << '\n';
1109
1110 }
1111
1112 //Вызов виртуальной функции
1113
1115
1116 //std::string vname = VMlib::fileNameStep("VeloBH", 0, wakeVortexesParams.convVelo.size(), "txt");
1117 //std::ofstream velofile;
1118 //velofile.open(W.getPassport().dir + vname);
1119
1120 //for (int i = 0; i < wakeVortexesParams.convVelo.size(); ++i)
1121 // velofile << wakeVortexesParams.convVelo[i][0] << " " << wakeVortexesParams.convVelo[i][1] << "\n";
1122 //velofile.close();
1123 //exit(-124);
1124
1125 //std::cout << "timeDnw = " << timeDnw << '\n';
1126 }
1127 fullTimer.stop();
1128
1130 //std::cout << "theta = " << W.getPassport().numericalSchemes.nbodyTheta << "\n";
1131
1133 /*
1134 VMlib::vmTimer timerExact;
1135
1136 if (W.getWake().vtx.size() > 0)
1137 {
1138 std::vector<fmm::particle2d> sources(W.getWake().vtx.size());
1139 #pragma omp parallel for
1140 for (int i = 0; i < (int)sources.size(); ++i)
1141 {
1142 const auto& w = W.getWake().vtx[i];
1143
1144 sources[i].center = fmm::point2d(w.r()[0], w.r()[1]);
1145 sources[i].q = w.g();
1146 sources[i].morton_code = 0;
1147 }
1148
1149 auto targets = sources;
1150 for (int i = 0; i < (int)sources.size(); ++i)
1151 targets[i].q = 0;
1152
1153 //double t = omp_get_wtime();
1154 //fmm::ComputeExact<fmm::InteractionType::Potential2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1155 timerExact.start();
1156 fmm::ComputeExact<fmm::InteractionType::Force2d>(sources, targets); // or fmm::gpu::ComputeExact... for gpu version
1157 timerExact.stop();
1158 //std::cout << "Compute exact time = " << omp_get_wtime() - t << std::endl;
1159
1160 //t = omp_get_wtime();
1161
1162 fmm::FastMultipole fmm(sources, targets, 1.e-8, fmm::FMM_AUTO, fmm::FMM_AUTO); // or fmm::gpu::FastMultipole... for gpu version
1163 fmm::ReadError<fmm::InteractionType::Force2d>(fmm.forces);
1164 //fmm::ReadError<fmm::InteractionType::Potential2d>(fmm.potentials);
1165 //std::cout << "Total time = " << omp_get_wtime() - t << std::endl;
1166
1167 std::cout << "Hybrid time ConvVelo Wake = " << fullTimer.duration() <<
1168 //W.timerConvVelo.duration() <<
1169 " ( " << timeUpd1 + timeUpd2 + timeBld1 + timeBld2 + timeUpw1 + timeUpw2 + timeDnw << " )" << '\n';
1170
1171 fmm::ReadErrorHyb(*((std::vector<std::array<double, 2>>*) &wakeVortexesParams.convVelo));
1172 std::cout << "Exact time = " << timerExact.duration() << '\n';
1173 }
1174 //*/
1175
1176
1177
1178#endif
1179
1180 std::vector<Point2D> nullVector(0);
1181 //вычисление конвективных скоростей по закону Био-Савара от виртуальных вихрей (точнее, от слоев)
1182 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1183 {
1184 //Влияние на след от панелей
1185#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_CONVVIRT))
1186
1188 {
1189 case 0:
1190 W.getBoundary(bou).GPUCalcConvVelocityToSetOfPointsFromSheets(W.getWake(), wakeVortexesParams.convVelo);
1191 break;
1192 case 1:
1193 if (bou == 0)
1194 GPUCalcConvVelocityToSetOfPointsFromSheets(W.getNonConstCuda().cntrTreeWake, W.getWake(), wakeVortexesParams.convVelo);
1195 break;
1196 }
1197 //
1198
1199#else
1201#endif
1202 }
1203
1204 //Скорости только что рожденных вихрей
1205 {
1206 size_t nVirtVortices = 0;
1207 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1208 nVirtVortices += W.getBoundary(bou).virtualWake.vtx.size();
1209
1210 size_t counter = wakeVortexesParams.convVelo.size() - nVirtVortices;
1211
1212 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1213 for (size_t v = 0; v < W.getBoundary(bou).virtualWake.vtx.size(); ++v)
1214 {
1217 - W.getV0();
1218 ++counter;
1219 }
1220 }
1221
1222 //Заполнение структур данных виртуальных вихрей
1223 {
1224 size_t nVirtVortices = 0;
1225 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1226 nVirtVortices += W.getBoundary(bou).virtualWake.vtx.size();
1227
1228 size_t counter = wakeVortexesParams.convVelo.size() - nVirtVortices;
1229
1230 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
1231 for (size_t v = 0; v < W.getBoundary(bou).virtualWake.vtx.size(); ++v)
1232 {
1233 virtualVortexesParams[bou].convVelo[v] = wakeVortexesParams.convVelo[counter];
1234 virtualVortexesParams[bou].epsastWake[v] = wakeVortexesParams.epsastWake[counter];
1235 ++counter;
1236 }
1237 }
1238
1239 W.getTimers().stop("ConvVel");
1240 W.getTimers().start("VelPres");
1241
1242 //вычисление скоростей в заданных точках только на соответствующем шаге по времени
1244#ifdef OPTIMIZER
1245 if ((W.getCurrentStep() >= OPTIMIZER_START_STEP && W.getCurrentStep() <= OPTIMIZER_STOP_STEP) || W.getCurrentStep() == 0)
1247#else
1248
1249 //t1 = -omp_get_wtime();
1251 //t1 += omp_get_wtime();
1252 //std::cout << "time ConvVelo VP = " << t1 << std::endl;
1253#endif
1254
1256 /*if ((W.getPassport().timeDiscretizationProperties.saveVPstep > 0) && (!(W.getCurrentStep() % W.getPassport().timeDiscretizationProperties.saveVPstep)))
1257 {
1258 int currentStep = W.getCurrentStep();
1259 if (currentStep >= 1100 && currentStep <= 1300)
1260 {
1261 CalcVeloToWakeVP();
1262 optimizedVelocity.AddVelocities(W.getNonConstMeasureVP().getNonConstVelocity());
1263 }
1264
1265 if (currentStep == 1200)
1266 {
1267 optimizedVelocity.PerformAveragingVelo(W.getPassport().dir);
1268 }
1269 }*/
1271
1272 W.getTimers().stop("VelPres");
1273}//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 1372 of file Velocity2D.cpp.

1373{
1374 CalcDiffVeloI1I2ToSetOfPointsFromSheets(pointsDb, domainRadius, bnd, I1, I2);
1375}
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 1367 of file Velocity2D.cpp.

1368{
1369 CalcDiffVeloI1I2ToSetOfPointsFromWake(pointsDb, domainRadius, vorticesDb, I1, I2);
1370}//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 1278 of file Velocity2D.cpp.

1279{
1280 std::vector<Point2D> velConvWake;
1281 std::vector<std::vector<Point2D>> velConvBou;
1282
1283 int addWSize = (int)W.getMeasureVP().getWakeVP().vtx.size();
1284
1285 velConvWake.resize(addWSize, { 0.0, 0.0 });
1286
1287 velConvBou.resize(W.getNumberOfBoundary());
1288 for (size_t i = 0; i < W.getNumberOfBoundary(); ++i)
1289 velConvBou[i].resize(addWSize, { 0.0, 0.0 });
1290
1291 std::vector<Point2D>& velocityRef = W.getNonConstMeasureVP().getNonConstVelocity();
1292 velocityRef.assign(addWSize, W.getV0());
1293
1294#if (defined(USE_CUDA))
1295 W.getNonConstCuda().RefreshVP();
1296#endif
1297
1298#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_VP))
1299 std::unique_ptr<BHcu::CudaTreeInfo>& cntrTree = W.getNonConstCuda().cntrTreeVP;
1300
1302 {
1303 case 1:
1305 {
1306 cntrTree->MemoryAllocate((int)W.getCuda().n_CUDA_velVP);
1307 cntrTree->Update((int)W.getMeasureVP().getWakeVP().vtx.size(), W.getMeasureVP().getWakeVP().devVtxPtr);
1308 cntrTree->Build();
1309 GPUCalcConvVeloToSetOfPointsFromWake(cntrTree, W.getMeasureVP().getWakeVP(), velocityRef, W.getNonConstMeasureVP().getNonConstDomainRadius(), true, false);
1310 }
1311 break;
1312 case 0:
1313 GPUCalcConvVeloToSetOfPointsFromWake(cntrTree, W.getMeasureVP().getWakeVP(), velocityRef, W.getNonConstMeasureVP().getNonConstDomainRadius(), true, false);
1314 break;
1315 }
1316
1317
1318#else
1320 {
1321 case 0:
1323 break;
1324 case 1:
1326 double theta = W.getPassport().numericalSchemes.nbodyTheta;
1327
1329 W.getCntrTreeVP().Build();
1332 }
1333#endif
1334
1335
1336 for (size_t i = 0; i < W.getNumberOfBoundary(); ++i)
1337#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_VP))
1339 {
1340 case 0:
1341 W.getNonConstBoundary(i).GPUCalcConvVelocityToSetOfPointsFromSheets(W.getMeasureVP().getWakeVP(), velConvBou[i]);
1342
1343 for (int s = 0; s < addWSize; ++s)
1344 velocityRef[s] += velConvWake[s];
1345
1346 for (size_t bou = 0; bou < velConvBou.size(); ++bou)
1347 for (int j = 0; j < addWSize; ++j)
1348 velocityRef[j] += velConvBou[bou][j];
1349 break;
1350 case 1:
1351 if (i == 0)
1352 GPUCalcConvVelocityToSetOfPointsFromSheets(cntrTree, W.getMeasureVP().getWakeVP(), velocityRef);
1353 break;
1354 }
1355#else
1357 for (int i = 0; i < addWSize; ++i)
1358 velocityRef[i] += velConvWake[i];
1359
1360 for (size_t bou = 0; bou < velConvBou.size(); ++bou)
1361 for (int j = 0; j < addWSize; ++j)
1362 velocityRef[j] += velConvBou[bou][j];
1363#endif
1364}// 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 811 of file Velocity2D.cpp.

812{
813 Eigen::VectorXd locRhs;
814 std::vector<double> lastRhs(W.getNumberOfBoundary());
815
816 size_t currentRow = 0;
817 size_t currentSkosRow = 0;
818
819 size_t nAllVars = 0;
820 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
821 nAllVars += W.getBoundary(bou).GetUnknownsSize();
822
823 //Временные массивы для хранения правой части по быстрому методу (размеры задаются внутри CPUGetFASTWakeInfluenceToRhs)
824 std::vector<double> fastWakeRhs;
825 std::vector<double> fastWakeRhsLin;
826
827#ifndef USE_CUDA
828 if (W.getPassport().numericalSchemes.velocityComputation.second == 1) //Быстрый метод на CPU
829 CPUGetFASTWakeInfluenceToRhs(fastWakeRhs, fastWakeRhsLin);
830#endif
831 size_t curGlobPnl = 0;
832
833 for (size_t bou = 0; bou < W.getNumberOfBoundary(); ++bou)
834 {
835 const Airfoil& afl = W.getAirfoil(bou);
836 size_t np = afl.getNumberOfPanels();
837
838 size_t nVars;
839
840 nVars = W.getBoundary(bou).GetUnknownsSize();
841 locRhs.resize(nVars);
842
843 std::vector<double> wakeRhs;
844
845 double tt1 = omp_get_wtime();
846
847#if (defined(__CUDACC__) || defined(USE_CUDA)) && (defined(CU_RHS))
848 W.timerRhs.reset();
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 std::vector<double> vInfRhs;
884 afl.GetInfluenceFromVInfToPanel(vInfRhs);
885
886#pragma omp parallel for \
887 default(none) \
888 shared(locRhs, afl, bou, wakeRhs, vInfRhs, np) \
889 schedule(dynamic, DYN_SCHEDULE)
890 for (int i = 0; i < (int)afl.getNumberOfPanels(); ++i)
891 {
892 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] - прямолинейные
893 if (W.getBoundary(bou).sheetDim > 1)
894 locRhs(np + i) = -vInfRhs[np + i] - wakeRhs[np + i];
895
897 //Если включен быстрый метод и есть подвижные тела, то пока что все равно вычисляем IQ
899 {
900 for (size_t q = 0; q < W.getNumberOfBoundary(); ++q)
901 {
902 const auto& sht = W.getBoundary(q).sheets;
903 const auto& iq = W.getIQ(bou, q);
904
905 const Airfoil& aflOther = W.getAirfoil(q);
906 if (W.getMechanics(q).isMoves)
907 {
908 for (size_t j = 0; j < aflOther.getNumberOfPanels(); ++j)
909 {
910 if ((i != j) || (bou != q))
911 {
912 locRhs(i) += -iq.first(i, j) * sht.attachedVortexSheet(j, 0);
913 locRhs(i) += -iq.second(i, j) * sht.attachedSourceSheet(j, 0);
914 }//if (i != j)
915
916 }//for j
917 }
918 }//for q
919 }
920 }//for i
921
922 lastRhs[bou] = 0.0;
923
924#pragma omp for
925 for (int q = 0; q < (int)afl.gammaThrough.size(); ++q)
926 lastRhs[bou] += afl.gammaThrough[q];
927
929
930 const double currT = W.getCurrentTime();
931 const double dt = W.getPassport().timeDiscretizationProperties.dt;
932
933 lastRhs[bou] += (W.getMechanics(bou).circulation - W.getMechanics(bou).circulationOld) * (W.getAirfoil(bou).inverse ? 1.0 : -1.0);
934
936
937 //размазываем правую часть
938 for (size_t i = 0; i < nVars; ++i)
939 rhsReord(i + currentSkosRow) = locRhs(i);
940
941 rhsReord(nAllVars + bou) = lastRhs[bou];
942
943 currentRow += nVars + 1;
944 currentSkosRow += nVars;
945 }// for bou
946}
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: