VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
VM2D Namespace Reference

Classes

class  Airfoil
 Абстрактный класс, определяющий обтекаемый профиль More...
 
class  AirfoilDeformable
 Класс, определяющий тип обтекаемого профиля More...
 
class  AirfoilGeometry
 Класс, определяющий форму профиля More...
 
struct  AirfoilParams
 
class  AirfoilRigid
 Класс, определяющий тип обтекаемого профиля More...
 
class  Beam
 Вспомогательный класс Beam для описания упругой хорды деформируемой балки More...
 
class  Boundary
 Абстрактный класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле More...
 
class  BoundaryConstLayerAver
 Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле More...
 
class  BoundaryLinLayerAver
 Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле More...
 
class  BoundaryVortexCollocN
 Класс, определяющий способ удовлетворения граничного условия на обтекаемом профиле More...
 
struct  ChordPanel
 
class  CpuTreeInfo
 Структура, хранящая данные и указатели на массивы на GPU для оптимизации итерационного решения СЛАУ на GPU. More...
 
class  Gpu
 Класс, обеспечивающий возможность выполнения вычислений на GPU по технологии Nvidia CUDA. More...
 
class  MeasureVP
 Класс, отвечающий за вычисление поля скорости и давления в заданых точках для вывода More...
 
class  Mechanics
 Абстрактный класс, определяющий вид механической системы More...
 
class  MechanicsDeformable
 Класс, определяющий вид механической системы More...
 
class  MechanicsRigidGivenLaw
 Класс, определяющий вид механической системы More...
 
class  MechanicsRigidImmovable
 Класс, определяющий вид механической системы More...
 
class  MechanicsRigidOscillPart
 Класс, определяющий вид механической системы More...
 
class  MechanicsRigidRotatePart
 Класс, определяющий вид механической системы More...
 
struct  NumericalSchemes
 Структура, задающая используемые численные схемы More...
 
class  Passport
 
struct  PhysicalProperties
 Структура, задающая физические свойства задачи More...
 
class  Sheet
 Класс, опеделяющий слои на поверхности обтекаемого профиля More...
 
struct  sweepVectors
 Структура, определяющий необходимые массивы для рализации метода прогонки More...
 
class  Velocity
 Абстрактный класс, определяющий способ вычисления скоростей More...
 
class  VelocityBarnesHut
 Класс, определяющий способ вычисления скоростей More...
 
class  VelocityBiotSavart
 Класс, определяющий способ вычисления скоростей More...
 
class  VirtualWake
 Класс, опеделяющий вихревой след (пелену) More...
 
struct  VortexesParams
 Структура, определяющая параметры виртуальных вихрей для отдельного профиля More...
 
class  Wake
 Класс, опеделяющий вихревой след (пелену) More...
 
class  WakeDataBase
 Класс, опеделяющий набор вихрей More...
 
struct  WakeDiscretizationProperties
 
class  World2D
 Класс, опеделяющий текущую решаемую задачу More...
 

Functions

template<typename T >
double norm (const std::vector< T > &b)
 Шаблонная функция вычисления евклидовой нормы вектора или списка
 
template<typename T >
double norm2 (const std::vector< T > &b)
 Шаблонная функция вычисления евклидовой нормы вектора или списка
 
template<typename T >
std::vector< T > operator* (const T lambda, const std::vector< T > &x)
 Шаблонная функция умножения числа на вектор
 
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 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 (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 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)
 
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)
 
unsigned int ExpandBits (unsigned int v)
 
int ceilpow2 (int x, int p)
 
int ceilhalf (int x)
 

Function Documentation

◆ ceilhalf()

int VM2D::ceilhalf ( int  x)
inline

Definition at line 84 of file cpuTreeInfo.cpp.

85 {
86 return (x >> 1) + (x & 1);
87 }
Here is the caller graph for this function:

◆ ceilpow2()

int VM2D::ceilpow2 ( int  x,
int  p 
)
inline

Definition at line 78 of file cpuTreeInfo.cpp.

79 {
80 return (x >> p) + !!(x & ((1 << p) - 1));
81 }
Here is the caller graph for this function:

◆ ExpandBits()

unsigned int VM2D::ExpandBits ( unsigned int  v)
inline

Definition at line 48 of file cpuTreeInfo.cpp.

49 {
50 // вставит 1 нуль
51 v = (v | (v << 8)) & 0x00FF00FF; // 00000000`00000000`abcdefgh`ijklmnop
52 // | 00000000`abcdefgh`ijklmnop`00000000
53 // = 00000000`abcdefgh`XXXXXXXX`ijklmnop
54 // & 00000000`11111111`00000000`11111111
55 // = 00000000`abcdefgh`00000000`ijklmnop
56
57 v = (v | (v << 4)) & 0x0F0F0F0F; // 00000000`abcdefgh`00000000`ijklmnop
58 // | 0000abcd`efgh0000`0000ijkl`mnop0000
59 // = 0000abcd`XXXXefgh`0000ijkl`XXXXmnop
60 // & 00001111`00001111`00001111`00001111
61 // = 0000abcd`0000efgh`0000ijkl`0000mnop
62
63 v = (v | (v << 2)) & 0x33333333; // 0000abcd`0000efgh`0000ijkl`0000mnop
64 // | 00abcd00`00efgh00`00ijkl00`00mnop00
65 // = 00abXXcd`00efXXgh`00ijXXkl`00mnXXop
66 // & 00110011`00110011`00110011`00110011
67 // = 00ab00cd`00ef00gh`00ij00kl`00mn00op
68
69 v = (v | (v << 1)) & 0x55555555; // 00ab00cd`00ef00gh`00ij00kl`00mn00op
70 // | 0ab00cd0`0ef00gh0`0ij00kl0`0mn00op0
71 // = 0aXb0cXd`0eXf0gXh`0iXj0kXl`0mXn0oXp
72 // & 01010101`01010101`01010101`01010101
73 // = 0a0b0c0d`0e0f0g0h`0i0j0k0l`0m0n0o0p
74 return v;
75 }
Here is the caller graph for this function:

◆ GMRES_Direct()

void VM2D::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 
)

Definition at line 206 of file Gmres2D.cpp.

216{
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);
229
230 std::vector<double> vecFromV(nAllVars, 0.0);
231
232 std::vector<double> h((nAllVars + 1) * maxIter, 0.0);
233 double beta = 0.0, gs, normb = 0.0;
234 size_t m = 0;
235
236 for (size_t i = 0; i < nAllVars; ++i)
237 normb += rhsDir[i] * rhsDir[i];
238 normb = sqrt(normb);
239
240 for (size_t i = 0; i < nAllVars; ++i)
241 residual[i] = rhsDir[i];
242
243#pragma omp parallel for
244 for (int aflI = 0; aflI < nafl; ++aflI)
245 {
246 // SolMdirect(mtrDir, residual, pos[aflI], nAllVars - nafl + aflI, W.getAirfoil(aflI).getNumberOfPanels(), r, (vsize[aflI] == 2*n[aflI]));
247 r = residual;
248 }
249
250 for (size_t i = 0; i < nAllVars; ++i)
251 beta += r[i] * r[i];
252 beta = sqrt(beta);
253 gs = beta;
254 g[0] = beta;
255
256 // ,
257 if (beta == 0)
258 {
259 for (size_t aflI = 0; aflI < nafl; ++aflI)
260 {
261 for (size_t i = 0; i < vsize[aflI]; ++i)
262 gam[aflI][i] = 0.0;
263 R[aflI] = 0.0;
264 }
265 return;
266 }
267
268 for (size_t aflI = 0; aflI < nafl; ++aflI)
269 R[aflI] = x[x.size() - nafl + aflI];
270
271 for (size_t i = 0; i < nAllVars; ++i)
272 v[i * (maxIter + 1) + 0] = r[i] / beta;
273
274 for (size_t j = 0; j < nAllVars; ++j)
275 {
276 double timer1 = omp_get_wtime();
277
278 for (size_t p = 0; p < nAllVars; ++p)
279 vecFromV[p] = v[p * (maxIter + 1) + j];
280
281 //cblas_dgemv(CblasRowMajor, CblasNoTrans, nAllVars, nAllVars, 1.0, mtrDir.data(), nAllVars, &v[0 * (maxIter + 1) + j], (nAllVars + 1), 0.0, wOld.data(), 1);
282 //cblas_dgemv(CblasRowMajor, CblasNoTrans, nAllVars, nAllVars, 1.0, mtrDir.data(), nAllVars, vecFromV.data(), 1, 0.0, wOld.data(), 1);
283 for (int i = 0; i < nAllVars; ++i)
284 {
285 wOld[i] = 0.0;
286 for (int jj = 0; jj < nAllVars; ++jj)
287 {
288 wOld[i] += mtrDir[i * nAllVars + jj] * vecFromV[jj];
289 }
290 }
291
292 double timer2 = omp_get_wtime();
293
294#pragma omp parallel for
295 for (int aflI = 0; aflI < nafl; ++aflI)
296 {
297 // SolMdirect(mtrDir, wOld, pos[aflI], nAllVars - nafl + aflI, W.getAirfoil(aflI).getNumberOfPanels(), w, (vsize[aflI] == 2 * n[aflI]));
298 w = wOld;
299 }
300
301 for (size_t i = 0; i <= j; ++i)
302 {
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];
306
307 for (size_t q = 0; q < nAllVars; ++q)
308 w[q] -= h[i * maxIter + j] * v[q * (maxIter + 1) + i];
309 }//for i
310
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]);
315
316 for (size_t p = 0; p < nAllVars; ++p)
317 v[p * (maxIter + 1) + (j + 1)] = w[p] / h[(j + 1) * maxIter + j];
318
319 for (size_t i = 0; i < j; ++i)
320 {
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];
324 }
325
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];
329
330 gs *= -s[j];
331
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;
335
336 if ((fabs(gs) / normb) < W.getPassport().numericalSchemes.gmresEps)
337 {
338 m = j + 1;
339 break;
340 }
341 }//for j
342
343 //
344 for (size_t i = 0; i < m; ++i)
345 {
346 double buf = g[i];
347 g[i] *= c[i];
348 if (i < (m - 1))
349 g[i + 1] = -s[i] * buf;
350
351 }
352 y[m - 1] = g[m - 1] / h[(m - 1) * maxIter + (m - 1)];
353
354 for (size_t i = m - 2; i + 1 > 0; --i)
355 {
356 double sum = 0;
357 for (size_t j = i + 1; j < m; ++j)
358 sum += h[i * maxIter + j] * y[j];
359
360 y[i] = (g[i] - sum) / h[i * maxIter + i];
361 }
362
363 for (size_t p = 0; p < nAllVars; ++p)
364 {
365 for (size_t q = 0; q < m; ++q)
366 x[p] += v[p * (maxIter + 1) + q] * y[q];
367 }
368
369 std::cout << "#iterations: " << m << std::endl;
370
371 for (size_t aflI = 0; aflI < nafl; ++aflI)
372 {
373 for (size_t i = 0; i < vsize[aflI]; ++i)
374 gam[aflI][i] = x[pos[aflI] + i];
375 }
376
377 for (size_t aflI = 0; aflI < nafl; ++aflI)
378 R[aflI] = x[x.size() - nafl + aflI];
379}
NumericalSchemes numericalSchemes
Структура с используемыми численными схемами
Definition Passport2D.h:295
const Passport & getPassport() const
Возврат константной ссылки на паспорт
Definition World2D.h:251
Here is the call graph for this function:
Here is the caller graph for this function:

◆ IterRot()

bool 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 
)

Контроль невязки после выполнения очередной итерации 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 for (int i = 0; i < m - 1; ++i)
65 {
66 buf = H[i][m - 1];
67
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];
70 }
71
72 double izn = 1.0 / sqrt(H[m - 1][m - 1] * H[m - 1][m - 1] + H[m][m - 1] * H[m][m - 1]);
73
74 c.push_back(H[m - 1][m - 1] * izn);
75 s.push_back(H[m][m - 1] * izn);
76 gs *= -s[m - 1];
77
78
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
84
85 if (residualShow)
86 std::cout << "Iteration: " << iter << ", residual = " << (fabs(gs) / nrmRhs) << std::endl;
87
88 fl = ((fabs(gs) / nrmRhs) < epsGMRES);
89 return fl;
90}

◆ norm()

template<typename T >
double VM2D::norm ( const std::vector< T > &  b)
inline

Шаблонная функция вычисления евклидовой нормы вектора или списка

Parameters
[in]bконстантная ссылка на вектор

Definition at line 93 of file Gmres2D.h.

94 {
95 double norm = 0;
96 #ifndef OLD_OMP
97 #pragma omp simd reduction(+:norm)
98 #endif
99 for (size_t i = 0; i < b.size(); i++)
100 norm += (b[i] * b[i]);
101 return sqrt(norm);
102 }
double norm(const std::vector< T > &b)
Шаблонная функция вычисления евклидовой нормы вектора или списка
Definition Gmres2D.h:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ norm2()

template<typename T >
double VM2D::norm2 ( const std::vector< T > &  b)
inline

Шаблонная функция вычисления евклидовой нормы вектора или списка

Parameters
[in]bконстантная ссылка на вектор

Definition at line 108 of file Gmres2D.h.

109 {
110 double norm2 = 0;
111 //#ifndef OLD_OMP
112 //#pragma omp simd reduction(+:norm)
113 //#endif
114 for (size_t i = 0; i < b.size(); i++)
115 norm2 += (b[i] * b[i]);
116 return norm2;
117 }
double norm2(const std::vector< T > &b)
Шаблонная функция вычисления евклидовой нормы вектора или списка
Definition Gmres2D.h:108
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator*()

template<typename T >
std::vector< T > VM2D::operator* ( const T  lambda,
const std::vector< T > &  x 
)
inline

Шаблонная функция умножения числа на вектор

Definition at line 122 of file Gmres2D.h.

123 {
124 std::vector<T> c(x);
125 c.resize(x.size());
126
127 //#ifndef OLD_OMP
128 //#pragma omp simd
129 //#endif
130 for (size_t i = 0; i < x.size(); ++i)
131 c[i] *= lambda;
132 return c;
133 }

◆ SolCircleRun()

void 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 
)

Definition at line 393 of file Gmres2D.cpp.

394{
395 //std::vector<double> alpha(n), beta(n), delta(n), phi(n), xi(n);
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;
401
402 double yn, a;
403
404 double len24 = afl.len[0] * 24.0;
405
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];
409 double zn;
410
411 for (int i = 1; i < n - 1; ++i)
412 {
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;
418 }
419
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;
424
425 for (int i = n - 2; i > 0; --i)
426 {
427 phi[i] = alpha[i] * phi[i + 1] + beta[i];
428 xi[i] = alpha[i] * xi[i + 1] + delta[i];
429 }
430
431
432 double e = (afl.tau[n - 1] & prec1[p][n - 1]);
433 a = (afl.tau[n - 1] & prea1[p][n - 1]);
434
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]));
436
437 AX[n + n - 1] = yn;
438 for (int i = n - 2; i >= 0; --i)
439 AX[n + i] = phi[i + 1] * yn + xi[i + 1];
440}
std::vector< double > len
Длины панелей профиля
Definition Airfoil2D.h:94
std::vector< Point2D > tau
Касательные к панелям профиля
Definition Airfoil2D.h:91
std::vector< double > phi
Definition Gmres2D.h:70
std::vector< double > beta
Definition Gmres2D.h:67
std::vector< double > delta
Definition Gmres2D.h:69
std::vector< double > alpha
Definition Gmres2D.h:66
std::vector< double > xi
Definition Gmres2D.h:71

◆ SolCircleRundirect()

void 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 
)

Definition at line 93 of file Gmres2D.cpp.

94{
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);
98
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;
103
104 for (size_t i = 2; i <= np; ++i)
105 {
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;
110 }
111
112 u[np - 1] = beta[np];
113 v[np - 1] = alpha[np] + gamma[np];
114 for (size_t i = np - 2; i >= 1; --i)
115 {
116 u[i] = alpha[i + 1] * u[i + 1] + beta[i + 1];
117 v[i] = alpha[i + 1] * v[i + 1] + gamma[i + 1];
118 }
119
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];
123
124 return;
125}
Here is the caller graph for this function:

◆ SolM()

void VM2D::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 
)

Definition at line 444 of file Gmres2D.cpp.

446{
447 //std::vector<double> alpha(n), beta(n), gamma(n), delta(n), phi(n), xi(n), psi(n);
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;
455
456 double yn, ynn;
457 double lam1, lam2, mu1, mu2, xi1, xi2;
458 double a;
459
460 double len2 = afl.len[0] * 2.0;
461
462 alpha[1] = (afl.tau[0] & prec[p][0]) * len2;
463 beta[1] = (afl.tau[0] & prea[p][0]) * len2;
464 gamma[1] = len2;
465 delta[1] = -len2 * rhs[0];
466
467 double zn;
468
469 for (int i = 1; i < n - 1; ++i)
470 {
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;
477 }
478
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;
484
485 for (int i = n - 2; i > 0; --i)
486 {
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];
490 }
491
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)
499 {
500 lam2 += phi[j + 1];
501 mu2 += psi[j + 1];
502 xi2 -= xi[j + 1];
503 }
504 lam2 += 1.0;
505
506 if (!linScheme)
507 xi2 += rhs[n];
508 else if (linScheme)
509 xi2 += rhs[2 * n];
510
511 zn = lam1 * mu2 - lam2 * mu1;
512 yn = (xi1 * mu2 - xi2 * mu1) / zn;
513 ynn = -(xi1 * lam2 - xi2 * lam1) / zn;
514
515 if (!linScheme)
516 AX[n] = ynn;
517 else if (linScheme)
518 AX[2 * n] = ynn;
519
520 AX[n - 1] = yn;
521 for (int i = n - 2; i >= 0; --i)
522 AX[i] = phi[i + 1] * yn + psi[i + 1] * ynn + xi[i + 1];
523}
std::vector< double > psi
Definition Gmres2D.h:72
std::vector< double > gamma
Definition Gmres2D.h:68

◆ SolMdirect()

void 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 
)

Definition at line 130 of file Gmres2D.cpp.

131{
132 std::vector<double> alpha(np), beta(np), gamma(np), delta(np), phi(np), xi(np), psi(np);
133 double yn, ynn;
134 double lam1, lam2, mu1, mu2, xi1, xi2;
135 double a;
136
137 size_t nAllVars = rhs.size();
138
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;
144 double zn;
145
146
147 for (size_t i = 1; i < np - 1; ++i)
148 {
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;
155 }
156
157 a = A[(startRow + (np - 2)) * nAllVars + (startRow + (np - 3))];
158 zn = alpha[np - 2] * a + A[(startRow + (np - 2)) * nAllVars + (startRow + (np - 2))];
159
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;
163
164 for (size_t i = np - 2; i > 0; --i)
165 {
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];
169 }
170
171
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];
177
178 lam2 = mu2 = xi2 = 0.0;
179 for (size_t j = 0; j < np - 1; ++j)
180 {
181 lam2 += phi[j + 1];
182 mu2 += psi[j + 1];
183 xi2 -= xi[j + 1];
184 }
185 lam2 += 1.0;
186
187 xi2 += rhs[startRowReg];
188
189 zn = lam1 * mu2 - lam2 * mu1;
190 yn = (xi1 * mu2 - xi2 * mu1) / zn;
191 ynn = -(xi1 * lam2 - xi2 * lam1) / zn;
192
193 res[startRowReg] = ynn;
194
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];
198
199//
200 if (lin)
201 SolCircleRundirect(A, rhs, startRow, startRowReg, np, res);
202}
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:93
Here is the call graph for this function: