Skip to content

Commit 56bc7a3

Browse files
committed
WIP2
1 parent bb02c76 commit 56bc7a3

File tree

1 file changed

+81
-22
lines changed

1 file changed

+81
-22
lines changed

src/mesh/mesh_smoother_laplace.C

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,39 +103,98 @@ void LaplaceMeshSmoother::smooth(unsigned int n_iterations)
103103
if (_graph[node->id()].size() == 0)
104104
return;
105105

106+
// check if a node is on a given block boundary
107+
auto is_node_on_block_boundary = [&block_boundary_map](dof_id_type node_id, const std::pair<subdomain_id_type, subdomain_id_type> & block_boundary)
108+
{
109+
const auto it = block_boundary_map.find(node_id);
110+
if (it == block_boundary_map.end())
111+
return false;
112+
return it->second.count(block_boundary) > 0;
113+
};
114+
115+
// check if a series of vectors is collinear/coplanar
116+
RealVectorValue base;
117+
std::size_t n_edges = 0;
118+
auto has_zero_curvature = [this, &node, &base, &n_edges](dof_id_type connected_id) {
119+
const auto connected_node = _mesh.point(connected_id);
120+
const RealVectorValue vec = connected_node - *node;
121+
// if any connected edge has length zero we give up and don't move the node
122+
if (vec.norm_sq() < libMesh::TOLERANCE)
123+
return false;
124+
125+
// count edges
126+
n_edges++;
127+
128+
// store first two edges for later projection
129+
if (n_edges == 1) {
130+
base = vec;
131+
return true;
132+
}
133+
134+
// 2D - collinear - check cross product of first edge with all other edges
135+
if (_mesh.mesh_dimension() == 2)
136+
return (base.cross(vec).norm_sq() < libMesh::TOLERANCE);
137+
138+
// 3D
139+
if (n_edges == 2) {
140+
const auto cross = base.cross(vec);
141+
if (cross.norm_sq() < libMesh::TOLERANCE)
142+
n_edges--;
143+
else
144+
base = cross;
145+
return true;
146+
}
147+
148+
return (base * vec < libMesh::TOLERANCE);
149+
};
150+
106151
if (on_boundary.count(node->id()))
107152
{
108153
// project to boundary
154+
for (const auto & connected_id : _graph[node->id()])
155+
if (on_boundary.count(connected_id) && !has_zero_curvature(connected_id))
156+
return;
157+
// we have not failed the curvature check, but do we have enough edges?
158+
if (n_edges < _mesh.mesh_dimension())
159+
return;
160+
161+
// now project
162+
// base /= base.norm();
163+
// auto delta = new_positions[node->id()] - *node;
164+
// if (_mesh.mesh_dimension() == 2)
165+
// delta = base * (delta * base);
166+
// else
167+
// delta -= base * (delta * base);
168+
// *node += delta;
109169
return;
110170
}
111171

112-
// check if a node is on a given block boundary
113-
auto is_node_on_block_boundary = [&block_boundary_map](dof_id_type node_id, const std::pair<subdomain_id_type, subdomain_id_type> & block_boundary)
172+
const auto it = block_boundary_map.find(node->id());
173+
if (it != block_boundary_map.end())
114174
{
115-
auto range = block_boundary_map.equal_range(node_id);
116-
for (auto i = range.first; i != range.second; ++i)
117-
if (i->second == block_boundary)
118-
return true;
119-
return false;
120-
};
175+
const auto num_boundaries = it->second.size();
121176

122-
const auto range = block_boundary_map.equal_range(node->id());
123-
const auto num_boundaries = std::distance(range.first, range.second);
177+
// do not touch nodes at the intersection of two or more boundaries
178+
if (num_boundaries > 1)
179+
return;
124180

125-
// do not touch nodes at the intersection of two or more boundaries
126-
if (num_boundaries > 1)
127-
return;
181+
if (num_boundaries == 1)
182+
{
183+
// project to block boundary
184+
const auto & boundary = *(it->second.begin());
185+
// iterate over neighboring nodes that share the same boundary and check if all edges are coplanar/collinear
186+
for (const auto & connected_id : _graph[node->id()])
187+
if (is_node_on_block_boundary(connected_id, boundary) && !has_zero_curvature(connected_id))
188+
return;
189+
// we have not failed the curvature check, but do we have enough edges?
190+
if (n_edges < _mesh.mesh_dimension())
191+
return;
128192

129-
if (num_boundaries == 1)
130-
{
131-
// project to block boundary
132-
const auto & boundary = range.first->second;
133-
// iterate over neighboring nodes that share the same boundary and check if all edges are coplanar/collinear
134-
for (const auto & connected_id : _graph[node->id()])
135-
if (is_node_on_block_boundary(connected_id, boundary))
136-
continue;
193+
// now project
194+
// if (_mesh.mesh_dimension() == 2)
137195

138-
return;
196+
return;
197+
}
139198
}
140199

141200
// otherwise just move the node freely

0 commit comments

Comments
 (0)