deal.II version GIT relicensing-2017-g7ae82fad8b 2024-10-22 19:20: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
particle_accessor.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_particle_accessor_h
16#define dealii_particles_particle_accessor_h
17
18#include <deal.II/base/config.h>
19
21
22#include <deal.II/grid/tria.h>
24
27
29
30namespace Particles
31{
32 // Forward declarations
33#ifndef DOXYGEN
34 template <int, int>
35 class ParticleIterator;
36 template <int, int>
37 class ParticleHandler;
38#endif
39
43 template <int dim, int spacedim = dim>
45 {
46 public:
81 {
85 ParticlesInCell() = default;
86
97
101 std::vector<typename PropertyPool<dim, spacedim>::Handle> particles;
102
107 };
108
112 using particle_container = std::list<ParticlesInCell>;
113
117 void *
119
120
124 const void *
126
147 void
148 set_location(const Point<spacedim> &new_location);
149
155 const Point<spacedim> &
157
181
202 void
203 set_reference_location(const Point<dim> &new_reference_location);
204
208 const Point<dim> &
210
214 void
216
221 get_id() const;
222
243
248 bool
250
271 void
272 set_properties(const std::vector<double> &new_properties);
273
294 void
296
320 void
321 set_properties(const Tensor<1, dim> &new_properties);
322
330 {
331 // The implementation is up here inside the class declaration because
332 // NVCC (at least in 12.5 and 12.6) otherwise produce a compile error:
333 //
334 // error: no declaration matches ‘::ArrayView<__remove_cv(const
335 // double)> ::Particles::ParticleAccessor<dim,
336 // spacedim>::get_properties()’
337 //
338 // See https://github.com/dealii/dealii/issues/17148
340
342 }
343
344
352
358 std::size_t
360
366
372 template <class Archive>
373 void
374 save(Archive &ar, const unsigned int version) const;
375
381 template <class Archive>
382 void
383 load(Archive &ar, const unsigned int version);
384
385#ifdef DOXYGEN
391 template <class Archive>
392 void
393 serialize(Archive &archive, const unsigned int version);
394#else
395 // This macro defines the serialize() method that is compatible with
396 // the templated save() and load() method that have been implemented.
397 BOOST_SERIALIZATION_SPLIT_MEMBER()
398#endif
399
403 void
405
409 void
411
415 bool
417
421 bool
423
428 state() const;
429
430 private:
435
443 const typename particle_container::iterator particles_in_cell,
445 const unsigned int particle_index_within_cell);
446
453 get_handle() const;
454
460
465 typename particle_container::iterator particles_in_cell;
466
471
476
477 // Make ParticleIterator a friend to allow it constructing
478 // ParticleAccessors.
479 template <int, int>
480 friend class ParticleIterator;
481 template <int, int>
482 friend class ParticleHandler;
483 };
484
485
486
487 template <int dim, int spacedim>
488 template <class Archive>
489 inline void
490 ParticleAccessor<dim, spacedim>::load(Archive &ar, const unsigned int)
491 {
492 unsigned int n_properties = 0;
493
494 Point<spacedim> location;
495 Point<dim> reference_location;
497 ar &location &reference_location &id &n_properties;
498
499 set_location(location);
500 set_reference_location(reference_location);
501 set_id(id);
502
503 if (n_properties > 0)
504 {
505 ArrayView<double> properties(get_properties());
506 Assert(
507 properties.size() == n_properties,
509 "This particle was serialized with " +
510 std::to_string(n_properties) +
511 " properties, but the new property handler provides space for " +
512 std::to_string(properties.size()) +
513 " properties. Deserializing a particle only works for matching property sizes."));
514
515 ar &boost::serialization::make_array(properties.data(), n_properties);
516 }
517 }
518
519
520
521 template <int dim, int spacedim>
522 template <class Archive>
523 inline void
524 ParticleAccessor<dim, spacedim>::save(Archive &ar, const unsigned int) const
525 {
526 unsigned int n_properties = 0;
527 if ((property_pool != nullptr) &&
529 n_properties = get_properties().size();
530
531 Point<spacedim> location = get_location();
532 Point<dim> reference_location = get_reference_location();
533 types::particle_index id = get_id();
534
535 ar &location &reference_location &id &n_properties;
536
537 if (n_properties > 0)
538 ar &boost::serialization::make_array(get_properties().data(),
539 n_properties);
540 }
541
542
543 // ------------------------- inline functions ------------------------------
544
545 template <int dim, int spacedim>
547 : particles_in_cell(typename particle_container::iterator())
548 , property_pool(nullptr)
549 , particle_index_within_cell(numbers::invalid_unsigned_int)
550 {}
551
552
553
554 template <int dim, int spacedim>
556 const typename particle_container::iterator particles_in_cell,
557 const PropertyPool<dim, spacedim> &property_pool,
558 const unsigned int particle_index_within_cell)
559 : particles_in_cell(particles_in_cell)
560 , property_pool(const_cast<PropertyPool<dim, spacedim> *>(&property_pool))
561 , particle_index_within_cell(particle_index_within_cell)
562 {}
563
564
565
566 template <int dim, int spacedim>
567 inline const void *
569 const void *data)
570 {
572
573 const types::particle_index *id_data =
574 static_cast<const types::particle_index *>(data);
575 set_id(*id_data++);
576 const double *pdata = reinterpret_cast<const double *>(id_data);
577
578 Point<spacedim> location;
579 for (unsigned int i = 0; i < spacedim; ++i)
580 location[i] = *pdata++;
581 set_location(location);
582
583 Point<dim> reference_location;
584 for (unsigned int i = 0; i < dim; ++i)
585 reference_location[i] = *pdata++;
586 set_reference_location(reference_location);
587
588 // See if there are properties to load
589 if (has_properties())
590 {
591 const ArrayView<double> particle_properties =
592 property_pool->get_properties(get_handle());
593 const unsigned int size = particle_properties.size();
594 for (unsigned int i = 0; i < size; ++i)
595 particle_properties[i] = *pdata++;
596 }
597
598 return static_cast<const void *>(pdata);
599 }
600
601
602
603 template <int dim, int spacedim>
604 inline void *
606 void *data) const
607 {
609
610 types::particle_index *id_data = static_cast<types::particle_index *>(data);
611 *id_data = get_id();
612 ++id_data;
613 double *pdata = reinterpret_cast<double *>(id_data);
614
615 // Write location
616 for (unsigned int i = 0; i < spacedim; ++i, ++pdata)
617 *pdata = get_location()[i];
618
619 // Write reference location
620 for (unsigned int i = 0; i < dim; ++i, ++pdata)
621 *pdata = get_reference_location()[i];
622
623 // Write properties
624 if (has_properties())
625 {
626 const ArrayView<double> particle_properties =
627 property_pool->get_properties(get_handle());
628 for (unsigned int i = 0; i < particle_properties.size(); ++i, ++pdata)
629 *pdata = particle_properties[i];
630 }
631
632 return static_cast<void *>(pdata);
633 }
634
635
636
637 template <int dim, int spacedim>
638 inline void
640 {
642
643 property_pool->set_location(get_handle(), new_loc);
644 }
645
646
647
648 template <int dim, int spacedim>
649 inline const Point<spacedim> &
651 {
653
654 return property_pool->get_location(get_handle());
655 }
656
657
658
659 template <int dim, int spacedim>
660 inline Point<spacedim> &
662 {
664
665 return property_pool->get_location(get_handle());
666 }
667
668
669
670 template <int dim, int spacedim>
671 inline void
673 const Point<dim> &new_loc)
674 {
676
677 property_pool->set_reference_location(get_handle(), new_loc);
678 }
679
680
681
682 template <int dim, int spacedim>
683 inline const Point<dim> &
685 {
687
688 return property_pool->get_reference_location(get_handle());
689 }
690
691
692
693 template <int dim, int spacedim>
696 {
698
699 return property_pool->get_id(get_handle());
700 }
701
702
703
704 template <int dim, int spacedim>
707 {
709
710 return get_handle();
711 }
712
713
714
715 template <int dim, int spacedim>
716 inline void
718 {
720
721 property_pool->set_id(get_handle(), new_id);
722 }
723
724
725
726 template <int dim, int spacedim>
727 inline bool
729 {
731
732 // Particles always have a property pool associated with them,
733 // but we can access properties only if there is a valid handle.
734 // The only way a particle can have no valid handle if it has
735 // been moved-from -- but that leaves an object in an invalid
736 // state, and so we can just assert that that can't be the case.
739 return (property_pool->n_properties_per_slot() > 0);
740 }
741
742
743
744 template <int dim, int spacedim>
745 inline void
747 const std::vector<double> &new_properties)
748 {
750
751 set_properties(
752 ArrayView<const double>(new_properties.data(), new_properties.size()));
753 }
754
755
756
757 template <int dim, int spacedim>
758 inline void
760 const ArrayView<const double> &new_properties)
761 {
763
764 const ArrayView<double> property_values =
765 property_pool->get_properties(get_handle());
766
767 Assert(new_properties.size() == property_values.size(),
769 "You are trying to assign properties with an incompatible length. "
770 "The particle has space to store " +
771 std::to_string(property_values.size()) +
772 " properties, but you are trying to assign " +
773 std::to_string(new_properties.size()) +
774 " properties. This is not allowed."));
775
776 if (property_values.size() > 0)
777 std::copy(new_properties.begin(),
778 new_properties.end(),
779 property_values.begin());
780 }
781
782
783
784 template <int dim, int spacedim>
785 inline void
787 const Tensor<1, dim> &new_properties)
788 {
790
791 // A Tensor object is not an array, so we cannot just create an
792 // ArrayView object for it. Rather, copy the data into a true
793 // array and make the ArrayView from that.
794 double array[dim];
795 for (unsigned int d = 0; d < dim; ++d)
796 array[d] = new_properties[d];
797
798 set_properties(make_array_view(array));
799 }
800
801
802
803 template <int dim, int spacedim>
806 {
808
809 return property_pool->get_properties(get_handle());
810 }
811
812
813
814 template <int dim, int spacedim>
815 inline const typename Triangulation<dim, spacedim>::cell_iterator &
817 {
819 Assert(particles_in_cell->cell.state() == IteratorState::valid,
821
822 return particles_in_cell->cell;
823 }
824
825
826
827 // template <int dim, int spacedim>
828 // inline ArrayView<double>
829 // ParticleAccessor<dim, spacedim>::get_properties()
830
831
832
833 template <int dim, int spacedim>
834 inline std::size_t
836 {
838
839 std::size_t size = sizeof(get_id()) +
840 sizeof(double) * spacedim + // get_location()
841 sizeof(double) * dim; // get_reference_location()
842
843 if (has_properties())
844 {
845 size += sizeof(double) * get_properties().size();
846 }
847 return size;
848 }
849
850
851
852 template <int dim, int spacedim>
853 inline void
855 {
857
858 ++particle_index_within_cell;
859
860 if (particle_index_within_cell >= particles_in_cell->particles.size())
861 {
862 particle_index_within_cell = 0;
863 ++particles_in_cell;
864 }
865 }
866
867
868
869 template <int dim, int spacedim>
870 inline void
872 {
874
875 if (particle_index_within_cell > 0)
876 --particle_index_within_cell;
877 else
878 {
879 --particles_in_cell;
880 particle_index_within_cell = particles_in_cell->particles.empty() ?
881 0 :
882 particles_in_cell->particles.size() - 1;
883 }
884 }
885
886
887
888 template <int dim, int spacedim>
889 inline bool
891 const ParticleAccessor<dim, spacedim> &other) const
892 {
893 return !(*this == other);
894 }
895
896
897
898 template <int dim, int spacedim>
899 inline bool
901 const ParticleAccessor<dim, spacedim> &other) const
902 {
903 return (property_pool == other.property_pool) &&
904 (particles_in_cell == other.particles_in_cell) &&
905 (particle_index_within_cell == other.particle_index_within_cell);
906 }
907
908
909
910 template <int dim, int spacedim>
913 {
914 if (property_pool != nullptr &&
915 particles_in_cell->cell.state() == IteratorState::valid &&
916 particle_index_within_cell < particles_in_cell->particles.size())
918 else if (property_pool != nullptr &&
919 particles_in_cell->cell.state() == IteratorState::past_the_end &&
920 particle_index_within_cell == 0)
922 else
924
926 }
927
928
929
930 template <int dim, int spacedim>
933 {
934 return particles_in_cell->particles[particle_index_within_cell];
935 }
936
937
938
939 template <int dim, int spacedim>
940 inline const typename PropertyPool<dim, spacedim>::Handle &
942 {
943 return particles_in_cell->particles[particle_index_within_cell];
944 }
945
946} // namespace Particles
947
949
950namespace boost
951{
952 namespace geometry
953 {
954 namespace index
955 {
956 // Forward declaration of bgi::indexable
957 template <class T>
958 struct indexable;
959
964 template <int dim, int spacedim>
965 struct indexable<::Particles::ParticleAccessor<dim, spacedim>>
966 {
971 using result_type = const ::Point<spacedim> &;
972
974 operator()(const ::Particles::ParticleAccessor<dim, spacedim>
975 &accessor) const
976 {
977 return accessor.get_location();
978 }
979 };
980 } // namespace index
981 } // namespace geometry
982} // namespace boost
983
984#endif
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
Definition array_view.h:949
iterator begin() const
Definition array_view.h:702
iterator end() const
Definition array_view.h:711
value_type * data() const noexcept
Definition array_view.h:661
std::size_t size() const
Definition array_view.h:684
particle_container::iterator particles_in_cell
const Point< spacedim > & get_location() const
types::particle_index get_id() const
void save(Archive &ar, const unsigned int version) const
types::particle_index get_local_index() const
std::list< ParticlesInCell > particle_container
const void * read_particle_data_from_memory(const void *data)
void load(Archive &ar, const unsigned int version)
const Triangulation< dim, spacedim >::cell_iterator & get_surrounding_cell() const
IteratorState::IteratorStates state() const
bool operator!=(const ParticleAccessor< dim, spacedim > &other) const
void set_properties(const Tensor< 1, dim > &new_properties)
void set_location(const Point< spacedim > &new_location)
PropertyPool< dim, spacedim >::Handle & get_handle()
void serialize(Archive &archive, const unsigned int version)
ArrayView< double > get_properties()
void set_reference_location(const Point< dim > &new_reference_location)
const Point< dim > & get_reference_location() const
std::size_t serialized_size_in_bytes() const
const PropertyPool< dim, spacedim >::Handle & get_handle() const
void set_properties(const std::vector< double > &new_properties)
Point< spacedim > & get_location()
ParticleAccessor(const typename particle_container::iterator particles_in_cell, const PropertyPool< dim, spacedim > &property_pool, const unsigned int particle_index_within_cell)
PropertyPool< dim, spacedim > * property_pool
void * write_particle_data_to_memory(void *data) const
void set_properties(const ArrayView< const double > &new_properties)
ArrayView< const double > get_properties() const
bool operator==(const ParticleAccessor< dim, spacedim > &other) const
void set_id(const types::particle_index &new_id)
ArrayView< double, ::MemorySpace::Host > get_properties(const Handle handle)
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.
Triangulation< dim, spacedim >::active_cell_iterator cell
ParticlesInCell(const std::vector< typename PropertyPool< dim, spacedim >::Handle > &particles, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
std::vector< typename PropertyPool< dim, spacedim >::Handle > particles
result_type operator()(const ::Particles::ParticleAccessor< dim, spacedim > &accessor) const