BioCMAMC-ST
move_kernel.hpp
1#ifndef __SIMULATION_MOVE_KERNEL_HPP__
2#define __SIMULATION_MOVE_KERNEL_HPP__
3
4#include <Kokkos_Assert.hpp>
5#include <Kokkos_Core.hpp>
6#include <Kokkos_Printf.hpp>
7#include <Kokkos_Random.hpp>
8#include <biocma_cst_config.hpp>
9#include <cassert>
10#include <common/common.hpp>
11#include <mc/alias.hpp>
12#include <mc/domain.hpp>
13#include <mc/events.hpp>
14#include <mc/prng/prng.hpp>
15#include <mc/traits.hpp>
16#include <simulation/probability_leaving.hpp>
17#include <simulation/probe.hpp>
18#include <utility>
19
21{
22 constexpr bool enable_leave = true;
23 constexpr bool disable_leave = false;
24 constexpr bool disable_move = false;
25 constexpr bool enable_move = true;
26
27 template <class ExecutionSpace,
28 class ViewType,
29 class RandomPool,
30 class IndexType = int64_t,
31 const std::size_t CHUNK_SIZE>
32 void
33 fill_random(const ExecutionSpace& exec,
34 ViewType a,
35 RandomPool g,
36 typename ViewType::const_value_type begin,
37 typename ViewType::const_value_type end)
38 {
39 int64_t LDA = a.extent(0);
40
41 if (LDA > 0)
42 {
43 Kokkos::parallel_for(
44 "Kokkos::fill_random",
45 Kokkos::RangePolicy<ExecutionSpace>(
46 exec, 0, (LDA + (CHUNK_SIZE - 1)) / CHUNK_SIZE),
47 Kokkos::Impl::fill_random_functor_begin_end<ViewType,
48 RandomPool,
49 CHUNK_SIZE,
50 ViewType::rank,
51 IndexType>(
52 a, g, begin, end));
53 }
54 }
55
61 KOKKOS_INLINE_FUNCTION std::size_t
63 const bool do_serch,
66 cumulative_probability,
67 const std::size_t i_compartment,
68 const double random_number)
69 {
70 const int mask_do_serch = static_cast<int>(do_serch);
71 const int max_neighbor = static_cast<int>(neighbors.extent(1));
72
73 KOKKOS_ASSERT(max_neighbor >= 1);
74 KOKKOS_ASSERT(random_number <= 1. && random_number >= 0.);
75 KOKKOS_ASSERT(neighbors.extent(1) == cumulative_probability.extent(1));
76
77 // Do not use cumulative_probability(i_compartment, max_neighbor - 1)==1
78 // Bcause proba can be 0.999999999
79 // KOKKOS_ASSERT(cumulative_probability(i_compartment, max_neighbor -
80 // 1)>0.95); //5% relative
81
82 // v1.1: This assert was there to be sure that the particle will leave but
83 // actually
84 // not needed because if rand< then left will be the last at the the ned of
85 // the loop
86 // KOKKOS_ASSERT(cumulative_probability(i_compartment, max_neighbor - 1)
87 // >= random_number);
88
89 int left = 0;
90 int right = mask_do_serch * (max_neighbor - 1);
91 while (left < right)
92 {
93 const int mid = (left + right) >> 1; // NOLINT
94 const auto pm = cumulative_probability(i_compartment, mid);
95 const int mask = static_cast<int>(random_number > pm);
96 left = mask * (mid + 1) + (1 - mask) * left;
97 right = mask * right + (1 - mask) * mid;
98 }
99 KOKKOS_ASSERT(left >= 0 && static_cast<size_t>(left) < neighbors.extent(1));
100 const auto ret = i_compartment * (1 - mask_do_serch)
101 + neighbors(i_compartment, left) * mask_do_serch;
102 return ret;
103 }
104
105 template <typename ViewType1>
106 void
107 find_flow(const ViewType1& leaving_flow,
108 const std::size_t position,
110 MC::LeavingFlow::float_type& _liquid_volume)
111 {
112 std::size_t i_flow = 0;
113 const std::size_t n_flow = leaving_flow.size();
114 val_flow = 0.;
115 _liquid_volume = 0.;
116 // do-while because n_flow is likely to be 1
117 do
118 {
119 const auto& [index, flow, liquid_volume] = leaving_flow(i_flow++);
120 if (position == index)
121 {
122 val_flow = flow;
123 _liquid_volume = liquid_volume;
124 break;
125 }
126 } while (i_flow < n_flow);
127 }
128
129 struct TagRNG
130 {
131 };
132 struct TagMove
133 {
134 };
135 struct TagLeave
136 {
137 };
138
140 {
141 using TeamPolicy = Kokkos::TeamPolicy<ComputeSpace>;
142 using TeamMember = TeamPolicy::member_type;
143 MoveFunctor() = default;
144 MoveFunctor(std::size_t p_team_move,
145 std::size_t p_team_leave,
147 MC::ParticleStatus _status,
149 MC::pool_type _random_pool,
150 MC::EventContainer _events,
152 MC::ParticleAges _ages)
153 : MoveFunctor(p_team_move,
154 p_team_leave,
155 0,
156 std::move(p),
157 std::move(_status),
158 0,
159 std::move(m),
160 std::move(_random_pool),
161 std::move(_events),
162 std::move(_probes),
163 std::move(_ages),
164 false,
165 false) {};
166
167 MoveFunctor(std::size_t p_team_move,
168 std::size_t p_team_leave,
169 double _d_t,
171 MC::ParticleStatus _status,
172 std::size_t n_p,
174 MC::pool_type _random_pool,
175 MC::EventContainer _events,
177 MC::ParticleAges _ages,
178 bool b_move,
179 bool b_leave)
180 : d_t(_d_t), positions(std::move(p)), n_particles(n_p),
181 move(std::move(m)), random_pool(_random_pool), // NOLINT
182 status(std::move(_status)), events(std::move(_events)),
183 probes(std::move(_probes)), ages(std::move(_ages)),
184 m_p_team_leave(p_team_leave), m_p_team_move(p_team_move),
185 enable_move(b_move), enable_leave(b_leave) {};
186
187 void
188 update(double _d_t,
189 std::size_t n_p,
191 MC::ParticlePositions _positions,
192 MC::ParticleStatus _status,
193 MC::ParticleAges _ages,
194 bool b_move,
195 bool b_leave)
196 {
197
198 this->d_t = _d_t;
199 this->n_particles = n_p;
200 this->enable_leave = b_leave;
201 this->enable_move = b_move;
202 this->move = std::move(move_i);
203
204 this->positions = std::move(_positions);
205 this->status = std::move(_status);
206 this->ages = std::move(_ages);
207 }
208
209 KOKKOS_INLINE_FUNCTION void
211 const Kokkos::TeamPolicy<ComputeSpace>::member_type& team) const
212 {
213 using ScratchSpace
214 = Kokkos::TeamPolicy<>::execution_space::scratch_memory_space;
215 using ScratchView = Kokkos::View<float*, ScratchSpace>;
216
217 const std::size_t count = m_p_team_move;
218 const std::size_t p0 = team.league_rank() * count;
219 const std::size_t n_particle = n_particles;
220
221 const auto upper_bound
222 = ((p0 + count) >= n_particle) ? n_particle - p0 : count;
223 KOKKOS_ASSERT(upper_bound > 0 && upper_bound < n_particle);
224 const auto& rp = random_pool;
225
226 const std::size_t N = count * 2;
227
228 // rng is actually a flat m*p array
229 const std::size_t p = team.team_size();
230 const std::size_t m = (N + p - 1) / p;
231
232 ScratchView rng(team.team_scratch(0), N);
233
234 // Use "tiling" to minimize contention when aquired_state
235 // State is aquired m times instead of N, it is supposed to reduce
236 // contention
237 Kokkos::parallel_for(Kokkos::TeamThreadRange(team, 0, m),
238 [&rp, &rng, p, N](const std::size_t idx)
239 {
240 // Ok to use here, get_state should be called in
241 // each thread
242 auto gen = rp.get_state();
243
244 const std::size_t base = idx * p;
245 // current thread iteration p times with the same
246 // state
247 for (std::size_t k = 0; k < p; ++k)
248 {
249 const std::size_t i = base + k;
250 if (i >= N)
251 {
252 break;
253 }
254
255 rng(i) = gen.frand(0., 1.);
256 }
257
258 rp.free_state(gen);
259 });
260 team.team_barrier();
261
262 // We can use flat array index here ordering of random doesnt matter
263 Kokkos::parallel_for(Kokkos::TeamThreadRange(team, 0, upper_bound),
264 [&](const std::size_t idx)
265 {
266 const auto flat_index = p0 + idx;
267 const std::size_t base = idx * 2;
268 KOKKOS_ASSERT(base + 1 < N);
269 const auto rng1 = rng(base);
270 const auto rng2 = rng(base + 1);
271 handle_move(flat_index, rng1, rng2);
272 });
273 }
274
275 // KOKKOS_INLINE_FUNCTION void
276 // operator()(TagLeave _tag,
277 // const TeamMember& team,
278 // std::size_t& local_dead_count) const
279 // {
280 // (void)_tag;
281 // const std::size_t count = m_p_team_leave;
282 // const std::size_t p0 = team.league_rank() * count;
283 // const std::size_t n_particle = n_particles;
284 // const auto _d_t = static_cast<float>(d_t);
285
286 // const auto upper_bound
287 // = ((p0 + count) >= n_particle) ? n_particle - p0 : count;
288 // KOKKOS_ASSERT(upper_bound > 0 && upper_bound < n_particle);
289
290 // const std::size_t n_flow = move.leaving_flow.extent(0);
291
292 // using ScratchSpace = TeamPolicy::execution_space::scratch_memory_space;
293 // using ScratchView = Kokkos::View<MC::LeavingFlow*, ScratchSpace>;
294 // const auto leaving_flow = ScratchView(team.team_scratch(0), n_flow);
295
296 // // Kokkos::parallel_for(Kokkos::TeamVectorRange(team, n_flow),
297 // // [&](const std::size_t j)
298 // // { leaving_flow(j) = move.leaving_flow(j); });
299
300 // Kokkos::single(Kokkos::PerTeam(team),
301 // [&]()
302 // {
303 // for (std::size_t j = 0; j < n_flow; ++j)
304 // {
305 // leaving_flow(j) = move.leaving_flow(j);
306 // }
307 // });
308
309 // team.team_barrier();
310
311 // std::size_t t_local = 0;
312 // Kokkos::parallel_reduce(
313 // Kokkos::TeamThreadRange(team, 0, upper_bound),
314 // [&](const std::size_t relative_index,
315 // std::size_t& thread_local_dead_count)
316 // {
317 // const std::size_t flatten_index = p0 + relative_index;
318 // if (status(flatten_index) == MC::Status::Idle)
319 // {
320 // ages(flatten_index, 0) += _d_t;
321 // handle_exit<ScratchSpace>(
322 // flatten_index, leaving_flow, thread_local_dead_count);
323 // }
324 // },
325 // t_local);
326
327 // team.team_barrier();
328
329 // Kokkos::single(Kokkos::PerTeam(team),
330 // [&]()
331 // {
332 // Kokkos::single(Kokkos::PerThread(team),
333 // [&]() { local_dead_count += t_local;
334 // });
335 // });
336 // // Kokkos::single(Kokkos::PerTeam(team),
337 // // [&]()
338 // // {
339 // // Kokkos::single(Kokkos::PerThread(team),
340 // // [&]() {
341 // // local_dead_count
342 // // += t_local;
343 // // });
344 // // });
345 // }
346
347 KOKKOS_INLINE_FUNCTION void
348 operator()([[maybe_unused]] TagLeave _tag,
349 const std::size_t& idx,
350 std::size_t& local_dead_count) const
351 {
352 if (status(idx) != MC::Status::Idle) [[unlikely]]
353 {
354 return;
355 }
356
357 ages(idx, 0) += d_t;
358 handle_exit(idx, move.leaving_flow, local_dead_count);
359 }
360
361 // KOKKOS_INLINE_FUNCTION void
362 // operator()(TagLeave _tag,
363 // const Kokkos::TeamPolicy<ComputeSpace>::member_type&
364 // team_handle, std::size_t& local_dead_count) const
365 // {
366 // (void)_tag;
367 // const std::size_t league_size = team_handle.league_size();
368 // const std::size_t league_rank = team_handle.league_rank();
369 // const std::size_t start_idx = league_rank * (n_particles /
370 // league_size); std::size_t end_idx = (league_rank + 1) * (n_particles /
371 // league_size);
372
373 // if (league_rank == (league_size - 1))
374 // {
375 // end_idx = n_particles;
376 // }
377 // Kokkos::parallel_for(
378 // Kokkos::TeamThreadRange(team_handle, start_idx, end_idx),
379 // [&](int idx)
380 // {
381 // ages(idx, 0) += d_t;
382 // handle_exit(idx, local_dead_count);
383 // });
384 // }
385
386 [[nodiscard]] bool
388 {
389 return enable_leave || enable_move;
390 }
391
392 KOKKOS_FUNCTION void
393 handle_move(const std::size_t idx, const float rng1, const float rng2) const
394 {
395
396 // const auto rng1 = static_cast<float>(random(idx, 0));
397 // const auto rng2 = static_cast<float>(random(idx, 1));
398
399 KOKKOS_ASSERT(rng1 >= 0. && rng1 <= 1 && rng2 >= 0. && rng2 <= 1);
400
401 const std::size_t i_current_compartment = positions(idx);
402
403 KOKKOS_ASSERT(
404 i_current_compartment < move.liquid_volume.extent(0)
405 && "Particle position is incorect (greater than compartment number)");
406
407 const bool mask_next = probability_leaving<fast_tag>(
408 rng1,
409 move.liquid_volume(i_current_compartment),
410 move.diag_transition(i_current_compartment),
411 d_t);
412
413 positions(idx) = __find_next_compartment(mask_next,
414 move.neighbors,
415 move.cumulative_probability,
416 i_current_compartment,
417 rng2);
418
419 // positions(idx)
420 // = (mask_next) ? __find_next_compartment(move.neighbors,
421 // move.cumulative_probability,
422 // i_current_compartment,
423 // rng2)
424 // : i_current_compartment;
425
426 KOKKOS_ASSERT(
427 positions(idx) < move.liquid_volume.extent(0)
428 && " Position after move is greater than compartment number");
429
430 if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
431 {
432 if (mask_next)
433 {
434 events.wrap_incr<MC::EventType::Move>();
435 }
436 }
437 }
438
439 // KOKKOS_INLINE_FUNCTION void
440 // inner_handle_exit(const std::size_t i_flow,
441 // const std::size_t idx,
442 // const double liquid_volume,
443 // const std::size_t position,
444 // const MC::LeavingFlowView<true>& leaving_flow,
445 // std ::size_t& dead_count) const
446 // {
447 // // FIXME : when move AND exit, take the same random number,
448 // // is it really important ?
449 // const auto random_number = static_cast<float>(random(idx, 2));
450 // const auto& [index, flow] = leaving_flow(i_flow);
451
452 // const bool is_leaving = (position == index)
453 // && probability_leaving<void>(
454 // random_number, liquid_volume, flow, d_t);
455
456 // const int leave_mask = static_cast<int>(is_leaving);
457
458 // // If using probes
459 // if constexpr (AutoGenerated::FlagCompileTime::use_probe)
460 // {
461 // // Execute probe set, but only actually do something if leaving
462 // if (is_leaving)
463 // {
464 // const auto _ = probes.set(ages(idx, 0));
465 // }
466 // }
467 // if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
468 // {
469
470 // events.add<MC::EventType::Exit>(leave_mask);
471 // }
472
473 // dead_count += leave_mask;
474 // ages(idx, 0) = (1 - leave_mask) * ages(idx, 0) /*leave_mask * 0 + */;
475 // status(idx) = is_leaving ? MC::Status::Exit : status(idx);
476 // }
477
478 // KOKKOS_FORCEINLINE_FUNCTION void
479 // handle_exit(std::size_t idx,
480 // const MC::VolumeView<ComputeSpace, true>& liquid_volumes,
481 // std::size_t& dead_count) const
482 // {
483 // const auto position = positions(idx);
484 // const auto liquid_volume = liquid_volumes(position);
485 // const MC::LeavingFlowView<true>& leaving_flow = move.leaving_flow;
486 // const std::size_t n_flow = leaving_flow.size();
487 // for (std::size_t i_flow = 0LU; i_flow < n_flow; ++i_flow)
488 // {
489 // inner_handle_exit(
490 // i_flow, idx, liquid_volume, position, leaving_flow, dead_count);
491 // }
492 // }
493
494 // KOKKOS_FORCEINLINE_FUNCTION void
495 // handle_exit(std::size_t idx,
496 // const MC::VolumeView<ComputeSpace, true>& liquid_volumes,
497 // std::size_t& dead_count) const
498 // {
499 // const std::size_t position = positions(idx);
500 // const double liquid_volume = liquid_volumes(position);
501 // const MC::LeavingFlowView<true>& leaving_flow = move.leaving_flow;
502 // const std::size_t n_flow = leaving_flow.size();
503
504 // // Strategy: most of the time there is only one flow (0d reactor or
505 // // uniquement leaving point)
506 // // Then the first flow is out of the loop
507 // // For the first leaving flow use precomputed index_random_leave
508 // // If the particle position is correct probability to leave is high
509 // // then pregenerated only one number and get random on the fly in the
510 // // loop if needed
511
512 // // One improvement is to use rng1 as long as as the we do consume it
513 // // If first ok_p is false, rng1 is then not used
514 // // This needs a branch ?
515
516 // auto rng1 = static_cast<float>(random(idx, index_random_leave));
517
518 // const auto& [index, flow] = leaving_flow(0);
519 // const bool p
520 // = probability_leaving<precision_tag>(rng1, liquid_volume, flow,
521 // d_t);
522 // const bool ok_p = position == index;
523 // const int m = static_cast<int>(ok_p) * static_cast<int>(p);
524 // int leave_mask = m;
525
526 // for (std::size_t i_flow = 1; i_flow < n_flow; ++i_flow)
527 // {
528 // if (leave_mask != 0)
529 // {
530 // break;
531 // }
532 // const auto& [index, flow] = leaving_flow(i_flow);
533 // const bool ok_p = position == index;
534 // if (!ok_p)
535 // {
536 // continue;
537 // }
538
539 // // if (!ok_p || leave_mask != 0)
540 // // {
541 // // continue;
542 // // }
543 // auto gen = random_pool.get_state();
544 // rng1 = gen.frand(0, 1);
545 // random_pool.free_state(gen);
546
547 // const bool p = probability_leaving<precision_tag>(
548 // rng1, liquid_volume, flow, d_t);
549
550 // const int m = static_cast<int>(ok_p) * static_cast<int>(p);
551 // leave_mask |= m;
552 // }
553
554 // dead_count += leave_mask;
555
556 // // DO this betore age set to 0
557 // if constexpr (AutoGenerated::FlagCompileTime::use_probe)
558 // {
559 // // Execute probe set, but only actually do something if leaving
560 // if (leave_mask != 0)
561 // {
562 // // const auto _ = probes.template set<(ages(idx, 0));
563 // }
564 // }
565
566 // ages(idx, 0) *= (1 - leave_mask);
567
568 // // status(idx) = (leave_mask == 0) ? status(idx) : MC::Status::Exit;
569
570 // status(idx) = static_cast<MC::Status>(
571 // static_cast<int>(status(idx)) * (1 - leave_mask)
572 // + static_cast<int>(MC::Status::Exit) * leave_mask);
573
574 // if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
575 // {
576 // events.add<MC::EventType::Exit>(leave_mask);
577 // }
578 // }
579 //
580 //
581
582 // TODO Improvement 1D/3D:
583 // Assumption: given leaving_flow is valid (i_flow < n_compartment)
584 // Add templated free-function "find_flow"
585 // specialize function to empty with tag 0D
586 template <typename ExecSpace>
587 KOKKOS_FORCEINLINE_FUNCTION std::size_t
589 const std::size_t idx,
590 const Kokkos::View<const MC::LeavingFlow*, ExecSpace>& leaving_flow,
591 std::size_t& dead_count) const
592 {
593
594 using mem_space = ComputeSpace::memory_space;
595
596 const std::size_t position = positions(idx);
597
598 // Strategy:
599 // first find the value of leaving flow (0-> particle doesn´t leave)
600 // do-while +early break is ok as n_flow is likely <10
601 // second: calculate probability leaving, flow=0 => p=0 theres no need
602 // to check condition
603 MC::LeavingFlow::float_type found_flow_value = 0.;
604 MC::LeavingFlow::float_type found_liquid_volume = 0.;
605 find_flow(leaving_flow, position, found_flow_value, found_liquid_volume);
606
607 int leave_mask = 0;
608 // Cases
609 // 0D: one flow and position always 0 then (val_flow != 0.) is always true
610 // 3D: only for few particles
611 //
612 if (found_flow_value != 0.)
613 {
614 auto gen = random_pool.get_state();
615 const auto rng1 = gen.frand(0., 1.);
616 random_pool.free_state(gen);
617
618 KOKKOS_ASSERT(found_liquid_volume > 0.);
619 KOKKOS_ASSERT(found_flow_value > 0.);
621 rng1, found_liquid_volume, found_flow_value, d_t);
622
623 leave_mask = static_cast<int>(p);
624 // DO this betore age is reset to 0
625 // if (p)
626 // {
627 dead_count += leave_mask;
628 // }
629 if constexpr (AutoGenerated::FlagCompileTime::use_probe)
630 {
631 if (leave_mask != 0)
632 {
633 const auto _ = probes.set<mem_space>(ages(idx, 0));
634 }
635 }
636 ages(idx, 0) *= (1 - leave_mask);
637 status(idx) = static_cast<MC::Status>(
638 static_cast<int>(status(idx)) * (1 - leave_mask)
639 + static_cast<int>(MC::Status::Exit) * leave_mask);
640
641 if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
642 {
643 events.add<MC::EventType::Exit>(leave_mask);
644 }
645 }
646
647 return 0;
648 }
649
650 double d_t{};
652 std::size_t n_particles{};
659 std::size_t m_p_team_leave{};
660 std::size_t m_p_team_move{};
661
662 // Kokkos::View<float**, Kokkos::LayoutLeft> random;
663
666 };
667} // namespace Simulation::KernelInline
668
669#endif
std::conditional_t< is_const, Kokkos::View< const std::size_t **, Kokkos::LayoutRight, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > >, Kokkos::View< std::size_t **, Kokkos::LayoutRight, ExecSpace > > NeighborsView
Definition alias.hpp:206
Kokkos::View< Status *, ComputeSpace > ParticleStatus
Definition alias.hpp:141
Kokkos::View< uint64_t *, ComputeSpace > ParticlePositions
Definition alias.hpp:140
@ Move
Move in domain.
Definition events.hpp:21
@ Exit
Remove particle from list due to move in domain.
Definition events.hpp:20
Status
Definition alias.hpp:125
@ Idle
Definition alias.hpp:126
@ Exit
Definition alias.hpp:128
ParticleAgesBase< ComputeSpace > ParticleAges
Definition alias.hpp:144
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:100
std::conditional_t< is_const, Kokkos::View< const double **, Kokkos::LayoutRight, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > >, Kokkos::View< double **, Kokkos::LayoutRight, ExecSpace > > CumulativeProbabilityView
Definition alias.hpp:197
Definition kernels.hpp:17
void fill_random(const ExecutionSpace &exec, ViewType a, RandomPool g, typename ViewType::const_value_type begin, typename ViewType::const_value_type end)
Definition move_kernel.hpp:33
constexpr bool enable_leave
Definition move_kernel.hpp:22
constexpr bool enable_move
Definition move_kernel.hpp:25
KOKKOS_INLINE_FUNCTION std::size_t __find_next_compartment(const bool do_serch, const MC::NeighborsView< ComputeSpace, true > &neighbors, const MC::CumulativeProbabilityView< ComputeSpace, true > &cumulative_probability, const std::size_t i_compartment, const double random_number)
probably overkill binary search to find next compartment
Definition move_kernel.hpp:62
constexpr bool disable_leave
Definition move_kernel.hpp:23
KOKKOS_INLINE_FUNCTION bool probability_leaving(float random_number, double volume, double flow, double dt)
Definition probability_leaving.hpp:18
KOKKOS_INLINE_FUNCTION bool probability_leaving< fast_tag >(float random_number, double volume, double flow, double dt)
Definition probability_leaving.hpp:35
constexpr bool disable_move
Definition move_kernel.hpp:24
void find_flow(const ViewType1 &leaving_flow, const std::size_t position, MC::LeavingFlow::float_type &val_flow, MC::LeavingFlow::float_type &_liquid_volume)
Definition move_kernel.hpp:107
Probes< AutoGenerated::probe_buffer_size > ProbeAutogeneratedBuffer
Definition probe.hpp:148
Structure to store information about domain needed during MC cycle data is likely to change between e...
Definition domain.hpp:29
Use to count events that occurs during Monte-Carlo processing cycles.
Definition events.hpp:150
double float_type
Definition domain.hpp:19
MoveFunctor(std::size_t p_team_move, std::size_t p_team_leave, double _d_t, MC::ParticlePositions p, MC::ParticleStatus _status, std::size_t n_p, MC::DomainState< ComputeSpace > m, MC::pool_type _random_pool, MC::EventContainer _events, ProbeAutogeneratedBuffer _probes, MC::ParticleAges _ages, bool b_move, bool b_leave)
Definition move_kernel.hpp:167
KOKKOS_FUNCTION void handle_move(const std::size_t idx, const float rng1, const float rng2) const
Definition move_kernel.hpp:393
bool enable_leave
Definition move_kernel.hpp:665
KOKKOS_INLINE_FUNCTION void operator()(TagLeave _tag, const std::size_t &idx, std::size_t &local_dead_count) const
Definition move_kernel.hpp:348
MoveFunctor(std::size_t p_team_move, std::size_t p_team_leave, MC::ParticlePositions p, MC::ParticleStatus _status, MC::DomainState< ComputeSpace > m, MC::pool_type _random_pool, MC::EventContainer _events, ProbeAutogeneratedBuffer _probes, MC::ParticleAges _ages)
Definition move_kernel.hpp:144
bool need_launch() const
Definition move_kernel.hpp:387
Kokkos::TeamPolicy< ComputeSpace > TeamPolicy
Definition move_kernel.hpp:141
TeamPolicy::member_type TeamMember
Definition move_kernel.hpp:142
MC::ParticlePositions positions
Definition move_kernel.hpp:651
std::size_t m_p_team_move
Definition move_kernel.hpp:660
double d_t
Definition move_kernel.hpp:650
MC::DomainState< ComputeSpace, true > move
Definition move_kernel.hpp:653
KOKKOS_FORCEINLINE_FUNCTION std::size_t handle_exit(const std::size_t idx, const Kokkos::View< const MC::LeavingFlow *, ExecSpace > &leaving_flow, std::size_t &dead_count) const
Definition move_kernel.hpp:588
std::size_t n_particles
Definition move_kernel.hpp:652
MC::EventContainer events
Definition move_kernel.hpp:656
ProbeAutogeneratedBuffer probes
Definition move_kernel.hpp:657
void update(double _d_t, std::size_t n_p, MC::DomainState< ComputeSpace > move_i, MC::ParticlePositions _positions, MC::ParticleStatus _status, MC::ParticleAges _ages, bool b_move, bool b_leave)
Definition move_kernel.hpp:188
MC::ParticleStatus status
Definition move_kernel.hpp:655
KOKKOS_INLINE_FUNCTION void operator()(TagMove, const Kokkos::TeamPolicy< ComputeSpace >::member_type &team) const
Definition move_kernel.hpp:210
bool enable_move
Definition move_kernel.hpp:664
MC::ParticleAges ages
Definition move_kernel.hpp:658
std::size_t m_p_team_leave
Definition move_kernel.hpp:659
MC::pool_type random_pool
Definition move_kernel.hpp:654
Definition move_kernel.hpp:136
Definition move_kernel.hpp:133
Definition move_kernel.hpp:130