libMesh
Public Member Functions | List of all members
MeshSmootherTest Class Reference
Inheritance diagram for MeshSmootherTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (MeshSmootherTest)
 The goal of this test is to verify proper operation of the MeshSmoother subclasses. More...
 
 CPPUNIT_TEST (testLaplaceQuad)
 
 CPPUNIT_TEST (testLaplaceTri)
 
 CPPUNIT_TEST (testVariationalEdge2)
 
 CPPUNIT_TEST (testVariationalEdge3)
 
 CPPUNIT_TEST (testVariationalEdge3MultipleSubdomains)
 
 CPPUNIT_TEST (testVariationalQuad)
 
 CPPUNIT_TEST (testVariationalQuadMultipleSubdomains)
 
 CPPUNIT_TEST (testVariationalTri3)
 
 CPPUNIT_TEST (testVariationalTri6)
 
 CPPUNIT_TEST (testVariationalTri6MultipleSubdomains)
 
 CPPUNIT_TEST (testVariationalHex8)
 
 CPPUNIT_TEST (testVariationalHex20)
 
 CPPUNIT_TEST (testVariationalHex27)
 
 CPPUNIT_TEST (testVariationalHex27MultipleSubdomains)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testLaplaceSmoother (ReplicatedMesh &mesh, MeshSmoother &smoother, ElemType type)
 
void testVariationalSmoother (ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
 
void testLaplaceQuad ()
 
void testLaplaceTri ()
 
void testVariationalEdge2 ()
 
void testVariationalEdge3 ()
 
void testVariationalEdge3MultipleSubdomains ()
 
void testVariationalQuad ()
 
void testVariationalQuadMultipleSubdomains ()
 
void testVariationalTri3 ()
 
void testVariationalTri6 ()
 
void testVariationalTri6MultipleSubdomains ()
 
void testVariationalHex8 ()
 
void testVariationalHex20 ()
 
void testVariationalHex27 ()
 
void testVariationalHex27MultipleSubdomains ()
 

Detailed Description

Definition at line 173 of file mesh_smoother_test.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/14]

MeshSmootherTest::CPPUNIT_TEST ( testLaplaceQuad  )

◆ CPPUNIT_TEST() [2/14]

MeshSmootherTest::CPPUNIT_TEST ( testLaplaceTri  )

◆ CPPUNIT_TEST() [3/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalEdge2  )

◆ CPPUNIT_TEST() [4/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalEdge3  )

◆ CPPUNIT_TEST() [5/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalEdge3MultipleSubdomains  )

◆ CPPUNIT_TEST() [6/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalQuad  )

◆ CPPUNIT_TEST() [7/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalQuadMultipleSubdomains  )

◆ CPPUNIT_TEST() [8/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalTri3  )

◆ CPPUNIT_TEST() [9/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalTri6  )

◆ CPPUNIT_TEST() [10/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalTri6MultipleSubdomains  )

◆ CPPUNIT_TEST() [11/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalHex8  )

◆ CPPUNIT_TEST() [12/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalHex20  )

◆ CPPUNIT_TEST() [13/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalHex27  )

◆ CPPUNIT_TEST() [14/14]

MeshSmootherTest::CPPUNIT_TEST ( testVariationalHex27MultipleSubdomains  )

◆ CPPUNIT_TEST_SUITE_END()

MeshSmootherTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

MeshSmootherTest::LIBMESH_CPPUNIT_TEST_SUITE ( MeshSmootherTest  )

The goal of this test is to verify proper operation of the MeshSmoother subclasses.

◆ setUp()

void MeshSmootherTest::setUp ( )
inline

Definition at line 207 of file mesh_smoother_test.C.

207 {}

◆ tearDown()

void MeshSmootherTest::tearDown ( )
inline

Definition at line 209 of file mesh_smoother_test.C.

209 {}

◆ testLaplaceQuad()

void MeshSmootherTest::testLaplaceQuad ( )
inline

Definition at line 480 of file mesh_smoother_test.C.

References mesh, libMesh::QUAD4, and TestCommWorld.

481  {
483  LaplaceMeshSmoother laplace(mesh);
484 
485  testLaplaceSmoother(mesh, laplace, QUAD4);
486  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
void testLaplaceSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, ElemType type)
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
This class defines the data structures necessary for Laplace smoothing.

◆ testLaplaceSmoother()

void MeshSmootherTest::testLaplaceSmoother ( ReplicatedMesh mesh,
MeshSmoother smoother,
ElemType  type 
)
inline

Definition at line 211 of file mesh_smoother_test.C.

References libMesh::MeshTools::Generation::build_square(), mesh, libMesh::Real, libMesh::MeshTools::Modification::redistribute(), libMesh::MeshSmoother::smooth(), and libMesh::TOLERANCE.

212  {
213  LOG_UNIT_TEST;
214 
215  constexpr unsigned int n_elems_per_side = 4;
216 
218  mesh, n_elems_per_side, n_elems_per_side, 0., 1., 0., 1., type);
219 
220  // Move it around so we have something that needs smoothing
221  DistortSquare ds;
223 
224  // Assert the distortion is as expected
225  auto center_distortion_is =
226  [](const Node & node, int d, bool distortion, Real distortion_tol = TOLERANCE) {
227  const Real r = node(d);
228  const Real R = r * n_elems_per_side;
229  CPPUNIT_ASSERT_GREATER(-TOLERANCE * TOLERANCE, r);
230  CPPUNIT_ASSERT_GREATER(-TOLERANCE * TOLERANCE, 1 - r);
231 
232  // If we're at the boundaries we should *never* be distorted
233  if (std::abs(node(0)) < TOLERANCE * TOLERANCE ||
234  std::abs(node(0) - 1) < TOLERANCE * TOLERANCE)
235  {
236  const Real R1 = node(1) * n_elems_per_side;
237  CPPUNIT_ASSERT_LESS(TOLERANCE * TOLERANCE, std::abs(R1 - std::round(R1)));
238  return true;
239  }
240 
241  if (std::abs(node(1)) < TOLERANCE * TOLERANCE ||
242  std::abs(node(1) - 1) < TOLERANCE * TOLERANCE)
243  {
244  const Real R0 = node(0) * n_elems_per_side;
245  CPPUNIT_ASSERT_LESS(TOLERANCE * TOLERANCE, std::abs(R0 - std::round(R0)));
246 
247  return true;
248  }
249 
250  // If we're at the center we're fine
251  if (std::abs(r - 0.5) < TOLERANCE * TOLERANCE)
252  return true;
253 
254  return ((std::abs(R - std::round(R)) > distortion_tol) == distortion);
255  };
256 
257  for (auto node : mesh.node_ptr_range())
258  {
259  CPPUNIT_ASSERT(center_distortion_is(*node, 0, true));
260  CPPUNIT_ASSERT(center_distortion_is(*node, 1, true));
261  }
262 
263  // Enough iterations to mostly fix us up. Laplace seems to be at 1e-3
264  // tolerance by iteration 6, so hopefully everything is there on any
265  // system by 8.
266  for (unsigned int i = 0; i != 8; ++i)
267  smoother.smooth();
268 
269  // Make sure we're not too distorted anymore.
270  for (auto node : mesh.node_ptr_range())
271  {
272  CPPUNIT_ASSERT(center_distortion_is(*node, 0, false, 1e-3));
273  CPPUNIT_ASSERT(center_distortion_is(*node, 1, false, 1e-3));
274  }
275  }
A Node is like a Point, but with more information.
Definition: node.h:52
static constexpr Real TOLERANCE
MeshBase & mesh
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
virtual void smooth()=0
Function which actually performs the smoothing operations.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void redistribute(MeshBase &mesh, const FunctionBase< Real > &mapfunc)
Deterministically perturb the nodal locations.

◆ testLaplaceTri()

void MeshSmootherTest::testLaplaceTri ( )
inline

Definition at line 488 of file mesh_smoother_test.C.

References mesh, TestCommWorld, and libMesh::TRI3.

489  {
491  LaplaceMeshSmoother laplace(mesh);
492 
493  testLaplaceSmoother(mesh, laplace, TRI3);
494  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
void testLaplaceSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, ElemType type)
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
This class defines the data structures necessary for Laplace smoothing.

◆ testVariationalEdge2()

void MeshSmootherTest::testVariationalEdge2 ( )
inline

Definition at line 497 of file mesh_smoother_test.C.

References libMesh::EDGE2, mesh, and TestCommWorld.

498  {
500  VariationalMeshSmoother variational(mesh);
501 
502  testVariationalSmoother(mesh, variational, EDGE2);
503  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalEdge3()

void MeshSmootherTest::testVariationalEdge3 ( )
inline

Definition at line 505 of file mesh_smoother_test.C.

References libMesh::EDGE3, mesh, and TestCommWorld.

506  {
508  VariationalMeshSmoother variational(mesh);
509 
510  testVariationalSmoother(mesh, variational, EDGE3);
511  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalEdge3MultipleSubdomains()

void MeshSmootherTest::testVariationalEdge3MultipleSubdomains ( )
inline

Definition at line 513 of file mesh_smoother_test.C.

References libMesh::EDGE3, mesh, and TestCommWorld.

514  {
516  VariationalMeshSmoother variational(mesh);
517 
518  testVariationalSmoother(mesh, variational, EDGE3, true);
519  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalHex20()

void MeshSmootherTest::testVariationalHex20 ( )
inline

Definition at line 569 of file mesh_smoother_test.C.

References libMesh::HEX20, mesh, and TestCommWorld.

570  {
572  VariationalMeshSmoother variational(mesh);
573 
574  testVariationalSmoother(mesh, variational, HEX20);
575  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalHex27()

void MeshSmootherTest::testVariationalHex27 ( )
inline

Definition at line 577 of file mesh_smoother_test.C.

References libMesh::HEX27, mesh, and TestCommWorld.

578  {
580  VariationalMeshSmoother variational(mesh);
581 
582  testVariationalSmoother(mesh, variational, HEX27);
583  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalHex27MultipleSubdomains()

void MeshSmootherTest::testVariationalHex27MultipleSubdomains ( )
inline

Definition at line 585 of file mesh_smoother_test.C.

References libMesh::HEX27, mesh, and TestCommWorld.

586  {
588  VariationalMeshSmoother variational(mesh);
589 
590  testVariationalSmoother(mesh, variational, HEX27, true);
591  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalHex8()

void MeshSmootherTest::testVariationalHex8 ( )
inline

Definition at line 561 of file mesh_smoother_test.C.

References libMesh::HEX8, mesh, and TestCommWorld.

562  {
564  VariationalMeshSmoother variational(mesh);
565 
566  testVariationalSmoother(mesh, variational, HEX8);
567  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalQuad()

void MeshSmootherTest::testVariationalQuad ( )
inline

Definition at line 521 of file mesh_smoother_test.C.

References mesh, libMesh::QUAD4, and TestCommWorld.

522  {
524  VariationalMeshSmoother variational(mesh);
525 
526  testVariationalSmoother(mesh, variational, QUAD4);
527  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalQuadMultipleSubdomains()

void MeshSmootherTest::testVariationalQuadMultipleSubdomains ( )
inline

Definition at line 529 of file mesh_smoother_test.C.

References mesh, libMesh::QUAD4, and TestCommWorld.

530  {
532  VariationalMeshSmoother variational(mesh);
533 
534  testVariationalSmoother(mesh, variational, QUAD4, true);
535  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalSmoother()

void MeshSmootherTest::testVariationalSmoother ( ReplicatedMesh mesh,
MeshSmoother smoother,
const ElemType  type,
const bool  multiple_subdomains = false 
)
inline

Definition at line 277 of file mesh_smoother_test.C.

References libMesh::absolute_fuzzy_equals(), libMesh::BoundaryInfo::boundary_ids(), libMesh::MeshTools::Generation::build_cube(), libMesh::MeshTools::Generation::build_line(), libMesh::MeshTools::Generation::build_square(), dim, libMesh::MeshBase::elem_default_orders(), libMesh::Utility::enum_to_string(), libMesh::ReferenceElem::get(), libMesh::MeshBase::get_boundary_info(), libMesh::make_range(), mesh, libMesh::Real, libMesh::MeshTools::Modification::redistribute(), libMesh::relative_fuzzy_equals(), libMesh::MeshSmoother::smooth(), and libMesh::TOLERANCE.

281  {
282  LOG_UNIT_TEST;
283 
284  // Get mesh dimension, determine whether type is triangular
285  const auto * ref_elem = &(ReferenceElem::get(type));
286  const auto dim = ref_elem->dim();
287  const bool type_is_tri = Utility::enum_to_string(type).compare(0, 3, "TRI") == 0;
288 
289  unsigned int n_elems_per_side = 5;
290 
291  // The current distortion mechanism in DistortHyperCube, combined with the
292  // way multiple subdomains are assigned below, has the property that:
293  // - When n_elems_per_side is even, some of the subdomain boundary nodes
294  // are colinear, leading to sliding node constraints.
295  // - When n_elems_per_side is odd, none of the subdomain boundary nodes
296  // are colinear, leading to all subdomain boundary nodes being fixed.
297  // Our check for preserved subdomain boundaries is overly restrictive
298  // because we error if any subdomain boundary nodes move during smoothing.
299  // To avoid this error, instead of implementing a more elaborate check for
300  // sliding subdomain boundary nodes, we require n_elems_per_side to be odd.
301  libmesh_error_msg_if(n_elems_per_side % 2 != 1,
302  "n_elems_per_side should be odd.");
303 
304  switch (dim)
305  {
306  case 1:
307  MeshTools::Generation::build_line(mesh, n_elems_per_side, 0., 1., type);
308  break;
309  case 2:
311  mesh, n_elems_per_side, n_elems_per_side, 0., 1., 0., 1., type);
312  break;
313 
314  case 3:
316  n_elems_per_side,
317  n_elems_per_side,
318  n_elems_per_side,
319  0.,
320  1.,
321  0.,
322  1.,
323  0.,
324  1.,
325  type);
326  break;
327 
328  default:
329  libmesh_error_msg("Unsupported dimension " << dim);
330  }
331 
332  // Move it around so we have something that needs smoothing
333  DistortHyperCube dh(dim);
335 
336  // Add multiple subdomains if requested
337  std::unordered_map<dof_id_type, Point> subdomain_boundary_node_id_to_point;
338  if (multiple_subdomains)
339  {
340  // Modify the subdomain ids in an interesting way
341  for (auto * elem : mesh.active_element_ptr_range())
342  {
343  unsigned int subdomain_id = 0;
344  for (const auto d : make_range(dim))
345  if (elem->vertex_average()(d) > 0.5)
346  ++subdomain_id;
347  elem->subdomain_id() += subdomain_id;
348  }
349 
350  // This loop should NOT be combined with the one above because we need to
351  // finish checking and updating subdomain ids for all elements before
352  // recording the final subdomain boundary.
353  for (auto * elem : mesh.active_element_ptr_range())
354  for (const auto & s : elem->side_index_range())
355  {
356  const auto * neighbor = elem->neighbor_ptr(s);
357  if (neighbor == nullptr)
358  continue;
359 
360  if (elem->subdomain_id() != neighbor->subdomain_id())
361  // This side is part of a subdomain boundary, record the
362  // corresponding node locations
363  for (const auto & n : elem->nodes_on_side(s))
364  subdomain_boundary_node_id_to_point[elem->node_id(n)] =
365  Point(*(elem->get_nodes()[n]));
366  }
367  }
368 
369 
370  // Get the mesh order
371  const auto &elem_orders = mesh.elem_default_orders();
372  libmesh_error_msg_if(
373  elem_orders.size() != 1,
374  "The variational smoother cannot be used for mixed-order meshes!");
375  const auto fe_order = *elem_orders.begin();
376 
377  // Function to assert the distortion is as expected
378  const auto &boundary_info = mesh.get_boundary_info();
379  auto distortion_is = [
380  &n_elems_per_side, &dim, &boundary_info, &fe_order
381  ](const Node &node, bool distortion, Real distortion_tol = TOLERANCE)
382  {
383  // Get boundary ids associated with the node
384  std::vector<boundary_id_type> boundary_ids;
385  boundary_info.boundary_ids(&node, boundary_ids);
386 
387  // This tells us what type of node we are: internal, sliding, or fixed
388  const auto num_dofs = dim - boundary_ids.size();
389  /*
390  * The following cases of num_dofs are possible, ASSUMING all boundaries
391  * are non-overlapping
392  * 3D: 3-0, 3-1, 3-2, 3-3
393  * = 3 2 1 0
394  * internal sliding, sliding, fixed
395  * 2D: 2-0, 2-1, 2-2
396  * = 2 1 0
397  * internal sliding, fixed
398  * 1D: 1-0, 1-1
399  * = 1 0
400  * internal fixed
401  *
402  * We expect that R is an integer in [0, n_elems_per_side] for
403  * num_dofs of the node's cooridinantes, while the remaining coordinates
404  * are fixed to the boundary with value 0 or 1. In other words, at LEAST
405  * dim - num_dofs coordinantes should be 0 or 1.
406  */
407 
408  std::size_t num_zero_or_one = 0;
409 
410  bool distorted = false;
411  for (const auto d : make_range(dim))
412  {
413  const Real r = node(d);
414  const Real R = r * n_elems_per_side * fe_order;
415  CPPUNIT_ASSERT_GREATER(-distortion_tol * distortion_tol, r);
416  CPPUNIT_ASSERT_GREATER(-distortion_tol * distortion_tol, 1 - r);
417 
418  const bool d_distorted = std::abs(R - std::round(R)) > distortion_tol;
419  distorted |= d_distorted;
420  num_zero_or_one +=
421  (absolute_fuzzy_equals(r, 0.) || absolute_fuzzy_equals(r, 1.));
422  }
423 
424  CPPUNIT_ASSERT_GREATEREQUAL(dim - num_dofs, num_zero_or_one);
425 
426  // We can never expect a fixed node to be distorted
427  if (num_dofs == 0)
428  // if (num_dofs < dim)
429  return true;
430  return distorted == distortion;
431  };
432 
433  // Function to check if a given node has changed based on previous mapping
434  auto is_subdomain_boundary_node_the_same = [&subdomain_boundary_node_id_to_point](
435  const Node & node) {
436  auto it = subdomain_boundary_node_id_to_point.find(node.id());
437  if (it != subdomain_boundary_node_id_to_point.end())
438  return (relative_fuzzy_equals(Point(node), subdomain_boundary_node_id_to_point[node.id()]));
439  else
440  // node is not a subdomain boundary node, just return true
441  return true;
442  };
443 
444  // Make sure our DistortSquare transformation has distorted the mesh
445  for (auto node : mesh.node_ptr_range())
446  CPPUNIT_ASSERT(distortion_is(*node, true));
447 
448  // Transform the square mesh of triangles to a parallelogram mesh of
449  // triangles. This will allow the Variational Smoother to smooth the mesh
450  // to the optimal case of equilateral triangles
451  if (type_is_tri)
452  {
453  SquareToParallelogram stp;
455  }
456 
457  smoother.smooth();
458 
459  // Transform the parallelogram mesh back to a square mesh. In the case of
460  // the Variational Smoother, equilateral triangular elements will be
461  // transformed into right triangular elements that align with the original
462  // undistorted mesh.
463  if (type_is_tri)
464  {
465  ParallelogramToSquare pts;
467  }
468 
469  // Make sure we're not too distorted anymore OR that interval subdomain boundary nodes did not
470  // change.
471  for (auto node : mesh.node_ptr_range())
472  {
473  if (multiple_subdomains)
474  CPPUNIT_ASSERT(is_subdomain_boundary_node_the_same(*node));
475  else
476  CPPUNIT_ASSERT(distortion_is(*node, false, 1e-3));
477  }
478  }
const std::set< Order > & elem_default_orders() const
Definition: mesh_base.h:289
A Node is like a Point, but with more information.
Definition: node.h:52
static constexpr Real TOLERANCE
unsigned int dim
MeshBase & mesh
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:165
virtual void smooth()=0
Function which actually performs the smoothing operations.
std::string enum_to_string(const T e)
bool absolute_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: fuzzy_equals.h:64
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
void redistribute(MeshBase &mesh, const FunctionBase< Real > &mapfunc)
Deterministically perturb the nodal locations.
void build_line(UnstructuredMesh &mesh, const unsigned int nx, const Real xmin=0., const Real xmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 1D meshes.
bool relative_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
Definition: fuzzy_equals.h:78
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
const Elem & get(const ElemType type_in)
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.

◆ testVariationalTri3()

void MeshSmootherTest::testVariationalTri3 ( )
inline

Definition at line 537 of file mesh_smoother_test.C.

References mesh, TestCommWorld, and libMesh::TRI3.

538  {
540  VariationalMeshSmoother variational(mesh);
541 
542  testVariationalSmoother(mesh, variational, TRI3);
543  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalTri6()

void MeshSmootherTest::testVariationalTri6 ( )
inline

Definition at line 545 of file mesh_smoother_test.C.

References mesh, TestCommWorld, and libMesh::TRI6.

546  {
548  VariationalMeshSmoother variational(mesh);
549 
550  testVariationalSmoother(mesh, variational, TRI6);
551  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

◆ testVariationalTri6MultipleSubdomains()

void MeshSmootherTest::testVariationalTri6MultipleSubdomains ( )
inline

Definition at line 553 of file mesh_smoother_test.C.

References mesh, TestCommWorld, and libMesh::TRI3.

554  {
556  VariationalMeshSmoother variational(mesh);
557 
558  testVariationalSmoother(mesh, variational, TRI3, true);
559  }
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
void testVariationalSmoother(ReplicatedMesh &mesh, MeshSmoother &smoother, const ElemType type, const bool multiple_subdomains=false)
This is an implementation of Larisa Branets&#39; smoothing algorithms.

The documentation for this class was generated from the following file: