32 auto edges = get_edges();
34 auto &thread_counts = edges.sizes.indexes;
36 edges.neigh_cache.check_sizes(thread_counts);
37 edges.positions.check_sizes(thread_counts);
38 edges.old_h.check_sizes(thread_counts);
39 edges.new_h.ensure_sizes(thread_counts);
40 edges.eps_h.ensure_sizes(thread_counts);
41 edges.was_limited.ensure_sizes(thread_counts);
43 auto &neigh_cache = edges.neigh_cache.neigh_cache;
44 auto &positions = edges.positions.get_spans();
45 auto &old_h = edges.old_h.get_spans();
46 auto &new_h = edges.new_h.get_spans();
47 auto &eps_h = edges.eps_h.get_spans();
48 auto &was_limited = edges.was_limited.get_spans();
50 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
52 static constexpr Tscal Rkern = SPHKernel::Rkern;
59 [gpart_mass = this->gpart_mass,
60 h_evol_max = this->h_evol_max,
61 h_evol_iter_max = this->h_evol_iter_max,
62 trigger_threshold = this->trigger_threshold,
63 epsilon_h = this->epsilon_h](
66 const Tvec *__restrict r,
67 const Tscal *__restrict h_old,
68 Tscal *__restrict h_new,
69 Tscal *__restrict eps,
70 u32 *__restrict was_limited) {
74 Tscal part_mass = gpart_mass;
75 Tscal h_max_tot_max_evol = h_evol_max;
76 Tscal h_max_evol_p = h_evol_iter_max;
77 Tscal h_max_evol_m = 1 / h_evol_iter_max;
79 if (eps[id_a] > epsilon_h) {
83 Tscal h_a = h_new[id_a];
84 Tscal dint = h_a * h_a * Rkern * Rkern;
90 u32 count_within_next = 0;
92 particle_looper.for_each_object(id_a, [&](
u32 id_b) {
93 Tvec dr = xyz_a - r[id_b];
94 Tscal rab2 = sycl::dot(dr, dr);
96 if (rab2 <= dint * h_max_evol_p * h_max_evol_p) {
104 Tscal rab = sycl::sqrt(rab2);
106 rho_sum += part_mass * SPHKernel::W_3d(rab, h_a);
107 sumdWdh += part_mass * SPHKernel::dhW_3d(rab, h_a);
112 using namespace shamrock::sph;
114 Tscal rho_ha = rho_h(part_mass, h_a, SPHKernel::hfactd);
115 Tscal new_h = newton_iterate_new_h(rho_ha, rho_sum, sumdWdh, h_a);
117 bool exceed_inner_threshold = count_within > trigger_threshold;
118 bool exceed_outer_threshold = count_within_next > trigger_threshold;
120 if (exceed_inner_threshold) {
121 h_new[id_a] = h_max_evol_m * h_a;
123 was_limited[id_a] = 1;
127 if (exceed_outer_threshold && new_h > h_a) {
129 was_limited[id_a] = 1;
133 if (new_h < h_a * h_max_evol_m)
134 new_h = h_max_evol_m * h_a;
135 if (new_h > h_a * h_max_evol_p)
136 new_h = h_max_evol_p * h_a;
138 Tscal ha_0 = h_old[id_a];
140 if (new_h < ha_0 * h_max_tot_max_evol) {
142 eps[id_a] = sycl::fabs(new_h - h_a) / ha_0;
144 h_new[id_a] = ha_0 * h_max_tot_max_evol;
147 was_limited[id_a] = 0;