OpenLB 1.7
Loading...
Searching...
No Matches
communicatable.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 COMMUNICATABLE_H
25#define COMMUNICATABLE_H
26
27#include <vector>
28#include <cstdint>
29#include <typeindex>
30
31#include "core/blockStructure.h"
32
33namespace olb {
34
35template <typename T>
36class ConstSpan {
37private:
38 const T* const _base;
39 const std::size_t _size;
40
41public:
42 ConstSpan(const T* base, std::size_t size):
43 _base(base), _size(size) { }
44
45 ConstSpan(const std::vector<T>& v):
46 ConstSpan{v.data(), v.size()} { }
47
48 const T* data() const {
49 return _base;
50 }
51
52 T operator[](std::size_t i) const {
53 return _base[i];
54 }
55
56 const T* begin() const {
57 return _base;
58 }
59 const T* end() const {
60 return _base + _size;
61 }
62
63 std::size_t size() const {
64 return _size;
65 }
66
67};
68
70 virtual ~Communicatable() { };
71
72 virtual std::size_t size(ConstSpan<CellID> indices) const = 0;
74
78 virtual std::size_t serialize(ConstSpan<CellID> indices,
79 std::uint8_t* buffer) const = 0;
81
85 virtual std::size_t deserialize(ConstSpan<CellID> indices,
86 const std::uint8_t* buffer) = 0;
87};
88
89template <typename COMMUNICATEE>
91private:
92 COMMUNICATEE& _communicatee;
93
94public:
95 ConcreteCommunicatable(COMMUNICATEE& communicatee):
96 _communicatee{communicatee} { }
97
99 std::size_t size(ConstSpan<CellID> indices) const override
100 {
101 return indices.size() * sizeof(typename COMMUNICATEE::value_type);
102 }
103
105 std::size_t serialize(ConstSpan<CellID> indices,
106 std::uint8_t* buffer) const override
107 {
108 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
109 auto* target = reinterpret_cast<typename COMMUNICATEE::value_type*>(buffer);
110 for (CellID index : indices) {
111 *(target++) = _communicatee[index];
112 }
113 } else {
114 std::uint8_t* target = buffer;
115 for (CellID index : indices) {
116 std::memcpy(target,
117 reinterpret_cast<const void*>(&_communicatee[index]),
118 sizeof(typename COMMUNICATEE::value_type));
119 target += sizeof(typename COMMUNICATEE::value_type);
120 }
121 }
122 return indices.size() * sizeof(typename COMMUNICATEE::value_type);
123 }
124
126 std::size_t deserialize(ConstSpan<CellID> indices,
127 const std::uint8_t* buffer) override
128 {
129 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
130 const auto* source = reinterpret_cast<const typename COMMUNICATEE::value_type*>(buffer);
131 for (CellID index : indices) {
132 _communicatee[index] = *(source++);
133 }
134 } else {
135 const std::uint8_t* source = buffer;
136 for (CellID index : indices) {
137 std::memcpy(reinterpret_cast<void*>(&_communicatee[index]),
138 source,
139 sizeof(typename COMMUNICATEE::value_type));
140 source += sizeof(typename COMMUNICATEE::value_type);
141 }
142 }
143 return indices.size() * sizeof(typename COMMUNICATEE::value_type);
144 }
145
153
155 std::size_t size() const
156 {
157 return std::tuple_size<COMMUNICATEE>::value * sizeof(typename COMMUNICATEE::value_type);
158 }
159
161 std::size_t serialize(std::uint8_t* buffer) const
162 {
163 std::size_t noI = std::tuple_size<COMMUNICATEE>::value;
164 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
165 auto* target = reinterpret_cast<typename COMMUNICATEE::value_type*>(buffer);
166 for (CellID index=0; index<noI; ++index) {
167 *(target++) = _communicatee[index];
168 }
169 } else {
170 std::uint8_t* target = buffer;
171 for (CellID index=0; index<noI; ++index) {
172 std::memcpy(target,
173 reinterpret_cast<const void*>(&_communicatee[index]),
174 sizeof(typename COMMUNICATEE::value_type));
175 target += sizeof(typename COMMUNICATEE::value_type);
176 }
177 }
178 return noI * sizeof(typename COMMUNICATEE::value_type);
179 }
180
182 std::size_t deserialize(const std::uint8_t* buffer)
183 {
184 std::size_t noI = std::tuple_size<COMMUNICATEE>::value;
185 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
186 const auto* source = reinterpret_cast<const typename COMMUNICATEE::value_type*>(buffer);
187 for (CellID index=0; index<noI; ++index) {
188 _communicatee[index] = *(source++);
189 }
190 } else {
191 const std::uint8_t* source = buffer;
192 for (CellID index=0; index<noI; ++index) {
193 std::memcpy(reinterpret_cast<void*>(&_communicatee[index]),
194 source,
195 sizeof(typename COMMUNICATEE::value_type));
196 source += sizeof(typename COMMUNICATEE::value_type);
197 }
198 }
199 return noI * sizeof(typename COMMUNICATEE::value_type);
200 }
201
202};
203
204template <typename COLUMN>
205class ConcreteCommunicatable<std::vector<COLUMN>> final : public Communicatable {
206private:
207 std::vector<COLUMN>& _vector;
208
209public:
210 ConcreteCommunicatable(std::vector<COLUMN>& vector):
211 _vector{vector} { }
212
214 std::size_t size(ConstSpan<CellID> indices) const
215 {
216 std::size_t size = 0;
217 for (unsigned iD=0; iD < _vector.size(); ++iD) {
218 size += ConcreteCommunicatable<COLUMN>(_vector[iD]).size(indices);
219 }
220 return size;
221 }
222
224 std::size_t serialize(ConstSpan<CellID> indices,
225 std::uint8_t* buffer) const
226 {
227 std::size_t size = ConcreteCommunicatable<COLUMN>(_vector[0]).size(indices);
228 std::uint8_t* curr = buffer;
229 #ifdef PARALLEL_MODE_OMP
230 #pragma omp parallel for schedule(static,1)
231 #endif
232 for (unsigned iD=0; iD < _vector.size(); ++iD) {
233 ConcreteCommunicatable<COLUMN>(_vector[iD]).serialize(indices, curr + iD*size);
234 }
235 return _vector.size() * size;
236 }
237
239 std::size_t deserialize(ConstSpan<CellID> indices,
240 const std::uint8_t* buffer)
241 {
242 std::size_t size = ConcreteCommunicatable<COLUMN>(_vector[0]).size(indices);
243 const std::uint8_t* curr = buffer;
244 #ifdef PARALLEL_MODE_OMP
245 #pragma omp parallel for schedule(static,1)
246 #endif
247 for (unsigned iD=0; iD < _vector.size(); ++iD) {
248 ConcreteCommunicatable<COLUMN>(_vector[iD]).deserialize(indices, curr + iD*size);
249 }
250 return _vector.size() * size;
251 }
252
253};
254
255template <typename COMMUNICATEE>
257private:
258 COMMUNICATEE& _communicatee;
259 const std::vector<std::type_index>& _fields;
260
261public:
262 MultiConcreteCommunicatable(COMMUNICATEE& communicatee,
263 const std::vector<std::type_index>& fields):
264 _communicatee{communicatee},
265 _fields{fields} { }
266
268 std::size_t size(ConstSpan<CellID> indices) const override
269 {
270 std::size_t size = 0;
271 for (auto& field : _fields) {
272 size += _communicatee.getCommunicatable(field).size(indices);
273 }
274 return size;
275 }
276
278 std::size_t serialize(ConstSpan<CellID> indices,
279 std::uint8_t* buffer) const override
280 {
281 std::uint8_t* curr = buffer;
282 for (auto& field : _fields) {
283 curr += _communicatee.getCommunicatable(field).serialize(indices, curr);
284 }
285 return curr - buffer;
286 }
287
289 std::size_t deserialize(ConstSpan<CellID> indices,
290 const std::uint8_t* buffer) override
291 {
292 const std::uint8_t* curr = buffer;
293 for (auto& field : _fields) {
294 curr += _communicatee.getCommunicatable(field).deserialize(indices, curr);
295 }
296 return curr - buffer;
297 }
298};
299
300
301
302}
303
304#endif
std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const
Serialize data at locations indices to buffer
ConcreteCommunicatable(std::vector< COLUMN > &vector)
std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer)
Deserialize data at locations indices to buffer
std::size_t size(ConstSpan< CellID > indices) const
Get serialized size for data at locations indices
std::size_t size() const
ADDITIONAL NON OVERWITTEN CALLS: Removing the necessity to provide indices.
std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer) override
Deserialize data at locations indices to buffer
std::size_t serialize(std::uint8_t *buffer) const
Serialize complete data.
std::size_t deserialize(const std::uint8_t *buffer)
Deserialize complete data.
std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const override
Serialize data at locations indices to buffer
ConcreteCommunicatable(COMMUNICATEE &communicatee)
std::size_t size(ConstSpan< CellID > indices) const override
Get serialized size for data at locations indices
const T * data() const
ConstSpan(const std::vector< T > &v)
T operator[](std::size_t i) const
ConstSpan(const T *base, std::size_t size)
const T * end() const
std::size_t size() const
const T * begin() const
std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const override
Serialize data at locations indices to buffer
MultiConcreteCommunicatable(COMMUNICATEE &communicatee, const std::vector< std::type_index > &fields)
std::size_t size(ConstSpan< CellID > indices) const override
Get serialized size for data at locations indices
std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer) override
Deserialize data at locations indices to buffer
Top level namespace for all of OpenLB.
std::uint32_t CellID
Type for sequential block-local cell indices.
virtual std::size_t size(ConstSpan< CellID > indices) const =0
virtual std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const =0
Serialize data at locations indices to buffer
virtual std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer)=0
Deserialize data at locations indices to buffer