| 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.