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_