Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
IterateSmoothingLengthDensityNeighLim.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
16
18#include "shambase/string.hpp"
20#include "shamcomm/logs.hpp"
25
26using namespace shammodels::sph::modules;
27
28template<class Tvec, class SPHKernel>
30 StackEntry stack_loc{};
31
32 auto edges = get_edges();
33
34 auto &thread_counts = edges.sizes.indexes;
35
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);
42
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();
49
50 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
51
52 static constexpr Tscal Rkern = SPHKernel::Rkern;
53
55 dev_sched,
56 sham::DDMultiRef{neigh_cache, positions, old_h},
57 sham::DDMultiRef{new_h, eps_h, was_limited},
58 thread_counts,
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](
64 u32 id_a,
65 auto ploop_ptrs,
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) {
71 // attach the neighbor looper on the cache
72 shamrock::tree::ObjectCacheIterator particle_looper(ploop_ptrs);
73
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;
78
79 if (eps[id_a] > epsilon_h) {
80
81 Tvec xyz_a = r[id_a]; // could be recovered from lambda
82
83 Tscal h_a = h_new[id_a];
84 Tscal dint = h_a * h_a * Rkern * Rkern;
85
86 Tscal rho_sum = 0;
87 Tscal sumdWdh = 0;
88
89 u32 count_within = 0;
90 u32 count_within_next = 0;
91
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);
95
96 if (rab2 <= dint * h_max_evol_p * h_max_evol_p) {
97 count_within_next++;
98 }
99
100 if (rab2 > dint) {
101 return; // early return if the particle is too far away
102 }
103
104 Tscal rab = sycl::sqrt(rab2);
105
106 rho_sum += part_mass * SPHKernel::W_3d(rab, h_a);
107 sumdWdh += part_mass * SPHKernel::dhW_3d(rab, h_a);
108
109 count_within++;
110 });
111
112 using namespace shamrock::sph;
113
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);
116
117 bool exceed_inner_threshold = count_within > trigger_threshold;
118 bool exceed_outer_threshold = count_within_next > trigger_threshold;
119
120 if (exceed_inner_threshold) {
121 h_new[id_a] = h_max_evol_m * h_a;
122 eps[id_a] = 0;
123 was_limited[id_a] = 1;
124 return;
125 }
126
127 if (exceed_outer_threshold && new_h > h_a) {
128 eps[id_a] = 0;
129 was_limited[id_a] = 1;
130 return;
131 }
132
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;
137
138 Tscal ha_0 = h_old[id_a];
139
140 if (new_h < ha_0 * h_max_tot_max_evol) {
141 h_new[id_a] = new_h;
142 eps[id_a] = sycl::fabs(new_h - h_a) / ha_0;
143 } else {
144 h_new[id_a] = ha_0 * h_max_tot_max_evol;
145 eps[id_a] = -1;
146 }
147 was_limited[id_a] = 0;
148 }
149 });
150}
151
152template<class Tvec, class SPHKernel>
154 std::string tex = R"tex(
155 Iterate smoothing length and density
156
157 \begin{align}
158 \rho_i &= \sum_{j \in \mathcal{N}_i} m_j W(r_{ij}, h_i) \\
159 \frac{\partial \rho_i}{\partial h_i} &= \sum_{j \in \mathcal{N}_i} m_j \frac{\partial W}{\partial h}(r_{ij}, h_i) \\
160 h_i^{\rm new} &= h_i - \frac{\rho_i - \rho_h(m_i, h_i)}{\frac{\partial \rho_i}{\partial h_i} + \frac{3\rho_h(m_i, h_i)}{h_i}} \\
161 \epsilon_i &= \frac{|h_i^{\rm new} - h_i|}{h_i^{\rm old}}
162 \end{align}
163
164 where:
165 \begin{itemize}
166 \item $\mathcal{N}_i$ is the set of neighbors of particle $i$
167 \item $W(r, h)$ is the SPH kernel function
168 \item $\rho_h(m, h) = m \left(\frac{h_{\rm fact}}{h}\right)^3$ is the target density
169 \item $h_{\rm fact} = {hfact}$ is the kernel factor
170 \item $R_{\rm kern} = {Rkern}$ is the kernel radius
171 \end{itemize}
172
173 Input: ${sizes}$, ${neigh_cache}$, ${positions}$, ${old_h}$
174 Output: ${new_h}$, ${eps_h}$
175 )tex";
176
177 replace_edges_tex_symbols(tex);
178
179 shambase::replace_all(tex, "{hfact}", sham::format("{}", SPHKernel::hfactd));
180 shambase::replace_all(tex, "{Rkern}", sham::format("{}", SPHKernel::Rkern));
181
182 return tex;
183}
184
185template class shammodels::sph::modules::
186 IterateSmoothingLengthDensityNeighLim<f64_3, shammath::M4<f64>>;
187template class shammodels::sph::modules::
188 IterateSmoothingLengthDensityNeighLim<f64_3, shammath::M6<f64>>;
189template class shammodels::sph::modules::
190 IterateSmoothingLengthDensityNeighLim<f64_3, shammath::M8<f64>>;
191
192template class shammodels::sph::modules::
193 IterateSmoothingLengthDensityNeighLim<f64_3, shammath::C2<f64>>;
194template class shammodels::sph::modules::
195 IterateSmoothingLengthDensityNeighLim<f64_3, shammath::C4<f64>>;
196template class shammodels::sph::modules::
197 IterateSmoothingLengthDensityNeighLim<f64_3, shammath::C6<f64>>;
Declares the IterateSmoothingLengthDensityNeighLim module for iterating smoothing length based on the...
std::uint32_t u32
32 bit unsigned integer
void distributed_data_kernel_call(sham::DeviceScheduler_ptr dev_sched, RefIn in, RefOut in_out, const shambase::DistributedData< index_t > &thread_counts, Functor &&func)
A variant of sham::kernel_call for distributed data.
void replace_all(std::string &inout, std::string_view what, std::string_view with)
replace all occurence of a search string with another
Definition string.hpp:106
namespace for the sph model modules
sph kernels
This file contains the definition for the stacktrace related functionality.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
A variant of sham::MultiRef for distributed data.