VM2D 1.14
Vortex methods for 2D flows simulation
Loading...
Searching...
No Matches
SummScript12.h
Go to the documentation of this file.
1
2 inline void Summ12()
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 mom5;
22 double2 mom6;
23 double2 mom7;
24 double2 mom8;
25 double2 mom9;
26 double2 mom10;
27 double2 mom11;
28 double2 cen; //центр текущего родительского узла
29 double2 dr; //вектор от центра родителя к центру ребенка
30
31 int m[2]; //для листа это 1, для внутреннего узла это число листьев в нем
32 int cm; //масса текущего узла = сумма масс двух детей
33 const int nnodes = 2 * (int)object.size() - 1;
34 const int nbodies = (int)object.size();
35#pragma omp for schedule(dynamic,5)
36 for (int k = nbodies; k < nnodes; ++k)
37 {
38 //MortonTree:
39 // 0 1 2 ... (nb-2) x (nb+0) (nb+1) (nb+2) ... (nb+(nb-1))
40 // ---------------- -----------------------------------
41 // cells bodies
42
43 //Martin's tree:
44 // 0 1 2 ... (nb-1) x x x x (nn-(nb-1)) ... (nn-2) (nn-1)
45 // ---------------- ----------------------------
46 // bodies sorted and reversed cells
47 //printf("k = %d\n", k);
48
49 j = 0;
50 cm = 0;
51
52 // iterate over all cells assigned to thread
53 while (cm == 0)
54 {
55 j = 2;
56 int srt = indexSort[(nnodes - 1) - k]; //проход снизу вверх - т.е. в обратном порядке
57 int2 chdPair = child[srt];
58
59 for (i = 0; i < 2; i++) {
60 int chd = i * chdPair.second + (1 - i) * chdPair.first; // i==0 => .x; i==1 => .y
61
62 ch = (chd >= nbodies) ? (chd - nbodies) : ((nnodes - 1) - indexSortT[chd]);
63
64 if ((chd >= nbodies) || (mass[nnodes - 1 - ch] >= 0))
65 j--;
66 }
67
68 if (j == 0)
69 {
70 // all children are ready
71 const int kch = ((nnodes - 1) - k) * orderAlignment; //позиция, куда будут записаны мм для текущего внутреннего узла в массиве moms
72 //moms хранится не по индексу srt, а по отсортированному порядку узлов
73
74 //Считаем bounding box текущего узла из двух детей
75 for (i = 0; i < 2; i++)
76 {
77 const int chd = i * chdPair.second + (1 - i) * chdPair.first; // индекс i-го ребенка
78 if (chd >= nbodies)//если ребенок - это лист
79 {
80 ch = chd - nbodies; //номер частицы в отсортированном массиве
81 const int sortedBody = mortonCodesIdx[ch];
82
83 double4 xyAB = gabForLeaves[sortedBody];
84 lu[i] = double4{
85 ::fmin(xyAB[0], xyAB[2]), ::fmin(xyAB[1], xyAB[3]),
86 ::fmax(xyAB[0], xyAB[2]), ::fmax(xyAB[1], xyAB[3])
87 };
88 }
89 else
90 {
91 ch = indexSortT[chd];
92 // если внутренний узел, его bounding box уже должен быть посчитан, тк идем снизу вверх
93 lu[i] = lowerupper[chd];
94 }
95 }//for i
96
97 // Объединяем bounding box двух детей:
98 lowerupper[srt] = double4{
99 ::fmin(lu[0][0], lu[1][0]), ::fmin(lu[0][1], lu[1][1]),
100 ::fmax(lu[0][2], lu[1][2]), ::fmax(lu[0][3], lu[1][3])
101 };
102 // Центр текущего узла
103 cen = center[srt] = double2{ 0.5 * (lowerupper[srt][0] + lowerupper[srt][2]),
104 0.5 * (lowerupper[srt][1] + lowerupper[srt][3]) };
105
106 const double2 zero = { 0.0, 0.0 };
107 double2 momh0 = zero;
108 double2 momh1 = zero;
109 double2 momh2 = zero;
110 double2 momh3 = zero;
111 double2 momh4 = zero;
112 double2 momh5 = zero;
113 double2 momh6 = zero;
114 double2 momh7 = zero;
115 double2 momh8 = zero;
116 double2 momh9 = zero;
117 double2 momh10 = zero;
118 double2 momh11 = zero;
119 //переносим мультипольные моменты в центр родительской ячейки
120 for (i = 0; i < 2; i++)
121 {
122 const int chd = i * chdPair.second + (1 - i) * chdPair.first;
123 if (chd >= nbodies) //если ребенок - это лист
124 {
125 ch = chd - nbodies;
126 const int sortedBody = mortonCodesIdx[ch];
127
128 if (objectType == object_T::point4)
129 {
130 mom0 = double2{ gamma[sortedBody], 0.0 };
131 //для вихря все остальные мм нулевые
132mom1 = mom2 = mom3 = mom4 = mom5 = mom6 = mom7 = mom8 = mom9 = mom10 = mom11 = double2{ 0.0, 0.0 };
133 double2 pos = object[sortedBody];
134 dr = pos - cen;
135 m[i] = 1;
136 } //objectType==point4
137
138 if (objectType == object_T::panel)
139 {
140 //...
141 } //objectType == panel
142
143 }
144 else // если ребенок - внутренний узел
145 {
146 const int srtT = indexSortT[chd];
147 ch = (nnodes - 1) - srtT;
148
149 const int nch = srtT * orderAlignment;
150
151 mom0 = double2{ moms[nch + 0][0], (double)0 };
152 mom1 = moms[nch + 1];
153 mom2 = moms[nch + 2];
154 mom3 = moms[nch + 3];
155 mom4 = moms[nch + 4];
156 mom5 = moms[nch + 5];
157 mom6 = moms[nch + 6];
158 mom7 = moms[nch + 7];
159 mom8 = moms[nch + 8];
160 mom9 = moms[nch + 9];
161 mom10 = moms[nch + 10];
162 mom11 = moms[nch + 11];
163 dr = center[chd] - cen;
164 m[i] = mass[srtT];
165 }
166 // add child's contribution
167
168 momh0 += mom0;
169 momh1 += mom1;
170 momh2 += mom2;
171 momh3 += mom3;
172 momh4 += mom4;
173 momh5 += mom5;
174 momh6 += mom6;
175 momh7 += mom7;
176 momh8 += mom8;
177 momh9 += mom9;
178 momh10 += mom10;
179 momh11 += mom11;
180
181 double2 z = dr;
182
183 momh1 += multz(mom0, z);
184 momh2 += 2 * multz(mom1, z);
185 momh3 += 3 * multz(mom2, z);
186 momh4 += 4 * multz(mom3, z);
187 momh5 += 5 * multz(mom4, z);
188 momh6 += 6 * multz(mom5, z);
189 momh7 += 7 * multz(mom6, z);
190 momh8 += 8 * multz(mom7, z);
191 momh9 += 9 * multz(mom8, z);
192 momh10 += 10 * multz(mom9, z);
193 momh11 += 11 * multz(mom10, z);
194
195 z = multz(z, dr);
196
197 momh2 += multz(mom0, z);
198 momh3 += 3 * multz(mom1, z);
199 momh4 += 6 * multz(mom2, z);
200 momh5 += 10 * multz(mom3, z);
201 momh6 += 15 * multz(mom4, z);
202 momh7 += 21 * multz(mom5, z);
203 momh8 += 28 * multz(mom6, z);
204 momh9 += 36 * multz(mom7, z);
205 momh10 += 45 * multz(mom8, z);
206 momh11 += 55 * multz(mom9, z);
207
208 z = multz(z, dr);
209
210 momh3 += multz(mom0, z);
211 momh4 += 4 * multz(mom1, z);
212 momh5 += 10 * multz(mom2, z);
213 momh6 += 20 * multz(mom3, z);
214 momh7 += 35 * multz(mom4, z);
215 momh8 += 56 * multz(mom5, z);
216 momh9 += 84 * multz(mom6, z);
217 momh10 += 120 * multz(mom7, z);
218 momh11 += 165 * multz(mom8, z);
219
220 z = multz(z, dr);
221
222 momh4 += multz(mom0, z);
223 momh5 += 5 * multz(mom1, z);
224 momh6 += 15 * multz(mom2, z);
225 momh7 += 35 * multz(mom3, z);
226 momh8 += 70 * multz(mom4, z);
227 momh9 += 126 * multz(mom5, z);
228 momh10 += 210 * multz(mom6, z);
229 momh11 += 330 * multz(mom7, z);
230
231 z = multz(z, dr);
232
233 momh5 += multz(mom0, z);
234 momh6 += 6 * multz(mom1, z);
235 momh7 += 21 * multz(mom2, z);
236 momh8 += 56 * multz(mom3, z);
237 momh9 += 126 * multz(mom4, z);
238 momh10 += 252 * multz(mom5, z);
239 momh11 += 462 * multz(mom6, z);
240
241 z = multz(z, dr);
242
243 momh6 += multz(mom0, z);
244 momh7 += 7 * multz(mom1, z);
245 momh8 += 28 * multz(mom2, z);
246 momh9 += 84 * multz(mom3, z);
247 momh10 += 210 * multz(mom4, z);
248 momh11 += 462 * multz(mom5, z);
249
250 z = multz(z, dr);
251
252 momh7 += multz(mom0, z);
253 momh8 += 8 * multz(mom1, z);
254 momh9 += 36 * multz(mom2, z);
255 momh10 += 120 * multz(mom3, z);
256 momh11 += 330 * multz(mom4, z);
257
258 z = multz(z, dr);
259
260 momh8 += multz(mom0, z);
261 momh9 += 9 * multz(mom1, z);
262 momh10 += 45 * multz(mom2, z);
263 momh11 += 165 * multz(mom3, z);
264
265 z = multz(z, dr);
266
267 momh9 += multz(mom0, z);
268 momh10 += 10 * multz(mom1, z);
269 momh11 += 55 * multz(mom2, z);
270
271 z = multz(z, dr);
272
273 momh10 += multz(mom0, z);
274 momh11 += 11 * multz(mom1, z);
275
276 z = multz(z, dr);
277
278 momh11 += multz(mom0, z);
279 }
280
281 // Сохраняем итоговые моменты текущего внутреннего узла в общий массив
282 momh0[1] = 0;
283 moms[kch + 0] = momh0;
284 moms[kch + 1] = momh1;
285 moms[kch + 2] = momh2;
286 moms[kch + 3] = momh3;
287 moms[kch + 4] = momh4;
288 moms[kch + 5] = momh5;
289 moms[kch + 6] = momh6;
290 moms[kch + 7] = momh7;
291 moms[kch + 8] = momh8;
292 moms[kch + 9] = momh9;
293 moms[kch + 10] = momh10;
294 moms[kch + 11] = momh11;
295 cm = m[0] + m[1];
296 }
297
298#pragma omp flush
299
300 if (cm != 0)
301 {
302 mass[nnodes - 1 - k] = cm;// Записываем массу текущего узла
303 //k += inc;
304 //flag = 0;
305 }
306 }//while flag==0
307 }//for k
308 }
309 }//Summ12()
#define orderAlignment
Definition Gpudefs.h:94
void Summ12()
Definition SummScript12.h:2