VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
SummScript5.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void Summ5 ()
 

Function Documentation

◆ Summ5()

void Summ5 ( )
inline

Definition at line 2 of file SummScript5.h.

3 {
4 using double4 = Point4D;
5 using double2 = Point2D;
6 using int2 = std::pair<int, int>;
7
8 //цикл по внутренним узлам снизу вверх
9
10#pragma omp parallel
11 {
12 int i, j, ch;
13
14 double4 lu[2]; //bounding boxes двух детей
15
16 double2 mom0;
17 double2 mom1;
18 double2 mom2;
19 double2 mom3;
20 double2 mom4;
21 double2 cen; //центр текущего родительского узла
22 double2 dr; //вектор от центра родителя к центру ребенка
23
24 int m[2]; //для листа это 1, для внутреннего узла это число листьев в нем
25 int cm; //масса текущего узла = сумма масс двух детей
26 const int nnodes = 2 * (int)object.size() - 1;
27 const int nbodies = (int)object.size();
28#pragma omp for schedule(dynamic,5)
29 for (int k = nbodies; k < nnodes; ++k)
30 {
31 //MortonTree:
32 // 0 1 2 ... (nb-2) x (nb+0) (nb+1) (nb+2) ... (nb+(nb-1))
33 // ---------------- -----------------------------------
34 // cells bodies
35
36 //Martin's tree:
37 // 0 1 2 ... (nb-1) x x x x (nn-(nb-1)) ... (nn-2) (nn-1)
38 // ---------------- ----------------------------
39 // bodies sorted and reversed cells
40 //printf("k = %d\n", k);
41
42 j = 0;
43 cm = 0;
44
45 // iterate over all cells assigned to thread
46 while (cm == 0)
47 {
48 j = 2;
49 int srt = indexSort[(nnodes - 1) - k]; //проход снизу вверх - т.е. в обратном порядке
50 int2 chdPair = child[srt];
51
52 for (i = 0; i < 2; i++) {
53 int chd = i * chdPair.second + (1 - i) * chdPair.first; // i==0 => .x; i==1 => .y
54
55 ch = (chd >= nbodies) ? (chd - nbodies) : ((nnodes - 1) - indexSortT[chd]);
56
57 if ((chd >= nbodies) || (mass[nnodes - 1 - ch] >= 0))
58 j--;
59 }
60
61 if (j == 0)
62 {
63 // all children are ready
64 const int kch = ((nnodes - 1) - k) * orderAlignment; //позиция, куда будут записаны мм для текущего внутреннего узла в массиве moms
65 //moms хранится не по индексу srt, а по отсортированному порядку узлов
66
67 //Считаем bounding box текущего узла из двух детей
68 for (i = 0; i < 2; i++)
69 {
70 const int chd = i * chdPair.second + (1 - i) * chdPair.first; // индекс i-го ребенка
71 if (chd >= nbodies)//если ребенок - это лист
72 {
73 ch = chd - nbodies; //номер частицы в отсортированном массиве
74 const int sortedBody = mortonCodesIdx[ch];
75
76 double4 xyAB = gabForLeaves[sortedBody];
77 lu[i] = double4{
78 ::fmin(xyAB[0], xyAB[2]), ::fmin(xyAB[1], xyAB[3]),
79 ::fmax(xyAB[0], xyAB[2]), ::fmax(xyAB[1], xyAB[3])
80 };
81 }
82 else
83 {
84 ch = indexSortT[chd];
85 // если внутренний узел, его bounding box уже должен быть посчитан, тк идем снизу вверх
86 lu[i] = lowerupper[chd];
87 }
88 }//for i
89
90 // Объединяем bounding box двух детей:
91 lowerupper[srt] = double4{
92 ::fmin(lu[0][0], lu[1][0]), ::fmin(lu[0][1], lu[1][1]),
93 ::fmax(lu[0][2], lu[1][2]), ::fmax(lu[0][3], lu[1][3])
94 };
95 // Центр текущего узла
96 cen = center[srt] = double2{ 0.5 * (lowerupper[srt][0] + lowerupper[srt][2]),
97 0.5 * (lowerupper[srt][1] + lowerupper[srt][3]) };
98
99 const double2 zero = { 0.0, 0.0 };
100 double2 momh0 = zero;
101 double2 momh1 = zero;
102 double2 momh2 = zero;
103 double2 momh3 = zero;
104 double2 momh4 = zero;
105 //переносим мультипольные моменты в центр родительской ячейки
106 for (i = 0; i < 2; i++)
107 {
108 const int chd = i * chdPair.second + (1 - i) * chdPair.first;
109 if (chd >= nbodies) //если ребенок - это лист
110 {
111 ch = chd - nbodies;
112 const int sortedBody = mortonCodesIdx[ch];
113
114 if (objectType == object_T::point4)
115 {
116 mom0 = double2{ gamma[sortedBody], 0.0 };
117 //для вихря все остальные мм нулевые
118mom1 = mom2 = mom3 = mom4 = double2{ 0.0, 0.0 };
119 double2 pos = object[sortedBody];
120 dr = pos - cen;
121 m[i] = 1;
122 } //objectType==point4
123
124 if (objectType == object_T::panel)
125 {
126 //...
127 } //objectType == panel
128
129 }
130 else // если ребенок - внутренний узел
131 {
132 const int srtT = indexSortT[chd];
133 ch = (nnodes - 1) - srtT;
134
135 const int nch = srtT * orderAlignment;
136
137 mom0 = double2{ moms[nch + 0][0], (double)0 };
138 mom1 = moms[nch + 1];
139 mom2 = moms[nch + 2];
140 mom3 = moms[nch + 3];
141 mom4 = moms[nch + 4];
142 dr = center[chd] - cen;
143 m[i] = mass[srtT];
144 }
145 // add child's contribution
146
147 momh0 += mom0;
148 momh1 += mom1;
149 momh2 += mom2;
150 momh3 += mom3;
151 momh4 += mom4;
152
153 double2 z = dr;
154
155 momh1 += multz(mom0, z);
156 momh2 += 2 * multz(mom1, z);
157 momh3 += 3 * multz(mom2, z);
158 momh4 += 4 * multz(mom3, z);
159
160 z = multz(z, dr);
161
162 momh2 += multz(mom0, z);
163 momh3 += 3 * multz(mom1, z);
164 momh4 += 6 * multz(mom2, z);
165
166 z = multz(z, dr);
167
168 momh3 += multz(mom0, z);
169 momh4 += 4 * multz(mom1, z);
170
171 z = multz(z, dr);
172
173 momh4 += multz(mom0, z);
174 }
175
176 // Сохраняем итоговые моменты текущего внутреннего узла в общий массив
177 momh0[1] = 0;
178 moms[kch + 0] = momh0;
179 moms[kch + 1] = momh1;
180 moms[kch + 2] = momh2;
181 moms[kch + 3] = momh3;
182 moms[kch + 4] = momh4;
183 cm = m[0] + m[1];
184 }
185
186#pragma omp flush
187
188 if (cm != 0)
189 {
190 mass[nnodes - 1 - k] = cm;// Записываем массу текущего узла
191 //k += inc;
192 //flag = 0;
193 }
194 }//while flag==0
195 }//for k
196 }
197 }
#define orderAlignment
Definition Gpudefs.h:94
Point2D multz(const Point2D &a, const Point2D &b)
Умножение комплексных чисел
Definition Point2D.h:210
Here is the caller graph for this function: