270{
271
272
274
275#ifdef USE_CUDA
277#endif
278
279
280
282
283
285 {
286 std::unique_ptr<Passport> revisePspPtr;
290
292
293 }
294
295
297
298 size_t countStrongCoupling = 0;
299 for (
size_t m = 0; m <
mechanics.size(); ++m)
300 {
303 {
305 ++countStrongCoupling;
306 }
307 }
308
309 bool semiImplicitStrategy = ((countStrongCoupling ==
mechanics.size()) && (
mechanics.size() > 0));
311 info(
'i') <<
"Strong (semi-implicit) coupling strategy" << std::endl;
312
313
314
315 int nTotPan = 0;
318
319
320 if (!semiImplicitStrategy)
321 {
323
326 if (
getPassport().numericalSchemes.velocityComputation.second == 0 &&
getPassport().numericalSchemes.linearSystemSolver.second == 2)
327 {
328#ifdef USE_CUDA
330 if (nTotPan > 0)
331 {
333 auto& treePnlVrt = *
getCuda().inflTreePnlVortex;
335 treePnlVrt.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
336
338 {
339
340 treePnlVrt.UpdatePanelGeometry(nTotPan, (double4*)afl.devRPtr);
341 treePnlVrt.Build();
342 }
343
344 treePnlVrt.UpdatePanelAttachedVortexIntensity(afl.devAttachedVortexSheetPtr, afl.devAttachedVortexSheetLinPtr);
345 treePnlVrt.UpwardTraversal(
getPassport().numericalSchemes.gmresMultipoleOrder);
346 }
347#endif
348 }
349
350 if (
getPassport().numericalSchemes.velocityComputation.second == 1)
351 {
352#ifdef USE_CUDA
355
356
357 auto& treeWake = *
getCuda().inflTreeWake;
358 treeWake.MemoryAllocate((
int)
getCuda().n_CUDA_wake);
360 treeWake.Build();
361 treeWake.UpwardTraversal(
getPassport().numericalSchemes.nbodyMultipoleOrder);
362
363 if (nTotPan > 0)
364 {
366 auto& treePnl = *
getCuda().cntrTreePnl;
367 auto& treePnlVrt = *
getCuda().inflTreePnlVortex;
368 auto& treePnlSrc = *
getCuda().inflTreePnlSource;
369 auto& treePnlAux = *
getCuda().auxTreePnl;
370
372 {
373 treePnl.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
374 treePnlAux.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
375 treePnlVrt.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
377 treePnlSrc.MemoryAllocate((
int)
getCuda().n_CUDA_pnls);
378 }
379
381 {
382
383 treePnlVrt.UpdatePanelGeometry(nTotPan, (double4*)afl.devRPtr);
384 treePnlVrt.Build();
385
386
387 treePnl.UpdatePanelGeometry((int)nTotPan, (double4*)afl.devRPtr);
388 treePnl.Build();
389
390
392 {
393 treePnlSrc.UpdatePanelGeometry(nTotPan, (double4*)afl.devRPtr);
394 treePnlSrc.UpdatePanelAttachedSourceIntensity(afl.devAttachedSourceSheetPtr, afl.devAttachedSourceSheetLinPtr);
395 treePnlSrc.Build();
396 treePnlSrc.UpwardTraversal(
getPassport().numericalSchemes.nbodyMultipoleOrder);
397 }
398 }
399
400 treePnlVrt.UpdatePanelAttachedVortexIntensity(afl.devAttachedVortexSheetPtr, afl.devAttachedVortexSheetLinPtr);
401 treePnlVrt.UpwardTraversal(
getPassport().numericalSchemes.nbodyMultipoleOrder);
402 }
403#else
405 {
409 }
410 std::vector<std::pair<Point2D, Point2D>> panels;
411
413 {
415
416 for (size_t i = 0; i < afl.getNumberOfPanels(); ++i)
417 panels.push_back({ afl.getR(i), afl.getR(i + 1) });
418 }
419 if (panels.size() > 0)
420 {
421 cntrTreePnl->UpdatePanelGeometry(panels, std::max(4, (
int)(log2(panels.size())) - 2));
424 }
425#endif
426 }
428
431
432
433 if (
getPassport().physicalProperties.typeAccel.second == 3)
434 {
438 {
440 {
442 {
447 }
450 info(
'i') <<
"Added Masses for airfoil #" << bou <<
" = { " << lambdaAdd[bou][0] <<
", " << lambdaAdd[bou][1] <<
", " << muAdd[bou] <<
" }" << std::endl;
451
452 char direction;
453 switch ((
int)(
getPassport().physicalProperties.timeAccel))
454 {
455 case 0:
456 direction = 'x';
457 break;
458 case 1:
459 direction = 'y';
460 break;
461 case 2:
462 direction = 'w';
463 break;
464 default:
465 direction = '?';
466 info(
'e') <<
"Wrong dirfection is specified!" << std::endl;
467 exit(1);
468 }
469
471 std::ofstream addMassFile;
473 {
474 addMassFile.open(addMassFileName);
475 addMassFile << "Added Masses for airfoil:" << std::endl;
476 }
477 else
478 addMassFile.open(addMassFileName, std::ios_base::app);
479
480 addMassFile << direction << "-direction: " << lambdaAdd[bou][0] << " " << lambdaAdd[bou][1] << " " << muAdd[bou] << std::endl;
481
482 addMassFile.close();
483 }
484 }
486 }
487
489 if (nTotPan > 0 &&
getPassport().numericalSchemes.velocityComputation.second == 1)
490 {
492#ifdef USE_CUDA
493 getCuda().inflTreePnlVortex->UpdatePanelFreeAndAttachedVortexIntensity(afl.devFreeVortexSheetPtr, afl.devFreeVortexSheetLinPtr, afl.devAttachedVortexSheetPtr, afl.devAttachedVortexSheetLinPtr);
494 getCuda().inflTreePnlVortex->UpwardTraversal(
getPassport().numericalSchemes.nbodyMultipoleOrder);
495#endif
496 }
498
499
501
502
503#ifdef TURB
505 std::vector<double> nut;
506 CalcVeloDifference(nut);
508
509 for (
size_t q = 0; q <
getWake().
vtx.size(); ++q)
511#endif
512
513
514
515
516
518
519#ifdef OPTIMIZER
521#endif
522 {
524
526
527#ifdef USE_CUDA
529#else
531#endif
532
534 {
535
536
538
539 if (
measureVP->getTotalNumberOfRealPoints() > 0)
541
542
543
544
545
547 {
548 std::ofstream presForcesFile;
550 {
552 presForcesFile << "time,Fx,Fy,Py" << std::endl;
553 }
554 else
555 presForcesFile.open(
getPassport().
dir +
"presForcesFile.csv", std::ios_base::app);
556
557 auto r =
measureVP->GetVPinElasticPoints();
558 Point2D presForce = { 0.0, 0.0 };
559 double yPower = 0.0;
560
561 for (int q = 0; q < r.size(); ++q)
562 {
565 }
566
567 presForcesFile <<
currentTime <<
"," << scaleP * presForce[0] <<
"," << scaleP * presForce[1] <<
"," << scaleP * yPower << std::endl;
568 presForcesFile.close();
569 }
570 }
571
572
574 {
575
577 if (ptr && ptr->
beam->fsi)
578 {
579 auto r =
measureVP->GetVPinElasticPoints();
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 std::vector<double> currentPres(ptr->
chord.size());
598 for (
size_t j = 0; j < ptr->
chord.size(); ++j)
599 {
600
601 currentPres[j] = -(r[2 * j + 0].second - r[2 * j + 1].second);
602 }
603
604 if (ptr->
beam->presLastSteps.size() < ptr->
beam->nLastSteps)
605 ptr->
beam->presLastSteps.push_back(currentPres);
606 else
607 {
608 for (
int w = 1; w < ptr->
beam->nLastSteps; ++w)
609 ptr->
beam->presLastSteps[w - 1] = std::move(ptr->
beam->presLastSteps[w]);
610 ptr->
beam->presLastSteps.back() = currentPres;
611 }
612
613 for (
int q = 0; q < ptr->
beam->R; ++q)
614 {
615 ptr->
beam->qCoeff[q] = 0;
616
617 if (ptr->
beam->presLastSteps.size() == ptr->
beam->nLastSteps)
618 {
619 for (
size_t j = 0; j < ptr->
chord.size(); ++j)
620 {
621 double averpres = 0.0;
622
623
624 for (
int i = 0; i < ptr->
beam->nLastSteps; ++i)
625 averpres += ptr->
beam->presLastSteps[i][j];
626 averpres /= ptr->
beam->nLastSteps;
627
629 }
630 ptr->
beam->qCoeff[q] /= (ptr->
beam->intSqUnitShape * ptr->
beam->L);
631 }
632
633
634 }
635
636 std::ofstream phiFile;
638 {
640 phiFile << "time";
641 for (
int p = 0; p < ptr->
beam->R; ++p)
642 phiFile << ",phi-" << std::to_string(p + 1);
643 for (
int p = 0; p < ptr->
beam->R; ++p)
644 phiFile << ",q-" << std::to_string(p + 1);
645 phiFile << std::endl;
646 }
647 else
648 phiFile.open(
getPassport().
dir +
"phiFile.csv", std::ios_base::app);
649
651 for (
int p = 0; p < ptr->
beam->R; ++p)
652 phiFile <<
"," << ptr->
beam->phi(p, 0);
653 for (
int p = 0; p < ptr->
beam->R; ++p)
654 phiFile <<
"," << ptr->
beam->qCoeff[p];
655
656 phiFile << std::endl;
657
658 phiFile.close();
659 }
660 }
661
662
663 }
664
665
667 {
668 mech->GetHydroDynamForce();
669 mech->GenerateForcesString();
670 mech->GeneratePositionString();
671 }
672
673
674#ifdef TURB
676
677
678#else
680#endif
683
684
686
687
688
689
690
691
692
693 }
694
695
696
697 if (semiImplicitStrategy)
698 {
701
703
704
706
707
708
709
710
711
712
714 {
717 }
718
721
724
725
726
727 for (
size_t m = 0; m <
mechanics.size(); ++m)
728 {
730
732 if (mechVar)
733 {
735 {
736 getInfo(
'e') <<
"Added mass of the airfoil should be non-zero!" << std::endl;
737 exit(1);
738 }
746 }
747 else
748 exit(3333);
749 }
750 }
751
752
754
756
757
758
760
761
762
763
764
765
766
767
768
769
770
773 << std::setprecision(3) \
775 << std::setprecision(6) \
776 << std::endl;
777
779
782
783
784
785
786
787
788}
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
std::vector< Point2D > nrm
Нормали к панелям профиля
Point2D rcm
Положение центра масс профиля
Sheet sheets
Слои на профиле
Абстрактный класс, определяющий вид механической системы
Point2D hydroDynamForce
Вектор гидродинамической силы и момент, действующие на профиль
void GeneratePositionString()
Сохранение строки со статистикой в файл нагрузок
void GenerateForcesString()
Сохранение строки со статистикой в файл нагрузок
Point2D & getV()
текущая скорость профиля
bool & getStrongCoupling()
std::string defaultsFileFullName
std::vector< std::string > varLine
std::string switchersFileFullName
std::string mechanicsFileFullName
std::string fileFullName
Имена файлов
void GetReviseParamsFromParser(const Passport &newPassport, const std::vector< std::string > paramList)
Считывание измененных параметров
const double & attachedVortexSheet(size_t n, size_t moment) const
const double & freeVortexSheet(size_t n, size_t moment) const
std::vector< Vortex2D > vtx
Список вихревых элементов
void WakeAndAirfoilsMotion(bool dynamics, std::vector< double > *nutPtr=nullptr)
Перемещение вихрей и профилей на шаге
VMlib::vmTimer timerInitialBuild
void CalcPanelsVeloAndAttachedSheets()
Вычисление скоростей панелей и интенсивностей присоединенных слоев вихрей и источников
void CalcVortexVelo()
Вычисление скоростей (и конвективных, и диффузионных) вихрей (в пелене и виртуальных),...
void CalcAndSolveLinearSystem()
Набор матрицы, правой части и решение СЛАУ
const Boundary & getBoundary(size_t i) const
Возврат константной ссылки на объект граничного условия
bool ifDivisible(int val) const
Mechanics & getNonConstMechanics(size_t i) const
Возврат неконстантной ссылки на объект механики
Wake & getNonConstWake() const
Возврат неконстантной ссылки на вихревой след
void GenerateStatString(size_t stepNo, double curTime, size_t N)
Формирование очередной строки файла временной статистики
void resetAll()
Сброс всех счетчиков
double durationStep() const
Вывод счетчика всего шага в секундах
size_t getCurrentStep() const
Возврат константной ссылки на параметры распараллеливания по MPI.
numvector< T, 2 > kcross() const
Геометрический поворот двумерного вектора на 90 градусов
bool fileExistTest(std::string &fileName, LogStream &info, bool exitKey=false, const std::list< std::string > &extList={})
Проверка существования файла
double rho
Плотность потока
std::vector< std::string > reviseParameters
Список перечитываемых параметров
int revisePassportStep
Шаг перечитывания паспорта