libMesh
variational_smoother_constraint.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef LIBMESH_VARIATIONAL_SMOOTHER_CONSTRAINT_H
19 #define LIBMESH_VARIATIONAL_SMOOTHER_CONSTRAINT_H
20 
21 // Local Includes
22 #include "libmesh/system.h"
23 #include "libmesh/dof_map.h"
24 
25 // C++ includes
26 #include <variant>
27 
28 namespace libMesh
29 {
30 
31 // Forward declarations
32 class PointConstraint;
33 class LineConstraint;
34 class PlaneConstraint;
35 class InvalidConstraint;
36 
43 using ConstraintVariant = std::variant<PointConstraint, LineConstraint,
45 
50 {
51 
52 public:
53  PointConstraint() = default;
54 
61 
70  bool operator<(const PointConstraint &other) const;
71 
77  bool operator==(const PointConstraint &other) const;
78 
84  bool contains_point(const PointConstraint &p) const { return *this == p; }
85 
95  ConstraintVariant intersect(const ConstraintVariant &other) const;
96 
100  const Point &point() const { return _point; }
101 
105  const Real &tol() const { return _tol; }
106 
107 private:
108  // Life is easier if we don't make this const
113 
118 };
119 
124 {
125 public:
126  LineConstraint() = default;
127 
134  LineConstraint(const Point &point, const Point &direction,
135  const Real &tol = TOLERANCE * TOLERANCE);
136 
145  bool operator<(const LineConstraint &other) const;
146 
152  bool operator==(const LineConstraint &other) const;
153 
159  bool contains_point(const PointConstraint &p) const;
160 
166  bool is_parallel(const LineConstraint &l) const;
167 
173  bool is_parallel(const PlaneConstraint &p) const;
174 
184  ConstraintVariant intersect(const ConstraintVariant &other) const;
185 
189  const Point &point() const { return _point; }
190 
194  const Point &direction() const { return _direction; }
195 
199  const Real &tol() const { return _tol; }
200 
201 private:
202  // Life is easier if we don't make these const
207 
212 
217 };
218 
223 {
224 
225 public:
226  PlaneConstraint() = default;
227 
234  PlaneConstraint(const Point &point, const Point &normal,
235  const Real &tol = TOLERANCE * TOLERANCE);
236 
245  bool operator<(const PlaneConstraint &other) const;
246 
252  bool operator==(const PlaneConstraint &other) const;
253 
259  bool contains_point(const PointConstraint &p) const;
260 
266  bool contains_line(const LineConstraint &l) const;
267 
273  bool is_parallel(const PlaneConstraint &p) const;
274 
280  bool is_parallel(const LineConstraint &l) const;
281 
291  ConstraintVariant intersect(const ConstraintVariant &other) const;
292 
296  const Point &point() const { return _point; }
297 
301  const Point &normal() const { return _normal; }
302 
306  const Real &tol() const { return _tol; }
307 
308 private:
309  // Life is easier if we don't make these const
314 
319 
324 };
325 
331 {
332 
333 public:
335  : _err_msg("We should never get here! The InvalidConstraint object should be "
336  "detected and replaced with a valid ConstraintVariant prior to calling "
337  "any class methods.")
338  {
339  }
340 
345  libmesh_assert_msg(false, _err_msg);
346  return *this;
347  }
348 
352  bool contains_point(const PointConstraint &) const {
353  libmesh_assert_msg(false, _err_msg);
354  return false;
355  }
356 
357 private:
358  std::string _err_msg;
359 };
360 
369  const ConstraintVariant &b) {
370  // std::visit applies the visitor v (a Callable that can be called with any
371  // combination of types from Variants) to the active value inside a
372  // std::Variant. This circumvents the issue that the literal ConstraintVariant
373  // type does not have a method called 'intersect' (but the types defining
374  // ConstraintVariant do)
375  return std::visit(
376  [](const auto &lhs, const auto &rhs) -> ConstraintVariant {
377  return lhs.intersect(rhs);
378  },
379  a, b);
380 }
381 
390 {
391 private:
392 
394 
399 
404  void fix_node(const Node & node);
405 
413  void constrain_node_to_plane(const Node & node, const Point & ref_normal_vec);
414 
422  void constrain_node_to_line(const Node & node, const Point & line_vec);
423 
431  static void find_nodal_or_face_neighbors(
432  const MeshBase & mesh,
433  const Node & node,
434  const std::unordered_map<dof_id_type, std::vector<const Elem *>> & nodes_to_elem_map,
435  std::vector<const Node *> & neighbors);
436 
445  static bool nodes_share_boundary_id(
446  const Node & boundary_node,
447  const Node & neighbor_node,
448  const Elem & containing_elem,
449  const BoundaryInfo & boundary_info);
450 
463  static std::set<std::set<const Node *>>
465  const MeshBase &mesh, const Node &node, const subdomain_id_type sub_id,
466  const std::unordered_map<dof_id_type, std::vector<const Elem *>>
467  &nodes_to_elem_map);
468 
481  static std::set<std::set<const Node *>> get_neighbors_for_boundary_constraint(
482  const MeshBase &mesh, const Node &node,
483  const std::unordered_set<dof_id_type> &boundary_node_ids,
484  const BoundaryInfo &boundary_info,
485  const std::unordered_map<dof_id_type, std::vector<const Elem *>>
486  &nodes_to_elem_map);
487 
496  const Node &node, const unsigned int dim,
497  const std::set<std::set<const Node *>> &side_grouped_boundary_neighbors);
498 
506  void impose_constraint(const Node &node, const ConstraintVariant &constraint);
507 
508 public:
515  VariationalSmootherConstraint(System & sys, const bool & preserve_subdomain_boundaries);
516 
517  virtual ~VariationalSmootherConstraint() override;
518 
519  virtual void constrain() override;
520 };
521 
522 
523 } // namespace libMesh
524 
525 #endif // LIBMESH_VARIATIONAL_SMOOTHER_CONSTRAINT_H
bool operator<(const LineConstraint &other) const
Comparison operator for ordering LineConstraint objects.
const Point & normal() const
Const getter for the _normal attribute.
bool contains_point(const PointConstraint &p) const
Query whether a point lies on another point.
void constrain_node_to_plane(const Node &node, const Point &ref_normal_vec)
Constrain a node to remain in the given plane during mesh smoothing.
A Node is like a Point, but with more information.
Definition: node.h:52
bool contains_point(const PointConstraint &) const
Dummy contains_point method that should never be called.
Constraint class for the VariationalMeshSmoother.
bool contains_point(const PointConstraint &p) const
Query whether a point lies on the plane.
static constexpr Real TOLERANCE
unsigned int dim
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Real _tol
Tolerance to use for numerical comparisons.
bool operator==(const PointConstraint &other) const
Equality operator.
ConstraintVariant intersect(const ConstraintVariant &other) const
Computes the intersection of this line with another constraint.
The libMesh namespace provides an interface to certain functionality in the library.
Point _point
A point on the constraining plane.
bool contains_line(const LineConstraint &l) const
Query whether a line lies on the plane.
This is the MeshBase class.
Definition: mesh_base.h:75
Point _normal
The direction normal to the constraining plane.
ConstraintVariant intersect_constraints(const ConstraintVariant &a, const ConstraintVariant &b)
Dispatch intersection between two constraint variants.
bool is_parallel(const LineConstraint &l) const
Query whether a line is parallel to this line.
bool operator<(const PlaneConstraint &other) const
Comparison operator for ordering PlaneConstraint objects.
Represents an invalid constraint (i.e., when the two constraints don&#39;t intersect) ...
ConstraintVariant intersect(const ConstraintVariant &) const
Dummy intersect method that should never be called.
static std::set< std::set< const Node * > > get_neighbors_for_boundary_constraint(const MeshBase &mesh, const Node &node, const std::unordered_set< dof_id_type > &boundary_node_ids, const BoundaryInfo &boundary_info, const std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem_map)
Get the relevant nodal neighbors for an external boundary constraint.
Point _point
A point on the constraining line.
Point _direction
Direction of the constraining line.
static std::set< std::set< const Node * > > get_neighbors_for_subdomain_constraint(const MeshBase &mesh, const Node &node, const subdomain_id_type sub_id, const std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem_map)
Get the relevant nodal neighbors for a subdomain constraint.
const Point & direction() const
Const getter for the _direction attribute.
void constrain_node_to_line(const Node &node, const Point &line_vec)
Constrain a node to remain on the given line during mesh smoothing.
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
const Point & point() const
Const getter for the _point attribute.
Represents a plane constraint defined by a point and normal vector.
virtual ~VariationalSmootherConstraint() override
bool operator<(const PointConstraint &other) const
Comparison operator for ordering PointConstraint objects.
Real _tol
Tolerance to use for numerical comparisons.
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
bool operator==(const LineConstraint &other) const
Equality operator.
const bool _preserve_subdomain_boundaries
Whether nodes on subdomain boundaries are subject to change via smoothing.
static bool nodes_share_boundary_id(const Node &boundary_node, const Node &neighbor_node, const Elem &containing_elem, const BoundaryInfo &boundary_info)
Determines whether two neighboring nodes share a common boundary id.
Point _point
Location of constraint.
virtual void constrain() override
Constraint function.
ConstraintVariant intersect(const ConstraintVariant &other) const
Computes the intersection of this point with another constraint.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point & point() const
Const getter for the _point attribute.
const Real & tol() const
Const getter for the _tol attribute.
Represents a fixed point constraint.
Real _tol
Tolerance to use for numerical comparisons.
static ConstraintVariant determine_constraint(const Node &node, const unsigned int dim, const std::set< std::set< const Node *>> &side_grouped_boundary_neighbors)
Determines the appropriate constraint (PointConstraint, LineConstraint, or PlaneConstraint) for a nod...
Abstract base class to be used for system constraints.
Definition: system.h:179
void impose_constraint(const Node &node, const ConstraintVariant &constraint)
Applies a given constraint to a node (e.g., fixing it, restricting it to a line or plane)...
Represents a line constraint defined by a base point and direction vector.
const Point & point() const
Const getter for the _point attribute.
std::variant< PointConstraint, LineConstraint, PlaneConstraint, InvalidConstraint > ConstraintVariant
Type used to store a constraint that may be a PlaneConstraint, LineConstraint, or PointConstraint...
bool is_parallel(const PlaneConstraint &p) const
Query whether a plane is parallel to this plane.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
bool operator==(const PlaneConstraint &other) const
Equality operator.
const Real & tol() const
Const getter for the _tol attribute.
static void find_nodal_or_face_neighbors(const MeshBase &mesh, const Node &node, const std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem_map, std::vector< const Node *> &neighbors)
Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to t...
void fix_node(const Node &node)
Constrain (i.e., fix) a node to not move during mesh smoothing.
VariationalSmootherConstraint(System &sys, const bool &preserve_subdomain_boundaries)
Constructor.
bool contains_point(const PointConstraint &p) const
Query whether a point lies on the line.
uint8_t dof_id_type
Definition: id_types.h:67
const Real & tol() const
Const getter for the _tol attribute.
ConstraintVariant intersect(const ConstraintVariant &other) const
Computes the intersection of this plane with another constraint.