62 #include "intersection.cuh" 69 passport(dynamic_cast<const
Passport&>(passport_)),
139 info(
'e') <<
"Unknown scheme!" << std::endl;
230 std::vector<MechanicsRigidOscillPart*> mechOscilPart;
233 mechOscilPart.resize(
mechanics.size(),
nullptr);
235 for (
size_t s = 0; s <
mechanics.size(); ++s)
236 mechOscilPart[s] = dynamic_cast<MechanicsRigidOscillPart*>(
mechanics[0].
get());
240 for (
size_t s = 0; s <
mechanics.size(); ++s)
241 mechanics[s]->hydroDynamForce = { 0.0, 0.0 };
253 mech->GetHydroDynamForce();
254 mech->GenerateForcesString();
255 mech->GeneratePositionString();
258 for (
size_t s = 0; s < mechanics.size(); ++s)
259 if (mechOscilPart[s])
262 mechOscilPart[s]->UpdateU();
287 info(
'e') <<
"!!! Exception from unknown source !!!" << std::endl;
299 #if (!defined(USE_CUDA)) 300 for (
size_t afl = 0; afl <
airfoil.size(); ++afl)
303 if (newPos.size() > 0)
306 double* devNewpos_ptr;
307 cuReserveDevMem((
void*&)devNewpos_ptr, newPos.size() *
sizeof(double) * 2, 0);
308 cuCopyFixedArray(devNewpos_ptr, newPos.data(), newPos.size() *
sizeof(double) * 2, 0);
310 for (
size_t afl = 0; afl <
airfoil.size(); ++afl)
312 std::vector<double> gamma(
airfoil[afl]->getNumberOfPanels(), 0.0);
313 std::vector<unsigned int> hit = lbvh_check_inside((
int)
currentStep, (
int)newPos.size(), devNewpos_ptr, (int)
airfoil[afl]->getNumberOfPanels(),
airfoil[afl]->devRPtr);
314 for (
int i = 0; i < newPos.size(); ++i)
316 if (hit[i] != (
unsigned int)(-1))
318 gamma[hit[i]] +=
wake->vtx[i].g();
319 wake->vtx[i].g() = 0.0;
322 airfoil[afl]->gammaThrough = gamma;
325 cuDeleteFromDev(devNewpos_ptr);
359 info(
't') <<
"Inverting matrix" << std::endl;
361 #if (defined(USE_CUDA)) 363 for (
int i = 0; i < (int)
matr.rows(); ++i)
364 for (
int j = 0; j < (int)
matr.cols(); ++j)
365 invMatr(i, j) = (i == j) ? 1.0 : 0.0;
432 sol =
matr.partialPivLu().solve(rhs);
442 Eigen::MatrixXd locMatr;
443 Eigen::MatrixXd otherMatr;
444 Eigen::VectorXd locLastLine, locLastCol;
446 std::vector<std::vector<Point2D>> locIQ;
447 std::vector<std::vector<Point2D>> locOtherIQ;
452 for (
int i = 0; i <
matr.rows(); ++i)
453 for (
int j = 0; j <
matr.cols(); ++j)
457 size_t currentRow = 0;
459 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
461 size_t nVars =
boundary[bou]->GetUnknownsSize();
464 locMatr.resize(nVars, nVars);
465 locLastLine.resize(nVars);
466 locLastCol.resize(nVars);
471 boundary[bou]->FillMatrixSelf(locMatr, locLastLine, locLastCol);
476 for (
size_t i = 0; i < nVars; ++i)
480 for (
size_t j = 0; j < nVars; ++j)
481 matr(i + currentRow, j + currentRow) = locMatr(i, j);
482 matr(currentRow + nVars, i + currentRow) = locLastLine(i);
483 matr(i + currentRow, currentRow + nVars) = locLastCol(i);
489 size_t currentCol = 0;
490 for (
size_t oth = 0; oth <
boundary.size(); ++oth)
492 size_t nVarsOther =
boundary[oth]->GetUnknownsSize();
496 otherMatr.resize(nVars, nVarsOther);
501 for (
size_t i = 0; i < nVars; ++i)
503 for (
size_t j = 0; j < nVarsOther; ++j)
504 matr(i + currentRow, j + currentCol) = otherMatr(i, j);
507 currentCol += nVarsOther + 1;
511 currentRow += nVars + 1;
530 for (
size_t i = 1; i <
boundary.size(); ++i)
537 matrSize += (*it)->GetUnknownsSize();
539 matr.resize(matrSize, matrSize);
544 size_t nVari =
boundary[i]->GetUnknownsSize();
547 size_t nVarj =
boundary[j]->GetUnknownsSize();
548 IQ[i][j].first.resize(nVari, nVarj);
549 IQ[i][j].second.resize(nVari, nVarj);
553 rhs.resize(matrSize);
571 #if defined(__CUDACC__) || defined(USE_CUDA) 574 cuda.RefreshVirtualWakes(2);
592 #if defined(__CUDACC__) || defined(USE_CUDA) 593 for (
size_t i = 0; i <
airfoil.size(); ++i)
594 cuda.CopyMemToDev<
double, 1>(
airfoil[i]->getNumberOfPanels(),
airfoil[i]->meanEpsOverPanel.data(),
airfoil[i]->devMeanEpsOverPanelPtr);
669 for (
size_t i = 0; i <
airfoil.size(); ++i)
673 for (
size_t i = 0; i <
airfoil.size(); ++i)
674 boundary[i]->ComputeAttachedSheetsIntensity();
685 size_t nvt =
wake->vtx.size();
687 nvt +=
boundary[i]->virtualWake.vtx.size();
693 #pragma omp parallel for 694 for (
int i = 0; i < (int)
wake->vtx.size(); ++i)
696 newPos[i] =
wake->vtx[i].r() \
697 + (
velocity->wakeVortexesParams.convVelo[i] +
698 velocity->wakeVortexesParams.diffVelo[i] +
702 int curCounterNewPos = (int)
wake->vtx.size();
704 wake->vtx.resize(nvt);
707 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
709 #pragma omp parallel for 710 for (
int i = 0; i < (int)
boundary[bou]->virtualWake.vtx.size(); ++i)
712 wake->vtx[curCounterNewPos + i] = (
boundary[bou]->virtualWake.vtx[i]);
713 newPos[curCounterNewPos + i] = (
boundary[bou]->virtualWake.vtx[i].r() \
714 + (
velocity->virtualVortexesParams[bou].convVelo[i] +
715 velocity->virtualVortexesParams[bou].diffVelo[i] +
718 curCounterNewPos += (int)
boundary[bou]->virtualWake.vtx.size();
727 mechanics[mechanicsNumber]->GenerateForcesHeader();
728 mechanics[mechanicsNumber]->GeneratePositionHeader();
736 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
743 for (
size_t oth = 0; oth <
boundary.size(); ++oth)
761 size_t nVarsOther =
boundary[oth]->GetUnknownsSize();
780 #if defined(__CUDACC__) || defined(USE_CUDA) 786 if ((sch == 0) || (sch == 1) || (sch == 10))
790 info(
'e') <<
"schemeSwitcher is not 0, or 1, or 10! " << std::endl;
796 cuda.RefreshVirtualWakes(1);
804 (
mechanics.size() > 1 && !std::any_of(
mechanics.begin(),
mechanics.end(), [](
const std::unique_ptr<Mechanics>& m) {
return m->isMoves; }))
843 size_t currentRow = 0;
844 for (
size_t bou = 0; bou <
boundary.size(); ++bou)
846 size_t nVars =
boundary[bou]->GetUnknownsSize();
847 Eigen::VectorXd locSol;
848 locSol.resize(nVars);
849 for (
size_t i = 0; i < nVars; ++i)
850 locSol(i) =
sol(currentRow + i);
852 boundary[bou]->SolutionToFreeVortexSheetAndVirtualVortex(locSol);
853 currentRow += nVars + 1;
858 Point2D addMass = { 0.0, 0.0 };
859 for (
size_t q = 0; q <
airfoil[0]->getNumberOfPanels(); ++q)
865 std::cout <<
"AddMass = " << addMass << std::endl;
875 std::vector<Point2D> newPos;
880 double totalForce = 0;
881 for (
size_t afl = 0; afl <
airfoil.size(); ++afl)
883 totalForce +=
mechanics[afl]->hydroDynamForce[1];
887 mechanics[0]->hydroDynamForce[1] = totalForce;
907 if (afl->numberInPassport == 0)
909 mechanics[afl->numberInPassport]->Move();
916 double du = mech0.getU() - mech0.getUOld();
921 mechI.getUOld() = mechI.getU();
926 airfoil[afl->numberInPassport]->Move({ 0.0, dy });
935 mechanics[afl->numberInPassport]->Move();
940 bou->virtualWake.vtx.clear();
949 for (
size_t i = 0; i <
wake->vtx.size(); ++i)
950 wake->vtx[i].r() = newPos[i];
std::unique_ptr< Velocity > velocity
Умный укзатель на объект, определяющий методику вычисления скоростей
Заголовочный файл с описанием класса Passport (двумерный) и cоответствующими структурами ...
Times & getTimestat() const
Возврат ссылки на временную статистику выполнения шага расчета по времени
static std::ostream * defaultWorld2DLogStream
Поток вывода логов и ошибок задачи
virtual void ToZero() override
Обнуление состояния временной статистики
std::pair< std::string, int > velocityComputation
Eigen::MatrixXd invMatr
Обратная матрица
timePeriod timeCalcVortexDiffVelo
Начало и конец процесса вычисления диффузионных скоростей вихрей
Заголовочный файл с описанием класса Wake.
void setSchemeSwitcher(int schemeSwitcher_)
Установка переключателя расчетных схем
Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле ...
std::string problemName
Название задачи
void MoveVortexes(std::vector< Point2D > &newPos)
Вычисляем новые положения вихрей (в пелене и виртуальных)
Класс для сбора статистики времени исполнения основных шагов алгоритма и вывода ее в файл ...
std::pair< std::string, int > boundaryCondition
Метод аппроксимации граничных условий
Заголовочный файл с описанием класса World2D.
Eigen::VectorXd rhs
Правая часть системы
virtual void GenerateStatString() const override
Сохранение строки со статистикой в файл временной статистики
double getCurrTime() const
Возвращает текуще время
size_t getNumberOfBoundary() const
Возврат количества граничных условий в задаче
void assignStream(std::ostream *pStr_, const std::string &label_)
Связывание потока логов с потоком вывода
LogStream info
Поток для вывода логов и сообщений об ошибках
double maxGamma
Максимально допустимая циркуляция вихря
Заголовочный файл с описанием класса VelocityBiotSavart.
std::vector< std::unique_ptr< Airfoil > > oldAirfoil
Список умных указателей на обтекаемые профили для сохранения старого положения
Класс, определяющий вид механической системы
Класс, определяющий вид механической системы
Заголовочный файл с описанием класса AirfoilRect.
std::string dir
Рабочий каталог задачи
Заголовочный файл с описанием класса MechanicsRigidRotatePart.
PhysicalProperties physicalProperties
Структура с физическими свойствами задачи
std::unique_ptr< Wake > wake
Умный указатель на вихревой след
timePeriod timeCalcVortexConvVelo
Начало и конец процесса вычисления конвективных скоростей вихрей
Класс, опеделяющий паспорт двумерной задачи
Класс, обеспечивающий возможность выполнения вычислений на GPU по технологии Nvidia CUDA...
std::unique_ptr< WakeDataBase > source
Умный указатель на источники
Класс, определяющий вид механической системы
Заголовочный файл с описанием класса BoundaryVortexCollocN.
timePeriod timeMoveVortexes
Начало и конец процесса перемещения вихрей
void setMaxGamma(double gam_)
Установка максимально допустимой циркуляции вихря
Eigen::MatrixXd matr
Матрица системы
void GenerateMechanicsHeader(size_t mechanicsNumber)
bool ifDivisible(int val) const
double accelCft() const
Функция-множитель, позволяющая моделировать разгон
std::vector< std::unique_ptr< Mechanics > > mechanics
Список умных указателей на типы механической системы для каждого профиля
timePeriod timeSaveKadr
Начало и конец процесса сохранения кадра в файл
TimeDiscretizationProperties timeDiscretizationProperties
Структура с параметрами процесса интегрирования по времени
Заголовочный файл с описанием класса MechanicsRigidImmovable.
Заголовочный файл с описанием класса MechanicsRigidOscillPart.
std::unique_ptr< MeasureVP > measureVP
Умный указатель на алгоритм вычисления полей скоростей и давления (для сохранения в файл) ...
static double dT(const timePeriod &t)
Класс, определяющий тип обтекаемого профиля
Класс, опеделяющий вихревой след (пелену)
World2D(const VMlib::PassportGen &passport_)
Конструктор
timePeriod timeSolveLinearSystem
Начало и конец процесса решения системы линейных алгебраических уравнений
Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле ...
std::unique_ptr< TimesGen > timestat
Сведения о временах выполнения основных операций
virtual void Step() override
Функция выполнения предварительного шага
Абстрактный класс, опеделяющий паспорт задачи
double timeStart
Начальное время
double rho
Плотность потока
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
void CheckInside(std::vector< Point2D > &newPos, const std::vector< std::unique_ptr< Airfoil >> &oldAirfoil)
Проверка проникновения вихрей внутрь профиля
std::string fileSource
Имя файла с положениями источников (без полного пути)
int saveVPstep
Шаг вычисления и сохранения скорости и давления
Заголовочный файл с описанием класса StreamParser.
size_t problemNumber
Номер задачи
void ReserveMemoryForMatrixAndRhs()
Вычисляем размер матрицы и резервируем память под нее и под правую часть
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
Заголовочный файл с описанием класса BoundaryLinLayerAver.
timePeriod timeFillMatrixAndRhs
Начало и конец процесса заполнения матрицы и формирования правой части
Класс, опеделяющий двумерный вектор
void PrintLogoToStream(std::ostream &str)
Передача в поток вывода шапки программы VM2D/VM3D.
void setAccelCoeff(double cft_)
Установка коэффициента разгона потока
Gpu cuda
Объект, управляющий графическим ускорителем
Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле ...
Заголовочный файл с описанием класса BoundaryConstLayerAver.
std::string fileWake
Имя файла с начальным состоянием вихревого следа (без полного пути)
timePeriod timeCheckInside
Начало и конец процесса контроля протыкания
Класс, отвечающий за вычисление поля скорости и давления в заданых точках для вывода ...
double & getY()
текущее отклонение профиля
Заголовочный файл с описанием класса MeasureVP.
std::vector< std::unique_ptr< Airfoil > > airfoil
Список умных указателей на обтекаемые профили
const Passport & getPassport() const
Возврат константной ссылки на паспорт
bool useInverseMatrix
Признак использования обратной матрицы
void setCurrTime(double t_) const
Установка текущего времени
std::pair< std::string, int > panelsType
Тип панелей (0 — прямые)
std::vector< std::vector< std::pair< Eigen::MatrixXd, Eigen::MatrixXd > > > IQ
Матрица, состоящая из пар матриц, в которых хранятся касательные и нормальные компоненты интегралов о...
void CalcAndSolveLinearSystem()
Набор матрицы, правой части и решение СЛАУ
Eigen::VectorXd sol
Решение системы
void calcMeanEpsOverPanel()
Вычисление средних значений eps на панелях
Класс, определяющий вид механической системы
size_t currentStep
Текущий номер шага в решаемой задаче
void CalcPanelsVeloAndAttachedSheets()
Вычисление скоростей панелей и интенсивностей присоединенных слоев вихрей и источников ...
timePeriod timeReserveMemoryForMatrixAndRhs
Начало и конец процесса выделения памяти под матрицу и правую часть
void addCurrTime(double dt_) const
Добавление шага к текущему времени
Point2D V0() const
Функция скорости набегающего потока с учетом разгона
void FillIQ()
Заполнение матрицы, состоящей из интегралов от (r-xi) / |r-xi|^2.
std::vector< AirfoilParams > airfoilParams
Список структур с параметрами профилей
void CalcVortexVelo(bool shiftTime)
Вычисление скоростей (и конвективных, и диффузионных) вихрей (в пелене и виртуальных), а также в точках вычисления VP.
Класс, опеделяющий набор вихрей
std::string wakesDir
Каталог с файлами вихревых следов
WakeDiscretizationProperties wakeDiscretizationProperties
Структура с параметрами дискретизации вихревого следа
void FillMatrixAndRhs()
Заполнение матрицы системы для всех профилей
void endl()
Вывод в поток логов пустой строки
std::vector< std::unique_ptr< Boundary > > boundary
Список умных указателей на формирователи граничных условий на профилях
void SolveLinearSystem()
Решение системы линейных алгебраических уравнений
Класс, определяющий способ вычисления скоростей
const Passport & passport
Константная ссылка на паспорт конкретного расчета
timePeriod timeWholeStep
Начало и конец процесса выполнения шага целиком
Airfoil & getNonConstAirfoil(size_t i) const
Возврат неконстантной ссылки на объект профиля
std::string airfoilsDir
Каталог с файлами профилей
Заголовочный файл с описанием класса MechanicsRigidGivenLaw.
timePeriod timeOther
Все прочее
std::vector< size_t > dispBoundaryInSystem
Список номеров, с которых начинаются элементы правой части (или матрицы) системы для профилей ...
void WakeAndAirfoilsMotion()
Перемещение вихрей и профилей на шаге
Абстрактный класс, определяющий вид механической системы