VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
VM2D::GmresSolver Class Reference

#include <Gmres2D.h>

Collaboration diagram for VM2D::GmresSolver:

Public Member Functions

 GmresSolver (const World2D &W_)
 
 ~GmresSolver ()
 
bool IterRot (const double nrmRhs, double &gs, int m, bool residualShow)
 Контроль невязки после выполнения очередной итерации GMRES.
 
void PreCalculateCoef (int aflIndex)
 
void SolCircleRundirect (const std::vector< double > &A, const std::vector< double > &rhs, size_t startRow, size_t startRowReg, size_t np, std::vector< double > &res)
 
void SolMdirect (const std::vector< double > &A, const std::vector< double > &rhs, size_t startRow, size_t startRowReg, size_t np, std::vector< double > &res, bool lin)
 
void GMRES_Direct (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 SolM (std::vector< double > &AX, const std::vector< double > &rhs, int p)
 
void SolCircleRun (std::vector< double > &AX, const std::vector< double > &rhs, int p)
 

Private Attributes

const World2DW
 
std::vector< double > w
 
std::vector< double > c
 
std::vector< double > s
 
std::vector< double > Vflat
 
std::vector< std::vector< double > > H
 
std::vector< std::vector< double > > diag
 
std::vector< std::vector< Point2D > > prea
 
std::vector< std::vector< Point2D > > prec
 
std::vector< std::vector< Point2D > > prea1
 
std::vector< std::vector< Point2D > > prec1
 
std::vector< sweepVectorsallSW
 
std::vector< std::vector< double > > allBuf2
 
std::vector< size_t > np
 
std::vector< double > bufnewSol
 
std::vector< double > bufcurrentSol
 
std::vector< double > g
 
std::vector< double > Y
 
size_t totalVsize
 
size_t nTotPan
 
const size_t iterSize = 100
 

Detailed Description

Definition at line 145 of file Gmres2D.h.

Constructor & Destructor Documentation

◆ GmresSolver()

GmresSolver::GmresSolver ( const World2D W_)

Definition at line 602 of file Gmres2D.cpp.

603 : W(W_)
604{
605#ifdef USE_CUDA
606 cublasCreate(&cublas_handle);
607#endif
608
610 const size_t nAfl = W.getNumberOfAirfoil();
611
612 nTotPan = 0;
613 for (size_t s = 0; s < nAfl; ++s)
615
617
618#ifdef USE_CUDA
619 cudaMalloc((void**)&devViBund, (totalVsize + nAfl) * sizeof(double) * iterSize);
620 cudaMalloc((void**)&devw, (totalVsize + nAfl) * sizeof(double));
621
622 //cudaMalloc(&mulptr, iterSize * sizeof(double));
623 //std::vector<double> mul(iterSize);
624#endif
625
626 w.resize(totalVsize + nAfl);
627 c.reserve(iterSize);
628 s.reserve(iterSize);
629
630 Vflat.reserve((totalVsize + nAfl) * iterSize);
631
632 diag.resize(nAfl);
633 H.resize(iterSize + 1);
634 for (int i = 0; i < iterSize + 1; ++i)
635 H[i].resize(iterSize);
636
637 for (int p = 0; p < (int)nAfl; ++p)
638 {
639 size_t nPanelsP = W.getAirfoil(p).getNumberOfPanels();
640 if (!linScheme)
641 diag[p].resize(nPanelsP);
642 else
643 diag[p].resize(2 * nPanelsP);
644 }
645
646 // PRECONDITIONER
647 prea.resize(nAfl);
648 prec.resize(nAfl);
649
650 if (linScheme)
651 {
652 prea1.resize(nAfl);
653 prec1.resize(nAfl);
654 }
655
656#pragma omp parallel for
657 for (int p = 0; p < nAfl; ++p)
658 {
659 const auto& aflP = W.getAirfoil(p);
660 size_t nPanelsP = aflP.getNumberOfPanels();
661
662 prea[p].resize(nPanelsP);
663 prec[p].resize(nPanelsP);
664 if (linScheme)
665 {
666 prea1[p].resize(nPanelsP);
667 prec1[p].resize(nPanelsP);
668 }
669 }
670
671 allSW.resize(nAfl);
672 allBuf2.resize(nAfl);
673 np.resize(nAfl, 0);
674
675 for (size_t p = 0; p < nAfl; ++p)
676 {
677 size_t nPanelsP = W.getAirfoil(p).getNumberOfPanels();
678
679 allSW[p].resize(nPanelsP);
680
681 if (!linScheme)
682 allBuf2[p].resize(nPanelsP + 1);
683 else
684 allBuf2[p].resize(2 * nPanelsP + 1);
685
686 if (p == 0)
687 continue;
688
689 np[p] = np[p - 1];
690 if (!linScheme)
691 np[p] += (/*(p == 0) ? 0 :*/ W.getAirfoil(p - 1).getNumberOfPanels());
692 else
693 np[p] += (/*(p == 0) ? 0 :*/ 2 * W.getAirfoil(p - 1).getNumberOfPanels());
694 }
695
696 bufnewSol.resize(totalVsize);
697 bufcurrentSol.resize(totalVsize, 0.0);
698
699 g.reserve(iterSize);
700 Y.reserve(iterSize);
701
702#ifdef USE_CUDA
703 W.getNonConstCuda().AllocateSolution(W.getNonConstCuda().dev_sol, nTotPan);
704 if (linScheme)
705 W.getNonConstCuda().AllocateSolution(W.getNonConstCuda().dev_solLin, nTotPan);
706 else
707 W.getNonConstCuda().dev_solLin = nullptr;
708#endif
709};
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Definition Airfoil2D.h:163
std::vector< double > bufcurrentSol
Definition Gmres2D.h:166
std::vector< double > s
Definition Gmres2D.h:156
std::vector< std::vector< Point2D > > prec
Definition Gmres2D.h:160
const World2D & W
Definition Gmres2D.h:148
std::vector< std::vector< double > > allBuf2
Definition Gmres2D.h:163
std::vector< std::vector< Point2D > > prea1
Definition Gmres2D.h:160
std::vector< std::vector< Point2D > > prea
Definition Gmres2D.h:160
std::vector< double > c
Definition Gmres2D.h:156
size_t totalVsize
Definition Gmres2D.h:169
std::vector< double > bufnewSol
Definition Gmres2D.h:166
std::vector< std::vector< double > > H
Definition Gmres2D.h:158
std::vector< size_t > np
Definition Gmres2D.h:164
std::vector< double > Vflat
Definition Gmres2D.h:157
const size_t iterSize
Definition Gmres2D.h:172
std::vector< sweepVectors > allSW
Definition Gmres2D.h:162
std::vector< std::vector< double > > diag
Definition Gmres2D.h:158
std::vector< std::vector< Point2D > > prec1
Definition Gmres2D.h:160
std::vector< double > Y
Definition Gmres2D.h:167
std::vector< double > g
Definition Gmres2D.h:167
std::vector< double > w
Definition Gmres2D.h:156
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
Definition Passport2D.h:307
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
Definition World2D.h:180
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Definition World2D.h:163
Gpu & getNonConstCuda() const
Возврат неконстантной ссылки на объект, связанный с видеокартой (GPU)
Definition World2D.h:278
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition World2D.h:263
std::pair< std::string, int > boundaryCondition
Метод аппроксимации граничных условий
Definition Passport2D.h:190
Here is the call graph for this function:

◆ ~GmresSolver()

GmresSolver::~GmresSolver ( )

Definition at line 711 of file Gmres2D.cpp.

712{
713#ifdef USE_CUDA
714 cublasDestroy(cublas_handle);
715
717 W.getNonConstCuda().ReleaseSolution(W.getNonConstCuda().dev_sol);
718 if (linScheme)
719 W.getNonConstCuda().ReleaseSolution(W.getNonConstCuda().dev_solLin);
720
721 //W.getNonConstCuda().inflTreePnlVortex->MemoryFreeForGMRES();
722 cudaFree(devViBund);
723 cudaFree(devw);
724 //cudaFree(mulptr);
725
726#endif
727}
Here is the call graph for this function:

Member Function Documentation

◆ GMRES_Direct()

void GmresSolver::GMRES_Direct ( 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 
)

Definition at line 204 of file Gmres2D.cpp.

213{
214 const size_t maxIter = nAllVars + 1;
215 std::vector<double> x(nAllVars, 0.0);
216 std::vector<double> y(nAllVars, 0.0);
217 std::vector<double> residual(nAllVars, 0.0);
218 std::vector<double> r(nAllVars, 0.0);
219 std::vector<double> w(nAllVars, 0.0);
220 std::vector<double> wOld(nAllVars, 0.0);
221 std::vector<double> g(nAllVars, 0.0);
222 std::vector<double> c(nAllVars, 0.0);
223 std::vector<double> s(nAllVars, 0.0);
224 std::vector<double> hisGs(nAllVars + 1, 0.0);
225 std::vector<double> v(nAllVars * (maxIter + 1), 0.0);
226
227 std::vector<double> vecFromV(nAllVars, 0.0);
228
229 std::vector<double> h((nAllVars + 1) * maxIter, 0.0);
230 double beta = 0.0, gs, normb = 0.0;
231 size_t m = 0;
232
233 for (size_t i = 0; i < nAllVars; ++i)
234 normb += rhsDir[i] * rhsDir[i];
235 normb = sqrt(normb);
236
237 for (size_t i = 0; i < nAllVars; ++i)
238 residual[i] = rhsDir[i];
239
240#pragma omp parallel for
241 for (int aflI = 0; aflI < nafl; ++aflI)
242 {
243 // SolMdirect(mtrDir, residual, pos[aflI], nAllVars - nafl + aflI, W.getAirfoil(aflI).getNumberOfPanels(), r, (vsize[aflI] == 2*n[aflI]));
244 r = residual;
245 }
246
247 for (size_t i = 0; i < nAllVars; ++i)
248 beta += r[i] * r[i];
249 beta = sqrt(beta);
250 gs = beta;
251 g[0] = beta;
252
253 // ,
254 if (beta == 0)
255 {
256 for (size_t aflI = 0; aflI < nafl; ++aflI)
257 {
258 for (size_t i = 0; i < vsize[aflI]; ++i)
259 gam[aflI][i] = 0.0;
260 R[aflI] = 0.0;
261 }
262 return;
263 }
264
265 for (size_t aflI = 0; aflI < nafl; ++aflI)
266 R[aflI] = x[x.size() - nafl + aflI];
267
268 for (size_t i = 0; i < nAllVars; ++i)
269 v[i * (maxIter + 1) + 0] = r[i] / beta;
270
271 for (size_t j = 0; j < nAllVars; ++j)
272 {
273 double timer1 = omp_get_wtime();
274
275 for (size_t p = 0; p < nAllVars; ++p)
276 vecFromV[p] = v[p * (maxIter + 1) + j];
277
278 //cblas_dgemv(CblasRowMajor, CblasNoTrans, nAllVars, nAllVars, 1.0, mtrDir.data(), nAllVars, &v[0 * (maxIter + 1) + j], (nAllVars + 1), 0.0, wOld.data(), 1);
279 //cblas_dgemv(CblasRowMajor, CblasNoTrans, nAllVars, nAllVars, 1.0, mtrDir.data(), nAllVars, vecFromV.data(), 1, 0.0, wOld.data(), 1);
280 for (int i = 0; i < nAllVars; ++i)
281 {
282 wOld[i] = 0.0;
283 for (int jj = 0; jj < nAllVars; ++jj)
284 {
285 wOld[i] += mtrDir[i * nAllVars + jj] * vecFromV[jj];
286 }
287 }
288
289 double timer2 = omp_get_wtime();
290
291#pragma omp parallel for
292 for (int aflI = 0; aflI < nafl; ++aflI)
293 {
294 // SolMdirect(mtrDir, wOld, pos[aflI], nAllVars - nafl + aflI, W.getAirfoil(aflI).getNumberOfPanels(), w, (vsize[aflI] == 2 * n[aflI]));
295 w = wOld;
296 }
297
298 for (size_t i = 0; i <= j; ++i)
299 {
300 h[i * maxIter + j] = 0.0;
301 for (size_t q = 0; q < nAllVars; ++q)
302 h[i * maxIter + j] += w[q] * v[q * (maxIter + 1) + i];
303
304 for (size_t q = 0; q < nAllVars; ++q)
305 w[q] -= h[i * maxIter + j] * v[q * (maxIter + 1) + i];
306 }//for i
307
308 h[(j + 1) * maxIter + j] = 0.0;
309 for (size_t p = 0; p < nAllVars; ++p)
310 h[(j + 1) * maxIter + j] += w[p] * w[p];
311 h[(j + 1) * maxIter + j] = sqrt(h[(j + 1) * maxIter + j]);
312
313 for (size_t p = 0; p < nAllVars; ++p)
314 v[p * (maxIter + 1) + (j + 1)] = w[p] / h[(j + 1) * maxIter + j];
315
316 for (size_t i = 0; i < j; ++i)
317 {
318 double buf = h[i * maxIter + j];
319 h[i * maxIter + j] = c[i] * buf + s[i] * h[(i + 1) * maxIter + j];
320 h[(i + 1) * maxIter + j] = -s[i] * buf + c[i] * h[(i + 1) * maxIter + j];
321 }
322
323 double zn = sqrt(h[j * maxIter + j] * h[j * maxIter + j] + h[(j + 1) * maxIter + j] * h[(j + 1) * maxIter + j]);
324 c[j] = fabs(h[j * maxIter + j] / zn);
325 s[j] = c[j] * h[(j + 1) * maxIter + j] / h[j * maxIter + j];
326
327 gs *= -s[j];
328
329 h[j * maxIter + j] = c[j] * h[j * maxIter + j] + s[j] * h[(j + 1) * maxIter + j];
330 h[(j + 1) * maxIter + j] = 0.0;
331 hisGs[j] = fabs(gs) / normb;
332
333 if ((fabs(gs) / normb) < W.getPassport().numericalSchemes.gmresEps)
334 {
335 m = j + 1;
336 break;
337 }
338 }//for j
339
340 //
341 for (size_t i = 0; i < m; ++i)
342 {
343 double buf = g[i];
344 g[i] *= c[i];
345 if (i < (m - 1))
346 g[i + 1] = -s[i] * buf;
347
348 }
349 y[m - 1] = g[m - 1] / h[(m - 1) * maxIter + (m - 1)];
350
351 for (size_t i = m - 2; i + 1 > 0; --i)
352 {
353 double sum = 0;
354 for (size_t j = i + 1; j < m; ++j)
355 sum += h[i * maxIter + j] * y[j];
356
357 y[i] = (g[i] - sum) / h[i * maxIter + i];
358 }
359
360 for (size_t p = 0; p < nAllVars; ++p)
361 {
362 for (size_t q = 0; q < m; ++q)
363 x[p] += v[p * (maxIter + 1) + q] * y[q];
364 }
365
366 std::cout << "#iterations: " << m << std::endl;
367
368 for (size_t aflI = 0; aflI < nafl; ++aflI)
369 {
370 for (size_t i = 0; i < vsize[aflI]; ++i)
371 gam[aflI][i] = x[pos[aflI] + i];
372 }
373
374 for (size_t aflI = 0; aflI < nafl; ++aflI)
375 R[aflI] = x[x.size() - nafl + aflI];
376}
Here is the call graph for this function:

◆ IterRot()

bool GmresSolver::IterRot ( const double  nrmRhs,
double &  gs,
int  m,
bool  residualShow 
)

Контроль невязки после выполнения очередной итерации GMRES.

Parameters
[in,out]Hссылка на матрицу вращений Гивенса
[in]rhsконстантная ссылка на вектор правой части решаемой СЛАУ
[in,out]gsссылка на правую часть решаемой СЛАУ

Definition at line 59 of file Gmres2D.cpp.

60{
61 bool fl;
62 double buf;
63
64 double epsGMRES = W.getPassport().numericalSchemes.gmresEps;
65
66 for (int i = 0; i < m - 1; ++i)
67 {
68 buf = H[i][m - 1];
69
70 H[i][m - 1] = c[i] * buf + s[i] * H[i + 1][m - 1];
71 H[i + 1][m - 1] = -s[i] * buf + c[i] * H[i + 1][m - 1];
72 }
73
74 double izn = 1.0 / sqrt(H[m - 1][m - 1] * H[m - 1][m - 1] + H[m][m - 1] * H[m][m - 1]);
75
76 c.push_back(H[m - 1][m - 1] * izn);
77 s.push_back(H[m][m - 1] * izn);
78 gs *= -s[m - 1];
79
80 H[m - 1][m - 1] = c[m - 1] * H[m - 1][m - 1] + s[m - 1] * H[m][m - 1];
81 H[m][m - 1] = 0.0;
82
83 if (residualShow)
84 std::cout << "Iteration: " << m << ", residual = " << (fabs(gs) / nrmRhs) << std::endl;
85
86 fl = ((fabs(gs) / nrmRhs) < epsGMRES);
87 return fl;
88}
Here is the call graph for this function:

◆ PreCalculateCoef()

void GmresSolver::PreCalculateCoef ( int  aflIndex)

Definition at line 532 of file Gmres2D.cpp.

533{
534 Point2D p1, s1, p2, s2, di, dj;
535 numvector<double, 3> alpha, lambda;
536 numvector<Point2D, 3> v00, v11;
537 Point2D i00, i11;
538
539 const Airfoil& aflP = W.getAirfoil(aflIndex);
540
541 size_t nPanelsP = aflP.getNumberOfPanels();
543
544 for (size_t i = 0; i < nPanelsP; ++i)
545 {
546 std::array<int, 2> vecV = { ((int)i - 1 >= 0) ? int(i - 1) : int(nPanelsP - 1), (i + 1 < nPanelsP) ? int(i + 1) : 0 };
547 for (int j : vecV)
548 {
549 p1 = aflP.getR(i + 1) - aflP.getR(j + 1);
550 s1 = aflP.getR(i + 1) - aflP.getR(j);
551 p2 = aflP.getR(i) - aflP.getR(j + 1);
552 s2 = aflP.getR(i) - aflP.getR(j);
553 di = aflP.getR(i + 1) - aflP.getR(i);
554 dj = aflP.getR(j + 1) - aflP.getR(j);
555
556 alpha = { \
557 (aflP.isAfter(j, i)) ? 0.0 : VMlib::Alpha(s2, s1), \
558 VMlib::Alpha(s2, p1), \
559 (aflP.isAfter(i, j)) ? 0.0 : VMlib::Alpha(p1, p2) \
560 };
561
562 lambda = { \
563 (aflP.isAfter(j, i)) ? 0.0 : VMlib::Lambda(s2, s1), \
564 VMlib::Lambda(s2, p1), \
565 (aflP.isAfter(i, j)) ? 0.0 : VMlib::Lambda(p1, p2) \
566 };
567
568 v00 = {
569 VMlib::Omega(s1, di.unit(), dj.unit()),
570 -VMlib::Omega(di, di.unit(), dj.unit()),
571 VMlib::Omega(p2, di.unit(), dj.unit())
572 };
573
574 i00 = IDPI / di.length() * (-(alpha[0] * v00[0] + alpha[1] * v00[1] + alpha[2] * v00[2]).kcross() \
575 + (lambda[0] * v00[0] + lambda[1] * v00[1] + lambda[2] * v00[2]));
576
577 if (aflP.isAfter(j, i))
578 prec[aflIndex][i] = (i00.kcross()) * (1.0 / dj.length());
579 if (aflP.isAfter(i, j))
580 prea[aflIndex][i] = (i00.kcross()) * (1.0 / dj.length());
581
582 if (linScheme) {
583
584 v11 = { 1.0 / (12.0 * di.length() * dj.length()) * \
585 (2.0 * (s1 & Omega(s1 - 3.0 * p2, di.unit(), dj.unit())) * VMlib::Omega(s1, di.unit(), dj.unit()) - \
586 s1.length2() * (s1 - 3.0 * p2)) - 0.25 * VMlib::Omega(s1, di.unit(), dj.unit()),
587 -di.length() / (12.0 * dj.length()) * Omega(di, dj.unit(), dj.unit()),
588 -dj.length() / (12.0 * di.length()) * Omega(dj, di.unit(), di.unit()) };
589
590 i11 = (IDPI / di.length()) * ((alpha[0] + alpha[2]) * v11[0] + (alpha[1] + alpha[2]) * v11[1] + alpha[2] * v11[2]\
591 + ((lambda[0] + lambda[2]) * v11[0] + (lambda[1] + lambda[2]) * v11[1] + lambda[2] * v11[2] \
592 + 1.0 / 12.0 * (dj.length() * di.unit() + di.length() * dj.unit() - 2.0 * VMlib::Omega(s1, di.unit(), dj.unit()))).kcross());
593 if (aflP.isAfter(j, i))
594 prec1[aflIndex][i] = (i11) * (1.0 / dj.length());
595 if (aflP.isAfter(i, j))
596 prea1[aflIndex][i] = (i11) * (1.0 / dj.length());
597 }
598 }
599 }
600}
const double IDPI
Число .
Definition defs.h:79
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
Definition Airfoil2D.h:113
Абстрактный класс, определяющий обтекаемый профиль
Definition Airfoil2D.h:182
bool isAfter(size_t i, size_t j) const
Проверка, идет ли вершина i следом за вершиной j.
Definition Airfoil2D.cpp:76
Шаблонный класс, определяющий вектор фиксированной длины Фактически представляет собой массив,...
Definition numvector.h:99
numvector< T, 2 > kcross() const
Геометрический поворот двумерного вектора на 90 градусов
Definition numvector.h:511
auto length2() const -> typename std::remove_const< typename std::remove_reference< decltype(this->data[0])>::type >::type
Вычисление квадрата нормы (длины) вектора
Definition numvector.h:386
auto unit(P newlen=1) const -> numvector< typename std::remove_const< decltype(this->data[0] *newlen)>::type, n >
Вычисление орта вектора или вектора заданной длины, коллинеарного данному
Definition numvector.h:402
P length() const
Вычисление 2-нормы (длины) вектора
Definition numvector.h:374
double Lambda(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления логарифма отношения норм векторов
Definition defs.cpp:268
double Alpha(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления угла между векторами
Definition defs.cpp:262
Point2D Omega(const Point2D &a, const Point2D &b, const Point2D &c)
Вспомогательная функция вычисления величины .
Definition defs.cpp:274
Here is the call graph for this function:

◆ SolCircleRun()

void GmresSolver::SolCircleRun ( std::vector< double > &  AX,
const std::vector< double > &  rhs,
int  p 
)

Definition at line 390 of file Gmres2D.cpp.

391{
392 const Airfoil& afl = W.getAirfoil(p);
393 int n = (int)afl.getNumberOfPanels();
394 sweepVectors& sw = allSW[p];
396
397 std::vector<double>& alpha = sw.alpha;
398 std::vector<double>& beta = sw.beta;
399 std::vector<double>& delta = sw.delta;
400 std::vector<double>& phi = sw.phi;
401 std::vector<double>& xi = sw.xi;
402
403 double yn, a;
404
405 double len24 = afl.len[0] * 24.0;
406
407 alpha[1] = (afl.tau[0] & prec1[p][0]) * len24;
408 beta[1] = (afl.tau[0] & prea1[p][0]) * len24;
409 delta[1] = -len24 * rhs[n + 0];
410 double zn;
411
412 for (int i = 1; i < n - 1; ++i)
413 {
414 a = (afl.tau[i] & prea1[p][i]);
415 zn = a * alpha[i] - 1.0 / (24.0 * afl.len[i]);
416 alpha[i + 1] = -(afl.tau[i] & prec1[p][i]) / zn;
417 beta[i + 1] = -a * beta[i] / zn;
418 delta[i + 1] = (rhs[n + i] - a * delta[i]) / zn;
419 }
420
421 a = afl.tau[n - 2] & prea1[p][n - 2];
422 zn = alpha[n - 2] * a - 1.0 / (24.0 * afl.len[n - 2]);
423 phi[n - 1] = -((afl.tau[n - 2] & prec1[p][n - 2]) + beta[n - 2] * a) / zn;
424 xi[n - 1] = (rhs[n + n - 2] - delta[n - 2] * a) / zn;
425
426 for (int i = n - 2; i > 0; --i)
427 {
428 phi[i] = alpha[i] * phi[i + 1] + beta[i];
429 xi[i] = alpha[i] * xi[i + 1] + delta[i];
430 }
431
432
433 double e = (afl.tau[n - 1] & prec1[p][n - 1]);
434 a = (afl.tau[n - 1] & prea1[p][n - 1]);
435
436 yn = (rhs[n + n - 1] - e * xi[1] - a * xi[n - 1]) / (e * phi[1] + a * phi[n - 1] - 1.0 / (24.0 * afl.len[n - 1]));
437
438 AX[n + n - 1] = yn;
439 for (int i = n - 2; i >= 0; --i)
440 AX[n + i] = phi[i + 1] * yn + xi[i + 1];
441}
std::vector< double > len
Длины панелей профиля
Definition Airfoil2D.h:94
std::vector< Point2D > tau
Касательные к панелям профиля
Definition Airfoil2D.h:91
Структура, определяющий необходимые массивы для рализации метода прогонки
Definition Gmres2D.h:69
std::vector< double > phi
Definition Gmres2D.h:74
std::vector< double > beta
Definition Gmres2D.h:71
std::vector< double > delta
Definition Gmres2D.h:73
std::vector< double > alpha
Definition Gmres2D.h:70
std::vector< double > xi
Definition Gmres2D.h:75
Here is the call graph for this function:

◆ SolCircleRundirect()

void GmresSolver::SolCircleRundirect ( const std::vector< double > &  A,
const std::vector< double > &  rhs,
size_t  startRow,
size_t  startRowReg,
size_t  np,
std::vector< double > &  res 
)

Definition at line 91 of file Gmres2D.cpp.

92{
93 size_t nAllVars = rhs.size();
94 std::vector<double> alpha(np + 2), beta(np + 2), gamma(np + 2);
95 std::vector<double> u(np), v(np);
96
97 double zn = A[(startRow + np + 1) * nAllVars + (startRow + np + 1)];
98 alpha[2] = -A[(startRow + np + 1) * nAllVars + (startRow + np + 2)] / zn;
99 beta[2] = rhs[startRow + np + 1] / zn;
100 gamma[2] = -A[(startRow + np + 1) * nAllVars + (startRow + np + 0)] / zn;
101
102 for (size_t i = 2; i <= np; ++i)
103 {
104 zn = A[(startRow + np + (i % np)) * nAllVars + (startRow + np + (i % np))] + alpha[i] * A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i - 1) % np))];
105 alpha[i + 1] = -A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i + 1) % np))] / zn;
106 beta[i + 1] = (rhs[startRow + np + (i % np)] - beta[i] * A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i - 1) % np))]) / zn;
107 gamma[i + 1] = -(gamma[i] * A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i - 1) % np))]) / zn;
108 }
109
110 u[np - 1] = beta[np];
111 v[np - 1] = alpha[np] + gamma[np];
112 for (size_t i = np - 2; i >= 1; --i)
113 {
114 u[i] = alpha[i + 1] * u[i + 1] + beta[i + 1];
115 v[i] = alpha[i + 1] * v[i + 1] + gamma[i + 1];
116 }
117
118 res[startRow + np] = (beta[np + 1] + alpha[np + 1] * u[1]) / (1.0 - gamma[np + 1] - alpha[np + 1] * v[1]);
119 for (size_t i = 1; i < np; ++i)
120 res[startRow + np + i] = u[i] + res[startRow + np] * v[i];
121
122 return;
123}
Here is the caller graph for this function:

◆ SolM()

void GmresSolver::SolM ( std::vector< double > &  AX,
const std::vector< double > &  rhs,
int  p 
)

Definition at line 445 of file Gmres2D.cpp.

446{
447 const Airfoil& afl = W.getAirfoil(p);
448 int n = (int)afl.getNumberOfPanels();
449 sweepVectors& sw = allSW[p];
451
452 std::vector<double>& alpha = sw.alpha;
453 std::vector<double>& beta = sw.beta;
454 std::vector<double>& gamma = sw.gamma;
455 std::vector<double>& delta = sw.delta;
456 std::vector<double>& phi = sw.phi;
457 std::vector<double>& xi = sw.xi;
458 std::vector<double>& psi = sw.psi;
459
460 double yn, ynn;
461 double lam1, lam2, mu1, mu2, xi1, xi2;
462 double a;
463
464 double len2 = afl.len[0] * 2.0;
465
466 alpha[1] = (afl.tau[0] & prec[p][0]) * len2;
467 beta[1] = (afl.tau[0] & prea[p][0]) * len2;
468 gamma[1] = len2;
469 delta[1] = -len2 * rhs[0];
470
471 double zn;
472
473 for (int i = 1; i < n - 1; ++i)
474 {
475 a = (afl.tau[i] & prea[p][i]);
476 zn = a * alpha[i] - 0.5 / afl.len[i];
477 alpha[i + 1] = -(afl.tau[i] & prec[p][i]) / zn;
478 beta[i + 1] = -a * beta[i] / zn;
479 gamma[i + 1] = -(1.0 + a * gamma[i]) / zn;
480 delta[i + 1] = (rhs[i] - a * delta[i]) / zn;
481 }
482
483 a = afl.tau[n - 2] & prea[p][n - 2];
484 zn = alpha[n - 2] * a - 0.5 / afl.len[n - 2];
485 phi[n - 1] = -((afl.tau[n - 2] & prec[p][n - 2]) + beta[n - 2] * a) / zn;
486 psi[n - 1] = -(1.0 + gamma[n - 2] * a) / zn;
487 xi[n - 1] = (rhs[n - 2] - delta[n - 2] * a) / zn;
488
489 for (int i = n - 2; i > 0; --i)
490 {
491 phi[i] = alpha[i] * phi[i + 1] + beta[i];
492 psi[i] = alpha[i] * psi[i + 1] + gamma[i];
493 xi[i] = alpha[i] * xi[i + 1] + delta[i];
494 }
495
496 double e = (afl.tau[n - 1] & prec[p][n - 1]);
497 a = (afl.tau[n - 1] & prea[p][n - 1]);
498 lam1 = e * phi[1] + a * phi[n - 1] - 0.5 / afl.len[n - 1];
499 mu1 = e * psi[1] + a * psi[n - 1] + 1.0;
500 xi1 = rhs[n - 1] - e * xi[1] - a * xi[n - 1];
501 lam2 = mu2 = xi2 = 0.0;
502 for (int j = 0; j < n - 1; ++j)
503 {
504 lam2 += phi[j + 1];
505 mu2 += psi[j + 1];
506 xi2 -= xi[j + 1];
507 }
508 lam2 += 1.0;
509
510 if (!linScheme)
511 xi2 += rhs[n];
512 else if (linScheme)
513 xi2 += rhs[2 * n];
514
515 zn = lam1 * mu2 - lam2 * mu1;
516 yn = (xi1 * mu2 - xi2 * mu1) / zn;
517 ynn = -(xi1 * lam2 - xi2 * lam1) / zn;
518
519 if (!linScheme)
520 AX[n] = ynn;
521 else if (linScheme)
522 AX[2 * n] = ynn;
523
524 AX[n - 1] = yn;
525 for (int i = n - 2; i >= 0; --i)
526 AX[i] = phi[i + 1] * yn + psi[i + 1] * ynn + xi[i + 1];
527}
std::vector< double > psi
Definition Gmres2D.h:76
std::vector< double > gamma
Definition Gmres2D.h:72
Here is the call graph for this function:

◆ SolMdirect()

void GmresSolver::SolMdirect ( const std::vector< double > &  A,
const std::vector< double > &  rhs,
size_t  startRow,
size_t  startRowReg,
size_t  np,
std::vector< double > &  res,
bool  lin 
)

Definition at line 128 of file Gmres2D.cpp.

129{
130 std::vector<double> alpha(np), beta(np), gamma(np), delta(np), phi(np), xi(np), psi(np);
131 double yn, ynn;
132 double lam1, lam2, mu1, mu2, xi1, xi2;
133 double a;
134
135 size_t nAllVars = rhs.size();
136
137 double izn = 1.0 / A[(startRow + 0) * nAllVars + (startRow + 0)];
138 alpha[1] = -A[(startRow + 0) * nAllVars + (startRow + 1)] * izn;
139 beta[1] = -A[(startRow + 0) * nAllVars + (startRow + np - 1)] * izn;
140 gamma[1] = -A[(startRow + 0) * nAllVars + (startRowReg)] * izn;
141 delta[1] = rhs[startRow] * izn;
142 double zn;
143
144
145 for (size_t i = 1; i < np - 1; ++i)
146 {
147 a = A[(startRow + i) * nAllVars + (startRow + i - 1)];
148 zn = a * alpha[i] + A[(startRow + i) * nAllVars + (startRow + i)];
149 alpha[i + 1] = -A[(startRow + i) * nAllVars + (startRow + i + 1)] / zn;
150 beta[i + 1] = -a * beta[i] / zn;
151 gamma[i + 1] = -(A[(startRow + i) * nAllVars + (startRowReg)] + a * gamma[i]) / zn;
152 delta[i + 1] = (rhs[startRow + i] - a * delta[i]) / zn;
153 }
154
155 a = A[(startRow + (np - 2)) * nAllVars + (startRow + (np - 3))];
156 zn = alpha[np - 2] * a + A[(startRow + (np - 2)) * nAllVars + (startRow + (np - 2))];
157
158 phi[np - 1] = -(A[(startRow + np - 2) * nAllVars + (startRow + np - 1)] + a * beta[np - 2]) / zn;
159 psi[np - 1] = -(A[(startRow + np - 2) * nAllVars + (startRowReg)] + gamma[np - 2] * a) / zn;
160 xi[np - 1] = (rhs[startRow + np - 2] - delta[np - 2] * a) / zn;
161
162 for (size_t i = np - 2; i > 0; --i)
163 {
164 phi[i] = alpha[i] * phi[i + 1] + beta[i];
165 psi[i] = alpha[i] * psi[i + 1] + gamma[i];
166 xi[i] = alpha[i] * xi[i + 1] + delta[i];
167 }
168
169
170 double e = A[(startRow + np - 1) * nAllVars + (startRow + 0)];
171 a = A[(startRow + np - 1) * nAllVars + (startRow + np - 2)];
172 lam1 = e * phi[1] + a * phi[np - 1] + A[(startRow + np - 1) * nAllVars + (startRow + np - 1)];
173 mu1 = e * psi[1] + a * psi[np - 1] + A[(startRow + np - 1) * nAllVars + (startRowReg)];
174 xi1 = rhs[startRow + np - 1] - e * xi[1] - a * xi[np - 1];
175
176 lam2 = mu2 = xi2 = 0.0;
177 for (size_t j = 0; j < np - 1; ++j)
178 {
179 lam2 += phi[j + 1];
180 mu2 += psi[j + 1];
181 xi2 -= xi[j + 1];
182 }
183 lam2 += 1.0;
184
185 xi2 += rhs[startRowReg];
186
187 zn = lam1 * mu2 - lam2 * mu1;
188 yn = (xi1 * mu2 - xi2 * mu1) / zn;
189 ynn = -(xi1 * lam2 - xi2 * lam1) / zn;
190
191 res[startRowReg] = ynn;
192
193 res[startRow + np - 1] = yn;
194 for (size_t i = np - 2; i + 1 > 0; --i)
195 res[startRow + i] = phi[i + 1] * yn + psi[i + 1] * ynn + xi[i + 1];
196
197//
198 if (lin)
199 SolCircleRundirect(A, rhs, startRow, startRowReg, np, res);
200}
void SolCircleRundirect(const std::vector< double > &A, const std::vector< double > &rhs, size_t startRow, size_t startRowReg, size_t np, std::vector< double > &res)
Definition Gmres2D.cpp:91
Here is the call graph for this function:

Member Data Documentation

◆ allBuf2

std::vector<std::vector<double> > VM2D::GmresSolver::allBuf2
private

Definition at line 163 of file Gmres2D.h.

◆ allSW

std::vector<sweepVectors> VM2D::GmresSolver::allSW
private

Definition at line 162 of file Gmres2D.h.

◆ bufcurrentSol

std::vector<double> VM2D::GmresSolver::bufcurrentSol
private

Definition at line 166 of file Gmres2D.h.

◆ bufnewSol

std::vector<double> VM2D::GmresSolver::bufnewSol
private

Definition at line 166 of file Gmres2D.h.

◆ c

std::vector<double> VM2D::GmresSolver::c
private

Definition at line 156 of file Gmres2D.h.

◆ diag

std::vector<std::vector<double> > VM2D::GmresSolver::diag
private

Definition at line 158 of file Gmres2D.h.

◆ g

std::vector<double> VM2D::GmresSolver::g
private

Definition at line 167 of file Gmres2D.h.

◆ H

std::vector<std::vector<double> > VM2D::GmresSolver::H
private

Definition at line 158 of file Gmres2D.h.

◆ iterSize

const size_t VM2D::GmresSolver::iterSize = 100
private

Definition at line 172 of file Gmres2D.h.

◆ np

std::vector<size_t> VM2D::GmresSolver::np
private

Definition at line 164 of file Gmres2D.h.

◆ nTotPan

size_t VM2D::GmresSolver::nTotPan
private

Definition at line 170 of file Gmres2D.h.

◆ prea

std::vector<std::vector<Point2D> > VM2D::GmresSolver::prea
private

Definition at line 160 of file Gmres2D.h.

◆ prea1

std::vector<std::vector<Point2D> > VM2D::GmresSolver::prea1
private

Definition at line 160 of file Gmres2D.h.

◆ prec

std::vector<std::vector<Point2D> > VM2D::GmresSolver::prec
private

Definition at line 160 of file Gmres2D.h.

◆ prec1

std::vector<std::vector<Point2D> > VM2D::GmresSolver::prec1
private

Definition at line 160 of file Gmres2D.h.

◆ s

std::vector<double> VM2D::GmresSolver::s
private

Definition at line 156 of file Gmres2D.h.

◆ totalVsize

size_t VM2D::GmresSolver::totalVsize
private

Definition at line 169 of file Gmres2D.h.

◆ Vflat

std::vector<double> VM2D::GmresSolver::Vflat
private

Definition at line 157 of file Gmres2D.h.

◆ W

const World2D& VM2D::GmresSolver::W
private

Definition at line 148 of file Gmres2D.h.

◆ w

std::vector<double> VM2D::GmresSolver::w
private

Definition at line 156 of file Gmres2D.h.

◆ Y

std::vector<double> VM2D::GmresSolver::Y
private

Definition at line 167 of file Gmres2D.h.


The documentation for this class was generated from the following files: