OpenLB 1.8.1
Loading...
Searching...
No Matches
operator.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 Adrian Kummerlaender
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef GPU_CUDA_OPERATOR_HH
25#define GPU_CUDA_OPERATOR_HH
26
27#include "operator.h"
28
29#include "context.hh"
30#include "dynamics.hh"
31
32#include "solver/names.h"
33
34namespace olb {
35
37struct CollisionSubdomainMask;
38
40namespace gpu {
41
43namespace cuda {
44
46template <typename T, typename DESCRIPTOR, typename DYNAMICS>
48private:
52 bool* _mask;
53
54 CellStatistic<T> apply(DeviceContext<T,DESCRIPTOR>& lattice, CellID iCell) __device__ {
55 DataOnlyCell<T,DESCRIPTOR> cell(lattice, iCell);
56 return DYNAMICS().collide(cell, _parameters);
57 }
58
59public:
61
65 _parameters{parameters},
66 _mask{mask}
67 { }
68
70
74 bool operator()(DeviceContext<T,DESCRIPTOR>& lattice, CellID iCell) __device__ {
75 if (_mask[iCell]) {
76 apply(lattice, iCell);
77 return true;
78 }
79 return false;
80 }
81
83 bool operator()(DeviceContext<T,DESCRIPTOR>& lattice, CellID iCell, CellStatistic<T>& statistic) __device__ {
84 if (_mask[iCell]) {
85 statistic = apply(lattice, iCell);
86 return true;
87 }
88 return false;
89 }
90
91};
92
94template <typename T, typename DESCRIPTOR, typename DYNAMICS>
96private:
98
99public:
101 _parameters{parameters}
102 { }
103
104 bool operator()(DeviceContext<T,DESCRIPTOR>& lattice, CellID iCell) __device__ {
105 DataOnlyCell<T,DESCRIPTOR> cell(lattice, iCell);
106 DYNAMICS().collide(cell, _parameters);
107 return true;
108 }
109
110 bool operator()(DeviceContext<T,DESCRIPTOR>& lattice, CellID iCell, CellStatistic<T>& statistic) __device__ {
111 DataOnlyCell<T,DESCRIPTOR> cell(lattice, iCell);
112 statistic = DYNAMICS().collide(cell, _parameters);
113 return true;
114 }
115
116};
117
118
120template <typename OPERATOR>
122private:
124 bool* _mask;
125
126public:
128 _mask{mask}
129 { }
130
131 template <typename T, typename DESCRIPTOR>
132 bool operator()(DeviceBlockLattice<T,DESCRIPTOR>& lattice, CellID iCell) __device__ {
133 if (_mask[iCell]) {
134 Cell<T,DESCRIPTOR> cell(lattice, iCell);
135 OPERATOR().apply(cell);
136 return true;
137 }
138 return false;
139 }
140
141};
142
144
147template <typename OPERATOR>
149 template <typename T, typename DESCRIPTOR>
150 bool operator()(DeviceBlockLattice<T,DESCRIPTOR>& lattice, CellID iCell) __device__ {
151 Cell<T,DESCRIPTOR> cell(lattice, iCell);
152 OPERATOR().apply(cell);
153 return true;
154 }
155
156};
157
159template <typename T, typename DESCRIPTOR, typename OPERATOR>
161private:
163
164public:
166 _parameters{parameters}
167 { }
168
169 bool operator()(DeviceBlockLattice<T,DESCRIPTOR>& lattice, CellID iCell) __device__ {
170 Cell<T,DESCRIPTOR> cell(lattice, iCell);
171 OPERATOR().apply(cell, _parameters);
172 return true;
173 }
174
175};
176
178template <typename COUPLER>
180 template <typename CONTEXT>
181 bool operator()(CONTEXT& lattices,
182 CellID iCell) __device__ {
183 auto cells = lattices.exchange_values([&](auto name) -> auto {
184 return Cell{lattices.get(name), iCell};
185 });
186 COUPLER().apply(cells);
187 return true;
188 }
189};
190
192template <typename COUPLER, typename COUPLEES>
194private:
195 typename COUPLER::parameters::template decompose_into<
197 > _parameters;
198
199public:
200 template <typename PARAMETERS>
202 _parameters{parameters}
203 { }
204
205 template <typename CONTEXT>
206 bool operator()(CONTEXT& lattices,
207 CellID iCell) __device__ {
208 auto cells = lattices.exchange_values([&](auto name) -> auto {
209 return Cell{lattices.get(name), iCell};
210 });
211 COUPLER().apply(cells, _parameters);
212 return true;
213 }
214
215};
216
218template <typename COUPLER, typename COUPLEES>
220private:
222 typename meta::merge<
223 typename COUPLER::parameters,
227 >
228 >
229 > _parameters;
230
231public:
232 template <typename PARAMETERS>
234 _parameters{parameters}
235 { }
236
237 template <typename CONTEXT>
238 bool operator()(CONTEXT& lattices,
239 CellID iParticle) __device__ {
240 using V = typename CONTEXT::template value_t<names::Points>::value_t;
241 using DESCRIPTOR = typename CONTEXT::template value_t<names::Points>::descriptor_t;
242 const auto originR = _parameters.template get<fields::BLOCK_LOWER>();
243 const auto deltaX = _parameters.template get<fields::converter::PHYS_DELTA_X>();
244 const Vector<V*,DESCRIPTOR::d> physRs(lattices.get(meta::id<names::Points>{})
245 .template getField<fields::PHYS_R>());
246 const PhysR<V,DESCRIPTOR::d> physR{physRs, iParticle};
247 const LatticeR<DESCRIPTOR::d> latticeR = util::floor((physR - originR) / deltaX + V{0.5});
248 auto cells = lattices.exchange_values([&](auto name) -> auto {
249 if constexpr (std::is_same_v<typename decltype(name)::type, names::Points>) {
250 return DataOnlyCell{lattices.get(name), iParticle};
251 } else {
252 const auto iCell = lattices.get(name).getCellId(latticeR);
253 return Cell{lattices.get(name), iCell};
254 }
255 });
256 COUPLER().apply(cells, _parameters);
257 return true;
258 }
259
260};
261
263
278template <typename T, typename DESCRIPTOR, typename... DYNAMICS>
282 bool* subdomain = block.template getData<CollisionSubdomainMask>().deviceData();
283 DeviceContext<T,DESCRIPTOR> lattice(block);
284 if (block.statisticsEnabled()) {
286 lattice,
287 subdomain,
289 block.template getData<OperatorParameters<DYNAMICS>>().parameters,
290 block.template getData<DynamicsMask<DYNAMICS>>().deviceData()
291 }...,
293 } else {
295 lattice,
296 subdomain,
298 block.template getData<OperatorParameters<DYNAMICS>>().parameters,
299 block.template getData<DynamicsMask<DYNAMICS>>().deviceData()
300 }...,
302 }
303 };
304}
305
306
308namespace kernel {
309
311template <typename CONTEXT, typename... OPERATORS>
312void call_operators(CONTEXT lattice, bool* subdomain, OPERATORS... ops) __global__ {
313 const CellID iCell = blockIdx.x * blockDim.x + threadIdx.x;
314 if (!(iCell < lattice.getNcells()) || !subdomain[iCell]) {
315 return;
316 }
317 (ops(lattice, iCell) || ... );
318}
319
321
324template <typename CONTEXT, typename... OPERATORS>
325void call_operators_with_statistics(CONTEXT lattice, bool* subdomain, OPERATORS... ops) __global__ {
326 const CellID iCell = blockIdx.x * blockDim.x + threadIdx.x;
327 if (!(iCell < lattice.getNcells()) || !subdomain[iCell]) {
328 return;
329 }
330 typename CONTEXT::value_t** statistic = lattice.template getField<descriptors::STATISTIC>();
331 int* statisticGenerated = lattice.template getField<descriptors::STATISTIC_GENERATED>()[0];
332 CellStatistic<typename CONTEXT::value_t> cellStatistic{-1, -1};
333 if ((ops(lattice, iCell, cellStatistic) || ... )) {
334 if (cellStatistic) {
335 statisticGenerated[iCell] = 1;
336 statistic[0][iCell] = cellStatistic.rho;
337 statistic[1][iCell] = cellStatistic.uSqr;
338 } else {
339 statisticGenerated[iCell] = 0;
340 statistic[0][iCell] = 0;
341 statistic[1][iCell] = 0;
342 }
343 }
344}
345
347template <typename CONTEXT, typename... OPERATORS>
348void call_list_operators(CONTEXT lattice,
349 const CellID* indices, std::size_t nIndices,
350 OPERATORS... ops) __global__ {
351 const std::size_t iIndex = blockIdx.x * blockDim.x + threadIdx.x;
352 if (!(iIndex < nIndices)) {
353 return;
354 }
355 (ops(lattice, indices[iIndex]) || ... );
356}
357
359
362template <typename CONTEXT, typename... OPERATORS>
364 const CellID* indices, std::size_t nIndices,
365 OPERATORS... ops) __global__ {
366 const std::size_t iIndex = blockIdx.x * blockDim.x + threadIdx.x;
367 if (!(iIndex < nIndices)) {
368 return;
369 }
370 typename CONTEXT::value_t** statistic = lattice.template getField<descriptors::STATISTIC>();
371 int* statisticGenerated = lattice.template getField<descriptors::STATISTIC_GENERATED>()[0];
372 CellStatistic<typename CONTEXT::value_t> cellStatistic{-1, -1};
373 if ((ops(lattice, indices[iIndex], cellStatistic) || ... )) {
374 if (cellStatistic) {
375 statisticGenerated[indices[iIndex]] = 1;
376 statistic[0][indices[iIndex]] = cellStatistic.rho;
377 statistic[1][indices[iIndex]] = cellStatistic.uSqr;
378 } else {
379 statisticGenerated[indices[iIndex]] = 0;
380 statistic[0][indices[iIndex]] = 0;
381 statistic[1][indices[iIndex]] = 0;
382 }
383 }
384}
385
387template <typename CONTEXTS, typename... OPERATORS>
388void call_coupling_operators(CONTEXTS lattices, bool* subdomain, OPERATORS... ops) __global__ {
389 const CellID iCell = blockIdx.x * blockDim.x + threadIdx.x;
390 const auto nCells = lattices.template get<0>().getNcells();
391 if (!(iCell < nCells) || !subdomain[iCell]) {
392 return;
393 }
394 (ops(lattices, iCell) || ... );
395}
396
398template <typename CONTEXTS, typename... OPERATORS>
399void call_particle_coupling_operators(CONTEXTS lattices,
400 std::size_t nParticles,
401 OPERATORS... ops) __global__ {
402 const CellID iParticle = blockIdx.x * blockDim.x + threadIdx.x;
403 if (!(iParticle < nParticles)) {
404 return;
405 }
406 (ops(lattices, iParticle) || ... );
407}
408
409
411template <typename T, typename DESCRIPTOR, typename DYNAMICS, typename PARAMETERS=typename DYNAMICS::ParametersD>
412void construct_dynamics(void* target, PARAMETERS* parameters) __global__ {
413 new (target) ConcreteDynamics<T,DESCRIPTOR,DYNAMICS>(parameters);
414}
415
416}
417
419
422template <typename CONTEXT, typename... ARGS>
423void call_operators(CONTEXT& lattice, bool* subdomain, ARGS&&... args) {
424 const auto block_size = 32;
425 const auto block_count = (lattice.getNcells() + block_size - 1) / block_size;
426 kernel::call_operators<CONTEXT,ARGS...><<<block_count,block_size>>>(
427 lattice, subdomain, std::forward<decltype(args)>(args)...);
429}
430
432template <typename CONTEXT, typename... ARGS>
433void async_call_operators(cudaStream_t stream, CONTEXT& lattice, bool* subdomain, ARGS&&... args) {
434 const auto block_size = 32;
435 const auto block_count = (lattice.getNcells() + block_size - 1) / block_size;
436 kernel::call_operators<CONTEXT,ARGS...><<<block_count,block_size,0,stream>>>(
437 lattice, subdomain, std::forward<decltype(args)>(args)...);
439}
440
442
445template <typename CONTEXT, typename... ARGS>
446void call_operators_with_statistics(CONTEXT& lattice, bool* subdomain, ARGS&&... args) {
447 const auto block_size = 32;
448 const auto block_count = (lattice.getNcells() + block_size - 1) / block_size;
449 kernel::call_operators_with_statistics<CONTEXT,ARGS...><<<block_count,block_size>>>(
450 lattice, subdomain, std::forward<decltype(args)>(args)...);
452}
453
455template <typename CONTEXT, typename... ARGS>
456void async_call_operators_with_statistics(cudaStream_t stream, CONTEXT& lattice, bool* subdomain, ARGS&&... args) {
457 const auto block_size = 32;
458 const auto block_count = (lattice.getNcells() + block_size - 1) / block_size;
459 kernel::call_operators_with_statistics<CONTEXT,ARGS...><<<block_count,block_size,0,stream>>>(
460 lattice, subdomain, std::forward<decltype(args)>(args)...);
462}
463
465
468template <typename CONTEXT, typename... ARGS>
469void call_list_operators(CONTEXT& lattice,
470 const gpu::cuda::Column<CellID>& cells,
471 ARGS&&... args) {
472 const auto block_size = 32;
473 const auto block_count = (cells.size() + block_size - 1) / block_size;
474 kernel::call_list_operators<CONTEXT,ARGS...><<<block_count, block_size>>>(
475 lattice,
476 cells.deviceData(), cells.size(),
477 std::forward<decltype(args)>(args)...);
479}
480
482template <typename CONTEXT, typename... ARGS>
483void async_call_list_operators(cudaStream_t stream,
484 CONTEXT& lattice,
485 const gpu::cuda::Column<CellID>& cells,
486 ARGS&&... args) {
487 const auto block_size = 32;
488 const auto block_count = (cells.size() + block_size - 1) / block_size;
490 lattice,
491 cells.deviceData(), cells.size(),
492 std::forward<decltype(args)>(args)...);
494}
495
497template <typename CONTEXT, typename... ARGS>
499 CONTEXT& lattice,
500 const gpu::cuda::Column<CellID>& cells,
501 ARGS&&... args) {
502 const auto block_size = 32;
503 const auto block_count = (cells.size() + block_size - 1) / block_size;
505 lattice,
506 cells.deviceData(), cells.size(),
507 std::forward<decltype(args)>(args)...);
509}
510
512template <typename CONTEXT, typename... ARGS>
513void call_coupling_operators(CONTEXT& lattices, bool* subdomain, ARGS&&... args) {
514 const auto nCells = lattices.template get<0>().getNcells();
515 const auto block_size = 32;
516 const auto block_count = (nCells + block_size - 1) / block_size;
517 kernel::call_coupling_operators<CONTEXT,ARGS...><<<block_count,block_size>>>(
518 lattices, subdomain, std::forward<decltype(args)>(args)...);
520}
521
523template <typename CONTEXT, typename... ARGS>
524void call_particle_coupling_operators(CONTEXT& lattices, ARGS&&... args) {
525 const auto nParticles = lattices.get(meta::id<names::Points>{}).getNcells();
526 const auto block_size = 32;
527 const auto block_count = (nParticles + block_size - 1) / block_size;
528 kernel::call_particle_coupling_operators<CONTEXT,ARGS...><<<block_count,block_size>>>(
529 lattices, nParticles, std::forward<decltype(args)>(args)...);
531}
532
533}
534
535}
536
537template <typename T, typename DESCRIPTOR, typename DYNAMICS>
539 _dynamics(new DYNAMICS()),
540 _parameters(nullptr),
541 _mask(nullptr),
542 _cells(0),
543 _modified(true),
544 _stream(cudaStreamDefault)
545{ }
546
547template <typename T, typename DESCRIPTOR, typename DYNAMICS>
551{
552 using namespace gpu::cuda;
553 DeviceContext<T,DESCRIPTOR> lattice(block);
554 if (block.statisticsEnabled()) {
555 call_operators_with_statistics(
556 lattice,
557 subdomain.deviceData(),
558 MaskedCollision<T,DESCRIPTOR,DYNAMICS>{_parameters->parameters, _mask->deviceData()},
559 DynamicDispatchCollision{});
560 } else {
561 call_operators(
562 lattice,
563 subdomain.deviceData(),
564 MaskedCollision<T,DESCRIPTOR,DYNAMICS>{_parameters->parameters, _mask->deviceData()},
565 DynamicDispatchCollision{});
566 }
567}
568
569template <typename T, typename DESCRIPTOR, typename DYNAMICS>
570void ConcreteBlockCollisionO<T,DESCRIPTOR,Platform::GPU_CUDA,DYNAMICS>::applyIndividual(
571 ConcreteBlockLattice<T,DESCRIPTOR,Platform::GPU_CUDA>& block,
572 ConcreteBlockMask<T,Platform::GPU_CUDA>& subdomain)
573{
574 using namespace gpu::cuda;
575 DeviceContext<T,DESCRIPTOR> lattice(block);
576 // Primitive heuristic for preferring mask-based to list-based dispatch
577 if (_mask->weight() > 0.5*subdomain.weight()) {
578 if (block.statisticsEnabled()) {
580 _stream.get(),
581 lattice,
582 subdomain.deviceData(),
583 MaskedCollision<T,DESCRIPTOR,DYNAMICS>{_parameters->parameters, _mask->deviceData()});
584 } else {
586 _stream.get(),
587 lattice,
588 subdomain.deviceData(),
589 MaskedCollision<T,DESCRIPTOR,DYNAMICS>{_parameters->parameters, _mask->deviceData()});
590 }
591
592 // Use list of cell indices
593 } else {
594 // Update cell list from mask
595 if (_modified) {
596 _cells.clear();
597 for (CellID iCell=0; iCell < block.getNcells(); ++iCell) {
598 if (_mask->operator[](iCell)) {
599 _cells.push_back(iCell);
600 }
601 }
602 _cells.setProcessingContext(ProcessingContext::Simulation);
603 _modified = false;
604 }
605
606 if (block.statisticsEnabled()) {
608 _stream.get(),
609 lattice,
610 _cells,
611 ListedCollision<T,DESCRIPTOR,DYNAMICS>{_parameters->parameters});
612 } else {
614 _stream.get(),
615 lattice,
616 _cells,
617 ListedCollision<T,DESCRIPTOR,DYNAMICS>{_parameters->parameters});
618 }
619 }
620}
621
622template <typename T, typename DESCRIPTOR, typename DYNAMICS>
625{
626 // Fetch pointers to DYNAMICS-specific parameter and mask data
627 _parameters = &block.template getData<OperatorParameters<DYNAMICS>>();
628 _mask = &block.template getData<DynamicsMask<DYNAMICS>>();
629
630 {
631 // Construct on-device dynamics proxy for dynamic dispatch
634 _deviceDynamics.get(),
635 _parameters->deviceData());
637
638 // Fetch pointer to on-device dynamic-dispatch field
639 _dynamicsOfCells = block.template getField<gpu::cuda::DYNAMICS<T,DESCRIPTOR>>()[0].data();
640 }
641}
642
643template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
645 _cells(0),
646 _modified{false},
647 _stream{cudaStreamDefault}
648{ }
649
650template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
653{
654 if (_cells.size() > 0) {
655 if (_modified) {
656 _cells.deduplicate();
657 _cells.setProcessingContext(ProcessingContext::Simulation);
658 _modified = false;
659 }
662 lattice,
663 _cells,
665 }
666}
667
668template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
670 _cells(0),
671 _modified{false},
672 _stream{cudaStreamDefault}
673{ }
674
675template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
678{
679 if (_cells.size() > 0) {
680 if (_modified) {
681 _cells.deduplicate();
682 _cells.setProcessingContext(ProcessingContext::Simulation);
683 _modified = false;
684 }
685 using namespace gpu::cuda;
686 DeviceBlockLattice<T,DESCRIPTOR> lattice(block);
687 async_call_list_operators(_stream.get(),
688 lattice,
689 _cells,
690 ListedPostProcessorWithParameters<T,DESCRIPTOR,OPERATOR>{_parameters->parameters});
691 }
692}
693
694
695template <typename COUPLER, typename COUPLEES>
697 CellID iCell, bool state)
698{
699 if (!_mask) {
700 _mask = std::make_unique<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
702 _lattices.template get<0>()->template getData<CollisionSubdomainMask>()
703 );
704 }
705 _mask->set(iCell, state);
706}
707
708template <typename COUPLER, typename COUPLEES>
710{
711 auto deviceLattice = _lattices.exchange_values([&](auto name) -> auto {
712 return gpu::cuda::DeviceBlockLattice{*_lattices.get(name)};
713 });
714 if (_mask) {
715 _mask->setProcessingContext(ProcessingContext::Simulation);
717 deviceLattice, _mask->deviceData(),
719 } else {
720 auto& mask = _lattices.template get<0>()->template getData<CollisionSubdomainMask>();
722 deviceLattice, mask.deviceData(),
724 }
725}
726
727template <typename COUPLER, typename COUPLEES>
729 CellID iCell, bool state)
730{
731 if (!_mask) {
732 _mask = std::make_unique<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
734 _lattices.template get<0>()->template getData<CollisionSubdomainMask>()
735 );
736 }
737 _mask->set(iCell, state);
738}
739
740template <typename COUPLER, typename COUPLEES>
742{
743 auto deviceLattice = _lattices.exchange_values([&](auto name) -> auto {
744 return gpu::cuda::DeviceBlockLattice{*_lattices.get(name)};
745 });
746 if (_mask) {
747 _mask->setProcessingContext(ProcessingContext::Simulation);
749 deviceLattice, _mask->deviceData(),
751 } else {
752 auto& mask = _lattices.template get<0>()->template getData<CollisionSubdomainMask>();
754 deviceLattice, mask.deviceData(),
756 }
757}
758
759template <typename COUPLER, typename COUPLEES>
765
766template <typename COUPLER, typename COUPLEES>
768{
769 if (_lattices.get(meta::id<names::Points>{})->getNcells() == 0) {
770 return;
771 }
772
773 auto* particleLattice = _lattices.get(meta::id<names::Points>{});
774 auto deviceLattice = _lattices.exchange_values([&](auto name) -> auto {
775 if constexpr (std::is_same_v<typename decltype(name)::type, names::Points>) {
776 return gpu::cuda::DeviceContext{*_lattices.get(name)};
777 } else {
778 return gpu::cuda::DeviceBlockLattice{*_lattices.get(name)};
779 }
780 });
781
783 deviceLattice,
785}
786
787}
788
789#endif
#define OPERATOR(OP, rhs)
Definition aDiffTape.h:64
Collision operation of concrete DYNAMICS on concrete block lattices of PLATFORM.
Definition operator.h:104
Coupling of COUPLEES using concrete OPERATOR with SCOPE on PLATFORM lattices.
Definition operator.h:135
Implementation of BlockLattice on a concrete PLATFORM.
Block application of concrete OPERATOR called using SCOPE on PLATFORM.
Definition operator.h:58
Particle coupling of COUPLEES using concrete OPERATOR with SCOPE on PLATFORM lattices.
Definition operator.h:139
Plain old scalar vector.
Device-side implementation of the Cell concept for post processors.
Definition context.hh:313
Plain column for CUDA GPU targets.
Definition column.h:49
const T * deviceData() const
Definition column.hh:146
std::size_t size() const override
Definition column.hh:128
Implementation of gpu::cuda::Dynamics for concrete DYNAMICS.
Definition dynamics.hh:83
Device-side implementation of the data-only Cell concept for collision steps.
Definition dynamics.hh:37
Device-side view of a block lattice.
Definition context.hh:244
Structure for passing pointers to on-device data into CUDA kernels.
Definition dynamics.hh:36
List-based application of DYNAMICS::collide for use in kernel::call_list_operators.
Definition operator.hh:95
bool operator()(DeviceContext< T, DESCRIPTOR > &lattice, CellID iCell) __device__
Definition operator.hh:104
bool operator()(DeviceContext< T, DESCRIPTOR > &lattice, CellID iCell, CellStatistic< T > &statistic) __device__
Definition operator.hh:110
ListedCollision(ParametersOfOperatorD< T, DESCRIPTOR, DYNAMICS > &parameters) __host__
Definition operator.hh:100
List-based application of OPERATOR::apply with parameters.
Definition operator.hh:160
bool operator()(DeviceBlockLattice< T, DESCRIPTOR > &lattice, CellID iCell) __device__
Definition operator.hh:169
ListedPostProcessorWithParameters(ParametersOfOperatorD< T, DESCRIPTOR, OPERATOR > &parameters) __host__
Definition operator.hh:165
Masked application of DYNAMICS::collide for use in kernel::call_operators.
Definition operator.hh:47
bool operator()(DeviceContext< T, DESCRIPTOR > &lattice, CellID iCell) __device__
Chainable call operator for use in kernel::call_operators.
Definition operator.hh:74
MaskedCollision(ParametersOfOperatorD< T, DESCRIPTOR, DYNAMICS > &parameters, bool *mask) any_platform
Constructor (commonly called on the host side)
Definition operator.hh:64
bool operator()(DeviceContext< T, DESCRIPTOR > &lattice, CellID iCell, CellStatistic< T > &statistic) __device__
Chainable call operator with statistics storage.
Definition operator.hh:83
Masked application of OPERATOR::apply.
Definition operator.hh:121
MaskedPostProcessor(bool *mask) any_platform
Definition operator.hh:127
bool operator()(DeviceBlockLattice< T, DESCRIPTOR > &lattice, CellID iCell) __device__
Definition operator.hh:132
Unrestricted application of COUPLING::apply with parameters.
Definition operator.hh:219
bool operator()(CONTEXT &lattices, CellID iParticle) __device__
Definition operator.hh:238
ParticleCouplingWithParameters(PARAMETERS &parameters) any_platform
Definition operator.hh:233
Unrestricted application of COUPLING::apply with parameters.
Definition operator.hh:193
bool operator()(CONTEXT &lattices, CellID iCell) __device__
Definition operator.hh:206
UnmaskedCouplingWithParameters(PARAMETERS &parameters) any_platform
Definition operator.hh:201
void check()
Check errors.
Definition device.hh:48
T * malloc(std::size_t size)
Allocate data on device.
Definition device.hh:89
void call_coupling_operators(CONTEXTS lattices, bool *subdomain, OPERATORS... ops) __global__
CUDA kernel for applying UnmaskedCoupling(WithParameters)
Definition operator.hh:388
void call_particle_coupling_operators(CONTEXTS lattices, std::size_t nParticles, OPERATORS... ops) __global__
CUDA kernel for applying UnmaskedCoupling(WithParameters)
Definition operator.hh:399
void call_list_operators(CONTEXT lattice, const CellID *indices, std::size_t nIndices, OPERATORS... ops) __global__
CUDA kernel for applying generic OPERATORS with OperatorScope::PerCell or ListedCollision.
Definition operator.hh:348
void construct_dynamics(void *target, PARAMETERS *parameters) __global__
CUDA kernel for constructing on-device ConcreteDynamics.
Definition operator.hh:412
void call_operators(CONTEXT lattice, bool *subdomain, OPERATORS... ops) __global__
CUDA kernel for applying purely local collision steps.
Definition operator.hh:312
void call_list_operators_with_statistics(CONTEXT lattice, const CellID *indices, std::size_t nIndices, OPERATORS... ops) __global__
CUDA kernel for applying ListedCollision.
Definition operator.hh:363
void call_operators_with_statistics(CONTEXT lattice, bool *subdomain, OPERATORS... ops) __global__
CUDA kernel for applying purely local collision steps while tracking statistics.
Definition operator.hh:325
void async_call_list_operators(cudaStream_t stream, CONTEXT &lattice, const gpu::cuda::Column< CellID > &cells, ARGS &&... args)
Apply operators to listed cell indices (async version)
Definition operator.hh:483
void async_call_operators(cudaStream_t stream, CONTEXT &lattice, bool *subdomain, ARGS &&... args)
Apply masked collision operators to lattice (async)
Definition operator.hh:433
void call_operators(CONTEXT &lattice, bool *subdomain, ARGS &&... args)
Apply masked collision operators to lattice.
Definition operator.hh:423
void async_call_list_operators_with_statistics(cudaStream_t stream, CONTEXT &lattice, const gpu::cuda::Column< CellID > &cells, ARGS &&... args)
Apply ListedCollision with statistics (async version)
Definition operator.hh:498
void async_call_operators_with_statistics(cudaStream_t stream, CONTEXT &lattice, bool *subdomain, ARGS &&... args)
Apply masked collision operators to lattice while tracking statistics (async)
Definition operator.hh:456
void call_list_operators(CONTEXT &lattice, const gpu::cuda::Column< CellID > &cells, ARGS &&... args)
Apply operators to listed cell indices.
Definition operator.hh:469
void call_particle_coupling_operators(CONTEXT &lattices, ARGS &&... args)
Apply coupling on particles and lattices.
Definition operator.hh:524
void call_operators_with_statistics(CONTEXT &lattice, bool *subdomain, ARGS &&... args)
Apply masked collision operators to lattice while tracking statistics.
Definition operator.hh:446
std::function< void(ConcreteBlockLattice< T, DESCRIPTOR, Platform::GPU_CUDA > &)> getFusedCollisionO()
Helper for constructing fused collision operators.
Definition operator.hh:280
void call_coupling_operators(CONTEXT &lattices, bool *subdomain, ARGS &&... args)
Apply coupling on subdomain.
Definition operator.hh:513
typename LIST_A::template decompose_into< LIST_B::template include > merge
Merge elements of LIST_A and LIST_B into new list.
Definition meta.h:344
ADf< T, DIM > floor(const ADf< T, DIM > &a)
Definition aDiff.h:869
Top level namespace for all of OpenLB.
std::uint32_t CellID
Type for sequential block-local cell indices.
@ Simulation
Data available on host for e.g. functor evaluation.
@ GPU_CUDA
Vector CPU (AVX2 / AVX-512 collision)
typename ParametersD< T, DESCRIPTOR >::template include< typename OPERATOR::parameters > ParametersOfOperatorD
Deduce ParametersD of OPERATOR w.r.t. T and DESCRIPTOR.
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:77
Base of block-wide coupling operators executed by SuperLatticeCoupling.
Definition operator.h:108
Return value of any collision.
Definition interface.h:45
Describe mask of DYNAMICS in Data.
Definition data.h:72
On-device field mirroring BlockDynamicsMap.
Definition dynamics.h:39
Last node in a MaskedDynamics chain in kernel::call_operators.
Definition dynamics.hh:150
List-based application of OPERATOR::apply.
Definition operator.hh:148
bool operator()(DeviceBlockLattice< T, DESCRIPTOR > &lattice, CellID iCell) __device__
Definition operator.hh:150
Unrestricted application of COUPLING::apply.
Definition operator.hh:179
bool operator()(CONTEXT &lattices, CellID iCell) __device__
Definition operator.hh:181
Identity type to pass non-constructible types as value.
Definition meta.h:79
Plain wrapper for list of types.
Definition meta.h:276