deal.II version GIT relicensing-2076-g6b43d56a25 2024-11-02 12:30:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
property_pool.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_particles_property_pool_h
16#define dealii_particles_property_pool_h
17
18#include <deal.II/base/config.h>
19
21#include <deal.II/base/point.h>
22
23
25
26namespace types
27{
28 /* Type definitions */
29
30#ifdef DEAL_II_WITH_64BIT_INDICES
42 using particle_index = std::uint64_t;
43
44# ifdef DEAL_II_WITH_MPI
49# define DEAL_II_PARTICLE_INDEX_MPI_TYPE MPI_UINT64_T
50# endif
51
52#else
64 using particle_index = unsigned int;
65
66# ifdef DEAL_II_WITH_MPI
71# define DEAL_II_PARTICLE_INDEX_MPI_TYPE MPI_UNSIGNED
72# endif
73#endif
74} // namespace types
75
76namespace Particles
77{
100 template <int dim, int spacedim = dim>
102 {
103 public:
109 using Handle = unsigned int;
110
114 static const Handle invalid_handle;
115
119 PropertyPool(const unsigned int n_properties_per_slot);
120
127
134 void
135 clear();
136
142 Handle
144
149 void
151
156 const Point<spacedim> &
157 get_location(const Handle handle) const;
158
164 get_location(const Handle handle);
165
169 void
171
176 const Point<dim> &
177 get_reference_location(const Handle handle) const;
178
183 void
186
192 get_id(const Handle handle) const;
193
198 void
200
206 get_properties(const Handle handle)
207 {
208 // The implementation is up here inside the class declaration because
209 // NVCC (at least in 12.5 and 12.6) otherwise produce a compile error:
210 //
211 // error: no declaration matches ‘::ArrayView<__remove_cv(const
212 // double)> ::Particles::PropertyPool<dim,
213 // spacedim>::get_properties(Handle)’
214 //
215 // See https://github.com/dealii/dealii/issues/17148
216
217 const std::vector<double>::size_type data_index =
218 (handle != invalid_handle) ? handle * n_properties : 0;
219
220 // Ideally we would need to assert that 'handle' has not been deallocated
221 // by searching through 'currently_available_handles'. However, this
222 // is expensive and this function is performance critical, so instead
223 // just check against the array range, and rely on the fact
224 // that handles are invalidated when handed over to
225 // deallocate_properties_array().
226 Assert(data_index <= properties.size() - n_properties,
228 "Invalid property handle. This can happen if the "
229 "handle was duplicated and then one copy was deallocated "
230 "before trying to access the properties."));
231
232 return ArrayView<double>(properties.data() + data_index, n_properties);
233 }
234
235
240 void
241 reserve(const std::size_t size);
242
246 unsigned int
247 n_properties_per_slot() const;
248
253 unsigned int
254 n_slots() const;
255
259 unsigned int
260 n_registered_slots() const;
261
270 void
271 sort_memory_slots(const std::vector<Handle> &handles_to_sort);
272
273 private:
277 const unsigned int n_properties;
278
284 std::vector<Point<spacedim>> locations;
285
291 std::vector<Point<dim>> reference_locations;
292
298 std::vector<types::particle_index> ids;
299
305 std::vector<double> properties;
306
314 std::vector<Handle> currently_available_handles;
315 };
316
317
318
319 /* ---------------------- inline and template functions ------------------ */
320
321 template <int dim, int spacedim>
322 inline const Point<spacedim> &
324 {
325 const std::vector<double>::size_type data_index =
326 (handle != invalid_handle) ? handle : 0;
327
328 // Ideally we would need to assert that 'handle' has not been deallocated
329 // by searching through 'currently_available_handles'. However, this
330 // is expensive and this function is performance critical, so instead
331 // just check against the array range, and rely on the fact
332 // that handles are invalidated when handed over to
333 // deallocate_properties_array().
334 Assert(data_index <= locations.size() - 1,
335 ExcMessage("Invalid location handle. This can happen if the "
336 "handle was duplicated and then one copy was deallocated "
337 "before trying to access the properties."));
338
339 return locations[data_index];
340 }
341
342
343
344 template <int dim, int spacedim>
345 inline Point<spacedim> &
347 {
348 const std::vector<double>::size_type data_index =
349 (handle != invalid_handle) ? handle : 0;
350
351 // Ideally we would need to assert that 'handle' has not been deallocated
352 // by searching through 'currently_available_handles'. However, this
353 // is expensive and this function is performance critical, so instead
354 // just check against the array range, and rely on the fact
355 // that handles are invalidated when handed over to
356 // deallocate_properties_array().
357 Assert(data_index <= locations.size() - 1,
358 ExcMessage("Invalid location handle. This can happen if the "
359 "handle was duplicated and then one copy was deallocated "
360 "before trying to access the properties."));
361
362 return locations[data_index];
363 }
364
365
366
367 template <int dim, int spacedim>
368 inline void
371 {
372 const std::vector<double>::size_type data_index =
373 (handle != invalid_handle) ? handle : 0;
374
375 // Ideally we would need to assert that 'handle' has not been deallocated
376 // by searching through 'currently_available_handles'. However, this
377 // is expensive and this function is performance critical, so instead
378 // just check against the array range, and rely on the fact
379 // that handles are invalidated when handed over to
380 // deallocate_properties_array().
381 Assert(data_index <= locations.size() - 1,
382 ExcMessage("Invalid location handle. This can happen if the "
383 "handle was duplicated and then one copy was deallocated "
384 "before trying to access the properties."));
385
386 locations[data_index] = new_location;
387 }
388
389
390
391 template <int dim, int spacedim>
392 inline const Point<dim> &
394 {
395 const std::vector<double>::size_type data_index =
396 (handle != invalid_handle) ? handle : 0;
397
398 // Ideally we would need to assert that 'handle' has not been deallocated
399 // by searching through 'currently_available_handles'. However, this
400 // is expensive and this function is performance critical, so instead
401 // just check against the array range, and rely on the fact
402 // that handles are invalidated when handed over to
403 // deallocate_properties_array().
404 Assert(data_index <= reference_locations.size() - 1,
405 ExcMessage("Invalid location handle. This can happen if the "
406 "handle was duplicated and then one copy was deallocated "
407 "before trying to access the properties."));
408
409 return reference_locations[data_index];
410 }
411
412
413
414 template <int dim, int spacedim>
415 inline void
417 const Handle handle,
419 {
420 const std::vector<double>::size_type data_index =
421 (handle != invalid_handle) ? handle : 0;
422
423 // Ideally we would need to assert that 'handle' has not been deallocated
424 // by searching through 'currently_available_handles'. However, this
425 // is expensive and this function is performance critical, so instead
426 // just check against the array range, and rely on the fact
427 // that handles are invalidated when handed over to
428 // deallocate_properties_array().
429 Assert(data_index <= reference_locations.size() - 1,
430 ExcMessage("Invalid location handle. This can happen if the "
431 "handle was duplicated and then one copy was deallocated "
432 "before trying to access the properties."));
433
434 reference_locations[data_index] = new_reference_location;
435 }
436
437
438
439 template <int dim, int spacedim>
442 {
443 const std::vector<double>::size_type data_index =
444 (handle != invalid_handle) ? handle : 0;
445
446 // Ideally we would need to assert that 'handle' has not been deallocated
447 // by searching through 'currently_available_handles'. However, this
448 // is expensive and this function is performance critical, so instead
449 // just check against the array range, and rely on the fact
450 // that handles are invalidated when handed over to
451 // deallocate_properties_array().
452 Assert(data_index <= ids.size() - 1,
453 ExcMessage("Invalid location handle. This can happen if the "
454 "handle was duplicated and then one copy was deallocated "
455 "before trying to access the properties."));
456
457 return ids[data_index];
458 }
459
460
461
462 template <int dim, int spacedim>
463 inline void
466 {
467 const std::vector<double>::size_type data_index =
468 (handle != invalid_handle) ? handle : 0;
469
470 // Ideally we would need to assert that 'handle' has not been deallocated
471 // by searching through 'currently_available_handles'. However, this
472 // is expensive and this function is performance critical, so instead
473 // just check against the array range, and rely on the fact
474 // that handles are invalidated when handed over to
475 // deallocate_properties_array().
476 Assert(data_index <= ids.size() - 1,
477 ExcMessage("Invalid location handle. This can happen if the "
478 "handle was duplicated and then one copy was deallocated "
479 "before trying to access the properties."));
480
481 ids[data_index] = new_id;
482 }
483
484
485
486 // template <int dim, int spacedim>
487 // inline ArrayView<double, ::MemorySpace::Host>
488 // PropertyPool<dim, spacedim>::get_properties(const Handle handle)
489
490
491
492 template <int dim, int spacedim>
493 inline unsigned int
495 {
496 return locations.size();
497 }
498
499
500} // namespace Particles
501
503
504#endif
const Point< spacedim > & get_location(const Handle handle) const
std::vector< Point< dim > > reference_locations
unsigned int n_properties_per_slot() const
unsigned int n_registered_slots() const
unsigned int n_slots() const
const unsigned int n_properties
void deregister_particle(Handle &handle)
void set_id(const Handle handle, const types::particle_index &new_id)
types::particle_index get_id(const Handle handle) const
void set_reference_location(const Handle handle, const Point< dim > &new_reference_location)
void reserve(const std::size_t size)
void set_location(const Handle handle, const Point< spacedim > &new_location)
const Point< dim > & get_reference_location(const Handle handle) const
void sort_memory_slots(const std::vector< Handle > &handles_to_sort)
Point< spacedim > & get_location(const Handle handle)
std::vector< Point< spacedim > > locations
std::vector< types::particle_index > ids
ArrayView< double, ::MemorySpace::Host > get_properties(const Handle handle)
static const Handle invalid_handle
std::vector< Handle > currently_available_handles
std::vector< double > properties
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
Definition types.h:32
unsigned int particle_index