Utopia  2
Framework for studying models of complex & adaptive systems.
hexagonal.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_CORE_GRIDS_HEXAGONAL_HH
2 #define UTOPIA_CORE_GRIDS_HEXAGONAL_HH
3 
4 #include "base.hh"
5 
6 namespace Utopia {
13 
47 template<class Space>
49  : public Grid<Space>
50 {
51 public:
53  using Base = Grid<Space>;
54 
56  static constexpr DimType dim = Space::dim;
57 
59  using SpaceVec = typename Space::SpaceVec;
60 
63 
66 
67 
68 private:
69  // -- HexagonalGrid-specific members --------------------------------------
72 
74 
77 
78 public:
79  // -- Constructors --------------------------------------------------------
81 
84  HexagonalGrid (std::shared_ptr<Space> space, const Config& cfg)
85  :
86  Base(space, cfg),
89  {
90  // Make sure the cells really are hexagonal
91  static_assert(dim == 2, "Hexagonal grid is only implemented for 2D "
92  "space!");
93 
94  const SpaceVec eff_res = effective_resolution();
95 
96  // check that the cell extent corresponds to that of pointy-topped
97  // hexagonal cells
98  // NOTE the test only requires the aspect ratio is precise to 2% for
99  // easy user experience. The hexagonal grid requires a space
100  // with an aspect ratio involving a sqrt(3)
101  if ( fabs(_cell_extent[0] / _cell_extent[1] - sqrt(3.) / 2.)
102  > get_as<double>("aspect_ratio_tolerance", cfg, 0.02))
103  {
104  SpaceVec required_space = SpaceVec({1., 0.75 * 2. / sqrt(3.)});
105  required_space[0] = this->_space->extent[0];
106  required_space[1] = _shape[1] * _cell_extent[0] * 1.5 /sqrt(3.);
107  std::stringstream required_space_ss;
108  required_space_ss << required_space;
109 
110  throw std::invalid_argument(fmt::format(
111  "Given the extent of the physical space and the specified "
112  "resolution, a mapping with hexagonal cells could not be "
113  "found! Either adjust the the extent of physical space or the "
114  "resolution of the grid. Alternatively increase the tolerance "
115  "to distorted hexagons or choose another grid. \n"
116  "The required aspect ratio of sqrt(3) / 2 is violated by {} "
117  "(> `aspect_ratio_tolerance` = {})! \n"
118  "With the given resolution, set the space extent to : \n"
119  "{} or increase the resolution.",
120  fabs(_cell_extent[0] / _cell_extent[1] - sqrt(3.) / 2.),
121  get_as<double>("aspect_ratio_tolerance", cfg, 0.02),
122  required_space_ss.str()
123  ));
124 
125  }
126  }
127 
128 
129  // -- Implementations of virtual base class functions ---------------------
130  // .. Number of cells & shape .............................................
131 
133 
135  IndexType num_cells() const override {
136  return _shape[0] * _shape[1];
137  }
138 
140  SpaceVec effective_resolution() const override {
141  return SpaceVec({static_cast<double>(_shape[0]), 0.75*_shape[1]})
142  / this->_space->extent;
143  }
144 
146  MultiIndex shape() const override {
147  return _shape;
148  }
149 
151  GridStructure structure() const override {
153  }
154 
155 
156  // .. Position-related methods ............................................
158 
160  MultiIndex midx_of(const IndexType id) const override {
161  return MultiIndex({id % _shape[0], id / _shape[0]});
162  }
163 
165 
167  SpaceVec barycenter_of(const IndexType id) const override {
168  MultiIndex mid = midx_of(id);
169  if (mid[1] % 2 == 0) {
170  // even row
171  return (mid % SpaceVec({1., 0.75}) + SpaceVec({1., 0.5}))
172  % _cell_extent;
173  }
174  else {
175  // odd row
176  return ( (mid % SpaceVec({1, 0.75}) + SpaceVec({0.5, 0.5}))
177  % _cell_extent);
178  }
179  }
180 
182 
186  SpaceVec extent_of(const IndexType) const override {
187  return _cell_extent;
188  }
189 
191 
197  std::vector<SpaceVec> vertices_of(const IndexType id) const override {
198  std::vector<SpaceVec> vertices{};
199  vertices.reserve(6);
200 
201  const SpaceVec center = barycenter_of(id);
202 
203  vertices.push_back(center + SpaceVec({-0.5, -0.25}) % _cell_extent);
204  vertices.push_back(center + SpaceVec({ 0. , -0.5 }) % _cell_extent);
205  vertices.push_back(center + SpaceVec({ 0.5, -0.25}) % _cell_extent);
206  vertices.push_back(center + SpaceVec({ 0.5, 0.25}) % _cell_extent);
207  vertices.push_back(center + SpaceVec({ 0. , 0.5 }) % _cell_extent);
208  vertices.push_back(center + SpaceVec({-0.5, 0.25}) % _cell_extent);
209 
210  return vertices;
211  }
212 
214 
248  IndexType cell_at(const SpaceVec& pos) const override {
249  SpaceVec ridx = pos;
250  // check position
251  if (this->is_periodic()) {
252  ridx = this->_space->map_into_space(pos);
253  }
254  else if (not this->_space->contains(pos)) {
255  throw std::invalid_argument("The given position is outside "
256  "the non-periodic space associated with this grid!");
257  }
258 
259  // relative and centered in cell 0
260  ridx = ridx / _cell_extent - SpaceVec({1., 0.5});
261 
262  arma::Col<int>::fixed<dim> midx = {
263  static_cast<int>(std::round(ridx[0] + 2. / 3. * ridx[1])),
264  static_cast<int>(std::round(4. / 3. * ridx[1]))
265  };
266 
267  // correct for offset
268  midx[0] -= std::floor(midx[1] / 2.);
269 
270  if (not this->is_periodic()) {
271  // remap not represented space to first cell in this row
272  // NOTE this distorts the cells, but the rectangular space is
273  // correctly represented
274  if (midx[0] == -1) {
275  midx[0]++;
276  }
277  if (midx[1] == -1) {
278  midx[1]++;
279  }
280 
281  // Associate points on high-value boundaries with boundary cells
282  if (midx[0] == static_cast<int>(_shape[0])) {
283  midx[0]--;
284  }
285  }
286  else {
287  midx[0] = (midx[0] + _shape[0]) % _shape[0];
288  midx[1] = (midx[1] + _shape[1]) % _shape[1];
289  }
290 
291  // From the multi index, calculate the corresponding ID
292  return static_cast<IndexType>(midx[0] + (midx[1] * _shape[0]));
293  // Equivalent to:
294  // midx[0] * id_shift<0>()
295  // + midx[1] * id_shift<1>()
296  }
297 
299 
307  std::set<IndexType> boundary_cells(std::string select="all") const override
308  {
309  if ( select != "all"
310  and select != "left" and select != "right"
311  and select != "bottom" and select != "top")
312  {
313  throw std::invalid_argument("Invalid value for argument "
314  "`select` in call to method SquareGrid::boundary_cells! "
315  "Available arguments (for currently selected "
316  "dimensionality) are: "
317  "'all', 'left', 'right', 'bottom', 'top'. Given value: '"
318  + select + "'");
319  }
320 
321  // The target set all IDs are to be emplaced in
322  std::set<IndexType> bc_ids;
323 
324  // For periodic space, this is easy:
325  if (this->is_periodic()) {
326  return {};
327  }
328 
329  // NOTE It is important to use the hinting features of std::set
330  // here, which allow to run the following in amortized
331  // constant time instead of logarithmic with set size.
332  // Below, it always makes sense to hint at inserting right
333  // before the end.
334  // Hint for the first element needs to be the beginning
335  auto hint = bc_ids.begin();
336 
337  // Bottom boundary (lowest IDs)
338  if (select == "all" or select == "bottom") {
339  // 0, ..., _shape[0] - 1
340  for (DistType id = 0; id < _shape[0]; id++) {
341  bc_ids.emplace_hint(hint, id);
342  hint = bc_ids.end();
343  }
344  }
345 
346  // Left boundary
347  if (select == "left") {
348  // First IDs in _shape[1] rows: 0, _shape[0], 2*_shape[0], ...
349  for (DistType row = 0; row < _shape[1]; row++) {
350  bc_ids.emplace_hint(hint, row * _shape[0]);
351  hint = bc_ids.end();
352  }
353  }
354 
355  // Right boundary
356  if (select == "right") {
357  // Last IDs in _shape[1] rows
358  const auto offset = _shape[0] - 1;
359 
360  for (DistType row = 0; row < _shape[1]; row++) {
361  bc_ids.emplace_hint(hint, offset + row * _shape[0]);
362  hint = bc_ids.end();
363  }
364  }
365 
366  // Left AND right (only for 'all' case, allows better hints)
367  if (select == "all") {
368  // First and last IDs in _shape[1] rows
369  const auto offset = _shape[0] - 1;
370 
371  for (DistType row = 0; row < _shape[1]; row++) {
372  // Left boundary cell
373  bc_ids.emplace_hint(hint, row * _shape[0]);
374 
375  // Right boundary cell (higher than left cell ID)
376  bc_ids.emplace_hint(bc_ids.end(),
377  offset + row * _shape[0]);
378 
379  hint = bc_ids.end();
380  }
381  }
382 
383  // Top boundary (highest IDs)
384  if (select == "all" or select == "top") {
385  // _shape[0] * (_shape[1]-1), ..., _shape[0] * _shape[1] - 1
386  for (DistType id = _shape[0] * (_shape[1]-1);
387  id < _shape[0] * _shape[1]; id++)
388  {
389  bc_ids.emplace_hint(hint, id);
390  hint = bc_ids.end();
391  }
392  }
393 
394  return bc_ids;
395  }
396 
397 
398 private:
399  // -- Helper functions ----------------------------------------------------
401 
415 
416  // obtain the sidelength of a unit area hexagon
417  // A = 3^1.5 / 2 s^2
418  double s = sqrt(2. / (3 * sqrt(3)));
419  double width = sqrt(3) * s;
420  double height = 2 * s;
421 
422  shape[0] = std::round( this->_space->extent[0] / width
423  * this->_resolution);
424  shape[1] = std::round( this->_space->extent[1] / (0.75 * height)
425  * this->_resolution);
426 
427  // in non periodic space pair number of rows required
428  if (this->is_periodic()) {
429  shape[1] = shape[1] - shape[1] % 2;
430  }
431 
432  return shape;
433  }
434 
435 
436 protected:
437  // -- Neighborhood interface ----------------------------------------------
440  const Config& nb_params) override
441  {
442  if (nb_mode == NBMode::empty) {
443  return this->_nb_empty;
444  }
445  else if (nb_mode == NBMode::hexagonal) {
447  }
448  else {
449  throw std::invalid_argument("No '" + nb_mode_to_string(nb_mode)
450  + "' neighborhood available for HexagonalGrid! "
451  "Available modes: empty, hexagonal.");
452  }
453  }
454 
457  const Config&) const override
458  {
459  if (nb_mode == NBMode::empty) {
460  return 0;
461  }
462  else if (nb_mode == NBMode::hexagonal) {
463  return 6;
464  }
465  else {
466  throw std::invalid_argument("No '" + nb_mode_to_string(nb_mode)
467  + "' neighborhood available for HexagonalGrid! "
468  "Available modes: empty, hexagonal.");
469  }
470  }
471 
472 
473  // .. Neighborhood implementations ........................................
474  // NOTE With C++20, the below lambdas would allow template arguments
475 
476  // .. hexagonal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
477 
479 
493  // Extract the optional distance parameter
494  constexpr bool check_shape = true;
495  const auto distance = get_nb_param_distance<check_shape>(nb_params);
496 
497  // For distance 1, use the specialized functions which are defined as
498  // class members (to don't bloat this method even more). Those
499  // functions do not require any calculation or capture that goes beyond
500  // the capture of ``this``.
501  if (distance <= 1) {
502  if (this->is_periodic()) {
503  return _nb_hexagonal_periodic;
504  }
505  else {
507  }
508  }
509  // else: distance is > 1. Depending on periodicity of the grid, define
510  // the relevant lambda and let it capture as many values as possible in
511  // order to avoid recomputation.
512 
513  throw std::invalid_argument(fmt::format(
514  "Hexagonal neighborhood is not implemented for a "
515  "distance larger than 1. Requested distance was {}.",
516  distance
517  ));
518  }
519 
520 
523  [this](const IndexType root_id)
524  {
525  // Instantiate container in which to store the neighboring cell IDs
526  IndexContainer neighbor_ids{};
527 
528  // The number of neighbors is known; pre-allocating space brings a
529  // speed improvement of about factor 2.
530  neighbor_ids.reserve(3 * dim);
531 
532  // Depending on the number of dimensions, add the IDs of neighboring
533  // cells in those dimensions
534  add_neighbors_in_<0, true>(root_id, neighbor_ids);
535  add_neighbors_in_<1, true>(root_id, neighbor_ids);
536  add_neighbors_in_<2, true>(root_id, neighbor_ids);
537 
538  // Return the container of cell indices
539  return neighbor_ids;
540  };
541 
542 
545  [this](const IndexType root_id)
546  {
547  // Instantiate container in which to store the neighboring cell IDs
548  IndexContainer neighbor_ids{};
549 
550  // The number of neighbors is known; pre-allocating space brings a
551  // speed improvement of about factor 2
552  neighbor_ids.reserve(2 * dim);
553 
554  // Depending on the number of dimensions, add the IDs of neighboring
555  // cells in those dimensions
556  add_neighbors_in_<0, false>(root_id, neighbor_ids);
557  add_neighbors_in_<1, false>(root_id, neighbor_ids);
558  add_neighbors_in_<2, false>(root_id, neighbor_ids);
559 
560  // Return the container of cell indices
561  return neighbor_ids;
562  };
563 
564 
565  // .. Neighborhood helper functions .......................................
566 
568 
584  template<DimType axis, bool periodic>
585  void add_neighbors_in_(const IndexType root_id,
586  IndexContainer& neighbor_ids) const
587  {
588  // Assure the number of dimensions is supported
589  static_assert(axis < 3);
590 
591  // left and right
592  if constexpr (axis == 0) {
593  // Compute a normalized id
594  const IndexType nrm_id = root_id % _shape[0];
595 
596  // Check if at low value boundary
597  if (nrm_id == 0) {
598  // left most column
599  if constexpr (periodic) {
600  neighbor_ids.push_back(root_id - 1 + _shape[0]);
601  }
602  // else: not periodic; nothing to add here
603  }
604  else {
605  // Not at boundary; no need for the correction term
606  neighbor_ids.push_back(root_id - 1);
607  }
608 
609  // Check if at high value boundary
610  if (nrm_id == _shape[0] - 1) {
611  // right most column
612  if constexpr (periodic) {
613  neighbor_ids.push_back(root_id + 1 - _shape[0]);
614  }
615  // else: not periodic; nothing to add here
616  }
617  else {
618  // Not at boundary; no need for the correction term
619  neighbor_ids.push_back(root_id + 1);
620  }
621  }
622  // top-left and bottom-right
623  else if constexpr (axis == 1) {
624  // Compute normalized ids
625  const IndexType nrm_id_0 = root_id % _shape[0]; // column
626  const IndexType nrm_id_1 = ( (root_id % (_shape[0] * _shape[1]))
627  / _shape[0]); // row
628 
629  // Check if at low value boundary
630  if (nrm_id_1 == 0) {
631  // bottom row
632  if constexpr (periodic) {
633  if (nrm_id_0 < _shape[0] - 1) {
634  neighbor_ids.push_back( root_id - _shape[0] + 1
635  + _shape[0] * _shape[1]);
636  }
637  else {
638  // also right most
639  neighbor_ids.push_back( root_id - 2*_shape[0] + 1
640  + _shape[0] * _shape[1]);
641  }
642  }
643  // else: not periodic; nothing to add here
644  }
645  else if (nrm_id_0 == _shape[0] - 1 and nrm_id_1 % 2 == 0) {
646  // right column, offset rows
647  if constexpr (periodic) {
648  neighbor_ids.push_back(root_id - 2*_shape[0] + 1);
649  }
650  // else: not periodic; nothing to add here
651  }
652  else if (nrm_id_1 % 2 == 0) {
653  // offset row
654  // Not at boundary; no need for the correction term
655  neighbor_ids.push_back(root_id - _shape[0] + 1);
656  }
657  else {
658  // non-offset row
659  neighbor_ids.push_back(root_id - _shape[0]);
660  }
661 
662  // Check if at high value boundary
663  if (nrm_id_1 == _shape[1] - 1) {
664  // top row
665  if constexpr (periodic) {
666  if (nrm_id_0 > 0) {
667  // is an non-offset row
668  neighbor_ids.push_back( root_id + _shape[0] - 1
669  - _shape[0] * _shape[1]);
670  }
671  else {
672  // left most cell
673  neighbor_ids.push_back( root_id + 2*_shape[0] - 1
674  - _shape[0] * _shape[1]);
675  }
676  }
677  // else: not periodic; nothing to add here
678  }
679  else if (nrm_id_0 == 0 and nrm_id_1 % 2 == 1){
680  // left column impair row
681  if constexpr (periodic) {
682  neighbor_ids.push_back(root_id + 2*_shape[0] - 1);
683  }
684  }
685  else if (nrm_id_1 % 2 == 0) {
686  // Not at boundary; no need for the correction term
687  neighbor_ids.push_back(root_id + _shape[0]);
688  }
689  else {
690  // non-offset row
691  neighbor_ids.push_back(root_id + _shape[0] - 1);
692  }
693  }
694  // top right and bottom left
695  else {
696  // Compute normalized ids
697  const IndexType nrm_id_0 = root_id % _shape[0]; // column
698  const IndexType nrm_id_1 = ( (root_id % (_shape[0] * _shape[1]))
699  / _shape[0]); // row
700 
701  if (nrm_id_1 == 0) {
702  // bottom row
703  if constexpr (periodic) {
704  neighbor_ids.push_back( root_id - _shape[0]
705  + _shape[0] * _shape[1]);
706  }
707  // else: not periodic; nothing to add here
708  }
709  else if (nrm_id_0 == 0 and nrm_id_1 % 2 == 1) {
710  // left most, non-offset row
711  if constexpr (periodic) {
712  neighbor_ids.push_back(root_id - 1);
713  }
714  // else: not periodic; nothing to add here
715  }
716  else if (nrm_id_1 % 2 == 1) {
717  neighbor_ids.push_back(root_id - _shape[0] - 1);
718  }
719  else {
720  neighbor_ids.push_back(root_id - _shape[0]);
721  }
722 
723  if (nrm_id_1 == _shape[1] - 1) {
724  // top row
725  if constexpr (periodic) {
726  neighbor_ids.push_back( root_id + _shape[0]
727  - _shape[0] * _shape[1]);
728  }
729  // else: not periodic; nothing to add here
730  }
731  else if (nrm_id_0 == _shape[0] - 1 and nrm_id_1 % 2 == 0) {
732  // right column in offset row
733  if constexpr (periodic) {
734  neighbor_ids.push_back(root_id + 1);
735  }
736  // else: not periodic; nothing to add here
737  }
738  else if (nrm_id_1 % 2 == 0) {
739  neighbor_ids.push_back(root_id + _shape[0] + 1);
740  }
741  else {
742  neighbor_ids.push_back(root_id + _shape[0]);
743  }
744  }
745  }
746 
747 
748  // .. Neighborhood parameter extraction helpers ...........................
749 
751 
763  template<bool check_shape=false>
764  DistType get_nb_param_distance(const Config& params) const {
765  const auto distance = get_as<DistType>("distance", params, 1);
766 
767  // Check the value is smaller than the grid shape. It needs to fit into
768  // the shape of the grid, otherwise all the algorithms above would have
769  // to check for duplicate entries and be set-based, which would be
770  // very inefficient.
771  if constexpr (check_shape) {
772  if ( this->is_periodic()
773  and (distance * 2 + 1 > this->shape().min()))
774  {
775  // To inform about the grid shape, print it to the stringstream
776  // and include it in the error message below.
777  std::stringstream shape_ss;
778  this->shape().print(shape_ss, "Grid Shape:");
779 
780  throw std::invalid_argument("The grid shape is too small to "
781  "accomodate a neighborhood with 'distance' parameter set "
782  "to " + get_as<std::string>("distance", params, "1")
783  + " in a periodic space!\n" + shape_ss.str());
784  }
785  }
786 
787  return distance;
788  }
789 };
790 
791 
792 // end group CellManager
797 } // namespace Utopia
798 
799 #endif // UTOPIA_CORE_GRIDS_HEXAGONAL_HH
The base class for all grid discretizations used by the CellManager.
Definition: base.hh:99
bool is_periodic() const
Whether the space this grid maps to is periodic.
Definition: base.hh:304
const NBMode & nb_mode() const
Const reference to the currently selected neighborhood mode.
Definition: base.hh:198
const std::shared_ptr< Space > _space
The space that is to be discretized.
Definition: base.hh:120
const Config & nb_params() const
The neighborhood parameters of the currently selected neighborhood.
Definition: base.hh:203
NBFuncID< Self > _nb_empty
A neighborhood function for empty neighborhood.
Definition: base.hh:323
const std::shared_ptr< Space > & space() const
Const reference to the space this grid maps to.
Definition: base.hh:299
DataIO::Config Config
The configuration type.
Definition: base.hh:114
A grid discretization using hexagonal cells.
Definition: hexagonal.hh:50
typename Space::SpaceVec SpaceVec
The type of vectors that have a relation to physical space.
Definition: hexagonal.hh:59
HexagonalGrid(std::shared_ptr< Space > space, const Config &cfg)
Construct a hexagonal grid discretization.
Definition: hexagonal.hh:84
MultiIndex shape() const override
Get shape of the hexagonal grid.
Definition: hexagonal.hh:146
NBFuncID< Base > get_nb_func(NBMode nb_mode, const Config &nb_params) override
Retrieve the neighborhood function depending on the mode.
Definition: hexagonal.hh:439
SpaceVec extent_of(const IndexType) const override
Returns the extent of the cell with the given ID.
Definition: hexagonal.hh:186
NBFuncID< Base > _nb_hexagonal_nonperiodic
The Von-Neumann neighborhood for non-periodic grids.
Definition: hexagonal.hh:544
const SpaceVec _cell_extent
The extent of each cell of this discretization (same for all)
Definition: hexagonal.hh:76
MultiIndex determine_shape() const
Get shape of the hexagonal grid.
Definition: hexagonal.hh:413
void add_neighbors_in_(const IndexType root_id, IndexContainer &neighbor_ids) const
Add both direct neighbors to a container of indices.
Definition: hexagonal.hh:585
GridStructure structure() const override
Structure of the grid.
Definition: hexagonal.hh:151
NBFuncID< Base > get_nb_func_hexagonal(const Config &nb_params)
Returns a standalone hexagonal neighborhood function.
Definition: hexagonal.hh:492
IndexType num_cells() const override
Number of hexagonal cells required to fill the physical space.
Definition: hexagonal.hh:135
std::set< IndexType > boundary_cells(std::string select="all") const override
Retrieve a set of cell indices that are at a specified boundary.
Definition: hexagonal.hh:307
SpaceVec effective_resolution() const override
The effective cell resolution into each physical space dimension.
Definition: hexagonal.hh:140
static constexpr DimType dim
The dimensionality of the space to be discretized (for easier access)
Definition: hexagonal.hh:56
const MultiIndex _shape
The (multi-index) shape of the grid, resulting from resolution.
Definition: hexagonal.hh:71
DistType expected_num_neighbors(const NBMode &nb_mode, const Config &) const override
Computes the expected number of neighbors for a neighborhood mode.
Definition: hexagonal.hh:456
SpaceVec barycenter_of(const IndexType id) const override
Returns the barycenter of the cell with the given ID.
Definition: hexagonal.hh:167
std::vector< SpaceVec > vertices_of(const IndexType id) const override
Returns the vertices of the cell with the given ID.
Definition: hexagonal.hh:197
DistType get_nb_param_distance(const Config &params) const
Extract the distance neighborhood parameter from the given config.
Definition: hexagonal.hh:764
MultiIndexType< dim > MultiIndex
The type of multi-index like arrays, e.g. the grid shape.
Definition: hexagonal.hh:62
NBFuncID< Base > _nb_hexagonal_periodic
The Von-Neumann neighborhood for periodic grids.
Definition: hexagonal.hh:522
IndexType cell_at(const SpaceVec &pos) const override
Return the ID of the cell covering the given point in physical space.
Definition: hexagonal.hh:248
MultiIndex midx_of(const IndexType id) const override
Returns the multi-index of the cell with the given ID.
Definition: hexagonal.hh:160
NBMode
Possible neighborhood types; availability depends on choice of grid.
Definition: base.hh:52
std::string nb_mode_to_string(const NBMode &nb_mode)
Given an NBMode enum value, return the corresponding string key.
Definition: base.hh:78
GridStructure
Available grid implementations.
Definition: base.hh:13
std::function< IndexContainer(const IndexType)> NBFuncID
Type of the neighborhood calculating function.
Definition: base.hh:92
@ hexagonal
The hexagonal neighbourhood, i.e. the neighbourhood on a hexagonal grid.
@ empty
Every entity is utterly alone in the world.
@ hexagonal
A hexagonal lattice grid.
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
@ vertices
Iterate over vertices.
Definition: agent.hh:11
arma::Col< IndexType >::fixed< dim > MultiIndexType
Type for index type vectors that are associated with a physical space.
Definition: types.hh:53
std::vector< IndexType > IndexContainer
Type for container of indices.
Definition: types.hh:43
unsigned short DimType
Type for dimensions, i.e. very small unsigned integers.
Definition: types.hh:34
unsigned int DistType
Type for distancens, i.e. intermediately long unsigned integers.
Definition: types.hh:37
std::size_t IndexType
Type for indices, i.e. values used for container indexing, agent IDs, ...
Definition: types.hh:40
SpaceVecType< dim > SpaceVec
The type for vectors relating to physical space.
Definition: space.hh:33
static constexpr std::size_t dim
The dimensionality of the space.
Definition: space.hh:30