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];
15
16 double2 mom0;
17 double2 mom1;
18 double2 mom2;
19 double2 mom3;
20 double2 cen;
21 double2 dr;
22
23 int m[2];
24 int cm;
25 const int nnodes = 2 * (int)object.size() - 1;
26 const int nbodies = (int)object.size();
27#pragma omp for schedule(dynamic,5)
28 for (int k = nbodies; k < nnodes; ++k)
29 {
30
31
32
33
34
35
36
37
38
39
40
41 j = 0;
42 cm = 0;
43
44
45 while (cm == 0)
46 {
47 j = 2;
48 int srt = indexSort[(nnodes - 1) - k];
49 int2 chdPair = child[srt];
50
51 for (i = 0; i < 2; i++) {
52 int chd = i * chdPair.second + (1 - i) * chdPair.first;
53
54 ch = (chd >= nbodies) ? (chd - nbodies) : ((nnodes - 1) - indexSortT[chd]);
55
56 if ((chd >= nbodies) || (mass[nnodes - 1 - ch] >= 0))
57 j--;
58 }
59
60 if (j == 0)
61 {
62
64
65
66
67 for (i = 0; i < 2; i++)
68 {
69 const int chd = i * chdPair.second + (1 - i) * chdPair.first;
70 if (chd >= nbodies)
71 {
72 ch = chd - nbodies;
73 const int sortedBody = mortonCodesIdx[ch];
74
75 double4 xyAB = gabForLeaves[sortedBody];
76 lu[i] = double4{
77 ::fmin(xyAB[0], xyAB[2]), ::fmin(xyAB[1], xyAB[3]),
78 ::fmax(xyAB[0], xyAB[2]), ::fmax(xyAB[1], xyAB[3])
79 };
80 }
81 else
82 {
83 ch = indexSortT[chd];
84
85 lu[i] = lowerupper[chd];
86 }
87 }
88
89
90 lowerupper[srt] = double4{
91 ::fmin(lu[0][0], lu[1][0]), ::fmin(lu[0][1], lu[1][1]),
92 ::fmax(lu[0][2], lu[1][2]), ::fmax(lu[0][3], lu[1][3])
93 };
94
95 cen = center[srt] = double2{ 0.5 * (lowerupper[srt][0] + lowerupper[srt][2]),
96 0.5 * (lowerupper[srt][1] + lowerupper[srt][3]) };
97
98 const double2 zero = { 0.0, 0.0 };
99 double2 momh0 = zero;
100 double2 momh1 = zero;
101 double2 momh2 = zero;
102 double2 momh3 = zero;
103
104 for (i = 0; i < 2; i++)
105 {
106 const int chd = i * chdPair.second + (1 - i) * chdPair.first;
107 if (chd >= nbodies)
108 {
109 ch = chd - nbodies;
110 const int sortedBody = mortonCodesIdx[ch];
111
113 {
114 mom0 = double2{ gamma[sortedBody], 0.0 };
115
116mom1 = mom2 = mom3 = double2{ 0.0, 0.0 };
117 double2 pos = object[sortedBody];
118 dr = pos - cen;
119 m[i] = 1;
120 }
121
123 {
124
125 }
126
127 }
128 else
129 {
130 const int srtT = indexSortT[chd];
131 ch = (nnodes - 1) - srtT;
132
134
135 mom0 = double2{ moms[nch + 0][0], (double)0 };
136 mom1 = moms[nch + 1];
137 mom2 = moms[nch + 2];
138 mom3 = moms[nch + 3];
139 dr = center[chd] - cen;
140 m[i] = mass[srtT];
141 }
142
143
144 momh0 += mom0;
145 momh1 += mom1;
146 momh2 += mom2;
147 momh3 += mom3;
148
149 double2 z = dr;
150
151 momh1 +=
multz(mom0, z);
152 momh2 += 2 *
multz(mom1, z);
153 momh3 += 3 *
multz(mom2, z);
154
156
157 momh2 +=
multz(mom0, z);
158 momh3 += 3 *
multz(mom1, z);
159
161
162 momh3 +=
multz(mom0, z);
163 }
164
165
166 momh0[1] = 0;
167 moms[kch + 0] = momh0;
168 moms[kch + 1] = momh1;
169 moms[kch + 2] = momh2;
170 moms[kch + 3] = momh3;
171 cm = m[0] + m[1];
172 }
173
174#pragma omp flush
175
176 if (cm != 0)
177 {
178 mass[nnodes - 1 - k] = cm;
179
180
181 }
182 }
183 }
184 }
185 }
Point2D multz(const Point2D &a, const Point2D &b)
Умножение комплексных чисел