53#include "spline/spline.h"
55#include "treeKernels.cuh"
63 , numberInPassport(numberInPassport_)
78 return ((i == j + 1) || (i == 0 && j ==
r_.size() - 1));
147 auto check = [aflRj, aflRj1](
const Point2D& start,
const Point2D& finish)
149 return ((((aflRj - start) ^ (finish - start)) * ((aflRj1 - start) ^ (finish - start)) <= 0) && \
150 (((start - aflRj) ^ (aflRj1 - aflRj)) * ((finish - aflRj) ^ (aflRj1 - aflRj)) <= 0));
156 for (
size_t q = 0; (!flag) && (q < ((wayNumber == 0) ? 1 :
possibleWays[wayNumber - 1].size() + 1)); ++q)
161 flag = ( check(start, finish));
177 std::cout <<
"Possible way to vertex inside airfoil not found" << std::endl;
178 std::cout <<
"!!!" << std::endl;
179 std::cout <<
"dest = " << 0.5 * (
getR(i) +
getR(i + 1)) << std::endl;
180 std::cout <<
"j = " << j << std::endl;
183 std::cout <<
"rcm = " <<
rcm << std::endl;
188 std::cout <<
"Possible way # " << w << std::endl;
193 std::cout << std::endl;
199 airfoilFileStep <<
getR(s)[0] <<
" " <<
getR(s)[1] <<
"\n";
200 airfoilFileStep.close();
216 std::ifstream airfoilFile;
218 if (fileExistTest(filename,
W.
getInfo(),
true, {
"txt",
"TXT" }))
238 std::vector<Point2D> rFromFile;
239 airfoilParser.
get(
"r", rFromFile);
241 if (rFromFile.size() > 0)
245 r_.reserve(rFromFile.size());
246 r_.push_back(rFromFile[0]);
247 for (
size_t i = 1; i < rFromFile.size(); ++i)
248 if ((rFromFile[i] - rFromFile[i - 1]).length2() > 1e-12)
249 r_.push_back(rFromFile[i]);
252 if ((
r_.back() -
r_.front()).length2() < 1e-12)
253 r_.resize(
r_.size() - 1);
257 W.
getInfo(
'e') <<
"Airfoil shape is given explicitely, it can not be automatically split!" << std::endl;
263 std::vector<GeomPoint> geomFromFile;
265 airfoilParser.
get(
"geometry", geomFromFile);
267 if ((geomFromFile.front() - geomFromFile.back()).length2() < 1e-12)
268 geomFromFile.resize(geomFromFile.size() - 1);
272 std::vector<double> L(geomFromFile.size());
273 double totalLength = 0.0;
274 std::vector<size_t> nc = {};
275 std::vector<size_t> ni = {};
277 for (
size_t i = 0; i < geomFromFile.size(); ++i)
279 const Point2D& p1 = geomFromFile[i];
280 const Point2D& p2 = geomFromFile[(i + 1) % geomFromFile.size()];
282 L[i] = (p2 - p1).length();
317 std::vector<size_t> splineStart, splineFinish;
319 while (i < geomFromFile.size())
321 while (i < geomFromFile.size() && !(geomFromFile[i].type ==
"c"))
324 if (i < geomFromFile.size())
326 splineStart.push_back(i);
329 while (i < geomFromFile.size() && !(geomFromFile[i].type ==
"c"))
332 splineFinish.push_back(i);
336 if ((splineStart.size() > 0) && (splineStart[0] != 0))
337 splineFinish.back() = splineStart[0];
341 r_.reserve(geomFromFile.size());
342 for (
size_t i = 0; i < geomFromFile.size(); ++i)
343 r_.push_back(geomFromFile[i]);
347 double hRef = totalLength / reqN;
349 std::vector<int> nPanels;
351 bool cyclic = (splineStart.size() == 0);
355 splineStart.push_back(0);
356 splineFinish.push_back(geomFromFile.size());
359 for (
size_t s = 0; s < splineStart.size(); ++s)
362 std::vector<double> T, X, Y;
364 size_t splineLegs = splineFinish[s] - splineStart[s];
365 if (splineFinish[s] <= splineStart[s])
366 splineLegs += geomFromFile.
size();
368 T.reserve(splineLegs + 1);
374 for (
size_t i = splineStart[s]; i <= splineStart[s] + splineLegs; ++i)
376 const Point2D& pt = geomFromFile[i % geomFromFile.size()];
382 if ((i == splineStart[s]) && (splineFinish[s] - splineStart[s] == 1))
384 double halfL = (i < geomFromFile.size()) ? 0.5 * L[i] : 0.5 * (geomFromFile.front() - geomFromFile.back()).length();
387 Point2D nextPt = geomFromFile[(i + 1) % geomFromFile.size()];
389 X.push_back(0.5 * (pt[0] + nextPt[0]));
390 Y.push_back(0.5 * (pt[1] + nextPt[1]));
395 tbuf += (i < geomFromFile.size()) ? L[i] : (geomFromFile.front() - geomFromFile.back()).length();
401 s1.set_boundary(tk::spline::cyclic);
402 s2.set_boundary(tk::spline::cyclic);
406 s1.set_boundary(tk::spline::second_deriv, 0.0, tk::spline::second_deriv, 0.0);
407 s2.set_boundary(tk::spline::second_deriv, 0.0, tk::spline::second_deriv, 0.0);
413 int NumberOfPanelsSpline = (int)ceil(T.back() / hRef);
414 double hSpline = T.back() / NumberOfPanelsSpline;
416 for (
int i = 0; i < NumberOfPanelsSpline; ++i)
417 r_.push_back({ s1(hSpline * i), s2(hSpline * i) });
419 nPanels.push_back(NumberOfPanelsSpline);
427 W.
getInfo(
'e') <<
"No points on airfoil contour!" << std::endl;
432 std::reverse(
r_.begin(),
r_.end());
435 for (
size_t q = 0; q <
r_.size(); ++q)
436 v_.push_back({ 0.0, 0.0 });
440 int defaultNPossibleWays = 0;
441 airfoilParser.get(
"nPossibleWays", nPossibleWays, &defaultNPossibleWays,
false);
444 for (
int q = 0; q < nPossibleWays; ++q)
445 airfoilParser.get(
"possibleWay" + std::to_string(q + 1),
possibleWays[q]);
448 auto xMinMax = std::minmax_element(
r_.begin(),
r_.end(), Point2D::cmp<
'x'>);
449 auto yMinMax = std::minmax_element(
r_.begin(),
r_.end(), Point2D::cmp<
'y'>);
452 {
Point2D({ (*xMinMax.first)[0], (*yMinMax.first)[1] }),
Point2D({ (*xMinMax.second)[0], (*yMinMax.second)[1] }) };
457 double rotationAngle = param.
angle;
469 std::ofstream of(fname);
470 for (
size_t i = 0; i <
r_.size(); ++i)
471 of <<
r_[i][0] <<
" " <<
r_[i][1] << std::endl;
481 for (
size_t q = 0; q <
r_.size(); ++q)
485 area += (cntq[0] * drq[1] - cntq[1] * drq[0]);
497 std::vector<double> selfI0;
498 std::vector<Point2D> selfI3;
500 std::vector<double> currViscousStress;
501 currViscousStress.resize(
r_.size(), 0.0);
504 selfI0.resize(pointsDb.
vtx.size(), 0.0);
505 selfI3.resize(pointsDb.
vtx.size(), { 0.0, 0.0 });
507#pragma warning (push)
508#pragma warning (disable: 4101)
511 double lxi, lxi_m, lenj_m;
521 double iDDomRad, domRad, expon;
524#pragma omp parallel for \
526 shared(domainRadius, pointsDb, selfI0, selfI3, currViscousStress, PI) \
527 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)
528 for (
int i = 0; i < pointsDb.
vtx.size(); ++i)
533 iDDomRad = 1.0 / domRad;
535 for (
size_t j = 0; j <
r_.size(); ++j)
538 q = vtxI.
r() - 0.5 * (
getR(j) +
getR(j + 1));
542 d = fabs(q &
nrm[j]);
544 if ((d < 50.0 *
len[j]) && (fabs(s) < 50.0 *
len[j]))
548 if ((d > 5.0 *
len[j]) || (fabs(s) > 5.0 *
len[j]))
553 expon = exp(-lxi) *
len[j];
558 selfI0[i] += (xi & mn) * (lxi + 1.0) / (lxi * lxi);
564 else if ((d >= 0.1 *
len[j]) || (fabs(s) > 0.5 *
len[j]))
567 double den = (fabs(s) < 0.5 *
len[j]) ? d : (fabs(s) + d - 0.5 *
len[j]);
569 new_n = std::max(1,
static_cast<int>(ceil(5.0 *
len[j] / den)));
571 h = v0 * (1.0 / new_n);
573 for (
int m = 0;
m < new_n; ++
m)
575 xi_m = (vtxI.
r() - (
getR(j) + h * (
m + 0.5))) * iDDomRad;
578 lenj_m =
len[j] / new_n;
579 expon = exp(-lxi_m) * lenj_m;
584 selfI0[i] += (xi_m & mn) * (lxi_m + 1.0) / (lxi_m * lxi_m);
594 selfI0[i] += -
PI * domRad;
595 double mnog = 2.0 * domRad * (1.0 - exp(-
len[j] * iDDomRad / 2.0) * cosh(fabs(s) * iDDomRad));
596 selfI3[i] +=
nrm[j] * mnog;
602 currViscousStress[j] += vs;
613 for (
size_t i = 0; i < I0.size(); ++i)
617 if (I0[i] != -
PI * domRad)
619 if (selfI0[i] == -
PI * domRad)
637void Airfoil::GPUGetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(std::vector<double>& domainRadius, std::vector<double>& I0, std::vector<Point2D>& I3)
639 std::vector<double> newViscousStress;
649 const size_t nr =
r_.size();
651 float*& dev_ptr_i0f =
W.
getWake().devI0fPtr;
652 float*& dev_ptr_i3f =
W.
getWake().devI3fPtr;
659 std::vector<Point2D> newI3(npt);
660 std::vector<double> newI0(npt);
661 std::vector<Point2Df> newI3f(npt);
662 std::vector<float> newI0f(npt);
664 newViscousStress.resize(nTotPan);
666 if ((npt > 0) && (nr > 0))
668 double*& dev_ptr_visstr = devViscousStressesPtr;
670 std::vector<double> locvisstr(nTotPan);
672 std::vector<double> zeroVec(nTotPan, 0.0);
673 cuCopyFixedArray(dev_ptr_visstr, zeroVec.data(), nTotPan *
sizeof(
double), 101);
677 double* dev_ptr_pt =
W.
getWake().devVtxPtr;
678 double* dev_ptr_i0 =
W.
getWake().devI0Ptr;
679 double* dev_ptr_i3 =
W.
getWake().devI3Ptr;
680 double* dev_ptr_rad =
W.
getWake().devRadPtr;
683 W.
getCuda().CopyMemFromDev<double, 2>(npt, dev_ptr_i3, (
double*)newI3.data());
684 W.
getCuda().CopyMemFromDev<double, 1>(npt, dev_ptr_i0, newI0.data());
685 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_visstr, newViscousStress.data());
688 for (
size_t q = 0; q < I3.size(); ++q)
699 auto& treeWake = *
W.
getCuda().inflTreeWake;
703 W.
getCuda().CopyMemFromDev<float, 2>(npt, dev_ptr_i3f, (
float*)newI3f.data());
704 W.
getCuda().CopyMemFromDev<float, 1>(npt, dev_ptr_i0f, newI0f.data());
705 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_visstr, newViscousStress.data());
707 for (
size_t q = 0; q < I3.size(); ++q)
713 size_t curGlobPnl = 0;
718 tmpVisStress.resize(0);
719 tmpVisStress.insert(tmpVisStress.end(), newViscousStress.begin() + curGlobPnl, newViscousStress.begin() + curGlobPnl + np);
734void Airfoil::GPUGetDiffVelocityI0I3ToSetOfPointsAndViscousStresses(std::vector<double>& domainRadius, std::vector<double>& I0, std::vector<Point2D>& I3)
738 std::vector<double> newViscousStress;
753 size_t npt = pointsDb.
vtx.size();
761 double*& dev_ptr_pt = pointsDb.devVtxPtr;
762 double*& dev_ptr_rad = pointsDb.devRadPtr;
763 double*& dev_ptr_meanEps = devMeanEpsOverPanelPtr;
764 const size_t nr =
r_.size();
765 double*& dev_ptr_r = devRPtr;
767 double*& dev_ptr_i0 = pointsDb.devI0Ptr;
768 double*& dev_ptr_i3 = pointsDb.devI3Ptr;
770 float*& dev_ptr_i0f = pointsDb.devI0fPtr;
771 float*& dev_ptr_i3f = pointsDb.devI3fPtr;
779 double tNEIB = -omp_get_wtime();
782 bool isMovable =
false;
786 std::vector<int> nearestPanIdx(npt);
787 int* nearestPanIdx_dev;
788 cudaMalloc(&nearestPanIdx_dev, npt *
sizeof(
int));
789 BHcu::treeClosestPanelToPointsCalculationWrapper(*
W.
getCuda().auxTreePnl, *
W.
getCuda().cntrTreeWake, nearestPanIdx_dev,
false);
790 cudaMemcpy(nearestPanIdx.data(), nearestPanIdx_dev, npt *
sizeof(
int), cudaMemcpyDeviceToHost);
791 cudaFree(nearestPanIdx_dev);
806 std::vector<double> dist2ToNearestPan(npt);
807#pragma omp parallel for
808 for (
int i = 0; i < (int)npt; ++i)
811 double prod = (pointsDb.
vtx[i].r() - pnlCen) &
W.
getAirfoil(0).
tau[nearestPanIdx[i]];
814 dist2ToNearestPan[i] =
sqr((pointsDb.
vtx[i].r() - pnlCen) &
W.
getAirfoil(0).
nrm[nearestPanIdx[i]]);
816 dist2ToNearestPan[i] = (pointsDb.
vtx[i].r() -
W.
getAirfoil(0).
getR(nearestPanIdx[i])).length2();
818 dist2ToNearestPan[i] = (pointsDb.
vtx[i].r() -
W.
getAirfoil(0).
getR(nearestPanIdx[i] + 1)).length2();
820 tNEIB += omp_get_wtime();
824 double tSelectVortex = -omp_get_wtime();
826 if (vorticesToProcess.size() < npt)
828 size_t curSize = vorticesToProcess.size();
832 }
while (curSize < npt);
833 vorticesToProcess.resize(curSize);
838 for (
int q = 0; q < (int)npt; ++q)
845 vorticesToProcess[vtp++] = q;
848 if (batch.size() < vtp * 3 * 5)
850 size_t curSize = batch.size() / (3*5);
854 }
while (curSize < vtp);
856 batch.resize(curSize * 3 * 5);
857 signy.resize(curSize * 5);
858 nnout.resize(curSize * 2 * 5);
859 batchPanels.resize(curSize * 5);
862#pragma omp parallel for
863 for (
int v = 0; v < (int)vtp; ++v)
867 for (
int s = 0; s < 5; ++s)
869 int panIndex = nearestPanIdx[vorticesToProcess[v]] + s - 2;
885 batch[v * 15 + 3 * s + 0] = fabsf((
float)relPos[0]);
886 batch[v * 15 + 3 * s + 1] = fabsf((
float)relPos[1]);
887 signy[v * 5 + s] = (relPos[1] > 0) ? 1 : -1;
890 batch[v * 15 + 3 * s + 2] = (float)(domrad /
W.
getAirfoil(0).
len[panIndex]);
892 batchPanels[v * 5 + s] = panIndex;
895 tSelectVortex += omp_get_wtime();
898 double tNN2 = -omp_get_wtime();
899 NN.setup_layers(vtp * 5);
900 tNN2 += omp_get_wtime();
902 double tNN3 = -omp_get_wtime();
903 NN.start((
int)(vtp * 5), batch.data(), nnout.data(), signy.data());
904 tNN3 += omp_get_wtime();
906 double tNN4 = -omp_get_wtime();
908 tNN4 += omp_get_wtime();
919 std::vector<double> nnI0(npt, 0.0);
920 std::vector<Point2D> nnI3(npt, {0.0, 0.0});
922 newViscousStress.resize(nTotPan);
924#pragma omp parallel for
925 for (
int v = 0; v < vtp; ++v)
929 for (
int s = 0; s < 5; ++s)
931 float absx = batch[v * 15 + 3 * s + 0];
932 float absy = batch[v * 15 + 3 * s + 1];
933 if ((absx < 0.5f) && (absy < 1e-3))
935 nnI0[vorticesToProcess[v]] += -
PI * domrad * domrad;
937 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]];
941 nnI0[vorticesToProcess[v]] += (-nnout[v * 10 + s * 2 + 1] *
sqr(
W.
getAirfoil(0).
len[batchPanels[v * 5 + s]]));
942 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]];
945 int curPnl = batchPanels[v * 5 + s];
952 nnI0[vorticesToProcess[v]] /= domrad;
964 if ((npt > 0) && (nr > 0))
966 double*& dev_ptr_visstr = devViscousStressesPtr;
967 std::vector<double> locvisstr(nTotPan);
968 cuCopyFixedArray(dev_ptr_visstr, newViscousStress.data(), nTotPan *
sizeof(
double), 101);
1011 for (
size_t q = 0; q < I3.size(); ++q)
1028 size_t curGlobPnl = 0;
1033 tmpVisStress.resize(0);
1034 tmpVisStress.insert(tmpVisStress.end(), newViscousStress.begin() + curGlobPnl, newViscousStress.begin() + curGlobPnl + np);
1054 double sumAngle = 0.0;
1058 for (
size_t i = 0; i <
r_.size(); ++i)
1060 v1 =
getR(i) - point;
1061 v2 =
getR(i + 1) - point;
1062 sumAngle += atan2(v1 ^ v2, v1 & v2);
1065 if (fabs(sumAngle) < 0.1)
1077 for (
size_t i = 0; i <
r_.size(); ++i)
1094 if (
nrm.size() !=
r_.size())
1096 nrm.resize(
r_.size());
1097 psn.resize(
r_.size());
1098 tau.resize(
r_.size());
1099 len.resize(
r_.size());
1105#pragma omp parallel for private(rpan)
1106 for (
int i = 0; i < (int)
r_.size(); ++i)
1115#pragma omp parallel for
1116 for (
int i = 0; i < (int)
r_.size(); ++i)
1118 int next = (i == (int)
r_.size() - 1 ? 0 : i + 1);
1119 int prev = (i == 0 ? (int)
r_.size() - 1 : i - 1);
1121 psn[i] = std::make_pair( (
nrm[prev] +
nrm[i]).unit(), (
nrm[i] +
nrm[next]).unit() );
1133 for (
size_t i = 0; i <
r_.size(); ++i)
1151 for (
size_t i = 0; i <
r_.size(); ++i)
1158 pts =
rcm + (rotMatrix & (oldPts -
rcm));
1169 for (
size_t i = 0; i <
r_.size(); ++i)
1176 pts =
rcm +
Point2D{ factor[0] * (oldPts -
rcm)[0], factor[1] * (oldPts -
rcm)[1] };
1186 std::vector<double> res(p * p, 0.0);
1188 if ((i == j) && (&airfoil ==
this))
1190 res[0] = 0.5 * (
tau[i] ^
nrm[i]);
1194 res[3] = (1.0 / 12.0) * res[0];
1205 res[0] = miq.first(i, j);
1227 bool self = (&otherAirfoil ==
this);
1238 Point2D p1, s1, p2, s2, di, dj, i00, i01, i10, i11;
1242#pragma omp parallel for \
1244 shared(otherAirfoil, self, aflNSelf, aflNOther, matrPair, p, IDPI, IQPI) \
1245 private(npI, npJ, alpha, lambda, p1, s1, p2, s2, di, dj, i00, i01, i10, i11, v00, v11, v01, v10) schedule(dynamic, DYN_SCHEDULE)
1252 if ((i == j) && self)
1255 matrPair.first(i, j) = 0.0;
1256 matrPair.second(i, j) = 0.0;
1260 matrPair.first(i, npJ + j) = 0.0;
1261 matrPair.first(npI + i, j) = 0.0;
1263 matrPair.second(i, npJ + j) = -
IQPI;
1264 matrPair.second(npI + i, j) =
IQPI;
1266 matrPair.first(npI + i, npJ + j) = 0.0;
1267 matrPair.second(npI + i, npJ + j) = 0.0;
1278 p1 =
getR(i + 1) - otherAirfoil.
getR(j + 1);
1279 s1 =
getR(i + 1) - otherAirfoil.
getR(j);
1280 p2 =
getR(i) - otherAirfoil.
getR(j + 1);
1281 s2 =
getR(i) - otherAirfoil.
getR(j);
1283 dj = otherAirfoil.
getR(j + 1) - otherAirfoil.
getR(j);
1287 VMlib::Alpha(s2, p1), \
1293 VMlib::Lambda(s2, p1), \
1303 i00 =
IDPI /
len[i] * (-(alpha[0] * v00[0] + alpha[1] * v00[1] + alpha[2] * v00[2]).kcross() \
1304 + (lambda[0] * v00[0] + lambda[1] * v00[1] + lambda[2] * v00[2]));
1306 matrPair.first(i, j) = i00 &
nrm[i];
1307 matrPair.second(i, j) = i00 & taui;
1317 i01 =
IDPI /
len[i] * (-((alpha[0] + alpha[2]) * v01[0] + (alpha[1] + alpha[2]) * v01[1]).kcross() \
1318 + ((lambda[0] + lambda[2]) * v01[0] + (lambda[1] + lambda[2]) * v01[1]) - 0.5 * di.
length() * tauj);
1320 matrPair.first(i, npJ + j) = i01 &
nrm[i];
1321 matrPair.second(i, npJ + j) = i01 & taui;
1329 i10 =
IDPI /
len[i] * (-((alpha[0] + alpha[2]) * v10[0] + alpha[2] * v10[1]).kcross() \
1330 + ((lambda[0] + lambda[2]) * v10[0] + lambda[2] * v10[1]) + 0.5 * dj.
length() * taui);
1332 matrPair.first(npI + i, j) = i10 &
nrm[i];
1333 matrPair.second(npI + i, j) = i10 & taui;
1342 i11 =
IDPI /
len[i] * (-((alpha[0] + alpha[2]) * v11[0] + (alpha[1] + alpha[2]) * v11[1] + alpha[2] * v11[2]).kcross()\
1343 + (lambda[0] + lambda[2]) * v11[0] + (lambda[1] + lambda[2]) * v11[1] + lambda[2] * v11[2] \
1346 matrPair.first(npI + i, npJ + j) = i11 &
nrm[i];
1347 matrPair.second(npI + i, npJ + j) = i11 & taui;
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса Boundary.
Заголовочный файл с функциями для метода GMRES.
Заголовочный файл с описанием класса 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.
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-нормы (длины) вектора
double Lambda(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления логарифма отношения норм векторов
T sqr(T x)
Возведение числа в квадрат
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
Шаг вычисления и сохранения скорости и давления