OpenLB 1.8.1
Loading...
Searching...
No Matches
blockD.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2024 Adrian Kummerlaender
4 *
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25#ifndef BLOCK_D_H
26#define BLOCK_D_H
27
28namespace olb {
29
30template<typename T, typename DESCRIPTOR> class BlockD;
31template<typename T, typename DESCRIPTOR, Platform PLATFORM> class ConcreteBlockD;
32
34template<typename T, typename DESCRIPTOR>
36
37using value_t = T;
38using descriptor_t = DESCRIPTOR;
40
41template <Platform PLATFORM>
43
44};
45
46template<typename T, typename DESCRIPTOR>
48private:
49 BlockD<T,DESCRIPTOR>& _lattice;
50 std::size_t _iRow;
51
52public:
54 std::size_t iRow):
55 _lattice(lattice),
56 _iRow(iRow) { }
57
58 template<typename FIELD>
59 auto getField() const {
60 return _lattice.template getField<FIELD>().get(_iRow);
61 }
62
63 template<typename FIELD>
64 void setField(const FieldD<T,DESCRIPTOR,FIELD>& data) const {
65 _lattice.template getField<FIELD>().set(_iRow, data);
66 }
67
68};
69
70template <typename OPERATOR>
72
73template <typename OPERATOR>
74requires (OPERATOR::scope == OperatorScope::PerCell)
76 static constexpr OperatorScope scope = OperatorScope::PerBlock;
77
78 template <typename BLOCK>
79 void apply(BLOCK& block) {
80 for (std::size_t iCell=0; iCell < block.getNcells(); ++iCell) {
81 cpu::PlainCell<typename BLOCK::value_t,
82 typename BLOCK::descriptor_t,
83 BLOCK::platform>
84 cell(block, iCell);
85 OPERATOR{}.apply(cell);
86 }
87 }
88};
89
90template <typename OPERATOR>
91requires (OPERATOR::scope == OperatorScope::PerCellWithParameters)
93 static constexpr OperatorScope scope = OperatorScope::PerBlock;
94
95 template <typename BLOCK>
96 void apply(BLOCK& block) {
97 auto params = block.template getData<OperatorParameters<OPERATOR>>()
98 .parameters
99 .template copyAs<typename BLOCK::value_t>();
100 for (std::size_t iCell=0; iCell < block.getNcells(); ++iCell) {
101 cpu::PlainCell<typename BLOCK::value_t,
102 typename BLOCK::descriptor_t,
103 BLOCK::platform>
104 cell(block, iCell);
105 OPERATOR{}.apply(cell, params);
106 }
107 }
108};
109
110template<typename T, typename DESCRIPTOR>
111class BlockD : public BlockStructure<DESCRIPTOR>
112 , public Serializable {
113protected:
115
117 template<typename F>
118 auto dispatch(F&& f) const {
120 _platform,
121 this,
122 f);
123 }
124 template<typename F>
125 auto dispatch(F&& f) {
127 _platform,
128 this,
129 f);
130 }
131
132public:
133 BlockD(Vector<int,DESCRIPTOR::d> size, int padding, Platform platform);
134 virtual ~BlockD();
135
137
142
143 virtual void resize(Vector<int,DESCRIPTOR::d> size) = 0;
144
147 return _platform;
148 }
149
150 template <Platform PLATFORM>
152 if (auto* ptr = dynamic_cast<ConcreteBlockD<T,DESCRIPTOR,PLATFORM>*>(this)) [[likely]] {
153 return *ptr;
154 } else {
155 throw std::runtime_error("Invalid PLATFORM");
156 }
157 }
158
160 template<typename FIELD_TYPE>
161 bool hasData() {
162 return dispatch([&](const auto* lattice) -> bool {
163 return lattice->template hasData<FIELD_TYPE>();
164 });
165 }
166
168 template<typename FIELD_TYPE>
169 const auto& getData(FIELD_TYPE field = FIELD_TYPE{}) const
170 {
171 return *dispatch([&](const auto* lattice) -> const auto* {
172 return &(lattice->template getData<FIELD_TYPE>().asAbstract());
173 });
174 }
176 template<typename FIELD_TYPE>
177 auto& getData(FIELD_TYPE field = FIELD_TYPE{})
178 {
179 return *dispatch([&](auto* lattice) -> auto* {
180 return &(lattice->template getData<FIELD_TYPE>().asAbstract());
181 });
182 }
183
185 template<typename FIELD>
186 const auto& getField(FIELD field = FIELD{}) const
187 {
188 return getData(Array<FIELD>{});
189 }
191 template<typename FIELD>
193 {
194 return getField<FIELD>().get(this->getCellId(loc));
195 }
196
198 template<typename FIELD>
199 auto& getField(FIELD field = FIELD{})
200 {
201 return getData(Array<FIELD>{});
202 }
204 template<typename FIELD>
206 {
207 getField<FIELD>().set(this->getCellId(loc), fieldD);
208 }
209
211 template <typename FIELD>
213 dispatch([&](auto* lattice) {
214 lattice->template setParameter<FIELD>(value);
215 });
216 }
217 template <typename PARAMETER, typename FIELD>
219 dispatch([&](auto* lattice) {
220 lattice->template setParameter<PARAMETER>(fieldArray);
221 });
222 }
223 template <typename PARAMETER, Platform PLATFORM, typename FIELD>
225 dispatch([&](auto* lattice) {
226 lattice->template setParameter<PARAMETER>(fieldArray);
227 });
228 }
229
231 return {*this, iCell};
232 }
233
234 template <typename OPERATOR>
235 void apply() {
236 dispatch([&](auto* lattice) {
237 lattice->template apply<OPERATOR>();
238 });
239 }
240
241 virtual bool hasCommunicatable(std::type_index) const = 0;
242 virtual Communicatable& getCommunicatable(std::type_index) = 0;
243
244};
245
247template<typename T, typename DESCRIPTOR, Platform PLATFORM>
248class ConcreteBlockD final : public BlockD<T,DESCRIPTOR> {
249private:
255 std::map<std::type_index, std::unique_ptr<Communicatable>> _communicatables;
256
257public:
258 using value_t = T;
259 using descriptor_t = DESCRIPTOR;
260
261 static constexpr Platform platform = PLATFORM;
262
263 ConcreteBlockD(Vector<int,DESCRIPTOR::d> size, int padding=0);
264
266 _data.setProcessingContext(context);
267 }
268
269 void resize(Vector<int,DESCRIPTOR::d> size) override;
270
271 template<typename FIELD_TYPE>
272 bool hasData() const;
273 template<typename FIELD_TYPE>
274 const auto& getData() const;
275 template<typename FIELD_TYPE>
276 auto& getData();
277
278 template<typename FIELD>
279 const auto& getField(FIELD field = FIELD()) const;
280 template<typename FIELD>
281 auto& getField(FIELD field = FIELD());
282
283 bool hasCommunicatable(std::type_index field) const override {
284 return _communicatables.find(field) != _communicatables.end();
285 }
286 Communicatable& getCommunicatable(std::type_index field) override {
287 return *_communicatables.at(field).get();
288 }
289
290 template <typename FIELD>
292 {
293 _data.template forEachCastable<AbstractedConcreteParameters<T,DESCRIPTOR>>([&](auto* parameters) {
294 auto& params = parameters->asAbstract();
295 if (params.template provides<FIELD>()) {
296 params.template set<FIELD>(value);
297 parameters->setProcessingContext(ProcessingContext::Simulation);
298 }
299 });
300 }
301
302 template <typename PARAMETER, Platform _PLATFORM, typename FIELD>
304 {
305 if constexpr (PLATFORM == Platform::GPU_CUDA) {
306 static_assert(PLATFORM == _PLATFORM, "FieldArrayD must be available on PLATFORM");
307 }
308 FieldD<T,DESCRIPTOR,PARAMETER> fieldArrayPointers;
309 for (unsigned iD=0; iD < fieldArray.d; ++iD) {
310 if constexpr (PLATFORM == Platform::GPU_CUDA) {
311 fieldArrayPointers[iD] = fieldArray[iD].deviceData();
312 } else {
313 fieldArrayPointers[iD] = fieldArray[iD].data();
314 }
315 }
316 setParameter<PARAMETER>(std::move(fieldArrayPointers));
317 }
318
319 template <typename PARAMETER, typename FIELD>
321 {
322 auto& fieldArray = dynamic_cast<FieldArrayD<T,DESCRIPTOR,PLATFORM,FIELD>&>(abstractFieldArray);
323 setParameter<PARAMETER>(fieldArray);
324 }
325
327
331 return _data.getRegistry();
332 }
333
334 template <typename OPERATOR>
335 void apply() {
336 static_assert(OPERATOR::scope == OperatorScope::PerBlock,
337 "OPERATOR is not PerBlock scoped");
338 OPERATOR{}.apply(*this);
339 }
340
342 std::size_t getNblock() const override;
344 std::size_t getSerializableSize() const override;
346 bool* getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) override;
348 void postLoad() override;
349
350};
351
352
354
357template <typename T, typename DESCRIPTOR, typename... ARGS>
358std::unique_ptr<BlockD<T,DESCRIPTOR>> makeSharedBlockD(
359 LoadBalancer<T>& loadBalancer, ARGS&&... args)
360{
361 #if defined(PLATFORM_GPU_CUDA)
362 if (loadBalancer.isLocal(Platform::GPU_CUDA)) {
363 return std::unique_ptr<BlockD<T,DESCRIPTOR>>(
364 new ConcreteBlockD<T,DESCRIPTOR,Platform::GPU_CUDA>(std::forward<ARGS&&>(args)...));
365 } else {
366 return std::unique_ptr<BlockD<T,DESCRIPTOR>>(
367 new ConcreteBlockD<T,DESCRIPTOR,Platform::CPU_SISD>(std::forward<ARGS&&>(args)...));
368 }
369 #else
370 return std::unique_ptr<BlockD<T,DESCRIPTOR>>(
371 new ConcreteBlockD<T,DESCRIPTOR,Platform::CPU_SISD>(std::forward<ARGS&&>(args)...));
372 #endif
373}
374
375}
376
377#endif
#define OPERATOR(OP, rhs)
Definition aDiffTape.h:64
Platform-agnostic interface to concrete host-side field arrays.
Definition fieldArrayD.h:49
const Platform _platform
Definition blockD.h:114
bool hasData()
Return whether FIELD_TYPE is available / has been allocated.
Definition blockD.h:161
BlockD(Vector< int, DESCRIPTOR::d > size, int padding, Platform platform)
Definition blockD.hh:33
void setField(LatticeR< DESCRIPTOR::d > loc, const FieldD< T, DESCRIPTOR, FIELD > &fieldD)
Set FIELD to fieldD at loc.
Definition blockD.h:205
virtual ~BlockD()
Definition blockD.hh:39
virtual void setProcessingContext(ProcessingContext)=0
Set processing context.
auto & getField(FIELD field=FIELD{})
Return abstract interface for FIELD array.
Definition blockD.h:199
void setParameter(FieldArrayD< T, DESCRIPTOR, PLATFORM, FIELD > &fieldArray)
Definition blockD.h:224
const auto & getField(FIELD field=FIELD{}) const
Return abstract interface for FIELD array.
Definition blockD.h:186
ConcreteBlockD< T, DESCRIPTOR, PLATFORM > & asConcrete()
Definition blockD.h:151
auto & getData(FIELD_TYPE field=FIELD_TYPE{})
Return abstract interface for concrete FIELD_TYPE data.
Definition blockD.h:177
BlockLatticeRowView< T, DESCRIPTOR > get(std::size_t iCell)
Definition blockD.h:230
auto dispatch(F &&f) const
Calls f on concrete implementation of the BlockD interface.
Definition blockD.h:118
void setParameter(AbstractFieldArrayD< T, DESCRIPTOR, FIELD > &fieldArray)
Definition blockD.h:218
Platform getPlatform() const
Return platform used to process lattice.
Definition blockD.h:146
const auto & getData(FIELD_TYPE field=FIELD_TYPE{}) const
Return abstract interface for concrete FIELD_TYPE data.
Definition blockD.h:169
void apply()
Definition blockD.h:235
virtual void resize(Vector< int, DESCRIPTOR::d > size)=0
auto dispatch(F &&f)
Definition blockD.h:125
virtual bool hasCommunicatable(std::type_index) const =0
virtual Communicatable & getCommunicatable(std::type_index)=0
void setParameter(FieldD< T, DESCRIPTOR, FIELD > value)
Set value of parameter FIELD.
Definition blockD.h:212
auto getField(LatticeR< DESCRIPTOR::d > loc) const
Return value of FIELD at loc.
Definition blockD.h:192
BlockLatticeRowView(BlockD< T, DESCRIPTOR > &lattice, std::size_t iRow)
Definition blockD.h:53
void setField(const FieldD< T, DESCRIPTOR, FIELD > &data) const
Definition blockD.h:64
auto getField() const
Definition blockD.h:59
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
static constexpr unsigned d
Implementation of BlockD on a concrete PLATFORM.
Definition cell.h:32
const auto & getData() const
Definition blockD.hh:75
void resize(Vector< int, DESCRIPTOR::d > size) override
Definition blockD.hh:60
void setProcessingContext(ProcessingContext context) override
Set processing context.
Definition blockD.h:265
Communicatable & getCommunicatable(std::type_index field) override
Definition blockD.h:286
ConcreteBlockD(Vector< int, DESCRIPTOR::d > size, int padding=0)
Definition blockD.hh:43
bool hasCommunicatable(std::type_index field) const override
Definition blockD.h:283
void postLoad() override
Reinit population structure after deserialization.
Definition blockD.hh:154
void setParameter(FieldArrayD< T, DESCRIPTOR, _PLATFORM, FIELD > &fieldArray)
Definition blockD.h:303
bool hasData() const
Definition blockD.hh:68
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode) override
Return a pointer to the memory of the current block and its size for the serializable interface.
Definition blockD.hh:145
static constexpr Platform platform
Definition blockD.h:261
void setParameter(FieldD< T, DESCRIPTOR, FIELD > value)
Definition blockD.h:291
std::size_t getSerializableSize() const override
Binary size for the serializer.
Definition blockD.hh:139
std::size_t getNblock() const override
Number of data blocks for the serializable interface.
Definition blockD.hh:133
auto & getDataRegistry()
Return reference to Data's FieldTypeRegistry.
Definition blockD.h:330
DESCRIPTOR descriptor_t
Definition blockD.h:259
const auto & getField(FIELD field=FIELD()) const
Definition blockD.hh:122
void setParameter(AbstractFieldArrayD< T, DESCRIPTOR, FIELD > &abstractFieldArray)
Definition blockD.h:320
Storage of any FIELD_TYPE data on PLATFORM.
Definition data.h:424
void setProcessingContext(ProcessingContext context) override
Set processing context of all managed fields.
Definition data.h:507
auto & getRegistry()
Expose FieldTypeRegistry for device-support.
Definition data.h:514
SoA storage for instances of a single FIELD.
Base class for all LoadBalancer.
Definition vtiWriter.h:42
bool isLocal(const int &glob) const
returns whether glob is on this process
Plain old scalar vector.
Top level namespace for all of OpenLB.
auto callUsingConcretePlatform(Platform platform, typename CONCRETIZABLE::base_t *ptr, F f)
Dispatcher for concrete platform access.
Definition dispatch.h:41
ProcessingContext
OpenLB processing contexts.
Definition platform.h:54
@ Simulation
Data available on host for e.g. functor evaluation.
Platform
OpenLB execution targets.
Definition platform.h:35
@ GPU_CUDA
Vector CPU (AVX2 / AVX-512 collision)
BlockStructureD< DESCRIPTOR::d > BlockStructure
OperatorScope
Block-wide operator application scopes.
@ 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...
std::unique_ptr< BlockD< T, DESCRIPTOR > > makeSharedBlockD(LoadBalancer< T > &loadBalancer, ARGS &&... args)
Constructs BlockD accessible on all locally used platforms.
Definition blockD.h:358
Describe FieldArray of a FIELD in Data.
Definition data.h:50
void apply(BLOCK &block)
Definition blockD.h:79
Curried ConcreteBlockD eemplate for use in callUsingConcretePlatform.
Definition blockD.h:35
DESCRIPTOR descriptor_t
Definition blockD.h:38