57typedef Eigen::Map<const Eigen::VectorXd>
MapVec;
59bool VM2D::IterRot(std::vector<std::vector<double>>& H,
const double nrmRhs,
double& gs, std::vector<double>& c, std::vector<double>& s,
int m,
int n,
double epsGMRES,
int iter,
bool residualShow)
64 for (
int i = 0; i < m - 1; ++i)
68 H[i][m - 1] = c[i] * buf + s[i] * H[i + 1][m - 1];
69 H[i + 1][m - 1] = -s[i] * buf + c[i] * H[i + 1][m - 1];
72 double izn = 1.0 / sqrt(H[m - 1][m - 1] * H[m - 1][m - 1] + H[m][m - 1] * H[m][m - 1]);
74 c.push_back(H[m - 1][m - 1] * izn);
75 s.push_back(H[m][m - 1] * izn);
80 H[m - 1][m - 1] = c[m - 1] * H[m - 1][m - 1] + s[m - 1] * H[m][m - 1];
86 std::cout <<
"Iteration: " << iter <<
", residual = " << (fabs(gs) / nrmRhs) << std::endl;
88 fl = ((fabs(gs) / nrmRhs) < epsGMRES);
93void VM2D::SolCircleRundirect(
const std::vector<double>& A,
const std::vector<double>& rhs,
size_t startRow,
size_t startRowReg,
size_t np, std::vector<double>& res)
95 size_t nAllVars = rhs.size();
96 std::vector<double> alpha(np + 2), beta(np + 2), gamma(np + 2);
97 std::vector<double> u(np), v(np);
99 double zn = A[(startRow + np + 1) * nAllVars + (startRow + np + 1)];
100 alpha[2] = -A[(startRow + np + 1) * nAllVars + (startRow + np + 2)] / zn;
101 beta[2] = rhs[startRow + np + 1] / zn;
102 gamma[2] = -A[(startRow + np + 1) * nAllVars + (startRow + np + 0)] / zn;
104 for (
size_t i = 2; i <= np; ++i)
106 zn = A[(startRow + np + (i % np)) * nAllVars + (startRow + np + (i % np))] + alpha[i] * A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i - 1) % np))];
107 alpha[i + 1] = -A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i + 1) % np))] / zn;
108 beta[i + 1] = (rhs[startRow + np + (i % np)] - beta[i] * A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i - 1) % np))]) / zn;
109 gamma[i + 1] = -(gamma[i] * A[(startRow + np + (i % np)) * nAllVars + (startRow + np + ((i - 1) % np))]) / zn;
112 u[np - 1] = beta[np];
113 v[np - 1] = alpha[np] + gamma[np];
114 for (
size_t i = np - 2; i >= 1; --i)
116 u[i] = alpha[i + 1] * u[i + 1] + beta[i + 1];
117 v[i] = alpha[i + 1] * v[i + 1] + gamma[i + 1];
120 res[startRow + np] = (beta[np + 1] + alpha[np + 1] * u[1]) / (1.0 - gamma[np + 1] - alpha[np + 1] * v[1]);
121 for (
size_t i = 1; i < np; ++i)
122 res[startRow + np + i] = u[i] + res[startRow + np] * v[i];
130void VM2D::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)
132 std::vector<double> alpha(np), beta(np), gamma(np), delta(np), phi(np), xi(np), psi(np);
134 double lam1, lam2, mu1, mu2, xi1, xi2;
137 size_t nAllVars = rhs.size();
139 double izn = 1.0 / A[(startRow + 0) * nAllVars + (startRow + 0)];
140 alpha[1] = -A[(startRow + 0) * nAllVars + (startRow + 1)] * izn;
141 beta[1] = -A[(startRow + 0) * nAllVars + (startRow + np - 1)] * izn;
142 gamma[1] = -A[(startRow + 0) * nAllVars + (startRowReg)] * izn;
143 delta[1] = rhs[startRow] * izn;
147 for (
size_t i = 1; i < np - 1; ++i)
149 a = A[(startRow + i) * nAllVars + (startRow + i - 1)];
150 zn = a * alpha[i] + A[(startRow + i) * nAllVars + (startRow + i)];
151 alpha[i + 1] = -A[(startRow + i) * nAllVars + (startRow + i + 1)] / zn;
152 beta[i + 1] = -a * beta[i] / zn;
153 gamma[i + 1] = -(A[(startRow + i) * nAllVars + (startRowReg)] + a * gamma[i]) / zn;
154 delta[i + 1] = (rhs[startRow + i] - a * delta[i]) / zn;
157 a = A[(startRow + (np - 2)) * nAllVars + (startRow + (np - 3))];
158 zn = alpha[np - 2] * a + A[(startRow + (np - 2)) * nAllVars + (startRow + (np - 2))];
160 phi[np - 1] = -(A[(startRow + np - 2) * nAllVars + (startRow + np - 1)] + a * beta[np - 2]) / zn;
161 psi[np - 1] = -(A[(startRow + np - 2) * nAllVars + (startRowReg)] + gamma[np - 2] * a) / zn;
162 xi[np - 1] = (rhs[startRow + np - 2] - delta[np - 2] * a) / zn;
164 for (
size_t i = np - 2; i > 0; --i)
166 phi[i] = alpha[i] * phi[i + 1] + beta[i];
167 psi[i] = alpha[i] * psi[i + 1] + gamma[i];
168 xi[i] = alpha[i] * xi[i + 1] + delta[i];
172 double e = A[(startRow + np - 1) * nAllVars + (startRow + 0)];
173 a = A[(startRow + np - 1) * nAllVars + (startRow + np - 2)];
174 lam1 = e * phi[1] + a * phi[np - 1] + A[(startRow + np - 1) * nAllVars + (startRow + np - 1)];
175 mu1 = e * psi[1] + a * psi[np - 1] + A[(startRow + np - 1) * nAllVars + (startRowReg)];
176 xi1 = rhs[startRow + np - 1] - e * xi[1] - a * xi[np - 1];
178 lam2 = mu2 = xi2 = 0.0;
179 for (
size_t j = 0; j < np - 1; ++j)
187 xi2 += rhs[startRowReg];
189 zn = lam1 * mu2 - lam2 * mu1;
190 yn = (xi1 * mu2 - xi2 * mu1) / zn;
191 ynn = -(xi1 * lam2 - xi2 * lam1) / zn;
193 res[startRowReg] = ynn;
195 res[startRow + np - 1] = yn;
196 for (
size_t i = np - 2; i + 1 > 0; --i)
197 res[startRow + i] = phi[i + 1] * yn + psi[i + 1] * ynn + xi[i + 1];
210 const std::vector<double>& mtrDir,
211 const std::vector<double>& rhsDir,
212 const std::vector<int>& pos,
213 const std::vector<int>& vsize,
214 std::vector<std::vector<double>>& gam,
215 std::vector<double>& R)
217 const size_t maxIter = nAllVars + 1;
218 std::vector<double> x(nAllVars, 0.0);
219 std::vector<double> y(nAllVars, 0.0);
220 std::vector<double> residual(nAllVars, 0.0);
221 std::vector<double> r(nAllVars, 0.0);
222 std::vector<double> w(nAllVars, 0.0);
223 std::vector<double> wOld(nAllVars, 0.0);
224 std::vector<double> g(nAllVars, 0.0);
225 std::vector<double> c(nAllVars, 0.0);
226 std::vector<double> s(nAllVars, 0.0);
227 std::vector<double> hisGs(nAllVars + 1, 0.0);
228 std::vector<double> v(nAllVars * (maxIter + 1), 0.0);
230 std::vector<double> vecFromV(nAllVars, 0.0);
232 std::vector<double> h((nAllVars + 1) * maxIter, 0.0);
233 double beta = 0.0, gs, normb = 0.0;
236 for (
size_t i = 0; i < nAllVars; ++i)
237 normb += rhsDir[i] * rhsDir[i];
240 for (
size_t i = 0; i < nAllVars; ++i)
241 residual[i] = rhsDir[i];
243#pragma omp parallel for
244 for (
int aflI = 0; aflI < nafl; ++aflI)
250 for (
size_t i = 0; i < nAllVars; ++i)
259 for (
size_t aflI = 0; aflI < nafl; ++aflI)
261 for (
size_t i = 0; i < vsize[aflI]; ++i)
268 for (
size_t aflI = 0; aflI < nafl; ++aflI)
269 R[aflI] = x[x.size() - nafl + aflI];
271 for (
size_t i = 0; i < nAllVars; ++i)
272 v[i * (maxIter + 1) + 0] = r[i] / beta;
274 for (
size_t j = 0; j < nAllVars; ++j)
276 double timer1 = omp_get_wtime();
278 for (
size_t p = 0; p < nAllVars; ++p)
279 vecFromV[p] = v[p * (maxIter + 1) + j];
283 for (
int i = 0; i < nAllVars; ++i)
286 for (
int jj = 0; jj < nAllVars; ++jj)
288 wOld[i] += mtrDir[i * nAllVars + jj] * vecFromV[jj];
292 double timer2 = omp_get_wtime();
294#pragma omp parallel for
295 for (
int aflI = 0; aflI < nafl; ++aflI)
301 for (
size_t i = 0; i <= j; ++i)
303 h[i * maxIter + j] = 0.0;
304 for (
size_t q = 0; q < nAllVars; ++q)
305 h[i * maxIter + j] += w[q] * v[q * (maxIter + 1) + i];
307 for (
size_t q = 0; q < nAllVars; ++q)
308 w[q] -= h[i * maxIter + j] * v[q * (maxIter + 1) + i];
311 h[(j + 1) * maxIter + j] = 0.0;
312 for (
size_t p = 0; p < nAllVars; ++p)
313 h[(j + 1) * maxIter + j] += w[p] * w[p];
314 h[(j + 1) * maxIter + j] = sqrt(h[(j + 1) * maxIter + j]);
316 for (
size_t p = 0; p < nAllVars; ++p)
317 v[p * (maxIter + 1) + (j + 1)] = w[p] / h[(j + 1) * maxIter + j];
319 for (
size_t i = 0; i < j; ++i)
321 double buf = h[i * maxIter + j];
322 h[i * maxIter + j] = c[i] * buf + s[i] * h[(i + 1) * maxIter + j];
323 h[(i + 1) * maxIter + j] = -s[i] * buf + c[i] * h[(i + 1) * maxIter + j];
326 double zn = sqrt(h[j * maxIter + j] * h[j * maxIter + j] + h[(j + 1) * maxIter + j] * h[(j + 1) * maxIter + j]);
327 c[j] = fabs(h[j * maxIter + j] / zn);
328 s[j] = c[j] * h[(j + 1) * maxIter + j] / h[j * maxIter + j];
332 h[j * maxIter + j] = c[j] * h[j * maxIter + j] + s[j] * h[(j + 1) * maxIter + j];
333 h[(j + 1) * maxIter + j] = 0.0;
334 hisGs[j] = fabs(gs) / normb;
344 for (
size_t i = 0; i < m; ++i)
349 g[i + 1] = -s[i] * buf;
352 y[m - 1] = g[m - 1] / h[(m - 1) * maxIter + (m - 1)];
354 for (
size_t i = m - 2; i + 1 > 0; --i)
357 for (
size_t j = i + 1; j < m; ++j)
358 sum += h[i * maxIter + j] * y[j];
360 y[i] = (g[i] - sum) / h[i * maxIter + i];
363 for (
size_t p = 0; p < nAllVars; ++p)
365 for (
size_t q = 0; q < m; ++q)
366 x[p] += v[p * (maxIter + 1) + q] * y[q];
369 std::cout <<
"#iterations: " << m << std::endl;
371 for (
size_t aflI = 0; aflI < nafl; ++aflI)
373 for (
size_t i = 0; i < vsize[aflI]; ++i)
374 gam[aflI][i] = x[pos[aflI] + i];
377 for (
size_t aflI = 0; aflI < nafl; ++aflI)
378 R[aflI] = x[x.size() - nafl + aflI];
393void VM2D::SolCircleRun(std::vector<double>& AX,
const std::vector<double>& rhs,
const Airfoil& afl,
const std::vector<std::vector<Point2D>>& prea1,
const std::vector<std::vector<Point2D>>& prec1,
int p,
int n,
sweepVectors& sw)
396 std::vector<double>& alpha = sw.
alpha;
397 std::vector<double>& beta = sw.
beta;
398 std::vector<double>& delta = sw.
delta;
399 std::vector<double>& phi = sw.
phi;
400 std::vector<double>& xi = sw.
xi;
404 double len24 = afl.
len[0] * 24.0;
406 alpha[1] = (afl.
tau[0] & prec1[p][0]) * len24;
407 beta[1] = (afl.
tau[0] & prea1[p][0]) * len24;
408 delta[1] = -len24 * rhs[n + 0];
411 for (
int i = 1; i < n - 1; ++i)
413 a = (afl.
tau[i] & prea1[p][i]);
414 zn = a * alpha[i] - 1.0 / (24.0 * afl.
len[i]);
415 alpha[i + 1] = -(afl.
tau[i] & prec1[p][i]) / zn;
416 beta[i + 1] = -a * beta[i] / zn;
417 delta[i + 1] = (rhs[n + i] - a * delta[i]) / zn;
420 a = afl.
tau[n - 2] & prea1[p][n - 2];
421 zn = alpha[n - 2] * a - 1.0 / (24.0 * afl.
len[n - 2]);
422 phi[n - 1] = -((afl.
tau[n - 2] & prec1[p][n - 2]) + beta[n - 2] * a) / zn;
423 xi[n - 1] = (rhs[n + n - 2] - delta[n - 2] * a) / zn;
425 for (
int i = n - 2; i > 0; --i)
427 phi[i] = alpha[i] * phi[i + 1] + beta[i];
428 xi[i] = alpha[i] * xi[i + 1] + delta[i];
432 double e = (afl.
tau[n - 1] & prec1[p][n - 1]);
433 a = (afl.
tau[n - 1] & prea1[p][n - 1]);
435 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]));
438 for (
int i = n - 2; i >= 0; --i)
439 AX[n + i] = phi[i + 1] * yn + xi[i + 1];
445 const std::vector<std::vector<Point2D>>& prea,
const std::vector<std::vector<Point2D>>& prec,
int p,
int n,
bool linScheme,
sweepVectors& sw)
448 std::vector<double>& alpha = sw.
alpha;
449 std::vector<double>& beta = sw.
beta;
450 std::vector<double>& gamma = sw.
gamma;
451 std::vector<double>& delta = sw.
delta;
452 std::vector<double>& phi = sw.
phi;
453 std::vector<double>& xi = sw.
xi;
454 std::vector<double>& psi = sw.
psi;
457 double lam1, lam2, mu1, mu2, xi1, xi2;
460 double len2 = afl.
len[0] * 2.0;
462 alpha[1] = (afl.
tau[0] & prec[p][0]) * len2;
463 beta[1] = (afl.
tau[0] & prea[p][0]) * len2;
465 delta[1] = -len2 * rhs[0];
469 for (
int i = 1; i < n - 1; ++i)
471 a = (afl.
tau[i] & prea[p][i]);
472 zn = a * alpha[i] - 0.5 / afl.
len[i];
473 alpha[i + 1] = -(afl.
tau[i] & prec[p][i]) / zn;
474 beta[i + 1] = -a * beta[i] / zn;
475 gamma[i + 1] = -(1.0 + a * gamma[i]) / zn;
476 delta[i + 1] = (rhs[i] - a * delta[i]) / zn;
479 a = afl.
tau[n - 2] & prea[p][n - 2];
480 zn = alpha[n - 2] * a - 0.5 / afl.
len[n - 2];
481 phi[n - 1] = -((afl.
tau[n - 2] & prec[p][n - 2]) + beta[n - 2] * a) / zn;
482 psi[n - 1] = -(1.0 + gamma[n - 2] * a) / zn;
483 xi[n - 1] = (rhs[n - 2] - delta[n - 2] * a) / zn;
485 for (
int i = n - 2; i > 0; --i)
487 phi[i] = alpha[i] * phi[i + 1] + beta[i];
488 psi[i] = alpha[i] * psi[i + 1] + gamma[i];
489 xi[i] = alpha[i] * xi[i + 1] + delta[i];
492 double e = (afl.
tau[n - 1] & prec[p][n - 1]);
493 a = (afl.
tau[n - 1] & prea[p][n - 1]);
494 lam1 = e * phi[1] + a * phi[n - 1] - 0.5 / afl.
len[n - 1];
495 mu1 = e * psi[1] + a * psi[n - 1] + 1.0;
496 xi1 = rhs[n - 1] - e * xi[1] - a * xi[n - 1];
497 lam2 = mu2 = xi2 = 0.0;
498 for (
int j = 0; j < n - 1; ++j)
511 zn = lam1 * mu2 - lam2 * mu1;
512 yn = (xi1 * mu2 - xi2 * mu1) / zn;
513 ynn = -(xi1 * lam2 - xi2 * lam1) / zn;
521 for (
int i = n - 2; i >= 0; --i)
522 AX[i] = phi[i + 1] * yn + psi[i + 1] * ynn + xi[i + 1];
531std::vector<Point2D> & prea,
532std::vector<Point2D>& prec,
533std::vector<Point2D>& prea1,
534std::vector<Point2D>& prec1,
537 Point2D p1, s1, p2, s2, di, dj;
542 for (
size_t i = 0; i < nPanelsP; ++i)
544 std::array<int, 2> vecV = { ((int)i - 1 >= 0) ? int(i - 1) : int(nPanelsP - 1), (i + 1 < nPanelsP) ?
int(i + 1) : 0 };
547 p1 = aflP.
getR(i + 1) - aflP.
getR(j + 1);
548 s1 = aflP.
getR(i + 1) - aflP.
getR(j);
549 p2 = aflP.
getR(i) - aflP.
getR(j + 1);
551 di = aflP.
getR(i + 1) - aflP.
getR(i);
552 dj = aflP.
getR(j + 1) - aflP.
getR(j);
556 VMlib::Alpha(s2, p1), \
562 VMlib::Lambda(s2, p1), \
572 i00 =
IDPI / di.
length() * (-(alpha[0] * v00[0] + alpha[1] * v00[1] + alpha[2] * v00[2]).kcross() \
573 + (lambda[0] * v00[0] + lambda[1] * v00[1] + lambda[2] * v00[2]));
588 i11 = (
IDPI / di.
length()) * ((alpha[0] + alpha[2]) * v11[0] + (alpha[1] + alpha[2]) * v11[1] + alpha[2] * v11[2]\
589 + ((lambda[0] + lambda[2]) * v11[0] + (lambda[1] + lambda[2]) * v11[1] + lambda[2] * v11[2] \
592 prec1[i] = (i11) * (1.0 / dj.
length());
594 prea1[i] = (i11) * (1.0 / dj.
length());
602#include <cublas_v2.h>
604void VM2D::GMRES(
const World2D& W,
605 std::vector<std::vector<double>>& X,
606 std::vector<double>& R,
607 const std::vector<std::vector<double>>& rhs,
608 const std::vector<double> rhsReg,
612 VMlib::vmTimer tAll(
"All"), tPre(
"Pre"), tIter(
"Iter"), tPost(
"Post"), tIter1(
"Iter1"), tIterOther(
"IterOther"),
613 tCG(
"tCG"), tGC(
"tGC"), tWrapper(
"tWrapper"), tSplit(
"tSplit"), tPrecond(
"tPrecond"), tRot(
"tRot"),
614 tRotA(
"tRotA"), tRotB(
"tRotB"), tRotC(
"tRotC"), tRotD(
"tRotD");
616 cublasHandle_t cublas_handle;
617 cublasCreate(&cublas_handle);
621 size_t totalVsize = 0;
622 for (
size_t i = 0; i < nAfl; ++i)
626 for (
size_t s = 0; s < nAfl; ++s)
633 const size_t iterSize = 50;
635 double* devViBund, *devw;
636 cudaMalloc((
void**)&devViBund, (totalVsize + nAfl) *
sizeof(
double) * iterSize);
637 cudaMalloc((
void**)&devw, (totalVsize + nAfl) *
sizeof(
double));
640 cudaMalloc(&mulptr, iterSize *
sizeof(
double));
641 std::vector<double> mul(iterSize);
649 std::vector<double> w(totalVsize + nAfl), c, s;
653 std::vector<double> Vflat;
654 Vflat.reserve((totalVsize + nAfl) * iterSize);
656 std::vector<std::vector<double>> H, diag(nAfl);
657 H.resize(iterSize + 1);
658 for (
int i = 0; i < iterSize + 1; ++i)
659 H[i].resize(iterSize);
661 for (
int p = 0; p < (int)nAfl; ++p)
665 diag[p].resize(nPanelsP);
667 diag[p].resize(2 * nPanelsP);
669 for (
int i = 0; i < nPanelsP; ++i)
672 diag[p][i] = 0.5 / lenI;
675 diag[p][i + nPanelsP] = (1.0 / 24.0) / lenI;
680#pragma omp parallel for reduction(+:nrmRhs)
681 for (
int p = 0; p < (int)nAfl; ++p)
682 nrmRhs +=
norm2(rhs[p]);
683 nrmRhs = sqrt(nrmRhs);
685 std::vector<std::vector<double>> residual(nAfl);
686 for (
size_t p = 0; p < nAfl; ++p)
687 residual[p] = rhs[p];
689 for (
size_t i = 0; i < nAfl; ++i)
690 Vflat.insert(Vflat.end(), residual[i].begin(), residual[i].end());
692 for (
size_t i = 0; i < nAfl; ++i)
693 Vflat.push_back(rhsReg[i]);
696 std::vector<std::vector<Point2D>> prea(nAfl), prec(nAfl), prea1(nAfl), prec1(nAfl);
698 for (
size_t p = 0; p < nAfl; ++p)
703 prea[p].resize(nPanelsP);
704 prec[p].resize(nPanelsP);
705 prea1[p].resize(nPanelsP);
706 prec1[p].resize(nPanelsP);
711 std::vector<sweepVectors> allSW(nAfl);
712 std::vector<std::vector<double>> allBuf2(nAfl);
713 std::vector<size_t> np(nAfl, 0);
715 for (
size_t p = 0; p < nAfl; ++p)
719 allSW[p].resize(nPanelsP);
722 allBuf2[p].resize(nPanelsP + 1);
724 allBuf2[p].resize(2 * nPanelsP + 1);
736#pragma omp parallel for
737 for (
int p = 0; p < (int)nAfl; ++p)
739 std::vector<double>& vbuf1 = allBuf2[p];
742 for (
size_t i = 0; i < nPanelsP; ++i)
744 vbuf1[i] = Vflat[np[p] + i];
746 vbuf1[i + nPanelsP] = Vflat[np[p] + nPanelsP + i];
750 vbuf1[nPanelsP] = Vflat[(totalVsize + nAfl) - (nAfl - p)];
752 vbuf1[2 * nPanelsP] = Vflat[(totalVsize + nAfl) - (nAfl - p)];
762 for (
size_t j = np[p]; j < np[p] + nPanelsP; ++j)
764 Vflat[j] = vbuf1[j - np[p]];
766 Vflat[j + nPanelsP] = vbuf1[j - np[p] + nPanelsP];
768 Vflat[(totalVsize + nAfl) - (nAfl - p)] = vbuf1[vbuf1.size() - 1];
772 for (
int t = 0; t < (totalVsize + nAfl); ++t)
773 beta += Vflat[t] * Vflat[t];
778 for (
int t = 0; t < (totalVsize + nAfl); ++t)
787 cublasDestroy(cublas_handle);
793 std::vector<double> bufnewSol((
linScheme ? 2 : 1) * nTotPan), bufcurrentSol(totalVsize, 0.0);
796 treePnlInfl.MemoryAllocateForGMRES();
804 double* dev_ptr_rhs = W.
getAirfoil(0).devRhsPtr;
807 const double zero = 0.0, unit = 1.0;
814 for (
int j = 0; j < totalVsize - 1; ++j)
827#pragma omp parallel for
829 bufcurrentSol[npred + p] = Vflat[(totalVsize + nAfl)*(j) + npred + p] / W.
getAirfoil(i).
len[p];
837#pragma omp parallel for
840 bufcurrentSol[npred + p] = Vflat[(totalVsize + nAfl) * j + (2 * npred + p)] / W.
getAirfoil(i).
len[p];
858 treePnlInfl.UpwardTraversal(order);
859 treePnlInfl.DownwardTraversalGMRES(dev_ptr_rhs, dev_ptr_rhsLin, theta, order, j);
867 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhs, w.data(), 22);
871 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhs, bufnewSol.data(), 22);
872 W.
getCuda().CopyMemFromDev<double, 1>(nTotPan, dev_ptr_rhsLin, bufnewSol.data() + nTotPan, 22);
883#pragma omp parallel for
886 w[2 * npred + j] = bufnewSol[npred + j];
893 for (
size_t pi = 0; pi < nAfl; ++pi)
896#pragma omp parallel for
897 for (
int i = 0; i < (int)nPanelsPi; ++i)
899 w[cntr + i] += Vflat[(totalVsize + nAfl) * j + (totalVsize + pi)] - Vflat[(totalVsize + nAfl) * j + (cntr + i)] * diag[pi][i];
901 w[cntr + i + nPanelsPi] += -Vflat[(totalVsize + nAfl) * j + (cntr + i + nPanelsPi)] * diag[pi][i + nPanelsPi];
909 for (
size_t i = 0; i < nAfl; ++i)
910 w[totalVsize + i] = 0.0;
913 for (
size_t i = 0; i < nAfl; ++i)
916 for (
size_t k = 0; k < nPanelsI; ++k)
917 w[totalVsize + i] += Vflat[(totalVsize + nAfl) * j + (cntr + k)];
928#pragma omp parallel for
929 for (
int p = 0; p < (int)nAfl; ++p)
931 std::vector<double>& vbuf2 = allBuf2[p];
935 for (
size_t i = 0; i < nPanelsP; ++i)
937 vbuf2[i] = w[np[p] + i];
939 vbuf2[i + nPanelsP] = w[np[p] + nPanelsP + i];
943 vbuf2[nPanelsP] = w[w.size() - (nAfl - p)];
945 vbuf2[2 * nPanelsP] = w[w.size() - (nAfl - p)];
954 for (
size_t j = np[p]; j < np[p] + nPanelsP; ++j)
956 w[j] = vbuf2[j - np[p]];
958 w[j + nPanelsP] = vbuf2[j - np[p] + nPanelsP];
961 w[w.size() - (nAfl - p)] = vbuf2[vbuf2.size() - 1];
971 if (j == H.size() - 1)
974 for (
int i = 0; i < j * 2 + 2; ++i)
975 H[i].resize(j * 2 + 1);
977 Vflat.reserve((totalVsize + nAfl) * j * 2);
983 cudaMalloc((
void**)&mulptr, j * 2 *
sizeof(
double));
985 double* devViBund_new;
986 cudaMalloc((
void**)&devViBund_new, (totalVsize + nAfl) * j * 2 *
sizeof(
double));
987 cudaMemcpy(devViBund_new, devViBund, (totalVsize + nAfl) * j *
sizeof(
double), cudaMemcpyDeviceToDevice);
989 devViBund = devViBund_new;
995 cudaMemcpy(devViBund + w.size() * j, Vflat.data() + w.size() * j, (1) * w.size() *
sizeof(
double), cudaMemcpyHostToDevice);
996 cudaMemcpy(devw, w.data(), w.size() *
sizeof(
double), cudaMemcpyHostToDevice);
998 cublasDgemv(cublas_handle, CUBLAS_OP_T, (
int)w.size(), (
int)Vflat.size() / (
int)w.size(), &unit, devViBund, (
int)w.size(), devw, 1, &zero, mulptr, 1);
999 cudaMemcpy(mul.data(), mulptr, (j+1) *
sizeof(
double), cudaMemcpyDeviceToHost);
1001 for (
int i = 0; i <= j; ++i)
1008 cublasDaxpy(cublas_handle, \
1011 devViBund + w.size() * i, 1, \
1018 cudaMemcpy(w.data(), devw, w.size() *
sizeof(
double), cudaMemcpyDeviceToHost);
1035 Vflat.insert(Vflat.end(), w.begin(), w.end());
1036 for (
int t = 0; t < (totalVsize + nAfl); ++t)
1037 Vflat[Vflat.size() - t - 1] /= nrmw;
1045 std::cout <<
"iterations in GMRES = " << j + 1 << std::endl;
1071 std::vector<double> g(m + 1);
1076 for (
int i = 0; i < m; i++)
1079 g[i] = c[i] * oldValue;
1080 g[i + 1] = -s[i] * oldValue;
1085 std::vector<double> Y(m);
1086 Y[m - 1] = g[m - 1] / H[m - 1][m - 1];
1089 for (
int k = (
int)m - 2; k >= 0; --k)
1092 for (
int s = k + 1; s < m; ++s)
1093 sum += H[k][s] * Y[s];
1094 Y[k] = (g[k] - sum) / H[k][k];
1099 for (
size_t p = 0; p < nAfl; p++) {
1104 for (
size_t i = 0; i < nPanelsP; i++)
1107 for (
size_t j = 0; j < m; j++)
1108 sum += Vflat[(totalVsize + nAfl) * j + (i + cntr)] * Y[j];
1112 for (
size_t i = 0; i < 2 * nPanelsP; i++)
1115 for (
size_t j = 0; j < m; j++)
1116 sum += Vflat[(totalVsize + nAfl) * j + (i + cntr)] * Y[j];
1127 for (
size_t p = 0; p < nAfl; p++)
1129 for (
size_t j = 0; j < m; j++)
1130 sum += Vflat[(totalVsize + nAfl) * j + (totalVsize + p)] * Y[j];
1139 treePnlInfl.MemoryFreeForGMRES();
1140 cudaFree(devViBund);
1144 cublasDestroy(cublas_handle);
Заголовочный файл с описанием класса Airfoil.
Заголовочный файл с описанием класса Boundary.
void PreCalculateCoef(const Airfoil &aflP, size_t nPanelsP, std::vector< Point2D > &prea, std::vector< Point2D > &prec, std::vector< Point2D > &prea1, std::vector< Point2D > &prec1, bool linScheme)
Eigen::Map< const Eigen::VectorXd > MapVec
Заголовочный файл с функциями для метода GMRES.
Заголовочный файл с описанием класса MeasureVP.
Заголовочный файл с описанием класса Mechanics.
Заголовочный файл с описанием класса Preprocessor.
Заголовочный файл с описанием класса StreamParser.
Заголовочный файл с описанием класса Velocity.
Заголовочный файл с описанием класса Wake.
Заголовочный файл с описанием класса World2D.
std::vector< double > len
Длины панелей профиля
const Point2D & getR(size_t q) const
Возврат константной ссылки на вершину профиля
std::vector< Point2D > tau
Касательные к панелям профиля
size_t getNumberOfPanels() const
Возврат количества панелей на профиле
Абстрактный класс, определяющий обтекаемый профиль
bool isAfter(size_t i, size_t j) const
Проверка, идет ли вершина i следом за вершиной j.
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
Класс, опеделяющий текущую решаемую задачу
size_t getNumberOfAirfoil() const
Возврат количества профилей в задаче
const Airfoil & getAirfoil(size_t i) const
Возврат константной ссылки на объект профиля
Gpu & getNonConstCuda() const
Возврат неконстантной ссылки на объект, связанный с видеокартой (GPU)
const Gpu & getCuda() const
Возврат константной ссылки на объект, связанный с видеокартой (GPU)
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Шаблонный класс, определяющий вектор фиксированной длины Фактически представляет собой массив,...
numvector< T, 2 > kcross() const
Геометрический поворот двумерного вектора на 90 градусов
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-нормы (длины) вектора
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)
double norm(const std::vector< T > &b)
Шаблонная функция вычисления евклидовой нормы вектора или списка
void SolCircleRun(std::vector< double > &AX, const std::vector< double > &rhs, const Airfoil &afl, const std::vector< std::vector< Point2D > > &prea1, const std::vector< std::vector< Point2D > > &prec1, int p, int n, sweepVectors &sw)
bool IterRot(std::vector< std::vector< double > > &H, const double nrmRhs, double &gs, std::vector< double > &c, std::vector< double > &s, int m, int n, double epsGMRES, int iter, bool residualShow)
Контроль невязки после выполнения очередной итерации GMRES.
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 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 SolM(std::vector< double > &AX, const std::vector< double > &rhs, const Airfoil &afl, const std::vector< std::vector< Point2D > > &prea, const std::vector< std::vector< Point2D > > &prec, int p, int n, bool linScheme, sweepVectors &sw)
double norm2(const std::vector< T > &b)
Шаблонная функция вычисления евклидовой нормы вектора или списка
double Lambda(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления логарифма отношения норм векторов
double Alpha(const Point2D &p, const Point2D &s)
Вспомогательная функция вычисления угла между векторами
Point2D Omega(const Point2D &a, const Point2D &b, const Point2D &c)
Вспомогательная функция вычисления величины .
Структура, определяющий необходимые массивы для рализации метода прогонки
std::vector< double > phi
std::vector< double > beta
std::vector< double > psi
std::vector< double > delta
std::vector< double > alpha
std::vector< double > gamma