Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
ComputeDustTtilde.hpp
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
10#pragma once
11
18
19#include "shambase/string.hpp"
21#include "shambackends/vec.hpp"
28
29#define NODE_EDGES(X_RO, X_RW) \
30 /* scalars */ \
31 X_RO(shamrock::solvergraph::ScalarEdge<Tscal>, gpart_mass) \
32 \
33 /* counts */ \
34 X_RO(shamrock::solvergraph::Indexes<u32>, part_counts) \
35 \
36 /* fields */ \
37 X_RO(shamrock::solvergraph::IFieldSpan<Tscal>, hpart) \
38 X_RO(shamrock::solvergraph::IFieldSpan<Tscal>, s_j) \
39 X_RO(shamrock::solvergraph::IFieldSpan<Tscal>, t_j) \
40 \
41 /* outputs */ \
42 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, Ttilde_sj)
43
45
46 template<class Tvec, template<class> class SPHKernel>
47 class ComputeDustTtilde : public shamrock::solvergraph::INode {
48
49 using Tscal = shambase::VecComponent<Tvec>;
50 using Kernel = SPHKernel<Tscal>;
51
52 static constexpr Tscal kernel_radius = SPHKernel<Tscal>::Rkern;
53
54 u32 ndust;
55
56 public:
57 ComputeDustTtilde(u32 ndust) : ndust(ndust) {}
58
59 EXPAND_NODE_EDGES(NODE_EDGES)
60
62
64
65 auto edges = get_edges();
66
67 auto &part_counts = edges.part_counts.indexes;
68
69 // check that all input edges have the particles with ghosts zones
70 edges.hpart.check_sizes(part_counts);
71 edges.s_j.check_sizes(part_counts);
72 edges.t_j.check_sizes(part_counts);
73
74 // ensure that the output edges are of size part_counts (output without ghosts zones)
75 edges.Ttilde_sj.ensure_sizes(part_counts);
76
77 const Tscal pmass = edges.gpart_mass.value;
78
79 auto total_specie_count = part_counts.template map<u32>([&](u64 id, u32 count) {
80 return count * ndust;
81 });
82
83 // call the kernel for each patches with part_counts.get(id_patch) threads of patch
84 // id_patch
86 shamsys::instance::get_compute_scheduler_ptr(),
88 edges.hpart.get_spans(), edges.s_j.get_spans(), edges.t_j.get_spans()},
89 sham::DDMultiRef{edges.Ttilde_sj.get_spans()},
90 total_specie_count,
91 [pmass, ndust = ndust](
92 u32 thread_id, // = part_id * ndust + jdust
93 const Tscal *__restrict hpart, // [part_counts]
94 const Tscal *__restrict s_j, // [part_counts * ndust]
95 const Tscal *__restrict t_j, // [part_counts * ndust]
96 Tscal *__restrict Ttilde_sj // [part_counts * ndust]
97 ) {
98 u32 id_a = thread_id / ndust;
99 u32 jdust = thread_id % ndust;
100
101 Tscal h_a = hpart[id_a];
102 Tscal sj_a = s_j[thread_id];
103 Tscal tj_a = t_j[thread_id];
104
105 using namespace shamrock::sph;
106 Tscal rho_a = rho_h(pmass, h_a, Kernel::hfactd);
107
108 auto epsilon = [&](Tscal sj) {
109 return sj * sj / rho_a;
110 };
111
112#if false
113 /*
114 * Hutchison 2018 eq 15
115 * \tilde{T}_{sj} = \epsilon_j t_j - \sum_{k} \epsilon_k^2 t_k
116 */
117
118 Tscal eps_j_a = epsilon(sj_a);
119 Tscal Ttilde_sj_a = eps_j_a * tj_a;
120
121 for (u32 k = 0; k < ndust; k++) {
122 Tscal sk_a = s_j[id_a * ndust + k];
123 Tscal tk_a = t_j[id_a * ndust + k];
124
125 Tscal eps_k_a = epsilon(sk_a);
126 Ttilde_sj_a -= eps_k_a * eps_k_a * tk_a;
127 }
128#endif
129
130 // Now if i assume that Tsj in Hutchison 2018 meant tsj, then
131 Tscal sum_eps = 0;
132 Tscal sum_Tseps = 0;
133 for (u32 k = 0; k < ndust; k++) {
134 Tscal sk_a = s_j[id_a * ndust + k];
135 Tscal tk_a = t_j[id_a * ndust + k];
136 Tscal eps_k_a = epsilon(sk_a);
137 sum_eps += eps_k_a;
138 sum_Tseps += eps_k_a * tk_a;
139 }
140 Tscal Ttilde_sj_a = (tj_a - sum_Tseps) / (1 - sum_eps);
141
142 Ttilde_sj[thread_id] = Ttilde_sj_a;
143 });
144 }
145
146 inline virtual std::string _impl_get_label() const { return "ComputeDustTtilde"; };
147
148 inline virtual std::string _impl_get_tex() const {
149 auto gpart_mass = get_ro_edge_base(0).get_tex_symbol();
150 auto part_counts = get_ro_edge_base(1).get_tex_symbol();
151 auto hpart = get_ro_edge_base(2).get_tex_symbol();
152 auto s_j = get_ro_edge_base(3).get_tex_symbol();
153 auto t_j = get_ro_edge_base(4).get_tex_symbol();
154 auto Ttilde_sj = get_rw_edge_base(0).get_tex_symbol();
155
156 std::string tex = R"tex(
157 Combined dust stopping times $\tilde{T}_{s,j}$ (Hutchison 2018, eq.~15)
158
159 \begin{align}
160 \rho_a &= m_p \left( \frac{h_{\rm fact}}{ {hpart}_a } \right)^3 \\
161 \epsilon_{j,a} &= \frac{ {s_j}_{j,a}^2 }{ \rho_a } \\
162 {Ttilde_sj}_{j,a} &= \epsilon_{j,a} \, {t_j}_{j,a}
163 - \sum_{k=0}^{N_{\rm dust}-1} \epsilon_{k,a}^2 \, {t_j}_{k,a} \\
164 a &\in [0, {part_counts}), \quad j \in [0, N_{\rm dust}) \\
165 m_p &= {gpart_mass}, \quad N_{\rm dust} = {ndust}, \quad h_{\rm fact} = {hfact}
166 \end{align}
167 )tex";
168
169 shambase::replace_all(tex, "{gpart_mass}", gpart_mass);
170 shambase::replace_all(tex, "{part_counts}", part_counts);
171 shambase::replace_all(tex, "{hpart}", hpart);
172 shambase::replace_all(tex, "{s_j}", s_j);
173 shambase::replace_all(tex, "{t_j}", t_j);
174 shambase::replace_all(tex, "{Ttilde_sj}", Ttilde_sj);
175 shambase::replace_all(tex, "{ndust}", shambase::format("{}", ndust));
176 shambase::replace_all(tex, "{hfact}", shambase::format("{}", Kernel::hfactd));
177
178 return tex;
179 };
180 };
181} // namespace shammodels::sph::modules
182
183#undef NODE_EDGES
Header file describing a Node Instance.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
virtual std::string _impl_get_label() const
get the label of the node
virtual std::string _impl_get_tex() const
get the tex of the node
Inode is node between data edges, takes multiple inputs, multiple outputs.
Definition INode.hpp:30
IEdge & get_rw_edge_base(int slot)
Get a reference to a read write edge and cast it to the type IEdge.
Definition INode.hpp:100
const IEdge & get_ro_edge_base(int slot)
Get a reference to a read only edge.
Definition INode.hpp:91
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:110
namespace for the sph model modules
#define __shamrock_stack_entry()
Macro to create a stack entry.
A variant of sham::MultiRef for distributed data.