7 #ifndef NIHU_LEAF_PRECOMPUTE_HPP_INCLUDED
8 #define NIHU_LEAF_PRECOMPUTE_HPP_INCLUDED
14 #include <Eigen/SparseCore>
16 #ifdef NIHU_FMM_PARALLEL
22 #include <type_traits>
31 template <
class Result,
class FmmTag>
35 template <
class Result>
40 typedef Result result_t;
42 typedef unsigned int index_t;
43 typedef std::vector<index_t> indices_t;
44 typedef std::vector<result_t> container_t;
46 template <
class Operator,
class ClusterDerived>
48 : m_pcontainer(
new container_t(tree.get_leaf_src_indices().size()))
51 auto tstart = std::chrono::steady_clock::now();
52 auto const &src_indices = tree.get_leaf_src_indices();
53 #ifdef NIHU_FMM_PARALLEL
54 #pragma omp parallel for
56 for (
int i = 0; i < src_indices.size(); ++i)
58 size_t to = src_indices[i];
59 (*m_pcontainer)[i] = op(to);
60 (*m_psingle_idx)[to] = i;
62 #ifdef NIHU_FMM_PARALLEL
65 auto tend = std::chrono::steady_clock::now();
66 m_assembly_time = std::chrono::duration_cast<std::chrono::microseconds>(tend - tstart).count();
69 size_t get_assembly_time()
const
71 return m_assembly_time;
74 result_t
const &operator()(
size_t to)
const
76 return (*m_pcontainer)[(*m_psingle_idx)[to]];
80 std::shared_ptr<container_t> m_pcontainer;
81 std::shared_ptr<indices_t> m_psingle_idx;
82 size_t m_assembly_time;
86 template <
class Result>
91 typedef Result result_t;
92 typedef interaction_lists::list_t list_t;
94 template <
class Operator,
class ClusterDerived>
100 typedef Eigen::Triplet<size_t, size_t> triplet_t;
101 auto tstart = std::chrono::steady_clock::now();
102 std::vector<triplet_t> triplets;
104 for (
size_t to = 0; to < list.size(); ++to)
106 for (
auto from : list[to])
108 m_container.push_back(op(to, from));
109 triplets.push_back(triplet_t(to, from, idx));
113 m_double_idx.setFromTriplets(triplets.begin(), triplets.end());
114 auto tend = std::chrono::steady_clock::now();
115 m_assembly_time = std::chrono::duration_cast<std::chrono::microseconds>(tend - tstart).count();
118 size_t get_assembly_time()
const
120 return m_assembly_time;
123 result_t
const &operator()(
size_t to,
size_t from)
const
125 return m_container[m_double_idx.coeff(to, from)];
129 std::vector<result_t> m_container;
130 Eigen::SparseMatrix<size_t> m_double_idx;
131 size_t m_assembly_time;
136 template <
class Operator>
137 auto create_p2x_precompute(
139 cluster_tree<
typename std::decay<Operator>::type::cluster_t>
const &tree,
140 interaction_lists::list_t
const &list)
142 typedef typename std::decay<Operator>::type operator_t;
144 typename operator_t::result_t,
145 typename operator_t::fmm_tag
149 template <
class Operator>
150 auto create_p2x_precompute(Operator
const &op,
151 cluster_tree<
typename std::decay<Operator>::type::cluster_t>
const &tree)
153 typedef typename std::decay<Operator>::type operator_t;
154 return p2x_precompute<
155 typename operator_t::result_t,
156 typename operator_t::fmm_tag
161 template <
class Result,
class FmmTag>
165 template <
class Result>
170 typedef Result result_t;
172 template <
class Operator>
174 cluster_tree<
typename std::decay<Operator>::type::cluster_t>
const &tree)
175 : m_pcontainer(tree.get_leaf_rec_indices().size())
176 , m_single_idx(tree.get_n_clusters())
178 auto tstart = std::chrono::steady_clock::now();
179 auto const &list = tree.get_leaf_rec_indices();
180 #ifdef NIHU_FMM_PARALLEL
181 #pragma omp parallel for
183 for (
int i = 0; i < list.size(); ++i)
186 m_pcontainer[i] = op(to);
187 m_single_idx[to] = i;
189 #ifdef NIHU_FMM_PARALLEL
192 auto tend = std::chrono::steady_clock::now();
193 m_assembly_time = std::chrono::duration_cast<std::chrono::microseconds>(tend - tstart).count();
196 result_t
const &operator()(
size_t to)
const
198 return m_pcontainer[m_single_idx[to]];
201 size_t get_assembly_time()
const
203 return m_assembly_time;
207 std::vector<result_t> m_pcontainer;
208 std::vector<size_t> m_single_idx;
209 size_t m_assembly_time;
215 template <
class Result>
220 typedef interaction_lists::list_t list_t;
221 typedef Result result_t;
223 typedef unsigned int index_t;
224 typedef Eigen::SparseMatrix<index_t> indices_t;
225 typedef std::vector<result_t> container_t;
227 template <
class Operator>
229 cluster_tree<
typename std::decay<Operator>::type::cluster_t>
const &tree, list_t
const &list)
230 : m_pcontainer(
new container_t)
231 , m_pdouble_idx(
new indices_t(tree.get_n_clusters(), tree.get_n_clusters()))
233 typedef Eigen::Triplet<size_t, size_t> triplet_t;
234 auto tstart = std::chrono::steady_clock::now();
235 std::vector<triplet_t> triplets;
237 for (
size_t to = 0; to < list.size(); ++to)
239 for (
auto from : list[to])
241 m_pcontainer->push_back(op(to, from));
242 triplets.push_back(triplet_t(to, from, idx));
246 m_pdouble_idx->setFromTriplets(triplets.begin(), triplets.end());
247 auto tend = std::chrono::steady_clock::now();
248 m_assembly_time = std::chrono::duration_cast<std::chrono::microseconds>(tend - tstart).count();
251 result_t
const &operator()(
size_t to,
size_t from)
const
253 return (*m_pcontainer)[m_pdouble_idx->coeff(to, from)];
256 size_t get_assembly_time()
const
258 return m_assembly_time;
262 std::shared_ptr<container_t> m_pcontainer;
263 std::shared_ptr<indices_t> m_pdouble_idx;
264 size_t m_assembly_time;
269 template <
class Operator>
270 auto create_x2p_precompute(
272 cluster_tree<
typename std::decay<Operator>::type::cluster_t>
const &tree,
273 interaction_lists::list_t
const &list)
275 typedef typename std::decay<Operator>::type operator_t;
278 typename operator_t::result_t,
283 template <
class Operator>
284 auto create_x2p_precompute(
286 cluster_tree<
typename std::decay<Operator>::type::cluster_t>
const &tree)
288 typedef typename std::decay<Operator>::type operator_t;
289 return x2p_precompute<
290 typename operator_t::result_t,