NiHu  2.0
lists.hpp
Go to the documentation of this file.
1 
7 #ifndef NIHU_LISTS_HPP_INCLUDED
8 #define NIHU_LISTS_HPP_INCLUDED
9 
10 #include "cluster_tree.hpp"
11 
12 #include <iostream>
13 #include <iterator>
14 #include <vector>
15 
16 namespace NiHu
17 {
18 namespace fmm
19 {
20 
23 {
24 public:
25  enum {
26  P2P = 0,
27  P2M = 1,
28  L2P = 2,
29  P2L = 3,
30  M2P = 4,
31  M2M = 5,
32  L2L = 6,
33  M2L = 7,
34  Near = 8
35  };
36 
37  typedef std::vector<std::vector<size_t> > list_t;
38 
39 private:
40  static size_t const num_lists = 9;
41  list_t lists[num_lists];
42  static const bool p2l_allowed = false;
43 
44 public:
49  template <class ClusterDerived>
51  {
52  for (size_t i = 0; i < num_lists; ++i)
53  lists[i].resize(tree.get_n_clusters());
54  this->fill_lists(0, tree);
55  }
56 
61  list_t const &get_list(size_t idx) const
62  {
63  return this->lists[idx];
64  }
65 
66 private:
75  template <class ClusterDerived>
76  void add_adjacent_leaves(size_t to, size_t from, cluster_tree<ClusterDerived> const &tree)
77  {
78  if (tree[from].is_leaf())
79  {
80  if (tree[to].is_receiver() && tree[from].is_source())
81  this->lists[P2P][to].push_back(from);
82  if (tree[from].get_level() > tree[to].get_level())
83  if (tree[from].is_receiver() && tree[to].is_source())
84  this->lists[P2P][from].push_back(to);
85  }
86  else
87  {
88  for (auto pc : tree[from].get_children())
89  {
90  if (!interaction_lists::p2l_allowed
91  || tree[to].get_bounding_box().is_adjacent(tree[pc].get_bounding_box()))
92  add_adjacent_leaves(to, pc, tree);
93  else
94  {
95  if (tree[to].is_receiver() && tree[pc].is_source())
96  this->lists[M2P][to].push_back(pc);
97  if (tree[pc].is_receiver() && tree[to].is_source())
98  this->lists[P2L][pc].push_back(to);
99  }
100  }
101  }
102  }
103 
109  template <class ClusterDerived>
110  void fill_lists(size_t root, cluster_tree<ClusterDerived> const &tree)
111  {
112  // the root is in itself's near field
113  if (root == 0)
114  this->lists[Near][root].push_back(root);
115  else
116  {
117  // find the parent's near field
118  for (auto ppn : this->lists[Near][tree[root].get_parent()])
119  {
120  // traverse the parent's near field's children
121  for (auto p : tree[ppn].get_children())
122  {
123  // adjacent cousin : near field
124  if (tree[root].get_bounding_box().is_adjacent(tree[p].get_bounding_box()))
125  this->lists[Near][root].push_back(p);
126  else // non-adjacent cousin: interaction list
127  if (tree[root].is_receiver() && tree[p].is_source())
128  this->lists[M2L][root].push_back(p);
129  }
130  }
131  }
132 
133  if (tree[root].is_leaf())
134  for (auto pc : this->lists[Near][root])
135  add_adjacent_leaves(root, pc, tree);
136  else
137  {
138  for (auto pc : tree[root].get_children())
139  {
140  if (tree[root].get_level() >= 2)
141  {
142  if (tree[root].is_source())
143  this->lists[M2M][root].push_back(pc);
144  if (tree[root].is_receiver())
145  this->lists[L2L][pc].push_back(root);
146  }
147 
148  fill_lists(pc, tree);
149  }
150  }
151  }
152 
153 public:
157  void print_debug(std::ostream &os = std::cout)
158  {
159  std::ostream_iterator<size_t> out_it(os, ", ");
160 
161  for (size_t c = 0; c < this->lists[0].size(); ++c)
162  {
163  std::cout << c << std::endl;
164  os << "(M2L): ";
165  std::copy(this->lists[M2L][c].begin(), this->lists[M2L][c].end(), out_it);
166  os << std::endl;
167 
168  os << "(M2P): ";
169  std::copy(this->lists[M2P][c].begin(), this->lists[M2P][c].end(), out_it);
170  os << std::endl;
171 
172  os << "(P2L): ";
173  std::copy(this->lists[P2L][c].begin(), this->lists[P2L][c].end(), out_it);
174  os << std::endl;
175 
176  os << "(P2P): ";
177  std::copy(this->lists[P2P][c].begin(), this->lists[P2P][c].end(), out_it);
178  os << std::endl;
179  }
180  }
181 };
182 
183 } // end of namespace fmm
184 } // end of namespace NiHu
185 
186 #endif /* NIHU_LISTS_HPP_INCLUDED */
NiHu::fmm::cluster_tree::get_n_clusters
size_t get_n_clusters() const
return number of clusters
Definition: cluster_tree.hpp:282
NiHu::fmm::interaction_lists::interaction_lists
interaction_lists(cluster_tree< ClusterDerived > const &tree)
constructor from cluster tree
Definition: lists.hpp:50
NiHu::fmm::interaction_lists::get_list
const list_t & get_list(size_t idx) const
return a selected list
Definition: lists.hpp:61
NiHu::fmm::cluster_tree
Class representing a cluster tree.
Definition: cluster_tree.hpp:33
cluster_tree.hpp
Implementation of class NiHu::fmm::cluster_tree.
NiHu::fmm::interaction_lists::print_debug
void print_debug(std::ostream &os=std::cout)
print debug information of the lists to a stream
Definition: lists.hpp:157
NiHu::fmm::interaction_lists
class storing the different interaction lists of a tree
Definition: lists.hpp:22