Medusa  1.1
Coordinate Free Mehless Method implementation
GeneralFill.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_DOMAINS_GENERALFILL_HPP_
2 #define MEDUSA_BITS_DOMAINS_GENERALFILL_HPP_
3 
9 #include "GeneralFill_fwd.hpp"
11 
14 #include <random>
18 
19 namespace mm {
20 
21 template <typename vec_t>
22 GeneralFill<vec_t>::GeneralFill() : seed_(get_seed()) {}
23 
25 template <typename vec_t>
26 template <typename func_t>
27 void GeneralFill<vec_t>::operator()(DomainDiscretization<vec_t>& domain, const func_t& h,
28  int type) const {
29  KDTreeMutable<vec_t> tree;
30  operator()(domain, h, tree, type);
31 }
32 
33 template <typename vec_t>
34 template <typename func_t, typename search_structure_t>
35 void GeneralFill<vec_t>::operator()(DomainDiscretization<vec_t>& domain, const func_t& h,
36  search_structure_t& search, int type) const {
37  if (type == 0) type = 1;
38  std::mt19937 gen(seed_);
39  KDTree<vec_t> boundary_search;
40  domain.makeDiscreteContainsStructure(boundary_search);
41 
42  int cur_node = 0;
43  int end_node = domain.size();
44  if (end_node == 0) { // If domain is empty, pick a random node inside it.
45  vec_t lo_bound, hi_bound, random_node;
46  std::tie(lo_bound, hi_bound) = domain.shape().bbox();
47  std::vector<std::uniform_real_distribution<scalar_t>> distributions;
48  for (int j = 0; j < dim; ++j) distributions.emplace_back(lo_bound[j], hi_bound[j]);
49  int count = 0;
50  do {
51  for (int j = 0; j < dim; ++j) { random_node[j] = distributions[j](gen); }
52  if (++count >= 10000) {
53  std::string message = "No suitable node in domain could be found after 10000 tries."
54  " This might happen if domain volume is very small compared "
55  "to the volume of the bounding box. Try manually supplying "
56  "the initial point.";
57  throw std::runtime_error(message);
58  }
59  } while (!domain.contains(random_node, boundary_search));
60  domain.addInternalNode(random_node, type);
61  end_node = 1;
62  }
63 
64  // Main algorithm loop.
65  search.insert(domain.positions());
66  while (cur_node < end_node && end_node < max_points) {
67  vec_t p = domain.pos(cur_node);
68  scalar_t r = h(p);
69  assert_msg(r > 0, "Nodal spacing radius should be > 0, got %g.", r);
70 
72  ::construct(r, n_samples, gen);
73  // filter candidates regarding the domain and proximity criteria
74  for (const auto& f : candidates) {
75  vec_t node = p + f; // Shift center to point `p`.
76  if (!domain.contains(node, boundary_search)) continue; // If node is not in the domain.
77  if (search.existsPointInSphere(node, r*zeta)) continue; // If node is not far enough
78  domain.addInternalNode(node, type); // from other nodes.
79  search.insert(node);
80  end_node++;
81  }
82  cur_node++;
83  }
84  if (end_node >= max_points) {
85  std::cerr << "Maximum number of points reached, fill may be incomplete." << std::endl;
86  }
87 }
88 
89 template <typename vec_t>
90 GeneralFill<vec_t>& GeneralFill<vec_t>::proximityTolerance(scalar_t zeta) {
91  assert_msg((0 < zeta && zeta < 1), "Zeta must be between 0 and 1, got %f.", zeta);
92  this->zeta = zeta;
93  return *this;
94 }
96 
97 } // namespace mm
98 
99 #endif // MEDUSA_BITS_DOMAINS_GENERALFILL_HPP_
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
scalar_t
Scalar scalar_t
Type of the elements, alias of Scalar.
Definition: MatrixBaseAddons.hpp:16
GeneralFill_fwd.hpp
dim
@ dim
Number of elements of this matrix.
Definition: MatrixBaseAddons.hpp:14
randutils.hpp
mm::GeneralFill::proximityTolerance
GeneralFill & proximityTolerance(scalar_t zeta)
Set proximity tolerance.
assert_msg
#define assert_msg(cond,...)
Assert with better error reporting.
Definition: assert.hpp:75
KDTreeMutable.hpp
mm::get_seed
unsigned int get_seed()
Return a random seed.
Definition: randutils.hpp:25
KDTree.hpp
assert.hpp
discretization_helpers.hpp
mm::discretization_helpers::SphereDiscretization::construct
static std::vector< Eigen::Matrix< scalar_t, dim, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, dim, 1 > > > construct(scalar_t radius, int num_samples, generator_t &generator)
Construct a randomized discretization.
Definition: discretization_helpers.hpp:85
Range.hpp
mm::GeneralFill::operator()
void operator()(DomainDiscretization< vec_t > &domain, const func_t &h, int type=0) const
Fills given domain according to the nodal spacing function h.