Line | % of fetches | Source |
---|---|---|
1 | #include "node_server.hpp" | |
2 | #include "node_client.hpp" | |
3 | #include "future.hpp" | |
4 | #include "options.hpp" | |
5 | #include "util.hpp" | |
6 | ||
7 | #include <hpx/include/run_as.hpp> | |
8 | #include <hpx/include/lcos.hpp> | |
9 | #include <hpx/include/util.hpp> | |
10 | ||
11 | extern options opts; | |
12 | ||
13 | typedef node_server::send_gravity_boundary_action send_gravity_boundary_action_type; | |
14 | HPX_REGISTER_ACTION(send_gravity_boundary_action_type); | |
15 | ||
16 | hpx::future<void> node_client::send_gravity_boundary(gravity_boundary_type&& data, | |
17 | const geo::direction& dir, bool monopole) const { | |
18 | return hpx::async<typename node_server::send_gravity_boundary_action>(get_gid(), | |
19 | std::move(data), dir, monopole); | |
20 | } | |
21 | ||
22 | void node_server::recv_gravity_boundary(gravity_boundary_type&& bdata, | |
23 | const geo::direction& dir, bool monopole) { | |
24 | neighbor_gravity_type tmp; | |
25 | tmp.data = std::move(bdata); | |
26 | tmp.is_monopole = monopole; | |
27 | tmp.direction = dir; | |
28 | neighbor_gravity_channels[dir].set_value(std::move(tmp)); | |
29 | } | |
30 | ||
31 | typedef node_server::send_gravity_expansions_action send_gravity_expansions_action_type; | |
32 | HPX_REGISTER_ACTION(send_gravity_expansions_action_type); | |
33 | ||
34 | void node_server::recv_gravity_expansions(expansion_pass_type&& v) { | |
35 | parent_gravity_channel.set_value(std::move(v)); | |
36 | } | |
37 | ||
38 | hpx::future<void> node_client::send_gravity_expansions(expansion_pass_type&& data) const { | |
39 | return hpx::async<typename node_server::send_gravity_expansions_action>(get_gid(), | |
40 | std::move(data)); | |
41 | } | |
42 | ||
43 | typedef node_server::send_gravity_multipoles_action send_gravity_multipoles_action_type; | |
44 | HPX_REGISTER_ACTION(send_gravity_multipoles_action_type); | |
45 | ||
46 | hpx::future<void> node_client::send_gravity_multipoles(multipole_pass_type&& data, | |
47 | const geo::octant& ci) const { | |
48 | return hpx::async<typename node_server::send_gravity_multipoles_action>(get_gid(), | |
49 | std::move(data), ci); | |
50 | } | |
51 | ||
52 | void node_server::recv_gravity_multipoles(multipole_pass_type&& v, | |
53 | const geo::octant& ci) { | |
54 | child_gravity_channels[ci].set_value(std::move(v)); | |
55 | } | |
56 | ||
57 | typedef node_server::send_hydro_boundary_action send_hydro_boundary_action_type; | |
58 | HPX_REGISTER_ACTION(send_hydro_boundary_action_type); | |
59 | ||
60 | hpx::future<void> node_client::send_hydro_boundary(std::vector<real>&& data, | |
61 | const geo::direction& dir) const { | |
62 | return hpx::async<typename node_server::send_hydro_boundary_action>(get_gid(), | |
63 | std::move(data), dir); | |
64 | } | |
65 | ||
66 | void node_server::recv_hydro_boundary(std::vector<real>&& bdata, | |
67 | const geo::direction& dir) { | |
68 | sibling_hydro_type tmp; | |
69 | tmp.data = std::move(bdata); | |
70 | tmp.direction = dir; | |
71 | sibling_hydro_channels[dir].set_value(std::move(tmp)); | |
72 | } | |
73 | ||
74 | typedef node_server::send_hydro_children_action send_hydro_children_action_type; | |
75 | HPX_REGISTER_ACTION(send_hydro_children_action_type); | |
76 | ||
77 | void node_server::recv_hydro_children(std::vector<real>&& data, const geo::octant& ci) { | |
78 | child_hydro_channels[ci].set_value(std::move(data)); | |
79 | } | |
80 | ||
81 | hpx::future<void> node_client::send_hydro_children(std::vector<real>&& data, | |
82 | const geo::octant& ci) const { | |
83 | return hpx::async<typename node_server::send_hydro_children_action>(get_gid(), | |
84 | std::move(data), ci); | |
85 | } | |
86 | ||
87 | typedef node_server::send_hydro_flux_correct_action send_hydro_flux_correct_action_type; | |
88 | HPX_REGISTER_ACTION(send_hydro_flux_correct_action_type); | |
89 | ||
90 | hpx::future<void> node_client::send_hydro_flux_correct(std::vector<real>&& data, | |
91 | const geo::face& face, | |
92 | const geo::octant& ci) const { | |
93 | return hpx::async<typename node_server::send_hydro_flux_correct_action>(get_gid(), | |
94 | std::move(data), face, ci); | |
95 | } | |
96 | ||
97 | void node_server::recv_hydro_flux_correct(std::vector<real>&& data, const geo::face& face, | |
98 | const geo::octant& ci) { | |
99 | const geo::quadrant index(ci, face.get_dimension()); | |
100 | niece_hydro_channels[face][index].set_value(std::move(data)); | |
101 | } | |
102 | ||
103 | typedef node_server::line_of_centers_action line_of_centers_action_type; | |
104 | HPX_REGISTER_ACTION(line_of_centers_action_type); | |
105 | ||
106 | hpx::future<line_of_centers_t> node_client::line_of_centers( | |
107 | const std::pair<space_vector, space_vector>& line) const { | |
108 | return hpx::async<typename node_server::line_of_centers_action>(get_gid(), line); | |
109 | } | |
110 | ||
111 | void output_line_of_centers(FILE* fp, const line_of_centers_t& loc) { | |
112 | for (integer i = 0; i != loc.size(); ++i) { | |
113 | fprintf(fp, "%e ", loc[i].first); | |
114 | for (integer j = 0; j != NF + NGF; ++j) { | |
115 | fprintf(fp, "%e ", loc[i].second[j]); | |
116 | } | |
117 | fprintf(fp, "\n"); | |
118 | } | |
119 | } | |
120 | ||
121 | line_of_centers_t node_server::line_of_centers( | |
122 | const std::pair<space_vector, space_vector>& line) const { | |
123 | std::list < hpx::future < line_of_centers_t >> futs; | |
124 | line_of_centers_t return_line; | |
125 | if (is_refined) { | |
126 | for (integer ci = 0; ci != NCHILD; ++ci) { | |
127 | futs.push_back(children[ci].line_of_centers(line)); | |
128 | } | |
129 | std::map<real, std::vector<real>> map; | |
130 | for (auto&& fut : futs) { | |
131 | auto tmp = fut.get(); | |
132 | for (integer ii = 0; ii != tmp.size(); ++ii) { | |
133 | if (map.find(tmp[ii].first) == map.end()) { | |
134 | map.emplace(std::move(tmp[ii])); | |
135 | } | |
136 | } | |
137 | } | |
138 | return_line.resize(map.size()); | |
139 | std::move(map.begin(), map.end(), return_line.begin()); | |
140 | } else { | |
141 | return_line = grid_ptr->line_of_centers(line); | |
142 | } | |
143 | ||
144 | return return_line; | |
145 | } | |
146 | ||
147 | void line_of_centers_analyze(const line_of_centers_t& loc, real omega, | |
148 | std::pair<real, real>& rho1_max, std::pair<real, real>& rho2_max, | |
149 | std::pair<real, real>& l1_phi, std::pair<real, real>& l2_phi, | |
150 | std::pair<real, real>& l3_phi, real& rho1_phi, real& rho2_phi) { | |
151 | ||
152 | for (auto& l : loc) { | |
153 | ASSERT_NONAN(l.first); | |
154 | for (integer f = 0; f != NF + NGF; ++f) { | |
155 | ASSERT_NONAN(l.second[f]); | |
156 | } | |
157 | } | |
158 | ||
159 | rho1_max.second = rho2_max.second = 0.0; | |
160 | integer rho1_maxi, rho2_maxi; | |
161 | /// printf( "LOCSIZE %i\n", loc.size()); | |
162 | for (integer i = 0; i != loc.size(); ++i) { | |
163 | const real x = loc[i].first; | |
164 | const real rho = loc[i].second[rho_i]; | |
165 | const real pot = loc[i].second[pot_i]; | |
166 | // printf( "%e %e\n", x, rho); | |
167 | if (rho1_max.second < rho) { | |
168 | // printf( "!\n"); | |
169 | rho1_max.second = rho; | |
170 | rho1_max.first = x; | |
171 | rho1_maxi = i; | |
172 | real phi_eff = pot / ASSERT_POSITIVE(rho) - 0.5 * x * x * omega * omega; | |
173 | rho1_phi = phi_eff; | |
174 | } | |
175 | } | |
176 | for (integer i = 0; i != loc.size(); ++i) { | |
177 | const real x = loc[i].first; | |
178 | if (x * rho1_max.first < 0.0) { | |
179 | const real rho = loc[i].second[rho_i]; | |
180 | const real pot = loc[i].second[pot_i]; | |
181 | if (rho2_max.second < rho) { | |
182 | rho2_max.second = rho; | |
183 | rho2_max.first = x; | |
184 | rho2_maxi = i; | |
185 | real phi_eff = pot / ASSERT_POSITIVE(rho) - 0.5 * x * x * omega * omega; | |
186 | rho2_phi = phi_eff; | |
187 | } | |
188 | } | |
189 | } | |
190 | l1_phi.second = -std::numeric_limits < real > ::max(); | |
191 | l2_phi.second = -std::numeric_limits < real > ::max(); | |
192 | l3_phi.second = -std::numeric_limits < real > ::max(); | |
193 | for (integer i = 0; i != loc.size(); ++i) { | |
194 | const real x = loc[i].first; | |
195 | const real rho = loc[i].second[rho_i]; | |
196 | const real pot = loc[i].second[pot_i]; | |
197 | real phi_eff = pot / ASSERT_POSITIVE(rho) - 0.5 * x * x * omega * omega; | |
198 | if (x > std::min(rho1_max.first, rho2_max.first) | |
199 | && x < std::max(rho1_max.first, rho2_max.first)) { | |
200 | if (phi_eff > l1_phi.second) { | |
201 | l1_phi.second = phi_eff; | |
202 | l1_phi.first = x; | |
203 | } | |
204 | } else if (std::abs(x) > std::abs(rho2_max.first) && x * rho2_max.first > 0.0) { | |
205 | if (phi_eff > l2_phi.second) { | |
206 | l2_phi.second = phi_eff; | |
207 | l2_phi.first = x; | |
208 | } | |
209 | } else if (std::abs(x) > std::abs(rho1_max.first)) { | |
210 | if (phi_eff > l3_phi.second) { | |
211 | l3_phi.second = phi_eff; | |
212 | l3_phi.first = x; | |
213 | } | |
214 | } | |
215 | } | |
216 | } | |
217 | ||
218 | typedef node_server::start_run_action start_run_action_type; | |
219 | HPX_REGISTER_ACTION(start_run_action_type); | |
220 | ||
221 | hpx::future<void> node_client::start_run(bool b) const { | |
222 | return hpx::async<typename node_server::start_run_action>(get_gid(), b); | |
223 | } | |
224 | ||
225 | void node_server::start_run(bool scf) { | |
226 | timings::scope ts(timings_, timings::time_total); | |
227 | integer output_cnt; | |
228 | ||
229 | if (!hydro_on) { | |
230 | save_to_file("X.chk"); | |
231 | diagnostics(); | |
232 | return; | |
233 | } | |
234 | printf("%e %e\n", grid::get_A(), grid::get_B()); | |
235 | if (scf) { | |
236 | run_scf(); | |
237 | set_pivot(); | |
238 | printf("Adjusting velocities:\n"); | |
239 | auto diag = diagnostics(); | |
240 | space_vector dv; | |
241 | dv[XDIM] = -diag.grid_sum[sx_i] / diag.grid_sum[rho_i]; | |
242 | dv[YDIM] = -diag.grid_sum[sy_i] / diag.grid_sum[rho_i]; | |
243 | dv[ZDIM] = -diag.grid_sum[sz_i] / diag.grid_sum[rho_i]; | |
244 | this->velocity_inc(dv); | |
245 | save_to_file("scf.chk"); | |
246 | } | |
247 | ||
248 | printf("Starting...\n"); | |
249 | solve_gravity(false); | |
250 | int ngrids = regrid(me.get_gid(), false); | |
251 | ||
252 | real output_dt = opts.output_dt; | |
253 | ||
254 | printf("OMEGA = %e, output_dt = %e\n", grid::get_omega(), output_dt); | |
255 | real& t = current_time; | |
256 | integer step_num = 0; | |
257 | ||
258 | auto fut_ptr = me.get_ptr(); | |
259 | node_server* root_ptr = fut_ptr.get(); | |
260 | ||
261 | output_cnt = root_ptr->get_rotation_count() / output_dt; | |
262 | hpx::future<void> diag_fut = hpx::make_ready_future(); | |
263 | profiler_output (stdout); | |
264 | real bench_start, bench_stop; | |
265 | while (current_time < opts.stop_time) { | |
266 | if (step_num > opts.stop_step) | |
267 | break; | |
268 | ||
269 | auto time_start = std::chrono::high_resolution_clock::now(); | |
270 | if (!opts.disable_output && root_ptr->get_rotation_count() / output_dt >= output_cnt) { | |
271 | // if (step_num != 0) { | |
272 | ||
273 | char fname[33]; // 21 bytes for int (max) + some leeway | |
274 | sprintf(fname, "X.%i.chk", int(output_cnt)); | |
275 | save_to_file(fname); | |
276 | ||
277 | sprintf(fname, "X.%i.silo", int(output_cnt)); | |
278 | output(fname, output_cnt, false); | |
279 | ||
280 | // SYSTEM(std::string("cp *.dat ./dat_back/\n")); | |
281 | // } | |
282 | ++output_cnt; | |
283 | ||
284 | } | |
285 | if (step_num == 0) { | |
286 | bench_start = hpx::util::high_resolution_clock::now() / 1e9; | |
287 | } | |
288 | ||
289 | // break; | |
290 | auto ts_fut = hpx::async([=]() {return timestep_driver();}); | |
291 | step().get(); | |
292 | real dt = ts_fut.get(); | |
293 | real omega_dot = 0.0, omega = 0.0, theta = 0.0, theta_dot = 0.0; | |
294 | omega = grid::get_omega(); | |
295 | if (opts.problem == DWD) { | |
296 | auto diags = diagnostics(); | |
297 | ||
298 | const real dx = diags.secondary_com[XDIM] - diags.primary_com[XDIM]; | |
299 | const real dy = diags.secondary_com[YDIM] - diags.primary_com[YDIM]; | |
300 | const real dx_dot = diags.secondary_com_dot[XDIM] | |
301 | - diags.primary_com_dot[XDIM]; | |
302 | const real dy_dot = diags.secondary_com_dot[YDIM] | |
303 | - diags.primary_com_dot[YDIM]; | |
304 | theta = atan2(dy, dx); | |
305 | omega = grid::get_omega(); | |
306 | theta_dot = (dy_dot * dx - dx_dot * dy) / (dx * dx + dy * dy) - omega; | |
307 | const real w0 = grid::get_omega() * 100.0; | |
308 | const real theta_dot_dot = (2.0 * w0 * theta_dot + w0 * w0 * theta); | |
309 | omega_dot = theta_dot_dot; | |
310 | omega += omega_dot * dt; | |
311 | // omega_dot += theta_dot_dot*dt; | |
312 | grid::set_omega(omega); | |
313 | } | |
314 | double time_elapsed = std::chrono::duration_cast<std::chrono::duration<double>>( | |
315 | std::chrono::high_resolution_clock::now() - time_start).count(); | |
316 | ||
317 | // run output on separate thread | |
318 | if (!opts.disable_output) | |
319 | { | |
320 | hpx::threads::run_as_os_thread([=]() | |
321 | { | |
322 | FILE* fp = fopen( "step.dat", "at"); | |
323 | fprintf(fp, "%i %e %e %e %e %e %e %e %e %i\n", | |
324 | int(step_num), double(t), double(dt), time_elapsed, rotational_time, | |
325 | theta, theta_dot, omega, omega_dot, int(ngrids)); | |
326 | fclose(fp); | |
327 | }); // do not wait for it fo finish | |
328 | } | |
329 | ||
330 | printf("%i %e %e %e %e %e %e %e %e\n", int(step_num), double(t), double(dt), | |
331 | time_elapsed, rotational_time, theta, theta_dot, omega, omega_dot); | |
332 | ||
333 | // t += dt; | |
334 | ++step_num; | |
335 | ||
336 | if (step_num % refinement_freq() == 0) { | |
337 | ngrids = regrid(me.get_gid(), false); | |
338 | ||
339 | // run output on separate thread | |
340 | auto need_break = hpx::threads::run_as_os_thread([&]() | |
341 | { | |
342 | FILE* fp = fopen("profile.txt", "wt"); | |
343 | profiler_output(fp); | |
344 | fclose(fp); | |
345 | ||
346 | // set_omega_and_pivot(); | |
347 | bench_stop = hpx::util::high_resolution_clock::now() / 1e9; | |
348 | if (scf || opts.bench) { | |
349 | printf("Total time = %e s\n", double(bench_stop - bench_start)); | |
350 | FILE* fp = fopen("bench.dat", "at"); | |
351 | fprintf(fp, "%i %e\n", int(hpx::find_all_localities().size()), | |
352 | double(bench_stop - bench_start)); | |
353 | fclose(fp); | |
354 | return true; | |
355 | } | |
356 | return false; | |
357 | }); | |
358 | if (need_break.get()) | |
359 | break; | |
360 | } | |
361 | // set_omega_and_pivot(); | |
362 | if (scf) { | |
363 | bench_stop = hpx::util::high_resolution_clock::now() / 1e9; | |
364 | printf("Total time = %e s\n", double(bench_stop - bench_start)); | |
365 | // FILE* fp = fopen( "bench.dat", "at" ); | |
366 | // fprintf( fp, "%i %e\n", int(hpx::find_all_localities().size()), double(bench_stop - bench_start)); | |
367 | // fclose(fp); | |
368 | break; | |
369 | } | |
370 | } | |
371 | compare_analytic(); | |
372 | output("final.silo", output_cnt, true); | |
373 | } | |
374 | ||
375 | typedef node_server::step_action step_action_type; | |
376 | HPX_REGISTER_ACTION(step_action_type); | |
377 | ||
378 | hpx::future<void> node_client::step() const { | |
379 | return hpx::async<typename node_server::step_action>(get_gid()); | |
380 | } | |
381 | ||
382 | hpx::future<void> node_server::refined_step(std::vector<hpx::future<void>> child_futs) { | |
383 | timings::scope ts(timings_, timings::time_computation); | |
384 | const real dx = TWO * grid::get_scaling_factor() / real(INX << my_location.level()); | |
385 | real cfl0 = cfl; | |
386 | ||
387 | // FIXME: is this correct? ('a' was never re-initialized for refined == true) | |
388 | real a = std::numeric_limits<real>::min(); | |
389 | ||
390 | dt_ = cfl0 * dx / a; | |
391 | ||
392 | hpx::future<void> fut = all_hydro_bounds(); | |
393 | for (integer rk = 0; rk < NRK; ++rk) { | |
394 | ||
395 | fut = fut.then( | |
396 | [rk, this](hpx::future<void> f) | |
397 | { | |
398 | f.get(); // propagate exceptions | |
399 | ||
400 | if (rk == 0) { | |
401 | local_timestep_channel.set_value(dt_); | |
402 | } | |
403 | ||
404 | compute_fmm(DRHODT, false); | |
405 | ||
406 | if (rk == 0) { | |
407 | dt_ = global_timestep_channel.get_future().get(); | |
408 | } | |
409 | ||
410 | compute_fmm(RHO, true); | |
411 | return all_hydro_bounds(); | |
412 | }); | |
413 | } | |
414 | ||
415 | return hpx::dataflow( | |
416 | [this](hpx::future<void> f, std::vector<hpx::future<void>> children) | |
417 | { | |
418 | // propagate exceptions | |
419 | f.get(); | |
420 | for (auto& f: children) | |
421 | { | |
422 | if (f.has_exception()) | |
423 | f.get(); | |
424 | } | |
425 | ||
426 | grid_ptr->dual_energy_update(); | |
427 | current_time += dt_; | |
428 | if (grid::get_omega() != 0.0) { | |
429 | rotational_time += grid::get_omega() * dt_; | |
430 | } else { | |
431 | rotational_time = current_time; | |
432 | } | |
433 | ++step_num; | |
434 | }, | |
435 | std::move(fut), std::move(child_futs)); | |
436 | } | |
437 | ||
438 | hpx::future<void> node_server::nonrefined_step() { | |
439 | timings::scope ts(timings_, timings::time_computation); | |
440 | ||
441 | real cfl0 = cfl; | |
442 | dt_ = ZERO; | |
443 | ||
444 | hpx::future<void> fut = all_hydro_bounds(); | |
445 | ||
446 | grid_ptr->store(); | |
447 | ||
448 | for (integer rk = 0; rk < NRK; ++rk) { | |
449 | ||
450 | fut = fut.then( | |
451 | [rk, cfl0, this](hpx::future<void> f) | |
452 | { | |
453 | f.get(); // propagate exceptions | |
454 | ||
455 | grid_ptr->reconstruct(); | |
456 | real a = grid_ptr->compute_fluxes(); | |
457 | ||
458 | hpx::future<void> fut_flux = exchange_flux_corrections(); | |
459 | ||
460 | if (rk == 0) { | |
461 | const real dx = TWO * grid::get_scaling_factor() / | |
462 | real(INX << my_location.level()); | |
463 | dt_ = cfl0 * dx / a; | |
464 | local_timestep_channel.set_value(dt_); | |
465 | } | |
466 | ||
467 | return fut_flux.then( | |
468 | [rk, this](hpx::future<void> f) | |
469 | { | |
470 | f.get(); // propagate exceptions | |
471 | ||
472 | grid_ptr->compute_sources(current_time); | |
473 | grid_ptr->compute_dudt(); | |
474 | ||
475 | compute_fmm(DRHODT, false); | |
476 | ||
477 | if (rk == 0) { | |
478 | dt_ = global_timestep_channel.get_future().get(); | |
479 | } | |
480 | ||
481 | grid_ptr->next_u(rk, current_time, dt_); | |
482 | ||
483 | compute_fmm(RHO, true); | |
484 | return all_hydro_bounds(); | |
485 | }); | |
486 | }); | |
487 | } | |
488 | ||
489 | return fut.then( | |
490 | [this](hpx::future<void> f) | |
491 | { | |
492 | f.get(); // propagate exceptions | |
493 | ||
494 | grid_ptr->dual_energy_update(); | |
495 | ||
496 | current_time += dt_; | |
497 | if (grid::get_omega() != 0.0) { | |
498 | rotational_time += grid::get_omega() * dt_; | |
499 | } else { | |
500 | rotational_time = current_time; | |
501 | } | |
502 | ++step_num; | |
503 | }); | |
504 | } | |
505 | ||
506 | hpx::future<void> node_server::step() { | |
507 | grid_ptr->set_coordinates(); | |
508 | ||
509 | if (is_refined) { | |
510 | std::vector<hpx::future<void>> child_futs; | |
511 | child_futs.reserve(NCHILD); | |
512 | for (integer ci = 0; ci != NCHILD; ++ci) { | |
513 | child_futs.push_back(children[ci].step()); | |
514 | } | |
515 | return refined_step(std::move(child_futs)); | |
516 | } | |
517 | ||
518 | return nonrefined_step(); | |
519 | } | |
520 | ||
521 | typedef node_server::timestep_driver_ascend_action timestep_driver_ascend_action_type; | |
522 | HPX_REGISTER_ACTION(timestep_driver_ascend_action_type); | |
523 | ||
524 | hpx::future<void> node_client::timestep_driver_ascend(real dt) const { | |
525 | return hpx::async<typename node_server::timestep_driver_ascend_action>(get_gid(), dt); | |
526 | } | |
527 | ||
528 | void node_server::timestep_driver_ascend(real dt) { | |
529 | global_timestep_channel.set_value(dt); | |
530 | if (is_refined) { | |
531 | std::vector<hpx::future<void>> futs; | |
532 | futs.reserve(children.size()); | |
533 | for(auto& child: children) { | |
534 | futs.push_back(child.timestep_driver_ascend(dt)); | |
535 | } | |
536 | wait_all_and_propagate_exceptions(futs); | |
537 | } | |
538 | } | |
539 | ||
540 | typedef node_server::timestep_driver_descend_action timestep_driver_descend_action_type; | |
541 | HPX_REGISTER_ACTION(timestep_driver_descend_action_type); | |
542 | ||
543 | hpx::future<real> node_client::timestep_driver_descend() const { | |
544 | return hpx::async<typename node_server::timestep_driver_descend_action>(get_gid()); | |
545 | } | |
546 | ||
547 | hpx::future<real> node_server::timestep_driver_descend() { | |
548 | if (is_refined) { | |
549 | std::vector<hpx::future<real>> futs; | |
550 | futs.reserve(children.size() + 1); | |
551 | for(auto& child: children) { | |
552 | futs.push_back(child.timestep_driver_descend()); | |
553 | } | |
554 | futs.push_back(local_timestep_channel.get_future()); | |
555 | ||
556 | return hpx::dataflow( | |
557 | [](std::vector<hpx::future<real>> dts_fut) -> double | |
558 | { | |
559 | auto dts = hpx::util::unwrapped(dts_fut); | |
560 | return *std::min_element(dts.begin(), dts.end()); | |
561 | }, | |
562 | std::move(futs)); | |
563 | } else { | |
564 | return local_timestep_channel.get_future(); | |
565 | } | |
566 | } | |
567 | ||
568 | typedef node_server::timestep_driver_action timestep_driver_action_type; | |
569 | HPX_REGISTER_ACTION(timestep_driver_action_type); | |
570 | ||
571 | hpx::future<real> node_client::timestep_driver() const { | |
572 | return hpx::async<typename node_server::timestep_driver_action>(get_gid()); | |
573 | } | |
574 | ||
575 | real node_server::timestep_driver() { | |
576 | const real dt = timestep_driver_descend().get(); | |
577 | timestep_driver_ascend(dt); | |
578 | return dt; | |
579 | } | |
580 | ||
581 | typedef node_server::velocity_inc_action velocity_inc_action_type; | |
582 | HPX_REGISTER_ACTION(velocity_inc_action_type); | |
583 | ||
584 | hpx::future<void> node_client::velocity_inc(const space_vector& dv) const { | |
585 | return hpx::async<typename node_server::velocity_inc_action>(get_gid(), dv); | |
586 | } | |
587 | ||
588 | void node_server::velocity_inc(const space_vector& dv) { | |
589 | if (is_refined) { | |
590 | std::vector<hpx::future<void>> futs; | |
591 | futs.reserve(NCHILD); | |
592 | for (auto& child : children) { | |
593 | futs.push_back(child.velocity_inc(dv)); | |
594 | } | |
595 | wait_all_and_propagate_exceptions(futs); | |
596 | } else { | |
597 | grid_ptr->velocity_inc(dv); | |
598 | } | |
599 | } | |
600 | ||
601 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.