ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
ReactionKernelIndexed_all.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022-2026 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20// kernel generated with pystencils v1.4+1.ge851f4e, lbmpy v1.4+1.ge9efe34,
21// sympy v1.12.1, lbmpy_walberla/pystencils_walberla from waLBerla commit
22// 007e77e077ad9d22b5eed6f3d3118240993e553c
23
24#pragma once
25
26#include <waLBerlaDefinitions.h>
27
30
33
36
39
42
43#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
44
47
50
53
56
59
60#endif
61
62#include <domain_decomposition/BlockDataID.h>
63
64#include <cstddef>
65#include <memory>
66#include <stdexcept>
67#include <utility>
68#include <vector>
69
70namespace walberla {
71namespace detail {
72namespace ReactionKernelIndexedSelector {
73
74template <typename FloatType = double, std::size_t N = 1> struct KernelTrait {
75 using ReactionKernelIndexed =
76 pystencils::ReactionKernelIndexed_1_double_precision;
77};
78
79template <> struct KernelTrait<double, 2> {
80 using ReactionKernelIndexed =
81 pystencils::ReactionKernelIndexed_2_double_precision;
82};
83
84template <> struct KernelTrait<double, 3> {
85 using ReactionKernelIndexed =
86 pystencils::ReactionKernelIndexed_3_double_precision;
87};
88
89template <> struct KernelTrait<double, 4> {
90 using ReactionKernelIndexed =
91 pystencils::ReactionKernelIndexed_4_double_precision;
92};
93
94template <> struct KernelTrait<double, 5> {
95 using ReactionKernelIndexed =
96 pystencils::ReactionKernelIndexed_5_double_precision;
97};
98
99template <> struct KernelTrait<float, 1> {
100 using ReactionKernelIndexed =
101 pystencils::ReactionKernelIndexed_1_single_precision;
102};
103
104template <> struct KernelTrait<float, 2> {
105 using ReactionKernelIndexed =
106 pystencils::ReactionKernelIndexed_2_single_precision;
107};
108
109template <> struct KernelTrait<float, 3> {
110 using ReactionKernelIndexed =
111 pystencils::ReactionKernelIndexed_3_single_precision;
112};
113
114template <> struct KernelTrait<float, 4> {
115 using ReactionKernelIndexed =
116 pystencils::ReactionKernelIndexed_4_single_precision;
117};
118
119template <> struct KernelTrait<float, 5> {
120 using ReactionKernelIndexed =
121 pystencils::ReactionKernelIndexed_5_single_precision;
122};
123
124template <typename FloatType, class Reactant, std::size_t... ints>
125auto get_kernel_impl(const std::vector<std::shared_ptr<Reactant>> &reactants,
126 const double coefficient, const BlockDataID &indexFieldID,
127 std::index_sequence<ints...> int_seq) {
128 auto kernel = std::make_shared<
129 typename KernelTrait<FloatType, int_seq.size()>::ReactionKernelIndexed>(
130 indexFieldID,
131 walberla::BlockDataID(
132 reactants[ints]->get_species()->get_density_id())...,
133 numeric_cast<FloatType>(reactants[ints]->get_order())...,
134 numeric_cast<FloatType>(coefficient),
135 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
136
137 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
138 return sweep;
139}
140
141template <typename FloatType, class Reactant, class... Args>
142auto get_kernel_impl(const std::vector<std::shared_ptr<Reactant>> &reactants,
143 Args... args) {
144 switch (reactants.size()) {
145
146 case 1:
147 return get_kernel_impl<FloatType>(reactants, args...,
148 std::make_index_sequence<1>{});
149
150 case 2:
151 return get_kernel_impl<FloatType>(reactants, args...,
152 std::make_index_sequence<2>{});
153
154 case 3:
155 return get_kernel_impl<FloatType>(reactants, args...,
156 std::make_index_sequence<3>{});
157
158 case 4:
159 return get_kernel_impl<FloatType>(reactants, args...,
160 std::make_index_sequence<4>{});
161
162 case 5:
163 return get_kernel_impl<FloatType>(reactants, args...,
164 std::make_index_sequence<5>{});
165
166 default:
167 throw std::runtime_error("reactions of this size are not implemented!");
168 }
169}
170
171template <class Reactant, class... Args>
172auto get_kernel(const std::vector<std::shared_ptr<Reactant>> &reactants,
173 Args... args) {
174
175 const auto is_double_precision =
176 reactants[0]->get_species()->is_double_precision();
177
178 if (is_double_precision) {
179 return get_kernel_impl<double>(reactants, args...);
180 }
181
182 return get_kernel_impl<float>(reactants, args...);
183}
184
185#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
186
187template <typename FloatType = double, std::size_t N = 1>
188struct KernelTraitGPU {
189 using ReactionKernelIndexedGPU =
190 pystencils::ReactionKernelIndexed_1_double_precision_CUDA;
191};
192
193template <> struct KernelTraitGPU<double, 2> {
194 using ReactionKernelIndexedGPU =
195 pystencils::ReactionKernelIndexed_2_double_precision_CUDA;
196};
197
198template <> struct KernelTraitGPU<double, 3> {
199 using ReactionKernelIndexedGPU =
200 pystencils::ReactionKernelIndexed_3_double_precision_CUDA;
201};
202
203template <> struct KernelTraitGPU<double, 4> {
204 using ReactionKernelIndexedGPU =
205 pystencils::ReactionKernelIndexed_4_double_precision_CUDA;
206};
207
208template <> struct KernelTraitGPU<double, 5> {
209 using ReactionKernelIndexedGPU =
210 pystencils::ReactionKernelIndexed_5_double_precision_CUDA;
211};
212
213template <> struct KernelTraitGPU<float, 1> {
214 using ReactionKernelIndexedGPU =
215 pystencils::ReactionKernelIndexed_1_single_precision_CUDA;
216};
217
218template <> struct KernelTraitGPU<float, 2> {
219 using ReactionKernelIndexedGPU =
220 pystencils::ReactionKernelIndexed_2_single_precision_CUDA;
221};
222
223template <> struct KernelTraitGPU<float, 3> {
224 using ReactionKernelIndexedGPU =
225 pystencils::ReactionKernelIndexed_3_single_precision_CUDA;
226};
227
228template <> struct KernelTraitGPU<float, 4> {
229 using ReactionKernelIndexedGPU =
230 pystencils::ReactionKernelIndexed_4_single_precision_CUDA;
231};
232
233template <> struct KernelTraitGPU<float, 5> {
234 using ReactionKernelIndexedGPU =
235 pystencils::ReactionKernelIndexed_5_single_precision_CUDA;
236};
237
238template <typename FloatType, class Reactant, std::size_t... ints>
239auto get_kernel_impl_gpu(
240 const std::vector<std::shared_ptr<Reactant>> &reactants,
241 const double coefficient, const BlockDataID &indexFieldID,
242 std::index_sequence<ints...> int_seq) {
243 auto kernel = std::make_shared<typename KernelTraitGPU<
244 FloatType, int_seq.size()>::ReactionKernelIndexedGPU>(
245 indexFieldID,
246 walberla::BlockDataID(
247 reactants[ints]->get_species()->get_density_id())...,
248 numeric_cast<FloatType>(reactants[ints]->get_order())...,
249 numeric_cast<FloatType>(coefficient),
250 numeric_cast<FloatType>(reactants[ints]->get_stoech_coeff())...);
251
252 std::function<void(IBlock *)> sweep = [kernel](IBlock *b) { kernel->run(b); };
253 return sweep;
254}
255
256template <typename FloatType, class Reactant, class... Args>
257auto get_kernel_impl_gpu(
258 const std::vector<std::shared_ptr<Reactant>> &reactants, Args... args) {
259 switch (reactants.size()) {
260
261 case 1:
262 return get_kernel_impl_gpu<FloatType>(reactants, args...,
263 std::make_index_sequence<1>{});
264
265 case 2:
266 return get_kernel_impl_gpu<FloatType>(reactants, args...,
267 std::make_index_sequence<2>{});
268
269 case 3:
270 return get_kernel_impl_gpu<FloatType>(reactants, args...,
271 std::make_index_sequence<3>{});
272
273 case 4:
274 return get_kernel_impl_gpu<FloatType>(reactants, args...,
275 std::make_index_sequence<4>{});
276
277 case 5:
278 return get_kernel_impl_gpu<FloatType>(reactants, args...,
279 std::make_index_sequence<5>{});
280
281 default:
282 throw std::runtime_error("reactions of this size are not implemented!");
283 }
284}
285
286template <class Reactant, class... Args>
287auto get_kernel_gpu(const std::vector<std::shared_ptr<Reactant>> &reactants,
288 Args... args) {
289
290 const auto is_double_precision =
291 reactants[0]->get_species()->is_double_precision();
292
293 if (is_double_precision) {
294 return get_kernel_impl_gpu<double>(reactants, args...);
295 }
296
297 return get_kernel_impl_gpu<float>(reactants, args...);
298}
299
300#endif
301
302} // namespace ReactionKernelIndexedSelector
303} // namespace detail
304} // namespace walberla
\file PackInfoPdfDoublePrecision.cpp \author pystencils