/home/users/khuck/src/octotiger/src/node_server_actions_2.cpp

Line% of fetchesSource
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.