Reference documentation for deal.II version GIT relicensing-422-gb369f187d8 2024-04-17 18:10:02+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
338
351 void
353
359 std::size_t
361
370
379
385 template <class Archive>
386 void
387 save(Archive &ar, const unsigned int version) const;
388
398 template <class Archive>
399 void
400 load(Archive &ar, const unsigned int version);
401
402#ifdef DOXYGEN
408 template <class Archive>
409 void
410 serialize(Archive &archive, const unsigned int version);
411#else
412 // This macro defines the serialize() method that is compatible with
413 // the templated save() and load() method that have been implemented.
414 BOOST_SERIALIZATION_SPLIT_MEMBER()
415#endif
416
420 void
422
426 void
428
432 bool
434
438 bool
440
445 state() const;
446
447 private:
452
460 const typename particle_container::iterator particles_in_cell,
462 const unsigned int particle_index_within_cell);
463
470 get_handle() const;
471
477
482 typename particle_container::iterator particles_in_cell;
483
488
493
494 // Make ParticleIterator a friend to allow it constructing
495 // ParticleAccessors.
496 template <int, int>
497 friend class ParticleIterator;
498 template <int, int>
499 friend class ParticleHandler;
500 };
501
502
503
504 template <int dim, int spacedim>
505 template <class Archive>
506 inline void
507 ParticleAccessor<dim, spacedim>::load(Archive &ar, const unsigned int)
508 {
509 unsigned int n_properties = 0;
510
511 Point<spacedim> location;
512 Point<dim> reference_location;
514 ar &location &reference_location &id &n_properties;
515
516 set_location(location);
517 set_reference_location(reference_location);
518 set_id(id);
519
520 if (n_properties > 0)
521 {
522 ArrayView<double> properties(get_properties());
523 Assert(
524 properties.size() == n_properties,
526 "This particle was serialized with " +
527 std::to_string(n_properties) +
528 " properties, but the new property handler provides space for " +
529 std::to_string(properties.size()) +
530 " properties. Deserializing a particle only works for matching property sizes."));
531
532 ar &boost::serialization::make_array(properties.data(), n_properties);
533 }
534 }
535
536
537
538 template <int dim, int spacedim>
539 template <class Archive>
540 inline void
541 ParticleAccessor<dim, spacedim>::save(Archive &ar, const unsigned int) const
542 {
543 unsigned int n_properties = 0;
544 if ((property_pool != nullptr) &&
546 n_properties = get_properties().size();
547
548 Point<spacedim> location = get_location();
549 Point<dim> reference_location = get_reference_location();
550 types::particle_index id = get_id();
551
552 ar &location &reference_location &id &n_properties;
553
554 if (n_properties > 0)
555 ar &boost::serialization::make_array(get_properties().data(),
556 n_properties);
557 }
558
559
560 // ------------------------- inline functions ------------------------------
561
562 template <int dim, int spacedim>
564 : particles_in_cell(typename particle_container::iterator())
565 , property_pool(nullptr)
566 , particle_index_within_cell(numbers::invalid_unsigned_int)
567 {}
568
569
570
571 template <int dim, int spacedim>
573 const typename particle_container::iterator particles_in_cell,
574 const PropertyPool<dim, spacedim> &property_pool,
575 const unsigned int particle_index_within_cell)
576 : particles_in_cell(particles_in_cell)
577 , property_pool(const_cast<PropertyPool<dim, spacedim> *>(&property_pool))
578 , particle_index_within_cell(particle_index_within_cell)
579 {}
580
581
582
583 template <int dim, int spacedim>
584 inline const void *
586 const void *data)
587 {
589
590 const types::particle_index *id_data =
591 static_cast<const types::particle_index *>(data);
592 set_id(*id_data++);
593 const double *pdata = reinterpret_cast<const double *>(id_data);
594
595 Point<spacedim> location;
596 for (unsigned int i = 0; i < spacedim; ++i)
597 location[i] = *pdata++;
598 set_location(location);
599
600 Point<dim> reference_location;
601 for (unsigned int i = 0; i < dim; ++i)
602 reference_location[i] = *pdata++;
603 set_reference_location(reference_location);
604
605 // See if there are properties to load
606 if (has_properties())
607 {
608 const ArrayView<double> particle_properties =
609 property_pool->get_properties(get_handle());
610 const unsigned int size = particle_properties.size();
611 for (unsigned int i = 0; i < size; ++i)
612 particle_properties[i] = *pdata++;
613 }
614
615 return static_cast<const void *>(pdata);
616 }
617
618
619
620 template <int dim, int spacedim>
621 inline void *
623 void *data) const
624 {
626
627 types::particle_index *id_data = static_cast<types::particle_index *>(data);
628 *id_data = get_id();
629 ++id_data;
630 double *pdata = reinterpret_cast<double *>(id_data);
631
632 // Write location
633 for (unsigned int i = 0; i < spacedim; ++i, ++pdata)
634 *pdata = get_location()[i];
635
636 // Write reference location
637 for (unsigned int i = 0; i < dim; ++i, ++pdata)
638 *pdata = get_reference_location()[i];
639
640 // Write properties
641 if (has_properties())
642 {
643 const ArrayView<double> particle_properties =
644 property_pool->get_properties(get_handle());
645 for (unsigned int i = 0; i < particle_properties.size(); ++i, ++pdata)
646 *pdata = particle_properties[i];
647 }
648
649 return static_cast<void *>(pdata);
650 }
651
652
653
654 template <int dim, int spacedim>
655 inline void
657 {
659
660 property_pool->set_location(get_handle(), new_loc);
661 }
662
663
664
665 template <int dim, int spacedim>
666 inline const Point<spacedim> &
668 {
670
671 return property_pool->get_location(get_handle());
672 }
673
674
675
676 template <int dim, int spacedim>
677 inline Point<spacedim> &
679 {
681
682 return property_pool->get_location(get_handle());
683 }
684
685
686
687 template <int dim, int spacedim>
688 inline void
690 const Point<dim> &new_loc)
691 {
693
694 property_pool->set_reference_location(get_handle(), new_loc);
695 }
696
697
698
699 template <int dim, int spacedim>
700 inline const Point<dim> &
702 {
704
705 return property_pool->get_reference_location(get_handle());
706 }
707
708
709
710 template <int dim, int spacedim>
713 {
715
716 return property_pool->get_id(get_handle());
717 }
718
719
720
721 template <int dim, int spacedim>
724 {
726
727 return get_handle();
728 }
729
730
731
732 template <int dim, int spacedim>
733 inline void
735 {
737
738 property_pool->set_id(get_handle(), new_id);
739 }
740
741
742
743 template <int dim, int spacedim>
744 inline bool
746 {
748
749 // Particles always have a property pool associated with them,
750 // but we can access properties only if there is a valid handle.
751 // The only way a particle can have no valid handle if it has
752 // been moved-from -- but that leaves an object in an invalid
753 // state, and so we can just assert that that can't be the case.
756 return (property_pool->n_properties_per_slot() > 0);
757 }
758
759
760
761 template <int dim, int spacedim>
762 inline void
764 const std::vector<double> &new_properties)
765 {
767
768 set_properties(
769 ArrayView<const double>(new_properties.data(), new_properties.size()));
770 }
771
772
773
774 template <int dim, int spacedim>
775 inline void
777 const ArrayView<const double> &new_properties)
778 {
780
781 const ArrayView<double> property_values =
782 property_pool->get_properties(get_handle());
783
784 Assert(new_properties.size() == property_values.size(),
786 "You are trying to assign properties with an incompatible length. "
787 "The particle has space to store " +
788 std::to_string(property_values.size()) +
789 " properties, but you are trying to assign " +
790 std::to_string(new_properties.size()) +
791 " properties. This is not allowed."));
792
793 if (property_values.size() > 0)
794 std::copy(new_properties.begin(),
795 new_properties.end(),
796 property_values.begin());
797 }
798
799
800
801 template <int dim, int spacedim>
802 inline void
804 const Tensor<1, dim> &new_properties)
805 {
807
808 // A Tensor object is not an array, so we cannot just create an
809 // ArrayView object for it. Rather, copy the data into a true
810 // array and make the ArrayView from that.
811 double array[dim];
812 for (unsigned int d = 0; d < dim; ++d)
813 array[d] = new_properties[d];
814
815 set_properties(make_array_view(array));
816 }
817
818
819
820 template <int dim, int spacedim>
823 {
825
826 return property_pool->get_properties(get_handle());
827 }
828
829
830
831 template <int dim, int spacedim>
832 inline void
834 PropertyPool<dim, spacedim> &new_property_pool)
835 {
836 Assert(&new_property_pool == property_pool, ExcInternalError());
837 (void)new_property_pool;
838 }
839
840
841
842 template <int dim, int spacedim>
843 inline const typename Triangulation<dim, spacedim>::cell_iterator &
845 {
847 Assert(particles_in_cell->cell.state() == IteratorState::valid,
849
850 return particles_in_cell->cell;
851 }
852
853
854
855 template <int dim, int spacedim>
856 inline const typename Triangulation<dim, spacedim>::cell_iterator &
858 const Triangulation<dim, spacedim> & /*triangulation*/) const
859 {
861 Assert(particles_in_cell->cell.state() == IteratorState::valid,
863
864 return particles_in_cell->cell;
865 }
866
867
868
869 template <int dim, int spacedim>
870 inline ArrayView<double>
872 {
874
875 return property_pool->get_properties(get_handle());
876 }
877
878
879
880 template <int dim, int spacedim>
881 inline std::size_t
883 {
885
886 std::size_t size = sizeof(get_id()) +
887 sizeof(double) * spacedim + // get_location()
888 sizeof(double) * dim; // get_reference_location()
889
890 if (has_properties())
891 {
892 size += sizeof(double) * get_properties().size();
893 }
894 return size;
895 }
896
897
898
899 template <int dim, int spacedim>
900 inline void
902 {
904
905 ++particle_index_within_cell;
906
907 if (particle_index_within_cell >= particles_in_cell->particles.size())
908 {
909 particle_index_within_cell = 0;
910 ++particles_in_cell;
911 }
912 }
913
914
915
916 template <int dim, int spacedim>
917 inline void
919 {
921
922 if (particle_index_within_cell > 0)
923 --particle_index_within_cell;
924 else
925 {
926 --particles_in_cell;
927 particle_index_within_cell = particles_in_cell->particles.empty() ?
928 0 :
929 particles_in_cell->particles.size() - 1;
930 }
931 }
932
933
934
935 template <int dim, int spacedim>
936 inline bool
938 const ParticleAccessor<dim, spacedim> &other) const
939 {
940 return !(*this == other);
941 }
942
943
944
945 template <int dim, int spacedim>
946 inline bool
948 const ParticleAccessor<dim, spacedim> &other) const
949 {
950 return (property_pool == other.property_pool) &&
951 (particles_in_cell == other.particles_in_cell) &&
952 (particle_index_within_cell == other.particle_index_within_cell);
953 }
954
955
956
957 template <int dim, int spacedim>
960 {
961 if (property_pool != nullptr &&
962 particles_in_cell->cell.state() == IteratorState::valid &&
963 particle_index_within_cell < particles_in_cell->particles.size())
965 else if (property_pool != nullptr &&
966 particles_in_cell->cell.state() == IteratorState::past_the_end &&
967 particle_index_within_cell == 0)
969 else
971
973 }
974
975
976
977 template <int dim, int spacedim>
980 {
981 return particles_in_cell->particles[particle_index_within_cell];
982 }
983
984
985
986 template <int dim, int spacedim>
987 inline const typename PropertyPool<dim, spacedim>::Handle &
989 {
990 return particles_in_cell->particles[particle_index_within_cell];
991 }
992
993} // namespace Particles
994
996
997namespace boost
998{
999 namespace geometry
1000 {
1001 namespace index
1002 {
1003 // Forward declaration of bgi::indexable
1004 template <class T>
1005 struct indexable;
1006
1011 template <int dim, int spacedim>
1013 {
1018 using result_type = const ::Point<spacedim> &;
1019
1021 operator()(const ::Particles::ParticleAccessor<dim, spacedim>
1022 &accessor) const
1023 {
1024 return accessor.get_location();
1025 }
1026 };
1027 } // namespace index
1028 } // namespace geometry
1029} // namespace boost
1030
1031#endif
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, 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
const Triangulation< dim, spacedim >::cell_iterator & get_surrounding_cell(const Triangulation< dim, spacedim > &triangulation) const
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)
void set_property_pool(PropertyPool< dim, spacedim > &property_pool)
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)
Definition point.h:111
#define DEAL_II_DEPRECATED
Definition config.h:207
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
#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.
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
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