65#include "treeKernels.cuh"
77 passport(dynamic_cast<const
Passport&>(passport_)),
87 std::vector<std::string> timerLabels = {
"Step",
"MatRhs",
"Solve",
"ConvVel",
"DiffVel",
"Force",
"VelPres",
"Inside",
"Restr",
"Save"};
88 timers = std::make_unique<VMlib::TimersGen>(*
this, timerLabels);
114 auto CreateBoundary = [
this](
size_t i) {
132 info(
'e') <<
"Unknown scheme!" << std::endl;
180 if (
getPassport().wakeDiscretizationProperties.eps == 0)
182 double sumLength = 0.0;
183 size_t totNumPan = 0;
190 double eps = 0.5 * sumLength / totNumPan;
196 if (
getPassport().wakeDiscretizationProperties.epscol == 0)
207 prm.chord = (prm.initialGab.second[0] - prm.initialGab.first[0]) * prm.scale[0];
208 info(
'i') <<
"airfoil #" << afl <<
" chord = " << prm.chord <<
" is calculated automatically" << std::endl;
276 size_t countStrongCoupling = 0;
277 for (
size_t m = 0; m <
mechanics.size(); ++m)
283 ++countStrongCoupling;
287 bool semiImplicitStrategy = ((countStrongCoupling ==
mechanics.size()) && (
mechanics.size() > 0));
289 info(
'i') <<
"Strong (semi-implicit) coupling strategy" << std::endl;
297 if (!semiImplicitStrategy)
303 if (
getPassport().numericalSchemes.velocityComputation.second == 0 &&
getPassport().numericalSchemes.linearSystemSolver.second == 2)
310 auto& treePnlVrt = *
getCuda().inflTreePnlVortex;
312 treePnlVrt.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
317 treePnlVrt.UpdatePanelGeometry(nTotPan, (double4*)afl.devRPtr);
321 treePnlVrt.UpdatePanelAttachedVortexIntensity(afl.devAttachedVortexSheetPtr, afl.devAttachedVortexSheetLinPtr);
327 if (
getPassport().numericalSchemes.velocityComputation.second == 1)
334 auto& treeWake = *
getCuda().inflTreeWake;
335 treeWake.MemoryAllocate((
int)
getCuda().n_CUDA_wake);
338 treeWake.UpwardTraversal(
getPassport().numericalSchemes.nbodyMultipoleOrder);
343 auto& treePnl = *
getCuda().cntrTreePnl;
344 auto& treePnlVrt = *
getCuda().inflTreePnlVortex;
345 auto& treePnlSrc = *
getCuda().inflTreePnlSource;
346 auto& treePnlAux = *
getCuda().auxTreePnl;
350 treePnl.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
351 treePnlAux.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
352 treePnlVrt.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
354 treePnlSrc.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
360 treePnlVrt.UpdatePanelGeometry(nTotPan, (double4*)afl.devRPtr);
364 treePnl.UpdatePanelGeometry((
int)nTotPan, (double4*)afl.devRPtr);
370 treePnlSrc.UpdatePanelGeometry(nTotPan, (double4*)afl.devRPtr);
371 treePnlSrc.UpdatePanelAttachedSourceIntensity(afl.devAttachedSourceSheetPtr, afl.devAttachedSourceSheetLinPtr);
377 treePnlVrt.UpdatePanelAttachedVortexIntensity(afl.devAttachedVortexSheetPtr, afl.devAttachedVortexSheetLinPtr);
388 if (
getPassport().physicalProperties.typeAccel.second == 3)
405 info(
'i') <<
"Added Masses for airfoil #" << bou <<
" = { " << lambdaAdd[bou][0] <<
", " << lambdaAdd[bou][1] <<
", " << muAdd[bou] <<
" }" << std::endl;
408 switch ((
int)(
getPassport().physicalProperties.timeAccel))
421 info(
'e') <<
"Wrong dirfection is specified!" << std::endl;
426 std::ofstream addMassFile;
429 addMassFile.open(addMassFileName);
430 addMassFile <<
"Added Masses for airfoil:" << std::endl;
433 addMassFile.open(addMassFileName, std::ios_base::app);
435 addMassFile << direction <<
"-direction: " << lambdaAdd[bou][0] <<
" " << lambdaAdd[bou][1] <<
" " << muAdd[bou] << std::endl;
446 if (nTotPan > 0 &&
getPassport().numericalSchemes.velocityComputation.second == 1)
450 getCuda().inflTreePnlVortex->UpdatePanelFreeAndAttachedVortexIntensity(afl.devFreeVortexSheetPtr, afl.devFreeVortexSheetLinPtr, afl.devAttachedVortexSheetPtr, afl.devAttachedVortexSheetLinPtr);
474 if (
measureVP->getTotalNumberOfRealPoints() > 0)
477 if (ptr && !ptr->
beam->fsi)
483 std::ofstream presForcesFile;
487 presForcesFile <<
"time,Fx,Fy,Py" << std::endl;
490 presForcesFile.open(
getPassport().
dir +
"presForcesFile.csv", std::ios_base::app);
492 auto r =
measureVP->GetVPinElasticPoints();
493 Point2D presForce = { 0.0, 0.0 };
496 for (
int q = 0; q < r.size(); ++q)
502 presForcesFile <<
currentTime <<
"," << scaleP * presForce[0] <<
"," << scaleP * presForce[1] <<
"," << scaleP * yPower << std::endl;
503 presForcesFile.close();
510 if (ptr && ptr->
beam->fsi)
512 auto r =
measureVP->GetVPinElasticPoints();
530 std::vector<double> currentPres(ptr->
chord.size());
531 for (
size_t j = 0; j < ptr->
chord.size(); ++j)
534 currentPres[j] = -(r[2 * j + 0].second - r[2 * j + 1].second);
537 if (ptr->
beam->presLastSteps.size() < ptr->
beam->nLastSteps)
538 ptr->
beam->presLastSteps.push_back(currentPres);
541 for (
int w = 1; w < ptr->
beam->nLastSteps; ++w)
542 ptr->
beam->presLastSteps[w - 1] = std::move(ptr->
beam->presLastSteps[w]);
543 ptr->
beam->presLastSteps.back() = currentPres;
546 for (
int q = 0; q < ptr->
beam->R; ++q)
548 ptr->
beam->qCoeff[q] = 0;
550 if (ptr->
beam->presLastSteps.size() == ptr->
beam->nLastSteps)
552 for (
size_t j = 0; j < ptr->
chord.size(); ++j)
554 double averpres = 0.0;
557 for (
int i = 0; i < ptr->
beam->nLastSteps; ++i)
558 averpres += ptr->
beam->presLastSteps[i][j];
559 averpres /= ptr->
beam->nLastSteps;
563 ptr->
beam->qCoeff[q] /= (ptr->
beam->intSqUnitShape * ptr->
beam->L);
569 std::ofstream phiFile;
574 for (
int p = 0; p < ptr->
beam->R; ++p)
575 phiFile <<
",phi-" << std::to_string(p + 1);
576 phiFile << std::endl;
579 phiFile.open(
getPassport().
dir +
"phiFile.csv", std::ios_base::app);
582 for (
int p = 0; p < ptr->
beam->R; ++p)
583 phiFile <<
"," << ptr->
beam->phi(p, 0);
584 phiFile << std::endl;
595 mech->GetHydroDynamForce();
596 mech->GenerateForcesString();
597 mech->GeneratePositionString();
618 if (semiImplicitStrategy)
648 for (
size_t m = 0; m <
mechanics.size(); ++m)
657 getInfo(
'e') <<
"Added mass of the airfoil should be non-zero!" << std::endl;
694 << std::setprecision(3) \
696 << std::setprecision(6) \
713void World2D::CheckInside(std::vector<Point2D>& newPos,
const std::vector<std::unique_ptr<AirfoilGeometry>>& oldAirfoil)
722#if (!defined(USE_CUDA))
724 for (
size_t afl = 0; afl <
airfoil.size(); ++afl)
736 for (
size_t afl = 0; afl <
airfoil.size(); ++afl)
737 nTotPanels += (
int)
airfoil[afl]->getNumberOfPanels();
745 auxTree.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
746 auxTree.UpdatePanelGeometry(nTotPanels, (double4*)
airfoil[0]->devRPtr);
748 auxTree.UpwardTraversal(0);
751 std::vector<int> hit(newPos.size());
755 double* devNewpos_ptr;
756 cudaMalloc(&devNewpos_ptr, newPos.size() *
sizeof(
double) * 2);
757 cudaMemcpy(devNewpos_ptr, newPos.data(), newPos.size() *
sizeof(
double) * 2, cudaMemcpyHostToDevice);
759 auto& cntrTreePnt = *
getCuda().cntrTreePoint;
760 cntrTreePnt.MemoryAllocate((
int)
getCuda().n_CUDA_wake);
761 cntrTreePnt.Update((
int)newPos.size(), devNewpos_ptr, 0.0);
764 BHcu::treeClosestPanelToPointsCalculationWrapper(auxTree, cntrTreePnt,
getWake().devNearestPanelPtr,
true,
getAirfoil(0).devPsnPtr);
766 cudaMemcpy(hit.data(),
getWake().devNearestPanelPtr, newPos.size() *
sizeof(
int), cudaMemcpyDeviceToHost);
767 cudaFree(devNewpos_ptr);
771 std::vector<std::pair<Point2D, Point2D>> segments(newPos.size());
772 for (
size_t i = 0; i < newPos.size(); ++i)
774 segments[i].first =
wake->vtx[i].r();
775 segments[i].second = newPos[i];
777 double* devSegments_ptr;
779 cudaMalloc(&devSegments_ptr, newPos.size() *
sizeof(
double) * 4);
780 cudaMemcpy(devSegments_ptr, segments.data(), newPos.size() *
sizeof(
double) * 4, cudaMemcpyHostToDevice);
782 auto& cntrTreeSeg = *
getCuda().cntrTreeSegment;
783 cntrTreeSeg.MemoryAllocate((
int)
getCuda().n_CUDA_wake);
784 cntrTreeSeg.UpdatePanelGeometry((
int)newPos.size(), (double4*)devSegments_ptr);
787 BHcu::treePanelsSegmentsIntersectionCalculationWrapper(auxTree, cntrTreeSeg,
getWake().devNearestPanelPtr);
788 cudaMemcpy(hit.data(),
getWake().devNearestPanelPtr, newPos.size() *
sizeof(
int), cudaMemcpyDeviceToHost);
789 cudaFree(devSegments_ptr);
792 size_t panCounter = 0;
793 for (
size_t afl = 0; afl <
airfoil.size(); ++afl)
795 std::vector<double> gamma(
airfoil[afl]->getNumberOfPanels(), 0.0);
796 for (
int i = 0; i < newPos.size(); ++i)
800 if ((hit[i] >= panCounter) && (hit[i] < panCounter +
airfoil[afl]->getNumberOfPanels()))
802 if (fabs(
wake->vtx[i].g()) > 1.0)
803 std::cout <<
"Too large gamma is through: i = " << i <<
", " << hit[i] <<
", " <<
"gamma[hit[i] - panCounter] += " <<
wake->vtx[i].g() << std::endl;
805 gamma[hit[i] - panCounter] +=
wake->vtx[i].g();
806 wake->vtx[i].g() = 0.0;
810 airfoil[afl]->gammaThrough = gamma;
811 panCounter +=
airfoil[afl]->getNumberOfPanels();
887 if (linSystemScheme == 0)
889 double t1 = -omp_get_wtime();
892 info(
't') <<
"Inverting matrix... ";
894#if (defined(USE_CUDA))
896 for (
int i = 0; i < (int)
matrReord.rows(); ++i)
897 for (
int j = 0; j < (int)
matrReord.cols(); ++j)
898 invMatr(i, j) = (i == j) ? 1.0 : 0.0;
903 info(
't') <<
"done" << std::endl;
907 info(
't') <<
"Solving system at step #0... ";
936 info(
't') <<
"done" << std::endl;
938 t1 += omp_get_wtime();
1007 if ((linSystemScheme == 1 || linSystemScheme == 2))
1011 nFullVars += (
int)(
boundary[i]->GetUnknownsSize());
1015 Ggam[i].resize(
boundary[i]->GetUnknownsSize());
1020 std::vector<double> Grhs(
rhsReord.size());
1021 for (
int i = 0; i <
rhsReord.size(); ++i)
1026 Gpos[i] = Gpos[i - 1] + (
int)(
boundary[i - 1]->GetUnknownsSize());
1030 Gvsize[i] = (
int)(
boundary[i]->GetUnknownsSize());
1035 std::vector<double> Gmatr(nFullVars * nFullVars);
1036 for (
size_t i = 0; i < nFullVars; ++i)
1037 for (
size_t j = 0; j < nFullVars; ++j)
1038 Gmatr[i * nFullVars + j] =
matrReord(i, j);
1041 for (
int j = 0; j <
boundary[i]->GetUnknownsSize(); ++j)
1042 auto y_test =
airfoil[i]->len[j %
airfoil[i]->getNumberOfPanels()];
1046 sol.resize(nFullVars);
1049 for (
int j = 0; j <
boundary[i]->GetUnknownsSize(); ++j)
1050 sol(cntr++) = Ggam[i][j] ;
1052 sol(cntr++) = GR[i];
1063 getInfo(
'e') <<
"Direct GMRES for CUDA is not implemented" << std::endl;
1073 GGrhs[i].resize(
boundary[i]->GetUnknownsSize());
1075 for (
int j = 0; j <
boundary[i]->GetUnknownsSize(); ++j)
1086 double time_GMRES = -omp_get_wtime();
1087 GMRES(*
this, Ggam, GR, GGrhs, GrhsReg, niter,
linScheme);
1088 time_GMRES += omp_get_wtime();
1089 std::cout <<
"Time_GMRES = " << time_GMRES << std::endl;
1091 sol.resize(nFullVars);
1094 for (
int j = 0; j <
boundary[i]->GetUnknownsSize(); ++j)
1095 sol(cntr++) = Ggam[i][j] /
airfoil[i]->len[j %
airfoil[i]->getNumberOfPanels()];
1097 sol(cntr++) = GR[i];
1121 if (linSystemScheme == 0 || linSystemScheme == 1)
1126 Eigen::MatrixXd locMatr;
1127 Eigen::MatrixXd otherMatr;
1128 Eigen::VectorXd locLastLine, locLastCol;
1130 std::vector<std::vector<Point2D>> locIQ;
1131 std::vector<std::vector<Point2D>> locOtherIQ;
1136 for (
int i = 0; i <
matrReord.rows(); ++i)
1137 for (
int j = 0; j <
matrReord.cols(); ++j)
1141 size_t currentRow = 0;
1142 size_t currentSkosRow = 0;
1144 size_t nAllVars = 0;
1145 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1146 nAllVars +=
boundary[bou]->GetUnknownsSize();
1148 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1150 size_t nVars =
boundary[bou]->GetUnknownsSize();
1153 locMatr.resize(nVars, nVars);
1154 locLastLine.resize(nVars);
1155 locLastCol.resize(nVars);
1159 boundary[bou]->FillMatrixSelf(locMatr, locLastLine, locLastCol);
1163 for (
size_t i = 0; i < nVars; ++i)
1167 for (
size_t j = 0; j < nVars; ++j)
1168 matrReord(i + currentSkosRow, j + currentSkosRow) = locMatr(i, j);
1170 matrReord(nAllVars + bou, i + currentSkosRow) = locLastLine(i);
1171 matrReord(i + currentSkosRow, nAllVars + bou) = locLastCol(i);
1177 size_t currentCol = 0;
1178 size_t currentSkosCol = 0;
1179 for (
size_t oth = 0; oth <
boundary.size(); ++oth)
1181 size_t nVarsOther =
boundary[oth]->GetUnknownsSize();
1185 otherMatr.resize(nVars, nVarsOther);
1190 for (
size_t i = 0; i < nVars; ++i)
1192 for (
size_t j = 0; j < nVarsOther; ++j)
1193 matrReord(i + currentSkosRow, j + currentSkosCol) = otherMatr(i, j);
1196 currentCol += nVarsOther + 1;
1197 currentSkosCol += nVarsOther;
1201 currentRow += nVars + 1;
1202 currentSkosRow += nVars;
1222 for (
size_t i = 1; i <
boundary.size(); ++i)
1228 size_t matrSkosSize = 0;
1232 matrSize += (*it)->GetUnknownsSize();
1233 matrSkosSize += (*it)->GetUnknownsSize();
1249 size_t nVari =
boundary[i]->GetUnknownsSize();
1252 size_t nVarj =
boundary[j]->GetUnknownsSize();
1253 IQ[i][j].first.resize(nVari, nVarj);
1254 IQ[i][j].second.resize(nVari, nVarj);
1281#if defined(__CUDACC__) || defined(USE_CUDA)
1282 cuda.RefreshWake(2);
1284 cuda.RefreshAfls(2);
1285 cuda.RefreshVirtualWakes(2);
1298#if defined(__CUDACC__) || defined(USE_CUDA)
1299 for (
size_t i = 0; i <
airfoil.size(); ++i)
1300 cuda.CopyMemToDev<
double, 1>(
airfoil[i]->getNumberOfPanels(),
airfoil[i]->meanEpsOverPanel.data(),
airfoil[i]->devMeanEpsOverPanelPtr);
1311 if (afl->viscousStress.size() == 0)
1312 afl->viscousStress.resize(afl->getNumberOfPanels(), 0.0);
1388 for (
size_t i = 0; i <
airfoil.size(); ++i)
1392 for (
size_t i = 0; i <
airfoil.size(); ++i)
1393 boundary[i]->ComputeAttachedSheetsIntensity();
1405 size_t nvt =
wake->vtx.size();
1406 size_t nVirtVortex = 0;
1408 nVirtVortex +=
boundary[i]->virtualWake.vtx.size();
1423#pragma omp parallel for
1424 for (
int i = 0; i < (int)
wake->vtx.size(); ++i)
1426 newPos[i] =
wake->vtx[i].r()
1427 + (
velocity->wakeVortexesParams.convVelo[i] +
1428 velocity->wakeVortexesParams.diffVelo[i] +
1443 size_t counter =
wake->vtx.size() - nVirtVortex;
1444 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1446 for (
int i = 0; i < (int)
boundary[bou]->virtualWake.vtx.size(); ++i)
1448 wake->vtx[counter].g() =
boundary[bou]->virtualWake.vtx[i].g();
1459 mechanics[mechanicsNumber]->GenerateForcesHeader();
1460 mechanics[mechanicsNumber]->GeneratePositionHeader();
1468 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1475 for (
size_t oth = 0; oth <
boundary.size(); ++oth)
1512#if defined(__CUDACC__) || defined(USE_CUDA)
1518 if ((sch == 1) || (sch == 2) || (sch == 0))
1522 info(
'e') <<
"schemeSwitcher is not 0, or 1, or 2! " << std::endl;
1526 cuda.RefreshWake(1);
1527 cuda.RefreshAfls(1);
1528 cuda.RefreshVirtualWakes(1);
1533 if (linSystemScheme == 0)
1600 size_t currentRow = 0;
1601 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1603 size_t nVars =
boundary[bou]->GetUnknownsSize();
1604 Eigen::VectorXd locSol;
1605 locSol.resize(nVars);
1606 for (
size_t i = 0; i < nVars; ++i)
1607 locSol(i) =
sol(currentRow + i);
1609 boundary[bou]->SolutionToFreeVortexSheetAndVirtualVortex(locSol);
1610 currentRow += nVars;
1614 size_t nVirtVortices = 0;
1615 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1616 nVirtVortices +=
boundary[bou]->virtualWake.vtx.size();
1618 wake->vtx.reserve(
wake->vtx.size() + nVirtVortices);
1619 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
1620 for (
size_t v = 0; v <
boundary[bou]->virtualWake.vtx.size(); ++v)
1621 wake->vtx.push_back(
Vortex2D{ boundary[bou]->virtualWake.vtx[v].r(), 0.0 });
1655 std::vector<Point2D> newPos;
1683 if (afl->numberInPassport == 0)
1685 mechanics[afl->numberInPassport]->Move();
1690 if (mechTest !=
nullptr)
1711 airfoil[afl->numberInPassport]->Move(dr);
1712 airfoil[afl->numberInPassport]->Rotate(dphi);
1726 mechanics[afl->numberInPassport]->Move();
1738#if defined(__CUDACC__) || defined(USE_CUDA)
1739 cuda.RefreshAfls(2);
1743 bou->virtualWake.vtx.clear();
1750 for (
size_t i = 0; i <
wake->vtx.size(); ++i)
1751 wake->vtx[i].r() = newPos[i];
1761 [](
const std::unique_ptr<Mechanics>& m) {
return (m->isMoves); });
1768 [](
const std::unique_ptr<Mechanics>& m) {
return (m->isMoves || m->isDeform); });
Заголовочный файл с описанием класса AirfoilRect.
Заголовочный файл с описанием класса BoundaryConstLayerAver.
Заголовочный файл с описанием класса BoundaryLinLayerAver.
Заголовочный файл с описанием класса BoundaryVortexCollocN.
Заголовочный файл с функциями для метода GMRES.
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса MechanicsRigidGivenLaw.
Заголовочный файл с описанием класса MechanicsRigidImmovable.
Заголовочный файл с описанием класса MechanicsRigidOscillPart.
Заголовочный файл с описанием класса MechanicsRigidRotatePart.
Заголовочный файл с описанием класса StreamParser.
Заголовочный файл с описанием класса VelocityBarnesHut.
Заголовочный файл с описанием класса VelocityBiotSavart.
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса World2D.
Класс, определяющий форму профиля
std::vector< double > len
Длины панелей профиля
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
std::vector< Point2D > nrm
Нормали к панелям профиля
Point2D rcm
Положение центра масс профиля
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
void calcMeanEpsOverPanel()
Вычисление средних значений eps на панелях
Класс, определяющий тип обтекаемого профиля
Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле
Sheet sheets
Слои на профиле
Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле
Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле
Класс, обеспечивающий возможность выполнения вычислений на GPU по технологии Nvidia CUDA.
void setAccelCoeff(double cft_)
Установка коэффициента разгона потока
void setMaxGamma(double gam_)
Установка максимально допустимой циркуляции вихря
void setSchemeSwitcher(int schemeSwitcher_)
Установка переключателя расчетных схем
Класс, отвечающий за вычисление поля скорости и давления в заданых точках для вывода
Абстрактный класс, определяющий вид механической системы
Point2D hydroDynamForce
Вектор гидродинамической силы и момент, действующие на профиль
void GeneratePositionString()
Сохранение строки со статистикой в файл нагрузок
void GenerateForcesString()
Сохранение строки со статистикой в файл нагрузок
Класс, определяющий вид механической системы
Класс, определяющий вид механической системы
Класс, определяющий вид механической системы
Point2D & getR()
текущее отклонение профиля
double & getPhi()
текущий угол поворота профиля
Point2D & getV()
текущая скорость профиля
bool & getStrongCoupling()
double & getW()
текущая угловая скорость профиля
Класс, определяющий вид механической системы
std::string wakesDir
Каталог с файлами вихревых следов
PhysicalProperties physicalProperties
Структура с физическими свойствами задачи
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
std::string airfoilsDir
Каталог с файлами профилей
std::vector< AirfoilParams > airfoilParams
Список структур с параметрами профилей
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
const double & attachedVortexSheet(size_t n, size_t moment) const
const double & freeVortexSheet(size_t n, size_t moment) const
Класс, определяющий способ вычисления скоростей
Класс, определяющий способ вычисления скоростей
Класс, опеделяющий набор вихрей
Класс, опеделяющий вихревой след (пелену)
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Gpu cuda
Объект, управляющий графическим ускорителем
void ReserveMemoryForMatrixAndRhs()
Вычисляем размер матрицы и резервируем память под нее и под правую часть
bool isAnyMovable() const
Возврат признака того, что хотя бы один из профилей подвижный
void MoveVortexes(std::vector< Point2D > &newPos)
Вычисляем новые положения вихрей (в пелене и виртуальных)
std::vector< std::unique_ptr< Airfoil > > airfoil
Список умных указателей на обтекаемые профили
VMlib::vmTimer timerInitialBuild
bool isAnyMovableOrDeformable() const
Возврат признака того, что хотя бы один из профилей подвижный или деформируемый
std::unique_ptr< MeasureVP > measureVP
Умный указатель на алгоритм вычисления полей скоростей и давления (для сохранения в файл)
Eigen::MatrixXd matrReord
Матрица системы
bool useInverseMatrix
Признак использования обратной матрицы
const Wake & getWake() const
Возврат константной ссылки на вихревой след
Eigen::MatrixXd invMatr
Обратная матрица
void CalcPanelsVeloAndAttachedSheets()
Вычисление скоростей панелей и интенсивностей присоединенных слоев вихрей и источников
void CalcVortexVelo()
Вычисление скоростей (и конвективных, и диффузионных) вихрей (в пелене и виртуальных),...
std::vector< std::unique_ptr< AirfoilGeometry > > oldAirfoil
Список умных указателей на обтекаемые профили для сохранения старого положения
World2D(const VMlib::PassportGen &passport_)
Конструктор
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
const std::vector< std::unique_ptr< Mechanics > > & getMechanicsVector() const
VMlib::vmTimer timerInside
Gpu & getNonConstCuda() const
Возврат неконстантной ссылки на объект, связанный с видеокартой (GPU)
std::unique_ptr< WakeDataBase > source
Умный указатель на источники
void CalcAndSolveLinearSystem()
Набор матрицы, правой части и решение СЛАУ
Eigen::VectorXd rhsReord
Правая часть системы
std::vector< size_t > dispBoundaryInSystem
Список номеров, с которых начинаются элементы правой части (или матрицы) системы для профилей
VMlib::TimersGen & getTimers() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
void FillIQ()
Заполнение матрицы, состоящей из интегралов от (r-xi) / |r-xi|^2.
Point2D getV0() const
Возврат текущей скорости набегающего потока
void WakeAndAirfoilsMotion(bool dynamics)
Перемещение вихрей и профилей на шаге
std::vector< std::unique_ptr< Mechanics > > mechanics
Список умных указателей на типы механической системы для каждого профиля
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
std::vector< std::unique_ptr< Boundary > > boundary
Список умных указателей на формирователи граничных условий на профилях
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Passport & getNonConstPassport() const
Возврат неконстантной ссылки на паспорт
void GenerateMechanicsHeader(size_t mechanicsNumber)
void CheckInside(std::vector< Point2D > &newPos, const std::vector< std::unique_ptr< AirfoilGeometry > > &oldAirfoil)
Проверка проникновения вихрей внутрь профиля
void SolveLinearSystem()
Решение системы линейных алгебраических уравнений
std::unique_ptr< Wake > wake
Умный указатель на вихревой след
const Boundary & getBoundary(size_t i) const
Возврат константной ссылки на объект граничного условия
bool ifDivisible(int val) const
size_t getNumberOfBoundary() const
Возврат количества граничных условий в задаче
std::unique_ptr< Velocity > velocity
Умный укзатель на объект, определяющий методику вычисления скоростей
const Passport & passport
Константная ссылка на паспорт конкретного расчета
void FillMatrixAndRhs()
Заполнение матрицы системы для всех профилей
virtual void Step() override
Функция выполнения предварительного шага
VMlib::vmTimer timerFillMatrix
Eigen::VectorXd sol
Решение системы
Mechanics & getNonConstMechanics(size_t i) const
Возврат неконстантной ссылки на объект механики
std::vector< std::vector< std::pair< Eigen::MatrixXd, Eigen::MatrixXd > > > IQ
Матрица, состоящая из пар матриц, в которых хранятся касательные и нормальные компоненты интегралов о...
Airfoil & getNonConstAirfoil(size_t i) const
Возврат неконстантной ссылки на объект профиля
VMlib::vmTimer timerSlaeSolve
void endl()
Вывод в поток логов пустой строки
void assignStream(std::ostream *pStr_, const std::string &label_)
Связывание потока логов с потоком вывода
Абстрактный класс, опеделяющий паспорт задачи
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
std::string problemName
Название задачи
std::string dir
Рабочий каталог задачи
size_t problemNumber
Номер задачи
void GenerateStatString(size_t stepNo, double curTime, size_t N)
Формирование очередной строки файла временной статистики
void stop(const std::string &timerLabel)
Останов счетчика
void start(const std::string &timerLabel)
Запуск счетчика
void resetAll()
Сброс всех счетчиков
double durationStep() const
Вывод счетчика всего шага в секундах
Класс, опеделяющий двумерный вихревой элемент
std::unique_ptr< TimersGen > timers
Сведения о временах выполнения основных операций
double currentTime
Текущее время в решаемой задаче
VMlib::LogStream & getInfo() const
Возврат ссылки на объект LogStream Используется в техничеcких целях для организации вывода
double getCurrentTime() const
size_t currentStep
Текущий номер шага в решаемой задаче
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
LogStream info
Поток для вывода логов и сообщений об ошибках
numvector< T, 2 > kcross() const
Геометрический поворот двумерного вектора на 90 градусов
const vmTimer & stop() const
Останов работающего счетчика времени
const vmTimer & start() const
Запуск (первый или повторный) счетчика времени
const vmTimer & reset() const
Сброс счетчика времени
void GMRES_Direct(const World2D &W, int nAllVars, int nafl, const std::vector< double > &mtrDir, const std::vector< double > &rhsDir, const std::vector< int > &pos, const std::vector< int > &vsize, std::vector< std::vector< double > > &gam, std::vector< double > &R)
void PrintLogoToStream(std::ostream &str)
Передача в поток вывода шапки программы VM2D/VM3D.
bool fileExistTest(std::string &fileName, LogStream &info, bool exitKey=false, const std::list< std::string > &extList={})
Проверка существования файла
static std::ostream * defaultWorld2DLogStream
Поток вывода логов и ошибок задачи
std::pair< std::string, int > boundaryCondition
Метод аппроксимации граничных условий
std::pair< std::string, int > velocityComputation
std::pair< std::string, int > linearSystemSolver
double accelCft(double currentTime) const
Функция-множитель, позволяющая моделировать разгон
double vRef
Референсная скорость
double rho
Плотность потока
std::string fileSource
Имя файла с положениями источников (без полного пути)
double epscol
Радиус коллапса
std::string fileWake
Имя файла с начальным состоянием вихревого следа (без полного пути)
double maxGamma
Максимально допустимая циркуляция вихря
double eps2
Квадрат радиуса вихря
double timeStart
Начальное время
int saveVPstep
Шаг вычисления и сохранения скорости и давления
double timeStop
Конечное время