OpenLB 1.7
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().apply(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 T computeEquilibrium(int iPop, T rho, T* u) override {
88 return DYNAMICS().computeEquilibrium(iPop, rho, u);
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 #ifdef PARALLEL_MODE_OMP
155 #pragma omp parallel for schedule(dynamic,1) reduction(+ : statistics)
156 #endif
157 for (int iX=0; iX < block.getNx(); ++iX) {
158 for (int iY=0; iY < block.getNy(); ++iY) {
159 std::size_t iCell = block.getCellId(iX,iY,0);
160 for (int iZ=0; iZ < block.getNz(); ++iZ) {
162 if (auto cellStatistic = mask[iCell] ? DYNAMICS().apply(cell, parameters)
163 : _dynamicsOfCells[iCell]->collide(cell)) {
164 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
165 }
166 iCell += 1;
167 }
168 }
169 }
170 } else {
171 #ifdef PARALLEL_MODE_OMP
172 #pragma omp parallel for schedule(dynamic,1) reduction(+ : statistics)
173 #endif
174 for (int iX=0; iX < block.getNx(); ++iX) {
175 std::size_t iCell = block.getCellId(iX,0);
176 for (int iY=0; iY < block.getNy(); ++iY) {
178 if (auto cellStatistic = mask[iCell] ? DYNAMICS().apply(cell, parameters)
179 : _dynamicsOfCells[iCell]->collide(cell)) {
180 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
181 }
182 iCell += 1;
183 }
184 }
185 }
186
187 block.getStatistics().incrementStats(statistics);
188 }
189
193 {
194 // Update cell list from mask
195 if (_modified) {
196 _cells.clear();
197 for (CellID iCell=0; iCell < block.getNcells(); ++iCell) {
198 if (_mask->operator[](iCell)) {
199 _cells.push_back(iCell);
200 }
201 }
202 _modified = false;
203 }
204
205 auto& parameters = *_parameters;
206 typename LatticeStatistics<T>::Aggregatable statistics{};
207
208 #ifdef PARALLEL_MODE_OMP
209 #pragma omp declare reduction(+ : typename LatticeStatistics<T>::Aggregatable : omp_out += omp_in) initializer (omp_priv={})
210 #endif
211
212 #ifdef PARALLEL_MODE_OMP
213 #pragma omp parallel for schedule(static) reduction(+ : statistics)
214 #endif
215 for (std::size_t i=0; i < _cells.size(); ++i) {
216 std::size_t iCell = _cells[i];
218 if (auto cellStatistic = DYNAMICS().apply(cell, parameters)) {
219 statistics.increment(cellStatistic.rho, cellStatistic.uSqr);
220 }
221 }
222
223 block.getStatistics().incrementStats(statistics);
224 }
225
226public:
228 _dynamics(new DYNAMICS()),
229 _parameters(nullptr),
230 _mask(nullptr),
231 _cells(0),
232 _modified(true)
233 { }
234
235 std::type_index id() const override
236 {
237 return typeid(DYNAMICS);
238 }
239
240 std::size_t weight() const override
241 {
242 return _mask->weight();
243 }
244
245 void set(CellID iCell, bool state, bool overlap) override
246 {
248 if constexpr (!std::is_same_v<DYNAMICS,NoDynamics<T,DESCRIPTOR>>) {
249 if (!overlap) {
250 _mask->set(iCell, state);
251 }
252 }
253 if (state) {
254 _dynamicsOfCells[iCell] = _concreteDynamics.get();
255 }
256 _modified = true;
257 }
258
260 {
261 return _dynamics.get();
262 }
263
265 {
266 _parameters = &block.template getData<OperatorParameters<DYNAMICS>>().parameters;
267 _mask = &block.template getData<DynamicsMask<DYNAMICS>>();
268 if constexpr (dynamics::has_parametrized_momenta_v<DYNAMICS>) {
269 _dynamics->setMomentaParameters(_parameters);
270 }
271
272 _concreteDynamics.reset(new cpu::sisd::ConcreteDynamics<T,DESCRIPTOR,DYNAMICS>(_parameters));
273 // Fetch pointer to concretized dynamic-dispatch field
274 _dynamicsOfCells = block.template getField<cpu::DYNAMICS<T,DESCRIPTOR,Platform::CPU_SISD>>()[0].data();
275 }
276
278
283 CollisionDispatchStrategy strategy) override
284 {
285 switch (strategy) {
287 return applyDominant(block, subdomain);
289 return applyIndividual(block, subdomain);
290 default:
291 throw std::runtime_error("Invalid collision dispatch strategy");
292 }
293 }
294
295};
296
297
299template <typename T, typename DESCRIPTOR, CONCEPT(CellOperator) OPERATOR>
300class ConcreteBlockO<T,DESCRIPTOR,Platform::CPU_SISD,OPERATOR,OperatorScope::PerCell> final
301 : public BlockO<T,DESCRIPTOR,Platform::CPU_SISD> {
302private:
303 std::vector<CellID> _cells;
304 bool _modified;
305
306public:
307 std::type_index id() const override
308 {
309 return typeid(OPERATOR);
310 }
311
312 void set(CellID iCell, bool state) override
313 {
314 if (state) {
315 _cells.emplace_back(iCell);
316 _modified = true;
317 }
318 }
319
322
324 {
325 if (_modified) {
326 std::sort(_cells.begin(), _cells.end());
327 _cells.erase(std::unique(_cells.begin(), _cells.end()), _cells.end());
328 _modified = false;
329 }
330 if (_cells.size() > 0) {
332 #ifdef PARALLEL_MODE_OMP
333 #pragma omp parallel for schedule(static) firstprivate(cell)
334 #endif
335 for (CellID iCell : _cells) {
336 cell.setCellId(iCell);
337 OPERATOR().apply(cell);
338 }
339 }
340 }
341
342};
343
344
345template <typename T, typename DESCRIPTOR, CONCEPT(CellOperator) OPERATOR>
347 : public BlockO<T,DESCRIPTOR,Platform::CPU_SISD> {
348private:
349 std::vector<CellID> _cells;
350 bool _modified;
351
353
354public:
355 std::type_index id() const override
356 {
357 return typeid(OPERATOR);
358 }
359
360 void set(CellID iCell, bool state) override
361 {
362 if (state) {
363 _cells.emplace_back(iCell);
364 _modified = true;
365 }
366 }
367
369 {
370 _parameters = &block.template getData<OperatorParameters<OPERATOR>>().parameters;
371 }
372
374 {
375 if (_modified) {
376 std::sort(_cells.begin(), _cells.end());
377 _cells.erase(std::unique(_cells.begin(), _cells.end()), _cells.end());
378 _modified = false;
379 }
380 if (_cells.size() > 0) {
382 #ifdef PARALLEL_MODE_OMP
383 #pragma omp parallel for schedule(static) firstprivate(cell)
384 #endif
385 for (CellID iCell : _cells) {
386 cell.setCellId(iCell);
387 OPERATOR().apply(cell, *_parameters);
388 }
389 }
390 }
391
392};
393
394
396
399template <typename T, typename DESCRIPTOR, CONCEPT(BlockOperator) OPERATOR>
400class ConcreteBlockO<T,DESCRIPTOR,Platform::CPU_SISD,OPERATOR,OperatorScope::PerBlock> final
401 : public BlockO<T,DESCRIPTOR,Platform::CPU_SISD> {
402public:
403 std::type_index id() const override
404 {
405 return typeid(OPERATOR);
406 }
407
408 void set(CellID iCell, bool state) override
409 {
410 throw std::logic_error("BlockO::set not supported for OperatorScope::PerBlock");
411 }
412
414 {
415 OPERATOR().setup(block);
416 }
417
419 {
420 OPERATOR().apply(block);
421 }
422
423};
424
425}
426
427#endif
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:245
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:264
std::size_t weight() const override
Returns number of assigned cells.
Definition operator.h:240
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:281
Collision operation of concrete DYNAMICS on concrete block lattices of PLATFORM.
Implementation of BlockLattice on a concrete PLATFORM.
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:368
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:360
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:373
void set(CellID iCell, bool state) override
Set whether iCell is covered by the operator (optional)
Definition operator.h:408
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:413
void apply(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:312
void apply(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:323
void setup(ConcreteBlockLattice< T, DESCRIPTOR, Platform::CPU_SISD > &block) override
Definition operator.h:320
Block application of concrete OPERATOR called using SCOPE on PLATFORM.
Definition operator.h:65
Cell concept for concrete block lattices on CPU platforms.
Definition cell.h:87
void setCellId(std::size_t iCell)
Definition cell.h:108
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 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
T computeEquilibrium(int iPop, T rho, T *u) override
Definition operator.h:87
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:36
CollisionDispatchStrategy
Collision dispatch strategy.
Definition operator.h:88
@ 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:97
Base of block-wide operators such as post processors.
Definition operator.h:41
Return value of any collision.
Definition interface.h:43
Interface for per-cell dynamics.
Definition interface.h:54
CPU specific field mirroring BlockDynamicsMap.
Definition cell.h:80
Virtual interface for dynamically-dispatched dynamics access on CPU targets.
Definition cell.h:39
virtual CellStatistic< T > collide(Cell< T, DESCRIPTOR, PLATFORM > &cell)=0