faunus
celllistimpl.h
1 #pragma once
2 
11 #include "core.h"
12 #include "celllist.h"
13 #include <set>
14 #include <map>
15 #include <algorithm>
16 #include <cassert>
17 #include <range/v3/range/conversion.hpp>
18 #include <spdlog/spdlog.h>
19 
49 namespace Faunus::CellList {
50 
54 namespace Grid {
55 
60 template <typename TGridType> struct AbstractGrid : private TGridType
61 {
62  using GridType = TGridType;
63  using typename GridType::CellCoord;
64  using typename GridType::CellIndex;
65  using typename GridType::Point;
66  using typename GridType::SpaceAxis;
67 
68  virtual CellCoord coordinates(CellIndex index) const = 0;
69  virtual CellIndex index(const CellCoord& coordinates) const = 0;
70  virtual CellCoord coordinatesAt(const Point& position) const = 0;
71  virtual CellIndex indexAt(const Point& position) const = 0;
72  virtual bool isCell(const CellCoord& coordinates) const = 0;
73  virtual bool isCellAt(const Point& point) const = 0;
74  virtual CellIndex size() const = 0;
75  virtual ~AbstractGrid() = default;
76 };
77 
78 template <typename TGridType> struct AbstractNeighborGrid : public virtual AbstractGrid<TGridType>
79 {
80  using GridType = TGridType;
81  using typename TGridType::CellCoord;
82 
83  virtual bool isNeighborCell(const CellCoord& coordinates, const CellCoord& offset) const = 0;
84  virtual ~AbstractNeighborGrid() = default;
85 };
86 
95 template <typename TGridType> class GridBase : public virtual AbstractGrid<TGridType>
96 {
97  public:
98  using GridType = typename AbstractGrid<TGridType>::GridType;
99  using typename GridType::CellCoord;
100  using typename GridType::CellIndex;
101  using typename GridType::Point;
102  using typename GridType::SpaceAxis;
103 
112  CellCoord coordinates(const CellIndex index) const override
113  {
114  assert(index < size());
115  return cell_index_to_coordinates.unaryExpr([index](const auto modulo) {
116  return index % modulo;
117  }) / cell_coordinates_to_index;
118  }
119 
125  CellIndex index(const CellCoord& coordinates) const override
126  {
127  assert(isCell(coordinates));
128  return (coordinates * cell_coordinates_to_index).sum();
129  }
130 
139  CellCoord coordinatesAt(const Point& position) const override
140  {
141  assert(isCellAt(position));
142  return (position / cell).floor().template cast<CellIndex>();
143  }
144 
150  CellIndex indexAt(const Point& position) const override
151  {
152  return index(coordinatesAt(position));
153  }
154 
163  bool isCell(const CellCoord& coordinates) const override
164  {
165  return (coordinates < this->getCellListEnd()).all() &&
166  (coordinates >= CellCoord::Zero()).all();
167  }
168 
177  bool isCellAt(const Point& point) const override
178  {
179  return (point < this->getBox()).all() && (point >= Point::Zero()).all();
180  }
181 
185  CellIndex size() const override { return cell_list_end.prod(); };
186 
191  GridBase(const Point& box, SpaceAxis minimal_cell_dimension)
192  : minimal_cell_dimension(minimal_cell_dimension)
193  {
194  updateCellGrid(box);
195  }
196 
197  protected:
198  const CellCoord& getCellListEnd() const { return cell_list_end; }
199 
200  const Point& getBox() const { return box; }
201 
202  const Point& getCell() const { return cell; }
203 
204  private:
205  CellCoord cell_list_end;
206  SpaceAxis minimal_cell_dimension;
208  Point box;
209  Point cell;
210 
213  CellCoord cell_coordinates_to_index;
216  CellCoord cell_index_to_coordinates;
217 
223  void updateCellGrid(const Point& new_box)
224  {
225  box = new_box;
226  cell_list_end = (box / box.min(minimal_cell_dimension)).floor().template cast<CellIndex>();
227  cell = box / cell_list_end.template cast<SpaceAxis>();
228 
229  // (x, y, z, …) -> (1, x, x*y, …)
230  cell_coordinates_to_index[0] = 1;
231  cell_index_to_coordinates[0] = cell_list_end[0];
232  for (int i = 1; i < TGridType::Dimension; ++i) {
233  cell_coordinates_to_index[i] = cell_list_end[i - 1] * cell_coordinates_to_index[i - 1];
234  cell_index_to_coordinates[i] = cell_list_end[i] * cell_index_to_coordinates[i - 1];
235  }
236  }
237 };
238 
244 template <typename TGridType>
245 class FixedBoundaryGrid : public GridBase<TGridType>, virtual public AbstractNeighborGrid<TGridType>
246 {
247  using Base = GridBase<TGridType>;
248 
249  public:
250  using typename AbstractNeighborGrid<TGridType>::GridType;
251  using typename GridType::CellCoord;
252 
262  bool isNeighborCell(const CellCoord& coordinates, const CellCoord& offset) const
263  {
264  return Base::isCell(coordinates + offset);
265  }
266 
267  using Base::Base; // use parent constructors
268 };
269 
282 template <typename TGridType>
283 class PeriodicBoundaryGrid : public GridBase<TGridType>,
284  virtual public AbstractNeighborGrid<TGridType>
285 {
286  using Base = GridBase<TGridType>;
287 
288  public:
289  using GridType = typename AbstractNeighborGrid<TGridType>::GridType;
290  using typename GridType::CellCoord;
291  using typename GridType::CellIndex;
292  using typename GridType::Point;
293  using typename GridType::SpaceAxis;
294 
303  CellCoord coordinates(const CellIndex index) const override { return Base::coordinates(index); }
304 
313  CellIndex index(const CellCoord& coordinates) const override
314  {
315  auto pbc_coordinates = coordinates;
316  auto& boundary_coords = this->getCellListEnd();
317  for (auto i = 0; i < pbc_coordinates.size(); ++i) {
318  if (coordinates[i] < 0) {
319  pbc_coordinates[i] +=
320  boundary_coords[i] * (std::abs(coordinates[i]) / boundary_coords[i] + 1);
321  }
322  else if (coordinates[i] >= boundary_coords[i]) {
323  pbc_coordinates[i] -= boundary_coords[i] * (coordinates[i] / boundary_coords[i]);
324  }
325  }
326  return Base::index(pbc_coordinates);
327  }
328 
337  CellCoord coordinatesAt(const Point& position) const override
338  {
339  assert(isCellAt(position));
340  return (position / this->getCell()).floor().template cast<CellIndex>();
341  }
342 
348  CellIndex indexAt(const Point& position) const override
349  {
350  return this->index(this->coordinatesAt(position));
351  }
352 
361  bool isCell(const CellCoord&) const override { return true; }
362 
371  bool isCellAt(const Point&) const override { return true; }
372 
385  bool isNeighborCell([[maybe_unused]] const CellCoord& coordinates,
386  const CellCoord& offset) const override
387  {
388  return (offset >= neighbours_cell_offset_min).all() &&
389  (offset <= neighbours_cell_offset_max).all();
390  }
391 
392  PeriodicBoundaryGrid(const Point& box, SpaceAxis cell_dimension)
393  : Base(box, cell_dimension)
394  {
395  updateCellGrid();
396  }
397 
398  private:
399  CellCoord neighbours_cell_offset_min;
400  CellCoord neighbours_cell_offset_max;
402 
409  void updateCellGrid()
410  {
411  const auto cell_list_middle = (this->getCellListEnd() - 1).template cast<double>() * 0.5;
412  neighbours_cell_offset_min = -cell_list_middle.floor().template cast<CellIndex>();
413  neighbours_cell_offset_max = cell_list_middle.ceil().template cast<CellIndex>();
414  }
415 };
416 
421 template <bool PBC, class TGridType>
422 using GridBoundary = typename std::conditional<PBC, PeriodicBoundaryGrid<TGridType>,
428 template <bool PBC> using Grid3DBoundary = GridBoundary<PBC, Grid3DType>;
429 using Grid3DFixed = Grid3DBoundary<false>;
430 using Grid3DPeriodic = Grid3DBoundary<true>;
431 } // namespace Grid
432 
439 namespace Container {
449 template <typename TMember, typename TIndex>
450 class DenseContainer : virtual public AbstractContainer<TMember, TIndex>
451 {
452  public:
454  using typename ContainerType::Index;
455  using typename ContainerType::Members;
456 
457  const Members& get(Index index) const override
458  {
459  assert(index >= 0 && index < indexEnd());
460  return container[index];
461  }
462 
463  Members& get(Index index) override
464  {
465  assert(index >= 0 && index < indexEnd());
466  return container[index];
467  }
468 
469  const Members& getEmpty() const override { return empty_set; }
470 
479  std::vector<Index> indices() const override
480  {
481  std::vector<Index> indices;
482  indices.reserve(std::distance(container.begin(), container.end()));
483  auto iterator = container.begin();
484  while ((iterator = std::find_if(iterator, container.end(), [](const auto& members) {
485  return !members.empty();
486  })) != container.end()) {
487  indices.push_back(std::distance(iterator, container.begin()));
488  std::advance(iterator, 1);
489  }
490  return indices;
491  }
492 
493  explicit DenseContainer(std::size_t size)
494  {
495  if (size >= max_container_size) {
496  faunus_logger->error("Size of the cell list container is too large! \n"
497  "Try using a sparse version (i.e. dense: false)");
498  throw std::runtime_error("cell list `container` size too large");
499  }
500  container.resize(size);
501  }
502 
503  protected:
504  Index indexEnd() const { return container.size(); }
505 
506  private:
507  const std::size_t max_container_size = 1000000000;
508  const Members empty_set;
509  std::vector<Members> container;
510 };
511 
520 template <typename TMember, typename TIndex>
521 class SparseContainer : virtual public AbstractContainer<TMember, TIndex>
522 {
523  public:
525  using typename ContainerType::Index;
526  using typename ContainerType::Members;
527 
528  const Members& get(Index index) const override
529  {
530  assert(index >= 0 && index < indexEnd());
531  try {
532  return container.at(index);
533  }
534  catch (std::out_of_range& e) {
535  return empty_set;
536  }
537  }
538 
539  Members& get(Index index) override
540  {
541  assert(index >= 0 && index < indexEnd());
542  try {
543  return container.at(index);
544  }
545  catch (std::out_of_range& e) {
546  [[maybe_unused]] auto [iterator, flag] = container.emplace(index, Members{});
547  return iterator->second;
548  }
549  }
550 
551  const Members& getEmpty() const override { return empty_set; }
552 
560  std::vector<Index> indices() const override
561  {
562  std::vector<Index> indices;
563  indices.reserve(std::distance(container.begin(), container.end()));
564  std::transform(container.begin(), container.end(), back_inserter(indices),
565  [](const auto& pair) { return pair.first; });
566  return indices;
567  }
568 
569  explicit SparseContainer(std::size_t size)
570  : index_end(size)
571  {
572  }
573 
574  protected:
575  Index indexEnd() const { return index_end; }
576 
577  private:
578  Index index_end;
579  const Members empty_set;
580  std::unordered_map<Index, Members> container;
581 };
582 
589 template <class TContainer> class Container : public TContainer
590 {
591  public:
592  using ContainerType = ContainerTypeOf<TContainer>;
593  using Member = MemberOf<ContainerType>;
594  using Index = IndexOf<ContainerType>;
595 
596  void insert(const Member& member, const Index index_new)
597  {
598  assert(index_new < this->indexEnd());
599  this->get(index_new).push_back(member);
600  }
601 
602  void erase(const Member& member, const Index index_old)
603  {
604  assert(index_old < this->indexEnd());
605  auto& members = this->get(index_old);
606  // std::erase_if available in C++20
607  auto remove_it = std::remove(members.begin(), members.end(), member);
608  members.erase(remove_it, members.end());
609  // end of std::erase_if
610  }
611 
612  void move(const Member& member, const Index index_old, const Index index_new)
613  {
614  erase(member, index_old);
615  insert(member, index_new);
616  }
617 
618  using TContainer::TContainer; // use parent constructor
619 };
620 
621 } // namespace Container
622 
631 template <class TContainer, class TGrid>
633  : protected TGrid,
634  protected TContainer,
635  virtual public AbstractImmutableCellList<ContainerTypeOf<TContainer>, GridTypeOf<TGrid>>
636 {
637  public:
638  using AbstractCellList =
640  using Grid = TGrid;
641  using Container = TContainer;
642  using typename AbstractCellList::CellCoord;
643  using typename AbstractCellList::CellIndex;
644  using typename AbstractCellList::GridType;
645  using typename AbstractCellList::Member;
646  using typename AbstractCellList::Members;
647 
653  const Members& getMembers(const CellCoord& cell_coordinates) override
654  {
655  return this->get(this->index(cell_coordinates));
656  }
657 
664  const Members& getNeighborMembers(const CellCoord& cell_coordinates,
665  const CellCoord& cell_offset) override
666  {
667  if (this->isNeighborCell(cell_coordinates, cell_offset)) {
668  return getMembers(cell_coordinates + cell_offset);
669  }
670  else {
671  return getEmpty();
672  }
673  }
674 
678  std::vector<CellCoord> getCells() const override
679  {
680  const auto indices = this->indices();
681  return std::views::all(indices) |
682  std::views::transform([this](auto index) { return this->coordinates(index); }) |
683  ranges::to_vector;
684  }
685 
689  CellIndex gridSize() const override { return Grid::size(); }
690 
698  const TGrid& getGrid() { return *this; }
699 
704  explicit CellListBase(const TGrid& cell_grid)
705  : Grid(cell_grid)
706  , Container(cell_grid.size())
707  {
708  }
709 
715  CellListBase(const typename TGrid::Point& box, const typename TGrid::SpaceAxis cell_dimension)
716  : Grid(box, cell_dimension)
717  , Container(Grid::size())
718  {
719  }
720 
721  protected:
722  // const auto& getMembers(const CellIndex cell_index) const { return this->get(cell_index); }
723  // auto& getMembers(const CellIndex cell_index) { return this->get(cell_index); }
724  // const auto& getEmptyCell() const { return this->getEmpty(); }
725 
726  using Container::erase;
727  using Container::get;
728  using Container::getEmpty;
729  using Container::insert;
730  using Container::move;
731 };
732 
736 template <typename TMember, class TGrid,
737  template <typename, typename> class TCellList = CellListBase,
738  template <typename, typename> class TContainer = Container::DenseContainer>
739 using CellListType =
740  TCellList<Container::Container<TContainer<TMember, Grid::IndexOf<TGrid>>>, TGrid>;
741 
750 template <class TContainer, class TGrid>
752  : public CellListBase<TContainer, TGrid>,
753  virtual public AbstractSortableCellList<ContainerTypeOf<TContainer>, GridTypeOf<TGrid>>
754 {
756 
757  public:
759  GridTypeOf<TGrid>>::AbstractCellList;
760  using Grid = TGrid;
761  using Container = TContainer;
762  using typename AbstractCellList::CellCoord;
763  using typename AbstractCellList::CellIndex;
764  using typename AbstractCellList::Member;
765  using typename AbstractCellList::Members;
766 
772  const Members& getSortedMembers(const CellCoord& cell_coordinates) override
773  {
774  return getSorted(this->index(cell_coordinates));
775  }
776 
783  const Members& getNeighborSortedMembers(const CellCoord& cell_coordinates,
784  const CellCoord& cell_offset) override
785  {
786  if (this->isNeighborCell(cell_coordinates, cell_offset)) {
787  return getSortedMembers(cell_coordinates + cell_offset);
788  }
789  else {
790  return this->getEmpty();
791  }
792  }
793 
798  explicit SortableCellList(const GridOf<TBase>& cell_grid)
799  : TBase(cell_grid)
800  {
801  is_sorted.resize(this->size(), false);
802  }
803 
809  SortableCellList(const typename GridOf<TBase>::Point& box,
810  const typename GridOf<TBase>::SpaceAxis cell_dimension)
811  : TBase(box, cell_dimension)
812  {
813  is_sorted.resize(this->size(), false);
814  }
815 
816  protected:
817  void insert(const Member& member, const CellIndex& new_cell_index)
818  {
819  TBase::insert(member, new_cell_index);
820  if (is_sorted[new_cell_index]) {
821  is_sorted[new_cell_index] = false;
822  }
823  }
824 
825  void remove(const Member& member, const CellIndex& old_cell_index)
826  {
827  TBase::remove(member, old_cell_index);
828  if (is_sorted[old_cell_index]) {
829  is_sorted[old_cell_index] = false;
830  }
831  }
832 
838  const Members& getSorted(const CellIndex cell_index)
839  {
840  auto& members = this->get(cell_index);
841  if (!is_sorted[cell_index]) {
842  std::sort(members.begin(), members.end());
843  is_sorted[cell_index] = true;
844  }
845  assert(std::is_sorted(members.begin(), members.end()));
846  return members;
847  }
848 
849  private:
850  // TODO perhaps a map for sparse containers
851  std::vector<bool> is_sorted;
852 };
853 
860 template <class TBase> class CellListReverseMap : public TBase
861 {
862  public:
863  using typename TBase::AbstractCellList;
864  using typename AbstractCellList::CellCoord;
865  using typename AbstractCellList::CellIndex;
866  using typename AbstractCellList::Member;
867  using typename TBase::Container;
868  using typename TBase::Grid;
869 
870  void addMember(const Member& member, const CellCoord& new_cell_coordinates)
871  {
872  this->insert(member, this->index(new_cell_coordinates));
873  }
874 
875  void removeMember(const Member& member)
876  {
877  const auto old_cell_index = member2cell.at(member);
878  this->erase(member, old_cell_index);
879  member2cell.erase(member);
880  }
881 
882  void updateMember(const Member& member, const CellCoord& new_cell_coordinates)
883  {
884  this->update(member, this->index(new_cell_coordinates));
885  }
886 
891  bool containsMember(const Member& member) { return member2cell.count(member) != 0; }
892 
900  template <typename T> void importMembers(CellListReverseMap& source, const T& members)
901  {
902  for (const auto& member : members) {
903  insert(member, source.member2cell[member]);
904  }
905  }
906 
907  using TBase::TBase;
908 
909  protected:
910  void insert(const Member& member, const CellIndex& new_cell_index)
911  {
912  assert(member2cell.count(member) == 0); // FIXME C++20 contains
913  TBase::insert(member, new_cell_index);
914  member2cell.insert({member, new_cell_index});
915  }
916 
917  void update(const Member& member, const CellIndex& new_cell_index)
918  {
919  const auto old_cell_index = member2cell.at(member);
920  if (new_cell_index != old_cell_index) {
921  TBase::move(member, old_cell_index, new_cell_index);
922  member2cell.at(member) = new_cell_index;
923  }
924  }
925 
926  private:
927  // TODO as a vector because size of Particle vector is constant
928  std::map<Member, CellIndex> member2cell;
929 };
930 
937 template <class TBase> class CellListSpatial : public CellListReverseMap<TBase>
938 {
939  public:
941  using typename CellListReverseMap<TBase>::Grid;
944  using typename AbstractCellList::Member;
945  using typename AbstractCellList::GridType::Point;
946 
947  void insertMember(const Member& member, const Point& new_position)
948  {
949  const auto new_cell_index = this->indexAt(new_position);
950  this->insert(member, new_cell_index);
951  }
952 
953  void updateMemberAt(const Member& member, const Point& new_position)
954  {
955  const auto new_cell_index = this->indexAt(new_position);
956  this->update(member, new_cell_index);
957  }
958 
960 };
961 
971 template <typename TCellListMinuend, typename TCellListSubtrahend>
973  : virtual public AbstractSortableCellList<ContainerTypeOf<ContainerOf<TCellListMinuend>>,
974  GridTypeOf<GridOf<TCellListMinuend>>>
975 {
976  using CellListMinuend = TCellListMinuend;
977  using CellListSubtrahend = TCellListSubtrahend;
978 
979  public:
980  using AbstractCellList = typename CellListMinuend::AbstractCellList;
981  using Grid = typename CellListMinuend::Grid;
982  using Container = typename CellListMinuend::Container;
983  using typename AbstractCellList::CellCoord;
984  using typename AbstractCellList::CellIndex;
985  using typename AbstractCellList::Member;
986  using typename AbstractCellList::Members;
987 
988  const Members& getSortedMembers(const CellCoord& cell_coordinates) override
989  {
990  const auto subtrahend_cell = subtrahend->getSortedMembers(cell_coordinates);
991  if (std::size(subtrahend_cell) == 0) {
992  // nothing to subtract
993  return minuend->getSortedMembers(cell_coordinates);
994  }
995  else {
996  const auto cell_index = minuend->getGrid().index(cell_coordinates);
997  auto difference_cell_it = difference_cache.find(cell_index);
998  if (difference_cell_it == difference_cache.end()) {
999  // not cached yet
1000  auto minuend_cell = minuend->getSortedMembers(cell_coordinates);
1001  std::tie(difference_cell_it, std::ignore) =
1002  difference_cache.emplace(cell_index, Members{});
1003  std::set_difference(minuend_cell.begin(), minuend_cell.end(),
1004  subtrahend_cell.begin(), subtrahend_cell.end(),
1005  std::back_inserter(difference_cell_it->second));
1006  }
1007  return difference_cell_it->second;
1008  }
1009  }
1010 
1011  const Members& getMembers(const CellCoord& cell_coordinates) override
1012  {
1013  if (subtrahend->getMembers(cell_coordinates).empty()) {
1014  // avoid difference and soring when not necessary
1015  return minuend->getMembers(cell_coordinates);
1016  }
1017  else {
1018  return getSortedMembers(cell_coordinates);
1019  }
1020  }
1021 
1022  const Members& getNeighborSortedMembers(const CellCoord& cell_coordinates,
1023  const CellCoord& cell_offset) override
1024  {
1025  if (minuend->getGrid().isNeighborCell(cell_coordinates, cell_offset)) {
1026  // avoid difference and soring when not necessary
1027  return getSortedMembers(cell_coordinates + cell_offset);
1028  }
1029  else {
1030  return minuend->getNeighborMembers(cell_coordinates, cell_offset);
1031  }
1032  }
1033 
1034  const Members& getNeighborMembers(const CellCoord& cell_coordinates,
1035  const CellCoord& cell_offset) override
1036  {
1037  if (minuend->getGrid().isNeighborCell(cell_coordinates, cell_offset)) {
1038  return getMembers(cell_coordinates + cell_offset);
1039  }
1040  else {
1041  return minuend->getNeighborMembers(cell_coordinates, cell_offset);
1042  }
1043  }
1044 
1045  CellIndex gridSize() const override { return minuend->gridSize(); }
1046 
1047  auto& getGrid() { return minuend->getGrid(); }
1048 
1049  std::vector<CellCoord> getCells() const override { return minuend->getCells(); }
1050 
1051  CellListDifference(std::shared_ptr<TCellListMinuend> minuend,
1052  std::shared_ptr<TCellListSubtrahend> subtrahend)
1053  : minuend(minuend)
1054  , subtrahend(subtrahend)
1055  {
1056  }
1057 
1058  private:
1059  std::shared_ptr<CellListMinuend> minuend;
1060  std::shared_ptr<CellListSubtrahend> subtrahend;
1061  std::map<CellIndex, Members> difference_cache;
1062 };
1063 
1064 } // namespace Faunus::CellList
CellIndex index(const CellCoord &coordinates) const override
Compute the cell index from the cell coordinates.
Definition: celllistimpl.h:125
Container based on a map suitable for system with a non-uniform or low member density.
Definition: celllistimpl.h:521
Eigen::Vector3d Point
3D vector used for positions, velocities, forces etc.
Definition: coordinates.h:7
std::vector< CellCoord > getCells() const override
Definition: celllistimpl.h:678
const Members & getSorted(const CellIndex cell_index)
Get members in a sorted order.
Definition: celllistimpl.h:838
A mixing returning members in a cell in sorted order, e.g., for lookup or filtering.
Definition: celllistimpl.h:751
CellCoord coordinates(const CellIndex index) const override
Compute the cell coordinates from the cell index.
Definition: celllistimpl.h:112
TIndex Index
the cell index (key) type
Definition: celllist.h:96
const Members & getMembers(const CellCoord &cell_coordinates) override
Gets cell members at given cell coordinates.
Definition: celllistimpl.h:1011
double T
floating point size
Definition: units.h:73
CellIndex size() const override
Definition: celllistimpl.h:185
A basic class for a cell list allowing to keep members organized into a grid.
Definition: celllistimpl.h:632
const Members & getEmpty() const override
Gets cell members of an empty cell. Allows non-existing cells.
Definition: celllistimpl.h:551
CellIndex gridSize() const override
Definition: celllistimpl.h:689
A mixin using spatial coordinates instead of cell coordinates when inserting or removing a member...
Definition: celllistimpl.h:937
CellIndex indexAt(const Point &position) const override
Compute the cell index from the spatial position.
Definition: celllistimpl.h:150
An interface of a container.
Definition: celllist.h:93
const Members & getNeighborMembers(const CellCoord &cell_coordinates, const CellCoord &cell_offset) override
Gets cell members at given cell coordinates.
Definition: celllistimpl.h:1034
A cell grid core class assuming fixed boundary conditions.
Definition: celllistimpl.h:95
std::vector< Index > indices() const override
Return all cell indicis that may contain members.
Definition: celllistimpl.h:560
void insertMember(const Member &member, const Point &new_position)
< point
Definition: celllistimpl.h:947
Containers store members in individual cells with a common minimalistic interface.
Eigen::Array< SpaceAxis, Dimension, 1 > Point
a point in the VDimensional space
Definition: celllist.h:43
CellListBase(const TGrid &cell_grid)
Construct an empty cell list from a grid.
Definition: celllistimpl.h:704
const Members & getMembers(const CellCoord &cell_coordinates) override
< members type
Definition: celllistimpl.h:653
CellIndex index(const CellCoord &coordinates) const override
Compute the cell index from the cell coordinates.
Definition: celllistimpl.h:313
TCellIndex CellIndex
a single coordinate in cell space, e.g., int; also an absolute cell index
Definition: celllist.h:42
typename Grid::CoordOf< GridType > CellCoord
grid (cell) coordinates type
Definition: celllist.h:145
bool isCell(const CellCoord &coordinates) const override
Verifies if coordinates are valid in the grid.
Definition: celllistimpl.h:163
GridBase(const Point &box, SpaceAxis minimal_cell_dimension)
Definition: celllistimpl.h:191
Fixed boundary conditions.
Definition: celllistimpl.h:245
bool isCellAt(const Point &point) const override
Verifies if spatial coordinates are in the box.
Definition: celllistimpl.h:177
const Members & getSortedMembers(const CellCoord &cell_coordinates) override
< members type
Definition: celllistimpl.h:772
Eigen::Array< CellIndex, Dimension, 1 > CellCoord
VDimensional cell coordinates.
Definition: celllist.h:44
TSpaceAxis SpaceAxis
a single coordinate in physical space, e.g., double
Definition: celllist.h:40
const TGrid & getGrid()
Static cast itself to a grid.
Definition: celllistimpl.h:698
Definition: celllist.h:15
typename Container::MemberOf< ContainerType > Member
member type
Definition: celllist.h:143
std::vector< Member > Members
the cell members type
Definition: celllist.h:98
TIndex Index
the cell index (key) type
Definition: celllist.h:96
const Members & getEmpty() const override
Gets cell members of an empty cell. Allows non-existing cells.
Definition: celllistimpl.h:469
const Members & getNeighborSortedMembers(const CellCoord &cell_coordinates, const CellCoord &cell_offset) override
Get members of a neighbor cell in a sorted order.
Definition: celllistimpl.h:783
CellListBase(const typename TGrid::Point &box, const typename TGrid::SpaceAxis cell_dimension)
Construct an empty cell list knowing a box dimension and minimal cell dimension.
Definition: celllistimpl.h:715
std::vector< CellCoord > getCells() const override
Gets indicies of non-empty cells.
Definition: celllistimpl.h:1049
Wrapper of two cell list to efficiently provide difference of members, i.e., members presented in the...
Definition: celllistimpl.h:972
CellCoord coordinatesAt(const Point &position) const override
Compute cell coordinates from a spatial position.
Definition: celllistimpl.h:337
GridTypeOf< TGrid > GridType
abstract grid type
Definition: celllist.h:141
SortableCellList(const typename GridOf< TBase >::Point &box, const typename GridOf< TBase >::SpaceAxis cell_dimension)
Construct an empty cell list knowing a box dimension and minimal cell dimension.
Definition: celllistimpl.h:809
void importMembers(CellListReverseMap &source, const T &members)
Imports members from other list without computing cell coordinates from member positions.
Definition: celllistimpl.h:900
CellCoord coordinatesAt(const Point &position) const override
Compute cell coordinates from a spatial position.
Definition: celllistimpl.h:139
typename Container::MembersOf< ContainerType > Members
members type
Definition: celllist.h:142
typename Container::MembersOf< ContainerType > Members
members type
Definition: celllist.h:142
typename Grid::IndexOf< GridType > CellIndex
grid (cell) index type
Definition: celllist.h:144
bool isCell(const CellCoord &) const override
Verifies if coordinates are valid in the grid.
Definition: celllistimpl.h:361
Periodic boundary conditions.
Definition: celllistimpl.h:283
typename Grid::CoordOf< GridType > CellCoord
grid (cell) coordinates type
Definition: celllist.h:145
std::vector< Member > Members
the cell members type
Definition: celllist.h:98
bool isNeighborCell([[maybe_unused]] const CellCoord &coordinates, const CellCoord &offset) const override
Verifies if offseted coordinates are valid taking into account periodic boundary conditions.
Definition: celllistimpl.h:385
std::vector< Member > Members
the cell members type
Definition: celllist.h:98
Eigen::Array< CellIndex, Dimension, 1 > CellCoord
VDimensional cell coordinates.
Definition: celllist.h:44
Container based on a vector suitable for system with a uniform and high member density.
Definition: celllistimpl.h:450
const Members & getNeighborMembers(const CellCoord &cell_coordinates, const CellCoord &cell_offset) override
Get cell members at given offseted cell coordinates, or empty if offseted dcoordinates do not exist...
Definition: celllistimpl.h:664
const Members & getSortedMembers(const CellCoord &cell_coordinates) override
< members type
Definition: celllistimpl.h:988
CellIndex indexAt(const Point &position) const override
Compute the cell index from the spatial position.
Definition: celllistimpl.h:348
typename Grid::IndexOf< GridType > CellIndex
grid (cell) index type
Definition: celllist.h:144
CellIndex gridSize() const override
Get cells count. Valid cell indices are in the range [0, gridSize).
Definition: celllistimpl.h:1045
bool isNeighborCell(const CellCoord &coordinates, const CellCoord &offset) const
Verifies if offseted coordinates are valid.
Definition: celllistimpl.h:262
Interface of a grid.
Definition: celllistimpl.h:60
Reverse mapping (from particle to its cell) is stored.
Definition: celllistimpl.h:860
std::vector< Index > indices() const override
Return all cell indices that may contain members.
Definition: celllistimpl.h:479
typename Container::MemberOf< ContainerType > Member
member type
Definition: celllist.h:143
An interface of a immutable cell list.
Definition: celllist.h:137
CellCoord coordinates(const CellIndex index) const override
Compute the cell coordinates from the cell index.
Definition: celllistimpl.h:303
bool containsMember(const Member &member)
returns true if member is present in the cell list false if not
Definition: celllistimpl.h:891
An interface to a cell list that can return cell&#39;s members in sorted order.
Definition: celllist.h:168
SortableCellList(const GridOf< TBase > &cell_grid)
Construct an empty cell list from a grid.
Definition: celllistimpl.h:798
bool isCellAt(const Point &) const override
Verifies if spatial coordinates are in the box.
Definition: celllistimpl.h:371