52#include "spline/spline.h"
60 , numberInPassport(numberInPassport_)
75 return ((i == j + 1) || (i == 0 && j ==
r_.size() - 1));
144 auto check = [aflRj, aflRj1](
const Point2D& start,
const Point2D& finish)
146 return ((((aflRj - start) ^ (finish - start)) * ((aflRj1 - start) ^ (finish - start)) <= 0) && \
147 (((start - aflRj) ^ (aflRj1 - aflRj)) * ((finish - aflRj) ^ (aflRj1 - aflRj)) <= 0));
153 for (
size_t q = 0; (!flag) && (q < ((wayNumber == 0) ? 1 :
possibleWays[wayNumber - 1].size() + 1)); ++q)
158 flag = ( check(start, finish));
174 std::cout <<
"Possible way to vertex inside airfoil not found" << std::endl;
175 std::cout <<
"!!!" << std::endl;
176 std::cout <<
"dest = " << 0.5 * (
getR(i) +
getR(i + 1)) << std::endl;
177 std::cout <<
"j = " << j << std::endl;
180 std::cout <<
"rcm = " <<
rcm << std::endl;
185 std::cout <<
"Possible way # " << w << std::endl;
190 std::cout << std::endl;
196 airfoilFileStep <<
getR(s)[0] <<
" " <<
getR(s)[1] <<
"\n";
197 airfoilFileStep.close();
213 std::ifstream airfoilFile;
215 if (fileExistTest(filename,
W.
getInfo(),
true, {
"txt",
"TXT" }))
235 std::vector<Point2D> rFromFile;
236 airfoilParser.
get(
"r", rFromFile);
238 if (rFromFile.size() > 0)
242 r_.reserve(rFromFile.size());
243 r_.push_back(rFromFile[0]);
244 for (
size_t i = 1; i < rFromFile.size(); ++i)
245 if ((rFromFile[i] - rFromFile[i - 1]).length2() > 1e-12)
246 r_.push_back(rFromFile[i]);
249 if ((
r_.back() -
r_.front()).length2() < 1e-12)
250 r_.resize(
r_.size() - 1);
254 W.
getInfo(
'e') <<
"Airfoil shape is given explicitely, it can not be automatically split!" << std::endl;
260 std::vector<GeomPoint> geomFromFile;
262 airfoilParser.
get(
"geometry", geomFromFile);
264 if ((geomFromFile.front() - geomFromFile.back()).length2() < 1e-12)
265 geomFromFile.resize(geomFromFile.size() - 1);
269 std::vector<double> L(geomFromFile.size());
270 double totalLength = 0.0;
271 std::vector<size_t> nc = {};
272 std::vector<size_t> ni = {};
274 for (
size_t i = 0; i < geomFromFile.size(); ++i)
276 const Point2D& p1 = geomFromFile[i];
277 const Point2D& p2 = geomFromFile[(i + 1) % geomFromFile.size()];
279 L[i] = (p2 - p1).length();
314 std::vector<size_t> splineStart, splineFinish;
316 while (i < geomFromFile.size())
318 while (i < geomFromFile.size() && !(geomFromFile[i].type ==
"c"))
321 if (i < geomFromFile.size())
323 splineStart.push_back(i);
326 while (i < geomFromFile.size() && !(geomFromFile[i].type ==
"c"))
329 splineFinish.push_back(i);
333 if ((splineStart.size() > 0) && (splineStart[0] != 0))
334 splineFinish.back() = splineStart[0];
338 r_.reserve(geomFromFile.size());
339 for (
size_t i = 0; i < geomFromFile.size(); ++i)
340 r_.push_back(geomFromFile[i]);
344 double hRef = totalLength / reqN;
346 std::vector<int> nPanels;
348 bool cyclic = (splineStart.size() == 0);
352 splineStart.push_back(0);
353 splineFinish.push_back(geomFromFile.size());
356 for (
size_t s = 0; s < splineStart.size(); ++s)
359 std::vector<double> T, X, Y;
361 size_t splineLegs = splineFinish[s] - splineStart[s];
362 if (splineFinish[s] <= splineStart[s])
363 splineLegs += geomFromFile.
size();
365 T.reserve(splineLegs + 1);
371 for (
size_t i = splineStart[s]; i <= splineStart[s] + splineLegs; ++i)
373 const Point2D& pt = geomFromFile[i % geomFromFile.size()];
379 if ((i == splineStart[s]) && (splineFinish[s] - splineStart[s] == 1))
381 double halfL = (i < geomFromFile.size()) ? 0.5 * L[i] : 0.5 * (geomFromFile.front() - geomFromFile.back()).length();
384 Point2D nextPt = geomFromFile[(i + 1) % geomFromFile.size()];
386 X.push_back(0.5 * (pt[0] + nextPt[0]));
387 Y.push_back(0.5 * (pt[1] + nextPt[1]));
392 tbuf += (i < geomFromFile.size()) ? L[i] : (geomFromFile.front() - geomFromFile.back()).length();
398 s1.set_boundary(tk::spline::cyclic);
399 s2.set_boundary(tk::spline::cyclic);
403 s1.set_boundary(tk::spline::second_deriv, 0.0, tk::spline::second_deriv, 0.0);
404 s2.set_boundary(tk::spline::second_deriv, 0.0, tk::spline::second_deriv, 0.0);
410 int NumberOfPanelsSpline = (int)ceil(T.back() / hRef);
411 double hSpline = T.back() / NumberOfPanelsSpline;
413 for (
int i = 0; i < NumberOfPanelsSpline; ++i)
414 r_.push_back({ s1(hSpline * i), s2(hSpline * i) });
416 nPanels.push_back(NumberOfPanelsSpline);
424 W.
getInfo(
'e') <<
"No points on airfoil contour!" << std::endl;
429 std::reverse(
r_.begin(),
r_.end());
432 for (
size_t q = 0; q <
r_.size(); ++q)
433 v_.push_back({ 0.0, 0.0 });
437 int defaultNPossibleWays = 0;
438 airfoilParser.get(
"nPossibleWays", nPossibleWays, &defaultNPossibleWays,
false);
441 for (
int q = 0; q < nPossibleWays; ++q)
442 airfoilParser.get(
"possibleWay" + std::to_string(q + 1),
possibleWays[q]);
445 auto xMinMax = std::minmax_element(
r_.begin(),
r_.end(), Point2D::cmp<
'x'>);
446 auto yMinMax = std::minmax_element(
r_.begin(),
r_.end(), Point2D::cmp<
'y'>);
449 {
Point2D({ (*xMinMax.first)[0], (*yMinMax.first)[1] }),
Point2D({ (*xMinMax.second)[0], (*yMinMax.second)[1] }) };
454 double rotationAngle = param.
angle;
466 std::ofstream of(fname);
467 for (
size_t i = 0; i <
r_.size(); ++i)
468 of <<
r_[i][0] <<
" " <<
r_[i][1] << std::endl;
478 for (
size_t q = 0; q <
r_.size(); ++q)
482 area += (cntq[0] * drq[1] - cntq[1] * drq[0]);
494 std::vector<double> selfI0;
495 std::vector<Point2D> selfI3;
497 std::vector<double> currViscousStress;
498 currViscousStress.resize(
r_.size(), 0.0);
501 selfI0.resize(pointsDb.
vtx.size(), 0.0);
502 selfI3.resize(pointsDb.
vtx.size(), { 0.0, 0.0 });
504#pragma warning (push)
505#pragma warning (disable: 4101)
508 double lxi, lxi_m, lenj_m;
518 double iDDomRad, domRad, expon;
521#pragma omp parallel for \
523 shared(domainRadius, pointsDb, selfI0, selfI3, currViscousStress, PI) \
524 private(xi, xi_m, lxi, lxi_m, lenj_m, v0, q, new_n, mn, h, d, s, vec, vs, expon, domRad, iDDomRad) schedule(dynamic, DYN_SCHEDULE)
525 for (
int i = 0; i < pointsDb.
vtx.size(); ++i)
530 iDDomRad = 1.0 / domRad;
532 for (
size_t j = 0; j <
r_.size(); ++j)
535 q = vtxI.
r() - 0.5 * (
getR(j) +
getR(j + 1));
539 d = fabs(q &
nrm[j]);
541 if ((d < 50.0 *
len[j]) && (fabs(s) < 50.0 *
len[j]))
545 if ((d > 5.0 *
len[j]) || (fabs(s) > 5.0 *
len[j]))
550 expon = exp(-lxi) *
len[j];
555 selfI0[i] += (xi & mn) * (lxi + 1.0) / (lxi * lxi);
561 else if ((d >= 0.1 *
len[j]) || (fabs(s) > 0.5 *
len[j]))
564 double den = (fabs(s) < 0.5 *
len[j]) ? d : (fabs(s) + d - 0.5 *
len[j]);
566 new_n = std::max(1,
static_cast<int>(ceil(5.0 *
len[j] / den)));
568 h = v0 * (1.0 / new_n);
570 for (
int m = 0;
m < new_n; ++
m)
572 xi_m = (vtxI.
r() - (
getR(j) + h * (
m + 0.5))) * iDDomRad;
575 lenj_m =
len[j] / new_n;
576 expon = exp(-lxi_m) * lenj_m;
581 selfI0[i] += (xi_m & mn) * (lxi_m + 1.0) / (lxi_m * lxi_m);
591 selfI0[i] += -
PI * domRad;
592 double mnog = 2.0 * domRad * (1.0 - exp(-
len[j] * iDDomRad / 2.0) * cosh(fabs(s) * iDDomRad));
593 selfI3[i] +=
nrm[j] * mnog;
599 currViscousStress[j] += vs;
610 for (
size_t i = 0; i < I0.size(); ++i)
614 if (I0[i] != -
PI * domRad)
616 if (selfI0[i] == -
PI * domRad)
646void Airfoil::GPUGetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(std::vector<double>& domainRadius, std::vector<double>& I0, std::vector<Point2D>& I3)
648 std::vector<double> newViscousStress;
658 const size_t nr =
r_.size();
660 float*& dev_ptr_i0f =
W.
getWake().devI0fPtr;
661 float*& dev_ptr_i3f =
W.
getWake().devI3fPtr;
668 std::vector<Point2D> newI3(npt);
669 std::vector<double> newI0(npt);
670 std::vector<Point2Df> newI3f(npt);
671 std::vector<float> newI0f(npt);
673 newViscousStress.resize(nTotPan);
675 if ((npt > 0) && (nr > 0))
677 double*& dev_ptr_visstr = devViscousStressesPtr;
679 std::vector<double> locvisstr(nTotPan);
681 std::vector<double> zeroVec(nTotPan, 0.0);
682 cuCopyFixedArray(dev_ptr_visstr, zeroVec.data(), nTotPan *
sizeof(
double), 101);
686 double* dev_ptr_pt =
W.
getWake().devVtxPtr;
687 double* dev_ptr_i0 =
W.
getWake().devI0Ptr;
688 double* dev_ptr_i3 =
W.
getWake().devI3Ptr;
689 double* dev_ptr_rad =
W.
getWake().devRadPtr;
692 W.
getCuda().CopyMemFromDev<double, 2>(npt, dev_ptr_i3, (
double*)newI3.data());
693 W.
getCuda().CopyMemFromDev<double, 1>(npt, dev_ptr_i0, newI0.data());
694 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_visstr, newViscousStress.data());
697 for (
size_t q = 0; q < I3.size(); ++q)
708 auto& treeWake = *
W.
getCuda().inflTreeWake;
712 W.
getCuda().CopyMemFromDev<float, 2>(npt, dev_ptr_i3f, (
float*)newI3f.data());
713 W.
getCuda().CopyMemFromDev<float, 1>(npt, dev_ptr_i0f, newI0f.data());
714 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_visstr, newViscousStress.data());
716 for (
size_t q = 0; q < I3.size(); ++q)
722 size_t curGlobPnl = 0;
727 tmpVisStress.resize(0);
728 tmpVisStress.insert(tmpVisStress.end(), newViscousStress.begin() + curGlobPnl, newViscousStress.begin() + curGlobPnl + np);
743void Airfoil::GPUGetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(
const WakeDataBase& pointsDb, std::vector<double>& domainRadius, std::vector<double>& I0, std::vector<Point2D>& I3)
745 std::vector<double> newViscousStress;
757 size_t npt = pointsDb.
vtx.size();
765 double*& dev_ptr_pt = pointsDb.devVtxPtr;
766 double*& dev_ptr_rad = pointsDb.devRadPtr;
767 double*& dev_ptr_meanEps = devMeanEpsOverPanelPtr;
768 const size_t nr =
r_.size();
769 double*& dev_ptr_r = devRPtr;
771 double*& dev_ptr_i0 = pointsDb.devI0Ptr;
772 double*& dev_ptr_i3 = pointsDb.devI3Ptr;
774 float*& dev_ptr_i0f = pointsDb.devI0fPtr;
775 float*& dev_ptr_i3f = pointsDb.devI3fPtr;
783 double tNEIB = -omp_get_wtime();
786 bool isMovable =
false;
790 std::vector<std::pair<int,double>> nearestPan = panelSearcher.get_nearest_panels(
W.
getCurrentStep(), (
int)npt, dev_ptr_pt, (
int)nr, dev_ptr_r, isMovable);
791 tNEIB += omp_get_wtime();
793 double tSelectVortex = -omp_get_wtime();
795 if (vorticesToProcess.size() < npt)
797 size_t curSize = vorticesToProcess.size();
801 }
while (curSize < npt);
802 vorticesToProcess.resize(curSize);
807 for (
int q = 0; q < (int)npt; ++q)
814 vorticesToProcess[vtp++] = q;
817 if (batch.size() < vtp * 3 * 5)
819 size_t curSize = batch.size() / (3*5);
823 }
while (curSize < vtp);
824 batch.resize(curSize * 3 * 5);
825 signy.resize(curSize * 5);
826 nnout.resize(curSize * 2 * 5);
827 batchPanels.resize(curSize * 5);
830#pragma omp parallel for
831 for (
int v = 0; v < (int)vtp; ++v)
835 for (
int s = 0; s < 5; ++s)
837 int panIndex = nearestPan[vorticesToProcess[v]].first + s - 2;
851 batch[v * 15 + 3 * s + 0] = fabsf((
float)relPos[0]);
852 batch[v * 15 + 3 * s + 1] = fabsf((
float)relPos[1]);
853 signy[v * 5 + s] = (relPos[1] > 0) ? 1 : -1;
856 batch[v * 15 + 3 * s + 2] = (float)(domrad /
W.
getAirfoil(0).
len[panIndex]);
858 batchPanels[v * 5 + s] = panIndex;
861 tSelectVortex += omp_get_wtime();
864 double tNN2 = -omp_get_wtime();
865 NN.setup_layers(vtp * 5);
866 tNN2 += omp_get_wtime();
868 double tNN3 = -omp_get_wtime();
869 NN.start((
int)(vtp * 5), batch.data(), nnout.data());
870 tNN3 += omp_get_wtime();
872 double tNN4 = -omp_get_wtime();
874 tNN4 += omp_get_wtime();
876 std::cout <<
"tNEIB = " << tNEIB << std::endl;
877 std::cout <<
"tSelectVortex = " << tSelectVortex << std::endl;
878 std::cout <<
"tNN2 = " << tNN2 << std::endl;
879 std::cout <<
"tNN3 = " << tNN3 << std::endl;
880 std::cout <<
"tNN4 = " << tNN4 << std::endl;
881 std::cout <<
"tSum = " << tNEIB + tSelectVortex + tNN2 + tNN3 + tNN4 << std::endl;
885 std::vector<double> nnI0(npt, 0.0);
886 std::vector<Point2D> nnI3(npt, {0.0, 0.0});
888#pragma omp parallel for
889 for (
int v = 0; v < vtp; ++v)
893 for (
int s = 0; s < 5; ++s)
895 float xx = batch[v * 15 + 3 * s + 0];
896 float yy = signy[v*5+s] * batch[v * 15 + 3 * s + 1];
897 if ((fabs(xx) < 0.5f) && (fabs(yy) < 1e-3))
898 nnI0[vorticesToProcess[v]] += -
PI * domrad * domrad;
900 nnI0[vorticesToProcess[v]] += (-nnout[v * 10 + s * 2 + 1] *
sqr(
W.
getAirfoil(0).
len[batchPanels[v * 5 + s]]));
901 nnI3[vorticesToProcess[v]] += (nnout[v * 10 + s * 2 + 0] *
W.
getAirfoil(0).
len[batchPanels[v * 5 + s]]) *
W.
getAirfoil(0).
nrm[batchPanels[v * 5 + s]];
903 nnI0[vorticesToProcess[v]] /= domrad;
912 newViscousStress.resize(nTotPan);
915 if ((npt > 0) && (nr > 0))
917 double*& dev_ptr_visstr = devViscousStressesPtr;
919 std::vector<double> locvisstr(nTotPan);
921 std::vector<double> zeroVec(nTotPan, 0.0);
922 cuCopyFixedArray(dev_ptr_visstr, zeroVec.data(), nTotPan *
sizeof(
double), 101);
966 for (
size_t q = 0; q < I3.size(); ++q)
983 size_t curGlobPnl = 0;
988 tmpVisStress.resize(0);
989 tmpVisStress.insert(tmpVisStress.end(), newViscousStress.begin() + curGlobPnl, newViscousStress.begin() + curGlobPnl + np);
1009 double sumAngle = 0.0;
1013 for (
size_t i = 0; i <
r_.size(); ++i)
1015 v1 =
getR(i) - point;
1016 v2 =
getR(i + 1) - point;
1017 sumAngle += atan2(v1 ^ v2, v1 & v2);
1020 if (fabs(sumAngle) < 0.1)
1032 for (
size_t i = 0; i <
r_.size(); ++i)
1049 if (
nrm.size() !=
r_.size())
1051 nrm.resize(
r_.size());
1052 psn.resize(
r_.size());
1053 tau.resize(
r_.size());
1054 len.resize(
r_.size());
1060#pragma omp parallel for private(rpan)
1061 for (
int i = 0; i < (int)
r_.size(); ++i)
1070#pragma omp parallel for
1071 for (
int i = 0; i < (int)
r_.size(); ++i)
1073 int next = (i == (int)
r_.size() - 1 ? 0 : i + 1);
1074 int prev = (i == 0 ? (int)
r_.size() - 1 : i - 1);
1076 psn[i] = std::make_pair( (
nrm[prev] +
nrm[i]).unit(), (
nrm[i] +
nrm[next]).unit() );
1088 for (
size_t i = 0; i <
r_.size(); ++i)
1106 for (
size_t i = 0; i <
r_.size(); ++i)
1113 pts =
rcm + (rotMatrix & (oldPts -
rcm));
1124 for (
size_t i = 0; i <
r_.size(); ++i)
1131 pts =
rcm +
Point2D{ factor[0] * (oldPts -
rcm)[0], factor[1] * (oldPts -
rcm)[1] };
1141 std::vector<double> res(p * p, 0.0);
1143 if ((i == j) && (&airfoil ==
this))
1145 res[0] = 0.5 * (
tau[i] ^
nrm[i]);
1149 res[3] = (1.0 / 12.0) * res[0];
1160 res[0] = miq.first(i, j);
1182 bool self = (&otherAirfoil ==
this);
1193 Point2D p1, s1, p2, s2, di, dj, i00, i01, i10, i11;
1197#pragma omp parallel for \
1199 shared(otherAirfoil, self, aflNSelf, aflNOther, matrPair, p, IDPI, IQPI) \
1200 private(npI, npJ, alpha, lambda, p1, s1, p2, s2, di, dj, i00, i01, i10, i11, v00, v11, v01, v10) schedule(dynamic, DYN_SCHEDULE)
1207 if ((i == j) && self)
1210 matrPair.first(i, j) = 0.0;
1211 matrPair.second(i, j) = 0.0;
1215 matrPair.first(i, npJ + j) = 0.0;
1216 matrPair.first(npI + i, j) = 0.0;
1218 matrPair.second(i, npJ + j) = -
IQPI;
1219 matrPair.second(npI + i, j) =
IQPI;
1221 matrPair.first(npI + i, npJ + j) = 0.0;
1222 matrPair.second(npI + i, npJ + j) = 0.0;
1233 p1 =
getR(i + 1) - otherAirfoil.
getR(j + 1);
1234 s1 =
getR(i + 1) - otherAirfoil.
getR(j);
1235 p2 =
getR(i) - otherAirfoil.
getR(j + 1);
1236 s2 =
getR(i) - otherAirfoil.
getR(j);
1238 dj = otherAirfoil.
getR(j + 1) - otherAirfoil.
getR(j);
1242 VMlib::Alpha(s2, p1), \
1248 VMlib::Lambda(s2, p1), \
1258 i00 =
IDPI /
len[i] * (-(alpha[0] * v00[0] + alpha[1] * v00[1] + alpha[2] * v00[2]).kcross() \
1259 + (lambda[0] * v00[0] + lambda[1] * v00[1] + lambda[2] * v00[2]));
1261 matrPair.first(i, j) = i00 &
nrm[i];
1262 matrPair.second(i, j) = i00 & taui;
1272 i01 =
IDPI /
len[i] * (-((alpha[0] + alpha[2]) * v01[0] + (alpha[1] + alpha[2]) * v01[1]).kcross() \
1273 + ((lambda[0] + lambda[2]) * v01[0] + (lambda[1] + lambda[2]) * v01[1]) - 0.5 * di.
length() * tauj);
1275 matrPair.first(i, npJ + j) = i01 &
nrm[i];
1276 matrPair.second(i, npJ + j) = i01 & taui;
1284 i10 =
IDPI /
len[i] * (-((alpha[0] + alpha[2]) * v10[0] + alpha[2] * v10[1]).kcross() \
1285 + ((lambda[0] + lambda[2]) * v10[0] + lambda[2] * v10[1]) + 0.5 * dj.
length() * taui);
1287 matrPair.first(npI + i, j) = i10 &
nrm[i];
1288 matrPair.second(npI + i, j) = i10 & taui;
1297 i11 =
IDPI /
len[i] * (-((alpha[0] + alpha[2]) * v11[0] + (alpha[1] + alpha[2]) * v11[1] + alpha[2] * v11[2]).kcross()\
1298 + (lambda[0] + lambda[2]) * v11[0] + (lambda[1] + lambda[2]) * v11[1] + lambda[2] * v11[2] \
1301 matrPair.first(npI + i, npJ + j) = i11 &
nrm[i];
1302 matrPair.second(npI + i, npJ + j) = i11 & taui;
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса Boundary.
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса Mechanics.
Заголовочный файл с описанием класса Preprocessor.
Заголовочный файл с описанием класса StreamParser.
Заголовочный файл с описанием класса Velocity.
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса World2D.
std::vector< Point2D > r_
Координаты начал панелей
std::vector< Point2D > v_
Скорости начал панелей
double phiAfl
Поворот профиля
std::vector< double > len
Длины панелей профиля
std::vector< std::pair< Point2D, Point2D > > psn
Псевдонормали к панелям профиля
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
double area
Площадь профиля
std::vector< Point2D > nrm
Нормали к панелям профиля
std::vector< Point2D > tau
Касательные к панелям профиля
bool inverse
Признак разворота нормалей (для расчета внутренних течений)
Point2D rcm
Положение центра масс профиля
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Абстрактный класс, определяющий обтекаемый профиль
const World2D & W
Константная ссылка на решаемую задачу
void calcMeanEpsOverPanel()
Вычисление средних значений eps на панелях
virtual void GetInfluenceFromSourcesToPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &panelRhs) const
Вычисление влияния части подряд идущих источников из области течения на панель для правой части
virtual void GetInfluenceFromSourceSheetToVortex(size_t panel, const Vortex2D &vtx, Point2D &vel) const
Вычисление влияния слоя источников конкретной прямолинейной панели на вихрь в области течения
virtual void Scale(const Point2D &)
Масштабирование профиля
bool isAfter(size_t i, size_t j) const
Проверка, идет ли вершина i следом за вершиной j.
virtual void GetDiffVelocityI0I3ToWakeAndViscousStresses(const WakeDataBase &pointsDb, std::vector< double > &domainRadius, std::vector< double > &I0, std::vector< Point2D > &I3)
bool isOutsideGabarits(const Point2D &r) const
Определяет, находится ли точка с радиус-вектором вне габаритного прямоугольника профиля
Point2D upRight
Правый верхний угол габаритного прямоугольника профиля
std::vector< double > gammaThrough
Суммарные циркуляции вихрей, пересекших панели профиля на прошлом шаге
std::vector< int > wayToVertex
Номера путей к вершинам
virtual void GetGabarits(double gap=0.02)
Вычисляет габаритный прямоугольник профиля
bool isInsideGabarits(const Point2D &r) const
Определяет, находится ли точка с радиус-вектором внутри габаритного прямоугольника профиля
double J
Полярный момент инерции профиля относительно центра масс
virtual void GetInfluenceFromVorticesToPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &panelRhs) const
Вычисление влияния части подряд идущих вихрей из вихревого следа на панель для правой части
virtual void Move(const Point2D &dr)
Перемещение профиля
virtual void GetInfluenceFromVInfToPanel(std::vector< double > &vInfRhs) const
Вычисление влияния набегающего потока на панель для правой части
void CalcNrmTauLen()
Вычисление нормалей, касательных и длин панелей по текущему положению вершин
virtual bool IsPointInAirfoil(const Point2D &point) const
Определяет, находится ли точка с радиус-вектором внутри профиля
void lightningTest()
Тест на "отвещенность".
Point2D lowLeft
Левый нижний угол габаритного прямоугольника профиля
std::vector< double > viscousStress
Нейросеть для коэффициентов I0 и I3 диффузионной скорости
virtual void calcIQ(size_t p, const Airfoil &otherAirfoil, std::pair< Eigen::MatrixXd, Eigen::MatrixXd > &matrPair) const
Вычисление коэффициентов матрицы, состоящей из интегралов от (r-xi)/|r-xi|^2.
virtual void GetInfluenceFromVortexSheetToVortex(size_t panel, const Vortex2D &vtx, Point2D &vel) const
Вычисление влияния вихревых слоев (свободный + присоединенный) конкретной прямолинейной панели на вих...
virtual void GetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(const WakeDataBase &pointsDb, std::vector< double > &domainRadius, std::vector< double > &I0, std::vector< Point2D > &I3)
Вычисление числителей и знаменателей диффузионных скоростей в заданном наборе точек,...
Airfoil(const World2D &W_, const size_t numberInPassport_)
const size_t numberInPassport
Номер профиля в паспорте
std::vector< std::vector< Point2D > > possibleWays
Возможные пути внутри профиля от точки (0, 0) к центрам всех панелей
virtual void Rotate(double alpha)
Поворот профиля
virtual std::vector< double > getA(size_t p, size_t i, const Airfoil &airfoil, size_t j) const
Вычисление коэффициентов матрицы A для расчета влияния панели на панель
std::vector< double > meanEpsOverPanel
Средние значения Eps на панелях
virtual void ReadFromFile(const std::string &dir)
Считывание профиля из файла
Абстрактный класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле
virtual void GetInfluenceFromVorticesToRectPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &wakeRhs) const =0
Вычисление влияния части подряд идущих вихрей из вихревого следа на прямолинейную панель для правой ч...
virtual void GetInfluenceFromSourcesToRectPanel(size_t panel, const Vortex2D *ptr, ptrdiff_t count, std::vector< double > &wakeRhs) const =0
Вычисление влияния части подряд источников из области течения на прямолинейную панель для правой част...
virtual void GetInfluenceFromSourceSheetAtRectPanelToVortex(size_t panel, const Vortex2D &vtx, Point2D &vel) const =0
Вычисление влияния слоя источников конкретной прямолинейной панели на вихрь в области течения
virtual void GetInfluenceFromVInfToRectPanel(std::vector< double > &vInfRhs) const =0
Вычисление влияния набегающего потока на прямолинейную панель для правой части
std::vector< std::pair< int, int > > vortexBeginEnd
Номера первого и последнего вихрей, рождаемых на каждой панели профиля (формируется после решения СЛА...
virtual void GetInfluenceFromVortexSheetAtRectPanelToVortex(size_t panel, const Vortex2D &vtx, Point2D &vel) const =0
Вычисление влияния вихревых слоев (свободный + присоединенный) конкретной прямолинейной панели на вих...
VirtualWake virtualWake
Виртуальный вихревой след конкретного профиля
const bool isMoves
Переменная, отвечающая за то, двигается профиль или нет
const bool isDeform
Переменная, отвечающая за то, деформируется профиль или нет
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
std::vector< AirfoilParams > airfoilParams
Список структур с параметрами профилей
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
std::vector< VortexesParams > virtualVortexesParams
Вектор струтур, определяющий параметры виртуальных вихрей для профилей
VortexesParams wakeVortexesParams
Струтура, определяющая параметры вихрей в следе
Класс, опеделяющий набор вихрей
std::vector< Vortex2D > vtx
Список вихревых элементов
Класс, опеделяющий текущую решаемую задачу
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
const Wake & getWake() const
Возврат константной ссылки на вихревой след
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
const Mechanics & getMechanics(size_t i) const
Возврат константной ссылки на объект механики
const std::pair< Eigen::MatrixXd, Eigen::MatrixXd > & getIQ(size_t i, size_t j) const
Возврат константной ссылки на объект, связанный с матрицей интегралов от (r-xi)/|r-xi|^2.
const Velocity & getVelocity() const
Возврат константной ссылки на объект для вычисления скоростей
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Passport & getNonConstPassport() const
Возврат неконстантной ссылки на паспорт
const Boundary & getBoundary(size_t i) const
Возврат константной ссылки на объект граничного условия
Airfoil & getNonConstAirfoil(size_t i) const
Возврат неконстантной ссылки на объект профиля
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
std::string dir
Рабочий каталог задачи
Класс, опеделяющий двумерный вектор
Класс, позволяющий выполнять предварительную обработку файлов
Класс, позволяющий выполнять разбор файлов и строк с настройками и параметрами
bool get(const std::string &name, std::vector< Point2D > &res, const std::vector< Point2D > *defValue=nullptr, bool echoDefault=true) const
Считывание вектора из двумерных точек из базы данных
Класс, опеделяющий двумерный вихревой элемент
HD Point2D & r()
Функция для доступа к радиус-вектору вихря
HD double & g()
Функция для доступа к циркуляции вихря
VMlib::LogStream & getInfo() const
Возврат ссылки на объект LogStream Используется в техничеcких целях для организации вывода
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
Шаблонный класс, определяющий матрицу фиксированного размера Фактически представляет собой массив,...
Шаблонный класс, определяющий вектор фиксированной длины Фактически представляет собой массив,...
auto length2() const -> typename std::remove_const< typename std::remove_reference< decltype(this->data[0])>::type >::type
Вычисление квадрата нормы (длины) вектора
auto unit(P newlen=1) const -> numvector< typename std::remove_const< decltype(this->data[0] *newlen)>::type, n >
Вычисление орта вектора или вектора заданной длины, коллинеарного данному
P length() const
Вычисление 2-нормы (длины) вектора
T sqr(T x)
Умножение a на комплексно сопряженноe к b.
double Lambda(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления логарифма отношения норм векторов
double Alpha(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления угла между векторами
Point2D Omega(const Point2D &a, const Point2D &b, const Point2D &c)
Вспомогательная функция вычисления величины .
Описание класса nummatrix.
Point2D basePoint
Смещение центра масс (перенос профиля)
std::string fileAirfoil
Имя файла с начальным состоянием профилей (без полного пути)
double angle
Угол поворота (угол атаки)
Point2D scale
Коэффициент масштабирования
size_t requiredNPanels
Желаемое число панелей для разбиения геометрии
bool inverse
Признак разворота нормалей (для расчета внутреннего течения)
std::pair< std::string, int > velocityComputation
Структура, определяющая параметры виртуальных вихрей для отдельного профиля
std::vector< double > epsastWake
Вектор характерных радиусов вихревых доменов (eps*)
double getMinEpsAst() const
Функция минимально возможного значения для epsAst.
int saveVPstep
Шаг вычисления и сохранения скорости и давления