Line | % of fetches | Source |
---|---|---|
1 | #include "node_server.hpp" | |
2 | #include "node_client.hpp" | |
3 | #include "diagnostics.hpp" | |
4 | #include "future.hpp" | |
5 | #include "taylor.hpp" | |
6 | #include "profiler.hpp" | |
7 | ||
8 | #include <hpx/include/lcos.hpp> | |
9 | #include <hpx/runtime/serialization/list.hpp> | |
10 | #include <hpx/include/run_as.hpp> | |
11 | ||
12 | #include "options.hpp" | |
13 | ||
14 | typedef node_server::check_for_refinement_action check_for_refinement_action_type; | |
15 | HPX_REGISTER_ACTION(check_for_refinement_action_type); | |
16 | ||
17 | hpx::future<bool> node_client::check_for_refinement() const { | |
18 | return hpx::async<typename node_server::check_for_refinement_action>(get_gid()); | |
19 | } | |
20 | ||
21 | bool node_server::check_for_refinement() { | |
22 | bool rc = false; | |
23 | std::vector<hpx::future<bool>> futs; | |
24 | if (is_refined) { | |
25 | futs.reserve(children.size()); | |
26 | for (auto& child : children) { | |
27 | futs.push_back(child.check_for_refinement()); | |
28 | } | |
29 | } | |
30 | if (hydro_on) { | |
31 | all_hydro_bounds().get(); | |
32 | } | |
33 | wait_all_and_propagate_exceptions(futs); | |
34 | if (!rc) { | |
35 | rc = grid_ptr->refine_me(my_location.level()); | |
36 | } | |
37 | if (rc) { | |
38 | if (refinement_flag++ == 0) { | |
39 | if (!parent.empty()) { | |
40 | const auto neighbors = my_location.get_neighbors(); | |
41 | parent.force_nodes_to_exist( | |
42 | std::list < node_location > (neighbors.begin(), neighbors.end())).get(); | |
43 | } | |
44 | } | |
45 | } | |
46 | return refinement_flag != 0; | |
47 | } | |
48 | ||
49 | typedef node_server::copy_to_locality_action copy_to_locality_action_type; | |
50 | HPX_REGISTER_ACTION(copy_to_locality_action_type); | |
51 | ||
52 | hpx::future<hpx::id_type> node_client::copy_to_locality(const hpx::id_type& id) const { | |
53 | return hpx::async<typename node_server::copy_to_locality_action>(get_gid(), id); | |
54 | } | |
55 | ||
56 | hpx::future<hpx::id_type> node_server::copy_to_locality(const hpx::id_type& id) { | |
57 | ||
58 | std::vector<hpx::id_type> cids; | |
59 | if (is_refined) { | |
60 | cids.resize(NCHILD); | |
61 | for (auto& ci : geo::octant::full_set()) { | |
62 | cids[ci] = children[ci].get_gid(); | |
63 | } | |
64 | } | |
65 | auto rc = hpx::new_<node_server | |
66 | >(id, my_location, step_num, is_refined, current_time, rotational_time, | |
67 | child_descendant_count, std::move(*grid_ptr), cids); | |
68 | clear_family(); | |
69 | return rc; | |
70 | } | |
71 | ||
72 | extern options opts; | |
73 | ||
74 | typedef node_server::diagnostics_action diagnostics_action_type; | |
75 | HPX_REGISTER_ACTION(diagnostics_action_type); | |
76 | ||
77 | hpx::future<diagnostics_t> node_client::diagnostics( | |
78 | const std::pair<space_vector, space_vector>& axis, const std::pair<real, real>& l1, | |
79 | real c1, | |
80 | real c2) const { | |
81 | return hpx::async<typename node_server::diagnostics_action>(get_gid(), axis, l1, c1, | |
82 | c2); | |
83 | } | |
84 | ||
85 | typedef node_server::compare_analytic_action compare_analytic_action_type; | |
86 | HPX_REGISTER_ACTION(compare_analytic_action_type); | |
87 | ||
88 | hpx::future<analytic_t> node_client::compare_analytic() const { | |
89 | return hpx::async<typename node_server::compare_analytic_action>(get_gid()); | |
90 | } | |
91 | ||
92 | analytic_t node_server::compare_analytic() { | |
93 | analytic_t a; | |
94 | if (!is_refined) { | |
95 | a = grid_ptr->compute_analytic(current_time); | |
96 | } else { | |
97 | std::vector<hpx::future<analytic_t>> futs; | |
98 | futs.reserve(NCHILD); | |
99 | for (integer i = 0; i != NCHILD; ++i) { | |
100 | futs.push_back(children[i].compare_analytic()); | |
101 | } | |
102 | for (integer i = 0; i != NCHILD; ++i) { | |
103 | a += futs[i].get(); | |
104 | } | |
105 | } | |
106 | if (my_location.level() == 0) { | |
107 | printf("L1, L2\n"); | |
108 | for (integer field = 0; field != NF; ++field) { | |
109 | if (a.l1a[field] > 0.0) { | |
110 | printf("%16s %e %e\n", grid::field_names[field], | |
111 | a.l1[field] / a.l1a[field], std::sqrt(a.l2[field] / a.l2a[field])); | |
112 | } | |
113 | } | |
114 | } | |
115 | return a; | |
116 | } | |
117 | ||
118 | diagnostics_t node_server::diagnostics() const { | |
119 | auto axis = grid_ptr->find_axis(); | |
120 | auto loc = line_of_centers(axis); | |
121 | real this_omega = grid::get_omega(); | |
122 | std::pair<real, real> rho1, rho2, l1, l2, l3; | |
123 | real phi_1, phi_2; | |
124 | line_of_centers_analyze(loc, this_omega, rho1, rho2, l1, l2, l3, phi_1, phi_2); | |
125 | //if( rho1.first > rho2.first ) { | |
126 | // for( integer d = 0; d != NDIM; ++d ) { | |
127 | // //printf( "Flipping axis\n" ); | |
128 | // axis.first[d] = -axis.first[d]; | |
129 | // loc = line_of_centers(axis); | |
130 | // line_of_centers_analyze(loc, this_omega, rho1, rho2, l1, phi_1, phi_2); | |
131 | // } | |
132 | // } | |
133 | auto diags = diagnostics(axis, l1, rho1.first, rho2.first); | |
134 | ||
135 | diags.z_moment -= diags.grid_sum[rho_i] | |
136 | * (std::pow(diags.grid_com[XDIM], 2) + std::pow(diags.grid_com[YDIM], 2)); | |
137 | diags.primary_z_moment -= diags.primary_sum[rho_i] | |
138 | * (std::pow(diags.primary_com[XDIM], 2) + std::pow(diags.primary_com[YDIM], 2)); | |
139 | diags.secondary_z_moment -= | |
140 | diags.secondary_sum[rho_i] | |
141 | * (std::pow(diags.secondary_com[XDIM], 2) | |
142 | + std::pow(diags.secondary_com[YDIM], 2)); | |
143 | if (diags.primary_sum[rho_i] < diags.secondary_sum[rho_i]) { | |
144 | std::swap(diags.primary_sum, diags.secondary_sum); | |
145 | std::swap(diags.primary_com, diags.secondary_com); | |
146 | std::swap(diags.primary_com_dot, diags.secondary_com_dot); | |
147 | std::swap(rho1, rho2); | |
148 | std::swap(phi_1, phi_2); | |
149 | std::swap(diags.primary_z_moment, diags.secondary_z_moment); | |
150 | } | |
151 | ||
152 | if (opts.problem != SOLID_SPHERE) { | |
153 | // run output on separate thread | |
154 | hpx::threads::run_as_os_thread([&]() | |
155 | { | |
156 | FILE* fp = fopen("diag.dat", "at"); | |
157 | fprintf(fp, "%23.16e ", double(current_time)); | |
158 | for (integer f = 0; f != NF; ++f) { | |
159 | fprintf(fp, "%23.16e ", double(diags.grid_sum[f] + diags.outflow_sum[f])); | |
160 | fprintf(fp, "%23.16e ", double(diags.outflow_sum[f])); | |
161 | } | |
162 | for (integer f = 0; f != NDIM; ++f) { | |
163 | fprintf(fp, "%23.16e ", double(diags.l_sum[f])); | |
164 | } | |
165 | fprintf(fp, "\n"); | |
166 | fclose(fp); | |
167 | }).get(); | |
168 | ||
169 | real a = 0.0; | |
170 | for (integer d = 0; d != NDIM; ++d) { | |
171 | a += std::pow(diags.primary_com[d] - diags.secondary_com[d], 2); | |
172 | } | |
173 | a = std::sqrt(a); | |
174 | real j1 = 0.0; | |
175 | real j2 = 0.0; | |
176 | real m1 = diags.primary_sum[rho_i]; | |
177 | real m2 = diags.secondary_sum[rho_i]; | |
178 | j1 -= diags.primary_com_dot[XDIM] | |
179 | * (diags.primary_com[YDIM] - diags.grid_com[YDIM]) * m1; | |
180 | j1 += diags.primary_com_dot[YDIM] | |
181 | * (diags.primary_com[XDIM] - diags.grid_com[XDIM]) * m1; | |
182 | j2 -= diags.secondary_com_dot[XDIM] | |
183 | * (diags.secondary_com[YDIM] - diags.grid_com[YDIM]) * m2; | |
184 | j2 += diags.secondary_com_dot[YDIM] | |
185 | * (diags.secondary_com[XDIM] - diags.grid_com[XDIM]) * m2; | |
186 | const real jorb = j1 + j2; | |
187 | j1 = diags.primary_sum[zz_i] - j1; | |
188 | j2 = diags.secondary_sum[zz_i] - j2; | |
189 | ||
190 | // run output on separate thread | |
191 | hpx::threads::run_as_os_thread([&]() | |
192 | { | |
193 | FILE* fp = fopen("binary.dat", "at"); | |
194 | fprintf(fp, "%15.8e ", double(current_time)); | |
195 | fprintf(fp, "%15.8e ", double(m1)); | |
196 | fprintf(fp, "%15.8e ", double(m2)); | |
197 | fprintf(fp, "%15.8e ", double(this_omega)); | |
198 | fprintf(fp, "%15.8e ", double(a)); | |
199 | fprintf(fp, "%15.8e ", double(rho1.second)); | |
200 | fprintf(fp, "%15.8e ", double(rho2.second)); | |
201 | fprintf(fp, "%15.8e ", double(jorb)); | |
202 | fprintf(fp, "%15.8e ", double(j1)); | |
203 | fprintf(fp, "%15.8e ", double(j2)); | |
204 | fprintf(fp, "%15.8e ", double(diags.z_moment)); | |
205 | fprintf(fp, "%15.8e ", double(diags.primary_z_moment)); | |
206 | fprintf(fp, "%15.8e ", double(diags.secondary_z_moment)); | |
207 | fprintf(fp, "\n"); | |
208 | fclose(fp); | |
209 | ||
210 | fp = fopen("minmax.dat", "at"); | |
211 | fprintf(fp, "%23.16e ", double(current_time)); | |
212 | for (integer f = 0; f != NF; ++f) { | |
213 | fprintf(fp, "%23.16e ", double(diags.field_min[f])); | |
214 | fprintf(fp, "%23.16e ", double(diags.field_max[f])); | |
215 | } | |
216 | fprintf(fp, "\n"); | |
217 | fclose(fp); | |
218 | ||
219 | fp = fopen("com.dat", "at"); | |
220 | fprintf(fp, "%23.16e ", double(current_time)); | |
221 | for (integer d = 0; d != NDIM; ++d) { | |
222 | fprintf(fp, "%23.16e ", double(diags.primary_com[d])); | |
223 | } | |
224 | for (integer d = 0; d != NDIM; ++d) { | |
225 | fprintf(fp, "%23.16e ", double(diags.secondary_com[d])); | |
226 | } | |
227 | for (integer d = 0; d != NDIM; ++d) { | |
228 | fprintf(fp, "%23.16e ", double(diags.grid_com[d])); | |
229 | } | |
230 | fprintf(fp, "\n"); | |
231 | fclose(fp); | |
232 | }).get(); | |
233 | } else { | |
234 | printf("L1\n"); | |
235 | printf("Gravity Phi Error - %e\n", (diags.l1_error[0] / diags.l1_error[4])); | |
236 | printf("Gravity gx Error - %e\n", (diags.l1_error[1] / diags.l1_error[5])); | |
237 | printf("Gravity gy Error - %e\n", (diags.l1_error[2] / diags.l1_error[6])); | |
238 | printf("Gravity gz Error - %e\n", (diags.l1_error[3] / diags.l1_error[7])); | |
239 | printf("L2\n"); | |
240 | printf("Gravity Phi Error - %e\n", | |
241 | std::sqrt(diags.l2_error[0] / diags.l2_error[4])); | |
242 | printf("Gravity gx Error - %e\n", | |
243 | std::sqrt(diags.l2_error[1] / diags.l2_error[5])); | |
244 | printf("Gravity gy Error - %e\n", | |
245 | std::sqrt(diags.l2_error[2] / diags.l2_error[6])); | |
246 | printf("Gravity gz Error - %e\n", | |
247 | std::sqrt(diags.l2_error[3] / diags.l2_error[7])); | |
248 | printf("Total Mass = %e\n", diags.grid_sum[rho_i]); | |
249 | for (integer d = 0; d != NDIM; ++d) { | |
250 | printf("%e %e\n", diags.gforce_sum[d], diags.gtorque_sum[d]); | |
251 | } | |
252 | } | |
253 | ||
254 | return diags; | |
255 | } | |
256 | ||
257 | diagnostics_t node_server::diagnostics(const std::pair<space_vector, space_vector>& axis, | |
258 | const std::pair<real, real>& l1, real c1, real c2) const { | |
259 | ||
260 | diagnostics_t sums; | |
261 | if (is_refined) { | |
262 | std::vector<hpx::future<diagnostics_t>> futs; | |
263 | futs.reserve(NCHILD); | |
264 | for (integer ci = 0; ci != NCHILD; ++ci) { | |
265 | futs.push_back(children[ci].diagnostics(axis, l1, c1, c2)); | |
266 | } | |
267 | auto child_sums = hpx::util::unwrapped(futs); | |
268 | sums = std::accumulate(child_sums.begin(), child_sums.end(), sums); | |
269 | } else { | |
270 | ||
271 | sums.primary_sum = grid_ptr->conserved_sums(sums.primary_com, | |
272 | sums.primary_com_dot, axis, l1, +1); | |
273 | sums.secondary_sum = grid_ptr->conserved_sums(sums.secondary_com, | |
274 | sums.secondary_com_dot, axis, l1, -1); | |
275 | sums.primary_z_moment = grid_ptr->z_moments(axis, l1, +1); | |
276 | sums.secondary_z_moment = grid_ptr->z_moments(axis, l1, -1); | |
277 | sums.grid_sum = grid_ptr->conserved_sums(sums.grid_com, sums.grid_com_dot, axis, | |
278 | l1, 0); | |
279 | sums.outflow_sum = grid_ptr->conserved_outflows(); | |
280 | sums.l_sum = grid_ptr->l_sums(); | |
281 | auto tmp = grid_ptr->field_range(); | |
282 | sums.field_min = std::move(tmp.first); | |
283 | sums.field_max = std::move(tmp.second); | |
284 | sums.gforce_sum = grid_ptr->gforce_sum(false); | |
285 | sums.gtorque_sum = grid_ptr->gforce_sum(true); | |
286 | auto tmp2 = grid_ptr->diagnostic_error(); | |
287 | sums.l1_error = tmp2.first; | |
288 | sums.l2_error = tmp2.second; | |
289 | auto vols = grid_ptr->frac_volumes(); | |
290 | sums.roche_vol1 = grid_ptr->roche_volume(axis, l1, std::min(c1, c2), false); | |
291 | sums.roche_vol2 = grid_ptr->roche_volume(axis, l1, std::max(c1, c2), true); | |
292 | sums.primary_volume = vols[spc_ac_i - spc_i] + vols[spc_ae_i - spc_i]; | |
293 | sums.secondary_volume = vols[spc_dc_i - spc_i] + vols[spc_de_i - spc_i]; | |
294 | sums.z_moment = grid_ptr->z_moments(axis, l1, 0); | |
295 | } | |
296 | ||
297 | return sums; | |
298 | } | |
299 | ||
300 | diagnostics_t::diagnostics_t() : | |
301 | primary_sum(NF, ZERO), secondary_sum(NF, ZERO), grid_sum(NF, ZERO), outflow_sum(NF, | |
302 | ZERO), l_sum(NDIM, ZERO), field_max(NF, | |
303 | -std::numeric_limits < real > ::max()), field_min(NF, | |
304 | +std::numeric_limits < real > ::max()), gforce_sum(NDIM, ZERO), gtorque_sum(NDIM, | |
305 | ZERO) { | |
306 | for (integer d = 0; d != NDIM; ++d) { | |
307 | primary_z_moment = secondary_z_moment = z_moment = 0.0; | |
308 | roche_vol1 = roche_vol2 = primary_volume = secondary_volume = 0.0; | |
309 | primary_com[d] = secondary_com[d] = grid_com[d] = 0.0; | |
310 | primary_com_dot[d] = secondary_com_dot[d] = grid_com_dot[d] = 0.0; | |
311 | } | |
312 | } | |
313 | ||
314 | diagnostics_t& diagnostics_t::operator+=(const diagnostics_t& other) { | |
315 | primary_z_moment += other.primary_z_moment; | |
316 | secondary_z_moment += other.secondary_z_moment; | |
317 | z_moment += other.z_moment; | |
318 | for (integer d = 0; d != NDIM; ++d) { | |
319 | primary_com[d] *= primary_sum[rho_i]; | |
320 | secondary_com[d] *= secondary_sum[rho_i]; | |
321 | grid_com[d] *= grid_sum[rho_i]; | |
322 | primary_com_dot[d] *= primary_sum[rho_i]; | |
323 | secondary_com_dot[d] *= secondary_sum[rho_i]; | |
324 | grid_com_dot[d] *= grid_sum[rho_i]; | |
325 | } | |
326 | for (integer f = 0; f != NF; ++f) { | |
327 | grid_sum[f] += other.grid_sum[f]; | |
328 | primary_sum[f] += other.primary_sum[f]; | |
329 | secondary_sum[f] += other.secondary_sum[f]; | |
330 | outflow_sum[f] += other.outflow_sum[f]; | |
331 | field_max[f] = std::max(field_max[f], other.field_max[f]); | |
332 | field_min[f] = std::min(field_min[f], other.field_min[f]); | |
333 | } | |
334 | for (integer d = 0; d != NDIM; ++d) { | |
335 | l_sum[d] += other.l_sum[d]; | |
336 | gforce_sum[d] += other.gforce_sum[d]; | |
337 | gtorque_sum[d] += other.gtorque_sum[d]; | |
338 | } | |
339 | if (l1_error.size() < other.l1_error.size()) { | |
340 | l1_error.resize(other.l1_error.size(), ZERO); | |
341 | l2_error.resize(other.l2_error.size(), ZERO); | |
342 | } | |
343 | for (std::size_t i = 0; i != l1_error.size(); ++i) { | |
344 | l1_error[i] += other.l1_error[i]; | |
345 | } | |
346 | for (std::size_t i = 0; i != l1_error.size(); ++i) { | |
347 | l2_error[i] += other.l2_error[i]; | |
348 | } | |
349 | for (integer d = 0; d != NDIM; ++d) { | |
350 | primary_com[d] += other.primary_com[d] * other.primary_sum[rho_i]; | |
351 | secondary_com[d] += other.secondary_com[d] * other.secondary_sum[rho_i]; | |
352 | grid_com[d] += other.grid_com[d] * other.grid_sum[rho_i]; | |
353 | primary_com_dot[d] += other.primary_com_dot[d] * other.primary_sum[rho_i]; | |
354 | secondary_com_dot[d] += other.secondary_com_dot[d] * other.secondary_sum[rho_i]; | |
355 | grid_com_dot[d] += other.grid_com_dot[d] * other.grid_sum[rho_i]; | |
356 | } | |
357 | for (integer d = 0; d != NDIM; ++d) { | |
358 | if (primary_sum[rho_i] > 0.0) { | |
359 | primary_com[d] /= primary_sum[rho_i]; | |
360 | primary_com_dot[d] /= primary_sum[rho_i]; | |
361 | } | |
362 | if (secondary_sum[rho_i] > 0.0) { | |
363 | secondary_com[d] /= secondary_sum[rho_i]; | |
364 | secondary_com_dot[d] /= secondary_sum[rho_i]; | |
365 | } | |
366 | grid_com[d] /= grid_sum[rho_i]; | |
367 | grid_com_dot[d] /= grid_sum[rho_i]; | |
368 | } | |
369 | roche_vol1 += other.roche_vol1; | |
370 | roche_vol2 += other.roche_vol2; | |
371 | primary_volume += other.primary_volume; | |
372 | secondary_volume += other.secondary_volume; | |
373 | return *this; | |
374 | } | |
375 | ||
376 | typedef node_server::force_nodes_to_exist_action force_nodes_to_exist_action_type; | |
377 | HPX_REGISTER_ACTION(force_nodes_to_exist_action_type); | |
378 | ||
379 | hpx::future<void> node_client::force_nodes_to_exist( | |
380 | std::list<node_location>&& locs) const { | |
381 | return hpx::async<typename node_server::force_nodes_to_exist_action>(get_gid(), | |
382 | std::move(locs)); | |
383 | } | |
384 | ||
385 | void node_server::force_nodes_to_exist(const std::list<node_location>& locs) { | |
386 | std::vector<hpx::future<void>> futs; | |
387 | std::list<node_location> parent_list; | |
388 | std::vector < std::list < node_location >> child_lists(NCHILD); | |
389 | for (auto& loc : locs) { | |
390 | assert(loc != my_location); | |
391 | if (loc.is_child_of(my_location)) { | |
392 | if (refinement_flag++ == 0 && !parent.empty()) { | |
393 | const auto neighbors = my_location.get_neighbors(); | |
394 | parent.force_nodes_to_exist( | |
395 | std::list < node_location > (neighbors.begin(), neighbors.end())).get(); | |
396 | } | |
397 | if (is_refined) { | |
398 | for (auto& ci : geo::octant::full_set()) { | |
399 | if (loc.is_child_of(my_location.get_child(ci))) { | |
400 | child_lists[ci].push_back(loc); | |
401 | break; | |
402 | } | |
403 | } | |
404 | } | |
405 | } else { | |
406 | assert(!parent.empty()); | |
407 | parent_list.push_back(loc); | |
408 | } | |
409 | } | |
410 | constexpr auto full_set = geo::octant::full_set(); | |
411 | futs.reserve(full_set.size() + 1); | |
412 | for (auto& ci : full_set) { | |
413 | if (is_refined && child_lists[ci].size()) { | |
414 | futs.push_back(children[ci].force_nodes_to_exist(std::move(child_lists[ci]))); | |
415 | } | |
416 | } | |
417 | if (parent_list.size()) { | |
418 | futs.push_back(parent.force_nodes_to_exist(std::move(parent_list))); | |
419 | } | |
420 | ||
421 | wait_all_and_propagate_exceptions(futs); | |
422 | } | |
423 | ||
424 | typedef node_server::form_tree_action form_tree_action_type; | |
425 | HPX_REGISTER_ACTION(form_tree_action_type); | |
426 | ||
427 | hpx::future<void> node_client::form_tree(const hpx::id_type& id1, const hpx::id_type& id2, | |
428 | const std::vector<hpx::id_type>& ids) { | |
429 | return hpx::async<typename node_server::form_tree_action>(get_gid(), id1, id2, | |
430 | std::move(ids)); | |
431 | } | |
432 | ||
433 | void node_server::form_tree(const hpx::id_type& self_gid, const hpx::id_type& parent_gid, | |
434 | const std::vector<hpx::id_type>& neighbor_gids) { | |
435 | for (auto& dir : geo::direction::full_set()) { | |
436 | neighbors[dir] = neighbor_gids[dir]; | |
437 | } | |
438 | me = self_gid; | |
439 | parent = parent_gid; | |
440 | if (is_refined) { | |
441 | std::vector<hpx::future<void>> cfuts; | |
442 | cfuts.reserve(2*2*2); | |
443 | amr_flags.resize(NCHILD); | |
444 | for (integer cx = 0; cx != 2; ++cx) { | |
445 | for (integer cy = 0; cy != 2; ++cy) { | |
446 | for (integer cz = 0; cz != 2; ++cz) { | |
447 | std::vector<hpx::future<hpx::id_type>> child_neighbors_f( | |
448 | geo::direction::count()); | |
449 | std::vector<hpx::id_type> child_neighbors(geo::direction::count()); | |
450 | const integer ci = cx + 2 * cy + 4 * cz; | |
451 | for (integer dx = -1; dx != 2; ++dx) { | |
452 | for (integer dy = -1; dy != 2; ++dy) { | |
453 | for (integer dz = -1; dz != 2; ++dz) { | |
454 | if (!(dx == 0 && dy == 0 && dz == 0)) { | |
455 | const integer x = cx + dx + 2; | |
456 | const integer y = cy + dy + 2; | |
457 | const integer z = cz + dz + 2; | |
458 | geo::direction i; | |
459 | i.set(dx, dy, dz); | |
460 | auto& ref = child_neighbors_f[i]; | |
461 | auto other_child = (x % 2) + 2 * (y % 2) | |
462 | + 4 * (z % 2); | |
463 | if (x / 2 == 1 && y / 2 == 1 && z / 2 == 1) { | |
464 | ref = hpx::make_ready_future<hpx::id_type>( | |
465 | children[other_child].get_gid()); | |
466 | } else { | |
467 | geo::direction dir = geo::direction( | |
468 | (x / 2) + NDIM * ((y / 2) + NDIM * (z / 2))); | |
469 | ref = neighbors[dir].get_child_client( | |
470 | other_child); | |
471 | } | |
472 | } | |
473 | } | |
474 | } | |
475 | } | |
476 | ||
477 | for (auto& dir : geo::direction::full_set()) { | |
478 | child_neighbors[dir] = child_neighbors_f[dir].get(); | |
479 | if (child_neighbors[dir] == hpx::invalid_id) { | |
480 | amr_flags[ci][dir] = true; | |
481 | } else { | |
482 | amr_flags[ci][dir] = false; | |
483 | } | |
484 | } | |
485 | cfuts.push_back( | |
486 | children[ci].form_tree(children[ci].get_gid(), me.get_gid(), | |
487 | std::move(child_neighbors))); | |
488 | } | |
489 | } | |
490 | } | |
491 | ||
492 | wait_all_and_propagate_exceptions(cfuts); | |
493 | } else { | |
494 | std::vector < hpx::future<std::vector<hpx::id_type>>>nfuts(NFACE); | |
495 | for (auto& f : geo::face::full_set()) { | |
496 | const auto& neighbor = neighbors[f.to_direction()]; | |
497 | if (!neighbor.empty()) { | |
498 | nfuts[f] = neighbor.get_nieces(me.get_gid(), f ^ 1); | |
499 | } else { | |
500 | nfuts[f] = hpx::make_ready_future(std::vector<hpx::id_type>()); | |
501 | } | |
502 | } | |
503 | for (auto& f : geo::face::full_set()) { | |
504 | auto ids = nfuts[f].get(); | |
505 | nieces[f].resize(ids.size()); | |
506 | for (std::size_t i = 0; i != ids.size(); ++i) { | |
507 | nieces[f][i] = ids[i]; | |
508 | } | |
509 | } | |
510 | } | |
511 | ||
512 | } | |
513 | ||
514 | typedef node_server::get_child_client_action get_child_client_action_type; | |
515 | HPX_REGISTER_ACTION(get_child_client_action_type); | |
516 | ||
517 | hpx::future<hpx::id_type> node_client::get_child_client(const geo::octant& ci) { | |
518 | if (get_gid() != hpx::invalid_id) { | |
519 | return hpx::async<typename node_server::get_child_client_action>(get_gid(), ci); | |
520 | } else { | |
521 | auto tmp = hpx::invalid_id; | |
522 | return hpx::make_ready_future<hpx::id_type>(std::move(tmp)); | |
523 | } | |
524 | } | |
525 | ||
526 | hpx::id_type node_server::get_child_client(const geo::octant& ci) { | |
527 | if (is_refined) { | |
528 | return children[ci].get_gid(); | |
529 | } else { | |
530 | return hpx::invalid_id; | |
531 | } | |
532 | } | |
533 | ||
534 | typedef node_server::get_nieces_action get_nieces_action_type; | |
535 | HPX_REGISTER_ACTION(get_nieces_action_type); | |
536 | ||
537 | hpx::future<std::vector<hpx::id_type>> node_client::get_nieces(const hpx::id_type& aunt, | |
538 | const geo::face& f) const { | |
539 | return hpx::async<typename node_server::get_nieces_action>(get_gid(), aunt, f); | |
540 | } | |
541 | ||
542 | std::vector<hpx::id_type> node_server::get_nieces(const hpx::id_type& aunt, | |
543 | const geo::face& face) const { | |
544 | std::vector<hpx::id_type> nieces; | |
545 | if (is_refined) { | |
546 | std::vector<hpx::future<void>> futs; | |
547 | nieces.reserve(geo::quadrant::count()); | |
548 | futs.reserve(geo::quadrant::count()); | |
549 | for (auto& ci : geo::octant::face_subset(face)) { | |
550 | nieces.push_back(children[ci].get_gid()); | |
551 | futs.push_back(children[ci].set_aunt(aunt, face)); | |
552 | } | |
553 | for (auto&& this_fut : futs) { | |
554 | this_fut.get(); | |
555 | } | |
556 | } | |
557 | return nieces; | |
558 | } | |
559 | ||
560 | typedef node_server::get_ptr_action get_ptr_action_type; | |
561 | HPX_REGISTER_ACTION(get_ptr_action_type); | |
562 | ||
563 | std::uintptr_t node_server::get_ptr() { | |
564 | return reinterpret_cast<std::uintptr_t>(this); | |
565 | } | |
566 | ||
567 | hpx::future<node_server*> node_client::get_ptr() const { | |
568 | return hpx::async<typename node_server::get_ptr_action>(get_gid()).then( | |
569 | [](hpx::future<std::uintptr_t>&& fut) { | |
570 | return reinterpret_cast<node_server*>(fut.get()); | |
571 | }); | |
572 | } | |
573 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.