Reference documentation for deal.II version GIT relicensing-1054-gedd46abbd6 2024-07-12 01:20:01+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
367
373 template <class Archive>
374 void
375 save(Archive &ar, const unsigned int version) const;
376
386 template <class Archive>
387 void
388 load(Archive &ar, const unsigned int version);
389
390#ifdef DOXYGEN
396 template <class Archive>
397 void
398 serialize(Archive &archive, const unsigned int version);
399#else
400 // This macro defines the serialize() method that is compatible with
401 // the templated save() and load() method that have been implemented.
402 BOOST_SERIALIZATION_SPLIT_MEMBER()
403#endif
404
408 void
410
414 void
416
420 bool
422
426 bool
428
433 state() const;
434
435 private:
440
448 const typename particle_container::iterator particles_in_cell,
450 const unsigned int particle_index_within_cell);
451
458 get_handle() const;
459
465
470 typename particle_container::iterator particles_in_cell;
471
476
481
482 // Make ParticleIterator a friend to allow it constructing
483 // ParticleAccessors.
484 template <int, int>
485 friend class ParticleIterator;
486 template <int, int>
487 friend class ParticleHandler;
488 };
489
490
491
492 template <int dim, int spacedim>
493 template <class Archive>
494 inline void
495 ParticleAccessor<dim, spacedim>::load(Archive &ar, const unsigned int)
496 {
497 unsigned int n_properties = 0;
498
499 Point<spacedim> location;
500 Point<dim> reference_location;
502 ar &location &reference_location &id &n_properties;
503
504 set_location(location);
505 set_reference_location(reference_location);
506 set_id(id);
507
508 if (n_properties > 0)
509 {
510 ArrayView<double> properties(get_properties());
511 Assert(
512 properties.size() == n_properties,
514 "This particle was serialized with " +
515 std::to_string(n_properties) +
516 " properties, but the new property handler provides space for " +
517 std::to_string(properties.size()) +
518 " properties. Deserializing a particle only works for matching property sizes."));
519
520 ar &boost::serialization::make_array(properties.data(), n_properties);
521 }
522 }
523
524
525
526 template <int dim, int spacedim>
527 template <class Archive>
528 inline void
529 ParticleAccessor<dim, spacedim>::save(Archive &ar, const unsigned int) const
530 {
531 unsigned int n_properties = 0;
532 if ((property_pool != nullptr) &&
534 n_properties = get_properties().size();
535
536 Point<spacedim> location = get_location();
537 Point<dim> reference_location = get_reference_location();
538 types::particle_index id = get_id();
539
540 ar &location &reference_location &id &n_properties;
541
542 if (n_properties > 0)
543 ar &boost::serialization::make_array(get_properties().data(),
544 n_properties);
545 }
546
547
548 // ------------------------- inline functions ------------------------------
549
550 template <int dim, int spacedim>
552 : particles_in_cell(typename particle_container::iterator())
553 , property_pool(nullptr)
554 , particle_index_within_cell(numbers::invalid_unsigned_int)
555 {}
556
557
558
559 template <int dim, int spacedim>
561 const typename particle_container::iterator particles_in_cell,
562 const PropertyPool<dim, spacedim> &property_pool,
563 const unsigned int particle_index_within_cell)
564 : particles_in_cell(particles_in_cell)
565 , property_pool(const_cast<PropertyPool<dim, spacedim> *>(&property_pool))
566 , particle_index_within_cell(particle_index_within_cell)
567 {}
568
569
570
571 template <int dim, int spacedim>
572 inline const void *
574 const void *data)
575 {
577
578 const types::particle_index *id_data =
579 static_cast<const types::particle_index *>(data);
580 set_id(*id_data++);
581 const double *pdata = reinterpret_cast<const double *>(id_data);
582
583 Point<spacedim> location;
584 for (unsigned int i = 0; i < spacedim; ++i)
585 location[i] = *pdata++;
586 set_location(location);
587
588 Point<dim> reference_location;
589 for (unsigned int i = 0; i < dim; ++i)
590 reference_location[i] = *pdata++;
591 set_reference_location(reference_location);
592
593 // See if there are properties to load
594 if (has_properties())
595 {
596 const ArrayView<double> particle_properties =
597 property_pool->get_properties(get_handle());
598 const unsigned int size = particle_properties.size();
599 for (unsigned int i = 0; i < size; ++i)
600 particle_properties[i] = *pdata++;
601 }
602
603 return static_cast<const void *>(pdata);
604 }
605
606
607
608 template <int dim, int spacedim>
609 inline void *
611 void *data) const
612 {
614
615 types::particle_index *id_data = static_cast<types::particle_index *>(data);
616 *id_data = get_id();
617 ++id_data;
618 double *pdata = reinterpret_cast<double *>(id_data);
619
620 // Write location
621 for (unsigned int i = 0; i < spacedim; ++i, ++pdata)
622 *pdata = get_location()[i];
623
624 // Write reference location
625 for (unsigned int i = 0; i < dim; ++i, ++pdata)
626 *pdata = get_reference_location()[i];
627
628 // Write properties
629 if (has_properties())
630 {
631 const ArrayView<double> particle_properties =
632 property_pool->get_properties(get_handle());
633 for (unsigned int i = 0; i < particle_properties.size(); ++i, ++pdata)
634 *pdata = particle_properties[i];
635 }
636
637 return static_cast<void *>(pdata);
638 }
639
640
641
642 template <int dim, int spacedim>
643 inline void
645 {
647
648 property_pool->set_location(get_handle(), new_loc);
649 }
650
651
652
653 template <int dim, int spacedim>
654 inline const Point<spacedim> &
656 {
658
659 return property_pool->get_location(get_handle());
660 }
661
662
663
664 template <int dim, int spacedim>
665 inline Point<spacedim> &
667 {
669
670 return property_pool->get_location(get_handle());
671 }
672
673
674
675 template <int dim, int spacedim>
676 inline void
678 const Point<dim> &new_loc)
679 {
681
682 property_pool->set_reference_location(get_handle(), new_loc);
683 }
684
685
686
687 template <int dim, int spacedim>
688 inline const Point<dim> &
690 {
692
693 return property_pool->get_reference_location(get_handle());
694 }
695
696
697
698 template <int dim, int spacedim>
701 {
703
704 return property_pool->get_id(get_handle());
705 }
706
707
708
709 template <int dim, int spacedim>
712 {
714
715 return get_handle();
716 }
717
718
719
720 template <int dim, int spacedim>
721 inline void
723 {
725
726 property_pool->set_id(get_handle(), new_id);
727 }
728
729
730
731 template <int dim, int spacedim>
732 inline bool
734 {
736
737 // Particles always have a property pool associated with them,
738 // but we can access properties only if there is a valid handle.
739 // The only way a particle can have no valid handle if it has
740 // been moved-from -- but that leaves an object in an invalid
741 // state, and so we can just assert that that can't be the case.
744 return (property_pool->n_properties_per_slot() > 0);
745 }
746
747
748
749 template <int dim, int spacedim>
750 inline void
752 const std::vector<double> &new_properties)
753 {
755
756 set_properties(
757 ArrayView<const double>(new_properties.data(), new_properties.size()));
758 }
759
760
761
762 template <int dim, int spacedim>
763 inline void
765 const ArrayView<const double> &new_properties)
766 {
768
769 const ArrayView<double> property_values =
770 property_pool->get_properties(get_handle());
771
772 Assert(new_properties.size() == property_values.size(),
774 "You are trying to assign properties with an incompatible length. "
775 "The particle has space to store " +
776 std::to_string(property_values.size()) +
777 " properties, but you are trying to assign " +
778 std::to_string(new_properties.size()) +
779 " properties. This is not allowed."));
780
781 if (property_values.size() > 0)
782 std::copy(new_properties.begin(),
783 new_properties.end(),
784 property_values.begin());
785 }
786
787
788
789 template <int dim, int spacedim>
790 inline void
792 const Tensor<1, dim> &new_properties)
793 {
795
796 // A Tensor object is not an array, so we cannot just create an
797 // ArrayView object for it. Rather, copy the data into a true
798 // array and make the ArrayView from that.
799 double array[dim];
800 for (unsigned int d = 0; d < dim; ++d)
801 array[d] = new_properties[d];
802
803 set_properties(make_array_view(array));
804 }
805
806
807
808 template <int dim, int spacedim>
811 {
813
814 return property_pool->get_properties(get_handle());
815 }
816
817
818
819 template <int dim, int spacedim>
820 inline void
822 PropertyPool<dim, spacedim> &new_property_pool)
823 {
824 Assert(&new_property_pool == property_pool, ExcInternalError());
825 (void)new_property_pool;
826 }
827
828
829
830 template <int dim, int spacedim>
831 inline const typename Triangulation<dim, spacedim>::cell_iterator &
833 {
835 Assert(particles_in_cell->cell.state() == IteratorState::valid,
837
838 return particles_in_cell->cell;
839 }
840
841
842
843 template <int dim, int spacedim>
844 inline ArrayView<double>
846 {
848
849 return property_pool->get_properties(get_handle());
850 }
851
852
853
854 template <int dim, int spacedim>
855 inline std::size_t
857 {
859
860 std::size_t size = sizeof(get_id()) +
861 sizeof(double) * spacedim + // get_location()
862 sizeof(double) * dim; // get_reference_location()
863
864 if (has_properties())
865 {
866 size += sizeof(double) * get_properties().size();
867 }
868 return size;
869 }
870
871
872
873 template <int dim, int spacedim>
874 inline void
876 {
878
879 ++particle_index_within_cell;
880
881 if (particle_index_within_cell >= particles_in_cell->particles.size())
882 {
883 particle_index_within_cell = 0;
884 ++particles_in_cell;
885 }
886 }
887
888
889
890 template <int dim, int spacedim>
891 inline void
893 {
895
896 if (particle_index_within_cell > 0)
897 --particle_index_within_cell;
898 else
899 {
900 --particles_in_cell;
901 particle_index_within_cell = particles_in_cell->particles.empty() ?
902 0 :
903 particles_in_cell->particles.size() - 1;
904 }
905 }
906
907
908
909 template <int dim, int spacedim>
910 inline bool
912 const ParticleAccessor<dim, spacedim> &other) const
913 {
914 return !(*this == other);
915 }
916
917
918
919 template <int dim, int spacedim>
920 inline bool
922 const ParticleAccessor<dim, spacedim> &other) const
923 {
924 return (property_pool == other.property_pool) &&
925 (particles_in_cell == other.particles_in_cell) &&
926 (particle_index_within_cell == other.particle_index_within_cell);
927 }
928
929
930
931 template <int dim, int spacedim>
934 {
935 if (property_pool != nullptr &&
936 particles_in_cell->cell.state() == IteratorState::valid &&
937 particle_index_within_cell < particles_in_cell->particles.size())
939 else if (property_pool != nullptr &&
940 particles_in_cell->cell.state() == IteratorState::past_the_end &&
941 particle_index_within_cell == 0)
943 else
945
947 }
948
949
950
951 template <int dim, int spacedim>
954 {
955 return particles_in_cell->particles[particle_index_within_cell];
956 }
957
958
959
960 template <int dim, int spacedim>
961 inline const typename PropertyPool<dim, spacedim>::Handle &
963 {
964 return particles_in_cell->particles[particle_index_within_cell];
965 }
966
967} // namespace Particles
968
970
971namespace boost
972{
973 namespace geometry
974 {
975 namespace index
976 {
977 // Forward declaration of bgi::indexable
978 template <class T>
979 struct indexable;
980
985 template <int dim, int spacedim>
986 struct indexable<::Particles::ParticleAccessor<dim, spacedim>>
987 {
992 using result_type = const ::Point<spacedim> &;
993
995 operator()(const ::Particles::ParticleAccessor<dim, spacedim>
996 &accessor) const
997 {
998 return accessor.get_location();
999 }
1000 };
1001 } // namespace index
1002 } // namespace geometry
1003} // namespace boost
1004
1005#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)
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.
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