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 SISD_OPERATOR_H
25#define SISD_OPERATOR_H
26
27#include "mask.h"
28
29#include "core/meta.h"
30#include "core/operator.h"
31
34
35#include "dynamics/dynamics.h"
36
37namespace olb {
38
39namespace cpu {
40
42namespace sisd {
43
45template <typename T, typename DESCRIPTOR, typename DYNAMICS>
46class ConcreteDynamics final : public cpu::Dynamics<T,DESCRIPTOR,Platform::CPU_SISD> {
47private:
49
50public:
52 _parameters{parameters} {
53 }
54
56 return DYNAMICS().collide(cell, *_parameters);
57 }
58
60 return typename DYNAMICS::MomentaF().computeRho(cell);
61 }
63 typename DYNAMICS::MomentaF().computeU(cell, u);
64 }
66 typename DYNAMICS::MomentaF().computeJ(cell, j);
67 }
68 void computeRhoU(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SISD>& cell, T& rho, T* u) override {
69 typename DYNAMICS::MomentaF().computeRhoU(cell, rho, u);
70 }
71 void computeStress(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SISD>& cell, T& rho, T* u, T* pi) override {
72 typename DYNAMICS::MomentaF().computeStress(cell, rho, u, pi);
73 }
74 void computeAllMomenta(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SISD>& cell, T& rho, T* u, T* pi) override {
75 typename DYNAMICS::MomentaF().computeAllMomenta(cell, rho, u, pi);
76 }
77
78 T getOmegaOrFallback(T fallback) override {
79 if constexpr (DYNAMICS::parameters::template contains<descriptors::OMEGA>()) {
80 return _parameters->template get<descriptors::OMEGA>();
81 } else {
82 return fallback;
83 }
84 __builtin_unreachable();
85 }
86
87 void computeEquilibrium(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SISD>& cell, T rho, T* u, T* fEq) override {
88 typename DYNAMICS::EquilibriumF().compute(cell, rho, u, fEq);
89 };
90
92 typename DYNAMICS::MomentaF().defineRho(cell, rho);
93 }
94
96 typename DYNAMICS::MomentaF().defineU(cell, u);
97 }
98
99 void defineRhoU(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SISD>& cell, T& rho, T* u) override {
100 typename DYNAMICS::MomentaF().defineRhoU(cell, rho, u);
101 }
102
103 void defineAllMomenta(cpu::Cell<T,DESCRIPTOR,Platform::CPU_SISD>& cell, T& rho, T* u, T* pi) override {
104 typename DYNAMICS::MomentaF().defineAllMomenta(cell, rho, u, pi);
105 }
106
108 typename DYNAMICS::MomentaF().inverseShiftRhoU(cell, rho, u);
109 }
110};
111
112}
113
114}
115
117
124template <typename T, typename DESCRIPTOR, typename DYNAMICS>
125class ConcreteBlockCollisionO<T,DESCRIPTOR,Platform::CPU_SISD,DYNAMICS> final
126 : public BlockCollisionO<T,DESCRIPTOR,Platform::CPU_SISD> {
127private:
128 std::unique_ptr<DYNAMICS> _dynamics;
129 std::unique_ptr<cpu::Dynamics<T,DESCRIPTOR,Platform::CPU_SISD>> _concreteDynamics;
130
133
135
136 std::vector<CellID> _cells;
137 bool _modified;
138
140
145 {
146 auto& parameters = *_parameters;
147 auto& mask = *_mask;
148 typename LatticeStatistics<T>::Aggregatable statistics{};
149 #ifdef PARALLEL_MODE_OMP
150 #pragma omp declare reduction(+ : typename LatticeStatistics<T>::Aggregatable : omp_out += omp_in) initializer (omp_priv={})
151 #endif
152
153 if constexpr (DESCRIPTOR::d == 3) {
154 if (block.statisticsEnabled()) {
155 #ifdef PARALLEL_MODE_OMP
156 #pragma omp parallel for schedule(dynamic,1) reduction(+ : statistics)
157 #endif
158 for (int iX=0; iX < block.getNx(); ++iX) {
159 for (int iY=0; iY < block.getNy(); ++iY) {
160 std::size_t iCell = block.getCellId(iX,iY,0);
161 for (int iZ=0; iZ < block.getNz(); ++iZ) {
163 if (auto cellStatistic = mask[iCell] ? DYNAMICS().collide(cell, parameters)
164 : _dynamicsOfCells[iCell]->collide(cell)) {
165 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
166 }
167 iCell += 1;
168 }
169 }
170 }
171 } else {
172 #ifdef PARALLEL_MODE_OMP
173 #pragma omp parallel for schedule(dynamic,1)
174 #endif
175 for (int iX=0; iX < block.getNx(); ++iX) {
176 for (int iY=0; iY < block.getNy(); ++iY) {
177 std::size_t iCell = block.getCellId(iX,iY,0);
178 for (int iZ=0; iZ < block.getNz(); ++iZ) {
180 if (mask[iCell]) [[likely]] {
181 DYNAMICS().collide(cell, parameters);
182 } else {
183 _dynamicsOfCells[iCell]->collide(cell);
184 }
185 iCell += 1;
186 }
187 }
188 }
189 }
190 } else {
191 if (block.statisticsEnabled()) {
192 #ifdef PARALLEL_MODE_OMP
193 #pragma omp parallel for schedule(dynamic,1) reduction(+ : statistics)
194 #endif
195 for (int iX=0; iX < block.getNx(); ++iX) {
196 std::size_t iCell = block.getCellId(iX,0);
197 for (int iY=0; iY < block.getNy(); ++iY) {
199 if (auto cellStatistic = mask[iCell] ? DYNAMICS().collide(cell, parameters)
200 : _dynamicsOfCells[iCell]->collide(cell)) {
201 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
202 }
203 iCell += 1;
204 }
205 }
206 } else {
207 #ifdef PARALLEL_MODE_OMP
208 #pragma omp parallel for schedule(dynamic,1)
209 #endif
210 for (int iX=0; iX < block.getNx(); ++iX) {
211 std::size_t iCell = block.getCellId(iX,0);
212 for (int iY=0; iY < block.getNy(); ++iY) {
214 if (mask[iCell]) [[likely]] {
215 DYNAMICS().collide(cell, parameters);
216 } else {
217 _dynamicsOfCells[iCell]->collide(cell);
218 }
219 iCell += 1;
220 }
221 }
222 }
223 }
224
225 if (block.statisticsEnabled()) {
226 block.getStatistics().incrementStats(statistics);
227 }
228 }
229
233 {
234 // Update cell list from mask
235 if (_modified) {
236 _cells.clear();
237 for (CellID iCell=0; iCell < block.getNcells(); ++iCell) {
238 if (_mask->operator[](iCell)) {
239 _cells.push_back(iCell);
240 }
241 }
242 _modified = false;
243 }
244
245 auto& parameters = *_parameters;
246 typename LatticeStatistics<T>::Aggregatable statistics{};
247
248 #ifdef PARALLEL_MODE_OMP
249 #pragma omp declare reduction(+ : typename LatticeStatistics<T>::Aggregatable : omp_out += omp_in) initializer (omp_priv={})
250 #endif
251
252 #ifdef PARALLEL_MODE_OMP
253 #pragma omp parallel for schedule(static) reduction(+ : statistics)
254 #endif
255 for (std::size_t i=0; i < _cells.size(); ++i) {
256 std::size_t iCell = _cells[i];
258 if (auto cellStatistic = DYNAMICS().collide(cell, parameters)) {
259 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
260 }
261 }
262
263 block.getStatistics().incrementStats(statistics);
264 }
265
266public:
268 _dynamics(new DYNAMICS()),
269 _parameters(nullptr),
270 _mask(nullptr),
271 _cells(0),
272 _modified(true)
273 { }
274
275 std::type_index id() const override
276 {
277 return typeid(DYNAMICS);
278 }
279
280 std::size_t weight() const override
281 {
282 return _mask->weight();
283 }
284
285 void set(CellID iCell, bool state, bool overlap) override
286 {
288 //if constexpr (!std::is_same_v<DYNAMICS,NoDynamics<T,DESCRIPTOR>>) {
289 if (!overlap) {
290 _mask->set(iCell, state);
291 }
292 //}
293 if (state) {
294 _dynamicsOfCells[iCell] = _concreteDynamics.get();
295 }
296 _modified = true;
297 }
298
300 {
301 return _dynamics.get();
302 }
303
305 {
306 _parameters = &block.template getData<OperatorParameters<DYNAMICS>>().parameters;
307 _mask = &block.template getData<DynamicsMask<DYNAMICS>>();
308 if constexpr (dynamics::has_parametrized_momenta_v<DYNAMICS>) {
309 _dynamics->setMomentaParameters(_parameters);
310 }
311
312 _concreteDynamics.reset(new cpu::sisd::ConcreteDynamics<T,DESCRIPTOR,DYNAMICS>(_parameters));
313 // Fetch pointer to concretized dynamic-dispatch field
314 _dynamicsOfCells = block.template getField<cpu::DYNAMICS<T,DESCRIPTOR,Platform::CPU_SISD>>()[0].data();
315 }
316
318
323 CollisionDispatchStrategy strategy) override
324 {
325 switch (strategy) {
327 return applyDominant(block, subdomain);
329 return applyIndividual(block, subdomain);
330 default:
331 throw std::runtime_error("Invalid collision dispatch strategy");
332 }
333 }
334
335};
336
337
339template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
341 : public BlockO<T,DESCRIPTOR,Platform::CPU_SISD> {
342private:
343 std::vector<CellID> _cells;
344 bool _modified;
345
346public:
347 std::type_index id() const override
348 {
349 return typeid(OPERATOR);
350 }
351
352 std::size_t weight() const override
353 {
354 return _cells.size();
355 }
356
357 void set(CellID iCell, bool state) override
358 {
359 if (state) {
360 _cells.emplace_back(iCell);
361 _modified = true;
362 }
363 }
364
367
369 {
370 if (_modified) {
371 std::sort(_cells.begin(), _cells.end());
372 _cells.erase(std::unique(_cells.begin(), _cells.end()), _cells.end());
373 _modified = false;
374 }
375 if (_cells.size() > 0) {
377 #ifdef PARALLEL_MODE_OMP
378 #pragma omp parallel for schedule(static) firstprivate(cell)
379 #endif
380 for (CellID iCell : _cells) {
381 cell.setCellId(iCell);
382 OPERATOR().apply(cell);
383 }
384 }
385 }
386
387};
388
389
390template <typename T, typename DESCRIPTOR, concepts::CellOperator OPERATOR>
392 : public BlockO<T,DESCRIPTOR,Platform::CPU_SISD> {
393private:
394 std::vector<CellID> _cells;
395 bool _modified;
396
398
399public:
400 std::type_index id() const override
401 {
402 return typeid(OPERATOR);
403 }
404
405 std::size_t weight() const override
406 {
407 return _cells.size();
408 }
409
410 void set(CellID iCell, bool state) override
411 {
412 if (state) {
413 _cells.emplace_back(iCell);
414 _modified = true;
415 }
416 }
417
419 {
420 _parameters = &block.template getData<OperatorParameters<OPERATOR>>().parameters;
421 }
422
424 {
425 if (_modified) {
426 std::sort(_cells.begin(), _cells.end());
427 _cells.erase(std::unique(_cells.begin(), _cells.end()), _cells.end());
428 _modified = false;
429 }
430 if (_cells.size() > 0) {
432 #ifdef PARALLEL_MODE_OMP
433 #pragma omp parallel for schedule(static) firstprivate(cell)
434 #endif
435 for (CellID iCell : _cells) {
436 cell.setCellId(iCell);
437 OPERATOR().apply(cell, *_parameters);
438 }
439 }
440 }
441
442};
443
444
446
449template <typename T, typename DESCRIPTOR, concepts::BlockOperator OPERATOR>
451 : public BlockO<T,DESCRIPTOR,Platform::CPU_SISD> {
452public:
453 std::type_index id() const override
454 {
455 return typeid(OPERATOR);
456 }
457
458 std::size_t weight() const override
459 {
460 return 0;
461 }
462
463 void set(CellID iCell, bool state) override
464 {
465 throw std::logic_error("BlockO::set not supported for OperatorScope::PerBlock");
466 }
467
469 {
470 OPERATOR().setup(block);
471 }
472
474 {
475 OPERATOR().apply(block);
476 }
477
478};
479
480}
481
482#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.
int getNy() const
Read only access to block height.
int getNx() const
Read only access to block width.
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
int getNz() const
Read only access to block height.
void set(CellID iCell, bool state, bool overlap) override
Set whether iCell is covered by the present collision step.
Definition operator.h:285
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:304
std::size_t weight() const override
Returns number of assigned cells.
Definition operator.h:280
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block, ConcreteBlockMask< T, Platform::CPU_SISD > &subdomain, CollisionDispatchStrategy strategy) override
Apply collision on subdomain of block.
Definition operator.h:321
Collision operation of concrete DYNAMICS on concrete block lattices of PLATFORM.
Definition operator.h:104
Implementation of BlockLattice on a concrete PLATFORM.
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:418
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:410
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:423
std::size_t weight() const override
Get number of cells covered by operator (optional)
Definition operator.h:405
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:463
std::size_t weight() const override
Get number of cells covered by operator (optional)
Definition operator.h:458
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:468
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:473
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:357
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:368
std::size_t weight() const override
Get number of cells covered by operator (optional)
Definition operator.h:352
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:365
Block application of concrete OPERATOR called using SCOPE on PLATFORM.
Definition operator.h:58
Cell concept for concrete block lattices on CPU platforms.
Definition cell.h:141
void setCellId(CellID iCell)
Definition cell.h:162
Implementation of cpu::Dynamics for concrete DYNAMICS on SISD blocks.
Definition operator.h:46
void defineU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T *u) override
Definition operator.h:95
void defineAllMomenta(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho, T *u, T *pi) override
Definition operator.h:103
void computeEquilibrium(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T rho, T *u, T *fEq) override
Definition operator.h:87
void computeStress(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho, T *u, T *pi) override
Definition operator.h:71
T computeRho(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell) override
Definition operator.h:59
ConcreteDynamics(ParametersOfOperatorD< T, DESCRIPTOR, DYNAMICS > *parameters)
Definition operator.h:51
CellStatistic< T > collide(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell) override
Definition operator.h:55
void inverseShiftRhoU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho, T *u) override
Definition operator.h:107
void defineRhoU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho, T *u) override
Definition operator.h:99
T getOmegaOrFallback(T fallback) override
Definition operator.h:78
void computeU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T *u) override
Definition operator.h:62
void computeRhoU(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho, T *u) override
Definition operator.h:68
void defineRho(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho) override
Definition operator.h:91
void computeJ(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T *j) override
Definition operator.h:65
void computeAllMomenta(cpu::Cell< T, DESCRIPTOR, Platform::CPU_SISD > &cell, T &rho, T *u, T *pi) override
Definition operator.h:74
Interface for post-processing steps – header file.
Top level namespace for all of OpenLB.
std::uint32_t CellID
Type for sequential block-local cell indices.
Platform
OpenLB execution targets.
Definition platform.h:35
CollisionDispatchStrategy
Collision dispatch strategy.
Definition operator.h:81
@ Individual
Apply all dynamics individually (async for Platform::GPU_CUDA)
@ 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
CPU specific field mirroring BlockDynamicsMap.
Definition cell.h:134
Virtual interface for dynamically-dispatched dynamics access on CPU targets.
Definition cell.h:42
virtual CellStatistic< T > collide(Cell< T, DESCRIPTOR, PLATFORM > &cell)=0