Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
IterateSmoothingLengthDensity.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
19#include "shamcomm/logs.hpp"
24
25using namespace shammodels::sph::modules;
26
27template<class Tvec, class SPHKernel>
29 StackEntry stack_loc{};
30
31 auto edges = get_edges();
32
33 auto &thread_counts = edges.sizes.indexes;
34
35 edges.neigh_cache.check_sizes(thread_counts);
36 edges.positions.check_sizes(thread_counts);
37 edges.old_h.check_sizes(thread_counts);
38 edges.new_h.check_sizes(thread_counts);
39 edges.eps_h.check_sizes(thread_counts);
40
41 auto &neigh_cache = edges.neigh_cache.neigh_cache;
42 auto &positions = edges.positions.get_spans();
43 auto &old_h = edges.old_h.get_spans();
44 auto &new_h = edges.new_h.get_spans();
45 auto &eps_h = edges.eps_h.get_spans();
46
47 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
48
49 static constexpr Tscal Rkern = SPHKernel::Rkern;
50
52 dev_sched,
53 sham::DDMultiRef{neigh_cache, positions, old_h},
54 sham::DDMultiRef{new_h, eps_h},
55 thread_counts,
56 [gpart_mass = this->gpart_mass,
57 h_evol_max = this->h_evol_max,
58 h_evol_iter_max = this->h_evol_iter_max](
59 u32 id_a,
60 auto ploop_ptrs,
61 const Tvec *__restrict r,
62 const Tscal *__restrict h_old,
63 Tscal *__restrict h_new,
64 Tscal *__restrict eps) {
65 // attach the neighbor looper on the cache
66 shamrock::tree::ObjectCacheIterator particle_looper(ploop_ptrs);
67
68 Tscal part_mass = gpart_mass;
69 Tscal h_max_tot_max_evol = h_evol_max;
70 Tscal h_max_evol_p = h_evol_iter_max;
71 Tscal h_max_evol_m = 1 / h_evol_iter_max;
72
73 // TODO: make this tolerance configurable
74 if (eps[id_a] > 1e-6) {
75
76 Tvec xyz_a = r[id_a]; // could be recovered from lambda
77
78 Tscal h_a = h_new[id_a];
79 Tscal dint = h_a * h_a * Rkern * Rkern;
80
81 Tscal rho_sum = 0;
82 Tscal sumdWdh = 0;
83
84 particle_looper.for_each_object(id_a, [&](u32 id_b) {
85 Tvec dr = xyz_a - r[id_b];
86 Tscal rab2 = sycl::dot(dr, dr);
87
88 if (rab2 > dint) {
89 return; // early return if the particle is too far away
90 }
91
92 Tscal rab = sycl::sqrt(rab2);
93
94 rho_sum += part_mass * SPHKernel::W_3d(rab, h_a);
95 sumdWdh += part_mass * SPHKernel::dhW_3d(rab, h_a);
96 });
97
98 using namespace shamrock::sph;
99
100 Tscal rho_ha = rho_h(part_mass, h_a, SPHKernel::hfactd);
101 Tscal new_h = newton_iterate_new_h(rho_ha, rho_sum, sumdWdh, h_a);
102
103 if (new_h < h_a * h_max_evol_m)
104 new_h = h_max_evol_m * h_a;
105 if (new_h > h_a * h_max_evol_p)
106 new_h = h_max_evol_p * h_a;
107
108 Tscal ha_0 = h_old[id_a];
109
110 if (new_h < ha_0 * h_max_tot_max_evol) {
111 h_new[id_a] = new_h;
112 eps[id_a] = sycl::fabs(new_h - h_a) / ha_0;
113 } else {
114 h_new[id_a] = ha_0 * h_max_tot_max_evol;
115 eps[id_a] = -1;
116 }
117 }
118 });
119}
120
121template<class Tvec, class SPHKernel>
123 auto sizes = get_ro_edge_base(0).get_tex_symbol();
124 auto neigh_cache = get_ro_edge_base(1).get_tex_symbol();
125 auto positions = get_ro_edge_base(2).get_tex_symbol();
126 auto old_h = get_ro_edge_base(3).get_tex_symbol();
127 auto new_h = get_rw_edge_base(0).get_tex_symbol();
128 auto eps_h = get_rw_edge_base(1).get_tex_symbol();
129
130 std::string tex = R"tex(
131 Iterate smoothing length and density
132
133 \begin{align}
134 \rho_i &= \sum_{j \in \mathcal{N}_i} m_j W(r_{ij}, h_i) \\
135 \frac{\partial \rho_i}{\partial h_i} &= \sum_{j \in \mathcal{N}_i} m_j \frac{\partial W}{\partial h}(r_{ij}, h_i) \\
136 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}} \\
137 \epsilon_i &= \frac{|h_i^{\rm new} - h_i|}{h_i^{\rm old}}
138 \end{align}
139
140 where:
141 \begin{itemize}
142 \item $\mathcal{N}_i$ is the set of neighbors of particle $i$
143 \item $W(r, h)$ is the SPH kernel function
144 \item $\rho_h(m, h) = m \left(\frac{h_{\rm fact}}{h}\right)^3$ is the target density
145 \item $h_{\rm fact} = {hfact}$ is the kernel factor
146 \item $R_{\rm kern} = {Rkern}$ is the kernel radius
147 \end{itemize}
148
149 Input: ${sizes}$, ${neigh_cache}$, ${positions}$, ${old_h}$
150 Output: ${new_h}$, ${eps_h}$
151 )tex";
152
153 shambase::replace_all(tex, "{sizes}", sizes);
154 shambase::replace_all(tex, "{neigh_cache}", neigh_cache);
155 shambase::replace_all(tex, "{positions}", positions);
156 shambase::replace_all(tex, "{old_h}", old_h);
157 shambase::replace_all(tex, "{new_h}", new_h);
158 shambase::replace_all(tex, "{eps_h}", eps_h);
159 shambase::replace_all(tex, "{hfact}", shambase::format("{}", SPHKernel::hfactd));
160 shambase::replace_all(tex, "{Rkern}", shambase::format("{}", SPHKernel::Rkern));
161
162 return tex;
163}
164
168
Declares the IterateSmoothingLengthDensity module for iterating smoothing length based on the SPH den...
std::uint32_t u32
32 bit unsigned integer
virtual std::string _impl_get_tex() const
get the tex of the node
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:183
namespace for the sph model modules
sph kernels
This file contains the definition for the stacktrace related functionality.
A variant of sham::MultiRef for distributed data.