OpenLB 1.8.1
Loading...
Searching...
No Matches
operator.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 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 SIMD_OPERATOR_H
25#define SIMD_OPERATOR_H
26
27#include "mask.h"
28
29#include "core/meta.h"
30#include "core/operator.h"
31
33
34#include "dynamics/dynamics.h"
35
37
38namespace olb {
39
40template <typename T>
41struct CellStatistic<cpu::simd::Pack<T>> {
44
45 operator bool() const {
46 return true;
47 }
48};
49
50namespace cpu {
51
53namespace simd {
54
56template <typename T, unsigned D>
57class FieldPtr : public ScalarVector<Pack<T>,D,FieldPtr<T,D>> {
58private:
59 ColumnVector<Column<T>,D>& _data;
60 std::size_t _index;
61
62 friend typename ScalarVector<Pack<T>,D,FieldPtr>::type;
63
64 std::array<Pack<T>,D> _packs;
65
66protected:
67
68public:
69 FieldPtr(ColumnVector<Column<T>,D>& columns, std::size_t index):
70 _data(columns),
71 _index(index) {
72 meta::call_n_times<D>([&](unsigned iD) {
73 _packs[iD] = &_data[iD][_index];
74 });
75 }
76
78 _data(rhs._data),
79 _index(rhs._index),
80 _packs(rhs._packs) { }
81
82 const Pack<T>* getComponentPointer(unsigned iDim) const
83 {
84 return &_packs[iDim];
85 }
86
88 {
89 return &_packs[iDim];
90 }
91
92 template <typename U, typename IMPL>
94 {
95 for (unsigned iDim=0; iDim < D; ++iDim) {
96 this->operator[](iDim) = rhs[iDim];
97 }
98 return *this;
99 }
100
101};
102
104
110template <typename T, typename DESCRIPTOR, typename V, typename... RW_FIELDS>
111class Cell {
112private:
113 using rw_fields = meta::list<RW_FIELDS...>;
114
116 std::size_t _iCell;
117 Mask<T>& _mask;
118
120
123 std::tuple<FieldD<V,DESCRIPTOR,RW_FIELDS>...> _fields;
124
125public:
126 using value_t = V;
127 using descriptor_t = DESCRIPTOR;
128
131 _lattice(lattice),
132 _iCell(iCell),
133 _mask(mask)
134 {
135 rw_fields::for_each([&](auto field) {
136 using FIELD = typename decltype(field)::type;
137 auto& array = _lattice.template getField<FIELD>();
138 auto& pack = std::get<(rw_fields::template index<FIELD>())>(_fields);
139 //meta::call_n_times<(DESCRIPTOR::template size<FIELD>())>([&](unsigned iD) {
140 for (unsigned iD=0; iD < DESCRIPTOR::template size<FIELD>(); ++iD) {
141 pack[iD] = cpu::simd::Pack<T>(&array[iD][_iCell]);
142 }
143 });
144 }
145
148 {
149 rw_fields::for_each([&](auto field) {
150 using FIELD = typename decltype(field)::type;
151 auto& array = _lattice.template getField<FIELD>();
152 auto& pack = std::get<(rw_fields::template index<FIELD>())>(_fields);
153 //meta::call_n_times<(DESCRIPTOR::template size<FIELD>())>([&](unsigned iD) {
154 for (unsigned iD=0; iD < DESCRIPTOR::template size<FIELD>(); ++iD) {
155 cpu::simd::maskstore(&array[iD][_iCell], _mask, pack[iD]);
156 }
157 });
158 }
159
161 V& operator[](unsigned iPop) {
162 return std::get<(rw_fields::template index<descriptors::POPULATION>())>(_fields)[iPop];
163 }
164
166 template <typename FIELD>
167 auto getField() const {
168 if constexpr (rw_fields::template contains<FIELD>()) {
169 if constexpr (DESCRIPTOR::template size<FIELD>() == 1) {
170 return std::get<(rw_fields::template index<FIELD>())>(_fields)[0];
171 } else {
172 return std::get<(rw_fields::template index<FIELD>())>(_fields);
173 }
174 } else {
175 auto& fieldArray = _lattice.template getField<FIELD>();
176 if constexpr (DESCRIPTOR::template size<FIELD>() == 1) {
177 return cpu::simd::Pack<T>(&fieldArray[0][_iCell]);
178 } else {
179 return FieldD<V,DESCRIPTOR,FIELD>([&](unsigned iD) {
180 return &fieldArray[iD][_iCell];
181 });
182 }
183 }
184 __builtin_unreachable();
185 }
186
188 template <typename FIELD>
190 if constexpr (rw_fields::template contains<FIELD>()) {
191 std::get<(rw_fields::template index<FIELD>())>(_fields) = value;
192 } else {
193 auto& array = _lattice.template getField<FIELD>();
194 for (unsigned iD=0; iD < DESCRIPTOR::template size<FIELD>(); ++iD) {
195 cpu::simd::maskstore(&array[iD][_iCell], _mask, value[iD]);
196 }
197 }
198 }
199
201 template <typename FIELD>
203 if constexpr (rw_fields::template contains<FIELD>()) {
204 std::get<(rw_fields::template index<FIELD>())>(_fields) = value;
205 } else {
206 auto& array = _lattice.template getField<FIELD>();
207 for (unsigned iD=0; iD < DESCRIPTOR::template size<FIELD>(); ++iD) {
208 cpu::simd::maskstore(&array[iD][_iCell], _mask, value[iD]);
209 }
210 }
211 }
212
214 template <typename FIELD>
215 std::enable_if_t<rw_fields::template contains<FIELD>(), FieldD<V,DESCRIPTOR,FIELD>&>
217 return std::get<(rw_fields::template index<FIELD>())>(_fields);
218 }
219
221 template <typename FIELD>
222 std::enable_if_t<!rw_fields::template contains<FIELD>(), FieldD<V,DESCRIPTOR,FIELD>>
224 return getField<FIELD>();
225 }
226
228 template <typename FIELD>
229 std::enable_if_t<rw_fields::template contains<FIELD>(),V&>
230 getFieldComponent(unsigned iD) {
231 return std::get<(rw_fields::template index<FIELD>())>(_fields)[iD];
232 }
233
235 template <typename FIELD>
236 std::enable_if_t<!rw_fields::template contains<FIELD>(),V>
237 getFieldComponent(unsigned iD) {
238 return &_lattice.template getField<FIELD>()[iD][_iCell];
239 }
240
241};
242
243
245template <typename T, typename DESCRIPTOR, typename DYNAMICS>
246class ConcreteDynamics final : public cpu::Dynamics<T,DESCRIPTOR,Platform::CPU_SIMD> {
247private:
249
250public:
252 _parameters{parameters} {
253 }
254
256 return DYNAMICS().collide(cell, *_parameters);
257 }
258
260 return typename DYNAMICS::MomentaF().computeRho(cell);
261 }
263 typename DYNAMICS::MomentaF().computeU(cell, u);
264 }
266 typename DYNAMICS::MomentaF().computeJ(cell, j);
267 }
268 void computeRhoU(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SIMD>& cell, T& rho, T* u) override {
269 typename DYNAMICS::MomentaF().computeRhoU(cell, rho, u);
270 }
271 void computeStress(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SIMD>& cell, T& rho, T* u, T* pi) override {
272 typename DYNAMICS::MomentaF().computeStress(cell, rho, u, pi);
273 }
274 void computeAllMomenta(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SIMD>& cell, T& rho, T* u, T* pi) override {
275 typename DYNAMICS::MomentaF().computeAllMomenta(cell, rho, u, pi);
276 }
277
278 T getOmegaOrFallback(T fallback) override {
279 if constexpr (DYNAMICS::parameters::template contains<descriptors::OMEGA>()) {
280 return _parameters->template get<descriptors::OMEGA>();
281 } else {
282 return fallback;
283 }
284 __builtin_unreachable();
285 }
286
287 void computeEquilibrium(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SIMD>& cell, T rho, T* u, T* fEq) override {
288 typename DYNAMICS::EquilibriumF().compute(cell, rho, u, fEq);
289 };
290
292 typename DYNAMICS::MomentaF().defineRho(cell, rho);
293 }
294
296 typename DYNAMICS::MomentaF().defineU(cell, u);
297 }
298
299 void defineRhoU(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SIMD>& cell, T& rho, T* u) override {
300 typename DYNAMICS::MomentaF().defineRhoU(cell, rho, u);
301 }
302
303 void defineAllMomenta(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SIMD>& cell, T& rho, T* u, T* pi) override {
304 typename DYNAMICS::MomentaF().defineAllMomenta(cell, rho, u, pi);
305 }
306
308 typename DYNAMICS::MomentaF().inverseShiftRhoU(cell, rho, u);
309 }
310};
311
312}
313
314}
315
316
318
324template <typename T, typename DESCRIPTOR, typename DYNAMICS>
325class ConcreteBlockCollisionO<T,DESCRIPTOR,Platform::CPU_SIMD,DYNAMICS> final
326 : public BlockCollisionO<T,DESCRIPTOR,Platform::CPU_SIMD> {
327private:
328 std::unique_ptr<DYNAMICS> _dynamics;
329 std::unique_ptr<cpu::Dynamics<T,DESCRIPTOR,Platform::CPU_SIMD>> _concreteDynamics;
330
333
335
338 typename LatticeStatistics<T>::Aggregatable& statistics,
339 std::size_t iCell)
340 {
342 if (auto cellStatistic = _dynamicsOfCells[iCell]->collide(cell)) {
343 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
344 }
345 }
346
352 typename LatticeStatistics<T>::Aggregatable& statistics,
353 std::size_t iCell)
354 {
355 if constexpr (dynamics::is_vectorizable_v<DYNAMICS>) {
356 if (cpu::simd::Mask<T> m = {mask.raw(), iCell}) {
358 auto simdParameters = parameters.template copyAs<cpu::simd::Pack<T>>();
359 auto cellStatistic = DYNAMICS().collide(cell, simdParameters);
360 for (unsigned i=0; i < cpu::simd::Pack<T>::size; ++i) {
361 if (mask[iCell+i]) {
362 if (cellStatistic.rho[i] != T{-1}) {
363 statistics.increment(cellStatistic.rho[i], cellStatistic.uSqr[i]);
364 }
365 } else if (subdomain[iCell+i]) {
366 applyOther(block, statistics, iCell+i);
367 }
368 }
369 } else {
370 for (std::size_t i=iCell; i < iCell+cpu::simd::Pack<T>::size; ++i) {
371 if (subdomain[i]) {
372 applyOther(block, statistics, i);
373 }
374 }
375 }
376 }
377 }
378
379public:
381 _dynamics(new DYNAMICS()),
382 _parameters(nullptr),
383 _mask(nullptr)
384 { }
385
386 std::type_index id() const override
387 {
388 return typeid(DYNAMICS);
389 }
390
391 std::size_t weight() const override
392 {
393 return _mask->weight();
394 }
395
396 void set(CellID iCell, bool state, bool overlap) override
397 {
399 if constexpr (!std::is_same_v<DYNAMICS,NoDynamics<T,DESCRIPTOR>>) {
400 if (!overlap) {
401 _mask->set(iCell, state);
402 }
403 }
404 if (state) {
405 _dynamicsOfCells[iCell] = _concreteDynamics.get();
406 }
407 }
408
410 {
411 return _dynamics.get();
412 }
413
415 {
416 _parameters = &block.template getData<OperatorParameters<DYNAMICS>>().parameters;
417 _mask = &block.template getData<DynamicsMask<DYNAMICS>>();
418 if constexpr (dynamics::has_parametrized_momenta_v<DYNAMICS>) {
419 _dynamics->setMomentaParameters(_parameters);
420 }
421
422 _concreteDynamics.reset(new cpu::simd::ConcreteDynamics<T,DESCRIPTOR,DYNAMICS>(_parameters));
423 // Fetch pointer to concretized dynamic-dispatch field
424 _dynamicsOfCells = block.template getField<cpu::DYNAMICS<T,DESCRIPTOR,Platform::CPU_SIMD>>()[0].data();
425 }
426
430 CollisionDispatchStrategy strategy) override
431 {
432 if (strategy != CollisionDispatchStrategy::Dominant) {
433 throw std::runtime_error("Platform::CPU_SIMD currently only support CollisionDispatchStrategy::Dominant");
434 }
435
436 auto& mask = *_mask;
437 typename LatticeStatistics<T>::Aggregatable statistics{};
438 #ifdef PARALLEL_MODE_OMP
439 #pragma omp declare reduction(+ : typename LatticeStatistics<T>::Aggregatable : omp_out += omp_in) initializer (omp_priv={})
440 #endif
441
442 if constexpr (dynamics::is_vectorizable_v<DYNAMICS>) {
443 // Ensure that serialized mask storage is up-to-date
444 mask.setProcessingContext(ProcessingContext::Simulation);
445 // Apply collision to cells
446 #ifdef PARALLEL_MODE_OMP
447 #pragma omp parallel for schedule(static) reduction(+ : statistics)
448 #endif
449 for (CellID iCell=0; iCell < block.getNcells(); iCell += cpu::simd::Pack<T>::size) {
450 apply(block, subdomain, mask, *_parameters, statistics, iCell);
451 }
452 } else { // Fallback for non-vectorizable collision operators
453 #ifdef PARALLEL_MODE_OMP
454 #pragma omp parallel for schedule(static) reduction(+ : statistics)
455 #endif
456 for (std::size_t iCell=0; iCell < block.getNcells(); ++iCell) {
457 if (mask[iCell]) {
459 if (auto cellStatistic = DYNAMICS().collide(cell, *_parameters)) {
460 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
461 }
462 } else if (subdomain[iCell]) {
463 applyOther(block, statistics, iCell);
464 }
465 }
466 }
467
468 block.getStatistics().incrementStats(statistics);
469 }
470
471};
472
473
475template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
477 : public BlockO<T,DESCRIPTOR,Platform::CPU_SIMD> {
478private:
479 std::vector<CellID> _cells;
480 bool _modified;
481
482public:
483 ConcreteBlockO() = default;
484
485 std::type_index id() const override
486 {
487 return typeid(OPERATOR);
488 }
489
490 std::size_t weight() const override
491 {
492 return _cells.size();
493 }
494
495 void set(CellID iCell, bool state) override
496 {
497 if (state) {
498 _cells.emplace_back(iCell);
499 _modified = true;
500 }
501 }
502
505
507 {
508 if (_modified) {
509 std::sort(_cells.begin(), _cells.end());
510 _cells.erase(std::unique(_cells.begin(), _cells.end()), _cells.end());
511 _modified = false;
512 }
513 if (_cells.size() > 0) {
515 #ifdef PARALLEL_MODE_OMP
516 #pragma omp parallel for schedule(static) firstprivate(cell)
517 #endif
518 for (CellID iCell : _cells) {
519 cell.setCellId(iCell);
520 OPERATOR().apply(cell);
521 }
522 }
523 }
524
525};
526
527
528template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
530 : public BlockO<T,DESCRIPTOR,Platform::CPU_SIMD> {
531private:
532 std::vector<CellID> _cells;
533 bool _modified;
534
536
537public:
538 ConcreteBlockO() = default;
539
540 std::type_index id() const override
541 {
542 return typeid(OPERATOR);
543 }
544
545 std::size_t weight() const override
546 {
547 return _cells.size();
548 }
549
550 void set(CellID iCell, bool state) override
551 {
552 if (state) {
553 _cells.emplace_back(iCell);
554 _modified = true;
555 }
556 }
557
559 {
560 _parameters = &block.template getData<OperatorParameters<OPERATOR>>().parameters;
561 }
562
564 {
565 if (_modified) {
566 std::sort(_cells.begin(), _cells.end());
567 _cells.erase(std::unique(_cells.begin(), _cells.end()), _cells.end());
568 _modified = false;
569 }
570 if (_cells.size() > 0) {
572 #ifdef PARALLEL_MODE_OMP
573 #pragma omp parallel for schedule(static) firstprivate(cell)
574 #endif
575 for (CellID iCell : _cells) {
576 cell.setCellId(iCell);
577 OPERATOR().apply(cell, *_parameters);
578 }
579 }
580 }
581
582};
583
584
586
589template <typename T, typename DESCRIPTOR, concepts::BlockOperator OPERATOR>
591 : public BlockO<T,DESCRIPTOR,Platform::CPU_SIMD> {
592public:
593 std::type_index id() const override
594 {
595 return typeid(OPERATOR);
596 }
597
598 std::size_t weight() const override
599 {
600 return 0;
601 }
602
603 void set(CellID iCell, bool state) override
604 {
605 throw std::logic_error("BlockO::set not supported for OperatorScope::PerBlock");
606 }
607
609 {
610 OPERATOR().setup(block);
611 }
612
614 {
615 OPERATOR().apply(block);
616 }
617
618};
619
620}
621
622#endif
#define OPERATOR(OP, rhs)
Definition aDiffTape.h:64
LatticeStatistics< T > & getStatistics()
Return a handle to the LatticeStatistics object.
std::size_t getNcells() const
Get number of cells.
Vector of columns.
std::size_t weight() const override
Returns number of assigned cells.
Definition operator.h:391
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:414
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block, ConcreteBlockMask< T, Platform::CPU_SIMD > &subdomain, CollisionDispatchStrategy strategy) override
Apply collision on entire block.
Definition operator.h:428
void set(CellID iCell, bool state, bool overlap) override
Set whether iCell is covered by the present collision step.
Definition operator.h:396
Collision operation of concrete DYNAMICS on concrete block lattices of PLATFORM.
Definition operator.h:104
Implementation of BlockLattice on a concrete PLATFORM.
std::size_t weight() const override
Get number of cells covered by operator (optional)
Definition operator.h:545
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:563
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:558
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:550
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:608
std::size_t weight() const override
Get number of cells covered by operator (optional)
Definition operator.h:598
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:603
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:613
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:503
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:495
std::size_t weight() const override
Get number of cells covered by operator (optional)
Definition operator.h:490
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &block) override
Definition operator.h:506
Block application of concrete OPERATOR called using SCOPE on PLATFORM.
Definition operator.h:58
Plain old scalar vector.
Cell concept for concrete block lattices on CPU platforms.
Definition cell.h:141
void setCellId(CellID iCell)
Definition cell.h:162
Implementation of the Cell concept for vectorized collision operators.
Definition operator.h:111
auto getField() const
Return pack-valued copy of FIELD.
Definition operator.h:167
V & operator[](unsigned iPop)
Return reference to iPop population pack.
Definition operator.h:161
std::enable_if_t< rw_fields::template contains< FIELD >(), FieldD< V, DESCRIPTOR, FIELD > & > getFieldPointer()
Return reference to pack-valued interim storage vector of r/w field.
Definition operator.h:216
void setField(const FieldD< V, DESCRIPTOR, FIELD > &value)
Set compoents of FIELD from pack-valued vector.
Definition operator.h:202
std::enable_if_t<!rw_fields::template contains< FIELD >(), FieldD< V, DESCRIPTOR, FIELD > > getFieldPointer()
Return pack-valued copy of non r/w field.
Definition operator.h:223
DESCRIPTOR descriptor_t
Definition operator.h:127
void setField(FieldD< V, DESCRIPTOR, FIELD > &&value)
Set compoents of FIELD from pack-valued vector.
Definition operator.h:189
std::enable_if_t<!rw_fields::template contains< FIELD >(), V > getFieldComponent(unsigned iD)
Return pack-valued copy of non r/w field component.
Definition operator.h:237
std::enable_if_t< rw_fields::template contains< FIELD >(), V & > getFieldComponent(unsigned iD)
Return reference to pack-valued interim storage component of r/w field.
Definition operator.h:230
Cell(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SIMD > &lattice, std::size_t iCell, Mask< T > &mask)
Load r/w fields into SIMD packs.
Definition operator.h:130
~Cell()
Store modified r/w fields back into lattice taking into account the mask.
Definition operator.h:147
Plain column for SIMD CPU targets.
Definition column.h:53
Implementation of cpu::Dynamics for concrete DYNAMICS on SIMD blocks.
Definition operator.h:246
void computeJ(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T *j) override
Definition operator.h:265
CellStatistic< T > collide(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell) override
Definition operator.h:255
void inverseShiftRhoU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho, T *u) override
Definition operator.h:307
T computeRho(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell) override
Definition operator.h:259
void computeRhoU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho, T *u) override
Definition operator.h:268
void computeStress(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho, T *u, T *pi) override
Definition operator.h:271
void defineAllMomenta(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho, T *u, T *pi) override
Definition operator.h:303
void defineU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T *u) override
Definition operator.h:295
void computeAllMomenta(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho, T *u, T *pi) override
Definition operator.h:274
ConcreteDynamics(ParametersOfOperatorD< T, DESCRIPTOR, DYNAMICS > *parameters)
Definition operator.h:251
void computeEquilibrium(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T rho, T *u, T *fEq) override
Definition operator.h:287
T getOmegaOrFallback(T fallback) override
Definition operator.h:278
void defineRhoU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho, T *u) override
Definition operator.h:299
void computeU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T *u) override
Definition operator.h:262
void defineRho(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SIMD > &cell, T &rho) override
Definition operator.h:291
SIMD-specific pointer to a pack of rows of a D-dimensional field.
Definition operator.h:57
Pack< T > * getComponentPointer(unsigned iDim)
Definition operator.h:87
FieldPtr< T, D > & operator=(const GenericVector< U, D, IMPL > &rhs)
Definition operator.h:93
FieldPtr(ColumnVector< Column< T >, D > &columns, std::size_t index)
Definition operator.h:69
FieldPtr(FieldPtr< T, D > &&rhs)
Definition operator.h:77
const Pack< T > * getComponentPointer(unsigned iDim) const
Definition operator.h:82
Interface for post-processing steps – header file.
void maskstore(T *target, Mask< T > mask, Pack< T > value)
void call_n_times(F &&f, std::index_sequence< INDICES... >)
Call F for each index (exlicitly unrolled loop)
Definition meta.h:519
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.
Platform
OpenLB execution targets.
Definition platform.h:35
@ CPU_SIMD
Basic scalar CPU.
Vector< typename FIELD::template value_type< T >, DESCRIPTOR::template size< FIELD >() > FieldD
Vector storing a single field instance.
Definition vector.h:480
CollisionDispatchStrategy
Collision dispatch strategy.
Definition operator.h:81
@ Dominant
Apply dominant dynamics using mask and fallback to virtual dispatch for others.
typename ParametersD< T, DESCRIPTOR >::template include< typename OPERATOR::parameters > ParametersOfOperatorD
Deduce ParametersD of OPERATOR w.r.t. T and DESCRIPTOR.
@ PerBlock
Per-block application, i.e. OPERATOR::apply is passed a ConcreteBlockLattice.
@ PerCell
Per-cell application, i.e. OPERATOR::apply is passed a CELL concept implementation.
@ PerCellWithParameters
Per-cell application with parameters, i.e. OPERATOR::apply is passed a CELL concept implementation an...
Collision operation on concrete blocks of PLATFORM.
Definition operator.h:90
Base of block-wide operators such as post processors.
Definition operator.h:44
Return value of any collision.
Definition interface.h:45
Interface for per-cell dynamics.
Definition interface.h:56
Generic vector of values supporting basic arithmetic.
constexpr const T & operator[](unsigned iDim) const any_platform
Vector of scalars.
GenericVector< T, D, FieldPtr< T, D > > type
CPU specific field mirroring BlockDynamicsMap.
Definition cell.h:134
Virtual interface for dynamically-dispatched dynamics access on CPU targets.
Definition cell.h:42
Plain wrapper for list of types.
Definition meta.h:276
static constexpr void for_each(F f)
Calls f for each type of TYPES by-value (in reversed order!)
Definition meta.h:331