1 #ifndef MEDUSA_BITS_DOMAINS_BASICRELAX_HPP_
2 #define MEDUSA_BITS_DOMAINS_BASICRELAX_HPP_
18 template <
class domain_t,
class radius_func_type>
20 typedef typename domain_t::vector_t vec_t;
27 int N = domain.
size();
33 assert_msg(0 <= i && i < N,
"Node index %d out of range [0, %d) in relax.", i, N);
37 assert_msg(!bnd.empty(),
"Relax requires boundary nodes, but this domain has none!");
43 bool removed_nodes_warning =
false;
47 tree.
reset(domain.positions());
63 for (k = 0; k < nodes.size(); ++k) {
65 assert_msg(domain.type(i) > 0,
"Only interior nodes are to be relaxed");
66 vec_t pos = domain.pos(i);
68 double d0 = std::pow((domain.pos(indices[1]) - pos).norm(), 1.0 /
dim);
71 for (
int j = 1; j < indices.
size(); ++j) {
73 vec_t r = domain.pos(indices[j]) - pos;
74 assert_msg(r.norm() > 1e-15,
"Nodes %d and %d have the same coordinates %s. "
75 "Try using lower initial heat.", i, indices[j], pos);
78 r_0 = r_func(domain.pos(indices[j]));
82 if (r_0 < 0) dp[k] = 0.2 * dp[k].normalized() * a_f * d0;
83 dp[k] = -a_f * d0 * dp[k];
85 if (!domain.shape().contains(pos + dp[k])) {
90 to_remove.push_back(k);
91 to_delete.push_back(nodes[k]);
95 tmp = 0.5 * (2 * pos + dp[k]);
96 normal = dp[k].normalized();
100 int s = bnd[idx[0]], t = bnd[idx[1]];
101 tmp = 0.5 * (domain.pos(s) + domain.pos(t));
102 normal = (0.5 * (domain.normal(s) + domain.normal(t))).normalized();
109 std::tie(success, proj) = domain.shape().projectPointToBoundary(tmp, normal);
114 std::tie(ind, dist) = boundary_tree.
query(proj, 2);
119 double d_1 = std::sqrt(dist[0]);
120 double d_2 = std::sqrt(dist[1]);
121 double d_0 = std::sqrt(dist[0] + dist[1]);
123 normal = ((1 - d_1 / d_0) * domain.normal(bnd[ind[0]])
124 + (1 - d_2 / d_0) * domain.normal(bnd[ind[1]])).normalized();
125 int boundary_type = domain.type(bnd[ind[0]]);
126 domain.changeToBoundary(i, proj, boundary_type, normal);
127 boundary_tree.
insert(proj);
130 to_remove.push_back(k);
132 removed_nodes_warning =
true;
134 to_remove.push_back(k);
135 to_delete.push_back(nodes[k]);
142 "No nodes in relax pool anymore, perhaps use lower heat");
147 for (k = 0; k < nodes.size(); ++k) {
148 domain.pos(nodes[k]) += dp[k];
154 domain.removeNodes(to_delete);
156 debug_out <<
"nodes_final(:,:)=" << domain.positions <<
";\n";
157 debug_out <<
"normal =" << domain.normals() <<
";\n";
159 debug_out <<
"boundary =" << boundary <<
";\n";
160 debug_out <<
"boundary_map =" << domain.boundary_map() <<
";\n";
163 if (removed_nodes_warning) {
164 print_red(
"warning -- nodes removed during relax due to projection fail\n");
170 #endif // MEDUSA_BITS_DOMAINS_BASICRELAX_HPP_